Compare commits

...

4 Commits

Author SHA1 Message Date
CrescentLeaf
1fec2bba06 feat(wip): 顯示消息的時間 2025-09-30 21:56:18 +08:00
CrescentLeaf
706a340407 fix: 在沒有消息時, 發送消息並拉取導致的消息重複 2025-09-30 21:54:25 +08:00
CrescentLeaf
7e81484932 refactor: 獨立 openImageViewer 2025-09-30 21:37:31 +08:00
CrescentLeaf
d7d8351dc9 ui: 添加細節: 添加聯絡人可直接回車, 可直接點擊清空 2025-09-30 21:35:58 +08:00
7 changed files with 57 additions and 42 deletions

View File

@@ -2,4 +2,5 @@ export default class Message {
declare id: number declare id: number
declare text: string declare text: string
declare user_id: string declare user_id: string
declare time: string
} }

View File

@@ -82,6 +82,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
if (checkApiSuccessOrSncakbar(re, "拉取歷史記錄失敗")) return if (checkApiSuccessOrSncakbar(re, "拉取歷史記錄失敗")) return
const returnMsgs = (re.data!.messages as Message[]).reverse() const returnMsgs = (re.data!.messages as Message[]).reverse()
page.current++
if (returnMsgs.length == 0) { if (returnMsgs.length == 0) {
setShowNoMoreMessagesTip(true) setShowNoMoreMessagesTip(true)
setTimeout(() => setShowNoMoreMessagesTip(false), 1000) setTimeout(() => setShowNoMoreMessagesTip(false), 1000)
@@ -91,8 +92,6 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
const oldest = messagesList[0] const oldest = messagesList[0]
setMessagesList(returnMsgs.concat(messagesList)) setMessagesList(returnMsgs.concat(messagesList))
setTimeout(() => chatPanelRef.current!.scrollTo({ top: $(`#chat_${target}_message_${oldest.id}`).get(0).offsetTop, behavior: 'smooth' }), 100) setTimeout(() => chatPanelRef.current!.scrollTo({ top: $(`#chat_${target}_message_${oldest.id}`).get(0).offsetTop, behavior: 'smooth' }), 100)
page.current++
} }
React.useEffect(() => { React.useEffect(() => {

View File

@@ -1,23 +1,8 @@
import openImageViewer from "../openImageViewer.ts"
import { snackbar } from "../snackbar.ts"
import { $ } from 'mdui/jq' import { $ } from 'mdui/jq'
import 'pinch-zoom-element'
import { snackbar } from "../snackbar.ts";
function openImageViewer(src: string) {
$('#image-viewer-dialog-inner').empty()
const e = new Image()
e.onload = () => ($('#image-viewer-dialog-inner').get(0) as any).scaleTo(0.1, {
// Transform origin. Can be a number, or string percent, eg "50%"
originX: '50%',
originY: '50%',
// Should the transform origin be relative to the container, or content?
relativeTo: 'container',
})
e.src = src
$('#image-viewer-dialog-inner').append(e)
$('#image-viewer-dialog').attr('open', 'true')
}
customElements.define('chat-image', class extends HTMLElement { customElements.define('chat-image', class extends HTMLElement {
constructor() { constructor() {

View File

@@ -16,26 +16,33 @@ export default function AddContactDialog({
addContactDialogRef, addContactDialogRef,
}: Refs) { }: Refs) {
const inputUserAccountRef = React.useRef<TextField>(null) const inputUserAccountRef = React.useRef<TextField>(null)
async function addContact() {
const re = await Client.invoke("User.addContact", {
account: inputUserAccountRef.current!.value,
token: data.access_token,
})
if (checkApiSuccessOrSncakbar(re, "添加失敗")) return
snackbar({
message: "添加成功!",
placement: "top",
})
EventBus.emit('ContactsList.updateContacts')
inputUserAccountRef.current!.value = ''
addContactDialogRef.current!.open = false
}
return ( return (
<mdui-dialog close-on-overlay-click close-on-esc headline="添加對話" ref={addContactDialogRef}> <mdui-dialog close-on-overlay-click close-on-esc headline="添加對話" ref={addContactDialogRef}>
, ... , ...
<mdui-text-field style={{ marginTop: "10px", }} label="對方的 用戶 ID / 用戶名" ref={inputUserAccountRef as any}></mdui-text-field> <mdui-text-field style={{ marginTop: "10px", }} clearable label="對方的 用戶 ID / 用戶名" ref={inputUserAccountRef as any} onKeyDown={(event) => {
if (event.key == 'Enter')
addContact()
}}></mdui-text-field>
<mdui-button slot="action" variant="text" onClick={() => addContactDialogRef.current!.open = false}></mdui-button> <mdui-button slot="action" variant="text" onClick={() => addContactDialogRef.current!.open = false}></mdui-button>
<mdui-button slot="action" variant="text" onClick={async () => { <mdui-button slot="action" variant="text" onClick={() => addContact()}></mdui-button>
const re = await Client.invoke("User.addContact", {
account: inputUserAccountRef.current!.value,
token: data.access_token,
})
if (checkApiSuccessOrSncakbar(re, "添加失敗")) return
snackbar({
message: "添加成功!",
placement: "top",
})
EventBus.emit('ContactsList.updateContacts')
addContactDialogRef.current!.open = false
}}></mdui-button>
</mdui-dialog> </mdui-dialog>
) )
} }

View File

@@ -0,0 +1,17 @@
import { $ } from 'mdui/jq'
import 'pinch-zoom-element'
export default function openImageViewer(src: string) {
$('#image-viewer-dialog-inner').empty()
const e = new Image()
e.onload = () => ($('#image-viewer-dialog-inner').get(0) as any).scaleTo(0.1, {
// Transform origin. Can be a number, or string percent, eg "50%"
originX: '50%',
originY: '50%',
// Should the transform origin be relative to the container, or content?
relativeTo: 'container',
})
e.src = src
$('#image-viewer-dialog-inner').append(e)
$('#image-viewer-dialog').attr('open', 'true')
}

View File

@@ -2,6 +2,7 @@ export default class MessageBean {
declare id: number declare id: number
declare text: string declare text: string
declare user_id?: string declare user_id?: string
declare time: string
[key: string]: unknown [key: string]: unknown
} }

View File

@@ -27,7 +27,8 @@ export default class MessagesManager {
CREATE TABLE IF NOT EXISTS ${this.getTableName()} ( CREATE TABLE IF NOT EXISTS ${this.getTableName()} (
/* 序号, MessageId */ id INTEGER PRIMARY KEY AUTOINCREMENT, /* 序号, MessageId */ id INTEGER PRIMARY KEY AUTOINCREMENT,
/* 消息文本 */ text TEXT NOT NULL, /* 消息文本 */ text TEXT NOT NULL,
/* 发送者 */ user_id TEXT NOT NULL /* 发送者 */ user_id TEXT NOT NULL,
/* 發送時間 */ time INT8 NOT NULL
); );
`) `)
} }
@@ -36,17 +37,21 @@ export default class MessagesManager {
} }
addMessage({ addMessage({
text, text,
user_id user_id,
time
}: { }: {
text: string, text: string,
user_id?: string user_id?: string,
time?: number
}) { }) {
return MessagesManager.database.prepare(`INSERT INTO ${this.getTableName()} ( return MessagesManager.database.prepare(`INSERT INTO ${this.getTableName()} (
text, text,
user_id user_id,
) VALUES (?, ?);`).run( time
) VALUES (?, ?, ?);`).run(
text, text,
user_id || null user_id || null,
time || Date.now()
).lastInsertRowid ).lastInsertRowid
} }
addSystemMessage(text: string) { addSystemMessage(text: string) {