diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e6a97a129523e05dbf396364f3ee2d50f694f499..c791bf08c6f62877ca74ed6b3a67a60d559c2cad 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,6 +156,7 @@ dependencies { implementation(libs.acra.limiter) implementation(libs.commonutils.core) + implementation(libs.commonutils.compose) implementation(libs.commonutils.voyager) dokkaPlugin(libs.dokka.android) diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt index 1eb22a529fdbad99e6a8565de183fe6ec53df7ec..4f2918c44c801b0fade1b52a0f29a5f776529d2b 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt @@ -11,12 +11,12 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import kotlinx.coroutines.plus import kotlinx.coroutines.runBlocking -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.android.toastShort import net.novagamestudios.common_utils.compose.application -import net.novagamestudios.common_utils.error -import net.novagamestudios.common_utils.info -import net.novagamestudios.common_utils.toastShort -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.error +import net.novagamestudios.common_utils.logging.info +import net.novagamestudios.common_utils.logging.warn import net.novagamestudios.kaffeekasse.api.hiwi_tracker.HiwiTrackerAPI import net.novagamestudios.kaffeekasse.api.hiwi_tracker.HiwiTrackerScraper import net.novagamestudios.kaffeekasse.api.kaffeekasse.KaffeekasseAPI diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/MainActivity.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/MainActivity.kt index eea4033c523d7321680c6790fb64a36c77c3c7ce..cf3fc51985ec182818aadb7f4aff157719f431fe 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/MainActivity.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/MainActivity.kt @@ -14,7 +14,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch -import net.novagamestudios.common_utils.LocalLogger +import net.novagamestudios.common_utils.logging.LocalLogger import net.novagamestudios.kaffeekasse.repositories.SettingsRepository import net.novagamestudios.kaffeekasse.ui.App import net.novagamestudios.kaffeekasse.ui.util.removeScrollableTabRowMinimumTabWidth diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/UpdateReciever.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/UpdateReciever.kt index 46ad143eccb57661a96b92ff1863e586451e9eab..a671abee299f94f76bcb9d7847e861ac8f23471f 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/UpdateReciever.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/UpdateReciever.kt @@ -3,8 +3,8 @@ package net.novagamestudios.kaffeekasse import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.info +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.info class UpdateReceiver : BroadcastReceiver(), Logger { diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/api/hiwi_tracker/HiwiTrackerAPI.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/api/hiwi_tracker/HiwiTrackerAPI.kt index be4b62b1a3a49b38d72322f6dfd43c32c536eefc..e9b9fc0aa252f141cc8e47bc62dcb69def0b11d3 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/api/hiwi_tracker/HiwiTrackerAPI.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/api/hiwi_tracker/HiwiTrackerAPI.kt @@ -2,9 +2,9 @@ package net.novagamestudios.kaffeekasse.api.hiwi_tracker import io.ktor.http.parameters import kotlinx.datetime.format -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.kaffeekasse.api.portal.PortalClient +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.kaffeekasse.api.hiwi_tracker.model.MonthDataResponse +import net.novagamestudios.kaffeekasse.api.portal.PortalClient import net.novagamestudios.kaffeekasse.model.hiwi_tracker.MonthKey diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseAPI.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseAPI.kt index 8e8d1767ed7315d71e32616eef0c59a7b902aa4e..67c37a6938104df782f84b467a1f63bf48fde274 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseAPI.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseAPI.kt @@ -3,10 +3,9 @@ package net.novagamestudios.kaffeekasse.api.kaffeekasse import io.ktor.http.Parameters import io.ktor.http.parameters import io.ktor.util.sha1 -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.error -import net.novagamestudios.kaffeekasse.api.portal.PortalClient +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.error import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.ItemListResponse import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.KaffeekasseAPIResponse import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.LoggedInUserResponse @@ -16,6 +15,7 @@ import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.LogoutUserResponse import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.PurchaseResponse import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.UserInfoResponse import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.UserListResponse +import net.novagamestudios.kaffeekasse.api.portal.PortalClient import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.KaffeekasseAPIResponse.Error.Code as ErrorCode class KaffeekasseAPI( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseScraper.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseScraper.kt index 76b51fb1264977914fa6ea4245b18263d3721a5d..75cdb85653bab36de3bc608bc063d79e7e03491e 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseScraper.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/KaffeekasseScraper.kt @@ -12,7 +12,7 @@ import it.skrape.selects.html5.select import it.skrape.selects.html5.table import it.skrape.selects.html5.td import it.skrape.selects.html5.tr -import net.novagamestudios.common_utils.info +import net.novagamestudios.common_utils.logging.info import net.novagamestudios.kaffeekasse.api.portal.PortalClient import net.novagamestudios.kaffeekasse.model.kaffeekasse.Cart import net.novagamestudios.kaffeekasse.model.kaffeekasse.KnownItem diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/BasicUserInfo.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/BasicUserInfo.kt index 3e2b94425645f533a870493706a34dd241d342b3..fee012cba5e8300c6293fe12821f8f5cac30daee 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/BasicUserInfo.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/BasicUserInfo.kt @@ -2,8 +2,8 @@ package net.novagamestudios.kaffeekasse.api.kaffeekasse.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import net.novagamestudios.common_utils.serialization.BooleanAsIntSerializer import net.novagamestudios.kaffeekasse.model.kaffeekasse.Name -import net.novagamestudios.kaffeekasse.util.IntAsBooleanSerializer @Serializable data class BasicUserInfo( @@ -12,7 +12,7 @@ data class BasicUserInfo( @SerialName("name") override val name: Name, @SerialName("empty_pin") - val noPinSet: @Serializable(with = IntAsBooleanSerializer::class) Boolean? = null + val noPinSet: @Serializable(with = BooleanAsIntSerializer::class) Boolean? = null ) : APIPurchaseAccount { val mayHavePin get() = noPinSet == null || !noPinSet } \ No newline at end of file diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/ItemListResponse.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/ItemListResponse.kt index 6960eb3b2a2b9624719b51d7ddf9c36e683a3891..3bcb65e111f9cb0c3c8b2fea8d196bd2c0851743 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/ItemListResponse.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/api/kaffeekasse/model/ItemListResponse.kt @@ -3,7 +3,7 @@ package net.novagamestudios.kaffeekasse.api.kaffeekasse.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement -import net.novagamestudios.kaffeekasse.util.IntAsBooleanSerializer +import net.novagamestudios.common_utils.serialization.BooleanAsIntSerializer @Serializable data class ItemListResponse( @@ -25,7 +25,7 @@ data class ItemListResponse( val sortP: Double, @SerialName("itemtype_id") val itemTypeId: Int, - val enabled: @Serializable(with = IntAsBooleanSerializer::class) Boolean, + val enabled: @Serializable(with = BooleanAsIntSerializer::class) Boolean, @SerialName("has_condition_reports") val hasConditionReports: JsonElement ) diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/api/portal/PortalClient.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/api/portal/PortalClient.kt index 220c91ec8a9aa7dbc301c201c4dc6ee940a59f38..722892d66f83c314f26370994e4202e2a3b91a8b 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/api/portal/PortalClient.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/api/portal/PortalClient.kt @@ -33,12 +33,12 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.decodeFromJsonElement -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.error -import net.novagamestudios.common_utils.info -import net.novagamestudios.common_utils.verbose -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.error +import net.novagamestudios.common_utils.logging.info +import net.novagamestudios.common_utils.logging.verbose +import net.novagamestudios.common_utils.logging.warn import net.novagamestudios.kaffeekasse.api.portal.model.PortalAPIResponse import net.novagamestudios.kaffeekasse.model.credentials.Login import net.novagamestudios.kaffeekasse.model.credentials.isValid diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/MonthKey.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/MonthKey.kt index 6f1113a88aadade00e66a9467920d7d1c1de078d..9c41025c31aaacc45a53abec1d0472d31c3691e6 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/MonthKey.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/MonthKey.kt @@ -6,7 +6,7 @@ import kotlinx.datetime.LocalDate import kotlinx.datetime.Month import kotlinx.datetime.number import kotlinx.serialization.Serializable -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger @Serializable diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/WorkEntry.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/WorkEntry.kt index 865b1c11e1bfa03c5ca169c0d616ed713cb2db9c..75612ddf0e75a14721457768316ceef51fa7e8ad 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/WorkEntry.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/model/hiwi_tracker/WorkEntry.kt @@ -2,7 +2,7 @@ package net.novagamestudios.kaffeekasse.model.hiwi_tracker import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalTime -import net.novagamestudios.kaffeekasse.util.minus +import net.novagamestudios.common_utils.minus import kotlin.time.Duration import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Credentials.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Credentials.kt index 44c20473d2786b93707d564744cf051938578004..4e28f13c46adbeb880883c7ead3a88d929777be1 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Credentials.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Credentials.kt @@ -11,12 +11,12 @@ import androidx.credentials.exceptions.CreateCredentialException import androidx.credentials.exceptions.CreateCredentialUnsupportedException import androidx.credentials.exceptions.GetCredentialCancellationException import androidx.credentials.exceptions.GetCredentialException -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.error -import net.novagamestudios.common_utils.info -import net.novagamestudios.common_utils.toastShort -import net.novagamestudios.common_utils.verbose +import net.novagamestudios.common_utils.android.toastShort +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.error +import net.novagamestudios.common_utils.logging.info +import net.novagamestudios.common_utils.logging.verbose import net.novagamestudios.kaffeekasse.BuildConfig import net.novagamestudios.kaffeekasse.model.credentials.DeviceCredentials import net.novagamestudios.kaffeekasse.model.credentials.Login diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/LoginRepository.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/LoginRepository.kt index 421ae736a2ecb1da986e12382be658594ab5c47c..61fd147d4e9d45de83b0a60cca7b4bd009ddb60c 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/LoginRepository.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/LoginRepository.kt @@ -4,12 +4,14 @@ import android.content.Context import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.sync.Mutex -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.info -import net.novagamestudios.common_utils.toastShort -import net.novagamestudios.common_utils.verbose -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.android.toastShort +import net.novagamestudios.common_utils.collection.mapState +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.info +import net.novagamestudios.common_utils.logging.verbose +import net.novagamestudios.common_utils.logging.warn +import net.novagamestudios.common_utils.withReentrantLock import net.novagamestudios.kaffeekasse.api.kaffeekasse.KaffeekasseAPI import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.BasicUserInfo import net.novagamestudios.kaffeekasse.model.credentials.DeviceCredentials @@ -19,8 +21,6 @@ import net.novagamestudios.kaffeekasse.model.kaffeekasse.UserAuthCredentials import net.novagamestudios.kaffeekasse.model.session.Session import net.novagamestudios.kaffeekasse.repositories.i11.KaffeekasseRepository import net.novagamestudios.kaffeekasse.repositories.i11.PortalRepository -import net.novagamestudios.kaffeekasse.util.mapState -import net.novagamestudios.kaffeekasse.util.withReentrantLock class LoginRepository( private val credentialsRepository: Credentials, diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Settings.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Settings.kt index c80b801d8860c1a6f49e76a9f12186a7640b5a0c..940db21350e34b6bfad9ea790d303bb45b369a17 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Settings.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/Settings.kt @@ -11,10 +11,10 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -import net.novagamestudios.common_utils.JsonToDataStore import net.novagamestudios.common_utils.compose.state.DataStoreState import net.novagamestudios.common_utils.compose.state.MutableDataStoreState import net.novagamestudios.common_utils.compose.state.stateIn +import net.novagamestudios.common_utils.serialization.JsonToDataStore import net.novagamestudios.kaffeekasse.model.credentials.DeviceCredentials import net.novagamestudios.kaffeekasse.ui.util.derived import java.io.File diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/SettingsRepository.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/SettingsRepository.kt index b586c6cad1827c6407dda022f7d7d502c4ec02b9..3ebfeb3bb49aaf1bc3a5e9d803bcbf411beb5a4d 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/SettingsRepository.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/SettingsRepository.kt @@ -1,9 +1,9 @@ package net.novagamestudios.kaffeekasse.repositories import kotlinx.coroutines.flow.StateFlow +import net.novagamestudios.common_utils.collection.mapState import net.novagamestudios.common_utils.compose.state.MutableDataStoreState import net.novagamestudios.kaffeekasse.model.session.realUserOrNull -import net.novagamestudios.kaffeekasse.util.mapState class SettingsRepository( repositoryProvider: RepositoryProvider, diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/UpdateController.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/UpdateController.kt index 0579bc8ae27b32b52ff14a23ab20c707469bee40..ffcc855c3860902a4f7dad3326886aa3b7dcc4bd 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/UpdateController.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/UpdateController.kt @@ -11,11 +11,11 @@ import io.ktor.http.contentLength import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.jvm.javaio.copyTo import kotlinx.coroutines.flow.MutableStateFlow -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.compose.components.Progress -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.error -import net.novagamestudios.common_utils.info +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.error +import net.novagamestudios.common_utils.logging.info import net.novagamestudios.kaffeekasse.MainActivity import net.novagamestudios.kaffeekasse.UpdateReceiver import net.novagamestudios.kaffeekasse.model.app.AppRelease diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/HiwiTrackerRepository.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/HiwiTrackerRepository.kt index 7f16d4635523b1fc44d56e847183248ace4f2ae5..8dc5bab4cbee58de04d0475a4d4d0d3c094d52fc 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/HiwiTrackerRepository.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/HiwiTrackerRepository.kt @@ -1,8 +1,8 @@ package net.novagamestudios.kaffeekasse.repositories.i11 import kotlinx.coroutines.CoroutineScope -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug import net.novagamestudios.kaffeekasse.api.hiwi_tracker.HiwiTrackerAPI import net.novagamestudios.kaffeekasse.api.hiwi_tracker.HiwiTrackerScraper import net.novagamestudios.kaffeekasse.api.hiwi_tracker.model.MonthDataResponse diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/KaffeekasseRepository.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/KaffeekasseRepository.kt index 451c832b7c617ff3e3925efe8fadfc7d9832da8a..3a1e29b5f1146b72d486263ecd711f10f01331e4 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/KaffeekasseRepository.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/KaffeekasseRepository.kt @@ -3,7 +3,7 @@ package net.novagamestudios.kaffeekasse.repositories.i11 import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.kaffeekasse.api.kaffeekasse.KaffeekasseAPI import net.novagamestudios.kaffeekasse.api.kaffeekasse.KaffeekasseScraper import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.APIPurchaseAccount diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/PortalRepository.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/PortalRepository.kt index 48d3c7ad185788ebbb84409aaf84854f95275a84..99a376d330f0b2a0b4d7192aa7d8117c1f733291 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/PortalRepository.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/i11/PortalRepository.kt @@ -4,10 +4,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.info -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.info +import net.novagamestudios.common_utils.logging.warn import net.novagamestudios.kaffeekasse.api.kaffeekasse.KaffeekasseAPI import net.novagamestudios.kaffeekasse.api.portal.PortalClient import net.novagamestudios.kaffeekasse.model.credentials.Login diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabPackageReleases.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabPackageReleases.kt index 0c4189ebc1d4599d823b2313b392efa5015d1591..ca0aae25ffd2c3d776c4b586bd6a89955a86800a 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabPackageReleases.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabPackageReleases.kt @@ -1,9 +1,9 @@ package net.novagamestudios.kaffeekasse.repositories.releases import kotlinx.coroutines.flow.MutableStateFlow -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.info +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.info import net.novagamestudios.kaffeekasse.gitlab.GitLab import net.novagamestudios.kaffeekasse.gitlab.GitLabPackage import net.novagamestudios.kaffeekasse.gitlab.GitLabPackageFile diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabReleases.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabReleases.kt index d6751153b695f91b6bf644f3beb130b89227513a..52cdbc8e12b0ae0cda3c9b879fa04cd3e8ce4e2e 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabReleases.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/repositories/releases/GitLabReleases.kt @@ -1,9 +1,9 @@ package net.novagamestudios.kaffeekasse.repositories.releases import kotlinx.coroutines.flow.MutableStateFlow -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.info +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.info import net.novagamestudios.kaffeekasse.gitlab.GitLab import net.novagamestudios.kaffeekasse.model.app.AppRelease import net.novagamestudios.kaffeekasse.model.app.AppVersion diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/App.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/App.kt index e730cac502d3c4b0e6fecb0f34c578564775b3f3..9ff0445c9c3989572b3b387589a9ee20159ff8b1 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/App.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/App.kt @@ -16,15 +16,16 @@ import androidx.compose.ui.Modifier import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.LoggerForFun import net.novagamestudios.common_utils.compose.components.BoxCenter -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.verbose +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.LoggerForFun +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.verbose import net.novagamestudios.common_utils.voyager.model.GlobalScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.common_utils.voyager.model.collectAsStateHere import net.novagamestudios.common_utils.voyager.model.getValue +import net.novagamestudios.common_utils.voyager.requireWithKey import net.novagamestudios.kaffeekasse.App import net.novagamestudios.kaffeekasse.model.session.Session import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider @@ -33,7 +34,6 @@ import net.novagamestudios.kaffeekasse.ui.navigation.AppModulesScreen import net.novagamestudios.kaffeekasse.ui.navigation.AppScreenTransition import net.novagamestudios.kaffeekasse.ui.navigation.LoginNavigation import net.novagamestudios.kaffeekasse.ui.theme.KaffeekasseTheme -import net.novagamestudios.kaffeekasse.ui.util.navigation.requireWithKey class AppScreenModel private constructor( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt index 3c91f642899740bcdd21c196025cdd4d752477f9..31d362ac170dda6149654bbc2612c4f61d3de5aa 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt @@ -30,6 +30,7 @@ import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.navigator.tab.LocalTabNavigator import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.collectAsStateHere +import net.novagamestudios.common_utils.voyager.nearestScreen import net.novagamestudios.kaffeekasse.AppModule import net.novagamestudios.kaffeekasse.AppModules import net.novagamestudios.kaffeekasse.HiwiTrackerModule @@ -41,7 +42,6 @@ import net.novagamestudios.kaffeekasse.ui.navigation.AppModulesScreen import net.novagamestudios.kaffeekasse.ui.navigation.HiwiTrackerNavigation import net.novagamestudios.kaffeekasse.ui.navigation.KaffeekasseNavigation import net.novagamestudios.kaffeekasse.ui.navigation.ModuleTab -import net.novagamestudios.kaffeekasse.ui.util.navigation.nearestScreen class AppModulesScreenModel private constructor( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt index e19d2417d19ef0732f8a45b5bc0c01679a91d522..1c8dad9e7406b699431219245aa317602103a571 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt @@ -46,19 +46,19 @@ import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.screenModelScope import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.android.toastLong import net.novagamestudios.common_utils.compose.DashedShape +import net.novagamestudios.common_utils.compose.Toasts +import net.novagamestudios.common_utils.compose.ToastsState import net.novagamestudios.common_utils.compose.components.CircularLoadingBox import net.novagamestudios.common_utils.compose.components.ColumnCenter import net.novagamestudios.common_utils.compose.components.LinearProgressIndicator import net.novagamestudios.common_utils.compose.components.RowCenter -import net.novagamestudios.common_utils.compose.components.Toasts -import net.novagamestudios.common_utils.compose.components.ToastsState import net.novagamestudios.common_utils.compose.components.TransparentListItem import net.novagamestudios.common_utils.compose.state.ReentrantActionState import net.novagamestudios.common_utils.compose.state.collectAsStateIn -import net.novagamestudios.common_utils.error -import net.novagamestudios.common_utils.toastLong +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.error import net.novagamestudios.common_utils.voyager.model.GlobalScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.common_utils.voyager.model.getValue diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/EnterWorkingHours.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/EnterWorkingHours.kt index 8ea31df70592760ac74affc31dd5f12c427d0667..9c20b6fa47f410d68c0ecbe0df53422e39a16a93 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/EnterWorkingHours.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/EnterWorkingHours.kt @@ -74,16 +74,17 @@ import kotlinx.datetime.format.MonthNames import kotlinx.datetime.format.Padding import kotlinx.datetime.toKotlinLocalDate import kotlinx.datetime.toKotlinLocalTime -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.compose.Toasts +import net.novagamestudios.common_utils.compose.ToastsState import net.novagamestudios.common_utils.compose.components.BoxCenter import net.novagamestudios.common_utils.compose.components.CircularLoadingBox import net.novagamestudios.common_utils.compose.components.ColumnCenter import net.novagamestudios.common_utils.compose.components.RowCenter -import net.novagamestudios.common_utils.compose.components.Toasts -import net.novagamestudios.common_utils.compose.components.ToastsState import net.novagamestudios.common_utils.compose.state.ReentrantActionState import net.novagamestudios.common_utils.compose.thenIf -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.warn +import net.novagamestudios.common_utils.minus import net.novagamestudios.kaffeekasse.R import net.novagamestudios.kaffeekasse.model.hiwi_tracker.WorkEntry import net.novagamestudios.kaffeekasse.model.hiwi_tracker.WorkEntry.Companion.MaxWorkWithoutLargeBreak @@ -98,7 +99,6 @@ import net.novagamestudios.kaffeekasse.ui.theme.disabled import net.novagamestudios.kaffeekasse.ui.util.ClockFace import net.novagamestudios.kaffeekasse.ui.util.TimePickerState import net.novagamestudios.kaffeekasse.ui.util.monochrome -import net.novagamestudios.kaffeekasse.util.minus import kotlin.math.roundToInt import kotlin.time.Duration import kotlin.time.Duration.Companion.hours diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/HiwiTrackerModule.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/HiwiTrackerModule.kt index 6c80049a7c897e3147f2a5f293d5967100f204d5..e236ab51adc78aec98389a17cdd66e357bb2f239 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/HiwiTrackerModule.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/HiwiTrackerModule.kt @@ -1,15 +1,13 @@ package net.novagamestudios.kaffeekasse.ui.hiwi_tracker -import androidx.compose.runtime.Composable import cafe.adriel.voyager.core.model.ScreenModel -import cafe.adriel.voyager.navigator.Navigator -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.model.session.Session import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.HiwiTrackerNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel class HiwiTrackerModuleScreenModel private constructor( @@ -24,7 +22,4 @@ class HiwiTrackerModuleScreenModel private constructor( } } -class HiwiTrackerModuleContent(provider: ScreenModelProvider<HiwiTrackerModuleScreenModel>) : ScaffoldContentWithModel<HiwiTrackerModuleScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) { } -} +class HiwiTrackerModuleContent(provider: ScreenModelProvider<HiwiTrackerModuleScreenModel>) : AppScaffoldContentWithModel<HiwiTrackerModuleScreenModel>(provider) diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/Overview.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/Overview.kt index 1cee1d6495aaf6de06d75e6c167b8742f2a53b7a..3917787df2669c15e2b4fe9559f80591c9887156 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/Overview.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/hiwi_tracker/Overview.kt @@ -81,13 +81,14 @@ import kotlinx.datetime.format.Padding import kotlinx.datetime.format.char import kotlinx.datetime.toKotlinLocalTime import kotlinx.datetime.todayIn -import net.novagamestudios.common_utils.Logger import net.novagamestudios.common_utils.compose.DashedShape import net.novagamestudios.common_utils.compose.components.BoxCenter import net.novagamestudios.common_utils.compose.components.CircularProgressIndicator import net.novagamestudios.common_utils.compose.components.RowCenter -import net.novagamestudios.common_utils.debug -import net.novagamestudios.common_utils.verbose +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug +import net.novagamestudios.common_utils.logging.verbose +import net.novagamestudios.common_utils.voyager.BackNavigationHandler import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.api.hiwi_tracker.model.MonthDataResponse @@ -103,13 +104,12 @@ import net.novagamestudios.kaffeekasse.ui.AppInfoTopBarAction import net.novagamestudios.kaffeekasse.ui.AppModuleSelection import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.FailureRetryScreen import net.novagamestudios.kaffeekasse.ui.login.LogoutTopBarAction +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.HiwiTrackerNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.theme.disabled import net.novagamestudios.kaffeekasse.ui.util.HorizontalKeyedPager import net.novagamestudios.kaffeekasse.ui.util.HorizontalPagedLayout import net.novagamestudios.kaffeekasse.ui.util.KeyedPagerState -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler import net.novagamestudios.kaffeekasse.ui.util.onClickComingSoon import net.novagamestudios.kaffeekasse.ui.util.synchronizePagerState import net.novagamestudios.kaffeekasse.util.richdata.RichData @@ -213,10 +213,7 @@ class OverviewScreenModel private constructor( } -class OverviewContent(provider: ScreenModelProvider<OverviewScreenModel>) : ScaffoldContentWithModel<OverviewScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) = Overview(model) - +class OverviewContent(provider: ScreenModelProvider<OverviewScreenModel>) : AppScaffoldContentWithModel<OverviewScreenModel>(provider) { @Composable override fun TopAppBarTitle(navigator: Navigator) { AppModuleSelection() @@ -236,7 +233,7 @@ class OverviewContent(provider: ScreenModelProvider<OverviewScreenModel>) : Scaf @Composable -private fun Overview( +fun Overview( model: OverviewScreenModel, modifier: Modifier = Modifier ) = PullToRefreshBox( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Account.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Account.kt index 9c4349de15bf1b78031f95fc1e0a4ca2f202eedc..4934d911edb1583afbfbc6f39dbc341bd3eb7cbe 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Account.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Account.kt @@ -25,11 +25,11 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.navigator.Navigator -import net.novagamestudios.common_utils.Logger import net.novagamestudios.common_utils.compose.components.BoxCenter import net.novagamestudios.common_utils.compose.components.CircularProgressIndicator import net.novagamestudios.common_utils.compose.components.ColumnCenter import net.novagamestudios.common_utils.format +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.model.kaffeekasse.Account @@ -38,13 +38,13 @@ import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider import net.novagamestudios.kaffeekasse.repositories.i11.KaffeekasseRepository import net.novagamestudios.kaffeekasse.ui.AppInfoTopBarAction import net.novagamestudios.kaffeekasse.ui.login.LogoutTopBarAction +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.AppSubpageTitle import net.novagamestudios.kaffeekasse.ui.navigation.KaffeekasseNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.util.FailureRetryScreen import net.novagamestudios.kaffeekasse.ui.util.PullToRefreshBox import net.novagamestudios.kaffeekasse.ui.util.RichDataContent -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler +import net.novagamestudios.common_utils.voyager.BackNavigationHandler import net.novagamestudios.kaffeekasse.util.richdata.collectAsRichStateHere class AccountScreenModel private constructor( @@ -63,10 +63,7 @@ class AccountScreenModel private constructor( } } -class AccountContent(provider: ScreenModelProvider<AccountScreenModel>) : ScaffoldContentWithModel<AccountScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) = Account(model) - +class AccountContent(provider: ScreenModelProvider<AccountScreenModel>) : AppScaffoldContentWithModel<AccountScreenModel>(provider) { @Composable override fun TopAppBarTitle(navigator: Navigator) { AppSubpageTitle("Konto") @@ -86,7 +83,7 @@ class AccountContent(provider: ScreenModelProvider<AccountScreenModel>) : Scaffo @Composable -private fun Account( +fun Account( model: AccountScreenModel, modifier: Modifier = Modifier ) = PullToRefreshBox( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/KaffeekasseModule.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/KaffeekasseModule.kt index c2c331ac449d4b9a2d036999f54e8ea72377895f..1271439e355097a413a93eb7953d33bf1501134e 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/KaffeekasseModule.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/KaffeekasseModule.kt @@ -10,17 +10,17 @@ import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.navigator.Navigator -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.voyager.BackNavigationHandler import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.KaffeekasseModule.Companion.kaffeekasseCartProvider import net.novagamestudios.kaffeekasse.model.kaffeekasse.MutableCart import net.novagamestudios.kaffeekasse.model.kaffeekasse.isNotEmpty import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.KaffeekasseNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.theme.ifAnimationsEnabled -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler class KaffeekasseModuleScreenModel private constructor( @@ -34,10 +34,7 @@ class KaffeekasseModuleScreenModel private constructor( } } -class KaffeekasseModuleContent(provider: ScreenModelProvider<KaffeekasseModuleScreenModel>) : ScaffoldContentWithModel<KaffeekasseModuleScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) { } - +class KaffeekasseModuleContent(provider: ScreenModelProvider<KaffeekasseModuleScreenModel>) : AppScaffoldContentWithModel<KaffeekasseModuleScreenModel>(provider) { @Composable override fun TopAppBarNavigationIcon(navigator: Navigator) { CartEmptyNavigation(model, backNavigationHandler(navigator)) diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/ManualBill.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/ManualBill.kt index 3b6ff39d4e445c499d6db7140b47952507332b03..bbdd9751f76d847c1931e7b3767603b721e56d12 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/ManualBill.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/ManualBill.kt @@ -36,10 +36,10 @@ import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.navigator.Navigator -import net.novagamestudios.common_utils.Logger import net.novagamestudios.common_utils.compose.components.CircularProgressIndicator import net.novagamestudios.common_utils.compose.components.RowCenter import net.novagamestudios.common_utils.compose.tabIndicatorOffset +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.KaffeekasseModule.Companion.kaffeekasseCartProvider @@ -59,16 +59,16 @@ import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.CheckoutState import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.CustomItems import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.CustomItemsState import net.novagamestudios.kaffeekasse.ui.login.LogoutTopBarAction +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.AppSubpageTitle import net.novagamestudios.kaffeekasse.ui.navigation.KaffeekasseNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.util.FailureRetryScreen import net.novagamestudios.kaffeekasse.ui.util.RichDataContent import net.novagamestudios.kaffeekasse.ui.util.TopBarSearchAction import net.novagamestudios.kaffeekasse.ui.util.TopBarSearchField import net.novagamestudios.kaffeekasse.ui.util.TopBarSearchFieldState -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler.Companion.then +import net.novagamestudios.common_utils.voyager.BackNavigationHandler +import net.novagamestudios.common_utils.voyager.BackNavigationHandler.Companion.then import net.novagamestudios.kaffeekasse.util.richdata.collectAsRichStateHere @@ -191,12 +191,7 @@ class ManualBillScreenModel private constructor( } -class ManualBillContent(provider: ScreenModelProvider<ManualBillScreenModel>) : ScaffoldContentWithModel<ManualBillScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) { - DynamicManualBill(model) - } - +class ManualBillContent(provider: ScreenModelProvider<ManualBillScreenModel>) : AppScaffoldContentWithModel<ManualBillScreenModel>(provider) { @Composable override fun TopAppBarTitle(navigator: Navigator) { RowCenter { @@ -225,7 +220,7 @@ class ManualBillContent(provider: ScreenModelProvider<ManualBillScreenModel>) : @Composable -private fun DynamicManualBill( +fun DynamicManualBill( model: ManualBillScreenModel, modifier: Modifier = Modifier, postTabsContent: (@Composable () -> Unit)? = null diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Transactions.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Transactions.kt index 1cfed98f088c0c527e2230c983a34485fc92aec5..7edd7f217b28e879caed126757bea36274c2c02d 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Transactions.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/Transactions.kt @@ -39,7 +39,7 @@ import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.navigator.Navigator -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.App @@ -50,13 +50,13 @@ import net.novagamestudios.kaffeekasse.model.session.Session import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider import net.novagamestudios.kaffeekasse.repositories.i11.KaffeekasseRepository import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.cards.CategoryIcon +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.AppSubpageTitle import net.novagamestudios.kaffeekasse.ui.navigation.KaffeekasseNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.util.FailureRetryScreen import net.novagamestudios.kaffeekasse.ui.util.PullToRefreshBox import net.novagamestudios.kaffeekasse.ui.util.RichDataContent -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler +import net.novagamestudios.common_utils.voyager.BackNavigationHandler import net.novagamestudios.kaffeekasse.ui.util.openInBrowser import net.novagamestudios.kaffeekasse.util.richdata.collectAsRichStateHere import java.time.LocalDate @@ -87,10 +87,7 @@ class TransactionsScreenModel private constructor( } -class TransactionsContent(provider: ScreenModelProvider<TransactionsScreenModel>) : ScaffoldContentWithModel<TransactionsScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) = Transactions(model) - +class TransactionsContent(provider: ScreenModelProvider<TransactionsScreenModel>) : AppScaffoldContentWithModel<TransactionsScreenModel>(provider) { @Composable override fun TopAppBarTitle(navigator: Navigator) { AppSubpageTitle("Übersicht") @@ -114,7 +111,7 @@ class TransactionsContent(provider: ScreenModelProvider<TransactionsScreenModel> @Composable -private fun Transactions( +fun Transactions( model: TransactionsScreenModel, modifier: Modifier = Modifier ) = PullToRefreshBox( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/TransactionsCharts.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/TransactionsCharts.kt index 723d84287d440a666a917b020a71699806b6470e..ade4aa7eeb054c6499455ca6c32a9c5a63986ce6 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/TransactionsCharts.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/TransactionsCharts.kt @@ -76,8 +76,8 @@ import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.supervisorScope -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.debug +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.debug import net.novagamestudios.kaffeekasse.model.kaffeekasse.ItemCategory import net.novagamestudios.kaffeekasse.model.kaffeekasse.Transaction import net.novagamestudios.kaffeekasse.ui.kaffeekasse.TransactionsChartsState.ChartSettings.TimeFilter diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CategorizedItems.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CategorizedItems.kt index 659dd7650786a1d16ad104e617f266889b3b7e44..e91a08b99a78aac10391df5e4d55fbcf2290d2ea 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CategorizedItems.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CategorizedItems.kt @@ -20,8 +20,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import kotlinx.coroutines.launch +import net.novagamestudios.common_utils.android.toastShort import net.novagamestudios.common_utils.compose.state.MutableDataStoreState -import net.novagamestudios.common_utils.toastShort import net.novagamestudios.kaffeekasse.App.Companion.settings import net.novagamestudios.kaffeekasse.model.kaffeekasse.Cart import net.novagamestudios.kaffeekasse.model.kaffeekasse.Item @@ -32,7 +32,7 @@ import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.cards.BasicCard import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.cards.CategoryCard import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.cards.LazyBasicCardGrid import net.novagamestudios.kaffeekasse.ui.theme.ifAnimationsEnabled -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler +import net.novagamestudios.common_utils.voyager.BackNavigationHandler class CategorizedItemsState( items: Iterable<Item> diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/Checkout.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/Checkout.kt index 1483f64555eece1d4bffb9962af76fa52abc1d96..b809438ec9c1c879c17b9534b72f7fb34e071881 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/Checkout.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/Checkout.kt @@ -48,15 +48,15 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.launch -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.compose.Toasts +import net.novagamestudios.common_utils.compose.ToastsState import net.novagamestudios.common_utils.compose.components.BoxCenter import net.novagamestudios.common_utils.compose.components.CircularLoadingBox -import net.novagamestudios.common_utils.compose.components.Toasts -import net.novagamestudios.common_utils.compose.components.ToastsState import net.novagamestudios.common_utils.compose.components.TransparentListItem import net.novagamestudios.common_utils.compose.maskedCircleIcon import net.novagamestudios.common_utils.compose.state.ReentrantActionState -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.warn import net.novagamestudios.kaffeekasse.KaffeekasseModule.Companion.kaffeekasseCartProvider import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.APIPurchaseAccount import net.novagamestudios.kaffeekasse.model.kaffeekasse.Cart diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CustomItems.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CustomItems.kt index a0b715c75ae3fa8295808fbc807a4d2a308e21bb..6b65b4bd1a7a06b136187a3b011214c941f9eb3c 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CustomItems.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/CustomItems.kt @@ -31,11 +31,11 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.compose.DashedShape import net.novagamestudios.common_utils.compose.components.ColumnCenter import net.novagamestudios.common_utils.compose.state.ReentrantActionState -import net.novagamestudios.common_utils.verbose +import net.novagamestudios.common_utils.logging.verbose import net.novagamestudios.kaffeekasse.model.kaffeekasse.Item import net.novagamestudios.kaffeekasse.model.kaffeekasse.MutableCart import net.novagamestudios.kaffeekasse.model.kaffeekasse.Transaction diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/cards/Item.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/cards/Item.kt index 29429ce1f8ed61d1dae169c7ceb2d99c25b72b4a..509a4f4bc7ff87486e1267137a58f0de892b969d 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/cards/Item.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/kaffeekasse/components/cards/Item.kt @@ -52,11 +52,11 @@ import coil.compose.SubcomposeAsyncImage import coil.request.ImageRequest import io.ktor.http.URLBuilder import io.ktor.http.URLProtocol -import net.novagamestudios.common_utils.LocalLogger import net.novagamestudios.common_utils.compose.components.BoxCenter import net.novagamestudios.common_utils.compose.maskedCircleIcon -import net.novagamestudios.common_utils.info -import net.novagamestudios.common_utils.warn +import net.novagamestudios.common_utils.logging.LocalLogger +import net.novagamestudios.common_utils.logging.info +import net.novagamestudios.common_utils.logging.warn import net.novagamestudios.kaffeekasse.App import net.novagamestudios.kaffeekasse.app import net.novagamestudios.kaffeekasse.model.kaffeekasse.Item diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/Login.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/Login.kt index 9c7ae038eaf50451c33145ef3c259a22302ecb5b..e88727d079100729346c3e7977b521d6e6857392 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/Login.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/Login.kt @@ -1,23 +1,21 @@ package net.novagamestudios.kaffeekasse.ui.login -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Logout -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.navigator.Navigator import kotlinx.coroutines.launch -import net.novagamestudios.common_utils.Logger -import net.novagamestudios.common_utils.compose.components.BoxCenter import net.novagamestudios.common_utils.compose.components.CircularLoadingBox +import net.novagamestudios.common_utils.compose.components.scaffold.currentScaffoldContent +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.voyager.BackNavigationHandler import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.common_utils.voyager.model.collectAsStateHere @@ -26,10 +24,8 @@ import net.novagamestudios.kaffeekasse.model.session.Session import net.novagamestudios.kaffeekasse.repositories.LoginRepository import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider import net.novagamestudios.kaffeekasse.repositories.i11.PortalRepository -import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldNavigatorDefaultContent +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.LoginNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler class LoginScreenModel private constructor( @@ -52,27 +48,18 @@ class LoginScreenModel private constructor( } } -class LoginContent(provider: ScreenModelProvider<LoginScreenModel>) : ScaffoldContentWithModel<LoginScreenModel>(provider) { +class LoginContent(provider: ScreenModelProvider<LoginScreenModel>) : AppScaffoldContentWithModel<LoginScreenModel>(provider) { @Composable - override fun Content(navigator: Navigator) { - if (model.isLoading) { - BoxCenter(Modifier.fillMaxSize()) { - CircularProgressIndicator() - } - } else { - navigator.AppScaffoldNavigatorDefaultContent("login-navigator-content") - } - Additional(model, navigator) - } + override fun TopAppBarNavigationIcon(navigator: Navigator) { } @Composable override fun backNavigationHandler(navigator: Navigator): BackNavigationHandler { - return default(navigator) { backNavigationHandler(it) } ?: BackNavigationHandler.default() + return navigator.currentScaffoldContent()?.backNavigationHandler(navigator) ?: BackNavigationHandler.default() } } @Composable -private fun Additional(model: LoginScreenModel, navigator: Navigator) { +fun LoginAdditional(model: LoginScreenModel, navigator: Navigator) { when (navigator.lastItem) { is LoginNavigation.FormScreen -> { val session = model.session diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginDevice.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginDevice.kt index a09daf2db38259b36587d8d57a0fce7f030b0fbd..e37cd50dd913eb3317271762884988fcf1e904ce 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginDevice.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginDevice.kt @@ -35,11 +35,11 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import net.novagamestudios.common_utils.compose.components.CircularLoadingBox import net.novagamestudios.common_utils.compose.state.collectAsStateIn +import net.novagamestudios.common_utils.voyager.nearestScreen import net.novagamestudios.kaffeekasse.model.credentials.DeviceCredentials import net.novagamestudios.kaffeekasse.model.credentials.isValid import net.novagamestudios.kaffeekasse.repositories.LoginRepository import net.novagamestudios.kaffeekasse.ui.navigation.LoginNavigation -import net.novagamestudios.kaffeekasse.ui.util.navigation.nearestScreen import net.novagamestudios.kaffeekasse.ui.util.rememberSerializableState diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginForm.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginForm.kt index bc4608226baf54bf66ce819d200c583f49e3f9b3..ade5e1c1041096710363351b0716016e5bcf05cf 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginForm.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/LoginForm.kt @@ -49,8 +49,8 @@ import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.navigator.Navigator import kotlinx.coroutines.launch -import net.novagamestudios.common_utils.Logger import net.novagamestudios.common_utils.compose.components.BoxCenter +import net.novagamestudios.common_utils.logging.Logger import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.common_utils.voyager.model.collectAsStateHere @@ -63,8 +63,8 @@ import net.novagamestudios.kaffeekasse.repositories.i11.PortalRepository import net.novagamestudios.kaffeekasse.ui.AppInfoTopBarAction import net.novagamestudios.kaffeekasse.ui.FullscreenIconButton import net.novagamestudios.kaffeekasse.ui.kaffeekasse.components.FailureRetryScreen +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.LoginNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.util.autofill import net.novagamestudios.kaffeekasse.ui.util.rememberSerializableState @@ -106,10 +106,7 @@ class LoginFormScreenModel private constructor( } } -class LoginFormContent(provider: ScreenModelProvider<LoginFormScreenModel>) : ScaffoldContentWithModel<LoginFormScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) = LoginForm(model) - +class LoginFormContent(provider: ScreenModelProvider<LoginFormScreenModel>) : AppScaffoldContentWithModel<LoginFormScreenModel>(provider) { @Composable override fun TopAppBarActions(navigator: Navigator) { AppInfoTopBarAction() @@ -119,7 +116,7 @@ class LoginFormContent(provider: ScreenModelProvider<LoginFormScreenModel>) : Sc } @Composable -private fun LoginForm( +fun LoginForm( model: LoginFormScreenModel, modifier: Modifier = Modifier ) = BoxCenter(modifier) { diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/UserSelection.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/UserSelection.kt index a97127a2321c196d77a1ab6210b29bd9af74bf11..14275b2c9e8653e7fecbeef68d663ade8e10b9c4 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/UserSelection.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/login/UserSelection.kt @@ -67,15 +67,15 @@ import cafe.adriel.voyager.navigator.Navigator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch -import net.novagamestudios.common_utils.Logger +import net.novagamestudios.common_utils.compose.Toasts +import net.novagamestudios.common_utils.compose.ToastsState import net.novagamestudios.common_utils.compose.components.LinearProgressIndicator import net.novagamestudios.common_utils.compose.components.RowCenter -import net.novagamestudios.common_utils.compose.components.Toasts -import net.novagamestudios.common_utils.compose.components.ToastsState import net.novagamestudios.common_utils.compose.state.rememberDerivedStateOf +import net.novagamestudios.common_utils.logging.Logger +import net.novagamestudios.common_utils.logging.warn import net.novagamestudios.common_utils.voyager.model.ScreenModelFactory import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider -import net.novagamestudios.common_utils.warn import net.novagamestudios.kaffeekasse.App import net.novagamestudios.kaffeekasse.R import net.novagamestudios.kaffeekasse.api.kaffeekasse.model.BasicUserInfo @@ -88,8 +88,8 @@ import net.novagamestudios.kaffeekasse.repositories.i11.KaffeekasseRepository import net.novagamestudios.kaffeekasse.ui.AppInfoTopBarAction import net.novagamestudios.kaffeekasse.ui.FullscreenIconButton import net.novagamestudios.kaffeekasse.ui.handleSession +import net.novagamestudios.kaffeekasse.ui.navigation.AppScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.navigation.LoginNavigation -import net.novagamestudios.kaffeekasse.ui.navigation.ScaffoldContentWithModel import net.novagamestudios.kaffeekasse.ui.util.AlphabetSelectionChar import net.novagamestudios.kaffeekasse.ui.util.FailureRetryScreen import net.novagamestudios.kaffeekasse.ui.util.HorizontalSelectionBar @@ -99,7 +99,7 @@ import net.novagamestudios.kaffeekasse.ui.util.TopBarSearchAction import net.novagamestudios.kaffeekasse.ui.util.TopBarSearchField import net.novagamestudios.kaffeekasse.ui.util.TopBarSearchFieldState import net.novagamestudios.kaffeekasse.ui.util.VerticalSelectionBar -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler +import net.novagamestudios.common_utils.voyager.BackNavigationHandler import net.novagamestudios.kaffeekasse.ui.util.pullToRefresh import net.novagamestudios.kaffeekasse.util.richdata.asRichDataFlow import net.novagamestudios.kaffeekasse.util.richdata.combineRich @@ -179,10 +179,7 @@ class UserSelectionScreenModel private constructor( } -class UserSelectionContent(provider: ScreenModelProvider<UserSelectionScreenModel>) : ScaffoldContentWithModel<UserSelectionScreenModel>(provider) { - @Composable - override fun Content(navigator: Navigator) = UserSelection(model) - +class UserSelectionContent(provider: ScreenModelProvider<UserSelectionScreenModel>) : AppScaffoldContentWithModel<UserSelectionScreenModel>(provider) { @Composable override fun TopAppBarTitle(navigator: Navigator) { Row(verticalAlignment = Alignment.CenterVertically) { @@ -217,7 +214,7 @@ class UserSelectionContent(provider: ScreenModelProvider<UserSelectionScreenMode @Composable -private fun UserSelection( +fun UserSelection( model: UserSelectionScreenModel, modifier: Modifier = Modifier ) { diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt index 23e6682733a2d3796279f02285f15e483e7dd94c..0b18171354edbf72b6501aab9c127e73eeabe64a 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt @@ -1,66 +1,45 @@ package net.novagamestudios.kaffeekasse.ui.navigation -import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandHorizontally import androidx.compose.animation.shrinkHorizontally import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.unit.dp +import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator +import net.novagamestudios.common_utils.compose.components.scaffold.TopAppBar +import net.novagamestudios.common_utils.compose.components.scaffold.TopAppBarContent +import net.novagamestudios.common_utils.compose.nestedScroll +import net.novagamestudios.common_utils.voyager.AnimatedBackNavigationIcon +import net.novagamestudios.common_utils.voyager.debugNavigation +import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.kaffeekasse.CrashHandling import net.novagamestudios.kaffeekasse.ui.theme.LocalAnimationSwitch import net.novagamestudios.kaffeekasse.ui.theme.ifAnimationsEnabled -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler -import net.novagamestudios.kaffeekasse.ui.util.navigation.debugNavigation -@Composable -fun AppScaffoldNavigator( - key: String, - initialRoute: List<Screen>, - scaffoldContent: ScaffoldContent, - title: @Composable (Navigator) -> Unit = { scaffoldContent.TopAppBarTitle(it) }, - navigationIcon: @Composable (Navigator) -> Unit = { scaffoldContent.TopAppBarNavigationIcon(it) }, - actions: @Composable RowScope.(Navigator) -> Unit = { scaffoldContent.TopAppBarActions(it) }, - topAppBarScrollBehavior: TopAppBarScrollBehavior? = TopAppBarDefaults.enterAlwaysScrollBehavior(), - backNavigationHandlerProvider: @Composable (Navigator) -> BackNavigationHandler = { scaffoldContent.backNavigationHandler(it) }, - content: @Composable Navigator.() -> Unit = { AppScaffoldNavigatorDefaultContent("$key-content") } -) = AppScaffoldNavigator( - key = key, - initialRoute = initialRoute, - title = title, - navigationIcon = navigationIcon, - actions = actions, - topAppBarScrollBehavior = topAppBarScrollBehavior, - backNavigationHandlerProvider = backNavigationHandlerProvider, - content = content -) +interface AppScaffoldContent : TopAppBarContent + +abstract class AppScaffoldContentWithModel<out T : ScreenModel>( + provider: ScreenModelProvider<T> +) : AppScaffoldContent, ScreenModelProvider<T> by provider + @Composable fun AppScaffoldNavigator( key: String, initialRoute: List<Screen>, - title: @Composable (Navigator) -> Unit = { }, - navigationIcon: @Composable (Navigator) -> Unit = { }, - actions: @Composable RowScope.(Navigator) -> Unit = { }, - topAppBarScrollBehavior: TopAppBarScrollBehavior? = TopAppBarDefaults.enterAlwaysScrollBehavior(), - backNavigationHandlerProvider: @Composable (Navigator) -> BackNavigationHandler = { BackNavigationHandler.default() }, + scaffoldContent: AppScaffoldContent, + topAppBarScrollBehavior: TopAppBarScrollBehavior? = TopAppBarDefaults.enterAlwaysScrollBehavior().takeIf { LocalAnimationSwitch.current }, content: @Composable Navigator.() -> Unit = { AppScaffoldNavigatorDefaultContent("$key-content") } ) = Navigator( screens = initialRoute, @@ -69,23 +48,35 @@ fun AppScaffoldNavigator( ) { navigator -> debugNavigation() CrashHandling.updateNavigation(navigator) - val backNavigationHandler = backNavigationHandlerProvider(navigator) - AppScaffold( + Scaffold( + Modifier.nestedScroll(topAppBarScrollBehavior?.nestedScrollConnection), topBar = { - AppTopBar( - title = { title(navigator) }, - navigationIcon = { - DefaultBackNavigation(backNavigationHandler) - navigationIcon(navigator) + TopAppBar( + content = scaffoldContent, + navigator = navigator, + backNavigationIcon = { + AnimatedBackNavigationIcon( + handler = it, + enter = expandHorizontally().ifAnimationsEnabled(), + exit = shrinkHorizontally().ifAnimationsEnabled() + ) }, - actions = { actions(navigator) }, + colors = TopAppBarDefaults.topAppBarColors( + scrolledContainerColor = MaterialTheme.colorScheme.surface + ), scrollBehavior = topAppBarScrollBehavior ) - }, - topAppBarScrollBehavior = topAppBarScrollBehavior - ) { - navigator.content() - backNavigationHandler.BackHandler() + } + ) { paddingValues -> + Box( + Modifier + .padding(paddingValues) + .fillMaxSize(), + propagateMinConstraints = true + ) { + navigator.content() + scaffoldContent.backNavigationHandler(navigator).BackHandler() + } } } @@ -98,61 +89,6 @@ fun Navigator.AppScaffoldNavigatorDefaultContent( } } -@Composable -private fun AppScaffold( - modifier: Modifier = Modifier, - topBar: @Composable () -> Unit = { }, - topAppBarScrollBehavior: TopAppBarScrollBehavior? = null, - content: @Composable () -> Unit -) = Scaffold( - modifier.run { - if (topAppBarScrollBehavior == null || !LocalAnimationSwitch.current) this - else nestedScroll(topAppBarScrollBehavior.nestedScrollConnection) - }, - topBar = topBar -) { paddingValues -> - Box( - Modifier - .padding(paddingValues) - .fillMaxSize(), - propagateMinConstraints = true - ) { - content() - } -} - -@Composable -fun AppTopBar( - title: @Composable () -> Unit, - modifier: Modifier = Modifier, - navigationIcon: @Composable () -> Unit = {}, - actions: @Composable RowScope.() -> Unit = {}, - scrollBehavior: TopAppBarScrollBehavior? = null -) = TopAppBar( - title = { title() }, - modifier = modifier, - navigationIcon = { navigationIcon() }, - actions = { actions() }, - colors = TopAppBarDefaults.topAppBarColors( - scrolledContainerColor = MaterialTheme.colorScheme.surface - ), - scrollBehavior = scrollBehavior.takeIf { LocalAnimationSwitch.current } -) @Composable fun AppSubpageTitle(text: String) = Text(text, Modifier.padding(start = 8.dp)) - -@Composable -fun DefaultBackNavigation( - handler: BackNavigationHandler -) { - AnimatedVisibility( - visible = handler.canNavigateBack(), - enter = expandHorizontally().ifAnimationsEnabled(), - exit = shrinkHorizontally().ifAnimationsEnabled() - ) { - IconButton(onClick = { handler.onNavigateBack() }) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back") - } - } -} \ No newline at end of file diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt index 0275f8820f7ea20e1e86c782a2860a5f84db8640..a3da37d2e9d46fb81e54644b99f5d0985e15786c 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt @@ -2,6 +2,7 @@ package net.novagamestudios.kaffeekasse.ui.navigation import androidx.compose.foundation.background import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -11,6 +12,8 @@ import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.navigator.tab.TabNavigator import cafe.adriel.voyager.navigator.tab.TabOptions +import net.novagamestudios.common_utils.compose.components.BoxCenter +import net.novagamestudios.common_utils.compose.components.scaffold.ScaffoldContentProvider import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider import net.novagamestudios.common_utils.voyager.model.getValue import net.novagamestudios.common_utils.voyager.screen.ScreenWithModel @@ -20,27 +23,34 @@ import net.novagamestudios.kaffeekasse.model.session.deviceOrNull import net.novagamestudios.kaffeekasse.ui.AppModulesScreenModel import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.HiwiTrackerModuleContent import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.HiwiTrackerModuleScreenModel +import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.Overview import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.OverviewContent import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.OverviewScreenModel +import net.novagamestudios.kaffeekasse.ui.kaffeekasse.Account import net.novagamestudios.kaffeekasse.ui.kaffeekasse.AccountContent import net.novagamestudios.kaffeekasse.ui.kaffeekasse.AccountScreenModel +import net.novagamestudios.kaffeekasse.ui.kaffeekasse.DynamicManualBill import net.novagamestudios.kaffeekasse.ui.kaffeekasse.KaffeekasseModuleContent import net.novagamestudios.kaffeekasse.ui.kaffeekasse.KaffeekasseModuleScreenModel import net.novagamestudios.kaffeekasse.ui.kaffeekasse.ManualBillContent import net.novagamestudios.kaffeekasse.ui.kaffeekasse.ManualBillScreenModel +import net.novagamestudios.kaffeekasse.ui.kaffeekasse.Transactions import net.novagamestudios.kaffeekasse.ui.kaffeekasse.TransactionsContent import net.novagamestudios.kaffeekasse.ui.kaffeekasse.TransactionsScreenModel +import net.novagamestudios.kaffeekasse.ui.login.LoginAdditional import net.novagamestudios.kaffeekasse.ui.login.LoginContent +import net.novagamestudios.kaffeekasse.ui.login.LoginForm import net.novagamestudios.kaffeekasse.ui.login.LoginFormContent import net.novagamestudios.kaffeekasse.ui.login.LoginFormScreenModel import net.novagamestudios.kaffeekasse.ui.login.LoginScreenModel +import net.novagamestudios.kaffeekasse.ui.login.UserSelection import net.novagamestudios.kaffeekasse.ui.login.UserSelectionContent import net.novagamestudios.kaffeekasse.ui.login.UserSelectionScreenModel sealed interface LoginNavigation { - companion object : LoginNavigation, ScreenWithModel<LoginScreenModel>, ScaffoldScreen { + companion object : LoginNavigation, ScreenWithModel<LoginScreenModel>, ScaffoldContentProvider { @get:Composable override val model by LoginScreenModel private val initialScreen: Screen @Composable get() = model .session @@ -51,25 +61,34 @@ sealed interface LoginNavigation { @Composable override fun Content() = AppScaffoldNavigator( key = "login-navigator", initialRoute = listOf(initialScreen), - title = { scaffoldContent.TopAppBarTitle(it) }, - actions = { scaffoldContent.TopAppBarActions(it) }, + scaffoldContent = scaffoldContent, topAppBarScrollBehavior = null, - content = { scaffoldContent.Content(this) }, - backNavigationHandlerProvider = { scaffoldContent.backNavigationHandler(it) } + content = { + if (model.isLoading) { + BoxCenter(Modifier.fillMaxSize()) { + CircularProgressIndicator() + } + } else { + AppScaffoldNavigatorDefaultContent("login-navigator-content") + } + LoginAdditional(model, this) + } ) } - data object FormScreen : LoginNavigation, ScreenWithModel<LoginFormScreenModel>, ScaffoldScreen { + data object FormScreen : LoginNavigation, ScreenWithModel<LoginFormScreenModel>, ScaffoldContentProvider { private fun readResolve(): Any = FormScreen @get:Composable override val model by LoginFormScreenModel override val scaffoldContent = LoginFormContent(this) + @Composable override fun Content() = LoginForm(model) } data class UserSelectionScreen( val device: Device - ) : LoginNavigation, ScreenWithModel<UserSelectionScreenModel>, ScaffoldScreen { + ) : LoginNavigation, ScreenWithModel<UserSelectionScreenModel>, ScaffoldContentProvider { @get:Composable override val model by UserSelectionScreenModel override val scaffoldContent = UserSelectionContent(this) + @Composable override fun Content() = UserSelection(model) } } @@ -110,7 +129,7 @@ sealed interface KaffeekasseNavigation { data class Tab( override val session: Session.WithRealUser - ) : ModuleTab, KaffeekasseNavigation, ScreenModelProvider<KaffeekasseModuleScreenModel>, ScaffoldScreen { + ) : ModuleTab, KaffeekasseNavigation, ScreenModelProvider<KaffeekasseModuleScreenModel>, ScaffoldContentProvider { @get:Composable override val model by KaffeekasseModuleScreenModel override val scaffoldContent = KaffeekasseModuleContent(this) @Composable override fun Content() = AppScaffoldNavigator( @@ -123,23 +142,26 @@ sealed interface KaffeekasseNavigation { data class ManualBillScreen( val session: Session.WithRealUser - ) : KaffeekasseNavigation, ScreenWithModel<ManualBillScreenModel>, ScaffoldScreen { + ) : KaffeekasseNavigation, ScreenWithModel<ManualBillScreenModel>, ScaffoldContentProvider { @get:Composable override val model by ManualBillScreenModel override val scaffoldContent = ManualBillContent(this) + @Composable override fun Content() = DynamicManualBill(model) } data class AccountScreen( val session: Session.WithRealUser - ) : KaffeekasseNavigation, ScreenWithModel<AccountScreenModel>, ScaffoldScreen { + ) : KaffeekasseNavigation, ScreenWithModel<AccountScreenModel>, ScaffoldContentProvider { @get:Composable override val model by AccountScreenModel override val scaffoldContent = AccountContent(this) + @Composable override fun Content() = Account(model) } data class TransactionsScreen( val session: Session.WithRealUser - ) : KaffeekasseNavigation, ScreenWithModel<TransactionsScreenModel>, ScaffoldScreen { + ) : KaffeekasseNavigation, ScreenWithModel<TransactionsScreenModel>, ScaffoldContentProvider { @get:Composable override val model by TransactionsScreenModel override val scaffoldContent = TransactionsContent(this) + @Composable override fun Content() = Transactions(model) } } @@ -148,7 +170,7 @@ sealed interface HiwiTrackerNavigation { data class Tab( override val session: Session.WithRealUser - ) : ModuleTab, HiwiTrackerNavigation, ScreenModelProvider<HiwiTrackerModuleScreenModel>, ScaffoldScreen { + ) : ModuleTab, HiwiTrackerNavigation, ScreenModelProvider<HiwiTrackerModuleScreenModel>, ScaffoldContentProvider { @get:Composable override val model by HiwiTrackerModuleScreenModel override val scaffoldContent = HiwiTrackerModuleContent(this) @Composable override fun Content() = AppScaffoldNavigator( @@ -161,8 +183,9 @@ sealed interface HiwiTrackerNavigation { data class OverviewScreen( val session: Session.WithRealUser - ) : HiwiTrackerNavigation, ScreenWithModel<OverviewScreenModel>, ScaffoldScreen { + ) : HiwiTrackerNavigation, ScreenWithModel<OverviewScreenModel>, ScaffoldContentProvider { @get:Composable override val model by OverviewScreenModel override val scaffoldContent = OverviewContent(this) + @Composable override fun Content() = Overview(model) } } diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/ScaffoldContent.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/ScaffoldContent.kt deleted file mode 100644 index 4c00c388d4ecdbd72e7d2125c812c5bbca62d39d..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/ScaffoldContent.kt +++ /dev/null @@ -1,44 +0,0 @@ -package net.novagamestudios.kaffeekasse.ui.navigation - -import androidx.compose.runtime.Composable -import cafe.adriel.voyager.core.model.ScreenModel -import cafe.adriel.voyager.core.screen.Screen -import cafe.adriel.voyager.navigator.LocalNavigator -import cafe.adriel.voyager.navigator.Navigator -import cafe.adriel.voyager.navigator.currentOrThrow -import net.novagamestudios.common_utils.voyager.model.ScreenModelProvider -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler -import java.io.Serializable - - -abstract class ScaffoldContent : Serializable { - @Composable - abstract fun Content(navigator: Navigator) - @Composable - open fun TopAppBarNavigationIcon(navigator: Navigator): Unit = default(navigator) { TopAppBarNavigationIcon(it) } ?: Unit - @Composable - open fun TopAppBarTitle(navigator: Navigator): Unit = default(navigator) { TopAppBarTitle(it) } ?: Unit - @Composable - open fun TopAppBarActions(navigator: Navigator): Unit = default(navigator) { TopAppBarActions(it) } ?: Unit - @Composable - open fun backNavigationHandler(navigator: Navigator): BackNavigationHandler = default(navigator) { backNavigationHandler(it) } ?: BackNavigationHandler.Disabled - - @Composable - protected inline fun <R> default(navigator: Navigator, block: ScaffoldContent.(Navigator) -> R): R? { - val screen = navigator.lastItem - if (screen !is ScaffoldScreen) return null - val scaffoldContent = screen.scaffoldContent - if (scaffoldContent == this) return null - return scaffoldContent.block(navigator) - } -} - -abstract class ScaffoldContentWithModel<out T : ScreenModel>( - provider: ScreenModelProvider<T> -) : ScaffoldContent(), ScreenModelProvider<T> by provider - -interface ScaffoldScreen : Screen { - val scaffoldContent: ScaffoldContent - @Composable - override fun Content() = scaffoldContent.Content(LocalNavigator.currentOrThrow) -} diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/Helpers.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/Helpers.kt index d740b225547a81cf21619448d7864538bf89741c..0b98aa8ed0a4d28422ef1c1a88b0f580ac44c891 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/Helpers.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/Helpers.kt @@ -21,9 +21,9 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import io.ktor.http.Url -import net.novagamestudios.common_utils.LoggerForFun -import net.novagamestudios.common_utils.error -import net.novagamestudios.common_utils.toastShort +import net.novagamestudios.common_utils.android.toastShort +import net.novagamestudios.common_utils.logging.LoggerForFun +import net.novagamestudios.common_utils.logging.error @Composable diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/TopBarSearchField.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/TopBarSearchField.kt index 118993cc476965a9dc05d3167bf58f9327350526..6726d62d130ce4317003e7bead6529385db7fc53 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/TopBarSearchField.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/TopBarSearchField.kt @@ -16,7 +16,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester -import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler +import net.novagamestudios.common_utils.voyager.BackNavigationHandler class TopBarSearchFieldState { diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/navigation/BackNavigationHandler.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/navigation/BackNavigationHandler.kt deleted file mode 100644 index eafa69a88d42c823319f547f145fa0ff773e839a..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/navigation/BackNavigationHandler.kt +++ /dev/null @@ -1,67 +0,0 @@ -package net.novagamestudios.kaffeekasse.ui.util.navigation - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import cafe.adriel.voyager.navigator.LocalNavigator -import cafe.adriel.voyager.navigator.Navigator -import cafe.adriel.voyager.navigator.currentOrThrow - -interface BackNavigationHandler { - - /** - * @return true if back navigation ui components should be shown. - * false does not mean that the navigation can not be handled - */ - fun canNavigateBack(): Boolean - - /** - * @return true if the navigation was handled and false if it should be passed on - */ - fun onNavigateBack(): Boolean - - @Composable - fun BackHandler() = androidx.activity.compose.BackHandler { - onNavigateBack() - } - - companion object { - val Disabled = object : BackNavigationHandler { - override fun canNavigateBack() = false - override fun onNavigateBack() = true - @Composable - override fun BackHandler() { } - } - fun forNavigator(navigator: Navigator) = object : BackNavigationHandler { - override fun canNavigateBack() = navigator.canPop - override fun onNavigateBack(): Boolean { - navigator.pop() - return true - } - } - @Composable - fun default(): BackNavigationHandler { - val navigator = LocalNavigator.currentOrThrow - return remember(navigator) { forNavigator(navigator) } - } - infix fun BackNavigationHandler?.then(parent: BackNavigationHandler?) = object : - BackNavigationHandler { - override fun canNavigateBack(): Boolean { - return this@then?.canNavigateBack() == true || parent?.canNavigateBack() == true - } - override fun onNavigateBack(): Boolean { - return this@then?.onNavigateBack() == true || parent?.onNavigateBack() == true - } - } - - fun derivedOf( - canNavigateBack: () -> Boolean, - onNavigateBack: () -> Boolean - ) = object : BackNavigationHandler { - private val _canNavigateBack by derivedStateOf(canNavigateBack) - override fun canNavigateBack() = _canNavigateBack - override fun onNavigateBack() = onNavigateBack() - } - } -} diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/navigation/Navigation.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/navigation/Navigation.kt deleted file mode 100644 index 2aabdf67219712f62d8bc412da1c89b816902170..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/util/navigation/Navigation.kt +++ /dev/null @@ -1,56 +0,0 @@ -package net.novagamestudios.kaffeekasse.ui.util.navigation - -import androidx.compose.runtime.Composable -import cafe.adriel.voyager.core.annotation.InternalVoyagerApi -import cafe.adriel.voyager.core.screen.Screen -import cafe.adriel.voyager.navigator.LocalNavigator -import cafe.adriel.voyager.navigator.Navigator -import cafe.adriel.voyager.navigator.currentOrThrow -import net.novagamestudios.common_utils.debug - -@OptIn(InternalVoyagerApi::class) -@Composable -fun debugNavigation() { - fun StringBuilder.addNavigator(navigator: Navigator) { - navigator.parent?.let { addNavigator(it) } - val indent = " ".repeat(navigator.level) - appendLine("${indent}Navigator: ${navigator.key}") - navigator.items.forEach { screen -> - appendLine("${indent}- ${screen.key}: ${screen::class.qualifiedName}") - } - } - val navigator = LocalNavigator.currentOrThrow - val result = StringBuilder().apply { - addNavigator(navigator) - }.toString() - debug { result } -} - -tailrec fun Navigator.findNavigatorOrNull(predicate: (Navigator) -> Boolean): Navigator? { - if (predicate(this)) return this - return parent?.findNavigatorOrNull(predicate) -} - -@OptIn(InternalVoyagerApi::class) -fun Navigator.requireWithKey(key: String) = findNavigatorOrNull { it.key == key } - ?: error("Navigator with key '$key' not found") - - -@Composable -inline fun <reified T : Screen> nearestScreenOrNull(): T? { - var navigator = LocalNavigator.current - while (navigator != null) { - val screen = navigator.items.filterIsInstance<T>().lastOrNull() - if (screen != null) return screen - navigator = navigator.parent - } - return null -} - -@Composable -inline fun <reified T : Screen> nearestScreen(): T { - return nearestScreenOrNull() ?: error("No screen of type ${T::class.qualifiedName} found") -} - -@Suppress("RecursivePropertyAccessor") -val Navigator.root: Navigator get() = parent?.root ?: this diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/util/JSParser.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/util/JSParser.kt deleted file mode 100644 index 8c8b1e0179b9da05437b5579f7953240b9617ba9..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/util/JSParser.kt +++ /dev/null @@ -1,198 +0,0 @@ -package net.novagamestudios.kaffeekasse.util - -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.json.JsonArray -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive - - -private data class Cursor( - val data: String, - private var i: Int -) { - fun peek(): Char { - if (!hasNext()) throw Exception("Unexpected end of data") - return data[i] - } - fun next(): Char { - val char = peek() - i++ - return char - } - fun hasNext(): Boolean = i < data.length - - fun peek(n: Int): String? { - if (i + n > data.length) return null - return data.substring(i, i + n) - } - - - fun whitespace() { - while (hasNext() && peek().isWhitespace()) next() - } - - inline fun nextWhile(crossinline predicate: (Char) -> Boolean) = sequence { - while (hasNext()) { - if (!predicate(peek())) break - yield(next()) - } - } - - fun expect(expect: Char) { - val actual = next() - if (actual != expect) throw Exception("Expected '$expect' but got '$actual' at ${i - 1}") - } - fun expect(expect: Set<Char>): Char { - val actual = next() - if (actual !in expect) throw Exception( - "Expected one of ${expect.joinToString(separator = ", ") { "'$it'" }} but got '$actual' at $i" - ) - return actual - } - fun peekExpect(expect: Set<Char>): Char { - val actual = peek() - if (actual !in expect) throw Exception( - "Expected one of ${expect.joinToString(separator = ", ") { "'$it'" }} but got '$actual' at $i" - ) - return actual - } - - fun tryNext(str: String): Boolean { - if (i + str.length > data.length) return false - if (data.substring(i, i + str.length) != str) return false - i += str.length - return true - } - - override fun toString(): String { - val window = 20 - return data.substring((i - window / 2)..<i) + "|" + data.substring(i..<(i + window / 2)) - } -} - -private fun Cursor.parseJSArray(): JsonArray { - whitespace() - expect('[') - whitespace() - if (peek() == ']') return JsonArray(emptyList()) - val content = mutableListOf<JsonElement>() - while (true) { - content += parseJSElement() - whitespace() - if (expect(setOf(',', ']')) == ']') break - } - return JsonArray(content) -} - -private fun Cursor.parseJSObject(): JsonObject { - whitespace() - expect('{') - whitespace() - if (peek() == '}') return JsonObject(emptyMap()) - val content = mutableMapOf<String, JsonElement>() - while (true) { - whitespace() - val key = tryParseJSIdentifier() - ?: tryParseJSString() - ?: tryParseJSNumber()?.toString() - ?: throw Exception("Invalid key starting with '${peek()}'") - if (key in content) throw Exception("Duplicate key \"$key\"") - whitespace() - expect(':') - whitespace() - content[key] = parseJSElement() - whitespace() - if (expect(setOf(',', '}')) == '}') break - } - return JsonObject(content) -} - - -private fun Cursor.tryParseJSBoolean(): Boolean? { - if (tryNext("true")) return true - if (tryNext("false")) return false - return null -} - - -private fun Cursor.tryParseJSIdentifier(): String? { - if (peek().let { it.isLetter() || it == '$' || it == '_' }) { - return nextWhile { it.isLetterOrDigit() || it == '$' || it == '_' }.joinToString("") - } - return null -} -private fun Cursor.tryParseJSNumber(): Number? { - if (peek().isDigit()) { - return nextWhile { it.isDigit() }.fold(0) { number, char -> number * 10 + char.digitToInt() } - } - return null -} - -private fun Cursor.parseJSStringChar(start: Char): Char? { - val char = next() - if (char == '\\') { - return when (val esc = next()) { - '0' -> Char(0) - 'b' -> '\b' - 'f' -> TODO() - 'n' -> '\n' - 'r' -> '\r' - 't' -> '\t' - 'v' -> TODO() - '\'' -> '\'' - '"' -> '"' - '\\' -> '\\' - 'x' -> Char("${next()}${next()}".toInt(16)) - 'u' -> Char("${next()}${next()}${next()}${next()}".toInt(16)) - else -> throw Exception("Unknown escaped char '$esc'") - } - } - if (char == start) return null - return char -} - -private fun Cursor.tryParseJSString(): String? { - if (peek().let { it == '\'' || it == '"' }) { - val start = next() - var str = "" - while (true) { - val char = parseJSStringChar(start) ?: break - str += char - } - return str - } - return null -} - -@OptIn(ExperimentalSerializationApi::class) -private fun Cursor.parseJSPrimitive(): JsonPrimitive { - whitespace() - if (tryNext("null")) return JsonPrimitive(null) - tryParseJSBoolean()?.let { return JsonPrimitive(it) } - tryParseJSNumber()?.let { return JsonPrimitive(it) } - tryParseJSString()?.let { return JsonPrimitive(it) } - - tryParseJSIdentifier()?.let { return JsonPrimitive("$$it") } - throw Exception("Unexpected character '${peek()}'") -} - -private fun Cursor.parseJSElement(): JsonElement { - whitespace() - return when (peek()) { - '{' -> parseJSObject() - '[' -> parseJSArray() - else -> parseJSPrimitive() - } -} - -object JSParser { - fun parseToJson(str: String): JsonElement { - Cursor(str, 0).run { - return parseJSElement().also { - whitespace() - if (hasNext()) throw Exception("Expected end of data") - } - } - } -} diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/util/ReentrantMutex.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/util/ReentrantMutex.kt deleted file mode 100644 index 2fac48e1e99702c7eabfff3095d4ce169217b094..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/util/ReentrantMutex.kt +++ /dev/null @@ -1,23 +0,0 @@ -package net.novagamestudios.kaffeekasse.util - -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.coroutineContext - - -//class ReentrantMutex { -// private val mutex = Mutex() -// val isLocked get() = mutex.isLocked -// suspend fun <T> withReentrantLock(block: suspend () -> T) = mutex.withReentrantLock(block) -//} - -suspend fun <T> Mutex.withReentrantLock(block: suspend () -> T): T { - val key = ReentrantMutexContextKey(this) - if (coroutineContext[key] != null) return block() - return withContext(ReentrantMutexContextElement(key)) { withLock { block() } } -} - -private class ReentrantMutexContextElement(override val key: ReentrantMutexContextKey) : CoroutineContext.Element -private data class ReentrantMutexContextKey(val mutex: Mutex) : CoroutineContext.Key<ReentrantMutexContextElement> diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/util/Serialization.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/util/Serialization.kt deleted file mode 100644 index d8a1431308dc7c77eb9ff5ec655b4e7cf224d24d..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/util/Serialization.kt +++ /dev/null @@ -1,18 +0,0 @@ -package net.novagamestudios.kaffeekasse.util - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - - -object IntAsBooleanSerializer : KSerializer<Boolean> { - override val descriptor = PrimitiveSerialDescriptor("IntAsBoolean", PrimitiveKind.INT) - override fun serialize(encoder: Encoder, value: Boolean) { - encoder.encodeInt(if (value) 1 else 0) - } - override fun deserialize(decoder: Decoder): Boolean { - return decoder.decodeInt() != 0 - } -} diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/util/Util.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/util/Util.kt deleted file mode 100644 index 44d29309106ce4014dd9b0d0987b6761f677947e..0000000000000000000000000000000000000000 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/util/Util.kt +++ /dev/null @@ -1,37 +0,0 @@ -package net.novagamestudios.kaffeekasse.util - -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.sync.Mutex -import kotlinx.datetime.LocalTime -import kotlin.time.Duration -import kotlin.time.Duration.Companion.nanoseconds - - -operator fun LocalTime.minus(other: LocalTime): Duration { - return (toNanosecondOfDay() - other.toNanosecondOfDay()).nanoseconds -} - - -inline fun Mutex.tryWithLock(owner: Any? = null, block: () -> Unit): Boolean { - if (!tryLock(owner)) return false - try { - block() - } finally { - unlock(owner) - } - return true -} - -fun <T, R> StateFlow<T>.mapState( - transform: (T) -> R -): StateFlow<R> = object : StateFlow<R> { - override val replayCache: List<R> get() = this@mapState.replayCache.map(transform) - override val value: R get() = transform(this@mapState.value) - override suspend fun collect(collector: FlowCollector<R>): Nothing { - this@mapState.collect { value -> collector.emit(transform(value)) } - } -} - -context (T) -fun <T> context(): T = this@T diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataFlow.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataFlow.kt index 71c1a3a27970700897ae367854a1c6cde4e1998f..e66a320aa3373b36a13c00de9a03d6f7499ff939 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataFlow.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataFlow.kt @@ -13,8 +13,8 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.transform import kotlinx.coroutines.flow.transformLatest +import net.novagamestudios.common_utils.collection.mapState import net.novagamestudios.common_utils.compose.components.Progress -import net.novagamestudios.kaffeekasse.util.mapState typealias RichDataFlow<T> = Flow<RichData<T>> diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataSource.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataSource.kt index 403996b5c0b4eba0bdad85a278afe286cf1df69c..0edfe02b366c2904211afdb7fc906cdafb780bde 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataSource.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/util/richdata/RichDataSource.kt @@ -7,9 +7,8 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.launchIn -import net.novagamestudios.common_utils.Logger import net.novagamestudios.common_utils.compose.components.Progress -import net.novagamestudios.common_utils.error +import net.novagamestudios.common_utils.logging.Logger import kotlin.coroutines.suspendCoroutine typealias RichDataCollector<T> = FlowCollector<RichData<T>> diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b04dcf62f344d57f9e68ee447da76c4cbf636ac9..0f97579c3f30575cba2272f394498852b0914db3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ vico = "2.0.0-alpha.8" voyager = "1.0.0" coil = "2.6.0" acra = "5.11.3" -commonutils = "ee87e097c5" +commonutils = "e4ef869304" junit4 = "4.13.2" [plugins] @@ -83,10 +83,13 @@ acra-toast = { group = "ch.acra", name = "acra-toast", version.ref = "acra" } acra-limiter = { group = "ch.acra", name = "acra-limiter", version.ref = "acra" } acra-advancedscheduler = { group = "ch.acra", name = "acra-advanced-scheduler", version.ref = "acra" } +# JitPack commonutils-core = { group = "com.gitlab.JojoIV", name = "common_utils-core", version.ref = "commonutils" } +commonutils-compose = { group = "com.gitlab.JojoIV", name = "common_utils-compose", version.ref = "commonutils" } commonutils-voyager = { group = "com.gitlab.JojoIV", name = "common_utils-voyager", version.ref = "commonutils" } # Maven Local #commonutils-core = { group = "net.novagamestudios.common_utils", name = "common_utils-core", version = "unspecified" } +#commonutils-compose = { group = "net.novagamestudios.common_utils", name = "common_utils-compose", version = "unspecified" } #commonutils-voyager = { group = "net.novagamestudios.common_utils", name = "common_utils-voyager", version = "unspecified" } junit4 = { group = "junit", name = "junit", version.ref = "junit4" }