diff options
Diffstat (limited to 'src/features/publishDebugInfo/Component.tsx')
-rw-r--r-- | src/features/publishDebugInfo/Component.tsx | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/features/publishDebugInfo/Component.tsx b/src/features/publishDebugInfo/Component.tsx new file mode 100644 index 000000000..e265902dd --- /dev/null +++ b/src/features/publishDebugInfo/Component.tsx | |||
@@ -0,0 +1,208 @@ | |||
1 | import { inject, observer } from 'mobx-react'; | ||
2 | import { Component, ReactElement } from 'react'; | ||
3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; | ||
4 | import withStyles, { WithStylesProps } from 'react-jss'; | ||
5 | import { StoresProps } from '../../@types/ferdium-components.types'; | ||
6 | import { state as ModalState } from './store'; | ||
7 | import { H1 } from '../../components/ui/headline'; | ||
8 | import { sendAuthRequest } from '../../api/utils/auth'; | ||
9 | import Button from '../../components/ui/button'; | ||
10 | import Input from '../../components/ui/input/index'; | ||
11 | import Modal from '../../components/ui/Modal'; | ||
12 | import { DEBUG_API } from '../../config'; | ||
13 | |||
14 | const debug = require('../../preload-safe-debug')( | ||
15 | 'Ferdium:feature:publishDebugInfo', | ||
16 | ); | ||
17 | |||
18 | const messages = defineMessages({ | ||
19 | title: { | ||
20 | id: 'feature.publishDebugInfo.title', | ||
21 | defaultMessage: 'Publish debug information', | ||
22 | }, | ||
23 | info: { | ||
24 | id: 'feature.publishDebugInfo.info', | ||
25 | defaultMessage: | ||
26 | "Publishing your debug information helps us find issues and errors in Ferdium. By publishing your debug information you accept Ferdium Debugger's privacy policy and terms of service", | ||
27 | }, | ||
28 | error: { | ||
29 | id: 'feature.publishDebugInfo.error', | ||
30 | defaultMessage: | ||
31 | 'There was an error while trying to publish the debug information. Please try again later or view the console for more information.', | ||
32 | }, | ||
33 | privacy: { | ||
34 | id: 'feature.publishDebugInfo.privacy', | ||
35 | defaultMessage: 'Privacy policy', | ||
36 | }, | ||
37 | terms: { | ||
38 | id: 'feature.publishDebugInfo.terms', | ||
39 | defaultMessage: 'Terms of service', | ||
40 | }, | ||
41 | publish: { | ||
42 | id: 'feature.publishDebugInfo.publish', | ||
43 | defaultMessage: 'Accept and publish', | ||
44 | }, | ||
45 | published: { | ||
46 | id: 'feature.publishDebugInfo.published', | ||
47 | defaultMessage: 'Your debug log was published and is now availible at', | ||
48 | }, | ||
49 | }); | ||
50 | |||
51 | const styles = theme => ({ | ||
52 | modal: { | ||
53 | width: '80%', | ||
54 | maxWidth: 600, | ||
55 | background: theme.styleTypes.primary.contrast, | ||
56 | paddingTop: 30, | ||
57 | }, | ||
58 | headline: { | ||
59 | fontSize: 20, | ||
60 | marginBottom: 20, | ||
61 | marginTop: -27, | ||
62 | }, | ||
63 | info: { | ||
64 | paddingBottom: 20, | ||
65 | }, | ||
66 | link: { | ||
67 | color: `${theme.styleTypes.primary.accent} !important`, | ||
68 | padding: 10, | ||
69 | cursor: 'pointer', | ||
70 | }, | ||
71 | button: { | ||
72 | width: '100%', | ||
73 | marginTop: 10, | ||
74 | cursor: 'pointer', | ||
75 | }, | ||
76 | }); | ||
77 | |||
78 | interface IProps | ||
79 | extends Partial<StoresProps>, | ||
80 | WithStylesProps<typeof styles>, | ||
81 | WrappedComponentProps {} | ||
82 | |||
83 | interface IState { | ||
84 | log: null; | ||
85 | error: boolean; | ||
86 | isSendingLogs: boolean; | ||
87 | } | ||
88 | |||
89 | @inject('stores', 'actions') | ||
90 | @observer | ||
91 | class PublishDebugLogModal extends Component<IProps, IState> { | ||
92 | constructor(props: IProps) { | ||
93 | super(props); | ||
94 | |||
95 | this.state = { | ||
96 | log: null, | ||
97 | error: false, | ||
98 | isSendingLogs: false, | ||
99 | }; | ||
100 | } | ||
101 | |||
102 | // Close this modal | ||
103 | close(): void { | ||
104 | ModalState.isModalVisible = false; | ||
105 | this.setState({ | ||
106 | log: null, | ||
107 | error: false, | ||
108 | isSendingLogs: false, | ||
109 | }); | ||
110 | } | ||
111 | |||
112 | async publishDebugInfo(): Promise<void> { | ||
113 | debug('debugInfo: starting publish'); | ||
114 | this.setState({ | ||
115 | isSendingLogs: true, | ||
116 | }); | ||
117 | |||
118 | const debugInfo = JSON.stringify(this.props.stores?.app?.debugInfo); | ||
119 | |||
120 | const request = await sendAuthRequest( | ||
121 | `${DEBUG_API}/create`, | ||
122 | { | ||
123 | method: 'POST', | ||
124 | body: JSON.stringify({ | ||
125 | log: debugInfo, | ||
126 | }), | ||
127 | }, | ||
128 | false, | ||
129 | ); | ||
130 | |||
131 | debug(`debugInfo: publishing status: ${request.status}`); | ||
132 | if (request.status === 200) { | ||
133 | const response = await request.json(); | ||
134 | if (response.id) { | ||
135 | this.setState({ log: response.id }); | ||
136 | } else { | ||
137 | this.setState({ error: true }); | ||
138 | } | ||
139 | } else { | ||
140 | this.setState({ error: true }); | ||
141 | } | ||
142 | |||
143 | debug('debugInfo: finished publishing'); | ||
144 | } | ||
145 | |||
146 | render(): ReactElement { | ||
147 | const { isModalVisible } = ModalState; | ||
148 | const { classes, intl } = this.props; | ||
149 | const { log, error, isSendingLogs } = this.state; | ||
150 | |||
151 | return ( | ||
152 | <Modal | ||
153 | isOpen={isModalVisible} | ||
154 | shouldCloseOnOverlayClick | ||
155 | className={`${classes.modal} publish-debug`} | ||
156 | close={() => this.close()} | ||
157 | > | ||
158 | <H1 className={classes.headline}> | ||
159 | {intl.formatMessage(messages.title)} | ||
160 | </H1> | ||
161 | {log && ( | ||
162 | <> | ||
163 | <p className={classes.info}> | ||
164 | {intl.formatMessage(messages.published)} | ||
165 | </p> | ||
166 | {/* TODO - [TS DEBT] need to check if <Input/> take readOnly and use it */} | ||
167 | <Input showLabel={false} value={`${DEBUG_API}/${log}`} readOnly /> | ||
168 | </> | ||
169 | )} | ||
170 | {error && ( | ||
171 | <p className={classes.info}>{intl.formatMessage(messages.error)}</p> | ||
172 | )} | ||
173 | {!log && !error && ( | ||
174 | <> | ||
175 | <p className={classes.info}>{intl.formatMessage(messages.info)}</p> | ||
176 | <a | ||
177 | href={`${DEBUG_API}/privacy.html`} | ||
178 | target="_blank" | ||
179 | className={classes.link} | ||
180 | rel="noreferrer" | ||
181 | > | ||
182 | {intl.formatMessage(messages.privacy)} | ||
183 | </a> | ||
184 | <a | ||
185 | href={`${DEBUG_API}/terms.html`} | ||
186 | target="_blank" | ||
187 | className={classes.link} | ||
188 | rel="noreferrer" | ||
189 | > | ||
190 | {intl.formatMessage(messages.terms)} | ||
191 | </a> | ||
192 | <Button | ||
193 | type="button" | ||
194 | label={intl.formatMessage(messages.publish)} | ||
195 | className={classes.button} | ||
196 | onClick={() => this.publishDebugInfo()} | ||
197 | disabled={isSendingLogs} | ||
198 | /> | ||
199 | </> | ||
200 | )} | ||
201 | </Modal> | ||
202 | ); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | export default injectIntl( | ||
207 | withStyles(styles, { injectTheme: true })(PublishDebugLogModal), | ||
208 | ); | ||