Skip to content

Commit c82dfcf

Browse files
committed
Use constants, Remove redundant message types
Constants (defined once) are better than hardcoded strings, also allows for better type checking Removed redundant message types getSetting and setSetting (zype)
1 parent 5984b55 commit c82dfcf

19 files changed

Lines changed: 122 additions & 91 deletions

File tree

src/scripts/background_script.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getBrowserInstance } from './helpers/sharedExt';
1+
import { BrowserMessage, getBrowserInstance, parseTypeObject } from './helpers/sharedExt';
22
import { Creator, loadCreators as _loadCreators, creatorHasVideo, normalizeString } from './helpers/youtube';
33

44
const videoFetch = 50;
@@ -8,13 +8,15 @@ getBrowserInstance().browserAction.onClicked.addListener(() => {
88
});
99

1010
getBrowserInstance().runtime.onMessage.addListener(async (message: string | { [key: string]: any }) => {
11-
if (typeof message === 'string') message = { type: message };
12-
switch (message.type) {
13-
case 'loadCreators':
14-
return console.debug(await loadCreators());
15-
case 'getYoutubeId':
16-
return getYoutubeId(message);
17-
}
11+
try {
12+
const msg = parseTypeObject(message);
13+
switch (msg.type) {
14+
case BrowserMessage.LOAD_CREATORS:
15+
return console.debug(await loadCreators());
16+
case BrowserMessage.GET_YTID:
17+
return getYoutubeId(msg);
18+
}
19+
} catch {}
1820
});
1921

2022
getBrowserInstance().runtime.onInstalled.addListener(async (details) => {

src/scripts/content/api/store.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { getCookie } from '../../helpers/shared';
1+
import { NEBULA_AUTH_KEY, getCookie } from '../../helpers/shared';
22

33
export const opt = {
44
auth: null as string,
55
};
66

77
export const refreshToken = async () => {
8-
const cookie = getCookie('nebula-auth');
8+
const cookie = getCookie(NEBULA_AUTH_KEY);
99
let apiToken = '';
1010
try {
1111
({ apiToken } = JSON.parse(cookie));

src/scripts/content/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import iconWatchLater from '../../icons/watchlater.svg';
22
import { durationLocation, queueBottonLocation } from '../helpers/locations';
3-
import { getBrowserInstance, injectScript, isMobile, isVideoPage, mutation, videoUrlMatch, ytvideo } from '../helpers/sharedExt';
3+
import { BrowserMessage, getBrowserInstance, injectScript, isMobile, isVideoPage, mutation, videoUrlMatch, ytvideo } from '../helpers/sharedExt';
44
import { creatorRegex, loadPrefix } from '../page/dispatcher';
55
import { enqueueChannelVideos } from './api';
66
import { handle } from './message';
@@ -152,7 +152,7 @@ const loadComments = async () => {
152152
console.debug(`Requesting '${title}' by ${creator}`);
153153

154154
try {
155-
const vid: ytvideo = await getBrowserInstance().runtime.sendMessage({ type: 'getYoutubeId', creator, title });
155+
const vid: ytvideo = await getBrowserInstance().runtime.sendMessage({ type: BrowserMessage.GET_YTID, creator, title });
156156
const v = document.createElement('span');
157157
v.classList.add('enhancer-yt');
158158
const a = document.createElement('a');
@@ -177,7 +177,7 @@ const createLinkForAll = () => {
177177
if (!container)
178178
return;
179179

180-
const link = !container.children.length ? document.createElement('a') : container.children[0].cloneNode(true) as HTMLLinkElement;
180+
const link = !container.children.length ? document.createElement('a') : container.children[0].cloneNode(true) as HTMLAnchorElement;
181181
link.style.color = link.querySelector('svg')?.getAttribute('fill');
182182
link.innerHTML = iconWatchLater;
183183
link.href = '#';

src/scripts/content/message.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getBrowserInstance, parseTypeObject, replyMessage, videosettings } from '../helpers/sharedExt';
1+
import { Events, Message, getBrowserInstance, isQueueMessage, parseTypeObject, replyMessage } from '../helpers/sharedExt';
22
import { Queue } from './queue';
33

44
const { local } = getBrowserInstance().storage;
@@ -14,35 +14,24 @@ export const handle = (e: MessageEvent) => {
1414
const msg = parseTypeObject<Msg>(e.data, true);
1515
if (msg === null)
1616
return true; // ignore invalid messages
17-
if (msg.type?.startsWith('enhancer-message-'))
17+
if (msg.type.startsWith('enhancer-message-'))
1818
return true; // ignore replies
1919

20-
if (msg.type?.startsWith('queue'))
20+
if (isQueueMessage(msg.type))
2121
return Queue.get().handleMessage(e, msg);
2222

2323
let promise: Promise<any> = null;
2424
switch (msg.type) {
25-
case 'getSetting': {
26-
const { setting } = msg;
27-
promise = Promise.resolve(setting ? videosettings[setting as keyof typeof videosettings] : videosettings);
28-
break;
29-
}
30-
case 'setSetting': {
31-
const { setting } = msg;
32-
const v = isNaN(msg.value) || msg.value == '' ? msg.value as string : +msg.value;
33-
videosettings[setting as keyof typeof videosettings] = v as never;
34-
return true;
35-
}
36-
case 'getStorage':
25+
case Message.GET_STORAGE:
3726
promise = local.get(msg.get);
3827
break;
39-
case 'getMessage':
28+
case Message.GET_MESSAGE:
4029
promise = Promise.resolve(getBrowserInstance().i18n.getMessage(msg.message));
4130
break;
42-
case 'getQueueStatus':
31+
case Message.GET_QSTATUS:
4332
promise = Promise.resolve({ canNext: Queue.get().canGoNext(), canPrev: Queue.get().canGoPrev() });
4433
break;
45-
case 'registerListener':
34+
case Message.REGISTER_LISTENER:
4635
registerListener(e, msg);
4736
return true;
4837
default:
@@ -55,7 +44,7 @@ export const handle = (e: MessageEvent) => {
5544

5645
const registerListener = (e: MessageEvent, msg: Msg) => {
5746
switch (msg.event) {
58-
case 'queueChange':
47+
case Events.QUEUE_CHANGE:
5948
Queue.get().onChange(() => replyMessage(e, msg.name, { canNext: Queue.get().canGoNext(), canPrev: Queue.get().canGoPrev() }));
6049
break;
6150
}

src/scripts/content/queue/add.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import type { Queue } from './index';
66
export async function addToStore(this: Queue, name: string, el?: HTMLElement): Promise<video>;
77
export async function addToStore(this: Queue, name: Nebula.Video[]): Promise<video[]>;
88
export async function addToStore(this: Queue, name: string | Nebula.Video[], el?: HTMLElement): Promise<video | video[]> {
9-
if (typeof name !== 'string') {
9+
if (typeof name !== 'string')
1010
return name.map(v => this.store[v.slug] = extractData(v));
11-
}
1211

1312
console.debug('Added video', name);
1413
if (!(el instanceof HTMLElement)) {

src/scripts/content/queue/drag.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { DRAG_HEIGHT, DRAG_INDEX } from '../../helpers/shared';
12
import type { Queue } from './index';
23

34
const dragElement = (e: DragEvent) => {
@@ -9,8 +10,8 @@ const dragElement = (e: DragEvent) => {
910
return e.preventDefault();
1011
const scroll = el.parentElement.scrollTop;
1112
const h = el.getBoundingClientRect().height;
12-
e.dataTransfer.setData('text/index', `${i}`);
13-
e.dataTransfer.setData('text/height', `${h}`);
13+
e.dataTransfer.setData(DRAG_INDEX, `${i}`);
14+
e.dataTransfer.setData(DRAG_HEIGHT, `${h}`);
1415
el.style.marginTop = `-${h}px`;
1516
el.classList.add('dragging');
1617
el.before(fake(h));
@@ -22,7 +23,7 @@ const dropElement = (q: Queue, e: DragEvent) => {
2223
if (el === null)
2324
return;
2425
let i = Array.from(el.parentElement.children).findIndex(n => n.isSameNode(el));
25-
const o = +e.dataTransfer.getData('text/index');
26+
const o = +e.dataTransfer.getData(DRAG_INDEX);
2627
if (i === -1 || i === o)
2728
return;
2829
el.parentElement.querySelector('.fake')?.remove();
@@ -40,12 +41,12 @@ const dragOverElement = (e: DragEvent) => {
4041
const fi = f !== null ? Array.from(el.parentElement.children).findIndex(n => n.isSameNode(f)) : 0;
4142
f?.remove();
4243
const i = Array.from(el.parentElement.children).findIndex(n => n.isSameNode(el));
43-
const o = +e.dataTransfer.getData('text/index');
44+
const o = +e.dataTransfer.getData(DRAG_INDEX);
4445
if (i === -1 || i === o)
4546
return;
4647
const p = el.parentElement;
4748
const s = i < fi ? (i > 0 ? p.children[i - 1] : null) : p.children[i];
48-
const h = +e.dataTransfer.getData('text/height');
49+
const h = +e.dataTransfer.getData(DRAG_HEIGHT);
4950
const node = fake(h);
5051
if (s === null)
5152
p.firstChild.before(node);

src/scripts/content/queue/listener.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getBrowserInstance } from '../../helpers/sharedExt';
1+
import { Message, getBrowserInstance, videoUrlMatch } from '../../helpers/sharedExt';
22
import type { Queue } from './index';
33

44
const confirmClear = getBrowserInstance().i18n.getMessage('pageQueueClearConfirm');
@@ -45,18 +45,18 @@ export function clickTop(this: Queue, e: MouseEvent) {
4545

4646
export function handleMessage(this: Queue, e: MessageEvent, msg: { type: string, [key: string]: any }): true {
4747
switch (msg.type) {
48-
case 'queueGotoNext':
48+
case Message.QUEUE_NEXT:
4949
this.gotoNext();
5050
break;
51-
case 'queueGotoPrev':
51+
case Message.QUEUE_PREV:
5252
this.gotoPrev();
5353
break;
5454
}
5555
return true;
5656
}
5757

5858
export function popState(this: Queue) {
59-
const match = window.location.pathname.match(/^\/videos\/(.+?)\/?$/);
59+
const match = window.location.pathname.match(videoUrlMatch);
6060
if (match === null) return this.goto(-1, false);
6161
this.goto(this.queue.indexOf(match[1]), false);
6262
}

src/scripts/helpers/shared/communication.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import { Events, Message } from './constants';
12
import { clone, parseTypeObject } from './helpers';
23

3-
export const sendMessage = <T>(name: string, data?: { [key: string]: any }, expectAnswer = true, skipOriginCheck = false) => {
4+
export function sendMessage(name: Message.GET_MESSAGE, data: { message: string }): Promise<string>;
5+
export function sendMessage(name: Message.GET_QSTATUS): Promise<{ canNext: boolean, canPrev: boolean }>;
6+
export function sendMessage<T>(name: Exclude<Message, Message.GET_MESSAGE | Message.GET_QSTATUS>, data?: { [key: string]: any }, expectAnswer?: boolean, skipOriginCheck?: boolean): Promise<T>;
7+
export function sendMessage<T>(name: Message, data?: { [key: string]: any }, expectAnswer = true, skipOriginCheck = false) {
48
if (!expectAnswer) {
59
window.parent.postMessage(JSON.stringify({ ...data, type: name }), '*');
610
return Promise.resolve(undefined as T);
@@ -22,10 +26,12 @@ export const sendMessage = <T>(name: string, data?: { [key: string]: any }, expe
2226
window.addEventListener('message', c);
2327
window.parent.postMessage(JSON.stringify({ ...data, type: name, name: e }), '*');
2428
});
25-
};
29+
}
2630

27-
export type Listener = (res: any, err: any) => void;
28-
export const sendEventHandler = (event: string, listener: Listener, skipOriginCheck = false) => {
31+
export type Listener<R = any, E = any> = (res: R, err: E) => void;
32+
export function sendEventHandler(event: Events.QUEUE_CHANGE, listener: Listener<{ canNext: boolean, canPrev: boolean }>, skipOriginCheck?: boolean): void;
33+
export function sendEventHandler(event: Exclude<Events, Events.QUEUE_CHANGE>, listener: Listener, skipOriginCheck?: boolean): void;
34+
export function sendEventHandler(event: Events, listener: Listener, skipOriginCheck = false) {
2935
const e = `enhancer-event-${event}-${Math.random().toString().substr(2)}`;
3036
const c = (ev: MessageEvent) => {
3137
if (!skipOriginCheck && !ev.origin.match(/https?:\/\/(?:watchnebula.com|(?:.+\.)?nebula.app)/)) return;
@@ -36,8 +42,8 @@ export const sendEventHandler = (event: string, listener: Listener, skipOriginCh
3642
} catch {}
3743
};
3844
window.addEventListener('message', c);
39-
window.parent.postMessage(JSON.stringify({ type: 'registerListener', name: e, event }), '*');
40-
};
45+
window.parent.postMessage(JSON.stringify({ type: Message.REGISTER_LISTENER, name: e, event }), '*');
46+
}
4147

4248
export const replyMessage = (e: MessageEvent, name: string, data?: any, err?: any) => name &&
4349
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Internal
2+
export const enum Message {
3+
QUEUE_NEXT = 'queueGotoNext',
4+
QUEUE_PREV = 'queueGotoPrev',
5+
6+
GET_STORAGE = 'getStorage',
7+
GET_MESSAGE = 'getMessage',
8+
GET_QSTATUS = 'getQueueStatus',
9+
10+
REGISTER_LISTENER = 'registerListener',
11+
}
12+
export const isQueueMessage = (msg: string) => msg.startsWith('queue');
13+
14+
export const enum Events {
15+
QUEUE_CHANGE = 'queueChange',
16+
}
17+
18+
export const DRAG_INDEX = 'text/index';
19+
export const DRAG_HEIGHT = 'text/height';
20+
21+
22+
export const enum BrowserMessage {
23+
LOAD_CREATORS = 'loadCreators',
24+
GET_YTID = 'getYoutubeId',
25+
}
26+
27+
28+
// Nebula
29+
export const NEBULA_AUTH_KEY = 'nebula-auth';

src/scripts/helpers/shared/helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ export const parseMaybeJSON = (data: string) => {
8383
return data;
8484
}
8585
};
86-
export const parseTypeObject = <T extends { type: string }>(data: string, nullable = false): T => {
87-
const d = parseMaybeJSON(data);
86+
export const parseTypeObject = <T extends { type: string }>(data: string | Record<string, any>, nullable = false): T => {
87+
const d = typeof data === 'string' ? parseMaybeJSON(data) : data;
8888
if (typeof d === 'string') return { type: d } as T;
8989
if (typeof d.type === 'string') return d;
9090
if (nullable) return null;

0 commit comments

Comments
 (0)