fixed refresh, tablet drawer, drawer titles

This commit is contained in:
ivic00
2024-11-20 00:27:43 +01:00
parent bd890406b1
commit 81477ed85b
8 changed files with 251 additions and 178 deletions

View File

@ -2,7 +2,13 @@ import React, { useEffect } from "react";
import { Drawer } from "expo-router/drawer";
import { useSignOut } from "@/hooks/firebase/useSignOut";
import { DrawerContentScrollView } from "@react-navigation/drawer";
import { Button, ButtonSize, Text, View } from "react-native-ui-lib";
import {
Button,
ButtonSize,
Text,
TouchableOpacity,
View,
} from "react-native-ui-lib";
import { ImageBackground, StyleSheet } from "react-native";
import DrawerButton from "@/components/shared/DrawerButton";
import NavGroceryIcon from "@/assets/svgs/NavGroceryIcon";
@ -11,7 +17,6 @@ import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon";
import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon";
import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon";
import ViewSwitch from "@/components/pages/(tablet_pages)/ViewSwitch";
import { MaterialIcons } from "@expo/vector-icons";
import { useSetAtom } from "jotai";
import {
isFamilyViewAtom,
@ -23,6 +28,7 @@ import Ionicons from "@expo/vector-icons/Ionicons";
import * as Device from "expo-device";
import { DeviceType } from "expo-device";
import FeedbackNavIcon from "@/assets/svgs/FeedbackNavIcon";
import DrawerIcon from "@/assets/svgs/DrawerIcon";
export default function TabLayout() {
const { mutateAsync: signOut } = useSignOut();
@ -37,6 +43,20 @@ export default function TabLayout() {
detachInactiveScreens
screenOptions={({ navigation, route }) => ({
headerShown: true,
headerTitleAlign:
Device.deviceType === DeviceType.TABLET ? "left" : "center",
headerTitleStyle: {
fontFamily: "Manrope_600SemiBold",
fontSize: Device.deviceType === DeviceType.TABLET ? 22 : 17,
},
headerLeft: (props) => (
<TouchableOpacity
onPress={navigation.toggleDrawer}
style={{ marginLeft: 16 }}
>
<DrawerIcon />
</TouchableOpacity>
),
headerRight: () => {
// Only show ViewSwitch on calendar and todos pages
const showViewSwitch = ["calendar", "todos", "index"].includes(
@ -48,9 +68,8 @@ export default function TabLayout() {
</View>
) : null;
},
headerStyle: { height: Device.deviceType === DeviceType.TABLET ? 100 : undefined},
drawerStyle: {
width: Device.deviceType === DeviceType.TABLET ? "50%" : "90%",
width: Device.deviceType === DeviceType.TABLET ? "30%" : "90%",
backgroundColor: "#f9f8f7",
height: "100%",
},
@ -117,7 +136,7 @@ export default function TabLayout() {
icon={<FeedbackNavIcon />}
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ flex: 1, paddingRight: 0 }}>
{/*<DrawerButton
color="#fd1775"
title={"My Reminders"}
@ -233,14 +252,20 @@ export default function TabLayout() {
name="index"
options={{
drawerLabel: "Calendar",
title: "Calendar",
title:
Device.deviceType === DeviceType.TABLET
? "Family Calendar"
: "Calendar",
}}
/>
<Drawer.Screen
name="calendar"
options={{
drawerLabel: "Calendar",
title: "Calendar",
title:
Device.deviceType === DeviceType.TABLET
? "Family Calendar"
: "Calendar",
drawerItemStyle: { display: "none" },
}}
/>
@ -276,7 +301,10 @@ export default function TabLayout() {
name="todos"
options={{
drawerLabel: "To-Do",
title: "To-Dos",
title:
Device.deviceType === DeviceType.TABLET
? "Family To Do's"
: "To Do's",
}}
/>
<Drawer.Screen

View File

@ -1,16 +1,26 @@
import React, { useState } from "react";
import { ScrollView, RefreshControl } from "react-native";
import { useSetAtom } from "jotai";
import { ScrollView, RefreshControl, View } from "react-native";
import { useAtom } from "jotai";
import CalendarPage from "@/components/pages/calendar/CalendarPage";
import { refreshTriggerAtom } from "@/components/pages/calendar/atoms";
import { colorMap } from "@/constants/colorMap";
import TabletCalendarPage from "@/components/pages/(tablet_pages)/calendar/TabletCalendarPage";
import { DeviceType } from "expo-device";
import * as Device from "expo-device";
import { useCalSync } from "@/hooks/useCalSync";
import Toast from "react-native-toast-message";
export default function Screen() {
const [refreshing, setRefreshing] = useState(false);
const setRefreshTrigger = useSetAtom(refreshTriggerAtom);
const [shouldRefresh, setShouldRefresh] = useAtom(refreshTriggerAtom);
const {
isConnectedToGoogle,
isConnectedToMicrosoft,
isConnectedToApple,
resyncAllCalendars,
isSyncing,
} = useCalSync();
const onRefresh = React.useCallback(async () => {
setRefreshing(true);
@ -18,45 +28,65 @@ export default function Screen() {
const minimumDelay = new Promise((resolve) => setTimeout(resolve, 1000));
try {
setRefreshTrigger((prev) => !prev);
await Promise.all([minimumDelay]);
if (isConnectedToGoogle || isConnectedToMicrosoft || isConnectedToApple) {
await Promise.all([resyncAllCalendars(), minimumDelay]);
} else {
await minimumDelay;
}
} catch (error) {
console.error("Refresh failed:", error);
} finally {
setRefreshing(false);
setShouldRefresh((prev) => !prev);
}
}, [setRefreshTrigger]);
}, [
resyncAllCalendars,
isConnectedToGoogle,
isConnectedToMicrosoft,
isConnectedToApple,
]);
return (
<>
{Device.deviceType === DeviceType.TABLET ? (
<TabletCalendarPage />
) : (
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{ flex: 1 }}
refreshControl={
<RefreshControl
colors={[
colorMap.pink,
colorMap.green,
colorMap.orange,
colorMap.purple,
colorMap.teal,
]}
tintColor={colorMap.pink}
progressBackgroundColor={"white"}
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
bounces={true}
showsVerticalScrollIndicator={false}
>
<CalendarPage />
</ScrollView>
)}
</>
<View style={{ flex: 1 }}>
<View style={{ flex: 1, zIndex: -2 }}>
{Device.deviceType === DeviceType.TABLET ? (
<TabletCalendarPage />
) : (
<CalendarPage />
)}
</View>
<ScrollView
style={{
position: "absolute",
top: 0,
left: Device.deviceType === DeviceType.TABLET ? "15%" : 0,
right: Device.deviceType === DeviceType.TABLET ? "25%" : 0,
height: Device.deviceType === DeviceType.TABLET ? "9%" : "12%",
width: Device.deviceType === DeviceType.TABLET ? "62%" : "100%",
zIndex: 100,
backgroundColor: "transparent",
}}
contentContainerStyle={{ flex: 1 }}
refreshControl={
<RefreshControl
colors={[
colorMap.pink,
colorMap.green,
colorMap.orange,
colorMap.purple,
colorMap.teal,
]}
tintColor={colorMap.pink}
progressBackgroundColor={"white"}
refreshing={refreshing || isSyncing}
onRefresh={onRefresh}
/>
}
bounces={true}
showsVerticalScrollIndicator={false}
pointerEvents={refreshing || isSyncing ? "auto" : "none"}
/>
</View>
);
}

View File

@ -0,0 +1,19 @@
import * as React from "react"
import Svg, { SvgProps, Path } from "react-native-svg"
const DrawerIcon = (props: SvgProps) => (
<Svg
width={27}
height={18}
fill="none"
{...props}
>
<Path
stroke="#83807F"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2.7}
d="M2 1.995h22.667M2 9.14h14.167M2 16.285h7.083"
/>
</Svg>
)
export default DrawerIcon

View File

@ -1,92 +1,88 @@
import { Text, TouchableOpacity, View } from "react-native-ui-lib";
import React, { useEffect, useState } from "react";
import { SegmentedControl, View } from "react-native-ui-lib";
import React, { memo, useCallback, useEffect, useRef, useState } from "react";
import { StyleSheet } from "react-native";
import { NavigationProp } from "@react-navigation/native";
import view from "react-native-ui-lib/src/components/view";
import { NavigationProp, useNavigationState } from "@react-navigation/native";
interface ViewSwitchProps {
navigation: NavigationProp<any>; // Adjust according to your navigation structure
}
const ViewSwitch: React.FC<ViewSwitchProps> = ({ navigation }) => {
const [pageIndex, setPageIndex] = useState<number>(navigation.getState().index);
const ViewSwitch = memo(function ViewSwitch({
navigation,
}: {
navigation: any;
}) {
const isNavigating = useRef(false);
const navigationState = useNavigationState((state) => state);
const [selectedIndex, setSelectedIndex] = useState(
navigationState.index === 6 ? 1 : 0
);
// Sync the selected index with navigation state
useEffect(() => {
setPageIndex(navigation.getState().index);
}, [navigation.getState().index])
return (
<View
row
spread
style={{
borderRadius: 30,
backgroundColor: "#ebebeb",
alignItems: "center",
justifyContent: "center",
// iOS shadow
shadowColor: "#000",
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0,
shadowRadius: 0,
// Android shadow (elevation)
elevation: 0,
}}
centerV
>
<TouchableOpacity
onPress={() => {
navigation.navigate("calendar");
}}
>
<View
centerV
centerH
height={54}
paddingH-15
style={ pageIndex == 1 || pageIndex == 0 ? styles.switchBtnActive : styles.switchBtn}
>
<Text color={pageIndex == 1 || pageIndex == 0 ? "white" : "black"} style={styles.switchTxt}>
Calendar
</Text>
</View>
</TouchableOpacity>
const newIndex = navigationState.index === 6 ? 1 : 0;
if (selectedIndex !== newIndex) {
setSelectedIndex(newIndex);
}
isNavigating.current = false;
}, [navigationState.index]);
<TouchableOpacity
onPress={() => {
navigation.navigate("todos");
}}
>
<View
centerV
centerH
height={54}
paddingH-15
style={pageIndex == 6 ? styles.switchBtnActive : styles.switchBtn}
>
<Text color={pageIndex == 6 ? "white" : "black"} style={styles.switchTxt}>
Chores
</Text>
</View>
</TouchableOpacity>
const handleSegmentChange = useCallback(
(index: number) => {
if (isNavigating.current) return;
if (index === selectedIndex) return;
isNavigating.current = true;
setSelectedIndex(index);
// Delay navigation slightly to allow the segment control to update
requestAnimationFrame(() => {
navigation.navigate(index === 0 ? "calendar" : "todos");
});
console.log(selectedIndex)
},
[navigation, selectedIndex]
);
return (
<View style={styles.container}>
<SegmentedControl
segments={[
{ label: "Calendar", segmentLabelStyle: styles.labelStyle },
{ label: "To Do's", segmentLabelStyle: styles.labelStyle },
]}
containerStyle={styles.segmentContainer}
style={styles.segment}
backgroundColor="#ebebeb"
inactiveColor="black"
activeColor="white"
activeBackgroundColor="#ea156c"
outlineColor="white"
outlineWidth={3}
onChangeIndex={handleSegmentChange}
initialIndex={selectedIndex}
/>
</View>
);
};
});
export default ViewSwitch;
const styles = StyleSheet.create({
switchBtnActive: {
backgroundColor: "#ea156c",
borderRadius: 50,
width: 110,
},
switchBtn: {
container: {
borderRadius: 30,
backgroundColor: "#ebebeb",
borderRadius: 50,
width: 110,
shadowColor: "#000",
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0,
},
switchTxt: {
segmentContainer: {
height: 44,
width: 220,
},
segment: {
borderRadius: 50,
borderWidth: 0,
height: 44,
},
labelStyle: {
fontSize: 16,
fontFamily: "Manrope_600SemiBold",
},

View File

@ -21,7 +21,9 @@ const TabletCalendarPage = () => {
return (
<TabletContainer>
<InnerCalendar />
<View flexG paddingB-25>
<InnerCalendar />
</View>
</TabletContainer>
);
};

View File

@ -1,6 +1,6 @@
import { View, Text, ViewProps } from "react-native-ui-lib";
import React, { ReactNode } from "react";
import { Dimensions, StyleSheet } from "react-native";
import React, { ReactNode, useEffect, useState } from "react";
import { Dimensions, StyleSheet, useWindowDimensions } from "react-native";
import UsersList from "./UsersList";
import { ScrollView } from "react-native-gesture-handler";
@ -8,12 +8,52 @@ interface TabletContainerProps extends ViewProps {
children: ReactNode;
}
const { width, height } = Dimensions.get("window");
const TabletContainer: React.FC<TabletContainerProps> = ({
children,
...props
}) => {
const window = useWindowDimensions();
const [containerWidth, setContainerWidth] = useState(Dimensions.get('window').width);
const [containerHeight, setContainerHeight] = useState(Dimensions.get('window').height);
// Update dimensions on mount and when window size changes
useEffect(() => {
const updateDimensions = () => {
setContainerWidth(window.width);
setContainerHeight(window.height);
};
updateDimensions();
// Force a second update after a brief delay to handle any initial rendering issues
const timer = setTimeout(updateDimensions, 100);
return () => clearTimeout(timer);
}, [window.width, window.height]);
const styles = StyleSheet.create({
container: {
backgroundColor: "white",
flex: 1,
flexDirection: 'row',
borderTopColor: "#a9a9a9",
width: containerWidth,
borderTopWidth: 1,
},
calendarContainer: {
backgroundColor: "white",
height: containerHeight,
width: containerWidth * 0.89,
},
profilesContainer: {
width: containerWidth * 0.11,
height: containerHeight,
borderLeftWidth: 1,
borderLeftColor: "#a9a9a9",
backgroundColor: "white",
},
});
return (
<View style={styles.container}>
<View row>
@ -28,27 +68,4 @@ const TabletContainer: React.FC<TabletContainerProps> = ({
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: "white",
flex: 1,
flexDirection: 'row',
borderTopColor: "#a9a9a9",
width: '80%',
borderTopWidth: 1,
},
calendarContainer: {
backgroundColor: "white",
height: height,
width: width * 0.89,
},
profilesContainer: {
width: width * 0.11,
height: height,
borderLeftWidth: 1,
borderLeftColor: "#a9a9a9",
backgroundColor: "white",
},
});
export default TabletContainer;
export default TabletContainer;

View File

@ -2,38 +2,19 @@ import React from "react";
import { View } from "react-native-ui-lib";
import HeaderTemplate from "@/components/shared/HeaderTemplate";
import { InnerCalendar } from "@/components/pages/calendar/InnerCalendar";
import { useSetAtom } from "jotai";
import { refreshEnabledAtom } from "./atoms";
export default function CalendarPage() {
const setRefreshEnabled = useSetAtom(refreshEnabledAtom);
const disableRefreshControl = () => setRefreshEnabled(false);
const enableRefreshControl = () => setRefreshEnabled(true);
return (
<View
style={{ flex: 1, height: "100%", padding: 10 }}
paddingH-22
paddingT-0
>
<View
onStartShouldSetResponder={() => {
enableRefreshControl();
console.log("yeah");
return true;
}}
onResponderRelease={() => {
disableRefreshControl();
console.log("sure");
console.log(refreshEnabledAtom)
}}
>
<HeaderTemplate
message={"Let's get your week started !"}
isWelcome
isCalendar={true}
/>
</View>
<HeaderTemplate
message={"Let's get your week started !"}
isWelcome
isCalendar={true}
/>
<InnerCalendar />
</View>
);

View File

@ -17,9 +17,9 @@ const DrawerButton = (props: IDrawerButtonProps) => {
const styles = StyleSheet.create({
iconContainer: {
width: "70%",
width: isTablet ? '50%' : "70%",
aspectRatio: 1,
borderRadius: 50,
borderRadius: 100,
},
labelStyle: { fontSize: 15, fontFamily: "Poppins_400Regular" },
});
@ -42,7 +42,7 @@ const DrawerButton = (props: IDrawerButtonProps) => {
</View>
)}
style={{
aspectRatio: 1,
aspectRatio: isTablet ? 1.2 : 1,
borderRadius: 18.55,
marginBottom: 12,
flexDirection: "column",