Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Affichage du "numéro de semaine" dans l'EDT #545

Merged
merged 11 commits into from
Jan 21, 2025
15 changes: 6 additions & 9 deletions src/components/Global/PapillonPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ import { NativeText } from "./NativeComponents";
import { BlurView } from "expo-blur";
import { Check } from "lucide-react-native";

export type PickerDataItem = { index?: number, label: string, icon?: JSX.Element, onPress?: () => unknown };
export type PickerData = string[] | PickerDataItem[];
type PickerData = string[] | { label: string, icon?: JSX.Element, onPress: () => unknown, checked?: boolean }[];

interface PapillonPickerProps {
children: React.ReactNode
data: PickerData
selected?: string | PickerDataItem
selected?: string
contentContainerStyle?: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>
delay?: number,
direction?: "left" | "right",
animated?: boolean,
onSelectionChange?: any
onSelectionChange?: (item: string) => unknown
}

const PapillonPicker: React.FC<PapillonPickerProps> = ({
Expand Down Expand Up @@ -70,10 +69,8 @@ const PapillonPicker: React.FC<PapillonPickerProps> = ({
styles.picker,
direction === "left" ? {
left: 0,
transformOrigin: "top left",
} : {
right: 0,
transformOrigin: "top right",
},
{
backgroundColor: Platform.OS === "ios" ? theme.colors.card + 50 : theme.colors.card,
Expand All @@ -94,7 +91,7 @@ const PapillonPicker: React.FC<PapillonPickerProps> = ({
}}
tint={theme.dark ? "dark" : "light"}
>
{data.map((item, index) => {
{data.filter((item) => item !== null).map((item, index) => {
// check if item is a string or a component
const isNotString = typeof item !== "string";

Expand Down Expand Up @@ -139,7 +136,7 @@ const PapillonPicker: React.FC<PapillonPickerProps> = ({

<View style={{ flex: 1 }} />

{item === selected && (
{item === selected || (isNotString && item.checked) && (
<Check
size={20}
strokeWidth={2.5}
Expand Down Expand Up @@ -207,4 +204,4 @@ const styles = StyleSheet.create({
},
});

export default PapillonPicker;
export default PapillonPicker;
23 changes: 22 additions & 1 deletion src/services/pronote/timetable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PronoteAccount } from "@/stores/account/types";
import { TimetableClassStatus, type Timetable, type TimetableClass } from "../shared/Timetable";
import { TimetableClassStatus, WeekFrequency, type Timetable, type TimetableClass } from "../shared/Timetable";
import { ErrorServiceUnauthenticated } from "../shared/errors";
import pronote from "pawnote";
import { info } from "@/utils/logger/logger";
Expand Down Expand Up @@ -108,3 +108,24 @@ const category_match = {
9: "Accompagnement personnalisé",
12: "Visioconférence",
};

export const getWeekFrequency = (account: PronoteAccount, weekNumber: number): WeekFrequency | null => {
if (!account.instance)
throw new ErrorServiceUnauthenticated("pronote");

if (weekNumber < 1 || weekNumber > 62) {
info("PRONOTE->getTimetableForWeek(): Le numéro de semaine est en dehors des bornes (1<>62), null est retourné.", "pronote");
return null;
}

const frequency = pronote.frequency(account.instance, weekNumber);

if (!frequency)
return null;

return {
textLabel: "Semaine",
freqLabel: frequency.label,
num: frequency.fortnight
};
};
6 changes: 6 additions & 0 deletions src/services/shared/Timetable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ export enum TimetableClassStatus {
ONLINE = "En ligne",
TEST = "ds",
}

export interface WeekFrequency {
textLabel: string,
freqLabel: string,
num: number
}
17 changes: 17 additions & 0 deletions src/services/timetable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { epochWNToPronoteWN, weekNumberToDateRange } from "@/utils/epochWeekNumb
import { checkIfSkoSupported } from "./skolengo/default-personalization";
import { error } from "@/utils/logger/logger";
import { fetchIcalData } from "./local/ical";
import { WeekFrequency } from "./shared/Timetable";

/**
* Updates the state and cache for the timetable of given week number.
Expand Down Expand Up @@ -53,3 +54,19 @@ export async function updateTimetableForWeekInCache <T extends Account> (account
// Fetch iCal data
await fetchIcalData(account, force);
}

/**
* Gets the week "frequency" object for the given week number.
*
* @example "Q1"/"Q2", "S1"/"S2"
*/
export async function getWeekFrequency <T extends Account> (account: T, epochWeekNumber: number): Promise<WeekFrequency | null> {
switch (account.service) {
case AccountService.Pronote:
const { getWeekFrequency } = await import("./pronote/timetable");
const weekNumber = epochWNToPronoteWN(epochWeekNumber, account);
return getWeekFrequency(account, weekNumber);
default:
return null;
}
}
1 change: 1 addition & 0 deletions src/stores/account/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface Personalization {
hideProfilePicOnHomeScreen: boolean,
hideTabTitles: boolean,
showTabBackground: boolean,
showWeekFrequency: boolean,
transparentTabBar: boolean,
hideTabBar: boolean,
popupRestauration?: boolean,
Expand Down
65 changes: 62 additions & 3 deletions src/views/account/Lessons/Lessons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { StyleSheet } from "react-native";
import type { Screen } from "@/router/helpers/types";
import { useCurrentAccount } from "@/stores/account";
import { useTimetableStore } from "@/stores/timetable";
import { updateTimetableForWeekInCache } from "@/services/timetable";
import { getWeekFrequency, updateTimetableForWeekInCache } from "@/services/timetable";
import { Page } from "./Atoms/Page";
import { LessonsDateModal } from "./LessonsHeader";
import { dateToEpochWeekNumber } from "@/utils/epochWeekNumber";
Expand All @@ -22,7 +22,7 @@ import { animPapillon } from "@/utils/ui/animations";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useTheme } from "@react-navigation/native";
import AnimatedNumber from "@/components/Global/AnimatedNumber";
import { CalendarPlus, MoreVertical } from "lucide-react-native";
import { CalendarPlus, Eye, MoreVertical } from "lucide-react-native";
import {
PapillonHeaderAction,
PapillonHeaderSelector,
Expand All @@ -31,9 +31,12 @@ import {
} from "@/components/Global/PapillonModernHeader";
import PapillonPicker from "@/components/Global/PapillonPicker";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { WeekFrequency } from "@/services/shared/Timetable";

const Lessons: Screen<"Lessons"> = ({ route, navigation }) => {
const account = useCurrentAccount((store) => store.account!);
const mutateProperty = useCurrentAccount((store) => store.mutateProperty);

const timetables = useTimetableStore((store) => store.timetables);

const outsideNav = route.params?.outsideNav;
Expand All @@ -43,6 +46,9 @@ const Lessons: Screen<"Lessons"> = ({ route, navigation }) => {
const loadedWeeks = useRef<Set<number>>(new Set());
const currentlyLoadingWeeks = useRef<Set<number>>(new Set());

const [shouldShowWeekFrequency, setShouldShowWeekFrequency] = useState(account.personalization.showWeekFrequency);
Skythrew marked this conversation as resolved.
Show resolved Hide resolved
const [weekFrequency, setWeekFrequency] = useState<WeekFrequency | null>(null);

useEffect(() => {
// add all week numbers in timetables to loadedWeeks
for (const week in timetables) {
Expand All @@ -66,9 +72,19 @@ const Lessons: Screen<"Lessons"> = ({ route, navigation }) => {
void (async () => {
const weekNumber = getWeekFromDate(pickerDate);
await loadTimetableWeek(weekNumber, false);
setWeekFrequency((await getWeekFrequency(account, weekNumber)));
})();
}, [pickerDate, account.instance]);

useEffect(() => {
void (async () => {
mutateProperty("personalization", {
...account.personalization,
showWeekFrequency: shouldShowWeekFrequency
});
})();
}, [shouldShowWeekFrequency]);

useEffect(() => {
loadTimetableWeek(getWeekFromDate(new Date()), true);
}, [account.personalization.icalURLs]);
Expand Down Expand Up @@ -312,6 +328,41 @@ const Lessons: Screen<"Lessons"> = ({ route, navigation }) => {
>
{pickerDate.toLocaleDateString("fr-FR", { month: "long" })}
</Reanimated.Text>

{weekFrequency && shouldShowWeekFrequency && (
<Reanimated.View
layout={animPapillon(LinearTransition)}
entering={FadeIn.duration(150)}
exiting={FadeOut.duration(150)}
>
<Reanimated.View
style={[
{
borderColor: theme.colors.text,
borderWidth: 1,
paddingHorizontal: 4,
paddingVertical: 3,
borderRadius: 6,
opacity: 0.5,
},
]}
layout={animPapillon(LinearTransition)}
>
<Reanimated.Text
style={[
{
color: theme.colors.text,
fontFamily: "medium",
letterSpacing: 0.5,
},
]}
layout={animPapillon(LinearTransition)}
>
{weekFrequency.freqLabel}
</Reanimated.Text>
</Reanimated.View>
</Reanimated.View>
) }
</PapillonHeaderSelector>

<PapillonHeaderSeparator />
Expand All @@ -327,7 +378,15 @@ const Lessons: Screen<"Lessons"> = ({ route, navigation }) => {
onPress: () => {
navigation.navigate("LessonsImportIcal", {});
}
}
},
...(weekFrequency != null) ? [{
icon: <Eye />,
label: "Afficher type sem.",
onPress: () => {
setShouldShowWeekFrequency(!shouldShowWeekFrequency);
},
checked: shouldShowWeekFrequency,
}] : []
]}
>
<PapillonHeaderAction
Expand Down
Loading