diff options
Diffstat (limited to 'src/components/services/content/ServiceView.tsx')
-rw-r--r-- | src/components/services/content/ServiceView.tsx | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/src/components/services/content/ServiceView.tsx b/src/components/services/content/ServiceView.tsx new file mode 100644 index 000000000..e41184431 --- /dev/null +++ b/src/components/services/content/ServiceView.tsx | |||
@@ -0,0 +1,192 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import { autorun, IReactionDisposer } from 'mobx'; | ||
3 | import { observer, inject } from 'mobx-react'; | ||
4 | import classnames from 'classnames'; | ||
5 | import TopBarProgress from 'react-topbar-progress-indicator'; | ||
6 | import ServiceModel from '../../../models/Service'; | ||
7 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; | ||
8 | import WebviewLoader from '../../ui/WebviewLoader'; | ||
9 | import WebviewCrashHandler from './WebviewCrashHandler'; | ||
10 | import WebviewErrorHandler from './WebviewErrorHandler'; | ||
11 | import ServiceDisabled from './ServiceDisabled'; | ||
12 | import ServiceWebview from './ServiceWebview'; | ||
13 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; | ||
14 | import { CUSTOM_WEBSITE_RECIPE_ID } from '../../../config'; | ||
15 | import { RealStores } from '../../../stores'; | ||
16 | |||
17 | interface IProps { | ||
18 | service: ServiceModel; | ||
19 | setWebviewRef: () => void; | ||
20 | detachService: () => void; | ||
21 | reload: () => void; | ||
22 | edit: () => void; | ||
23 | enable: () => void; | ||
24 | // isActive?: boolean; // TODO - [TECH DEBT][PROP NOT USED IN COMPONENT] check it | ||
25 | stores?: RealStores; | ||
26 | isSpellcheckerEnabled: boolean; | ||
27 | } | ||
28 | |||
29 | interface IState { | ||
30 | forceRepaint: boolean; | ||
31 | targetUrl: string; | ||
32 | statusBarVisible: boolean; | ||
33 | } | ||
34 | |||
35 | @inject('stores', 'actions') | ||
36 | @observer | ||
37 | class ServiceView extends Component<IProps, IState> { | ||
38 | // hibernationTimer = null; // TODO - [TS DEBT] class property not reassigned, need to find its purpose | ||
39 | |||
40 | autorunDisposer: IReactionDisposer | undefined; | ||
41 | |||
42 | forceRepaintTimeout: NodeJS.Timeout | undefined; | ||
43 | |||
44 | constructor(props: IProps) { | ||
45 | super(props); | ||
46 | |||
47 | this.state = { | ||
48 | forceRepaint: false, | ||
49 | targetUrl: '', | ||
50 | statusBarVisible: false, | ||
51 | }; | ||
52 | } | ||
53 | |||
54 | componentDidMount() { | ||
55 | this.autorunDisposer = autorun(() => { | ||
56 | if (this.props.service.isActive) { | ||
57 | this.setState({ forceRepaint: true }); | ||
58 | this.forceRepaintTimeout = setTimeout(() => { | ||
59 | this.setState({ forceRepaint: false }); | ||
60 | }, 100); | ||
61 | } | ||
62 | }); | ||
63 | } | ||
64 | |||
65 | componentWillUnmount() { | ||
66 | this.autorunDisposer!(); | ||
67 | clearTimeout(this.forceRepaintTimeout!); | ||
68 | // clearTimeout(this.hibernationTimer); // TODO - [TS DEBT] class property not reassigned, need to find its purpose | ||
69 | } | ||
70 | |||
71 | render() { | ||
72 | const { | ||
73 | detachService, | ||
74 | service, | ||
75 | setWebviewRef, | ||
76 | reload, | ||
77 | edit, | ||
78 | enable, | ||
79 | stores, | ||
80 | isSpellcheckerEnabled, | ||
81 | } = this.props; | ||
82 | |||
83 | const { navigationBarBehaviour, navigationBarManualActive } = | ||
84 | stores!.settings.app; | ||
85 | |||
86 | const showNavBar = | ||
87 | navigationBarBehaviour === 'always' || | ||
88 | (navigationBarBehaviour === 'custom' && | ||
89 | service.recipe.id === CUSTOM_WEBSITE_RECIPE_ID) || | ||
90 | navigationBarManualActive; | ||
91 | |||
92 | const webviewClasses = classnames({ | ||
93 | services__webview: true, | ||
94 | 'services__webview-wrapper': true, | ||
95 | 'is-active': service.isActive, | ||
96 | 'services__webview--force-repaint': this.state.forceRepaint, | ||
97 | }); | ||
98 | |||
99 | const statusBar = this.state.statusBarVisible ? ( | ||
100 | <StatusBarTargetUrl text={this.state.targetUrl} /> | ||
101 | ) : null; | ||
102 | |||
103 | return ( | ||
104 | <div | ||
105 | className={webviewClasses} | ||
106 | data-name={service.name} | ||
107 | style={{ order: service.order }} | ||
108 | > | ||
109 | {service.isActive && service.isEnabled && ( | ||
110 | <> | ||
111 | {service.hasCrashed && ( | ||
112 | <WebviewCrashHandler | ||
113 | name={service.recipe.name} | ||
114 | // webview={service.webview} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] check it | ||
115 | reload={reload} | ||
116 | /> | ||
117 | )} | ||
118 | {service.isEnabled && | ||
119 | service.isLoading && | ||
120 | service.isFirstLoad && | ||
121 | !service.isHibernating && | ||
122 | !service.isServiceAccessRestricted && ( | ||
123 | <WebviewLoader loaded={false} name={service.name} /> | ||
124 | )} | ||
125 | {service.isProgressbarEnabled && | ||
126 | service.isLoadingPage && | ||
127 | !service.isFirstLoad && <TopBarProgress />} | ||
128 | {service.isError && ( | ||
129 | <WebviewErrorHandler | ||
130 | name={service.recipe.name} | ||
131 | errorMessage={service.errorMessage} | ||
132 | reload={reload} | ||
133 | edit={edit} | ||
134 | /> | ||
135 | )} | ||
136 | </> | ||
137 | )} | ||
138 | {!service.isEnabled ? ( | ||
139 | <> | ||
140 | {service.isActive && ( | ||
141 | <ServiceDisabled | ||
142 | name={service.name !== '' ? service.name : service.recipe.name} | ||
143 | // webview={service.webview} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] check it | ||
144 | enable={enable} | ||
145 | /> | ||
146 | )} | ||
147 | </> | ||
148 | ) : ( | ||
149 | <> | ||
150 | {!service.isHibernating ? ( | ||
151 | <> | ||
152 | {showNavBar && <WebControlsScreen service={service} />} | ||
153 | <ServiceWebview | ||
154 | service={service} | ||
155 | setWebviewReference={setWebviewRef} | ||
156 | detachService={detachService} | ||
157 | isSpellcheckerEnabled={isSpellcheckerEnabled} | ||
158 | /> | ||
159 | </> | ||
160 | ) : ( | ||
161 | <div | ||
162 | style={{ | ||
163 | display: 'flex', | ||
164 | flexDirection: 'column', | ||
165 | justifyContent: 'center', | ||
166 | alignItems: 'center', | ||
167 | textAlign: 'center', | ||
168 | }} | ||
169 | > | ||
170 | <span | ||
171 | role="img" | ||
172 | aria-label="Sleeping Emoji" | ||
173 | style={{ fontSize: 42 }} | ||
174 | > | ||
175 | 😴 | ||
176 | </span> | ||
177 | <br /> | ||
178 | <br /> | ||
179 | This service is currently hibernating. | ||
180 | <br /> | ||
181 | Try switching services or reloading Ferdium. | ||
182 | </div> | ||
183 | )} | ||
184 | </> | ||
185 | )} | ||
186 | {statusBar} | ||
187 | </div> | ||
188 | ); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | export default ServiceView; | ||