commit d08702620638669d7d8aae629cec795fccb55233
Author: Fantič <58391275+FantaFantic@users.noreply.github.com>
Date:   Sat Dec 16 14:05:17 2023 +0100

    re #10917: ItemView design fix

diff --git a/src/components/item/ItemTabBar.tsx b/src/components/item/ItemTabBar.tsx
index 0741ce7..2856e35 100644
--- a/src/components/item/ItemTabBar.tsx
+++ b/src/components/item/ItemTabBar.tsx
@@ -91,7 +91,7 @@ const ItemTabBar = (props: { navigationState: { routes: any[] }, concordances: C
                                                     {concordances?.[i]?.id}
                                                 </Text>
                                             </HStack>
-                                            {i == index && <Divider color="primary" borderWidth={2} borderRadius={5} width={115} mt={1.5} />}
+                                            {i == index && <Divider color="primary" borderWidth={2} borderRadius={5} width={105} mt={1.5} />}
                                         </VStack>
 
                                     </Pressable>
@@ -109,7 +109,7 @@ const ItemTabBar = (props: { navigationState: { routes: any[] }, concordances: C
                                                 {concordances?.[0]?.id}
                                             </Text>
                                         </HStack>
-                                        {0 == 0 && <Divider color="#654B07" borderWidth={2} borderRadius={5} width={115} mt={1.5} />}
+                                        {0 == 0 && <Divider color="#654B07" borderWidth={2} borderRadius={5} width={105} mt={1.5} />}
                                     </VStack>
 
                                 </Pressable>
diff --git a/src/components/item/ItemView.tsx b/src/components/item/ItemView.tsx
index 1826cd4..3b61c4a 100644
--- a/src/components/item/ItemView.tsx
+++ b/src/components/item/ItemView.tsx
@@ -17,6 +17,7 @@ import { RootStackParamList } from "../../pages/Navigation"
 import { select } from "d3"
 import { CertaintyWithColors } from "../../stores/reducers/itemSlice"
 import { LeftArrowIcon, RightArrowIcon } from "../general/Icons"
+import { ZoomableImage } from "./ZoomableImage"
 
 interface ItemDetailProps {
     item: Item,
@@ -58,8 +59,8 @@ const ItemDetail = (props: ItemDetailProps) => {
                                     </Heading>
 
                                 </VStack>
-                                <Box marginLeft="auto" marginTop={1.5}> {/* marginLeft: "auto" pushes the Box to the right */}
-                                    <Button variant="outline" backgroundColor={"#F4DFAB"} borderRadius={8} size="sm" padding={0.5} >
+                                <Box marginLeft="auto" marginTop={1.5} alignItems={"end"}> {/* marginLeft: "auto" pushes the Box to the right */}
+                                    <Button variant="outline" backgroundColor={"#F4DFAB"} borderRadius={8} size="sm" padding={0.5} paddingLeft={2} paddingRight={2} >
                                         <Text color="#654B07" fontSize={12}>
                                             {item?.concordances?.[0]?.id}
                                         </Text>
@@ -108,8 +109,10 @@ const ItemDetail = (props: ItemDetailProps) => {
                                                 setSelectedImage(selectedImage - 1);
                                             }
                                         }} icon={<LeftArrowIcon color="#49454F" />} />
-                                        <Image size={Dimensions.get('window').width - 110} alt="image" source={{ uri: IMAGE_URL + "/" + item.images[selectedImage].imageUrl }} resizeMode={"contain"} />
-                                        <IconButton variant="ghost" style={{ height: 30, width: 30, borderRadius: 15}} onPress={() => {
+
+                                        <ZoomableImage fullScreen={false} size={Dimensions.get('window').width - 110} imageUri={IMAGE_URL + "/" + item.images[selectedImage].imageUrl} />
+
+                                        <IconButton variant="ghost" style={{ height: 30, width: 30, borderRadius: 15 }} onPress={() => {
                                             if (item.images && selectedImage + 1 < item.images.length) {
                                                 setSelectedImage(selectedImage + 1);
                                             }
diff --git a/src/components/item/ZoomableImage.tsx b/src/components/item/ZoomableImage.tsx
new file mode 100644
index 0000000..f00a63c
--- /dev/null
+++ b/src/components/item/ZoomableImage.tsx
@@ -0,0 +1,156 @@
+import React, { useState, useEffect, useRef } from "react";
+
+import { Flex, Image, Pressable, View } from "native-base"
+import { PinchGestureHandler, PanGestureHandler, State } from "react-native-gesture-handler";
+import Animated, { useAnimatedGestureHandler, useAnimatedStyle, useSharedValue } from "react-native-reanimated";
+import Svg, { SvgXml, Path } from "react-native-svg";
+import { FullscreenIcon, ExitfullscreenIcon } from "../general/Icons";
+import { Dimensions } from "react-native";
+
+export const ZoomableImage = (props: { size: number, imageUri: string, fullScreen?: boolean }) => {
+    const DEFAULT_SCALE = 1
+    const MIN_SCALE = 0.95
+
+    const [fullScreenMode, setFullScreenMode] = useState<boolean>(false);
+    const [viewSize, setViewSize] = useState({ height: 0, width: 0 });
+
+    const panRef = useRef<React.ReactElement>();
+    const pinchRef = useRef<React.ReactElement>();
+
+
+    useEffect(() => {
+        if (props.fullScreen != undefined) {
+            setFullScreenMode(props.fullScreen)
+        }
+    }, [props.fullScreen])
+
+    useEffect(() => {
+        setViewSize({
+            width: fullScreenMode ?
+                Dimensions.get('window').width - 20 : // full screen
+                Dimensions.get('window').width - 20, // not full screen
+            height: fullScreenMode ?
+                Dimensions.get('window').height - 122.5 : // full scren
+                Dimensions.get('window').height - 350, // not full screen
+        })
+    }, [fullScreenMode])
+    const translateX = useSharedValue(0);
+    const translateY = useSharedValue(0);
+    const scale = useSharedValue(DEFAULT_SCALE);
+
+    const onPanEvent = useAnimatedGestureHandler({
+        // handle one finger -> drag / move
+        onStart: (event, ctx: any) => {
+            if (event.numberOfPointers === 1) {
+                ctx.startX = translateX.value;
+                ctx.startY = translateY.value;
+            }
+        },
+        onActive: (event, ctx: any) => {
+            if (event.numberOfPointers === 1) {
+                translateX.value = ctx.startX + event.translationX;
+                translateY.value = ctx.startY + event.translationY;
+
+                console.log("xTranslate " + translateX.value + " yTranslate " + translateY.value)
+            }
+        },
+    });
+
+    const onGestureEvent = useAnimatedGestureHandler({
+        onStart: (_, ctx: any) => {
+            ctx.startScale = scale.value;
+        },
+        onActive: (event: any, ctx: any) => {
+            // handle two fingers -> zoom + -
+            if (event.numberOfPointers === 2) {
+                scale.value = ctx.startScale * event.scale;
+            }
+        },
+        onEnd: (event) => {
+            // handle two fingers -> zoom + -
+            if (event.numberOfPointers === 2) {
+                if (scale.value < MIN_SCALE) {
+                    scale.value = MIN_SCALE;
+                }
+                // You may add additional logic for maximum scale if needed
+
+                console.log("scale")
+                console.log(scale.value)
+            }
+        },
+    });
+
+    const animatedStyle = useAnimatedStyle(() => {
+        return {
+            transform: [
+                { translateX: translateX.value },
+                { translateY: translateY.value },
+                { scale: scale.value },
+            ],
+        };
+    });
+
+
+    return (
+        <View
+            // height={viewSize.height}
+            width={viewSize.width}
+            // @ts-ignore
+            style={
+                fullScreenMode ? {
+                    position: "absolute",
+                    top: -230,
+                    left: 0,
+                    zIndex: 1000,
+                    backgroundColor: "white",
+                }
+                    :
+                    {
+                        overflow: "hidden",
+                    }
+            }
+            borderColor={fullScreenMode ? "light.300" : undefined}
+            borderRadius={fullScreenMode ? 10 : 0}
+            borderWidth={fullScreenMode ? 0 : 1}
+        >
+            {/* control panel */}
+            <Flex direction="row" alignItems="center" justify="flex-end" style={{ height: 50, width: 100, top: fullScreenMode ? 10 : 0, right: fullScreenMode ? 20 : 15, position: "absolute", zIndex: 5 }}>
+                {
+                    fullScreenMode &&
+                    <Pressable padding={1.5} backgroundColor={"#654B07"} borderRadius={5} marginRight={-2} onPress={() => setFullScreenMode(false)}>
+                        <FullscreenIcon color="white" />
+                    </Pressable>
+                }
+
+            </Flex>
+
+            <PinchGestureHandler
+                ref={pinchRef}
+                // @ts-ignore
+                onGestureEvent={onGestureEvent}
+                simultaneousHandlers={[panRef]}>
+                <Animated.View style={[{ flex: 1 }, animatedStyle]}>
+                    <PanGestureHandler
+                        ref={panRef}
+                        simultaneousHandlers={[pinchRef]}
+                        onGestureEvent={onPanEvent}
+                        onHandlerStateChange={(nativeEvent: any) => {
+                            if (nativeEvent.state === State.END) {
+                                console.log(nativeEvent)
+                            }
+                        }}
+                    >
+                        <Animated.View style={[{
+                            flex: 1,
+                        }]}>
+                            <Pressable onPress={() => console.log("toggle fullscreen image")}>
+                                <Image size={viewSize.width} source={{uri: props.imageUri}} resizeMode={"contain"} />
+                            </Pressable>
+                        </Animated.View>
+                    </PanGestureHandler>
+                </Animated.View>
+            </PinchGestureHandler >
+        </View >
+    )
+
+}
\ No newline at end of file
diff --git a/src/pages/PlanViewPage.tsx b/src/pages/PlanViewPage.tsx
index 532d248..b33045b 100644
--- a/src/pages/PlanViewPage.tsx
+++ b/src/pages/PlanViewPage.tsx
@@ -63,9 +63,9 @@ const PlanViewPage = ({ route, navigation }: DrawerScreenProps<RootStackParamLis
           selectPlace(route.params.placeId)
         }
 
-        // if (!itemListLoading) {
-        //   searchSubmit(currentPage, route.params.roomId, route.params.placeId)
-        // }
+        
+        dispatch(getPlanInventories({ room: route.params.roomId, place: route.params.placeId }))
+
       }
       else {
         selectFloor(DEFAULT_FLOOR)
