有的没的.png
✨ 现在在群成员列表里可以直接点击发起会话(前提是群允许发起临时会话) ✨ 消息列表增加了清空按钮 ♿ 临时会话的上次消息时间改为了来源群 🐛 重新加载消息列表加载重复 🐛 linux 构建没有图标
This commit is contained in:
parent
9a7226bdf2
commit
0bcb326019
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
56
src/App.vue
56
src/App.vue
|
@ -1,13 +1,32 @@
|
|||
<template>
|
||||
<div class="top-bar" v-if="runtimeData.sysConfig.opt_no_window">
|
||||
<img src="img/icons/icon.svg">
|
||||
<span>Stapxs QQ Lite</span>
|
||||
<div class="space"></div>
|
||||
<div class="controller">
|
||||
<div @click="controllWin('minimize')" class="min"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M416 256c0 17.7-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg></div>
|
||||
<div @click="controllWin('close')" class="close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"/></svg></div>
|
||||
</div>
|
||||
</div>
|
||||
<TransitionGroup class="top-bar" name="appbar" tag="div" v-if="runtimeData.sysConfig.opt_no_window">
|
||||
<template v-if="runtimeData.sysConfig.opt_no_window_mac_style">
|
||||
<div class="controller mac">
|
||||
<div @click="controllWin('close')" class="close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"/></svg></div>
|
||||
<div @click="controllWin('minimize')" class="min"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M416 256c0 17.7-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg></div>
|
||||
<div @click="controllWin('maximize')" class="min"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg></div>
|
||||
<div @click="flushPage" v-if="process.env.NODE_ENV == 'development'"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M447.5 224H456c13.3 0 24-10.7 24-24V72c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L397.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L311 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8H447.5z"/></svg></div>
|
||||
</div>
|
||||
<span class="mac">
|
||||
Stapxs QQ Lite
|
||||
{{ process.env.NODE_ENV == 'development' ? '(Dev)' : '' }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img src="img/icons/icon.svg">
|
||||
<span>
|
||||
Stapxs QQ Lite
|
||||
{{ process.env.NODE_ENV == 'development' ? '(Dev)' : '' }}
|
||||
</span>
|
||||
<div class="space"></div>
|
||||
<div class="controller">
|
||||
<div @click="flushPage" v-if="process.env.NODE_ENV == 'development'" class="reflush"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M447.5 224H456c13.3 0 24-10.7 24-24V72c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L397.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L311 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8H447.5z"/></svg></div>
|
||||
<div @click="controllWin('minimize')" class="min"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M416 256c0 17.7-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg></div>
|
||||
<div @click="controllWin('maximize')" class="max"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M384 32C419.3 32 448 60.65 448 96V416C448 451.3 419.3 480 384 480H64C28.65 480 0 451.3 0 416V96C0 60.65 28.65 32 64 32H384zM384 80H64C55.16 80 48 87.16 48 96V416C48 424.8 55.16 432 64 432H384C392.8 432 400 424.8 400 416V96C400 87.16 392.8 80 384 80z"/></svg></div>
|
||||
<div @click="controllWin('close')" class="close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"/></svg></div>
|
||||
</div>
|
||||
</template>
|
||||
</TransitionGroup>
|
||||
<div id="base-app">
|
||||
<div class="layui-tab layui-tab-brief main-body">
|
||||
<ul class="layui-tab-title">
|
||||
|
@ -230,6 +249,7 @@ export default defineComponent({
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
process: process,
|
||||
Connector: Connector,
|
||||
defineAsyncComponent: defineAsyncComponent,
|
||||
save: Option.runASWEvent,
|
||||
|
@ -258,6 +278,13 @@ export default defineComponent({
|
|||
reader.send('win:' + name)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 刷新页面
|
||||
*/
|
||||
flushPage() {
|
||||
window.location.reload()
|
||||
},
|
||||
|
||||
/**
|
||||
* 发起连接
|
||||
|
@ -678,4 +705,15 @@ export default defineComponent({
|
|||
transform: translateX(-20px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 标题栏变更动画 */
|
||||
.appbar-enter-active,
|
||||
.appbar-leave-active {
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.appbar-enter-from,
|
||||
.appbar-leave-to {
|
||||
transform: translateY(-60px);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -579,8 +579,7 @@ textarea {
|
|||
border: 0;
|
||||
}
|
||||
.chat-info-tab > li {
|
||||
min-width: unset;
|
||||
width: 50px;
|
||||
min-width: 50px;
|
||||
}
|
||||
.chat-info-tab-member {
|
||||
padding: 0 20px;
|
||||
|
@ -589,6 +588,7 @@ textarea {
|
|||
transition: background .3s;
|
||||
align-items: center;
|
||||
border-radius: 7px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
}
|
||||
|
|
|
@ -425,9 +425,9 @@
|
|||
display: block;
|
||||
}
|
||||
.note-nomsg {
|
||||
margin: 100px auto 40px auto;
|
||||
color: var(--color-font-2);
|
||||
text-align: center;
|
||||
margin: 40px auto;
|
||||
display: block;
|
||||
opacity: 0.5;
|
||||
width: 80%;
|
||||
|
|
|
@ -47,6 +47,12 @@ html, body {
|
|||
.top-bar > div.controller > div.min > svg {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
.top-bar > div.controller > div.max > svg {
|
||||
transform: scale(0.7);
|
||||
}
|
||||
.top-bar > div.controller > div.reflush > svg {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
.top-bar > div.controller > div.close {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
@ -63,6 +69,51 @@ html, body {
|
|||
.top-bar > div.controller > div.close:hover > svg {
|
||||
fill: #fff;
|
||||
}
|
||||
.top-bar > div.controller.mac {
|
||||
align-items: center;
|
||||
}
|
||||
.top-bar > div.controller.mac > div {
|
||||
border-radius: 100%;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
padding: 0;
|
||||
}
|
||||
.top-bar > div.controller.mac > div {
|
||||
align-items: center;
|
||||
margin-right: 4px;
|
||||
margin-left: 5px;
|
||||
display: flex;
|
||||
}
|
||||
.top-bar > div.controller.mac > div {
|
||||
background: var(--color-main);
|
||||
}
|
||||
.top-bar > div.controller.mac > div:nth-child(1) {
|
||||
background: #ff5e57;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.top-bar > div.controller.mac > div:nth-child(2) {
|
||||
background: #febc2e;
|
||||
}
|
||||
.top-bar > div.controller.mac > div:nth-child(3) {
|
||||
background: #25c83f;
|
||||
}
|
||||
.top-bar > div.controller.mac > div > svg {
|
||||
transition: opacity .2s;
|
||||
cursor: pointer;
|
||||
height: 8px;
|
||||
fill: #000;
|
||||
opacity: 0;
|
||||
}
|
||||
.top-bar > div.controller.mac:hover > div > svg {
|
||||
fill: #000 !important;
|
||||
opacity: 1;
|
||||
}
|
||||
.top-bar > span.mac {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#app, #base-app {
|
||||
background-color: var(--color-bg);
|
||||
|
@ -477,7 +528,10 @@ html, body {
|
|||
}
|
||||
.menu > div > a {
|
||||
color: var(--color-font);
|
||||
text-overflow: ellipsis;
|
||||
transition: color .3s;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.menu > div:hover > a {
|
||||
color: var(--color-font-r);
|
||||
|
@ -1111,4 +1165,19 @@ html, body {
|
|||
}
|
||||
.v-leave-to > div.ss-card {
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
@keyframes wordsLoop {
|
||||
0% {
|
||||
transform: translateX(0px);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(0px);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(calc(-100% + 2.35rem));
|
||||
}
|
||||
100% {
|
||||
transform: translateX(calc(-100% + 2.35rem));
|
||||
}
|
||||
}
|
|
@ -109,8 +109,6 @@
|
|||
"option_dev_log_level_err": "错误",
|
||||
"option_dev_log_level_info": "基本",
|
||||
"option_dev_log_level_tip": "ReferenceError: moYu is not defined",
|
||||
"option_dev_msg_menu": "禁用自定义右击菜单",
|
||||
"option_dev_msg_menu_tip": "哼哼啊啊啊啊啊,让我选 ——",
|
||||
"option_dev_notice_all": "通知所有新消息",
|
||||
"option_dev_notice_all_tip": "让暴风雨来得更猛烈些吧!",
|
||||
"option_dev_notice_close": "禁用通知",
|
||||
|
@ -220,9 +218,9 @@
|
|||
"btn_next": "继续",
|
||||
"option_dev_backup": "维护与备份",
|
||||
"option_dev_get_backup": "导出设置项",
|
||||
"option_dev_get_backup_tip": "tar zcvf config.tar.gz /cookies/config",
|
||||
"option_dev_get_backup_tip": "tar zcvf config.tar.gz /localStorage",
|
||||
"option_dev_set_backup": "导入设置项",
|
||||
"option_dev_set_backup_tip": " tar zxvf cache.tar.gz /cookies/config",
|
||||
"option_dev_set_backup_tip": " tar zxvf cache.tar.gz /localStorage",
|
||||
"btn_no": "取消",
|
||||
"import_config_fail": "导入设置项失败",
|
||||
"option_dev_reset": "重置应用",
|
||||
|
@ -287,5 +285,8 @@
|
|||
"chat_fun_menu_file": "文件",
|
||||
"chat_view_file_viewer": "文件预览",
|
||||
"chat_temp": "临时会话",
|
||||
"pop_friend_added": "添加好友 {name} 成功!"
|
||||
"pop_friend_added": "添加好友 {name} 成功!",
|
||||
"option_view_no_window_mac_style": "MacOS 样式标题栏",
|
||||
"option_view_no_window_mac_style_tip": "看!Mac mini(炫耀",
|
||||
"chat_temp_from": "来自群聊:{group}"
|
||||
}
|
|
@ -110,8 +110,6 @@
|
|||
"option_dev_log_level_err": "僅致命錯誤",
|
||||
"option_dev_log_level_info": "基本",
|
||||
"option_dev_log_level_tip": "ReferenceError: moYu is not defined",
|
||||
"option_dev_msg_menu": "停用自訂滑鼠右鍵選單",
|
||||
"option_dev_msg_menu_tip": "哼哼啊啊啊啊啊,讓我選——",
|
||||
"option_dev_notice_all": "通知所有新訊息",
|
||||
"option_dev_notice_all_tip": "讓暴風雨來得更猛烈些吧!",
|
||||
"option_dev_notice_close": "停用通知",
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
d="M8.31 189.9l176-151.1c15.41-13.3 39.69-2.509 39.69 18.16v80.05C384.6 137.9 512 170.1 512 322.3c0 61.44-39.59 122.3-83.34 154.1c-13.66 9.938-33.09-2.531-28.06-18.62c45.34-145-21.5-183.5-176.6-185.8v87.92c0 20.7-24.31 31.45-39.69 18.16l-176-151.1C-2.753 216.6-2.784 199.4 8.31 189.9z">
|
||||
</path>
|
||||
</svg>
|
||||
<a class="msg-unknown"> {{ $t('chat_jump_reply') }} </a>
|
||||
<a class="msg-unknown" style="cursor: pointer;"> {{ $t('chat_jump_reply') }} </a>
|
||||
</div>
|
||||
|
||||
<span v-else class="msg-unknown">{{ '( ' + $t('chat_unsupported_msg') + ': ' + item.type + ' )'
|
||||
|
|
|
@ -17,6 +17,10 @@ export default function regIpcListener() {
|
|||
ipcMain.on('win:minimize', () => {
|
||||
if(win) win.minimize()
|
||||
})
|
||||
// 最大化
|
||||
ipcMain.on('win:maximize', () => {
|
||||
if(win) win.maximize()
|
||||
})
|
||||
// 重启应用
|
||||
ipcMain.on('win:relaunch', () => {
|
||||
app.relaunch()
|
||||
|
|
|
@ -11,17 +11,17 @@
|
|||
*/
|
||||
import qed from '@/assets/qed.txt'
|
||||
|
||||
import { Md5 } from 'ts-md5'
|
||||
import app from '@/main'
|
||||
import Option from './option'
|
||||
import Util from './util'
|
||||
import xss from 'xss'
|
||||
|
||||
import { Md5 } from 'ts-md5'
|
||||
import { reactive, nextTick, markRaw, defineAsyncComponent } from 'vue'
|
||||
import { PopInfo, PopType, Logger, LogType } from './base'
|
||||
import { Connector, login } from './connect'
|
||||
import { GroupMemberInfoElem, UserFriendElem, UserGroupElem, MsgItemElem, RunTimeDataElem, BotMsgType } from './elements/information'
|
||||
import { NotificationElem } from './elements/system'
|
||||
import xss from 'xss'
|
||||
|
||||
const popInfo = new PopInfo()
|
||||
|
||||
|
@ -169,20 +169,15 @@ function saveLoginInfo(data: { [key: string]: any }) {
|
|||
user_id: userId
|
||||
})
|
||||
}
|
||||
// 好友列表
|
||||
Connector.send('get_friend_list', {}, 'getFriendList')
|
||||
// 群列表
|
||||
Connector.send('get_group_list', {}, 'getGroupList')
|
||||
// 系统通知
|
||||
Connector.send('get_system_msg', {}, 'getSystemMsg')
|
||||
// 加载列表消息
|
||||
Util.reloadUsers()
|
||||
}
|
||||
|
||||
function saveUser(list: (UserFriendElem & UserGroupElem)[]) {
|
||||
runtimeData.userList = runtimeData.userList.concat(list)
|
||||
// 刷新置顶列表
|
||||
const info = runtimeData.sysConfig.top_info as { [key: string]: number[] } | null
|
||||
runtimeData.onMsgList = []
|
||||
if (info != null) {
|
||||
if (info != null && runtimeData.onMsgList.length <= 0) {
|
||||
const topList = info[runtimeData.loginInfo.uin]
|
||||
if (topList !== undefined) {
|
||||
list.forEach((item) => {
|
||||
|
@ -563,7 +558,7 @@ function saveMoreFileList(data: any) {
|
|||
|
||||
function newMsg(data: any) {
|
||||
// TODO: 没有对频道的支持计划
|
||||
if(data.message_type == 'guild') {
|
||||
if(data.detail_type == 'guild') {
|
||||
return
|
||||
}
|
||||
// 对消息进行转换
|
||||
|
@ -639,7 +634,7 @@ function newMsg(data: any) {
|
|||
}
|
||||
// 临时会话名字的特殊处理
|
||||
if (data.sub_type === 'group') {
|
||||
data.sender.nickname = app.config.globalProperties.$t('chat_temp') + '(' + data.sender.user_id + ')'
|
||||
data.sender.nickname = data.sender.user_id
|
||||
}
|
||||
// (发送者不是群组 || 群组 AT || 群组 AT 全体 || 打开了通知全部消息) 这些情况需要进行新消息处理
|
||||
if (data.message_type !== 'group' || data.atme || data.atall || Option.get('notice_all') === true) {
|
||||
|
@ -664,28 +659,30 @@ function newMsg(data: any) {
|
|||
}
|
||||
// 如果发送者不在消息列表里,将它添加到消息列表里
|
||||
if (get.length !== 1) {
|
||||
const getList = runtimeData.userList.filter((item) => { return item.user_id === id || item.group_id === id })
|
||||
if (getList.length === 1) {
|
||||
runtimeData.onMsgList.push(getList[0])
|
||||
// 如果消息子类是 group,那么是临时消息,需要进行特殊处理
|
||||
if (data.sub_type === 'group') {
|
||||
// 手动创建一个用户信息,因为临时消息的用户不在用户列表里
|
||||
const user = {
|
||||
user_id: data.user_id,
|
||||
// 因为临时消息没有返回昵称
|
||||
nickname: app.config.globalProperties.$t('chat_temp'),
|
||||
remark: data.sender.user_id,
|
||||
new_msg: true,
|
||||
message_id: data.message_id,
|
||||
raw_msg: data.raw_message,
|
||||
time: data.time,
|
||||
group_id: data.sender.group_id,
|
||||
group_name: ''
|
||||
} as UserFriendElem & UserGroupElem
|
||||
runtimeData.onMsgList.push(user)
|
||||
} else {
|
||||
const getList = runtimeData.userList.filter((item) => { return item.user_id === id || item.group_id === id })
|
||||
if (getList.length === 1) {
|
||||
runtimeData.onMsgList.push(getList[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果消息子类是 group,,那么是临时消息,需要进行特殊处理
|
||||
if (data.sub_type === 'group') {
|
||||
// 手动创建一个用户信息,因为临时消息的用户不在用户列表里
|
||||
const user = {
|
||||
user_id: data.user_id,
|
||||
// 因为临时消息没有返回昵称
|
||||
nickname: data.sender.user_id,
|
||||
remark: app.config.globalProperties.$t('chat_temp'),
|
||||
new_msg: true,
|
||||
message_id: data.message_id,
|
||||
raw_msg: data.raw_message,
|
||||
time: data.time,
|
||||
group_id: data.sender.group_id,
|
||||
group_name: ''
|
||||
} as UserFriendElem & UserGroupElem
|
||||
runtimeData.onMsgList.push(user)
|
||||
}
|
||||
|
||||
runtimeData.onMsgList.forEach((item) => {
|
||||
// 刷新新消息标签
|
||||
if (id !== runtimeData.chatInfo.show.id && (id == item.group_id || id == item.user_id)) {
|
||||
|
@ -762,8 +759,8 @@ function sendNotice(msg: any) {
|
|||
window.focus()
|
||||
// electron:需要让 electron 拉起页面
|
||||
if(runtimeData.tags.isElectron) {
|
||||
const electron = (process.env.IS_ELECTRON as any) === true ? window.require('electron') : null
|
||||
const reader = electron ? electron.ipcRenderer : null
|
||||
const electron = window.require('electron')
|
||||
const reader = electron.ipcRenderer
|
||||
if (reader) {
|
||||
reader.send('win:fouesWindow')
|
||||
}
|
||||
|
@ -857,7 +854,7 @@ function updateSysInfo(type: string) {
|
|||
Connector.send('get_system_msg', {}, 'getSystemMsg')
|
||||
switch(type) {
|
||||
case 'setFriendAdd':
|
||||
Connector.send('get_friend_list', {}, 'getFriendList'); break
|
||||
Util.reloadUsers(); break
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -878,19 +875,15 @@ function addSystemNotice(msg: any) {
|
|||
* @param msg 消息
|
||||
*/
|
||||
function friendNotice(msg: any) {
|
||||
// 重新加载联系人列表
|
||||
Util.reloadUsers();
|
||||
switch(msg.sub_type) {
|
||||
case 'increase': {
|
||||
// 重新加载联系人列表
|
||||
Connector.send('get_friend_list', {}, 'getFriendList')
|
||||
Connector.send('get_group_list', {}, 'getGroupList')
|
||||
// 添加系统通知
|
||||
new PopInfo().add(PopType.INFO, app.config.globalProperties.$t('pop_friend_added', { name: msg.nickname }))
|
||||
break
|
||||
}
|
||||
case 'decrease': {
|
||||
// 重新加载联系人列表
|
||||
Connector.send('get_friend_list', {}, 'getFriendList')
|
||||
Connector.send('get_group_list', {}, 'getGroupList')
|
||||
// 输出日志(显示为红色字体)
|
||||
console.log('%c消失了一个好友:' + msg.nickname + '(' + msg.user_id + ')', 'color:red;')
|
||||
break
|
||||
|
|
|
@ -725,6 +725,16 @@ export function hslToRgb(h: number, s: number, l: number) {
|
|||
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载用户列表
|
||||
*/
|
||||
export function reloadUsers() {
|
||||
runtimeData.userList = []
|
||||
Connector.send('get_friend_list', {}, 'getFriendList')
|
||||
Connector.send('get_group_list', {}, 'getGroupList')
|
||||
Connector.send('get_system_msg', {}, 'getSystemMsg')
|
||||
}
|
||||
|
||||
export default {
|
||||
openLink,
|
||||
getTrueLang,
|
||||
|
@ -739,5 +749,6 @@ export default {
|
|||
gitmojiToEmoji,
|
||||
randomNum,
|
||||
downloadFile,
|
||||
getSizeFromBytes
|
||||
getSizeFromBytes,
|
||||
reloadUsers
|
||||
}
|
|
@ -19,7 +19,10 @@
|
|||
<img :src="chat.show.avatar">
|
||||
<div>
|
||||
<p>{{ chat.show.name }}</p>
|
||||
<span>
|
||||
<span v-if="chat.show.temp">
|
||||
{{ $t('chat_temp_from', { group: chat.show.temp }) }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ list[list.length - 1] ? $t('chat_last_msg', {
|
||||
time: Intl.DateTimeFormat(trueLang,
|
||||
{ hour: "numeric", minute: "numeric", second: "numeric" }).format(new Date(list[list.length - 1].time *
|
||||
|
@ -471,7 +474,7 @@ export default defineComponent({
|
|||
this.loadMoreHistory()
|
||||
}
|
||||
// 底部
|
||||
if (body.scrollTop + body.clientHeight === body.scrollHeight) {
|
||||
if (body.scrollTop + body.clientHeight >= body.scrollHeight) {
|
||||
this.NewMsgNum = 0
|
||||
this.tags.showBottomButton = false
|
||||
// 去除阴影
|
||||
|
|
|
@ -76,6 +76,7 @@ import { UserGroupElem } from '@/function/elements/information'
|
|||
|
||||
import { Connector } from '@/function/connect'
|
||||
import { runtimeData } from '@/function/msg'
|
||||
import { reloadUsers } from '@/function/util'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ViewFriends',
|
||||
|
@ -167,9 +168,7 @@ export default defineComponent({
|
|||
* 重新加载联系人列表
|
||||
*/
|
||||
reloadUser () {
|
||||
Connector.send('get_friend_list', {}, 'getFriendList')
|
||||
Connector.send('get_group_list', {}, 'getGroupList')
|
||||
Connector.send('get_system_msg', {}, 'getSystemMsg')
|
||||
reloadUsers()
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,13 +49,13 @@
|
|||
{{ item.tag }}
|
||||
</div>
|
||||
</div>
|
||||
<header v-if="chat.info.group_info.gAdmins !== undefined">
|
||||
<!-- <header v-if="chat.info.group_info.gAdmins !== undefined">
|
||||
<span>{{ $t('chat_member_type_admin') }}</span>
|
||||
</header>
|
||||
<div class="admin" v-if="chat.info.group_info.gAdmins !== undefined">
|
||||
<img v-for="(item, index) in chat.info.group_info.gAdmins" :key="'chatinfoadmin-' + item"
|
||||
:src="`https://q1.qlogo.cn/g?b=qq&s=0&nk=${item}`" :title="chat.info.group_info.ns[index]">
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div v-else-if="chat.show.type === 'user'">
|
||||
<header>
|
||||
|
@ -86,10 +86,13 @@
|
|||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<header>
|
||||
<span>{{ $t('chat_chat_info_config') }}</span>
|
||||
</header>
|
||||
<OptInfo :type="'number'" :chat="chat"></OptInfo>
|
||||
<template v-if="!chat.show.temp">
|
||||
<!-- 临时会话没有这个板块 -->
|
||||
<header>
|
||||
<span>{{ $t('chat_chat_info_config') }}</span>
|
||||
</header>
|
||||
<OptInfo :type="'number'" :chat="chat"></OptInfo>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="chat.show.type === 'group'" class="layui-tab layui-tab-brief"
|
||||
|
@ -102,7 +105,7 @@
|
|||
</ul>
|
||||
<div class="chat-info-tab-body layui-tab-content">
|
||||
<div class="layui-tab-item layui-show chat-info-tab-member">
|
||||
<div v-for="item in chat.info.group_members" :key="'chatinfomlist-' + item.user_id">
|
||||
<div @click="startChat(item)" v-for="item in chat.info.group_members" :key="'chatinfomlist-' + item.user_id">
|
||||
<img loading="lazy" :src="`https://q1.qlogo.cn/g?b=qq&s=0&nk=${item.user_id}`">
|
||||
<div>
|
||||
<a>{{ item.nickname }}</a>
|
||||
|
@ -152,14 +155,15 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import app from '@/main'
|
||||
import BulletinBody from '@/components/BulletinBody.vue'
|
||||
import FileBody from '@/components/FileBody.vue'
|
||||
import OptInfo from './options/OptInfo.vue'
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import { getTrueLang } from '@/function/util'
|
||||
import { runtimeData } from '@/function/msg'
|
||||
import OptInfo from './options/OptInfo.vue'
|
||||
import { UserFriendElem, UserGroupElem } from '@/function/elements/information'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ViewInfo',
|
||||
|
@ -186,7 +190,51 @@ export default defineComponent({
|
|||
*/
|
||||
fileLoad(event: Event) {
|
||||
this.$emit('loadFile', event)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 发起聊天
|
||||
*/
|
||||
startChat(info: any) {
|
||||
// 如果是自己的话就忽略
|
||||
if (info.user_id != runtimeData.loginInfo.uin) {
|
||||
// 检查这个人是否已经在聊天列表中
|
||||
let chat = runtimeData.onMsgList.find((item: UserFriendElem & UserGroupElem) => {
|
||||
return item.user_id == info.user_id
|
||||
})
|
||||
if(!chat) {
|
||||
// 检查这个人是不是好友
|
||||
let friend = runtimeData.userList.find((item: UserFriendElem & UserGroupElem) => {
|
||||
return item.user_id == info.user_id
|
||||
})
|
||||
if(friend) {
|
||||
runtimeData.onMsgList.push(friend)
|
||||
chat = friend
|
||||
} else {
|
||||
// 创建一个临时聊天
|
||||
const user = {
|
||||
user_id: info.user_id,
|
||||
// 因为临时消息没有返回昵称
|
||||
nickname: app.config.globalProperties.$t('chat_temp'),
|
||||
remark: info.user_id,
|
||||
group_id: info.group_id,
|
||||
group_name: ''
|
||||
} as UserFriendElem & UserGroupElem
|
||||
runtimeData.onMsgList.push(user)
|
||||
chat = user
|
||||
}
|
||||
}
|
||||
// 切换到这个聊天
|
||||
this.$nextTick(() => {
|
||||
if(chat) {
|
||||
const item = document.getElementById('user-' + chat.user_id)
|
||||
if(item) {
|
||||
item.click()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
<div>
|
||||
<div class="base only">
|
||||
<span>{{ $t('message_title') }}</span>
|
||||
<div style="flex: 1;"></div>
|
||||
<svg @click="cleanList" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M170.5 51.6L151.5 80h145l-19-28.4c-1.5-2.2-4-3.6-6.7-3.6H177.1c-2.7 0-5.2 1.3-6.7 3.6zm147-26.6L354.2 80H368h48 8c13.3 0 24 10.7 24 24s-10.7 24-24 24h-8V432c0 44.2-35.8 80-80 80H112c-44.2 0-80-35.8-80-80V128H24c-13.3 0-24-10.7-24-24S10.7 80 24 80h8H80 93.8l36.7-55.1C140.9 9.4 158.4 0 177.1 0h93.7c18.7 0 36.2 9.4 46.6 24.9zM80 128V432c0 17.7 14.3 32 32 32H336c17.7 0 32-14.3 32-32V128H80zm80 64V400c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16s16 7.2 16 16zm80 0V400c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16s16 7.2 16 16zm80 0V400c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16s16 7.2 16 16z"/></svg>
|
||||
</div>
|
||||
<div class="small">
|
||||
<span v-show="runtimeData.tags.openSideBar">{{ $t('message_title') }}</span>
|
||||
|
@ -36,7 +38,7 @@
|
|||
<!-- 其他消息 -->
|
||||
<FriendBody v-for="item in runtimeData.onMsgList"
|
||||
:key="'inMessage-' + item.user_id ? item.user_id : item.group_id"
|
||||
:select="chat.show.id === item.user_id || chat.show.id === item.group_id" :data="item"
|
||||
:select="chat.show.id === item.user_id || (chat.show.id === item.group_id && chat.group_name != '')" :data="item"
|
||||
@click="userClick(item)" @contextmenu.prevent="readMsg(item)" @touchstart="readStart"
|
||||
@touchend="readEnd(item)">
|
||||
</FriendBody>
|
||||
|
@ -174,6 +176,27 @@ export default defineComponent({
|
|||
if (this.trRead) {
|
||||
this.readMsg(data)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 清空消息列表
|
||||
*/
|
||||
cleanList() {
|
||||
// 刷新置顶列表
|
||||
const info = runtimeData.sysConfig.top_info as { [key: string]: number[] } | null
|
||||
runtimeData.onMsgList = []
|
||||
if (info != null) {
|
||||
const topList = info[runtimeData.loginInfo.uin]
|
||||
if (topList !== undefined) {
|
||||
runtimeData.userList.forEach((item) => {
|
||||
const id = Number(item.user_id ? item.user_id : item.group_id)
|
||||
if (topList.indexOf(id) >= 0) {
|
||||
item.always_top = true
|
||||
runtimeData.onMsgList.push(item)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -25,22 +25,6 @@
|
|||
<option value="all">{{ $t('option_dev_log_level_all') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="opt-item">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path
|
||||
d="M384 480c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0zM224 352c-6.7 0-13-2.8-17.6-7.7l-104-112c-6.5-7-8.2-17.2-4.4-25.9s12.5-14.4 22-14.4l208 0c9.5 0 18.2 5.7 22 14.4s2.1 18.9-4.4 25.9l-104 112c-4.5 4.9-10.9 7.7-17.6 7.7z" />
|
||||
</svg>
|
||||
<div>
|
||||
<span>{{ $t('option_dev_msg_menu') }}</span>
|
||||
<span>{{ $t('option_dev_msg_menu_tip') }}</span>
|
||||
</div>
|
||||
<label class="ss-switch">
|
||||
<input type="checkbox" @change="save" name="msg_menu" v-model="runtimeData.sysConfig.msg_menu">
|
||||
<div>
|
||||
<div></div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="opt-item">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512">
|
||||
<path
|
||||
|
|
|
@ -173,13 +173,30 @@
|
|||
<span>{{ $t('option_view_no_window_tip') }}</span>
|
||||
</div>
|
||||
<label class="ss-switch">
|
||||
<input type="checkbox" @change="save" name="opt_no_window"
|
||||
<input type="checkbox" @change="save($event);restartapp()" name="opt_no_window"
|
||||
v-model="runtimeData.sysConfig.opt_no_window">
|
||||
<div>
|
||||
<div></div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<template v-if="runtimeData.sysConfig.opt_no_window && browser.os && browser.os.toLowerCase().indexOf('windows') < 0">
|
||||
<!-- 特别针对 Windows,诶我就是不给用 -->
|
||||
<div class="opt-item">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zm0-160c-53 0-96-43-96-96s43-96 96-96s96 43 96 96s-43 96-96 96z"/></svg>
|
||||
<div>
|
||||
<span>{{ $t('option_view_no_window_mac_style') }}</span>
|
||||
<span>{{ $t('option_view_no_window_mac_style_tip') }}</span>
|
||||
</div>
|
||||
<label class="ss-switch">
|
||||
<input type="checkbox" @change="save($event)" name="opt_no_window_mac_style"
|
||||
v-model="runtimeData.sysConfig.opt_no_window_mac_style">
|
||||
<div>
|
||||
<div></div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -217,6 +234,14 @@ export default defineComponent({
|
|||
setInitialScaleShow(event: Event) {
|
||||
const sender = event.target as HTMLInputElement
|
||||
this.initialScaleShow = Number(sender.value)
|
||||
},
|
||||
|
||||
restartapp() {
|
||||
const electron = (process.env.IS_ELECTRON as any) === true ? window.require('electron') : null
|
||||
const reader = electron ? electron.ipcRenderer : null
|
||||
if (reader) {
|
||||
reader.send('win:relaunch')
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -70,18 +70,15 @@ module.exports = {
|
|||
appId: 'com.stapxs.qq-web',
|
||||
productName: 'Stapxs QQ Lite',
|
||||
copyright: 'Copyright © 2022-2023 Stapx Steve [林槐]',
|
||||
icon: 'public/img/icons/icon.png',
|
||||
|
||||
directories: {
|
||||
output: 'dist_electron/out',
|
||||
|
||||
output: 'dist_electron/out'
|
||||
},
|
||||
|
||||
linux: {
|
||||
target: process.env.NODEJS_ENV === 'github-actions' ? ['AppImage', 'tar.gz'] : 'pacman',
|
||||
maintainer: 'Stapx Steve [林槐]',
|
||||
vendor: 'Stapxs Steve Team',
|
||||
icon: 'public/img/icons/icon.png',
|
||||
synopsis: '一个兼容 oicq-http 的非官方网页版 QQ 客户端。',
|
||||
category: 'Network',
|
||||
// TODO: 将来可能需要占用 QQ 自己的 MIME 类型
|
||||
|
|
Loading…
Reference in New Issue