有的没的.png

 现在在群成员列表里可以直接点击发起会话(前提是群允许发起临时会话)
 消息列表增加了清空按钮
 临时会话的上次消息时间改为了来源群
🐛 重新加载消息列表加载重复
🐛 linux 构建没有图标
This commit is contained in:
stapxs 2023-03-16 13:07:51 +08:00
parent 9a7226bdf2
commit 0bcb326019
18 changed files with 293 additions and 100 deletions

BIN
build/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -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>

View File

@ -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;
}

View File

@ -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%;

View File

@ -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));
}
}

View File

@ -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}"
}

View File

@ -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": "停用通知",

View File

@ -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 + ' )'

View File

@ -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()

View File

@ -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

View File

@ -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
}

View File

@ -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
//

View File

@ -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()
},
/**

View File

@ -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>

View File

@ -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)
}
})
}
}
}
}
})

View File

@ -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

View File

@ -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() {

View File

@ -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 类型