|
@ -1,5 +0,0 @@
|
||||||
[*.{js,jsx,ts,tsx,vue}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
|
@ -3,12 +3,13 @@ module.exports = {
|
||||||
env: {
|
env: {
|
||||||
node: true
|
node: true
|
||||||
},
|
},
|
||||||
extends: [
|
'extends': [
|
||||||
'plugin:vue/vue3-essential',
|
'plugin:vue/vue3-essential',
|
||||||
'@vue/standard'
|
'eslint:recommended',
|
||||||
|
'@vue/typescript/recommended'
|
||||||
],
|
],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: '@babel/eslint-parser'
|
ecmaVersion: 2020
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"module": "esnext",
|
|
||||||
"baseUrl": "./",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"paths": {
|
|
||||||
"@/*": [
|
|
||||||
"src/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"lib": [
|
|
||||||
"esnext",
|
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"scripthost"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
21
package.json
|
@ -21,22 +21,23 @@
|
||||||
"v-viewer": "^3.0.11",
|
"v-viewer": "^3.0.11",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-clipboard2": "^0.3.3",
|
"vue-clipboard2": "^0.3.3",
|
||||||
"vue-cookies": "^1.8.1",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-i18n": "9",
|
"vue-infinite-scroll": "^2.0.2",
|
||||||
"vue-infinite-scroll": "^2.0.2"
|
"vue3-cookies": "^1.0.6",
|
||||||
|
"vue3-infinite-scroll-better": "^2.2.0",
|
||||||
|
"xss": "^1.0.14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
"@babel/eslint-parser": "^7.12.16",
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
"@vue/cli-plugin-pwa": "~5.0.0",
|
"@vue/cli-plugin-pwa": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-typescript": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
"@vue/eslint-config-standard": "^6.1.0",
|
"@vue/eslint-config-typescript": "^9.1.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"typescript": "~4.5.5"
|
||||||
"eslint-plugin-promise": "^5.1.0",
|
|
||||||
"eslint-plugin-vue": "^8.0.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<meta name="referrer" content="no-referrer" id="referrer">
|
<meta name="referrer" content="no-referrer" id="referrer">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
|
||||||
<!-- Border Card UI -->
|
<!-- Border Card UI -->
|
||||||
<link rel="stylesheet" href="https://stapxs.github.io/Border-Card-UI/css/style.css">
|
<link rel="stylesheet" href="https://stapxs.github.io/Border-Card-UI/css/style.css">
|
||||||
<link rel="stylesheet" href="https://stapxs.github.io/Border-Card-UI/css/color-light.css">
|
<link rel="stylesheet" href="https://stapxs.github.io/Border-Card-UI/css/color-light.css">
|
||||||
|
|
419
src/App.vue
|
@ -1,18 +1,15 @@
|
||||||
<!--
|
|
||||||
* @FileDescription: 页面主框架
|
|
||||||
* @Author: Stapxs
|
|
||||||
* @Date: 2022/07/29
|
|
||||||
* @Version: 1.0
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<div class="layui-tab layui-tab-brief main-body">
|
<div class="layui-tab layui-tab-brief main-body">
|
||||||
<ul class="layui-tab-title">
|
<ul class="layui-tab-title">
|
||||||
<li @click="changeTab('主页', 'Home', true)" :class="login.status ? 'hiden-home' : 'layui-this'">
|
<li @click="changeTab('主页', 'Home', true)" :class="loginInfo.status ? 'hiden-home' : 'layui-this'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">><path d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
|
||||||
|
<path
|
||||||
|
d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z" />
|
||||||
|
</svg>
|
||||||
</li>
|
</li>
|
||||||
<li id="bar-msg" @click="changeTab('信息', 'Messages', false)" :class="!login.status ? '' : 'layui-this'">
|
<li id="bar-msg" @click="changeTab('信息', 'Messages', false)"
|
||||||
|
:class="!loginInfo.status ? '' : 'layui-this'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
<path
|
<path
|
||||||
d="M464 64C490.5 64 512 85.49 512 112C512 127.1 504.9 141.3 492.8 150.4L275.2 313.6C263.8 322.1 248.2 322.1 236.8 313.6L19.2 150.4C7.113 141.3 0 127.1 0 112C0 85.49 21.49 64 48 64H464zM217.6 339.2C240.4 356.3 271.6 356.3 294.4 339.2L512 176V384C512 419.3 483.3 448 448 448H64C28.65 448 0 419.3 0 384V176L217.6 339.2z" />
|
d="M464 64C490.5 64 512 85.49 512 112C512 127.1 504.9 141.3 492.8 150.4L275.2 313.6C263.8 322.1 248.2 322.1 236.8 313.6L19.2 150.4C7.113 141.3 0 127.1 0 112C0 85.49 21.49 64 48 64H464zM217.6 339.2C240.4 356.3 271.6 356.3 294.4 339.2L512 176V384C512 419.3 483.3 448 448 448H64C28.65 448 0 419.3 0 384V176L217.6 339.2z" />
|
||||||
|
@ -33,7 +30,8 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="layui-tab-content">
|
<div class="layui-tab-content">
|
||||||
<div :class="!login.status ? 'layui-tab-item layui-show' : 'layui-tab-item'" :name="$t('home_title')">
|
<div :class="!loginInfo.status ? 'layui-tab-item layui-show' : 'layui-tab-item'"
|
||||||
|
:name="$t('home_title')">
|
||||||
<div class="home-body">
|
<div class="home-body">
|
||||||
<div class="login-pan-card ss-card">
|
<div class="login-pan-card ss-card">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
|
@ -49,16 +47,18 @@
|
||||||
d="M172.5 131.1C228.1 75.51 320.5 75.51 376.1 131.1C426.1 181.1 433.5 260.8 392.4 318.3L391.3 319.9C381 334.2 361 337.6 346.7 327.3C332.3 317 328.9 297 339.2 282.7L340.3 281.1C363.2 249 359.6 205.1 331.7 177.2C300.3 145.8 249.2 145.8 217.7 177.2L105.5 289.5C73.99 320.1 73.99 372 105.5 403.5C133.3 431.4 177.3 435 209.3 412.1L210.9 410.1C225.3 400.7 245.3 404 255.5 418.4C265.8 432.8 262.5 452.8 248.1 463.1L246.5 464.2C188.1 505.3 110.2 498.7 60.21 448.8C3.741 392.3 3.741 300.7 60.21 244.3L172.5 131.1zM467.5 380C411 436.5 319.5 436.5 263 380C213 330 206.5 251.2 247.6 193.7L248.7 192.1C258.1 177.8 278.1 174.4 293.3 184.7C307.7 194.1 311.1 214.1 300.8 229.3L299.7 230.9C276.8 262.1 280.4 306.9 308.3 334.8C339.7 366.2 390.8 366.2 422.3 334.8L534.5 222.5C566 191 566 139.1 534.5 108.5C506.7 80.63 462.7 76.99 430.7 99.9L429.1 101C414.7 111.3 394.7 107.1 384.5 93.58C374.2 79.2 377.5 59.21 391.9 48.94L393.5 47.82C451 6.731 529.8 13.25 579.8 63.24C636.3 119.7 636.3 211.3 579.8 267.7L467.5 380z">
|
d="M172.5 131.1C228.1 75.51 320.5 75.51 376.1 131.1C426.1 181.1 433.5 260.8 392.4 318.3L391.3 319.9C381 334.2 361 337.6 346.7 327.3C332.3 317 328.9 297 339.2 282.7L340.3 281.1C363.2 249 359.6 205.1 331.7 177.2C300.3 145.8 249.2 145.8 217.7 177.2L105.5 289.5C73.99 320.1 73.99 372 105.5 403.5C133.3 431.4 177.3 435 209.3 412.1L210.9 410.1C225.3 400.7 245.3 404 255.5 418.4C265.8 432.8 262.5 452.8 248.1 463.1L246.5 464.2C188.1 505.3 110.2 498.7 60.21 448.8C3.741 392.3 3.741 300.7 60.21 244.3L172.5 131.1zM467.5 380C411 436.5 319.5 436.5 263 380C213 330 206.5 251.2 247.6 193.7L248.7 192.1C258.1 177.8 278.1 174.4 293.3 184.7C307.7 194.1 311.1 214.1 300.8 229.3L299.7 230.9C276.8 262.1 280.4 306.9 308.3 334.8C339.7 366.2 390.8 366.2 422.3 334.8L534.5 222.5C566 191 566 139.1 534.5 108.5C506.7 80.63 462.7 76.99 430.7 99.9L429.1 101C414.7 111.3 394.7 107.1 384.5 93.58C374.2 79.2 377.5 59.21 391.9 48.94L393.5 47.82C451 6.731 529.8 13.25 579.8 63.24C636.3 119.7 636.3 211.3 579.8 267.7L467.5 380z">
|
||||||
</path>
|
</path>
|
||||||
</svg>
|
</svg>
|
||||||
<input v-model="login.address" :placeholder="$t('home_card_address')" class="ss-input" id="sev_address" autocomplete="off">
|
<input v-model="loginInfo.address" :placeholder="$t('home_card_address')"
|
||||||
|
class="ss-input" id="sev_address" autocomplete="off">
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<svg style="padding: 0 2px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
<svg style="padding: 0 2px;" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 448 512">
|
||||||
<path
|
<path
|
||||||
d="M80 192V144C80 64.47 144.5 0 224 0C303.5 0 368 64.47 368 144V192H384C419.3 192 448 220.7 448 256V448C448 483.3 419.3 512 384 512H64C28.65 512 0 483.3 0 448V256C0 220.7 28.65 192 64 192H80zM144 192H304V144C304 99.82 268.2 64 224 64C179.8 64 144 99.82 144 144V192z">
|
d="M80 192V144C80 64.47 144.5 0 224 0C303.5 0 368 64.47 368 144V192H384C419.3 192 448 220.7 448 256V448C448 483.3 419.3 512 384 512H64C28.65 512 0 483.3 0 448V256C0 220.7 28.65 192 64 192H80zM144 192H304V144C304 99.82 268.2 64 224 64C179.8 64 144 99.82 144 144V192z">
|
||||||
</path>
|
</path>
|
||||||
</svg>
|
</svg>
|
||||||
<input v-model="login.token" :placeholder="$t('home_card_key')" class="ss-input" type="password" id="access_token"
|
<input v-model="loginInfo.token" :placeholder="$t('home_card_key')" class="ss-input"
|
||||||
autocomplete="off">
|
type="password" id="access_token" autocomplete="off">
|
||||||
</label>
|
</label>
|
||||||
<div style="display: flex;">
|
<div style="display: flex;">
|
||||||
<label class="default">
|
<label class="default">
|
||||||
|
@ -74,14 +74,15 @@
|
||||||
<a id="save_pwd_note" class="opt-tip login-tip" style="display: none;">
|
<a id="save_pwd_note" class="opt-tip login-tip" style="display: none;">
|
||||||
{{ $t('home_card_tip', { name: $t('name') }) }}
|
{{ $t('home_card_tip', { name: $t('name') }) }}
|
||||||
</a>
|
</a>
|
||||||
<button id="connect_btn" class="ss-button" type="submit">{{ $t('home_card_connect') }}</button>
|
<button id="connect_btn" class="ss-button" type="submit">{{ $t('home_card_connect')
|
||||||
|
}}</button>
|
||||||
</form>
|
</form>
|
||||||
<a href="https://github.com/Stapxs/Stapxs-QQ-Lite/blob/main/README.md#%E4%BD%BF%E7%94%A8" target="_blank"
|
<a href="https://github.com/Stapxs/Stapxs-QQ-Lite/blob/main/README.md#%E4%BD%BF%E7%94%A8"
|
||||||
style="margin-bottom: -20px;">{{ $t('home_card_how_to_connect') }}</a>
|
target="_blank" style="margin-bottom: -20px;">{{ $t('home_card_how_to_connect') }}</a>
|
||||||
<div class="wave-pan" style="margin-left: -30px;">
|
<div class="wave-pan" style="margin-left: -30px;">
|
||||||
<svg id="login-wave" class="waves-svg" xmlns="http://www.w3.org/2000/svg"
|
<svg id="login-wave" class="waves-svg" xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 170 70" preserveAspectRatio="none"
|
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 170 70"
|
||||||
shape-rendering="auto">
|
preserveAspectRatio="none" shape-rendering="auto">
|
||||||
<defs>
|
<defs>
|
||||||
<path id="gentle-wave"
|
<path id="gentle-wave"
|
||||||
d="M -160 44 c 30 0 58 -18 88 -18 s 58 18 88 18 s 58 -18 88 -18 s 58 18 88 18 v 44 h -352 Z">
|
d="M -160 44 c 30 0 58 -18 88 -18 s 58 18 88 18 s 58 -18 88 -18 s 58 18 88 18 v 44 h -352 Z">
|
||||||
|
@ -98,276 +99,242 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="messageTab" :class="login.status ? 'layui-tab-item layui-show' : 'layui-tab-item'">
|
<div id="messageTab" :class="loginInfo.status ? 'layui-tab-item layui-show' : 'layui-tab-item'">
|
||||||
<Messages
|
<!-- <Messages :chat="runtimeData.onChat" @userClick="changeChat" @loadHistory="loadHistory">
|
||||||
:chat="runtimeData.onChat"
|
</Messages> -->
|
||||||
@userClick="changeChat"
|
|
||||||
@loadHistory="loadHistory">
|
|
||||||
</Messages>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-tab-item">
|
<div class="layui-tab-item">
|
||||||
<Friends
|
<Friends
|
||||||
:list="runtimeData.userList === undefined ? [] : runtimeData.userList"
|
:list="runtimeData.userList"
|
||||||
@userClick="changeChat"
|
@loadHistory="loadHistory"
|
||||||
@addMessage="addIn"
|
@userClick="changeChat">
|
||||||
@loadHistory="loadHistory">
|
|
||||||
</Friends>
|
</Friends>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-tab-item">
|
<div class="layui-tab-item">
|
||||||
<Options :config="config" :login="login.status" :uinfo="login"></Options>
|
<Options :config="runtimeData.sysConfig" :info="runtimeData.loginInfo" :status="loginInfo">
|
||||||
|
</Options>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 消息主框体 -->
|
<!-- 消息主框体 -->
|
||||||
<component
|
<!-- "runtimeData.messageList" -->
|
||||||
|
<Chat
|
||||||
ref="chat"
|
ref="chat"
|
||||||
v-if="login.status && runtimeData.onChat !== undefined && runtimeData.onChat.id !== ''"
|
v-if="loginInfo.status && runtimeData.chatInfo !== undefined && runtimeData.chatInfo.show.id !== 0"
|
||||||
v-show="tags.showChat"
|
v-show="tags.showChat"
|
||||||
:is="runtimeData.pageView.chatView"
|
:mumberInfo="runtimeData.chatInfo.info.now_member_info === undefined ? {} : runtimeData.chatInfo.info.now_member_info"
|
||||||
:mergeList="runtimeData.mergeMessageList == undefined ? [] : runtimeData.mergeMessageList"
|
:mergeList="runtimeData.mergeMessageList == undefined ? [] : runtimeData.mergeMessageList"
|
||||||
:mumberInfo="runtimeData.nowMemberInfo === undefined ? {} : runtimeData.nowMemberInfo"
|
:list= runtimeData.messageList
|
||||||
:list="runtimeData.messageList"
|
:chat="runtimeData.chatInfo"></Chat>
|
||||||
:imgView="imgView"
|
|
||||||
:chat="runtimeData.onChat === undefined ? {} : runtimeData.onChat"
|
|
||||||
@hiddenUserInfo="hiddenUserInfo"
|
|
||||||
@cleanMerge="cleanMerge"
|
|
||||||
@viewImg="viewImg"></component>
|
|
||||||
<!-- 提示信息显示区 -->
|
|
||||||
<TransitionGroup class="app-msg" name="appmsg" tag="div">
|
|
||||||
<div v-for="msg in appMsgs" :key="'appmsg-' + msg.id">
|
|
||||||
<div v-html="msg.svg"></div>
|
|
||||||
<a>{{ msg.text }}</a>
|
|
||||||
<div v-if="!msg.autoClose" @click="popInfo.remove(msg.id)">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TransitionGroup>
|
|
||||||
<!-- 图片预览器 -->
|
|
||||||
<Viewer
|
|
||||||
class="viewer" ref="viewer"
|
|
||||||
:options="imgView.options"
|
|
||||||
:images="imgView.srcList"
|
|
||||||
@inited="inited">
|
|
||||||
<template #default="scope">
|
|
||||||
<img v-for="src in scope.images" :src="src[2]" :key="src[1]">
|
|
||||||
{{scope.options}}
|
|
||||||
</template>
|
|
||||||
</Viewer>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import Vue from 'vue'
|
import app from '@/main'
|
||||||
|
import appInfo from '../package.json'
|
||||||
|
import Option from './function/option'
|
||||||
|
|
||||||
import Util from './assets/js/util'
|
import { defineComponent } from 'vue'
|
||||||
import Option from './assets/js/options'
|
import { Connector, login as loginInfo } from './function/connect'
|
||||||
|
import { Logger, PopInfo, PopType } from './function/base'
|
||||||
|
import { runtimeData } from './function/msg'
|
||||||
|
import { BaseChatInfoElem, ChatInfoElem } from './function/elements/information'
|
||||||
|
import { buildMsgIdInfo } from './function/util'
|
||||||
|
|
||||||
import Friends from './pages/friends.vue'
|
import Options from './pages/Options.vue'
|
||||||
import Options from './pages/options.vue'
|
import Friends from './pages/Friends.vue'
|
||||||
import Messages from './pages/messages.vue'
|
import Chat from './pages/Chat.vue'
|
||||||
import { component as Viewer } from 'v-viewer'
|
|
||||||
|
|
||||||
import { logger, popInfo, popList } from './assets/js/base'
|
export default defineComponent({
|
||||||
import { connect as connector, login } from './assets/js/connect'
|
|
||||||
|
|
||||||
import config from '../package.json'
|
|
||||||
import { runtimeData } from './assets/js/msg'
|
|
||||||
|
|
||||||
// import { v4 as uuid } from 'uuid'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'App',
|
name: 'App',
|
||||||
// 应用组件
|
|
||||||
components: {
|
components: {
|
||||||
|
Options,
|
||||||
Friends,
|
Friends,
|
||||||
Messages,
|
Chat
|
||||||
Viewer,
|
|
||||||
Options
|
|
||||||
},
|
},
|
||||||
// 应用全局参数
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
inList: [],
|
loginInfo: loginInfo,
|
||||||
// 图片查看器相关参数
|
|
||||||
imgView: {
|
|
||||||
options: { inline: false, button: false, title: false, toolbar: { prev: true, rotateLeft: true, reset: true, rotateRight: true, next: true } },
|
|
||||||
srcList: []
|
|
||||||
},
|
|
||||||
// 下面的整理好了
|
|
||||||
login: login,
|
|
||||||
popInfo: popInfo,
|
|
||||||
appMsgs: popList,
|
|
||||||
runtimeData: runtimeData,
|
runtimeData: runtimeData,
|
||||||
|
globalData: {} as { [key: string]: any },
|
||||||
tags: {
|
tags: {
|
||||||
showChat: false
|
showChat: false
|
||||||
},
|
}
|
||||||
config: {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发起连接
|
* 发起连接
|
||||||
*/
|
*/
|
||||||
connect: function () {
|
connect() {
|
||||||
connector.create(this.login.address, this.login.token)
|
Connector.create(this.loginInfo.address, this.loginInfo.token)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换聊天
|
* 切换主标签卡判定
|
||||||
* @param { object } data 对象信息
|
* @param name 页面名称
|
||||||
|
* @param view 虚拟路径名称
|
||||||
|
* @param show 是否显示聊天面板
|
||||||
*/
|
*/
|
||||||
changeChat: function (data) {
|
changeTab(name: string, view: string, show: boolean) {
|
||||||
// 设置聊天信息
|
// // GA:发送页面路由统计
|
||||||
this.runtimeData.onChat = {
|
// this.$gtag.pageview({
|
||||||
type: data.type,
|
// page_path: '/' + view,
|
||||||
id: data.id,
|
// page_title: name
|
||||||
name: data.name,
|
// })
|
||||||
avatar: data.avatar,
|
if (!show) {
|
||||||
jump: data.jump,
|
|
||||||
info: {
|
|
||||||
group: {},
|
|
||||||
group_members: [],
|
|
||||||
group_files: {},
|
|
||||||
group_sub_files: {},
|
|
||||||
user: {},
|
|
||||||
me: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 清空合并转发缓存
|
|
||||||
Vue.set(runtimeData, 'mergeMessageList', [])
|
|
||||||
// 重置图片预览器状态
|
|
||||||
Object.assign(this.$data.imgView, this.$options.data().imgView)
|
|
||||||
if (data.type === 'group') {
|
|
||||||
// 获取自己在群内的资料
|
|
||||||
connector.send('get_group_member_info', { group_id: data.id, user_id: this.runtimeData.loginInfo.uin }, 'getUserInfoInGroup')
|
|
||||||
// 获取群成员列表
|
|
||||||
// PS:部分功能不返回用户名需要进来查找所以提前获取
|
|
||||||
connector.send('get_group_member_list', { group_id: data.id }, 'getGroupMemberList')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换主标签卡
|
|
||||||
* @param { string } name 页面名称(用于提交谷歌统计)
|
|
||||||
* @param { string } view view 名称(用于提交谷歌统计)
|
|
||||||
* @param { boolean } info 是否显示聊天页面
|
|
||||||
*/
|
|
||||||
changeTab: function (name, view, info) {
|
|
||||||
// GA:发送页面路由统计
|
|
||||||
this.$gtag.pageview({
|
|
||||||
page_path: '/' + view,
|
|
||||||
page_title: name
|
|
||||||
})
|
|
||||||
if (!info) {
|
|
||||||
this.tags.showChat = true
|
this.tags.showChat = true
|
||||||
} else {
|
} else {
|
||||||
this.tags.showChat = false
|
this.tags.showChat = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 用户列表交互相关
|
/**
|
||||||
addIn: function (data) {
|
* 水波动画启动器
|
||||||
document.getElementById('messageTab').click()
|
* @param wave HTML 对象
|
||||||
this.$refs.inMessage.addMesage(data)
|
* @returns 动画循环器对象
|
||||||
|
*/
|
||||||
|
waveAnimation(wave: HTMLElement | null) {
|
||||||
|
if (wave !== null) {
|
||||||
|
let waves = wave.children[1].children
|
||||||
|
let min = 20
|
||||||
|
let max = 195
|
||||||
|
let add = 1
|
||||||
|
let timer = setInterval(() => {
|
||||||
|
// 遍历波浪体
|
||||||
|
for (var i = 0; i < waves.length; i++) {
|
||||||
|
let now = waves[i].getAttribute('x')
|
||||||
|
if (Number(now) + add > max) {
|
||||||
|
waves[i].setAttribute('x', min.toString())
|
||||||
|
} else {
|
||||||
|
waves[i].setAttribute('x', (Number(now) + add).toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 50)
|
||||||
|
return timer
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 消息相关
|
/**
|
||||||
loadHistory: function (info) {
|
* 切换聊天对象状态
|
||||||
this.messageList = []
|
* @param data 切换信息
|
||||||
if (!Util.loadHistoryMessage(info.id, info.type)) {
|
*/
|
||||||
popInfo.add(popInfo.appMsgType.err, this.$t('pop_load_history_fail'), false)
|
changeChat: function (data: BaseChatInfoElem) {
|
||||||
|
// 设置聊天信息
|
||||||
|
this.runtimeData.chatInfo = {
|
||||||
|
show: data,
|
||||||
|
info: {
|
||||||
|
group_info: {},
|
||||||
|
user_info: {},
|
||||||
|
me_info: {},
|
||||||
|
group_members: [],
|
||||||
|
group_files: {},
|
||||||
|
group_sub_files: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 清空合并转发缓存
|
||||||
|
runtimeData.mergeMessageList = []
|
||||||
|
// 重置图片预览器状态
|
||||||
|
// Object.assign(this.$data.imgView, this.$options.data().imgView)
|
||||||
|
if (data.type === 'group') {
|
||||||
|
// 获取自己在群内的资料
|
||||||
|
Connector.send('get_group_member_info', { group_id: data.id, user_id: this.runtimeData.loginInfo.uin }, 'getUserInfoInGroup')
|
||||||
|
// 获取群成员列表
|
||||||
|
// PS:部分功能不返回用户名需要进来查找所以提前获取
|
||||||
|
Connector.send('get_group_member_list', { group_id: data.id }, 'getGroupMemberList')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cleanMerge: function () {
|
|
||||||
Vue.set(runtimeData, 'mergeMessageList', [])
|
/**
|
||||||
},
|
* 加载历史消息
|
||||||
hiddenUserInfo: function () {
|
* @param info 聊天基本信息
|
||||||
Vue.set(runtimeData, 'nowMemberInfo', {})
|
*/
|
||||||
},
|
loadHistory (info: BaseChatInfoElem) {
|
||||||
// 图片查看器相关
|
runtimeData.messageList = []
|
||||||
inited (viewer) {
|
if (!this.loadHistoryMessage(info.id, info.type)) {
|
||||||
this.$viewer = viewer
|
new PopInfo().add(PopType.ERR, this.$t('pop_load_history_fail'), false)
|
||||||
},
|
|
||||||
viewImg: function (msgId) {
|
|
||||||
// this.$viewer.destroy()
|
|
||||||
// this.$viewer.update()
|
|
||||||
// // 对列表进行排序
|
|
||||||
// this.imgView.srcList.sort(function (a, b) {
|
|
||||||
// if (a[0] < b[0]) return -1
|
|
||||||
// if (a[0] > b[0]) return 1
|
|
||||||
// return 0
|
|
||||||
// })
|
|
||||||
const listGet = this.imgView.srcList
|
|
||||||
let show = null
|
|
||||||
listGet.forEach(function (item, index) {
|
|
||||||
if (item[1] === msgId) {
|
|
||||||
show = index
|
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
if (show !== null) {
|
loadHistoryMessage(id: number, type: string) {
|
||||||
console.log(show)
|
console.log(id + "/" + type)
|
||||||
this.$viewer.view(show)
|
// 加载历史消息
|
||||||
this.$viewer.show()
|
// Note: https://github.com/takayama-lily/oicq/wiki/93.%E8%A7%A3%E6%9E%90%E6%B6%88%E6%81%AFID
|
||||||
|
var msgid = null
|
||||||
|
switch (type) {
|
||||||
|
case 'user': {
|
||||||
|
// friend msg id 为 4*4+1 = 17 bit
|
||||||
|
const buffer = new ArrayBuffer(17)
|
||||||
|
const dv = new DataView(buffer, 0)
|
||||||
|
dv.setInt32(0, id)
|
||||||
|
dv.setInt32(4, 0)
|
||||||
|
dv.setInt32(8, 0)
|
||||||
|
dv.setInt32(12, 0)
|
||||||
|
dv.setInt8(16, 0)
|
||||||
|
msgid = buildMsgIdInfo(buffer)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'group': {
|
||||||
|
// group msg id 为 4*5+1 = 21 bit
|
||||||
|
const buffer = new ArrayBuffer(21)
|
||||||
|
const dv = new DataView(buffer, 0)
|
||||||
|
dv.setInt32(0, id)
|
||||||
|
dv.setInt32(4, 0)
|
||||||
|
dv.setInt32(8, 0)
|
||||||
|
dv.setInt32(12, 0)
|
||||||
|
dv.setInt32(16, 0)
|
||||||
|
dv.setInt8(20, 0)
|
||||||
|
msgid = buildMsgIdInfo(buffer)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (msgid != null) {
|
||||||
|
// 发送请求
|
||||||
|
Connector.send(
|
||||||
|
'get_chat_history',
|
||||||
|
{ 'message_id': msgid },
|
||||||
|
'getChatHistoryFist'
|
||||||
|
)
|
||||||
|
return true
|
||||||
} else {
|
} else {
|
||||||
popInfo.add(popInfo.appMsgType.err, this.$t('pop_find_pic_fail'), false)
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted() {
|
||||||
Vue.configs = {}
|
const logger = new Logger()
|
||||||
Vue.$i18n = this.$i18n
|
|
||||||
Vue.loginInfo = {}
|
|
||||||
// 初始化波浪动画
|
|
||||||
Util.waveAnimation(document.getElementById('login-wave'))
|
|
||||||
// 加载 cookie 中的保存登陆信息
|
|
||||||
if (this.$cookies.isKey('address')) {
|
|
||||||
this.login.address = this.$cookies.get('address')
|
|
||||||
}
|
|
||||||
// 检查版本
|
// 检查版本
|
||||||
var cmp = require('semver-compare')
|
// var cmp = require('semver-compare')
|
||||||
const appVersion = config.version
|
// const appVersion = appInfo.version
|
||||||
const cacheVersion = this.$cookies.get('version')
|
// const cacheVersion = $cookies.get('version')
|
||||||
if (!this.$cookies.isKey('version') || cmp(appVersion, cacheVersion) === 1) {
|
// if (!$cookies.isKey('version') || cmp(appVersion, cacheVersion) === 1) {
|
||||||
// 更新 cookie 中的版本信息并抓取更新日志
|
// // 更新 cookie 中的版本信息并抓取更新日志
|
||||||
this.$cookies.set('version', appVersion, '1m')
|
// $cookies.set('version', appVersion, '1m')
|
||||||
logger.debug(this.$t('version_updated') + ': ' + cacheVersion + ' -> ' + appVersion)
|
// logger.debug(this.$t('version_updated') + ': ' + cacheVersion + ' -> ' + appVersion)
|
||||||
}
|
// }
|
||||||
// 页面加载完成后
|
// 页面加载完成后
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
|
const $cookies = app.config.globalProperties.$cookies
|
||||||
|
|
||||||
|
// 初始化波浪动画
|
||||||
|
this.waveAnimation(document.getElementById('login-wave'))
|
||||||
|
// 加载 cookie 中的保存登陆信息
|
||||||
|
if ($cookies.isKey('address')) {
|
||||||
|
this.loginInfo.address = $cookies.get('address')
|
||||||
|
}
|
||||||
// 加载设置项
|
// 加载设置项
|
||||||
this.$data.config = Option.load()
|
runtimeData.sysConfig = Option.load()
|
||||||
// 初始化完成
|
// 初始化完成
|
||||||
logger.debug(this.$t('log_welcome'))
|
logger.debug(this.$t('log_welcome'))
|
||||||
logger.debug(this.$t('log_runtime') + ': ' + process.env.NODE_ENV)
|
logger.debug(this.$t('log_runtime') + ': ' + process.env.NODE_ENV)
|
||||||
// 加载谷歌统计功能
|
// 加载谷歌统计功能
|
||||||
if (Option.get('close_ga') !== true && process.env.NODE_ENV === 'production') {
|
// if (Option.get('close_ga') !== true && process.env.NODE_ENV === 'production') {
|
||||||
// bootstrap().then(() => {
|
// bootstrap().then(() => {
|
||||||
// logger.debug(this.$t('log_GA_loaded'))
|
// logger.debug(this.$t('log_GA_loaded'))
|
||||||
// })
|
// })
|
||||||
} else if (process.env.NODE_ENV === 'development') {
|
// } else if (process.env.NODE_ENV === 'development') {
|
||||||
logger.debug(this.$t('log_GA_auto_closed'))
|
// logger.debug(this.$t('log_GA_auto_closed'))
|
||||||
}
|
// }
|
||||||
// GA:发送主页页面路由统计(首次打开)
|
|
||||||
this.$gtag.pageview({ page_path: '/Home', page_title: '主页' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.appmsg-move,
|
|
||||||
.appmsg-enter-active,
|
|
||||||
.appmsg-leave-active {
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
.appmsg-leave-active {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.appmsg-enter-from,
|
|
||||||
.appmsg-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(-20px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ textarea {
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child {
|
.chat-pan > div.info {
|
||||||
background: var(--color-card-1);
|
background: var(--color-card-1);
|
||||||
width: calc(100% - 60px);
|
width: calc(100% - 60px);
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
@ -25,41 +25,41 @@ textarea {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child > img {
|
.chat-pan > div.info > img {
|
||||||
border: 2px solid var(--color-card-2);
|
border: 2px solid var(--color-card-2);
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child > div:nth-child(2) p {
|
.chat-pan > div.info > div:nth-child(2) p {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child > div:nth-child(2) span {
|
.chat-pan > div.info > div:nth-child(2) span {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child > div:nth-child(3) {
|
.chat-pan > div.info > div:nth-child(3) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child > div:nth-child(4) {
|
.chat-pan > div.info > div:nth-child(4) {
|
||||||
background: var(--color-card-2);
|
background: var(--color-card-2);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 45px;
|
height: 45px;
|
||||||
width: 45px;
|
width: 45px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:first-child > div:nth-child(4) > svg {
|
.chat-pan > div.info > div:nth-child(4) > svg {
|
||||||
fill: var(--color-main);
|
fill: var(--color-main);
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-pan > div:nth-child(2) {
|
.chat-pan > div.chat {
|
||||||
max-width: calc(100% - 40px);
|
max-width: calc(100% - 40px);
|
||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
@ -70,7 +70,7 @@ textarea {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-pan > div:nth-child(3) {
|
.chat-pan > div.new-msg {
|
||||||
border-right: 7px solid var(--color-card);
|
border-right: 7px solid var(--color-card);
|
||||||
border-radius: 50px 0 0 50px;
|
border-radius: 50px 0 0 50px;
|
||||||
margin: -50px 20px 0 auto;
|
margin: -50px 20px 0 auto;
|
||||||
|
@ -78,7 +78,7 @@ textarea {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(3) > div {
|
.chat-pan > div.new-msg > div {
|
||||||
background: var(--color-card-1);
|
background: var(--color-card-1);
|
||||||
border-radius: 40px;
|
border-radius: 40px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -88,45 +88,45 @@ textarea {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(3) > div > svg {
|
.chat-pan > div.new-msg > div > svg {
|
||||||
fill: var(--color-font);
|
fill: var(--color-font);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
height: 17px;
|
height: 17px;
|
||||||
width: 17px;
|
width: 17px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(3) > div > span {
|
.chat-pan > div.new-msg > div > span {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
margin-left: -5px;
|
margin-left: -5px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) {
|
.chat-pan > div.more {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) {
|
.chat-pan > div.more > div:nth-child(2) {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div {
|
.chat-pan > div.more > div:nth-child(2) > div {
|
||||||
background: var(--color-card-1);
|
background: var(--color-card-1);
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div:first-child {
|
.chat-pan > div.more > div:nth-child(2) > div:first-child {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div:first-child > svg {
|
.chat-pan > div.more > div:nth-child(2) > div:first-child > svg {
|
||||||
fill: var(--color-font-1);
|
fill: var(--color-font-1);
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div:nth-child(2) {
|
.chat-pan > div.more > div:nth-child(2) > div:nth-child(2) {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div > textarea {
|
.chat-pan > div.more > div:nth-child(2) > div > textarea {
|
||||||
padding: 14px 20px 0 20px;
|
padding: 14px 20px 0 20px;
|
||||||
color: var(--color-font);
|
color: var(--color-font);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
@ -139,22 +139,53 @@ textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div > div {
|
.chat-pan > div.more > div:nth-child(2) > div > div {
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div > div:hover {
|
.chat-pan > div.more > div:nth-child(2) > div > div:hover {
|
||||||
background: var(--color-card-2);
|
background: var(--color-card-2);
|
||||||
}
|
}
|
||||||
.chat-pan > div:nth-child(4) > div:nth-child(2) > div svg {
|
.chat-pan > div.more > div:nth-child(2) > div svg {
|
||||||
fill: var(--color-font-1);
|
fill: var(--color-font-1);
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin: 11px;
|
margin: 11px;
|
||||||
}
|
}
|
||||||
|
.chat-pan > div.loading {
|
||||||
|
background: var(--color-card-1);
|
||||||
|
margin: -10px 15px 15px 15px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transition: all .3s;
|
||||||
|
border-radius: 7px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
padding: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
.chat-pan > div.loading.show {
|
||||||
|
height: unset;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes rotate {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
@keyframes rotate {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
.chat-pan > div.loading svg {
|
||||||
|
-webkit-animation: rotate 1.5s linear infinite;
|
||||||
|
animation: rotate 1.5s linear infinite;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-top: 2px;
|
||||||
|
height: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
.more-detail {
|
.more-detail {
|
||||||
transition: height .3s;
|
transition: height .3s;
|
||||||
|
@ -608,6 +639,9 @@ textarea {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
.group-files > div > div > div.main span {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
.group-files > div > div > div.download {
|
.group-files > div > div > div.download {
|
||||||
background: var(--color-card-2);
|
background: var(--color-card-2);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
@ -769,9 +803,9 @@ textarea {
|
||||||
fill: var(--color-font);
|
fill: var(--color-font);
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
}
|
}
|
||||||
.img-sender > div.card > div.sender {
|
/* .img-sender > div.card > div.sender {
|
||||||
|
|
||||||
}
|
} */
|
||||||
.img-sender > div.card > div.sender > input {
|
.img-sender > div.card > div.sender > input {
|
||||||
background: var(--color-card-1);
|
background: var(--color-card-1);
|
||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
|
|
|
@ -29,6 +29,13 @@
|
||||||
.message.merge > div.message-body {
|
.message.merge > div.message-body {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
.message.revoke {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.message.revoke.me {
|
||||||
|
display: flex;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
.message-body a {
|
.message-body a {
|
||||||
color: var(--color-font);
|
color: var(--color-font);
|
||||||
}
|
}
|
||||||
|
@ -408,6 +415,7 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 992px) {
|
@media (max-width: 992px) {
|
||||||
|
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 919 B After Width: | Height: | Size: 919 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1007 B After Width: | Height: | Size: 1007 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 940 B After Width: | Height: | Size: 940 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 959 B After Width: | Height: | Size: 959 B |
Before Width: | Height: | Size: 993 B After Width: | Height: | Size: 993 B |
Before Width: | Height: | Size: 1011 B After Width: | Height: | Size: 1011 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 975 B After Width: | Height: | Size: 975 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 913 B After Width: | Height: | Size: 913 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |