Skip to content

Commit

Permalink
Adding animation + space for vitals
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew-Beslogic committed Nov 7, 2024
1 parent ed7d8fc commit c48a40d
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 158 deletions.
188 changes: 101 additions & 87 deletions apps/releaf/mobile/src/app/box/components/Box.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { styled } from "nativewind";
import { TouchableOpacity, View, Text, GestureResponderEvent, Dimensions } from "react-native";
import { TouchableOpacity, View, Text, Dimensions, Animated, PanResponder } from "react-native";
import LinearGradient from "react-native-linear-gradient";
import { BoxItem } from "../../infrastructure/entities/box";
import { Edit } from '../../../assets/images/edit';
import { Logo } from '../../../assets/images/logo'
import { useState } from "react";
import { useRef } from "react";

const windowWidth = Dimensions.get('window').width;

Expand All @@ -14,102 +14,116 @@ const STouchableOpacity = styled(TouchableOpacity);
const SLinearGradient = styled(LinearGradient);

const MAX_NAME_LENGTH = 7;
export const BOX_LEFT_POSITION = -0.6 * windowWidth;
export const BOX_RIGHT_POSITION = 0;

export function Box({ box }: { box: BoxItem }) {
console.log('a small updates #5')
const [boxHoldPosition, setBoxHoldPosition] = useState<number>(0);
const [boxPosition, setBoxPosition] = useState<number>(0);
let finalPosition = 0;

const ontouchstart = (ev: GestureResponderEvent) => {
setBoxHoldPosition(ev.nativeEvent.locationX)
}
const pan = useRef(new Animated.ValueXY()).current;
const panResponder = useRef(
PanResponder.create({
onPanResponderGrant: () => {
pan.setOffset({ x: finalPosition, y: 0 });
pan.setValue({ x: 0, y: 0 });
},
onPanResponderMove: (ev, gesture) => {
if (
(finalPosition === BOX_LEFT_POSITION && gesture.dx < -20) ||
(finalPosition === BOX_LEFT_POSITION && (gesture.moveX + BOX_LEFT_POSITION - gesture.x0) >= BOX_RIGHT_POSITION)
) return
if (finalPosition === BOX_RIGHT_POSITION && gesture.dx > 20) return

const ontouchmove = (ev: GestureResponderEvent) => {
const diff = ev.nativeEvent.pageX - boxHoldPosition
const pagePercent = (diff / windowWidth) * 100
if (pagePercent < -60 || pagePercent > 0) return
if (Math.abs(diff - boxPosition) < 0.5) return
setBoxPosition(diff)
}
return Animated.event([null, {
dx: pan.x,
dy: pan.y
}])(ev, gesture)
},
onMoveShouldSetPanResponder: () => true,
onPanResponderRelease: (ev, gesture) => {
const screenPercent = (gesture.dx / windowWidth) * 100;
finalPosition = screenPercent < -30 ? BOX_LEFT_POSITION : BOX_RIGHT_POSITION;
pan.flattenOffset();

const ontouchend = (ev: GestureResponderEvent) => {
const pagePercent = (boxPosition / windowWidth) * 100
const diff = ev.nativeEvent.pageX - boxHoldPosition
setBoxPosition(diff)
if (pagePercent < -20) {
setBoxPosition((-60 / 100) * windowWidth)
} else {
setBoxPosition(0)
}
}
Animated.spring(pan, {
toValue: { x: finalPosition, y: 0 },
useNativeDriver: true,
}).start();
},
}),
).current;

return (
<SLinearGradient
onTouchStart={ontouchstart}
onTouchMove={ontouchmove}
onTouchEnd={ontouchend}
colors={['#8E7556', '#8E7556']}
className="rounded-3xl w-vw9/10 h-vw9.21/10 elevation-md mb-10"
style={{ transform: [{ translateX: boxPosition }] }}
<Animated.View
style={{
transform: [{ translateX: pan.x }],
}}
{...panResponder.panHandlers}
>
<SView className="top-0 left-0 right-0 bottom-0 absolute h-full z-40 bg-transparent"></SView>
<SLinearGradient
colors={['#FABB72', '#D49953']}
className="rounded-2xl h-vw9/10"
colors={['#8E7556', '#8E7556']}
className="rounded-3xl w-vw9/10 h-vw9.21/10 elevation-md mb-10"
>
<SView className="flex-wrap rounded-3xl h-full gap-1 justify-center ml-vw5/100 mr-vw7/100">
<SView className="flex-wrap justify-end flex-0.5 h-vw5/100 flex-row">
<SText className="ml-1 uppercase flex-4 text-base font-lato-bold">
{box.treeName}
</SText>
<SText className="text-end font-lato-bold">
<SText className='text-base'>{box.dateSinceGermination} </SText>
<SText className='text-sm'>jours</SText>
</SText>
</SView>
{box.seeds
.reduce((acc, curr, i) => {
if (i % 5 == 0) acc.push([]);
acc[acc.length - 1].push(curr);
return acc;
}, [])
.map((seeds, rowIndex) => (
<SView key={`${rowIndex}`} className="flex-wrap h-full gap-1 flex-1 flex-row">
{seeds.map((seed, i) => (
<SLinearGradient
colors={['#987851', '#f1d4b1']}
key={`${rowIndex}-${i}`}
className="h-full flex-1 justify-center items-center rounded-md"
>
<SView className="absolute z-20 top-2 left-0 right-0 bottom-0 bg-releaf-brown-900 rounded-md ml-vw0.5/100 mb-vw0.5/100 mt-vw0.5/100 mr-vw0.5/100"></SView>
<SView className="absolute z-10 top-0 left-0 right-0 bottom-0 bg-releaf-brown-800 rounded-md ml-vw0.5/100 mb-vw0.5/100 mt-vw0.5/100 mr-vw0.5/100"></SView>
<SView className="h-full z-40 flex-1 bg-transparent justify-end items-center rounded-md ml-vw0.5/100 mb-vw0.5/100 mt-vw0.5/100 mr-vw0.5/100">
<SText className="min-w-full text-center z-30 color-releaf-brown-100">
{(seed.name as string).substring(
0,
MAX_NAME_LENGTH
)}
{seed.name.length > MAX_NAME_LENGTH ? '.' : ''}
</SText>
</SView>
</SLinearGradient>
))}
</SView>
))}
<SView className="flex-wrap flex-row h-vw7/100 pt-1 pl-1 z-60">
<SText className="flex-1 text-base font-latoRegular">
<Logo></Logo>
</SText>
<STouchableOpacity
className='flex-4 flex-row gap-1'
>
<SText className="text-center flex-1 text-base font-caveat-bold bg-releaf-brown-500 rounded-l-md">{box.seedsAverageInchHeight} cm</SText>
<SText className="text-center flex-2 text-base font-caveat-bold bg-releaf-brown-500">{box.germinationDay}</SText>
<SText className="text-center flex-1 text-base bg-white rounded-r-md elevation-md"><Edit size={20}></Edit></SText>
</STouchableOpacity>
<SView className="top-0 left-0 right-0 bottom-0 absolute h-full z-40 bg-transparent"></SView>

<SLinearGradient
colors={['#FABB72', '#D49953']}
className="rounded-2xl h-vw9/10"
>
<SView className="flex-wrap rounded-3xl h-full gap-1 justify-center ml-vw5/100 mr-vw7/100">
<SView className="flex-wrap justify-end flex-0.5 h-vw5/100 flex-row">
<SText className="ml-1 uppercase flex-4 text-base font-lato-bold">
{box.treeName}2
</SText>
<SText className="text-end font-lato-bold">
<SText className='text-base'>{box.dateSinceGermination} </SText>
<SText className='text-sm'>jours</SText>
</SText>
</SView>
{box.seeds
.reduce((acc, curr, i) => {
if (i % 5 == 0) acc.push([]);
acc[acc.length - 1].push(curr);
return acc;
}, [])
.map((seeds, rowIndex) => (
<SView key={`${rowIndex}`} className="flex-wrap h-full gap-1 flex-1 flex-row">
{seeds.map((seed, i) => (
<SLinearGradient
colors={['#987851', '#f1d4b1']}
key={`${rowIndex}-${i}`}
className="h-full flex-1 justify-center items-center rounded-md"
>
<SView className="absolute z-20 top-2 left-0 right-0 bottom-0 bg-releaf-brown-900 rounded-md ml-vw0.5/100 mb-vw0.5/100 mt-vw0.5/100 mr-vw0.5/100"></SView>
<SView className="absolute z-10 top-0 left-0 right-0 bottom-0 bg-releaf-brown-800 rounded-md ml-vw0.5/100 mb-vw0.5/100 mt-vw0.5/100 mr-vw0.5/100"></SView>
<SView className="h-full z-40 flex-1 bg-transparent justify-end items-center rounded-md ml-vw0.5/100 mb-vw0.5/100 mt-vw0.5/100 mr-vw0.5/100">
<SText className="min-w-full text-center z-30 color-releaf-brown-100">
{(seed.name as string).substring(
0,
MAX_NAME_LENGTH
)}
{seed.name.length > MAX_NAME_LENGTH ? '.' : ''}
</SText>
</SView>
</SLinearGradient>
))}
</SView>
))}
<SView className="flex-wrap flex-row h-vw7/100 pt-1 pl-1 z-60">
<SText className="flex-1 text-base font-latoRegular">
<Logo></Logo>
</SText>
<STouchableOpacity
className='flex-4 flex-row gap-1'
>
<SText className="text-center flex-1 text-base font-caveat-bold bg-releaf-brown-500 rounded-l-md">{box.seedsAverageInchHeight} cm</SText>
<SText className="text-center flex-2 text-base font-caveat-bold bg-releaf-brown-500">{box.germinationDay}</SText>
<SText className="text-center flex-1 text-base bg-white rounded-r-md elevation-md"><Edit size={20}></Edit></SText>
</STouchableOpacity>
</SView>
</SView>
</SView>
</SLinearGradient>
</SLinearGradient>
</SLinearGradient>
</Animated.View>
);
}
94 changes: 26 additions & 68 deletions apps/releaf/mobile/src/app/box/components/Vitals.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,30 @@
const styles = StyleSheet.create({
// :root {
// --wide-box-bg-color: #f4efe9;
// }

// .box {
// width: 350px;
// height: 400px;
// background: linear-gradient(#F2E9DD, #D8C8B6);
// border-radius: 15px;
// gap: 3px;
// padding: 5px 10px;
// }

// .vitals {
// color: #433A2E;
// font-size: x-large;
// font-weight: 500;
// }

// .symbol {
// flex: 2;
// display: flex;
// justify-content: center;
// font-size: 2rem;
// }

// .percent {
// flex: 1.2;
// margin: 0 20px;
// background-color: white;
// padding: 5px 0;
// text-align: center;
// font-size: larger;
// font-weight: 500;
// }

// .wide-box {
// display: flex;
// flex: auto;
// align-items: center;
// border-radius: 15px;
// background-color: var(--wide-box-bg-color);
// }

// body {
// padding: 25px 50px;
// }

// .battery-wrapper {
// padding: 0.5rem;
// border-left: 2px solid #EFE7DE;
// height: 100%;
// display: flex;
// align-items: center;
// }

// .warning {
// position: absolute;
// top: 10px;
// left: 10px;
// }
});

export const CircleVitalStatus = ({ type = 'light' }) => {
return (<View></View>);
import { styled } from "nativewind";
import { View, Text, } from "react-native";
import LinearGradient from "react-native-linear-gradient";
import { HealthMetrics } from "../../../assets/images/health-metrics";

const SLinearGradient = styled(LinearGradient);
const SView = styled(View);
const SText = styled(Text);

export const Vitals = ({ type = 'light' }) => {
return (<SLinearGradient
colors={['#8E7555', '#8E7555']}
className="rounded-3xl h-vw7.9/10 elevation-md mb-10"
>
<SLinearGradient
colors={['#F3E9DD', '#D8C9B7']}
className="rounded-2xl h-vw7.8/10 pl-vw1/3"
>
<SView className="flex-row items-center pt-2">
<HealthMetrics height={20} width={20}></HealthMetrics>
<SText className="pl-2 font-lato-bold text-2xl color-releaf-brown-900">Vitals</SText>
</SView>
</SLinearGradient>
</SLinearGradient>);
// <View styles={class="box flex flex-col"}>
{/* class="box flex flex-col" */}
{/* <div class="flex justify-center">
{/* class="box flex flex-col" */ }
{/* <div class="flex justify-center">
<img src="assets/vitals/cross.svg" alt="cross" />
<span class="vitals">Vitals</span>
</div>
Expand Down
2 changes: 0 additions & 2 deletions apps/releaf/mobile/src/app/box/screens/BoxDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ export function BoxDetailsScreen({ route, navigation }) {
const [date, setDate] = useState(new Date());
const [open, setOpen] = useState(false);

const boxService = new BoxService();

const [isLoading, setIsLoading] = useState(true);
const [boxDetails, setBoxDetails] = useState<BoxDetails>(null);

Expand Down
10 changes: 9 additions & 1 deletion apps/releaf/mobile/src/app/box/screens/Boxes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { styled } from 'nativewind';
import { selectTreeDefinitions } from '../../store/slices/treeDefinitionSlice';
import { useSelector } from 'react-redux';
import { Box } from '../components/Box';
import { Vitals } from '../components/Vitals';

const styles = StyleSheet.create({
title: {
Expand Down Expand Up @@ -108,7 +109,14 @@ function BoxScreen({ navigation }) {

<SView className="justify-center items-center p-3">
{boxes.map((box, boxIndex) => (
<Box key={boxIndex} box={box}></Box>
<SView className='relative'>
<SView className="z-10">
<Box key={boxIndex} box={box}></Box>
</SView>
<SView className='absolute left-1 right-1 top-9'>
<Vitals></Vitals>
</SView>
</SView>
))}
</SView>
</ScrollView>
Expand Down
10 changes: 10 additions & 0 deletions apps/releaf/mobile/src/assets/images/health-metrics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Svg, { Path } from "react-native-svg"


export const HealthMetrics = ({ width = 20, height = 20 }) => {
return (
<Svg width={width} height={height} viewBox="0 0 20 20" fill="none">
<Path d="M5 20V15H0V11H6.45L8.15 13.55C8.23333 13.6833 8.35 13.7917 8.5 13.875C8.65 13.9583 8.80833 14 8.975 14C9.19167 14 9.39167 13.9333 9.575 13.8C9.75833 13.6667 9.88333 13.5 9.95 13.3L11.3 9.25L12.15 10.55C12.25 10.6833 12.375 10.7917 12.525 10.875C12.675 10.9583 12.8333 11 13 11H20V15H15V20H5ZM8.7 10.75L7.825 9.45C7.74167 9.31667 7.625 9.20833 7.475 9.125C7.325 9.04167 7.16667 9 7 9H0V5H5V0H15V5H20V9H13.525L11.825 6.45C11.7417 6.31667 11.625 6.20833 11.475 6.125C11.325 6.04167 11.1667 6 11 6C10.7833 6 10.5875 6.06667 10.4125 6.2C10.2375 6.33333 10.1167 6.5 10.05 6.7L8.7 10.75Z" fill="#433A2E" />
</Svg>
)
}
Loading

0 comments on commit c48a40d

Please sign in to comment.