perf: 优化全局监听事件

This commit is contained in:
kuaifan 2024-12-12 14:14:51 +08:00
parent 5b02d8008f
commit dbeb9dd561
21 changed files with 90 additions and 127 deletions

View File

@ -39,13 +39,13 @@
"internal-ip": "^6.2.0",
"jquery": "^3.6.4",
"jspdf": "^2.5.1",
"le5le-store": "^1.0.7",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0",
"markdown-it-link-attributes": "^4.0.1",
"mitt": "^3.0.1",
"notification-koro1": "^1.1.1",
"openpgp_hi": "^5.7.0-1",
"photoswipe": "^5.2.8",

View File

@ -50,7 +50,7 @@ import MeetingManager from "./pages/manage/components/MeetingManager";
import DropdownMenu from "./components/DropdownMenu";
import {ctrlPressed} from "./mixins/ctrlPressed";
import {mapState} from "vuex";
import {Store} from "le5le-store";
import emitter from "./store/events";
export default {
mixins: [ctrlPressed],
@ -323,7 +323,7 @@ export default {
// meeting/1234567890/xxxxx
if (/^\/meeting\/\d+\/\S+$/.test(pathname)) {
const meetingId = pathname.split('/')[2];
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'join',
meetingid: meetingId,
meetingdisabled: true,

View File

@ -22,9 +22,9 @@
</template>
<script>
import {Store} from "le5le-store";
import {mapGetters, mapState} from "vuex";
import NetworkException from "../NetworkException";
import emitter from "../../store/events";
export default {
name: "MobileTabbar",
@ -177,7 +177,7 @@ export default {
case 'dialog':
location = {name: 'manage-messenger', params: {dialogAction: 'dialog'}};
if (this.routeName === 'manage-messenger') {
Store.set('clickAgainDialog', true);
emitter.emit('clickAgainDialog', true);
}
break;

View File

@ -42,7 +42,7 @@
<script>
const VMPreview = () => import('./VMEditor/preview');
import axios from "axios";
import {Store} from "le5le-store";
import emitter from "../store/events";
export default {
name: 'RightBottom',
@ -50,7 +50,6 @@ export default {
data() {
return {
loadIng: 0,
subscribe: null,
apiVersion: '',
systemVersion: window.systemInfo.version,
@ -70,9 +69,7 @@ export default {
this.checkVersion()
//
if (this.$Electron) {
this.subscribe = Store.subscribe('updateNotification', _ => {
this.updateShow = true
})
emitter.on('updateNotification', this.onUpdateShow);
this.$Electron.registerMsgListener('updateDownloaded', info => {
this.$store.state.clientNewVersion = info.version
this.updateVersion = info.version;
@ -83,10 +80,7 @@ export default {
},
beforeDestroy() {
if (this.subscribe) {
this.subscribe.unsubscribe();
this.subscribe = null;
}
emitter.off('updateNotification', this.onUpdateShow);
},
watch: {
@ -112,6 +106,10 @@ export default {
},
methods: {
onUpdateShow() {
this.updateShow = true
},
isNotServer() {
let apiHome = $A.getDomain(window.systemInfo.apiUrl)
return this.$isSoftware && (apiHome == "" || apiHome == "public")
@ -224,7 +222,7 @@ export default {
},
useSSOLogin() {
Store.set('useSSOLogin', true);
emitter.emit('useSSOLogin', true);
},
tagVersion(tag) {

View File

@ -21,8 +21,8 @@
</template>
<script>
import {Store} from "le5le-store";
import mixin from './mixin';
import emitter from "../../store/events";
export default {
name: 'UserAvatar',
@ -30,28 +30,16 @@ export default {
data() {
return {
user: null,
subscribe: null
}
},
mounted() {
this.getData();
//
this.subscribe = Store.subscribe('userActive', ({type, data}) => {
if (data.userid == this.userid) {
if (type === 'line') {
this.user && this.$set(this.user, 'online', data.online);
} else {
this.setUser(data)
}
}
});
emitter.on('userActive', this.userActive);
this.$store.state.userAvatar[this._uid] = this.$props;
},
beforeDestroy() {
if (this.subscribe) {
this.subscribe.unsubscribe();
this.subscribe = null;
}
emitter.off('userActive', this.userActive);
if (this.$store.state.userAvatar[this._uid] !== undefined) {
delete this.$store.state.userAvatar[this._uid];
}
@ -146,6 +134,16 @@ export default {
}
},
methods: {
userActive({type, data}) {
if (data.userid == this.userid) {
if (type === 'line') {
this.user && this.$set(this.user, 'online', data.online);
} else {
this.setUser(data)
}
}
},
getData() {
if (!this.$store.state.userId) {
return;

View File

@ -164,9 +164,9 @@
<script>
import {mapState} from "vuex";
import {Store} from "le5le-store";
import {languageList, languageName, setLanguage} from "../language";
import VueQrcode from "@chenfengyuan/vue-qrcode";
import emitter from "../store/events";
export default {
components: {VueQrcode},
@ -200,8 +200,6 @@ export default {
needInvite: false,
subscribe: null,
privacyShow: false,
}
},
@ -218,17 +216,12 @@ export default {
//
this.qrcodeTimer = setInterval(this.qrcodeStatus, 2000);
//
this.subscribe = Store.subscribe('useSSOLogin', () => {
this.inputServerUrl();
});
emitter.on('useSSOLogin', this.inputServerUrl);
},
beforeDestroy() {
clearInterval(this.qrcodeTimer);
if (this.subscribe) {
this.subscribe.unsubscribe();
this.subscribe = null;
}
emitter.off('useSSOLogin', this.inputServerUrl);
},
activated() {

View File

@ -366,7 +366,7 @@ import UserSelect from "../components/UserSelect.vue";
import ImgUpload from "../components/ImgUpload.vue";
import ApproveDetails from "./manage/approve/details.vue";
import notificationKoro from "notification-koro1";
import {Store} from "le5le-store";
import emitter from "../store/events";
export default {
components: {
@ -411,20 +411,15 @@ export default {
},
addTaskShow: false,
addTaskSubscribe: null,
createGroupShow: false,
createGroupData: {},
createGroupLoad: 0,
createGroupSubscribe: null,
exportTaskShow: false,
exportCheckinShow: false,
exportApproveShow: false,
dialogMsgSubscribe: null,
projectKeyValue: '',
projectKeyLoading: 0,
projectSearchShow: false,
@ -453,17 +448,16 @@ export default {
approveDetails: {id: 0},
approveDetailsShow: false,
approveDetailsSubscribe: null,
}
},
mounted() {
this.notificationInit();
//
this.addTaskSubscribe = Store.subscribe('addTask', this.onAddTask);
this.createGroupSubscribe = Store.subscribe('createGroup', this.onCreateGroup);
this.dialogMsgSubscribe = Store.subscribe('dialogMsgPush', this.addDialogMsg);
this.approveDetailsSubscribe = Store.subscribe('approveDetails', this.openApproveDetails);
emitter.on('addTask', this.onAddTask);
emitter.on('createGroup', this.onCreateGroup);
emitter.on('dialogMsgPush', this.addDialogMsg);
emitter.on('approveDetails', this.openApproveDetails);
//
document.addEventListener('keydown', this.shortcutEvent);
},
@ -482,22 +476,10 @@ export default {
},
beforeDestroy() {
if (this.addTaskSubscribe) {
this.addTaskSubscribe.unsubscribe();
this.addTaskSubscribe = null;
}
if (this.createGroupSubscribe) {
this.createGroupSubscribe.unsubscribe();
this.createGroupSubscribe = null;
}
if (this.dialogMsgSubscribe) {
this.dialogMsgSubscribe.unsubscribe();
this.dialogMsgSubscribe = null;
}
if (this.approveDetailsSubscribe) {
this.approveDetailsSubscribe.unsubscribe();
this.approveDetailsSubscribe = null;
}
emitter.off('addTask', this.onAddTask);
emitter.off('createGroup', this.onCreateGroup);
emitter.off('dialogMsgPush', this.addDialogMsg);
emitter.off('approveDetails', this.openApproveDetails);
//
document.removeEventListener('keydown', this.shortcutEvent);
},
@ -818,7 +800,7 @@ export default {
this.workReportShow = true;
return;
case 'version':
Store.set('updateNotification', null);
emitter.emit('updateNotification', null);
return;
case 'clearCache':
$A.IDBSet("clearCache", "handle").then(_ => {
@ -918,14 +900,14 @@ export default {
break;
case 'createMeeting':
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'create',
userids: [this.userId],
});
break;
case 'joinMeeting':
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'join',
});
break;

View File

@ -226,7 +226,7 @@ import SystemMeeting from "./setting/components/SystemMeeting";
import SystemThirdAccess from "./setting/components/SystemThirdAccess";
import SystemEmailSetting from "./setting/components/SystemEmailSetting";
import SystemAppPush from "./setting/components/SystemAppPush";
import { Store } from "le5le-store";
import emitter from "../../store/events";
export default {
components: {
@ -513,13 +513,13 @@ export default {
onMeeting(name) {
switch (name) {
case 'createMeeting':
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'create',
userids: [this.userId],
});
break;
case 'joinMeeting':
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'join',
});
break;

View File

@ -251,7 +251,7 @@ import ImgUpload from "../../../components/ImgUpload";
import ApproveSetting from "./setting";
import ApproveExport from "../components/ApproveExport";
import {mapState} from 'vuex'
import {Store} from "le5le-store";
import emitter from "../../../store/events";
export default {
components: {list, listDetails, DrawerOverlay, ImgUpload, ApproveSetting, ApproveExport},
@ -492,7 +492,7 @@ export default {
})
//
if (window.innerWidth < 426) {
Store.set('approveDetails', item.id);
emitter.emit('approveDetails', item.id);
return;
}
if (window.innerWidth < 1010) {

View File

@ -46,9 +46,9 @@
<script>
import {mapState, mapGetters} from "vuex";
import Calendar from "./components/Calendar";
import {Store} from "le5le-store";
import TaskMenu from "./components/TaskMenu";
import {addLanguage} from "../../language";
import emitter from "../../store/events";
export default {
components: {TaskMenu, Calendar},
@ -309,7 +309,7 @@ export default {
start.format('YYYY-MM-DD HH:mm:ss'),
end.format('YYYY-MM-DD HH:mm:ss')
]).then(times => {
Store.set('addTask', {
emitter.emit('addTask', {
times,
owner: [this.userId],
beforeClose: () => guide.clearGuideElement()

View File

@ -234,7 +234,7 @@ import clickoutside from "../../../../directives/clickoutside";
import longpress from "../../../../directives/longpress";
import {inputLoadAdd, inputLoadIsLast, inputLoadRemove} from "./one";
import {isMarkdownFormat} from "../../../../store/markdown";
import {Store} from "le5le-store";
import emitter from "../../../../store/events";
export default {
name: 'ChatInput',
@ -1312,7 +1312,7 @@ export default {
break;
case 'meeting':
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'create',
dialog_id: this.dialogId,
userids: [this.userId],

View File

@ -174,7 +174,6 @@
<script>
import WCircle from "../../../../components/WCircle";
import {mapGetters, mapState} from "vuex";
import {Store} from "le5le-store";
import longpress from "../../../../directives/longpress";
import TextMsg from "./text.vue";
@ -187,6 +186,7 @@ import VoteMsg from "./vote.vue";
import TemplateMsg from "./template";
import LoadMsg from "./load.vue";
import UnknownMsg from "./unknown.vue";
import emitter from "../../../../store/events";
export default {
name: "DialogView",
@ -470,7 +470,7 @@ export default {
if (this.operateVisible) {
return
}
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'join',
name: this.msgData.msg.name,
meetingid: this.msgData.msg.meetingid,

View File

@ -695,7 +695,6 @@ import DialogRespond from "./DialogRespond";
import ChatInput from "./ChatInput";
import VirtualList from "vue-virtual-scroll-list-hi"
import {Store} from "le5le-store";
import ImgUpload from "../../../components/ImgUpload.vue";
import {choiceEmojiOne} from "./ChatInput/one";
@ -707,6 +706,7 @@ import DialogComplaint from "./DialogComplaint";
import touchclick from "../../../directives/touchclick";
import {languageList} from "../../../language";
import {isLocalResourcePath} from "../../../components/Replace/utils";
import emitter from "../../../store/events";
export default {
name: "DialogWrapper",
@ -1867,7 +1867,7 @@ export default {
//
case "meeting-create":
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'create',
userids: [this.userId],
});
@ -1875,7 +1875,7 @@ export default {
//
case "meeting-join":
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'join',
});
break;
@ -2533,7 +2533,7 @@ export default {
if (this.dialogData.dialog_user && this.userId != this.dialogData.dialog_user.userid) {
userids.push(this.dialogData.dialog_user.userid)
}
Store.set('createGroup', userids);
emitter.emit('createGroup', userids);
break;
case "modifyNormal":
@ -3080,7 +3080,7 @@ export default {
content = content.replace(/<li\s+data-list="checked">/g, `<li class="tox-checklist--checked">`)
content = content.replace(/<li\s+data-list="unchecked">/g, `<li>`)
content = content.replace(/<ol[^>]*>([\s\S]*?)<\/ol>/g, `<ul class="tox-checklist">$1</ul>`)
Store.set('addTask', {owner: [this.userId], content});
emitter.emit('addTask', {owner: [this.userId], content});
break;
case "todo":
@ -3469,7 +3469,7 @@ export default {
break;
}
if (approveElement.classList.contains('open-approve-details')) {
Store.set('approveDetails', approveElement.getAttribute("data-id"));
emitter.emit('approveDetails', approveElement.getAttribute("data-id"));
return;
}
approveElement = approveElement.parentElement;

View File

@ -122,11 +122,11 @@
</template>
<script>
import {Store} from "le5le-store";
import {mapState} from 'vuex'
import MeetingPlayer from "./MeetingPlayer.vue";
import DragBallComponent from "../../../components/DragBallComponent";
import UserSelect from "../../../components/UserSelect.vue";
import emitter from "../../../store/events";
export default {
name: "MeetingManager",
@ -142,7 +142,6 @@ export default {
data() {
return {
loadIng: 0,
subscribe: null,
addShow: false,
addData: {
@ -183,14 +182,11 @@ export default {
},
mounted() {
this.subscribe = Store.subscribe('addMeeting', this.onAdd);
emitter.on('addMeeting', this.onAdd);
},
beforeDestroy() {
if (this.subscribe) {
this.subscribe.unsubscribe();
this.subscribe = null;
}
emitter.off('addMeeting', this.onAdd);
},
watch: {

View File

@ -515,7 +515,6 @@
import Draggable from 'vuedraggable'
import TaskPriority from "./TaskPriority";
import {mapGetters, mapState} from "vuex";
import {Store} from 'le5le-store';
import TaskAddSimple from "./TaskAddSimple";
import TaskRow from "./TaskRow";
import TaskArchived from "./TaskArchived";
@ -532,6 +531,7 @@ import ProjectGantt from "./ProjectGantt";
import UserSelect from "../../../components/UserSelect.vue";
import UserAvatarTip from "../../../components/UserAvatar/tip.vue";
import VMPreviewNostyle from "../../../components/VMEditor/nostyle.vue";
import emitter from "../../../store/events";
export default {
name: "ProjectPanel",
@ -1086,7 +1086,7 @@ export default {
},
addTaskOpen(params) {
Store.set('addTask', params);
emitter.emit('addTask', params);
},
addColumnOpen() {
@ -1408,7 +1408,7 @@ export default {
if (receive === true) {
//
setTimeout(() => {
Store.set('receiveTask', true);
emitter.emit('receiveTask', true);
}, 300)
}
},

View File

@ -559,7 +559,6 @@ import TaskPriority from "./TaskPriority";
import TaskUpload from "./TaskUpload";
import DialogWrapper from "./DialogWrapper";
import ProjectLog from "./ProjectLog";
import {Store} from "le5le-store";
import TaskMenu from "./TaskMenu";
import ChatInput from "./ChatInput";
import UserSelect from "../../../components/UserSelect.vue";
@ -569,6 +568,7 @@ import TaskExistTips from "./TaskExistTips.vue";
import TEditorTask from "../../../components/TEditorTask.vue";
import TaskContentHistory from "./TaskContentHistory.vue";
import TaskTagAdd from "./ProjectTaskTag/add.vue";
import emitter from "../../../store/events";
export default {
name: "TaskDetail",
@ -662,7 +662,6 @@ export default {
dialogDrag: false,
imageAttachment: true,
receiveTaskSubscribe: null,
loops: [
{key: 'never', label: '从不'},
@ -713,18 +712,13 @@ export default {
this.nowTime = $A.dayjs().unix();
}, 1000);
//
this.receiveTaskSubscribe = Store.subscribe('receiveTask', () => {
this.receiveShow = true;
});
emitter.on('receiveTask', this.onReceiveShow);
},
destroyed() {
clearInterval(this.nowInterval);
//
if (this.receiveTaskSubscribe) {
this.receiveTaskSubscribe.unsubscribe();
this.receiveTaskSubscribe = null;
}
emitter.off('receiveTask', this.onReceiveShow);
},
computed: {
@ -1048,6 +1042,10 @@ export default {
},
methods: {
onReceiveShow() {
this.receiveShow = true;
},
within24Hours(date) {
return ($A.dayjs(date).unix() - this.nowTime) < 86400
},

View File

@ -110,8 +110,8 @@
import TaskPriority from "./TaskPriority";
import TaskAddSimple from "./TaskAddSimple";
import {mapState} from "vuex";
import {Store} from "le5le-store";
import TaskMenu from "./TaskMenu";
import emitter from "../../../store/events";
export default {
name: "TaskRow",
@ -250,7 +250,7 @@ export default {
if (receive === true) {
//
setTimeout(() => {
Store.set('receiveTask', true);
emitter.emit('receiveTask', true);
}, 300)
}
},

View File

@ -259,7 +259,7 @@
import {mapState} from "vuex";
import DialogWrapper from "./components/DialogWrapper";
import longpress from "../../directives/longpress";
import {Store} from "le5le-store";
import emitter from "../../store/events";
const navDatas = {
menus: [
@ -304,8 +304,6 @@ export default {
operateStyles: {},
operateVisible: false,
operateType: 'dialog',
clickAgainSubscribe: null,
}
},
@ -323,15 +321,11 @@ export default {
this.openDialog(id)
}
//
this.clickAgainSubscribe = Store.subscribe('clickAgainDialog', this.shakeUnread);
emitter.on('clickAgainDialog', this.shakeUnread);
},
beforeDestroy() {
if (this.clickAgainSubscribe) {
this.clickAgainSubscribe.unsubscribe();
this.clickAgainSubscribe = null;
}
//
emitter.off('clickAgainDialog', this.shakeUnread)
document.removeEventListener('keydown', this.shortcutEvent);
},
@ -550,7 +544,6 @@ export default {
if (id > 0) {
this.openDialog(id)
}
this.clickAgainSubscribe = Store.subscribe('clickAgainDialog', this.shakeUnread);
}
},
immediate: true
@ -1168,12 +1161,12 @@ export default {
userids.push(this.operateItem.userid)
}
if (act === 'meet') {
Store.set('addMeeting', {
emitter.emit('addMeeting', {
type: 'create',
userids,
});
} else {
Store.set('createGroup', userids);
emitter.emit('createGroup', userids);
}
break;

View File

@ -43,9 +43,9 @@
<script>
import {mapState} from "vuex";
import {Store} from "le5le-store";
import axios from "axios";
import MobileNavTitle from "../../../components/Mobile/NavTitle.vue";
import emitter from "../../../store/events";
export default {
components: {MobileNavTitle},
@ -177,7 +177,7 @@ export default {
default:
if (path === 'version' && !!this.clientNewVersion) {
Store.set('updateNotification', null);
emitter.emit('updateNotification', null);
return
}
this.goForward({name: 'manage-setting-' + path});

View File

@ -1,7 +1,7 @@
import {Store} from 'le5le-store';
import * as openpgp from 'openpgp_hi/lightweight';
import {initLanguage, languageList, languageName} from "../language";
import {$callData, $urlSafe, SSEClient} from './utils'
import emitter from "./events";
export default {
/**
@ -663,7 +663,7 @@ export default {
if (temp && time - temp._time <= 30) {
setTimeout(() => {
state.cacheUserActive = Object.assign(temp, {__:Math.random()});
Store.set('userActive', {type: 'cache', data: temp});
emitter.emit('userActive', {type: 'cache', data: temp});
}, timeout += 5);
return false;
}
@ -715,7 +715,7 @@ export default {
state.cacheUserBasic.push(data)
}
state.cacheUserActive = Object.assign(data, {__:Math.random()});
Store.set('userActive', {type: 'cache', data});
emitter.emit('userActive', {type: 'cache', data});
//
$A.IDBSave("cacheUserBasic", state.cacheUserBasic)
},
@ -3738,7 +3738,7 @@ export default {
break
case "line":
Store.set('userActive', {type: 'line', data: msgDetail.data});
emitter.emit('userActive', {type: 'line', data: msgDetail.data});
break
case "msgStream":
@ -3819,7 +3819,7 @@ export default {
}
}
if (!silence) {
Store.set('dialogMsgPush', data);
emitter.emit('dialogMsgPush', data);
}
}
}

5
resources/assets/js/store/events.js vendored Normal file
View File

@ -0,0 +1,5 @@
import mitt from 'mitt';
const emitter = mitt();
export default emitter;