Finish notification system (for now)
This commit is contained in:
parent
12b15c58f8
commit
0310e1e2de
14
src/common/data/notifications.js
Normal file
14
src/common/data/notifications.js
Normal file
@ -0,0 +1,14 @@
|
||||
let Notifications = Object.freeze({
|
||||
'TEST_NOTIFICATION': {
|
||||
icon: 'card-text',
|
||||
text: 'This is a test notification.',
|
||||
timeout: -1,
|
||||
},
|
||||
'AARD_DRM': {
|
||||
icon: 'exclamation-triangle',
|
||||
text: '<b>Autodetection cannot run on this video.</b> This usually happens when sites use DRM. You will have to set aspect ratio manually.',
|
||||
timeout: 5000,
|
||||
}
|
||||
});
|
||||
|
||||
export default Notifications;
|
@ -5,11 +5,10 @@
|
||||
<Icon
|
||||
class="flex-nogrow flex-noshrink"
|
||||
:icon="notificationIcon"
|
||||
@click="closeNotification()"
|
||||
>
|
||||
</Icon>
|
||||
</div>
|
||||
<div class="notification-context flex-grow flex-shrink flex flex-column">
|
||||
<div class="notification-content flex-grow flex-shrink flex flex-column flex-cross-center">
|
||||
<div
|
||||
class="notification-text"
|
||||
v-html="notificationText"
|
||||
@ -21,18 +20,41 @@
|
||||
>
|
||||
<div
|
||||
v-for="action of notificationActions"
|
||||
class="action-button"
|
||||
:key="action"
|
||||
@click="action.command"
|
||||
>
|
||||
<Icon v-if="action.icon" :icon="action.icon"></Icon>{{action.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="hideActions"
|
||||
class="hide-actions"
|
||||
>
|
||||
Never show again:<wbr>
|
||||
<template
|
||||
v-for="action of hideActions"
|
||||
:key="action"
|
||||
>
|
||||
<i @click="closeNotification">
|
||||
<a
|
||||
class="hide-action-button"
|
||||
@click="action.command"
|
||||
>
|
||||
{{action.label}}
|
||||
</a>
|
||||
<wbr>
|
||||
</i>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification-icon">
|
||||
<div
|
||||
class="notification-icon action-button"
|
||||
@click="closeNotification()"
|
||||
>
|
||||
<Icon
|
||||
class="flex-nogrow flex-noshrink"
|
||||
icon="x"
|
||||
@click="closeNotification()"
|
||||
>
|
||||
</Icon>
|
||||
</div>
|
||||
@ -50,20 +72,19 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// notificationIcon: null,
|
||||
// notificationText: null,
|
||||
// notificationActions: null,
|
||||
// showNotification: false,
|
||||
notificationTimeout: null,
|
||||
notificationIcon: "exclamation-triangle",
|
||||
notificationText: "this is a test notification <b>with some html for bold measure</b>",
|
||||
notificationText: "<b>Sample text.</b> This will be replaced with real notification later.",
|
||||
notificationActions: null,
|
||||
showNotification: true,
|
||||
hideActions: null,
|
||||
showNotification: false,
|
||||
};
|
||||
},
|
||||
...mapState([
|
||||
'notificationConfig'
|
||||
]),
|
||||
computed: {
|
||||
...mapState([
|
||||
'notificationConfig'
|
||||
]),
|
||||
},
|
||||
watch: {
|
||||
/**
|
||||
* Sets new notification config. Currently, we can only show one notification at a time.
|
||||
@ -79,31 +100,39 @@ export default {
|
||||
* label: label of the button
|
||||
* icon: icon of the button
|
||||
* }
|
||||
* ],
|
||||
* hideOptions: [
|
||||
* // more of notificationActions except it's a special case
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
notificationConfig(newConfig) {
|
||||
console.log('notificationConfig?');
|
||||
if (newConfig) {
|
||||
this.notificationText = newConfig.text;
|
||||
this.notificationActions = newConfig.notificationActions;
|
||||
this.notificationIcon = newConfig.icon;
|
||||
this.hideActions = newConfig.hideActions;
|
||||
|
||||
this.showNotification = true;
|
||||
|
||||
if (newConfig.timeout !== -1) {
|
||||
this.notificationTimeout = setTimeout(() => this.closeNotification(), newConfig.timeout ?? 10000);
|
||||
this.notificationTimeout = setTimeout(() => this.closeNotification(), newConfig.timeout ?? 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeNotification() {
|
||||
console.log("close notification!")
|
||||
|
||||
clearTimeout(this.notificationTimeout);
|
||||
|
||||
this.showNotification = false;
|
||||
this.notificationIcon = null;
|
||||
this.notificationText = null;
|
||||
this.notificationActions = null;
|
||||
this.hideActions = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,18 +149,62 @@ export default {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
font-size: 16px;
|
||||
|
||||
.notification-popup {
|
||||
pointer-events: auto !important;
|
||||
position: absolute;
|
||||
z-index: 99999999;
|
||||
top: 2em;
|
||||
right: 2em;
|
||||
width: 32em;
|
||||
|
||||
padding: 0.7em 0.5em;
|
||||
|
||||
font-family: 'Overpass';
|
||||
|
||||
background-color: rgba(108, 55, 12, 0.779);
|
||||
top: 2rem;
|
||||
left: 2rem;
|
||||
width: 15rem;
|
||||
color: #fff;
|
||||
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.notifcation-content {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.notification-text {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
font-size: 3rem;
|
||||
font-size: 3em;
|
||||
line-height: 0.5;
|
||||
}
|
||||
.action-button {
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hide-actions {
|
||||
color: #ccc;
|
||||
font-size: 0.8em;
|
||||
justify-self: flex-end;
|
||||
align-self: flex-end;
|
||||
margin-top: 1em;
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
|
||||
.hide-action-button {
|
||||
color: #eee;
|
||||
font-size: 0.9em;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: rgba(255,255,255,0.5);
|
||||
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,23 +1,31 @@
|
||||
import UI from './UI';
|
||||
import VuexWebExtensions from 'vuex-webextensions';
|
||||
import NotificationUi from '../../../csui/NotificationUi.vue';
|
||||
import Notifications from '../../../common/data/notifications';
|
||||
|
||||
if (process.env.CHANNEL !== 'stable'){
|
||||
console.info("Loading: PlayerNotificationUi");
|
||||
}
|
||||
|
||||
let MuteScope = Object.freeze({
|
||||
CurrentSite: 'current-site',
|
||||
Global: 'global'
|
||||
});
|
||||
|
||||
class PlayerNotificationUi extends UI {
|
||||
|
||||
constructor (
|
||||
playerElement
|
||||
) {
|
||||
playerElement,
|
||||
settings
|
||||
) {
|
||||
super(
|
||||
'notification',
|
||||
PlayerNotificationUi.getStoreConfig(),
|
||||
PlayerNotificationUi.getUiConfig(playerElement),
|
||||
PlayerNotificationUi.getCommsConfig()
|
||||
)
|
||||
);
|
||||
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
|
||||
@ -42,11 +50,13 @@ class PlayerNotificationUi extends UI {
|
||||
},
|
||||
mutations: {
|
||||
'uw-set-notification'(state, payload) {
|
||||
console.log('mutation!', state, payload);
|
||||
state['notificationConfig'] = payload;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
'uw-set-notification'({commit}, payload) {
|
||||
console.log('action!', commit, payload);
|
||||
commit('uw-set-notification', payload);
|
||||
}
|
||||
}
|
||||
@ -78,7 +88,7 @@ class PlayerNotificationUi extends UI {
|
||||
/**
|
||||
* Show notification on screen.
|
||||
*
|
||||
* @param notificationConfig notification config
|
||||
* @param notificationConfig notification config (or ID of notification config in /common/data/notifications.js)
|
||||
*
|
||||
* notificationConfig should resemble this:
|
||||
* {
|
||||
@ -91,11 +101,79 @@ class PlayerNotificationUi extends UI {
|
||||
* label: label of the button
|
||||
* icon: icon of the button
|
||||
* }
|
||||
* ],
|
||||
* hideActions: [
|
||||
* // more of notificationActions but with special case
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* When notificationConfig is a string, the function will add two additional notifications on the notificationActionsPile
|
||||
* * never show this notification ever again on any site
|
||||
* * never show this notification again on this site
|
||||
*/
|
||||
showNotification(notificationConfig) {
|
||||
this.vuexStore?.dispatch('uw-set-notification', notificationConfig);
|
||||
if (typeof notificationConfig === 'string') {
|
||||
try {
|
||||
const config = Notifications[notificationConfig];
|
||||
|
||||
// this should _never_ appear on production version of the extension, but it should help with development.
|
||||
if (!config) {
|
||||
return this.vuexStore?.dispatch('uw-set-notification', {
|
||||
icon: 'x-circle-fill',
|
||||
text: `Notification for key ${notificationConfig} does not exist.`,
|
||||
timeout: -1,
|
||||
});
|
||||
}
|
||||
|
||||
// don't show notification if it's muted
|
||||
if (this.isNotificationMuted(notificationConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.vuexStore?.dispatch('uw-set-notification', {
|
||||
...config,
|
||||
hideActions: [
|
||||
{
|
||||
command: () => this.muteNotification(notificationConfig, MuteScope.CurrentSite),
|
||||
label: 'this site'
|
||||
},
|
||||
{
|
||||
command: () => this.muteNotification(notificationConfig, MuteScope.Global),
|
||||
label: 'never ever'
|
||||
}
|
||||
]
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('theres been an error:', e)
|
||||
}
|
||||
} else {
|
||||
this.vuexStore?.dispatch('uw-set-notification', notificationConfig);
|
||||
}
|
||||
}
|
||||
|
||||
muteNotification(notificationId, scope) {
|
||||
// ensure objects we try to set exist
|
||||
if (!this.settings.active.mutedNotifications) {
|
||||
this.settings.active.mutedNotifications = {};
|
||||
}
|
||||
if (!this.settings.active.mutedNotifications[notificationId]) {
|
||||
this.settings.active.mutedNotifications[notificationId] = {};
|
||||
}
|
||||
|
||||
// actually mute notification
|
||||
if (scope === MuteScope.Global) {
|
||||
this.settings.active.mutedNotifications[notificationId].$global = true;
|
||||
} else {
|
||||
this.settings.active.mutedNotifications[notificationId][window.location.hostname] = true;
|
||||
}
|
||||
|
||||
// persist settings
|
||||
this.settings.saveWithoutReload();
|
||||
}
|
||||
|
||||
isNotificationMuted(notificationId) {
|
||||
return this.settings.active.mutedNotifications?.[notificationId]?.$global
|
||||
|| this.settings.active.mutedNotifications?.[notificationId]?.[window.location.hostname];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,19 +38,12 @@ class UI {
|
||||
|
||||
async initUi() {
|
||||
const random = Math.round(Math.random() * 69420);
|
||||
// const uwid = `uw-${this.interfaceId}-root-${random}`
|
||||
const uwid = 'not-so-random-id'
|
||||
const uwid = `uw-${this.interfaceId}-root-${random}`
|
||||
|
||||
const rootDiv = document.createElement('div');
|
||||
|
||||
try {
|
||||
rootDiv.setAttribute('style', `position: ${this.uiConfig.style?.position ?? 'relative'}; width: ${this.uiConfig.style?.width ?? '100%'}; height: ${this.uiConfig.style?.height ?? '100%'}; ${this.uiConfig.additionalStyle ?? ''}`);
|
||||
rootDiv.setAttribute('id', uwid);
|
||||
} catch (e) {
|
||||
console.error("ERROR:", e)
|
||||
}
|
||||
|
||||
console.warn('UI: init 3', this.uiConfig);
|
||||
rootDiv.setAttribute('style', `position: ${this.uiConfig.style?.position ?? 'relative'}; width: ${this.uiConfig.style?.width ?? '100%'}; height: ${this.uiConfig.style?.height ?? '100%'}; ${this.uiConfig.additionalStyle ?? ''}`);
|
||||
rootDiv.setAttribute('id', uwid);
|
||||
|
||||
|
||||
if (this.uiConfig?.parentElement) {
|
||||
|
@ -44,7 +44,7 @@ class PlayerData {
|
||||
this.extensionMode = videoData.extensionMode;
|
||||
this.invalid = false;
|
||||
this.element = this.getPlayer();
|
||||
this.notificationService = new PlayerNotificationUi(this.element);
|
||||
this.notificationService = new PlayerNotificationUi(this.element, this.settings);
|
||||
this.dimensions = undefined;
|
||||
this.overlayNode = undefined;
|
||||
|
||||
@ -65,6 +65,7 @@ class PlayerData {
|
||||
this.checkPlayerSizeChange();
|
||||
}
|
||||
this.startChangeDetection();
|
||||
|
||||
} catch (e) {
|
||||
console.error('[Ultrawidify::PlayerData::ctor] There was an error setting up player data. You should be never seeing this message. Error:', e);
|
||||
this.invalid = true;
|
||||
@ -472,6 +473,10 @@ class PlayerData {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
showNotification(notificationId) {
|
||||
this.notificationService?.showNotification(notificationId);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.CHANNEL !== 'stable'){
|
||||
|
Loading…
Reference in New Issue
Block a user