about summary refs log tree commit diff
path: root/src/view/com/util/images/ImageLayoutGrid.tsx
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-12-30 11:55:25 -0600
committerPaul Frazee <pfrazee@gmail.com>2022-12-30 11:55:25 -0600
commit55500e2f66d5f30f1aedf63d4355a6b7568d4552 (patch)
treec8c9fea21991a47ad491812fb0e4f0b13dc8ce76 /src/view/com/util/images/ImageLayoutGrid.tsx
parentf609794bd2dec01937a31fff142efcaf44fa396b (diff)
downloadvoidsky-55500e2f66d5f30f1aedf63d4355a6b7568d4552.tar.zst
Improve image layout
Diffstat (limited to 'src/view/com/util/images/ImageLayoutGrid.tsx')
-rw-r--r--src/view/com/util/images/ImageLayoutGrid.tsx148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx
new file mode 100644
index 000000000..cb560dd35
--- /dev/null
+++ b/src/view/com/util/images/ImageLayoutGrid.tsx
@@ -0,0 +1,148 @@
+import React from 'react'
+import {
+  Image,
+  ImageStyle,
+  LayoutChangeEvent,
+  StyleProp,
+  StyleSheet,
+  TouchableWithoutFeedback,
+  View,
+  ViewStyle,
+} from 'react-native'
+
+interface Dim {
+  width: number
+  height: number
+}
+
+export type ImageLayoutGridType = 'two' | 'three' | 'four'
+
+export function ImageLayoutGrid({
+  type,
+  uris,
+  onPress,
+  style,
+}: {
+  type: ImageLayoutGridType
+  uris: string
+  onPress?: (index: number) => void
+  style?: StyleProp<ViewStyle>
+}) {
+  const [containerInfo, setContainerInfo] = React.useState<Dim | undefined>()
+
+  const onLayout = (evt: LayoutChangeEvent) => {
+    setContainerInfo({
+      width: evt.nativeEvent.layout.width,
+      height: evt.nativeEvent.layout.height,
+    })
+  }
+
+  return (
+    <View style={style} onLayout={onLayout}>
+      {containerInfo ? (
+        <ImageLayoutGridInner
+          type={type}
+          uris={uris}
+          onPress={onPress}
+          containerInfo={containerInfo}
+        />
+      ) : undefined}
+    </View>
+  )
+}
+
+function ImageLayoutGridInner({
+  type,
+  uris,
+  onPress,
+  containerInfo,
+}: {
+  type: ImageLayoutGridType
+  uris: string
+  onPress?: (index: number) => void
+  containerInfo: Dim
+}) {
+  const size1 = React.useMemo<ImageStyle>(() => {
+    if (type === 'three') {
+      const size = (containerInfo.width - 10) / 3
+      return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
+    } else {
+      const size = (containerInfo.width - 5) / 2
+      return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
+    }
+  }, [type, containerInfo])
+  const size2 = React.useMemo<ImageStyle>(() => {
+    if (type === 'three') {
+      const size = ((containerInfo.width - 10) / 3) * 2 + 5
+      return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
+    } else {
+      const size = (containerInfo.width - 5) / 2
+      return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
+    }
+  }, [type, containerInfo])
+
+  if (type === 'two') {
+    return (
+      <View style={styles.flexRow}>
+        <TouchableWithoutFeedback onPress={() => onPress?.(0)}>
+          <Image source={{uri: uris[0]}} style={size1} />
+        </TouchableWithoutFeedback>
+        <View style={styles.wSpace} />
+        <TouchableWithoutFeedback onPress={() => onPress?.(1)}>
+          <Image source={{uri: uris[1]}} style={size1} />
+        </TouchableWithoutFeedback>
+      </View>
+    )
+  }
+  if (type === 'three') {
+    return (
+      <View style={styles.flexRow}>
+        <TouchableWithoutFeedback onPress={() => onPress?.(0)}>
+          <Image source={{uri: uris[0]}} style={size2} />
+        </TouchableWithoutFeedback>
+        <View style={styles.wSpace} />
+        <View>
+          <TouchableWithoutFeedback onPress={() => onPress?.(1)}>
+            <Image source={{uri: uris[1]}} style={size1} />
+          </TouchableWithoutFeedback>
+          <View style={{height: 5}} />
+          <TouchableWithoutFeedback onPress={() => onPress?.(2)}>
+            <Image source={{uri: uris[2]}} style={size1} />
+          </TouchableWithoutFeedback>
+        </View>
+      </View>
+    )
+  }
+  if (type === 'four') {
+    return (
+      <View style={styles.flexRow}>
+        <View>
+          <TouchableWithoutFeedback onPress={() => onPress?.(0)}>
+            <Image source={{uri: uris[0]}} style={size1} />
+          </TouchableWithoutFeedback>
+          <View style={styles.hSpace} />
+          <TouchableWithoutFeedback onPress={() => onPress?.(1)}>
+            <Image source={{uri: uris[1]}} style={size1} />
+          </TouchableWithoutFeedback>
+        </View>
+        <View style={styles.wSpace} />
+        <View>
+          <TouchableWithoutFeedback onPress={() => onPress?.(2)}>
+            <Image source={{uri: uris[2]}} style={size1} />
+          </TouchableWithoutFeedback>
+          <View style={styles.hSpace} />
+          <TouchableWithoutFeedback onPress={() => onPress?.(3)}>
+            <Image source={{uri: uris[3]}} style={size1} />
+          </TouchableWithoutFeedback>
+        </View>
+      </View>
+    )
+  }
+  return <View />
+}
+
+const styles = StyleSheet.create({
+  flexRow: {flexDirection: 'row'},
+  wSpace: {width: 5},
+  hSpace: {height: 5},
+})