From a138afe7b974755803c085665fe85b7533f24650 Mon Sep 17 00:00:00 2001 From: Law Wai Chun Date: Fri, 27 Dec 2024 17:57:16 -0800 Subject: [PATCH] Update PinDialog --- src/AppWrapper.tsx | 13 +-- src/components/layout/PinDialog.tsx | 42 +++++++--- src/components/route-eta/StopAccordion.tsx | 4 +- src/context/AppContext.tsx | 22 ------ src/context/PinnedEtasContext.tsx | 92 ++++++++++++++++++++++ src/pages/DataImport.tsx | 1 - vite.config.ts | 2 +- 7 files changed, 133 insertions(+), 43 deletions(-) create mode 100644 src/context/PinnedEtasContext.tsx diff --git a/src/AppWrapper.tsx b/src/AppWrapper.tsx index 9fa86a225778..0c10a57a190b 100644 --- a/src/AppWrapper.tsx +++ b/src/AppWrapper.tsx @@ -9,6 +9,7 @@ import { ErrorBoundary } from "react-error-boundary"; import { CollectionContextProvider } from "./CollectionContext"; import { ReactNativeContextProvider } from "./context/ReactNativeContext"; import { EmotionContextProvider } from "./context/EmotionContext"; +import { PinnedEtasContextProvider } from "./context/PinnedEtasContext"; const App = React.lazy(() => import("./App")); const AppWrapper = () => { @@ -30,11 +31,13 @@ const AppWrapper = () => { - - - - - + + + + + + + diff --git a/src/components/layout/PinDialog.tsx b/src/components/layout/PinDialog.tsx index 1bdab9de8d76..f2684f09e939 100644 --- a/src/components/layout/PinDialog.tsx +++ b/src/components/layout/PinDialog.tsx @@ -9,12 +9,13 @@ import { } from "@mui/material"; import { RefObject, useContext, useRef } from "react"; import Draggable from "react-draggable"; -import AppContext from "../../context/AppContext"; import SuccinctTimeReport from "../home/SuccinctTimeReport"; import { + Minimize as MinimizeIcon, Close as CloseIcon, PushPin as PushPinIcon, } from "@mui/icons-material"; +import PinnedEtasContext from "../../context/PinnedEtasContext"; const PinDialogContainer = (props: ContainerProps) => { const nodeRef = useRef(null); @@ -31,7 +32,13 @@ const PinDialogContainer = (props: ContainerProps) => { }; export default function PinDialog() { - const { pinnedEtas, togglePinnedEta } = useContext(AppContext); + const { + pinnedEtas, + isHidden, + togglePinnedEta, + tooglePinnedEtasDialog, + closePinnedEtas, + } = useContext(PinnedEtasContext); if (pinnedEtas.length === 0) { return null; @@ -50,19 +57,30 @@ export default function PinDialog() { bgcolor: (t) => t.palette.background.default, }} > - + + + + + + + + + + + - {pinnedEtas.map((eta) => ( - - - - togglePinnedEta(eta)}> - - + {!isHidden && + pinnedEtas.map((eta) => ( + + + + togglePinnedEta(eta)}> + + + - - ))} + ))} ); diff --git a/src/components/route-eta/StopAccordion.tsx b/src/components/route-eta/StopAccordion.tsx index cf3bf2b66571..531416f33626 100644 --- a/src/components/route-eta/StopAccordion.tsx +++ b/src/components/route-eta/StopAccordion.tsx @@ -27,7 +27,7 @@ import ReactNativeContext from "../../context/ReactNativeContext"; import useLanguage from "../../hooks/useTranslation"; import DbContext from "../../context/DbContext"; import CollectionContext from "../../CollectionContext"; -import AppContext from "../../context/AppContext"; +import PinnedEtasContext from "../../context/PinnedEtasContext"; interface StopAccordionProps { routeId: string; @@ -57,7 +57,7 @@ const StopAccordion = React.forwardRef( useContext(CollectionContext); const { alarmStopId, toggleStopAlarm } = useContext(ReactNativeContext); const { isStopAlarm } = useContext(ReactNativeContext); - const { pinnedEtas, togglePinnedEta } = useContext(AppContext); + const { pinnedEtas, togglePinnedEta } = useContext(PinnedEtasContext); const { t } = useTranslation(); const language = useLanguage(); const { fares, faresHoliday } = routeList[routeId]; diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx index 1641154fbf4e..19627da73a5d 100644 --- a/src/context/AppContext.tsx +++ b/src/context/AppContext.tsx @@ -43,10 +43,6 @@ export interface AppState { * route search history */ routeSearchHistory: string[]; - /** - * ETAs for PinDialog - */ - pinnedEtas: string[]; /** * filter routes by route schedule against time */ @@ -132,7 +128,6 @@ interface AppContextValue extends AppState { toggleEnergyMode: () => void; togglePlatformMode: () => void; toggleVibrateDuration: () => void; - togglePinnedEta: (eta: string) => void; toggleAnalytics: () => void; // not updateRefreshInterval: (interval: number) => void; toggleAnnotateScheduled: () => void; @@ -227,7 +222,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps) => { compassPermission: isCompassPermission(compassPermission) ? compassPermission : "default", - pinnedEtas: [], isRouteFilter: !!JSON.parse( localStorage.getItem("isRouteFilter") ?? "false" ), @@ -506,20 +500,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps) => { ); }, []); - const togglePinnedEta = useCallback((eta: string) => { - setStateRaw( - produce((state: State) => { - if (state.pinnedEtas.includes(eta)) { - state.pinnedEtas = state.pinnedEtas.filter( - (pinnedEta) => eta !== pinnedEta - ); - } else { - state.pinnedEtas = [...state.pinnedEtas, eta]; - } - }) - ); - }, []); - const updateSearchRouteByButton = useCallback( (buttonValue: string) => { vibrate(state.vibrateDuration); @@ -784,7 +764,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps) => { toggleEnergyMode, togglePlatformMode, toggleVibrateDuration, - togglePinnedEta, toggleAnalytics, updateRefreshInterval, toggleAnnotateScheduled, @@ -816,7 +795,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps) => { toggleEnergyMode, togglePlatformMode, toggleVibrateDuration, - togglePinnedEta, toggleAnalytics, updateRefreshInterval, toggleAnnotateScheduled, diff --git a/src/context/PinnedEtasContext.tsx b/src/context/PinnedEtasContext.tsx new file mode 100644 index 000000000000..3337b187e0c9 --- /dev/null +++ b/src/context/PinnedEtasContext.tsx @@ -0,0 +1,92 @@ +import React, { useState, useCallback, useMemo } from "react"; +import type { ReactNode } from "react"; +import { produce } from "immer"; + +export interface PinnedEtasState { + /** + * ETAs for PinDialog + */ + pinnedEtas: string[]; + /** + * boolean hide + */ + isHidden: boolean; +} + +interface PinnedEtasContextValue extends PinnedEtasState { + togglePinnedEta: (eta: string) => void; + tooglePinnedEtasDialog: () => void; + closePinnedEtas: () => void; +} + +interface PinnedEtasContextProviderProps { + children: ReactNode; +} + +const PinnedEtasContext = React.createContext( + {} as PinnedEtasContextValue +); + +export const PinnedEtasContextProvider = ({ + children, +}: PinnedEtasContextProviderProps) => { + const getInitialState = (): PinnedEtasState => { + return { + pinnedEtas: [], + isHidden: false, + }; + }; + + type State = PinnedEtasState; + const [state, setStateRaw] = useState(getInitialState); + + const togglePinnedEta = useCallback((eta: string) => { + setStateRaw( + produce((state: State) => { + if (state.pinnedEtas.includes(eta)) { + state.pinnedEtas = state.pinnedEtas.filter( + (pinnedEta) => eta !== pinnedEta + ); + } else { + state.isHidden = false; + state.pinnedEtas = [...state.pinnedEtas, eta]; + } + }) + ); + }, []); + + const tooglePinnedEtasDialog = useCallback(() => { + setStateRaw( + produce((state: State) => { + state.isHidden = !state.isHidden; + }) + ); + }, []); + + const closePinnedEtas = useCallback(() => { + setStateRaw( + produce((state: State) => { + state.pinnedEtas = []; + }) + ); + }, []); + + const contextValue: PinnedEtasContextValue = useMemo( + () => ({ + ...state, + togglePinnedEta, + tooglePinnedEtasDialog, + closePinnedEtas, + }), + [closePinnedEtas, state, togglePinnedEta, tooglePinnedEtasDialog] + ); + + return ( + + {children} + + ); +}; + +export default PinnedEtasContext; +export type { PinnedEtasContextValue }; diff --git a/src/pages/DataImport.tsx b/src/pages/DataImport.tsx index d4a65c63ce18..7299bf27ea53 100644 --- a/src/pages/DataImport.tsx +++ b/src/pages/DataImport.tsx @@ -106,7 +106,6 @@ const DataImport = () => { searchRoute: "", selectedRoute: "1-1-CHUK-YUEN-ESTATE-STAR-FERRY", routeSearchHistory: obj.routeSearchHistory ?? [], - pinnedEtas: [], isRouteFilter: obj.isRouteFilter ?? true, busSortOrder: obj.busSortOrder ?? "KMB first", numPadOrder: obj.numPadOrder ?? "123456789c0b", diff --git a/vite.config.ts b/vite.config.ts index 47bc2436f844..dd49c2171323 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -19,7 +19,7 @@ export default defineConfig(({mode}: ConfigEnv) => { server: { https: true, host: true, - port: 11443, + port: 443, // port: parseInt(env.PORT ?? "9100", 10), // strictPort: true, },