@@ -11,6 +11,7 @@ import {
1111 useBounds ,
1212 useGetStationsWithTermination ,
1313 useLoopLine ,
14+ usePresetStops ,
1415 useSavedRoutes ,
1516} from '~/hooks' ;
1617import { directionToDirectionName , type LineDirection } from '~/models/Bound' ;
@@ -126,6 +127,7 @@ export const SelectBoundModal: React.FC<Props> = ({
126127 const navigation = useNavigation ( ) ;
127128 const [ stationAtom , setStationState ] = useAtom ( stationState ) ;
128129 const {
130+ station : confirmedStation ,
129131 pendingStation : station ,
130132 pendingStations : stations ,
131133 wantedDestination,
@@ -214,18 +216,31 @@ export const SelectBoundModal: React.FC<Props> = ({
214216 navigation . navigate ( 'Main' as never ) ;
215217 } , [ navigation ] ) ;
216218
219+ const {
220+ presetOrigin,
221+ presetStops,
222+ nearestPresetStation,
223+ resolvePresetDirection,
224+ } = usePresetStops ( {
225+ savedRouteDirection : savedRoute ?. direction ,
226+ stations,
227+ wantedDestination,
228+ confirmedStation,
229+ } ) ;
230+
217231 const handleBoundSelected = useCallback (
218232 (
219233 selectedStation : Station ,
220234 direction : LineDirection ,
221- terminateBySelectedStation = false
235+ terminateBySelectedStation = false ,
236+ stopsOverride ?: Station [ ]
222237 ) => {
223238 if ( isTransitioningRef . current ) return ;
224239 isTransitioningRef . current = true ;
225240 setIsTransitioning ( true ) ;
226241
227- let stops = stations ;
228- if ( terminateBySelectedStation && effectiveStation ) {
242+ let stops = stopsOverride ?? stations ;
243+ if ( ! stopsOverride && terminateBySelectedStation && effectiveStation ) {
229244 const destIdx = stations . findIndex (
230245 ( s ) => s . groupId === selectedStation . groupId
231246 ) ;
@@ -240,23 +255,34 @@ export const SelectBoundModal: React.FC<Props> = ({
240255 }
241256 }
242257
258+ const effectiveDirection = stopsOverride
259+ ? resolvePresetDirection ( selectedStation , stops )
260+ : direction ;
261+
262+ const departureFallback =
263+ effectiveDirection === 'INBOUND' ? stops [ 0 ] : stops . at ( - 1 ) ;
264+ const startStation = stopsOverride
265+ ? ( nearestPresetStation ?? departureFallback ?? effectiveStation )
266+ : effectiveStation ;
267+
243268 setLineState ( ( prev ) => ( {
244269 ...prev ,
245270 selectedLine : line ,
246271 pendingLine : null ,
247272 } ) ) ;
248273 setStationState ( ( prev ) => ( {
249274 ...prev ,
250- station : effectiveStation ,
275+ station : startStation ,
251276 stations : stops ,
252277 selectedBound :
253- direction === 'INBOUND' ? stops [ stops . length - 1 ] : stops [ 0 ] ,
254- selectedDirection : direction ,
278+ effectiveDirection === 'INBOUND' ? ( stops . at ( - 1 ) ?? null ) : stops [ 0 ] ,
279+ selectedDirection : effectiveDirection ,
255280 pendingStation : null ,
256281 pendingStations : [ ] ,
257- wantedDestination : terminateBySelectedStation
258- ? prev . wantedDestination
259- : null ,
282+ wantedDestination :
283+ terminateBySelectedStation || stopsOverride
284+ ? prev . wantedDestination
285+ : null ,
260286 } ) ) ;
261287 setNavigationState ( ( prev ) => ( {
262288 ...prev ,
@@ -269,6 +295,8 @@ export const SelectBoundModal: React.FC<Props> = ({
269295 [
270296 navigateToMain ,
271297 effectiveStation ,
298+ nearestPresetStation ,
299+ resolvePresetDirection ,
272300 stations ,
273301 line ,
274302 pendingTrainType ,
@@ -362,9 +390,7 @@ export const SelectBoundModal: React.FC<Props> = ({
362390 } ;
363391 const finalStop =
364392 wantedDestination ??
365- ( direction === 'INBOUND'
366- ? boundStations [ 0 ]
367- : boundStations [ boundStations . length - 1 ] ) ;
393+ ( direction === 'INBOUND' ? boundStations [ 0 ] : boundStations . at ( - 1 ) ) ;
368394
369395 const lineForCard = finalStop ?. line ;
370396 const trainTypeForCard = finalStop ?. trainType ;
@@ -403,27 +429,34 @@ export const SelectBoundModal: React.FC<Props> = ({
403429 ( s ) => s . groupId === wantedDestination . groupId
404430 ) ;
405431
406- if (
407- currentStationIndex === - 1 ||
408- wantedStationIndex === - 1 ||
409- currentStationIndex === wantedStationIndex
410- ) {
432+ if ( wantedStationIndex === - 1 ) {
411433 return < > </ > ;
412434 }
413435
414- const dir : LineDirection =
415- currentStationIndex < wantedStationIndex ? 'INBOUND' : 'OUTBOUND' ;
436+ // 現在駅が経路内にない場合は savedRoute.direction から方向を決定
437+ const canDetermineFromIndex =
438+ currentStationIndex !== - 1 &&
439+ currentStationIndex !== wantedStationIndex ;
440+ let dir : LineDirection = savedRoute ?. direction ?? 'INBOUND' ;
441+ if ( canDetermineFromIndex ) {
442+ dir =
443+ currentStationIndex < wantedStationIndex ? 'INBOUND' : 'OUTBOUND' ;
444+ }
416445
446+ // wantedDestination 方向のカード
417447 if ( direction === dir && line ) {
418- const title = isLoopLine
419- ? loopLineDirectionText ( direction )
420- : normalLineDirectionText ( boundStations ) ;
448+ const title = normalLineDirectionText ( boundStations ) ;
421449 const subtitle = buildSubtitle ( lineForCard , trainTypeForCard ) ?? '' ;
422450 return (
423451 < CommonCard
424452 line = { lineForCard ?? line }
425453 onPress = { ( ) =>
426- handleBoundSelected ( wantedDestination , dir , ! ! wantedDestination )
454+ handleBoundSelected (
455+ wantedDestination ,
456+ dir ,
457+ ! ! wantedDestination ,
458+ presetStops
459+ )
427460 }
428461 disabled = { isTransitioning }
429462 loading = { isTransitioning }
@@ -433,6 +466,45 @@ export const SelectBoundModal: React.FC<Props> = ({
433466 />
434467 ) ;
435468 }
469+
470+ // 逆方向カード: presetOrigin がない or GPS確定駅が起点と同じ場合は非表示
471+ if (
472+ ! presetOrigin ||
473+ confirmedStation ?. groupId === presetOrigin . groupId
474+ ) {
475+ return < > </ > ;
476+ }
477+
478+ if ( boundStations . length ) {
479+ const reverseLineForCard =
480+ ( presetOrigin . line as Line | undefined ) ?? lineForCard ;
481+ const reverseSubtitle =
482+ buildSubtitle ( reverseLineForCard , presetOrigin . trainType ) ?? '' ;
483+ const reverseDirForNav : LineDirection =
484+ savedRoute ?. direction === 'INBOUND' ? 'OUTBOUND' : 'INBOUND' ;
485+ return (
486+ < CommonCard
487+ onPress = { ( ) =>
488+ handleBoundSelected (
489+ presetOrigin ,
490+ reverseDirForNav ,
491+ false ,
492+ presetStops
493+ )
494+ }
495+ disabled = { isTransitioning }
496+ loading = { isTransitioning }
497+ line = { reverseLineForCard }
498+ title = {
499+ isJapanese
500+ ? `${ presetOrigin . name } 方面`
501+ : `for ${ presetOrigin . nameRoman ?? '' } `
502+ }
503+ subtitle = { reverseSubtitle }
504+ targetStation = { presetOrigin }
505+ />
506+ ) ;
507+ }
436508 return < > </ > ;
437509 }
438510
@@ -478,6 +550,10 @@ export const SelectBoundModal: React.FC<Props> = ({
478550 line ,
479551 loopLineDirectionText ,
480552 normalLineDirectionText ,
553+ savedRoute ?. direction ,
554+ confirmedStation ?. groupId ,
555+ presetOrigin ,
556+ presetStops ,
481557 ]
482558 ) ;
483559
0 commit comments