Recently Written · git

scan-subread

PDF reader that follows an audiobook with the SubRead suite

git clone https://github.com/equwal/scan-subread

Log | Files | Refs


src/suite.ts (2829 bytes)

1 // The checklist of the SubRead suite: which apps are on the device, and
2 // what to do for an app that is missing. Pure: no DOM.
3 
4 import {
5   ANKI_RELEASES,
6   DICTIONARY_RELEASES,
7   OPEN_OVERLAY,
8   OVERLAY_RELEASES,
9   SUBREAD_RELEASES,
10   type Message,
11 } from './messages';
12 import type { SuiteApps } from './subread';
13 
14 /** One line of the checklist. `ok` is true when the app is ready. */
15 export interface ChecklistItem extends Message {
16   ok: boolean;
17 }
18 
19 /**
20  * The line of SubRead Overlay. `playerError` is the error of the last
21  * player state, undefined before the first state. A state or `no_player`
22  * shows that the overlay has notification access.
23  */
24 function overlayItem(apps: SuiteApps, playerError: string | null | undefined): ChecklistItem {
25   if (!apps.overlay && !apps.overlayDebug) {
26     return {
27       ok: false,
28       text: 'SubRead Overlay: not installed.',
29       link: { href: OVERLAY_RELEASES, text: 'Get SubRead Overlay' },
30     };
31   }
32   switch (playerError) {
33     case 'no_notification_access':
34       return { ok: false, text: 'SubRead Overlay: no notification access.', action: OPEN_OVERLAY };
35     case 'no_overlay':
36       return { ok: false, text: 'SubRead Overlay: does not answer.', action: OPEN_OVERLAY };
37     case null:
38     case 'no_player':
39       return {
40         ok: true,
41         text: 'SubRead Overlay: installed, with notification access.',
42         action: OPEN_OVERLAY,
43       };
44     default:
45       return { ok: true, text: 'SubRead Overlay: installed.', action: OPEN_OVERLAY };
46   }
47 }
48 
49 function dictionaryItem(count: number): ChecklistItem {
50   if (count > 0) return { ok: true, text: `Dictionary apps: ${count}.` };
51   return {
52     ok: false,
53     text: 'Dictionary apps: none.',
54     link: { href: DICTIONARY_RELEASES, text: 'Get SubRead Dictionary' },
55   };
56 }
57 
58 function subreadItem(version: string | null): ChecklistItem {
59   if (version === null) {
60     return {
61       ok: false,
62       text: 'SubRead: not installed.',
63       link: { href: SUBREAD_RELEASES, text: 'Get SubRead' },
64     };
65   }
66   return { ok: true, text: version ? `SubRead ${version}: installed.` : 'SubRead: installed.' };
67 }
68 
69 function ankiItem(installed: boolean): ChecklistItem {
70   if (installed) return { ok: true, text: 'SubRead Anki: installed.' };
71   return {
72     ok: false,
73     text: 'SubRead Anki: not installed.',
74     link: { href: ANKI_RELEASES, text: 'Get SubRead Anki' },
75   };
76 }
77 
78 /**
79  * The checklist: SubRead Overlay, the dictionary apps, SubRead and SubRead
80  * Anki. `playerError` is the error of the last player state, undefined
81  * before the first state.
82  */
83 export function suiteChecklist(
84   apps: SuiteApps,
85   playerError: string | null | undefined,
86 ): ChecklistItem[] {
87   return [
88     overlayItem(apps, playerError),
89     dictionaryItem(apps.dictionaries),
90     subreadItem(apps.subread),
91     ankiItem(apps.anki),
92   ];
93 }