/** * @file Setting page */ import { IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonItemDivider, IonItemGroup, IonLabel, IonList, IonMenuButton, IonModal, IonNote, IonPage, IonSelect, IonSelectOption, IonTitle, IonToggle, IonToolbar, isPlatform, useIonActionSheet, } from "@ionic/react"; import { downloadOutline, downloadSharp, ellipsisVertical, logOutOutline, logOutSharp, menuSharp, refreshOutline, refreshSharp, warningOutline, warningSharp, } from "ionicons/icons"; import {FC, useEffect, useRef, useState} from "react"; import {useHistory} from "react-router-dom"; import AddToHomeScreen from "~/assets/icons/md-add-to-home-screen.svg?react"; import PlusApp from "~/assets/icons/sf-symbols-plus.app.svg?react"; import SquareAndArrowUp from "~/assets/icons/sf-symbols-square.and.arrow.up.svg?react"; import {useEphemeralStore} from "~/lib/stores/ephemeral"; import {usePersistentStore} from "~/lib/stores/persistent"; import {client} from "~/lib/supabase"; import {GlobalMessageMetadata, MeasurementSystem, Theme} from "~/lib/types"; import {GIT_BRANCH, GIT_COMMIT, VERSION} from "~/lib/vars"; import styles from "~/pages/settings.module.css"; /** * Account deleted message metadata */ const ACCOUNT_DELETED_MESSAGE_METADATA: GlobalMessageMetadata = { symbol: Symbol("settings.account-deleted"), name: "Account Deleted", description: "Your account has been successfully deleted", }; /** * Settings page * @returns JSX */ export const Settings: FC = () => { // Hooks const [beforeInstallPromptEvent, setBeforeInstallPromptEvent] = useState(); const [appInstalled, setAppInstalled] = useState( window.matchMedia("(display-mode: standalone)").matches, ); const appInstallInstructionsModal = useRef(null); const setMessage = useEphemeralStore(state => state.setMessage); const theme = usePersistentStore(state => state.theme); const setTheme = usePersistentStore(state => state.setTheme); const showFABs = usePersistentStore(state => state.showFABs); const setShowFABs = usePersistentStore(state => state.setShowFABs); const slidingActions = usePersistentStore(state => state.useSlidingActions); const setSlidingActions = usePersistentStore( state => state.setUseSlidingActions, ); const showAmbientEffect = usePersistentStore( state => state.showAmbientEffect, ); const setShowAmbientEffect = usePersistentStore( state => state.setShowAmbientEffect, ); const measurementSystem = usePersistentStore( state => state.measurementSystem, ); const setMeasurementSystem = usePersistentStore( state => state.setMeasurementSystem, ); const reset = usePersistentStore(state => state.reset); const history = useHistory(); const [present] = useIonActionSheet(); // Methods /** * Begin the app installation process */ const installApp = async () => { await (beforeInstallPromptEvent === undefined ? appInstallInstructionsModal.current?.present() : beforeInstallPromptEvent.prompt()); }; /** * Reset all settings * @returns Promise */ const resetSettings = () => present({ header: "Reset all settings", subHeader: "Are you sure you want to reset all settings? You will be signed out.", buttons: [ { text: "Cancel", role: "cancel", }, { text: "Reset", role: "destructive", handler: reset, }, ], }); /** * Sign out * @returns Promise */ const signOut = () => present({ header: "Sign out", subHeader: "Are you sure you want to sign out?", buttons: [ { text: "Cancel", role: "cancel", }, { text: "Sign out", role: "destructive", /** * Sign out handler */ handler: async () => { // Sign out await client.auth.signOut(); // Redirect to the home history.push("/"); }, }, ], }); /** * Delete account * @returns Promise */ const deleteAccount = () => present({ header: "Delete Your Account", subHeader: "Are you sure you want to delete your account? This action cannot be undone.", buttons: [ { text: "Cancel", role: "cancel", }, { text: "Delete My Account", role: "destructive", /** * Delete account handler */ handler: async () => { // Delete the account const {error} = await client.rpc("delete_account"); // Handle error if (error) { return; } // Sign out await client.auth.signOut(); // Redirect to the home history.push("/"); // Display the message setMessage(ACCOUNT_DELETED_MESSAGE_METADATA); }, }, ], }); // Effects useEffect(() => { // Capture the installed event window.addEventListener("appinstalled", () => setAppInstalled(true)); // Capture the installable event window.addEventListener( "beforeinstallprompt", event => { event.preventDefault(); setBeforeInstallPromptEvent(event as BeforeInstallPromptEvent); }, { once: true, }, ); }, []); return ( Settings

App Install Instructions

This website is a Progresive Web App (PWA), meaning it has app functionality. You can install it on your device by following the below instructions:

    {(() => { if (isPlatform("ios")) { return ( <>
  1. Press the share button on the menu bar below.
  2. Select Add to Home Screen.
  3. ); } else if (isPlatform("android")) { return ( <>
  4. Press the three dots on the menu bar above.
  5. Select Add to Home screen.
  6. ); } else { return ( <>
  7. Open your browser's menu.
  8. Select Add to Home Screen, Install Beacon, or similar option.
  9. ); } })()}
Look and Feel setTheme(event.detail.value)} value={theme} > Light Dark setShowFABs(event.detail.checked)} > Show floating action buttons setSlidingActions(event.detail.checked)} > Use sliding actions on posts setShowAmbientEffect(event.detail.checked) } > Show ambient effect below posts setMeasurementSystem(event.detail.value)} value={measurementSystem} > Metric Imperial Miscellaneous Install app {appInstalled ? "(Already Installed)" : ""} Reset all settings Account Sign out Delete Account About Version {VERSION} Branch {GIT_BRANCH} Commit {GIT_COMMIT} Links Frequently Asked Questions Terms and Conditions Privacy Policy Source code Bug report/feature request
); };