diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/main/src/infrastructure/electron/impl/ElectronServiceView.ts | 12 | ||||
-rw-r--r-- | packages/main/src/infrastructure/electron/types.ts | 4 | ||||
-rw-r--r-- | packages/main/src/stores/MainStore.ts | 21 | ||||
-rw-r--r-- | packages/main/src/stores/Service.ts | 60 | ||||
-rw-r--r-- | packages/renderer/src/components/locationBar/GoAdornment.tsx | 9 | ||||
-rw-r--r-- | packages/renderer/src/components/locationBar/LocationTextField.tsx | 19 | ||||
-rw-r--r-- | packages/renderer/src/components/locationBar/NavigationButtons.tsx | 16 | ||||
-rw-r--r-- | packages/renderer/src/stores/Service.ts | 46 | ||||
-rw-r--r-- | packages/shared/src/contextBridge/SophieRenderer.ts | 2 | ||||
-rw-r--r-- | packages/shared/src/index.ts | 8 | ||||
-rw-r--r-- | packages/shared/src/schemas/Action.ts (renamed from packages/shared/src/schemas.ts) | 29 | ||||
-rw-r--r-- | packages/shared/src/schemas/BrowserViewBounds.ts | 35 | ||||
-rw-r--r-- | packages/shared/src/schemas/ServiceAction.ts | 51 | ||||
-rw-r--r-- | packages/shared/src/schemas/ThemeSource.ts | 29 | ||||
-rw-r--r-- | packages/shared/src/stores/GlobalSettingsBase.ts | 2 |
15 files changed, 304 insertions, 39 deletions
diff --git a/packages/main/src/infrastructure/electron/impl/ElectronServiceView.ts b/packages/main/src/infrastructure/electron/impl/ElectronServiceView.ts index 6ff8e21..e5fdf11 100644 --- a/packages/main/src/infrastructure/electron/impl/ElectronServiceView.ts +++ b/packages/main/src/infrastructure/electron/impl/ElectronServiceView.ts | |||
@@ -105,6 +105,18 @@ export default class ElectronServiceView implements ServiceView { | |||
105 | this.browserView.webContents.goForward(); | 105 | this.browserView.webContents.goForward(); |
106 | } | 106 | } |
107 | 107 | ||
108 | reload(ignoreCache: boolean): void { | ||
109 | if (ignoreCache) { | ||
110 | this.browserView.webContents.reloadIgnoringCache(); | ||
111 | } else { | ||
112 | this.browserView.webContents.reload(); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | stop(): void { | ||
117 | this.browserView.webContents.stop(); | ||
118 | } | ||
119 | |||
108 | setBounds(bounds: BrowserViewBounds): void { | 120 | setBounds(bounds: BrowserViewBounds): void { |
109 | this.browserView.setBounds(bounds); | 121 | this.browserView.setBounds(bounds); |
110 | } | 122 | } |
diff --git a/packages/main/src/infrastructure/electron/types.ts b/packages/main/src/infrastructure/electron/types.ts index 9f03214..63974ce 100644 --- a/packages/main/src/infrastructure/electron/types.ts +++ b/packages/main/src/infrastructure/electron/types.ts | |||
@@ -61,6 +61,10 @@ export interface ServiceView { | |||
61 | 61 | ||
62 | goForward(): void; | 62 | goForward(): void; |
63 | 63 | ||
64 | reload(ignoreCache: boolean): void; | ||
65 | |||
66 | stop(): void; | ||
67 | |||
64 | setBounds(bounds: BrowserViewBounds): void; | 68 | setBounds(bounds: BrowserViewBounds): void; |
65 | 69 | ||
66 | dispose(): void; | 70 | dispose(): void; |
diff --git a/packages/main/src/stores/MainStore.ts b/packages/main/src/stores/MainStore.ts index cb4f4c9..bf351d7 100644 --- a/packages/main/src/stores/MainStore.ts +++ b/packages/main/src/stores/MainStore.ts | |||
@@ -74,9 +74,6 @@ const MainStore = types | |||
74 | }, | 74 | }, |
75 | dispatch(action: Action): void { | 75 | dispatch(action: Action): void { |
76 | switch (action.action) { | 76 | switch (action.action) { |
77 | case 'reload-all-services': | ||
78 | // TODO | ||
79 | break; | ||
80 | case 'set-browser-view-bounds': | 77 | case 'set-browser-view-bounds': |
81 | this.setBrowserViewBounds(action.browserViewBounds); | 78 | this.setBrowserViewBounds(action.browserViewBounds); |
82 | break; | 79 | break; |
@@ -89,6 +86,24 @@ const MainStore = types | |||
89 | case 'set-show-location-bar': | 86 | case 'set-show-location-bar': |
90 | self.settings.setShowLocationBar(action.showLocationBar); | 87 | self.settings.setShowLocationBar(action.showLocationBar); |
91 | break; | 88 | break; |
89 | case 'reload-all-services': | ||
90 | // TODO | ||
91 | break; | ||
92 | case 'dispatch-service-action': { | ||
93 | const { serviceId, serviceAction } = action; | ||
94 | const service = self.shared.servicesById.get(serviceId); | ||
95 | if (service === undefined) { | ||
96 | log.error( | ||
97 | 'No such service', | ||
98 | serviceId, | ||
99 | 'to dispatch action', | ||
100 | serviceAction, | ||
101 | ); | ||
102 | } else { | ||
103 | service.dispatch(serviceAction); | ||
104 | } | ||
105 | break; | ||
106 | } | ||
92 | default: | 107 | default: |
93 | log.error('Unknown action to dispatch', action); | 108 | log.error('Unknown action to dispatch', action); |
94 | break; | 109 | break; |
diff --git a/packages/main/src/stores/Service.ts b/packages/main/src/stores/Service.ts index abef7c2..cbd8662 100644 --- a/packages/main/src/stores/Service.ts +++ b/packages/main/src/stores/Service.ts | |||
@@ -19,14 +19,17 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | import type { UnreadCount } from '@sophie/service-shared'; | 21 | import type { UnreadCount } from '@sophie/service-shared'; |
22 | import { defineServiceModel } from '@sophie/shared'; | 22 | import { defineServiceModel, ServiceAction } from '@sophie/shared'; |
23 | import { Instance, getSnapshot } from 'mobx-state-tree'; | 23 | import { Instance, getSnapshot } from 'mobx-state-tree'; |
24 | 24 | ||
25 | import type { ServiceView } from '../infrastructure/electron/types'; | 25 | import type { ServiceView } from '../infrastructure/electron/types'; |
26 | import { getLogger } from '../utils/log'; | ||
26 | 27 | ||
27 | import ServiceSettings from './ServiceSettings'; | 28 | import ServiceSettings from './ServiceSettings'; |
28 | import type ServiceConfig from './config/ServiceConfig'; | 29 | import type ServiceConfig from './config/ServiceConfig'; |
29 | 30 | ||
31 | const log = getLogger('Service'); | ||
32 | |||
30 | const Service = defineServiceModel(ServiceSettings) | 33 | const Service = defineServiceModel(ServiceSettings) |
31 | .views((self) => ({ | 34 | .views((self) => ({ |
32 | get config(): ServiceConfig { | 35 | get config(): ServiceConfig { |
@@ -87,6 +90,61 @@ const Service = defineServiceModel(ServiceSettings) | |||
87 | setServiceView(serviceView: ServiceView | undefined): void { | 90 | setServiceView(serviceView: ServiceView | undefined): void { |
88 | self.serviceView = serviceView; | 91 | self.serviceView = serviceView; |
89 | }, | 92 | }, |
93 | goBack(): void { | ||
94 | self.serviceView?.goBack(); | ||
95 | }, | ||
96 | goForward(): void { | ||
97 | self.serviceView?.goForward(); | ||
98 | }, | ||
99 | reload(ignoreCache = false): void { | ||
100 | if (self.serviceView === undefined) { | ||
101 | this.startedLoading(); | ||
102 | } else { | ||
103 | self.serviceView?.reload(ignoreCache); | ||
104 | } | ||
105 | }, | ||
106 | stop(): void { | ||
107 | self.serviceView?.stop(); | ||
108 | }, | ||
109 | go(url: string): void { | ||
110 | if (self.serviceView === undefined) { | ||
111 | self.currentUrl = url; | ||
112 | this.startedLoading(); | ||
113 | } else { | ||
114 | self.serviceView?.loadURL(url).catch((error) => { | ||
115 | log.warn('Error while loading', url, error); | ||
116 | this.crashed(); | ||
117 | }); | ||
118 | } | ||
119 | }, | ||
120 | goHome(): void { | ||
121 | this.go(self.settings.url); | ||
122 | }, | ||
123 | dispatch(action: ServiceAction): void { | ||
124 | switch (action.action) { | ||
125 | case 'back': | ||
126 | this.goBack(); | ||
127 | break; | ||
128 | case 'forward': | ||
129 | this.goForward(); | ||
130 | break; | ||
131 | case 'reload': | ||
132 | this.reload(action.ignoreCache); | ||
133 | break; | ||
134 | case 'stop': | ||
135 | this.stop(); | ||
136 | break; | ||
137 | case 'go-home': | ||
138 | this.goHome(); | ||
139 | break; | ||
140 | case 'go': | ||
141 | this.go(action.url); | ||
142 | break; | ||
143 | default: | ||
144 | log.error('Unknown action to dispatch', action); | ||
145 | break; | ||
146 | } | ||
147 | }, | ||
90 | })); | 148 | })); |
91 | 149 | ||
92 | /* | 150 | /* |
diff --git a/packages/renderer/src/components/locationBar/GoAdornment.tsx b/packages/renderer/src/components/locationBar/GoAdornment.tsx index 43c8b7b..f049b8e 100644 --- a/packages/renderer/src/components/locationBar/GoAdornment.tsx +++ b/packages/renderer/src/components/locationBar/GoAdornment.tsx | |||
@@ -20,11 +20,15 @@ | |||
20 | 20 | ||
21 | import IconGo from '@mui/icons-material/Send'; | 21 | import IconGo from '@mui/icons-material/Send'; |
22 | import Button from '@mui/material/Button'; | 22 | import Button from '@mui/material/Button'; |
23 | import React from 'react'; | 23 | import React, { MouseEventHandler } from 'react'; |
24 | 24 | ||
25 | import ButtonAdornment, { NO_LABEL_BUTTON_CLASS_NAME } from './ButtonAdornment'; | 25 | import ButtonAdornment, { NO_LABEL_BUTTON_CLASS_NAME } from './ButtonAdornment'; |
26 | 26 | ||
27 | export default function GoAdornment(): JSX.Element { | 27 | export default function GoAdornment({ |
28 | onClick, | ||
29 | }: { | ||
30 | onClick: MouseEventHandler<HTMLButtonElement>; | ||
31 | }): JSX.Element { | ||
28 | return ( | 32 | return ( |
29 | <ButtonAdornment position="end"> | 33 | <ButtonAdornment position="end"> |
30 | <Button | 34 | <Button |
@@ -32,6 +36,7 @@ export default function GoAdornment(): JSX.Element { | |||
32 | color="inherit" | 36 | color="inherit" |
33 | startIcon={<IconGo />} | 37 | startIcon={<IconGo />} |
34 | className={NO_LABEL_BUTTON_CLASS_NAME} | 38 | className={NO_LABEL_BUTTON_CLASS_NAME} |
39 | onClick={onClick} | ||
35 | /> | 40 | /> |
36 | </ButtonAdornment> | 41 | </ButtonAdornment> |
37 | ); | 42 | ); |
diff --git a/packages/renderer/src/components/locationBar/LocationTextField.tsx b/packages/renderer/src/components/locationBar/LocationTextField.tsx index e6da59f..e711abc 100644 --- a/packages/renderer/src/components/locationBar/LocationTextField.tsx +++ b/packages/renderer/src/components/locationBar/LocationTextField.tsx | |||
@@ -94,9 +94,18 @@ function LocationTextField({ | |||
94 | setChanged(true); | 94 | setChanged(true); |
95 | }} | 95 | }} |
96 | onKeyUp={(event) => { | 96 | onKeyUp={(event) => { |
97 | if (event.key === 'Escape') { | 97 | switch (event.key) { |
98 | resetValue(); | 98 | case 'Escape': |
99 | event.preventDefault(); | 99 | resetValue(); |
100 | event.preventDefault(); | ||
101 | break; | ||
102 | case 'Enter': | ||
103 | service?.go(value); | ||
104 | event.preventDefault(); | ||
105 | break; | ||
106 | default: | ||
107 | // Nothing to do, let the key event through. | ||
108 | break; | ||
100 | } | 109 | } |
101 | }} | 110 | }} |
102 | size="small" | 111 | size="small" |
@@ -106,7 +115,9 @@ function LocationTextField({ | |||
106 | startAdornment={ | 115 | startAdornment={ |
107 | <UrlAdornment changed={changed} splitResult={splitResult} /> | 116 | <UrlAdornment changed={changed} splitResult={splitResult} /> |
108 | } | 117 | } |
109 | endAdornment={changed ? <GoAdornment /> : undefined} | 118 | endAdornment={ |
119 | changed ? <GoAdornment onClick={() => service?.go(value)} /> : undefined | ||
120 | } | ||
110 | value={value} | 121 | value={value} |
111 | /> | 122 | /> |
112 | ); | 123 | ); |
diff --git a/packages/renderer/src/components/locationBar/NavigationButtons.tsx b/packages/renderer/src/components/locationBar/NavigationButtons.tsx index ce59692..e71d3d8 100644 --- a/packages/renderer/src/components/locationBar/NavigationButtons.tsx +++ b/packages/renderer/src/components/locationBar/NavigationButtons.tsx | |||
@@ -48,25 +48,35 @@ function NavigationButtons({ | |||
48 | <IconButton | 48 | <IconButton |
49 | aria-label="Back" | 49 | aria-label="Back" |
50 | disabled={service === undefined || !service.canGoBack} | 50 | disabled={service === undefined || !service.canGoBack} |
51 | onClick={() => service?.goBack()} | ||
51 | > | 52 | > |
52 | {direction === 'ltr' ? <IconArrowBack /> : <IconArrowForward />} | 53 | {direction === 'ltr' ? <IconArrowBack /> : <IconArrowForward />} |
53 | </IconButton> | 54 | </IconButton> |
54 | <IconButton | 55 | <IconButton |
55 | aria-label="Forward" | 56 | aria-label="Forward" |
56 | disabled={service === undefined || !service.canGoForward} | 57 | disabled={service === undefined || !service.canGoForward} |
58 | onClick={() => service?.goForward()} | ||
57 | > | 59 | > |
58 | {direction === 'ltr' ? <IconArrowForward /> : <IconArrowBack />} | 60 | {direction === 'ltr' ? <IconArrowForward /> : <IconArrowBack />} |
59 | </IconButton> | 61 | </IconButton> |
60 | {service?.state === 'loading' ? ( | 62 | {service?.state === 'loading' ? ( |
61 | <IconButton aria-label="Stop"> | 63 | <IconButton aria-label="Stop" onClick={() => service?.stop()}> |
62 | <IconStop /> | 64 | <IconStop /> |
63 | </IconButton> | 65 | </IconButton> |
64 | ) : ( | 66 | ) : ( |
65 | <IconButton aria-label="Refresh" disabled={service === undefined}> | 67 | <IconButton |
68 | aria-label="Refresh" | ||
69 | disabled={service === undefined} | ||
70 | onClick={(event) => service?.reload(event.shiftKey)} | ||
71 | > | ||
66 | <IconRefresh /> | 72 | <IconRefresh /> |
67 | </IconButton> | 73 | </IconButton> |
68 | )} | 74 | )} |
69 | <IconButton aria-label="Home" disabled={service === undefined}> | 75 | <IconButton |
76 | aria-label="Home" | ||
77 | disabled={service === undefined} | ||
78 | onClick={() => service?.goHome()} | ||
79 | > | ||
70 | <IconHome /> | 80 | <IconHome /> |
71 | </IconButton> | 81 | </IconButton> |
72 | </Box> | 82 | </Box> |
diff --git a/packages/renderer/src/stores/Service.ts b/packages/renderer/src/stores/Service.ts index c2c938a..7878ea0 100644 --- a/packages/renderer/src/stores/Service.ts +++ b/packages/renderer/src/stores/Service.ts | |||
@@ -18,12 +18,54 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { defineServiceModel } from '@sophie/shared'; | 21 | import { defineServiceModel, ServiceAction } from '@sophie/shared'; |
22 | import { Instance } from 'mobx-state-tree'; | 22 | import { Instance } from 'mobx-state-tree'; |
23 | 23 | ||
24 | import getEnv from '../env/getEnv'; | ||
25 | |||
24 | import ServiceSettings from './ServiceSettings'; | 26 | import ServiceSettings from './ServiceSettings'; |
25 | 27 | ||
26 | const Service = defineServiceModel(ServiceSettings); | 28 | const Service = defineServiceModel(ServiceSettings).actions((self) => ({ |
29 | dispatch(serviceAction: ServiceAction): void { | ||
30 | getEnv(self).dispatchMainAction({ | ||
31 | action: 'dispatch-service-action', | ||
32 | serviceId: self.id, | ||
33 | serviceAction, | ||
34 | }); | ||
35 | }, | ||
36 | goBack(): void { | ||
37 | this.dispatch({ | ||
38 | action: 'back', | ||
39 | }); | ||
40 | }, | ||
41 | goForward(): void { | ||
42 | this.dispatch({ | ||
43 | action: 'forward', | ||
44 | }); | ||
45 | }, | ||
46 | reload(ignoreCache = false): void { | ||
47 | this.dispatch({ | ||
48 | action: 'reload', | ||
49 | ignoreCache, | ||
50 | }); | ||
51 | }, | ||
52 | stop(): void { | ||
53 | this.dispatch({ | ||
54 | action: 'stop', | ||
55 | }); | ||
56 | }, | ||
57 | go(url: string): void { | ||
58 | this.dispatch({ | ||
59 | action: 'go', | ||
60 | url, | ||
61 | }); | ||
62 | }, | ||
63 | goHome(): void { | ||
64 | this.dispatch({ | ||
65 | action: 'go-home', | ||
66 | }); | ||
67 | }, | ||
68 | })); | ||
27 | 69 | ||
28 | /* | 70 | /* |
29 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | 71 | eslint-disable-next-line @typescript-eslint/no-redeclare -- |
diff --git a/packages/shared/src/contextBridge/SophieRenderer.ts b/packages/shared/src/contextBridge/SophieRenderer.ts index 9e087da..dc77c97 100644 --- a/packages/shared/src/contextBridge/SophieRenderer.ts +++ b/packages/shared/src/contextBridge/SophieRenderer.ts | |||
@@ -18,7 +18,7 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { Action } from '../schemas'; | 21 | import { Action } from '../schemas/Action'; |
22 | import { SharedStoreListener } from '../stores/SharedStoreBase'; | 22 | import { SharedStoreListener } from '../stores/SharedStoreBase'; |
23 | 23 | ||
24 | export default interface SophieRenderer { | 24 | export default interface SophieRenderer { |
diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 66debf7..fa3fbfd 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts | |||
@@ -22,7 +22,13 @@ export type { default as SophieRenderer } from './contextBridge/SophieRenderer'; | |||
22 | 22 | ||
23 | export { MainToRendererIpcMessage, RendererToMainIpcMessage } from './ipc'; | 23 | export { MainToRendererIpcMessage, RendererToMainIpcMessage } from './ipc'; |
24 | 24 | ||
25 | export { Action, BrowserViewBounds, ThemeSource } from './schemas'; | 25 | export { Action } from './schemas/Action'; |
26 | |||
27 | export { BrowserViewBounds } from './schemas/BrowserViewBounds'; | ||
28 | |||
29 | export { ServiceAction } from './schemas/ServiceAction'; | ||
30 | |||
31 | export { ThemeSource } from './schemas/ThemeSource'; | ||
26 | 32 | ||
27 | export type { | 33 | export type { |
28 | GlobalSettingsSnapshotIn, | 34 | GlobalSettingsSnapshotIn, |
diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas/Action.ts index 9d87d10..d5d0a8d 100644 --- a/packages/shared/src/schemas.ts +++ b/packages/shared/src/schemas/Action.ts | |||
@@ -20,27 +20,9 @@ | |||
20 | 20 | ||
21 | import { z } from 'zod'; | 21 | import { z } from 'zod'; |
22 | 22 | ||
23 | export const BrowserViewBounds = /* @__PURE__ */ (() => | 23 | import { BrowserViewBounds } from './BrowserViewBounds'; |
24 | z.object({ | 24 | import { ServiceAction } from './ServiceAction'; |
25 | x: z.number().int().nonnegative(), | 25 | import { ThemeSource } from './ThemeSource'; |
26 | y: z.number().int().nonnegative(), | ||
27 | width: z.number().int().nonnegative(), | ||
28 | height: z.number().int().nonnegative(), | ||
29 | }))(); | ||
30 | |||
31 | /* | ||
32 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
33 | Intentionally naming the type the same as the schema definition. | ||
34 | */ | ||
35 | export type BrowserViewBounds = z.infer<typeof BrowserViewBounds>; | ||
36 | |||
37 | export const ThemeSource = /* @__PURE__ */ z.enum(['system', 'light', 'dark']); | ||
38 | |||
39 | /* | ||
40 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
41 | Intentionally naming the type the same as the schema definition. | ||
42 | */ | ||
43 | export type ThemeSource = z.infer<typeof ThemeSource>; | ||
44 | 26 | ||
45 | export const Action = /* @__PURE__ */ (() => | 27 | export const Action = /* @__PURE__ */ (() => |
46 | z.union([ | 28 | z.union([ |
@@ -63,6 +45,11 @@ export const Action = /* @__PURE__ */ (() => | |||
63 | z.object({ | 45 | z.object({ |
64 | action: z.literal('reload-all-services'), | 46 | action: z.literal('reload-all-services'), |
65 | }), | 47 | }), |
48 | z.object({ | ||
49 | action: z.literal('dispatch-service-action'), | ||
50 | serviceId: z.string(), | ||
51 | serviceAction: ServiceAction, | ||
52 | }), | ||
66 | ]))(); | 53 | ]))(); |
67 | 54 | ||
68 | /* | 55 | /* |
diff --git a/packages/shared/src/schemas/BrowserViewBounds.ts b/packages/shared/src/schemas/BrowserViewBounds.ts new file mode 100644 index 0000000..e668a4a --- /dev/null +++ b/packages/shared/src/schemas/BrowserViewBounds.ts | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { z } from 'zod'; | ||
22 | |||
23 | export const BrowserViewBounds = /* @__PURE__ */ (() => | ||
24 | z.object({ | ||
25 | x: z.number().int().nonnegative(), | ||
26 | y: z.number().int().nonnegative(), | ||
27 | width: z.number().int().nonnegative(), | ||
28 | height: z.number().int().nonnegative(), | ||
29 | }))(); | ||
30 | |||
31 | /* | ||
32 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
33 | Intentionally naming the type the same as the schema definition. | ||
34 | */ | ||
35 | export type BrowserViewBounds = z.infer<typeof BrowserViewBounds>; | ||
diff --git a/packages/shared/src/schemas/ServiceAction.ts b/packages/shared/src/schemas/ServiceAction.ts new file mode 100644 index 0000000..a4a7049 --- /dev/null +++ b/packages/shared/src/schemas/ServiceAction.ts | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { z } from 'zod'; | ||
22 | |||
23 | export const ServiceAction = /* @__PURE__ */ (() => | ||
24 | z.union([ | ||
25 | z.object({ | ||
26 | action: z.literal('back'), | ||
27 | }), | ||
28 | z.object({ | ||
29 | action: z.literal('forward'), | ||
30 | }), | ||
31 | z.object({ | ||
32 | action: z.literal('reload'), | ||
33 | ignoreCache: z.boolean(), | ||
34 | }), | ||
35 | z.object({ | ||
36 | action: z.literal('stop'), | ||
37 | }), | ||
38 | z.object({ | ||
39 | action: z.literal('go-home'), | ||
40 | }), | ||
41 | z.object({ | ||
42 | action: z.literal('go'), | ||
43 | url: z.string(), | ||
44 | }), | ||
45 | ]))(); | ||
46 | |||
47 | /* | ||
48 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
49 | Intentionally naming the type the same as the schema definition. | ||
50 | */ | ||
51 | export type ServiceAction = z.infer<typeof ServiceAction>; | ||
diff --git a/packages/shared/src/schemas/ThemeSource.ts b/packages/shared/src/schemas/ThemeSource.ts new file mode 100644 index 0000000..6db5788 --- /dev/null +++ b/packages/shared/src/schemas/ThemeSource.ts | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { z } from 'zod'; | ||
22 | |||
23 | export const ThemeSource = /* @__PURE__ */ z.enum(['system', 'light', 'dark']); | ||
24 | |||
25 | /* | ||
26 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
27 | Intentionally naming the type the same as the schema definition. | ||
28 | */ | ||
29 | export type ThemeSource = z.infer<typeof ThemeSource>; | ||
diff --git a/packages/shared/src/stores/GlobalSettingsBase.ts b/packages/shared/src/stores/GlobalSettingsBase.ts index 48092fd..1bd0628 100644 --- a/packages/shared/src/stores/GlobalSettingsBase.ts +++ b/packages/shared/src/stores/GlobalSettingsBase.ts | |||
@@ -26,7 +26,7 @@ import { | |||
26 | IAnyModelType, | 26 | IAnyModelType, |
27 | } from 'mobx-state-tree'; | 27 | } from 'mobx-state-tree'; |
28 | 28 | ||
29 | import { ThemeSource } from '../schemas'; | 29 | import { ThemeSource } from '../schemas/ThemeSource'; |
30 | 30 | ||
31 | import ServiceBase from './ServiceBase'; | 31 | import ServiceBase from './ServiceBase'; |
32 | 32 | ||