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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions src/components/Global/PapillonPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { NativeText } from "./NativeComponents";
import { BlurView } from "expo-blur";
import { Check } from "lucide-react-native";

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

interface PapillonPickerProps {
children: React.ReactNode
Expand Down Expand Up @@ -91,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 @@ -136,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
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',
Skythrew marked this conversation as resolved.
Show resolved Hide resolved
freqLabel: frequency.label,
num: frequency.fortnight
}
Skythrew marked this conversation as resolved.
Show resolved Hide resolved
}
Skythrew marked this conversation as resolved.
Show resolved Hide resolved
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
}
Skythrew marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 18 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,20 @@ 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);

Skythrew marked this conversation as resolved.
Show resolved Hide resolved
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 && (
Skythrew marked this conversation as resolved.
Show resolved Hide resolved
<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