feat: 新增独立窗口打开会话

This commit is contained in:
kuaifan 2025-03-21 00:09:16 +08:00
parent 37f379c890
commit bee36801ab
7 changed files with 108 additions and 19 deletions

View File

@ -109,7 +109,15 @@ if (!isSoftware) {
}
// 加载路由
Vue.prototype.goForward = function(route, isReplace) {
Vue.prototype.goForward = function(route, isReplace, noBroadcast = false) {
if ($A.isSubElectron && !noBroadcast) {
$A.Electron.sendMessage('broadcastCommand', {
channel: 'goForward',
payload: {route, isReplace},
});
$A.Electron.sendMessage('mainWindowActive');
return
}
// 处理路由格式
if (typeof route === 'string') {
if ($A.strExists(route, '/')) {
@ -237,6 +245,9 @@ $A.Electron?.listener('syncDispatch', async ({dispatchId: targetId, action, data
data.__sync__ = true
await store.dispatch(action, data)
})
$A.Electron?.listener('goForward', ({route, isReplace}) => {
$A.goForward(route, isReplace, true)
})
// 绑定截图快捷键
$A.bindScreenshotKey = (data) => {

View File

@ -4,8 +4,8 @@
<div class="dialog-user">
<div class="member-head">
<div class="member-title">{{$L('项目成员')}}<span @click="memberShowAll=!memberShowAll">({{projectData.project_user.length}})</span></div>
<div class="member-open" @click="onMsgOpen" :title="$L('在消息中打开')">
<Icon type="ios-chatbubbles-outline"/>
<div class="member-open" @click="onOpenDialog" :title="$L('独立窗口显示')">
<i class="taskfont open-dialog">&#xe776;</i>
</div>
<div class="member-close" @click="onClose">
<Icon type="ios-close"/>
@ -37,15 +37,6 @@ export default {
return {
loadIng: false,
memberShowAll: false,
beforeDestroyClose: false,
}
},
beforeDestroy() {
if (this.beforeDestroyClose) {
requestAnimationFrame(_ => {
this.$store.dispatch('toggleProjectParameter', 'chat');
})
}
},
@ -58,16 +49,19 @@ export default {
},
methods: {
onMsgOpen() {
this.$store.dispatch("openDialog", this.projectData.dialog_id);
this.goForward({name: 'manage-messenger', params: {dialogAction: 'dialog'}});
this.beforeDestroyClose = true;
onOpenDialog() {
this.$store.dispatch('openDialogWindow', this.projectData.dialog_id);
this.toggleParameter();
},
onClose() {
this.$emit('on-close');
this.toggleParameter();
},
toggleParameter() {
this.$store.dispatch('toggleProjectParameter', 'chat');
}
},
}
}
</script>

View File

@ -194,6 +194,12 @@
<i class="taskfont" v-html="operateItem.silence ? '&#xe7eb;' : '&#xe7d7;'"></i>
</div>
</DropdownItem>
<DropdownItem v-if="$Electron" divided @click.native="handleDialogClick('single')">
<div class="item">
{{ $L('独立窗口显示') }}
<i class="taskfont">&#xe776;</i>
</div>
</DropdownItem>
<DropdownItem @click.native="handleDialogClick('hide')" :disabled="!!operateItem.top_at">
<div class="item">
{{ $L('不显示该会话') }}
@ -1123,6 +1129,10 @@ export default {
});
break;
case 'single':
this.$store.dispatch('openDialogWindow', this.operateItem.id);
break;
case 'hide':
this.$store.dispatch("call", {
url: 'dialog/hide',

View File

@ -0,0 +1,39 @@
<template>
<div class="electron-dialog">
<PageTitle :title="dialogData.name"/>
<DialogWrapper v-if="dialogId > 0" :dialogId="dialogId" :beforeBack="onBeforeClose" location="modal"/>
</div>
</template>
<style lang="scss" scoped>
.electron-dialog {
height: 100%;
display: flex;
flex-direction: column;
}
</style>
<script>
import DialogWrapper from "../manage/components/DialogWrapper.vue";
import {mapState} from "vuex";
export default {
components: {DialogWrapper},
computed: {
...mapState(['cacheDialogs']),
dialogId() {
const {dialogId} = this.$route.params;
return parseInt(/^\d+$/.test(dialogId) ? dialogId : 0);
},
dialogData() {
return this.cacheDialogs.find(({id}) => id === this.dialogId) || {}
}
},
methods: {
onBeforeClose() {
}
}
}
</script>

View File

@ -153,6 +153,11 @@ export default [
path: '/single/task/:taskId',
component: () => import('./pages/single/task.vue'),
},
{
name: 'single-dialog',
path: '/single/dialog/:dialogId',
component: () => import('./pages/single/dialog.vue'),
},
{
name: 'single-apps',
path: '/single/apps/*',

View File

@ -1214,6 +1214,28 @@ export default {
$A.Electron.sendMessage('openWebTabWindow', params)
},
/**
* 打开会话独立窗口客户端
* @param state
* @param dispatch
* @param dialogId
* @returns {Promise<void>}
*/
async openDialogWindow({state, dispatch}, dialogId) {
const dialogData = state.cacheDialogs.find(({id}) => id === dialogId) || {}
dispatch('openChildWindow', {
name: `dialog-${dialogId}`,
path: `/single/dialog/${dialogId}`,
force: false,
config: {
title: dialogData.name,
parent: null,
width: Math.min(window.screen.availWidth, 1024),
height: Math.min(window.screen.availHeight, 768),
},
});
},
/** *****************************************************************************************/
/** ************************************** 文件 **********************************************/
/** *****************************************************************************************/
@ -2992,6 +3014,14 @@ export default {
*/
openDialog({state, dispatch}, dialog_id) {
return new Promise(async (resolve, reject) => {
if ($A.isSubElectron) {
const data = $A.isJson(dialog_id) ? dialog_id : {dialog_id}
$A.syncDispatch("openDialog", data)
$A.Electron.sendMessage('mainWindowActive');
resolve()
return
}
//
let search_msg_id;
let dialog_msg_id;
if ($A.isJson(dialog_id)) {

View File

@ -26,8 +26,8 @@
cursor: pointer;
margin-right: 8px;
.ivu-icon-ios-chatbubbles-outline {
font-size: 22px;
.open-dialog {
font-size: 24px;
}
}
.member-close {