diff --git a/services/user/Chainmail/ui/src/components/compose-dialog.tsx b/services/user/Chainmail/ui/src/components/compose-dialog.tsx
index c6be19ef6..aea7bbf15 100644
--- a/services/user/Chainmail/ui/src/components/compose-dialog.tsx
+++ b/services/user/Chainmail/ui/src/components/compose-dialog.tsx
@@ -169,72 +169,78 @@ export const ComposeDialog = ({
>
{trigger}
{
// This helps in not focusing on the trigger after closing the modal
e.preventDefault();
}}
>
-
- Compose message
-
- Send a message to another account on the network
-
-
-
-
-
+
);
diff --git a/services/user/Chainmail/ui/src/components/editor/link-widget.tsx b/services/user/Chainmail/ui/src/components/editor/link-widget.tsx
index b15b4b21d..a8c101533 100644
--- a/services/user/Chainmail/ui/src/components/editor/link-widget.tsx
+++ b/services/user/Chainmail/ui/src/components/editor/link-widget.tsx
@@ -1,136 +1,64 @@
-import { commandsCtx } from "@milkdown/core";
-import { updateLinkCommand } from "@milkdown/preset-commonmark";
-import { Plugin } from "@milkdown/prose/state";
-import { DecorationSet } from "@milkdown/prose/view";
-import { useInstance } from "@milkdown/react";
-import { $prose } from "@milkdown/utils";
-import type { useWidgetViewFactory } from "@prosemirror-adapter/react";
-import { useWidgetViewContext } from "@prosemirror-adapter/react";
+import type { Ctx } from "@milkdown/ctx";
+import type { EditorView } from "@milkdown/prose/view";
+import type { EditorState } from "@milkdown/prose/state";
-export const LinkWidgetBefore = () => {
- return <>[>;
-};
+import { editorViewCtx } from "@milkdown/core";
+import { linkSchema } from "@milkdown/preset-commonmark";
+import {
+ configureLinkTooltip,
+ linkTooltipAPI,
+ linkTooltipState,
+} from "@milkdown/components/link-tooltip";
+import { TooltipProvider, tooltipFactory } from "@milkdown/plugin-tooltip";
-export const LinkWidgetAfter = () => {
- const { spec } = useWidgetViewContext();
- const [loading, editor] = useInstance();
- const href = spec?.href ?? "";
- const title = spec?.title ?? "";
+import "../../styles/link-tooltip.css";
- return (
- <>
- ]
-
- (
- {
- <>
- link:
- {
- if (loading) return;
- editor().action((ctx) => {
- const commands = ctx.get(commandsCtx);
- commands.call(updateLinkCommand.key, {
- href: e.target.value,
- });
- });
- }}
- className="rounded border-none bg-gray-50 px-2 py-0 ring-1 dark:bg-gray-900"
- type="text"
- defaultValue={href}
- />
-
- title:
- "
- {
- if (loading) return;
- editor().action((ctx) => {
- const commands = ctx.get(commandsCtx);
- commands.call(updateLinkCommand.key, {
- title: e.target.value,
- });
- });
- }}
- className="rounded border-none bg-gray-50 px-2 py-0 ring-1 dark:bg-gray-900"
- type="text"
- defaultValue={title}
- />
- "
- >
- }
- )
-
- >
- );
-};
+export { linkTooltipPlugin } from "@milkdown/components/link-tooltip";
-export const linkPlugin = (
- widgetViewFactory: ReturnType,
-) => {
- const before = widgetViewFactory({
- as: "span",
- component: LinkWidgetBefore,
- });
- const after = widgetViewFactory({ as: "span", component: LinkWidgetAfter });
-
- return $prose(
- () =>
- new Plugin({
- state: {
- init() {
- return DecorationSet.empty;
- },
- apply(tr) {
- const { selection } = tr;
+export const insertLinkTooltip = tooltipFactory("CREATE_LINK");
- const { $from, $to } = selection;
- const node = tr.doc.nodeAt(selection.from);
+export function tooltipPluginView(ctx: Ctx) {
+ return (_view: EditorView) => {
+ const content = document.createElement("div");
+ const provider = new TooltipProvider({
+ content,
+ shouldShow: (view: EditorView) => {
+ const { selection, doc } = view.state;
+ const has = doc.rangeHasMark(
+ selection.from,
+ selection.to,
+ linkSchema.type(ctx),
+ );
+ if (has || selection.empty) return false;
- const mark = node?.marks.find(
- (mark) => mark.type.name === "link",
- );
+ return true;
+ },
+ });
- if (!mark) return DecorationSet.empty;
+ content.onmousedown = (e: MouseEvent) => {
+ e.preventDefault();
+ const view = ctx.get(editorViewCtx);
+ const { selection } = view.state;
+ ctx.get(linkTooltipAPI.key).addLink(selection.from, selection.to);
+ provider.hide();
+ };
- let markPos = { start: -1, end: -1 };
- tr.doc.nodesBetween(
- $from.start(),
- $to.end(),
- (n, pos) => {
- if (node === n) {
- markPos = {
- start: pos,
- end:
- pos +
- Math.max(n.textContent.length, 1),
- };
+ return {
+ update: (updatedView: EditorView, prevState: EditorState) => {
+ if (ctx.get(linkTooltipState.key).mode === "edit") return;
+ provider.update(updatedView, prevState);
+ },
+ destroy: () => {
+ provider.destroy();
+ content.remove();
+ },
+ };
+ };
+}
- // stop recursing if result is found
- return false;
- }
- return undefined;
- },
- );
-
- return DecorationSet.create(tr.doc, [
- before(markPos.start),
- after(markPos.end, {
- href: mark.attrs.href,
- title: mark.attrs.title,
- }),
- ]);
- },
- },
- props: {
- decorations(state) {
- return this.getState(state);
- },
- },
- }),
- );
-};
+export function linkTooltipConfig(ctx: Ctx) {
+ ctx.set(insertLinkTooltip.key, {
+ view: tooltipPluginView(ctx),
+ });
+ configureLinkTooltip(ctx);
+}
diff --git a/services/user/Chainmail/ui/src/components/markdown-editor.tsx b/services/user/Chainmail/ui/src/components/markdown-editor.tsx
index c0c079de2..7dada5b5c 100644
--- a/services/user/Chainmail/ui/src/components/markdown-editor.tsx
+++ b/services/user/Chainmail/ui/src/components/markdown-editor.tsx
@@ -1,6 +1,3 @@
-import type { MilkdownPlugin } from "@milkdown/ctx";
-
-import { useMemo } from "react";
import { atom, useSetAtom } from "jotai";
import {
defaultValueCtx,
@@ -9,21 +6,17 @@ import {
rootCtx,
schemaCtx,
} from "@milkdown/core";
-import { $view } from "@milkdown/utils";
+// import { $view } from "@milkdown/utils";
import { nord } from "@milkdown/theme-nord";
import { Milkdown, useEditor } from "@milkdown/react";
import { commonmark } from "@milkdown/preset-commonmark";
import { gfm } from "@milkdown/preset-gfm";
import { listItemBlockComponent } from "@milkdown/components/list-item-block";
-import {
- configureLinkTooltip,
- linkTooltipPlugin,
-} from "@milkdown/components/link-tooltip";
import { listener, listenerCtx } from "@milkdown/plugin-listener";
import { history } from "@milkdown/plugin-history";
// import { math, mathBlockSchema } from "@milkdown/plugin-math";
// import { diagram, diagramSchema } from "@milkdown/plugin-diagram";
-import { useNodeViewFactory } from "@prosemirror-adapter/react";
+// import { useNodeViewFactory } from "@prosemirror-adapter/react";
import { Node, Schema } from "@milkdown/prose/model";
import {
@@ -33,6 +26,11 @@ import {
// import { MathBlock, MermaidDiagram } from "./editor";
// import { MathBlock } from "./editor";
+import {
+ insertLinkTooltip,
+ linkTooltipConfig,
+ linkTooltipPlugin,
+} from "./editor/link-widget";
import "@milkdown/theme-nord/style.css";
// import "katex/dist/katex.min.css";
@@ -56,7 +54,7 @@ export const MarkdownEditor = ({
updateMarkdown,
readOnly = false,
}: EditorProps) => {
- const nodeViewFactory = useNodeViewFactory();
+ // const nodeViewFactory = useNodeViewFactory();
const setSelection = useSetAtom(editorSelectionAtom);
// const mathPlugins: MilkdownPlugin[] = useMemo(() => {
@@ -89,8 +87,8 @@ export const MarkdownEditor = ({
.config((ctx) => {
ctx.set(rootCtx, root);
ctx.set(defaultValueCtx, initialValue);
- configureLinkTooltip(ctx);
})
+ .config(linkTooltipConfig)
.config((ctx) => {
if (readOnly) return;
const listener = ctx.get(listenerCtx);
@@ -120,7 +118,8 @@ export const MarkdownEditor = ({
.use(listItemBlockComponent)
// .use(mathPlugins)
// .use(diagramPlugins)
- .use(linkTooltipPlugin),
+ .use(linkTooltipPlugin)
+ .use(insertLinkTooltip),
);
return ;
diff --git a/services/user/Chainmail/ui/src/hooks/use-user.ts b/services/user/Chainmail/ui/src/hooks/use-user.ts
index b0023cd55..a63bdaeda 100644
--- a/services/user/Chainmail/ui/src/hooks/use-user.ts
+++ b/services/user/Chainmail/ui/src/hooks/use-user.ts
@@ -48,7 +48,13 @@ export function useUser() {
};
useEffect(() => {
- getConnectedAccounts();
+ const logIn = async () => {
+ await logInAs("alice");
+ await logInAs("bob");
+ getConnectedAccounts();
+ };
+ if (availableAccounts.length) return;
+ logIn();
}, []);
return {
diff --git a/services/user/Chainmail/ui/src/routes/home.tsx b/services/user/Chainmail/ui/src/routes/home.tsx
index 83ff93b7f..a3bbcaa87 100644
--- a/services/user/Chainmail/ui/src/routes/home.tsx
+++ b/services/user/Chainmail/ui/src/routes/home.tsx
@@ -37,13 +37,9 @@ export function Home() {
Inbox
-
-
- }
- />
-
+ }
+ />
diff --git a/services/user/Chainmail/ui/src/styles/editor.css b/services/user/Chainmail/ui/src/styles/editor.css
index 8fc586848..462f5d51a 100644
--- a/services/user/Chainmail/ui/src/styles/editor.css
+++ b/services/user/Chainmail/ui/src/styles/editor.css
@@ -10,6 +10,10 @@
@apply mx-auto h-full max-w-none dark:text-foreground;
}
+.prose a {
+ @apply dark:text-foreground;
+}
+
/* list-item-block */
.prose :where(li):not(:where([class~="not-prose"] *)) {
margin-top: 0.5em;
@@ -68,89 +72,3 @@ milkdown-list-item-block .label-wrapper {
align-items: center;
color: darkcyan;
}
-
-milkdown-link-preview {
- & > .link-preview {
- @apply rounded-md border bg-white;
- height: 42px;
- display: flex;
- justify-content: center;
- padding: 8px;
- gap: 8px;
- cursor: pointer;
-
- & > .link-display:hover:before {
- display: block;
- }
-
- & > .link-display:before {
- content: "click to copy link";
- position: absolute;
- transform: translate(50%, -130%);
- padding: 6px 10px;
- font-size: 12px;
- border-radius: 10px;
- background: #000;
- color: #fff;
- text-align: center;
-
- display: none;
- }
-
- & > .link-icon {
- & > svg {
- width: 14px;
- height: 14px;
- }
- padding: 5px;
- }
-
- & > .link-display {
- width: 240px;
- line-height: 24px;
- overflow: hidden;
- text-overflow: ellipsis;
- font-size: 14px;
- &:hover {
- text-decoration: underline;
- }
- }
-
- & > .button {
- & > svg {
- width: 14px;
- height: 14px;
- }
- padding: 5px;
- @apply rounded-md;
- &:hover {
- @apply bg-accent;
- }
- }
- }
-}
-
-milkdown-link-edit {
- & > .link-edit {
- @apply flex justify-center gap-2 rounded-md border bg-white px-3 py-2;
- height: 42px;
-
- & > .input-area {
- outline: none;
- background: transparent;
- width: 200px;
- font-size: 14px;
- }
-
- & > .button {
- @apply flex cursor-pointer items-center rounded-md px-1.5;
- font-size: 12px;
- &:hover {
- @apply bg-accent;
- }
- &.hidden {
- visibility: hidden;
- }
- }
- }
-}
diff --git a/services/user/Chainmail/ui/src/styles/link-tooltip.css b/services/user/Chainmail/ui/src/styles/link-tooltip.css
new file mode 100644
index 000000000..1eb21df00
--- /dev/null
+++ b/services/user/Chainmail/ui/src/styles/link-tooltip.css
@@ -0,0 +1,99 @@
+milkdown-link-preview {
+ position: absolute;
+ &[data-show="false"] {
+ display: none;
+ }
+
+ @apply dark:text-background;
+
+ & > .link-preview {
+ @apply absolute -right-40 -top-12 z-20 rounded-md border bg-white;
+ height: 42px;
+ display: flex;
+ justify-content: center;
+ padding: 8px;
+ gap: 8px;
+ cursor: pointer;
+
+ & > .link-display:hover:before {
+ display: block;
+ }
+
+ & > .link-display:before {
+ content: "click to copy link";
+ position: absolute;
+ transform: translate(50%, -130%);
+ padding: 6px 10px;
+ font-size: 12px;
+ border-radius: 10px;
+ background: #000;
+ color: #fff;
+ text-align: center;
+
+ display: none;
+ }
+
+ & > .link-icon {
+ @apply px-1;
+ & > svg {
+ width: 14px;
+ height: 14px;
+ }
+ }
+
+ & > .link-display {
+ width: 240px;
+ line-height: 24px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 14px;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+ & > .button {
+ & > svg {
+ width: 14px;
+ height: 14px;
+ }
+ @apply rounded-md px-1;
+ &:hover {
+ @apply bg-accent dark:text-foreground;
+ }
+ }
+ }
+}
+
+milkdown-link-edit {
+ position: absolute;
+ &[data-show="false"] {
+ display: none;
+ }
+
+ @apply dark:text-background;
+
+ & > .link-edit {
+ @apply absolute -right-40 -top-12 z-20 flex justify-center gap-2 rounded-md border bg-white px-3 py-2;
+ height: 42px;
+
+ & > .input-area {
+ outline: none;
+ background: transparent;
+ width: 200px;
+ font-size: 14px;
+ }
+
+ & > .button {
+ @apply flex w-max cursor-pointer items-center rounded-md px-1.5;
+ font-size: 12px;
+ &:hover {
+ @apply bg-accent dark:text-foreground;
+ }
+ &.hidden {
+ visibility: hidden;
+ }
+ }
+ }
+}