From a744b6871b20fe069021ccd718a77bbe63f22e33 Mon Sep 17 00:00:00 2001 From: MoonLeeeaf <150461955+MoonLeeeaf@users.noreply.github.com> Date: Sat, 11 May 2024 23:49:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=B3=E9=94=AE=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E8=8F=9C=E5=8D=95,=20change:=20=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=BD=8D=E7=BD=AE,=20fix:?= =?UTF-8?q?=20=E7=BE=8E=E5=8C=96=E9=80=A0=E6=88=90=E7=9A=84=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E6=A1=86=E6=8C=89=E9=92=AECSS=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ling_chair_http/config.json | 2 +- ling_chair_http/index.css | 5 +- ling_chair_http/index.html | 10 ++- ling_chair_http/index.js | 136 +++++++++++++++++++++++++----- ling_chair_http/mdui-prettier.css | 13 +-- server_src/val.js | 2 +- server_src/wsApi.js | 4 +- 7 files changed, 138 insertions(+), 34 deletions(-) diff --git a/ling_chair_http/config.json b/ling_chair_http/config.json index 3e24632..d8ada1e 100644 --- a/ling_chair_http/config.json +++ b/ling_chair_http/config.json @@ -1,4 +1,4 @@ { "appTitle": "", - "canChangeServer": false + "canChangeServer": true } \ No newline at end of file diff --git a/ling_chair_http/index.css b/ling_chair_http/index.css index 783ef43..c1b3b46 100644 --- a/ling_chair_http/index.css +++ b/ling_chair_http/index.css @@ -39,4 +39,7 @@ body { flex: 1; } - +.menu-on-message { + margin-top: 60px; + z-index: 100; +} diff --git a/ling_chair_http/index.html b/ling_chair_http/index.html index 322c350..1f2b2d6 100644 --- a/ling_chair_http/index.html +++ b/ling_chair_http/index.html @@ -32,14 +32,14 @@ - - - + + + 铃之椅 @@ -49,6 +49,8 @@ class="mdui-theme-primary-teal mdui-theme-accent-teal mdui-drawer-body-left mdui-appbar-with-toolbar mdui-theme-layout-auto" id="app"> + +
@@ -139,7 +141,7 @@
+ style="position: sticky;max-width: 100%;margin-bottom: -30px;bottom: 0;z-index: 101;">
  • 插入图片 diff --git a/ling_chair_http/index.js b/ling_chair_http/index.js index ae3f0e7..50e4ae9 100644 --- a/ling_chair_http/index.js +++ b/ling_chair_http/index.js @@ -21,6 +21,28 @@ const UrlArgs = new URL(location.href).searchParams +function setOnRightClick(e, cb) { + if (!(e instanceof jQuery)) + e = $(e) + + let longPressTimer + if (!cb) throw new Error("定义回调!!!!") + e.on('contextmenu', function (e) { + e.preventDefault() // 阻止默认右键菜单 + cb() + }) + + e.on('mousedown', function () { + longPressTimer = setTimeout(function () { + cb() + }, 1000) + }) + + e.on('mouseup', function () { + clearTimeout(longPressTimer) + }); +} + if (UrlArgs.get("debug")) { let script = document.createElement('script') script.src = "//cdn.jsdelivr.net/npm/eruda" @@ -130,10 +152,7 @@ viewBinding.drawerChangeServer.click(() => { viewBinding.drawerSignOut.click(() => { mdui.confirm('确定要登出账号吗', () => { - localStorage.refreshToken = "" - localStorage.isSignIn = false - - setTimeout(() => location.reload(), 300) + User.signOutAndReload() }, () => { }, { confirmText: "确定", cancelText: "取消" @@ -157,17 +176,26 @@ viewBinding.dialogSignInPasswd.keydown((e) => { }) viewBinding.switchNotifications.click((a) => { - if (localStorage.useNotifications === "true" || localStorage.useNotifications != null) { - localStorage.useNotifications = false + if ((localStorage.useNotifications == "true" || localStorage.useNotifications != null) && localStorage.useNotifications != "false") { + localStorage.useNotifications = "false" viewBinding.switchNotificationsIcon.text("notifications_off") } else { - localStorage.useNotifications = true + localStorage.useNotifications = "true" viewBinding.switchNotificationsIcon.text("notifications") } }) -if (localStorage.useNotifications === "true") +if (localStorage.useNotifications == "true") viewBinding.switchNotificationsIcon.text("notifications") +// https://www.runoob.com/w3cnote/javascript-copy-clipboard.html +function copyText(t) { + let cp = viewBinding.textCopier.get(0) + cp.value = t + cp.select() + cp.setSelectionRange(0, 99999) + navigator.clipboard.writeText(cp.value) +} + // https://zhuanlan.zhihu.com/p/162910462 Date.prototype.format = function (tms, format) { let tmd = new Date(tms) @@ -335,7 +363,7 @@ class ChatMsgAdapter { // 错了 应该是客户端少发条才对 不然不能多设备同步 if (ChatMsgAdapter.target !== localStorage.userName && ChatMsgAdapter.type === "single") { let i = ChatMsgAdapter.isAtBottom() - await ChatMsgAdapter.addMsg(localStorage.userName, msg, re.data.time) + await ChatMsgAdapter.addMsg(localStorage.userName, msg, re.data.time, re.data.msgid) if (i) ChatMsgAdapter.scrollToBottom() } }) @@ -367,9 +395,9 @@ class ChatMsgAdapter { if (re) histroy = histroy.reverse() for (let index in histroy) { let i = histroy[index] - let e = await this.addMsg(i.name, i.msg, i.time, re, true) + let e = await this.addMsg(i.name, i.msg, i.time, re, i.msgid) // 因为某些因素直接DEBUG到吐血 断点继续都不报错 原因不明 - sc = sc + (e == null ? 20 : e.get(0).offsetTop) + sc = sc + (e == null ? 25 : e.get(0).offsetTop) } window.scrollBy({ top: sc, @@ -385,11 +413,11 @@ class ChatMsgAdapter { return e } static isAtBottom() { - let elementRect = viewBinding.pageChatSeesion.get(0).getBoundingClientRect(); - return (elementRect.bottom <= window.innerHeight); + let elementRect = viewBinding.pageChatSeesion.get(0).getBoundingClientRect() + return (elementRect.bottom <= window.innerHeight) } // 不会压栈 只添加消息 返回消息的JQ对象 - static async addMsg(name, m, t, re) { + static async addMsg(name, m, t, re, msgid) { let nick = await NickCache.getNick(name) // re.data == null ? name : re.data.nick @@ -400,8 +428,8 @@ class ChatMsgAdapter { temp = `
    ` + nick + ` -
    - ` + msg + ` +
    + ` + msg + `
    @@ -411,8 +439,8 @@ class ChatMsgAdapter {
    ` + nick + ` -
    - ` + msg + ` +
    + ` + msg + `
    ` @@ -477,6 +505,58 @@ class ChatMsgAdapter { static saveToLocal() { localStorage["chat_msg_" + this.target] = JSON.stringify(this.msgList) }*/ + // 为消息设置长按/右键事件 + static initMsgElementEvents() { + let listeners = {} + let menu + let callback = (e) => { + if (menu) menu.close() + // 从 span 切到 div + if (e.get(0).tagName.toLowerCase() != "div") e = $(e.get(0).parentNode) + // 从 消息框 切到 更上层 + e = $(e.get(0).parentNode) + let menuHtml = $.parseHTML(``) + let $menu = $(menuHtml) + e.before($menu) + menu = new mdui.Menu(e.get(0), menuHtml, { + position: "bottom", + align: "right", + // covered: true, + }) + $menu.on('closed.mdui.menu', () => { + $(menuHtml).remove() + }) + menu.open() + } + viewBinding.pageChatSeesion.on('contextmenu mousedown mouseup', '.message-content', (e) => { + let eventType = e.type + let self = $(e.target) + + // 根据事件类型执行不同操作 + switch (eventType) { + case 'contextmenu': + e.preventDefault() // 阻止默认行为 + callback(self) + break + case 'mousedown': + listeners[self + ""] = setTimeout(() => { + callback(self) + }, 300) // 300颗够吗 应该够吧 + break + case 'mouseup': + clearTimeout(listeners[self + ""]) + listeners[self + ""] = null + break + } + }) + } } class Hash { @@ -562,10 +642,24 @@ class User { client.emit("user.auth", { name: localStorage.userName, refreshToken: localStorage.refreshToken }, (re) => { if (re.code !== 0) { console.error(re) - return mdui.snackbar("验证用户失败!") + if (!re.invalid) + return mdui.snackbar("验证用户失败!") + + mdui.alert("账号刷新令牌已过期, 请重新登录哦", "提示", () => User.signOutAndReload(), { + confirmText: "确定", + closeOnConfirm: false, + closeOnEsc: false, + modal: true, + }) } }) } + static signOutAndReload() { + localStorage.refreshToken = "" + localStorage.isSignIn = false + + setTimeout(() => location.reload(), 300) + } static registerCallback() { client.on("msg.receive", async (a) => { if (checkEmpty([a.target, a.msg, a.type])) @@ -579,7 +673,7 @@ class User { let n = new 通知().setTitle("新消息 - " + await NickCache.getNick(a.target)).setMessage(a.msg.msg).setIcon(User.getUserHeadUrl(a.target)).show(async () => { await ChatMsgAdapter.switchTo(a.target, a.type) - ChatMsgAdapter.scrollToBottom() + location.replace("#msgid_" + a.msg.msgid) n.close() }) }) @@ -642,3 +736,5 @@ else { // 感谢AI的力量 Stickyfill.add($("*").filter((a, b) => $(b).css('position') === 'sticky')) + +ChatMsgAdapter.initMsgElementEvents() diff --git a/ling_chair_http/mdui-prettier.css b/ling_chair_http/mdui-prettier.css index b1bec10..e3009e7 100644 --- a/ling_chair_http/mdui-prettier.css +++ b/ling_chair_http/mdui-prettier.css @@ -21,16 +21,19 @@ body { .mdui-menu-item > a { padding-right: 3px; } -.mdui-dialog-actions a, -.mdui-dialog-actions button { - border-radius: 40px; -} -.mdui-btn { +.mdui-btn:not(.mdui-btn-icon, .mdui-dialog-actions button, .mdui-dialog-actions a) { padding-left: 20px; padding-right: 20px; height: 40px; border-radius: 10px; } +.mdui-dialog-actions a, +.mdui-dialog-actions button { + padding-left: 20px; + padding-right: 20px; + height: 40px; + border-radius: 40px; +} /* 配色方案 */ diff --git a/server_src/val.js b/server_src/val.js index a75ff26..9ba2fa3 100644 --- a/server_src/val.js +++ b/server_src/val.js @@ -9,7 +9,7 @@ const io = require("./iolib") let vals = {} // 配置目录 -vals.LINGCHAIR_CONFIG_DIR = "ling_chair_config" +vals.LINGCHAIR_CONFIG_DIR = "ling_chair_data" // HTTP 服务器资源目录 vals.LINGCHAIR_HTTP_DIR = "ling_chair_http" // 服务端配置 diff --git a/server_src/wsApi.js b/server_src/wsApi.js index cec1c23..834f070 100644 --- a/server_src/wsApi.js +++ b/server_src/wsApi.js @@ -46,7 +46,7 @@ let api = { return cb({ msg: "参数缺失", code: -1 }) if (!users.checkRefreshToken(a.name, a.refreshToken)) - return cb({ code: -1, msg: "刷新令牌错误" }) + return cb({ code: -1, msg: "刷新令牌错误", invalid: true }) log(color.yellow + "客户端 " + client.handshake.address + " 完成了用户 " + a.name + " 的验证" + color.none) @@ -193,7 +193,7 @@ let api = { log("尝试向客户端 " + v.handshake.address + " 发送事件 [msg.receive], 参数为 " + JSON.stringify(args)) }) - cb({ msg: msg, code: 0, data: { time: time } }) + cb({ msg: msg, code: 0, data: { time: time, msgid: msgid } }) }, // 单聊获取历史记录