Skip to content
This repository was archived by the owner on Aug 11, 2025. It is now read-only.

Commit 5c07aa2

Browse files
Fix issue 2666 - Releases Screen (#2667)
* WIP: Setup the new Releases Screen * WIP: ReleasesScreen's UI * WIP: ReleasesDataSource and ReleasesViewModel * Refactor ReleasesViewModel * Improve UI * Improve UI * Connect ReleasesScreen to be accessed in SettingsScreen * Connect ReleasesScreen to be accessed in SettingsScreen through a button * Improve UI and add logic for displaying commits * Improve UI * Refactor ReleasesViewModel * Support open release from the ReleaseInfoCard in the browser * WIP: Error state * Refactor ReleasesScreen * Refactor ReleasesViewModel * Resolve PR feedback about names and add comment on one function for better understanding * Resolve PR feedback - use .map instead of for loop in toCommitsList function * Resolve PR feedback about event's name * Resolve PR feedback - add tests for ReleasesContentParser class's functions * Resolve PR feedback - make fetchReleaseInfo in ReleasesViewModel function to do only side-effects * Resolve PR feedback - make onTryAgainClick in ReleasesViewModel function to do only side-effects * Resolve PR feedback - change iconPadding of ReleasesScreen button * Resolve PR feedback - refactor ReleasesScreen * Resolve PR feedback - refactor ReleasesScreen * Resolve PR feedback - improve Releases Screen's UI * Fix Detekt issues * Fix Detekt issues * Fix Detekt issues * Fix Detekt issues * Update Lint baseline * Update module lint baseline
1 parent 2ee680d commit 5c07aa2

File tree

16 files changed

+502
-87
lines changed

16 files changed

+502
-87
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ dependencies {
158158
implementation(projects.screenMain)
159159
implementation(projects.screenHome)
160160
implementation(projects.screenContributors)
161+
implementation(projects.screenReleases)
161162

162163
implementation(libs.bundles.kotlin)
163164
implementation(libs.bundles.ktor)

app/lint-baseline.xml

Lines changed: 5 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -45,72 +45,6 @@
4545
column="20"/>
4646
</issue>
4747

48-
<issue
49-
id="GradleDependency"
50-
message="A newer version of androidx.compose.material3:material3 than 1.1.1 is available: 1.1.2"
51-
errorLine1="compose-material3 = &quot;1.1.1&quot;"
52-
errorLine2=" ~~~~~~~">
53-
<location
54-
file="../gradle/libs.versions.toml"
55-
line="10"
56-
column="21"/>
57-
</issue>
58-
59-
<issue
60-
id="GradleDependency"
61-
message="A newer version of androidx.compose.material3:material3-window-size-class than 1.1.1 is available: 1.1.2"
62-
errorLine1="compose-material3 = &quot;1.1.1&quot;"
63-
errorLine2=" ~~~~~~~">
64-
<location
65-
file="../gradle/libs.versions.toml"
66-
line="10"
67-
column="21"/>
68-
</issue>
69-
70-
<issue
71-
id="GradleDependency"
72-
message="A newer version of androidx.room:room-compiler than 2.6.0-beta01 is available: 2.6.0-rc01"
73-
errorLine1="room = &quot;2.6.0-beta01&quot;"
74-
errorLine2=" ~~~~~~~~~~~~~~">
75-
<location
76-
file="../gradle/libs.versions.toml"
77-
line="13"
78-
column="8"/>
79-
</issue>
80-
81-
<issue
82-
id="GradleDependency"
83-
message="A newer version of androidx.room:room-ktx than 2.6.0-beta01 is available: 2.6.0-rc01"
84-
errorLine1="room = &quot;2.6.0-beta01&quot;"
85-
errorLine2=" ~~~~~~~~~~~~~~">
86-
<location
87-
file="../gradle/libs.versions.toml"
88-
line="13"
89-
column="8"/>
90-
</issue>
91-
92-
<issue
93-
id="GradleDependency"
94-
message="A newer version of androidx.room:room-runtime than 2.6.0-beta01 is available: 2.6.0-rc01"
95-
errorLine1="room = &quot;2.6.0-beta01&quot;"
96-
errorLine2=" ~~~~~~~~~~~~~~">
97-
<location
98-
file="../gradle/libs.versions.toml"
99-
line="13"
100-
column="8"/>
101-
</issue>
102-
103-
<issue
104-
id="GradleDependency"
105-
message="A newer version of androidx.activity:activity-ktx than 1.8.0-beta01 is available: 1.8.0-rc01"
106-
errorLine1="androidx-activity = { module = &quot;androidx.activity:activity-ktx&quot;, version = &quot;1.8.0-beta01&quot; }"
107-
errorLine2=" ~~~~~~~~~~~~~~">
108-
<location
109-
file="../gradle/libs.versions.toml"
110-
line="103"
111-
column="76"/>
112-
</issue>
113-
11448
<issue
11549
id="PrivateResource"
11650
message="Overriding `@string/selected` which is marked as private in androidx.compose.ui:ui-android:1.5.1. If deliberate, use tools:override=&quot;true&quot;, otherwise pick a different name."
@@ -7489,17 +7423,6 @@
74897423
column="1"/>
74907424
</issue>
74917425

7492-
<issue
7493-
id="UnusedResources"
7494-
message="The resource `R.drawable.ic_vue_money_tag` appears to be unused"
7495-
errorLine1="&lt;vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
7496-
errorLine2="^">
7497-
<location
7498-
file="../ivy-resources/src/main/res/drawable/ic_vue_money_tag.xml"
7499-
line="1"
7500-
column="1"/>
7501-
</issue>
7502-
75037426
<issue
75047427
id="UnusedResources"
75057428
message="The resource `R.drawable.ic_vue_money_ticket` appears to be unused"
@@ -9545,7 +9468,7 @@
95459468
errorLine2="^">
95469469
<location
95479470
file="src/main/java/com/ivy/settings/SettingsScreen.kt"
9548-
line="770"
9471+
line="781"
95499472
column="1"/>
95509473
</issue>
95519474

@@ -9556,7 +9479,7 @@
95569479
errorLine2="^">
95579480
<location
95589481
file="src/main/java/com/ivy/settings/SettingsScreen.kt"
9559-
line="1039"
9482+
line="1050"
95609483
column="1"/>
95619484
</issue>
95629485

@@ -11481,7 +11404,7 @@
1148111404
errorLine2="^">
1148211405
<location
1148311406
file="src/main/java/com/ivy/settings/SettingsScreen.kt"
11484-
line="770"
11407+
line="781"
1148511408
column="1"/>
1148611409
</issue>
1148711410

@@ -11492,7 +11415,7 @@
1149211415
errorLine2="^">
1149311416
<location
1149411417
file="src/main/java/com/ivy/settings/SettingsScreen.kt"
11495-
line="1039"
11418+
line="1050"
1149611419
column="1"/>
1149711420
</issue>
1149811421

@@ -11580,7 +11503,7 @@
1158011503
errorLine2=" ~~~~~~~~~~~~~">
1158111504
<location
1158211505
file="src/main/java/com/ivy/legacy/frp/OnScreenStart.kt"
11583-
line="10"
11506+
line="11"
1158411507
column="5"/>
1158511508
</issue>
1158611509

app/src/main/java/com/ivy/IvyNavGraph.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import com.ivy.navigation.MainScreen
3434
import com.ivy.navigation.OnboardingScreen
3535
import com.ivy.navigation.PieChartStatisticScreen
3636
import com.ivy.navigation.PlannedPaymentsScreen
37+
import com.ivy.navigation.ReleasesScreen
3738
import com.ivy.navigation.ReportScreen
3839
import com.ivy.navigation.Screen
3940
import com.ivy.navigation.SearchScreen
@@ -42,6 +43,7 @@ import com.ivy.onboarding.OnboardingScreen
4243
import com.ivy.piechart.PieChartStatisticScreen
4344
import com.ivy.planned.edit.EditPlannedScreen
4445
import com.ivy.planned.list.PlannedPaymentsScreen
46+
import com.ivy.releases.ReleasesScreenImpl
4547
import com.ivy.reports.ReportScreen
4648
import com.ivy.search.SearchScreen
4749
import com.ivy.settings.SettingsScreen
@@ -78,5 +80,6 @@ fun BoxWithConstraintsScope.IvyNavGraph(screen: Screen?) {
7880
FeaturesScreen -> FeaturesScreenImpl()
7981
AttributionsScreen -> AttributionsScreenImpl()
8082
ContributorsScreen -> ContributorsScreenImpl()
83+
ReleasesScreen -> ReleasesScreenImpl()
8184
}
8285
}

ivy-navigation/src/main/java/com/ivy/navigation/Screens.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,6 @@ data object FeaturesScreen : Screen
138138

139139
data object AttributionsScreen : Screen
140140

141-
data object ContributorsScreen : Screen
141+
data object ContributorsScreen : Screen
142+
143+
data object ReleasesScreen : Screen

screen-releases/build.gradle.kts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
plugins {
2+
id("ivy.feature")
3+
}
4+
5+
android {
6+
namespace = "com.ivy.releases"
7+
}
8+
9+
dependencies {
10+
implementation(projects.ivyCore)
11+
implementation(projects.ivyResources)
12+
implementation(projects.ivyDesign)
13+
implementation(projects.ivyNavigation)
14+
implementation(projects.ivyCoreUi)
15+
16+
implementation(libs.bundles.ktor)
17+
}

screen-releases/lint-baseline.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<issues format="6" by="lint 8.1.1" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.1)" variant="all" version="8.1.1">
3+
4+
</issues>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.ivy.releases
2+
3+
import kotlinx.collections.immutable.ImmutableList
4+
5+
data class ReleaseInfo(
6+
val releaseName: String,
7+
val releaseUrl: String,
8+
val releaseDate: String,
9+
val releaseCommits: ImmutableList<String>
10+
)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.ivy.releases
2+
3+
import kotlinx.collections.immutable.ImmutableList
4+
import kotlinx.collections.immutable.persistentListOf
5+
import kotlinx.collections.immutable.toImmutableList
6+
import javax.inject.Inject
7+
8+
class ReleasesContentParser @Inject constructor() {
9+
fun toCommitsList(commits: String?): ImmutableList<String> {
10+
if (commits.isNullOrBlank()) return persistentListOf()
11+
val commitsList = commits.split("\n")
12+
13+
return commitsList.map { commit ->
14+
// remove " -"
15+
commit.drop(2).trim()
16+
}.toImmutableList()
17+
}
18+
19+
companion object {
20+
private const val REDUNDANT_CHARS_COUNT = 10
21+
}
22+
23+
fun toReleaseDate(date: String): String {
24+
// e.g. transforms original "2023-09-16T17:42:08Z" into "2023-09-16"
25+
return date.dropLast(REDUNDANT_CHARS_COUNT)
26+
}
27+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.ivy.releases
2+
3+
import androidx.annotation.Keep
4+
import io.ktor.client.HttpClient
5+
import io.ktor.client.call.body
6+
import io.ktor.client.request.get
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.withContext
9+
import kotlinx.serialization.SerialName
10+
import kotlinx.serialization.Serializable
11+
import javax.inject.Inject
12+
13+
class ReleasesDataSource @Inject constructor(
14+
private val httpClient: HttpClient
15+
) {
16+
17+
@Keep
18+
@Serializable
19+
data class ReleaseDto(
20+
@SerialName("tag_name")
21+
val releaseName: String,
22+
@SerialName("html_url")
23+
val releaseUrl: String,
24+
@SerialName("published_at")
25+
val releaseDate: String,
26+
@SerialName("body")
27+
val commits: String?
28+
)
29+
30+
suspend fun fetchReleaseInfo(): List<ReleaseDto>? {
31+
return try {
32+
withContext(Dispatchers.IO) {
33+
httpClient.get("https://api.github.com/repos/Ivy-Apps/ivy-wallet/releases")
34+
.body<List<ReleaseDto>?>()
35+
}
36+
} catch (e: Exception) {
37+
null
38+
}
39+
}
40+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.ivy.releases
2+
3+
sealed interface ReleasesEvent {
4+
data object OnTryAgainClick : ReleasesEvent
5+
}

0 commit comments

Comments
 (0)