fix: 次駅表示をDirection非依存に修正(JS/Kotlin両方)
- JS側: currentPosition[0]ではなくstopStationIDList上のmax(idx0,idx1)で進行方向の駅を判定 - Kotlin側: pollRunnable復活、allStationsのダイヤ順でmaxOf(idx0,idx1)で向かう駅を判定 - Kotlin at-station: 停車中は現在駅を表示(JS側と統一) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -217,12 +217,17 @@ export const FixedTrain: FC<props> = ({ trainID }) => {
|
||||
const delayTime = train?.delay == "入線" ? 0 : train?.delay;
|
||||
let additionalSkipCount = 0;
|
||||
|
||||
// 2駅間走行中の場合: currentPosition[0]が向かう駅IDなので
|
||||
// trainDataWidhThroughでその駅以降の最初の停車駅を探す
|
||||
// 2駅間走行中の場合: ダイヤ順で後ろのインデックスが進行方向の駅
|
||||
// Direction に関係なく、travel-order で大きい方が「向かう駅」
|
||||
let searchStart: number;
|
||||
if (currentPosition.length === 2) {
|
||||
const toIdx = stopStationIDList.findIndex(d => d.includes(currentPosition[0]));
|
||||
searchStart = toIdx >= 0 ? toIdx : searchCountLast;
|
||||
const idx0 = stopStationIDList.findIndex(d => d.includes(currentPosition[0]));
|
||||
const idx1 = stopStationIDList.findIndex(d => d.includes(currentPosition[1]));
|
||||
const aheadIdx = Math.max(
|
||||
idx0 >= 0 ? idx0 : -1,
|
||||
idx1 >= 0 ? idx1 : -1
|
||||
);
|
||||
searchStart = aheadIdx >= 0 ? aheadIdx : searchCountLast;
|
||||
} else {
|
||||
searchStart = searchCountFirst;
|
||||
}
|
||||
|
||||
@@ -62,9 +62,12 @@ class LiveActivityForegroundService : Service() {
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val pollRunnable = object : Runnable {
|
||||
override fun run() {
|
||||
// ポーリングは無効化。JS側が10秒ごとに更新を送信する。
|
||||
// ネイティブ側のポーリングはDirectionを考慮できず
|
||||
// JS側の更新と競合して不正な表示になるため。
|
||||
if (!isRunning) return
|
||||
when (currentMode) {
|
||||
"train" -> executor.execute { pollTrainPosition() }
|
||||
"station" -> executor.execute { pollStationTrains() }
|
||||
}
|
||||
handler.postDelayed(this, POLL_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,37 +236,75 @@ class LiveActivityForegroundService : Service() {
|
||||
|
||||
val delay = parseDelay(train)
|
||||
val stationStops = parseLinesJson(stationStopsJson)
|
||||
val posStations = pos.split("~")
|
||||
val currentStation = posStations.firstOrNull()
|
||||
?.replace("(下り)", "")?.replace("(上り)", "")
|
||||
?.replace("(下り)", "")?.replace("(上り)", "")
|
||||
?.trim() ?: ""
|
||||
val nextStation = if (posStations.size > 1) {
|
||||
posStations[1]
|
||||
.replace("(下り)", "").replace("(上り)", "")
|
||||
.replace("(下り)", "").replace("(上り)", "")
|
||||
.trim()
|
||||
} else ""
|
||||
|
||||
// allStationsから現在地インデックスを計算
|
||||
val allStations = parseAllStationsJson(allStationsJson)
|
||||
val currentIndex = if (allStations.isNotEmpty()) {
|
||||
allStations.indexOfFirst { it.first == currentStation }.let { if (it < 0) 0 else it }
|
||||
} else {
|
||||
if (stationStops.isNotEmpty() && currentStation.isNotEmpty()) {
|
||||
stationStops.indexOf(currentStation).let { if (it < 0) 0 else it }
|
||||
} else 0
|
||||
}
|
||||
val progressTotal = if (allStations.isNotEmpty()) allStations.size else stationStops.size
|
||||
|
||||
val delayText = if (delay > 0) "${delay}分遅れ" else "定刻"
|
||||
// Posの方向表記を除去
|
||||
val cleanedPos = pos
|
||||
.replace("(下り)", "").replace("(上り)", "")
|
||||
.replace("(下り)", "").replace("(上り)", "")
|
||||
.replace("(徳島線)", "").replace("(高徳線)", "")
|
||||
.replace("(坂出方)", "").replace("(児島方)", "")
|
||||
.trim()
|
||||
val posStations = cleanedPos.split("~").map { it.trim() }
|
||||
val isAtStation = posStations.size <= 1
|
||||
|
||||
// allStationsのダイヤ順で現在地と次の停車駅を決定
|
||||
var nextStopName = ""
|
||||
var currentIndex = 0
|
||||
|
||||
if (allStations.isNotEmpty()) {
|
||||
if (isAtStation) {
|
||||
// 駅に停車中: 現在駅を表示(JS側と同じ "ただいま [駅名]")
|
||||
val stationName = posStations.firstOrNull() ?: ""
|
||||
val idx = allStations.indexOfFirst { it.first == stationName }
|
||||
currentIndex = if (idx >= 0) idx else 0
|
||||
nextStopName = stationName
|
||||
} else {
|
||||
// 2駅間走行中: 両方の駅をallStationsで見つけ、ダイヤ上で後ろにある方が向かう駅
|
||||
val idx0 = allStations.indexOfFirst { it.first == posStations[0] }
|
||||
val idx1 = allStations.indexOfFirst { it.first == posStations.getOrElse(1) { "" } }
|
||||
val towardIdx: Int
|
||||
if (idx0 >= 0 && idx1 >= 0) {
|
||||
// ダイヤ順で後ろの方が「向かっている駅」
|
||||
towardIdx = maxOf(idx0, idx1)
|
||||
currentIndex = minOf(idx0, idx1)
|
||||
} else if (idx0 >= 0) {
|
||||
towardIdx = idx0
|
||||
currentIndex = idx0
|
||||
} else if (idx1 >= 0) {
|
||||
towardIdx = idx1
|
||||
currentIndex = idx1
|
||||
} else {
|
||||
towardIdx = 0
|
||||
currentIndex = 0
|
||||
}
|
||||
// 向かう駅以降で最初の停車駅を探す
|
||||
for (i in towardIdx until allStations.size) {
|
||||
if (allStations[i].second) { // isStop == true
|
||||
nextStopName = allStations[i].first
|
||||
break
|
||||
}
|
||||
}
|
||||
if (nextStopName.isEmpty() && posStations.size > 1) {
|
||||
nextStopName = posStations[1]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// allStationsが空の場合のフォールバック
|
||||
val stationName = posStations.firstOrNull() ?: ""
|
||||
currentIndex = if (stationStops.isNotEmpty()) {
|
||||
stationStops.indexOf(stationName).let { if (it < 0) 0 else it }
|
||||
} else 0
|
||||
nextStopName = if (posStations.size > 1) posStations[1] else stationName
|
||||
}
|
||||
|
||||
val progressTotal = if (allStations.isNotEmpty()) allStations.size else stationStops.size
|
||||
val delayText = if (delay > 0) "${delay}分遅れ" else "定刻"
|
||||
val positionLabel = if (isAtStation) "ただいま" else "次は"
|
||||
val displayStation = if (isAtStation) currentStation else nextStation
|
||||
val bodyLines = mutableListOf<String>()
|
||||
bodyLines.add("$positionLabel $displayStation")
|
||||
if (!isAtStation && currentStation.isNotEmpty() && nextStation.isNotEmpty()) {
|
||||
bodyLines.add("${currentStation}~${nextStation}間走行中")
|
||||
bodyLines.add("$positionLabel $nextStopName")
|
||||
if (!isAtStation) {
|
||||
bodyLines.add("${cleanedPos}間走行中")
|
||||
}
|
||||
bodyLines.add(delayText)
|
||||
val body = bodyLines.joinToString("\n")
|
||||
@@ -279,7 +320,7 @@ class LiveActivityForegroundService : Service() {
|
||||
val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
nm.notify(NOTIFICATION_ID, notification)
|
||||
}
|
||||
Log.d(TAG, "Poll updated: pos=$pos delay=$delay")
|
||||
Log.d(TAG, "Poll updated: pos=$pos nextStop=$nextStopName delay=$delay")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Poll error", e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user