mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 07:07:16 +00:00
bugfixes
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">"Cally "</string>
|
<string name="app_name">\"Cally \"</string>
|
||||||
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
|
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
|
||||||
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
|
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
|
||||||
<string name="expo_system_ui_user_interface_style" translatable="false">light</string>
|
<string name="expo_system_ui_user_interface_style" translatable="false">light</string>
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {RefreshControl, ScrollView, View} from "react-native";
|
import {RefreshControl, ScrollView, View} from "react-native";
|
||||||
import CalendarPage from "@/components/pages/calendar/CalendarPage";
|
import CalendarPage from "@/components/pages/calendar/CalendarPage";
|
||||||
import {colorMap} from "@/constants/colorMap";
|
|
||||||
import TabletCalendarPage from "@/components/pages/(tablet_pages)/calendar/TabletCalendarPage";
|
import TabletCalendarPage from "@/components/pages/(tablet_pages)/calendar/TabletCalendarPage";
|
||||||
import * as Device from "expo-device";
|
import * as Device from "expo-device";
|
||||||
import {DeviceType} from "expo-device";
|
import {DeviceType} from "expo-device";
|
||||||
import {useCalSync} from "@/hooks/useCalSync";
|
import {useCalSync} from "@/hooks/useCalSync";
|
||||||
|
import {colorMap} from "@/constants/colorMap";
|
||||||
|
|
||||||
export default function Screen() {
|
export default function Screen() {
|
||||||
const isTablet = Device.deviceType === DeviceType.TABLET;
|
const isTablet = Device.deviceType === DeviceType.TABLET;
|
||||||
const {
|
const {resyncAllCalendars, isSyncing} = useCalSync();
|
||||||
resyncAllCalendars,
|
|
||||||
isSyncing,
|
|
||||||
} = useCalSync();
|
|
||||||
|
|
||||||
const onRefresh = React.useCallback(async () => {
|
const onRefresh = React.useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
@ -22,58 +19,68 @@ export default function Screen() {
|
|||||||
}
|
}
|
||||||
}, [resyncAllCalendars]);
|
}, [resyncAllCalendars]);
|
||||||
|
|
||||||
return (
|
const refreshControl = (
|
||||||
<View style={{ flex: 1 }}>
|
<RefreshControl
|
||||||
<View style={{ flex: 1, zIndex: 0 }}>
|
colors={[
|
||||||
{Device.deviceType === DeviceType.TABLET ? (
|
colorMap.pink,
|
||||||
<TabletCalendarPage />
|
colorMap.green,
|
||||||
) : (
|
colorMap.orange,
|
||||||
<CalendarPage />
|
colorMap.purple,
|
||||||
)}
|
colorMap.teal,
|
||||||
</View>
|
]}
|
||||||
|
tintColor={colorMap.pink}
|
||||||
<ScrollView
|
progressBackgroundColor="white"
|
||||||
style={{
|
refreshing={isSyncing}
|
||||||
position: "absolute",
|
onRefresh={onRefresh}
|
||||||
top: 0,
|
style={isTablet ? {
|
||||||
left: isTablet ? "15%" : 0,
|
position: "absolute",
|
||||||
height: isTablet ? "9%" : "4%",
|
left: "50%",
|
||||||
width: isTablet ? "62%" : "100%",
|
transform: [{translateX: -20}],
|
||||||
zIndex: 50,
|
} : undefined}
|
||||||
backgroundColor: "transparent",
|
/>
|
||||||
}}
|
|
||||||
contentContainerStyle={{
|
|
||||||
flex: 1,
|
|
||||||
justifyContent: "center",
|
|
||||||
paddingRight: 200,
|
|
||||||
}}
|
|
||||||
refreshControl={
|
|
||||||
<RefreshControl
|
|
||||||
colors={[
|
|
||||||
colorMap.pink,
|
|
||||||
colorMap.green,
|
|
||||||
colorMap.orange,
|
|
||||||
colorMap.purple,
|
|
||||||
colorMap.teal,
|
|
||||||
]}
|
|
||||||
tintColor={colorMap.pink}
|
|
||||||
progressBackgroundColor={"white"}
|
|
||||||
refreshing={isSyncing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
left: "50%", // Position at screen center
|
|
||||||
transform: [
|
|
||||||
// Offset by half its own width
|
|
||||||
{ translateX: -20 }, // Assuming the refresh control is ~40px wide
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
bounces={true}
|
|
||||||
showsVerticalScrollIndicator={false}
|
|
||||||
pointerEvents={isSyncing ? "auto" : "none"}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
if (isTablet) {
|
||||||
|
return (
|
||||||
|
<View style={{flex: 1}}>
|
||||||
|
<View style={{flex: 1, zIndex: 0}}>
|
||||||
|
<TabletCalendarPage/>
|
||||||
|
</View>
|
||||||
|
<ScrollView
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: "15%",
|
||||||
|
height: "9%",
|
||||||
|
width: "62%",
|
||||||
|
zIndex: 50,
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
}}
|
||||||
|
contentContainerStyle={{
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingRight: 200,
|
||||||
|
}}
|
||||||
|
refreshControl={refreshControl}
|
||||||
|
bounces={true}
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
pointerEvents={isSyncing ? "auto" : "none"}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView
|
||||||
|
style={{flex: 1, height: "100%"}}
|
||||||
|
contentContainerStyle={{flex: 1, height: "100%"}}
|
||||||
|
refreshControl={refreshControl}
|
||||||
|
bounces={true}
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
>
|
||||||
|
<View style={{flex: 1}}>
|
||||||
|
<CalendarPage/>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import React, {memo} from "react";
|
import React, {memo} from "react";
|
||||||
import {Button, Picker, PickerModes, SegmentedControl, Text, View,} from "react-native-ui-lib";
|
import {Button, Picker, PickerModes, SegmentedControl, Text, View} from "react-native-ui-lib";
|
||||||
import {MaterialIcons} from "@expo/vector-icons";
|
import {MaterialIcons} from "@expo/vector-icons";
|
||||||
import {months} from "./constants";
|
import {months} from "./constants";
|
||||||
import {StyleSheet} from "react-native";
|
import {StyleSheet} from "react-native";
|
||||||
@ -8,6 +8,7 @@ import {modeAtom, selectedDateAtom} from "@/components/pages/calendar/atoms";
|
|||||||
import {format, isSameDay} from "date-fns";
|
import {format, isSameDay} from "date-fns";
|
||||||
import * as Device from "expo-device";
|
import * as Device from "expo-device";
|
||||||
import {Mode} from "react-native-big-calendar";
|
import {Mode} from "react-native-big-calendar";
|
||||||
|
import { FontAwesome5 } from '@expo/vector-icons';
|
||||||
|
|
||||||
export const CalendarHeader = memo(() => {
|
export const CalendarHeader = memo(() => {
|
||||||
const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
|
const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
|
||||||
@ -15,8 +16,8 @@ export const CalendarHeader = memo(() => {
|
|||||||
const isTablet = Device.deviceType === Device.DeviceType.TABLET;
|
const isTablet = Device.deviceType === Device.DeviceType.TABLET;
|
||||||
|
|
||||||
const segments = isTablet
|
const segments = isTablet
|
||||||
? [{label: "D"}, {label: "W"}, {label: "M"}] // Tablet segments
|
? [{label: "D"}, {label: "W"}, {label: "M"}]
|
||||||
: [{label: "D"}, {label: "3D"}, {label: "M"}]; // Phone segments
|
: [{label: "D"}, {label: "3D"}, {label: "M"}];
|
||||||
|
|
||||||
const handleSegmentChange = (index: number) => {
|
const handleSegmentChange = (index: number) => {
|
||||||
let selectedMode: Mode;
|
let selectedMode: Mode;
|
||||||
@ -46,28 +47,18 @@ export const CalendarHeader = memo(() => {
|
|||||||
|
|
||||||
const getInitialIndex = () => {
|
const getInitialIndex = () => {
|
||||||
if (isTablet) {
|
if (isTablet) {
|
||||||
// Tablet index mapping
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "day":
|
case "day": return 0;
|
||||||
return 0;
|
case "week": return 1;
|
||||||
case "week":
|
case "month": return 2;
|
||||||
return 1;
|
default: return 1;
|
||||||
case "month":
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
return 1; // Default to week view for tablets
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Phone index mapping
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "day":
|
case "day": return 0;
|
||||||
return 0;
|
case "3days": return 1;
|
||||||
case "3days":
|
case "month": return 2;
|
||||||
return 1;
|
default: return 1;
|
||||||
case "month":
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
return 1; // Default to 3day view for phones
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -110,31 +101,16 @@ export const CalendarHeader = memo(() => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View row centerV>
|
<View row centerV>
|
||||||
{!isSelectedDateToday && (
|
<Button
|
||||||
<Button
|
size={"xSmall"}
|
||||||
size={"xSmall"}
|
marginR-1
|
||||||
marginR-0
|
avoidInnerPadding
|
||||||
avoidInnerPadding
|
style={styles.todayButton}
|
||||||
style={{
|
onPress={() => setSelectedDate(new Date())}
|
||||||
borderRadius: 50,
|
>
|
||||||
backgroundColor: "white",
|
<MaterialIcons name="calendar-today" size={30} color="#5f6368" />
|
||||||
borderWidth: 0.7,
|
<Text style={styles.todayDate}>{format(new Date(), "d")}</Text>
|
||||||
borderColor: "#dadce0",
|
</Button>
|
||||||
height: 30,
|
|
||||||
paddingHorizontal: 10,
|
|
||||||
}}
|
|
||||||
labelStyle={{
|
|
||||||
fontSize: 12,
|
|
||||||
color: "black",
|
|
||||||
fontFamily: "Manrope_500Medium",
|
|
||||||
}}
|
|
||||||
label={format(new Date(), "dd/MM/yyyy")}
|
|
||||||
onPress={() => {
|
|
||||||
setSelectedDate(new Date());
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<View>
|
<View>
|
||||||
<SegmentedControl
|
<SegmentedControl
|
||||||
segments={segments}
|
segments={segments}
|
||||||
@ -159,4 +135,19 @@ const styles = StyleSheet.create({
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontFamily: "Manrope_600SemiBold",
|
fontFamily: "Manrope_600SemiBold",
|
||||||
},
|
},
|
||||||
|
todayButton: {
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
borderWidth: 0,
|
||||||
|
height: 30,
|
||||||
|
width: 30,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
todayDate: {
|
||||||
|
position: 'absolute',
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: "Manrope_600SemiBold",
|
||||||
|
color: "#5f6368",
|
||||||
|
top: '30%',
|
||||||
|
},
|
||||||
});
|
});
|
@ -145,15 +145,10 @@ export const ManuallyAddEventModal = () => {
|
|||||||
setIsPrivate(editEvent?.private || false);
|
setIsPrivate(editEvent?.private || false);
|
||||||
|
|
||||||
setStartTime(() => {
|
setStartTime(() => {
|
||||||
const date = new Date(initialDate ?? new Date());
|
const date = initialDate ?? new Date();
|
||||||
const minutes = date.getMinutes();
|
date.setSeconds(0, 0);
|
||||||
date.setMinutes(0, 0, 0);
|
|
||||||
if (minutes >= 30) {
|
|
||||||
date.setHours(date.getHours() + 1);
|
|
||||||
}
|
|
||||||
return date;
|
return date;
|
||||||
});
|
});
|
||||||
|
|
||||||
setEndTime(() => {
|
setEndTime(() => {
|
||||||
if (editEvent?.end) {
|
if (editEvent?.end) {
|
||||||
return startOfMinute(new Date(editEvent.end));
|
return startOfMinute(new Date(editEvent.end));
|
||||||
|
5
eas.json
5
eas.json
@ -11,7 +11,10 @@
|
|||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"distribution": "internal",
|
"distribution": "internal",
|
||||||
"channel": "preview"
|
"channel": "production",
|
||||||
|
"android": {
|
||||||
|
"buildType": "apk"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"channel": "production",
|
"channel": "production",
|
||||||
|
@ -1212,6 +1212,7 @@ async function fetchAndSaveGoogleEvents({token, refreshToken, email, familyId, c
|
|||||||
email,
|
email,
|
||||||
creatorId,
|
creatorId,
|
||||||
externalOrigin: "google",
|
externalOrigin: "google",
|
||||||
|
private: item.visibility === "private" || item.visibility === "confidential",
|
||||||
};
|
};
|
||||||
events.push(googleEvent);
|
events.push(googleEvent);
|
||||||
});
|
});
|
||||||
@ -1399,7 +1400,7 @@ async function fetchAndSaveMicrosoftEvents({token, refreshToken, email, familyId
|
|||||||
|
|
||||||
const url = `https://graph.microsoft.com/v1.0/me/calendar/events`;
|
const url = `https://graph.microsoft.com/v1.0/me/calendar/events`;
|
||||||
const queryParams = new URLSearchParams({
|
const queryParams = new URLSearchParams({
|
||||||
$select: 'subject,start,end,id,isAllDay',
|
$select: 'subject,start,end,id,isAllDay,sensitivity',
|
||||||
$filter: `start/dateTime ge '${timeMin}' and end/dateTime le '${timeMax}'`
|
$filter: `start/dateTime ge '${timeMin}' and end/dateTime le '${timeMax}'`
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1450,7 +1451,8 @@ async function fetchAndSaveMicrosoftEvents({token, refreshToken, email, familyId
|
|||||||
familyId,
|
familyId,
|
||||||
email,
|
email,
|
||||||
creatorId,
|
creatorId,
|
||||||
externalOrigin: "microsoft"
|
externalOrigin: "microsoft",
|
||||||
|
private: item.sensitivity === "private" || item.sensitivity === "confidential",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,8 +9,10 @@
|
|||||||
"ios": "TAMAGUI_TARGET=native npx expo run:ios",
|
"ios": "TAMAGUI_TARGET=native npx expo run:ios",
|
||||||
"ios-native": "TAMAGUI_TARGET=native npx expo run:ios --device",
|
"ios-native": "TAMAGUI_TARGET=native npx expo run:ios --device",
|
||||||
"dev-ios": "TAMAGUI_TARGET=native npx eas-cli build --profile development --platform ios",
|
"dev-ios": "TAMAGUI_TARGET=native npx eas-cli build --profile development --platform ios",
|
||||||
|
"dev-android": "TAMAGUI_TARGET=native npx eas-cli build --profile development --platform android",
|
||||||
"build-ios": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform ios",
|
"build-ios": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform ios",
|
||||||
"build-android": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform android",
|
"build-android": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform android",
|
||||||
|
"build-apk": "TAMAGUI_TARGET=native eas build -p android --profile preview",
|
||||||
"build-cicd": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform all --non-interactive --no-wait --auto-submit ",
|
"build-cicd": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform all --non-interactive --no-wait --auto-submit ",
|
||||||
"build-ios-cicd": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform ios --non-interactive --no-wait --auto-submit ",
|
"build-ios-cicd": "TAMAGUI_TARGET=native npx eas-cli build --profile production --platform ios --non-interactive --no-wait --auto-submit ",
|
||||||
"build-dev-ios": "TAMAGUI_TARGET=native npx eas-cli build --profile development --platform ios",
|
"build-dev-ios": "TAMAGUI_TARGET=native npx eas-cli build --profile development --platform ios",
|
||||||
|
Reference in New Issue
Block a user