1
/*
2
 * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
5
 * the License. A copy of the License is located at
6
 *
7
 *     http://aws.amazon.com/apache2.0/
8
 *
9
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11
 * and limitations under the License.
12
 */
13

14 1
import * as React from 'react';
15

16 1
import { ConsoleLogger as Logger } from '@aws-amplify/core';
17 1
import { Storage } from '@aws-amplify/storage';
18

19 1
import AmplifyTheme from '../AmplifyTheme';
20 1
import { TextPicker } from '../Widget/TextPicker';
21 1
import { calcKey } from './Common';
22

23 1
const logger = new Logger('Storage.S3Text');
24

25
export interface IS3TextProps {
26
	body?: any;
27
	contentType?: any;
28
	fileToKey?:
29
	| string
30
	| ((param: { name: string; size: number; type: string }) => string);
31
	hidden?: any;
32
	identityId?: any;
33
	level?: string;
34
	onClick?: any;
35
	onError?: any;
36
	onLoad?: any;
37
	path?: any;
38
	picker?: any;
39
	selected?: any;
40
	style?: any;
41
	theme?: any;
42
	text?: string;
43
	textKey?: string;
44
	track?: any;
45
	translate?:
46
	| string
47
	| ((params: { type: string; key: string; content: string }) => string);
48
}
49

50
export interface IS3TextState {
51
	text: string;
52
	textKey: string;
53
}
54

55 1
export class S3Text extends React.Component<IS3TextProps, IS3TextState> {
56 1
	_isMounted = false;
57
	constructor(props) {
58 1
		super(props);
59

60 1
		this.handleOnLoad = this.handleOnLoad.bind(this);
61 1
		this.handleOnError = this.handleOnError.bind(this);
62 1
		this.handlePick = this.handlePick.bind(this);
63 1
		this.handleClick = this.handleClick.bind(this);
64

65 1
		const { text, textKey } = props;
66 1
		this.state = {
67 1
			text: text || '',
68 1
			textKey: textKey || '',
69
		};
70
	}
71

72 1
	getText(key, level, track, identityId) {
73 1
		if (!Storage || typeof Storage.get !== 'function') {
74 0
			throw new Error(
75
				'No Storage module found, please ensure @aws-amplify/storage is imported'
76
			);
77
		}
78 1
		Storage.get(key, {
79
			download: true,
80 1
			level: level ? level : 'public',
81
			track,
82
			identityId,
83
		})
84
			.then(data => {
85 1
				logger.debug(data);
86
				// @ts-ignore
87 1
				const text = data.Body.toString('utf8');
88 1
				if (this._isMounted) {
89 0
					this.setState({ text });
90
				}
91 0
				this.handleOnLoad(text);
92
			})
93
			.catch(err => {
94 1
				logger.debug(err);
95 1
				this.handleOnError(err);
96
			});
97
	}
98

99 1
	load() {
100 1
		const {
101 1
			path,
102 1
			textKey,
103 1
			body,
104 1
			contentType,
105 1
			level,
106 1
			track,
107 1
			identityId,
108
		} = this.props;
109 1
		if (!textKey && !path) {
110 1
			logger.debug('empty textKey and path');
111 1
			return;
112
		}
113

114 1
		const that = this;
115 1
		const key = textKey || path;
116 1
		logger.debug('loading ' + key + '...');
117 1
		if (body) {
118 1
			const type = contentType || 'text/*';
119 1
			if (!Storage || typeof Storage.put !== 'function') {
120 0
				throw new Error(
121
					'No Storage module found, please ensure @aws-amplify/storage is imported'
122
				);
123
			}
124 1
			const ret = Storage.put(key, body, {
125
				contentType: type,
126 1
				level: level ? level : 'public',
127
				track,
128
			});
129 1
			ret
130
				.then(data => {
131 1
					logger.debug(data);
132 1
					that.getText(key, level, track, identityId);
133
				})
134 1
				.catch(err => logger.debug(err));
135
		} else {
136 1
			that.getText(key, level, track, identityId);
137
		}
138
	}
139

140 1
	handleOnLoad(text) {
141 1
		const { onLoad } = this.props;
142 1
		if (onLoad) {
143 1
			onLoad(text);
144
		}
145
	}
146

147 1
	handleOnError(err) {
148 1
		const { onError } = this.props;
149 1
		if (onError) {
150 1
			onError(err);
151
		}
152
	}
153

154 1
	handlePick(data) {
155 1
		const that = this;
156

157 1
		const path = this.props.path || '';
158 1
		const { textKey, level, fileToKey, track, identityId } = this.props;
159 1
		const { file, name, size, type } = data;
160 1
		const key = textKey || path + calcKey(data, fileToKey);
161 1
		if (!Storage || typeof Storage.put !== 'function') {
162 0
			throw new Error(
163
				'No Storage module found, please ensure @aws-amplify/storage is imported'
164
			);
165
		}
166 1
		Storage.put(key, file, {
167 1
			level: level ? level : 'public',
168
			contentType: type,
169
			track,
170
		})
171
			.then(data => {
172 1
				logger.debug('handle pick data', data);
173 1
				that.getText(key, level, track, identityId);
174
			})
175 0
			.catch(err => logger.debug('handle pick error', err));
176
	}
177

178 1
	handleClick(evt) {
179 1
		const { onClick } = this.props;
180 1
		if (onClick) {
181 1
			onClick(evt);
182
		}
183
	}
184

185 1
	componentDidMount() {
186 1
		this._isMounted = true;
187 1
		this.load();
188
	}
189

190 1
	componentWillUnmount() {
191 0
		this._isMounted = false;
192
	}
193

194 1
	componentDidUpdate(prevProps) {
195
		const update =
196 1
			prevProps.path !== this.props.path ||
197
			prevProps.textKey !== this.props.textKey ||
198
			prevProps.body !== this.props.body;
199 1
		if (update) {
200 1
			this.load();
201
		}
202
	}
203

204 1
	textEl(text, theme) {
205 1
		if (!text) {
206 1
			return null;
207
		}
208

209 1
		const { selected } = this.props;
210 1
		const containerStyle: React.CSSProperties = { position: 'relative' };
211 1
		return (
212
			<div style={containerStyle} onClick={this.handleClick}>
213
				<pre style={theme.pre}>{text}</pre>
214 1
				<div style={selected ? theme.overlaySelected : theme.overlay}></div>
215
			</div>
216
		);
217
	}
218

219 1
	render() {
220 1
		const { hidden, style, picker, translate, textKey } = this.props;
221 1
		let text = this.state.text;
222 1
		if (translate) {
223 1
			text =
224
				typeof translate === 'string'
225 1
					? translate
226
					: translate({
227
						type: 'text',
228
						key: textKey,
229
						content: text,
230
					});
231
		}
232 1
		if (!text && !picker) {
233 1
			return null;
234
		}
235

236 1
		const theme = this.props.theme || AmplifyTheme;
237 1
		const textStyle = hidden
238 1
			? AmplifyTheme.hidden
239
			: Object.assign({}, theme.text, style);
240

241 1
		return (
242
			<div style={textStyle}>
243 1
				{textStyle ? this.textEl(text, theme) : null}
244
				{picker ? (
245 1
					<div>
246
						<TextPicker key="picker" onPick={this.handlePick} theme={theme} />
247
					</div>
248
				) : null}
249
			</div>
250
		);
251
	}
252 1
}
253

254
/**
255
 * @deprecated use named import
256
 */
257 1
export default S3Text;

Read our documentation on viewing source code .

Loading