14 Commits

Author SHA1 Message Date
MoonLeeeaf
6654141c18 chore: 文件头, 输入框UI优化, 部分头像优化, 其他 2024-05-29 23:40:13 +08:00
MoonLeeeaf
822a4ad4da chore: 规范命名 2024-05-29 17:40:10 +08:00
MoonLeeeaf
9f456b95c1 chore: 0.7.1 released 2024-05-29 16:30:57 +08:00
MoonLeeeaf
7d2798d4fd fix: .gitignore 2024-05-26 00:56:50 +08:00
MoonLeeeaf
0ccee91b3e chore: go back 2024-05-26 00:29:56 +08:00
MoonLeeeaf
48bad65df5 rebase 2024-05-25 16:41:27 +08:00
MoonLeeeaf
5b55ca77ec rebase 2024-05-25 16:34:17 +08:00
MoonLeeeaf
71b5b5b2df test: webpack 2024-05-25 10:44:35 +08:00
MoonLeeeaf
9c1dc4c540 chore: readme 2024-05-24 20:54:35 +08:00
MoonLeeeaf
f3bf5f88b5 chore: 软键盘调整布局(测试中) 2024-05-19 23:11:31 +08:00
MoonLeeeaf
971b8aff85 chore: Settings dialog UI 2024-05-19 22:41:28 +08:00
MoonLeeeaf
ddfbe547e1 chore: readme 2024-05-19 13:47:08 +08:00
MoonLeeeaf
b4bbe08ff2 fix: 无法设置昵称 2024-05-19 12:17:00 +08:00
MoonLeeeaf
6ec0005122 chore: ui 2024-05-19 12:14:47 +08:00
21 changed files with 803 additions and 374 deletions

39
.github/QA.md vendored Normal file
View File

@@ -0,0 +1,39 @@
### Q&A
#### 1. 协助项目
1. 若修改代码,请务必添加注释或者尽可能让方法名能被人所理解
2. 修改 readme 相关时,请不要留废话
3. 其它非代码注明性注释会不定期清理
4. 待补充
#### 2. 商业用途
不建议,不推荐,不赞同用于商业用途, 本项目的设计初衷是为了个人和团队使用, 而非用于圈钱, 因此如果确实需要商业化, 请考虑其他项目
因为这个项目还在初级阶段, 还有很多地方不够完善, 甚至有很多漏洞被利用, 造成不必要的损失
#### 3. 提问
1. 禁止人身攻击性回复
2. 请详细说明你的问题
3. 漏洞、BUG 类请给出代码位置
#### 4. 功能请求
目前不考虑,因为每一个做开源的人都应该以生活,以自己的感受为本
就像 weishu 大佬所说的:
> 我发现很多搞开源的开发者都把自己弄得很累
> 其实你把它当作是钓鱼,摩托,音响,单反那样的兴趣爱好就好多了
> 既然是爱好,就不要搞得像打第二份工一样,开心了就玩,玩腻了就扔一边
另外如果你提交功能 PR我有可能会直接 Close我没有太多精力去维护一个用不上的功能
#### 5. 待补充

BIN
.github/模块化_Babel.zip vendored Normal file

Binary file not shown.

BIN
.github/模块化_Webpack.zip vendored Normal file

Binary file not shown.

1
.gitignore vendored
View File

@@ -1,3 +1,2 @@
node_modules/
ling_chair_data/
ling_chair_config/

View File

@@ -79,7 +79,7 @@
.chat-message-left > .avatar,
.chat-message-right > .avatar {
width: 45px;
height: 45px;
width: 50px;
height: 50px;
border-radius: 50%;
}

View File

@@ -1,29 +1,14 @@
/*
* 铃之椅 - 把选择权还给用户, 让聊天权掌握在用户手中
* Copyright 2024 满月叶
* GitHub: https://github.com/MoonLeeeaf/LingChair-Web-Client
* 本项目使用 Apache 2.0 协议开源
*
* Copyright 2024 MoonLeeeaf
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ©2024 满月叶
* Github: MoonLeeeaf
* 铃之椅 网页端
*/
html, body {
max-height: 100%;
margin: 0;
padding: 0;
/* overflow: hidden; */
overflow: hidden;
/*font: initial;*/
}
body {
@@ -49,6 +34,24 @@ body {
position: sticky;
bottom: 0;
display: block;
height: var(--pseudo-height); /* 设置伪元素的高度 */
z-index: -1; /* 防止遮挡实际内容 */
}
}
.chat-seesion {
flex: 1 1 auto;
display: flex;
flex-direction: column;
position: relative;
}
/* https://segmentfault.com/q/1010000010391524 */
img {
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast; /* Webkit (non-standard naming) */
image-rendering: crisp-edges;
-ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */
}
img.round {
border-radius: 50%;
}

View File

@@ -1,26 +1,10 @@
<!doctype html>
<html lang="zh-cmn-Hans">
<!--
* 铃之椅 - 把选择权还给用户, 让聊天权掌握在用户手中
* Copyright 2024 满月叶
* GitHub: https://github.com/MoonLeeeaf/LingChair-Web-Client
* 本项目使用 Apache 2.0 协议开源
*
* Copyright 2024 MoonLeeeaf
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ©2024 满月叶
* Github: MoonLeeeaf
* 铃之椅 网页端
-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" />
@@ -28,9 +12,8 @@
<meta name="force-rendering" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<!-- 给老旧的设备提供支持 支持不了, 照样没法运行 -->
<!-- <script src='https://polyfill.io/v3/polyfill.min.js?features=default%2Cdom4%2Ces2015%2Ces2016%2Ces2017%2Ces2018%2Ces2019%2Ces2020%2Ces2021%2Ces2022%2Ces5%2Ces6%2Ces7'></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> -->
<!-- Maybe it can run :D -->
<script src='https://polyfill.io/v3/polyfill.min.js?features=default%2Cdom4%2Ces2015%2Ces2016%2Ces2017%2Ces2018%2Ces2019%2Ces2020%2Ces2021%2Ces2022%2Ces5%2Ces6%2Ces7'></script>
<!-- Styles -->
<link rel="stylesheet" href="https://unpkg.com/mdui@1.0.2/dist/css/mdui.min.css" />
@@ -38,11 +21,11 @@
<link rel="stylesheet" href="chat-message.css" />
<link rel="stylesheet" href="mdui-prettier.css" />
<!-- 代替私人 fixed 并提供更好的兼容性 -->
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/gh/wilddeer/stickyfill@2.1.0/dist/stickyfill.min.js"></script>
<script src="https://unpkg.com/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
<link rel="icon" href="icon.ico" />
<link rel="icon" href="res/icon.ico" />
<title>铃之椅</title>
</head>
@@ -58,7 +41,7 @@
<ul class="mdui-list" mdui-collapse="{accordion: true}">
<li class="mdui-list-item mdui-ripple">
<div class="mdui-list-item-avatar">
<img src="default_head.png" n-id="userHead" onerror="this.src='default_head.png'" />
<img src="default_head.png" n-id="userHead" onerror="this.src='res/default_head.png'" />
</div>
<div class="mdui-list-item-content"><a n-id="helloText">早安</a>, <a n-id="userNick">Unknown</a></div>
</li>
@@ -140,21 +123,22 @@
<a href="#page-chat-seesion" n-id="tabChatSeesion" class="mdui-ripple" style="text-transform: none;"></a>
</div>
<!-- 滚动到底部咋这么难写... -->
<div class="mdui-p-a-2" style="display: flex;flex-direction: column;">
<div style="display: flex;flex-direction: column;">
<!-- 写时间居中写到吐了 这样式表不能要了 -->
<div
style="margin-top: 30px;overflow: auto;width: 100%;max-width: 100%;height: 100%;max-height: 100%;min-height: 0;flex: 1 1 auto;display: flex;flex-direction: column;"
style="margin-top: 50px;overflow: auto;width: 100%;max-width: 100%;height: 100%;max-height: 100%;min-height: 0;flex: 1 1 auto;display: flex;flex-direction: column;"
n-id="chatPager">
<div class="mdui-center" style="margin: 15px;"><a href="javascript:;" onclick="ChatMsgAdapter.loadMore()"
class="mdui-text-color-theme">加载更多</a> | <a href="javascript:;"
onclick="ChatMsgAdapter.scrollToBottom()" class="mdui-text-color-theme">回到底部</a></div>
<div n-id="pageChatSeesion" style="flex: 1 1 auto;display: flex;flex-direction: column;position: relative;">
<div n-id="pageChatSeesion" class="chat-seesion">
</div>
<!-- 输入框和聊天消息重叠的原因就是死人 scrollbar, 把自动调整的距离调小, margin调大就行了 -->
</div>
<!-- 妈的黑化了 私人玩意这么难整 早知道 z-index 弄死它得了 浪费我时间 我就没试过这么离谱的样式表 第三方库真难写CSS 就应该先写后端的 啊啊啊啊啊啊 -->
<!-- 不黑化了 因为 stickyfill -->
<div class="mdui-toolbar mdui-theme-color-auto"
style="position: sticky;max-width: 100%;margin-bottom: -30px;bottom: 0;z-index: 101;" n-id="inputToolbar">
style="position: sticky;max-width: 100%;margin-top: 1px;bottom: 0;z-index: 101;padding-top: 7px;" n-id="inputToolbar">
<ul class="mdui-menu" id="msg-input-more">
<li class="mdui-menu-item">
<a class="mdui-ripple">插入图片</a>
@@ -222,21 +206,6 @@
</div>
</div>
<!--
<div class="mdui-dialog" n-id="dialogMyProfile">
<div class="mdui-dialog-title">
资料
</div>
<div class="mdui-dialog-content" style="margin-left:15px;margin-right:15px;">
<ul class="mdui-list">
</ul>
</div>
<div class="mdui-dialog-actions">
<button class="mdui-btn mdui-ripple" mdui-dialog-close>关闭</button>
</div>
</div> -->
<!-- 编辑昵称对话框 -->
<div class="mdui-dialog" n-id="dialogEditNick">
<div class="mdui-dialog-title">
@@ -264,7 +233,7 @@
<div class="mdui-dialog-content" style="margin-left:15px;margin-right:15px;">
<div class="mdui-textfield">
<label class="mdui-textfield-label">昵称</label>
<input n-id="dialogEditNickNick" class="mdui-textfield-input" maxlength="30" type="text" />
<input n-id="" class="mdui-textfield-input" maxlength="30" type="text" />
</div>
</div>
<div class="mdui-dialog-actions">
@@ -279,7 +248,7 @@
</div>
<div class="mdui-dialog-content" style="margin-left:15px;margin-right:15px;">
<div class="mdui-textfield">
<label class="mdui-textfield-label">好友/群的ID (不是名称)</label>
<label class="mdui-textfield-label">账号/群的ID (不是名称)</label>
<input n-id="dialogNewContactID" class="mdui-textfield-input" maxlength="30" type="text" />
</div>
<select class="mdui-select" mdui-select="{position: 'top'}" n-id="dialogNewContactType">
@@ -299,7 +268,7 @@
<div class="mdui-dialog-title">
设置
</div>
<div class="mdui-dialog-content" style="margin-left:15px;margin-right:15px;">
<div class="mdui-dialog-content">
<ul class="mdui-list">
<div class="mdui-subheader">我的资料</div>
<li class="mdui-list-item mdui-ripple" mdui-dialog-close
@@ -328,11 +297,6 @@
<script src="https://unpkg.com/crypto-js@4.2.0/crypto-js.js"></script>
<script src="https://unpkg.com/socket.io-client@4.7.4/dist/socket.io.min.js"></script>
<script src="https://unpkg.com/mdui@1.0.2/dist/js/mdui.min.js"></script>
<!-- 加了babel也许能解决下浏览器兼容问题 -->
<!-- <script type="module" src="index.js"></script>
<script nomodule type="text/babel" src="index.js"></script> -->
<!-- 就算弄语法兼容其他老旧设备照样用不了, 比如我的 iPad4 -->
<script src="index.js"></script>
</body>

View File

@@ -1,46 +1,17 @@
/*
* 铃之椅 - 把选择权还给用户, 让聊天权掌握在用户手中
* Copyright 2024 满月叶
* GitHub: https://github.com/MoonLeeeaf/LingChair-Web-Client
* 本项目使用 Apache 2.0 协议开源
*
* Copyright 2024 MoonLeeeaf
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ©2024 满月叶
* Github: MoonLeeeaf
* 铃之椅 网页端
*/
// 2024.5.28 睡着了
const sleep = (t) => new Promise((res) => setTimeout(res, t))
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)
});
// https://www.ruanyifeng.com/blog/2021/09/detecting-mobile-browser.html
function isMobile() {
return ('ontouchstart' in document.documentElement);
}
if (UrlArgs.get("debug")) {
@@ -112,7 +83,7 @@ class NData {
let viewBinding = NData.mount($("#app").get(0))
$.ajax({
url: "config.json",
url: "res/config.json",
dataType: "json",
success: (c) => {
viewBinding.appTitle.text(c.appTitle)
@@ -123,24 +94,6 @@ $.ajax({
},
})
/* // Toolbar 快捷按钮绑定
viewBinding.contactsRefresh.hide()
viewBinding.contactsAdd.hide()
viewBinding.tabChatList.on("show.mdui.tab", () => {
viewBinding.contactsRefresh.hide()
viewBinding.contactsAdd.hide()
})
viewBinding.tabContacts.on("show.mdui.tab", () => {
viewBinding.contactsRefresh.show()
viewBinding.contactsAdd.show()
})
viewBinding.tabChatSeesion.on("show.mdui.tab", () => {
viewBinding.contactsRefresh.hide()
viewBinding.contactsAdd.hide()
}) */
/* viewBinding.tabChatSeesion.hide() */
// 关于页面
viewBinding.menuAbout.click(() => mdui.alert('这是一个开源项目<br/>作者: MoonLeeeaf<br/>欢迎访问我们的<a class="mdui-text-color-theme-accent" href="https://github.com/LingChair/LingChair">项目主页</a>', '关于 铃之椅', () => { }, { confirmText: "关闭" }))
@@ -191,6 +144,10 @@ viewBinding.switchNotifications.click((a) => {
if (localStorage.useNotifications == "true")
viewBinding.switchNotificationsIcon.text("notifications")
viewBinding.inputMsg.blur(() => {
window.initInputResizerResize()
})
// https://www.runoob.com/w3cnote/javascript-copy-clipboard.html
function copyText(t) {
let btn = viewBinding.textCopierBtn
@@ -230,8 +187,6 @@ Date.prototype.format = function (tms, format) {
return format;
}
// new mdui.Drawer('#main-drawer').close()
class NickCache {
static data = {}
static async getNick(name) {
@@ -292,8 +247,6 @@ class 通知 {
if (localStorage.useNotifications !== "true") return
let n = new Notification(this.title, this.args)
n.onclick = onclick == null ? () => n.close() : (n) => onclick(n)
// n.onclose = onclose
// n.close()
return n
}
}
@@ -312,17 +265,14 @@ class ContactsList {
for (let index in ls) {
let name = ls[index]
let dick = await NickCache.getNick(name)
/*client.emit("user.getNick", { name: localStorage.userName }, (re) => {
let nick = re.data == null ? re.data.nick : null
let name = ls[index]*/
$($.parseHTML(`<li class="mdui-list-item mdui-ripple"><div class="mdui-list-item-avatar"><img src="` + User.getUserHeadUrl(name) + `" onerror="this.src='default_head.png'" /></div><div class="mdui-list-item-content">` + dick + `</div></li>`)).appendTo(viewBinding.contactsList).click(() => {
$($.parseHTML(`<li class="mdui-list-item mdui-ripple" mdui-drawer-close><div class="mdui-list-item-avatar"><img src="` + User.getUserHeadUrl(name) + `" onerror="this.src='res/default_head.png'" /></div><div class="mdui-list-item-content">` + dick + `</div></li>`)).appendTo(viewBinding.contactsList).click(() => {
ChatMsgAdapter.switchTo(name, "single")
})
//})
}
})
}
// 添加联系人,好友或者群聊
static add(name, type) {
if (type == "single") {
@@ -333,9 +283,7 @@ class ContactsList {
}
}
// 第一次写前端的消息加载, 代码很乱, 还请原谅~
// v0.7.0 大改UI 畏惧了 太庞大了
// 消息核心
class ChatPage {
static cached = {}
@@ -351,10 +299,10 @@ class ChatPage {
class ChatMsgAdapter {
static type
static target
// static msgList
static minMsgId
static time
static bbn
static resizeDick
// 切换聊天对象
static async switchTo(name, type) {
viewBinding.tabChatSeesion.show()
@@ -363,7 +311,6 @@ class ChatMsgAdapter {
this.type = type
this.target = name
// this.msgList = []
this.minMsgId = null
viewBinding.pageChatSeesion.empty()
@@ -387,7 +334,7 @@ class ChatMsgAdapter {
// 微机课闲的没事干玩玩 发现私聊会多发一个(一个是本地的, 另一个是发送成功的) 选择一个关掉就好了
// 这里我选择服务端不发送回调, 不然多设备同步会吵死
// 错了 应该是客户端少发条才对 不然不能多设备同步
if (ChatMsgAdapter.target !== localStorage.userName && ChatMsgAdapter.type === "single") {
if ((ChatMsgAdapter.target !== localStorage.userName) && ChatMsgAdapter.type === "single") {
let i = ChatMsgAdapter.isAtBottom()
await ChatMsgAdapter.addMsg(localStorage.userName, msg, re.data.time, re.data.msgid)
if (i) ChatMsgAdapter.scrollToBottom()
@@ -461,11 +408,11 @@ class ChatMsgAdapter {
<span id="msg-content">` + msg + `</span>
</div>
</div>
<img class="avatar" src="` + User.getUserHeadUrl(name) + `" onerror="this.src='default_head.png'" />
<img class="avatar" src="` + User.getUserHeadUrl(name) + `" onerror="this.src='res/default_head.png'" />
</div>`
else
temp = `<div class="chat-message-left">
<img class="avatar" src="` + User.getUserHeadUrl(name) + `" onerror="this.src='default_head.png'" />
<img class="avatar" src="` + User.getUserHeadUrl(name) + `" onerror="this.src='res/default_head.png'" />
<div class="message-content-with-nickname-left">
<span class="nickname">` + nick + `</span>
<div class="message-content mdui-card" id="msgid_` + msgid + `">
@@ -494,27 +441,11 @@ class ChatMsgAdapter {
return e
}
// 添加消息记录 作用在 UI 和 msgList
/* static async addMsgLocal(name, m, t, msgid) {
this.msgList.push({
name: name,
msg: m,
msgid: msgid,
})
this.addMsg(name, m, t)
} */
// 从服务器加载一些聊天记录, limit默认=13
static async loadMsgs(limit) {
let histroy = await this.getHistroy(this.msgList[0] == null ? null : this.msgList[0].msgid - 1, limit == null ? 13 : limit)
this.msgList = histroy
}
/* static async loadMsgsFromList(lst) {
for (let index in lst) {
let i = lst[index]
await this.addMsg(i.name, i.msg, i.time)
}
} */
static scrollToBottom() {
// 吐了啊 原来这样就行了 我何必在子element去整啊
viewBinding.chatPager.get(0).scrollBy({
@@ -522,21 +453,25 @@ class ChatMsgAdapter {
behavior: 'smooth'
})
}
// 从本地加载
/*static loadMsgsFromLocal(target) {
let data = localStorage["chat_msg_" + target]
if (data == null || data === "[]")
return []
return JSON.parse(data)
}
// 把当前聊天记录储存到本地
static saveToLocal() {
localStorage["chat_msg_" + this.target] = JSON.stringify(this.msgList)
}*/
// 自动调整使输入框置底 CSS真tm靠不住啊
static initInputResizer() {
let resize = () => viewBinding.pageChatSeesion.height(window.innerHeight - viewBinding.inputToolbar.height() - $("header.mdui-appbar").height() - viewBinding.chatTab.height() - 50)
// 实验表面移动端切出输入法时会触发1-2次resize事件
// 可以利用这个特性来实现自动滚动文本
let resize = () => {
// CSS 牵一发而动全身 因此这个减少的数值是每天都要更改的
viewBinding.pageChatSeesion.height(window.innerHeight - viewBinding.inputToolbar.height() - $("header.mdui-appbar").height() - viewBinding.chatTab.height() - 65)
let ledi = this.resizeDick - window.innerHeight
if (isMobile()) viewBinding.chatPager.get(0).scrollBy({
// 5.19晚1056分调配出来的秘方
// < 0 为窗口变大
// cnm的调试十万次就你tm检测不到底是吧就你语法天天错误是吧
// 欺负我现在用不了电脑
top: -(ledi) * ((ledi < 0 && this.isAtBottom()) ? 6 : -1), // (ledi < 0 ? 6 : 6),
behavior: 'smooth'
})
this.resizeDick = window.innerHeight
}
window.initInputResizerResize = resize
window.addEventListener("resize", resize)
resize()
}
@@ -581,11 +516,13 @@ class ChatMsgAdapter {
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
@@ -706,11 +643,13 @@ class User {
if (i) ChatMsgAdapter.scrollToBottom()
}
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)
location.replace("#msgid_" + a.msg.msgid)
n.close()
})
if (ChatMsgAdapter.target !== localStorage.userName) {
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)
location.replace("#msgid_" + a.msg.msgid)
n.close()
})
}
})
}
static async openProfileDialog(name) {

View File

@@ -6,15 +6,15 @@
/* 美化UI */
/* 恢复系统字体 */
body {
font-family: -apple-system, system-ui, -webkit-system-font;
}
/* 圆角化 */
.mdui-dialog {
border-radius: 23px;
}
.mdui-snackbar {
border-radius: 10px;
}
.mdui-menu {
border-radius: 10px;
}
@@ -37,13 +37,22 @@ body {
.mdui-select-open {
border-radius: 10px;
}
@media screen and (min-width: 768px) {
.mdui-snackbar {
border-radius: 10px;
}
}
/* 配色方案 */
.mdui-theme-color-auto {
background-color: #fff;
.mdui-list-item-avatar {
background-color: rgba(0, 0, 0, 0) !important;
}
/* 背景底色 */
.mdui-theme-color-auto {
background-color: rgba(0, 0, 0, 0);
}
@media (prefers-color-scheme: dark) {
.mdui-theme-color-auto {
background-color: #303030;

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

797
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "lingchair",
"description": "A simple, lightweight and powerful Instant Messaging application.",
"version": "0.6.1",
"version": "0.7.0",
"license": "Apache License 2.0",
"author": {
"name": "MoonLeeeaf",
@@ -11,7 +11,8 @@
"start": "node ./server_src/main.js"
},
"dependencies": {
"mime": "^4.0.1",
"express": "^4.19.2",
"sharp": "^0.33.4",
"socket.io": "^4.7.5"
},
"type": "commonjs"

View File

@@ -5,17 +5,19 @@
> [!NOTE]
> 本项目仍在实验阶段, [点我](final.md)可查看进展
>
> 如果发现有任何疑问, 欢迎提问
> 如果有任何问题,欢迎你提出来,我会不定时查看
>
> 另外 Android 客户端也在开发, 但因为从头开始写且生地中考临近, 因此暂时搁置
> 另外 Android 客户端也在开发, 但进展缓慢
### 使用
服务端:
1. 克隆本仓库源代码到本地
0. 确保安装了 Node.js
2. 运行 run.sh 或 run.bat
1. 克隆本仓库源代码到本地,并运行 run_build.sh 构建网页
2. 运行 run.sh
网页端:
@@ -23,18 +25,12 @@
* 克隆本仓库到本地并运行本地 HTTP 服务端
* 静态网页 (不推荐, 有跨域问题)
* 静态网页 (不推荐)
### [Q&A](.github/QA.md)
### 鸣谢
WIP
### [你知道吗](.github/do_you_know.md)
### 温馨提示
不建议,不推荐,不赞同用于商业用途, 本项目的设计初衷是为了个人和团队使用, 而非用于圈钱, 因此如果确实需要商业化, 请考虑其他项目
为什么? 因为这个项目还在初级阶段, 还有很多地方不够完善, 甚至有可能被一些 Hacker 抓到漏洞, 造成不必要的损失
因此我更建议个人及团队内部使用, 亦或者加密后放在公网使用

View File

@@ -12,7 +12,7 @@ const users = require("./api-users")
let getSameHashedValue = (a, b) => {
let _a = [hash.md5(a) + hash.sha256(a), hash.md5(b) + hash.sha256(b)].sort()
let [_1, _2] = _a
return hash.sha256hex(hash.sha256hex(_1) + hash.sha256hex(_2))
return hash.sha256(hash.sha256(_1) + hash.sha256(_2))
}
let getSingleChatDir = (a, b) => {

View File

@@ -7,10 +7,8 @@
const crypto = require("crypto")
let apis = {
sha256: (data) => crypto.createHash("sha256").update(data).digest("base64"),
md5: (data) => crypto.createHash("md5").update(data).digest("base64"),
sha256hex: (data) => crypto.createHash("sha256").update(data).digest("hex"),
md5hex: (data) => crypto.createHash("md5").update(data).digest("hex"),
sha256: (data) => crypto.createHash("sha256").update(data).digest("hex"),
md5: (data) => crypto.createHash("md5").update(data).digest("hex"),
}
module.exports = apis

View File

@@ -19,10 +19,10 @@ const vals = require("./val")
const color = require("./color")
//定义 Http 服务器回调
let httpServerCallback = require("./httpApi")
let httpServerCallback = require("./http-api")
// 定义 Socket.io 服务器回调
let wsServerCallback = require("./wsApi")
let wsServerCallback = require("./ws-api")
let httpServer
if (vals.LINGCHAIR_SERVER_CONFIG.useHttps)