git ssb

1+

Daan Patchwork / manyverse



Commit 201a1ec95299519bf5ea6670c4894f14aa5ac818

ux: feature: view images in fullscreen

Andre Staltz committed on 1/16/2019, 4:47:23 PM
Parent: 2141793f1bb0401b00cccd7a3531b5c20833b682

Files changed

package-lock.jsonchanged
package.jsonchanged
src/frontend/global-styles/markdown.tschanged
src/typings/react-native-image-view.d.tsadded
tsconfig.jsonchanged
package-lock.jsonView
The diff is too large to show. Use a local git client to view these changes.
Old file size: 646489 bytes
New file size: 648604 bytes
package.jsonView
@@ -53,42 +53,44 @@
5353 "mutant": "3.21.2",
5454 "muxrpc": "6.4.1",
5555 "nodejs-mobile-react-native": "0.3.1",
5656 "patchcore": "1.23.2",
57+ "promisify-tuple": "1.0.0",
5758 "prop-types": "15.6.x",
58- "promisify-tuple": "1.0.0",
5959 "pull-cat": "1.1.11",
6060 "pull-flat-list": "2.9.0",
6161 "pull-notify": "0.1.1",
6262 "pull-pushable": "2.1.1",
6363 "pull-stream": "3.6.9",
6464 "pull-thenable": "1.0.0",
65+ "quick-lru": "2.0.0",
6566 "quicktask": "1.1.0",
66- "quick-lru": "2.0.0",
6767 "react": "16.5.2",
6868 "react-human-time": "^1.1.0",
6969 "react-markdown": "3.4.0",
70- "react-xstream-hoc": "1.0.0",
7170 "react-native": "0.55.4",
7271 "react-native-android-local-notification": "1.1.0",
7372 "react-native-android-wifi": "0.0.34",
7473 "react-native-dialogs": "1.0.2",
7574 "react-native-floating-action": "1.13.0",
7675 "react-native-has-internet": "2.0.0",
7776 "react-native-image-crop-picker": "0.21.2",
77+ "react-native-image-view": "^2.1.2",
7878 "react-native-navigation": "2.1.2",
7979 "react-native-popup-menu": "0.14.0",
8080 "react-native-ssb-client-keys": "1.1.2",
8181 "react-native-ssb-shims": "4.0.0",
8282 "react-native-vector-icons": "6.1.0",
8383 "react-propify-methods": "16.3.1",
84+ "react-xstream-hoc": "1.0.0",
8485 "remark": "9.0.0",
8586 "remark-gemoji-to-emoji": "1.1.0",
86- "remark-images-to-ssb-serve-blobs": "2.0.0-1",
87+ "remark-images-to-ssb-serve-blobs": "2.1.0-1",
8788 "remark-linkify-regex": "1.0.0",
8889 "spawn-sync": "1.0.15",
8990 "ssb-client": "4.5.7",
9091 "ssb-ref": "2.9.1",
92+ "ssb-serve-blobs": "2.1.0",
9193 "ssb-threads": "2.2.0",
9294 "ssb-typescript": "1.4.0",
9395 "thread-sleep": "2.0.0",
9496 "utf-8-validate": "3.0.2",
@@ -121,5 +123,5 @@
121123 "react-native": {
122124 "os": "@staltz/react-native-os",
123125 "rn-viewpager": "@staltz/rn-viewpager"
124126 }
125-}
127+}
src/frontend/global-styles/markdown.tsView
@@ -8,22 +8,27 @@
88 import {
99 View,
1010 Text,
1111 Image,
12- ImageBackground,
1312 Dimensions,
1413 Linking,
14+ Clipboard,
1515 StyleSheet,
16+ TouchableWithoutFeedback as Touchable,
17+ ToastAndroid,
1618 } from 'react-native';
1719 import {Palette} from './palette';
1820 import {Dimensions as Dimens} from './dimens';
1921 import {Typography as Typ} from './typography';
2022 import {GlobalEventBus} from '../drivers/eventbus';
23+import ImageView from 'react-native-image-view';
24+import HeaderButton from '../components/HeaderButton';
2125 const remark = require('remark');
2226 const ReactMarkdown = require('react-markdown');
2327 const normalizeForReactNative = require('mdast-normalize-react-native');
2428 const gemojiToEmoji = require('remark-gemoji-to-emoji');
2529 const imagesToSsbServeBlobs = require('remark-images-to-ssb-serve-blobs');
30+const urlToBlobId = require('ssb-serve-blobs/url-to-id');
2631 const ref = require('ssb-ref');
2732 const linkifyRegex = require('remark-linkify-regex');
2833
2934 const pictureIcon = require('../../../images/image-area.png');
@@ -143,57 +148,112 @@
143148
144149 orderedBullet: {
145150 fontWeight: 'bold',
146151 },
152+
153+ imageBlobIdContainer: {
154+ flexDirection: 'row',
155+ backgroundColor: Palette.transparencyDark,
156+ alignItems: 'center',
157+ justifyContent: 'space-between',
158+ paddingHorizontal: Dimens.horizontalSpaceNormal,
159+ paddingVertical: Dimens.verticalSpaceTiny,
160+ },
161+
162+ imageBlobIdText: {
163+ flex: 1,
164+ color: Palette.colors.white,
165+ marginRight: Dimens.horizontalSpaceNormal,
166+ fontSize: Typ.fontSizeNormal,
167+ fontWeight: 'bold',
168+ fontFamily: Typ.fontFamilyReadableText,
169+ },
147170 });
148171
149-class ImageWithBG extends PureComponent<{src: string}, {loaded: boolean}> {
172+type StateImageWithBG = {
173+ fullscreen: boolean;
174+ fullwidth: number;
175+ fullheight: number;
176+};
177+
178+class ZoomableImage extends PureComponent<{src: string}, StateImageWithBG> {
150179 constructor(props: {src: string}) {
151180 super(props);
152- this.state = {loaded: false};
153- this.onLoad = () => {
154- this.setState({loaded: true});
155- };
181+ this.state = {fullscreen: false, fullwidth: 300, fullheight: 200};
182+ this.onOpen = () => this.setState({fullscreen: true});
183+ this.onClose = () => this.setState({fullscreen: false});
156184 }
157185
158- private onLoad: () => void;
186+ private onOpen: () => void;
187+ private onClose: () => void;
159188
189+ public componentDidMount() {
190+ const win = Dimensions.get('window');
191+ Image.getSize(
192+ this.props.src,
193+ (imgWidth: number, imgHeight: number) => {
194+ const ratio = imgHeight / imgWidth;
195+ this.setState({fullwidth: win.width, fullheight: win.width * ratio});
196+ },
197+ () => {},
198+ );
199+ }
200+
201+ public renderFooter(img: any) {
202+ const blobId = urlToBlobId(img.source.uri);
203+ return $(View, {style: styles.imageBlobIdContainer}, [
204+ $(
205+ Text,
206+ {
207+ numberOfLines: 1,
208+ ellipsizeMode: 'middle',
209+ style: styles.imageBlobIdText,
210+ },
211+ blobId,
212+ ),
213+ $(HeaderButton, {
214+ onPress: () => {
215+ Clipboard.setString(blobId);
216+ ToastAndroid.show("Copied this blob's ID", ToastAndroid.SHORT);
217+ },
218+ icon: 'content-copy',
219+ accessibilityLabel: 'Copy Blob ID',
220+ rightSide: true,
221+ }),
222+ ]);
223+ }
224+
160225 public render() {
161226 const d = Dimensions.get('window');
162227 const width = d.width - Dimens.horizontalSpaceBig * 2;
163228 const height = width * 0.7;
164- if (this.state.loaded) {
165- return $(Image, {
166- source: {uri: this.props.src},
167- style: {
168- marginTop: Dimens.verticalSpaceSmall,
169- marginBottom: Dimens.verticalSpaceSmall,
170- resizeMode: 'cover',
171- width,
172- height,
173- },
174- });
175- } else {
176- return $(
177- ImageBackground,
178- {
229+ const uri = this.props.src;
230+ const {fullwidth, fullheight} = this.state;
231+ return $(View, null, [
232+ this.state.fullscreen
233+ ? $(ImageView, {
234+ images: [{source: {uri}, width: fullwidth, height: fullheight}],
235+ imageIndex: 0,
236+ onClose: this.onClose,
237+ renderFooter: this.renderFooter,
238+ })
239+ : null,
240+ $(
241+ Touchable,
242+ {onPress: this.onOpen},
243+ $(Image, {
244+ source: {uri},
245+ defaultSource: pictureIcon,
179246 style: {
247+ resizeMode: 'cover',
180248 marginTop: Dimens.verticalSpaceSmall,
181249 marginBottom: Dimens.verticalSpaceSmall,
182- backgroundColor: Palette.backgroundVoidWeak,
183250 width,
184251 height,
185252 },
186- resizeMode: 'center',
187- source: pictureIcon,
188- },
189- $(Image, {
190- source: {uri: this.props.src},
191- onLoad: this.onLoad,
192- style: {resizeMode: 'cover', width, height},
193253 }),
194- );
195- }
254+ ),
255+ ]);
196256 }
197257 }
198258
199259 const renderers = {
@@ -271,9 +331,9 @@
271331
272332 thematicBreak: () => $(View, {style: styles.horizontalLine}),
273333
274334 image: (props: {src: string; title: string; alt: string}) => {
275- return $(ImageWithBG, {src: props.src});
335+ return $(ZoomableImage, {src: props.src});
276336 },
277337
278338 list: (props: {children: any; depth: number; ordered: boolean}) =>
279339 $(
src/typings/react-native-image-view.d.tsView
@@ -1,0 +1,4 @@
1+declare module 'react-native-image-view' {
2+ const ImageView: any;
3+ export default ImageView;
4+}
tsconfig.jsonView
@@ -21,8 +21,9 @@
2121 "src/backend/loader.ts",
2222 "src/backend/manifest.ts",
2323 "src/frontend/index.ts",
2424 "src/typings/react-native-dialogs.d.ts",
25+ "src/typings/react-native-image-view.d.ts",
2526 "src/typings/rn-viewpager.d.ts"
2627 ],
2728 "exclude": ["node_modules"]
2829 }

Built with git-ssb-web