15 Commits

Author SHA1 Message Date
MoonLeeeaf
5d7d7e7209 chore: 删除无用的测试文件 2024-06-15 18:37:30 +08:00
MoonLeeeaf
8446ba09c2 test: Tab Menu 2024-06-15 18:35:00 +08:00
MoonLeeeaf
d450797895 Merge branch 'main' of github.com:LingChair/LingChair 2024-06-15 18:32:50 +08:00
MoonLeeeaf
a326c16f1c fix: 异常数量的Tab栏指示器 2024-06-15 18:05:38 +08:00
MoonLeeeaf
3df9df6d85 style: ~ 2024-06-15 17:53:31 +08:00
MoonLeeeaf
585ea41831 change: 切换标签页不会滚动到底部 2024-06-15 12:44:57 +08:00
满月叶
12de793b26 docs: 使用h2代替h1 2024-06-15 10:34:26 +08:00
满月叶
84a5e52fbf docs: 修正英文readme语法错误 2024-06-15 10:33:57 +08:00
满月叶
436358e7c1 docs: add non-Chinese tip 2024-06-15 10:28:59 +08:00
满月叶
25d61b3a78 docs: remove a duplication language switch 2024-06-15 10:23:12 +08:00
满月叶
f2c9e51fd3 docs: readme_en 2024-06-15 10:19:34 +08:00
满月叶
cc5fcc1b02 docs: readme 2024-06-15 10:18:18 +08:00
满月叶
bf9ba20ede docs: English readme 2024-06-15 10:13:48 +08:00
满月叶
dcc4e040a5 docs: English readme 2024-06-15 10:09:42 +08:00
满月叶
733d5f76c3 docs: readme 2024-06-15 10:05:07 +08:00
7 changed files with 163 additions and 63 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -50,12 +50,12 @@ else {
Stickyfill.add($("*").filter((a, b) => $(b).css('position') === 'sticky')) Stickyfill.add($("*").filter((a, b) => $(b).css('position') === 'sticky'))
ChatMsgAdapter.initMsgElementEvents() ChatMsgAdapter.initMsgElementEvents()
ChatMsgAdapter.initInputResizer() ChatMsgAdapter.initInputResizer()
ChatTabManager.initTabElementEvents()
const showLinkDialog = (link) => mdui.alert(decodeURI(link) + "<br/>如果你确认此链接是安全的, 那么请<a class=\"mdui-text-color-theme-accent\" href=\"" + link + "\">点我</a>", '链接', () => { }, { confirmText: "关闭" }) const showLinkDialog = (link) => mdui.alert(decodeURI(link) + "<br/>如果你确认此链接是安全的, 那么请<a class=\"mdui-text-color-theme\" href=\"" + link + "\">点我</a>", '链接', () => { }, { confirmText: "关闭" })
const showImageDialog = (link, id, alt) => mdui.alert(`此图片链接来源未知: ${decodeURI(link)}<br/>如果你希望加载, 请<a class="mdui-text-color-theme-accent" mdui-dialog-close onclick="$('#${id}').html('<img src=\\'${link}\\' alt=\\'${decodeURI(alt)}\\' class=\\'message-image\\'></img>')">点我</a>`, '外部图片', () => { }, { confirmText: "关闭" }) const showImageDialog = (link, id, alt) => mdui.alert(`此图片链接来源未知: ${decodeURI(link)}<br/>如果你希望加载, 请<a class="mdui-text-color-theme" mdui-dialog-close onclick="$('#${id}').html('<img src=\\'${link}\\' alt=\\'${decodeURI(alt)}\\' class=\\'message-image\\'></img>')">点我</a>`, '外部图片', () => { }, { confirmText: "关闭" })
const showCodeDialog = (code) => mdui.alert(`<pre><code>${decodeURI(code)}</code></pre>`, '代码块', () => { }, { confirmText: "关闭" }) const showCodeDialog = (code) => mdui.alert(`<pre><code>${decodeURI(code)}</code></pre>`, '代码块', () => { }, { confirmText: "关闭" })
@@ -70,7 +70,7 @@ const renderer = {
return text return text
}, },
link(href, title, text) { link(href, title, text) {
return `<a class="mdui-text-color-theme-accent" onclick="showLinkDialog('${encodeURI(href)}')">[链接] ${text}</a>` return `<a class="mdui-text-color-theme" onclick="showLinkDialog('${encodeURI(href)}')">[链接] ${text}</a>`
}, },
image(href, title, text) { image(href, title, text) {
let h = Hash.sha256(href) let h = Hash.sha256(href)
@@ -81,10 +81,10 @@ const renderer = {
if (out) if (out)
return `<img src="${encodeURI(href)}" alt="${text}" class="message-image"></img>` return `<img src="${encodeURI(href)}" alt="${text}" class="message-image"></img>`
else else
return `<div id="${h}"><a class="mdui-text-color-theme-accent" onclick="showImageDialog('${encodeURI(href)}', '${h}', '${encodeURI(text)}')">[外部图片] ${text}</a></div>` return `<div id="${h}"><a class="mdui-text-color-theme" onclick="showImageDialog('${encodeURI(href)}', '${h}', '${encodeURI(text)}')">[外部图片] ${text}</a></div>`
}, },
code(src) { code(src) {
return `<a class="mdui-text-color-theme-accent" onclick="showCodeDialog(\`${encodeURI(src)}\`)">[代码块]</a>` return `<a class="mdui-text-color-theme" onclick="showCodeDialog(\`${encodeURI(src)}\`)">[代码块]</a>`
}, },
} }

View File

@@ -9,6 +9,7 @@
// ================================ // ================================
class CurrentUser { class CurrentUser {
/** @type { String } */
static myAccessToken static myAccessToken
/** /**
* 登录账号 * 登录账号
@@ -262,6 +263,8 @@ class ContactsList {
// 消息核心 // 消息核心
// ================================ // ================================
// 自古框架BUG多, 各种麻烦遭不住
class ChatTabManager { class ChatTabManager {
static tabs = {} static tabs = {}
/** /**
@@ -270,7 +273,14 @@ class ChatTabManager {
* @param { String } target * @param { String } target
*/ */
static add(title, target) { static add(title, target) {
$($.parseHTML(`<a onclick="ChatMsgAdapter.switchTo('${target}');" tag="chatTab" id="chatTab_${target}" class="mdui-ripple" style="text-transform: none;">${title}</a>`)).appendTo(viewBinding.chatTab) if (this.tabs[target]) return
let tabElement = $($.parseHTML(`<a onclick="ChatMsgAdapter.switchTo('${target}');" tag="chatTab" id="chatTab_${target}" class="mdui-ripple" style="text-transform: none;">${title}</a>`))
tabElement.appendTo(viewBinding.chatTab)
// 就你MDUI的B事最多 加Tab还多一个下划线 删掉就解决了
$(".mdui-tab-indicator").remove()
new mdui.Tab(viewBinding.chatTab).handleUpdate()
this.tabs[target] = tabElement
if (Object.keys(this.tabs).length == 1) tabElement.addClass("mdui-tab-active")
} }
/** /**
* 寻找Tab * 寻找Tab
@@ -278,14 +288,14 @@ class ChatTabManager {
* @returns { jQuery } element * @returns { jQuery } element
*/ */
static find(target) { static find(target) {
return $("#chatTab_" + target) return this.tabs[target]
} }
/** /**
* 点击Tab * 点击Tab
* @param { String } target * @param { String } target
*/ */
static click(target) { static click(target) {
this.find(this.target).click() this.find(target).get(0).click()
} }
/** /**
* 删除Tab * 删除Tab
@@ -293,6 +303,64 @@ class ChatTabManager {
*/ */
static remove(target) { static remove(target) {
this.find(target).remove() this.find(target).remove()
this.tabs[target] = null
}
static initTabElementEvents() {
let listeners = {}
let menu
let callback = (e) => {
if (menu) menu.close()
// 切到 div.message-content
let ele = e.get(0)
while ($(ele).attr("tag") != "msg-card")
ele = ele.parentNode
e = $(ele)
let menuHtml = $.parseHTML(`<ul class="mdui-menu menu-on-message">
<li class="mdui-menu-item">
<a onclick="copyText(\`${e.find("#msg-content").text()}\`)" class="mdui-ripple">复制</a>
</li>
<li class="mdui-menu-item">
<a onclick="mdui.alert(\`${e.find("#raw-msg-content").text()}\`, '消息原文', () => { }, { confirmText: '关闭' })" class="mdui-ripple">原文</a>
</li>
<li class="mdui-menu-item">
<a onclick="mdui.alert('未制作功能', '提示', () => { }, { confirmText: '关闭' })" class="mdui-ripple">转发</a>
</li>
</ul>`)
let $menu = $(menuHtml)
e.before($menu)
menu = new mdui.Menu(e.get(0), menuHtml, {
position: "bottom",
align: "auto",
// 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':
if (!isMobile()) return
listeners[self + ""] = setTimeout(() => {
callback(self)
}, 300) // 300颗够吗 应该够吧
break
case 'mouseup':
if (!isMobile()) return
clearTimeout(listeners[self + ""])
listeners[self + ""] = null
break
}
})
} }
} }
@@ -303,7 +371,9 @@ class ChatPage {
this.chatType = type this.chatType = type
ChatTabManager.add(title, this.chatTarget) ChatTabManager.add(title, this.chatTarget)
this.chatPageElement = $($.parseHTML(`<div class="chat-seesion" id="chatPageTargetIs${this.chatTarget}" target="${this.chatTarget}"></div>`)) this.chatPageElement = $($.parseHTML(`<div class="chat-seesion" id="chatPageTargetIs${this.chatTarget}" target="${this.chatTarget}"></div>`))
this.chatPageElement.hide()
this.chatPageElement.appendTo(viewBinding.pageChatSeesion) this.chatPageElement.appendTo(viewBinding.pageChatSeesion)
;(async () => await this.loadMore())()
} }
/** /**
* 获取当前的聊天栏 * 获取当前的聊天栏
@@ -316,7 +386,7 @@ class ChatPage {
* 获取当前聊天页面 * 获取当前聊天页面
* @returns { ChatPage } * @returns { ChatPage }
*/ */
static getCurrentChatPage(name) { static getCurrentChatPage() {
return ChatPage.cached[$(".chat-seesion[actived=true]").attr("target")] return ChatPage.cached[$(".chat-seesion[actived=true]").attr("target")]
} }
/** /**
@@ -331,17 +401,13 @@ class ChatPage {
let cpe = ChatPage.cached[k].chatPageElement let cpe = ChatPage.cached[k].chatPageElement
cpe.attr("actived", null) cpe.attr("actived", null)
cpe.hide() cpe.hide()
let tbe = ChatTabManager.find(k)
tbe.removeClass("mdui-tab-active")
} }
$(this.chatPageElement).empty()
$(this.chatPageElement).attr("actived", "true") $(this.chatPageElement).attr("actived", "true")
$(this.chatPageElement).show()
ChatTabManager.find(this.chatTarget).addClass("mdui-tab-active")
await this.loadMore() ChatTabManager.click(this.chatTarget)
ChatMsgAdapter.scrollToBottom()
$(this.chatPageElement).show()
} }
/** /**
* 连带Tab一起销毁 * 连带Tab一起销毁
@@ -362,18 +428,19 @@ class ChatPage {
if (histroy.length == 0) if (histroy.length == 0)
return mdui.snackbar("已经加载完了~") return mdui.snackbar("已经加载完了~")
let re = this.minMsgId != null let doReverse = this.minMsgId != null
this.minMsgId = histroy[0].msgid - 1 this.minMsgId = histroy[0].msgid - 1
let sc = 0 // 英语水平不够(
if (re) histroy = histroy.reverse() let scroll幅度 = 0
if (doReverse) histroy = histroy.reverse()
for (let index in histroy) { for (let index in histroy) {
let i = histroy[index] let i = histroy[index]
let e = await this.addMsg(i.name, i.msg, i.time, re, i.msgid) let msgElement = await this.addMsg(i.name, i.msg, i.time, doReverse, i.msgid)
// 因为某些因素直接DEBUG到吐血 断点继续都不报错 原因不明 // 因为某些因素直接DEBUG到吐血 断点继续都不报错 原因不明
sc = sc + (e == null ? 35 : getOffsetTop(chatPager, e.get(0))) scroll幅度 = scroll幅度 + (msgElement == null ? 35 : getOffsetTop(chatPager, msgElement.get(0)))
} }
chatPager.scrollBy({ chatPager.scrollBy({
top: sc, top: scroll幅度,
behavior: 'smooth' behavior: 'smooth'
}) })
} }

View File

@@ -121,7 +121,6 @@
<div class="mdui-tab mdui-accent-theme mdui-theme-color-auto" style="position: fixed; z-index: 114;width: 100%;" <div class="mdui-tab mdui-accent-theme mdui-theme-color-auto" style="position: fixed; z-index: 114;width: 100%;"
mdui-tab n-id="chatTab"> mdui-tab n-id="chatTab">
<!-- 侧滑栏的 z-index 是2000, 在移动端会直接覆盖 --> <!-- 侧滑栏的 z-index 是2000, 在移动端会直接覆盖 -->
<!-- <a href="#page-chat-seesion" n-id="tabChatSeesion" tag="chatTab" class="mdui-ripple" style="text-transform: none;"></a> -->
</div> </div>
<!-- 滚动到底部咋这么难写... --> <!-- 滚动到底部咋这么难写... -->
<div style="display: flex;flex-direction: column;"> <div style="display: flex;flex-direction: column;">

View File

@@ -1,31 +1,29 @@
## 铃之椅 [ 中文 | [English](readme_en.md) ]
<div align="center">
<h2> 铃之椅 </h2>
</div>
欢迎来到铃之椅! 这是一个即时通讯项目, 为通讯提供更多的选择, 为人民服务 欢迎来到铃之椅! 这是一个即时通讯项目, 为通讯提供更多的选择, 为人民服务
> [!NOTE] > [!NOTE]
> 本项目仍在实验阶段, [点我](final.md)可查看进展 > 本项目仍在实验阶段, [点我](final.md)可查看进展
> >
> 如果有任何问题,欢迎你提出来,我会不定时查看 > 欢迎各位提出项目修改意见
>
> 另外 Android 客户端也在开发, 但进展缓慢
### 使用 ### 使用
服务端: 服务端:
0. 确保安装 Node.js 0. 安装 Node.js
1. 克隆本仓库源代码到本地,并运行 run_build.sh 构建网页 1. 克隆或下载本仓库源代码,执行`npm install`,再执行`npm run start` 或者运行 run.bat / run.sh
2. 运行 run.sh 客户端:
网页端: * 使用服务端提供的网页 (推荐)
* 直接使用和服务端集成的网页 (推荐) * GitHub Pages (可能导致跨域问题)
* 克隆本仓库到本地并运行本地 HTTP 服务端
* 静态网页 (不推荐)
### [Q&A](.github/QA.md) ### [Q&A](.github/QA.md)

36
readme_en.md Normal file
View File

@@ -0,0 +1,36 @@
[ [中文](readme.md) | English ]
<div align="center">
<h2> LingChair </h2>
</div>
Welcome to LingChair! This is an IM project that it provide a new communication way. And it serves people.
> [!NOTE]
I'm sorry that I have no time to translate this project to English. This project is so large for me to rewrite, so there're still a lot of texts in Chinese.
>
> This project is still in progress, [Click me](final.md) to view progress. (Chinese)
>
> Comments and BUG report welcome
### Usage
Server:
0. Install Node.js
1. Clone this repo or download the source code, then run `npm install`, after that, run `npm run start` or run.bat / run.sh
Client:
* Use the pages that the server provide (Recommend)
* GitHub Pages (It may cause CORS security error)
### [Q&A (Chinese)](.github/QA.md)
### Credits
WIP
### [Do you know? (Chinese)](.github/do_you_know.md)