Skip to content

Commit

Permalink
add xlink
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Oct 25, 2023
1 parent 02d6159 commit 95f03d2
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 89 deletions.
28 changes: 28 additions & 0 deletions app/src/components/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 (
<a href={url} target={`_blank`} rel={`noopener noreferrer`} onClick={(e) => {
if (doAction(dispatch, url)) e.preventDefault();
}}>
{children}
</a>
)
},
code({ inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || "");
if (match && match[1] === "file")
Expand Down
18 changes: 11 additions & 7 deletions app/src/components/SelectGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -34,7 +34,9 @@ function GroupSelectItem(props: SelectItemProps) {
<div className={`mr-1`}>
{props.value}
{props.badge && (
<Badge className={`select-element badge ml-1 badge-${props.badge.variant}`}>
<Badge
className={`select-element badge ml-1 badge-${props.badge.variant}`}
>
{props.badge.name}
</Badge>
)}
Expand Down Expand Up @@ -104,11 +106,13 @@ function SelectGroupMobile(props: SelectGroupProps) {
<SelectTrigger className="select-group mobile">
<SelectValue placeholder={props.current.value} />
</SelectTrigger>
<SelectContent onCloseAutoFocus={(e) => {
e.preventDefault();
e.stopPropagation();
toggleEvent.emit(new Date().getTime());
}}>
<SelectContent
onCloseAutoFocus={(e) => {
e.preventDefault();
e.stopPropagation();
toggleEvent.emit(new Date().getTime());
}}
>
{props.list.map((select: SelectItemProps, idx: number) => (
<SelectItem key={idx} value={select.name}>
<GroupSelectItem {...select} />
Expand Down
3 changes: 2 additions & 1 deletion app/src/components/app/MenuBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
BadgeCent,
Boxes,
CalendarPlus,
Cloud, Gift,
Cloud,
Gift,
ListStart,
Plug,
} from "lucide-react";
Expand Down
63 changes: 36 additions & 27 deletions app/src/components/home/ChatWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -32,15 +38,15 @@ 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);
const { t } = useTranslation();
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 (
<div className={`chat-product`}>
Expand All @@ -62,31 +68,38 @@ function ChatSpace() {
<DialogContent>
<DialogHeader>
<DialogTitle>{t("contact.title")}</DialogTitle>
<DialogDescription />
<Button
className={`mx-auto`}
variant={`outline`}
onClick={() => window.open("https://docs.chatnio.net", "_blank")}
>
<BookMarked className={`h-4 w-4 mr-1.5`} />
{t("docs.title")}
</Button>
<a
href={"http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=1oKfIbNVXmMNMVzW1NiFSTKDcT1qIEq5&authKey=uslxslIBZtLImf4BSxjDqfx4hiJA52YV7PFM38W%2BOArr%2BhE0jwVdQCRYs0%2FXKX7W&noverify=0&group_code=565902327"}
target={"_blank"}
className={`mx-auto`}
>
<img src={`/source/qq.jpg`} className={`contact-image`} alt={`QQ`} />
</a>

<DialogDescription asChild>
<div className={`flex flex-row pt-4`}>
<Button
className={`mx-auto`}
variant={`outline`}
onClick={() => window.open("https://docs.chatnio.net", "_blank")}
>
<BookMarked className={`h-4 w-4 mr-1.5`} />
{t("docs.title")}
</Button>
<a
href={
"http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=1oKfIbNVXmMNMVzW1NiFSTKDcT1qIEq5&authKey=uslxslIBZtLImf4BSxjDqfx4hiJA52YV7PFM38W%2BOArr%2BhE0jwVdQCRYs0%2FXKX7W&noverify=0&group_code=565902327"
}
target={"_blank"}
className={`inline-flex mx-auto`}
>
<img
src={`/source/qq.jpg`}
className={`contact-image`}
alt={`QQ`}
/>
</a>
</div>
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
</div>
)
);
}


function ChatWrapper() {
const { t } = useTranslation();
const [file, setFile] = useState<FileObject>({
Expand Down Expand Up @@ -147,11 +160,7 @@ function ChatWrapper() {
return (
<div className={`chat-container`}>
<div className={`chat-wrapper`}>
{messages.length > 0 ? (
<ChatInterface />
) : (
<ChatSpace />
)}
{messages.length > 0 ? <ChatInterface /> : <ChatSpace />}
<div className={`chat-input`}>
<div className={`input-wrapper`}>
<TooltipProvider>
Expand Down
2 changes: 1 addition & 1 deletion app/src/conf.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
2 changes: 1 addition & 1 deletion app/src/conversation/invitation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export type InvitationResponse = {
status: boolean;
error: string;
quota: number;
}
};

export async function getInvitation(code: string): Promise<InvitationResponse> {
try {
Expand Down
42 changes: 21 additions & 21 deletions app/src/dialogs/Invitation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -44,20 +40,24 @@ function Invitation() {
<Button variant={`outline`} onClick={() => dispatch(closeDialog())}>
{t("invitation.cancel")}
</Button>
<Button onClick={async () => {
const resp = await getInvitation(code.trim());
if (resp.status) {
toast({
title: t("invitation.check-success"),
description: t("invitation.check-success-description", { amount: resp.quota }),
})
dispatch(closeDialog());
}
else toast({
title: t("invitation.check-failed"),
description: resp.error,
})
}}>
<Button
onClick={async () => {
const resp = await getInvitation(code.trim());
if (resp.status) {
toast({
title: t("invitation.check-success"),
description: t("invitation.check-success-description", {
amount: resp.quota,
}),
});
dispatch(closeDialog());
} else
toast({
title: t("invitation.check-failed"),
description: resp.error,
});
}}
>
{t("invitation.check")}
</Button>
</DialogFooter>
Expand Down
24 changes: 11 additions & 13 deletions app/src/dialogs/ShareManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,17 @@ function ShareManagement() {
<DialogContent>
<DialogHeader>
<DialogTitle>{t("share.manage")}</DialogTitle>
{
data.length > 0 ? (
<DialogDescription className={`share-table`}>
<ShareTable data={data} />
</DialogDescription>
) : (
<DialogDescription>
<p className={`text-center select-none mt-6 mb-2`}>
{t("conversation.empty")}
</p>
</DialogDescription>
)
}
{data.length > 0 ? (
<DialogDescription className={`share-table`}>
<ShareTable data={data} />
</DialogDescription>
) : (
<DialogDescription>
<p className={`text-center select-none mt-6 mb-2`}>
{t("conversation.empty")}
</p>
</DialogDescription>
)}
</DialogHeader>
<DialogFooter>
<Button variant={`outline`} onClick={() => dispatch(closeDialog())}>
Expand Down
26 changes: 14 additions & 12 deletions app/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,16 @@ const resources = {
invitation: {
title: "Redeem Code",
"input-placeholder": "Please enter the redeem code",
"cancel": "Cancel",
"check": "Check",
cancel: "Cancel",
check: "Check",
"check-success": "Redeem Success",
"check-success-description": "Redeem Success! You have received {{amount}} points, start your AI journey!",
"check-success-description":
"Redeem Success! You have received {{amount}} points, start your AI journey!",
"check-failed": "Redeem Failed",
},
contact: {
title: "Contact Us",
}
},
},
},
cn: {
Expand Down Expand Up @@ -397,16 +398,16 @@ const resources = {
invitation: {
title: "兑换码",
"input-placeholder": "请输入兑换码",
"cancel": "取消",
"check": "验证",
cancel: "取消",
check: "验证",
"check-success": "兑换成功",
"check-success-description": "兑换成功!您已获得 {{amount}} 点数,开始您的 AI 之旅吧!",
"check-success-description":
"兑换成功!您已获得 {{amount}} 点数,开始您的 AI 之旅吧!",
"check-failed": "兑换失败",
},
contact: {
title: "联系我们",
},

},
},
ru: {
Expand Down Expand Up @@ -605,15 +606,16 @@ const resources = {
invitation: {
title: "Код приглашения",
"input-placeholder": "Введите код приглашения",
"cancel": "Отмена",
"check": "Проверить",
cancel: "Отмена",
check: "Проверить",
"check-success": "Успешно",
"check-success-description": "Успешно! Вы получили {{amount}} очков, начните свое путешествие в мир AI!",
"check-success-description":
"Успешно! Вы получили {{amount}} очков, начните свое путешествие в мир AI!",
"check-failed": "Не удалось",
},
contact: {
title: "Связаться с нами",
}
},
},
},
};
Expand Down
12 changes: 7 additions & 5 deletions app/src/store/invitation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {createSlice} from "@reduxjs/toolkit";
import {RootState} from "./index.ts";
import { createSlice } from "@reduxjs/toolkit";
import { RootState } from "./index.ts";

export const invitationSlice = createSlice({
name: "invitation",
Expand All @@ -19,10 +19,12 @@ export const invitationSlice = createSlice({
closeDialog: (state) => {
state.dialog = false;
},
}
},
});

export const {toggleDialog, setDialog, openDialog, closeDialog} = invitationSlice.actions;
export const { toggleDialog, setDialog, openDialog, closeDialog } =
invitationSlice.actions;
export default invitationSlice.reducer;

export const dialogSelector = (state: RootState): boolean => state.invitation.dialog;
export const dialogSelector = (state: RootState): boolean =>
state.invitation.dialog;
Loading

0 comments on commit 95f03d2

Please sign in to comment.