From 1afecf04223a8a024c7bcb0976190f763716b97d Mon Sep 17 00:00:00 2001 From: Jamie McDonald Date: Sat, 16 Dec 2023 23:13:18 +0000 Subject: [PATCH] Define arrivals interface --- macOS/Arrivals/ArrivalsViewModel.swift | 4 +- macOS/Arrivals/SettingsViewModel.swift | 2 +- .../kotlin/com/jdamcd/tflarrivals/TflApi.kt | 8 ++-- .../{Arrivals.kt => TflArrivals.kt} | 43 ++++++++++++------- 4 files changed, 35 insertions(+), 22 deletions(-) rename shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/{Arrivals.kt => TflArrivals.kt} (74%) diff --git a/macOS/Arrivals/ArrivalsViewModel.swift b/macOS/Arrivals/ArrivalsViewModel.swift index 8c2b2a6..298ec68 100644 --- a/macOS/Arrivals/ArrivalsViewModel.swift +++ b/macOS/Arrivals/ArrivalsViewModel.swift @@ -6,14 +6,14 @@ class ArrivalsViewModel: ObservableObject { @Published var state: ArrivalsState = .idle @Published var loading = false - private let fetcher = Arrivals() + private let fetcher = ArrivalsBuilder().tflArrivals() func load() { if !loading { loading = true Task { do { - let result = try await fetcher.fetchArrivals() + let result = try await fetcher.latest() state = .data(result) } catch { state = .error diff --git a/macOS/Arrivals/SettingsViewModel.swift b/macOS/Arrivals/SettingsViewModel.swift index 50c81c7..6b8013f 100644 --- a/macOS/Arrivals/SettingsViewModel.swift +++ b/macOS/Arrivals/SettingsViewModel.swift @@ -5,7 +5,7 @@ import TflArrivals class SettingsViewModel: ObservableObject { @Published var state: SettingsState = .idle - private let fetcher = Arrivals() + private let fetcher = ArrivalsBuilder().tflArrivals() private let settings = Settings() func performSearch(_ query: String) { diff --git a/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflApi.kt b/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflApi.kt index 69eddaf..8e502bd 100644 --- a/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflApi.kt +++ b/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflApi.kt @@ -56,7 +56,7 @@ internal class TflApi { } @Serializable -data class ApiArrival( +internal data class ApiArrival( val id: Int, val stationName: String, val platformName: String, @@ -66,18 +66,18 @@ data class ApiArrival( ) @Serializable -data class ApiSearchResult( +internal data class ApiSearchResult( val matches: List ) @Serializable -data class ApiMatchedStop( +internal data class ApiMatchedStop( val id: String, val name: String ) @Serializable -data class ApiStopPoint( +internal data class ApiStopPoint( val commonName: String, val naptanId: String, val stopType: String, diff --git a/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/Arrivals.kt b/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflArrivals.kt similarity index 74% rename from shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/Arrivals.kt rename to shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflArrivals.kt index 95fc884..369b05a 100644 --- a/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/Arrivals.kt +++ b/shared/src/commonMain/kotlin/com/jdamcd/tflarrivals/TflArrivals.kt @@ -3,12 +3,27 @@ package com.jdamcd.tflarrivals import kotlin.coroutines.cancellation.CancellationException import kotlin.math.roundToInt -class Arrivals { - private val api = TflApi() - private val settings = Settings() +object ArrivalsBuilder { + fun tflArrivals(): Arrivals = TflArrivals(TflApi(), Settings()) +} + +interface Arrivals { + @Throws(NoDataException::class, CancellationException::class) + suspend fun latest(): ArrivalsInfo + + @Throws(CancellationException::class) + suspend fun searchStops(query: String): List + @Throws(CancellationException::class) + suspend fun stopDetails(id: String): StopDetails +} + +internal class TflArrivals( + private val api: TflApi, + private val settings: Settings +) : Arrivals { @Throws(NoDataException::class, CancellationException::class) - suspend fun fetchArrivals(): ArrivalsInfo { + override suspend fun latest(): ArrivalsInfo { try { val model = formatArrivals(api.fetchArrivals(settings.selectedStopId)) if (model.arrivals.isNotEmpty()) { @@ -22,12 +37,13 @@ class Arrivals { } @Throws(CancellationException::class) - suspend fun searchStops(query: String): List { + override suspend fun searchStops(query: String): List { return api.searchStations(query).matches .map { StopResult(it.id, it.name) } } - suspend fun stopDetails(id: String): StopDetails { + @Throws(CancellationException::class) + override suspend fun stopDetails(id: String): StopDetails { val stopPoint = api.stopDetails(id) return StopDetails( stopPoint.naptanId, @@ -43,18 +59,12 @@ class Arrivals { apiArrivals .sortedBy { it.timeToStation } .filter { - if (settings.platformFilter.isEmpty()) { - true - } else { + settings.platformFilter.isEmpty() || it.platformName.contains(settings.platformFilter, ignoreCase = true) - } } .filter { arrival -> - if (settings.directionFilter == SettingsConfig.DIRECTION_FILTER_DEFAULT) { - true - } else { + settings.directionFilter == SettingsConfig.DIRECTION_FILTER_DEFAULT || arrival.direction.contains(settings.directionFilter) - } } .take(3) .map { @@ -123,4 +133,7 @@ private fun formatStation(name: String) = .replace("DLR Station", "") .trim() -private fun formatDirection(direction: String) = direction.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() } +private fun formatDirection(direction: String) = + direction.replaceFirstChar { + if (it.isLowerCase()) it.titlecase() else it.toString() + }