diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index e004982..4789362 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -18,6 +18,7 @@ jobs:
build:
# The type of runner that the job will run on
runs-on: macos-latest
+ timeout-minutes: 120
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
@@ -30,6 +31,9 @@ jobs:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '17'
+ - name: Setup Android SDK
+ uses: android-actions/setup-android@v3
+
- name: Grant execute permission for gradlew
run: chmod +x gradlew
@@ -45,30 +49,15 @@ jobs:
fileDir: './'
encodedString: ${{ secrets.SIGNING_KEY }}
- - name: Generate baseline profile
- uses: reactivecircus/android-emulator-runner@v2
- with:
- api-level: 33
- avd-name: baselineProfGenerator
- target: google_apis
- arch: x86_64
- emulator-build: 9322596
- script: ./gradlew :benchmark:connectedBenchmarkAndroidTest -P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile
-
- - name: Move generated baseline profile to target folder
- run: mv -f './benchmark/build/outputs/connected_android_test_additional_output/benchmark/connected/baselineProfGenerator(AVD) - 13/BaselineProfileGenerator_generate-baseline-prof.txt' ./app/src/main/baseline-prof.txt
-
- - name: Check baseline-prof file status
- run: stat ./app/src/main/baseline-prof.txt
-
- - name: View some lines of baseline-prof file
- run: head ./app/src/main/baseline-prof.txt
-
- - name: Build with Gradle
- run: ./gradlew assemble
+ - name: Build release variant including baseline profile generation
+ run: ./gradlew :app:assembleRelease
+ -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile
+ -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
+ -Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true
+ -Pandroid.experimental.androidTest.numManagedDeviceShards=1
+ -Pandroid.experimental.testOptions.managedDevices.maxConcurrentDevices=1
- name: Build Release AAB
- id: buildRelease
run: ./gradlew bundleRelease
- name: Upload Android Release to Play Store
diff --git a/.gitignore b/.gitignore
index c567692..c44e4c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,7 +78,7 @@ captures/
*.keystore
# Google Services (e.g. APIs or Firebase)
-google-services.json
+# google-services.json
# Android Patch
gen-external-apklibs
@@ -120,6 +120,8 @@ obj/
.idea/jarRepositories.xml
.idea/navEditor.xml
.idea/inspectionProfiles
+.idea/appInsightsSettings.xml
+.idea/deploymentTargetDropDown.xml
# Legacy Eclipse project files
.classpath
diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml
new file mode 100644
index 0000000..23504e4
--- /dev/null
+++ b/.idea/appInsightsSettings.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index ea9dbd0..0c0c338 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -1,17 +1,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..ae3f30a
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/baseline-profiles-rules.pro b/app/baseline-profiles-rules.pro
deleted file mode 100644
index 0674e77..0000000
--- a/app/baseline-profiles-rules.pro
+++ /dev/null
@@ -1 +0,0 @@
--dontobfuscate
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index aa143c7..1fb13e6 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,16 +1,17 @@
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
- id("jumpkking.android.application")
- id("jumpkking.android.application.compose")
- id("jumpkking.android.hilt")
+ alias(libs.plugins.jumpkking.android.application)
+ alias(libs.plugins.jumpkking.android.application.compose)
+ alias(libs.plugins.jumpkking.android.hilt)
alias(libs.plugins.gms.google.services)
id("kotlin-parcelize")
alias(libs.plugins.firebase.crashlytics)
+ alias(libs.plugins.androidx.baselineprofile)
}
kotlin {
jvmToolchain {
- languageVersion.set(JavaLanguageVersion.of(11))
+ languageVersion.set(JavaLanguageVersion.of(17))
}
}
@@ -19,8 +20,9 @@ android {
defaultConfig {
applicationId = "com.joeloewi.jumpkking"
- versionCode = 14
- versionName = "1.0.14"
+ versionCode = 15
+ versionName = "1.0.15"
+ targetSdk = 34
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@@ -50,14 +52,6 @@ android {
)
signingConfig = signingConfigs.getByName("release")
}
-
- val benchmark by creating {
- initWith(release)
- signingConfig = signingConfigs.getByName("release")
- matchingFallbacks += listOf("release")
- isDebuggable = false
- proguardFiles("baseline-profiles-rules.pro")
- }
}
packaging {
@@ -67,6 +61,10 @@ android {
}
}
+baselineProfile {
+ automaticGenerationDuringBuild = true
+}
+
dependencies {
implementation(project(":data"))
implementation(project(":domain"))
@@ -92,11 +90,9 @@ dependencies {
//hilt
implementation(libs.hilt.android)
- kapt(libs.hilt.compiler)
//hilt-extension
implementation(libs.hilt.ext.work)
- kapt(libs.hilt.ext.compiler)
//compose
implementation(libs.androidx.compose.foundation)
@@ -140,9 +136,9 @@ dependencies {
///firebase
implementation(platform(libs.firebase.bom))
- implementation(libs.firebase.analytics.ktx)
- implementation(libs.firebase.crashlytics.ktx)
- implementation(libs.firebase.firestore.ktx)
+ implementation(libs.firebase.analytics)
+ implementation(libs.firebase.crashlytics)
+ implementation(libs.firebase.firestore)
implementation(libs.tts)
@@ -154,8 +150,6 @@ dependencies {
implementation(libs.kotlinx.coroutines.rx3)
implementation(libs.androidx.profileinstaller)
-}
-hilt {
- enableAggregatingTask = true
+ implementation(libs.kotlinx.collections.immutable)
}
\ No newline at end of file
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..038cae4
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,29 @@
+{
+ "project_info": {
+ "project_number": "YourProjectId",
+ "project_id": "abc",
+ "storage_bucket": "abc"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "Your:App:Id",
+ "android_client_info": {
+ "package_name": "com.joeloewi.jumpkking"
+ }
+ },
+ "oauth_client": [],
+ "api_key": [
+ {
+ "current_key": "APlaceholderAPIKeyWith-ThirtyNineCharsX"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": []
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/joeloewi/jumpkking/ExampleInstrumentedTest.kt b/app/src/androidTest/kotlin/com/joeloewi/jumpkking/ExampleInstrumentedTest.kt
similarity index 100%
rename from app/src/androidTest/java/com/joeloewi/jumpkking/ExampleInstrumentedTest.kt
rename to app/src/androidTest/kotlin/com/joeloewi/jumpkking/ExampleInstrumentedTest.kt
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9e108b7..d1e5e6e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -22,15 +22,9 @@
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
-
-
-
-
diff --git a/app/src/main/java/com/joeloewi/jumpkking/di/UseCaseModule.kt b/app/src/main/java/com/joeloewi/jumpkking/di/UseCaseModule.kt
deleted file mode 100644
index 6521231..0000000
--- a/app/src/main/java/com/joeloewi/jumpkking/di/UseCaseModule.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.joeloewi.jumpkking.di
-
-import com.joeloewi.domain.repository.FirebaseAuthRepository
-import com.joeloewi.domain.repository.ReportCardRepository
-import com.joeloewi.domain.repository.ValuesRepository
-import com.joeloewi.domain.usecase.FirebaseAuthUseCase
-import com.joeloewi.domain.usecase.ReportCardUseCase
-import com.joeloewi.domain.usecase.ValuesUseCase
-import dagger.Module
-import dagger.Provides
-import dagger.hilt.InstallIn
-import dagger.hilt.components.SingletonComponent
-import javax.inject.Singleton
-
-@Module
-@InstallIn(SingletonComponent::class)
-object UseCaseModule {
-
- @Provides
- @Singleton
- fun provideGetValuesUseCase(valuesRepository: ValuesRepository): ValuesUseCase.GetValues =
- ValuesUseCase.GetValues(valuesRepository)
-
- @Provides
- @Singleton
- fun provideSetJumpCountValuesUseCase(valuesRepository: ValuesRepository): ValuesUseCase.SetJumpCount =
- ValuesUseCase.SetJumpCount(valuesRepository)
-
- @Provides
- @Singleton
- fun provideGetAllPagedReportCardUseCase(reportCardRepository: ReportCardRepository): ReportCardUseCase.GetAllPaged =
- ReportCardUseCase.GetAllPaged(reportCardRepository)
-
- @Provides
- @Singleton
- fun provideInsertReportCardUseCase(reportCardRepository: ReportCardRepository): ReportCardUseCase.Insert =
- ReportCardUseCase.Insert(reportCardRepository)
-
- @Provides
- @Singleton
- fun provideGetOneReportCardUseCase(reportCardRepository: ReportCardRepository): ReportCardUseCase.GetOne =
- ReportCardUseCase.GetOne(reportCardRepository)
-
- @Provides
- @Singleton
- fun provideGetCurrentUserFirebaseAuthUseCase(firebaseAuthRepository: FirebaseAuthRepository): FirebaseAuthUseCase.GetCurrentUser =
- FirebaseAuthUseCase.GetCurrentUser(firebaseAuthRepository)
-
- @Provides
- @Singleton
- fun provideSignInAnonymouslyFirebaseAuthUseCase(firebaseAuthRepository: FirebaseAuthRepository): FirebaseAuthUseCase.SignInAnonymously =
- FirebaseAuthUseCase.SignInAnonymously(firebaseAuthRepository)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/initializer/ComposeViewInitializer.kt b/app/src/main/java/com/joeloewi/jumpkking/initializer/ComposeViewInitializer.kt
deleted file mode 100644
index c3a12bd..0000000
--- a/app/src/main/java/com/joeloewi/jumpkking/initializer/ComposeViewInitializer.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.joeloewi.jumpkking.initializer
-
-import android.content.Context
-import androidx.compose.ui.platform.ComposeView
-import androidx.lifecycle.ProcessLifecycleInitializer
-import androidx.startup.Initializer
-
-class ComposeViewInitializer : Initializer {
- override fun create(context: Context): ComposeView {
- return ComposeView(context)
- }
-
- override fun dependencies(): MutableList>> = mutableListOf(
- ProcessLifecycleInitializer::class.java
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/state/FriendsState.kt b/app/src/main/java/com/joeloewi/jumpkking/state/FriendsState.kt
deleted file mode 100644
index b8a1594..0000000
--- a/app/src/main/java/com/joeloewi/jumpkking/state/FriendsState.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.joeloewi.jumpkking.state
-
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.remember
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.navigation.NavController
-import com.google.firebase.crashlytics.internal.model.ImmutableList
-import com.joeloewi.jumpkking.ui.navigation.friends.FriendsDestination
-import com.joeloewi.jumpkking.viewmodel.FriendsViewModel
-
-@Stable
-class FriendsState(
- private val navController: NavController,
- val friends: ImmutableList,
- private val friendsViewModel: FriendsViewModel
-) {
- val insertReportCardState
- @Composable get() = friendsViewModel.insertReportCardState.collectAsStateWithLifecycle().value
-
- val jumpCount
- @Composable get() = friendsViewModel.jumpCount.collectAsStateWithLifecycle().value
-
- val textToSpeech
- @Composable get() = friendsViewModel.textToSpeech.collectAsStateWithLifecycle().value
-
- fun increaseJumpCount() {
- friendsViewModel.increaseJumpCount()
- }
-
- fun onViewRankingButtonClick() {
- navController.navigate(FriendsDestination.RankingScreen.route)
- }
-}
-
-enum class Friend {
- Hamster, Cat
-}
-
-@Composable
-fun rememberFriendsState(
- navController: NavController,
- friends: ImmutableList = ImmutableList.from(*Friend.values()),
- friendsViewModel: FriendsViewModel
-) = remember(
- navController,
- friends,
- friendsViewModel
-) {
- FriendsState(
- navController = navController,
- friends = friends,
- friendsViewModel = friendsViewModel
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/state/RankingState.kt b/app/src/main/java/com/joeloewi/jumpkking/state/RankingState.kt
deleted file mode 100644
index 06ae002..0000000
--- a/app/src/main/java/com/joeloewi/jumpkking/state/RankingState.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.joeloewi.jumpkking.state
-
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.remember
-import androidx.navigation.NavController
-import androidx.paging.compose.collectAsLazyPagingItems
-import com.joeloewi.jumpkking.viewmodel.RankingViewModel
-import kotlinx.coroutines.Dispatchers
-
-@Stable
-class RankingState(
- private val navController: NavController,
- private val rankingViewModel: RankingViewModel
-) {
- val androidId: String
- get() = rankingViewModel.androidId
-
- val pagedReportCards
- @Composable get() = rankingViewModel.pagedReportCards.collectAsLazyPagingItems(Dispatchers.IO)
-
- fun onCloseButtonClick() {
- navController.navigateUp()
- }
-}
-
-@Composable
-fun rememberRankingState(
- navController: NavController,
- rankingViewModel: RankingViewModel
-) = remember(
- navController,
- rankingViewModel
-) {
- RankingState(
- navController = navController,
- rankingViewModel = rankingViewModel
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/ui/theme/Theme.kt b/app/src/main/java/com/joeloewi/jumpkking/ui/theme/Theme.kt
deleted file mode 100644
index 21f218c..0000000
--- a/app/src/main/java/com/joeloewi/jumpkking/ui/theme/Theme.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.joeloewi.jumpkking.ui.theme
-
-import android.view.Window
-import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.SideEffect
-import androidx.compose.ui.platform.LocalView
-import androidx.core.view.WindowCompat
-import com.google.accompanist.themeadapter.material3.Mdc3Theme
-
-@Composable
-fun JumpKkingTheme(
- window: Window,
- content: @Composable () -> Unit
-) {
- val useDarkIcons = !isSystemInDarkTheme()
- val view = LocalView.current
-
- if (!view.isInEditMode) {
- SideEffect {
- WindowCompat.setDecorFitsSystemWindows(window, false)
- WindowCompat.getInsetsController(window, view).apply {
- isAppearanceLightStatusBars = useDarkIcons
- isAppearanceLightNavigationBars = useDarkIcons
- }
- }
- }
-
- Mdc3Theme(
- content = content
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/JumpKkingApplication.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/JumpKkingApplication.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/JumpKkingApplication.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/JumpKkingApplication.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/MainActivity.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/MainActivity.kt
similarity index 87%
rename from app/src/main/java/com/joeloewi/jumpkking/MainActivity.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/MainActivity.kt
index 3a770ca..f1fd0a1 100644
--- a/app/src/main/java/com/joeloewi/jumpkking/MainActivity.kt
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/MainActivity.kt
@@ -2,6 +2,7 @@ package com.joeloewi.jumpkking
import android.os.Bundle
import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.shape.CornerSize
@@ -17,7 +18,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
-import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
@@ -37,9 +37,7 @@ import com.joeloewi.jumpkking.ui.navigation.friends.screen.FriendsScreen
import com.joeloewi.jumpkking.ui.navigation.friends.screen.RankingScreen
import com.joeloewi.jumpkking.ui.theme.JumpKkingTheme
import com.joeloewi.jumpkking.util.LocalActivity
-import com.joeloewi.jumpkking.viewmodel.FriendsViewModel
import com.joeloewi.jumpkking.viewmodel.MainViewModel
-import com.joeloewi.jumpkking.viewmodel.RankingViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
@@ -53,6 +51,9 @@ class MainActivity : AppCompatActivity() {
val splashScreen = installSplashScreen()
super.onCreate(savedInstanceState)
+ DynamicColors.applyToActivityIfAvailable(this)
+ enableEdgeToEdge()
+
var currentUser by mutableStateOf>(Lce.Loading)
lifecycleScope.launch {
@@ -67,12 +68,8 @@ class MainActivity : AppCompatActivity() {
currentUser.isLoading
}
- DynamicColors.applyToActivityIfAvailable(this)
-
setContent {
- JumpKkingTheme(
- window = window
- ) {
+ JumpKkingTheme {
CompositionLocalProvider(LocalActivity provides this) {
JumpKkingApp()
}
@@ -90,6 +87,7 @@ fun JumpKkingApp() {
)
val bottomSheetNavigator = remember(sheetState) { BottomSheetNavigator(sheetState) }
val navController = rememberNavController(bottomSheetNavigator)
+ val activity = LocalActivity.current
ModalBottomSheetLayout(
sheetShape = MaterialTheme.shapes.large.copy(
@@ -103,7 +101,7 @@ fun JumpKkingApp() {
) {
NavHost(
navController = navController,
- route = "main",
+ route = activity::class.java.simpleName,
startDestination = JumpKkingNavigation.Friends.route
) {
navigation(
@@ -111,20 +109,18 @@ fun JumpKkingApp() {
route = JumpKkingNavigation.Friends.route
) {
composable(route = FriendsDestination.FriendsScreen.route) {
- val friendsViewModel: FriendsViewModel = hiltViewModel()
-
FriendsScreen(
- navController = navController,
- friendsViewModel = friendsViewModel
+ onViewRankingButtonClick = {
+ navController.navigate(FriendsDestination.RankingScreen.route)
+ }
)
}
bottomSheet(route = FriendsDestination.RankingScreen.route) {
- val rankingViewModel: RankingViewModel = hiltViewModel()
-
RankingScreen(
- navController = navController,
- rankingViewModel = rankingViewModel
+ onCloseButtonClick = {
+ navController.navigateUp()
+ }
)
}
}
diff --git a/app/src/main/java/com/joeloewi/jumpkking/di/InitializerEntryPoint.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/di/InitializerEntryPoint.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/di/InitializerEntryPoint.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/di/InitializerEntryPoint.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/di/UtilModule.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/di/UtilModule.kt
similarity index 67%
rename from app/src/main/java/com/joeloewi/jumpkking/di/UtilModule.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/di/UtilModule.kt
index e592e58..0219531 100644
--- a/app/src/main/java/com/joeloewi/jumpkking/di/UtilModule.kt
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/di/UtilModule.kt
@@ -7,12 +7,19 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
+import nl.marc_apps.tts.TextToSpeechEngine
+import nl.marc_apps.tts.TextToSpeechFactory
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
class UtilModule {
+ @Provides
+ fun provideTextToSpeechFactory(
+ @ApplicationContext context: Context
+ ): TextToSpeechFactory = TextToSpeechFactory(context, TextToSpeechEngine.SystemDefault)
+
@Provides
@Singleton
fun provideImageLoader(@ApplicationContext context: Context): ImageLoader =
diff --git a/app/src/main/java/com/joeloewi/jumpkking/initializer/CoilInitializer.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/initializer/CoilInitializer.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/initializer/CoilInitializer.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/initializer/CoilInitializer.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/initializer/DynamicColorInitializer.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/initializer/DynamicColorInitializer.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/initializer/DynamicColorInitializer.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/initializer/DynamicColorInitializer.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/state/Lce.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/state/Lce.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/state/Lce.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/state/Lce.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/ui/navigation/JumpKkingNavigation.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/JumpKkingNavigation.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/ui/navigation/JumpKkingNavigation.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/JumpKkingNavigation.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/FriendsDestination.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/FriendsDestination.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/FriendsDestination.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/FriendsDestination.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/screen/FriendsScreen.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/screen/FriendsScreen.kt
similarity index 66%
rename from app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/screen/FriendsScreen.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/screen/FriendsScreen.kt
index 684e8a5..6f4a2f4 100644
--- a/app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/screen/FriendsScreen.kt
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/screen/FriendsScreen.kt
@@ -1,37 +1,70 @@
package com.joeloewi.jumpkking.ui.navigation.friends.screen
-import androidx.compose.animation.*
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.SizeTransform
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.slideInVertically
+import androidx.compose.animation.slideOutVertically
+import androidx.compose.animation.togetherWith
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.absoluteOffset
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PageSize
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Leaderboard
-import androidx.compose.material3.*
-import androidx.compose.runtime.*
+import androidx.compose.material3.Card
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarDuration
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.composed
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.navigation.NavController
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.google.accompanist.pager.HorizontalPagerIndicator
import com.joeloewi.jumpkking.R
-import com.joeloewi.jumpkking.state.Friend
-import com.joeloewi.jumpkking.state.FriendsState
import com.joeloewi.jumpkking.state.Lce
-import com.joeloewi.jumpkking.state.rememberFriendsState
-import com.joeloewi.jumpkking.util.*
+import com.joeloewi.jumpkking.util.RoundTripState
+import com.joeloewi.jumpkking.util.RoundTripValue
+import com.joeloewi.jumpkking.util.animateRoundTripByDpAsState
+import com.joeloewi.jumpkking.util.castToQuotaReachedExceptionAndGetMessage
+import com.joeloewi.jumpkking.util.rememberRoundTripState
+import com.joeloewi.jumpkking.viewmodel.Friend
import com.joeloewi.jumpkking.viewmodel.FriendsViewModel
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import nl.marc_apps.tts.TextToSpeechInstance
@@ -39,35 +72,39 @@ import java.text.DecimalFormat
@Composable
fun FriendsScreen(
- navController: NavController,
+ onViewRankingButtonClick: () -> Unit,
friendsViewModel: FriendsViewModel = hiltViewModel()
) {
- val friendsState = rememberFriendsState(
- navController = navController,
- friendsViewModel = friendsViewModel
- )
+ val jumpCount by friendsViewModel.jumpCount.collectAsStateWithLifecycle()
+ val textToSpeech by friendsViewModel.textToSpeech.collectAsStateWithLifecycle()
+ val insertReportCardState by friendsViewModel.insertReportCardState.collectAsStateWithLifecycle()
- FriendsContent(friendsState = friendsState)
+ FriendsContent(
+ jumpCount = { jumpCount },
+ textToSpeech = { textToSpeech },
+ insertReportCardState = { insertReportCardState },
+ onViewRankingButtonClick = onViewRankingButtonClick,
+ onCountChange = friendsViewModel::increaseJumpCount
+ )
}
-@OptIn(
- ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class,
-)
+@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun FriendsContent(
- friendsState: FriendsState,
+ jumpCount: () -> Long,
+ textToSpeech: () -> Lce,
+ insertReportCardState: () -> Lce,
+ onViewRankingButtonClick: () -> Unit,
+ onCountChange: () -> Unit
) {
val snackbarHostState = remember { SnackbarHostState() }
- val jumpCount = friendsState.jumpCount
- val textToSpeech = friendsState.textToSpeech
- val pagerState = rememberPagerState()
- val insertReportCardState = friendsState.insertReportCardState
+ val pagerState = rememberPagerState { Friend.entries.size }
- LaunchedEffect(insertReportCardState) {
- with(insertReportCardState) {
- when (this) {
+ LaunchedEffect(Unit) {
+ snapshotFlow(insertReportCardState).catch { }.flowOn(Dispatchers.IO).collect {
+ when (it) {
is Lce.Error -> {
- val message = error.castToQuotaReachedExceptionAndGetMessage()
+ val message = it.error.castToQuotaReachedExceptionAndGetMessage()
with(snackbarHostState) {
currentSnackbarData?.dismiss()
@@ -101,8 +138,8 @@ private fun FriendsContent(
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
- AnimatedCount(count = jumpCount)
- IconButton(onClick = friendsState::onViewRankingButtonClick) {
+ AnimatedCount(count = jumpCount())
+ IconButton(onClick = onViewRankingButtonClick) {
Icon(
imageVector = Icons.Default.Leaderboard,
contentDescription = Icons.Default.Leaderboard.name
@@ -115,11 +152,10 @@ private fun FriendsContent(
) {
HorizontalPager(
state = pagerState,
- pageCount = friendsState.friends.size,
pageSize = PageSize.Fill,
- key = { Friend.values()[it].name }
+ key = { Friend.entries[it].name }
) { page ->
- when (Friend.values()[page]) {
+ when (Friend.entries[page]) {
Friend.Hamster -> {
val configuration = LocalConfiguration.current
val maxOffset by remember(configuration) {
@@ -132,14 +168,14 @@ private fun FriendsContent(
HamsterCard(
textToSpeech = textToSpeech,
roundTripState = roundTripState,
- onCountChange = friendsState::increaseJumpCount
+ onCountChange = onCountChange
)
}
Friend.Cat -> {
CatCard(
textToSpeech = textToSpeech,
- onCountChange = friendsState::increaseJumpCount
+ onCountChange = onCountChange
)
}
}
@@ -151,14 +187,13 @@ private fun FriendsContent(
) {
HorizontalPagerIndicator(
pagerState = pagerState,
- pageCount = friendsState.friends.size
+ pageCount = Friend.entries.size
)
}
}
}
}
-@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun AnimatedCount(
count: Long,
@@ -167,15 +202,15 @@ private fun AnimatedCount(
targetState = count,
transitionSpec = {
if (targetState > initialState) {
- slideInVertically { height -> height } + fadeIn() with
+ slideInVertically { height -> height } + fadeIn() togetherWith
slideOutVertically { height -> -height } + fadeOut()
} else {
- slideInVertically { height -> -height } + fadeIn() with
+ slideInVertically { height -> -height } + fadeIn() togetherWith
slideOutVertically { height -> height } + fadeOut()
}.using(
SizeTransform(clip = false)
)
- }
+ }, label = ""
) { targetCount ->
Text(
modifier = Modifier,
@@ -188,7 +223,7 @@ private fun AnimatedCount(
@Composable
private fun HamsterCard(
- textToSpeech: Lce,
+ textToSpeech: () -> Lce,
roundTripState: RoundTripState,
onCountChange: () -> Unit
) {
@@ -215,7 +250,7 @@ private fun HamsterCard(
@Composable
private fun CatCard(
- textToSpeech: Lce,
+ textToSpeech: () -> Lce,
onCountChange: () -> Unit
) {
Card(
@@ -240,7 +275,7 @@ private fun CatCard(
@Composable
private fun CatImage(
- textToSpeech: Lce,
+ textToSpeech: () -> Lce,
onCountChange: () -> Unit
) {
val meowing = remember { "뫼애앵" }
@@ -269,14 +304,14 @@ private fun CatImage(
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() },
- enabled = textToSpeech is Lce.Content && !isTtsPlaying
+ enabled = textToSpeech() is Lce.Content && !isTtsPlaying
) {
onCountChange()
coroutineScope.launch(Dispatchers.IO) {
onIsTtsPlayingChange(true)
- textToSpeech.content?.runCatching {
+ textToSpeech().content?.runCatching {
say(
text = meowing,
clearQueue = true,
@@ -297,39 +332,35 @@ private fun CatImage(
@Composable
private fun HamsterImage(
- textToSpeech: Lce,
+ textToSpeech: () -> Lce,
roundTripState: RoundTripState,
onCountChange: () -> Unit
) {
val kking = remember { "끼잉!" }
val coroutineScope = rememberCoroutineScope()
- val lifecycleOwner = LocalLifecycleOwner.current
val context = LocalContext.current
val roundTripValue = roundTripState.roundTripValue
- val roundTripAnimationOffset by animateRoundTripByDpAsState(roundTripState = roundTripState)
- val idleHamster = remember(context, lifecycleOwner) {
- ImageRequest.Builder(context)
- .data(R.drawable.idle_hamster)
- .lifecycle(lifecycleOwner)
- .build()
- }
- val jumpingHamster = remember(context, lifecycleOwner) {
- ImageRequest.Builder(context)
- .data(R.drawable.jumping_hamster)
- .lifecycle(lifecycleOwner)
- .build()
- }
+ val idleHamster = ImageRequest.Builder(context)
+ .data(R.drawable.idle_hamster)
+ .build()
+ val jumpingHamster = ImageRequest.Builder(context)
+ .data(R.drawable.jumping_hamster)
+ .build()
AsyncImage(
modifier = Modifier
.fillMaxWidth(0.4f)
.aspectRatio(1.0f)
.padding(bottom = 16.dp)
- .absoluteOffset(y = roundTripAnimationOffset)
+ .composed {
+ val roundTripAnimationOffset by animateRoundTripByDpAsState(roundTripState = roundTripState)
+
+ absoluteOffset(y = roundTripAnimationOffset)
+ }
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() },
- enabled = roundTripValue.isIdle && textToSpeech is Lce.Content
+ enabled = roundTripValue.isIdle && textToSpeech() is Lce.Content
) {
onCountChange()
@@ -338,16 +369,13 @@ private fun HamsterImage(
roundTripState.start()
}
- textToSpeech.content
+ textToSpeech().content
?.runCatching {
say(
text = kking,
clearQueue = true
)
}
- ?.onFailure { cause ->
- cause.printStackTrace()
- }
}
},
model = when (roundTripValue) {
diff --git a/app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/screen/RankingScreen.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/screen/RankingScreen.kt
similarity index 72%
rename from app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/screen/RankingScreen.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/screen/RankingScreen.kt
index e4783ea..199dbbb 100644
--- a/app/src/main/java/com/joeloewi/jumpkking/ui/navigation/friends/screen/RankingScreen.kt
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/navigation/friends/screen/RankingScreen.kt
@@ -1,53 +1,80 @@
package com.joeloewi.jumpkking.ui.navigation.friends.screen
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.WindowInsetsSides
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.only
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.safeDrawing
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.*
-import androidx.compose.material3.*
-import androidx.compose.runtime.*
+import androidx.compose.material.icons.filled.Close
+import androidx.compose.material.icons.filled.Leaderboard
+import androidx.compose.material.icons.filled.Refresh
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.ListItem
+import androidx.compose.material3.ListItemDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarDuration
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
-import androidx.navigation.NavController
+import androidx.hilt.navigation.compose.hiltViewModel
import androidx.paging.LoadState
-import androidx.paging.compose.itemsIndexed
+import androidx.paging.compose.LazyPagingItems
+import androidx.paging.compose.collectAsLazyPagingItems
+import androidx.paging.compose.itemKey
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.google.accompanist.placeholder.PlaceholderHighlight
import com.google.accompanist.placeholder.fade
import com.google.accompanist.placeholder.placeholder
-import com.joeloewi.jumpkking.state.RankingState
-import com.joeloewi.jumpkking.state.rememberRankingState
+import com.joeloewi.domain.entity.ReportCard
import com.joeloewi.jumpkking.util.castToQuotaReachedExceptionAndGetMessage
import com.joeloewi.jumpkking.viewmodel.RankingViewModel
import java.text.DecimalFormat
@Composable
fun RankingScreen(
- navController: NavController,
- rankingViewModel: RankingViewModel
+ onCloseButtonClick: () -> Unit,
+ rankingViewModel: RankingViewModel = hiltViewModel()
) {
- val rankingState = rememberRankingState(
- navController = navController,
- rankingViewModel = rankingViewModel
- )
+ val pagedReportCards = rankingViewModel.pagedReportCards.collectAsLazyPagingItems()
+ val androidId = rankingViewModel.androidId
RankingContent(
- rankingState = rankingState
+ pagedReportCards = pagedReportCards,
+ androidId = androidId,
+ onCloseButtonClick = onCloseButtonClick
)
}
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
private fun RankingContent(
- rankingState: RankingState
+ pagedReportCards: LazyPagingItems,
+ androidId: String,
+ onCloseButtonClick: () -> Unit
) {
val snackbarHostState = remember { SnackbarHostState() }
- val pagedReportCards = rankingState.pagedReportCards
LaunchedEffect(pagedReportCards.loadState) {
val loadStates = mutableListOf()
@@ -120,7 +147,7 @@ private fun RankingContent(
},
actions = {
IconButton(
- onClick = rankingState::onCloseButtonClick
+ onClick = onCloseButtonClick
) {
Icon(
imageVector = Icons.Default.Close,
@@ -137,13 +164,14 @@ private fun RankingContent(
.padding(innerPadding)
.fillMaxSize()
) {
- itemsIndexed(
- pagedReportCards,
- key = { _, item -> item.androidId }
- ) { index, item ->
+ items(
+ count = pagedReportCards.itemCount,
+ key = pagedReportCards.itemKey { it.androidId }
+ ) { index ->
+ val item = runCatching { pagedReportCards[index] }.getOrNull()
+
if (item != null) {
- val isMyReportCard =
- item.androidId == rankingState.androidId
+ val isMyReportCard = item.androidId == androidId
val backgroundColor =
if (isMyReportCard) {
@@ -160,10 +188,10 @@ private fun RankingContent(
leadingContent = {
Text(text = "${index + 1}")
},
- headlineText = {
+ headlineContent = {
Text(text = DecimalFormat.getInstance().format(item.jumpCount))
},
- supportingText = if (isMyReportCard) {
+ supportingContent = if (isMyReportCard) {
{
Text(
text = "나"
@@ -181,7 +209,6 @@ private fun RankingContent(
}
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ReportCardListItemPlaceHolder(
isPlaceholderVisible: Boolean = true
@@ -206,7 +233,7 @@ private fun ReportCardListItemPlaceHolder(
contentDescription = null
)
},
- headlineText = {
+ headlineContent = {
Text(
modifier = Modifier
.fillMaxWidth()
@@ -220,7 +247,7 @@ private fun ReportCardListItemPlaceHolder(
text = ""
)
},
- supportingText = {
+ supportingContent = {
Text(
modifier = Modifier
.fillMaxWidth()
diff --git a/app/src/main/java/com/joeloewi/jumpkking/ui/theme/ContentAlpha.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/theme/ContentAlpha.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/ui/theme/ContentAlpha.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/ui/theme/ContentAlpha.kt
diff --git a/app/src/main/kotlin/com/joeloewi/jumpkking/ui/theme/Theme.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/theme/Theme.kt
new file mode 100644
index 0000000..e148989
--- /dev/null
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/ui/theme/Theme.kt
@@ -0,0 +1,33 @@
+package com.joeloewi.jumpkking.ui.theme
+
+import android.os.Build
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+
+@Composable
+fun JumpKkingTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ dynamicColor: Boolean = true,
+ content: @Composable () -> Unit
+) {
+ val colorScheme = when {
+ dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+ val context = LocalContext.current
+ if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
+ }
+
+ darkTheme -> darkColorScheme()
+ else -> lightColorScheme()
+ }
+
+ MaterialTheme(
+ colorScheme = colorScheme,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/util/LifecycleExtensions.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/util/LifecycleExtensions.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/util/LifecycleExtensions.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/util/LifecycleExtensions.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/util/LocalActivity.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/util/LocalActivity.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/util/LocalActivity.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/util/LocalActivity.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/util/RoundTripOffsetAnimation.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/util/RoundTripOffsetAnimation.kt
similarity index 94%
rename from app/src/main/java/com/joeloewi/jumpkking/util/RoundTripOffsetAnimation.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/util/RoundTripOffsetAnimation.kt
index e9cafe5..f19380a 100644
--- a/app/src/main/java/com/joeloewi/jumpkking/util/RoundTripOffsetAnimation.kt
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/util/RoundTripOffsetAnimation.kt
@@ -19,12 +19,12 @@ import kotlinx.coroutines.suspendCancellableCoroutine
sealed class RoundTripValue {
open val isIdle: Boolean = false
- object Idle : RoundTripValue() {
+ data object Idle : RoundTripValue() {
override val isIdle: Boolean = true
}
- object Going : RoundTripValue()
- object TurningBack : RoundTripValue()
+ data object Going : RoundTripValue()
+ data object TurningBack : RoundTripValue()
}
@Stable
@@ -97,5 +97,5 @@ fun animateRoundTripByDpAsState(
coroutineScope.launch {
roundTripState.doTurnBackOrEnterIdle(it)
}
- }
+ }, label = ""
)
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/util/ThrowableExtensions.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/util/ThrowableExtensions.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/util/ThrowableExtensions.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/util/ThrowableExtensions.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/viewmodel/FriendsViewModel.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/FriendsViewModel.kt
similarity index 90%
rename from app/src/main/java/com/joeloewi/jumpkking/viewmodel/FriendsViewModel.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/FriendsViewModel.kt
index d739c6c..ae10f11 100644
--- a/app/src/main/java/com/joeloewi/jumpkking/viewmodel/FriendsViewModel.kt
+++ b/app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/FriendsViewModel.kt
@@ -1,6 +1,5 @@
package com.joeloewi.jumpkking.viewmodel
-import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.firebase.crashlytics.FirebaseCrashlytics
@@ -25,14 +24,14 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.rx3.asFlowable
import kotlinx.coroutines.rx3.asScheduler
-import nl.marc_apps.tts.TextToSpeech
+import nl.marc_apps.tts.TextToSpeechFactory
import okhttp3.internal.closeQuietly
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@HiltViewModel
class FriendsViewModel @Inject constructor(
- private val application: Application,
+ private val textToSpeechFactory: TextToSpeechFactory,
private val getValuesUseCase: ValuesUseCase.GetValues,
private val setJumpCountUseCase: ValuesUseCase.SetJumpCount,
private val setReportCardUseCase: ReportCardUseCase.Insert,
@@ -45,7 +44,7 @@ class FriendsViewModel @Inject constructor(
private val _jumpCount = _values.map { it.jumpCount }
private val _throttledJumpCount = _jumpCount
.flowOn(Dispatchers.IO)
- .asFlowable(viewModelScope.coroutineContext)
+ .asFlowable(Dispatchers.IO)
.observeOn(_ioScheduler)
.throttleLatest(5, TimeUnit.SECONDS)
.subscribeOn(_ioScheduler)
@@ -74,19 +73,19 @@ class FriendsViewModel @Inject constructor(
Lce.Error(cause)
}
)
- }.flowOn(Dispatchers.IO).stateIn(
+ }.catch { }.flowOn(Dispatchers.IO).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = Lce.Loading
)
- val jumpCount = _jumpCount.stateIn(
+ val jumpCount = _jumpCount.catch { }.flowOn(Dispatchers.IO).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = Values().jumpCount
)
val textToSpeech = callbackFlow {
- val textToSpeechInstance = TextToSpeech.runCatching {
- createOrThrow(application)
+ val textToSpeechInstance = textToSpeechFactory.runCatching {
+ createOrThrow()
}.fold(
onSuccess = {
Lce.Content(it)
@@ -105,7 +104,7 @@ class FriendsViewModel @Inject constructor(
}
FirebaseCrashlytics.getInstance().recordException(cause)
- }.stateIn(
+ }.flowOn(Dispatchers.IO).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = Lce.Loading
@@ -116,4 +115,8 @@ class FriendsViewModel @Inject constructor(
setJumpCountUseCase(getValuesUseCase().first().jumpCount + 1)
}
}
+}
+
+enum class Friend {
+ Hamster, Cat
}
\ No newline at end of file
diff --git a/app/src/main/java/com/joeloewi/jumpkking/viewmodel/MainViewModel.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/MainViewModel.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/viewmodel/MainViewModel.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/MainViewModel.kt
diff --git a/app/src/main/java/com/joeloewi/jumpkking/viewmodel/RankingViewModel.kt b/app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/RankingViewModel.kt
similarity index 100%
rename from app/src/main/java/com/joeloewi/jumpkking/viewmodel/RankingViewModel.kt
rename to app/src/main/kotlin/com/joeloewi/jumpkking/viewmodel/RankingViewModel.kt
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 4bdceec..f75a2f2 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,10 +1,7 @@
-
+