diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index 2411c67c..c2418b53 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -35,6 +35,7 @@ import { import ChatAutoComplete from './autocomplete'; import ChatInputHistory from './history'; import ChatUserFocus from './focus'; +import ChatWatchingFocus from './watching-focus'; import ChatStore from './store'; import Settings from './settings'; import ChatWindow from './window'; @@ -103,7 +104,6 @@ class Chat { this.regexhighlightnicks = null; this.regexhighlightself = null; this.replyusername = null; - this.watchingfocus = false; // An interface to tell the chat to do things via chat commands, or via emit // e.g. control.emit('CONNECT', 'ws://localhost:9001') is essentially chat.cmdCONNECT('ws://localhost:9001') @@ -290,6 +290,7 @@ class Chat { this.windowselect = this.ui.find('#chat-windows-select'); this.inputhistory = new ChatInputHistory(this); this.userfocus = new ChatUserFocus(this, this.css); + this.watchingfocus = new ChatWatchingFocus(this.ui); this.mainwindow = new ChatWindow('main').into(this); this.mutedtimer = new MutedTimer(this); this.chatpoll = new ChatPoll(this); @@ -368,13 +369,6 @@ class Chat { } }); - // Watching focus - this.ui.on('click touch', '#chat-watching-focus-btn', () => { - this.watchingfocus = !this.watchingfocus; - this.ui.toggleClass('watching-focus', this.watchingfocus); - this.ui.find('#chat-watching-focus-btn').toggleClass('active'); - }); - // Chat focus / menu close when clicking on some areas let downinoutput = false; this.output.on('mousedown', () => { diff --git a/assets/chat/js/watching-focus.js b/assets/chat/js/watching-focus.js new file mode 100644 index 00000000..2e069cdb --- /dev/null +++ b/assets/chat/js/watching-focus.js @@ -0,0 +1,76 @@ +/** + * Handles the dimming of chat messages from users not watching the same embedded stream + */ +class ChatWatchingFocus { + constructor(ui) { + this.ui = ui; + + // constant vars + this.watchingFocusClassName = 'watching-focus'; + this.userFocusClassName = 'focus'; + this.observer = new MutationObserver(this.mutationCallback); + + // mutable class vars + this.watchingFocusActive = null; + this.userFocusEnabled = null; + + this.init(); + } + + // Initialize variables & methods + init() { + this.watchingFocusActive = false; + this.userFocusEnabled = this.ui[0].classList.contains( + this.userFocusClassName, + ); + + // Start mutation observer + this.observe(this.ui[0]); + + // Watching focus button action + this.ui.on('click touch', '#chat-watching-focus-btn', () => + this.toggleWatchingFocus(), + ); + } + + observe(element) { + this.observer.observe(element, { attributes: true }); + } + + toggleWatchingFocus() { + this.watchingFocusActive = !this.watchingFocusActive; + this.ui.toggleClass(this.watchingFocusClassName, this.watchingFocusActive); + this.ui.find('#chat-watching-focus-btn').toggleClass('active'); + } + + mutationCallback = (mutationsList) => { + for (const mutation of mutationsList) { + if ( + mutation.type === 'attributes' && + mutation.attributeName === 'class' + ) { + const mutationUserFocusEnabled = mutation.target.classList.contains( + this.userFocusClassName, + ); + + // If focus class has been added or removed, do stuff + if (this.userFocusEnabled !== mutationUserFocusEnabled) { + this.userFocusEnabled = mutationUserFocusEnabled; + + // If 'focus' added to class list, disable 'watching-focus' + // else if 'focus' is removed, toggle 'watching-focus' according to previous boolean value + if (mutationUserFocusEnabled) { + this.ui.removeClass(this.watchingFocusClassName); + } else { + this.ui.toggleClass( + this.watchingFocusClassName, + this.watchingFocusActive, + ); + } + } + } + } + }; +} + +export default ChatWatchingFocus;