@everymatrix/nuts-inbox-widget 0.0.9 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/nuts-inbox-widget.cjs.js +1 -1
  3. package/dist/cjs/nuts-inbox-widget_3.cjs.entry.js +476 -449
  4. package/dist/collection/api/methods/index.js +135 -0
  5. package/dist/collection/api/methods/types.js +1 -0
  6. package/dist/collection/components/nuts-inbox-widget/nuts-inbox-widget.css +5 -0
  7. package/dist/collection/components/nuts-inbox-widget/nuts-inbox-widget.js +100 -123
  8. package/dist/collection/components/nuts-notification/constants.js +1 -0
  9. package/dist/collection/components/nuts-notification/nuts-notification.css +26 -11
  10. package/dist/collection/components/nuts-notification/nuts-notification.js +158 -100
  11. package/dist/collection/components/nuts-popover/nuts-popover.css +43 -0
  12. package/dist/collection/components/nuts-popover/nuts-popover.js +122 -61
  13. package/dist/collection/types/nuts-inbox-widget.types.js +0 -8
  14. package/dist/collection/utils/locale.utils.js +12 -4
  15. package/dist/collection/utils/utils.js +16 -0
  16. package/dist/components/nuts-inbox-widget.js +55 -235
  17. package/dist/components/nuts-notification2.js +278 -84
  18. package/dist/components/nuts-popover2.js +61 -45
  19. package/dist/esm/loader.js +1 -1
  20. package/dist/esm/nuts-inbox-widget.js +1 -1
  21. package/dist/esm/nuts-inbox-widget_3.entry.js +477 -450
  22. package/dist/nuts-inbox-widget/nuts-inbox-widget.esm.js +1 -1
  23. package/dist/nuts-inbox-widget/p-d0db9d2d.entry.js +1 -0
  24. package/dist/types/api/methods/index.d.ts +7 -0
  25. package/dist/types/api/methods/types.d.ts +65 -0
  26. package/dist/types/components/nuts-inbox-widget/nuts-inbox-widget.d.ts +20 -11
  27. package/dist/types/components/nuts-notification/constants.d.ts +1 -0
  28. package/dist/types/components/nuts-notification/nuts-notification.d.ts +18 -6
  29. package/dist/types/components/nuts-popover/nuts-popover.d.ts +17 -2
  30. package/dist/types/components.d.ts +50 -2
  31. package/dist/types/types/nuts-inbox-widget.types.d.ts +4 -7
  32. package/dist/types/utils/utils.d.ts +2 -0
  33. package/package.json +4 -1
  34. package/dist/nuts-inbox-widget/p-4788b3e5.entry.js +0 -1
  35. /package/dist/types/Users/{raul.vasile/workspace/everymatrix → adrian.pripon/Documents/Work}/widgets-stencil/packages/nuts-inbox-widget/.stencil/packages/nuts-inbox-widget/stencil.config.d.ts +0 -0
@@ -0,0 +1,135 @@
1
+ export const initializeSession = async ({ baseUrl, body, headers, }) => {
2
+ var _a;
3
+ const url = new URL(`${baseUrl}/widgets/session/initialize`);
4
+ const localHeaders = new Headers(headers);
5
+ localHeaders.append('Content-Type', 'application/json');
6
+ const options = {
7
+ method: 'POST',
8
+ body: JSON.stringify(body),
9
+ headers: localHeaders,
10
+ };
11
+ try {
12
+ const res = await fetch(url.href, options);
13
+ const data = await res.json();
14
+ const newToken = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.token;
15
+ headers.append('Widget-Authorization', `Bearer ${newToken}`);
16
+ const unseenCounter = await getUnseenCount({
17
+ baseUrl,
18
+ headers,
19
+ });
20
+ return {
21
+ token: newToken,
22
+ unseenCounter,
23
+ };
24
+ }
25
+ catch (error) {
26
+ console.log(error);
27
+ return {
28
+ token: null,
29
+ unseenCounter: 0,
30
+ };
31
+ }
32
+ };
33
+ export const getUnseenCount = async ({ baseUrl, headers, }) => {
34
+ var _a;
35
+ const url = new URL(`${baseUrl}/widgets/notifications/unseen?limit=100`);
36
+ const options = {
37
+ method: 'GET',
38
+ headers,
39
+ };
40
+ try {
41
+ const res = await fetch(url.href, options);
42
+ const data = await res.json();
43
+ const unseenCount = ((_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.count) || 0;
44
+ return unseenCount;
45
+ }
46
+ catch (error) {
47
+ console.log(error);
48
+ return 0;
49
+ }
50
+ };
51
+ export const deleteMessage = async ({ baseUrl, headers, messageId, }) => {
52
+ const url = new URL(`${baseUrl}/widgets/messages/${messageId}`);
53
+ const options = {
54
+ method: 'DELETE',
55
+ headers,
56
+ };
57
+ try {
58
+ await fetch(url.href, options);
59
+ return false;
60
+ }
61
+ catch (error) {
62
+ console.log(error);
63
+ return true;
64
+ }
65
+ };
66
+ export const markAsRead = async ({ baseUrl, body, headers, unread, }) => {
67
+ const url = new URL(`${baseUrl}/widgets/messages/markAs`);
68
+ const localHeaders = new Headers(headers);
69
+ localHeaders.append('Content-Type', 'application/json');
70
+ const options = {
71
+ method: 'POST',
72
+ headers: localHeaders,
73
+ body: JSON.stringify(body),
74
+ };
75
+ try {
76
+ const res = await fetch(url.href, options);
77
+ const data = await res.json();
78
+ return {
79
+ messageSeen: data.data[0].seen,
80
+ messageRead: data.data[0].read,
81
+ showSettingsModal: false,
82
+ };
83
+ }
84
+ catch (err) {
85
+ console.error('err', err);
86
+ return {
87
+ messageSeen: unread,
88
+ messageRead: unread,
89
+ showSettingsModal: true,
90
+ };
91
+ }
92
+ };
93
+ export const getNotifications = async ({ baseUrl, headers, page, }) => {
94
+ const url = new URL(`${baseUrl}/widgets/notifications/feed`);
95
+ url.searchParams.append('page', page.toString());
96
+ const options = {
97
+ method: 'GET',
98
+ headers,
99
+ };
100
+ try {
101
+ const res = await fetch(url.href, options);
102
+ const data = await res.json();
103
+ return {
104
+ isLoading: false,
105
+ numberOfNotifications: data.totalCount,
106
+ notifications: data.data,
107
+ };
108
+ }
109
+ catch (error) {
110
+ console.log(error);
111
+ return {
112
+ isLoading: false,
113
+ numberOfNotifications: 0,
114
+ notifications: [],
115
+ };
116
+ }
117
+ };
118
+ export const markAllAsRead = async ({ baseUrl, headers, }) => {
119
+ const url = new URL(`${baseUrl}/widgets/messages/read`);
120
+ const localHeaders = new Headers(headers);
121
+ localHeaders.append('Content-Type', 'application/json');
122
+ const options = {
123
+ method: 'POST',
124
+ body: JSON.stringify({}),
125
+ headers: localHeaders,
126
+ };
127
+ try {
128
+ await fetch(url.href, options);
129
+ return true;
130
+ }
131
+ catch (error) {
132
+ console.log(error);
133
+ return false;
134
+ }
135
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -8,9 +8,14 @@
8
8
  height: 40px;
9
9
  display: flex;
10
10
  }
11
+ .BellIconWrapper :hover {
12
+ cursor: pointer;
13
+ }
11
14
 
12
15
  .BellIcon {
13
16
  width: 40px;
14
17
  height: 40px;
15
18
  display: flex;
19
+ justify-content: center;
20
+ align-items: center;
16
21
  }
@@ -1,8 +1,8 @@
1
- import { __decorate, __metadata } from "tslib";
2
1
  import { getTranslations } from '../../utils/locale.utils';
3
- import { Component, h, Prop, State, Watch, Event } from '@stencil/core';
2
+ import { Component, h, Prop, State, Watch, Event, Listen, Element, } from '@stencil/core';
4
3
  import { io } from 'socket.io-client';
5
- import { ClickOutside } from "stencil-click-outside";
4
+ import { initializeSession } from '../../api/methods';
5
+ import { createAuthHeaders } from '../../utils/utils';
6
6
  export class NutsInboxWidget {
7
7
  constructor() {
8
8
  /**
@@ -29,10 +29,20 @@ export class NutsInboxWidget {
29
29
  * Translations via URL
30
30
  */
31
31
  this.translationUrl = '';
32
- this.isLoading = true;
32
+ this.isLoading = false;
33
33
  this.popoverVisible = false;
34
- this.ssEndpoint = 'https://nts.everymatrix.com/ss';
35
34
  this.token = null;
35
+ this.baseUrl = `${this.backendUrl}/v1/${this.operatorId}`;
36
+ this.initializeSessionBody = {
37
+ applicationIdentifier: this.applicationIdentifier,
38
+ subscriberId: this.subscriberId || `${this.operatorId}-${this.userId}`,
39
+ hmacHash: null,
40
+ };
41
+ this.defaultHeaders = createAuthHeaders(this.token, this.sessionId, this.admin);
42
+ this.togglePopover = () => {
43
+ this.popoverVisible = !this.popoverVisible;
44
+ window.postMessage({ type: 'nuts-popover-isVisible', value: this.popoverVisible }, window.location.href);
45
+ };
36
46
  this.setClientStyling = () => {
37
47
  let sheet = document.createElement('style');
38
48
  sheet.innerHTML = this.clientStyling;
@@ -46,28 +56,40 @@ export class NutsInboxWidget {
46
56
  .then((data) => {
47
57
  cssFile.innerHTML = data;
48
58
  this.clientStyling = data;
49
- setTimeout(() => { this.stylingContainer.prepend(cssFile); }, 1);
59
+ setTimeout(() => {
60
+ this.stylingContainer.prepend(cssFile);
61
+ }, 1);
50
62
  })
51
63
  .catch((err) => {
52
64
  console.log('error ', err);
53
65
  });
54
66
  };
55
- }
56
- paramChangeHandler(newValue, oldValue) {
57
- if (newValue != oldValue) {
58
- if (this.userId && this.sessionId && this.operatorId) {
59
- this.callSS();
60
- }
61
- }
67
+ this.assignRefToStylingContainer = (ref) => {
68
+ this.stylingContainer = ref;
69
+ };
70
+ this.assignRefToBell = (ref) => {
71
+ this.bellIconRef = ref;
72
+ };
62
73
  }
63
74
  initializeHandler(newValue, oldValue) {
64
75
  if (newValue != oldValue) {
65
76
  if (this.userId && this.operatorId && this.applicationIdentifier) {
66
- this.initializeSession();
77
+ initializeSession({
78
+ baseUrl: this.baseUrl,
79
+ body: this.initializeSessionBody,
80
+ headers: this.defaultHeaders,
81
+ }).then((initializeSessionResult) => {
82
+ this.token = initializeSessionResult.token;
83
+ this.unseenCount = initializeSessionResult.unseenCounter;
84
+ this.setupSocket();
85
+ });
67
86
  }
68
87
  }
69
88
  }
70
- clickOutsideHandle() {
89
+ clickOutsideHandle(ev) {
90
+ if (ev.composedPath().some((elem) => this.el === elem)) {
91
+ return;
92
+ }
71
93
  this.popoverVisible = false;
72
94
  window.postMessage({ type: 'nuts-popover-isVisible', value: this.popoverVisible }, window.location.href);
73
95
  }
@@ -79,33 +101,6 @@ export class NutsInboxWidget {
79
101
  this.bellIconRef.style.justifyContent = 'flex-end';
80
102
  }
81
103
  }
82
- callSS() {
83
- const url = new URL(`${this.ssEndpoint}/v1/${this.operatorId}/subscribers/${this.userId}/initialize`);
84
- const headers = new Headers();
85
- headers.append('authorization', this.sessionId);
86
- headers.append('Content-Type', 'application/json');
87
- const body = {
88
- deviceId: this.deviceId,
89
- language: this.language
90
- };
91
- const options = {
92
- method: 'POST',
93
- headers,
94
- body: JSON.stringify(body)
95
- };
96
- fetch(url.href, options)
97
- .then((res) => {
98
- if (res.status < 300) {
99
- return res.json();
100
- }
101
- })
102
- .catch((err) => {
103
- console.error('There was an error while trying to connect to the Notification System', err);
104
- })
105
- .finally(() => {
106
- this.isLoading = false;
107
- });
108
- }
109
104
  setupSocket() {
110
105
  if (this.token) {
111
106
  this.socketRef = io(this.socketUrl, {
@@ -127,63 +122,21 @@ export class NutsInboxWidget {
127
122
  });
128
123
  this.socketRef.on('unseen_count_changed', (data) => {
129
124
  this.unseenCount = data.unseenCount;
130
- this.unseenCount > 0 && window.postMessage({ type: 'nuts-new-notifications', value: this.unseenCount }, window.location.href);
125
+ this.unseenCount > 0 &&
126
+ window.postMessage({ type: 'nuts-new-notifications', value: this.unseenCount }, window.location.href);
131
127
  });
132
128
  }
133
129
  }
134
- getUnseenCounter() {
135
- let url = new URL(`${this.backendUrl}/v1/widgets/notifications/unseen?limit=100`);
136
- const headers = new Headers();
137
- headers.append('Authorization', `Bearer ${this.token || ''}`);
138
- const options = {
139
- method: 'GET',
140
- headers,
141
- };
142
- fetch(url.href, options)
143
- .then((res) => res.json())
144
- .then((data) => {
145
- this.unseenCount = data.data.count;
146
- });
147
- }
148
- async initializeSession() {
149
- return new Promise((resolve, reject) => {
150
- let url = new URL(`${this.backendUrl}/v1/widgets/session/initialize`);
151
- const headers = new Headers();
152
- headers.append('Authorization', `Bearer ${this.token || ''}`);
153
- headers.append('Content-Type', 'application/json');
154
- const body = {
155
- applicationIdentifier: this.applicationIdentifier,
156
- subscriberId: `${this.operatorId}-${this.userId}`,
157
- hmacHash: null
158
- };
159
- const options = {
160
- method: 'POST',
161
- body: JSON.stringify(body),
162
- headers,
163
- };
164
- fetch(url.href, options)
165
- .then(res => res.json())
166
- .then((data) => {
167
- this.token = data.data.token;
168
- this.setupSocket();
169
- this.getUnseenCounter();
170
- resolve(data);
171
- })
172
- .catch((err) => {
173
- reject(err);
174
- });
175
- });
176
- }
177
- togglePopover() {
178
- this.popoverVisible = !this.popoverVisible;
179
- window.postMessage({ type: 'nuts-popover-isVisible', value: this.popoverVisible }, window.location.href);
180
- }
181
130
  async connectedCallback() {
182
131
  if (this.userId && this.operatorId && this.applicationIdentifier) {
183
- this.initializeSession();
184
- }
185
- if (this.userId && this.operatorId && this.sessionId) {
186
- this.callSS();
132
+ const initializeSessionResult = await initializeSession({
133
+ baseUrl: this.baseUrl,
134
+ headers: this.defaultHeaders,
135
+ body: this.initializeSessionBody,
136
+ });
137
+ this.token = initializeSessionResult.token;
138
+ this.unseenCount = initializeSessionResult.unseenCounter;
139
+ this.setupSocket();
187
140
  }
188
141
  if (this.clientStylingUrl) {
189
142
  this.setClientStylingURL();
@@ -204,22 +157,22 @@ export class NutsInboxWidget {
204
157
  this.positionIcon();
205
158
  }
206
159
  renderBellIcon() {
207
- return (h("div", { onClick: () => this.togglePopover(), class: "BellIcon" },
160
+ return (h("div", { onClick: this.togglePopover, class: "BellIcon" },
208
161
  h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "32", height: "32", fill: "currentColor", class: "bi bi-bell", viewBox: "0 0 16 16" },
209
- " ",
162
+ ' ',
210
163
  h("path", { d: "M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2zM8 1.918l-.797.161A4.002 4.002 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4.002 4.002 0 0 0-3.203-3.92L8 1.917zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5.002 5.002 0 0 1 13 6c0 .88.32 4.2 1.22 6z" }),
211
- " "),
212
- this.unseenCount > 0 ? h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", class: "nc-bell-button-dot css-0 css-1eg2znq" },
164
+ ' '),
165
+ this.unseenCount > 0 ? (h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", class: "nc-bell-button-dot css-0 css-1eg2znq" },
213
166
  h("rect", { x: "1.5", y: "1.5", width: "13", height: "13", rx: "6.5", fill: "url(#paint0_linear_1722_2699)", stroke: "#1E1E26", "stroke-width": "3" }),
214
167
  h("defs", null,
215
168
  h("linearGradient", { id: "paint0_linear_1722_2699", x1: "8", y1: "13", x2: "8", y2: "3", gradientUnits: "userSpaceOnUse" },
216
169
  h("stop", { "stop-color": "#FF512F" }),
217
- h("stop", { offset: "1", "stop-color": "#DD2476" })))) : ''));
170
+ h("stop", { offset: "1", "stop-color": "#DD2476" }))))) : ('')));
218
171
  }
219
172
  render() {
220
- return (h("div", { ref: el => this.stylingContainer = el, class: "Wrapper" },
221
- h("div", { ref: el => this.bellIconRef = el, class: "BellIconWrapper" }, !this.isLoading && this.renderBellIcon()),
222
- this.popoverVisible && h("nuts-popover", { "notification-action": this.notificationAction, "unseen-count": this.unseenCount, token: this.token, "backend-url": this.backendUrl, "operator-id": this.operatorId, "user-id": this.userId, language: this.language, "client-styling": this.clientStyling, "translation-url": this.translationUrl })));
173
+ return (h("div", { ref: this.assignRefToStylingContainer, class: "Wrapper" },
174
+ h("div", { ref: this.assignRefToBell, class: "BellIconWrapper" }, !this.isLoading && this.renderBellIcon()),
175
+ this.popoverVisible && (h("nuts-popover", { "notification-action": this.notificationAction, sessionId: this.sessionId, admin: this.admin, "unseen-count": this.unseenCount, token: this.token, "backend-url": this.backendUrl, "operator-id": this.operatorId, "user-id": this.userId, language: this.language, "client-styling": this.clientStyling, "translation-url": this.translationUrl }))));
223
176
  }
224
177
  static get is() { return "nuts-inbox-widget"; }
225
178
  static get encapsulation() { return "shadow"; }
@@ -298,6 +251,23 @@ export class NutsInboxWidget {
298
251
  "attribute": "session-id",
299
252
  "reflect": true
300
253
  },
254
+ "admin": {
255
+ "type": "boolean",
256
+ "mutable": false,
257
+ "complexType": {
258
+ "original": "boolean",
259
+ "resolved": "boolean",
260
+ "references": {}
261
+ },
262
+ "required": false,
263
+ "optional": true,
264
+ "docs": {
265
+ "tags": [],
266
+ "text": "Indicates if the associated sessionId is an admin or a player sessionId"
267
+ },
268
+ "attribute": "admin",
269
+ "reflect": true
270
+ },
301
271
  "operatorId": {
302
272
  "type": "string",
303
273
  "mutable": false,
@@ -315,6 +285,23 @@ export class NutsInboxWidget {
315
285
  "attribute": "operator-id",
316
286
  "reflect": true
317
287
  },
288
+ "subscriberId": {
289
+ "type": "string",
290
+ "mutable": false,
291
+ "complexType": {
292
+ "original": "string",
293
+ "resolved": "string",
294
+ "references": {}
295
+ },
296
+ "required": false,
297
+ "optional": true,
298
+ "docs": {
299
+ "tags": [],
300
+ "text": "The subscriberID"
301
+ },
302
+ "attribute": "subscriber-id",
303
+ "reflect": true
304
+ },
318
305
  "deviceId": {
319
306
  "type": "string",
320
307
  "mutable": false,
@@ -491,10 +478,10 @@ export class NutsInboxWidget {
491
478
  "text": ""
492
479
  },
493
480
  "complexType": {
494
- "original": "Notifications[]",
495
- "resolved": "Notifications[]",
481
+ "original": "Notification[]",
482
+ "resolved": "Notification[]",
496
483
  "references": {
497
- "Notifications": {
484
+ "Notification": {
498
485
  "location": "import",
499
486
  "path": "../../types/nuts-inbox-widget.types"
500
487
  }
@@ -516,19 +503,8 @@ export class NutsInboxWidget {
516
503
  "references": {}
517
504
  }
518
505
  }]; }
506
+ static get elementRef() { return "el"; }
519
507
  static get watchers() { return [{
520
- "propName": "userId",
521
- "methodName": "paramChangeHandler"
522
- }, {
523
- "propName": "sessionId",
524
- "methodName": "paramChangeHandler"
525
- }, {
526
- "propName": "operatorId",
527
- "methodName": "paramChangeHandler"
528
- }, {
529
- "propName": "deviceId",
530
- "methodName": "paramChangeHandler"
531
- }, {
532
508
  "propName": "userId",
533
509
  "methodName": "initializeHandler"
534
510
  }, {
@@ -541,10 +517,11 @@ export class NutsInboxWidget {
541
517
  "propName": "translationUrl",
542
518
  "methodName": "handleNewTranslations"
543
519
  }]; }
520
+ static get listeners() { return [{
521
+ "name": "click",
522
+ "method": "clickOutsideHandle",
523
+ "target": "window",
524
+ "capture": false,
525
+ "passive": false
526
+ }]; }
544
527
  }
545
- __decorate([
546
- ClickOutside(),
547
- __metadata("design:type", Function),
548
- __metadata("design:paramtypes", []),
549
- __metadata("design:returntype", void 0)
550
- ], NutsInboxWidget.prototype, "clickOutsideHandle", null);
@@ -0,0 +1 @@
1
+ export const MAX_NOTIFICATION_TEXT_LENGTH = 150;
@@ -18,14 +18,16 @@ p {
18
18
  position: relative;
19
19
  display: flex;
20
20
  line-height: 20px;
21
- justify-content: flex-start;
22
- align-items: center;
21
+ justify-content: space-between;
22
+ align-items: flex-start;
23
23
  border-radius: 7px;
24
24
  margin: 10px 15px;
25
25
  color: var(--emfe-w-color-white, white);
26
26
  background: var(--emfe-w-color-gray-400, #23232b);
27
27
  font-weight: 400;
28
28
  font-size: 14px;
29
+ gap: 8px;
30
+ cursor: pointer;
29
31
  }
30
32
  @keyframes show {
31
33
  100% {
@@ -76,6 +78,19 @@ p {
76
78
  .NotificationContainer .ContentContainer {
77
79
  display: flex;
78
80
  flex-direction: column;
81
+ word-break: break-all;
82
+ }
83
+ .NotificationContainer .RightActionsContainer {
84
+ display: flex;
85
+ flex-direction: column;
86
+ }
87
+ .NotificationContainer .FlipX {
88
+ transform: rotateX(180deg) translate(0, 4px);
89
+ }
90
+ .NotificationContainer .AccordionArrow {
91
+ margin-left: 4px;
92
+ transition-duration: 0.2s;
93
+ transition-property: transform;
79
94
  }
80
95
  .NotificationContainer .Date {
81
96
  min-width: 55px;
@@ -86,12 +101,9 @@ p {
86
101
  color: var(--emfe-w-color-gray-200, #525266);
87
102
  }
88
103
  .NotificationContainer .Settings {
89
- opacity: 0;
90
- margin-left: auto;
91
- cursor: pointer;
92
- }
93
- .NotificationContainer:hover .Settings {
94
104
  opacity: 0.5;
105
+ display: inline;
106
+ cursor: pointer;
95
107
  }
96
108
 
97
109
  .Unseen::before {
@@ -104,8 +116,7 @@ p {
104
116
  }
105
117
 
106
118
  .Unseen:hover .UnseenButton {
107
- opacity: 0;
108
- width: 0px;
119
+ display: none;
109
120
  }
110
121
 
111
122
  .SettingsDropdown {
@@ -123,8 +134,8 @@ p {
123
134
  width: max-content;
124
135
  display: flex;
125
136
  flex-direction: column;
126
- margin-left: 195px;
127
- margin-top: -30px;
137
+ right: 50px;
138
+ top: 50px;
128
139
  }
129
140
  .SettingsDropdown svg {
130
141
  margin-right: 10px;
@@ -150,4 +161,8 @@ p {
150
161
  .SettingsDropdown button:hover {
151
162
  background: var(--emfe-w-color-gray-300, #3d3d4d);
152
163
  transition: 300ms;
164
+ }
165
+
166
+ .Wrapper {
167
+ position: relative;
153
168
  }