refactor: 重構後端代碼, 換用 Deno

This commit is contained in:
CrescentLeaf
2025-06-15 00:22:53 +08:00
parent 6c225b7bc5
commit d65ead11e1
29 changed files with 362 additions and 15645 deletions

View File

@@ -1,19 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
class Client {
}
class ClientUser {
}

View File

@@ -1,164 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
class MessageNormal extends HTMLElement {
static observedAttributes = ['avatar', 'sender-name', 'sender-id', 'msg', 'direction']
constructor() {
super()
const shadow = this.attachShadow({ mode: "open" })
}
connectedCallback() {
const shadow = this.shadowRoot
shadow.appendChild($('#message-normal-template').get(0).content.cloneNode(true))
$(shadow).find('#sender-name-left').hide()
this.update()
}
attributeChangedCallback(_name, _oldValue, _newValue) {
this.update()
}
update() {
const shadow = this.shadowRoot
// 消息视图的的左右方向
let isRightDirection = this.getAttribute('direction') == 'right'
$(shadow).find('#_direction_1').css('justify-content', isRightDirection ? 'flex-end' : 'flex-start')
$(shadow).find('#_direction_2').css('justify-content', isRightDirection ? 'flex-end' : 'flex-start')
$(shadow).find('#_direction_3').css('align-self', isRightDirection ? 'flex-end' : 'flex-start')
$(shadow).find('#_direction_3').css('margin-left', isRightDirection ? '' : '55px')
$(shadow).find('#_direction_3').css('margin-right', isRightDirection ? '55px' : '')
$(shadow).find('#sender-name-left')[isRightDirection ? 'show' : 'hide']()
$(shadow).find('#sender-name-right')[isRightDirection ? 'hide' : 'show']()
// 头像
let avatar = $(shadow).find('#avatar')
this.hasAttribute('avatar') ? avatar.attr('src', this.getAttribute('avatar')) : avatar.text((this.getAttribute('sender-name') || '').substring(0, 1))
// 发送者
$(shadow).find('#sender-name-left').text(this.getAttribute('sender-name'))
$(shadow).find('#sender-name-right').text(this.getAttribute('sender-name'))
$(shadow).find('#sender-id').text(this.getAttribute('sender-id'))
// 消息
this.hasAttribute('msg') && $(shadow).find('#msg').text(this.getAttribute('msg'))
}
}
class MessageSystem extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({ mode: "open" })
}
connectedCallback() {
const shadow = this.shadowRoot
shadow.appendChild($('#message-system-template').get(0).content.cloneNode(true))
}
}
class MessageHolder extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({ mode: "open" })
}
connectedCallback() {
const shadow = this.shadowRoot
shadow.appendChild($('#message-holder-template').get(0).content.cloneNode(true))
}
addMessage({ senderId = '', senderName = '', msg = '', avatar, direction = 'left' }, atStart) {
const v = new MessageNormal()
$(v).attr('sender-id', senderId).attr('sender-name', senderName).attr('avatar', avatar).attr('direction', direction).text(msg)
$(this)[atStart ? 'prepend' : 'append'](v)
}
addSystemMessage(msg, atStart) {
const v = new MessageSystem()
$(v).text(msg)
$(this)[atStart ? 'prepend' : 'append'](v)
}
getMessages(withSystemMessage) {
let ls = []
$(this).find('message-normal' + withSystemMessage ? ', message-system' : '').each((_i, e) => {
let a = $(e)
ls.push({
senderName: a.attr('sender-name'),
avatar: a.attr('avatar'),
senderId: a.attr('sender-id'),
direction: a.attr('direction'),
})
})
}
}
customElements.define('message-normal', MessageNormal)
customElements.define('message-system', MessageSystem)
customElements.define('message-holder', MessageHolder)
customElements.define('main-navigation-item', class extends mdui.NavigationRailItem {
static observedAttributes = ['img', 'id', 'text']
constructor() {
super()
const shadow = this.attachShadow({ mode: "open" })
}
connectedCallback() {
// 现在这是 mdui-navigation-rail-item, 不应该加到shadow而是自身
// 害得我修了好久
this.appendChild($('#main-navigation-item-template').get(0).content.cloneNode(true))
const self = this
const avatar = $(this).find('#avatar')
const avatarImg = $(this).find('#img')
avatarImg.bind('error', () => {
avatar.text((self.getAttribute('text') || '').substring(0, 1))
})
this.myUpdate()
super.connectedCallback()
}
attributeChangedCallback(_name, _oldValue, _newValue) {
this.myUpdate()
super.attributeChangedCallback()
}
myUpdate() {
this.hasAttribute('img') ? $(this).find('#img').attr('src', this.getAttribute('img')) : $(this).find('#avatar').text((this.getAttribute('text') || '').substring(0, 1))
$(this).find('#tip').attr('content', this.getAttribute('text'))
this.hasAttribute('id') && $(this).attr('value', this.getAttribute('id'))
}
})
customElements.define('message-img', class extends HTMLElement {
constructor() {
super()
}
connectedCallback() {
let e = new Image()
e.style.maxWidth = "100%"
e.style.maxHeight = "90%"
e.style.marginTop = "13px"
e.style.borderRadius = "var(--mdui-shape-corner-medium)"
e.src = $(this).attr('src')
e.alt = $(this).attr('alt')
e.onerror = () => {
$(this).html(`<br/><mdui-icon name="broken_image" style="font-size: 2rem;"></mdui-icon>`)
$(this).attr('alt', '图像损坏')
}
e.onclick = () => {
openImageViewer($(this).attr('src'))
}
this.appendChild(e)
}
})

View File

@@ -1,13 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
fetch('client_config.json').then((re) => re.json()).then((config) => {
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -1,448 +0,0 @@
<!doctype html>
<html lang="zh-CN" class="mdui-theme-auto">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" />
<meta name="renderer" content="webkit" />
<!-- UI -->
<script src="https://unpkg.com/mdui@2/mdui.global.js">
</script>
<link rel="icon" href="icon.ico" />
<link rel="stylesheet" href="https://unpkg.com/mdui@2/mdui.css" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet" />
<!-- Tools -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js">
</script>
<script src="https://cdn.jsdelivr.net/gh/GoogleChromeLabs/pinch-zoom@1.1.1/dist/pinch-zoom-min.js">
</script>
<!-- Connection -->
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@4.7.5/dist/socket.io.min.js">
</script>
<title>TheWhiteSilk</title>
<link href="style-shared.css" rel="stylesheet" />
<script src="utils-shared.js">
</script>
</head>
<body>
<a id="download-helper" style="display: none;">
</a>
<!-- 自定义元素 -->
<!-- 消息列表容器 -->
<template id="message-holder-template">
<div style="display: flex; flex-direction: column; justify-content: flex-end; /* align-items: center */; padding-top: 10px; padding-bottom: 14px;"
id="holder">
<slot name="top" part="top">
</slot>
<!-- 默认槽位 如果没有 内部嵌套元素将不会被渲染 -->
<slot>
</slot>
</div>
</template>
<!-- 普通消息 -->
<template id="message-normal-template">
<style>
/* 精准指针设备 令桌面端 */
@media (pointer: fine) {
#_direction_3 {
max-width: 50%;
}
}
/* 不精准指针设备 令移动端 */
@media (pointer: coarse) {
#_direction_3 {
max-width: 77%;
}
}
</style>
<div style="display: none;" id="sender-id">
</div>
<div id="_direction_1" slot="trigger"
style="width: 100%; display: flex; justify-content: flex-start; flex-direction: column;">
<div id="_direction_2" style="display: flex; justify-content: flex-start;">
<span style="align-self: center; font-size: 90%;" id="sender-name-left">
</span>
<mdui-avatar style="width: 43px; height: 43px; margin: 11px;" id="avatar">
</mdui-avatar>
<span style="align-self: center; font-size: 90%;" id="sender-name-right">
</span>
</div>
<mdui-card id="_direction_3" variant="elevated"
style="min-width: 0%; margin-left: 55px; margin-top: -5px; padding: 15px; align-self: flex-start;">
<span id="msg" style="font-size: 94%;">
<slot>
</slot>
</span>
</mdui-card>
</div>
</template>
<!-- 系统消息 -->
<template id="message-system-template">
<style>
/* 精准指针设备 令桌面端 */
@media (pointer: fine) {
#msg {
max-width: 50%;
font-size: 94%;
}
}
/* 不精准指针设备 令移动端 */
@media (pointer: coarse) {
#msg {
max-width: 90%;
font-size: 90%;
}
}
</style>
<div style="width: 100%; flex-direction: column; display: flex; margin-top: 25px; margin-bottom: 20px;">
<mdui-card variant="filled" id="msg"
style="align-self: center; padding-top: 9px; padding-bottom: 9px; padding-left: 18px; padding-right: 18px; font-size: 92%;">
<slot>
</slot>
</mdui-card>
</div>
</template>
<!-- 普通消息 -->
<template id="message-normal-template">
<div style="display: none;" id="sender-id">
</div>
<div id="_direction_1" slot="trigger"
style="width: 100%; display: flex; justify-content: flex-start; flex-direction: column;">
<div id="_direction_2" style="display: flex; justify-content: flex-start;">
<span style="align-self: center; font-size: 90%;" id="sender-name-left">
</span>
<mdui-avatar style="width: 43px; height: 43px; margin: 11px;" id="avatar">
</mdui-avatar>
<span style="align-self: center; font-size: 90%;" id="sender-name-right">
</span>
</div>
<mdui-card id="_direction_3" variant="elevated"
style="max-width: 80%; min-width: 0%; margin-left: 55px; margin-top: -5px; padding: 15px; align-self: flex-start;">
<span id="msg">
<slot>
</slot>
</span>
</mdui-card>
</div>
</template>
<!-- 系统消息 -->
<template id="message-system-template">
<div style="width: 100%; flex-direction: column; display: flex; margin-top: 25px; margin-bottom: 20px;">
<mdui-card variant="filled" id="msg"
style="max-width: 90%; align-self: center; padding-top: 9px; padding-bottom: 9px; padding-left: 18px; padding-right: 18px; font-size: 92%;">
<slot>
</slot>
</mdui-card>
</div>
</template>
<!-- 侧边导航栏 - 列表项目 -->
<template id="main-navigation-item-template">
<mdui-tooltip slot="icon" id="tip">
<mdui-avatar id="avatar">
<img id="img" style="width: 100%; height: 100%; object-fit: contain;" />
</mdui-avatar>
</mdui-tooltip>
</template>
<script src="custom-elements-index.js">
</script>
<!-- 主视图 -->
<!-- 巨坑: 父元素的高度必须小于子元素 否则overflow-y无效!!! 参考: https://blog.csdn.net/Jet_Lover/article/details/121957321 -->
<div style="display: flex;" id="app">
<style>
/* 让侧边栏能多个图标滑动 */
mdui-navigation-rail::part(items) {
overflow-y: auto;
}
</style>
<mdui-navigation-rail>
<shadow-inner>
<style>
*::-webkit-scrollbar {
width: 0px !important;
}
</style>
</shadow-inner>
<mdui-button-icon lowered="lowered" icon="menu" slot="top">
</mdui-button-icon>
<mdui-button-icon lowered="lowered" icon="add" slot="top">
</mdui-button-icon>
<mdui-dropdown slot="top" trigger="hover">-
<mdui-button-icon icon="watch_later--outlined" slot="trigger" id="switch-navigation-list-button">
</mdui-button-icon>
<mdui-menu id="switch-navigation-list-menu" selects="single" value="1">
<mdui-menu-item value="0">详细列表<mdui-icon slot="icon" name="watch_later--outlined"
id="switch-navigation-list-info-menuicon">
</mdui-icon>
</mdui-menu-item>
<mdui-divider>
</mdui-divider>
<mdui-menu-item value="1">最近</mdui-menu-item>
<mdui-menu-item value="2">联系人</mdui-menu-item>
<mdui-menu-item value="3">群聊</mdui-menu-item>
</mdui-menu>
</mdui-dropdown>
<mdui-dropdown slot="bottom" trigger="hover">
<mdui-button-icon icon="settings" slot="trigger">
</mdui-button-icon>
<mdui-menu id="switch-navigation-list-menu">
<mdui-menu-item onclick="$('#dialog-about').get(0).open = true">关于</mdui-menu-item>
</mdui-menu>
</mdui-dropdown>
<div id="main-navigation-list-1" class="contents-only">
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
<main-navigation-item text="满月" img="https://avatars.githubusercontent.com/u/150461955?v=4">
</main-navigation-item>
</div>
<div id="main-navigation-list-2" class="contents-only">
<main-navigation-item text="喵呜" img="114514">
</main-navigation-item>
</div>
<div id="main-navigation-list-3" class="contents-only">
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
<main-navigation-item text="裙子">
</main-navigation-item>
</div>
</mdui-navigation-rail>
<mdui-dialog id="nav-list-information-dialog" close-on-overlay-click="close-on-overlay-click">
<shadow-inner>
<style>
*::-webkit-scrollbar {
width: 0px !important;
}
</style>
</shadow-inner>
<mdui-list>
</mdui-list>
<mdui-button slot="action" variant="text" onclick="this.parentNode.open = false">关闭</mdui-button>
</mdui-dialog>
<mdui-dialog close-on-overlay-click="close-on-overlay-click" id="dialog-about">
<shadow-inner>
<style>
*::-webkit-scrollbar {
width: 0px !important;
}
</style>
</shadow-inner>
<div slot="description" style="display: flex; margin-bottom: -4px;">
<mdui-avatar src="icon.ico">
</mdui-avatar>
<div style="margin-left: 17px;">
<span style="font-size: 1.15rem;">LingChair</span>
<br />
<span style="margin-top: 20px; font-size: 0.8rem;">
Nightly
<br />
<span style="margin-top: 5px">
<a href="https://github.com/LingChair/LingChair">GitHub</a> 查看源码
</span>
</span>
</div>
</div>
</mdui-dialog>
<style>
#image-viewer-dialog::part(panel) {
background: rgba(0, 0, 0, 0) !important;
padding: 0 !important;
}
#image-viewer-dialog>mdui-button-icon[icon=close] {
z-index: 114514;
position: fixed;
top: 15px;
right: 15px;
}
#image-viewer-dialog>mdui-button-icon[icon=download] {
z-index: 114514;
position: fixed;
top: 15px;
right: 65px;
}
</style>
<mdui-dialog id="image-viewer-dialog" fullscreen="fullscreen">
<mdui-button-icon icon="download"
onclick="downloadFromUrl($('#image-viewer-dialog-inner > *').attr('src')).catch((e) => mdui.snackbar({message: '无法下载, 也许是被拒绝了吧?', closeOnOutsideClick: true}))">
</mdui-button-icon>
<mdui-button-icon icon="close" onclick="this.parentNode.open = false">
</mdui-button-icon>
<pinch-zoom id="image-viewer-dialog-inner" class="size-as-window">
</pinch-zoom>
</mdui-dialog>
<div id="right-contents" style="flex-grow: 1; overflow-y: visible; position:relative;">
<mdui-top-app-bar style="position: sticky; /* 好耶 是黏黏的胶水 想被胶水姐姐死死黏住不放~啊~(〃∇〃)姐姐好温柔~~suki♥ */; top: 0;"
id="input_toolbar">
<mdui-dropdown trigger="hover">
<mdui-button-icon icon="arrow_drop_down" slot="trigger">
</mdui-button-icon>
<mdui-menu>
<mdui-menu-item>主面板</mdui-menu-item>
</mdui-menu>
</mdui-dropdown>
<mdui-top-app-bar-title>院审</mdui-top-app-bar-title>
<div style="flex-grow: 1">
</div>
<mdui-dropdown trigger="hover">
<mdui-button-icon icon="more_vert" slot="trigger">
</mdui-button-icon>
<mdui-menu>
<mdui-menu-item>资料<mdui-icon slot="icon" name="info">
</mdui-icon>
</mdui-menu-item>
<mdui-menu-item>设置<mdui-icon slot="icon" name="settings">
</mdui-icon>
</mdui-menu-item>
</mdui-menu>
</mdui-dropdown>
</mdui-top-app-bar>
<message-holder>
<mdui-button variant="text" slot="top" style="align-self: center;">加载更多</mdui-button>
<div class="contents-only">
<message-normal direction="left" sender-name="测试" sender-id="test">
我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神
</message-normal>
<message-normal direction="left" sender-name="测试" sender-id="test">启动</message-normal>
<message-normal direction="left" sender-name="测试" sender-id="test">
我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神
</message-normal>
<message-system>原神 被 测试 踢出了群聊</message-system>
<message-system>
满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐满月姐姐
</message-system>
<message-normal direction="left" sender-name="测试" sender-id="test">启动</message-normal>
<message-normal direction="right" sender-name="阿弥诺斯" sender-id="阿弥诺斯">阿弥诺斯</message-normal>
<message-normal direction="right" sender-name="阿弥诺斯" sender-id="阿弥诺斯">
我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神我要玩原神
</message-normal>
<message-normal direction="right" sender-name="阿弥诺斯" sender-id="阿弥诺斯">我要玩原神<br />
<message-img src="https://www.yuanshen.com/images/ys.96a55539.png" />
</message-normal>
<message-normal direction="right" sender-name="阿弥诺斯" sender-id="阿弥诺斯">我要玩院审😭👊<br />
<message-img
src="https://huiji-thumb.huijistatic.com/aceattorney/uploads/thumb/e/e6/Skärmbild_(985).png/640px-Skärmbild_(985).png" />
</message-normal>
</div>
</message-holder>
<mdui-top-app-bar
style="z-index: 100; bottom: 0; position: sticky; /* 好耶 是黏黏的胶水 想被胶水姐姐死死黏住不放~啊~(〃∇〃)姐姐好温柔~~suki♥ */"
scroll-target="#right-contents" id="input_toolbar">
<mdui-text-field placeholder="(=・ω・=)" variant="outlined" autosize="autosize" id="input_message"
style="align-self: center; flex-grow: 1; max-height: 46px;">
</mdui-text-field>
<style>
#input_message::part(input) {
line-height: 15px;
}
</style>
<mdui-button-icon icon="send" id="send_message">
</mdui-button-icon>
<mdui-dropdown trigger="hover">
<mdui-button-icon icon="more_vert" slot="trigger">
</mdui-button-icon>
<mdui-menu>
<mdui-menu-item>插入图片<mdui-icon slot="icon" name="image">
</mdui-icon>
</mdui-menu-item>
<mdui-menu-item>插入音频<mdui-icon slot="icon" name="keyboard_voice">
</mdui-icon>
</mdui-menu-item>
<mdui-menu-item>插入文件<mdui-icon slot="icon" name="insert_drive_file">
</mdui-icon>
</mdui-menu-item>
<mdui-menu-item>插入链接<mdui-icon slot="icon" name="link">
</mdui-icon>
</mdui-menu-item>
<mdui-divider>
</mdui-divider>
<mdui-menu-item>插入名片<mdui-icon slot="icon" name="account_box">
</mdui-icon>
</mdui-menu-item>
<mdui-divider>
</mdui-divider>
<mdui-menu-item>展开输入框<mdui-icon slot="icon" name="open_in_full">
</mdui-icon>
</mdui-menu-item>
</mdui-menu>
</mdui-dropdown>
</mdui-top-app-bar>
</div>
</div>
<script src="client-side.js">
</script>
<script src="ui-controller-shared.js">
</script>
<script src="ui-controller-index.js">
</script>
<script src="global-appconfig.js">
</script>
</body>
</html>

View File

@@ -1,62 +0,0 @@
<!doctype html>
<html lang="zh-CN" class="mdui-theme-auto">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" />
<meta name="renderer" content="webkit" />
<!-- UI -->
<script src="https://unpkg.com/mdui@2/mdui.global.js">
</script>
<link rel="icon" href="icon.ico" />
<link rel="stylesheet" href="https://unpkg.com/mdui@2/mdui.css" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet" />
<!-- Tools -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js">
</script>
<!-- Connection -->
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@4.7.5/dist/socket.io.min.js">
</script>
<title>登录到 铃之椅</title>
<link href="style-shared.css" rel="stylesheet" />
<script src="utils-shared.js">
</script>
</head>
<body style="display: flex; flex-direction: column;" id="app">
<div class="size-as-window"
style="margin-top: calc(var(--window-height) / 2 - 190px); margin-left: 30px; margin-right: 30px;">
<h2>登录到 铃之椅</h2>
<mdui-text-field label="账号" style="margin-top: 30px;">
</mdui-text-field>
<mdui-text-field label="密码" type="password" toggle-password="toggle-password" style="margin-top: 30px;">
</mdui-text-field>
<div style="margin-top: 30px; display: flex; justify-content: center; margin-left: 40px; margin-right: 40px;">
<mdui-button class="fill-width">登录账号</mdui-button>
<div style="margin: 5px">
</div>
<mdui-button class="fill-width">注册账号</mdui-button>
<div style="margin: 5px">
</div>
<mdui-button class="fill-width">游客登录</mdui-button>
</div>
</div>
<span style="position: fixed; bottom: 10px; width: 100%; text-align: center;">©2024 满月叶</span>
<script src="ui-controller-shared.js">
</script>
<script src="client-side.js">
</script>
<script src="global-appconfig.js">
</script>
</body>
</html>

View File

@@ -1,87 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
/* 滑条*/
.no-scroll-bar::-webkit-scrollbar {
width: 0px !important;
}
/* https://blog.csdn.net/qq_39347364/article/details/111996581*/
*::-webkit-scrollbar {
width: 7px;
height: 10px;
}
*::-webkit-scrollbar-track {
width: 6px;
background: rgba(#101F1C, 0.1);
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
*::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, .5);
background-clip: padding-box;
min-height: 28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
transition: background-color .3s;
cursor: pointer;
}
*::-webkit-scrollbar-thumb:hover {
background-color: rgba(144, 147, 153, .3);
}
/* 使用系统字体 在部分系统表现很好*/
/* 我们至今仍未能知道桌面端浏览器字体的秘密*/
*:not(.material-icons, .mdui-icon, mdui-icon, .fa, .google-symbols) {
font-family: -apple-system, system-ui, -webkit-system-font !important;
}
body {
display: flex;
margin: 0 0 0 0;
}
/* 防止小尺寸图片模糊*/
* {
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
-ms-interpolation-mode: nearest-neighbor;
}
/* 与窗口同大小*/
.size-as-window {
width: var(--window-width);
height: var(--window-height);
}
/* Flex - 铺满*/
.fill-width {
width: 100%;
}
.fill-height {
height: 100%;
}
/* 链接使用主题色*/
a {
color: rgb(var(--mdui-color-primary));
}
.contents-only {
display: contents;
}

View File

@@ -1,190 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
/**
* ========================================================
* 侧边导航栏列表
* ========================================================
*/
// 按钮:查看详细列表
$('#switch-navigation-list-info-menuicon').parent().click(() => {
let list = $('#nav-list-information-dialog > mdui-list').empty()
let selected = $('#switch-navigation-list-menu').get(0).value
$('#main-navigation-list-' + selected + " > main-navigation-item").each((_i, e) => {
let i = $.parseHTML(`<mdui-list-item rounded></mdui-list-item>`)
let a = $.parseHTML(`<mdui-avatar slot="icon"></mdui-avatar>`)
let img = new Image()
img.style.cssText = `width: 100%; height: 100%; object-fit: contain;`
img.src = e.getAttribute('img')
img.onerror = () => {
$(a).text((e.getAttribute('text') || '').substring(0, 1))
}
$(a).append(img)
$(i).append(e.getAttribute('text'))
$(i).append(a)
list.append(i)
})
$('#nav-list-information-dialog').attr('headline', (function () {
let t
switch (selected + '') {
case "1":
t = '最近'
break;
case "2":
t = '联系人'
break;
case "3":
t = '群组'
break;
}
return t
})())
$('#nav-list-information-dialog').attr('open', true)
})
// 切换列表选项
let lastValue = $('#switch-navigation-list-menu').get(0).value
$('#switch-navigation-list-menu').on('change', (e) => {
// 当前选择的值
let value = e.target.value
// 特殊:详细列表
if (value == 0) {
// 选回原来的选项
e.target.value = lastValue
value = lastValue
$('#switch-navigation-list-menu > mdui-menu-item[value=' + value + ']').get(0).selected = true
$('#switch-navigation-list-menu > mdui-menu-item[value=0]').get(0).selected = false
// 错误示范: 在这里写点击事件
}
// 禁止空选择
if (value == null) {
e.target.value = lastValue
value = lastValue
$('#switch-navigation-list-menu > mdui-menu-item[value=' + value + ']').get(0).selected = true
}
// 显示指定的列表
$('#main-navigation-list-1').hide()
$('#main-navigation-list-2').hide()
$('#main-navigation-list-3').hide()
$('#main-navigation-list-' + value).show()
// 修改图标
let icon = (function () {
let ico
switch (value + '') {
case "1":
ico = 'watch_later--outlined'
break;
case "2":
ico = 'contacts--outlined'
break;
case "3":
ico = 'group--outlined'
break;
}
return ico
})()
$('#switch-navigation-list-button').attr('icon', icon)
$('#switch-navigation-list-info-menuicon').attr('name', icon)
// 更新最后的值用以防止空选择
lastValue = value
})
// 最开始只选择 最近, 隐藏其他列表
$('#main-navigation-list-2').hide()
$('#main-navigation-list-3').hide()
// 子项目被点击时
$('mdui-navigation-rail').on('click', (event) => {
let e = event.target
let tagName = e.tagName.toLowerCase()
while (tagName != 'main-navigation-item') {
e = e.parentNode
tagName = (e.tagName || 'mdui-navigation-rail').toLowerCase()
if (tagName == 'mdui-navigation-rail') return
}
// 获取到Item
})
/**
* ========================================================
* 输入框与消息编辑
* ========================================================
*/
windowOnResizingCallbacks.push((w, h) => {
$('#input_message').width(w - ($('mdui-navigation-rail').width() + $('#send_message').width() * 2 + 100))
})
/**
* ========================================================
* 消息列表
* ========================================================
*/
function scrollMessageHolderToBottom() {
window.scrollBy({
top: 1145141919810,
behavior: "smooth",
})
}
/**
* ========================================================
* 图片查看对话框
* ========================================================
*/
function openImageViewer(src) {
$('#image-viewer-dialog-inner').empty()
let e = new Image()
e.src = src
e.onerror = () => {
$('#image-viewer-dialog-inner').empty()
$('#image-viewer-dialog-inner').append($.parseHTML(`<mdui-icon name="broken_image" style="font-size: 2rem;"></mdui-icon>`))
}
$('#image-viewer-dialog-inner').append(e)
e.onload = () => $('#image-viewer-dialog-inner').get(0).setTransform({
scale: 0.6,
x: $(window).width() / 2 - (e.width / 4),
y: $(window).height() / 2 - (e.height / 3),
})
$('#image-viewer-dialog').get(0).open = true
}
/**
* ========================================================
* 下载
* ========================================================
*/
async function downloadFromUrl(src) {
let re = await fetch(src)
let blob = await re.blob()
let url = URL.createObjectURL(blob)
$('#download-helper').attr('download', url).attr('href', url).get(0).click()
setTimeout(() => URL.revokeObjectURL(url), 10000)
}
/**
* ========================================================
* 杂项
* ========================================================
*/
// mdui.setColorScheme("#FFB4AA")

View File

@@ -1,41 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
/**
* ========================================================
* 窗口大小
* ========================================================
*/
// 在窗口加载完毕后会将所有页面大小变化的回调都调用一次
const windowOnResizingCallbacks = []
function updateWindowSize() {
document.body.style.setProperty('--window-width', `${window.innerWidth}px`)
document.body.style.setProperty('--window-height', `${window.innerHeight}px`)
windowOnResizingCallbacks.forEach((v) => v(window.innerWidth, window.innerHeight))
}
window.addEventListener('resize', updateWindowSize)
// 初步确定(值有偏差)
$(() => updateWindowSize())
// 完全确定(值已经确定)
window.addEventListener('load', updateWindowSize)
/**
* ========================================================
* Shadow 元素辅助代码
* ========================================================
*/
// 将组件添加到影子DOM中
$(() => $('* > shadow-inner').each((_i, v) => {
$(v.parentElement.shadowRoot).append(v.children)
v.parentNode.removeChild(v)
}))

View File

@@ -1,30 +0,0 @@
/*
* ©2024 The LingChair Project
*
* Make a more colorful world...
*
* License - Apache License 2.0
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
* Organization - @LingChair <https://github.com/LingChair>
*/
/**
* ========================================================
* 移动端检测
* ========================================================
*/
const isMobile = () => ('ontouchstart' in document.documentElement)
/**
* ========================================================
* 移动端调试
* ========================================================
*/
if (isMobile()) {
let a = document.createElement('script')
a.src = "https://unpkg.com/eruda/eruda.js"
a.onload = () => eruda.init()
document.head.appendChild(a)
}