diff --git a/files_wcf/js/Bastelstu.be/Chat.js b/files_wcf/js/Bastelstu.be/Chat.js index 12fe7f8..4f4d05e 100644 --- a/files_wcf/js/Bastelstu.be/Chat.js +++ b/files_wcf/js/Bastelstu.be/Chat.js @@ -11,54 +11,85 @@ * or later of the General Public License. */ -define([ './Chat/console' - , 'Bastelstu.be/bottle' - , 'Bastelstu.be/_Push' - , 'WoltLabSuite/Core/Core' - , 'WoltLabSuite/Core/Language' - , 'WoltLabSuite/Core/Timer/Repeating' - , 'WoltLabSuite/Core/User' - , './Chat/Autocompleter' - , './Chat/CommandHandler' - , './Chat/DataStructure/Throttle' - , './Chat/Message' - , './Chat/Messenger' - , './Chat/ParseError' - , './Chat/ProfileStore' - , './Chat/Room' - , './Chat/Template' - , './Chat/Ui/Attachment/Upload' - , './Chat/Ui/AutoAway' - , './Chat/Ui/Chat' - , './Chat/Ui/ConnectionWarning' - , './Chat/Ui/ErrorDialog' - , './Chat/Ui/Input' - , './Chat/Ui/Input/Autocompleter' - , './Chat/Ui/MessageStream' - , './Chat/Ui/MessageActions/Delete' - , './Chat/Ui/Mobile' - , './Chat/Ui/Notification' - , './Chat/Ui/ReadMarker' - , './Chat/Ui/Settings' - , './Chat/Ui/Topic' - , './Chat/Ui/UserActionDropdownHandler' - , './Chat/Ui/UserList' - ], function (console, Bottle, Push, Core, Language, RepeatingTimer, CoreUser, Autocompleter, - CommandHandler, Throttle, Message, Messenger, ParseError, ProfileStore, Room, Template, UiAttachmentUpload, UiAutoAway, Ui, - UiConnectionWarning, ErrorDialog, UiInput, UiInputAutocompleter, UiMessageStream, UiMessageActionDelete, UiMobile, UiNotification, - UiReadMarker, UiSettings, UiTopic, UiUserActionDropdownHandler, UiUserList) { - "use strict"; +define([ + './Chat/console', + 'Bastelstu.be/bottle', + 'Bastelstu.be/_Push', + 'WoltLabSuite/Core/Core', + 'WoltLabSuite/Core/Language', + 'WoltLabSuite/Core/Timer/Repeating', + 'WoltLabSuite/Core/User', + './Chat/Autocompleter', + './Chat/CommandHandler', + './Chat/DataStructure/Throttle', + './Chat/Message', + './Chat/Messenger', + './Chat/ParseError', + './Chat/ProfileStore', + './Chat/Room', + './Chat/Template', + './Chat/Ui/Attachment/Upload', + './Chat/Ui/AutoAway', + './Chat/Ui/Chat', + './Chat/Ui/ConnectionWarning', + './Chat/Ui/ErrorDialog', + './Chat/Ui/Input', + './Chat/Ui/Input/Autocompleter', + './Chat/Ui/MessageStream', + './Chat/Ui/MessageActions/Delete', + './Chat/Ui/Mobile', + './Chat/Ui/Notification', + './Chat/Ui/ReadMarker', + './Chat/Ui/Settings', + './Chat/Ui/Topic', + './Chat/Ui/UserActionDropdownHandler', + './Chat/Ui/UserList', +], function ( + console, + Bottle, + Push, + Core, + Language, + RepeatingTimer, + CoreUser, + Autocompleter, + CommandHandler, + Throttle, + Message, + Messenger, + ParseError, + ProfileStore, + Room, + Template, + UiAttachmentUpload, + UiAutoAway, + Ui, + UiConnectionWarning, + ErrorDialog, + UiInput, + UiInputAutocompleter, + UiMessageStream, + UiMessageActionDelete, + UiMobile, + UiNotification, + UiReadMarker, + UiSettings, + UiTopic, + UiUserActionDropdownHandler, + UiUserList +) { + 'use strict' class Chat { constructor(roomID, config) { console.debug('Chat.constructor', 'Constructing …') - this.config = config + this.config = config - this.sessionID = Core.getUuid() + this.sessionID = Core.getUuid() // Setup Bottle containers - this.bottle = new Bottle() + this.bottle = new Bottle() this.bottle.value('bottle', this.bottle) this.bottle.value('config', config) this.bottle.constant('sessionID', this.sessionID) @@ -94,79 +125,105 @@ define([ './Chat/console' }) // Register Templates - const selector = [ '[type="x-text/template"]' - , '[data-application="be.bastelstu.chat"]' - , '[data-template-name]' - ].join('') + const selector = [ + '[type="x-text/template"]', + '[data-application="be.bastelstu.chat"]', + '[data-template-name]', + ].join('') const templates = elBySelAll(selector) - Array.prototype.forEach.call(templates, (function (template) { - this.bottle.factory(`Template.${template.dataset.templateName}`, function (container) { - const includeNames = (template.dataset.templateIncludes || '').split(/ /).filter(item => item !== "") - const includes = { } - includeNames.forEach(item => includes[item] = container[item]) + Array.prototype.forEach.call( + templates, + function (template) { + this.bottle.factory( + `Template.${template.dataset.templateName}`, + function (container) { + const includeNames = (template.dataset.templateIncludes || '') + .split(/ /) + .filter((item) => item !== '') + const includes = {} + includeNames.forEach((item) => (includes[item] = container[item])) - return new Template(template.textContent, includes) - }) - }).bind(this)) + return new Template(template.textContent, includes) + } + ) + }.bind(this) + ) // Register MessageTypes - Object.entries(this.config.messageTypes) - .forEach(([ objectType, messageType ]) => { - const MessageType = require(messageType.module) + Object.entries(this.config.messageTypes).forEach( + ([objectType, messageType]) => { + const MessageType = require(messageType.module) - this.bottle.factory(`MessageType.${objectType.replace(/\./g, '-')}`, _ => { - const deps = this.bottle.digest(MessageType.DEPENDENCIES || []) + this.bottle.factory( + `MessageType.${objectType.replace(/\./g, '-')}`, + (_) => { + const deps = this.bottle.digest(MessageType.DEPENDENCIES || []) - return new MessageType(...deps, objectType) - }) - }) + return new MessageType(...deps, objectType) + } + ) + } + ) // Register Commands - Object.values(this.config.commands).forEach(command => { + Object.values(this.config.commands).forEach((command) => { const Command = require(command.module) - this.bottle.factory(`Command.${command.package.replace(/\./g, '-')}:${command.identifier}`, _ => { - const deps = this.bottle.digest(Command.DEPENDENCIES || []) + this.bottle.factory( + `Command.${command.package.replace(/\./g, '-')}:${ + command.identifier + }`, + (_) => { + const deps = this.bottle.digest(Command.DEPENDENCIES || []) - return new Command(...deps, command) - }) + return new Command(...deps, command) + } + ) }) - this.bottle.constant('Trigger', new Map(Object.entries(this.config.triggers).map(([ trigger, commandID ]) => { - const command = this.config.commands[commandID] - const key = [ command.package, command.identifier ] - return [ trigger, key ] - }))) + this.bottle.constant( + 'Trigger', + new Map( + Object.entries(this.config.triggers).map(([trigger, commandID]) => { + const command = this.config.commands[commandID] + const key = [command.package, command.identifier] + return [trigger, key] + }) + ) + ) // Register Settings - Array.from(elBySelAll('#chatQuickSettingsNavigation .button[data-module]')).forEach(item => { + Array.from( + elBySelAll('#chatQuickSettingsNavigation .button[data-module]') + ).forEach((item) => { const Button = require(item.dataset.module) - this.bottle.instanceFactory(`UiSettingsButton.${item.dataset.module.replace(/\./g, '-')}`, (_, element) => { - const deps = this.bottle.digest(Button.DEPENDENCIES || []) - return new Button(element, ...deps) - }) + this.bottle.instanceFactory( + `UiSettingsButton.${item.dataset.module.replace(/\./g, '-')}`, + (_, element) => { + const deps = this.bottle.digest(Button.DEPENDENCIES || []) + return new Button(element, ...deps) + } + ) }) - this.knows = { from: undefined - , to: undefined - } + this.knows = { from: undefined, to: undefined } this.processMessagesThrottled = Throttle(this.processMessages.bind(this)) - this.queuedMessages = [ ] + this.queuedMessages = [] this.messageSinks = new Set() - this.pullTimer = undefined + this.pullTimer = undefined this.pullUserListTimer = undefined - this.pushConnected = false + this.pushConnected = false this.firstFailure = null } - service(name, _constructor, args = [ ]) { - this.bottle.factory(name, _ => { - const deps = this.bottle.digest(_constructor.DEPENDENCIES || [ ]) + service(name, _constructor, args = []) { + this.bottle.factory(name, (_) => { + const deps = this.bottle.digest(_constructor.DEPENDENCIES || []) return new _constructor(...deps, ...args) }) @@ -187,42 +244,58 @@ define([ './Chat/console' await this.bottle.container.Room.join() // Bind unload event to leave the Chat - window.addEventListener('unload', this.bottle.container.Room.leave.bind(this.bottle.container.Room, true)) - document.addEventListener('visibilitychange', _ => { + window.addEventListener( + 'unload', + this.bottle.container.Room.leave.bind(this.bottle.container.Room, true) + ) + document.addEventListener('visibilitychange', (_) => { this.processMessagesThrottled.setDelay(document.hidden ? 10000 : 125) }) - this.pullTimer = new RepeatingTimer(Throttle(this.pullMessages.bind(this)), this.config.reloadTime * 1e3) + this.pullTimer = new RepeatingTimer( + Throttle(this.pullMessages.bind(this)), + this.config.reloadTime * 1e3 + ) - Push.onConnect(_ => { + Push.onConnect((_) => { console.debug('Chat.bootstrap', 'Push connected') this.pushConnected = true this.pullTimer.setDelta(30e3) + }).catch((error) => { + console.debug(error) }) - .catch(error => { console.debug(error) }) - Push.onDisconnect(_ => { + Push.onDisconnect((_) => { console.debug('Chat.bootstrap', 'Push disconnected') this.pushConnected = false this.pullTimer.setDelta(this.config.reloadTime * 1e3) + }).catch((error) => { + console.debug(error) }) - .catch(error => { console.debug(error) }) - Push.onMessage('be.bastelstu.chat.message', this.pullMessages.bind(this)) - .catch(error => { console.debug(error) }) + Push.onMessage( + 'be.bastelstu.chat.message', + this.pullMessages.bind(this) + ).catch((error) => { + console.debug(error) + }) // Fetch user list every 60 seconds // This acts as a safety net: It should be kept current by messages whenever possible. - this.pullUserListTimer = new RepeatingTimer(this.updateUsers.bind(this), 60e3) + this.pullUserListTimer = new RepeatingTimer( + this.updateUsers.bind(this), + 60e3 + ) this.registerMessageSink(this.bottle.container.UiMessageStream) this.registerMessageSink(this.bottle.container.UiNotification) this.registerMessageSink(this.bottle.container.UiAutoAway) - await Promise.all([ this.pullMessages() - , this.updateUsers() - , this.bottle.container.ProfileStore.ensureUsersByIDs([ CoreUser.userId ]) - ]) + await Promise.all([ + this.pullMessages(), + this.updateUsers(), + this.bottle.container.ProfileStore.ensureUsersByIDs([CoreUser.userId]), + ]) return this } @@ -240,7 +313,11 @@ define([ './Chat/console' } hcf(err = undefined) { - console.debug('Chat.hcf', 'Gotcha! FIRE was caught! FIRE’s data was newly added to the POKéDEX.', err) + console.debug( + 'Chat.hcf', + 'Gotcha! FIRE was caught! FIRE’s data was newly added to the POKéDEX.', + err + ) this.pullTimer.stop() this.pullUserListTimer.stop() @@ -259,47 +336,64 @@ define([ './Chat/console' this.markAsBack() - let [ trigger, parameterString ] = this.bottle.container.CommandHandler.splitCommand(value) + let [ + trigger, + parameterString, + ] = this.bottle.container.CommandHandler.splitCommand(value) let command = null if (trigger === null) { - command = this.bottle.container.CommandHandler.getCommandByIdentifier('be.bastelstu.chat', 'plain') - } - else { - command = this.bottle.container.CommandHandler.getCommandByTrigger(trigger) + command = this.bottle.container.CommandHandler.getCommandByIdentifier( + 'be.bastelstu.chat', + 'plain' + ) + } else { + command = this.bottle.container.CommandHandler.getCommandByTrigger( + trigger + ) } if (command === null) { - this.ui.input.inputError(Language.get('chat.error.triggerNotFound', { trigger })) + this.ui.input.inputError( + Language.get('chat.error.triggerNotFound', { trigger }) + ) return } try { let parameters try { - parameters = this.bottle.container.CommandHandler.applyCommand(command, parameterString) - } - catch (e) { + parameters = this.bottle.container.CommandHandler.applyCommand( + command, + parameterString + ) + } catch (e) { if (e instanceof ParseError) { - e = new Error(Language.get('chat.error.invalidParameters', { data: e.data })) + e = new Error( + Language.get('chat.error.invalidParameters', { data: e.data }) + ) } throw e } - const payload = { commandID: command.id - , parameters - } + const payload = { commandID: command.id, parameters } try { await this.bottle.container.Messenger.push(payload) this.ui.input.hideInputError() - } - catch (error) { + } catch (error) { let seriousError = true - if (error.returnValues && error.returnValues.fieldName === 'message' && (error.returnValues.realErrorMessage || error.returnValues.errorType)) { - this.ui.input.inputError(error.returnValues.realErrorMessage || error.returnValues.errorType) + if ( + error.returnValues && + error.returnValues.fieldName === 'message' && + (error.returnValues.realErrorMessage || + error.returnValues.errorType) + ) { + this.ui.input.inputError( + error.returnValues.realErrorMessage || + error.returnValues.errorType + ) seriousError = false - } - else { + } else { this.ui.input.inputError(error.message) } @@ -314,8 +408,7 @@ define([ './Chat/console' } console.debug('Chat.onSubmit', `Done`) - } - catch (e) { + } catch (e) { this.ui.input.inputError(e.message) } } @@ -325,16 +418,23 @@ define([ './Chat/console' if (this.bottle.container.ProfileStore.getSelf().away == null) return console.debug('Chat.markAsBack', `Marking as back`) - const command = this.bottle.container.CommandHandler.getCommandByIdentifier('be.bastelstu.chat', 'back') - return this.bottle.container.Messenger.push({ commandID: command.id, parameters: { } }) - } - catch (err) { + const command = this.bottle.container.CommandHandler.getCommandByIdentifier( + 'be.bastelstu.chat', + 'back' + ) + return this.bottle.container.Messenger.push({ + commandID: command.id, + parameters: {}, + }) + } catch (err) { console.error('Chat.markAsBack', err) } } async onSendAttachment(event) { - return this.bottle.container.Messenger.pushAttachment(event.detail.tmpHash) + return this.bottle.container.Messenger.pushAttachment( + event.detail.tmpHash + ) } onAutocomplete(event) { @@ -354,18 +454,23 @@ define([ './Chat/console' } async pullMessages() { - console.debug('Chat.pullMessages', `Pulling new messages, starting at ${this.knows.to ? this.knows.to + 1 : ''}`) + console.debug( + 'Chat.pullMessages', + `Pulling new messages, starting at ${ + this.knows.to ? this.knows.to + 1 : '' + }` + ) let payload try { if (this.knows.to === undefined) { payload = await this.bottle.container.Messenger.pull() + } else { + payload = await this.bottle.container.Messenger.pull( + this.knows.to + 1 + ) } - else { - payload = await this.bottle.container.Messenger.pull(this.knows.to + 1) - } - } - catch (e) { + } catch (e) { this.handleError(e) return } @@ -386,12 +491,17 @@ define([ './Chat/console' if (this.knows.from !== undefined && this.knows.to !== undefined) { messages = messages.filter((message) => { - return !(this.knows.from <= message.messageID && message.messageID <= this.knows.to) + return !( + this.knows.from <= message.messageID && + message.messageID <= this.knows.to + ) }) } - if (this.knows.from === undefined || payload.from < this.knows.from) this.knows.from = payload.from - if (this.knows.to === undefined || payload.to > this.knows.to) this.knows.to = payload.to + if (this.knows.from === undefined || payload.from < this.knows.from) + this.knows.from = payload.from + if (this.knows.to === undefined || payload.to > this.knows.to) + this.knows.to = payload.to this.queuedMessages.push(messages) const end = (performance ? performance : Date).now() @@ -402,14 +512,17 @@ define([ './Chat/console' handleError(error) { if (this.firstFailure === null) { - console.error('Chat.handleError', `Request failed, 30 seconds until shutdown`) + console.error( + 'Chat.handleError', + `Request failed, 30 seconds until shutdown` + ) this.firstFailure = Date.now() this.ui.connectionWarning.show() } console.debugException(error) - if ((Date.now() - this.firstFailure) >= 30e3) { + if (Date.now() - this.firstFailure >= 30e3) { console.error('Chat.handleError', ' Failures for 30 seconds, aborting') this.hcf(error) @@ -419,16 +532,18 @@ define([ './Chat/console' async processMessages() { console.debug('Chat.processMessages', 'Processing messages') const start = (performance ? performance : Date).now() - const messages = [ ].concat(...this.queuedMessages) + const messages = [].concat(...this.queuedMessages) this.queuedMessages = [] if (messages.length === 0) return - await Promise.all(messages.map(async (message) => { - this.bottle.container.ProfileStore.pushLastActivity(message.userID) + await Promise.all( + messages.map(async (message) => { + this.bottle.container.ProfileStore.pushLastActivity(message.userID) - return message.getMessageType().preProcess(message) - })) + return message.getMessageType().preProcess(message) + }) + ) const updateUserList = messages.some((message) => { return message.getMessageType().shouldUpdateUserList(message) @@ -438,13 +553,19 @@ define([ './Chat/console' this.updateUsers() } - await this.bottle.container.ProfileStore.ensureUsersByIDs([ ].concat(...messages.map(message => message.getMessageType().getReferencedUsers(message)))) + await this.bottle.container.ProfileStore.ensureUsersByIDs( + [].concat( + ...messages.map((message) => + message.getMessageType().getReferencedUsers(message) + ) + ) + ) messages.forEach((message) => { message.getMessageType().preRender(message) }) - this.messageSinks.forEach(sink => sink.ingest(messages)) + this.messageSinks.forEach((sink) => sink.ingest(messages)) const end = (performance ? performance : Date).now() console.debug('Chat.processMessages', `took ${(end - start) / 1000}s`) } @@ -453,10 +574,12 @@ define([ './Chat/console' console.debug('Chat.updateUsers') const users = await this.bottle.container.Room.getUsers() - await this.bottle.container.ProfileStore.ensureUsersByIDs(users.map(user => user.userID)) + await this.bottle.container.ProfileStore.ensureUsersByIDs( + users.map((user) => user.userID) + ) this.ui.userList.render(users) } } return Chat -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Autocompleter.js b/files_wcf/js/Bastelstu.be/Chat/Autocompleter.js index 7c04de9..0b2bcfe 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Autocompleter.js +++ b/files_wcf/js/Bastelstu.be/Chat/Autocompleter.js @@ -11,35 +11,42 @@ * or later of the General Public License. */ -define([ './CommandHandler' - , './Parser' - ], function (CommandHandler, Parser) { - "use strict"; +define(['./CommandHandler', './Parser'], function (CommandHandler, Parser) { + 'use strict' - const DEPENDENCIES = [ 'CommandHandler' ] + const DEPENDENCIES = ['CommandHandler'] class Autocompleter { constructor(commandHandler) { - if (!(commandHandler instanceof CommandHandler)) throw new TypeError('You must pass a CommandHandler to the Autocompleter') + if (!(commandHandler instanceof CommandHandler)) + throw new TypeError( + 'You must pass a CommandHandler to the Autocompleter' + ) this.commandHandler = commandHandler } - * autocomplete(text) { + *autocomplete(text) { if (text === '/') { - yield * this.autocompleteCommandTrigger(text, '') + yield* this.autocompleteCommandTrigger(text, '') return } - const [ trigger, parameterString ] = this.commandHandler.splitCommand(text) + const [trigger, parameterString] = this.commandHandler.splitCommand(text) let command if (trigger === null) { - command = this.commandHandler.getCommandByIdentifier('be.bastelstu.chat', 'plain') - } - else { - const triggerDone = Parser.Slash.thenRight(Parser.AlnumTrigger.or(Parser.SymbolicTrigger).thenLeft(Parser.Whitespace)).parse(Parser.Streams.ofString(text)) + command = this.commandHandler.getCommandByIdentifier( + 'be.bastelstu.chat', + 'plain' + ) + } else { + const triggerDone = Parser.Slash.thenRight( + Parser.AlnumTrigger.or(Parser.SymbolicTrigger).thenLeft( + Parser.Whitespace + ) + ).parse(Parser.Streams.ofString(text)) if (!triggerDone.isAccepted()) { - yield * this.autocompleteCommandTrigger(text, trigger) + yield* this.autocompleteCommandTrigger(text, trigger) return } @@ -56,13 +63,12 @@ define([ './CommandHandler' for (const item of values) { yield `/${trigger} ${item}` } - } - else { - yield * values + } else { + yield* values } } - * autocompleteCommandTrigger(text, prefix) { + *autocompleteCommandTrigger(text, prefix) { const triggers = Array.from(this.commandHandler.getTriggers()) triggers.sort() @@ -70,7 +76,8 @@ define([ './CommandHandler' for (const trigger of triggers) { if (trigger === '') continue if (!trigger.startsWith(prefix)) continue - if (!this.commandHandler.getCommandByTrigger(trigger).isAvailable) continue + if (!this.commandHandler.getCommandByTrigger(trigger).isAvailable) + continue yield `/${trigger} ` } @@ -79,4 +86,4 @@ define([ './CommandHandler' Autocompleter.DEPENDENCIES = DEPENDENCIES return Autocompleter -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/BoxRoomList.js b/files_wcf/js/Bastelstu.be/Chat/BoxRoomList.js index 8c6f270..8fbe88e 100644 --- a/files_wcf/js/Bastelstu.be/Chat/BoxRoomList.js +++ b/files_wcf/js/Bastelstu.be/Chat/BoxRoomList.js @@ -11,13 +11,14 @@ * or later of the General Public License. */ -define([ './console' - , 'Bastelstu.be/_Push' - , 'WoltLabSuite/Core/Dom/Util' - , 'WoltLabSuite/Core/Timer/Repeating' - , 'Bastelstu.be/PromiseWrap/Ajax' - ], function (console, Push, DomUtil, RepeatingTimer, Ajax) { - "use strict"; +define([ + './console', + 'Bastelstu.be/_Push', + 'WoltLabSuite/Core/Dom/Util', + 'WoltLabSuite/Core/Timer/Repeating', + 'Bastelstu.be/PromiseWrap/Ajax', +], function (console, Push, DomUtil, RepeatingTimer, Ajax) { + 'use strict' let timer = undefined const mapping = new Map() @@ -29,26 +30,44 @@ define([ './console' mapping.set(container, this) if (timer == null) { - timer = new RepeatingTimer(BoxRoomList.updateBoxes.bind(BoxRoomList), 60e3) + timer = new RepeatingTimer( + BoxRoomList.updateBoxes.bind(BoxRoomList), + 60e3 + ) } - Push.onConnect(timer.setDelta.bind(timer, 300e3)).catch(error => { console.debug(error) }) - Push.onDisconnect(timer.setDelta.bind(timer, 60e3)).catch(error => { console.debug(error) }) - Push.onMessage('be.bastelstu.chat.join', BoxRoomList.updateBoxes.bind(BoxRoomList)).catch(error => { console.debug(error) }) - Push.onMessage('be.bastelstu.chat.leave', BoxRoomList.updateBoxes.bind(BoxRoomList)).catch(error => { console.debug(error) }) + Push.onConnect(timer.setDelta.bind(timer, 300e3)).catch((error) => { + console.debug(error) + }) + Push.onDisconnect(timer.setDelta.bind(timer, 60e3)).catch((error) => { + console.debug(error) + }) + Push.onMessage( + 'be.bastelstu.chat.join', + BoxRoomList.updateBoxes.bind(BoxRoomList) + ).catch((error) => { + console.debug(error) + }) + Push.onMessage( + 'be.bastelstu.chat.leave', + BoxRoomList.updateBoxes.bind(BoxRoomList) + ).catch((error) => { + console.debug(error) + }) } static updateBoxes() { - mapping.forEach(object => { + mapping.forEach((object) => { object.update() }) } async update() { - const payload = { className: 'chat\\data\\room\\RoomAction' - , actionName: 'getBoxRoomList' - , parameters: { } - } + const payload = { + className: 'chat\\data\\room\\RoomAction', + actionName: 'getBoxRoomList', + parameters: {}, + } payload.parameters.activeRoomID = this.container.dataset.activeRoomId payload.parameters.boxID = this.container.dataset.boxId @@ -59,9 +78,12 @@ define([ './console' } replace(data) { - if (data.returnValues.template == null) throw new Error('template could not be found in returnValues') + if (data.returnValues.template == null) + throw new Error('template could not be found in returnValues') - const fragment = DomUtil.createFragmentFromHtml(data.returnValues.template) + const fragment = DomUtil.createFragmentFromHtml( + data.returnValues.template + ) const oldRoomList = this.container.querySelector('.chatBoxRoomList') const newRoomList = fragment.querySelector('.chatBoxRoomList') @@ -69,7 +91,9 @@ define([ './console' throw new Error('.chatBoxRoomList could not be found in container') } if (newRoomList == null) { - throw new Error('.chatBoxRoomList could not be found in returned template') + throw new Error( + '.chatBoxRoomList could not be found in returned template' + ) } if (oldRoomList.dataset.hash !== newRoomList.dataset.hash) { @@ -78,11 +102,9 @@ define([ './console' } _ajaxSetup() { - return { silent: true - , ignoreError: true - } + return { silent: true, ignoreError: true } } } return BoxRoomList -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command.js b/files_wcf/js/Bastelstu.be/Chat/Command.js index 231468e..928422a 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ './Parser' ], function (Parser) { - "use strict"; +define(['./Parser'], function (Parser) { + 'use strict' const data = Symbol('data') @@ -28,9 +28,7 @@ define([ './Parser' ], function (Parser) { return Parser.Rest } - * autocomplete(parameterString) { - - } + *autocomplete(parameterString) {} get id() { return this[data].commandID @@ -54,4 +52,4 @@ define([ './Parser' ], function (Parser) { } return Command -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Away.js b/files_wcf/js/Bastelstu.be/Chat/Command/Away.js index 444b1f2..2616a36 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Away.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Away.js @@ -11,16 +11,14 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' class Away extends Command { getParameterParser() { - return Parser.Rest.map(reason => ({ reason })) + return Parser.Rest.map((reason) => ({ reason })) } } return Away -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Back.js b/files_wcf/js/Bastelstu.be/Chat/Command/Back.js index f140c8f..80d3f91 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Back.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Back.js @@ -11,10 +11,8 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' class Back extends Command { getParameterParser() { @@ -23,4 +21,4 @@ define([ '../Command' } return Back -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Ban.js b/files_wcf/js/Bastelstu.be/Chat/Command/Ban.js index 9d759ab..302ade1 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Ban.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Ban.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './_Suspension' ], function (Suspension) { - "use strict"; +define(['./_Suspension'], function (Suspension) { + 'use strict' - class Ban extends Suspension { - - } + class Ban extends Suspension {} return Ban -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Broadcast.js b/files_wcf/js/Bastelstu.be/Chat/Command/Broadcast.js index 57a5636..2ce7e89 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Broadcast.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Broadcast.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './Plain' ], function (Plain) { - "use strict"; +define(['./Plain'], function (Plain) { + 'use strict' - class Broadcast extends Plain { - - } + class Broadcast extends Plain {} return Broadcast -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Color.js b/files_wcf/js/Bastelstu.be/Chat/Command/Color.js index 65ef156..93399e7 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Color.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Color.js @@ -11,21 +11,22 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' class Color extends Command { getParameterParser() { // Either match a color in hexadecimal RGB notation or a color name (just letters) - const color = Parser.F.try(Parser.RGBHex.map(color => ({ type: 'hex', value: color }))) - .or(new Parser.X().word().map(word => ({ type: 'word', value: word }))) + const color = Parser.F.try( + Parser.RGBHex.map((color) => ({ type: 'hex', value: color })) + ).or(new Parser.X().word().map((word) => ({ type: 'word', value: word }))) // Either match a single color or two colors separated by a space - return Parser.F.try(color.then(Parser.C.char(' ').thenRight(color))).or(color.map(item => [ item ])) + return Parser.F.try(color.then(Parser.C.char(' ').thenRight(color))).or( + color.map((item) => [item]) + ) } } return Color -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Info.js b/files_wcf/js/Bastelstu.be/Chat/Command/Info.js index ebb1ab2..5b2709a 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Info.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Info.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore' ] + const DEPENDENCIES = ['ProfileStore'] class Info extends Command { constructor(profileStore, id) { super(id) @@ -24,10 +22,10 @@ define([ '../Command' } getParameterParser() { - return Parser.Username.map(username => ({ username })) + return Parser.Username.map((username) => ({ username })) } - * autocomplete(parameterString) { + *autocomplete(parameterString) { for (const userID of this.profileStore.getLastActivity()) { const user = this.profileStore.get(userID) if (!user.username.startsWith(parameterString)) continue @@ -39,4 +37,4 @@ define([ '../Command' Info.DEPENDENCIES = DEPENDENCIES return Info -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Me.js b/files_wcf/js/Bastelstu.be/Chat/Command/Me.js index ef14115..21d94ed 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Me.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Me.js @@ -11,14 +11,14 @@ * or later of the General Public License. */ -define([ './Plain', '../Parser' ], function (Plain, Parser) { - "use strict"; +define(['./Plain', '../Parser'], function (Plain, Parser) { + 'use strict' class Me extends Plain { getParameterParser() { - return Parser.Rest1.map(text => ({ text })) + return Parser.Rest1.map((text) => ({ text })) } } return Me -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Mute.js b/files_wcf/js/Bastelstu.be/Chat/Command/Mute.js index c5babce..259160d 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Mute.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Mute.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './_Suspension' ], function (Suspension) { - "use strict"; +define(['./_Suspension'], function (Suspension) { + 'use strict' - class Mute extends Suspension { - - } + class Mute extends Suspension {} return Mute -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Plain.js b/files_wcf/js/Bastelstu.be/Chat/Command/Plain.js index 4193436..4b96846 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Plain.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Plain.js @@ -11,13 +11,14 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - , 'WoltLabSuite/Core/StringUtil' - ], function (Command, Parser, StringUtil) { - "use strict"; +define(['../Command', '../Parser', 'WoltLabSuite/Core/StringUtil'], function ( + Command, + Parser, + StringUtil +) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore' ] + const DEPENDENCIES = ['ProfileStore'] class Plain extends Command { constructor(profileStore, id) { super(id) @@ -25,12 +26,12 @@ define([ '../Command' } getParameterParser() { - return Parser.Rest1 - .map(StringUtil.escapeHTML.bind(StringUtil)) - .map(text => ({ text })) + return Parser.Rest1.map( + StringUtil.escapeHTML.bind(StringUtil) + ).map((text) => ({ text })) } - * autocomplete(parameterString) { + *autocomplete(parameterString) { const parts = parameterString.split(/ /) const lastWord = parts.pop().toLowerCase() @@ -41,13 +42,21 @@ define([ '../Command' for (const userID of this.profileStore.getLastActivity()) { const user = this.profileStore.get(userID) const username = user.username.toLowerCase() - if (!username.startsWith(parameterString) && !username.startsWith(lastWord.replace(/^@/, ''))) continue + if ( + !username.startsWith(parameterString) && + !username.startsWith(lastWord.replace(/^@/, '')) + ) + continue - yield `${parts.concat([ lastWord.startsWith('@') ? `@${user.username}` : user.username ]).join(' ')} ` + yield `${parts + .concat([ + lastWord.startsWith('@') ? `@${user.username}` : user.username, + ]) + .join(' ')} ` } } } Plain.DEPENDENCIES = DEPENDENCIES return Plain -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Team.js b/files_wcf/js/Bastelstu.be/Chat/Command/Team.js index b23111a..9f06b3f 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Team.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Team.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './Plain' ], function (Plain) { - "use strict"; +define(['./Plain'], function (Plain) { + 'use strict' - class Team extends Plain { - - } + class Team extends Plain {} return Team -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Temproom.js b/files_wcf/js/Bastelstu.be/Chat/Command/Temproom.js index be9cfee..5c4e28d 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Temproom.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Temproom.js @@ -11,39 +11,44 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' class Temproom extends Command { getParameterParser() { const Create = Parser.C.string('create').thenReturns({ type: 'create' }) - const Invite = Parser.C.string('invite').thenLeft(Parser.Whitespace.rep()).thenRight(Parser.Username).map((username) => { - return { type: 'invite' - , username - } - }) + const Invite = Parser.C.string('invite') + .thenLeft(Parser.Whitespace.rep()) + .thenRight(Parser.Username) + .map((username) => { + return { type: 'invite', username } + }) const Delete = Parser.C.string('delete').thenReturns({ type: 'delete' }) return Create.or(Invite).or(Delete) } - * autocomplete(parameterString) { + *autocomplete(parameterString) { const Create = Parser.C.string('create') const Invite = Parser.C.string('invite') const Delete = Parser.C.string('delete') - const subcommandDone = Create.or(Invite).or(Delete).thenLeft(Parser.Whitespace) + const subcommandDone = Create.or(Invite) + .or(Delete) + .thenLeft(Parser.Whitespace) - const subcommandCheck = subcommandDone.parse(Parser.Streams.ofString(parameterString)) + const subcommandCheck = subcommandDone.parse( + Parser.Streams.ofString(parameterString) + ) if (subcommandCheck.isAccepted()) { return } - yield * [ 'create', 'invite ', 'delete' ].filter(item => item.startsWith(parameterString)) + yield* ['create', 'invite ', 'delete'].filter((item) => + item.startsWith(parameterString) + ) } } return Temproom -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Unban.js b/files_wcf/js/Bastelstu.be/Chat/Command/Unban.js index 35bd05e..17514af 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Unban.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Unban.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './_Unsuspension' ], function (Unsuspension) { - "use strict"; +define(['./_Unsuspension'], function (Unsuspension) { + 'use strict' - class Unban extends Unsuspension { - - } + class Unban extends Unsuspension {} return Unban -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Unmute.js b/files_wcf/js/Bastelstu.be/Chat/Command/Unmute.js index f0dbb72..2ce2818 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Unmute.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Unmute.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './_Unsuspension' ], function (Unsuspension) { - "use strict"; +define(['./_Unsuspension'], function (Unsuspension) { + 'use strict' - class Unmute extends Unsuspension { - - } + class Unmute extends Unsuspension {} return Unmute -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Where.js b/files_wcf/js/Bastelstu.be/Chat/Command/Where.js index 3cb1412..f8e5d5c 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Where.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Where.js @@ -11,10 +11,8 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' class Where extends Command { getParameterParser() { @@ -23,4 +21,4 @@ define([ '../Command' } return Where -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/Whisper.js b/files_wcf/js/Bastelstu.be/Chat/Command/Whisper.js index f5eb1ba..28609db 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/Whisper.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/Whisper.js @@ -11,25 +11,27 @@ * or later of the General Public License. */ -define([ '../Parser' - , './Plain' - ], function (Parser, Plain) { - "use strict"; +define(['../Parser', './Plain'], function (Parser, Plain) { + 'use strict' class Whisper extends Plain { getParameterParser() { - return Parser.Username.thenLeft(Parser.Whitespace.rep()).then(super.getParameterParser()).map(([ username, object ]) => { - object.username = username + return Parser.Username.thenLeft(Parser.Whitespace.rep()) + .then(super.getParameterParser()) + .map(([username, object]) => { + object.username = username - return object - }) + return object + }) } - * autocomplete(parameterString) { - const usernameDone = Parser.Username.thenLeft(Parser.Whitespace).parse(Parser.Streams.ofString(parameterString)) + *autocomplete(parameterString) { + const usernameDone = Parser.Username.thenLeft(Parser.Whitespace).parse( + Parser.Streams.ofString(parameterString) + ) if (usernameDone.isAccepted()) { - yield * super.autocomplete(parameterString) + yield* super.autocomplete(parameterString) return } @@ -43,4 +45,4 @@ define([ '../Parser' } return Whisper -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/_Suspension.js b/files_wcf/js/Bastelstu.be/Chat/Command/_Suspension.js index 01f922d..157f185 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/_Suspension.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/_Suspension.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore' ] + const DEPENDENCIES = ['ProfileStore'] class Suspension extends Command { constructor(profileStore, id) { super(id) @@ -24,51 +22,68 @@ define([ '../Command' } getParameterParser() { - const Globally = Parser.C.string('global').thenLeft(Parser.C.string('ly').opt()) + const Globally = Parser.C.string('global').thenLeft( + Parser.C.string('ly').opt() + ) const Forever = Parser.C.string('forever').thenReturns(null) - const Timespan = Parser.N.digits.then(Parser.C.charIn('dhm')).map(function ([ span, unit ]) { - switch (unit) { - case 'd': - return span * 86400; - case 'h': - return span * 3600; - case 'm': - return span * 60; - } - throw new Error('Unreachable') - }) - .rep() - .map(parts => parts.array().reduce((carry, item) => carry + item, 0)) - .map(offset => Math.floor(Date.now() / 1000) + offset) + const Timespan = Parser.N.digits + .then(Parser.C.charIn('dhm')) + .map(function ([span, unit]) { + switch (unit) { + case 'd': + return span * 86400 + case 'h': + return span * 3600 + case 'm': + return span * 60 + } + throw new Error('Unreachable') + }) + .rep() + .map((parts) => parts.array().reduce((carry, item) => carry + item, 0)) + .map((offset) => Math.floor(Date.now() / 1000) + offset) - const Duration = Forever.or(Timespan).or(Parser.ISODate.map(item => Math.floor(item.valueOf() / 1000))) + const Duration = Forever.or(Timespan).or( + Parser.ISODate.map((item) => Math.floor(item.valueOf() / 1000)) + ) return Parser.Username.thenLeft(Parser.Whitespace.rep()) - .then(Globally.thenLeft(Parser.Whitespace.rep()).thenReturns(true).or(Parser.F.returns(false))) - .then(Duration) - .then(Parser.Whitespace.rep().thenRight(Parser.Rest1).or(Parser.F.eos.thenReturns(null))) - .map(([ username, globally, duration, reason ]) => { - return { username - , globally - , duration - , reason - } - }) + .then( + Globally.thenLeft(Parser.Whitespace.rep()) + .thenReturns(true) + .or(Parser.F.returns(false)) + ) + .then(Duration) + .then( + Parser.Whitespace.rep() + .thenRight(Parser.Rest1) + .or(Parser.F.eos.thenReturns(null)) + ) + .map(([username, globally, duration, reason]) => { + return { username, globally, duration, reason } + }) } - * autocomplete(parameterString) { - const usernameDone = Parser.Username.thenLeft(Parser.Whitespace.rep()).map(username => `"${username.replace(/"/g, '""')}"`) - const globallyDone = usernameDone.then(Parser.C.string('global').thenLeft(Parser.C.string('ly').opt())).thenLeft(Parser.Whitespace.rep()) + *autocomplete(parameterString) { + const usernameDone = Parser.Username.thenLeft( + Parser.Whitespace.rep() + ).map((username) => `"${username.replace(/"/g, '""')}"`) + const globallyDone = usernameDone + .then(Parser.C.string('global').thenLeft(Parser.C.string('ly').opt())) + .thenLeft(Parser.Whitespace.rep()) - const usernameCheck = usernameDone.parse(Parser.Streams.ofString(parameterString)) + const usernameCheck = usernameDone.parse( + Parser.Streams.ofString(parameterString) + ) if (usernameCheck.isAccepted()) { - const globallyCheck = globallyDone.parse(Parser.Streams.ofString(parameterString)) + const globallyCheck = globallyDone.parse( + Parser.Streams.ofString(parameterString) + ) let prefix, rest if (globallyCheck.isAccepted()) { prefix = parameterString.substring(0, globallyCheck.offset) rest = parameterString.substring(globallyCheck.offset) - } - else { + } else { prefix = parameterString.substring(0, usernameCheck.offset) rest = parameterString.substring(usernameCheck.offset) } @@ -101,4 +116,4 @@ define([ '../Command' Suspension.DEPENDENCIES = DEPENDENCIES return Suspension -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Command/_Unsuspension.js b/files_wcf/js/Bastelstu.be/Chat/Command/_Unsuspension.js index 72973b8..d97d919 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Command/_Unsuspension.js +++ b/files_wcf/js/Bastelstu.be/Chat/Command/_Unsuspension.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ '../Command' - , '../Parser' - ], function (Command, Parser) { - "use strict"; +define(['../Command', '../Parser'], function (Command, Parser) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore' ] + const DEPENDENCIES = ['ProfileStore'] class Unsuspension extends Command { constructor(profileStore, id) { super(id) @@ -24,30 +22,39 @@ define([ '../Command' } getParameterParser() { - const Globally = Parser.C.string('global').thenLeft(Parser.C.string('ly').opt()) + const Globally = Parser.C.string('global').thenLeft( + Parser.C.string('ly').opt() + ) - return Parser.Username - .then(Parser.Whitespace.rep().thenRight(Globally.thenReturns(true)).or(Parser.F.returns(false))) - .map(([ username, globally ]) => { - return { username - , globally - } + return Parser.Username.then( + Parser.Whitespace.rep() + .thenRight(Globally.thenReturns(true)) + .or(Parser.F.returns(false)) + ).map(([username, globally]) => { + return { username, globally } }) } - * autocomplete(parameterString) { - const usernameDone = Parser.Username.thenLeft(Parser.Whitespace.rep()).map(username => `"${username.replace(/"/g, '""')}"`) - const globallyDone = usernameDone.then(Parser.C.string('global').thenLeft(Parser.C.string('ly').opt())).thenLeft(Parser.Whitespace.rep()) + *autocomplete(parameterString) { + const usernameDone = Parser.Username.thenLeft( + Parser.Whitespace.rep() + ).map((username) => `"${username.replace(/"/g, '""')}"`) + const globallyDone = usernameDone + .then(Parser.C.string('global').thenLeft(Parser.C.string('ly').opt())) + .thenLeft(Parser.Whitespace.rep()) - const usernameCheck = usernameDone.parse(Parser.Streams.ofString(parameterString)) + const usernameCheck = usernameDone.parse( + Parser.Streams.ofString(parameterString) + ) if (usernameCheck.isAccepted()) { - const globallyCheck = globallyDone.parse(Parser.Streams.ofString(parameterString)) + const globallyCheck = globallyDone.parse( + Parser.Streams.ofString(parameterString) + ) let prefix, rest if (globallyCheck.isAccepted()) { prefix = parameterString.substring(0, globallyCheck.offset) rest = parameterString.substring(globallyCheck.offset) - } - else { + } else { prefix = parameterString.substring(0, usernameCheck.offset) rest = parameterString.substring(usernameCheck.offset) } @@ -68,4 +75,4 @@ define([ '../Command' Unsuspension.DEPENDENCIES = DEPENDENCIES return Unsuspension -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/CommandHandler.js b/files_wcf/js/Bastelstu.be/Chat/CommandHandler.js index 7a1f227..78169aa 100644 --- a/files_wcf/js/Bastelstu.be/Chat/CommandHandler.js +++ b/files_wcf/js/Bastelstu.be/Chat/CommandHandler.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ './Parser' - , './ParseError' - ], function (Parser, ParseError) { - "use strict"; +define(['./Parser', './ParseError'], function (Parser, ParseError) { + 'use strict' - const DEPENDENCIES = [ 'Trigger', 'Command' ] + const DEPENDENCIES = ['Trigger', 'Command'] class CommandHandler { constructor(triggers, commands) { this.triggers = triggers @@ -28,19 +26,19 @@ define([ './Parser' if (result.isAccepted()) { return result.value - } - else { + } else { throw new ParseError('Empty trigger') } } applyCommand(command, parameterString) { - const result = command.getParameterParser().parse(Parser.Streams.ofString(parameterString)) + const result = command + .getParameterParser() + .parse(Parser.Streams.ofString(parameterString)) if (result.isAccepted()) { return result.value - } - else { + } else { throw new ParseError('Could not parse', { result, parameterString }) } } @@ -64,4 +62,4 @@ define([ './Parser' CommandHandler.DEPENDENCIES = DEPENDENCIES return CommandHandler -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/DataStructure/EventEmitter.js b/files_wcf/js/Bastelstu.be/Chat/DataStructure/EventEmitter.js index d3d6122..00169bf 100644 --- a/files_wcf/js/Bastelstu.be/Chat/DataStructure/EventEmitter.js +++ b/files_wcf/js/Bastelstu.be/Chat/DataStructure/EventEmitter.js @@ -11,13 +11,13 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' const listeners = new WeakMap() const EventEmitter = function (target) { Object.assign(target, { - on(type, listener, options = { }) { + on(type, listener, options = {}) { if (!listeners.has(this)) { listeners.set(this, new Map()) } @@ -33,22 +33,24 @@ define([ ], function () { listeners.get(this).get(type).delete(listener) }, - emit(type, detail = { }) { + emit(type, detail = {}) { if (!listeners.has(this)) return if (!listeners.get(this).has(type)) return const set = listeners.get(this).get(type) - set.forEach((function ({ listener, options }) { - if (options.once) { - set.delete(listener) - } + set.forEach( + function ({ listener, options }) { + if (options.once) { + set.delete(listener) + } - listener({ target: this, detail }) - }).bind(this)) - } + listener({ target: this, detail }) + }.bind(this) + ) + }, }) } return EventEmitter -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/DataStructure/LRU.js b/files_wcf/js/Bastelstu.be/Chat/DataStructure/LRU.js index 1c4f8b7..9ea3865 100644 --- a/files_wcf/js/Bastelstu.be/Chat/DataStructure/LRU.js +++ b/files_wcf/js/Bastelstu.be/Chat/DataStructure/LRU.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' const s = Symbol('s') const start = Symbol('start') @@ -24,7 +24,7 @@ define([ ], function () { } add(value) { - if (this[start] && this[start].value === value) { + if (this[start] && this[start].value === value) { return } @@ -45,14 +45,13 @@ define([ ], function () { this[s].set(value, obj) } - * [Symbol.iterator]() { + *[Symbol.iterator]() { let current = this[start] do { yield current.value - } - while ((current = current.next)) + } while ((current = current.next)) } } return LRU -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Node.js b/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Node.js index 1ced679..7756076 100644 --- a/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Node.js +++ b/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Node.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' class Node { constructor(value) { @@ -93,39 +93,52 @@ define([ ], function () { } search(value) { - if (value === this.value) return [ 'IS', this ] + if (value === this.value) return ['IS', this] if (value < this.value) { if (this.left !== undefined) return this.left.search(value) - return [ 'LEFT', this ] + return ['LEFT', this] } if (value > this.value) { if (this.right !== undefined) return this.right.search(value) - return [ 'RIGHT', this ] + return ['RIGHT', this] } throw new Error('Unreachable') } print(depth = 0) { - console.log(" ".repeat(depth) + `${this.value}: ${this.color} (Parent: ${this.parent ? this.parent.value : '-'})`) + console.log( + ' '.repeat(depth) + + `${this.value}: ${this.color} (Parent: ${ + this.parent ? this.parent.value : '-' + })` + ) if (this.left) this.left.print(depth + 1) - else console.log(" ".repeat(depth + 1) + '-') + else console.log(' '.repeat(depth + 1) + '-') if (this.right) this.right.print(depth + 1) - else console.log(" ".repeat(depth + 1) + '-') + else console.log(' '.repeat(depth + 1) + '-') } check() { - if (this.left && this.left.value >= this.value) throw new Error('Invalid' + this.value); - if (this.right && this.right.value <= this.value) throw new Error('Invalid' + this.value); - if (this.color === 'RED' && ((this.left && this.left.color !== 'BLACK') || (this.right && this.right.color !== 'BLACK'))) throw new Error('Invalid' + this.value); + if (this.left && this.left.value >= this.value) + throw new Error('Invalid' + this.value) + if (this.right && this.right.value <= this.value) + throw new Error('Invalid' + this.value) + if ( + this.color === 'RED' && + ((this.left && this.left.color !== 'BLACK') || + (this.right && this.right.color !== 'BLACK')) + ) + throw new Error('Invalid' + this.value) - let leftBlacks = 1, rightBlacks = 1 + let leftBlacks = 1, + rightBlacks = 1 if (this.left) { leftBlacks = this.left.check() } if (this.right) { rightBlacks = this.right.check() } - if (leftBlacks !== rightBlacks) throw new Error('Invalid' + this.value); + if (leftBlacks !== rightBlacks) throw new Error('Invalid' + this.value) if (this.color === 'BLACK') return leftBlacks + 1 return leftBlacks @@ -133,4 +146,4 @@ define([ ], function () { } return Node -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Tree.js b/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Tree.js index 4cbe2fe..063c788 100644 --- a/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Tree.js +++ b/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Tree.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ './Node' ], function (Node) { - "use strict"; +define(['./Node'], function (Node) { + 'use strict' class Tree { constructor() { @@ -29,22 +29,22 @@ define([ './Node' ], function (Node) { if (this.root === undefined) { this.root = node this.fix(node) - return [ 'RIGHT', undefined ] + return ['RIGHT', undefined] } const search = this.search(value) - const [ side, parent ] = search + const [side, parent] = search - if (side === 'IS') return [ side, parent.value ] + if (side === 'IS') return [side, parent.value] if (side === 'LEFT') { parent.left = node this.fix(node) - return [ side, parent.value ] + return [side, parent.value] } if (side === 'RIGHT') { parent.right = node this.fix(node) - return [ side, parent.value ] + return [side, parent.value] } throw new Error('Unreachable') } @@ -74,8 +74,7 @@ define([ './Node' ], function (Node) { if (N.isRightChild && N.parent.isLeftChild) { this.rotateLeft(N.parent) N = N.left - } - else if (N.isLeftChild && N.parent.isRightChild) { + } else if (N.isLeftChild && N.parent.isRightChild) { this.rotateRight(N.parent) N = N.right } @@ -86,8 +85,7 @@ define([ './Node' ], function (Node) { G.color = 'RED' if (N.isLeftChild) { this.rotateRight(G) - } - else { + } else { this.rotateLeft(G) } } @@ -99,11 +97,9 @@ define([ './Node' ], function (Node) { N.right = right.left if (N.parent === undefined) { this.root = right - } - else if (N.isLeftChild) { + } else if (N.isLeftChild) { N.parent.left = right - } - else if (N.isRightChild) { + } else if (N.isRightChild) { N.parent.right = right } @@ -117,11 +113,9 @@ define([ './Node' ], function (Node) { N.left = left.right if (N.parent === undefined) { this.root = left - } - else if (N.isLeftChild) { + } else if (N.isLeftChild) { N.parent.left = left - } - else if (N.isRightChild) { + } else if (N.isRightChild) { N.parent.right = left } left.right = N @@ -129,4 +123,4 @@ define([ './Node' ], function (Node) { } return Tree -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/DataStructure/Throttle.js b/files_wcf/js/Bastelstu.be/Chat/DataStructure/Throttle.js index 4d9128d..7ba7d15 100644 --- a/files_wcf/js/Bastelstu.be/Chat/DataStructure/Throttle.js +++ b/files_wcf/js/Bastelstu.be/Chat/DataStructure/Throttle.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' class Throttler { constructor(callback, delay = 125) { @@ -37,7 +37,7 @@ define([ ], function () { clearTimeout(this.timer) } - this.timer = setTimeout(_ => { + this.timer = setTimeout((_) => { this.timer = null this.hot = false @@ -60,8 +60,7 @@ define([ ], function () { guardedExecute() { if (this.hot) { this.awaiting = true - } - else { + } else { this.execute() } } @@ -71,11 +70,10 @@ define([ ], function () { } set delay(newDelay) { - if (this.awaiting && (Date.now() - this.last) > newDelay) { + if (this.awaiting && Date.now() - this.last > newDelay) { this._delay = 0 this.setTimer() - } - else if (this.timer) { + } else if (this.timer) { this._delay = Math.max(0, newDelay - (Date.now() - this.last)) this.setTimer() } @@ -98,4 +96,4 @@ define([ ], function () { } return throttle -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Helper.js b/files_wcf/js/Bastelstu.be/Chat/Helper.js index 6786e50..a486708 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Helper.js +++ b/files_wcf/js/Bastelstu.be/Chat/Helper.js @@ -11,10 +11,11 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Date/Util' - , 'WoltLabSuite/Core/Language' - ], function (DateUtil, Language) { - "use strict"; +define(['WoltLabSuite/Core/Date/Util', 'WoltLabSuite/Core/Language'], function ( + DateUtil, + Language +) { + 'use strict' class Helper { static deepFreeze(obj) { @@ -38,11 +39,13 @@ define([ 'WoltLabSuite/Core/Date/Util' */ static isInput(element) { if (element.tagName === 'INPUT') { - if (element.getAttribute('type') !== 'text' && element.getAttribute('type') !== 'password') { + if ( + element.getAttribute('type') !== 'text' && + element.getAttribute('type') !== 'password' + ) { return false } - } - else if (element.tagName !== 'TEXTAREA') { + } else if (element.tagName !== 'TEXTAREA') { return false } @@ -53,21 +56,20 @@ define([ 'WoltLabSuite/Core/Date/Util' let last = 0 let deferTimer = null - return function() { - const now = new Date().getTime() - const args = arguments + return function () { + const now = new Date().getTime() + const args = arguments const context = scope || this - if (last && (now < (last + threshold))) { + if (last && now < last + threshold) { clearTimeout(deferTimer) - return deferTimer = setTimeout(function() { + return (deferTimer = setTimeout(function () { last = now return fn.apply(context, args) - }, threshold) - } - else { + }, threshold)) + } else { last = now return fn.apply(context, args) @@ -108,8 +110,7 @@ define([ 'WoltLabSuite/Core/Date/Util' if (element.nextSibling) { element.parentNode.insertBefore(wrapper, element.nextSibling) - } - else { + } else { element.parentNode.appendChild(wrapper) } @@ -122,7 +123,7 @@ define([ 'WoltLabSuite/Core/Date/Util' throw new Error(`Unsupported element type: ${textarea.tagName}`) } - const pre = document.createElement('pre') + const pre = document.createElement('pre') const span = document.createElement('span') const mirror = function () { @@ -141,7 +142,7 @@ define([ 'WoltLabSuite/Core/Date/Util' pre.appendChild(document.createElement('br')) textarea.parentNode.insertBefore(pre, textarea) - textarea.addEventListener('input', mirror) + textarea.addEventListener('input', mirror) mirror() } @@ -150,11 +151,12 @@ define([ 'WoltLabSuite/Core/Date/Util' constructor(size) { super() - Object.defineProperty(this, 'size', { enumerable: false - , value: size - , writable: false - , configurable: false - }); + Object.defineProperty(this, 'size', { + enumerable: false, + value: size, + writable: false, + configurable: false, + }) } push() { @@ -164,7 +166,7 @@ define([ 'WoltLabSuite/Core/Date/Util' super.shift() } - return this.length; + return this.length } unshift() { @@ -174,7 +176,7 @@ define([ 'WoltLabSuite/Core/Date/Util' super.pop() } - return this.length; + return this.length } first() { @@ -190,9 +192,9 @@ define([ 'WoltLabSuite/Core/Date/Util' } static intToRGBHex(integer) { - const r = ((integer >> 16) & 0xFF).toString(16) - const g = ((integer >> 8) & 0xFF).toString(16) - const b = ((integer >> 0) & 0xFF).toString(16) + const r = ((integer >> 16) & 0xff).toString(16) + const g = ((integer >> 8) & 0xff).toString(16) + const b = ((integer >> 0) & 0xff).toString(16) const rr = r.length == 1 ? `0${r}` : r const gg = g.length == 1 ? `0${g}` : g @@ -263,8 +265,7 @@ define([ 'WoltLabSuite/Core/Date/Util' if (firstTextNode) { nodeRange.setStart(firstTextNode, 0) nodeRange.setEnd(lastTextNode, lastTextNode.length) - } - else { + } else { nodeRange.selectNodeContents(node) } @@ -282,9 +283,10 @@ define([ 'WoltLabSuite/Core/Date/Util' * @return {String} */ static getTextContent(node) { - const acceptNode = node => { + const acceptNode = (node) => { if (node instanceof Element) { - if (node.tagName === 'SCRIPT' || node.tagName === 'STYLE') return NodeFilter.FILTER_REJECT + if (node.tagName === 'SCRIPT' || node.tagName === 'STYLE') + return NodeFilter.FILTER_REJECT } return NodeFilter.FILTER_ACCEPT @@ -295,33 +297,34 @@ define([ 'WoltLabSuite/Core/Date/Util' const flags = NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT const treeWalker = document.createTreeWalker(node, flags, { acceptNode }) - const ignoredLinks = [ ] + const ignoredLinks = [] while (treeWalker.nextNode()) { const node = treeWalker.currentNode if (node instanceof Text) { - if (node.parentNode.tagName === 'A' && ignoredLinks.indexOf(node.parentNode) >= 0) { + if ( + node.parentNode.tagName === 'A' && + ignoredLinks.indexOf(node.parentNode) >= 0 + ) { continue } out += node.nodeValue.replace(/\n/g, '') - } - else { + } else { switch (node.tagName) { case 'IMG': { const alt = node.getAttribute('alt') if (node.classList.contains('smiley')) { out += ` ${alt} ` - } - else if (alt && alt !== '') { + } else if (alt && alt !== '') { out += ` ${alt} [Image ${node.src}] ` - } - else { + } else { out += ` [Image ${node.src}] ` } - break } + break + } case 'BR': case 'LI': @@ -329,16 +332,16 @@ define([ 'WoltLabSuite/Core/Date/Util' case 'DIV': case 'TR': out += '\n' - break + break case 'TH': case 'TD': out += '\t' - break + break case 'P': out += '\n\n' - break + break case 'A': { let link = node.href @@ -354,7 +357,9 @@ define([ 'WoltLabSuite/Core/Date/Util' const parts = text.split(/\u2026/) if (parts.length === 2) { - truncated = node.href.startsWith(parts[0]) && node.href.endsWith(parts[1]) + truncated = + node.href.startsWith(parts[0]) && + node.href.endsWith(parts[1]) } } @@ -364,7 +369,8 @@ define([ 'WoltLabSuite/Core/Date/Util' } out += link - break } + break + } } } } @@ -374,5 +380,4 @@ define([ 'WoltLabSuite/Core/Date/Util' } return Helper -}); - +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/LocalStorage.js b/files_wcf/js/Bastelstu.be/Chat/LocalStorage.js index dd8f31e..c0683bc 100644 --- a/files_wcf/js/Bastelstu.be/Chat/LocalStorage.js +++ b/files_wcf/js/Bastelstu.be/Chat/LocalStorage.js @@ -11,10 +11,13 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, LocalStorageEmulator) { - 'use strict'; +define(['WoltLabSuite/Core/Core', './LocalStorageEmulator'], function ( + Core, + LocalStorageEmulator +) { + 'use strict' - const DEPENDENCIES = [ ] + const DEPENDENCIES = [] class LocalStorage { constructor(subprefix) { this.subprefix = subprefix @@ -23,15 +26,17 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L } static isQuotaExceeded(error) { - return error instanceof DOMException && ( + return ( + error instanceof DOMException && // everything except Firefox - error.code === 22 || - // Firefox - error.code === 1014 || - // everything except Firefox - error.name === 'QuotaExceededError' || - // Firefox - error.name === 'NS_ERROR_DOM_QUOTA_REACHED') + (error.code === 22 || + // Firefox + error.code === 1014 || + // everything except Firefox + error.name === 'QuotaExceededError' || + // Firefox + error.name === 'NS_ERROR_DOM_QUOTA_REACHED') + ) } static isAvailable() { @@ -40,8 +45,7 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L window.localStorage.setItem(x, x) window.localStorage.removeItem(x) return true - } - catch (error) { + } catch (error) { return LocalStorage.isQuotaExceeded(error) } } @@ -50,8 +54,7 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L if (LocalStorage.isAvailable()) { this.storage = window.localStorage this.hasLocalStorage = true - } - else { + } else { console.info('Falling back to in-memory local storage emulation') this.storage = new LocalStorageEmulator() } @@ -97,13 +100,19 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L */ set(key, value) { try { - this.storage.setItem(`${this.storagePrefix}${key}`, JSON.stringify(value)) - } - catch (error) { + this.storage.setItem( + `${this.storagePrefix}${key}`, + JSON.stringify(value) + ) + } catch (error) { if (!LocalStorage.isQuotaExceeded(error)) throw error - console.warn(`Your localStorage has exceeded the size quota for this domain`) - console.warn(`We are falling back to an in-memory storage, this does not persist data!`) + console.warn( + `Your localStorage has exceeded the size quota for this domain` + ) + console.warn( + `We are falling back to an in-memory storage, this does not persist data!` + ) console.error(error) const storage = new LocalStorageEmulator() @@ -152,7 +161,7 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L * @returns {string} The last value of the provided setting */ remove(key) { - const value = this.get(key) + const value = this.get(key) const storageKey = `${this.storagePrefix}${key}` this.storage.removeItem(storageKey) @@ -167,13 +176,20 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L clear() { const _clear = (target) => { for (let key in target) { - if (!key.startsWith(this.storagePrefix) || !target.hasOwnProperty(key)) continue + if ( + !key.startsWith(this.storagePrefix) || + !target.hasOwnProperty(key) + ) + continue target.removeItem(key) } } - if (this.hasLocalStorage && this.storage instanceof LocalStorageEmulator) { + if ( + this.hasLocalStorage && + this.storage instanceof LocalStorageEmulator + ) { try { // Try to clear the real localStorage _clear(localStorage) @@ -188,8 +204,9 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L this.storage = localStorage console.log('Switched back to using the localStorage') + } catch (error) { + /* no we can’t */ } - catch (error) { /* no we can’t */ } } _clear(this.storage) @@ -198,4 +215,4 @@ define([ 'WoltLabSuite/Core/Core', './LocalStorageEmulator' ], function (Core, L LocalStorage.DEPENDENCIES = DEPENDENCIES return LocalStorage -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/LocalStorageEmulator.js b/files_wcf/js/Bastelstu.be/Chat/LocalStorageEmulator.js index dc8f0b5..093cd20 100644 --- a/files_wcf/js/Bastelstu.be/Chat/LocalStorageEmulator.js +++ b/files_wcf/js/Bastelstu.be/Chat/LocalStorageEmulator.js @@ -11,16 +11,19 @@ * or later of the General Public License. */ -define([ ], function () { - 'use strict'; +define([], function () { + 'use strict' class LocalStorageEmulator { - constructor () { + constructor() { this._data = new Map() return new Proxy(this, { get(target, property) { // Check if the property exists on the object or its prototype - if (target.hasOwnProperty(property) || Object.getPrototypeOf(target)[property]) { + if ( + target.hasOwnProperty(property) || + Object.getPrototypeOf(target)[property] + ) { return target[property] } @@ -29,18 +32,22 @@ define([ ], function () { }, set(target, property, value) { // Check if the property exists on the object or its prototype - if (target.hasOwnProperty(property) || Object.getPrototypeOf(target)[property]) { + if ( + target.hasOwnProperty(property) || + Object.getPrototypeOf(target)[property] + ) { target[property] = value - } - else { + } else { // Proxy to the underlying map target.setItem(property, value) } }, has(target, property) { - return target.hasOwnProperty(property) // check the properties of the object - || Object.getPrototypeOf(target)[property] // check its prototype - || target._data.has(property) // check the underlying map + return ( + target.hasOwnProperty(property) || // check the properties of the object + Object.getPrototypeOf(target)[property] || // check its prototype + target._data.has(property) + ) // check the underlying map }, ownKeys(target) { // Proxy to the underlying map @@ -50,9 +57,9 @@ define([ ], function () { // Make the properties of the map visible return { enumerable: true, - configurable: true + configurable: true, } - } + }, }) } @@ -80,10 +87,10 @@ define([ ], function () { this._data.clear() } - * [Symbol.iterator]() { - yield * this._data.values() + *[Symbol.iterator]() { + yield* this._data.values() } } return LocalStorageEmulator -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Log.js b/files_wcf/js/Bastelstu.be/Chat/Log.js index be44ef4..682951f 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Log.js +++ b/files_wcf/js/Bastelstu.be/Chat/Log.js @@ -11,19 +11,32 @@ * or later of the General Public License. */ -define([ './console' - , 'Bastelstu.be/bottle' - , 'WoltLabSuite/Core/Core' - , './Message' - , './Messenger' - , './ProfileStore' - , './Room' - , './Template' - , './Ui/Log' - , './Ui/MessageStream' - , './Ui/MessageActions/Delete' - ], function (console, Bottle, Core, Message, Messenger, ProfileStore, Room, Template, Ui, UiMessageStream, UiMessageActionDelete) { - "use strict"; +define([ + './console', + 'Bastelstu.be/bottle', + 'WoltLabSuite/Core/Core', + './Message', + './Messenger', + './ProfileStore', + './Room', + './Template', + './Ui/Log', + './Ui/MessageStream', + './Ui/MessageActions/Delete', +], function ( + console, + Bottle, + Core, + Message, + Messenger, + ProfileStore, + Room, + Template, + Ui, + UiMessageStream, + UiMessageActionDelete +) { + 'use strict' const loader = Symbol('loader') @@ -31,10 +44,10 @@ define([ './console' constructor(params, config) { console.debug('ChatLog.constructor', 'Constructing …') - this.config = config + this.config = config this.sessionID = Core.getUuid() - this.bottle = new Bottle() + this.bottle = new Bottle() this.bottle.value('bottle', this.bottle) this.bottle.value('config', config) this.bottle.constant('sessionID', this.sessionID) @@ -56,36 +69,45 @@ define([ './console' }) // Register Templates - const selector = [ '[type="x-text/template"]' - , '[data-application="be.bastelstu.chat"]' - , '[data-template-name]' - ].join('') + const selector = [ + '[type="x-text/template"]', + '[data-application="be.bastelstu.chat"]', + '[data-template-name]', + ].join('') const templates = elBySelAll(selector) - templates.forEach((function (template) { - this.bottle.factory(`Template.${elData(template, 'template-name')}`, function (container) { - const includeNames = (elData(template, 'template-includes') || '').split(/ /).filter(item => item !== "") - const includes = { } - includeNames.forEach(item => includes[item] = container[item]) + templates.forEach( + function (template) { + this.bottle.factory( + `Template.${elData(template, 'template-name')}`, + function (container) { + const includeNames = (elData(template, 'template-includes') || '') + .split(/ /) + .filter((item) => item !== '') + const includes = {} + includeNames.forEach((item) => (includes[item] = container[item])) - return new Template(template.textContent, includes) - }) - }).bind(this)) + return new Template(template.textContent, includes) + } + ) + }.bind(this) + ) // Register MessageTypes const messageTypes = Object.entries(this.config.messageTypes) - messageTypes.forEach(([ objectType, messageType ]) => { + messageTypes.forEach(([objectType, messageType]) => { const MessageType = require(messageType.module) - this.bottle.factory(`MessageType.${objectType.replace(/\./g, '-')}`, _ => { - const deps = this.bottle.digest(MessageType.DEPENDENCIES || []) + this.bottle.factory( + `MessageType.${objectType.replace(/\./g, '-')}`, + (_) => { + const deps = this.bottle.digest(MessageType.DEPENDENCIES || []) - return new MessageType(...deps, objectType) - }) + return new MessageType(...deps, objectType) + } + ) }) - this.knows = { from: undefined - , to: undefined - } + this.knows = { from: undefined, to: undefined } this.messageSinks = new Set() @@ -94,9 +116,11 @@ define([ './console' this.pulling = false } - service(name, _constructor, args = [ ]) { + service(name, _constructor, args = []) { this.bottle.factory(name, function (container) { - const deps = (_constructor.DEPENDENCIES || [ ]).map(dep => container[dep]) + const deps = (_constructor.DEPENDENCIES || []).map( + (dep) => container[dep] + ) return new _constructor(...deps, ...args) }) @@ -111,20 +135,34 @@ define([ './console' this.registerMessageSink(this.bottle.container.UiMessageStream) if (this.params.messageID > 0) { - await Promise.all([ this.pull(undefined, this.params.messageID) - , this.pull(this.params.messageID + 1) - ]) - } - else { + await Promise.all([ + this.pull(undefined, this.params.messageID), + this.pull(this.params.messageID + 1), + ]) + } else { await this.pull() } - this.bottle.container.UiMessageStream.on('nearTop', this.pullOlder.bind(this)) - this.bottle.container.UiMessageStream.on('reachedTop', this.pullOlder.bind(this)) - this.bottle.container.UiMessageStream.on('nearBottom', this.pullNewer.bind(this)) - this.bottle.container.UiMessageStream.on('reachedBottom', this.pullNewer.bind(this)) + this.bottle.container.UiMessageStream.on( + 'nearTop', + this.pullOlder.bind(this) + ) + this.bottle.container.UiMessageStream.on( + 'reachedTop', + this.pullOlder.bind(this) + ) + this.bottle.container.UiMessageStream.on( + 'nearBottom', + this.pullNewer.bind(this) + ) + this.bottle.container.UiMessageStream.on( + 'reachedBottom', + this.pullNewer.bind(this) + ) - const element = document.querySelector(`#message-${this.params.messageID}`) + const element = document.querySelector( + `#message-${this.params.messageID}` + ) // Force changing the hash to trigger a new lookup of the element. // At least Chrome won’t target an element if it is not in the DOM @@ -152,8 +190,7 @@ define([ './console' async pull(from, to) { try { await this.handlePull(await this.performPull(from, to)) - } - catch (e) { + } catch (e) { this.handleError(e) } } @@ -180,7 +217,12 @@ define([ './console' } async performPull(from = undefined, to = undefined) { - console.debug('ChatLog.performPull', `Pulling new messages; from: ${from !== undefined ? from : 'undefined'}, to: ${to !== undefined ? to : 'undefined'}`) + console.debug( + 'ChatLog.performPull', + `Pulling new messages; from: ${ + from !== undefined ? from : 'undefined' + }, to: ${to !== undefined ? to : 'undefined'}` + ) return this.bottle.container.Messenger.pull(from, to, true) } @@ -199,25 +241,35 @@ define([ './console' let messages = payload.messages if (this.knows.from !== undefined && this.knows.to !== undefined) { - messages = messages.filter((function (message) { - return !(this.knows.from <= message.messageID && message.messageID <= this.knows.to) - }).bind(this)) + messages = messages.filter( + function (message) { + return !( + this.knows.from <= message.messageID && + message.messageID <= this.knows.to + ) + }.bind(this) + ) } - if (this.knows.from === undefined || payload.from < this.knows.from) this.knows.from = payload.from - if (this.knows.to === undefined || payload.to > this.knows.to) this.knows.to = payload.to + if (this.knows.from === undefined || payload.from < this.knows.from) + this.knows.from = payload.from + if (this.knows.to === undefined || payload.to > this.knows.to) + this.knows.to = payload.to - await Promise.all(messages.map((message) => { - return message.getMessageType().preProcess(message) - })) + await Promise.all( + messages.map((message) => { + return message.getMessageType().preProcess(message) + }) + ) - const userIDs = messages.map(message => message.userID) - .filter(userID => userID !== null) + const userIDs = messages + .map((message) => message.userID) + .filter((userID) => userID !== null) await this.bottle.container.ProfileStore.ensureUsersByIDs(userIDs) - this.messageSinks.forEach(sink => sink.ingest(messages)) + this.messageSinks.forEach((sink) => sink.ingest(messages)) } } return Log -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Message.js b/files_wcf/js/Bastelstu.be/Chat/Message.js index 31d4b2c..87e804a 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Message.js +++ b/files_wcf/js/Bastelstu.be/Chat/Message.js @@ -11,13 +11,14 @@ * or later of the General Public License. */ -define([ './Helper' - , 'WoltLabSuite/Core/Date/Util' - , 'WoltLabSuite/Core/User' - ], function (Helper, DateUtil, User) { - "use strict"; +define([ + './Helper', + 'WoltLabSuite/Core/Date/Util', + 'WoltLabSuite/Core/User', +], function (Helper, DateUtil, User) { + 'use strict' - const m = Symbol('message') + const m = Symbol('message') class Message { constructor(MessageType, message) { @@ -87,4 +88,4 @@ define([ './Helper' } return Message -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType.js b/files_wcf/js/Bastelstu.be/Chat/MessageType.js index 9e57e18..db4f2e9 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType.js @@ -11,14 +11,15 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Date/Util' - , 'WoltLabSuite/Core/Language' - , 'WoltLabSuite/Core/Dom/Util' - , 'Bastelstu.be/Chat/User' - ], function (DateUtil, Language, DomUtil, User) { - "use strict"; +define([ + 'WoltLabSuite/Core/Date/Util', + 'WoltLabSuite/Core/Language', + 'WoltLabSuite/Core/Dom/Util', + 'Bastelstu.be/Chat/User', +], function (DateUtil, Language, DomUtil, User) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore', 'Template' ] + const DEPENDENCIES = ['ProfileStore', 'Template'] class MessageType { constructor(profileStore, templates, objectType) { this.profileStore = profileStore @@ -32,32 +33,31 @@ define([ 'WoltLabSuite/Core/Date/Util' } getReferencedUsers(message) { - if (message.userID === null) return [ ] + if (message.userID === null) return [] - return [ message.userID ] + return [message.userID] } - preProcess(message) { + preProcess(message) {} - } - - preRender(message) { - - } + preRender(message) {} render(message) { - const variables = { message - , users: this.profileStore - , author: this.profileStore.get(message.userID) - , DateUtil - , Language - } + const variables = { + message, + users: this.profileStore, + author: this.profileStore.get(message.userID), + DateUtil, + Language, + } if (variables.author == null) { variables.author = User.getGuest(message.username) } - return DomUtil.createFragmentFromHtml(this.templates[message.objectType.replace(/\./g, '-')].fetch(variables)) + return DomUtil.createFragmentFromHtml( + this.templates[message.objectType.replace(/\./g, '-')].fetch(variables) + ) } renderPlainText(message) { @@ -71,4 +71,4 @@ define([ 'WoltLabSuite/Core/Date/Util' MessageType.DEPENDENCIES = DEPENDENCIES return MessageType -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Away.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Away.js index 6772539..a4f23a8 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Away.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Away.js @@ -11,10 +11,12 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore', 'roomID' ].concat(MessageType.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['ProfileStore', 'roomID'].concat( + MessageType.DEPENDENCIES || [] + ) class Away extends MessageType { constructor(profileStore, roomID, ...superDeps) { super(...superDeps) @@ -24,12 +26,13 @@ define([ '../MessageType' ], function (MessageType) { } render(message) { - const isSilent = message.payload.rooms.find(room => room.roomID === this.roomID).isSilent + const isSilent = message.payload.rooms.find( + (room) => room.roomID === this.roomID + ).isSilent if (!isSilent) { return super.render(message) - } - else { + } else { return false } } @@ -45,4 +48,4 @@ define([ '../MessageType' ], function (MessageType) { Away.DEPENDENCIES = DEPENDENCIES return Away -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Back.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Back.js index 5be126a..c9a747b 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Back.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Back.js @@ -11,10 +11,12 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore', 'roomID' ].concat(MessageType.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['ProfileStore', 'roomID'].concat( + MessageType.DEPENDENCIES || [] + ) class Back extends MessageType { constructor(profileStore, roomID, ...superDeps) { super(...superDeps) @@ -24,12 +26,13 @@ define([ '../MessageType' ], function (MessageType) { } render(message) { - const isSilent = message.payload.rooms.find(room => room.roomID === this.roomID).isSilent + const isSilent = message.payload.rooms.find( + (room) => room.roomID === this.roomID + ).isSilent if (!isSilent) { return super.render(message) - } - else { + } else { return false } } @@ -45,4 +48,4 @@ define([ '../MessageType' ], function (MessageType) { Back.DEPENDENCIES = DEPENDENCIES return Back -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Broadcast.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Broadcast.js index e75c34c..8afe1be 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Broadcast.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Broadcast.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ './Plain' ], function (Plain) { - "use strict"; +define(['./Plain'], function (Plain) { + 'use strict' class Broadcast extends Plain { renderPlainText(message) { @@ -21,4 +21,4 @@ define([ './Plain' ], function (Plain) { } return Broadcast -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/ChatUpdate.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/ChatUpdate.js index f8cbcfa..fc6ac7a 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/ChatUpdate.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/ChatUpdate.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' class ChatUpdate extends MessageType { preRender(message) { @@ -25,4 +25,4 @@ define([ '../MessageType' ], function (MessageType) { } return ChatUpdate -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Color.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Color.js index e0ed75d..ccfa4a7 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Color.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Color.js @@ -11,15 +11,14 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' class Color extends MessageType { render(message) { if (message.isOwnMessage()) { return super.render(message) - } - else { + } else { return false } } @@ -34,4 +33,4 @@ define([ '../MessageType' ], function (MessageType) { } return Color -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Info.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Info.js index 833dea9..cfafabc 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Info.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Info.js @@ -11,12 +11,13 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Dom/Traverse' - , 'WoltLabSuite/Core/Language' - , '../Helper' - , '../MessageType' - ], function (DomTraverse, Language, Helper, MessageType) { - "use strict"; +define([ + 'WoltLabSuite/Core/Dom/Traverse', + 'WoltLabSuite/Core/Language', + '../Helper', + '../MessageType', +], function (DomTraverse, Language, Helper, MessageType) { + 'use strict' const decorators = Symbol('decorators') @@ -36,16 +37,19 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' } getReferencedUsers(message) { - return super.getReferencedUsers(message).concat([ message.payload.user.userID ]) + return super + .getReferencedUsers(message) + .concat([message.payload.user.userID]) } render(message) { const rooms = message.payload.rooms.map(function (item) { - const aug = { lastPull: null - , lastPullHTML: null - , lastPush: null - , lastPushHTML: null - } + const aug = { + lastPull: null, + lastPullHTML: null, + lastPush: null, + lastPushHTML: null, + } if (item.lastPull) { aug.lastPull = new Date(item.lastPull * 1000) @@ -57,28 +61,35 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' aug.lastPushHTML = Helper.getTimeElementHTML(aug.lastPush) } - return Object.assign({ }, item, aug) + return Object.assign({}, item, aug) }) const payload = Helper.deepFreeze( - Array.from(this[decorators]).reduce( (payload, decorator) => decorator(payload) - , Object.assign({ }, message.payload, { rooms }) - ) + Array.from(this[decorators]).reduce( + (payload, decorator) => decorator(payload), + Object.assign({}, message.payload, { rooms }) + ) ) - const fragment = super.render(new Proxy(message, { - get: function (target, property) { - if (property === 'payload') return payload - return target[property] - } - })) + const fragment = super.render( + new Proxy(message, { + get: function (target, property) { + if (property === 'payload') return payload + return target[property] + }, + }) + ) const icon = elCreate('span') icon.classList.add('icon', 'icon16', 'fa-times', 'jsTooltip', 'hideIcon') icon.setAttribute('title', Language.get('wcf.global.button.hide')) - icon.addEventListener('click', () => elHide(DomTraverse.parentBySel(icon, '.chatMessageBoundary'))) + icon.addEventListener('click', () => + elHide(DomTraverse.parentBySel(icon, '.chatMessageBoundary')) + ) - const elem = fragment.querySelector('.chatMessage .containerList > li:first-child .containerHeadline') + const elem = fragment.querySelector( + '.chatMessage .containerList > li:first-child .containerHeadline' + ) elem.insertBefore(icon, elem.firstChild) return fragment @@ -86,4 +97,4 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' } return Info -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Join.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Join.js index f0562cd..82dd6bb 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Join.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Join.js @@ -11,8 +11,11 @@ * or later of the General Public License. */ -define([ '../MessageType', 'WoltLabSuite/Core/Language' ], function (MessageType, Language) { - "use strict"; +define(['../MessageType', 'WoltLabSuite/Core/Language'], function ( + MessageType, + Language +) { + 'use strict' class Join extends MessageType { shouldUpdateUserList(message) { @@ -20,9 +23,15 @@ define([ '../MessageType', 'WoltLabSuite/Core/Language' ], function (MessageType } renderPlainText(message) { - return '[➡️] ' + Language.get('chat.messageType.be.bastelstu.chat.messageType.join.plain', { author: { username: message.username } }) + return ( + '[➡️] ' + + Language.get( + 'chat.messageType.be.bastelstu.chat.messageType.join.plain', + { author: { username: message.username } } + ) + ) } } return Join -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Leave.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Leave.js index 3a11d52..55253eb 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Leave.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Leave.js @@ -11,8 +11,11 @@ * or later of the General Public License. */ -define([ '../MessageType', 'WoltLabSuite/Core/Language' ], function (MessageType, Language) { - "use strict"; +define(['../MessageType', 'WoltLabSuite/Core/Language'], function ( + MessageType, + Language +) { + 'use strict' class Leave extends MessageType { shouldUpdateUserList(message) { @@ -20,9 +23,15 @@ define([ '../MessageType', 'WoltLabSuite/Core/Language' ], function (MessageType } renderPlainText(message) { - return '[⬅️️] ' + Language.get('chat.messageType.be.bastelstu.chat.messageType.leave.plain', { author: { username: message.username } }) + return ( + '[⬅️️] ' + + Language.get( + 'chat.messageType.be.bastelstu.chat.messageType.leave.plain', + { author: { username: message.username } } + ) + ) } } return Leave -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Me.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Me.js index ec678e8..3809584 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Me.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Me.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' - class Me extends MessageType { - - } + class Me extends MessageType {} return Me -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Plain.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Plain.js index 143ce7f..6f92344 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Plain.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Plain.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' class Plain extends MessageType { joinable(a, b) { @@ -25,4 +25,4 @@ define([ '../MessageType' ], function (MessageType) { } return Plain -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Suspend.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Suspend.js index 1b1c090..3ca66b6 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Suspend.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Suspend.js @@ -11,28 +11,35 @@ * or later of the General Public License. */ -define([ '../Helper' - , 'WoltLabSuite/Core/Date/Util' - , '../MessageType' - ], function (Helper, DateUtil, MessageType) { - "use strict"; +define([ + '../Helper', + 'WoltLabSuite/Core/Date/Util', + '../MessageType', +], function (Helper, DateUtil, MessageType) { + 'use strict' class Suspend extends MessageType { render(message) { - const expires = message.payload.suspension.expires !== null ? new Date(message.payload.suspension.expires * 1000) : null - const formattedExpires = expires !== null ? DateUtil.formatDateTime(expires) : null - const aug = { expires - , formattedExpires - } - const suspension = Object.assign({ }, message.payload.suspension, aug) - const payload = Helper.deepFreeze(Object.assign({ }, message.payload, { suspension })) + const expires = + message.payload.suspension.expires !== null + ? new Date(message.payload.suspension.expires * 1000) + : null + const formattedExpires = + expires !== null ? DateUtil.formatDateTime(expires) : null + const aug = { expires, formattedExpires } + const suspension = Object.assign({}, message.payload.suspension, aug) + const payload = Helper.deepFreeze( + Object.assign({}, message.payload, { suspension }) + ) - return super.render(new Proxy(message, { - get: function (target, property) { - if (property === 'payload') return payload - return target[property] - } - })) + return super.render( + new Proxy(message, { + get: function (target, property) { + if (property === 'payload') return payload + return target[property] + }, + }) + ) } shouldUpdateUserList(message) { @@ -41,4 +48,4 @@ define([ '../Helper' } return Suspend -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Team.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Team.js index c3e23b4..4f0f65a 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Team.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Team.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ './Plain' ], function (Plain) { - "use strict"; +define(['./Plain'], function (Plain) { + 'use strict' class Team extends Plain { joinable(a, b) { @@ -25,4 +25,4 @@ define([ './Plain' ], function (Plain) { } return Team -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomCreated.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomCreated.js index 1f452b1..853ee0a 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomCreated.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomCreated.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' - class TemproomCreated extends MessageType { - - } + class TemproomCreated extends MessageType {} return TemproomCreated -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomInvited.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomInvited.js index a4888bf..9b25c5f 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomInvited.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/TemproomInvited.js @@ -11,12 +11,10 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' - class TemproomInvited extends MessageType { - - } + class TemproomInvited extends MessageType {} return TemproomInvited -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Tombstone.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Tombstone.js index 3f3a67d..560da57 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Tombstone.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Tombstone.js @@ -11,10 +11,12 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' - const DEPENDENCIES = [ 'UiMessageStream' ].concat(MessageType.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['UiMessageStream'].concat( + MessageType.DEPENDENCIES || [] + ) class Tombstone extends MessageType { constructor(messageStream, ...superDeps) { super(...superDeps) @@ -37,17 +39,21 @@ define([ '../MessageType' ], function (MessageType) { if (!chatMessage) return false const rendered = super.render(message) - const oldIcon = node.querySelector('.chatMessageContent > .chatMessageIcon') + const oldIcon = node.querySelector( + '.chatMessageContent > .chatMessageIcon' + ) const newIcon = rendered.querySelector('.chatMessageIcon') if (oldIcon) { oldIcon.parentNode.replaceChild(newIcon, oldIcon) - } - else { + } else { chatMessage.parentNode.insertBefore(newIcon, chatMessage) } - chatMessage.parentNode.replaceChild(rendered.querySelector('.chatMessage'), chatMessage) + chatMessage.parentNode.replaceChild( + rendered.querySelector('.chatMessage'), + chatMessage + ) return false } @@ -55,4 +61,4 @@ define([ '../MessageType' ], function (MessageType) { Tombstone.DEPENDENCIES = DEPENDENCIES return Tombstone -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Unsuspend.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Unsuspend.js index 909f7de..2c664e1 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Unsuspend.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Unsuspend.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ '../MessageType' ], function (MessageType) { - "use strict"; +define(['../MessageType'], function (MessageType) { + 'use strict' class Unsuspend extends MessageType { shouldUpdateUserList(message) { @@ -21,4 +21,4 @@ define([ '../MessageType' ], function (MessageType) { } return Unsuspend -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Where.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Where.js index 772d7b2..c336409 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Where.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Where.js @@ -11,11 +11,12 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Dom/Traverse' - , 'WoltLabSuite/Core/Language' - , '../MessageType' - ], function (DomTraverse, Language, MessageType) { - "use strict"; +define([ + 'WoltLabSuite/Core/Dom/Traverse', + 'WoltLabSuite/Core/Language', + '../MessageType', +], function (DomTraverse, Language, MessageType) { + 'use strict' class Where extends MessageType { render(message) { @@ -24,7 +25,9 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' const icon = elCreate('span') icon.classList.add('icon', 'icon16', 'fa-times', 'jsTooltip', 'hideIcon') icon.setAttribute('title', Language.get('wcf.global.button.hide')) - icon.addEventListener('click', () => elHide(DomTraverse.parentBySel(icon, '.chatMessageBoundary'))) + icon.addEventListener('click', () => + elHide(DomTraverse.parentBySel(icon, '.chatMessageBoundary')) + ) const elem = fragment.querySelector('.jsRoomInfo > .containerHeadline') elem.insertBefore(icon, elem.firstChild) @@ -34,4 +37,4 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' } return Where -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/MessageType/Whisper.js b/files_wcf/js/Bastelstu.be/Chat/MessageType/Whisper.js index 6df0f06..ce3febf 100644 --- a/files_wcf/js/Bastelstu.be/Chat/MessageType/Whisper.js +++ b/files_wcf/js/Bastelstu.be/Chat/MessageType/Whisper.js @@ -11,10 +11,10 @@ * or later of the General Public License. */ -define([ './Plain' ], function (Plain) { - "use strict"; +define(['./Plain'], function (Plain) { + 'use strict' - const DEPENDENCIES = [ 'UiInput' ].concat(Plain.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['UiInput'].concat(Plain.DEPENDENCIES || []) class Whisper extends Plain { constructor(input, ...superDeps) { super(...superDeps) @@ -26,28 +26,39 @@ define([ './Plain' ], function (Plain) { const fragment = super.render(message) if (this.input != null) { - Array.prototype.forEach.call(fragment.querySelectorAll('[data-insert-whisper]'), (function (el) { - el.addEventListener('click', (function () { - const username = el.dataset.insertWhisper - const sanitizedUsername = username.replace(/"/g, '""') - const command = `/whisper "${sanitizedUsername}"` + Array.prototype.forEach.call( + fragment.querySelectorAll('[data-insert-whisper]'), + function (el) { + el.addEventListener( + 'click', + function () { + const username = el.dataset.insertWhisper + const sanitizedUsername = username.replace(/"/g, '""') + const command = `/whisper "${sanitizedUsername}"` - if (this.input.getText().indexOf(command) !== 0) { - this.input.insertText(`${command} `, { prepend: true, append: false }) - this.input.focus() - } - }).bind(this)) - }).bind(this)) + if (this.input.getText().indexOf(command) !== 0) { + this.input.insertText(`${command} `, { + prepend: true, + append: false, + }) + this.input.focus() + } + }.bind(this) + ) + }.bind(this) + ) } return fragment } joinable(a, b) { - return a.userID === b.userID && a.payload.recipient === b.payload.recipient + return ( + a.userID === b.userID && a.payload.recipient === b.payload.recipient + ) } } Whisper.DEPENDENCIES = DEPENDENCIES return Whisper -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Messenger.js b/files_wcf/js/Bastelstu.be/Chat/Messenger.js index a1a1696..bee6082 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Messenger.js +++ b/files_wcf/js/Bastelstu.be/Chat/Messenger.js @@ -11,16 +11,18 @@ * or later of the General Public License. */ -define([ './console' - , 'Bastelstu.be/PromiseWrap/Ajax' - , './Room' - ], function (console, Ajax, Room) { - "use strict"; +define(['./console', 'Bastelstu.be/PromiseWrap/Ajax', './Room'], function ( + console, + Ajax, + Room +) { + 'use strict' - const DEPENDENCIES = [ 'sessionID', 'Room', 'Message' ] + const DEPENDENCIES = ['sessionID', 'Room', 'Message'] class Messenger { constructor(sessionID, room, Message) { - if (!(room instanceof Room)) throw new TypeError('You must pass a Room to the Messenger') + if (!(room instanceof Room)) + throw new TypeError('You must pass a Room to the Messenger') this.sessionID = sessionID this.room = room @@ -30,9 +32,7 @@ define([ './console' async pull(from = 0, to = 0, inLog = false) { console.debug(`Messenger.pull`, 'from', from, 'to', to, 'inLog', inLog) - const payload = { actionName: 'pull' - , parameters: { inLog } - } + const payload = { actionName: 'pull', parameters: { inLog } } if (from !== 0 && to !== 0) { throw new Error('You must not set both from and to') } @@ -40,42 +40,41 @@ define([ './console' if (to !== 0) payload.parameters.to = to const data = await Ajax.api(this, payload) - const messages = Object.values(data.returnValues.messages).map((item) => this.Message.instance(item)) + const messages = Object.values(data.returnValues.messages).map((item) => + this.Message.instance(item) + ) const { from: newFrom, to: newTo } = data.returnValues return { messages, from: newFrom, to: newTo } } async push({ commandID, parameters }) { - const payload = { actionName: 'push' - , parameters: { commandID - , parameters: JSON.stringify(parameters) - } - } + const payload = { + actionName: 'push', + parameters: { commandID, parameters: JSON.stringify(parameters) }, + } return Ajax.api(this, payload) } async pushAttachment(tmpHash) { - const payload = { actionName: 'pushAttachment' - , parameters: { tmpHash } - } + const payload = { actionName: 'pushAttachment', parameters: { tmpHash } } return Ajax.api(this, payload) } _ajaxSetup() { - return { silent: true - , ignoreError: true - , data: { className: 'chat\\data\\message\\MessageAction' - , parameters: { roomID: this.room.roomID - , sessionID: this.sessionID - } - } - } + return { + silent: true, + ignoreError: true, + data: { + className: 'chat\\data\\message\\MessageAction', + parameters: { roomID: this.room.roomID, sessionID: this.sessionID }, + }, + } } } Messenger.DEPENDENCIES = DEPENDENCIES return Messenger -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/ParseError.js b/files_wcf/js/Bastelstu.be/Chat/ParseError.js index da7a5a5..cec45ca 100644 --- a/files_wcf/js/Bastelstu.be/Chat/ParseError.js +++ b/files_wcf/js/Bastelstu.be/Chat/ParseError.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' class ParseError extends Error { constructor(message, data) { @@ -23,4 +23,4 @@ define([ ], function () { } return ParseError -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Parser.js b/files_wcf/js/Bastelstu.be/Chat/Parser.js index cf62f6f..1fde5bb 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Parser.js +++ b/files_wcf/js/Bastelstu.be/Chat/Parser.js @@ -11,88 +11,112 @@ * or later of the General Public License. */ -define([ 'Bastelstu.be/parser-combinator' - ], function (parsec) { - "use strict"; +define(['Bastelstu.be/parser-combinator'], function (parsec) { + 'use strict' const { C, F, N, X, parser, Streams } = parsec const response = parsec.parsec.response const peek = function (p) { return new parser((input, index = 0) => - p - .parse(input, index) - .fold( - accept => response.accept(accept.value, accept.input, index, false), - reject => response.reject(input.location(reject.offset), false) + p.parse(input, index).fold( + (accept) => response.accept(accept.value, accept.input, index, false), + (reject) => response.reject(input.location(reject.offset), false) ) - ); + ) } - const Whitespace = F.satisfy(item => /\s/.test(item)) + const Whitespace = F.satisfy((item) => /\s/.test(item)) - const Rest = F.any.optrep().map(item => item.join('')) - const Rest1 = F.any.rep().map(item => item.join('')) + const Rest = F.any.optrep().map((item) => item.join('')) + const Rest1 = F.any.rep().map((item) => item.join('')) - const AlnumTrigger = C.letter.or(N.digit).rep().map(item => item.join('')) - const SymbolicTrigger = F.not(C.letter.or(N.digit).or(Whitespace)).rep().map(item => item.join('')) + const AlnumTrigger = C.letter + .or(N.digit) + .rep() + .map((item) => item.join('')) + const SymbolicTrigger = F.not(C.letter.or(N.digit).or(Whitespace)) + .rep() + .map((item) => item.join('')) const Slash = C.char('/') const Trigger = Slash.thenRight( - peek(Slash.map(item => null)).or(AlnumTrigger.thenLeft(Whitespace.rep().or(F.eos))).or(SymbolicTrigger.thenLeft(Whitespace.optrep())) + peek(Slash.map((item) => null)) + .or(AlnumTrigger.thenLeft(Whitespace.rep().or(F.eos))) + .or(SymbolicTrigger.thenLeft(Whitespace.optrep())) ).or(F.returns(null)) const Command = Trigger.then(Rest) const Quote = C.char('"') const QuotedUsername = Quote.thenRight( - ((Quote.thenRight(Quote)).or(F.not(Quote))).rep() - ).thenLeft(Quote).map(item => item.join('')) + Quote.thenRight(Quote).or(F.not(Quote)).rep() + ) + .thenLeft(Quote) + .map((item) => item.join('')) const Comma = C.char(',') - const UnquotedUsername = F.not(Comma.or(Quote).or(Whitespace)).then(F.not(Comma.or(Whitespace)).optrep().map(item => item.join(''))).map(item => item.join('')) + const UnquotedUsername = F.not(Comma.or(Quote).or(Whitespace)) + .then( + F.not(Comma.or(Whitespace)) + .optrep() + .map((item) => item.join('')) + ) + .map((item) => item.join('')) const Username = QuotedUsername.or(UnquotedUsername) - const Decimal = (length) => N.digit.occurrence(length).map(item => parseInt(item.join(''), 10)) + const Decimal = (length) => + N.digit.occurrence(length).map((item) => parseInt(item.join(''), 10)) const Hexadecimal = N.digit .or(C.charIn('abcdefABCDEF')) .rep() - .map(x => x.join('')) + .map((x) => x.join('')) - const RGBHex = (C.char('#').opt()) + const RGBHex = C.char('#') + .opt() .thenRight( - Hexadecimal.filter(x => x.length === 3 || x.length === 6) - .map(item => { - if (item.length === 3) { - item = `${item[0]}${item[0]}${item[1]}${item[1]}${item[2]}${item[2]}` - } + Hexadecimal.filter((x) => x.length === 3 || x.length === 6).map( + (item) => { + if (item.length === 3) { + item = `${item[0]}${item[0]}${item[1]}${item[1]}${item[2]}${item[2]}` + } - return item - }) - ).map(item => `#${item}`) + return item + } + ) + ) + .map((item) => `#${item}`) const Dash = C.char('-') - const Datestring = Decimal(4).filter(item => 2000 <= item && item <= 2030) - .thenLeft(Dash).then(Decimal(2).filter(item => 1 <= item && item <= 12)) - .thenLeft(Dash).then(Decimal(2).filter(item => 1 <= item)) + const Datestring = Decimal(4) + .filter((item) => 2000 <= item && item <= 2030) + .thenLeft(Dash) + .then(Decimal(2).filter((item) => 1 <= item && item <= 12)) + .thenLeft(Dash) + .then(Decimal(2).filter((item) => 1 <= item)) const Colon = C.char(':') - const Timestring = Decimal(2).filter(item => 0 <= item && item <= 23) - .thenLeft(Colon).then(Decimal(2).filter(item => 0 <= item && item <= 59)) - .thenLeft(Colon).then(Decimal(2).filter(item => 0 <= item && item <= 59)) + const Timestring = Decimal(2) + .filter((item) => 0 <= item && item <= 23) + .thenLeft(Colon) + .then(Decimal(2).filter((item) => 0 <= item && item <= 59)) + .thenLeft(Colon) + .then(Decimal(2).filter((item) => 0 <= item && item <= 59)) - const ISODate = Datestring.then(C.char('T').thenRight(Timestring).opt()).map(function ([ year, month, day, time ]) { - const date = new Date() - date.setFullYear(year) - date.setMonth(month - 1) - date.setDate(day) + const ISODate = Datestring.then(C.char('T').thenRight(Timestring).opt()).map( + function ([year, month, day, time]) { + const date = new Date() + date.setFullYear(year) + date.setMonth(month - 1) + date.setDate(day) - time.map(function ([ hour, minute, second ]) { - date.setHours(hour) - date.setMinutes(minute) - date.setSeconds(second) - }) + time.map(function ([hour, minute, second]) { + date.setHours(hour) + date.setMinutes(minute) + date.setSeconds(second) + }) - return date - }) + return date + } + ) return { Streams, @@ -122,4 +146,4 @@ define([ 'Bastelstu.be/parser-combinator' N, X, } -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/ProfileStore.js b/files_wcf/js/Bastelstu.be/Chat/ProfileStore.js index 62998cd..fb785d6 100644 --- a/files_wcf/js/Bastelstu.be/Chat/ProfileStore.js +++ b/files_wcf/js/Bastelstu.be/Chat/ProfileStore.js @@ -11,14 +11,15 @@ * or later of the General Public License. */ -define([ 'Bastelstu.be/PromiseWrap/Ajax' - , './DataStructure/LRU' - , './User' - , 'WoltLabSuite/Core/User' - ], function (Ajax, LRU, User, CoreUser) { - "use strict"; +define([ + 'Bastelstu.be/PromiseWrap/Ajax', + './DataStructure/LRU', + './User', + 'WoltLabSuite/Core/User', +], function (Ajax, LRU, User, CoreUser) { + 'use strict' - const DEPENDENCIES = [ ] + const DEPENDENCIES = [] /** * ProfileStore stores information about users. */ @@ -40,44 +41,47 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' */ async ensureUsersByIDs(userIDs) { // Dedup - userIDs = userIDs.filter((value, index, self) => self.indexOf(value) === index) - .map(userID => parseInt(userID, 10)) + userIDs = userIDs + .filter((value, index, self) => self.indexOf(value) === index) + .map((userID) => parseInt(userID, 10)) - const missing = [ ] - const promises = [ ] - userIDs.forEach((function (userID) { - if (this.isRecent(userID)) return - if (this.processing.has(userID)) { - promises.push(this.processing.get(userID)) - return - } - missing.push(userID) - }).bind(this)) + const missing = [] + const promises = [] + userIDs.forEach( + function (userID) { + if (this.isRecent(userID)) return + if (this.processing.has(userID)) { + promises.push(this.processing.get(userID)) + return + } + missing.push(userID) + }.bind(this) + ) if (missing.length > 0) { - const payload = { actionName: 'getUsersByID' - , parameters: { userIDs: missing } - } - const request = (async _ => { + const payload = { + actionName: 'getUsersByID', + parameters: { userIDs: missing }, + } + const request = (async (_) => { try { const response = await Ajax.api(this, payload) - return Object.entries(response.returnValues).forEach(([ userID, user ]) => { - userID = parseInt(userID, 10) - const data = { user: new User(user) - , date: Date.now() - } - this.users.set(userID, data) - this.processing.delete(userID) - }) - } - catch (err) { - missing.forEach(userID => this.processing.delete(userID)) + return Object.entries(response.returnValues).forEach( + ([userID, user]) => { + userID = parseInt(userID, 10) + const data = { user: new User(user), date: Date.now() } + this.users.set(userID, data) + this.processing.delete(userID) + } + ) + } catch (err) { + missing.forEach((userID) => this.processing.delete(userID)) throw err } })() - missing.forEach(userID => this.processing.set(userID, request)) + missing.forEach((userID) => this.processing.set(userID, request)) promises.push(request) } @@ -93,7 +97,7 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' async getUsersByIDs(userIDs) { await this.ensureUsersByIDs(userIDs) - return new Map(userIDs.map(userID => [ userID, this.get(userID) ])) + return new Map(userIDs.map((userID) => [userID, this.get(userID)])) } /** @@ -157,7 +161,7 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' const user = this.users.get(userID) if (user != null) { - return user.date > (Date.now() - (5 * 60e3)) + return user.date > Date.now() - 5 * 60e3 } return false @@ -169,7 +173,7 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' * @returns {User[]} */ values() { - return Array.from(this.users.values()).map(item => item.user) + return Array.from(this.users.values()).map((item) => item.user) } pushLastActivity(userID) { @@ -178,18 +182,19 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' this.lastActivity.add(userID) } - * getLastActivity() { - yield * this.lastActivity + *getLastActivity() { + yield* this.lastActivity } _ajaxSetup() { - return { silent: true - , ignoreError: true - , data: { className: 'chat\\data\\user\\UserAction' } - } + return { + silent: true, + ignoreError: true, + data: { className: 'chat\\data\\user\\UserAction' }, + } } } ProfileStore.DEPENDENCIES = DEPENDENCIES return ProfileStore -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Room.js b/files_wcf/js/Bastelstu.be/Chat/Room.js index 0e19153..66ba6c3 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Room.js +++ b/files_wcf/js/Bastelstu.be/Chat/Room.js @@ -11,20 +11,21 @@ * or later of the General Public License. */ -define([ 'Bastelstu.be/PromiseWrap/Ajax' - , 'WoltLabSuite/Core/Core' - , './User' - ], function (Ajax, Core, User) { - "use strict"; +define([ + 'Bastelstu.be/PromiseWrap/Ajax', + 'WoltLabSuite/Core/Core', + './User', +], function (Ajax, Core, User) { + 'use strict' - const DEPENDENCIES = [ 'sessionID', 'roomID' ] + const DEPENDENCIES = ['sessionID', 'roomID'] /** * Represents a chat room. */ class Room { constructor(sessionID, roomID) { this.sessionID = sessionID - this.roomID = roomID + this.roomID = roomID } /** @@ -33,12 +34,11 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' * @returns {Promise} */ async join() { - const payload = { className: 'chat\\data\\room\\RoomAction' - , actionName: 'join' - , parameters: { roomID: this.roomID - , sessionID: this.sessionID - } - } + const payload = { + className: 'chat\\data\\room\\RoomAction', + actionName: 'join', + parameters: { roomID: this.roomID, sessionID: this.sessionID }, + } return Ajax.api(this, payload) } @@ -49,12 +49,11 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' * @param {boolean} unload Send a beacon if true'ish and a regular AJAX request otherwise. */ leave(unload = false) { - const payload = { className: 'chat\\data\\room\\RoomAction' - , actionName: 'leave' - , parameters: { roomID: this.roomID - , sessionID: this.sessionID - } - } + const payload = { + className: 'chat\\data\\room\\RoomAction', + actionName: 'leave', + parameters: { roomID: this.roomID, sessionID: this.sessionID }, + } if (unload && FormData && (navigator.sendBeacon || window.fetch)) { // Ordinary AJAX requests are unreliable during unload: @@ -65,22 +64,26 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' const formData = new FormData() Core.serialize(payload) - .split('&') - .map((item) => item.split('=')) - .map((item) => item.map(decodeURIComponent)) - .forEach((item) => formData.append(item[0], item[1])) + .split('&') + .map((item) => item.split('=')) + .map((item) => item.map(decodeURIComponent)) + .forEach((item) => formData.append(item[0], item[1])) if (navigator.sendBeacon) { navigator.sendBeacon(url, formData) } if (window.fetch) { - fetch(url, { method: 'POST', keepalive: true, redirect: 'follow', body: formData }) + fetch(url, { + method: 'POST', + keepalive: true, + redirect: 'follow', + body: formData, + }) } return Promise.resolve() - } - else { + } else { return Ajax.api(this, payload) } } @@ -91,23 +94,22 @@ define([ 'Bastelstu.be/PromiseWrap/Ajax' * @returns {Promise} */ async getUsers() { - const payload = { className: 'chat\\data\\room\\RoomAction' - , actionName: 'getUsers' - , objectIDs: [ this.roomID ] - } + const payload = { + className: 'chat\\data\\room\\RoomAction', + actionName: 'getUsers', + objectIDs: [this.roomID], + } const result = await Ajax.api(this, payload) - return Object.values(result.returnValues).map(user => new User(user)) + return Object.values(result.returnValues).map((user) => new User(user)) } _ajaxSetup() { - return { silent: true - , ignoreError: true - } + return { silent: true, ignoreError: true } } } Room.DEPENDENCIES = DEPENDENCIES return Room -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Template.js b/files_wcf/js/Bastelstu.be/Chat/Template.js index b9ae41c..b4f7bbd 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Template.js +++ b/files_wcf/js/Bastelstu.be/Chat/Template.js @@ -11,30 +11,30 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Template' ], function (_Template) { - "use strict"; +define(['WoltLabSuite/Core/Template'], function (_Template) { + 'use strict' /** * Template extends WoltLab Suite's Templates by passing in a list of * re-usable sub-templates. */ class Template extends _Template { - constructor(string, templates = { }) { + constructor(string, templates = {}) { super(string) this.templates = templates const oldFetch = this.fetch - this.fetch = (function (variables) { - variables = Object.assign({ }, variables) + this.fetch = function (variables) { + variables = Object.assign({}, variables) - const templates = Object.assign({ }, this.templates, variables.t || { }) + const templates = Object.assign({}, this.templates, variables.t || {}) variables.t = templates return oldFetch(variables) - }).bind(this) + }.bind(this) } } return Template -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui.js b/files_wcf/js/Bastelstu.be/Chat/Ui.js index 4170f48..4bc0a74 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui.js @@ -11,13 +11,12 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' class Ui { - constructor() { - } + constructor() {} } return Ui -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Attachment/Upload.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Attachment/Upload.js index a7e7776..1f51577 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Attachment/Upload.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Attachment/Upload.js @@ -11,30 +11,42 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Language' - , 'WoltLabSuite/Core/Upload' - , 'WoltLabSuite/Core/Dom/Change/Listener' - , 'WoltLabSuite/Core/Dom/Util' - , 'WoltLabSuite/Core/Ui/Dialog' - , '../../DataStructure/EventEmitter' - ], function(Language, Upload, DomChangeListener, DomUtil, Dialog, EventEmitter) { - "use strict"; +define([ + 'WoltLabSuite/Core/Language', + 'WoltLabSuite/Core/Upload', + 'WoltLabSuite/Core/Dom/Change/Listener', + 'WoltLabSuite/Core/Dom/Util', + 'WoltLabSuite/Core/Ui/Dialog', + '../../DataStructure/EventEmitter', +], function ( + Language, + Upload, + DomChangeListener, + DomUtil, + Dialog, + EventEmitter +) { + 'use strict' - const DIALOG_BUTTON_ID = 'chatAttachmentUploadButton' + const DIALOG_BUTTON_ID = 'chatAttachmentUploadButton' const DIALOG_CONTAINER_ID = 'chatAttachmentUploadDialog' - const DEPENDENCIES = [ 'UiInput', 'Room' ]; + const DEPENDENCIES = ['UiInput', 'Room'] class UiAttachmentUpload extends Upload { constructor(input, room) { - const buttonContainer = document.querySelector(`#${DIALOG_CONTAINER_ID} > .upload`) + const buttonContainer = document.querySelector( + `#${DIALOG_CONTAINER_ID} > .upload` + ) const buttonContainerId = DomUtil.identify(buttonContainer) - const previewContainer = document.querySelector(`#${DIALOG_CONTAINER_ID} > .attachmentPreview`) + const previewContainer = document.querySelector( + `#${DIALOG_CONTAINER_ID} > .attachmentPreview` + ) const previewContainerId = DomUtil.identify(previewContainer) super(buttonContainerId, previewContainerId, { className: 'wcf\\data\\attachment\\AttachmentAction', - acceptableFiles: [ '.png', '.gif', '.jpg', '.jpeg' ] + acceptableFiles: ['.png', '.gif', '.jpg', '.jpeg'], }) this.input = input @@ -44,7 +56,9 @@ define([ 'WoltLabSuite/Core/Language' } bootstrap() { - this.uploadDescription = document.querySelector(`#${DIALOG_CONTAINER_ID} > small`) + this.uploadDescription = document.querySelector( + `#${DIALOG_CONTAINER_ID} > small` + ) const button = document.getElementById(DIALOG_BUTTON_ID) const container = document.getElementById(DIALOG_CONTAINER_ID) @@ -59,18 +73,20 @@ define([ 'WoltLabSuite/Core/Language' Dialog.openStatic(container.id, null, { title: elData(container, 'title'), - onShow: () => this.showDialog() + onShow: () => this.showDialog(), }) }) - const deleteAction = new WCF.Action.Delete('wcf\\data\\attachment\\AttachmentAction', `#${this.previewContainer.id} > p`) + const deleteAction = new WCF.Action.Delete( + 'wcf\\data\\attachment\\AttachmentAction', + `#${this.previewContainer.id} > p` + ) deleteAction.setCallback(() => this.closeDialog()) this.input.on('input', (event) => { if (event.target.input.value.length == 0) { button.classList.remove('disabled') - } - else { + } else { button.classList.add('disabled') } }) @@ -95,16 +111,13 @@ define([ 'WoltLabSuite/Core/Language' async send(tmpHash, event) { event.preventDefault() - const parameters = { promise: Promise.resolve() - , tmpHash - } + const parameters = { promise: Promise.resolve(), tmpHash } this.emit('send', parameters) try { await parameters.promise this.closeDialog() - } - catch (error) { + } catch (error) { // TODO: Error handling console.error(error) } @@ -141,14 +154,15 @@ define([ 'WoltLabSuite/Core/Language' * @see WoltLabSuite/Core/Upload#_getParameters */ _getParameters() { - this.tmpHash = [ ...crypto.getRandomValues(new Uint8Array(20)) ] - .map(m => ('0' + m.toString(16)).slice(-2)) + this.tmpHash = [...crypto.getRandomValues(new Uint8Array(20))] + .map((m) => ('0' + m.toString(16)).slice(-2)) .join('') - return { objectType: "be.bastelstu.chat.message" - , parentObjectID: this.room.roomID - , tmpHash: this.tmpHash - } + return { + objectType: 'be.bastelstu.chat.message', + parentObjectID: this.room.roomID, + tmpHash: this.tmpHash, + } } /** @@ -158,22 +172,28 @@ define([ 'WoltLabSuite/Core/Language' if (data.returnValues.errors && data.returnValues.errors[0]) { const error = data.returnValues.errors[0] - elInnerError(this._button, Language.get(`wcf.attachment.upload.error.${error.errorType}`, { - filename: error.filename - })) + elInnerError( + this._button, + Language.get(`wcf.attachment.upload.error.${error.errorType}`, { + filename: error.filename, + }) + ) return - } - else { + } else { elInnerError(this._button, '') } - if (data.returnValues.attachments && data.returnValues.attachments[uploadId]) { + if ( + data.returnValues.attachments && + data.returnValues.attachments[uploadId] + ) { this._removeButton() elHide(this.uploadDescription) const attachment = data.returnValues.attachments[uploadId] - const url = attachment.thumbnailURL || attachment.tinyURL || attachment.url + const url = + attachment.thumbnailURL || attachment.tinyURL || attachment.url if (!url) { throw new Error('Missing image URL') @@ -188,8 +208,7 @@ define([ 'WoltLabSuite/Core/Language' if (url === attachment.thumbnailURL) { img.classList.add('attachmentThumbnail') - } - else if (url === attachment.tinyURL) { + } else if (url === attachment.tinyURL) { img.classList.add('attachmentTinyThumbnail') } @@ -199,9 +218,8 @@ define([ 'WoltLabSuite/Core/Language' DomUtil.replaceElement(progress, img) this.createButtonGroup(uploadId, attachment.attachmentID, this.tmpHash) - } - else { - console.error("Received neither an error nor an attachment response") + } else { + console.error('Received neither an error nor an attachment response') console.error(data.returnValues) } } diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/AutoAway.js b/files_wcf/js/Bastelstu.be/Chat/Ui/AutoAway.js index fc9bb86..448cd6f 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/AutoAway.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/AutoAway.js @@ -11,25 +11,46 @@ * or later of the General Public License. */ -define([ '../console' - , '../CommandHandler' - , '../LocalStorage' - , '../Messenger' - , '../ProfileStore' - , 'WoltLabSuite/Core/Language' - , 'WoltLabSuite/Core/Timer/Repeating' - ], function (console, CommandHandler, LocalStorage, Messenger, ProfileStore, Language, RepeatingTimer) { - "use strict"; +define([ + '../console', + '../CommandHandler', + '../LocalStorage', + '../Messenger', + '../ProfileStore', + 'WoltLabSuite/Core/Language', + 'WoltLabSuite/Core/Timer/Repeating', +], function ( + console, + CommandHandler, + LocalStorage, + Messenger, + ProfileStore, + Language, + RepeatingTimer +) { + 'use strict' - const DEPENDENCIES = [ 'config', 'CommandHandler', 'Messenger', 'ProfileStore', 'UiInput' ] + const DEPENDENCIES = [ + 'config', + 'CommandHandler', + 'Messenger', + 'ProfileStore', + 'UiInput', + ] class AutoAway { constructor(config, commandHandler, messenger, profileStore, input) { - if (!(commandHandler instanceof CommandHandler)) throw new TypeError('You must pass a CommandHandler to the AutoAway') - if (!(messenger instanceof Messenger)) throw new TypeError('You must pass a Messenger to the AutoAway') - if (!(profileStore instanceof ProfileStore)) throw new TypeError('You must pass a ProfileStore to the AutoAway') + if (!(commandHandler instanceof CommandHandler)) + throw new TypeError('You must pass a CommandHandler to the AutoAway') + if (!(messenger instanceof Messenger)) + throw new TypeError('You must pass a Messenger to the AutoAway') + if (!(profileStore instanceof ProfileStore)) + throw new TypeError('You must pass a ProfileStore to the AutoAway') this.storage = new LocalStorage('AutoAway.') - this.awayCommand = commandHandler.getCommandByIdentifier('be.bastelstu.chat', 'away') + this.awayCommand = commandHandler.getCommandByIdentifier( + 'be.bastelstu.chat', + 'away' + ) if (this.awayCommand == null) { throw new Error('Unreachable') } @@ -47,16 +68,22 @@ define([ '../console' return } - this.timer = new RepeatingTimer(this.setAway.bind(this), this.config.autoAwayTime * 60e3) - this.input.on('input', this.inputListener = (event) => { - this.storage.set('channel', Date.now()) - this.reset() - }) + this.timer = new RepeatingTimer( + this.setAway.bind(this), + this.config.autoAwayTime * 60e3 + ) + this.input.on( + 'input', + (this.inputListener = (event) => { + this.storage.set('channel', Date.now()) + this.reset() + }) + ) this.storage.observe('channel', this.reset.bind(this)) } - + ingest(messages) { - if (messages.some(message => message.isOwnMessage())) this.reset() + if (messages.some((message) => message.isOwnMessage())) this.reset() } reset() { @@ -70,8 +97,11 @@ define([ '../console' async setAway() { console.debug('AutoAway.setAway', `Attempting to set as away`) - if (this.storage.get('setAway') >= (Date.now() - 10e3)) { - console.debug('AutoAway.setAway', `setAway called within the last 10 seconds in another Tab`) + if (this.storage.get('setAway') >= Date.now() - 10e3) { + console.debug( + 'AutoAway.setAway', + `setAway called within the last 10 seconds in another Tab` + ) return } this.storage.set('setAway', Date.now()) @@ -81,10 +111,13 @@ define([ '../console' return } - this.messenger.push({ commandID: this.awayCommand.id, parameters: { reason: Language.get('chat.user.autoAway') } }) + this.messenger.push({ + commandID: this.awayCommand.id, + parameters: { reason: Language.get('chat.user.autoAway') }, + }) } } AutoAway.DEPENDENCIES = DEPENDENCIES return AutoAway -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Chat.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Chat.js index 79f20c4..da6e014 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Chat.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Chat.js @@ -11,42 +11,58 @@ * or later of the General Public License. */ -define([ '../Ui' ], function (Ui) { - "use strict"; +define(['../Ui'], function (Ui) { + 'use strict' - const DEPENDENCIES = [ 'UiAttachmentUpload' - , 'UiAutoAway' - , 'UiConnectionWarning' - , 'UiInput' - , 'UiInputAutocompleter' - , 'UiMessageActionDelete' - , 'UiMessageStream' - , 'UiMobile' - , 'UiNotification' - , 'UiReadMarker' - , 'UiSettings' - , 'UiTopic' - , 'UiUserActionDropdownHandler' - , 'UiUserList' - ] + const DEPENDENCIES = [ + 'UiAttachmentUpload', + 'UiAutoAway', + 'UiConnectionWarning', + 'UiInput', + 'UiInputAutocompleter', + 'UiMessageActionDelete', + 'UiMessageStream', + 'UiMobile', + 'UiNotification', + 'UiReadMarker', + 'UiSettings', + 'UiTopic', + 'UiUserActionDropdownHandler', + 'UiUserList', + ] class Chat extends Ui { - constructor(attachmentUpload, autoAway, connectionWarning, input, autocompleter, messageActionDelete, messageStream, mobile, notification, readMarker, settings, topic, userActionDropdownHandler, userList) { + constructor( + attachmentUpload, + autoAway, + connectionWarning, + input, + autocompleter, + messageActionDelete, + messageStream, + mobile, + notification, + readMarker, + settings, + topic, + userActionDropdownHandler, + userList + ) { super() this.actionDropdownHandler = userActionDropdownHandler - this.attachmentUpload = attachmentUpload - this.autoAway = autoAway - this.autocompleter = autocompleter - this.connectionWarning = connectionWarning - this.input = input - this.messageActionDelete = messageActionDelete - this.messageStream = messageStream - this.mobile = mobile - this.notification = notification - this.readMarker = readMarker - this.settings = settings - this.topic = topic - this.userList = userList + this.attachmentUpload = attachmentUpload + this.autoAway = autoAway + this.autocompleter = autocompleter + this.connectionWarning = connectionWarning + this.input = input + this.messageActionDelete = messageActionDelete + this.messageStream = messageStream + this.mobile = mobile + this.notification = notification + this.readMarker = readMarker + this.settings = settings + this.topic = topic + this.userList = userList } bootstrap() { @@ -69,4 +85,4 @@ define([ '../Ui' ], function (Ui) { Chat.DEPENDENCIES = DEPENDENCIES return Chat -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/ConnectionWarning.js b/files_wcf/js/Bastelstu.be/Chat/Ui/ConnectionWarning.js index 5966d64..a94bc65 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/ConnectionWarning.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/ConnectionWarning.js @@ -11,25 +11,22 @@ * or later of the General Public License. */ -define([ '../console' - ], function (console) { - "use strict"; +define(['../console'], function (console) { + 'use strict' class ConnectionWarning { constructor() { this.warning = elById('chatConnectionWarning') } - bootstrap() { - - } + bootstrap() {} show() { elShow(this.warning) if (this.timeout) return console.debug('ConnectionWarning.show', 'Setting timeout') - this.timeout = setTimeout(_ => { + this.timeout = setTimeout((_) => { console.debug('ConnectionWarning.show', 'Timeout has passed') this.timeout = undefined @@ -44,9 +41,11 @@ define([ '../console' if (!this.timeout || force) { elHide(this.warning) window.clearTimeout(this.timeout) - } - else { - console.debug('ConnectionWarning.hide', 'Automatically hiding after timeout has passed') + } else { + console.debug( + 'ConnectionWarning.hide', + 'Automatically hiding after timeout has passed' + ) this.autoHide = true } } @@ -57,4 +56,4 @@ define([ '../console' } return ConnectionWarning -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/ErrorDialog.js b/files_wcf/js/Bastelstu.be/Chat/Ui/ErrorDialog.js index 3d5b0f2..c02bfa2 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/ErrorDialog.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/ErrorDialog.js @@ -11,28 +11,31 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Language' - , 'WoltLabSuite/Core/Template' - , 'WoltLabSuite/Core/Ui/Dialog' - ], function (Language, Template, UiDialog) { - "use strict"; +define([ + 'WoltLabSuite/Core/Language', + 'WoltLabSuite/Core/Template', + 'WoltLabSuite/Core/Ui/Dialog', +], function (Language, Template, UiDialog) { + 'use strict' - const html = [ '[type="x-text/template"]' - , '[data-application="be.bastelstu.chat"]' - , '[data-template-name="be-bastelstu-chat-errorDialog"]' - ].join('') + const html = [ + '[type="x-text/template"]', + '[data-application="be.bastelstu.chat"]', + '[data-template-name="be-bastelstu-chat-errorDialog"]', + ].join('') const wrapper = new Template(elBySel(html).textContent) class ErrorDialog { constructor(message) { - const options = { title: Language.get('wcf.global.error.title') - , closable: false - } + const options = { + title: Language.get('wcf.global.error.title'), + closable: false, + } UiDialog.openStatic('chatError', wrapper.fetch({ message }), options) } } return ErrorDialog -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Input.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Input.js index ebcfa12..6dfec90 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Input.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Input.js @@ -11,21 +11,22 @@ * or later of the General Public License. */ -define([ '../console' - , '../Helper' - , 'WoltLabSuite/Core/Core' - , 'WoltLabSuite/Core/Event/Key' - , '../DataStructure/EventEmitter' - , '../DataStructure/Throttle' - ], function (console, Helper, Core, EventKey, EventEmitter, Throttle) { - "use strict"; +define([ + '../console', + '../Helper', + 'WoltLabSuite/Core/Core', + 'WoltLabSuite/Core/Event/Key', + '../DataStructure/EventEmitter', + '../DataStructure/Throttle', +], function (console, Helper, Core, EventKey, EventEmitter, Throttle) { + 'use strict' class Input { constructor() { this.inputContainer = elById('chatInputContainer') - this.input = elBySel('textarea', this.inputContainer) - this.charCounter = elBySel('.charCounter', this.inputContainer) - this.errorElement = elBySel('.innerError', this.inputContainer) + this.input = elBySel('textarea', this.inputContainer) + this.charCounter = elBySel('.charCounter', this.inputContainer) + this.errorElement = elBySel('.innerError', this.inputContainer) } bootstrap() { @@ -34,21 +35,29 @@ define([ '../console' } this.input.addEventListener('keydown', this.handleInputKeyDown.bind(this)) - this.input.addEventListener('input', Throttle(this.handleInput.bind(this))) + this.input.addEventListener( + 'input', + Throttle(this.handleInput.bind(this)) + ) Helper.makeFlexible(this.input) this.handleInput() } handleInput(event) { - this.charCounter.textContent = `${this.input.value.length} / ${this.input.getAttribute('maxlength')}` + this.charCounter.textContent = `${ + this.input.value.length + } / ${this.input.getAttribute('maxlength')}` this.emit('input') } handleInputKeyDown(event) { if (EventKey.Enter(event) && !event.shiftKey) { if (event.isComposing) { - console.debug('Ui/Input.handleInputKeyDown', 'Ignored Enter key while composing characters.') + console.debug( + 'Ui/Input.handleInputKeyDown', + 'Ignored Enter key while composing characters.' + ) return } @@ -62,8 +71,7 @@ define([ '../console' if (!parameters.cancel) { this.emit('submit') } - } - else if (EventKey.Tab(event)) { + } else if (EventKey.Tab(event)) { // prevent leaving the input event.preventDefault() @@ -92,9 +100,7 @@ define([ '../console' insertText(text, options) { this.focus() - options = Object.assign({ append: true - , prepend: false - }, options) + options = Object.assign({ append: true, prepend: false }, options) if (!(options.append || options.prepend)) { // replace @@ -102,11 +108,11 @@ define([ '../console' } if (options.append) { - this.input.value += text; + this.input.value += text } if (options.prepend) { - this.input.value = text + this.input.value; + this.input.value = text + this.input.value } // always position caret at the end @@ -119,8 +125,7 @@ define([ '../console' inputError(message) { if (typeof window.elInnerError === 'function') { elInnerError(this.inputContainer.firstElementChild, message) - } - else { + } else { this.inputContainer.classList.add('formError') this.errorElement.textContent = message elShow(this.errorElement) @@ -130,8 +135,7 @@ define([ '../console' hideInputError() { if (typeof window.elInnerError === 'function') { elInnerError(this.inputContainer.firstElementChild, false) - } - else { + } else { this.inputContainer.classList.remove('formError') this.errorElement.textContent = '' elHide(this.errorElement) @@ -141,4 +145,4 @@ define([ '../console' EventEmitter(Input.prototype) return Input -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Input/Autocompleter.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Input/Autocompleter.js index ed990e1..29d3158 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Input/Autocompleter.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Input/Autocompleter.js @@ -11,17 +11,21 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Dom/Util' - , 'WoltLabSuite/Core/Event/Key' - , 'WoltLabSuite/Core/Ui/Suggestion' - ], function (DomUtil, EventKey, Suggestion) { - "use strict"; +define([ + 'WoltLabSuite/Core/Dom/Util', + 'WoltLabSuite/Core/Event/Key', + 'WoltLabSuite/Core/Ui/Suggestion', +], function (DomUtil, EventKey, Suggestion) { + 'use strict' - const DEPENDENCIES = [ 'UiInput' ] + const DEPENDENCIES = ['UiInput'] class Autocompleter extends Suggestion { constructor(input) { const elementId = DomUtil.identify(input.input) - const options = { callbackSelect: (_elementId, selection) => this.insertSelection(selection) } + const options = { + callbackSelect: (_elementId, selection) => + this.insertSelection(selection), + } super(elementId, options) @@ -76,11 +80,9 @@ define([ 'WoltLabSuite/Core/Dom/Util' sendCompletions(completions) { this.completions = new Map() - const returnValues = completions.map(completion => { + const returnValues = completions.map((completion) => { this.completions.set(++this.completionId, completion) - return { label: completion - , objectID: this.completionId - } + return { label: completion, objectID: this.completionId } }) this._ajaxSuccess({ returnValues }) @@ -89,4 +91,4 @@ define([ 'WoltLabSuite/Core/Dom/Util' Autocompleter.DEPENDENCIES = DEPENDENCIES return Autocompleter -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Log.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Log.js index b3b231c..caec08b 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Log.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Log.js @@ -11,10 +11,10 @@ * or later of the General Public License. */ -define([ '../Ui' ], function (Ui) { - "use strict"; +define(['../Ui'], function (Ui) { + 'use strict' - const DEPENDENCIES = [ 'UiMessageStream', 'UiMessageActionDelete' ] + const DEPENDENCIES = ['UiMessageStream', 'UiMessageActionDelete'] class Log extends Ui { constructor(messageStream, messageActionDelete) { super() @@ -32,4 +32,4 @@ define([ '../Ui' ], function (Ui) { Log.DEPENDENCIES = DEPENDENCIES return Log -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/MessageActions/Delete.js b/files_wcf/js/Bastelstu.be/Chat/Ui/MessageActions/Delete.js index d9554f0..9345ee5 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/MessageActions/Delete.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/MessageActions/Delete.js @@ -11,10 +11,14 @@ * or later of the General Public License. */ -define([ 'Bastelstu.be/Chat/Message', 'Bastelstu.be/PromiseWrap/Ajax', 'Bastelstu.be/PromiseWrap/Ui/Confirmation' ], function (Message, Ajax, Confirmation) { - "use strict"; +define([ + 'Bastelstu.be/Chat/Message', + 'Bastelstu.be/PromiseWrap/Ajax', + 'Bastelstu.be/PromiseWrap/Ui/Confirmation', +], function (Message, Ajax, Confirmation) { + 'use strict' - const DEPENDENCIES = [ 'UiMessageStream', 'Message' ] + const DEPENDENCIES = ['UiMessageStream', 'Message'] class Delete { constructor(messageStream, message) { this.messageStream = messageStream @@ -26,19 +30,19 @@ define([ 'Bastelstu.be/Chat/Message', 'Bastelstu.be/PromiseWrap/Ajax', 'Bastelst } bindListener({ detail }) { - detail.forEach(item => { + detail.forEach((item) => { if (!item) return const { node, message } = item const button = node.querySelector('.jsDeleteButton') if (!button) return - button.addEventListener('click', async event => { + button.addEventListener('click', async (event) => { event.preventDefault() await Confirmation.show({ message: button.dataset.confirmMessageHtml, - messageIsHtml: true + messageIsHtml: true, }) await this.delete(message.messageID) @@ -50,31 +54,31 @@ define([ 'Bastelstu.be/Chat/Message', 'Bastelstu.be/PromiseWrap/Ajax', 'Bastelst async delete(messageID) { { - const payload = { objectIDs: [ messageID ] } + const payload = { objectIDs: [messageID] } await Ajax.api(this, payload) } { const objectType = 'be.bastelstu.chat.messageType.tombstone' - const payload = { messageID - , userID: null - } + const payload = { messageID, userID: null } const message = this.Message.instance({ objectType, payload }) message.getMessageType().render(message) } } _ajaxSetup() { - return { silent: true - , ignoreError: true - , data: { className: 'chat\\data\\message\\MessageAction' - , actionName: 'trash' - } - } + return { + silent: true, + ignoreError: true, + data: { + className: 'chat\\data\\message\\MessageAction', + actionName: 'trash', + }, + } } } Delete.DEPENDENCIES = DEPENDENCIES return Delete -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/MessageStream.js b/files_wcf/js/Bastelstu.be/Chat/Ui/MessageStream.js index 86d9214..259474b 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/MessageStream.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/MessageStream.js @@ -11,29 +11,39 @@ * or later of the General Public License. */ -define([ '../Helper' - , 'WoltLabSuite/Core/Date/Util' - , 'WoltLabSuite/Core/Dom/Change/Listener' - , 'WoltLabSuite/Core/Language' - , 'WoltLabSuite/Core/User' - , 'WoltLabSuite/Core/Dom/Traverse' - , '../DataStructure/EventEmitter' - , '../DataStructure/RedBlackTree/Tree' - ], function (Helper, DateUtil, DomChangeListener, Language, User, DOMTraverse, EventEmitter, Tree) { - "use strict"; +define([ + '../Helper', + 'WoltLabSuite/Core/Date/Util', + 'WoltLabSuite/Core/Dom/Change/Listener', + 'WoltLabSuite/Core/Language', + 'WoltLabSuite/Core/User', + 'WoltLabSuite/Core/Dom/Traverse', + '../DataStructure/EventEmitter', + '../DataStructure/RedBlackTree/Tree', +], function ( + Helper, + DateUtil, + DomChangeListener, + Language, + User, + DOMTraverse, + EventEmitter, + Tree +) { + 'use strict' const enableAutoscroll = Symbol('enableAutoscroll') - const DEPENDENCIES = [ ] + const DEPENDENCIES = [] class MessageStream { constructor() { this.stream = elById('chatMessageStream') this.scrollContainer = elBySel('.scrollContainer', this.stream) - this[enableAutoscroll] = true + this[enableAutoscroll] = true this.lastScrollPosition = undefined - this.nodeMap = new WeakMap() - this.positions = new Tree() + this.nodeMap = new WeakMap() + this.positions = new Tree() } get enableAutoscroll() { @@ -50,7 +60,11 @@ define([ '../Helper' bootstrap() { this.scrollContainer.addEventListener('copy', this.onCopy.bind(this)) - this.scrollContainer.addEventListener('scroll', Helper.throttle(this.onScroll, 100, this), { passive: true }) + this.scrollContainer.addEventListener( + 'scroll', + Helper.throttle(this.onScroll, 100, this), + { passive: true } + ) } getDateMarker(date) { @@ -69,123 +83,131 @@ define([ '../Helper' } ingest(messages) { - let scrollTopBefore = this.enableAutoscroll ? 0 : this.scrollContainer.scrollTop + let scrollTopBefore = this.enableAutoscroll + ? 0 + : this.scrollContainer.scrollTop let prependedHeight = 0 - const ul = elBySel('ul', this.scrollContainer) + const ul = elBySel('ul', this.scrollContainer) const first = ul.firstElementChild - const ingested = messages.map((function (item) { - let currentScrollHeight = 0 + const ingested = messages.map( + function (item) { + let currentScrollHeight = 0 - const li = elCreate('li') + const li = elCreate('li') - // Allow messages types to not render a messages - // This can be used for status messages like ChatUpdate - let fragment - if ((fragment = item.getMessageType().render(item)) === false) return + // Allow messages types to not render a messages + // This can be used for status messages like ChatUpdate + let fragment + if ((fragment = item.getMessageType().render(item)) === false) return - if (fragment.querySelector(`.userMention[data-user-id="${User.userId}"]`)) li.classList.add('mentioned') + if ( + fragment.querySelector( + `.userMention[data-user-id="${User.userId}"]` + ) + ) + li.classList.add('mentioned') - li.appendChild(fragment) + li.appendChild(fragment) - li.classList.add('chatMessageBoundary') - li.setAttribute('id', `message-${item.messageID}`) - li.dataset.objectType = item.objectType - li.dataset.userId = item.userID - if (item.isOwnMessage()) li.classList.add('own') - if (item.isDeleted) li.classList.add('tombstone') + li.classList.add('chatMessageBoundary') + li.setAttribute('id', `message-${item.messageID}`) + li.dataset.objectType = item.objectType + li.dataset.userId = item.userID + if (item.isOwnMessage()) li.classList.add('own') + if (item.isDeleted) li.classList.add('tombstone') - const position = this.positions.insert(item.messageID) - if (position[1] !== undefined) { - const sibling = elById(`message-${position[1]}`) - if (!sibling) throw new Error('Unreachable') + const position = this.positions.insert(item.messageID) + if (position[1] !== undefined) { + const sibling = elById(`message-${position[1]}`) + if (!sibling) throw new Error('Unreachable') - let nodeBefore, nodeAfter - let dateMarkerBetween = false - if (position[0] === 'LEFT') { - nodeAfter = sibling - nodeBefore = sibling.previousElementSibling - - if (nodeBefore && nodeBefore.classList.contains('dateMarker')) { - elRemove(nodeBefore) + let nodeBefore, nodeAfter + let dateMarkerBetween = false + if (position[0] === 'LEFT') { + nodeAfter = sibling nodeBefore = sibling.previousElementSibling - } - } - else if (position[0] === 'RIGHT') { - nodeBefore = sibling - nodeAfter = sibling.nextElementSibling - if (nodeAfter && nodeAfter.classList.contains('dateMarker')) { - elRemove(nodeAfter) + if (nodeBefore && nodeBefore.classList.contains('dateMarker')) { + elRemove(nodeBefore) + nodeBefore = sibling.previousElementSibling + } + } else if (position[0] === 'RIGHT') { + nodeBefore = sibling nodeAfter = sibling.nextElementSibling + + if (nodeAfter && nodeAfter.classList.contains('dateMarker')) { + elRemove(nodeAfter) + nodeAfter = sibling.nextElementSibling + } + } else { + throw new Error('Unreachable') } - } - else { - throw new Error('Unreachable') - } - const messageBefore = this.nodeMap.get(nodeBefore) - if (nodeBefore && !messageBefore) throw new Error('Unreachable') - const messageAfter = this.nodeMap.get(nodeAfter) - if (nodeAfter && !messageAfter) throw new Error('Unreachable') + const messageBefore = this.nodeMap.get(nodeBefore) + if (nodeBefore && !messageBefore) throw new Error('Unreachable') + const messageAfter = this.nodeMap.get(nodeAfter) + if (nodeAfter && !messageAfter) throw new Error('Unreachable') - if (!this.enableAutoscroll && nodeAfter) currentScrollHeight = this.scrollContainer.scrollHeight + if (!this.enableAutoscroll && nodeAfter) + currentScrollHeight = this.scrollContainer.scrollHeight - let context = nodeAfter - if (nodeAfter) nodeAfter.classList.remove('first') - if (messageBefore) { - if (this.onDifferentDays(messageBefore.date, item.date)) { - const dateMarker = this.getDateMarker(item.date) - ul.insertBefore(dateMarker, nodeAfter) + let context = nodeAfter + if (nodeAfter) nodeAfter.classList.remove('first') + if (messageBefore) { + if (this.onDifferentDays(messageBefore.date, item.date)) { + const dateMarker = this.getDateMarker(item.date) + ul.insertBefore(dateMarker, nodeAfter) + li.classList.add('first') + } else { + if ( + messageBefore.objectType !== item.objectType || + !item.getMessageType().joinable(messageBefore, item) + ) { + li.classList.add('first') + } + } + } else { li.classList.add('first') } - else { - if (messageBefore.objectType !== item.objectType || !item.getMessageType().joinable(messageBefore, item)) { - li.classList.add('first') - } - } - } - else { - li.classList.add('first') - } - if (messageAfter) { - if (this.onDifferentDays(messageAfter.date, item.date)) { - const dateMarker = this.getDateMarker(messageAfter.date) - ul.insertBefore(dateMarker, nodeAfter) - context = dateMarker - nodeAfter.classList.add('first') - } - else { - if (messageAfter.objectType !== item.objectType || !item.getMessageType().joinable(item, messageAfter)) { + if (messageAfter) { + if (this.onDifferentDays(messageAfter.date, item.date)) { + const dateMarker = this.getDateMarker(messageAfter.date) + ul.insertBefore(dateMarker, nodeAfter) + context = dateMarker nodeAfter.classList.add('first') + } else { + if ( + messageAfter.objectType !== item.objectType || + !item.getMessageType().joinable(item, messageAfter) + ) { + nodeAfter.classList.add('first') + } } } + + ul.insertBefore(li, context) + + if (!this.enableAutoscroll && nodeAfter) { + prependedHeight += + this.scrollContainer.scrollHeight - currentScrollHeight + } + } else { + li.classList.add('first') + ul.insertBefore(li, null) } - ul.insertBefore(li, context); + this.nodeMap.set(li, item) - if (!this.enableAutoscroll && nodeAfter) { - prependedHeight += this.scrollContainer.scrollHeight - currentScrollHeight - } - } - else { - li.classList.add('first') - ul.insertBefore(li, null) - } + return { node: li, message: item } + }.bind(this) + ) - this.nodeMap.set(li, item) - - return { node: li - , message: item - } - }).bind(this)); - - if (ingested.some(item => item != null)) { + if (ingested.some((item) => item != null)) { if (this.enableAutoscroll) { this.scrollToBottom() - } - else { + } else { this.stream.classList.add('activity') this.scrollContainer.scrollTop = scrollTopBefore + prependedHeight } @@ -208,8 +230,11 @@ define([ '../Helper' let direction = 'down' - if (this.lastScrollPosition != null && scrollTop < this.lastScrollPosition) { - direction = 'up' + if ( + this.lastScrollPosition != null && + scrollTop < this.lastScrollPosition + ) { + direction = 'up' } if (direction === 'up') { @@ -219,12 +244,10 @@ define([ '../Helper' if (distanceFromTop <= 7) { this.emit('reachedTop') - } - else if (distanceFromTop <= 300) { + } else if (distanceFromTop <= 300) { this.emit('nearTop') } - } - else if (direction === 'down') { + } else if (direction === 'down') { if (distanceFromTop > 7) { this.emit('scrollDown') } @@ -232,8 +255,7 @@ define([ '../Helper' if (distanceFromBottom <= 7) { this.scrollToBottom() this.emit('reachedBottom') - } - else if (distanceFromBottom <= 300) { + } else if (distanceFromBottom <= 300) { this.emit('nearBottom') } } @@ -250,16 +272,19 @@ define([ '../Helper' // Get the first and last node in the selection let originalStart, start, end, originalEnd start = originalStart = selection.getRangeAt(0).startContainer - end = originalEnd = selection.getRangeAt(selection.rangeCount - 1).endContainer + end = originalEnd = selection.getRangeAt(selection.rangeCount - 1) + .endContainer const startOffset = selection.getRangeAt(0).startOffset - const endOffset = selection.getRangeAt(selection.rangeCount - 1).endOffset + const endOffset = selection.getRangeAt(selection.rangeCount - 1).endOffset // The Traverse module needs nodes of the Element type, the selected elements could be of type Text - while (!(start instanceof Element) && start.parentNode) start = start.parentNode + while (!(start instanceof Element) && start.parentNode) + start = start.parentNode while (!(end instanceof Element) && end.parentNode) end = end.parentNode - if (!start || !end) throw new Error('Unexpected error, no element nodes in selection') + if (!start || !end) + throw new Error('Unexpected error, no element nodes in selection') // Try to find the starting li element in the selection if (!start.id || start.id.indexOf('message-') !== 0) { @@ -272,7 +297,10 @@ define([ '../Helper' } // Do not select a message if we selected only a new line - if (originalStart instanceof Text && originalStart.textContent.substring(startOffset) === "") { + if ( + originalStart instanceof Text && + originalStart.textContent.substring(startOffset) === '' + ) { start = DOMTraverse.next(start) } @@ -289,15 +317,14 @@ define([ '../Helper' end = DOMTraverse.prev(end) } - const elements = [ ] - let next = start + const elements = [] + let next = start do { elements.push(next) if (next === end) break - } - while (next = DOMTraverse.next(next)) + } while ((next = DOMTraverse.next(next))) // Only apply our custom formatting when selecting multiple or whole messages if (elements.length === 1) { @@ -305,37 +332,59 @@ define([ '../Helper' range.setStart(originalStart, startOffset) range.setEnd(originalEnd, endOffset) - if (!Helper.rangeSpansTextContent(range, start.querySelector('.chatMessage'))) return + if ( + !Helper.rangeSpansTextContent( + range, + start.querySelector('.chatMessage') + ) + ) + return } try { - event.clipboardData.setData('text/plain', elements.map((el, index, arr) => { - const message = this.nodeMap.get(el) + event.clipboardData.setData( + 'text/plain', + elements + .map((el, index, arr) => { + const message = this.nodeMap.get(el) - if (el.classList.contains('dateMarker')) return `== ${el.textContent.trim()} ==` + if (el.classList.contains('dateMarker')) + return `== ${el.textContent.trim()} ==` - if (!message) return + if (!message) return - if (el.classList.contains('tombstone')) { - return `[${message.formattedTime}] ${Language.get('chat.messageType.be.bastelstu.chat.messageType.tombstone.message')}` - } + if (el.classList.contains('tombstone')) { + return `[${message.formattedTime}] ${Language.get( + 'chat.messageType.be.bastelstu.chat.messageType.tombstone.message' + )}` + } - const elem = elBySel('.chatMessage', el) + const elem = elBySel('.chatMessage', el) - let body - if (typeof (body = message.getMessageType().renderPlainText(message)) === 'undefined' || body === false) { - body = Helper.getTextContent(elem).replace(/\t+/g, '\t') // collapse multiple tabs - .replace(/ +/g, ' ') // collapse multiple spaces - .replace(/([\t ]*\n){2,}/g, '\n') // collapse line consisting of tabs, spaces and newlines - .replace(/^[\t ]+|[\t ]+$/gm, '') // remove leading and trailing whitespace per line - } + let body + if ( + typeof (body = message + .getMessageType() + .renderPlainText(message)) === 'undefined' || + body === false + ) { + body = Helper.getTextContent(elem) + .replace(/\t+/g, '\t') // collapse multiple tabs + .replace(/ +/g, ' ') // collapse multiple spaces + .replace(/([\t ]*\n){2,}/g, '\n') // collapse line consisting of tabs, spaces and newlines + .replace(/^[\t ]+|[\t ]+$/gm, '') // remove leading and trailing whitespace per line + } - return `[${message.formattedTime}] <${message.username}> ${body.trim()}` - }).filter(x => x).join('\n')) + return `[${message.formattedTime}] <${ + message.username + }> ${body.trim()}` + }) + .filter((x) => x) + .join('\n') + ) event.preventDefault() - } - catch (e) { + } catch (e) { console.error('Unable to use the clipboard API') console.error(e) } @@ -345,4 +394,4 @@ define([ '../Helper' MessageStream.DEPENDENCIES = DEPENDENCIES return MessageStream -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Mobile.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Mobile.js index 15db443..4ab4f62 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Mobile.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Mobile.js @@ -11,8 +11,8 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Ui/Screen' ], function (UiScreen) { - "use strict"; +define(['WoltLabSuite/Core/Ui/Screen'], function (UiScreen) { + 'use strict' const initialized = Symbol('initialized') @@ -22,10 +22,11 @@ define([ 'WoltLabSuite/Core/Ui/Screen' ], function (UiScreen) { } bootstrap() { - UiScreen.on('screen-md-down', { match: this.enable.bind(this) - , unmatch: this.disable.bind(this) - , setup: this.init.bind(this) - }) + UiScreen.on('screen-md-down', { + match: this.enable.bind(this), + unmatch: this.disable.bind(this), + setup: this.init.bind(this), + }) } init() { @@ -36,19 +37,15 @@ define([ 'WoltLabSuite/Core/Ui/Screen' ], function (UiScreen) { this.initQuickSettings() } - enable() { + enable() {} - } - - disable() { - - } + disable() {} initQuickSettings() { - const navigation = elBySel('#chatQuickSettingsNavigation > ul') + const navigation = elBySel('#chatQuickSettingsNavigation > ul') const quickSettings = elById('chatQuickSettings') - navigation.addEventListener(WCF_CLICK_EVENT, event => { + navigation.addEventListener(WCF_CLICK_EVENT, (event) => { event.stopPropagation() // mimic dropdown behavior @@ -57,7 +54,7 @@ define([ 'WoltLabSuite/Core/Ui/Screen' ], function (UiScreen) { }, 10) }) - quickSettings.addEventListener(WCF_CLICK_EVENT, event => { + quickSettings.addEventListener(WCF_CLICK_EVENT, (event) => { event.preventDefault() event.stopPropagation() @@ -67,4 +64,4 @@ define([ 'WoltLabSuite/Core/Ui/Screen' ], function (UiScreen) { } return Mobile -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Notification.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Notification.js index 34c4a08..ae296ec 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Notification.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Notification.js @@ -11,10 +11,10 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Language' ], function (Language) { - "use strict"; +define(['WoltLabSuite/Core/Language'], function (Language) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore' ] + const DEPENDENCIES = ['ProfileStore'] class Notification { constructor(profileStore) { this.profileStore = profileStore @@ -27,11 +27,14 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { } bootstrap() { - document.addEventListener('visibilitychange', this.onVisibilitychange.bind(this)) + document.addEventListener( + 'visibilitychange', + this.onVisibilitychange.bind(this) + ) } get systemSupported() { - return "Notification" in window + return 'Notification' in window } get systemDenied() { @@ -40,7 +43,10 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { get systemGranted() { if (this.systemDenied) { - console.warn('[Notification]', 'System Notifications: permission denied') + console.warn( + '[Notification]', + 'System Notifications: permission denied' + ) } return window.Notification.permission === 'granted' @@ -57,7 +63,7 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { ingest(messages) { if (!this.active) { - messages.forEach(message => { + messages.forEach((message) => { const body = message.getMessageType().renderPlainText(message) if (body === false) return @@ -70,10 +76,7 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { // The user information is guaranteed to be cached at this point const user = this.profileStore.get(message.userID) const title = Language.get('chat.notification.title', { message }) - const options = { body - , icon: user.imageUrl - , badge: user.imageUrl - } + const options = { body, icon: user.imageUrl, badge: user.imageUrl } const notification = new window.Notification(title, options) @@ -88,14 +91,14 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { updateBrowserTitle() { if (this.unread > 0) { document.title = `(${this.unread}) ${this.browserTitle}` - } - else { + } else { document.title = this.browserTitle } } enableSystemNotifications() { - if (!this.systemSupported) return Promise.reject(new Error('Notifications are not supported')) + if (!this.systemSupported) + return Promise.reject(new Error('Notifications are not supported')) if (this.systemGranted) { this.systemEnabled = true @@ -104,13 +107,12 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { } return new Promise((resolve, reject) => { - window.Notification.requestPermission(permission => { + window.Notification.requestPermission((permission) => { this.systemEnabled = permission === 'granted' if (this.systemEnabled) { resolve() - } - else { + } else { reject(new Error(permission)) } }) @@ -124,4 +126,4 @@ define([ 'WoltLabSuite/Core/Language' ], function (Language) { Notification.DEPENDENCIES = DEPENDENCIES return Notification -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/ReadMarker.js b/files_wcf/js/Bastelstu.be/Chat/Ui/ReadMarker.js index 97a2b84..02e98e8 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/ReadMarker.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/ReadMarker.js @@ -11,28 +11,34 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' - const DEPENDENCIES = [ 'UiMessageStream' ] + const DEPENDENCIES = ['UiMessageStream'] class ReadMarker { constructor(messageStream) { this.messageStream = messageStream } bootstrap() { - document.addEventListener('visibilitychange', this.onVisibilitychange.bind(this)) + document.addEventListener( + 'visibilitychange', + this.onVisibilitychange.bind(this) + ) } onVisibilitychange() { if (document.hidden) { const ul = elBySel('ul', this.messageStream.stream) - let lc = ul.lastElementChild + let lc = ul.lastElementChild // delete previous markers - Array.prototype.forEach.call(document.querySelectorAll('.readMarker'), marker => { - marker.classList.remove('readMarker') - }) + Array.prototype.forEach.call( + document.querySelectorAll('.readMarker'), + (marker) => { + marker.classList.remove('readMarker') + } + ) if (lc) { lc.classList.add('readMarker') @@ -43,4 +49,4 @@ define([ ], function () { ReadMarker.DEPENDENCIES = DEPENDENCIES return ReadMarker -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings.js index eb0f9cd..8b5f460 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings.js @@ -11,23 +11,27 @@ * or later of the General Public License. */ -define([ ], function () { - 'use strict'; +define([], function () { + 'use strict' - const DEPENDENCIES = [ 'UiSettingsButton' ] + const DEPENDENCIES = ['UiSettingsButton'] class Settings { constructor(modules) { this.modules = modules - this.buttons = Array.from(elBySelAll('#chatQuickSettingsNavigation .button[data-module]')) + this.buttons = Array.from( + elBySelAll('#chatQuickSettingsNavigation .button[data-module]') + ) } bootstrap() { - this.buttons.forEach(element => { - this.modules[element.dataset.module.replace(/\./g, '-')].instance(element).bootstrap() + this.buttons.forEach((element) => { + this.modules[element.dataset.module.replace(/\./g, '-')] + .instance(element) + .bootstrap() }) } } Settings.DEPENDENCIES = DEPENDENCIES return Settings -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/AutoscrollButton.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/AutoscrollButton.js index 195854d..6d9c8f8 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/AutoscrollButton.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/AutoscrollButton.js @@ -11,10 +11,12 @@ * or later of the General Public License. */ -define([ './ToggleButton' ], function (ToggleButton) { - 'use strict'; +define(['./ToggleButton'], function (ToggleButton) { + 'use strict' - const DEPENDENCIES = [ 'UiMessageStream' ].concat(ToggleButton.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['UiMessageStream'].concat( + ToggleButton.DEPENDENCIES || [] + ) class AutoscrollButton extends ToggleButton { constructor(element, messageStream, ...superDeps) { super(element, true, undefined, ...superDeps) @@ -40,4 +42,4 @@ define([ './ToggleButton' ], function (ToggleButton) { AutoscrollButton.DEPENDENCIES = DEPENDENCIES return AutoscrollButton -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/Button.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/Button.js index 732d500..a086513 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/Button.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/Button.js @@ -11,13 +11,14 @@ * or later of the General Public License. */ -define([ ], function () { - 'use strict'; +define([], function () { + 'use strict' - const DEPENDENCIES = [ ] + const DEPENDENCIES = [] class Button { constructor(element) { - if (!element || !element instanceof Element) throw new Error('No DOM element provided') + if (!element || !element instanceof Element) + throw new Error('No DOM element provided') this.element = element } @@ -33,4 +34,4 @@ define([ ], function () { Button.DEPENDENCIES = DEPENDENCIES return Button -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/FullscreenButton.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/FullscreenButton.js index c92cf79..26b99fb 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/FullscreenButton.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/FullscreenButton.js @@ -11,12 +11,17 @@ * or later of the General Public License. */ -define([ './ToggleButton' ], function (ToggleButton) { - 'use strict'; +define(['./ToggleButton'], function (ToggleButton) { + 'use strict' class FullscreenButton extends ToggleButton { constructor(element, ...superDeps) { - super(element, false, 'Bastelstu.be/Chat/Ui/Settings/FullscreenButton', ...superDeps) + super( + element, + false, + 'Bastelstu.be/Chat/Ui/Settings/FullscreenButton', + ...superDeps + ) } enable() { @@ -31,4 +36,4 @@ define([ './ToggleButton' ], function (ToggleButton) { } return FullscreenButton -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/NotificationsButton.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/NotificationsButton.js index 992d1ea..2b84d60 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/NotificationsButton.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/NotificationsButton.js @@ -11,13 +11,20 @@ * or later of the General Public License. */ -define([ './ToggleButton' ], function (ToggleButton) { - 'use strict'; +define(['./ToggleButton'], function (ToggleButton) { + 'use strict' - const DEPENDENCIES = [ 'UiNotification' ].concat(ToggleButton.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['UiNotification'].concat( + ToggleButton.DEPENDENCIES || [] + ) class NotificationsButton extends ToggleButton { constructor(element, notification, ...superDeps) { - super(element, false, 'Bastelstu.be/Chat/Ui/Settings/NotificationsButton', ...superDeps) + super( + element, + false, + 'Bastelstu.be/Chat/Ui/Settings/NotificationsButton', + ...superDeps + ) this.notification = notification } @@ -26,14 +33,17 @@ define([ './ToggleButton' ], function (ToggleButton) { super.bootstrap() // Hide the button if notifications are not supported or the permission has been denied - if (!this.notification.systemSupported || this.notification.systemDenied) { + if ( + !this.notification.systemSupported || + this.notification.systemDenied + ) { elRemove(this.element.closest('li')) } } enable() { super.enable() - this.notification.enableSystemNotifications().catch(error => { + this.notification.enableSystemNotifications().catch((error) => { this.disable() if (this.notification.systemDenied) elRemove(this.element) @@ -48,4 +58,4 @@ define([ './ToggleButton' ], function (ToggleButton) { NotificationsButton.DEPENDENCIES = DEPENDENCIES return NotificationsButton -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/SmiliesButton.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/SmiliesButton.js index c12e69e..53cf587 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/SmiliesButton.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/SmiliesButton.js @@ -11,12 +11,13 @@ * or later of the General Public License. */ -define([ './ToggleButton' - , 'WoltLabSuite/Core/Ui/Screen' - ], function (ToggleButton, UiScreen) { - 'use strict'; +define(['./ToggleButton', 'WoltLabSuite/Core/Ui/Screen'], function ( + ToggleButton, + UiScreen +) { + 'use strict' - const DEPENDENCIES = [ 'UiInput' ].concat(ToggleButton.DEPENDENCIES || [ ]) + const DEPENDENCIES = ['UiInput'].concat(ToggleButton.DEPENDENCIES || []) class SmiliesButton extends ToggleButton { constructor(element, input, ...superDeps) { super(element, false, undefined, ...superDeps) @@ -25,7 +26,7 @@ define([ './ToggleButton' } bootstrap() { - this.container = elById('smileyPickerContainer') + this.container = elById('smileyPickerContainer') // Remove this button if smileys are disabled if (!this.container) { @@ -37,7 +38,11 @@ define([ './ToggleButton' // Initialize the smiley picker tab menu $('.messageTabMenu').messageTabMenu() - $('#smilies-text').on('mousedown', '.jsSmiley', this.insertSmiley.bind(this)) + $('#smilies-text').on( + 'mousedown', + '.jsSmiley', + this.insertSmiley.bind(this) + ) this.closeButton.addEventListener('mousedown', this.disable.bind(this)) // Start in desktop mode @@ -48,9 +53,9 @@ define([ './ToggleButton' // Setup media queries UiScreen.on('screen-md-down', { - match: this.enableMobile.bind(this), + match: this.enableMobile.bind(this), unmatch: this.disableMobile.bind(this), - setup: this.setupMobile.bind(this) + setup: this.setupMobile.bind(this), }) } @@ -63,12 +68,23 @@ define([ './ToggleButton' */ setupMobile() { this.shadowToggleButton = document.createElement('span') - this.shadowToggleButton.classList.add('smiliesToggleMobileButton', 'button', 'small') - this.shadowToggleButton.innerHTML = '' - this.shadowToggleButton.addEventListener('mousedown', this.onClick.bind(this)) + this.shadowToggleButton.classList.add( + 'smiliesToggleMobileButton', + 'button', + 'small' + ) + this.shadowToggleButton.innerHTML = + '' + this.shadowToggleButton.addEventListener( + 'mousedown', + this.onClick.bind(this) + ) const shadowContainer = elBySel('#chatInputContainer > div') - shadowContainer.insertBefore(this.shadowToggleButton, shadowContainer.firstChild) + shadowContainer.insertBefore( + this.shadowToggleButton, + shadowContainer.firstChild + ) this.enableMobile() } @@ -156,4 +172,4 @@ define([ './ToggleButton' SmiliesButton.DEPENDENCIES = DEPENDENCIES return SmiliesButton -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/ToggleButton.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/ToggleButton.js index 56a0743..885df84 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/ToggleButton.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Settings/ToggleButton.js @@ -11,13 +11,14 @@ * or later of the General Public License. */ -define([ './Button' - , '../../LocalStorage' - , '../../DataStructure/EventEmitter' - ], function (Button, LocalStorage, EventEmitter) { - 'use strict'; +define([ + './Button', + '../../LocalStorage', + '../../DataStructure/EventEmitter', +], function (Button, LocalStorage, EventEmitter) { + 'use strict' - const DEPENDENCIES = [ ].concat(Button.DEPENDENCIES || [ ]) + const DEPENDENCIES = [].concat(Button.DEPENDENCIES || []) class ToggleButton extends Button { constructor(element, defaultState, storageKey, ...superDeps) { super(element, ...superDeps) @@ -38,8 +39,7 @@ define([ './Button' if (this.defaultState) { this.enable() - } - else { + } else { this.disable() } } @@ -69,8 +69,7 @@ define([ './Button' if (this.enabled) { this.disable() - } - else { + } else { this.enable() } } @@ -79,4 +78,4 @@ define([ './Button' ToggleButton.DEPENDENCIES = DEPENDENCIES return ToggleButton -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/Topic.js b/files_wcf/js/Bastelstu.be/Chat/Ui/Topic.js index 535fe9e..f90a37d 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/Topic.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/Topic.js @@ -11,18 +11,21 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Dom/Traverse' ], function (Traverse) { - "use strict"; +define(['WoltLabSuite/Core/Dom/Traverse'], function (Traverse) { + 'use strict' class Topic { bootstrap() { elBySelAll('.chatRoomTopic', document, function (element) { - elBySel('.jsDismissRoomTopicButton', element).addEventListener('click', function (event) { - elRemove(element) - }) + elBySel('.jsDismissRoomTopicButton', element).addEventListener( + 'click', + function (event) { + elRemove(element) + } + ) }) } } return Topic -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActionDropdownHandler.js b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActionDropdownHandler.js index 02c5831..c6d9640 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActionDropdownHandler.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActionDropdownHandler.js @@ -11,18 +11,23 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Dom/Traverse' - , 'WoltLabSuite/Core/Dom/Util' - , 'WoltLabSuite/Core/Ui/Dropdown/Simple' - ], function (DomTraverse, DomUtil, SimpleDropdown) { - "use strict"; +define([ + 'WoltLabSuite/Core/Dom/Traverse', + 'WoltLabSuite/Core/Dom/Util', + 'WoltLabSuite/Core/Ui/Dropdown/Simple', +], function (DomTraverse, DomUtil, SimpleDropdown) { + 'use strict' - const DEPENDENCIES = [ 'ProfileStore', 'Template.UserListDropdownMenuItems', 'bottle' ] + const DEPENDENCIES = [ + 'ProfileStore', + 'Template.UserListDropdownMenuItems', + 'bottle', + ] class UserActionDropdownHandler { constructor(profiles, dropdownTemplate, bottle) { - this.profiles = profiles - this.dropdownTemplate = dropdownTemplate - this.bottle = bottle + this.profiles = profiles + this.dropdownTemplate = dropdownTemplate + this.bottle = bottle this.container = elById('main') } @@ -32,7 +37,15 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' } onClick(event) { - const userElement = event.target.classList.contains('jsUserActionDropdown') ? event.target : DomTraverse.parentByClass(event.target, 'jsUserActionDropdown', this.container) + const userElement = event.target.classList.contains( + 'jsUserActionDropdown' + ) + ? event.target + : DomTraverse.parentByClass( + event.target, + 'jsUserActionDropdown', + this.container + ) if (!userElement) return @@ -46,23 +59,37 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' // Note: We would usually use firstElementChild here, but this // is not supported in Safari and Edge - const dropdown = DomUtil.createFragmentFromHtml(this.dropdownTemplate.fetch({ user })).querySelector('*') + const dropdown = DomUtil.createFragmentFromHtml( + this.dropdownTemplate.fetch({ user }) + ).querySelector('*') - Array.from(elBySelAll('[data-module]', dropdown)).forEach(element => { + Array.from(elBySelAll('[data-module]', dropdown)).forEach((element) => { const moduleName = element.dataset.module let userAction - if (!this.bottle.container.UserAction || (userAction = this.bottle.container.UserAction[`${moduleName.replace(/\./g, '-')}`]) == null) { - this.bottle.factory(`UserAction.${moduleName.replace(/\./g, '-')}`, _ => { - const UserAction = require(moduleName) - const deps = this.bottle.digest(UserAction.DEPENDENCIES || []) + if ( + !this.bottle.container.UserAction || + (userAction = this.bottle.container.UserAction[ + `${moduleName.replace(/\./g, '-')}` + ]) == null + ) { + this.bottle.factory( + `UserAction.${moduleName.replace(/\./g, '-')}`, + (_) => { + const UserAction = require(moduleName) + const deps = this.bottle.digest(UserAction.DEPENDENCIES || []) - return new UserAction(...deps) - }) + return new UserAction(...deps) + } + ) - userAction = this.bottle.container.UserAction[`${moduleName.replace(/\./g, '-')}`] + userAction = this.bottle.container.UserAction[ + `${moduleName.replace(/\./g, '-')}` + ] } - element.addEventListener(WCF_CLICK_EVENT, (event) => userAction.onClick(user, event)) + element.addEventListener(WCF_CLICK_EVENT, (event) => + userAction.onClick(user, event) + ) }) SimpleDropdown.initFragment(userElement, dropdown) @@ -77,4 +104,4 @@ define([ 'WoltLabSuite/Core/Dom/Traverse' UserActionDropdownHandler.DEPENDENCIES = DEPENDENCIES return UserActionDropdownHandler -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/Action.js b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/Action.js index 1050d4e..935b1e2 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/Action.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/Action.js @@ -11,14 +11,14 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' class Action { - constructor() { } + constructor() {} - onClick(userID, event) { } + onClick(userID, event) {} } return Action -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/BanAction.js b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/BanAction.js index cf90269..7fbc70f 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/BanAction.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/BanAction.js @@ -11,17 +11,15 @@ * or later of the General Public License. */ -define([ '../../console' - , './Action' - ], function (console, Action) { - "use strict"; +define(['../../console', './Action'], function (console, Action) { + 'use strict' - const DEPENDENCIES = [ 'UiInput' ] + const DEPENDENCIES = ['UiInput'] class BanAction extends Action { constructor(input) { super() - this.input = input + this.input = input } onClick(user, event) { @@ -35,7 +33,7 @@ define([ '../../console' this.input.insertText(command, { append: false, prepend: true }) this.input.focus() - setTimeout(_ => { + setTimeout((_) => { this.input.emit('autocomplete') }, 1) } @@ -43,4 +41,4 @@ define([ '../../console' BanAction.DEPENDENCIES = DEPENDENCIES return BanAction -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/MuteAction.js b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/MuteAction.js index 65f82e6..dd12bae 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/MuteAction.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/MuteAction.js @@ -11,17 +11,15 @@ * or later of the General Public License. */ -define([ '../../console' - , './Action' - ], function (console, Action) { - "use strict"; +define(['../../console', './Action'], function (console, Action) { + 'use strict' - const DEPENDENCIES = [ 'UiInput' ] + const DEPENDENCIES = ['UiInput'] class MuteAction extends Action { constructor(input) { super() - this.input = input + this.input = input } onClick(user, event) { @@ -35,7 +33,7 @@ define([ '../../console' this.input.insertText(command, { append: false, prepend: true }) this.input.focus() - setTimeout(_ => { + setTimeout((_) => { this.input.emit('autocomplete') }, 1) } @@ -43,4 +41,4 @@ define([ '../../console' MuteAction.DEPENDENCIES = DEPENDENCIES return MuteAction -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/WhisperAction.js b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/WhisperAction.js index a7ac5b1..120f6bb 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/WhisperAction.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/UserActions/WhisperAction.js @@ -11,15 +11,15 @@ * or later of the General Public License. */ -define([ './Action', '../../console' ], function (Action, console) { - "use strict"; +define(['./Action', '../../console'], function (Action, console) { + 'use strict' - const DEPENDENCIES = [ 'UiInput' ] + const DEPENDENCIES = ['UiInput'] class WhisperAction extends Action { constructor(input) { super() - this.input = input + this.input = input } onClick(user, event) { @@ -38,4 +38,4 @@ define([ './Action', '../../console' ], function (Action, console) { WhisperAction.DEPENDENCIES = DEPENDENCIES return WhisperAction -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/Ui/UserList.js b/files_wcf/js/Bastelstu.be/Chat/Ui/UserList.js index 2c099b3..6a4881d 100644 --- a/files_wcf/js/Bastelstu.be/Chat/Ui/UserList.js +++ b/files_wcf/js/Bastelstu.be/Chat/Ui/UserList.js @@ -11,28 +11,26 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/Dom/Util' ], function (DomUtil) { - "use strict"; +define(['WoltLabSuite/Core/Dom/Util'], function (DomUtil) { + 'use strict' - const DEPENDENCIES = [ 'Template.UserList' ] + const DEPENDENCIES = ['Template.UserList'] class UserList { constructor(userListTemplate) { - this.userListTemplate = userListTemplate - this.chatUserList = elById('chatUserList') + this.userListTemplate = userListTemplate + this.chatUserList = elById('chatUserList') } - bootstrap() { - - } + bootstrap() {} render(users) { users.sort((a, b) => a.username.localeCompare(b.username)) - const html = this.userListTemplate.fetch({ users }) + const html = this.userListTemplate.fetch({ users }) const fragment = DomUtil.createFragmentFromHtml(html) // Replace the current user list with the new one const currentList = elBySel('#chatUserList > .boxContent > ul') - const parentNode = currentList.parentNode + const parentNode = currentList.parentNode parentNode.removeChild(currentList) parentNode.appendChild(fragment) } @@ -40,4 +38,4 @@ define([ 'WoltLabSuite/Core/Dom/Util' ], function (DomUtil) { UserList.DEPENDENCIES = DEPENDENCIES return UserList -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/User.js b/files_wcf/js/Bastelstu.be/Chat/User.js index 5a84744..867a90d 100644 --- a/files_wcf/js/Bastelstu.be/Chat/User.js +++ b/files_wcf/js/Bastelstu.be/Chat/User.js @@ -11,11 +11,12 @@ * or later of the General Public License. */ -define([ 'WoltLabSuite/Core/User' - , 'WoltLabSuite/Core/StringUtil' - , './Helper' - ], function (CoreUser, StringUtil, Helper) { - "use strict"; +define([ + 'WoltLabSuite/Core/User', + 'WoltLabSuite/Core/StringUtil', + './Helper', +], function (CoreUser, StringUtil, Helper) { + 'use strict' const u = Symbol('user') @@ -25,15 +26,16 @@ define([ 'WoltLabSuite/Core/User' class User { constructor(user) { this[u] = Helper.deepFreeze(user) - - Object.getOwnPropertyNames(this[u]).forEach(key => { + + Object.getOwnPropertyNames(this[u]).forEach((key) => { if (this[key]) { throw new Error('Attempting to override existing property') } - Object.defineProperty(this, key, { value: this[u][key] - , enumerable: true - }) + Object.defineProperty(this, key, { + value: this[u][key], + enumerable: true, + }) }) } @@ -42,28 +44,36 @@ define([ 'WoltLabSuite/Core/User' if (this.color1 === null && this.color2 === null) return this.username // Single color - if (this.color1 === this.color2) return `${StringUtil.escapeHTML(this.username)}` + if (this.color1 === this.color2) + return `${StringUtil.escapeHTML(this.username)}` // Gradient - const r1 = (this.color1 >> 16) & 0xFF - const r2 = (this.color2 >> 16) & 0xFF - const g1 = (this.color1 >> 8) & 0xFF - const g2 = (this.color2 >> 8) & 0xFF - const b1 = this.color1 & 0xFF - const b2 = this.color2 & 0xFF + const r1 = (this.color1 >> 16) & 0xff + const r2 = (this.color2 >> 16) & 0xff + const g1 = (this.color1 >> 8) & 0xff + const g2 = (this.color2 >> 8) & 0xff + const b1 = this.color1 & 0xff + const b2 = this.color2 & 0xff const steps = this.username.length - 1 const r = (r1 - r2) / steps const g = (g1 - g2) / steps const b = (b1 - b2) / steps - return this[u].username.split('').map((letter, index) => { - const R = Math.round(r1 - index * r) - const G = Math.round(g1 - index * g) - const B = Math.round(b1 - index * b) + return this[u].username + .split('') + .map((letter, index) => { + const R = Math.round(r1 - index * r) + const G = Math.round(g1 - index * g) + const B = Math.round(b1 - index * b) - return `${StringUtil.escapeHTML(letter)}` - }).join('') + return `${StringUtil.escapeHTML( + letter + )}` + }) + .join('') } get self() { @@ -71,11 +81,7 @@ define([ 'WoltLabSuite/Core/User' } static getGuest(username) { - const payload = { username - , userID: null - , color1: null - , color2: null - } + const payload = { username, userID: null, color1: null, color2: null } return new User(payload) } @@ -90,4 +96,4 @@ define([ 'WoltLabSuite/Core/User' } return User -}); +}) diff --git a/files_wcf/js/Bastelstu.be/Chat/console.js b/files_wcf/js/Bastelstu.be/Chat/console.js index 9361f8e..5d92326 100644 --- a/files_wcf/js/Bastelstu.be/Chat/console.js +++ b/files_wcf/js/Bastelstu.be/Chat/console.js @@ -11,11 +11,11 @@ * or later of the General Public License. */ -define([ ], function () { - "use strict"; +define([], function () { + 'use strict' const start = Date.now() - let last = start + let last = start const group = function () { if (window.console.group) window.console.group() @@ -46,13 +46,12 @@ define([ ], function () { } const debug = function (handler, ...args) { - const now = Date.now() - const time = [ (now - start), `\t+${(now - last)}ms\t` ] + const now = Date.now() + const time = [now - start, `\t+${now - last}ms\t`] if (args.length) { println('debug', ...time, `[${handler}]\t`, ...args) - } - else { + } else { println('debug', ...time, handler) } @@ -61,7 +60,7 @@ define([ ], function () { const debugException = function (error) { if (error instanceof Error) { - let message = `[${error.name}] „${error.message}“ in ${error.fileName} on line ${error.lineNumber}\n` + let message = `[${error.name}] „${error.message}“ in ${error.fileName} on line ${error.lineNumber}\n` if (error.stack) { message += 'Stacktrace:\n' @@ -69,8 +68,7 @@ define([ ], function () { } println('error', message) - } - else if (error.code && error.message) { + } else if (error.code && error.message) { debugAjaxException(error) } } @@ -79,20 +77,21 @@ define([ ], function () { groupCollapsed() let details = `[${error.code}] ${error.message}` - const br2nl = (string) => string.split('\n') - .map(line => line.replace(/$/i, '')) - .join('\n') + const br2nl = (string) => + string + .split('\n') + .map((line) => line.replace(/$/i, '')) + .join('\n') if (error.stacktrace) { details += `\nStacktrace:\n${br2nl(error.stacktrace)}` - } - else if (error.exceptionID) { + } else if (error.exceptionID) { details += `\nException ID: ${error.exceptionID}` } println('debug', details) - error.previous.forEach(previous => { + error.previous.forEach((previous) => { let details = '' group() @@ -103,17 +102,18 @@ define([ ], function () { println('debug', details) }) - error.previous.forEach(_ => groupEnd()) + error.previous.forEach((_) => groupEnd()) groupEnd() } - return { log - , warn - , error - , debug - , debugException - , group - , groupCollapsed - , groupEnd - } -}); + return { + log, + warn, + error, + debug, + debugException, + group, + groupCollapsed, + groupEnd, + } +})