add classes for notification UI.
The UI classes are split into "general UI" part — a base class that could potentially be used for proper in-player UI if we ever get to that point — and part that's specific to our notification requirements.
This commit is contained in:
parent
55fbd30699
commit
38641df28e
98
src/ext/lib/uwui/PlayerNotificationUI.js
Normal file
98
src/ext/lib/uwui/PlayerNotificationUI.js
Normal file
@ -0,0 +1,98 @@
|
||||
import UI from './UI';
|
||||
import VuexWebExtensions from 'vuex-webextensions';
|
||||
import VideoNotification from '../../../csui/VideoNotification';
|
||||
|
||||
class PlayerNotification extends UI {
|
||||
|
||||
constructor (
|
||||
playerElement
|
||||
) {
|
||||
|
||||
super(
|
||||
'notification',
|
||||
getStoreConfig(),
|
||||
getUiConfig(playerElement),
|
||||
getCommsConfig()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
//#region constructor helpers
|
||||
// we will move some things out of the constructor in order to keep things clean
|
||||
getStoreConfig() {
|
||||
return {
|
||||
plugins: [
|
||||
VuexWebExtensions({
|
||||
persistentStates: [
|
||||
'notificationConfig'
|
||||
],
|
||||
}),
|
||||
],
|
||||
state: {
|
||||
// should be null by default!
|
||||
notificationConfig: {
|
||||
text: 'sample text <b>now with 100% more html formatting!</b>',
|
||||
icon: 'exclamation-circle',
|
||||
timeout: 5000,
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
'uw-set-notification'(state, payload) {
|
||||
state['notificationConfig'] = payload;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
'uw-set-notification'({commit}, payload) {
|
||||
commit('uw-set-notification', payload);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getUiConfig(playerElement) {
|
||||
return {
|
||||
parentElement: playerElement,
|
||||
component: VideoNotification
|
||||
}
|
||||
}
|
||||
|
||||
getCommsConfig() {
|
||||
return {
|
||||
handlers = {
|
||||
'show-notification': [(message) => this.showNotification(message)],
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region lifecycle
|
||||
replace(playerElement) {
|
||||
super.replace(this.getUiConfig(playerElement));
|
||||
}
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* Show notification on screen.
|
||||
*
|
||||
* @param notificationConfig notification config
|
||||
*
|
||||
* notificationConfig should resemble this:
|
||||
* {
|
||||
* timeout: number — how long we'll be displaying the notification. If empty, 10s. -1: until user dismisses it
|
||||
* icon: string — what icon we're gonna show. We're using bootstrap icons. Can be empty.
|
||||
* text: — notification text. Supports HTML.
|
||||
* notificationActions: [
|
||||
* {
|
||||
* command: function that gets executed upon clicking the button.
|
||||
* label: label of the button
|
||||
* icon: icon of the button
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
showNotification(notificationConfig) {
|
||||
this.vuexStore?.dispatch('uw-set-notification', notificationConfig);
|
||||
}
|
||||
}
|
||||
|
||||
export default PlayerNotification;
|
76
src/ext/lib/uwui/UI.js
Normal file
76
src/ext/lib/uwui/UI.js
Normal file
@ -0,0 +1,76 @@
|
||||
import { createApp } from 'vue';
|
||||
import { createStore } from 'vuex';
|
||||
|
||||
class UI {
|
||||
constructor(
|
||||
interfaceId,
|
||||
storeConfig,
|
||||
uiConfig, // {component, parentElement?}
|
||||
commsConfig,
|
||||
) {
|
||||
this.interfaceId = interfaceId;
|
||||
this.commsConfig = commsConfig;
|
||||
}
|
||||
|
||||
async init() {
|
||||
// If comms exist, we need to destroy it
|
||||
if (this.comms) {
|
||||
this.comms.destroy();
|
||||
}
|
||||
if (!this.settings) {
|
||||
this.settings = new Settings({
|
||||
onSettingsChanged: () => this.reloadSettings(),
|
||||
logger: this.logger
|
||||
});
|
||||
await this.settings.init();
|
||||
}
|
||||
|
||||
this.comms = new CommsClient('content-ui-port', null, this.commsConfig.handlers);
|
||||
|
||||
// initialize vuejs, but only once (check handled in initVue())
|
||||
// we need to initialize this _after_ initializing comms.
|
||||
this.initVue();
|
||||
}
|
||||
|
||||
async initVue() {
|
||||
this.vuexStore = createStore(this.storeConfig);
|
||||
}
|
||||
|
||||
async initUi() {
|
||||
const random = Math.round(Math.random() * 69420);
|
||||
const uwid = `uw-${this.interfaceId}-root-${random}`
|
||||
|
||||
const rootDiv = document.createElement('div');
|
||||
rootDiv.setAttribute('style', `position: ${uiConfig.style?.position ?? 'relative'}; width: ${uiConfig.style?.width ?? '100%'}; height: ${uiConfig.style?.height ?? '100%'}; ${uiConfig.additionalStyle}`);
|
||||
rootDiv.setAttribute('id', uwid);
|
||||
|
||||
if (this.uiConfig.parentElement) {
|
||||
this.uiConfig.parentElement.appendChild(rootDiv);
|
||||
} else {
|
||||
document.body.appendChild(rootDiv);
|
||||
}
|
||||
|
||||
this.element = rootDiv;
|
||||
|
||||
createApp(this.uiConfig.component)
|
||||
.use(this.vuexStore)
|
||||
.mount(`${uwid}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces ui config and re-inits the UI
|
||||
* @param {*} newUiConfig
|
||||
*/
|
||||
replace(newUiConfig) {
|
||||
this.element?.remove();
|
||||
this.uiConfig = newUiConfig;
|
||||
this.initUi();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.comms?.destroy();
|
||||
this.element?.remove();
|
||||
}
|
||||
}
|
||||
|
||||
export default UI;
|
Loading…
Reference in New Issue
Block a user