Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
aee81fb
Bump Compose to 1.8.0
emilymclean May 13, 2025
3b1b74b
Bump other libs
emilymclean May 13, 2025
a47ba02
Remove unused import
emilymclean May 13, 2025
5dd7ecd
Bump again in the vain hope it fixes things
emilymclean Jun 18, 2025
abc8ca4
Merge branch 'develop' into chore/bump-1.8.0
emilymclean Jun 18, 2025
9d932bb
Fix physics of sheet
emilymclean Jun 18, 2025
e03085e
Merge branch 'develop' into chore/bump-1.8.0
emilymclean Jun 28, 2025
970d53a
Merge branch 'develop' into chore/bump-1.8.0
emilymclean Jul 10, 2025
9e065ca
Get building properly on iOS
emilymclean Jul 10, 2025
c1b5bbe
Bump compose to avoid issue with Voyager
emilymclean Jul 10, 2025
843bc68
It's still broken for iOS
emilymclean Jul 10, 2025
f8ff13b
Merge remote-tracking branch 'origin/develop' into chore/bump-1.8.0
emilymclean Sep 19, 2025
63487cb
Bump compose again
emilymclean Sep 19, 2025
3ff7588
Fix last departure times that end on the next day
emilymclean Jan 5, 2026
6fbcede
Add test to ensure tomorrow service before 3am is prioritized over today
emilymclean Jan 5, 2026
3a89a68
Search for content banners matching stops/route
emilymclean Jan 9, 2026
8d4c2a7
Merge pull request #307 from emilymclean/hotfix/last-departure-wrapping
emilymclean Jan 9, 2026
23e849f
Correct ROUTE_BANNER_ID -> STOP_BANNER_ID
emilymclean Jan 9, 2026
f187c38
Merge pull request #308 from emilymclean/feature/content-banners-rout…
emilymclean Jan 9, 2026
c5200b1
Merge branch 'develop' into chore/bump-1.8.0
emilymclean Jan 21, 2026
f9e9f7e
Hallelujah the issue I described in voyager issue 541 was fixed on iOS
emilymclean Jan 21, 2026
a533bec
Update workflows to use java 21
emilymclean Jan 21, 2026
a170899
Merge pull request #226 from emilymclean/chore/bump-1.8.0
emilymclean Jan 21, 2026
175b7d7
Add countdown and countdown preference
emilymclean Jan 31, 2026
fc0f756
Cover generic case for offset
emilymclean Feb 1, 2026
43ebb57
Optimise time helpers & explicitly refresh periodically
emilymclean Feb 1, 2026
4148b00
Add countdown setting
emilymclean Feb 1, 2026
4622ed4
Add chinese translation for countdown
emilymclean Feb 20, 2026
1324407
Better handle early/late indication
emilymclean Feb 20, 2026
149f572
Remove unused strings
emilymclean Feb 21, 2026
9fddc34
Place derivedStateOf in remember
emilymclean Feb 21, 2026
5babe41
Increase location update frequency
emilymclean Feb 21, 2026
8d6f6e1
Merge pull request #310 from emilymclean/mclean/feature/arrival-count…
emilymclean Feb 21, 2026
d8082f8
Merge pull request #311 from emilymclean/mclean/feature/more-frequent…
emilymclean Feb 21, 2026
2029412
Make entire checkbox lockup clickable
emilymclean Feb 21, 2026
4d35879
Swap modifier order
emilymclean Feb 21, 2026
2a4900a
Merge pull request #312 from emilymclean/mclean/fix/make-entire-check…
emilymclean Feb 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/build.pkl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extends "package://components.emilym.cl/actions/actions@0.1.16#/common/build-app-support.pkl"
import "package://components.emilym.cl/actions/actions@0.1.16#/common/common.pkl" as common
extends "package://components.emilym.cl/actions/actions@0.1.21#/common/build-app-support.pkl"
import "package://components.emilym.cl/actions/actions@0.1.21#/common/common.pkl" as common

hidden modules: List<String>(length == 0) = List()
hidden extraBuildSteps: Listing<Step>
Expand All @@ -10,6 +10,8 @@ hidden instantVersionNumberOffset = 0
hidden gradleVersionNameName = "version"
hidden gradleVersionCodeName = "versionCode"

hidden javaVersion = "21"

local releaseFileName = "sinatra-${{ matrix.build.name }}-v${{ needs.version.outputs.version }}"
local iosReleaseFileName = "sinatra-iosApp-release-v${{ needs.version.outputs.version }}"

Expand Down Expand Up @@ -62,7 +64,7 @@ function buildJob(
}
steps = new Listing {
common.checkout
common.setupJdk
common.setupJdk(javaVersion)
...extraBuildSteps
new CommandStep {
run = """
Expand Down Expand Up @@ -428,7 +430,7 @@ jobs = new Mapping {
`runs-on` = "macos-latest"
steps = new Listing {
common.checkout
common.setupJdk
common.setupJdk(javaVersion)
new ActionStep {
uses = "ruby/setup-ruby@v1"
with {
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: temurin
- env:
MAPS_API_KEY: ${{ secrets.MAPS_API_KEY }}
Expand Down Expand Up @@ -198,10 +198,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: temurin
- env:
MAPS_API_KEY: ${{ secrets.MAPS_API_KEY }}
Expand Down Expand Up @@ -303,10 +303,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: temurin
- uses: ruby/setup-ruby@v1
with:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/lint.pkl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
amends "package://components.emilym.cl/actions/actions@0.1.16#/common/simple-gradle.pkl"
amends "package://components.emilym.cl/actions/actions@0.1.21#/common/simple-gradle.pkl"

jobName = "lint"
gradleTask = "lintVitalRelease"
name = "Lint"
javaVersion = "21"

extraBuildSteps {
new CommandStep {
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: temurin
- env:
MAPS_API_KEY: ${{ secrets.MAPS_API_KEY }}
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/test.pkl
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
amends "package://components.emilym.cl/actions/actions@0.1.16#/common/simple-gradle.pkl"
amends "package://components.emilym.cl/actions/actions@0.1.21#/common/simple-gradle.pkl"

jobName = "test"
gradleTask = "testDebugUnitTest"
name = "Unit Test"

javaVersion = "21"

modules = List("shared", "ui")
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: temurin
- name: Setup gradle
uses: gradle/actions/setup-gradle@v4
Expand Down
6 changes: 6 additions & 0 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,10 @@ secrets {
defaultPropertiesFileName = "local.defaults.properties"
ignoreList.add("keyToIgnore")
ignoreList.add("sdk.*")
}

kotlin {
compilerOptions {
optIn.add("kotlin.time.ExperimentalTime")
}
}
54 changes: 28 additions & 26 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
[versions]
agp = "8.7.3"
buildkonfigGradlePlugin = "0.17.0"
kotlin = "2.1.10"
compose = "1.7.8"
compose-material3 = "1.3.1"
agp = "8.11.0"
buildkonfigGradlePlugin = "0.17.1"
kotlin = "2.2.0"
compose = "1.10.1"
compose-material3 = "1.3.2"
androidx-activityCompose = "1.10.1"
lifecycleRuntimeCompose = "2.8.7"
mapsCompose = "6.4.1"
mockk = "1.13.16"
lifecycleRuntimeCompose = "2.9.1"
mapsCompose = "6.6.0"
mockk = "1.14.4"
aakira-napier = "2.7.1"
ktorfit = "2.4.0"
ktor = "3.1.0"
compose-adaptive = "1.0.0"
compose-plugin = "1.7.0"
ktorfit = "2.6.1"
ktor = "3.2.1"
compose-adaptive = "1.1.2"
compose-plugin = "1.10.0"
secretsGradlePlugin = "2.0.1"
serializable = "0.1.1"
kotlin-datetime = "0.6.1"
coil-compose = "3.0.0-rc01"
kotlin-datetime = "0.7.1"
coil-compose = "3.2.0"
units = "2.0.3"
requeststate = "2.2.0"
errorwidget = "2.0.2"
errorwidget = "2.0.3"
standardbutton = "2.0.3"
mediacontrol = "0.1.0"
koin = "4.0.0"
koin-annotations = "1.4.0"
kotlinx-serialization = "1.8.0"
koin = "4.1.0"
koin-annotations = "2.0.0-RC1"
kotlinx-serialization = "1.9.0"
pbandk = "0.16.0"
voyager = "1.1.0-beta03"
ksp = "2.1.10-1.0.31"
room = "2.7.0-rc02"
sqlite = "2.5.0-rc02"
ksp = "2.2.0-2.0.2"
room = "2.7.2"
sqlite = "2.5.2"
mokoPermissions = "0.19.1"
playServicesLocation = "21.3.0"
markdown = "0.31.0"
google-services = "4.4.2"
firebase-crashlytics = "3.0.3"
coroutines-test = "1.10.1"
datastore = "1.1.4"
markdown = "0.35.0"
google-services = "4.4.3"
firebase-crashlytics = "3.0.4"
coroutines-test = "1.10.2"
datastore = "1.1.7"
reorderable = "2.5.1"
kotlincrypto = "0.6.0"

Expand Down Expand Up @@ -84,6 +85,7 @@ ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "kto
emily-units = { module = "cl.emilym.compose:units", version.ref = "units" }
emily-serializable = { module = "cl.emilym.kmp:serializable", version.ref = "serializable" }
emily-requeststate = { module = "cl.emilym.compose:requeststate", version.ref = "requeststate" }
emily-standardbutton = { module = "cl.emilym.compose:standardbutton", version.ref = "standardbutton" }
emily-errorwidget = { module = "cl.emilym.compose:errorwidget", version.ref = "errorwidget" }
emily-mediacontrol = { module = "cl.emilym.compose:mediacontrol", version.ref = "mediacontrol" }

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Dec 03 10:07:45 AEDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
44 changes: 18 additions & 26 deletions iosApp/Sinatra.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@
7555FF77242A565900829871 /* Sources */,
7555FF79242A565900829871 /* Resources */,
F8776C6237F0DAB0F9E14335 /* Frameworks */,
2A174906683A2D4FF04FCB57 /* [CP] Copy Pods Resources */,
D8C0013CD90BBDAF4FF00390 /* [CP] Embed Pods Frameworks */,
5144DD9D2D0C2395002C42B2 /* Firebase Crashlytics */,
9D96ECC67CFE83FC450AD8D6 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -185,27 +185,6 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
2A174906683A2D4FF04FCB57 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n";
showEnvVarsInLog = 0;
};
5104D8122D099A1D003C36ED /* Compile Kotlin Framework */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -287,6 +266,23 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9D96ECC67CFE83FC450AD8D6 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n";
showEnvVarsInLog = 0;
};
D8C0013CD90BBDAF4FF00390 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -295,14 +291,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks.sh\"\n";
Expand Down
7 changes: 7 additions & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING
import com.google.devtools.ksp.gradle.KspAATask
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import kotlin.jvm.java

plugins {
alias(libs.plugins.kotlinMultiplatform)
Expand All @@ -13,6 +16,10 @@ plugins {
}

kotlin {
compilerOptions {
optIn.add("kotlin.time.ExperimentalTime")
}

androidTarget {
compilations.all {
compileTaskProvider.configure {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package cl.emilym.sinatra.data.models

import kotlinx.datetime.*
import java.time.temporal.ChronoField
import java.time.temporal.ChronoUnit
import java.time.temporal.TemporalField
import kotlin.test.*
import kotlin.time.Clock
import kotlin.time.Duration.Companion.days

class ServiceTest {
Expand All @@ -13,7 +16,7 @@ class ServiceTest {
private fun dateAt(hour: Int, minute: Int, dayOfWeek: DayOfWeek): Instant {
val today = now.toLocalDateTime(tz).date
val targetDate = today.toJavaLocalDate()
.with(DayOfWeek.MONDAY)
.with(java.time.DayOfWeek.MONDAY)
.plus((dayOfWeek.ordinal).toLong(), ChronoUnit.DAYS)
.toKotlinLocalDate()
return LocalDateTime(targetDate, LocalTime(hour, minute)).toInstant(tz)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,52 @@ class LastDepartureForStopUseCaseTest {
assertEquals(1.hours, result.first().departureTime.durationThroughDay)
}

@Test
fun `invoke prioritizes next day departure before 3am from over current day future departure`() = runTest {
// Given
val todayService = mockk<Service>()
val tomorrowService = mockk<Service>()

val todayFutureDeparture = DefaultStopTimetableTime.copy(
serviceId = "today-service",
routeId = "route1",
heading = "City",
departureTime = Time.create(23.hours) // Future departure today
)

val tomorrowEarlyDeparture = DefaultStopTimetableTime.copy(
serviceId = "tomorrow-service",
routeId = "route1",
heading = "City",
departureTime = Time.create(1.hours) // Future departure tomorrow (before 3am)
)

val servicesAndTimes = createServicesAndTimes(
services = listOf(todayService, tomorrowService),
times = listOf(todayFutureDeparture, tomorrowEarlyDeparture)
)

every { todayService.id } returns "today-service"
every { todayService.active(yesterday, testTimeZone) } returns false
every { todayService.active(today, testTimeZone) } returns true
every { todayService.active(tomorrow, testTimeZone) } returns false

every { tomorrowService.id } returns "tomorrow-service"
every { tomorrowService.active(yesterday, testTimeZone) } returns false
every { tomorrowService.active(today, testTimeZone) } returns false
every { tomorrowService.active(tomorrow, testTimeZone) } returns true

coEvery { servicesAndTimesForStopUseCase(testStopId) } returns servicesAndTimes

// When
val result = useCase(testStopId).first()

// Then
assertEquals(1, result.size)
assertEquals("tomorrow-service", result.first().serviceId)
assertEquals(1.hours, result.first().departureTime.durationThroughDay)
}

@Test
fun `invoke filters out school services when ShowSchoolServices is false`() = runTest {
// Given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ import org.koin.dsl.module
class SharedModule

val manualModule = module {
factory<Clock> { Clock.System }
factory<Clock> { kotlin.time.Clock.System }
}
Loading