Skip to content

Commit 90f2f35

Browse files
committed
Fix map screen showing hardcoded test route, wrong favorite-route sort order
- app/map.native.tsx: stop always querying/displaying the leftover dev test route (師大分部 -> 師大); read from/to from navigation params instead, matching the route planner screen. Also link to it from the route results screen ("地圖" button) so it's reachable. - app/index.tsx: fix favorite-route arrival sort putting "X分" buses ahead of imminent "進站中"/"將到站" ones. Remove the unused favoriteRouteArrivals state/fetchFavoriteRouteArrivals function, which was computed but never rendered anywhere.
1 parent 6005b2e commit 90f2f35

3 files changed

Lines changed: 24 additions & 167 deletions

File tree

app/index.tsx

Lines changed: 4 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ export default function StopScreen() {
5555

5656
// 常用路線狀態
5757
const [favoriteRoutes, setFavoriteRoutes] = useState<FavoriteRoute[]>([]);
58-
const [favoriteRouteArrivals, setFavoriteRouteArrivals] = useState<UIArrival[]>([]);
5958
const [selectedRouteIndex, setSelectedRouteIndex] = useState<number>(0);
6059

6160
// 顯示模式: 'favorite' | 'nearby' | 'default'
@@ -296,10 +295,6 @@ export default function StopScreen() {
296295
if (newIndex !== selectedRouteIndex && newIndex >= 0 && newIndex < favoriteRoutes.length) {
297296
setSelectedRouteIndex(newIndex);
298297
scrollRouteButtonToCenter(newIndex);
299-
// 從已載入的資料中切換
300-
if (allFavoriteArrivals[newIndex]) {
301-
setFavoriteRouteArrivals(allFavoriteArrivals[newIndex]);
302-
}
303298
}
304299
};
305300

@@ -342,8 +337,7 @@ export default function StopScreen() {
342337
});
343338

344339
setAllFavoriteArrivals(cachedArrivals);
345-
setFavoriteRouteArrivals(cachedArrivals[0]);
346-
340+
347341
// 在背景載入實際動態資料
348342
loadAllFavoriteRoutesArrivals(routes, false);
349343

@@ -356,7 +350,6 @@ export default function StopScreen() {
356350
} else {
357351
// 沒有常用路線,顯示預設站牌
358352
setDisplayMode('default');
359-
setFavoriteRouteArrivals([]);
360353
setAllFavoriteArrivals([]);
361354
// 清除定時器
362355
if (favoriteIntervalRef.current) clearInterval(favoriteIntervalRef.current);
@@ -417,15 +410,6 @@ export default function StopScreen() {
417410

418411
return tempArrivals;
419412
});
420-
421-
// 更新當前顯示的路線
422-
setFavoriteRouteArrivals(prev => {
423-
const updated = allNewArrivals[selectedRouteIndex] || prev;
424-
return prev.map(existingItem => {
425-
const newItem = updated.find(item => item.key === existingItem.key);
426-
return newItem ? { ...existingItem, estimatedTime: newItem.estimatedTime } : existingItem;
427-
});
428-
});
429413
} else {
430414
console.log('🆕 [Index] 初始載入模式 - 完整載入所有路線');
431415
const tempArrivals: UIArrival[][] = routes.map(route => {
@@ -450,11 +434,6 @@ export default function StopScreen() {
450434

451435
// 即時更新狀態,讓使用者看到已載入的資料
452436
setAllFavoriteArrivals([...tempArrivals]);
453-
454-
// 如果這是當前顯示的路線,立即更新顯示
455-
if (i === selectedRouteIndex) {
456-
setFavoriteRouteArrivals(arrivals);
457-
}
458437
}
459438
}
460439
} catch (error) {
@@ -542,12 +521,12 @@ export default function StopScreen() {
542521
});
543522
}
544523

545-
// 依照到站時間排序
524+
// 依照到站時間排序(即將到站/進站中優先於還要幾分鐘的班次)
546525
favoriteArrivals.sort((a, b) => {
547526
const timeA = a.estimatedTime;
548527
const timeB = b.estimatedTime;
549-
if (timeA.includes('分') && !timeB.includes('分')) return -1;
550-
if (!timeA.includes('分') && timeB.includes('分')) return 1;
528+
if (timeA.includes('分') && !timeB.includes('分')) return 1;
529+
if (!timeA.includes('分') && timeB.includes('分')) return -1;
551530
return 0;
552531
});
553532

@@ -559,134 +538,6 @@ export default function StopScreen() {
559538
}
560539
};
561540

562-
// 抽取指定常用路線的公車動態(快取快速顯示 + 背景更新)
563-
const fetchFavoriteRouteArrivals = async (routeIndex: number, forceRefresh: boolean = false) => {
564-
try {
565-
if (!serviceReady || favoriteRoutes.length === 0) {
566-
console.log('Service not ready or no favorite routes');
567-
return;
568-
}
569-
570-
const route = favoriteRoutes[routeIndex];
571-
if (!route) {
572-
console.log('Route not found at index:', routeIndex);
573-
return;
574-
}
575-
576-
console.log('Processing route:', route.fromStop, '→', route.toStop);
577-
578-
// 步驟 1: 如果有快取的路線名稱,立即顯示預設資料
579-
if (route.cachedRouteNames && route.cachedRouteNames.length > 0 && !forceRefresh) {
580-
console.log('使用快取路線:', route.cachedRouteNames);
581-
582-
// 立即顯示快取路線的預設資料(等待中...)
583-
const placeholderArrivals: UIArrival[] = route.cachedRouteNames.map((routeName) => ({
584-
route: routeName,
585-
estimatedTime: '查詢中...',
586-
key: `placeholder-${route.id}-${routeName}`,
587-
}));
588-
589-
setFavoriteRouteArrivals(placeholderArrivals);
590-
setDisplayMode('favorite');
591-
}
592-
593-
// 步驟 2: 取得起點站 SID
594-
const fromSids = plannerRef.current.getRepresentativeSids(route.fromStop);
595-
console.log('From stop SIDs:', fromSids);
596-
if (fromSids.length === 0) {
597-
setFavoriteRouteArrivals([]);
598-
setDisplayMode('default');
599-
return;
600-
}
601-
602-
// 步驟 3: 規劃路徑以取得可用路線名稱
603-
const plans = await plannerRef.current.plan(
604-
route.fromStop,
605-
route.toStop
606-
);
607-
608-
console.log('Plans found:', plans.length);
609-
if (plans.length === 0) {
610-
setFavoriteRouteArrivals([]);
611-
setDisplayMode('default');
612-
return;
613-
}
614-
615-
// 取得所有可用的公車路線名稱
616-
const routeNames = [...new Set(plans.map(bus => bus.routeName))];
617-
console.log('Route names:', routeNames);
618-
619-
// 更新快取(如果路線有變化或是第一次加載)
620-
if (!route.cachedRouteNames ||
621-
JSON.stringify(route.cachedRouteNames.sort()) !== JSON.stringify(routeNames.sort())) {
622-
console.log('更新路線快取...');
623-
await favoriteRoutesService.updateRouteCacheNames(
624-
route.fromStop,
625-
route.toStop,
626-
routeNames
627-
);
628-
// 重新載入常用路線以更新快取
629-
const updatedRoutes = await favoriteRoutesService.getAllRoutes(true);
630-
setFavoriteRoutes(updatedRoutes);
631-
}
632-
633-
// 步驟 4: 抽取起點站的即時公車資料
634-
const results = await plannerRef.current.fetchBusesAtSid(fromSids[0]);
635-
const allBuses = results.flat();
636-
console.log('All buses at', route.fromStop, ':', allBuses.length, 'buses');
637-
638-
// 找出起點站有的公車且在路線中
639-
const matchingBuses = allBuses.filter(bus =>
640-
routeNames.includes(bus.route)
641-
);
642-
643-
console.log('Matching buses:', matchingBuses.length);
644-
645-
// 轉換為 UI 格式(使用穩定的 key,加入 rawTime 避免同路線不同班次衝突)
646-
const favoriteArrivals: UIArrival[] = matchingBuses.map((bus) => ({
647-
route: bus.route,
648-
estimatedTime: bus.timeText,
649-
key: `fav2-${route.id}-${bus.rid}-${bus.route}-${bus.rawTime}`,
650-
}));
651-
652-
// 如果沒有匹配的公車,顯示所有可用路線但標註為無資料
653-
if (favoriteArrivals.length === 0 && routeNames.length > 0) {
654-
routeNames.forEach((routeName) => {
655-
favoriteArrivals.push({
656-
route: routeName,
657-
estimatedTime: '無資料',
658-
key: `fav-nodata-${route.id}-${routeName}`,
659-
});
660-
});
661-
}
662-
663-
// 依照到站時間排序
664-
favoriteArrivals.sort((a, b) => {
665-
const timeA = a.estimatedTime;
666-
const timeB = b.estimatedTime;
667-
if (timeA.includes('分') && !timeB.includes('分')) return -1;
668-
if (!timeA.includes('分') && timeB.includes('分')) return 1;
669-
return 0;
670-
});
671-
672-
console.log('Total favorite arrivals:', favoriteArrivals.length);
673-
674-
setFavoriteRouteArrivals(favoriteArrivals);
675-
676-
// 根據結果設定顯示模式
677-
if (favoriteArrivals.length > 0) {
678-
console.log('Setting display mode to: favorite');
679-
setDisplayMode('favorite');
680-
} else {
681-
console.log('Setting display mode to: default (no matching buses)');
682-
setDisplayMode('default');
683-
}
684-
} catch (error) {
685-
console.error('抽取常用路線公車動態失敗:', error);
686-
setDisplayMode('default');
687-
}
688-
};
689-
690541
// 長按路線顯示選單
691542
const handleLongPress = (route: FavoriteRoute) => {
692543
setSelectedRoute(route);
@@ -1011,10 +862,6 @@ export default function StopScreen() {
1011862
if (pagerRef.current) {
1012863
pagerRef.current.setPage(index);
1013864
}
1014-
// 從已載入的資料中切換
1015-
if (allFavoriteArrivals[index]) {
1016-
setFavoriteRouteArrivals(allFavoriteArrivals[index]);
1017-
}
1018865
}}
1019866
onLongPress={() => handleLongPress(route)}
1020867
delayLongPress={Platform.OS === 'web' ? 300 : 500}

app/map.native.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as Location from 'expo-location';
2-
import { useRouter } from 'expo-router';
2+
import { useLocalSearchParams, useRouter } from 'expo-router';
33
import React, { useEffect, useMemo, useRef, useState } from 'react';
44
import { ActivityIndicator, FlatList, Modal, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
55
import MapView, { Callout, Marker, Polyline, PROVIDER_DEFAULT, PROVIDER_GOOGLE } from 'react-native-maps';
@@ -36,6 +36,9 @@ export default function MapNative() {
3636
const [selectedRouteIndex, setSelectedRouteIndex] = useState<number>(0); // 選中的路線索引
3737
const [renderKey, setRenderKey] = useState<number>(0); // 強制重新渲染的 key
3838
const router = useRouter();
39+
const { from: fromParam, to: toParam } = useLocalSearchParams<{ from?: string; to?: string }>();
40+
const fromStop = Array.isArray(fromParam) ? fromParam[0] : fromParam;
41+
const toStop = Array.isArray(toParam) ? toParam[0] : toParam;
3942
const plannerRef = useRef(new BusPlannerService());
4043
const isAnimatingRef = useRef(false); // 防止動畫衝突
4144
const animationTimeoutRef = useRef<any>(null);
@@ -170,15 +173,16 @@ export default function MapNative() {
170173
})();
171174
}, []);
172175

173-
// 初始化 BusPlannerService 並查詢測試路線
176+
// 初始化 BusPlannerService,並在有起訖站參數時查詢路線
174177
useEffect(() => {
175178
(async () => {
176179
try {
177180
await plannerRef.current.initialize();
178181
console.log('BusPlannerService 初始化完成');
179-
180-
// 測試:查詢「師大分部」到「師大」的路線
181-
const routes = await plannerRef.current.plan('師大分部', '師大');
182+
183+
if (!fromStop || !toStop) return;
184+
185+
const routes = await plannerRef.current.plan(fromStop, toStop);
182186
console.log('找到路線數量:', routes.length);
183187
if (routes.length > 0) {
184188
console.log('第一條路線:', routes[0].routeName, routes[0].directionText);
@@ -188,18 +192,18 @@ export default function MapNative() {
188192
console.error('路線規劃初始化錯誤:', error);
189193
}
190194
})();
191-
}, []);
195+
}, [fromStop, toStop]);
192196

193197
// 更新路線動態資訊
194198
const updateRouteInfo = async () => {
195-
if (routeInfo.length === 0 || isUpdatingRoute) return;
196-
199+
if (!fromStop || !toStop || routeInfo.length === 0 || isUpdatingRoute) return;
200+
197201
try {
198202
setIsUpdatingRoute(true);
199203
console.log('更新路線動態...');
200-
204+
201205
// 重新查詢路線以獲取最新的到站時間
202-
const routes = await plannerRef.current.plan('師大分部', '師大');
206+
const routes = await plannerRef.current.plan(fromStop, toStop);
203207
if (routes.length > 0) {
204208
setRouteInfo(routes);
205209
console.log('路線動態更新完成,找到', routes.length, '條路線');

app/route.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,12 @@ export default function RouteScreen() {
569569
找到 {routeInfo.length} 條路線
570570
</Text>
571571
<View style={styles.headerActions}>
572+
<TouchableOpacity
573+
onPress={() => router.push({ pathname: '/map', params: { from: fromStop, to: toStop } })}
574+
style={styles.refreshButton}
575+
>
576+
<Text style={styles.refreshButtonText}>🗺 地圖</Text>
577+
</TouchableOpacity>
572578
<TouchableOpacity
573579
onPress={toggleFavorite}
574580
style={styles.favoriteButton}

0 commit comments

Comments
 (0)