From d4557ca0aec74944b75e1e7a01fc51266e7040e0 Mon Sep 17 00:00:00 2001 From: CrescentLeaf Date: Fri, 2 Jan 2026 01:27:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B9=B1=E4=BA=86,=20=E6=87=92=E5=BE=97?= =?UTF-8?q?=E8=AF=B4=E6=98=AF=E4=BB=80=E4=B9=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/env.d.ts | 13 ++++++++++ client/ui/InnerTextContainerElement.ts | 24 +++++++++++++++++++ client/ui/app-state/AppStateContext.ts | 2 +- .../ui/app-state/AppStateContextWrapper.tsx | 7 +++--- client/ui/app-state/ChatFragmentDialog.tsx | 7 +++--- client/ui/app-state/UserOrChatInfoDialog.tsx | 2 +- client/ui/chat-elements/chat-mention.ts | 8 ++----- client/ui/chat-fragment/ChatFragment.tsx | 9 +++++-- client/ui/main-page/RecentChatsList.tsx | 2 +- client/utils/isMobileUI.ts | 6 +++-- 10 files changed, 60 insertions(+), 20 deletions(-) create mode 100644 client/ui/InnerTextContainerElement.ts diff --git a/client/env.d.ts b/client/env.d.ts index 4824669..5417aa5 100644 --- a/client/env.d.ts +++ b/client/env.d.ts @@ -1,6 +1,19 @@ /// /// +// 貌似没有起效 +declare global { + namespace React { + namespace JSX { + interface IntrinsicElements { + 'input-element': { + 'value'?: string + } & React.DetailedHTMLProps, HTMLElement> + } + } + } +} + declare const __APP_VERSION__: string declare const __GIT_HASH__: string declare const __GIT_HASH_FULL__: string diff --git a/client/ui/InnerTextContainerElement.ts b/client/ui/InnerTextContainerElement.ts new file mode 100644 index 0000000..5502f24 --- /dev/null +++ b/client/ui/InnerTextContainerElement.ts @@ -0,0 +1,24 @@ +export default class InnerTextContainerElement extends HTMLElement { + static observedAttributes = ['text'] + declare textContainer: HTMLDivElement + declare slotContainer: HTMLSlotElement + declare text?: string + constructor() { + super() + this.attachShadow({ mode: 'open' }) + } + connectedCallback() { + this.shadowRoot!.appendChild(document.createElement('slot')) + } + attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) { + if (this.textContainer == null) { + this.textContainer = document.createElement('div') + // 注意这里不能加到 shadow + this.appendChild(this.textContainer) + this.textContainer.style.display = 'none' + } + this.textContainer.innerText = newValue || '' + } +} + +customElements.define('inner-text-container', InnerTextContainerElement) diff --git a/client/ui/app-state/AppStateContext.ts b/client/ui/app-state/AppStateContext.ts index bf5be36..079c58e 100644 --- a/client/ui/app-state/AppStateContext.ts +++ b/client/ui/app-state/AppStateContext.ts @@ -7,7 +7,7 @@ type AppState = { openUserInfo: (user: Chat | User | string) => void, openEditMyProfile: () => void, openAddFavouriteChat: () => void, - openChat: (chat: string | Chat) => void, + openChat: (chat: string | Chat, inDialog?: boolean) => void, closeChat: () => void, } diff --git a/client/ui/app-state/AppStateContextWrapper.tsx b/client/ui/app-state/AppStateContextWrapper.tsx index df28273..accbd98 100644 --- a/client/ui/app-state/AppStateContextWrapper.tsx +++ b/client/ui/app-state/AppStateContextWrapper.tsx @@ -12,6 +12,7 @@ import MainSharedContext, { Shared } from "../MainSharedContext" import ChatFragmentDialog from "./ChatFragmentDialog" import useAsyncEffect from "../../utils/useAsyncEffect" import ClientCache from "../../ClientCache" +import isMobileUI from "../../utils/isMobileUI" const config = await fetch('/config.json').then((re) => re.json()) @@ -42,7 +43,6 @@ export default function DialogContextWrapper({ children, useRef }: { children: R MainSharedContext, (context: Shared) => context.state.currentSelectedChatId ) - const [useChatFragmentDialog, setUseChatFragmentDialog] = React.useState(false) const chatFragmentDialogRef = React.useRef() useAsyncEffect(async () => { @@ -70,11 +70,10 @@ export default function DialogContextWrapper({ children, useRef }: { children: R static async openChat(chat: string | Chat, inDialog?: boolean) { if (chat instanceof Chat) chat = chat.getId() - setUseChatFragmentDialog(inDialog || false) setUserOrChatInfoDialogState([]) setCurrentSelectedChatId(chat) - useChatFragmentDialog && (chatFragmentDialogRef.current!.open = true) + inDialog && (chatFragmentDialogRef.current!.open = true) } static closeChat() { if (chatFragmentDialogRef.current!.open) { @@ -85,10 +84,10 @@ export default function DialogContextWrapper({ children, useRef }: { children: R setCurrentSelectedChatId('') } }}> + {} - {useChatFragmentDialog && currentSelectedChatId && currentSelectedChatId != '' && } {children} } diff --git a/client/ui/app-state/ChatFragmentDialog.tsx b/client/ui/app-state/ChatFragmentDialog.tsx index e990069..636004c 100644 --- a/client/ui/app-state/ChatFragmentDialog.tsx +++ b/client/ui/app-state/ChatFragmentDialog.tsx @@ -1,9 +1,10 @@ import { Dialog } from "mdui" import * as React from 'react' import LazyChatFragment from "../chat-fragment/LazyChatFragment" +import useEventListener from "../../utils/useEventListener" export default function ChatFragmentDialog({ chatId, useRef }: { chatId: string, useRef: React.MutableRefObject }) { - React.useEffect(() => { + useEventListener(useRef, 'open', () => { const shadow = useRef.current!.shadowRoot as ShadowRoot const panel = shadow.querySelector(".panel") as HTMLElement panel.style.padding = '0' @@ -13,14 +14,14 @@ export default function ChatFragmentDialog({ chatId, useRef }: { chatId: string, const body = shadow.querySelector(".body") as HTMLElement body.style.height = '100%' body.style.display = 'flex' - }, [chatId]) + }) return
- + {chatId != null && chatId != '' && }
} diff --git a/client/ui/app-state/UserOrChatInfoDialog.tsx b/client/ui/app-state/UserOrChatInfoDialog.tsx index d4303d8..25dac11 100644 --- a/client/ui/app-state/UserOrChatInfoDialog.tsx +++ b/client/ui/app-state/UserOrChatInfoDialog.tsx @@ -110,7 +110,7 @@ export default function UserOrChatInfoDialog({ chat, useRef }: { chat?: Chat, us })}>{favourited ? '取消收藏' : '收藏对话'} } { - AppState.openChat(chat!) + AppState.openChat(chat!, isMobileUI()) }}>打开对话 diff --git a/client/ui/chat-elements/chat-mention.ts b/client/ui/chat-elements/chat-mention.ts index fb30a0c..dee7526 100644 --- a/client/ui/chat-elements/chat-mention.ts +++ b/client/ui/chat-elements/chat-mention.ts @@ -37,18 +37,14 @@ export default class ChatMentionElement extends HTMLElement { const text = $(this).attr('text') this.link.style.fontStyle = '' if (chatId) { - this.link.onclick = (e) => { e.stopPropagation() - // deno-lint-ignore no-window - + this.openChatInfo?.(chatId) } } else if (userId) { - this.link.onclick = (e) => { e.stopPropagation() - // deno-lint-ignore no-window - + this.openUserInfo?.(userId) } } diff --git a/client/ui/chat-fragment/ChatFragment.tsx b/client/ui/chat-fragment/ChatFragment.tsx index 523db21..0085283 100644 --- a/client/ui/chat-fragment/ChatFragment.tsx +++ b/client/ui/chat-fragment/ChatFragment.tsx @@ -160,7 +160,7 @@ export default function ChatFragment({ }} onDrop={(e) => { // 文件拽入 }}> - { + { if (inputRef.current?.value.trim() == '') { // 清空缓存的文件 } @@ -181,7 +181,12 @@ export default function ChatFragment({ marginRight: '10px', marginTop: '3px', marginBottom: '3px', - }}> + }}> + { + // @ts-ignore + + } + { diff --git a/client/ui/main-page/RecentChatsList.tsx b/client/ui/main-page/RecentChatsList.tsx index 154e081..168c09a 100644 --- a/client/ui/main-page/RecentChatsList.tsx +++ b/client/ui/main-page/RecentChatsList.tsx @@ -77,7 +77,7 @@ export default function RecentChatsList({ ...props }: React.HTMLAttributes AppState.openChat(v.getId())} + onClick={() => AppState.openChat(v.getId(), isMobileUI())} key={v.getId()} recentChat={v} /> ) diff --git a/client/utils/isMobileUI.ts b/client/utils/isMobileUI.ts index 05fc130..bf63608 100644 --- a/client/utils/isMobileUI.ts +++ b/client/utils/isMobileUI.ts @@ -1,5 +1,7 @@ import data from "../data" +const searchParams = new URL(location.href).searchParams + export default function isMobileUI() { - return data.override_use_mobile_ui || /Mobi|Android|iPhone/i.test(navigator.userAgent) -} \ No newline at end of file + return data.override_use_mobile_ui || searchParams.get('mobile') == 'true' || /Mobi|Android|iPhone/i.test(navigator.userAgent) +}