Skip to content
This repository was archived by the owner on Oct 27, 2025. It is now read-only.

Commit a5a0f9a

Browse files
author
Morten Hundevad
authored
Changes that allow for dismiss via time or via "revision" number (#119)
currently it is just using the title of the article but intended to be the an plugin option later on so user can choose to show both or none. the expand option is also prepared to be an option using react for each "component/feature"
1 parent 7331c91 commit a5a0f9a

File tree

4 files changed

+165
-54
lines changed

4 files changed

+165
-54
lines changed

src/main.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,16 @@ export class Main {
196196
const page: INotificationsFilter = {
197197
timestamp: 0,
198198
pageId: pageId,
199+
revision: 0,
199200
};
200201
if (action == 'mute') {
201202
page.timestamp = Date.now();
202203
}
204+
205+
// TODO: to be changed to a "revision based dismiss" curently just pernanentm type may need to be changed to a string instead of a number
206+
if (action == 'hide') {
207+
page.revision = pageId;
208+
}
203209
NotificationsFilter.update(page);
204210
}
205211

src/ui/inpagenotification/Inspagenotification.tsx

Lines changed: 151 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,76 @@ import { IIncidentPage, IncidentPage } from '@/models/incident';
66
import { IProductPage, ProductPage } from '@/models/product';
77
import { IProductLinePage, ProductLinePage } from '@/models/product-line';
88

9-
export interface IInpagenotificationPage {
9+
export interface IInPageNotificationPage {
1010
page: Page;
1111
}
1212

13-
const InpagenotificationPage = ({ page }: IInpagenotificationPage) => {
14-
const componentReferance = React.createRef<HTMLParagraphElement>();
13+
export interface IInPageNotificationPageMenu {
14+
pageReferance: React.RefObject<HTMLParagraphElement | null>;
15+
}
16+
17+
export interface IInPageNotificationPageOptions {
18+
showMore: boolean;
19+
showMute: boolean;
20+
showHide: boolean;
21+
}
22+
23+
export interface IInPageNotificationMessage {
24+
message: string;
25+
}
26+
27+
export interface IInPageNotificationCategory {
28+
pages: [string, Page[]];
29+
}
30+
31+
export interface IInPageNotification {
32+
containerId: string;
33+
message: string;
34+
pages: IPage[];
35+
}
36+
37+
const InPageNotificationPageMenu = ({
38+
page,
39+
pageReferance,
40+
showMore,
41+
showMute,
42+
showHide,
43+
}: IInPageNotificationPage & IInPageNotificationPageMenu & IInPageNotificationPageOptions) => {
44+
return (
45+
<>
46+
<div className="page-menu">
47+
{showMore && <InPageNotificationPageMore />}
48+
{showMute && <InPageNotificationPageMute page={page} pageReferance={pageReferance} />}
49+
{showHide && <InPageNotificationPageHide page={page} pageReferance={pageReferance} />}
50+
</div>
51+
</>
52+
);
53+
};
54+
55+
const InPageNotificationPageMore = () => {
56+
const seeMore = (event: React.MouseEvent<HTMLElement>) => {
57+
event.preventDefault();
58+
const categoryHeader = event.currentTarget as HTMLElement;
59+
if (categoryHeader) {
60+
const categoryContent = categoryHeader.parentElement?.parentElement?.querySelector('.page-info');
61+
if (categoryContent) {
62+
categoryContent.classList.toggle('hidden');
63+
64+
categoryHeader.textContent = categoryContent.classList.contains('hidden') ? '⯈' : '▼';
65+
}
66+
}
67+
};
68+
return (
69+
<>
70+
<span className="page-more" onClick={seeMore}>
71+
72+
</span>
73+
</>
74+
);
75+
};
1576

16-
const closePage = () => {
77+
const InPageNotificationPageMute = ({ page, pageReferance }: IInPageNotificationPage & IInPageNotificationPageMenu) => {
78+
const mutePage = () => {
1779
const notifyUpdatePayload = {
1880
pageId: page.pageId,
1981
action: 'mute',
@@ -24,49 +86,87 @@ const InpagenotificationPage = ({ page }: IInpagenotificationPage) => {
2486
payload: notifyUpdatePayload,
2587
});
2688

27-
if (componentReferance) {
28-
componentReferance.current?.remove();
89+
if (pageReferance) {
90+
pageReferance.current?.remove();
2991
}
3092
};
93+
return (
94+
<>
95+
<span className="page-mute" onClick={mutePage}>
96+
🕑
97+
</span>
98+
</>
99+
);
100+
};
31101

32-
const seeMore = (event: React.MouseEvent<HTMLElement>) => {
33-
event.preventDefault();
34-
const categoryHeader = event.currentTarget as HTMLElement;
35-
if (categoryHeader) {
36-
const categoryContent = categoryHeader.parentElement?.parentElement?.querySelector('.page-info');
37-
if (categoryContent) {
38-
categoryContent.classList.toggle('hidden');
102+
const InPageNotificationPageHide = ({ page, pageReferance }: IInPageNotificationPage & IInPageNotificationPageMenu) => {
103+
const hidePage = () => {
104+
const notifyUpdatePayload = {
105+
pageId: page.pageId,
106+
action: 'hide',
107+
};
39108

40-
categoryHeader.textContent = categoryContent.classList.contains('hidden') ? '⯈' : '▼';
41-
}
109+
void browser.runtime.sendMessage({
110+
type: 'notifyUpdate',
111+
payload: notifyUpdatePayload,
112+
});
113+
114+
if (pageReferance) {
115+
pageReferance.current?.remove();
42116
}
43117
};
118+
return (
119+
<>
120+
<span className="page-hide" onClick={hidePage}>
121+
122+
</span>
123+
</>
124+
);
125+
};
126+
127+
const InPageNotificationPageInfo = ({ page }: IInPageNotificationPage) => {
128+
return (
129+
<>
130+
<div className="page-info hidden">{page.description}</div>
131+
</>
132+
);
133+
};
134+
135+
const InPageNotificationPageLink = ({ page }: IInPageNotificationPage) => {
136+
return (
137+
<>
138+
<a href={page.url()} target="_blank">
139+
{page.pageName}
140+
</a>
141+
</>
142+
);
143+
};
144+
145+
const InPageNotificationPage = ({ page }: IInPageNotificationPage) => {
146+
const componentReferance = React.createRef<HTMLParagraphElement>();
147+
148+
const showMore = true; // TODO, should come from an option?
149+
const showMute = true; // TODO, should come from an option?
150+
const showHide = true; // TODO, should come from an option?
44151

45152
return (
46153
<>
47154
<div className="page" ref={componentReferance}>
48-
<div className="page-menu">
49-
<span className="page-more" onClick={seeMore}>
50-
51-
</span>
52-
<span className="page-close" onClick={closePage}>
53-
54-
</span>
55-
</div>
56-
<a href={page.url()} target="_blank">
57-
{page.pageName}
58-
</a>
59-
<div className="page-info hidden">{page.description}</div>
155+
<InPageNotificationPageMenu
156+
page={page}
157+
showMore={showMore}
158+
showMute={showMute}
159+
showHide={showHide}
160+
pageReferance={componentReferance}
161+
/>
162+
<InPageNotificationPageLink page={page} />
163+
{showMore && <InPageNotificationPageInfo page={page} />}
60164
</div>
61165
</>
62166
);
63167
};
64168

65-
export interface IInpagenotificationMessage {
66-
message: string;
67-
}
68-
69-
const InpagenotificationMessage = ({ message }: IInpagenotificationMessage) => {
169+
const InPageNotificationMessage = ({ message }: IInPageNotificationMessage) => {
70170
if (message && message.length > 0) {
71171
return (
72172
<>
@@ -78,16 +178,12 @@ const InpagenotificationMessage = ({ message }: IInpagenotificationMessage) => {
78178
}
79179
};
80180

81-
export interface IInpagenotificationCategory {
82-
pages: [string, Page[]];
83-
}
84-
85-
const InpagenotificationCategory = ({ pages }: IInpagenotificationCategory) => {
181+
const InPageNotificationCategory = ({ pages }: IInPageNotificationCategory) => {
86182
const categoryTitle = pages[0];
87183
const pagesList = pages[1];
88184

89185
if (categoryTitle && pagesList) {
90-
const cattegoryPages = pagesList.map((page, index) => <InpagenotificationPage key={index} page={page} />);
186+
const cattegoryPages = pagesList.map((page, index) => <InPageNotificationPage key={index} page={page} />);
91187

92188
const toggleCategory = (event: React.MouseEvent<HTMLElement>) => {
93189
event.preventDefault();
@@ -118,13 +214,7 @@ const InpagenotificationCategory = ({ pages }: IInpagenotificationCategory) => {
118214
}
119215
};
120216

121-
export interface IInpagenotification {
122-
containerId: string;
123-
message: string;
124-
pages: IPage[];
125-
}
126-
127-
const Inpagenotification = ({ containerId, message, pages }: IInpagenotification) => {
217+
const InPageNotification = ({ containerId, message, pages }: IInPageNotification) => {
128218
/**
129219
* timeout even for hiding the notification after a set time
130220
*
@@ -189,8 +279,8 @@ const Inpagenotification = ({ containerId, message, pages }: IInpagenotification
189279
}
190280
});
191281

192-
const inpagenotificationCategorysPages = Object.entries(_pages).map(([category, categoryPages], index) => {
193-
if (categoryPages.length) return <InpagenotificationCategory key={index} pages={[category, categoryPages]} />;
282+
const InPageNotificationCategorysPages = Object.entries(_pages).map(([category, categoryPages], index) => {
283+
if (categoryPages.length) return <InPageNotificationCategory key={index} pages={[category, categoryPages]} />;
194284
});
195285

196286
return (
@@ -280,16 +370,23 @@ const Inpagenotification = ({ containerId, message, pages }: IInpagenotification
280370
cursor: pointer;
281371
font-weight:
282372
bold;
283-
373+
}
374+
375+
.page-menu > * {
284376
margin-left: 10px;
285377
}
286378
379+
.page-close {
380+
}
381+
287382
.page-more {
288-
margin-right: 10px;
289383
}
290384
291-
.page-close {
292-
}
385+
.page-mute {
386+
}
387+
388+
.page-hide {
389+
}
293390
294391
.wikilink {
295392
height: 100%;
@@ -379,12 +476,12 @@ const Inpagenotification = ({ containerId, message, pages }: IInpagenotification
379476
<strong>Consumer Rights Wiki</strong>
380477
</span>
381478
</a>
382-
<InpagenotificationMessage message={message} />
383-
<div className="categorys">{inpagenotificationCategorysPages}</div>
479+
<InPageNotificationMessage message={message} />
480+
<div className="categorys">{InPageNotificationCategorysPages}</div>
384481
</div>
385482
</div>
386483
</>
387484
);
388485
};
389486

390-
export default Inpagenotification;
487+
export default InPageNotification;

src/utils/helpers/local-storage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
export interface ILocalStoragePage {
77
timestamp: number;
88
pageId: number;
9+
dismissed: string;
910
}
1011

1112
class LocalStorage {
@@ -45,6 +46,7 @@ class LocalStorage {
4546
const page: ILocalStoragePage = {
4647
timestamp: 0,
4748
pageId: pageId,
49+
dismissed: '',
4850
};
4951

5052
const pages = LocalStorage.read();

src/utils/helpers/notification-filter.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Page } from '@/models/page';
55
export interface INotificationsFilter {
66
timestamp: number;
77
pageId: number;
8+
revision: number;
89
}
910

1011
class NotificationsFilter {
@@ -35,6 +36,11 @@ class NotificationsFilter {
3536

3637
if (!existingPage) return true;
3738

39+
// TODO: revision based finter curently just permanent using page id.
40+
if (existingPage.revision == entry.pageId) {
41+
return false;
42+
}
43+
3844
return existingPage.timestamp + muteTime < now;
3945
});
4046
}

0 commit comments

Comments
 (0)