@@ -5,7 +5,8 @@ import {
|
||||
NodeType,
|
||||
Schema,
|
||||
} from "prosemirror-model";
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
import { Command, Plugin, TextSelection } from "prosemirror-state";
|
||||
import { EditorView } from "prosemirror-view";
|
||||
import { Primitive } from "utility-types";
|
||||
import Suggestion from "../extensions/Suggestion";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
@@ -68,6 +69,7 @@ export default class Mention extends Suggestion {
|
||||
"data-type": node.attrs.type,
|
||||
"data-id": node.attrs.modelId,
|
||||
"data-actorId": node.attrs.actorId,
|
||||
"data-url": `mention://${node.attrs.id}/${node.attrs.type}/${node.attrs.modelId}`,
|
||||
},
|
||||
node.attrs.label,
|
||||
],
|
||||
@@ -79,6 +81,31 @@ export default class Mention extends Suggestion {
|
||||
return [mentionRule];
|
||||
}
|
||||
|
||||
get plugins(): Plugin[] {
|
||||
return [
|
||||
new Plugin({
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
mouseover: (view: EditorView, event: MouseEvent) => {
|
||||
const target = (event.target as HTMLElement)?.closest("span");
|
||||
if (
|
||||
target instanceof HTMLSpanElement &&
|
||||
this.editor.elementRef.current?.contains(target) &&
|
||||
!target.className.includes("ProseMirror-widget") &&
|
||||
(!view.editable || (view.editable && !view.hasFocus()))
|
||||
) {
|
||||
if (this.options.onHoverLink) {
|
||||
return this.options.onHoverLink(target);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
commands({ type }: { type: NodeType; schema: Schema }) {
|
||||
return (attrs: Record<string, Primitive>): Command =>
|
||||
(state, dispatch) => {
|
||||
|
||||
@@ -899,5 +899,14 @@
|
||||
"Webhooks can be used to notify your application when events happen in {{appName}}. Events are sent as a https request with a JSON payload in near real-time.": "Webhooks can be used to notify your application when events happen in {{appName}}. Events are sent as a https request with a JSON payload in near real-time.",
|
||||
"Inactive": "Inactive",
|
||||
"Create a webhook": "Create a webhook",
|
||||
"Never logged in": "Never logged in",
|
||||
"Online now": "Online now",
|
||||
"Online {{ timeAgo }}": "Online {{ timeAgo }}",
|
||||
"Viewed just now": "Viewed just now",
|
||||
"Viewed {{ timeAgo }}": "Viewed {{ timeAgo }}",
|
||||
"You updated {{ timeAgo }}": "You updated {{ timeAgo }}",
|
||||
"{{ user }} updated {{ timeAgo }}": "{{ user }} updated {{ timeAgo }}",
|
||||
"You created {{ timeAgo }}": "You created {{ timeAgo }}",
|
||||
"{{ user }} created {{ timeAgo }}": "{{ user }} created {{ timeAgo }}",
|
||||
"Uploading": "Uploading"
|
||||
}
|
||||
|
||||
@@ -209,5 +209,19 @@ export const NotificationEventDefaults = {
|
||||
[NotificationEventType.ExportCompleted]: true,
|
||||
};
|
||||
|
||||
export enum UnfurlType {
|
||||
Mention = "mention",
|
||||
Document = "document",
|
||||
}
|
||||
|
||||
export type Unfurl<T = unknown> = {
|
||||
url?: string;
|
||||
type: T;
|
||||
title: string;
|
||||
description: string;
|
||||
thumbnailUrl?: string | null;
|
||||
meta: Record<string, string>;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type ProsemirrorData = Record<string, any>;
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
/* eslint-disable import/no-duplicates */
|
||||
import { subDays, subMonths, subWeeks, subYears } from "date-fns";
|
||||
import {
|
||||
de,
|
||||
enUS,
|
||||
es,
|
||||
faIR,
|
||||
fr,
|
||||
it,
|
||||
ja,
|
||||
ko,
|
||||
nl,
|
||||
ptBR,
|
||||
pt,
|
||||
pl,
|
||||
ru,
|
||||
tr,
|
||||
vi,
|
||||
zhCN,
|
||||
zhTW,
|
||||
} from "date-fns/locale";
|
||||
import type { DateFilter } from "../types";
|
||||
|
||||
export function subtractDate(date: Date, period: DateFilter) {
|
||||
@@ -80,3 +100,35 @@ export function getCurrentDateTimeAsString(locales?: Intl.LocalesArgument) {
|
||||
minute: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
const locales = {
|
||||
de_DE: de,
|
||||
en_US: enUS,
|
||||
es_ES: es,
|
||||
fa_IR: faIR,
|
||||
fr_FR: fr,
|
||||
it_IT: it,
|
||||
ja_JP: ja,
|
||||
ko_KR: ko,
|
||||
nl_NL: nl,
|
||||
pt_BR: ptBR,
|
||||
pt_PT: pt,
|
||||
pl_PL: pl,
|
||||
ru_RU: ru,
|
||||
tr_TR: tr,
|
||||
vi_VN: vi,
|
||||
zh_CN: zhCN,
|
||||
zh_TW: zhTW,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the date-fns locale object for the given user language preference.
|
||||
*
|
||||
* @param language The user language
|
||||
* @returns The date-fns locale.
|
||||
*/
|
||||
export function dateLocale(language: string | null | undefined) {
|
||||
return language ? locales[language] : undefined;
|
||||
}
|
||||
|
||||
export { locales };
|
||||
|
||||
12
shared/utils/parseMentionUrl.ts
Normal file
12
shared/utils/parseMentionUrl.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
const parseMentionUrl = (url: string) => {
|
||||
const matches = url.match(
|
||||
/^mention:\/\/([a-z0-9-]+)\/([a-z]+)\/([a-z0-9-]+)$/
|
||||
);
|
||||
if (!matches) {
|
||||
return {};
|
||||
}
|
||||
const [id, mentionType, modelId] = matches.slice(1);
|
||||
return { id, mentionType, modelId };
|
||||
};
|
||||
|
||||
export default parseMentionUrl;
|
||||
Reference in New Issue
Block a user