From 95f03d21a54242ea583c5cd83ec2209eee47143a Mon Sep 17 00:00:00 2001 From: Zhang Minghan Date: Wed, 25 Oct 2023 20:37:36 +0800 Subject: [PATCH] add xlink --- app/src/components/Markdown.tsx | 28 +++++++++++ app/src/components/SelectGroup.tsx | 18 ++++--- app/src/components/app/MenuBar.tsx | 3 +- app/src/components/home/ChatWrapper.tsx | 63 ++++++++++++++----------- app/src/conf.ts | 2 +- app/src/conversation/invitation.ts | 2 +- app/src/dialogs/Invitation.tsx | 42 ++++++++--------- app/src/dialogs/ShareManagement.tsx | 24 +++++----- app/src/i18n.ts | 26 +++++----- app/src/store/invitation.ts | 12 +++-- manager/chat.go | 2 +- 11 files changed, 133 insertions(+), 89 deletions(-) diff --git a/app/src/components/Markdown.tsx b/app/src/components/Markdown.tsx index ff08f2b4..fbb689f9 100644 --- a/app/src/components/Markdown.tsx +++ b/app/src/components/Markdown.tsx @@ -7,13 +7,30 @@ import rehypeKatex from "rehype-katex"; import { parseFile } from "./plugins/file.tsx"; import "../assets/markdown/all.less"; import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { openDialog as openQuotaDialog } from "../store/quota.ts"; +import { openDialog as openSubscriptionDialog } from "../store/subscription.ts"; +import {AppDispatch} from "../store"; type MarkdownProps = { children: string; className?: string; }; +function doAction(dispatch: AppDispatch, url: string): boolean { + if (url === "/subscribe") { + dispatch(openSubscriptionDialog()); + return true; + } else if (url === "/buy") { + dispatch(openQuotaDialog()); + return true; + } + return false; +} + function Markdown({ children, className }: MarkdownProps) { + const dispatch = useDispatch(); + useEffect(() => { document.querySelectorAll(".file-instance").forEach((el) => { const parent = el.parentElement as HTMLElement; @@ -29,6 +46,17 @@ function Markdown({ children, className }: MarkdownProps) { className={`markdown-body ${className}`} children={children} components={{ + a({ href, children }) { + const url: string = href?.toString() || ""; + + return ( + { + if (doAction(dispatch, url)) e.preventDefault(); + }}> + {children} + + ) + }, code({ inline, className, children, ...props }) { const match = /language-(\w+)/.exec(className || ""); if (match && match[1] === "file") diff --git a/app/src/components/SelectGroup.tsx b/app/src/components/SelectGroup.tsx index 39eac4c6..a1392e3c 100644 --- a/app/src/components/SelectGroup.tsx +++ b/app/src/components/SelectGroup.tsx @@ -8,7 +8,7 @@ import { import { mobile } from "../utils.ts"; import { useEffect, useState } from "react"; import { Badge } from "./ui/badge.tsx"; -import {toggleEvent} from "../events/model.ts"; +import { toggleEvent } from "../events/model.ts"; export type SelectItemBadgeProps = { variant: "default" | "gold"; @@ -34,7 +34,9 @@ function GroupSelectItem(props: SelectItemProps) {
{props.value} {props.badge && ( - + {props.badge.name} )} @@ -104,11 +106,13 @@ function SelectGroupMobile(props: SelectGroupProps) { - { - e.preventDefault(); - e.stopPropagation(); - toggleEvent.emit(new Date().getTime()); - }}> + { + e.preventDefault(); + e.stopPropagation(); + toggleEvent.emit(new Date().getTime()); + }} + > {props.list.map((select: SelectItemProps, idx: number) => ( diff --git a/app/src/components/app/MenuBar.tsx b/app/src/components/app/MenuBar.tsx index 2daa5b5c..fbc655a1 100644 --- a/app/src/components/app/MenuBar.tsx +++ b/app/src/components/app/MenuBar.tsx @@ -18,7 +18,8 @@ import { BadgeCent, Boxes, CalendarPlus, - Cloud, Gift, + Cloud, + Gift, ListStart, Plug, } from "lucide-react"; diff --git a/app/src/components/home/ChatWrapper.tsx b/app/src/components/home/ChatWrapper.tsx index fe08433f..83efa97d 100644 --- a/app/src/components/home/ChatWrapper.tsx +++ b/app/src/components/home/ChatWrapper.tsx @@ -14,7 +14,13 @@ import { formatMessage } from "../../utils.ts"; import ChatInterface from "./ChatInterface.tsx"; import { Button } from "../ui/button.tsx"; import router from "../../router.tsx"; -import {BookMarked, ChevronRight, FolderKanban, Globe, Users2} from "lucide-react"; +import { + BookMarked, + ChevronRight, + FolderKanban, + Globe, + Users2, +} from "lucide-react"; import { Tooltip, TooltipContent, @@ -32,7 +38,7 @@ import { DialogHeader, DialogTitle, } from "../ui/dialog.tsx"; -import {toggleEvent} from "../../events/model.ts"; +import { toggleEvent } from "../../events/model.ts"; function ChatSpace() { const [open, setOpen] = useState(false); @@ -40,7 +46,7 @@ function ChatSpace() { const [prevent, setPrevent] = useState(0); toggleEvent.bind(setPrevent); - const notPrevent = (): boolean => (new Date().getTime() - prevent) >= 1000; + const notPrevent = (): boolean => new Date().getTime() - prevent >= 1000; return (
@@ -62,31 +68,38 @@ function ChatSpace() { {t("contact.title")} - - - - {`QQ`} - - + +
+ + + {`QQ`} + +
+
- ) + ); } - function ChatWrapper() { const { t } = useTranslation(); const [file, setFile] = useState({ @@ -147,11 +160,7 @@ function ChatWrapper() { return (
- {messages.length > 0 ? ( - - ) : ( - - )} + {messages.length > 0 ? : }
diff --git a/app/src/conf.ts b/app/src/conf.ts index e2ed5abf..9a86663b 100644 --- a/app/src/conf.ts +++ b/app/src/conf.ts @@ -1,7 +1,7 @@ import axios from "axios"; import { Model } from "./conversation/types.ts"; -export const version = "3.5.11"; +export const version = "3.5.12"; export const dev: boolean = window.location.hostname === "localhost"; export const deploy: boolean = true; export let rest_api: string = "http://localhost:8094"; diff --git a/app/src/conversation/invitation.ts b/app/src/conversation/invitation.ts index 2c531d11..149d70f7 100644 --- a/app/src/conversation/invitation.ts +++ b/app/src/conversation/invitation.ts @@ -4,7 +4,7 @@ export type InvitationResponse = { status: boolean; error: string; quota: number; -} +}; export async function getInvitation(code: string): Promise { try { diff --git a/app/src/dialogs/Invitation.tsx b/app/src/dialogs/Invitation.tsx index 8e62a5e2..eb8beb11 100644 --- a/app/src/dialogs/Invitation.tsx +++ b/app/src/dialogs/Invitation.tsx @@ -9,15 +9,11 @@ import { import { Button } from "../components/ui/button.tsx"; import { useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; -import { - closeDialog, - dialogSelector, - setDialog, -} from "../store/invitation.ts"; +import { closeDialog, dialogSelector, setDialog } from "../store/invitation.ts"; import { Input } from "../components/ui/input.tsx"; import { useToast } from "../components/ui/use-toast.ts"; -import {useState} from "react"; -import {getInvitation} from "../conversation/invitation.ts"; +import { useState } from "react"; +import { getInvitation } from "../conversation/invitation.ts"; function Invitation() { const { t } = useTranslation(); @@ -44,20 +40,24 @@ function Invitation() { - diff --git a/app/src/dialogs/ShareManagement.tsx b/app/src/dialogs/ShareManagement.tsx index 9f57c517..43ac8ecb 100644 --- a/app/src/dialogs/ShareManagement.tsx +++ b/app/src/dialogs/ShareManagement.tsx @@ -130,19 +130,17 @@ function ShareManagement() { {t("share.manage")} - { - data.length > 0 ? ( - - - - ) : ( - -

- {t("conversation.empty")} -

-
- ) - } + {data.length > 0 ? ( + + + + ) : ( + +

+ {t("conversation.empty")} +

+
+ )}