Crash fix (React Hooks violation):
- PlaybackTimeline.tsx: move ALL hooks (useRef for PanResponder, useCallback)
to before the early return; use seekRef/totalRef to share values into
PanResponder handlers without stale closure issues
Multiple recordings support:
- trainRecorder.ts: redesign to id-based multi-recording system
- RecordingMeta type for lightweight list (no snapshots)
- TrainRecording now includes id field
- saveRecording/loadRecordingById/deleteRecordingById/loadRecordingList
- migrateOldRecording() migrates old single MOCK_RECORDING key on first launch
- constants/storage.ts: add MOCK_RECORDINGS_INDEX + MOCK_RECORDING_DATA_PREFIX keys
- useTrainMenu: savedRecording → recordingList (RecordingMeta[]) + activeRecording (TrainRecording|null)
- startPlayback(id) loads full recording on demand
- deleteRecording(id) deletes by id and refreshes list
- stopPlayback clears activeRecording
- DataSourceSettings: recording list UI
- shows all recordings with date/time, snapshot count, duration
- ▶ play and 削除 buttons per row
- recording/playing status indicator
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements snapshot-based recording and playback of live train
position data for mock API debugging (admin-only).
Recording:
- startRecording() disables mock mode and begins capturing live
train snapshots every ~15s (via getCurrentTrain polling)
- Each snapshot stores { t: elapsed_ms, trains: TrainEntry[] }
- stopRecording() saves completed recording to AsyncStorage
Playback:
- startPlayback() enables mock mode and loops through snapshots
at their original recorded timing using useEffect+setTimeout
- stopPlayback() returns to idle
Storage:
- Single slot in AsyncStorage (MOCK_RECORDING key)
- Loaded on app start in useTrainMenu
- deleteRecording() removes it
New files:
- lib/mockApi/trainRecorder.ts — TrainRecording/TrainSnapshot types
+ save/load/delete AsyncStorage helpers
Modified files:
- constants/storage.ts — add MOCK_RECORDING key
- stateBox/useTrainMenu.tsx — recorder state + all controls
- stateBox/useCurrentTrain.tsx — call addTrainSnapshot after live fetch
- components/Settings/DataSourceSettings.tsx — record/play UI with
status dot, snapshot count, and action buttons
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The separate runtime MOCK switch on the map screen is removed.
Now the admin-only settings toggle (MOCK_API_FEATURE_ENABLED) is the
single control point — turning it on activates mock mode immediately,
turning it off deactivates it.
- useTrainMenu: remove mockApiEnabled/setMockApiEnabled state;
mockApiConfig now derives from mockApiFeatureEnabled alone
- WebView: use mockApiFeatureEnabled for key prop (triggers reload)
- Apps.tsx: remove MockApiToggle import and JSX usage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- constants/storage.ts: add MOCK_API_FEATURE_ENABLED key
- stateBox/useTrainMenu.tsx:
- import MOCK_TRAIN_POSITIONS; auto-populate on mount and on toggle-off
- add mockApiFeatureEnabled (persistent, admin-only) state + setter
- mockApiConfig now requires both mockApiFeatureEnabled AND mockApiEnabled
- components/Settings/DataSourceSettings.tsx:
- add mock API debug section (admin-gated, showDebugSelector)
- Switch toggles mockApiFeatureEnabled and persists to AsyncStorage
- components/Apps/MockApiToggle.tsx: new component
- absolute-positioned to the left of ReloadButton
- visible only when mockApiFeatureEnabled && mapSwitch==="true"
- MOCK label + Switch toggles mockApiEnabled runtime state
- components/Apps.tsx: render MockApiToggle alongside ReloadButton
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Implemented ShortcutWidget for quick access to app features with customizable shortcuts.
- Added DelayInfoWidget to display train delay information fetched from a remote endpoint.
- Created FelicaBalanceWidget to show the balance of Felica-compatible IC cards.
- Introduced OperationInfoWidget for displaying train operation status.
- Set up shared data handling for Felica snapshots between the main app and widget.
- Configured widget assets and entitlements for proper functionality.
- Updated Info.plist and expo-target.config.js for widget deployment.
- Add regionCode (byte[15]) to history entry in Android/iOS native code
- areaCode = regionCode >> 6 determines the transit area (0-3)
- stationId = (areaCode<<16) | (lineCode<<8) | stationCode
- Add lib/felicaStationMap.ts with 5900+ station entries from
metrodroid/felica_stations.db3 (GPL-3.0)
- FelicaHistoryPage now shows station names instead of raw L/S codes
- Falls back to raw code format if station is not in the database
- Introduced useElesite hook for managing elesite data and settings.
- Added elesite logo asset.
- Updated types to include elesite data structures.
- Enhanced TrainMenuProvider to manage elesite usage settings.
- Implemented data fetching and caching for elesite information.
- Added utility functions to retrieve train information from elesite data.