Skip to content

Commit

Permalink
fix: try to fix the blank page on mobile #48
Browse files Browse the repository at this point in the history
- deprecate the namespace approach
- the some APIs optional in order to force us to check before use
  • Loading branch information
t7yang committed Jul 30, 2024
1 parent 898c30e commit 712ca2d
Show file tree
Hide file tree
Showing 31 changed files with 159 additions and 199 deletions.
4 changes: 2 additions & 2 deletions src/background/clipboard/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LangType } from 'tongwen-core';
import { browser } from '../../service/browser';
import { i18n } from '../../service/i18n/i18n';
import { createNoti } from '../../service/notification/create-noti';
import { permissions } from '../../service/permissions/permissions';
import { BgState } from '../state';

const convertClipboardContent = (state: BgState, target: LangType): Promise<void> =>
Expand All @@ -11,7 +11,7 @@ const convertClipboardContent = (state: BgState, target: LangType): Promise<void
.then(text => navigator.clipboard.writeText(text));

export const convertClipboard = (state: BgState, target: LangType): Promise<void> =>
permissions
browser.permissions
.request({ permissions: ['clipboardRead', 'clipboardWrite'] })
.then(async isGet => (isGet && (await convertClipboardContent(state, target)), isGet))
.then(isGet => {
Expand Down
22 changes: 11 additions & 11 deletions src/background/menu/browser-action.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { LangType } from 'tongwen-core';
import { Menus } from 'webextension-polyfill';
import { isUrlLike } from '../../preference/filter-rule';
import { FilterTarget } from '../../preference/types/v2';
import { browser } from '../../service/browser';
import { i18n } from '../../service/i18n/i18n';
import { menus } from '../../service/menu/menus';
import { runtime } from '../../service/runtime/runtime';
import { addFilterRule } from '../../service/storage/local';
import { tabs } from '../../service/tabs/tabs';
import { getHostName, getRandomId } from '../../utilities';
import { convertClipboard } from '../clipboard';
import { BgState } from '../state';

// TODO: handle for none http protocol url
type AddDomainToRule = (t: FilterTarget) => (i: menus.OnClickData, t: tabs.Tab) => void;
type AddDomainToRule = (t: FilterTarget) => (i: browser.Menus.OnClickData, t: browser.Tabs.Tab) => void;
const addDomainToRules: AddDomainToRule = target => (_, tab) => {
isUrlLike(tab.url!) &&
addFilterRule({
Expand All @@ -23,7 +20,7 @@ const addDomainToRules: AddDomainToRule = target => (_, tab) => {
});
};

const createBrowserActionProperties: () => menus.CreateProperties[] = () => [
const createBrowserActionProperties: () => browser.Menus.CreateCreatePropertiesType[] = () => [
{
title: i18n.getMessage('MSG_ADD_DOMAIN_TO_DISABLED'),
onclick: addDomainToRules('disabled'),
Expand All @@ -38,13 +35,13 @@ const createBrowserActionProperties: () => menus.CreateProperties[] = () => [
},
{
title: i18n.getMessage('MSG_OPTION'),
onclick: () => runtime.openOptionsPage(),
onclick: () => browser.runtime.openOptionsPage(),
},
];

const reqConvertClipboard = (state: BgState, target: LangType) => () => void convertClipboard(state, target);

const createClipboardProperties: (s: BgState) => menus.CreateProperties[] = state => [
const createClipboardProperties: (s: BgState) => browser.Menus.CreateCreatePropertiesType[] = state => [
{
title: i18n.getMessage('MSG_CONVERT_CLIPBOARD_S2T'),
onclick: reqConvertClipboard(state, LangType.s2t),
Expand All @@ -57,12 +54,15 @@ const createClipboardProperties: (s: BgState) => menus.CreateProperties[] = stat

// TODO: need icon
export async function createBrowserActionMenus(state: BgState): Promise<(string | number)[]> {
const browserActionMenuItems: menus.CreateProperties[] = [
const browserActionMenuItems: browser.Menus.CreateCreatePropertiesType[] = [
...createBrowserActionProperties(),
...createClipboardProperties(state),
].map(item =>
Object.assign(item, { type: 'normal', contexts: ['browser_action'] } satisfies Menus.CreateCreatePropertiesType),
Object.assign(item, {
type: 'normal',
contexts: ['browser_action'],
} satisfies browser.Menus.CreateCreatePropertiesType),
);

return Promise.all(browserActionMenuItems.map(item => menus.create(item)));
return Promise.all(browserActionMenuItems.map(item => browser.menus.create(item)));
}
4 changes: 2 additions & 2 deletions src/background/runtime/handle-get-target.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Runtime } from 'webextension-polyfill';
import { MaybeTransTarget } from '../../preference/types/types';
import { FilterTarget } from '../../preference/types/v2';
import type { browser } from '../../service/browser';
import { BgState } from '../state';
import { getTargetByAutoConvert } from './handle-get-auto-convert';
import { getTargetByFilter } from './handle-get-filter-target';

// TODO: remove type assertion after Promise.then type infer bug fixed
type GetTarget = (s: BgState, tab: Runtime.MessageSender) => Promise<MaybeTransTarget>;
type GetTarget = (s: BgState, tab: browser.Runtime.MessageSender) => Promise<MaybeTransTarget>;
export const getTarget: GetTarget = (state, sender) =>
Promise.resolve(getTargetByFilter(state, sender.url!))
.then(
Expand Down
5 changes: 2 additions & 3 deletions src/background/state/bg-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Converter } from 'tongwen-core';
import { patchRulesRegExp } from '../../preference/filter-rule';
import { Pref } from '../../preference/types/lastest';
import { MenuId } from '../../service/menu/create-menu';
import { storage } from '../../service/storage/storage';
import { initialStorage } from '../../service/storage/storage';
import { Logger, loggerWith } from '../../utilities';
import { getConverter } from '../converter';

Expand All @@ -21,7 +21,6 @@ export const updateLogger = (state: BgState) => {
};

export const createBgState = async (): Promise<BgState> =>
storage
.initial()
initialStorage()
.then(pref => Promise.all([patchRegExp(pref), getConverter(pref.word)]))
.then(([pref, converter]) => ({ pref, converter, logger: loggerWith(pref.general.debugMode) }));
4 changes: 2 additions & 2 deletions src/background/state/mount-pref-listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { Pref } from '../../preference/types/lastest';
import { PrefFilter } from '../../preference/types/v2';
import { setBadge } from '../../service/browser-action/set-badge';
import { createMenu } from '../../service/menu/create-menu';
import { storage } from '../../service/storage/storage';
import { listenStorage } from '../../service/storage/storage';
import { getConverter } from '../converter';

export function mountPrefListener(state: BgState) {
storage.listen(
listenStorage(
changes => {
state.logger('[BG_RECEIVE_SYNC_PREF_CHANGE]', changes);

Expand Down
6 changes: 3 additions & 3 deletions src/content/state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TARGET_NODE_ATTRIBUTES } from 'tongwen-core';
import { storage } from '../service/storage/storage';
import { getStorage } from '../service/storage/storage';
import { ZhType } from '../service/tabs/tabs.constant';
import { getDetectLanguage } from './services';

Expand All @@ -22,8 +22,8 @@ export interface CtState {
converting: Promise<any>;
}

const getUpdateLangAttr = () => storage.get('general').then(({ general }) => general.updateLangAttr);
const getDebugMode = () => storage.get('general').then(({ general }) => general.debugMode);
const getUpdateLangAttr = () => getStorage('general').then(({ general }) => general.updateLangAttr);
const getDebugMode = () => getStorage('general').then(({ general }) => general.debugMode);

export async function createCtState(): Promise<CtState> {
return Promise.all([getDetectLanguage(), getUpdateLangAttr(), getDebugMode()]).then(
Expand Down
8 changes: 4 additions & 4 deletions src/options/hooks/filter/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Reducer, useEffect, useReducer, useState } from 'react';
import { getDefaultPref } from '../../../preference/default';
import { PrefFilterRule } from '../../../preference/types/v2';
import { storage } from '../../../service/storage/storage';
import { getStorage } from '../../../service/storage/storage';

export type UseFilterRuleAction =
| { type: 'DELETE'; payload: PrefFilterRule }
Expand Down Expand Up @@ -43,9 +43,9 @@ export const useFilter = () => {
const { rules, setRules } = useFilterRules(getDefaultPref().filter.rules);

useEffect(() => {
storage
.get('filter')
.then(({ filter: { enabled, rules } }) => void (setEnable(enabled), setRules({ type: 'RESET', payload: rules })));
getStorage('filter').then(
({ filter: { enabled, rules } }) => void (setEnable(enabled), setRules({ type: 'RESET', payload: rules })),
);
}, []);

return { enabled, setEnable, rules, setRules };
Expand Down
8 changes: 4 additions & 4 deletions src/options/hooks/general/use-general-opt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ChangeEventHandler, useEffect, useState } from 'react';
import { LangType } from 'tongwen-core';
import { getDefaultPref } from '../../../preference/default';
import { AutoConvertOpt, BrowserActionOpt, PrefGeneral } from '../../../preference/types/v2';
import { storage } from '../../../service/storage/storage';
import { getStorage, listenStorage, setStorage } from '../../../service/storage/storage';

export const useGeneralOpt = () => {
const [general, set] = useState<PrefGeneral>(getDefaultPref().general);

const setGeneral = <T extends keyof PrefGeneral>(key: T, value: PrefGeneral[T]) =>
storage.set({ general: { ...general, [key]: value } });
setStorage({ general: { ...general, [key]: value } });
const setAutoConvert: ChangeEventHandler<HTMLSelectElement> = e =>
void setGeneral('autoConvert', e.currentTarget.value as AutoConvertOpt);
const setBrowserAction: ChangeEventHandler<HTMLSelectElement> = e =>
Expand All @@ -22,15 +22,15 @@ export const useGeneralOpt = () => {

useEffect(
() =>
storage.listen(changes => changes.general?.newValue && set(changes.general?.newValue), {
listenStorage(changes => changes.general?.newValue && set(changes.general?.newValue), {
keys: ['general'],
areaName: ['local'],
}),
[],
);

useEffect(() => {
storage.get('general').then(({ general }) => set(general));
getStorage('general').then(({ general }) => set(general));
}, []);

return {
Expand Down
16 changes: 8 additions & 8 deletions src/options/hooks/menu/index.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
import { ChangeEventHandler, useEffect, useState } from 'react';
import { LangType } from 'tongwen-core';
import { getDefaultPref } from '../../../preference/default';
import { storage } from '../../../service/storage/storage';
import { getStorage, listenStorage, setStorage } from '../../../service/storage/storage';

export const useMenu = () => {
const [menu, set] = useState(getDefaultPref().menu);

const setMenuEnable: ChangeEventHandler<HTMLInputElement> = e =>
storage.set({ menu: { ...menu, enabled: e.currentTarget.checked } });
setStorage({ menu: { ...menu, enabled: e.currentTarget.checked } });
const setWebS2t: ChangeEventHandler<HTMLInputElement> = e =>
storage.set({
setStorage({
menu: {
...menu,
group: { ...menu.group, webpage: { ...menu.group.webpage, [LangType.s2t]: e.currentTarget.checked } },
},
});
const setWebT2s: ChangeEventHandler<HTMLInputElement> = e =>
storage.set({
setStorage({
menu: {
...menu,
group: { ...menu.group, webpage: { ...menu.group.webpage, [LangType.t2s]: e.currentTarget.checked } },
},
});
const setTextS2t: ChangeEventHandler<HTMLInputElement> = e =>
storage.set({
setStorage({
menu: {
...menu,
group: { ...menu.group, textarea: { ...menu.group.textarea, [LangType.s2t]: e.currentTarget.checked } },
},
});
const setTextT2s: ChangeEventHandler<HTMLInputElement> = e =>
storage.set({
setStorage({
menu: {
...menu,
group: { ...menu.group, textarea: { ...menu.group.textarea, [LangType.t2s]: e.currentTarget.checked } },
},
});

useEffect(() => storage.listen(changes => set(changes.menu?.newValue), { keys: ['menu'], areaName: ['local'] }), []);
useEffect(() => listenStorage(changes => set(changes.menu?.newValue), { keys: ['menu'], areaName: ['local'] }), []);

useEffect(() => {
storage.get('menu').then(({ menu }) => set(menu));
getStorage('menu').then(({ menu }) => set(menu));
}, []);

return { menu, setMenuEnable, setWebS2t, setWebT2s, setTextS2t, setTextT2s };
Expand Down
6 changes: 3 additions & 3 deletions src/options/hooks/word/use-word.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { useEffect, useState } from 'react';
import { getDefaultPref } from '../../../preference/default';
import { PrefWord } from '../../../preference/types/v2';
import { storage } from '../../../service/storage/storage';
import { getStorage, listenStorage } from '../../../service/storage/storage';

export const useWord = () => {
const [word, setWord] = useState<PrefWord>(getDefaultPref().word);

storage.listen(({ word }) => setWord(word?.newValue), { keys: ['word'], areaName: ['local'] });
listenStorage(({ word }) => setWord(word?.newValue), { keys: ['word'], areaName: ['local'] });

useEffect(
() =>
void storage.get('word').then(({ word }) => {
void getStorage('word').then(({ word }) => {
setWord(word);
}),
[],
Expand Down
4 changes: 2 additions & 2 deletions src/options/pages/filter/FilterSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createFilterRule } from '../../../preference/filter-rule';
import { PrefFilterRule } from '../../../preference/types/v2';
import { i18n } from '../../../service/i18n/i18n';
import { createNoti } from '../../../service/notification/create-noti';
import { storage } from '../../../service/storage/storage';
import { setStorage } from '../../../service/storage/storage';
import { Button, Checkbox, Modal } from '../../components';
import { useFilter } from '../../hooks/filter';
import { useToggle } from '../../hooks/state/use-toggle';
Expand Down Expand Up @@ -47,7 +47,7 @@ export const FilterSettings: FC = () => {
);

const save = useCallback(
() => storage.set({ filter: { enabled, rules } }).then(() => createNoti(i18n.getMessage('MSG_UPDATE_COMPLETED'))),
() => setStorage({ filter: { enabled, rules } }).then(() => createNoti(i18n.getMessage('MSG_UPDATE_COMPLETED'))),
[enabled, rules],
);

Expand Down
4 changes: 2 additions & 2 deletions src/options/pages/word/WordSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { LangType } from 'tongwen-core';
import { PrefWordDefault } from '../../../preference/types/v2';
import { i18n } from '../../../service/i18n/i18n';
import { createNoti } from '../../../service/notification/create-noti';
import { storage } from '../../../service/storage/storage';
import { setStorage } from '../../../service/storage/storage';
import { Button, Divider, Modal } from '../../components';
import { useToggle } from '../../hooks/state/use-toggle';
import { useWord } from '../../hooks/word/use-word';
Expand Down Expand Up @@ -62,7 +62,7 @@ export const WordSettings: FC = () => {
);

const save = useCallback(
() => storage.set({ word }).then(() => createNoti(i18n.getMessage('MSG_UPDATE_COMPLETED'))),
() => setStorage({ word }).then(() => createNoti(i18n.getMessage('MSG_UPDATE_COMPLETED'))),
[word],
);

Expand Down
7 changes: 0 additions & 7 deletions src/service/browser-action/browser-action.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/service/browser-action/set-badge.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { LangType } from 'tongwen-core';
import { Pref } from '../../preference/types/lastest';
import { BrowserActionOpt } from '../../preference/types/v2';
import { browserAction } from './browser-action';
import { browser } from '../browser';

const browserActionToBadge = (ba: BrowserActionOpt) => (ba === 'auto' ? 'A' : ba === LangType.s2t ? 'T' : 'S');

const color = '#C0C0C0';

export const setBadge = (pref: Pref) => {
const text = browserActionToBadge(pref.general.browserAction);
const setText = browserAction.setBadgeText({ text });
const setBg = browserAction.setBadgeBackgroundColor({ color });
const setText = browser.browserAction.setBadgeText({ text });
const setBg = browser.browserAction.setBadgeBackgroundColor({ color });

return Promise.all([setText, setBg]);
};
6 changes: 0 additions & 6 deletions src/service/commands/commands.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/service/downloads/downloads.ts

This file was deleted.

15 changes: 8 additions & 7 deletions src/service/menu/determine-context.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { PrefMenuGroup, PrefMenuGroupKeys, PrefMenuOptions } from '../../preference/types/v2';
import { menus } from './menus';
import type { browser } from '../browser';
import { ContextOnAll, ContextOnEditable } from './menus';

const hasEnabled = (options: PrefMenuOptions) => options.s2t || options.t2s;

export function getSubMenuContexts(prefKey: PrefMenuGroupKeys): menus.ContextType[] {
return prefKey === 'textarea' ? menus.ContextOnEditable : menus.ContextOnAll;
export function getSubMenuContexts(prefKey: PrefMenuGroupKeys): browser.Menus.ContextType[] {
return prefKey === 'textarea' ? ContextOnEditable : ContextOnAll;
}

export function getTopMenuContexts({ textarea, webpage }: PrefMenuGroup): menus.ContextType[] {
export function getTopMenuContexts({ textarea, webpage }: PrefMenuGroup): browser.Menus.ContextType[] {
const hasEditable = hasEnabled(textarea);
const hasOther = hasEnabled(webpage);

return hasEditable && hasOther
? [...menus.ContextOnAll, ...menus.ContextOnEditable]
? [...ContextOnAll, ...ContextOnEditable]
: hasEditable
? menus.ContextOnEditable
? ContextOnEditable
: hasOther
? menus.ContextOnAll
? ContextOnAll
: [];
}
Loading

0 comments on commit 712ca2d

Please sign in to comment.