Revize d0870262
Přidáno uživatelem Fantič před více než 1 rok
src/components/item/ItemTabBar.tsx | ||
---|---|---|
91 | 91 |
{concordances?.[i]?.id} |
92 | 92 |
</Text> |
93 | 93 |
</HStack> |
94 |
{i == index && <Divider color="primary" borderWidth={2} borderRadius={5} width={115} mt={1.5} />}
|
|
94 |
{i == index && <Divider color="primary" borderWidth={2} borderRadius={5} width={105} mt={1.5} />}
|
|
95 | 95 |
</VStack> |
96 | 96 |
|
97 | 97 |
</Pressable> |
... | ... | |
109 | 109 |
{concordances?.[0]?.id} |
110 | 110 |
</Text> |
111 | 111 |
</HStack> |
112 |
{0 == 0 && <Divider color="#654B07" borderWidth={2} borderRadius={5} width={115} mt={1.5} />}
|
|
112 |
{0 == 0 && <Divider color="#654B07" borderWidth={2} borderRadius={5} width={105} mt={1.5} />}
|
|
113 | 113 |
</VStack> |
114 | 114 |
|
115 | 115 |
</Pressable> |
src/components/item/ItemView.tsx | ||
---|---|---|
17 | 17 |
import { select } from "d3" |
18 | 18 |
import { CertaintyWithColors } from "../../stores/reducers/itemSlice" |
19 | 19 |
import { LeftArrowIcon, RightArrowIcon } from "../general/Icons" |
20 |
import { ZoomableImage } from "./ZoomableImage" |
|
20 | 21 |
|
21 | 22 |
interface ItemDetailProps { |
22 | 23 |
item: Item, |
... | ... | |
58 | 59 |
</Heading> |
59 | 60 |
|
60 | 61 |
</VStack> |
61 |
<Box marginLeft="auto" marginTop={1.5}> {/* marginLeft: "auto" pushes the Box to the right */} |
|
62 |
<Button variant="outline" backgroundColor={"#F4DFAB"} borderRadius={8} size="sm" padding={0.5} > |
|
62 |
<Box marginLeft="auto" marginTop={1.5} alignItems={"end"}> {/* marginLeft: "auto" pushes the Box to the right */}
|
|
63 |
<Button variant="outline" backgroundColor={"#F4DFAB"} borderRadius={8} size="sm" padding={0.5} paddingLeft={2} paddingRight={2} >
|
|
63 | 64 |
<Text color="#654B07" fontSize={12}> |
64 | 65 |
{item?.concordances?.[0]?.id} |
65 | 66 |
</Text> |
... | ... | |
108 | 109 |
setSelectedImage(selectedImage - 1); |
109 | 110 |
} |
110 | 111 |
}} icon={<LeftArrowIcon color="#49454F" />} /> |
111 |
<Image size={Dimensions.get('window').width - 110} alt="image" source={{ uri: IMAGE_URL + "/" + item.images[selectedImage].imageUrl }} resizeMode={"contain"} /> |
|
112 |
<IconButton variant="ghost" style={{ height: 30, width: 30, borderRadius: 15}} onPress={() => { |
|
112 |
|
|
113 |
<ZoomableImage fullScreen={false} size={Dimensions.get('window').width - 110} imageUri={IMAGE_URL + "/" + item.images[selectedImage].imageUrl} /> |
|
114 |
|
|
115 |
<IconButton variant="ghost" style={{ height: 30, width: 30, borderRadius: 15 }} onPress={() => { |
|
113 | 116 |
if (item.images && selectedImage + 1 < item.images.length) { |
114 | 117 |
setSelectedImage(selectedImage + 1); |
115 | 118 |
} |
src/components/item/ZoomableImage.tsx | ||
---|---|---|
1 |
import React, { useState, useEffect, useRef } from "react"; |
|
2 |
|
|
3 |
import { Flex, Image, Pressable, View } from "native-base" |
|
4 |
import { PinchGestureHandler, PanGestureHandler, State } from "react-native-gesture-handler"; |
|
5 |
import Animated, { useAnimatedGestureHandler, useAnimatedStyle, useSharedValue } from "react-native-reanimated"; |
|
6 |
import Svg, { SvgXml, Path } from "react-native-svg"; |
|
7 |
import { FullscreenIcon, ExitfullscreenIcon } from "../general/Icons"; |
|
8 |
import { Dimensions } from "react-native"; |
|
9 |
|
|
10 |
export const ZoomableImage = (props: { size: number, imageUri: string, fullScreen?: boolean }) => { |
|
11 |
const DEFAULT_SCALE = 1 |
|
12 |
const MIN_SCALE = 0.95 |
|
13 |
|
|
14 |
const [fullScreenMode, setFullScreenMode] = useState<boolean>(false); |
|
15 |
const [viewSize, setViewSize] = useState({ height: 0, width: 0 }); |
|
16 |
|
|
17 |
const panRef = useRef<React.ReactElement>(); |
|
18 |
const pinchRef = useRef<React.ReactElement>(); |
|
19 |
|
|
20 |
|
|
21 |
useEffect(() => { |
|
22 |
if (props.fullScreen != undefined) { |
|
23 |
setFullScreenMode(props.fullScreen) |
|
24 |
} |
|
25 |
}, [props.fullScreen]) |
|
26 |
|
|
27 |
useEffect(() => { |
|
28 |
setViewSize({ |
|
29 |
width: fullScreenMode ? |
|
30 |
Dimensions.get('window').width - 20 : // full screen |
|
31 |
Dimensions.get('window').width - 20, // not full screen |
|
32 |
height: fullScreenMode ? |
|
33 |
Dimensions.get('window').height - 122.5 : // full scren |
|
34 |
Dimensions.get('window').height - 350, // not full screen |
|
35 |
}) |
|
36 |
}, [fullScreenMode]) |
|
37 |
const translateX = useSharedValue(0); |
|
38 |
const translateY = useSharedValue(0); |
|
39 |
const scale = useSharedValue(DEFAULT_SCALE); |
|
40 |
|
|
41 |
const onPanEvent = useAnimatedGestureHandler({ |
|
42 |
// handle one finger -> drag / move |
|
43 |
onStart: (event, ctx: any) => { |
|
44 |
if (event.numberOfPointers === 1) { |
|
45 |
ctx.startX = translateX.value; |
|
46 |
ctx.startY = translateY.value; |
|
47 |
} |
|
48 |
}, |
|
49 |
onActive: (event, ctx: any) => { |
|
50 |
if (event.numberOfPointers === 1) { |
|
51 |
translateX.value = ctx.startX + event.translationX; |
|
52 |
translateY.value = ctx.startY + event.translationY; |
|
53 |
|
|
54 |
console.log("xTranslate " + translateX.value + " yTranslate " + translateY.value) |
|
55 |
} |
|
56 |
}, |
|
57 |
}); |
|
58 |
|
|
59 |
const onGestureEvent = useAnimatedGestureHandler({ |
|
60 |
onStart: (_, ctx: any) => { |
|
61 |
ctx.startScale = scale.value; |
|
62 |
}, |
|
63 |
onActive: (event: any, ctx: any) => { |
|
64 |
// handle two fingers -> zoom + - |
|
65 |
if (event.numberOfPointers === 2) { |
|
66 |
scale.value = ctx.startScale * event.scale; |
|
67 |
} |
|
68 |
}, |
|
69 |
onEnd: (event) => { |
|
70 |
// handle two fingers -> zoom + - |
|
71 |
if (event.numberOfPointers === 2) { |
|
72 |
if (scale.value < MIN_SCALE) { |
|
73 |
scale.value = MIN_SCALE; |
|
74 |
} |
|
75 |
// You may add additional logic for maximum scale if needed |
|
76 |
|
|
77 |
console.log("scale") |
|
78 |
console.log(scale.value) |
|
79 |
} |
|
80 |
}, |
|
81 |
}); |
|
82 |
|
|
83 |
const animatedStyle = useAnimatedStyle(() => { |
|
84 |
return { |
|
85 |
transform: [ |
|
86 |
{ translateX: translateX.value }, |
|
87 |
{ translateY: translateY.value }, |
|
88 |
{ scale: scale.value }, |
|
89 |
], |
|
90 |
}; |
|
91 |
}); |
|
92 |
|
|
93 |
|
|
94 |
return ( |
|
95 |
<View |
|
96 |
// height={viewSize.height} |
|
97 |
width={viewSize.width} |
|
98 |
// @ts-ignore |
|
99 |
style={ |
|
100 |
fullScreenMode ? { |
|
101 |
position: "absolute", |
|
102 |
top: -230, |
|
103 |
left: 0, |
|
104 |
zIndex: 1000, |
|
105 |
backgroundColor: "white", |
|
106 |
} |
|
107 |
: |
|
108 |
{ |
|
109 |
overflow: "hidden", |
|
110 |
} |
|
111 |
} |
|
112 |
borderColor={fullScreenMode ? "light.300" : undefined} |
|
113 |
borderRadius={fullScreenMode ? 10 : 0} |
|
114 |
borderWidth={fullScreenMode ? 0 : 1} |
|
115 |
> |
|
116 |
{/* control panel */} |
|
117 |
<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 }}> |
|
118 |
{ |
|
119 |
fullScreenMode && |
|
120 |
<Pressable padding={1.5} backgroundColor={"#654B07"} borderRadius={5} marginRight={-2} onPress={() => setFullScreenMode(false)}> |
|
121 |
<FullscreenIcon color="white" /> |
|
122 |
</Pressable> |
|
123 |
} |
|
124 |
|
|
125 |
</Flex> |
|
126 |
|
|
127 |
<PinchGestureHandler |
|
128 |
ref={pinchRef} |
|
129 |
// @ts-ignore |
|
130 |
onGestureEvent={onGestureEvent} |
|
131 |
simultaneousHandlers={[panRef]}> |
|
132 |
<Animated.View style={[{ flex: 1 }, animatedStyle]}> |
|
133 |
<PanGestureHandler |
|
134 |
ref={panRef} |
|
135 |
simultaneousHandlers={[pinchRef]} |
|
136 |
onGestureEvent={onPanEvent} |
|
137 |
onHandlerStateChange={(nativeEvent: any) => { |
|
138 |
if (nativeEvent.state === State.END) { |
|
139 |
console.log(nativeEvent) |
|
140 |
} |
|
141 |
}} |
|
142 |
> |
|
143 |
<Animated.View style={[{ |
|
144 |
flex: 1, |
|
145 |
}]}> |
|
146 |
<Pressable onPress={() => console.log("toggle fullscreen image")}> |
|
147 |
<Image size={viewSize.width} source={{uri: props.imageUri}} resizeMode={"contain"} /> |
|
148 |
</Pressable> |
|
149 |
</Animated.View> |
|
150 |
</PanGestureHandler> |
|
151 |
</Animated.View> |
|
152 |
</PinchGestureHandler > |
|
153 |
</View > |
|
154 |
) |
|
155 |
|
|
156 |
} |
src/pages/PlanViewPage.tsx | ||
---|---|---|
63 | 63 |
selectPlace(route.params.placeId) |
64 | 64 |
} |
65 | 65 |
|
66 |
// if (!itemListLoading) { |
|
67 |
// searchSubmit(currentPage, route.params.roomId, route.params.placeId)
|
|
68 |
// } |
|
66 |
|
|
67 |
dispatch(getPlanInventories({ room: route.params.roomId, place: route.params.placeId }))
|
|
68 |
|
|
69 | 69 |
} |
70 | 70 |
else { |
71 | 71 |
selectFloor(DEFAULT_FLOOR) |
Také k dispozici: Unified diff
re #10917: ItemView design fix