diff --git a/src/components/App.vue b/src/components/App.vue index 3132e1a31..acc2af3a3 100755 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -133,6 +133,7 @@ export default { this.initMediaviewer(); this.configureFavicon(); + this.listen(document, 'visibilitychange', this.onVisibilityChange); this.listen(document, 'keydown', (event) => this.onKeyDown(event)); this.listen(window, 'focus', (event) => this.onFocus(event)); this.listen(window, 'blur', (event) => this.onBlur(event)); @@ -330,12 +331,17 @@ export default { }, onFocus(event) { this.$state.ui.app_has_focus = true; - let buffer = this.$state.getActiveBuffer(); + this.$state.ui.favicon_counter = 0; + }, + onVisibilityChange(event) { + const newState = (document.visibilityState === 'visible'); + + const buffer = this.$state.getActiveBuffer(); if (buffer) { - buffer.markAsRead(true); + buffer.isVisible = newState; } - this.$state.ui.favicon_counter = 0; + this.$state.ui.app_is_visible = newState; }, onKeyDown(event) { this.$state.$emit('document.keydown', event); diff --git a/src/components/ServerView.vue b/src/components/ServerView.vue index 4e5bb3cba..1d0647072 100644 --- a/src/components/ServerView.vue +++ b/src/components/ServerView.vue @@ -52,7 +52,7 @@ export default { ChannelList, }, props: ['network'], - data: function data() { + data() { return { pluginUiElements: GlobalApi.singleton().serverViewPlugins, }; @@ -85,12 +85,18 @@ export default { this.showTab(tabName); }); }, + mounted() { + this.serverBuffer.active_tab = (this.hasMessages) ? 'messages' : 'settings'; + }, methods: { showTab(tabName) { this.$refs.tabs.setActiveByName(tabName); }, tabChanged(tabName) { - this.serverBuffer.show_input = (tabName === 'messages'); + const isMessages = (tabName === 'messages'); + this.serverBuffer.active_tab = tabName; + this.serverBuffer.isVisible = isMessages; + this.serverBuffer.show_input = isMessages; }, }, }; diff --git a/src/libs/state.js b/src/libs/state.js index 04e22cd31..4f6642acf 100644 --- a/src/libs/state.js +++ b/src/libs/state.js @@ -30,6 +30,7 @@ function createNewState() { active_buffer: '', last_active_buffers: [], app_has_focus: true, + app_is_visible: true, app_width: 0, app_height: 0, is_touch: false, @@ -364,35 +365,40 @@ function createNewState() { }, setActiveBuffer(networkid, bufferName) { + if (this.ui.active_network && this.ui.active_buffer) { + const oldBuffer = this.getBufferByName( + this.ui.active_network, + this.ui.active_buffer, + ); + if (oldBuffer) { + oldBuffer.isVisible = false; + } + } + if (!networkid) { this.ui.active_network = 0; this.ui.active_buffer = ''; - } else { - if (this.settings.useBufferHistory && this.ui.active_network) { - // Keep track of last 20 viewed buffers. When closing buffers we can go back - // to one of the previous ones - this.ui.last_active_buffers.push({ - networkid: this.ui.active_network, - bufferName: this.ui.active_buffer, - }); + return; + } - let lastActive = this.ui.last_active_buffers; - this.ui.last_active_buffers = lastActive.splice(lastActive.length - 20); - } + if (this.setting('useBufferHistory') && this.ui.active_network) { + // Keep track of last 20 viewed buffers. When closing buffers we can go back + // to one of the previous ones + this.ui.last_active_buffers.push({ + networkid: this.ui.active_network, + bufferName: this.ui.active_buffer, + }); - this.ui.active_network = networkid; - this.ui.active_buffer = bufferName; + let lastActive = this.ui.last_active_buffers; + this.ui.last_active_buffers = lastActive.splice(lastActive.length - 20); + } - // Clear any unread messages counters for this buffer - let buffer = this.getBufferByName(networkid, bufferName); - if (buffer && buffer.flags.unread) { - buffer.flags.unread = 0; - } + this.ui.active_network = networkid; + this.ui.active_buffer = bufferName; - // Update the buffers last read time - if (buffer) { - buffer.markAsRead(true); - } + let buffer = this.getBufferByName(networkid, bufferName); + if (buffer) { + buffer.isVisible = true; } }, @@ -594,11 +600,6 @@ function createNewState() { includeAsActivity = true; } - let isActiveBuffer = ( - buffer.networkid === this.ui.active_network && - buffer.name === this.ui.active_buffer - ); - let network = buffer.getNetwork(); let isNewMessage = message.time >= buffer.last_read; let isHighlight = !network ? @@ -642,12 +643,17 @@ function createNewState() { bufferMessage.isHighlight = isHighlight; - if (isNewMessage && isActiveBuffer && state.ui.app_has_focus) { + if (isNewMessage && buffer.isVisible) { buffer.last_read = message.time; } // Handle buffer flags - if (isNewMessage && includeAsActivity && !isActiveBuffer && !bufferMessage.ignore) { + if ( + isNewMessage && + includeAsActivity && + !buffer.isVisible && + !bufferMessage.ignore + ) { buffer.incrementFlag('unread'); if (isHighlight) { buffer.flag('highlight', true); @@ -700,7 +706,6 @@ function createNewState() { } if ( - isActiveBuffer && !state.ui.app_has_focus && message.type !== 'traffic' && ( diff --git a/src/libs/state/BufferState.js b/src/libs/state/BufferState.js index d1ba6daf6..fb3f4863b 100644 --- a/src/libs/state/BufferState.js +++ b/src/libs/state/BufferState.js @@ -30,10 +30,12 @@ export default class BufferState { chathistory_available: true, requested_modes: false, requested_banlist: false, + is_visible: false, is_requesting_chathistory: false, }; this.settings = { }; this.last_read = 0; + this.active_tab = null; this.active_timeout = null; this.message_count = 0; this.current_input = ''; @@ -121,6 +123,35 @@ export default class BufferState { this.topics.push(newVal); } + get isVisible() { + return this.flag('is_visible'); + } + + set isVisible(_newVal) { + let newVal = _newVal; + + if (this.active_tab && this.active_tab !== 'messages') { + // Prevent newVal from being true if we are on a tabbed buffer + // and the active tab is not 'messages' + newVal = false; + } + + this.flag('is_visible', newVal); + + if (newVal) { + this.flag('unread', 0); + this.flag('highlight', false); + this.markAsRead(true); + + return; + } + + // Buffer is no longer visible + if (this.active_timeout) { + this.markAsRead(false); + } + } + getNetwork() { return this.state.getNetwork(this.networkid); } @@ -370,7 +401,6 @@ export default class BufferState { ); } else { this.last_read = Date.now(); - this.flag('highlight', false); // If running under a bouncer, set it on the server-side too let network = this.getNetwork();