From 82106ddd5cf3d4c4f5e72f856021e2a34050d793 Mon Sep 17 00:00:00 2001 From: Dark-Louis Date: Mon, 8 Sep 2025 22:23:43 +0200 Subject: [PATCH 1/4] Fixed web start crashing - Re-added a library that was necessary but was removed in the previous commit - Fixed native features (such as haptics) that were crashing the web app --- package-lock.json | 21 +++++++++++++++++++++ package.json | 1 + src/App.tsx | 13 ++++++++++--- src/utils/haptics.ts | 7 +++++++ src/utils/hooks/useHaptics.ts | 9 +++++---- src/utils/native.ts | 2 ++ src/utils/statusBar.ts | 7 +++++++ 7 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 src/utils/haptics.ts create mode 100644 src/utils/native.ts create mode 100644 src/utils/statusBar.ts diff --git a/package-lock.json b/package-lock.json index 1d85f49..a0af2ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,6 +57,7 @@ "workbox-strategies": "^5.1.4" }, "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@capacitor/cli": "^6.0.0", "@types/isomorphic-fetch": "^0.0.36", "babel-plugin-tsconfig-paths": "^1.0.3" @@ -631,6 +632,26 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", diff --git a/package.json b/package.json index e0fe3b3..732882f 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ ] }, "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@capacitor/cli": "^6.0.0", "@types/isomorphic-fetch": "^0.0.36", "babel-plugin-tsconfig-paths": "^1.0.3" diff --git a/src/App.tsx b/src/App.tsx index 91a23d5..b6f8a4f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,7 +18,9 @@ import "./theme/globals.scss"; import Login from "./pages/Auth/Login"; -import { StatusBar, Style } from "@capacitor/status-bar"; +import { Style } from "@capacitor/status-bar"; +import { setStatusBar } from "./utils/statusBar"; +import { isNative } from "./utils/native"; import { useDarkMode } from "usehooks-ts"; import { ModalContextProvider } from "./contexts/modalContext"; import { ToastContextProvider } from "./contexts/toastContext"; @@ -37,8 +39,13 @@ dayjs.locale("fr"); dayjs.extend(relativeTime); setupIonicReact(); -StatusBar.setStyle({ style: Style.Dark }); -StatusBar.setBackgroundColor({ color: "#3f2a56" }); +setStatusBar(Style.Dark); +if (isNative) { + (async () => { + const { StatusBar } = await import("@capacitor/status-bar"); + try { await StatusBar.setBackgroundColor({ color: "#3f2a56" }); } catch {} + })(); +} // Locks screen orientation to portrait // window.screen.orientation.lock('portrait'); diff --git a/src/utils/haptics.ts b/src/utils/haptics.ts new file mode 100644 index 0000000..d58b14c --- /dev/null +++ b/src/utils/haptics.ts @@ -0,0 +1,7 @@ +import { Haptics, ImpactStyle } from "@capacitor/haptics"; +import { isNative } from "./native"; + +export async function hapticImpact(style: ImpactStyle = ImpactStyle.Medium) { + if (!isNative) return; + try { await Haptics.impact({ style }); } catch {} +} diff --git a/src/utils/hooks/useHaptics.ts b/src/utils/hooks/useHaptics.ts index ccbce1d..fc1a641 100644 --- a/src/utils/hooks/useHaptics.ts +++ b/src/utils/hooks/useHaptics.ts @@ -1,5 +1,6 @@ import { useLocalStorage } from "usehooks-ts"; -import { Haptics, ImpactStyle } from "@capacitor/haptics"; +import { ImpactStyle } from "@capacitor/haptics"; +import { hapticImpact } from "../haptics"; export const useHaptics = () => { const [haptics, setHaptics] = useLocalStorage("useHaptics", true); @@ -17,15 +18,15 @@ export const useHaptics = () => { }; const hapticsImpactHeavy = async () => { - haptics && (await Haptics.impact({ style: ImpactStyle.Heavy })); + haptics && (await hapticImpact(ImpactStyle.Heavy)); }; const hapticsImpactMedium = async () => { - haptics && (await Haptics.impact({ style: ImpactStyle.Medium })); + haptics && (await hapticImpact(ImpactStyle.Medium)); }; const hapticsImpactLight = async () => { - haptics && (await Haptics.impact({ style: ImpactStyle.Light })); + haptics && (await hapticImpact(ImpactStyle.Light)); }; return { diff --git a/src/utils/native.ts b/src/utils/native.ts new file mode 100644 index 0000000..fa504f6 --- /dev/null +++ b/src/utils/native.ts @@ -0,0 +1,2 @@ +import { Capacitor } from "@capacitor/core"; +export const isNative = Capacitor.isNativePlatform(); diff --git a/src/utils/statusBar.ts b/src/utils/statusBar.ts new file mode 100644 index 0000000..f6bc69c --- /dev/null +++ b/src/utils/statusBar.ts @@ -0,0 +1,7 @@ +import { Style, StatusBar } from "@capacitor/status-bar"; +import { isNative } from "./native"; + +export async function setStatusBar(style: Style) { + if (!isNative) return; + try { await StatusBar.setStyle({ style }); } catch {} +} From 62776158455b5a952b8fd13798e876ce7d8920c4 Mon Sep 17 00:00:00 2001 From: Dark-Louis Date: Wed, 10 Sep 2025 10:21:06 +0200 Subject: [PATCH 2/4] Fixed web start crashing v2 - Fixed another native feature (AppUpdate) that was crashing the web app --- src/pages/Home/index.tsx | 7 +++---- src/utils/appUpdate.ts | 11 +++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 src/utils/appUpdate.ts diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index 50b04d2..57b3ebf 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -29,9 +29,8 @@ import PageTemplate from "../Template"; import styles from "./Home.module.scss"; import clsx from "clsx"; import EventJunia from "../../components/Pages/Home/Events"; -import { Capacitor } from "@capacitor/core"; import { LocalNotifications } from "@capacitor/local-notifications"; -import { AppUpdate } from "@capawesome/capacitor-app-update"; +import { getAppUpdateInfoSafe } from "../../utils/appUpdate"; import { MauriaNoteType } from "../../types/note"; @@ -81,8 +80,8 @@ const intervalFetch = async () => { setTimeout(intervalFetch, 14400000); // setTimeout(intervalFetch, 30000); - if (Capacitor) { - const available = await AppUpdate.getAppUpdateInfo(); + const available = await getAppUpdateInfoSafe(); + if (available) { console.log(available); } } diff --git a/src/utils/appUpdate.ts b/src/utils/appUpdate.ts new file mode 100644 index 0000000..81ecae9 --- /dev/null +++ b/src/utils/appUpdate.ts @@ -0,0 +1,11 @@ +import { isNative } from "./native"; + +export async function getAppUpdateInfoSafe() { + if (!isNative) return null; + try { + const { AppUpdate } = await import("@capawesome/capacitor-app-update"); + return await AppUpdate.getAppUpdateInfo(); + } catch { + return null; + } +} From 6f71daaec3ce2540caae82f273d4330a468abdc0 Mon Sep 17 00:00:00 2001 From: Dark-Louis Date: Sat, 13 Sep 2025 20:16:33 +0200 Subject: [PATCH 3/4] New modal - Added the new update modal (for now, it always shows and doesn't check for the update version) - Added an update formatter function - Added an exception to .gitattributes for linux development --- .gitignore | 5 +- src/pages/Home/UpdateModalContent/index.tsx | 87 +++++++++++++++++++++ src/pages/Home/index.tsx | 3 + src/utils/updates.ts | 13 +++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/pages/Home/UpdateModalContent/index.tsx create mode 100644 src/utils/updates.ts diff --git a/.gitignore b/.gitignore index c51b484..7ad12f2 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,7 @@ yarn-error.log* # Config resources/android/**/* -resources/ios/**/* \ No newline at end of file +resources/ios/**/* + +# Linux +.gitattributes diff --git a/src/pages/Home/UpdateModalContent/index.tsx b/src/pages/Home/UpdateModalContent/index.tsx new file mode 100644 index 0000000..e2cfed4 --- /dev/null +++ b/src/pages/Home/UpdateModalContent/index.tsx @@ -0,0 +1,87 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import styles from "../../../components/common/Layout/Modal/modal.module.scss"; +import Button from "../../../components/common/Layout/Button/Button"; +import { ModalContext, ModalContextType } from "../../../contexts/modalContext"; +import { fetchUpdates } from "../../../utils/api/api"; +import { formatUpdatesContent } from "../../../utils/updates"; +import { MauriaUpdateLogType } from "../../../types/updateLog"; + +const UpdateModalContent = () => { + const { closeModal } = useContext(ModalContext) as ModalContextType; + + const { data: updates, isLoading } = useQuery({ + queryKey: ["updates-modal"], + queryFn: fetchUpdates, + }); + + if (isLoading) { + return ( + <> +
+

+ Y'a du nouveau sur Mauria ! +

+
+

Chargement des infos de la mise à jour...

+ + + ); + } + + if (updates === undefined || updates.length === 0) { + return ( + <> +
+

+ Y'a du nouveau sur Mauria ! +

+
+

Aucune information de mise à jour disponible.

+ + + ); + } + + return ( + <> +
+

+ Y'a du nouveau sur Mauria ! +

+
+

+ + Date de la mise à jour : + {updates[0].date} +
+
+ + {updates[0].titleVisu} + +
+

+ {formatUpdatesContent(updates[0].contentVisu)} +

+
+
+ + {updates[0].titleDev} + +
+

+ {formatUpdatesContent(updates[0].contentDev)} +

+

+ + + ); +}; + +export default UpdateModalContent; diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index 57b3ebf..5952b76 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -24,6 +24,7 @@ import { useMutation, useQueries, useQueryClient } from "@tanstack/react-query"; import { ToastContext, ToastContextType } from "../../contexts/toastContext"; import { ModalContext, ModalContextType } from "../../contexts/modalContext"; import WelcomeModalContent from "./WelcomeModalContent"; +import UpdateModalContent from "./UpdateModalContent"; import PageTemplate from "../Template"; import styles from "./Home.module.scss"; @@ -178,6 +179,8 @@ const Home: React.FC = () => { openModal(, () => setIsFirstLaunch(false)); } + openModal(); + const interval = setInterval(() => { updateMutation.mutate(); }, 10000); diff --git a/src/utils/updates.ts b/src/utils/updates.ts new file mode 100644 index 0000000..f92d863 --- /dev/null +++ b/src/utils/updates.ts @@ -0,0 +1,13 @@ +const formatUpdatesContent = (content: string): string => { + if (!content) return ""; + + return content + .replace(/^-+\s*/, "") + .split(" - ") + .map(line => line.trim()) + .filter(line => line.length > 0) + .map(line => `- ${line}`) + .join("\n"); +}; + +export { formatUpdatesContent }; From 8f115e4cbfda5557f693c448e007c7b6d6a43438 Mon Sep 17 00:00:00 2001 From: Dark-Louis Date: Sat, 13 Sep 2025 21:21:51 +0200 Subject: [PATCH 4/4] Last update storage - Checks and updates lastSeenVersion in localStorage before displaying the update modal --- src/pages/Home/index.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index 5952b76..e5f9529 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -6,6 +6,7 @@ import { fetchImportantMessage, fetchNotes, fetchPlanning, + fetchUpdates, getFirstName, } from "../../utils/api/api"; @@ -179,7 +180,22 @@ const Home: React.FC = () => { openModal(, () => setIsFirstLaunch(false)); } - openModal(); + (async () => { + try { + const updates = await fetchUpdates(); + const currentUpdateVersion = updates?.[0]?.version; + if (!currentUpdateVersion) return; + + const lastSeenVersion = localStorage.getItem("lastSeenVersion"); + + if (lastSeenVersion !== currentUpdateVersion) { + openModal(); + localStorage.setItem("lastSeenVersion", currentUpdateVersion); + } + } catch { + console.log("Update modal error") + } + })(); const interval = setInterval(() => { updateMutation.mutate();