From d9c582bac8ca39aa66325d577c279cc3e35493be Mon Sep 17 00:00:00 2001 From: zyr17 Date: Fri, 5 Jan 2024 00:56:32 +0800 Subject: [PATCH] resolve #27 use notification instead of alert --- package-lock.json | 13 +++++-- package.json | 1 + src/components/App.vue | 75 ++++++++++++++++++++++++++++++++++------- src/components/Deck.vue | 66 +++++++++++++++++++++++++++--------- src/index.js | 2 ++ src/locales/en-US.json | 1 + src/locales/zh-CN.json | 1 + 7 files changed, 130 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d774d9..fae1f70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { "name": "lpsim-frontend", - "version": "0.4.3.1", + "version": "0.4.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "lpsim-frontend", - "version": "0.4.3.1", + "version": "0.4.3.2", "license": "MIT", "dependencies": { "normalize.css": "^8.0.1", "vue": "^2.7.16", "vue-i18n": "^8.28.2", + "vue-notification": "^1.3.20", "vuex": "^3.6.2" }, "devDependencies": { @@ -872,6 +873,14 @@ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.28.2.tgz", "integrity": "sha512-C5GZjs1tYlAqjwymaaCPDjCyGo10ajUphiwA922jKt9n7KPpqR7oM1PCwYzhB/E7+nT3wfdG3oRre5raIT1rKA==" }, + "node_modules/vue-notification": { + "version": "1.3.20", + "resolved": "https://registry.npmjs.org/vue-notification/-/vue-notification-1.3.20.tgz", + "integrity": "sha512-vPj67Ah72p8xvtyVE8emfadqVWguOScAjt6OJDEUdcW5hW189NsqvfkOrctxHUUO9UYl9cTbIkzAEcPnHu+zBQ==", + "peerDependencies": { + "vue": "^2.0.0" + } + }, "node_modules/vuex": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", diff --git a/package.json b/package.json index b896e07..ec333cf 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "normalize.css": "^8.0.1", "vue": "^2.7.16", "vue-i18n": "^8.28.2", + "vue-notification": "^1.3.20", "vuex": "^3.6.2" }, "devDependencies": { diff --git a/src/components/App.vue b/src/components/App.vue index 2b068f2..fba3a87 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -267,6 +267,7 @@ + @@ -361,6 +362,14 @@ export default { window.addEventListener('keydown', this.handleKeyDown); }, methods: { + sendNotify(data) { + // send notify with unlimited time when in backend + if (document.hidden) { + data.duration = -1; + data.title = this.$t('Background message, click to hide') + } + this.$notify(data); + }, getFailFunc(msg, stopServerConnection = false) { function failFunc(err) { this.make_alert(this.$t(msg) + err, err); @@ -399,7 +408,10 @@ export default { console.log('PATCH', patch_message, Object.keys(patch_message.patch).length, 'KEYS'); this.updateLocales(patch_message); this.$store.commit('updateDataByPatch', patch_message); - alert(this.$t('Connected to server.')); + this.sendNotify({ + text: this.$t('Connected to server.'), + type: 'success' + }); this.serverConnected = true; // when successfully connected, start auto refreshing immediately. this.refreshTimeout = setTimeout(() => this.refreshData(), 0); @@ -442,7 +454,10 @@ export default { // before old connect server, this will check room name, and // update room name if it is valid. if (!this.checkRoomName()) { - alert(this.$t('Room name must be 4-12 characters, only contains alphabets, numbers or underscore(_).')); + this.sendNotify({ + text: this.$t('Room name must be 4-12 characters, only contains alphabets, numbers or underscore(_).'), + type: 'error' + }); return; } function postRoomNameSuccess(data) { @@ -450,18 +465,30 @@ export default { let status = data.status; console.log(port, status); if (status == 'failed') { - alert(this.$t('Create room failed. Please check backend output.')); + this.sendNotify({ + text: this.$t('Create room failed. Please check backend output.'), + type: 'error' + }); return; } if (status == 'full') { - alert(this.$t('Room is full. Please try to create new room later or enter existing rooms.')); + this.sendNotify({ + text: this.$t('Room is full. Please try to create new room later or enter existing rooms.'), + type: 'error' + }); return; } if (status == 'exist') { - alert(this.$t('Successfully enter room ') + this.roomName); + this.sendNotify({ + text: this.$t('Successfully enter room ') + this.roomName, + type: 'success' + }); } if (status == 'created') { - alert(this.$t('Successfully create room ') + this.roomName); + this.sendNotify({ + text: this.$t('Successfully create room ') + this.roomName, + type: 'success' + }); } let url = new URL(this.roomServerURL); url.port = port; @@ -483,13 +510,19 @@ export default { if (target_class == 'HTTPRoomServer' && this.roomName == '') { // if is room server, but room name is empty, raise alert. let msg = this.$t('Server is room server, but room name is empty. Please input room name.'); - alert(msg); + this.sendNotify({ + text: msg, + type: 'error' + }); return; } else if (target_class == 'HTTPServer' && this.roomName != '') { // if is match server, but room name is not empty, raise alert. let msg = this.$t('Server is match server, but room name is not empty. Please clear room name.'); - alert(msg); + this.sendNotify({ + text: msg, + type: 'error' + }); return; } if (!obj.info || obj.info.class == 'HTTPServer') { @@ -536,7 +569,10 @@ export default { this.requestData = []; this.processing = false; this.matchUUID = null; - if (make_alert) alert(this.$t('Game reset successfully!')); + if (make_alert) this.sendNotify({ + text: this.$t('Game reset successfully!'), + type: 'success' + }); }, checkVersion(serverURL, callback = undefined) { function versionSuccess(obj) { @@ -549,7 +585,10 @@ export default { version = version.replace(/\.post\d+$/, ''); // ignore post versions if (version != self_version) { let msg = this.$t('Server version is ') + version + this.$t(', but client version is ') + self_version + this.$t('. Client may not work properly.'); - alert(msg); + this.sendNotify({ + text: msg, + type: 'warn' + }); } } if (callback) callback(obj); @@ -643,7 +682,10 @@ export default { }, make_alert(title, data) { console.error(data); - alert(title + this.$t('\nFind detail in console.')); + this.sendNotify({ + text: title + this.$t('\nFind detail in console.'), + type: 'error' + }); clearTimeout(this.refreshTimeout); this.refreshTimeout = null; }, @@ -1184,7 +1226,10 @@ export default { let current_index = this.currentDataIndex; let match = this.matchData[current_index]; if (match.requests.length == 0) { - alert(this.$t('No available action at current index! cannot reset to this index.')); + this.sendNotify({ + text: this.$t('No available action at current index! cannot reset to this index.'), + type: 'error' + }); return; } let userConfirmation = confirm( @@ -2349,4 +2394,10 @@ span { cursor: default; } +#app .vue-notification { + font-size: 1.25vw; + padding: 0.5vw; + margin: 0.3vw; +} + diff --git a/src/components/Deck.vue b/src/components/Deck.vue index c3a8b04..63e06d9 100644 --- a/src/components/Deck.vue +++ b/src/components/Deck.vue @@ -118,6 +118,14 @@ export default { this.selectedVersion = this.availableVersions[this.availableVersions.length - 1]; }, methods: { + sendNotify(data) { + // send notify with unlimited time when in backend + if (document.hidden) { + data.duration = -1; + data.title = this.$t('Background message, click to hide') + } + this.$notify(data); + }, imgSrcError(event) { event.target.style.display = 'none'; @@ -175,12 +183,15 @@ export default { let nearestVersion = this.$store.getters.findNearestVersion(name, this.selectedVersion, this.$i18n.messages['en-US']); if (nearestVersion == null) { let type = name.split('/')[0]; - alert( - this.$t('Version for ', { version: this.selectedVersion }) - + this.$t(type == 'CHARACTOR' ? 'charactor: ' : 'card: ') - + this.$t(name) - + this.$t(' not exist!') - ); + this.sendNotify({ + text: ( + this.$t('Version for ', { version: this.selectedVersion }) + + this.$t(type == 'CHARACTOR' ? 'charactor: ' : 'card: ') + + this.$t(name) + + this.$t(' not exist!') + ), + type: 'error' + }); return; } this.$store.commit('addDeckCard', { @@ -279,7 +290,10 @@ export default { useDeckCode() { // Use the deck code if (this.inputDeckCode.length != 68) { - alert(this.$t('Deck code length should be 68!')); + this.sendNotify({ + text: this.$t('Deck code length should be 68!'), + type: 'error' + }); return; } try { @@ -294,9 +308,16 @@ export default { decks[this.playerIdx] = deckDict; this.$store.commit('setDeck', decks); let message = this.$t('Deck code parsed successfully! Currently not uploaded to server, please upload manually.'); - if (no_version.length > 0) - message += this.$t('\n\nWarning: the following cards/charactors are not available in selected version, they will be ignored:\n') + no_version.map((item) => this.$t(item.type + '/' + item.name)).join(', '); - alert(message); + this.sendNotify({ + text: message, + type: 'success' + }); + if (no_version.length > 0) { + this.sendNotify({ + text: this.$t('\n\nWarning: the following cards/charactors are not available in selected version, they will be ignored:\n') + no_version.map((item) => this.$t(item.type + '/' + item.name)).join(', '), + type: 'warn' + }); + } this.showDeckCodeDiv = false; this.$store.commit('addDeckModifyCounter', null); } @@ -308,7 +329,10 @@ export default { function successFunc(data) { // console.log(data); if (data == 'error') return; - alert(this.$t('Deck uploaded successfully!')); + this.sendNotify({ + text: this.$t('Deck uploaded successfully!'), + type: 'success' + }); // this.$store.commit('setShowDeckDiv', false); this.$store.commit('resetDeckModifyCounter', null); if (callback) callback(); @@ -344,7 +368,10 @@ export default { }, make_alert(title, data) { console.error(data); - alert(title + this.$t('\n\nFind detail in console.')); + this.sendNotify({ + text: title + this.$t('\n\nFind detail in console.'), + type: 'error' + }); }, clearCards() { if (!this.cardModifiable) return; @@ -381,14 +408,20 @@ export default { this.inputDeckCode = ''; } catch (error) { - alert(this.$t('Error in getting deck code. ') + error); + this.sendNotify({ + text: this.$t('Error in getting deck code. ') + error, + type: 'error' + }); throw error; } }, receiveDeckCodeFromServer() { // receive deck code from server and show div if (this.$store.state.deckModifyCounter > 0) { - alert(this.$t('Current deck is modified and not uploaded, please upload the deck before getting the deck code!')); + this.sendNotify({ + text: this.$t('Current deck is modified and not uploaded, please upload the deck before getting the deck code!'), + type: 'warn' + }); return; } const xhr = new XMLHttpRequest(); @@ -400,7 +433,10 @@ export default { this.inputDeckCode = ''; } else { - alert(this.$t('Error in getting deck code. ') + xhr.responseText); + this.sendNotify({ + text: this.$t('Error in getting deck code. ') + xhr.responseText, + type: 'error' + }); } } }; diff --git a/src/index.js b/src/index.js index 15c08d3..9f43608 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,11 @@ import App from './components/App.vue'; import store from './store'; import VueI18n from 'vue-i18n' import i18n_data from './i18n'; +import Notifications from 'vue-notification' Vue.config.productionTip = false; Vue.use(VueI18n); +Vue.use(Notifications); let i18n = new VueI18n(i18n_data); diff --git a/src/locales/en-US.json b/src/locales/en-US.json index a354498..fb59595 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -155,6 +155,7 @@ "Animation frequency (ms):": "Animation speed (ms):", "Error in update match data. ": "Error in update match data. ", " is not equal to current match length ": " is not equal to current match length {n}. ", + "Background message, click to hide": "Background sent message, click to hide", "SKILL_TYPE/NORMAL_ATTACK": "Normal Attack", "SKILL_TYPE/ELEMENTAL_SKILL": "Elemental Skill", diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 5784d02..ad3419d 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -155,6 +155,7 @@ "Animation frequency (ms):": "动画速度(毫秒):", "Error in update match data. ": "更新对战数据时发生错误。", " is not equal to current match length ": " 与当前对战帧数长度 {n} 不相等。", + "Background message, click to hide": "后台发送消息,点击隐藏", "SKILL_TYPE/NORMAL_ATTACK": "普通攻击", "SKILL_TYPE/ELEMENTAL_SKILL": "元素战技",