diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/AppWorker.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/AppWorker.kt index 2417132..384e107 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/AppWorker.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/AppWorker.kt @@ -1,18 +1,21 @@ package com.artemchep.keyguard.common +import com.artemchep.keyguard.common.io.attempt +import com.artemchep.keyguard.common.io.launchIn import com.artemchep.keyguard.common.model.MasterSession import com.artemchep.keyguard.common.usecase.GetVaultSession +import com.artemchep.keyguard.common.usecase.UpdateVersionLog import com.artemchep.keyguard.platform.lifecycle.LeLifecycleState import com.artemchep.keyguard.platform.lifecycle.onState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch import org.kodein.di.DirectDI import org.kodein.di.direct @@ -20,9 +23,11 @@ import org.kodein.di.instance class AppWorkerIm( private val getVaultSession: GetVaultSession, + private val updateVersionLog: UpdateVersionLog, ) : AppWorker { constructor(directDI: DirectDI) : this( getVaultSession = directDI.instance(), + updateVersionLog = directDI.instance(), ) override fun launch( @@ -35,7 +40,17 @@ class AppWorkerIm( .onState(LeLifecycleState.STARTED) { launchSyncManagerWhenAvailable(this) } - .collect() + .launchIn(this) + // The app should keep a log of last installed versions, + // so we can show a nice changelog to a user. + flow + .onState(LeLifecycleState.STARTED) { + updateVersionLog() + .attempt() + .launchIn(this) + } + .take(1) // no need to restart, the version won't change + .launchIn(this) } private fun launchSyncManagerWhenAvailable(scope: CoroutineScope) = getVaultSession() diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/model/AppVersionLog.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/model/AppVersionLog.kt new file mode 100644 index 0000000..ee0cd90 --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/model/AppVersionLog.kt @@ -0,0 +1,9 @@ +package com.artemchep.keyguard.common.model + +import kotlinx.datetime.Instant + +data class AppVersionLog( + val version: String, + val ref: String, + val timestamp: Instant, +) diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/keyvalue/KeyValueStore.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/keyvalue/KeyValueStore.kt index 9ee8f78..f21c31b 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/keyvalue/KeyValueStore.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/keyvalue/KeyValueStore.kt @@ -8,6 +8,9 @@ import kotlinx.coroutines.InternalCoroutinesApi import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json interface KeyValueStore { companion object { @@ -59,6 +62,30 @@ fun KeyValueStore.getObject( } } +inline fun KeyValueStore.getSerializable( + json: Json, + key: String, + defaultValue: T, +): KeyValuePreference = getObject( + key = key, + defaultValue = defaultValue, + serialize = { entity -> + if (entity == null) { + return@getObject "" + } + + json.encodeToString(entity) + }, + deserialize = { + runCatching { + json.decodeFromString(it) + }.getOrElse { + // Fallback to the default value + defaultValue + } + }, +) + inline fun > KeyValueStore.getEnumNullable( key: String, crossinline lens: (T) -> String, diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadRepository.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadRepository.kt index 387fc09..2828a5a 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadRepository.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadRepository.kt @@ -3,6 +3,7 @@ package com.artemchep.keyguard.common.service.settings import com.artemchep.keyguard.common.model.AppColors import com.artemchep.keyguard.common.model.AppFont import com.artemchep.keyguard.common.model.AppTheme +import com.artemchep.keyguard.common.model.AppVersionLog import com.artemchep.keyguard.common.model.NavAnimation import kotlinx.coroutines.flow.Flow import kotlinx.datetime.Instant @@ -64,6 +65,8 @@ interface SettingsReadRepository { fun getMarkdown(): Flow + fun getAppVersionLog(): Flow> + fun getNavAnimation(): Flow fun getNavLabel(): Flow diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadWriteRepository.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadWriteRepository.kt index 6c7ad0d..d7e8ef4 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadWriteRepository.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/SettingsReadWriteRepository.kt @@ -4,6 +4,7 @@ import com.artemchep.keyguard.common.io.IO import com.artemchep.keyguard.common.model.AppColors import com.artemchep.keyguard.common.model.AppFont import com.artemchep.keyguard.common.model.AppTheme +import com.artemchep.keyguard.common.model.AppVersionLog import com.artemchep.keyguard.common.model.NavAnimation import kotlinx.datetime.Instant import kotlin.time.Duration @@ -112,6 +113,10 @@ interface SettingsReadWriteRepository : SettingsReadRepository { markdown: Boolean, ): IO + fun setAppVersionLog( + log: List, + ): IO + fun setOnboardingLastVisitInstant( instant: Instant, ): IO diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/entity/VersionLogEntity.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/entity/VersionLogEntity.kt new file mode 100644 index 0000000..3f8edca --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/entity/VersionLogEntity.kt @@ -0,0 +1,47 @@ +package com.artemchep.keyguard.common.service.settings.entity + +import com.artemchep.keyguard.common.model.AppVersionLog +import kotlinx.datetime.Instant +import kotlinx.serialization.Serializable + +@Serializable +data class VersionLogEntity( + val items: List = emptyList(), +) { + companion object; + + @Serializable + data class Item( + val version: String, + val ref: String, + val timestamp: Instant, + ) +} + +fun VersionLogEntity.Companion.of( + log: List, +) = kotlin.run { + val items = log + .map { item -> + VersionLogEntity.Item( + version = item.version, + ref = item.ref, + timestamp = item.timestamp, + ) + } + VersionLogEntity( + items = items, + ) +} + +fun VersionLogEntity.toDomain(): List = run { + val items = items + .map { item -> + AppVersionLog( + version = item.version, + ref = item.ref, + timestamp = item.timestamp, + ) + } + items +} diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/impl/SettingsRepositoryImpl.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/impl/SettingsRepositoryImpl.kt index 49b7d0b..b1e1ca8 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/impl/SettingsRepositoryImpl.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/service/settings/impl/SettingsRepositoryImpl.kt @@ -1,20 +1,29 @@ package com.artemchep.keyguard.common.service.settings.impl import com.artemchep.keyguard.common.io.IO +import com.artemchep.keyguard.common.io.flatMap +import com.artemchep.keyguard.common.io.ioEffect import com.artemchep.keyguard.common.model.AppColors import com.artemchep.keyguard.common.model.AppFont import com.artemchep.keyguard.common.model.AppTheme +import com.artemchep.keyguard.common.model.AppVersionLog import com.artemchep.keyguard.common.model.NavAnimation import com.artemchep.keyguard.common.service.Files import com.artemchep.keyguard.common.service.keyvalue.KeyValueStore import com.artemchep.keyguard.common.service.keyvalue.asDuration import com.artemchep.keyguard.common.service.keyvalue.getEnumNullable import com.artemchep.keyguard.common.service.keyvalue.getObject +import com.artemchep.keyguard.common.service.keyvalue.getSerializable import com.artemchep.keyguard.common.service.keyvalue.setAndCommit import com.artemchep.keyguard.common.service.settings.SettingsReadWriteRepository +import com.artemchep.keyguard.common.service.settings.entity.VersionLogEntity +import com.artemchep.keyguard.common.service.settings.entity.of +import com.artemchep.keyguard.common.service.settings.entity.toDomain import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.datetime.Instant +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json import org.kodein.di.DirectDI import org.kodein.di.instance import kotlin.time.Duration @@ -24,6 +33,7 @@ import kotlin.time.Duration */ class SettingsRepositoryImpl( private val store: KeyValueStore, + private val json: Json, ) : SettingsReadWriteRepository { companion object { private const val KEY_AUTOFILL_INLINE_SUGGESTIONS = "autofill.inline_suggestions" @@ -51,6 +61,7 @@ class SettingsRepositoryImpl( private const val KEY_APP_ICONS = "app_icons" private const val KEY_WEBSITE_ICONS = "website_icons" private const val KEY_MARKDOWN = "markdown" + private const val KEY_VERSION_LOG = "version_log" private const val KEY_NAV_ANIMATION = "nav_animation" private const val KEY_NAV_LABEL = "nav_label" private const val KEY_TWO_PANEL_LAYOUT_LANDSCAPE = "two_panel_layout_landscape" @@ -185,8 +196,16 @@ class SettingsRepositoryImpl( }, ) + private val versionLogPref = + store.getSerializable( + json, + KEY_VERSION_LOG, + defaultValue = null, + ) + constructor(directDI: DirectDI) : this( store = directDI.instance(arg = Files.SETTINGS), + json = directDI.instance(), ) override fun setAutofillInlineSuggestions(inlineSuggestions: Boolean) = @@ -326,6 +345,26 @@ class SettingsRepositoryImpl( override fun getMarkdown() = markdownPref + override fun setAppVersionLog(log: List) = + ioEffect { + val entity = log + .takeIf { it.isNotEmpty() } + // convert to an entity + ?.let { + VersionLogEntity.of(it) + } + entity + }.flatMap { entity -> + versionLogPref + .setAndCommit(entity) + } + + override fun getAppVersionLog() = versionLogPref + .map { entity -> + entity?.toDomain() + .orEmpty() + } + override fun setNavAnimation(navAnimation: NavAnimation?) = navAnimationPref .setAndCommit(navAnimation) diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/GetVersionLog.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/GetVersionLog.kt new file mode 100644 index 0000000..d854b5d --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/GetVersionLog.kt @@ -0,0 +1,6 @@ +package com.artemchep.keyguard.common.usecase + +import com.artemchep.keyguard.common.model.AppVersionLog +import kotlinx.coroutines.flow.Flow + +interface GetVersionLog : () -> Flow> diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/UpdateVersionLog.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/UpdateVersionLog.kt new file mode 100644 index 0000000..6959940 --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/UpdateVersionLog.kt @@ -0,0 +1,5 @@ +package com.artemchep.keyguard.common.usecase + +import com.artemchep.keyguard.common.io.IO + +interface UpdateVersionLog : () -> IO diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/GetVersionLogImpl.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/GetVersionLogImpl.kt new file mode 100644 index 0000000..bfb4917 --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/GetVersionLogImpl.kt @@ -0,0 +1,20 @@ +package com.artemchep.keyguard.common.usecase.impl + +import com.artemchep.keyguard.common.service.settings.SettingsReadRepository +import com.artemchep.keyguard.common.usecase.GetVersionLog +import kotlinx.coroutines.flow.distinctUntilChanged +import org.kodein.di.DirectDI +import org.kodein.di.instance + +class GetVersionLogImpl( + settingsReadRepository: SettingsReadRepository, +) : GetVersionLog { + private val sharedFlow = settingsReadRepository.getAppVersionLog() + .distinctUntilChanged() + + constructor(directDI: DirectDI) : this( + settingsReadRepository = directDI.instance(), + ) + + override fun invoke() = sharedFlow +} diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/UpdateVersionLogImpl.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/UpdateVersionLogImpl.kt new file mode 100644 index 0000000..2c9b137 --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/UpdateVersionLogImpl.kt @@ -0,0 +1,62 @@ +package com.artemchep.keyguard.common.usecase.impl + +import com.artemchep.keyguard.common.io.IO +import com.artemchep.keyguard.common.io.bind +import com.artemchep.keyguard.common.io.ioEffect +import com.artemchep.keyguard.common.model.AppVersionLog +import com.artemchep.keyguard.common.service.settings.SettingsReadWriteRepository +import com.artemchep.keyguard.common.usecase.GetAppBuildRef +import com.artemchep.keyguard.common.usecase.GetAppVersionName +import com.artemchep.keyguard.common.usecase.UpdateVersionLog +import kotlinx.coroutines.flow.first +import kotlinx.datetime.Clock +import org.kodein.di.DirectDI +import org.kodein.di.instance + +class UpdateVersionLogImpl( + private val settingsReadWriteRepository: SettingsReadWriteRepository, + private val getAppBuildRef: GetAppBuildRef, + private val getAppVersionName: GetAppVersionName, +) : UpdateVersionLog { + constructor(directDI: DirectDI) : this( + settingsReadWriteRepository = directDI.instance(), + getAppBuildRef = directDI.instance(), + getAppVersionName = directDI.instance(), + ) + + override fun invoke(): IO = ioEffect { + val log = settingsReadWriteRepository + .getAppVersionLog() + .first() + .toMutableList() + + val buildRef = getAppBuildRef().first() + if (buildRef.isBlank()) { + return@ioEffect + } + // Check if the first entry in the log + // has the same build reference as the + // current one. If so, we do not need to + // update it. + val last = log.firstOrNull() + if (last?.ref == buildRef) { + return@ioEffect + } + + val version = getAppVersionName().first() + val newEntry = AppVersionLog( + version = version, + ref = buildRef, + timestamp = Clock.System.now(), + ) + // Append the new entry to the start of the + // log. Cap the size of the log to a small amount. + log.add(0, newEntry) + val newLog = log.take(3) + + // Save the updated log. + settingsReadWriteRepository + .setAppVersionLog(newLog) + .bind() + } +} diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/SettingPaneContent.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/SettingPaneContent.kt index a48eabb..0decd68 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/SettingPaneContent.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/SettingPaneContent.kt @@ -20,6 +20,7 @@ import com.artemchep.keyguard.feature.EmptyView import com.artemchep.keyguard.feature.home.settings.component.SettingComponent import com.artemchep.keyguard.feature.home.settings.component.settingAboutAppBuildDateProvider import com.artemchep.keyguard.feature.home.settings.component.settingAboutAppBuildRefProvider +import com.artemchep.keyguard.feature.home.settings.component.settingAboutAppChangelogProvider import com.artemchep.keyguard.feature.home.settings.component.settingAboutAppProvider import com.artemchep.keyguard.feature.home.settings.component.settingAboutTeamProvider import com.artemchep.keyguard.feature.home.settings.component.settingAboutTelegramProvider @@ -144,6 +145,7 @@ object Setting { const val ABOUT_APP = "about_app" const val ABOUT_APP_BUILD_DATE = "about_app_build_date" const val ABOUT_APP_BUILD_REF = "about_app_build_ref" + const val ABOUT_APP_CHANGELOG = "about_app_changelog" const val ABOUT_TEAM = "about_team" const val EXPERIMENTAL = "experimental" const val LAUNCH_APP_PICKER = "launch_app_picker" @@ -215,6 +217,7 @@ val hub = mapOf SettingComponent>( Setting.ABOUT_APP to ::settingAboutAppProvider, Setting.ABOUT_APP_BUILD_DATE to ::settingAboutAppBuildDateProvider, Setting.ABOUT_APP_BUILD_REF to ::settingAboutAppBuildRefProvider, + Setting.ABOUT_APP_CHANGELOG to ::settingAboutAppChangelogProvider, Setting.ABOUT_TEAM to ::settingAboutTeamProvider, Setting.REDDIT to ::settingAboutTelegramProvider, Setting.CROWDIN to ::settingLocalizationProvider, diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/component/SettingAboutAppChangelog.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/component/SettingAboutAppChangelog.kt new file mode 100644 index 0000000..054ed59 --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/component/SettingAboutAppChangelog.kt @@ -0,0 +1,85 @@ +package com.artemchep.keyguard.feature.home.settings.component + +import androidx.compose.foundation.layout.Row +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberUpdatedState +import com.artemchep.keyguard.common.usecase.GetVersionLog +import com.artemchep.keyguard.feature.navigation.LocalNavigationController +import com.artemchep.keyguard.feature.navigation.NavigationIntent +import com.artemchep.keyguard.res.Res +import com.artemchep.keyguard.ui.FlatItem +import com.artemchep.keyguard.ui.icons.ChevronIcon +import dev.icerock.moko.resources.compose.stringResource +import kotlinx.coroutines.flow.map +import org.kodein.di.DirectDI +import org.kodein.di.instance + +fun settingAboutAppChangelogProvider( + directDI: DirectDI, +) = settingAboutAppChangelogProvider( + getVersionLog = directDI.instance(), +) + +fun settingAboutAppChangelogProvider( + getVersionLog: GetVersionLog, +): SettingComponent = getVersionLog() + .map { log -> + if (log.size < 2) { + return@map null + } + + val newRef = log[0].ref + val oldRef = log[1].ref + + // composable + SettingIi( + search = SettingIi.Search( + group = "about", + tokens = listOf( + "about", + "app", + "changelog", + ), + ), + ) { + SettingAboutAppChangelog( + newRef = newRef, + oldRef = oldRef, + ) + } + } + +@Composable +private fun SettingAboutAppChangelog( + newRef: String, + oldRef: String, +) { + val controller by rememberUpdatedState(LocalNavigationController.current) + FlatItem( + title = { + Text( + text = stringResource(Res.strings.pref_item_app_changelog_title), + ) + }, + text = { + Row { + Text(newRef) + Text("...") + Text(oldRef) + } + }, + trailing = { + ChevronIcon() + }, + onClick = { + val intent = run { + val url = + "https://github.com/AChep/keyguard-app/compare/$oldRef...$newRef" + NavigationIntent.NavigateToBrowser(url) + } + controller.queue(intent) + }, + ) +} diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/other/OtherSettingsScreen.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/other/OtherSettingsScreen.kt index c5966c0..f880962 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/other/OtherSettingsScreen.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/settings/other/OtherSettingsScreen.kt @@ -54,6 +54,7 @@ fun OtherSettingsScreen() { SettingPaneItem.Item(Setting.ABOUT_APP), SettingPaneItem.Item(Setting.ABOUT_APP_BUILD_DATE), SettingPaneItem.Item(Setting.ABOUT_APP_BUILD_REF), + SettingPaneItem.Item(Setting.ABOUT_APP_CHANGELOG), ), ) } diff --git a/common/src/commonMain/resources/MR/base/strings.xml b/common/src/commonMain/resources/MR/base/strings.xml index 522842b..78a3c9c 100644 --- a/common/src/commonMain/resources/MR/base/strings.xml +++ b/common/src/commonMain/resources/MR/base/strings.xml @@ -851,6 +851,7 @@ This value matches the branch or tag name shown on GitHub. --> App build ref + App changelog Team behind the app Reddit community GitHub project diff --git a/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt b/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt index 2af8cf3..250abcb 100644 --- a/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt +++ b/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt @@ -141,6 +141,7 @@ import com.artemchep.keyguard.common.usecase.GetVaultLockAfterTimeout import com.artemchep.keyguard.common.usecase.GetVaultLockAfterTimeoutVariants import com.artemchep.keyguard.common.usecase.GetVaultPersist import com.artemchep.keyguard.common.usecase.GetVaultSession +import com.artemchep.keyguard.common.usecase.GetVersionLog import com.artemchep.keyguard.common.usecase.GetWebsiteIcons import com.artemchep.keyguard.common.usecase.GetWriteAccess import com.artemchep.keyguard.common.usecase.MessageHub @@ -189,6 +190,7 @@ import com.artemchep.keyguard.common.usecase.RemoveAttachment import com.artemchep.keyguard.common.usecase.RequestAppReview import com.artemchep.keyguard.common.usecase.ShowMessage import com.artemchep.keyguard.common.usecase.UnlockUseCase +import com.artemchep.keyguard.common.usecase.UpdateVersionLog import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.common.usecase.impl.AuthConfirmMasterKeyUseCaseImpl import com.artemchep.keyguard.common.usecase.impl.AuthGenerateMasterKeyUseCaseImpl @@ -255,6 +257,7 @@ import com.artemchep.keyguard.common.usecase.impl.GetVaultLockAfterTimeoutImpl import com.artemchep.keyguard.common.usecase.impl.GetVaultLockAfterTimeoutVariantsImpl import com.artemchep.keyguard.common.usecase.impl.GetVaultPersistImpl import com.artemchep.keyguard.common.usecase.impl.GetVaultSessionImpl +import com.artemchep.keyguard.common.usecase.impl.GetVersionLogImpl import com.artemchep.keyguard.common.usecase.impl.GetWebsiteIconsImpl import com.artemchep.keyguard.common.usecase.impl.GetWriteAccessImpl import com.artemchep.keyguard.common.usecase.impl.MessageHubImpl @@ -301,6 +304,7 @@ import com.artemchep.keyguard.common.usecase.impl.ReadWordlistFromFileImpl import com.artemchep.keyguard.common.usecase.impl.RemoveAttachmentImpl import com.artemchep.keyguard.common.usecase.impl.RequestAppReviewImpl import com.artemchep.keyguard.common.usecase.impl.UnlockUseCaseImpl +import com.artemchep.keyguard.common.usecase.impl.UpdateVersionLogImpl import com.artemchep.keyguard.common.usecase.impl.WindowCoroutineScopeImpl import com.artemchep.keyguard.copy.Base32ServiceJvm import com.artemchep.keyguard.copy.Base64ServiceJvm @@ -865,6 +869,11 @@ fun globalModuleJvm() = DI.Module( directDI = this, ) } + bindSingleton { + UpdateVersionLogImpl( + directDI = this, + ) + } bindSingleton { PutOnboardingLastVisitInstantImpl( directDI = this, @@ -910,6 +919,11 @@ fun globalModuleJvm() = DI.Module( directDI = this, ) } + bindSingleton { + GetVersionLogImpl( + directDI = this, + ) + } bindProvider { instance() }