+
@@ -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
with some html for bold measure",
+ notificationText: "
Sample text. 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;
}
}
\ No newline at end of file
diff --git a/src/ext/lib/uwui/PlayerNotificationUI.js b/src/ext/lib/uwui/PlayerNotificationUI.js
index 245592d..0b0afc5 100644
--- a/src/ext/lib/uwui/PlayerNotificationUI.js
+++ b/src/ext/lib/uwui/PlayerNotificationUI.js
@@ -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];
}
}
diff --git a/src/ext/lib/uwui/UI.js b/src/ext/lib/uwui/UI.js
index 35eb9ff..4ba063a 100644
--- a/src/ext/lib/uwui/UI.js
+++ b/src/ext/lib/uwui/UI.js
@@ -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) {
diff --git a/src/ext/lib/video-data/PlayerData.js b/src/ext/lib/video-data/PlayerData.js
index c6493e7..e7b54d3 100644
--- a/src/ext/lib/video-data/PlayerData.js
+++ b/src/ext/lib/video-data/PlayerData.js
@@ -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'){