Refactor/compose multiplatform - #12
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR refactors the iOS app to use Jetpack Compose Multiplatform, removes legacy SwiftUI code, and standardizes ViewModel implementations and DI across platforms.
- Migrated all iOS UI screens from SwiftUI to Compose Multiplatform and removed obsolete Swift code.
- Updated Koin modules (
SwiftModule,SharedModule) to register new settings and environment providers. - Refactored common ViewModels to use
androidx.lifecycle.ViewModel,viewModelScope, andMutableStateFlow, dropping KMP Native Coroutines annotations.
Reviewed Changes
Copilot reviewed 133 out of 145 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| shared/src/iosMain/kotlin/com/extopy/extensions/NumbersExtension.ios.kt | Added iOS-specific Double.simplify() implementation |
| shared/src/iosMain/kotlin/com/extopy/extensions/DatetimeExtension.ios.kt | Added iOS-specific Instant.timeAgo implementation |
| shared/src/iosMain/kotlin/com/extopy/di/SwiftModule.kt | Enhanced native settings DI and environment selection |
| shared/src/commonMain/kotlin/com/extopy/viewmodels/…ViewModel.kt | Converted to ViewModel subclasses and MutableStateFlow |
| shared/src/commonMain/kotlin/com/extopy/di/SharedModule.kt | Registered SettingsViewModel in shared DI module |
| ios/Extopy/UI/… | Removed all legacy SwiftUI view and extension files |
| android/src/.../values-*/strings.xml | Cleaned up obsolete string resources |
Comments suppressed due to low confidence (5)
shared/src/commonMain/kotlin/com/extopy/viewmodels/users/ProfileViewModel.kt:1
- ProfileViewModel uses viewModelScope but does not extend androidx.lifecycle.ViewModel; update the class signature to
class ProfileViewModel : ViewModel()to ensure viewModelScope is available.
package com.extopy.viewmodels.users
shared/src/commonMain/kotlin/com/extopy/viewmodels/timelines/TimelineViewModel.kt:1
- TimelineViewModel imports ViewModel and viewModelScope but does not extend ViewModel; change to
class TimelineViewModel : ViewModel().
package com.extopy.viewmodels.timelines
shared/src/commonMain/kotlin/com/extopy/viewmodels/timelines/SearchViewModel.kt:1
- SearchViewModel references viewModelScope but does not extend androidx.lifecycle.ViewModel; update the class to extend ViewModel for proper lifecycle support.
package com.extopy.viewmodels.timelines
shared/src/commonMain/kotlin/com/extopy/extensions/NumbersExtension.kt:25
- Add unit tests for
simplify()covering edge cases (e.g., large numbers, exact integers, rounding) to ensure consistent formatting across platforms.
expect fun Double.simplify(): String
shared/src/commonMain/kotlin/com/extopy/extensions/DatetimeExtension.kt:5
- Introduce tests for
timeAgologic, particularly the fallback to absolute dates, to validate behavior across different time intervals and locales.
expect val Instant.timeAgo: String
| if (get<ExtopyEnvironment>() == ExtopyEnvironment.DEVELOPMENT) "group.me.nathanfallet.Extopy.dev" | ||
| else "group.me.nathanfallet.Extopy" |
There was a problem hiding this comment.
[nitpick] Consider extracting the application-group identifiers into constants to avoid duplication and reduce the risk of typos.
| if (get<ExtopyEnvironment>() == ExtopyEnvironment.DEVELOPMENT) "group.me.nathanfallet.Extopy.dev" | |
| else "group.me.nathanfallet.Extopy" | |
| if (get<ExtopyEnvironment>() == ExtopyEnvironment.DEVELOPMENT) DEVELOPMENT_GROUP_IDENTIFIER | |
| else PRODUCTION_GROUP_IDENTIFIER |
| //navigate("timelines/users/${user.id}/followers") | ||
| }, | ||
| onFollowingClicked = { user -> | ||
| navigate.invoke("timelines/users/${user.id}/following") | ||
| //navigate("timelines/users/${user.id}/following") |
There was a problem hiding this comment.
[nitpick] Remove or implement this commented-out navigation path for followers to keep the codebase clean and avoid confusion.
| // Methods | ||
|
|
||
| fun handleAccountClick(account: User) { | ||
|
|
There was a problem hiding this comment.
The handleAccountClick method is empty; either implement its logic or add a // TODO: comment to clarify intended behavior.
| // TODO: Implement logic to handle account click events, such as navigation or updating account details. |
No description provided.