diff --git a/README.md b/README.md index d15f15ce..46eca737 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ [![Google Play](docs/assets/google_play.png)](https://play.google.com/store/apps/details?id=com.shifthackz.aisdv1.app) [![F-Droid](docs/assets/fdroid.png)](https://f-droid.org/packages/com.shifthackz.aisdv1.app.foss) -[![Izzy On Droid](docs/assets/izzy_on_droid.png)](https://apt.izzysoft.de/fdroid/index/apk/com.shifthackz.aisdv1.app.foss?repo=main) Stable Diffusion AI is an easy-to-use app that lets you quickly generate images from text or other images with just a few clicks. With this app, you can communicate with your own server and generate high-quality images in seconds. @@ -60,16 +59,6 @@ If for some reason you have no ability to run your server instance, you can togg AI Horde requires to use API KEY, this mobile app alows to use either default API KEY (which is "0000000000"), or type your own. You can sign up and get your own AI Horde API KEY [here](https://stablehorde.net/register). -### Option 3: Use SDAI Cloud - -**Disclaimer: This option is only available in [GooglePlay](https://play.google.com/store/apps/details?id=com.shifthackz.aisdv1.app) app version.** - -**Google Play app version includes some proprietary libraries (like Firebase and Google AdMob) to monetize this option. This functionality is NOT a part of the FOSS build and will be never included in FOSS build** - -SDAI Cloud is the AUTOMATIC1111 hosted by author of this app as an option for users that for some reason are not able to run or host their own AUTOMATIC1111 instance. - -Hosting this instance costs some money, and as this project is non-profitable the usage of SDAI Cloud is monetized by ads. Also the SDAI Cloud may not be available full-time, as this is running on the app author's own bare-metal machine which is hosted in Ukraine, as this area now is a warzone electricity and network downtimes can happen sometimes. - ## Supported languages App uses the language provided by OS default settings. @@ -86,9 +75,8 @@ Any contributions to the translations are welcome. ## Donate -Main **foss** flavor of the app is open source, and you are welcome to use it for free. -Only **play** flavor contains small ad-banner at the bottom navigation. +This software is open source, provided with no warranty, and you are welcome to use it for free. -The donation is optional, if you'd like to say thanks and show a little support, here is the button: +In case you find this software valuable, and you'd like to say thanks and show a little support, here is the button: [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/shifthackz) diff --git a/app/build.gradle b/app/build.gradle index 7eb6c0e7..ab736b7b 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,23 +8,15 @@ plugins { id 'kotlin-kapt' } -def taskRequests = getGradle().getStartParameter().getTaskRequests().toString() -def isPlay = !(taskRequests.contains("Foss") || taskRequests.contains("foss")) - -if (isPlay) { - apply from: "$project.rootDir/gradle/plugins.gradle" -} - apply from: "$project.rootDir/gradle/common.gradle" android { namespace 'com.shifthackz.aisdv1.app' defaultConfig { applicationId "com.shifthackz.aisdv1.app" - versionName "0.5.2" - versionCode 165 + versionName "0.5.3" + versionCode 166 - buildConfigField "String", "CLOUD_AI_URL", "\"https://sdai.moroz.cc\"" buildConfigField "String", "IMAGE_CDN_URL", "\"https://random.imagecdn.app\"" buildConfigField "String", "HORDE_AI_URL", "\"https://stablehorde.net\"" buildConfigField "String", "HORDE_AI_SIGN_UP_URL", "\"https://stablehorde.net/register\"" @@ -56,13 +48,8 @@ android { foss { dimension "type" applicationIdSuffix = ".foss" - resValue "string", "app_name", "SDAI FOSS" - buildConfigField "String", "BUILD_FLAVOR_TYPE", "\"FOSS\"" - } - playstore { - dimension "type" resValue "string", "app_name", "SDAI" - buildConfigField "String", "BUILD_FLAVOR_TYPE", "\"GOOGLE_PLAY\"" + buildConfigField "String", "BUILD_FLAVOR_TYPE", "\"FOSS\"" } } } @@ -75,7 +62,6 @@ dependencies { implementation project(":network") implementation project(":storage") implementation project(":domain") - implementation project(":feature:ads") implementation project(":feature:analytics") implementation project(":feature:auth") implementation project(":feature:diffusion") @@ -87,10 +73,8 @@ dependencies { implementation reactive.rxkotlin implementation reactive.rxandroid implementation log.timber - - playstoreImplementation platform(proprietary.fbBom) - playstoreImplementation proprietary.fbA - playstoreImplementation proprietary.fbC + implementation ui.catppuccinSplashscreen + implementation ui.catppuccinLegacy } kapt { diff --git a/app/google-services.json b/app/google-services.json deleted file mode 100644 index e55b92c8..00000000 --- a/app/google-services.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "project_info": { - "project_number": "457071394222", - "project_id": "stable-diffusion-android", - "storage_bucket": "stable-diffusion-android.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:457071394222:android:df6ae3f3e640d255c39c3f", - "android_client_info": { - "package_name": "com.shifthackz.aisdv1.app" - } - }, - "oauth_client": [ - { - "client_id": "457071394222-sre4vtc3rcsla98f22vqcpvui4rsg9a2.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.shifthackz.aisdv1.app", - "certificate_hash": "c00bf2d57403fbf23efbe7b1de6fecd58bf4cffa" - } - }, - { - "client_id": "457071394222-k0bu4kaj80h5jntcud5fjoppavt4atbt.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyAHdAfmzEBUyxaNk_xjz25Z9-TPm7bwfSQ" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "457071394222-k0bu4kaj80h5jntcud5fjoppavt4atbt.apps.googleusercontent.com", - "client_type": 3 - } - ] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 29bfb0e3..d26dbbf3 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,7 +25,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:requestLegacyExternalStorage="true" - android:theme="@style/Theme.AiSdCompose" + android:theme="@style/Theme.AiSdCompose.Splash" android:usesCleartextTraffic="true"> { object : LinksProvider { - override val cloudUrl: String = BuildConfig.CLOUD_AI_URL override val hordeUrl: String = BuildConfig.HORDE_AI_URL override val hordeSignUpUrl: String = BuildConfig.HORDE_AI_SIGN_UP_URL override val privacyPolicyUrl: String = BuildConfig.POLICY_URL @@ -76,13 +73,12 @@ val providersModule = module { override val isDebug: Boolean = BuildConfig.DEBUG override val buildNumber: Int = BuildConfig.VERSION_CODE override val version: BuildVersion = BuildVersion(BuildConfig.VERSION_NAME) - override val buildType: BuildType = BuildType.parse(BuildConfig.BUILD_FLAVOR_TYPE) override fun toString(): String = buildString { append("$version") if (BuildConfig.DEBUG) append("-dev") append(" ($buildNumber)") - buildType.takeIf { it == BuildType.FOSS }?.let { append(" $it") } + append(" FOSS") } } } diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index f48eed5b..63ef2c9d 100755 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -1,16 +1,18 @@ - - + + - \ No newline at end of file + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index fdbf6121..77d97260 100755 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,16 +1,18 @@ - - + + + + diff --git a/build.gradle b/build.gradle old mode 100755 new mode 100644 index 35b278fc..04fbacfe --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,12 @@ buildscript { ext { minSdk = 23 - targetSdk = 33 - } - def taskRequests = getGradle().getStartParameter().getTaskRequests().toString() - def isPlay = !(taskRequests.contains("Foss") || taskRequests.contains("foss")) - dependencies { - if (isPlay) { - classpath 'com.google.gms:google-services:4.3.15' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.7' - } + targetSdk = 34 } } plugins { - id 'com.android.application' version '8.1.0' apply false - id 'com.android.library' version '8.1.0' apply false - id 'org.jetbrains.kotlin.android' version '1.8.21' apply false + id 'com.android.application' version '8.2.0' apply false + id 'com.android.library' version '8.2.0' apply false + id 'org.jetbrains.kotlin.android' version '1.9.21' apply false } diff --git a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildInfoProvider.kt b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildInfoProvider.kt index b7718a05..ad85ba0f 100644 --- a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildInfoProvider.kt +++ b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildInfoProvider.kt @@ -4,5 +4,4 @@ interface BuildInfoProvider { val isDebug: Boolean val buildNumber: Int val version: BuildVersion - val buildType: BuildType } diff --git a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildType.kt b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildType.kt deleted file mode 100644 index 97dff8b5..00000000 --- a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/appbuild/BuildType.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.shifthackz.aisdv1.core.common.appbuild - -enum class BuildType { - FOSS, - GOOGLE_PLAY; - - companion object { - fun parse(value: String) = values().firstOrNull { "$it" == value } ?: GOOGLE_PLAY - } -} diff --git a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/extensions/UriExtensions.kt b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/extensions/UriExtensions.kt index f7f5e920..ffafb917 100644 --- a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/extensions/UriExtensions.kt +++ b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/extensions/UriExtensions.kt @@ -8,8 +8,6 @@ import androidx.annotation.ChecksSdkIntAtLeast import androidx.core.content.FileProvider import java.io.File -private const val APP_MARKET_PACKAGE = "com.shifthackz.aisdv1.app" - @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S_V2) fun shouldUseNewMediaStore(): Boolean { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2 @@ -29,6 +27,3 @@ fun Context.openUrl(url: String) { openUri(uri) } -fun Context.openMarket() { - openUri(Uri.parse("market://details?id=$APP_MARKET_PACKAGE")) -} diff --git a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/links/LinksProvider.kt b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/links/LinksProvider.kt index 3617f9f7..0b3706f1 100644 --- a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/links/LinksProvider.kt +++ b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/links/LinksProvider.kt @@ -1,7 +1,6 @@ package com.shifthackz.aisdv1.core.common.links interface LinksProvider { - val cloudUrl: String val hordeUrl: String val hordeSignUpUrl: String val privacyPolicyUrl: String diff --git a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/log/FileLoggingTree.kt b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/log/FileLoggingTree.kt index 0ca1db73..86ae92cd 100644 --- a/core/common/src/main/java/com/shifthackz/aisdv1/core/common/log/FileLoggingTree.kt +++ b/core/common/src/main/java/com/shifthackz/aisdv1/core/common/log/FileLoggingTree.kt @@ -10,7 +10,8 @@ import timber.log.Timber import java.io.File import java.io.FileOutputStream import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale class FileLoggingTree : Timber.Tree(), KoinComponent { @@ -42,7 +43,6 @@ class FileLoggingTree : Timber.Tree(), KoinComponent { appendLine("=== APP SESSION STARTED ===") appendLine() appendLine("Version : $buildInfoProvider") - appendLine("Type : ${buildInfoProvider.buildType}") appendLine() }) } diff --git a/core/ui/build.gradle b/core/ui/build.gradle index 0e2f0544..3b901c92 100755 --- a/core/ui/build.gradle +++ b/core/ui/build.gradle @@ -11,7 +11,7 @@ android { compose true } composeOptions { - kotlinCompilerExtensionVersion = "1.4.7" + kotlinCompilerExtensionVersion = "1.5.7" } } diff --git a/core/ui/src/main/java/com/shifthackz/aisdv1/core/ui/Screen.kt b/core/ui/src/main/java/com/shifthackz/aisdv1/core/ui/Screen.kt index aa695234..0858fe89 100644 --- a/core/ui/src/main/java/com/shifthackz/aisdv1/core/ui/Screen.kt +++ b/core/ui/src/main/java/com/shifthackz/aisdv1/core/ui/Screen.kt @@ -34,7 +34,7 @@ abstract class Screen { val statusBarDarkIcons = statusBarDarkIcons() val navigationBarColor = navigationBarColor() SideEffect { - systemUiController.setStatusBarColor(statusBarColor, statusBarDarkIcons) +// systemUiController.setStatusBarColor(statusBarColor, statusBarDarkIcons) systemUiController.setNavigationBarColor(navigationBarColor) } } diff --git a/core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/dimension/DimensionValidatorImpl.kt b/core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/dimension/DimensionValidatorImpl.kt index f4a66d5f..a8448d8c 100644 --- a/core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/dimension/DimensionValidatorImpl.kt +++ b/core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/dimension/DimensionValidatorImpl.kt @@ -27,13 +27,13 @@ internal class DimensionValidatorImpl( ) input.toInt() > maximum -> ValidationResult( isValid = false, - validationError = DimensionValidator.Error.LessThanMinimum(maximum), + validationError = DimensionValidator.Error.BiggerThanMaximum(maximum), ) else -> ValidationResult(isValid = true) } companion object { private const val MINIMUM = 64 - private const val MAXIMUM = 1024 + private const val MAXIMUM = 2048 } } diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/di/LocalDataSourceModule.kt b/data/src/main/java/com/shifthackz/aisdv1/data/di/LocalDataSourceModule.kt index 4a405ead..046a9fe3 100755 --- a/data/src/main/java/com/shifthackz/aisdv1/data/di/LocalDataSourceModule.kt +++ b/data/src/main/java/com/shifthackz/aisdv1/data/di/LocalDataSourceModule.kt @@ -3,17 +3,13 @@ package com.shifthackz.aisdv1.data.di import com.shifthackz.aisdv1.data.gateway.DatabaseClearGatewayImpl import com.shifthackz.aisdv1.data.gateway.mediastore.MediaStoreGatewayFactory import com.shifthackz.aisdv1.data.local.AppVersionLocalDataSource -import com.shifthackz.aisdv1.data.local.CoinLocalDataSource import com.shifthackz.aisdv1.data.local.DownloadableModelLocalDataSource -import com.shifthackz.aisdv1.data.local.FeatureFlagsLocalDataSource import com.shifthackz.aisdv1.data.local.GenerationResultLocalDataSource import com.shifthackz.aisdv1.data.local.ServerConfigurationLocalDataSource import com.shifthackz.aisdv1.data.local.StableDiffusionModelsLocalDataSource import com.shifthackz.aisdv1.data.local.StableDiffusionSamplersLocalDataSource import com.shifthackz.aisdv1.domain.datasource.AppVersionDataSource -import com.shifthackz.aisdv1.domain.datasource.CoinDataSource import com.shifthackz.aisdv1.domain.datasource.DownloadableModelDataSource -import com.shifthackz.aisdv1.domain.datasource.FeatureFlagsDataSource import com.shifthackz.aisdv1.domain.datasource.GenerationResultDataSource import com.shifthackz.aisdv1.domain.datasource.ServerConfigurationDataSource import com.shifthackz.aisdv1.domain.datasource.StableDiffusionModelsDataSource @@ -27,13 +23,11 @@ import org.koin.dsl.module val localDataSourceModule = module { singleOf(::DatabaseClearGatewayImpl) bind DatabaseClearGateway::class - singleOf(::FeatureFlagsLocalDataSource) bind FeatureFlagsDataSource.Local::class factoryOf(::StableDiffusionModelsLocalDataSource) bind StableDiffusionModelsDataSource.Local::class factoryOf(::StableDiffusionSamplersLocalDataSource) bind StableDiffusionSamplersDataSource.Local::class factoryOf(::ServerConfigurationLocalDataSource) bind ServerConfigurationDataSource.Local::class factoryOf(::GenerationResultLocalDataSource) bind GenerationResultDataSource.Local::class factoryOf(::AppVersionLocalDataSource) bind AppVersionDataSource.Local::class - factoryOf(::CoinLocalDataSource) bind CoinDataSource.Local::class factoryOf(::DownloadableModelLocalDataSource) bind DownloadableModelDataSource.Local::class factory { MediaStoreGatewayFactory(androidContext(), get()).invoke() } } diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/di/RemoteDataSourceModule.kt b/data/src/main/java/com/shifthackz/aisdv1/data/di/RemoteDataSourceModule.kt index 8152fda9..22c886ab 100755 --- a/data/src/main/java/com/shifthackz/aisdv1/data/di/RemoteDataSourceModule.kt +++ b/data/src/main/java/com/shifthackz/aisdv1/data/di/RemoteDataSourceModule.kt @@ -1,11 +1,25 @@ package com.shifthackz.aisdv1.data.di import com.shifthackz.aisdv1.core.common.extensions.fixUrlSlashes -import com.shifthackz.aisdv1.core.common.links.LinksProvider import com.shifthackz.aisdv1.data.gateway.ServerConnectivityGatewayImpl import com.shifthackz.aisdv1.data.provider.ServerUrlProvider -import com.shifthackz.aisdv1.data.remote.* -import com.shifthackz.aisdv1.domain.datasource.* +import com.shifthackz.aisdv1.data.remote.AppVersionRemoteDataSource +import com.shifthackz.aisdv1.data.remote.DownloadableModelRemoteDataSource +import com.shifthackz.aisdv1.data.remote.HordeGenerationRemoteDataSource +import com.shifthackz.aisdv1.data.remote.HordeStatusSource +import com.shifthackz.aisdv1.data.remote.RandomImageRemoteDataSource +import com.shifthackz.aisdv1.data.remote.ServerConfigurationRemoteDataSource +import com.shifthackz.aisdv1.data.remote.StableDiffusionGenerationRemoteDataSource +import com.shifthackz.aisdv1.data.remote.StableDiffusionModelsRemoteDataSource +import com.shifthackz.aisdv1.data.remote.StableDiffusionSamplersRemoteDataSource +import com.shifthackz.aisdv1.domain.datasource.AppVersionDataSource +import com.shifthackz.aisdv1.domain.datasource.DownloadableModelDataSource +import com.shifthackz.aisdv1.domain.datasource.HordeGenerationDataSource +import com.shifthackz.aisdv1.domain.datasource.RandomImageDataSource +import com.shifthackz.aisdv1.domain.datasource.ServerConfigurationDataSource +import com.shifthackz.aisdv1.domain.datasource.StableDiffusionGenerationDataSource +import com.shifthackz.aisdv1.domain.datasource.StableDiffusionModelsDataSource +import com.shifthackz.aisdv1.domain.datasource.StableDiffusionSamplersDataSource import com.shifthackz.aisdv1.domain.entity.ServerSource import com.shifthackz.aisdv1.domain.gateway.ServerConnectivityGateway import com.shifthackz.aisdv1.domain.preference.PreferenceManager @@ -21,11 +35,8 @@ val remoteDataSourceModule = module { single { ServerUrlProvider { endpoint -> val prefs = get() - val links = get() - val chain = if (prefs.useSdAiCloud) Single.fromCallable(links::cloudUrl) - else Single.fromCallable(prefs::serverUrl) - - chain + Single + .fromCallable(prefs::serverUrl) .map(String::fixUrlSlashes) .map { baseUrl -> "$baseUrl/$endpoint" } } @@ -37,9 +48,6 @@ val remoteDataSourceModule = module { factoryOf(::StableDiffusionModelsRemoteDataSource) bind StableDiffusionModelsDataSource.Remote::class factoryOf(::ServerConfigurationRemoteDataSource) bind ServerConfigurationDataSource.Remote::class factoryOf(::AppVersionRemoteDataSource) bind AppVersionDataSource.Remote::class - factoryOf(::CoinRemoteDateSource) bind CoinDataSource.Remote::class - factoryOf(::MotdRemoteDataSource) bind MotdDataSource.Remote::class - factoryOf(::FeatureFlagsRemoteDataSource) bind FeatureFlagsDataSource.Remote::class factoryOf(::RandomImageRemoteDataSource) bind RandomImageDataSource.Remote::class factoryOf(::DownloadableModelRemoteDataSource) bind DownloadableModelDataSource.Remote::class diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/di/RepositoryModule.kt b/data/src/main/java/com/shifthackz/aisdv1/data/di/RepositoryModule.kt index ff23d0e1..b751dd0a 100755 --- a/data/src/main/java/com/shifthackz/aisdv1/data/di/RepositoryModule.kt +++ b/data/src/main/java/com/shifthackz/aisdv1/data/di/RepositoryModule.kt @@ -1,7 +1,25 @@ package com.shifthackz.aisdv1.data.di -import com.shifthackz.aisdv1.data.repository.* -import com.shifthackz.aisdv1.domain.repository.* +import com.shifthackz.aisdv1.data.repository.DownloadableModelRepositoryImpl +import com.shifthackz.aisdv1.data.repository.GenerationResultRepositoryImpl +import com.shifthackz.aisdv1.data.repository.HordeGenerationRepositoryImpl +import com.shifthackz.aisdv1.data.repository.LocalDiffusionGenerationRepositoryImpl +import com.shifthackz.aisdv1.data.repository.RandomImageRepositoryImpl +import com.shifthackz.aisdv1.data.repository.ServerConfigurationRepositoryImpl +import com.shifthackz.aisdv1.data.repository.StableDiffusionGenerationRepositoryImpl +import com.shifthackz.aisdv1.data.repository.StableDiffusionModelsRepositoryImpl +import com.shifthackz.aisdv1.data.repository.StableDiffusionSamplersRepositoryImpl +import com.shifthackz.aisdv1.data.repository.TemporaryGenerationResultRepositoryImpl +import com.shifthackz.aisdv1.domain.repository.DownloadableModelRepository +import com.shifthackz.aisdv1.domain.repository.GenerationResultRepository +import com.shifthackz.aisdv1.domain.repository.HordeGenerationRepository +import com.shifthackz.aisdv1.domain.repository.LocalDiffusionGenerationRepository +import com.shifthackz.aisdv1.domain.repository.RandomImageRepository +import com.shifthackz.aisdv1.domain.repository.ServerConfigurationRepository +import com.shifthackz.aisdv1.domain.repository.StableDiffusionGenerationRepository +import com.shifthackz.aisdv1.domain.repository.StableDiffusionModelsRepository +import com.shifthackz.aisdv1.domain.repository.StableDiffusionSamplersRepository +import com.shifthackz.aisdv1.domain.repository.TemporaryGenerationResultRepository import org.koin.core.module.dsl.factoryOf import org.koin.core.module.dsl.singleOf import org.koin.dsl.bind @@ -16,10 +34,6 @@ val repositoryModule = module { factoryOf(::StableDiffusionSamplersRepositoryImpl) bind StableDiffusionSamplersRepository::class factoryOf(::ServerConfigurationRepositoryImpl) bind ServerConfigurationRepository::class factoryOf(::GenerationResultRepositoryImpl) bind GenerationResultRepository::class - factoryOf(::AppVersionRepositoryImpl) bind AppVersionRepository::class - factoryOf(::CoinRepositoryImpl) bind CoinRepository::class - factoryOf(::MotdRepositoryImpl) bind MotdRepository::class - factoryOf(::FeatureFlagsRepositoryImpl) bind FeatureFlagsRepository::class factoryOf(::RandomImageRepositoryImpl) bind RandomImageRepository::class factoryOf(::DownloadableModelRepositoryImpl) bind DownloadableModelRepository::class } diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/local/CoinLocalDataSource.kt b/data/src/main/java/com/shifthackz/aisdv1/data/local/CoinLocalDataSource.kt deleted file mode 100644 index f66a3284..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/local/CoinLocalDataSource.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.shifthackz.aisdv1.data.local - -import com.shifthackz.aisdv1.domain.datasource.CoinDataSource -import com.shifthackz.aisdv1.storage.db.coins.dao.CoinDao -import com.shifthackz.aisdv1.storage.db.coins.dao.EarnedCoinDao -import com.shifthackz.aisdv1.storage.db.coins.entity.CoinEntity -import com.shifthackz.aisdv1.storage.db.coins.entity.EarnedCoinEntity -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Single -import java.util.* - -internal class CoinLocalDataSource( - private val coinDao: CoinDao, - private val earnedCoinDao: EarnedCoinDao, -) : CoinDataSource.Local { - - override fun querySpentDailyCoinsForPeriod(start: Long, end: Long) = coinDao - .queryAvailableCoinsForPeriod(start, end) - .map { it.size } - - override fun queryEarnedCoins(): Single = earnedCoinDao.queryCount() - - override fun onDailyCoinSpent(): Completable = coinDao.insert(CoinEntity(0L, Date())) - - override fun onEarnedCoinSpent(): Completable = earnedCoinDao.deleteLast() - - override fun onEarnedCoinsRewarded(amount: Int): Completable = (1..amount) - .map { EarnedCoinEntity(0L, Date()) } - .let(earnedCoinDao::insert) -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/local/FeatureFlagsLocalDataSource.kt b/data/src/main/java/com/shifthackz/aisdv1/data/local/FeatureFlagsLocalDataSource.kt deleted file mode 100644 index 97d186b3..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/local/FeatureFlagsLocalDataSource.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.shifthackz.aisdv1.data.local - -import com.shifthackz.aisdv1.domain.datasource.FeatureFlagsDataSource -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Single - -internal class FeatureFlagsLocalDataSource : FeatureFlagsDataSource.Local { - - private var featureFlags = FeatureFlags() - private var fetched = false - - override fun getIsLoaded() = Single.just(fetched) - - override fun get() = Single.just(featureFlags) - - override fun store(flags: FeatureFlags) = Completable.fromAction { - fetched = true - featureFlags = flags - } -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/mappers/FeatureFlagsMappers.kt b/data/src/main/java/com/shifthackz/aisdv1/data/mappers/FeatureFlagsMappers.kt deleted file mode 100644 index d4bb5fcd..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/mappers/FeatureFlagsMappers.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.shifthackz.aisdv1.data.mappers - -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import com.shifthackz.aisdv1.network.response.FeatureFlagsResponse - -fun FeatureFlagsResponse.mapToDomain(): FeatureFlags = with (this) { - FeatureFlags( - adHomeBottomEnable = adHomeBottomEnable ?: false, - adGalleryBottomEnable = adGalleryBottomEnable ?: false, - ) -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/mappers/MotdMapper.kt b/data/src/main/java/com/shifthackz/aisdv1/data/mappers/MotdMapper.kt deleted file mode 100644 index 786c1e83..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/mappers/MotdMapper.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.shifthackz.aisdv1.data.mappers - -import com.shifthackz.aisdv1.domain.entity.Motd -import com.shifthackz.aisdv1.network.response.MotdResponse - -fun MotdResponse.toDomain(): Motd = with(this) { - Motd( - display = display ?: false, - title = title ?: "", - subTitle = subTitle ?: "", - ) -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/preference/PreferenceManagerImpl.kt b/data/src/main/java/com/shifthackz/aisdv1/data/preference/PreferenceManagerImpl.kt index 129aae1a..3163aa6d 100644 --- a/data/src/main/java/com/shifthackz/aisdv1/data/preference/PreferenceManagerImpl.kt +++ b/data/src/main/java/com/shifthackz/aisdv1/data/preference/PreferenceManagerImpl.kt @@ -18,16 +18,14 @@ class PreferenceManagerImpl( BehaviorSubject.createDefault(Unit) override var serverUrl: String - get() = (if (useSdAiCloud) "" else preferences.getString(KEY_SERVER_URL, "") - ?: "").fixUrlSlashes() + get() = (preferences.getString(KEY_SERVER_URL, "") ?: "").fixUrlSlashes() set(value) = preferences.edit() - .putString(KEY_SERVER_URL, (if (useSdAiCloud) "" else value).fixUrlSlashes()) + .putString(KEY_SERVER_URL, value.fixUrlSlashes()) .apply() .also { onPreferencesChanged() } override var demoMode: Boolean - get() = if (useSdAiCloud) false - else preferences.getBoolean(KEY_DEMO_MODE, false) + get() = preferences.getBoolean(KEY_DEMO_MODE, false) set(value) = preferences.edit() .putBoolean(KEY_DEMO_MODE, value) .apply() @@ -91,16 +89,12 @@ class PreferenceManagerImpl( .apply() .also { onPreferencesChanged() } - override val useSdAiCloud: Boolean - get() = source == ServerSource.SDAI - override fun observe(): Flowable = preferencesChangedSubject .toFlowable(BackpressureStrategy.LATEST) .map { Settings( serverUrl = serverUrl, demoMode = demoMode, - useSdAiCloud = useSdAiCloud, monitorConnectivity = monitorConnectivity, autoSaveAiResults = autoSaveAiResults, saveToMediaStore = saveToMediaStore, @@ -123,6 +117,6 @@ class PreferenceManagerImpl( private const val KEY_SERVER_SOURCE = "key_server_source" private const val KEY_HORDE_API_KEY = "key_horde_api_key" private const val KEY_LOCAL_NN_API = "key_local_nn_api" - private const val KEY_FORCE_SETUP_AFTER_UPDATE = "force_upd_setup_v0.x.x-v0.5.1" + private const val KEY_FORCE_SETUP_AFTER_UPDATE = "force_upd_setup_v0.x.x-v0.5.3" } } diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/remote/CoinRemoteDateSource.kt b/data/src/main/java/com/shifthackz/aisdv1/data/remote/CoinRemoteDateSource.kt deleted file mode 100644 index 163ebe93..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/remote/CoinRemoteDateSource.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.shifthackz.aisdv1.data.remote - -import com.shifthackz.aisdv1.domain.datasource.CoinDataSource -import com.shifthackz.aisdv1.network.api.sdai.CoinsRestApi -import io.reactivex.rxjava3.core.Single - -internal class CoinRemoteDateSource( - private val api: CoinsRestApi, -) : CoinDataSource.Remote { - - override fun fetchCoinsConfig(): Single = api - .fetchCoinsConfig() - .map { response -> response.coinsPerDay ?: 10 } - .onErrorReturn { 10 } -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/remote/FeatureFlagsRemoteDataSource.kt b/data/src/main/java/com/shifthackz/aisdv1/data/remote/FeatureFlagsRemoteDataSource.kt deleted file mode 100644 index c7172967..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/remote/FeatureFlagsRemoteDataSource.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.shifthackz.aisdv1.data.remote - -import com.shifthackz.aisdv1.data.mappers.mapToDomain -import com.shifthackz.aisdv1.domain.datasource.FeatureFlagsDataSource -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import com.shifthackz.aisdv1.network.api.sdai.FeatureFlagsRestApi -import com.shifthackz.aisdv1.network.response.FeatureFlagsResponse -import io.reactivex.rxjava3.core.Single - -internal class FeatureFlagsRemoteDataSource( - private val api: FeatureFlagsRestApi, -) : FeatureFlagsDataSource.Remote { - - override fun fetch(): Single = api - .fetchConfig() - .map(FeatureFlagsResponse::mapToDomain) -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/remote/MotdRemoteDataSource.kt b/data/src/main/java/com/shifthackz/aisdv1/data/remote/MotdRemoteDataSource.kt deleted file mode 100644 index db20458f..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/remote/MotdRemoteDataSource.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.shifthackz.aisdv1.data.remote - -import com.shifthackz.aisdv1.data.mappers.toDomain -import com.shifthackz.aisdv1.domain.datasource.MotdDataSource -import com.shifthackz.aisdv1.network.api.sdai.MotdRestApi -import com.shifthackz.aisdv1.network.response.MotdResponse - -internal class MotdRemoteDataSource( - private val api: MotdRestApi, -) : MotdDataSource.Remote { - - override fun fetch() = api - .fetchMotd() - .map(MotdResponse::toDomain) -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/repository/AppVersionRepositoryImpl.kt b/data/src/main/java/com/shifthackz/aisdv1/data/repository/AppVersionRepositoryImpl.kt deleted file mode 100644 index 53ab1241..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/repository/AppVersionRepositoryImpl.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.shifthackz.aisdv1.data.repository - -import com.shifthackz.aisdv1.domain.datasource.AppVersionDataSource -import com.shifthackz.aisdv1.domain.repository.AppVersionRepository - -internal class AppVersionRepositoryImpl( - private val remoteDataSource: AppVersionDataSource.Remote, - private val localDataSource: AppVersionDataSource.Local, -) : AppVersionRepository { - - override fun getActualVersion() = remoteDataSource.get() - - override fun getLocalVersion() = localDataSource.get() -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/repository/CoinRepositoryImpl.kt b/data/src/main/java/com/shifthackz/aisdv1/data/repository/CoinRepositoryImpl.kt deleted file mode 100644 index 797de1a3..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/repository/CoinRepositoryImpl.kt +++ /dev/null @@ -1,87 +0,0 @@ -package com.shifthackz.aisdv1.data.repository - -import com.shifthackz.aisdv1.core.common.extensions.getDayRange -import com.shifthackz.aisdv1.domain.datasource.CoinDataSource -import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.preference.SessionPreference -import com.shifthackz.aisdv1.domain.repository.CoinRepository -import io.reactivex.rxjava3.core.BackpressureStrategy -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Flowable -import io.reactivex.rxjava3.core.Single -import io.reactivex.rxjava3.subjects.PublishSubject -import java.util.* -import java.util.concurrent.TimeUnit - -internal class CoinRepositoryImpl( - private val coinLocalDataSource: CoinDataSource.Local, - private val coinRemoteDateSource: CoinDataSource.Remote, - private val preferenceManager: PreferenceManager, - private val sessionPreference: SessionPreference, -) : CoinRepository { - - private val eventCoinsUpdated: PublishSubject = PublishSubject.create() - - override fun observeAvailableCoins(): Flowable { - val coinsCalculationProducer: () -> Flowable = { - Single.zip( - calculateAvailableDailyCoins(), - calculateAvailableEarnedCoins(), - ::Pair, - ) - .map { (daily, earned) -> daily + earned } - .toFlowable() - } - - val coinsUpdatedEventProducer: () -> Flowable<*> = { - eventCoinsUpdated.toFlowable(BackpressureStrategy.LATEST) - } - - val coreTickProducer: () -> Flowable<*> = { - Flowable.interval(5L, TimeUnit.SECONDS) - } - - return Flowable - .merge(coinsCalculationProducer(), coreTickProducer(), coinsUpdatedEventProducer()) - .flatMap { coinsCalculationProducer() } - .replay(1) - .refCount(1, TimeUnit.SECONDS) - } - - override fun spendCoin(): Completable { - eventCoinsUpdated.onNext(Unit) - return if (preferenceManager.useSdAiCloud) { - calculateAvailableDailyCoins() - .flatMapCompletable { - if (it > 0) coinLocalDataSource.onDailyCoinSpent() - else coinLocalDataSource.onEarnedCoinSpent() - } - .doOnComplete { eventCoinsUpdated.onNext(Unit) } - } - else Completable.complete() - } - - override fun earnCoins(amount: Int) = coinLocalDataSource.onEarnedCoinsRewarded(amount) - - private fun getAvailableCoinsPerDay(): Single { - val availableCoinsPerDay = sessionPreference.coinsPerDay - return if (availableCoinsPerDay != -1) Single.just(availableCoinsPerDay) - else coinRemoteDateSource - .fetchCoinsConfig() - .doOnSuccess { sessionPreference.coinsPerDay = it } - } - - private fun calculateAvailableDailyCoins(): Single { - val (start, end) = Date().getDayRange() - return getAvailableCoinsPerDay() - .zipWith( - coinLocalDataSource.querySpentDailyCoinsForPeriod(start.time, end.time), - ::Pair, - ) - .map { (availableToday, spentToday) -> availableToday - spentToday } - .map { coins -> if (coins < 0) 0 else coins } - } - - private fun calculateAvailableEarnedCoins(): Single = - coinLocalDataSource.queryEarnedCoins() -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/repository/FeatureFlagsRepositoryImpl.kt b/data/src/main/java/com/shifthackz/aisdv1/data/repository/FeatureFlagsRepositoryImpl.kt deleted file mode 100644 index 95b694f0..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/repository/FeatureFlagsRepositoryImpl.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.shifthackz.aisdv1.data.repository - -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider -import com.shifthackz.aisdv1.core.common.appbuild.BuildType -import com.shifthackz.aisdv1.core.common.log.errorLog -import com.shifthackz.aisdv1.domain.datasource.FeatureFlagsDataSource -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import com.shifthackz.aisdv1.domain.repository.FeatureFlagsRepository - -internal class FeatureFlagsRepositoryImpl( - private val buildInfoProvider: BuildInfoProvider, - private val remoteDataSource: FeatureFlagsDataSource.Remote, - private val localDataSource: FeatureFlagsDataSource.Local, -) : FeatureFlagsRepository { - - override fun get() = when (buildInfoProvider.buildType) { - BuildType.FOSS -> localDataSource.get() - BuildType.GOOGLE_PLAY -> localDataSource - .getIsLoaded() - .flatMap { loaded -> - if (loaded) { - return@flatMap localDataSource.get() - } - return@flatMap remoteDataSource.fetch() - .flatMapCompletable(localDataSource::store) - .andThen(localDataSource.get()) - } - }.onErrorReturn { t -> - errorLog(t) - FeatureFlags() - } -} diff --git a/data/src/main/java/com/shifthackz/aisdv1/data/repository/MotdRepositoryImpl.kt b/data/src/main/java/com/shifthackz/aisdv1/data/repository/MotdRepositoryImpl.kt deleted file mode 100644 index e7a6b644..00000000 --- a/data/src/main/java/com/shifthackz/aisdv1/data/repository/MotdRepositoryImpl.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.shifthackz.aisdv1.data.repository - -import com.shifthackz.aisdv1.domain.datasource.MotdDataSource -import com.shifthackz.aisdv1.domain.repository.MotdRepository - -internal class MotdRepositoryImpl( - private val remoteDataSource: MotdDataSource.Remote, -) : MotdRepository { - - override fun fetchMotd() = remoteDataSource.fetch() -} diff --git a/dependencies.gradle b/dependencies.gradle index b29628e7..51c50c73 100755 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,11 +1,9 @@ ext { - composeBomVersion = '2023.06.01' - composeMaterialVersion = '1.1.1' - composeUiToolingVersion = '1.4.3' - composeNavVersion = '2.6.0' + composeBomVersion = '2023.10.01' + composeNavVersion = '2.7.6' lifecycleViewModelVersion = '2.6.1' lifecycleComposeVersion = '2.6.1' - coreKtxVersion = '1.10.1' + coreKtxVersion = '1.12.0' appCompatVersion = '1.6.1' activityVersion = '1.7.2' koinVersion = '3.4.3' @@ -25,9 +23,8 @@ ext { googleMaterialVersion = '1.9.0' accompanistSystemUiControllerVersion = '0.30.1' cryptoVersion = '1.0.0' - onnxruntimeVersion = 'latest.release' - - firebaseBomVersion = '32.2.0' + onnxruntimeVersion = '1.16.3' + catppuccinVersion = '0.1.1' testJunitVersion = '4.13.2' @@ -37,11 +34,11 @@ ext { activity : "androidx.activity:activity-ktx:$activityVersion", composeBom : "androidx.compose:compose-bom:$composeBomVersion", composeRuntime : "androidx.compose.runtime:runtime", - composeMaterial3 : "androidx.compose.material3:material3:$composeMaterialVersion", + composeMaterial3 : "androidx.compose.material3:material3", composeMaterialIconsExtended: "androidx.compose.material:material-icons-extended", composeUiGraphics : "androidx.compose.ui:ui-graphics", - composeUiTooling : "androidx.compose.ui:ui-tooling:$composeUiToolingVersion", - composeUiToolingPreview : "androidx.compose.ui:ui-tooling-preview:$composeUiToolingVersion", + composeUiTooling : "androidx.compose.ui:ui-tooling", + composeUiToolingPreview : "androidx.compose.ui:ui-tooling-preview", composeActivity : "androidx.activity:activity-compose:$activityVersion", composeViewModel : "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleViewModelVersion", composeNavigation : "androidx.navigation:navigation-compose:$composeNavVersion", @@ -58,7 +55,7 @@ ext { accompanistSystemUiController: "com.google.accompanist:accompanist-systemuicontroller:$accompanistSystemUiControllerVersion", ] microsoft = [ - onnxruntime : "com.microsoft.onnxruntime:onnxruntime-android:$onnxruntimeVersion" + onnxruntime: "com.microsoft.onnxruntime:onnxruntime-android:$onnxruntimeVersion" ] di = [ koinCore : "io.insert-koin:koin-core:$koinVersion", @@ -86,17 +83,14 @@ ext { rxnetwork: "io.github.softartdev:reactivenetwork-rx3:$rxNetworkVersion", ] ui = [ - imagePicker: "com.github.ShiftHackZ:ImagePicker:$imagePickerVersion" + imagePicker: "com.github.ShiftHackZ:ImagePicker:$imagePickerVersion", + catppuccinLegacy: "com.github.ShiftHackZ.Catppuccin-Android-Library:palette-legacy:$catppuccinVersion", + catppuccinCompose: "com.github.ShiftHackZ.Catppuccin-Android-Library:compose:$catppuccinVersion", + catppuccinSplashscreen: "com.github.ShiftHackZ.Catppuccin-Android-Library:splashscreen:$catppuccinVersion", ] log = [ timber: "com.jakewharton.timber:timber:$timberVersion", ] - proprietary = [ - fbBom: "com.google.firebase:firebase-bom:$firebaseBomVersion", - fbA : "com.google.firebase:firebase-analytics-ktx", - fbC : "com.google.firebase:firebase-crashlytics-ktx", - appL : "com.applovin:applovin-sdk:+" - ] test = [ junit: "junit:junit:$testJunitVersion", ] diff --git a/docs/models.json b/docs/models.json index 6476e6fd..775b23ef 100644 --- a/docs/models.json +++ b/docs/models.json @@ -1,9 +1,27 @@ [ { + "id": "0290c206-f60b-47fe-b4f6-5ad8055fd3a3", "name": "chilloutmix", + "size": "1.2 Gb", "sources": [ "https://share.moroz.cc/SDAI/chilloutmix.zip", "https://drive.google.com/uc?export=download&id=1Z8D3sHkvosKsfn9ufnB66TUuW46iYf-N&confirm=t&uuid=94ddf728-e146-4375-aeb3-d126b8da3f0b&at=AB6BwCATWdQj6xRTLZYu00DwfxAV:1692354151068" ] + }, + { + "id": "a1621c1c-0646-41bf-bc9f-6d0f23399799", + "name": "Absolute Reality", + "size": "1.01 Gb", + "sources": [ + "https://share.moroz.cc/SDAI/majicmix.zip" + ] + }, + { + "id": "dfd7304e-a1da-4bbb-8814-5342ac88814d", + "name": "Real Vision", + "size": "1.8 Gb", + "sources": [ + "https://share.moroz.cc/SDAI/realvision.zip" + ] } ] diff --git a/docs/version.json b/docs/version.json index 92feee7c..fb3a46ed 100644 --- a/docs/version.json +++ b/docs/version.json @@ -1,4 +1,4 @@ { - "googleplay": "0.5.1", + "googleplay": "0.5.3", "fdroid": "0.4.3" } diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/CoinDataSource.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/CoinDataSource.kt deleted file mode 100644 index 27ccabc4..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/CoinDataSource.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.shifthackz.aisdv1.domain.datasource - -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Single - -sealed interface CoinDataSource { - - interface Local : CoinDataSource { - fun querySpentDailyCoinsForPeriod(start: Long, end: Long): Single - fun queryEarnedCoins(): Single - fun onDailyCoinSpent(): Completable - fun onEarnedCoinSpent(): Completable - fun onEarnedCoinsRewarded(amount: Int): Completable - } - - interface Remote : CoinDataSource { - fun fetchCoinsConfig(): Single - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/FeatureFlagsDataSource.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/FeatureFlagsDataSource.kt deleted file mode 100644 index 59f13104..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/FeatureFlagsDataSource.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.shifthackz.aisdv1.domain.datasource - -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Single - -sealed interface FeatureFlagsDataSource { - - interface Remote { - fun fetch(): Single - } - - interface Local { - fun getIsLoaded(): Single - fun get(): Single - fun store(flags: FeatureFlags): Completable - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/MotdDataSource.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/MotdDataSource.kt deleted file mode 100644 index e17d0ed6..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/MotdDataSource.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.shifthackz.aisdv1.domain.datasource - -import com.shifthackz.aisdv1.domain.entity.Motd -import io.reactivex.rxjava3.core.Single - -sealed interface MotdDataSource { - - interface Remote { - fun fetch(): Single - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/di/DomainModule.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/di/DomainModule.kt index a1c67e8a..3c84c5b4 100755 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/di/DomainModule.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/di/DomainModule.kt @@ -5,13 +5,9 @@ import com.shifthackz.aisdv1.domain.usecase.caching.ClearAppCacheUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.caching.DataPreLoaderUseCase import com.shifthackz.aisdv1.domain.usecase.caching.DataPreLoaderUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.caching.GetLastResultFromCacheUseCase -import com.shifthackz.aisdv1.domain.usecase.caching.SaveLastResultToCacheUseCase import com.shifthackz.aisdv1.domain.usecase.caching.GetLastResultFromCacheUseCaseImpl +import com.shifthackz.aisdv1.domain.usecase.caching.SaveLastResultToCacheUseCase import com.shifthackz.aisdv1.domain.usecase.caching.SaveLastResultToCacheUseCaseImpl -import com.shifthackz.aisdv1.domain.usecase.coin.EarnRewardedCoinsUseCase -import com.shifthackz.aisdv1.domain.usecase.coin.EarnRewardedCoinsUseCaseImpl -import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase -import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.connectivity.ObserveSeverConnectivityUseCase import com.shifthackz.aisdv1.domain.usecase.connectivity.ObserveSeverConnectivityUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.connectivity.PingStableDiffusionServiceUseCase @@ -28,8 +24,6 @@ import com.shifthackz.aisdv1.domain.usecase.downloadable.DeleteModelUseCase import com.shifthackz.aisdv1.domain.usecase.downloadable.DeleteModelUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.downloadable.DownloadModelUseCase import com.shifthackz.aisdv1.domain.usecase.downloadable.DownloadModelUseCaseImpl -import com.shifthackz.aisdv1.domain.usecase.features.GetFeatureFlagsUseCase -import com.shifthackz.aisdv1.domain.usecase.features.GetFeatureFlagsUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemUseCase import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.gallery.GetAllGalleryUseCase @@ -52,8 +46,6 @@ import com.shifthackz.aisdv1.domain.usecase.generation.SaveGenerationResultUseCa import com.shifthackz.aisdv1.domain.usecase.generation.SaveGenerationResultUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.generation.TextToImageUseCase import com.shifthackz.aisdv1.domain.usecase.generation.TextToImageUseCaseImpl -import com.shifthackz.aisdv1.domain.usecase.motd.ObserveMotdUseCase -import com.shifthackz.aisdv1.domain.usecase.motd.ObserveMotdUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.sdmodel.GetStableDiffusionModelsUseCase import com.shifthackz.aisdv1.domain.usecase.sdmodel.GetStableDiffusionModelsUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.sdmodel.SelectStableDiffusionModelUseCase @@ -66,8 +58,6 @@ import com.shifthackz.aisdv1.domain.usecase.settings.SetServerConfigurationUseCa import com.shifthackz.aisdv1.domain.usecase.settings.SetServerConfigurationUseCaseImpl import com.shifthackz.aisdv1.domain.usecase.splash.SplashNavigationUseCase import com.shifthackz.aisdv1.domain.usecase.splash.SplashNavigationUseCaseImpl -import com.shifthackz.aisdv1.domain.usecase.version.CheckAppVersionUpdateUseCase -import com.shifthackz.aisdv1.domain.usecase.version.CheckAppVersionUpdateUseCaseImpl import org.koin.core.module.dsl.factoryOf import org.koin.dsl.bind import org.koin.dsl.module @@ -92,13 +82,8 @@ internal val useCasesModule = module { factoryOf(::TestHordeApiKeyUseCaseImpl) bind TestHordeApiKeyUseCase::class factoryOf(::SaveGenerationResultUseCaseImpl) bind SaveGenerationResultUseCase::class factoryOf(::ObserveSeverConnectivityUseCaseImpl) bind ObserveSeverConnectivityUseCase::class - factoryOf(::CheckAppVersionUpdateUseCaseImpl) bind CheckAppVersionUpdateUseCase::class - factoryOf(::ObserveCoinsUseCaseImpl) bind ObserveCoinsUseCase::class - factoryOf(::EarnRewardedCoinsUseCaseImpl) bind EarnRewardedCoinsUseCase::class - factoryOf(::ObserveMotdUseCaseImpl) bind ObserveMotdUseCase::class factoryOf(::ObserveHordeProcessStatusUseCaseImpl) bind ObserveHordeProcessStatusUseCase::class factoryOf(::GetMediaStoreInfoUseCaseImpl) bind GetMediaStoreInfoUseCase::class - factoryOf(::GetFeatureFlagsUseCaseImpl) bind GetFeatureFlagsUseCase::class factoryOf(::GetRandomImageUseCaseImpl) bind GetRandomImageUseCase::class factoryOf(::SaveLastResultToCacheUseCaseImpl) bind SaveLastResultToCacheUseCase::class factoryOf(::GetLastResultFromCacheUseCaseImpl) bind GetLastResultFromCacheUseCase::class diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/FeatureFlags.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/FeatureFlags.kt deleted file mode 100644 index 99950088..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/FeatureFlags.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.shifthackz.aisdv1.domain.entity - -data class FeatureFlags( - val adHomeBottomEnable: Boolean = false, - val adGalleryBottomEnable: Boolean = false, -) diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Motd.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Motd.kt deleted file mode 100644 index cb095a15..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Motd.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.shifthackz.aisdv1.domain.entity - -/** - * Represents server message model. - * - * MOTD: Message Of The Day - * - * @param display defines if message should be visible - * @param title string with message header - * @param subTitle string with message body - */ -data class Motd( - val display: Boolean = false, - val title: String = "", - val subTitle: String = "", -) { - val isEmpty: Boolean - get() = title.isEmpty() && subTitle.isEmpty() - - val isNotEmpty: Boolean - get() = !isEmpty -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/ServerSource.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/ServerSource.kt index e6f575f0..f33f047c 100644 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/ServerSource.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/ServerSource.kt @@ -2,11 +2,10 @@ package com.shifthackz.aisdv1.domain.entity enum class ServerSource(val key: String) { CUSTOM("custom"), - SDAI("sdai"), HORDE("horde"), LOCAL("local"); companion object { - fun parse(value: String) = values().find { it.key == value } ?: CUSTOM + fun parse(value: String) = entries.find { it.key == value } ?: CUSTOM } } diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Settings.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Settings.kt index 77d0c994..a3b205d4 100644 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Settings.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Settings.kt @@ -3,7 +3,6 @@ package com.shifthackz.aisdv1.domain.entity data class Settings( val serverUrl: String, val demoMode: Boolean, - val useSdAiCloud: Boolean, val monitorConnectivity: Boolean, val autoSaveAiResults: Boolean, val saveToMediaStore: Boolean, diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/feature/ad/AdFeature.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/feature/ad/AdFeature.kt deleted file mode 100644 index f69ad481..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/feature/ad/AdFeature.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.shifthackz.aisdv1.domain.feature.ad - -import android.app.Activity -import android.content.Context -import android.view.View - -interface AdFeature { - fun initialize(activity: Activity) - fun getHomeScreenBannerAd(context: Context): Ad - fun getGalleryDetailBannerAd(context: Context): Ad - fun showRewardedCoinsAd(activity: Activity, rewardCallback: (Int) -> Unit) - - data class Ad( - val id: String = "", - val view: View? = null, - ) { - val isEmpty: Boolean - get() = id.isEmpty() || view == null - } - - companion object { - val empty = object : AdFeature { - override fun initialize(activity: Activity) = Unit - override fun getHomeScreenBannerAd(context: Context): Ad = Ad() - override fun getGalleryDetailBannerAd(context: Context): Ad = Ad() - override fun showRewardedCoinsAd(activity: Activity, rewardCallback: (Int) -> Unit) = Unit - } - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/preference/PreferenceManager.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/preference/PreferenceManager.kt index d737507a..c1958c82 100644 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/preference/PreferenceManager.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/preference/PreferenceManager.kt @@ -16,7 +16,5 @@ interface PreferenceManager { var forceSetupAfterUpdate: Boolean var localUseNNAPI: Boolean - val useSdAiCloud: Boolean - fun observe(): Flowable } diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/AppVersionRepository.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/AppVersionRepository.kt deleted file mode 100644 index 3e921b21..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/AppVersionRepository.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.shifthackz.aisdv1.domain.repository - -import com.shifthackz.aisdv1.core.common.appbuild.BuildVersion -import io.reactivex.rxjava3.core.Single - -interface AppVersionRepository { - fun getActualVersion(): Single - fun getLocalVersion(): Single -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/CoinRepository.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/CoinRepository.kt deleted file mode 100644 index 100bd1f5..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/CoinRepository.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.shifthackz.aisdv1.domain.repository - -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Flowable - -interface CoinRepository { - fun observeAvailableCoins(): Flowable - fun spendCoin(): Completable - fun earnCoins(amount: Int): Completable -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/FeatureFlagsRepository.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/FeatureFlagsRepository.kt deleted file mode 100644 index 95d5c95d..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/FeatureFlagsRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.domain.repository - -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import io.reactivex.rxjava3.core.Single - -interface FeatureFlagsRepository { - fun get(): Single -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/MotdRepository.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/MotdRepository.kt deleted file mode 100644 index ace8bc9e..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/repository/MotdRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.domain.repository - -import com.shifthackz.aisdv1.domain.entity.Motd -import io.reactivex.rxjava3.core.Single - -interface MotdRepository { - fun fetchMotd(): Single -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/EarnRewardedCoinsUseCase.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/EarnRewardedCoinsUseCase.kt deleted file mode 100644 index dfb62864..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/EarnRewardedCoinsUseCase.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.coin - -import io.reactivex.rxjava3.core.Completable - -interface EarnRewardedCoinsUseCase { - operator fun invoke(amount: Int): Completable -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/EarnRewardedCoinsUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/EarnRewardedCoinsUseCaseImpl.kt deleted file mode 100644 index 99031ee8..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/EarnRewardedCoinsUseCaseImpl.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.coin - -import com.shifthackz.aisdv1.domain.repository.CoinRepository - -internal class EarnRewardedCoinsUseCaseImpl( - private val coinRepository: CoinRepository, -) : EarnRewardedCoinsUseCase { - - override fun invoke(amount: Int) = coinRepository.earnCoins(amount) -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/ObserveCoinsUseCase.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/ObserveCoinsUseCase.kt deleted file mode 100644 index f65b6484..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/ObserveCoinsUseCase.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.coin - -import io.reactivex.rxjava3.core.Flowable - -interface ObserveCoinsUseCase { - operator fun invoke(): Flowable - - sealed interface Result { - object FeatureNotAvailable : Result - object UsingOwnServer : Result - data class Coins(val value: Int) : Result - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/ObserveCoinsUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/ObserveCoinsUseCaseImpl.kt deleted file mode 100644 index ce253d1d..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/coin/ObserveCoinsUseCaseImpl.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.coin - -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider -import com.shifthackz.aisdv1.core.common.appbuild.BuildType -import com.shifthackz.aisdv1.domain.entity.Settings -import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.repository.CoinRepository -import io.reactivex.rxjava3.core.Flowable - -internal class ObserveCoinsUseCaseImpl( - private val buildInfoProvider: BuildInfoProvider, - private val preferenceManager: PreferenceManager, - private val coinRepository: CoinRepository, -) : ObserveCoinsUseCase { - - override fun invoke(): Flowable { - if (buildInfoProvider.buildType == BuildType.FOSS) { - return Flowable.just(ObserveCoinsUseCase.Result.FeatureNotAvailable) - } - val coinsProducer: () -> Flowable = { - coinRepository.observeAvailableCoins() - .map { coins -> - if (preferenceManager.useSdAiCloud) ObserveCoinsUseCase.Result.Coins(coins) - else ObserveCoinsUseCase.Result.UsingOwnServer - } - } - val prefsProducer: () -> Flowable = { - preferenceManager - .observe() - .map(Settings::useSdAiCloud) - .flatMap { useSdAiCloud -> - if (useSdAiCloud) coinsProducer() - else Flowable.just(ObserveCoinsUseCase.Result.UsingOwnServer) - } - } - return Flowable.mergeArray(coinsProducer.invoke(), prefsProducer.invoke()) - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/features/GetFeatureFlagsUseCase.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/features/GetFeatureFlagsUseCase.kt deleted file mode 100644 index f6981e09..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/features/GetFeatureFlagsUseCase.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.features - -import com.shifthackz.aisdv1.domain.entity.FeatureFlags -import io.reactivex.rxjava3.core.Single - -interface GetFeatureFlagsUseCase { - operator fun invoke(): Single -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/features/GetFeatureFlagsUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/features/GetFeatureFlagsUseCaseImpl.kt deleted file mode 100644 index 56f0ce89..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/features/GetFeatureFlagsUseCaseImpl.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.features - -import com.shifthackz.aisdv1.domain.repository.FeatureFlagsRepository - -internal class GetFeatureFlagsUseCaseImpl( - private val featureFlagsRepository: FeatureFlagsRepository, -) : GetFeatureFlagsUseCase { - - override fun invoke() = featureFlagsRepository.get() -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/ImageToImageUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/ImageToImageUseCaseImpl.kt index 94a48763..2ff795df 100644 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/ImageToImageUseCaseImpl.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/ImageToImageUseCaseImpl.kt @@ -4,7 +4,6 @@ import com.shifthackz.aisdv1.domain.entity.AiGenerationResult import com.shifthackz.aisdv1.domain.entity.ImageToImagePayload import com.shifthackz.aisdv1.domain.entity.ServerSource import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.repository.CoinRepository import com.shifthackz.aisdv1.domain.repository.HordeGenerationRepository import com.shifthackz.aisdv1.domain.repository.StableDiffusionGenerationRepository import io.reactivex.rxjava3.core.Single @@ -12,16 +11,10 @@ import io.reactivex.rxjava3.core.Single internal class ImageToImageUseCaseImpl( private val stableDiffusionGenerationRepository: StableDiffusionGenerationRepository, private val hordeGenerationRepository: HordeGenerationRepository, - private val coinRepository: CoinRepository, private val preferenceManager: PreferenceManager, ) : ImageToImageUseCase { override fun invoke(payload: ImageToImagePayload) = execute(payload) - .flatMap { result -> - coinRepository - .spendCoin() - .andThen(Single.just(result)) - } private fun execute(payload: ImageToImagePayload): Single { if (preferenceManager.source == ServerSource.HORDE) { diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/TextToImageUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/TextToImageUseCaseImpl.kt index 96766c06..9b3e5646 100755 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/TextToImageUseCaseImpl.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/generation/TextToImageUseCaseImpl.kt @@ -4,7 +4,6 @@ import com.shifthackz.aisdv1.domain.entity.AiGenerationResult import com.shifthackz.aisdv1.domain.entity.ServerSource import com.shifthackz.aisdv1.domain.entity.TextToImagePayload import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.repository.CoinRepository import com.shifthackz.aisdv1.domain.repository.HordeGenerationRepository import com.shifthackz.aisdv1.domain.repository.LocalDiffusionGenerationRepository import com.shifthackz.aisdv1.domain.repository.StableDiffusionGenerationRepository @@ -15,14 +14,9 @@ internal class TextToImageUseCaseImpl( private val hordeGenerationRepository: HordeGenerationRepository, private val localDiffusionGenerationRepository: LocalDiffusionGenerationRepository, private val preferenceManager: PreferenceManager, - private val coinRepository: CoinRepository, ) : TextToImageUseCase { override operator fun invoke(payload: TextToImagePayload) = execute(payload) - .flatMap { result -> - coinRepository.spendCoin() - .andThen(Single.just(result)) - } private fun execute(payload: TextToImagePayload): Single { return when (preferenceManager.source) { diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/motd/ObserveMotdUseCase.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/motd/ObserveMotdUseCase.kt deleted file mode 100644 index 5d02f3b6..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/motd/ObserveMotdUseCase.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.motd - -import com.shifthackz.aisdv1.domain.entity.Motd -import io.reactivex.rxjava3.core.Flowable - -interface ObserveMotdUseCase { - operator fun invoke(): Flowable -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/motd/ObserveMotdUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/motd/ObserveMotdUseCaseImpl.kt deleted file mode 100644 index fe34af68..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/motd/ObserveMotdUseCaseImpl.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.motd - -import com.shifthackz.aisdv1.domain.entity.Motd -import com.shifthackz.aisdv1.domain.repository.MotdRepository -import io.reactivex.rxjava3.core.BackpressureStrategy -import io.reactivex.rxjava3.core.Flowable -import io.reactivex.rxjava3.core.Observable -import java.util.concurrent.TimeUnit - -internal class ObserveMotdUseCaseImpl( - private val motdRepository: MotdRepository, -) : ObserveMotdUseCase { - - private val motdProducer: (Long) -> Observable = { - motdRepository - .fetchMotd() - .onErrorReturn { motd } - .doOnSuccess { motd = it } - .toObservable() - } - - private var motd: Motd = Motd() - - override operator fun invoke(): Flowable { - val refreshProducer: () -> Observable = { - Observable - .interval(30L, TimeUnit.SECONDS) - .flatMap(motdProducer::invoke) - } - - val merged = Observable.merge( - refreshProducer(), - motdProducer(-1L), - ) - - return merged.toFlowable(BackpressureStrategy.LATEST) - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/splash/SplashNavigationUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/splash/SplashNavigationUseCaseImpl.kt index 193b930e..852d6a7f 100644 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/splash/SplashNavigationUseCaseImpl.kt +++ b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/splash/SplashNavigationUseCaseImpl.kt @@ -20,7 +20,7 @@ internal class SplashNavigationUseCaseImpl( preferenceManager.source == ServerSource.HORDE -> { Action.LAUNCH_HOME } - preferenceManager.serverUrl.isEmpty() && !preferenceManager.useSdAiCloud -> { + preferenceManager.serverUrl.isEmpty() -> { Action.LAUNCH_SERVER_SETUP } else -> Action.LAUNCH_HOME diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/version/CheckAppVersionUpdateUseCase.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/version/CheckAppVersionUpdateUseCase.kt deleted file mode 100644 index a8b8dbe8..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/version/CheckAppVersionUpdateUseCase.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.version - -import com.shifthackz.aisdv1.core.common.appbuild.BuildVersion -import io.reactivex.rxjava3.core.Single - -interface CheckAppVersionUpdateUseCase { - - operator fun invoke(): Single - - sealed interface Result { - object NoUpdateNeeded : Result - data class NewVersionAvailable(val availableVersion: BuildVersion) : Result - } -} diff --git a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/version/CheckAppVersionUpdateUseCaseImpl.kt b/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/version/CheckAppVersionUpdateUseCaseImpl.kt deleted file mode 100644 index e0ef587c..00000000 --- a/domain/src/main/java/com/shifthackz/aisdv1/domain/usecase/version/CheckAppVersionUpdateUseCaseImpl.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.shifthackz.aisdv1.domain.usecase.version - -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider -import com.shifthackz.aisdv1.core.common.appbuild.BuildType -import com.shifthackz.aisdv1.core.common.appbuild.BuildVersion -import com.shifthackz.aisdv1.domain.repository.AppVersionRepository -import io.reactivex.rxjava3.core.Single - -internal class CheckAppVersionUpdateUseCaseImpl( - private val buildInfoProvider: BuildInfoProvider, - private val repository: AppVersionRepository, -) : CheckAppVersionUpdateUseCase { - - private val remoteVersionProducer: () -> Single = { - repository - .getActualVersion() - .onErrorReturn { BuildVersion() } - } - - private val localVersionProducer: () -> Single = { - repository.getLocalVersion() - } - - override fun invoke(): Single = - when (buildInfoProvider.buildType) { - BuildType.GOOGLE_PLAY -> Single - .zip(remoteVersionProducer(), localVersionProducer(), ::Pair) - .map { (actualVer, localVer) -> - if (localVer < actualVer) { - CheckAppVersionUpdateUseCase.Result.NewVersionAvailable(actualVer) - } else { - CheckAppVersionUpdateUseCase.Result.NoUpdateNeeded - } - } - - else -> Single.just(CheckAppVersionUpdateUseCase.Result.NoUpdateNeeded) - } -} diff --git a/feature/ads/.gitignore b/feature/ads/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/feature/ads/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/feature/ads/build.gradle b/feature/ads/build.gradle deleted file mode 100644 index b40db35a..00000000 --- a/feature/ads/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -plugins { - id 'com.android.library' - id 'org.jetbrains.kotlin.android' -} - -apply from: "$project.rootDir/gradle/common.gradle" - -android { - namespace 'com.shifthackz.aisdv1.feature.ads' - buildTypes.each { - it.buildConfigField("String", "BANNER_HOME_ID", "\"c66032471f8ba759\"") - it.buildConfigField("String", "BANNER_GALLERY_ID", "\"6522e4b9d477e41f\"") - it.buildConfigField("String", "COIN_REWARDED_ID", "\"d27e36a05fa45186\"") - } - flavorDimensions "type" - productFlavors { - foss { - dimension "type" - } - playstore { - dimension "type" - } - } -} - -dependencies { - implementation project(":core:common") - implementation project(":domain") - implementation di.koinCore - playstoreImplementation proprietary.appL -} diff --git a/feature/ads/consumer-rules.pro b/feature/ads/consumer-rules.pro deleted file mode 100644 index e69de29b..00000000 diff --git a/feature/ads/proguard-rules.pro b/feature/ads/proguard-rules.pro deleted file mode 100644 index 481bb434..00000000 --- a/feature/ads/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/feature/ads/src/foss/java/com/shifthackz/aisdv1/feature/ads/AdFeatureImpl.kt b/feature/ads/src/foss/java/com/shifthackz/aisdv1/feature/ads/AdFeatureImpl.kt deleted file mode 100644 index daffb13a..00000000 --- a/feature/ads/src/foss/java/com/shifthackz/aisdv1/feature/ads/AdFeatureImpl.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.shifthackz.aisdv1.feature.ads - -import android.app.Activity -import android.content.Context -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature - -internal class AdFeatureImpl : AdFeature { - override fun initialize(activity: Activity) = Unit - override fun getHomeScreenBannerAd(context: Context) = AdFeature.Ad() - override fun getGalleryDetailBannerAd(context: Context) = AdFeature.Ad() - override fun showRewardedCoinsAd(activity: Activity, rewardCallback: (Int) -> Unit) = Unit -} diff --git a/feature/ads/src/main/AndroidManifest.xml b/feature/ads/src/main/AndroidManifest.xml deleted file mode 100644 index 56a9e28a..00000000 --- a/feature/ads/src/main/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/feature/ads/src/main/java/com/shifthackz/aisdv1/feature/ads/di/AdFeatureModule.kt b/feature/ads/src/main/java/com/shifthackz/aisdv1/feature/ads/di/AdFeatureModule.kt deleted file mode 100644 index a63b666c..00000000 --- a/feature/ads/src/main/java/com/shifthackz/aisdv1/feature/ads/di/AdFeatureModule.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.shifthackz.aisdv1.feature.ads.di - -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature -import com.shifthackz.aisdv1.feature.ads.AdFeatureImpl -import org.koin.core.module.dsl.singleOf -import org.koin.dsl.bind -import org.koin.dsl.module - -val adFeatureOldModule = module { - singleOf(::AdFeatureImpl) bind AdFeature::class -} diff --git a/feature/ads/src/main/res/values/strings.xml b/feature/ads/src/main/res/values/strings.xml deleted file mode 100644 index 78e3a9e6..00000000 --- a/feature/ads/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Ads by AdMob: - diff --git a/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/AdFeatureImpl.kt b/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/AdFeatureImpl.kt deleted file mode 100644 index 5a299583..00000000 --- a/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/AdFeatureImpl.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.shifthackz.aisdv1.feature.ads - -import android.app.Activity -import android.content.Context -import android.view.ViewGroup -import android.widget.FrameLayout -import com.applovin.mediation.MaxAd -import com.applovin.mediation.MaxError -import com.applovin.mediation.MaxReward -import com.applovin.mediation.ads.MaxAdView -import com.applovin.mediation.ads.MaxRewardedAd -import com.applovin.sdk.AppLovinSdk -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature - -internal class AdFeatureImpl : AdFeature, LoggableMaxRewardedAdListener { - - private var rewardedAd: MaxRewardedAd? = null - private var rewardCallback: (Int) -> Unit = {} - - override fun initialize(activity: Activity) { - AppLovinSdk.getInstance(activity).mediationProvider = "max" - AppLovinSdk.initializeSdk(activity) { - loadRewardedCoinsAd(activity) - } - } - - override fun getHomeScreenBannerAd(context: Context): AdFeature.Ad { - return loadBannerAd(MaxAdView(BuildConfig.BANNER_HOME_ID, context)) - } - - override fun getGalleryDetailBannerAd(context: Context): AdFeature.Ad { - return loadBannerAd(MaxAdView(BuildConfig.BANNER_GALLERY_ID, context)) - } - - override fun showRewardedCoinsAd(activity: Activity, rewardCallback: (Int) -> Unit) { - this.rewardCallback = rewardCallback - rewardedAd - ?.takeIf { it.isReady } - ?.showAd() - } - - override fun onAdLoadFailed(p0: String?, p1: MaxError?) { - super.onAdLoadFailed(p0, p1) - rewardedAd?.loadAd() - } - - override fun onAdDisplayFailed(p0: MaxAd?, p1: MaxError?) { - super.onAdDisplayFailed(p0, p1) - rewardedAd?.loadAd() - } - - override fun onUserRewarded(p0: MaxAd?, p1: MaxReward?) { - super.onUserRewarded(p0, p1) - val amount = p1?.amount?.takeIf { it > 0 } ?: 1 - rewardCallback(amount) - rewardCallback = {} - } - - private fun loadRewardedCoinsAd(activity: Activity) { - rewardedAd = MaxRewardedAd - .getInstance(BuildConfig.COIN_REWARDED_ID, activity) - .also { ad -> ad.setListener(this) } - .also { ad -> ad.loadAd() } - } - - private fun loadBannerAd(adView: MaxAdView): AdFeature.Ad { - adView.loadAd() - adView.setListener(LoggableMaxAdViewListener.factory()) - adView.layoutParams = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - adView.context.resources.getDimensionPixelSize(R.dimen.ad_banner_height), - ) - return AdFeature.Ad( - id = adView.adUnitId, - view = adView, - ) - } -} diff --git a/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/LoggableMaxAdViewListener.kt b/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/LoggableMaxAdViewListener.kt deleted file mode 100644 index 1179cd02..00000000 --- a/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/LoggableMaxAdViewListener.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.shifthackz.aisdv1.feature.ads - -import com.applovin.mediation.MaxAd -import com.applovin.mediation.MaxAdViewAdListener -import com.applovin.mediation.MaxError -import com.shifthackz.aisdv1.core.common.log.debugLog - -interface LoggableMaxAdViewListener : MaxAdViewAdListener { - override fun onAdLoaded(p0: MaxAd?) { - log("onAdLoaded($p0)") - } - - override fun onAdDisplayed(p0: MaxAd?) { - log("onAdDisplayed($p0)") - } - - override fun onAdHidden(p0: MaxAd?) { - log("onAdHidden($p0)") - } - - override fun onAdClicked(p0: MaxAd?) { - log("onAdClicked($p0)") - } - - override fun onAdLoadFailed(p0: String?, p1: MaxError?) { - log("onAdLoadFailed($p0)") - } - - override fun onAdDisplayFailed(p0: MaxAd?, p1: MaxError?) { - log("onAdDisplayFailed($p0)") - } - - override fun onAdExpanded(p0: MaxAd?) { - log("onAdExpanded($p0)") - } - - override fun onAdCollapsed(p0: MaxAd?) { - log("onAdCollapsed($p0)") - } - - private fun log(msg: String) { - if (BuildConfig.DEBUG) debugLog(TAG, msg) - } - - companion object { - private const val TAG = "AppLovinAd" - - fun factory(): LoggableMaxAdViewListener { - return object : LoggableMaxAdViewListener {} - } - } -} diff --git a/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/LoggableMaxRewardedAdListener.kt b/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/LoggableMaxRewardedAdListener.kt deleted file mode 100644 index 30e34aa7..00000000 --- a/feature/ads/src/playstore/java/com/shifthackz/aisdv1/feature/ads/LoggableMaxRewardedAdListener.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.shifthackz.aisdv1.feature.ads - -import com.applovin.mediation.MaxAd -import com.applovin.mediation.MaxError -import com.applovin.mediation.MaxReward -import com.applovin.mediation.MaxRewardedAdListener -import com.shifthackz.aisdv1.core.common.log.debugLog - -internal interface LoggableMaxRewardedAdListener : MaxRewardedAdListener { - override fun onAdLoaded(p0: MaxAd?) { - log("onAdLoaded($p0)") - } - - override fun onAdDisplayed(p0: MaxAd?) { - log("onAdDisplayed($p0)") - } - - override fun onAdHidden(p0: MaxAd?) { - log("onAdHidden($p0)") - } - - override fun onAdClicked(p0: MaxAd?) { - log("onAdClicked($p0)") - } - - override fun onAdLoadFailed(p0: String?, p1: MaxError?) { - log("onAdLoadFailed($p0, $p1)") - } - - override fun onAdDisplayFailed(p0: MaxAd?, p1: MaxError?) { - log("onAdDisplayFailed($p0, $p1)") - } - - override fun onUserRewarded(p0: MaxAd?, p1: MaxReward?) { - log("onUserRewarded($p0, $p1)") - } - - @Deprecated("Deprecated in Java") - override fun onRewardedVideoStarted(p0: MaxAd?) { - log("onRewardedVideoStarted($p0)") - } - - @Deprecated("Deprecated in Java") - override fun onRewardedVideoCompleted(p0: MaxAd?) { - log("onRewardedVideoCompleted($p0)") - } - - private fun log(msg: String) { - if (BuildConfig.DEBUG) debugLog(TAG, msg) - } - - companion object { - private const val TAG = "AppLovinRewared" - } -} diff --git a/feature/ads/src/playstore/res/values/dimens.xml b/feature/ads/src/playstore/res/values/dimens.xml deleted file mode 100644 index f373c6e5..00000000 --- a/feature/ads/src/playstore/res/values/dimens.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - 50dp - diff --git a/feature/analytics/build.gradle b/feature/analytics/build.gradle index fdb56b76..8e862dd9 100644 --- a/feature/analytics/build.gradle +++ b/feature/analytics/build.gradle @@ -7,21 +7,10 @@ apply from: "$project.rootDir/gradle/common.gradle" android { namespace 'com.shifthackz.aisdv1.feature.analytics' - flavorDimensions "type" - productFlavors { - foss { - dimension "type" - } - playstore { - dimension "type" - } - } } dependencies { implementation project(":core:common") implementation project(":domain") implementation di.koinCore - playstoreImplementation platform(proprietary.fbBom) - playstoreImplementation proprietary.fbA } diff --git a/feature/analytics/src/foss/java/com/shifthackz/aisdv1/feature/analytics/provider/FirebaseAnalyticsProvider.kt b/feature/analytics/src/foss/java/com/shifthackz/aisdv1/feature/analytics/provider/FirebaseAnalyticsProvider.kt deleted file mode 100644 index 97073d31..00000000 --- a/feature/analytics/src/foss/java/com/shifthackz/aisdv1/feature/analytics/provider/FirebaseAnalyticsProvider.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.shifthackz.aisdv1.feature.analytics.provider - -import com.shifthackz.aisdv1.domain.feature.analytics.AnalyticsEvent -import com.shifthackz.aisdv1.feature.analytics.AnalyticsProvider - -internal class FirebaseAnalyticsProvider : AnalyticsProvider { - override fun create() = Unit - override fun logEvent(event: AnalyticsEvent) = Unit -} diff --git a/feature/analytics/src/main/java/com/shifthackz/aisdv1/feature/analytics/di/AnalyticsModule.kt b/feature/analytics/src/main/java/com/shifthackz/aisdv1/feature/analytics/di/AnalyticsModule.kt index 0bf79c9e..25663b91 100644 --- a/feature/analytics/src/main/java/com/shifthackz/aisdv1/feature/analytics/di/AnalyticsModule.kt +++ b/feature/analytics/src/main/java/com/shifthackz/aisdv1/feature/analytics/di/AnalyticsModule.kt @@ -2,7 +2,6 @@ package com.shifthackz.aisdv1.feature.analytics.di import com.shifthackz.aisdv1.domain.feature.analytics.Analytics import com.shifthackz.aisdv1.feature.analytics.AnalyticsClient -import com.shifthackz.aisdv1.feature.analytics.provider.FirebaseAnalyticsProvider import com.shifthackz.aisdv1.feature.analytics.provider.LoggableAnalyticsProvider import org.koin.dsl.module @@ -12,7 +11,6 @@ val analyticsModule = module { AnalyticsClient( listOf( LoggableAnalyticsProvider(), - FirebaseAnalyticsProvider(), ) ) } diff --git a/feature/analytics/src/playstore/java/com/shifthackz/aisdv1/feature/analytics/provider/FirebaseAnalyticsProvider.kt b/feature/analytics/src/playstore/java/com/shifthackz/aisdv1/feature/analytics/provider/FirebaseAnalyticsProvider.kt deleted file mode 100644 index 55d5c88e..00000000 --- a/feature/analytics/src/playstore/java/com/shifthackz/aisdv1/feature/analytics/provider/FirebaseAnalyticsProvider.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.shifthackz.aisdv1.feature.analytics.provider - -import com.google.firebase.analytics.FirebaseAnalytics -import com.google.firebase.analytics.ktx.analytics -import com.google.firebase.analytics.ktx.logEvent -import com.google.firebase.ktx.Firebase -import com.shifthackz.aisdv1.domain.feature.analytics.AnalyticsEvent -import com.shifthackz.aisdv1.feature.analytics.AnalyticsProvider - -internal class FirebaseAnalyticsProvider : AnalyticsProvider { - - private var firebaseAnalytics: FirebaseAnalytics? = null - - override fun create() { - firebaseAnalytics = Firebase.analytics - } - - override fun logEvent(event: AnalyticsEvent) { - if (firebaseAnalytics == null) create() - if (firebaseAnalytics == null) return - if (!event.isValid) return - firebaseAnalytics?.logEvent(event.name) { - event.parameters - .filter { (_, value) -> "$value".isNotEmpty() } - .forEach { (key, value) -> param(key, "$value") } - } - } -} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 79d56a0d..696d935f 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Jan 31 14:40:24 GMT+02:00 2023 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/api/sdai/FeatureFlagsRestApi.kt b/network/src/main/java/com/shifthackz/aisdv1/network/api/sdai/FeatureFlagsRestApi.kt deleted file mode 100644 index f900d14e..00000000 --- a/network/src/main/java/com/shifthackz/aisdv1/network/api/sdai/FeatureFlagsRestApi.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.shifthackz.aisdv1.network.api.sdai - -import com.shifthackz.aisdv1.network.response.FeatureFlagsResponse -import io.reactivex.rxjava3.core.Single -import retrofit2.http.GET - -interface FeatureFlagsRestApi { - - @GET("/feature-flags.json") - fun fetchConfig(): Single -} diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/api/sdai/MotdRestApi.kt b/network/src/main/java/com/shifthackz/aisdv1/network/api/sdai/MotdRestApi.kt deleted file mode 100644 index 1d7ecdfe..00000000 --- a/network/src/main/java/com/shifthackz/aisdv1/network/api/sdai/MotdRestApi.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.shifthackz.aisdv1.network.api.sdai - -import com.shifthackz.aisdv1.network.response.MotdResponse -import io.reactivex.rxjava3.core.Single -import retrofit2.http.GET - -interface MotdRestApi { - - @GET("/motd.json") - fun fetchMotd(): Single -} diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/di/NetworkModule.kt b/network/src/main/java/com/shifthackz/aisdv1/network/di/NetworkModule.kt index 1cf6921e..0e4ad5d2 100755 --- a/network/src/main/java/com/shifthackz/aisdv1/network/di/NetworkModule.kt +++ b/network/src/main/java/com/shifthackz/aisdv1/network/di/NetworkModule.kt @@ -10,8 +10,6 @@ import com.shifthackz.aisdv1.network.api.sdai.AppUpdateRestApi import com.shifthackz.aisdv1.network.api.sdai.CoinsRestApi import com.shifthackz.aisdv1.network.api.sdai.DownloadableModelsRestApi import com.shifthackz.aisdv1.network.api.sdai.DownloadableModelsRestApiImpl -import com.shifthackz.aisdv1.network.api.sdai.FeatureFlagsRestApi -import com.shifthackz.aisdv1.network.api.sdai.MotdRestApi import com.shifthackz.aisdv1.network.authenticator.RestAuthenticator import com.shifthackz.aisdv1.network.connectivity.ConnectivityMonitor import com.shifthackz.aisdv1.network.extensions.withBaseUrl @@ -68,7 +66,7 @@ val networkModule = module { single { NetworkInterceptors( listOf( - NetworkInterceptor(LoggingInterceptor(get()).get()), + NetworkInterceptor(LoggingInterceptor().get()), ) ) } @@ -114,18 +112,6 @@ val networkModule = module { .create(CoinsRestApi::class.java) } - single { - get() - .withBaseUrl(get().stableDiffusionAppApiUrl) - .create(MotdRestApi::class.java) - } - - single { - get() - .withBaseUrl(get().stableDiffusionAppApiUrl) - .create(FeatureFlagsRestApi::class.java) - } - single { get() .withBaseUrl(get().hordeApiUrl) diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/interceptor/LoggingInterceptor.kt b/network/src/main/java/com/shifthackz/aisdv1/network/interceptor/LoggingInterceptor.kt index 897e8822..e138632e 100644 --- a/network/src/main/java/com/shifthackz/aisdv1/network/interceptor/LoggingInterceptor.kt +++ b/network/src/main/java/com/shifthackz/aisdv1/network/interceptor/LoggingInterceptor.kt @@ -1,21 +1,13 @@ package com.shifthackz.aisdv1.network.interceptor -import com.shifthackz.aisdv1.core.common.extensions.withoutUrlProtocol import com.shifthackz.aisdv1.core.common.log.debugLog -import com.shifthackz.aisdv1.network.qualifiers.ApiUrlProvider import okhttp3.logging.HttpLoggingInterceptor -internal class LoggingInterceptor( - private val apiUrlProvider: ApiUrlProvider, -) { +internal class LoggingInterceptor { fun get() = HttpLoggingInterceptor { message -> - val badPredicate = message.contains( - apiUrlProvider.stableDiffusionCloudAiApiUrl.withoutUrlProtocol() - ) - if (!badPredicate) debugLog(HTTP_TAG, message) + debugLog(HTTP_TAG, message) }.apply { -// level = HttpLoggingInterceptor.Level.BODY level = HttpLoggingInterceptor.Level.HEADERS } diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/qualifiers/ApiUrlProvider.kt b/network/src/main/java/com/shifthackz/aisdv1/network/qualifiers/ApiUrlProvider.kt index 790934e3..faf00eec 100755 --- a/network/src/main/java/com/shifthackz/aisdv1/network/qualifiers/ApiUrlProvider.kt +++ b/network/src/main/java/com/shifthackz/aisdv1/network/qualifiers/ApiUrlProvider.kt @@ -3,7 +3,6 @@ package com.shifthackz.aisdv1.network.qualifiers interface ApiUrlProvider { val stableDiffusionAutomaticApiUrl: String val stableDiffusionAppApiUrl: String - val stableDiffusionCloudAiApiUrl: String val hordeApiUrl: String val imageCdnApiUrl: String } diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/response/FeatureFlagsResponse.kt b/network/src/main/java/com/shifthackz/aisdv1/network/response/FeatureFlagsResponse.kt deleted file mode 100644 index 7c8b5b8f..00000000 --- a/network/src/main/java/com/shifthackz/aisdv1/network/response/FeatureFlagsResponse.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.shifthackz.aisdv1.network.response - -import com.google.gson.annotations.SerializedName - -data class FeatureFlagsResponse( - @SerializedName("ad_home_bottom_enable") - val adHomeBottomEnable: Boolean?, - @SerializedName("ad_gallery_bottom_enable") - val adGalleryBottomEnable: Boolean?, -) diff --git a/network/src/main/java/com/shifthackz/aisdv1/network/response/MotdResponse.kt b/network/src/main/java/com/shifthackz/aisdv1/network/response/MotdResponse.kt deleted file mode 100644 index 30d14f78..00000000 --- a/network/src/main/java/com/shifthackz/aisdv1/network/response/MotdResponse.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.shifthackz.aisdv1.network.response - -import com.google.gson.annotations.SerializedName - -data class MotdResponse( - @SerializedName("display") - val display: Boolean?, - @SerializedName("title") - val title: String?, - @SerializedName("subtitle") - val subTitle: String?, -) diff --git a/presentation/build.gradle b/presentation/build.gradle index d65f200b..b9104e65 100755 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -12,7 +12,7 @@ android { compose true } composeOptions { - kotlinCompilerExtensionVersion = "1.4.7" + kotlinCompilerExtensionVersion = "1.5.7" } } @@ -39,5 +39,6 @@ dependencies { implementation reactive.rxandroid implementation ui.imagePicker + implementation ui.catppuccinCompose implementation "androidx.exifinterface:exifinterface:1.3.6" } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionActivity.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionActivity.kt index 02607d5b..9e34e84c 100755 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionActivity.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionActivity.kt @@ -16,13 +16,18 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import com.shifthackz.aisdv1.core.common.extensions.copyToClipboard -import com.shifthackz.aisdv1.core.common.extensions.openMarket import com.shifthackz.aisdv1.core.common.extensions.openUrl import com.shifthackz.aisdv1.core.common.file.FileProviderDescriptor import com.shifthackz.aisdv1.core.common.log.debugLog -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature import com.shifthackz.aisdv1.domain.feature.analytics.Analytics -import com.shifthackz.aisdv1.presentation.features.* +import com.shifthackz.aisdv1.presentation.features.FileSharingFeature +import com.shifthackz.aisdv1.presentation.features.GalleryExportZip +import com.shifthackz.aisdv1.presentation.features.GalleryGridItemClick +import com.shifthackz.aisdv1.presentation.features.GalleryItemImageShare +import com.shifthackz.aisdv1.presentation.features.GalleryItemInfoShare +import com.shifthackz.aisdv1.presentation.features.ImagePickerFeature +import com.shifthackz.aisdv1.presentation.features.ReportProblemEmailComposer +import com.shifthackz.aisdv1.presentation.features.SettingsConfigurationClick import com.shifthackz.aisdv1.presentation.screen.debug.DebugMenuAccessor import com.shifthackz.aisdv1.presentation.screen.debug.DebugMenuScreen import com.shifthackz.aisdv1.presentation.screen.gallery.detail.GalleryDetailScreen @@ -36,8 +41,6 @@ import com.shifthackz.aisdv1.presentation.screen.setup.ServerSetupViewModel import com.shifthackz.aisdv1.presentation.screen.splash.SplashScreen import com.shifthackz.aisdv1.presentation.theme.AiStableDiffusionAppTheme import com.shifthackz.aisdv1.presentation.utils.Constants -import com.shifthackz.aisdv1.presentation.widget.version.VersionCheckerComposable -import com.shifthackz.aisdv1.presentation.widget.version.VersionCheckerViewModel import org.koin.android.ext.android.inject import org.koin.androidx.compose.getViewModel import org.koin.androidx.compose.koinViewModel @@ -47,12 +50,10 @@ import org.koin.core.parameter.parametersOf class AiStableDiffusionActivity : ComponentActivity(), ImagePickerFeature, FileSharingFeature { private val galleryDetailSharing: GalleryDetailSharing by inject() - private val adFeature: AdFeature by inject() private val analytics: Analytics by inject() private val debugMenuAccessor: DebugMenuAccessor by inject() private val viewModel: AiStableDiffusionViewModel by viewModel() - private val versionCheckerViewModel: VersionCheckerViewModel by viewModel() private val notificationPermission = registerForActivityResult( ActivityResultContracts.RequestPermission() @@ -72,7 +73,7 @@ class AiStableDiffusionActivity : ComponentActivity(), ImagePickerFeature, FileS @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - adFeature.initialize(this) + actionBar?.hide() analytics.initialize() requestNotificationPermission() requestStoragePermission() @@ -170,21 +171,7 @@ class AiStableDiffusionActivity : ComponentActivity(), ImagePickerFeature, FileS "${Constants.ROUTE_SERVER_SETUP}/${ServerSetupLaunchSource.SETTINGS.key}" ) }, - launchUpdateCheck = { - analytics.logEvent(SettingsCheckUpdate) - versionCheckerViewModel.checkForUpdate(notifyIfSame = true) - }, - launchInAppReview = { - analytics.logEvent(SettingsOpenMarket) - openMarket() - }, launchUrl = ::openUrl, - launchRewarded = { - adFeature.showRewardedCoinsAd( - activity = this@AiStableDiffusionActivity, - rewardCallback = viewModel::earnRewardedCoins, - ) - }, launchDebugMenu = { if (debugMenuAccessor.invoke()) { navController.navigate(Constants.ROUTE_DEBUG) @@ -238,10 +225,6 @@ class AiStableDiffusionActivity : ComponentActivity(), ImagePickerFeature, FileS ).Build() } } - VersionCheckerComposable( - viewModel = versionCheckerViewModel, - launchMarket = { openMarket() }, - ).Build() } } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionViewModel.kt index 7b97cdf3..adfb12d8 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/activity/AiStableDiffusionViewModel.kt @@ -1,24 +1,12 @@ package com.shifthackz.aisdv1.presentation.activity -import com.shifthackz.aisdv1.core.common.extensions.EmptyLambda -import com.shifthackz.aisdv1.core.common.log.errorLog -import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider -import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread import com.shifthackz.aisdv1.core.viewmodel.RxViewModel import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.usecase.coin.EarnRewardedCoinsUseCase -import io.reactivex.rxjava3.kotlin.subscribeBy class AiStableDiffusionViewModel( - private val earnRewardedCoinsUseCase: EarnRewardedCoinsUseCase, private val preferenceManager: PreferenceManager, - private val schedulersProvider: SchedulersProvider, ) : RxViewModel() { - fun earnRewardedCoins(amount: Int) = !earnRewardedCoinsUseCase(amount) - .subscribeOnMainThread(schedulersProvider) - .subscribeBy(::errorLog, EmptyLambda) - fun onStoragePermissionsGranted() { preferenceManager.saveToMediaStore = true } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/core/GenerationMviViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/core/GenerationMviViewModel.kt index 9143e2a8..00940ac0 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/core/GenerationMviViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/core/GenerationMviViewModel.kt @@ -2,8 +2,6 @@ package com.shifthackz.aisdv1.presentation.core -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider -import com.shifthackz.aisdv1.core.common.appbuild.BuildType import com.shifthackz.aisdv1.core.common.extensions.EmptyLambda import com.shifthackz.aisdv1.core.common.log.errorLog import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider @@ -15,19 +13,15 @@ import com.shifthackz.aisdv1.domain.entity.HordeProcessStatus import com.shifthackz.aisdv1.domain.entity.StableDiffusionSampler import com.shifthackz.aisdv1.domain.feature.diffusion.LocalDiffusion import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase import com.shifthackz.aisdv1.domain.usecase.generation.ObserveHordeProcessStatusUseCase import com.shifthackz.aisdv1.domain.usecase.generation.ObserveLocalDiffusionProcessStatusUseCase import com.shifthackz.aisdv1.domain.usecase.sdsampler.GetStableDiffusionSamplersUseCase import com.shifthackz.aisdv1.presentation.widget.input.GenerationInputMode -import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.kotlin.subscribeBy abstract class GenerationMviViewModel( schedulersProvider: SchedulersProvider, - buildInfoProvider: BuildInfoProvider, preferenceManager: PreferenceManager, - observeCoinsUseCase: ObserveCoinsUseCase, getStableDiffusionSamplersUseCase: GetStableDiffusionSamplersUseCase, observeHordeProcessStatusUseCase: ObserveHordeProcessStatusUseCase, observeLocalDiffusionProcessStatusUseCase: ObserveLocalDiffusionProcessStatusUseCase? = null, @@ -86,20 +80,6 @@ abstract class GenerationMviViewModel( onComplete = EmptyLambda, ) ?.apply { addToDisposable() } - - if (buildInfoProvider.buildType == BuildType.GOOGLE_PLAY) { - !observeCoinsUseCase() - .subscribeOnMainThread(schedulersProvider) - .map {result -> - when (result) { - is ObserveCoinsUseCase.Result.Coins -> { - currentState.copyState(generateButtonEnabled = result.value > 0) - } - else -> currentState - } - } - .subscribeBy(::errorLog, EmptyLambda, ::setGenerationState) - } } open fun updateFormPreviousAiGeneration(ai: AiGenerationResult) = currentState diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/di/ViewModelModule.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/di/ViewModelModule.kt index 84d12c0c..039adabe 100755 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/di/ViewModelModule.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/di/ViewModelModule.kt @@ -14,10 +14,7 @@ import com.shifthackz.aisdv1.presentation.screen.setup.ServerSetupLaunchSource import com.shifthackz.aisdv1.presentation.screen.setup.ServerSetupViewModel import com.shifthackz.aisdv1.presentation.screen.splash.SplashViewModel import com.shifthackz.aisdv1.presentation.screen.txt2img.TextToImageViewModel -import com.shifthackz.aisdv1.presentation.widget.coins.AvailableCoinsViewModel import com.shifthackz.aisdv1.presentation.widget.connectivity.ConnectivityViewModel -import com.shifthackz.aisdv1.presentation.widget.motd.MotdViewModel -import com.shifthackz.aisdv1.presentation.widget.version.VersionCheckerViewModel import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.dsl.module @@ -32,21 +29,16 @@ val viewModelModule = module { viewModelOf(::SettingsViewModel) viewModelOf(::GalleryViewModel) viewModelOf(::ConnectivityViewModel) - viewModelOf(::VersionCheckerViewModel) - viewModelOf(::AvailableCoinsViewModel) - viewModelOf(::MotdViewModel) viewModelOf(::InputHistoryViewModel) viewModelOf(::DebugMenuViewModel) viewModel { parameters -> val launchSource = ServerSetupLaunchSource.fromKey(parameters.get()) val demoModeUrl = get().demoModeUrl - val cloudUrl = get().cloudUrl ServerSetupViewModel( launchSource = launchSource, getConfigurationUseCase = get(), demoModeUrl = demoModeUrl, - cloudUrl = cloudUrl, urlValidator = get(), stringValidator = get(), testConnectivityUseCase = get(), @@ -57,13 +49,12 @@ val viewModelModule = module { checkDownloadedModelUseCase = get(), dataPreLoaderUseCase = get(), schedulersProvider = get(), - buildInfoProvider = get(), preferenceManager = get(), analytics = get(), ) } viewModel { parameters -> - GalleryDetailViewModel(get(), parameters.get(), get(), get(), get(), get(), get(), get(), get(), get()) + GalleryDetailViewModel(parameters.get(), get(), get(), get(), get(), get(), get(), get(), get()) } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/features/AnalyticsEvents.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/features/AnalyticsEvents.kt index d0a0a849..cc71c471 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/features/AnalyticsEvents.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/features/AnalyticsEvents.kt @@ -42,10 +42,6 @@ object SettingsConfigurationClick : AnalyticsEvent(name = "settings_configuratio object SettingsCacheCleared : AnalyticsEvent(name = "settings_cache_cleared") -object SettingsCheckUpdate : AnalyticsEvent(name = "settings_check_update") - -object SettingsOpenMarket : AnalyticsEvent(name = "settings_open_market") - data class SdModelSelected(val value: String) : AnalyticsEvent( name = "settings_sd_model_selected", parameters = mapOf("model" to value), @@ -66,11 +62,6 @@ data class AutoSaveAiResultsChanged(val value: Boolean) : AnalyticsEvent( parameters = mapOf("enabled" to "$value"), ) -data class SaveToMediaStoreChanged(val value: Boolean) : AnalyticsEvent( - name = "settings_save_to_media_store_change", - parameters = mapOf("enabled" to "$value"), -) - data class FormAdvancedOptionsAlwaysShowChanged(val value: Boolean) : AnalyticsEvent( name = "settings_form_advanced_options_always_show_change", parameters = mapOf("enabled" to "$value"), diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailContract.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailContract.kt index 8f844f00..b8429db2 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailContract.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailContract.kt @@ -24,20 +24,17 @@ sealed interface GalleryDetailState : MviState { val tabs: List val selectedTab: Tab val screenDialog: Dialog - val bottomAdBanner: Boolean data class Loading( override val tabs: List = emptyList(), override val selectedTab: Tab = Tab.IMAGE, override val screenDialog: Dialog = Dialog.None, - override val bottomAdBanner: Boolean = false, ) : GalleryDetailState data class Content( override val tabs: List = emptyList(), override val selectedTab: Tab = Tab.IMAGE, override val screenDialog: Dialog = Dialog.None, - override val bottomAdBanner: Boolean = false, val generationType: AiGenerationResult.Type, val id: Long, val bitmap: Bitmap, @@ -67,11 +64,6 @@ sealed interface GalleryDetailState : MviState { is Loading -> copy(screenDialog = dialog) } - fun withBanner(enabled: Boolean) = when (this) { - is Content -> copy(bottomAdBanner = enabled) - is Loading -> copy(bottomAdBanner = enabled) - } - enum class Tab( @StringRes val label: Int, @DrawableRes val iconRes: Int, @@ -85,14 +77,14 @@ sealed interface GalleryDetailState : MviState { AiGenerationResult.Type.TEXT_TO_IMAGE -> listOf( IMAGE, INFO, ) - AiGenerationResult.Type.IMAGE_TO_IMAGE -> values().toList() + AiGenerationResult.Type.IMAGE_TO_IMAGE -> entries } } } sealed interface Dialog { - object None : Dialog - object DeleteConfirm : Dialog + data object None : Dialog + data object DeleteConfirm : Dialog } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailScreen.kt index 855af4f9..e4ccb679 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailScreen.kt @@ -4,13 +4,32 @@ package com.shifthackz.aisdv1.presentation.screen.gallery.detail import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.outlined.ArrowBack -import androidx.compose.material3.* +import androidx.compose.material3.Button +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -26,14 +45,13 @@ import com.shifthackz.aisdv1.core.model.asString import com.shifthackz.aisdv1.core.model.asUiText import com.shifthackz.aisdv1.core.ui.MviScreen import com.shifthackz.aisdv1.domain.entity.AiGenerationResult -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature import com.shifthackz.aisdv1.presentation.R -import com.shifthackz.aisdv1.presentation.widget.ad.AdBanner +import com.shifthackz.aisdv1.presentation.theme.colors import com.shifthackz.aisdv1.presentation.widget.dialog.DecisionInteractiveDialog import com.shifthackz.aisdv1.presentation.widget.image.ZoomableImage import com.shifthackz.aisdv1.presentation.widget.image.ZoomableImageSource +import com.shifthackz.catppuccin.palette.Catppuccin import org.koin.core.component.KoinComponent -import org.koin.core.component.inject import java.io.File class GalleryDetailScreen( @@ -44,14 +62,11 @@ class GalleryDetailScreen( private val copyToClipboard: (CharSequence) -> Unit = {}, ) : MviScreen(viewModel), KoinComponent { - private val adFeature: AdFeature by inject() - @Composable override fun Content() { ScreenContent( modifier = Modifier.fillMaxSize(), state = viewModel.state.collectAsStateWithLifecycle().value, - adFeature = adFeature, onNavigateBack = onNavigateBack, onTabSelected = viewModel::selectTab, onCopyTextClick = copyToClipboard, @@ -75,7 +90,6 @@ class GalleryDetailScreen( private fun ScreenContent( modifier: Modifier = Modifier, state: GalleryDetailState, - adFeature: AdFeature = AdFeature.empty, onNavigateBack: () -> Unit = {}, onTabSelected: (GalleryDetailState.Tab) -> Unit = {}, onCopyTextClick: (CharSequence) -> Unit = {}, @@ -139,7 +153,7 @@ private fun ScreenContent( is GalleryDetailState.Loading -> Unit } }, - bottomBar = { GalleryDetailNavigationBar(adFeature, state, onTabSelected) }, + bottomBar = { GalleryDetailNavigationBar(state, onTabSelected) }, ) when (state.screenDialog) { GalleryDetailState.Dialog.DeleteConfirm -> DecisionInteractiveDialog( @@ -157,25 +171,19 @@ private fun ScreenContent( @Composable private fun GalleryDetailNavigationBar( - adFeature: AdFeature, state: GalleryDetailState, onTabSelected: (GalleryDetailState.Tab) -> Unit, ) { Column { - if (state.bottomAdBanner) { - AdBanner( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - adFactory = adFeature::getGalleryDetailBannerAd, - ) - } NavigationBar { state.tabs.forEach { tab -> NavigationBarItem( selected = state.selectedTab == tab, label = { - Text(stringResource(id = tab.label)) + Text( + text = stringResource(id = tab.label), + color = LocalContentColor.current, + ) }, icon = { Image( @@ -249,10 +257,12 @@ private fun GalleryDetailsTable( .padding(16.dp) .padding(paddingValues), ) { - val colorOddBg = MaterialTheme.colorScheme.secondaryContainer - val colorOddText = MaterialTheme.colorScheme.onSecondaryContainer - val colorEvenBg = MaterialTheme.colorScheme.tertiaryContainer - val colorEvenText = MaterialTheme.colorScheme.onTertiaryContainer + val colorOddBg = MaterialTheme.colorScheme.surface + val colorOddText = colors( + light = Catppuccin.Latte.Text, + dark = Catppuccin.Frappe.Text + ) + val colorEvenBg = MaterialTheme.colorScheme.surfaceTint GalleryDetailRow( modifier = Modifier.background(color = colorOddBg), name = R.string.gallery_info_field_date.asUiText(), @@ -264,7 +274,7 @@ private fun GalleryDetailsTable( modifier = Modifier.background(color = colorEvenBg), name = R.string.gallery_info_field_type.asUiText(), value = state.type, - color = colorEvenText, + color = colorOddText, onCopyTextClick = onCopyTextClick, ) GalleryDetailRow( @@ -278,7 +288,7 @@ private fun GalleryDetailsTable( modifier = Modifier.background(color = colorEvenBg), name = R.string.gallery_info_field_negative_prompt.asUiText(), value = state.negativePrompt, - color = colorEvenText, + color = colorOddText, onCopyTextClick = onCopyTextClick, ) GalleryDetailRow( @@ -292,7 +302,7 @@ private fun GalleryDetailsTable( modifier = Modifier.background(color = colorEvenBg), name = R.string.gallery_info_field_sampling_steps.asUiText(), value = state.samplingSteps, - color = colorEvenText, + color = colorOddText, onCopyTextClick = onCopyTextClick, ) GalleryDetailRow( @@ -306,7 +316,7 @@ private fun GalleryDetailsTable( modifier = Modifier.background(color = colorEvenBg), name = R.string.gallery_info_field_restore_faces.asUiText(), value = state.restoreFaces, - color = colorEvenText, + color = colorOddText, onCopyTextClick = onCopyTextClick, ) GalleryDetailRow( @@ -320,7 +330,7 @@ private fun GalleryDetailsTable( modifier = Modifier.background(color = colorEvenBg), name = R.string.gallery_info_field_seed.asUiText(), value = state.seed, - color = colorEvenText, + color = colorOddText, onCopyTextClick = onCopyTextClick, ) GalleryDetailRow( @@ -334,7 +344,7 @@ private fun GalleryDetailsTable( modifier = Modifier.background(color = colorEvenBg), name = R.string.gallery_info_field_sub_seed_strength.asUiText(), value = state.subSeedStrength, - color = colorEvenText, + color = colorOddText, onCopyTextClick = onCopyTextClick, ) if (state.generationType == AiGenerationResult.Type.IMAGE_TO_IMAGE) GalleryDetailRow( @@ -362,6 +372,7 @@ private fun GalleryDetailsTable( Text( text = stringResource(id = R.string.action_send_to_txt2img), textAlign = TextAlign.Center, + color = LocalContentColor.current, ) } Spacer(modifier = Modifier.width(8.dp)) @@ -372,6 +383,7 @@ private fun GalleryDetailsTable( Text( text = stringResource(id = R.string.action_send_to_img2img), textAlign = TextAlign.Center, + color = LocalContentColor.current, ) } } @@ -383,6 +395,7 @@ private fun GalleryDetailsTable( Text( text = stringResource(id = R.string.action_share_prompt), textAlign = TextAlign.Center, + color = LocalContentColor.current, ) } Spacer(modifier = Modifier.width(8.dp)) @@ -393,6 +406,7 @@ private fun GalleryDetailsTable( Text( text = stringResource(id = R.string.action_delete_image), textAlign = TextAlign.Center, + color = LocalContentColor.current, ) } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailViewModel.kt index b296c659..4ffcea67 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/detail/GalleryDetailViewModel.kt @@ -7,10 +7,8 @@ import com.shifthackz.aisdv1.core.imageprocessing.Base64ToBitmapConverter import com.shifthackz.aisdv1.core.imageprocessing.Base64ToBitmapConverter.Input import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel import com.shifthackz.aisdv1.domain.entity.AiGenerationResult -import com.shifthackz.aisdv1.domain.entity.FeatureFlags import com.shifthackz.aisdv1.domain.feature.analytics.Analytics import com.shifthackz.aisdv1.domain.usecase.caching.GetLastResultFromCacheUseCase -import com.shifthackz.aisdv1.domain.usecase.features.GetFeatureFlagsUseCase import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemUseCase import com.shifthackz.aisdv1.domain.usecase.generation.GetGenerationResultUseCase import com.shifthackz.aisdv1.presentation.core.GenerationFormUpdateEvent @@ -20,7 +18,6 @@ import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.kotlin.subscribeBy class GalleryDetailViewModel( - getFeatureFlagsUseCase: GetFeatureFlagsUseCase, private val itemId: Long, private val getGenerationResultUseCase: GetGenerationResultUseCase, private val getLastResultFromCacheUseCase: GetLastResultFromCacheUseCase, @@ -35,18 +32,14 @@ class GalleryDetailViewModel( override val emptyState = GalleryDetailState.Loading() init { - !Single.zip( - getFeatureFlagsUseCase(), - getGenerationResult(itemId), - ::Pair, - ) + !getGenerationResult(itemId) + .subscribeOnMainThread(schedulersProvider) .postProcess() - .subscribeBy(::errorLog) { (ff, ai) -> + .subscribeBy(::errorLog) { ai -> ai .mapToUi() .withTab(currentState.selectedTab) - .withBanner(ff.adGalleryBottomEnable) .let(::setState) } } @@ -90,17 +83,16 @@ class GalleryDetailViewModel( .withDialog(dialog) .let(::setState) - private fun Single>.postProcess() = this - .flatMap { (ff, ai) -> - base64ToBitmapConverter(Input(ai.image)).map { bmp -> ff to (ai to bmp) } + private fun Single.postProcess() = this + .flatMap { ai -> + base64ToBitmapConverter(Input(ai.image)).map { bmp -> ai to bmp } } - .flatMap { (ff, data) -> - val (ai, bmp) = data + .flatMap { (ai, bmp) -> when (ai.type) { - AiGenerationResult.Type.TEXT_TO_IMAGE -> Single.just(ff to Triple(ai, bmp, null)) + AiGenerationResult.Type.TEXT_TO_IMAGE -> Single.just(Triple(ai, bmp, null)) AiGenerationResult.Type.IMAGE_TO_IMAGE -> base64ToBitmapConverter(Input(ai.inputImage)).map { bmp2 -> - ff to Triple(ai, bmp, bmp2) + Triple(ai, bmp, bmp2) } } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/list/GalleryScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/list/GalleryScreen.kt index bfb1cca4..3bca316f 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/list/GalleryScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/gallery/list/GalleryScreen.kt @@ -149,7 +149,7 @@ private fun ScreenContent( Row( modifier = Modifier .fillMaxWidth() - .background(MaterialTheme.colorScheme.tertiaryContainer) + .background(MaterialTheme.colorScheme.surfaceTint) ) { Text( modifier = Modifier @@ -159,7 +159,7 @@ private fun ScreenContent( id = R.string.gallery_media_store_banner, "${info.count}", ), - color = MaterialTheme.colorScheme.onTertiaryContainer, +// color = MaterialTheme.colorScheme.onTertiaryContainer, ) Spacer(modifier = Modifier.weight(1f)) TextButton( @@ -168,7 +168,10 @@ private fun ScreenContent( state.mediaStoreInfo.folderUri?.let(onOpenMediaStoreFolder::invoke) }, ) { - Text(text = stringResource(id = R.string.browse).toUpperCase(Locale.current)) + Text( + text = stringResource(id = R.string.browse).toUpperCase(Locale.current), + color = LocalContentColor.current, + ) } } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationContract.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationContract.kt index 8b0f8bd2..a5094b14 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationContract.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationContract.kt @@ -1,13 +1,8 @@ package com.shifthackz.aisdv1.presentation.screen.home -import com.shifthackz.aisdv1.core.ui.MviState import com.shifthackz.aisdv1.domain.entity.AiGenerationResult import com.shifthackz.aisdv1.presentation.utils.Constants -data class HomeNavigationState( - val bottomAdBanner: Boolean = false, -) : MviState - fun AiGenerationResult.Type.mapToRoute(): String = when (this) { AiGenerationResult.Type.TEXT_TO_IMAGE -> Constants.ROUTE_TXT_TO_IMG AiGenerationResult.Type.IMAGE_TO_IMAGE -> Constants.ROUTE_IMG_TO_IMG diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationGraph.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationGraph.kt index 52a42a2c..195d5692 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationGraph.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationGraph.kt @@ -29,10 +29,7 @@ fun NavGraphBuilder.homeScreenNavGraph( openGalleryItemDetails: (Long) -> Unit = {}, launchIntent: (Intent) -> Unit = {}, launchSetup: () -> Unit = {}, - launchUpdateCheck: () -> Unit = {}, - launchInAppReview: () -> Unit = {}, launchUrl: (String) -> Unit = {}, - launchRewarded: () -> Unit = {}, launchDebugMenu: () -> Unit = {}, shareLogFile: () -> Unit = {}, requestStoragePermissions: () -> Unit = {}, @@ -43,13 +40,11 @@ fun NavGraphBuilder.homeScreenNavGraph( viewModel = koinViewModel(), navItems = listOf( txt2ImgTab( - launchRewarded = launchRewarded, launchGalleryDetail = openGalleryItemDetails, ), img2imgTab( pickImage = pickImage, takePhoto = takePhoto, - launchRewarded = launchRewarded, launchGalleryDetail = openGalleryItemDetails, launchServerSetup = launchSetup, ), @@ -60,10 +55,7 @@ fun NavGraphBuilder.homeScreenNavGraph( ), settingsTab( launchSetup = launchSetup, - launchUpdateCheck = launchUpdateCheck, - launchInAppReview = launchInAppReview, launchUrl = launchUrl, - launchRewarded = launchRewarded, launchDebugMenu = launchDebugMenu, shareLogFile = shareLogFile, requestStoragePermissions = requestStoragePermissions, @@ -76,7 +68,6 @@ fun NavGraphBuilder.homeScreenNavGraph( @Composable private fun txt2ImgTab( - launchRewarded: () -> Unit, launchGalleryDetail: (Long) -> Unit, ) = HomeNavigationItem( name = stringResource(R.string.home_tab_txt_to_img), @@ -88,7 +79,6 @@ private fun txt2ImgTab( content = { TextToImageScreen( viewModel = koinViewModel(), - launchRewarded = launchRewarded, launchGalleryDetail = launchGalleryDetail, ).Build() }, @@ -98,7 +88,6 @@ private fun txt2ImgTab( private fun img2imgTab( pickImage: (ImagePickerCallback) -> Unit = {}, takePhoto: (ImagePickerCallback) -> Unit = {}, - launchRewarded: () -> Unit = {}, launchGalleryDetail: (Long) -> Unit, launchServerSetup: () -> Unit, ) = HomeNavigationItem( @@ -113,7 +102,6 @@ private fun img2imgTab( viewModel = koinViewModel(), pickImage = pickImage, takePhoto = takePhoto, - launchRewarded = launchRewarded, launchGalleryDetail = launchGalleryDetail, launchServerSetup = launchServerSetup, ).Build() @@ -145,10 +133,7 @@ private fun galleryTab( @Composable private fun settingsTab( launchSetup: () -> Unit = {}, - launchUpdateCheck: () -> Unit = {}, - launchInAppReview: () -> Unit = {}, launchUrl: (String) -> Unit = {}, - launchRewarded: () -> Unit = {}, launchDebugMenu: () -> Unit = {}, shareLogFile: () -> Unit = {}, requestStoragePermissions: () -> Unit = {}, @@ -162,10 +147,7 @@ private fun settingsTab( SettingsScreen( viewModel = koinViewModel(), launchSetup = launchSetup, - onCheckUpdatesItemClick = launchUpdateCheck, - launchInAppReview = launchInAppReview, launchUrl = launchUrl, - launchRewarded = launchRewarded, launchDebugMenu = launchDebugMenu, shareLogFile = shareLogFile, requestStoragePermissions = requestStoragePermissions, diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationScreen.kt index e2fc0a8a..17484139 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationScreen.kt @@ -3,9 +3,7 @@ package com.shifthackz.aisdv1.presentation.screen.home import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor import androidx.compose.material3.NavigationBar @@ -17,32 +15,23 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource -import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.ui.MviScreen -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature -import com.shifthackz.aisdv1.presentation.widget.ad.AdBanner +import com.shifthackz.aisdv1.core.ui.Screen import com.shifthackz.aisdv1.presentation.widget.connectivity.ConnectivityComposable -import com.shifthackz.aisdv1.presentation.widget.motd.MotdComposable import org.koin.androidx.compose.koinViewModel import org.koin.core.component.KoinComponent -import org.koin.core.component.inject class HomeNavigationScreen( private val viewModel: HomeNavigationViewModel, private val navItems: List = emptyList(), -) : MviScreen(viewModel), KoinComponent { - - private val adFeature: AdFeature by inject() +) : Screen(), KoinComponent { @Composable override fun Content() { require(navItems.isNotEmpty()) { "navItems collection must not be empty." } - val state = viewModel.state.collectAsStateWithLifecycle().value val navController = rememberNavController() val backStackEntry = navController.currentBackStackEntryAsState() @@ -61,14 +50,6 @@ class HomeNavigationScreen( Scaffold( bottomBar = { Column { - if (state.bottomAdBanner) { - AdBanner( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - adFactory = adFeature::getHomeScreenBannerAd, - ) - } NavigationBar { val currentRoute = backStackEntry.value?.destination?.route navItems.forEach { item -> @@ -76,7 +57,10 @@ class HomeNavigationScreen( NavigationBarItem( selected = selected, label = { - Text(text = item.name) + Text( + text = item.name, + color = LocalContentColor.current, + ) }, icon = { when (item.icon) { @@ -90,6 +74,7 @@ class HomeNavigationScreen( modifier = item.icon.modifier, imageVector = item.icon.vector, contentDescription = item.name, + tint = LocalContentColor.current, ) } }, @@ -105,7 +90,6 @@ class HomeNavigationScreen( content = { paddingValues -> Column(Modifier.padding(paddingValues)) { ConnectivityComposable(koinViewModel()).Build() - MotdComposable(koinViewModel()).Build() NavHost( modifier = Modifier.fillMaxSize(), navController = navController, diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationViewModel.kt index b0492e30..85639ab8 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/home/HomeNavigationViewModel.kt @@ -4,11 +4,9 @@ import androidx.lifecycle.viewModelScope import com.shifthackz.aisdv1.core.common.log.errorLog import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel +import com.shifthackz.aisdv1.core.viewmodel.RxViewModel import com.shifthackz.aisdv1.domain.entity.AiGenerationResult import com.shifthackz.aisdv1.domain.feature.analytics.Analytics -import com.shifthackz.aisdv1.domain.usecase.features.GetFeatureFlagsUseCase import com.shifthackz.aisdv1.presentation.core.GenerationFormUpdateEvent import com.shifthackz.aisdv1.presentation.features.HomeNavigationItemClick import io.reactivex.rxjava3.kotlin.subscribeBy @@ -19,24 +17,16 @@ import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch class HomeNavigationViewModel( - getFeatureFlagsUseCase: GetFeatureFlagsUseCase, generationFormUpdateEvent: GenerationFormUpdateEvent, schedulersProvider: SchedulersProvider, private val analytics: Analytics, -) : MviRxViewModel() { - - override val emptyState = HomeNavigationState() +) : RxViewModel() { private val routeEffectChannel: Channel = Channel() val routeEffectStream: Flow = routeEffectChannel.receiveAsFlow() init { - !getFeatureFlagsUseCase() - .subscribeOnMainThread(schedulersProvider) - .map { flags -> currentState.copy(bottomAdBanner = flags.adHomeBottomEnable) } - .subscribeBy(::errorLog, ::setState) - !generationFormUpdateEvent .observeRoute() .map(AiGenerationResult.Type::mapToRoute) diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageContract.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageContract.kt index a425c989..6967af22 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageContract.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageContract.kt @@ -47,11 +47,10 @@ data class ImageToImageState( } sealed interface Modal { - object None : Modal - object LoadingRandomImage : Modal + data object None : Modal + data object LoadingRandomImage : Modal data class Communicating(val hordeProcessStatus: HordeProcessStatus? = null) : Modal - object NoSdAiCoins : Modal - object PromptBottomSheet : Modal + data object PromptBottomSheet : Modal data class Image(val result: AiGenerationResult, val autoSaveEnabled: Boolean) : Modal data class Error(val error: UiText) : Modal } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageScreen.kt index 3fd2e555..7ce74a73 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageScreen.kt @@ -2,9 +2,23 @@ package com.shifthackz.aisdv1.presentation.screen.img2img -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArtTrack import androidx.compose.material.icons.filled.AutoFixNormal @@ -13,7 +27,17 @@ import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.DeviceUnknown import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Image -import androidx.compose.material3.* +import androidx.compose.material3.Button +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Slider +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -32,10 +56,8 @@ import com.shifthackz.aisdv1.presentation.R import com.shifthackz.aisdv1.presentation.modal.history.InputHistoryScreen import com.shifthackz.aisdv1.presentation.theme.sliderColors import com.shifthackz.aisdv1.presentation.utils.Constants -import com.shifthackz.aisdv1.presentation.widget.coins.AvailableCoinsComposable import com.shifthackz.aisdv1.presentation.widget.dialog.ErrorDialog import com.shifthackz.aisdv1.presentation.widget.dialog.GenerationImageResultDialog -import com.shifthackz.aisdv1.presentation.widget.dialog.NoSdAiCoinsDialog import com.shifthackz.aisdv1.presentation.widget.dialog.ProgressDialog import com.shifthackz.aisdv1.presentation.widget.input.GenerationInputForm import com.shifthackz.aisdv1.presentation.widget.input.GenerationInputMode @@ -46,7 +68,6 @@ class ImageToImageScreen( private val viewModel: ImageToImageViewModel, private val pickImage: (ImagePickerCallback) -> Unit, private val takePhoto: (ImagePickerCallback) -> Unit, - private val launchRewarded: () -> Unit, private val launchGalleryDetail: (Long) -> Unit, private val launchServerSetup: () -> Unit, ) : MviScreen(viewModel) { @@ -80,7 +101,6 @@ class ImageToImageScreen( onOpenPreviousGenerationInput = viewModel::openPreviousGenerationInput, onUpdateFromPreviousAiGeneration = viewModel::updateFormPreviousAiGeneration, onDismissScreenDialog = viewModel::dismissScreenDialog, - onLaunchRewarded = launchRewarded, ) } @@ -116,7 +136,6 @@ private fun ScreenContent( onOpenPreviousGenerationInput: () -> Unit = {}, onUpdateFromPreviousAiGeneration: (AiGenerationResult) -> Unit = {}, onDismissScreenDialog: () -> Unit = {}, - onLaunchRewarded: () -> Unit = {}, ) { Box(modifier) { Scaffold( @@ -150,7 +169,7 @@ private fun ScreenContent( .padding(horizontal = 16.dp), ) { InputImageState( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth().padding(top = 16.dp), imageState = state.imageState, onPickImage = onPickImage, onTakePhoto = onTakePhoto, @@ -226,10 +245,6 @@ private fun ScreenContent( bottomBar = { if (state.mode != GenerationInputMode.LOCAL) { Column(Modifier.fillMaxWidth()) { - AvailableCoinsComposable( - modifier = Modifier.fillMaxWidth(), - viewModel = koinViewModel() - ).Build() Button( modifier = Modifier .fillMaxWidth() @@ -259,7 +274,8 @@ private fun ScreenContent( ) { Text( modifier = Modifier.padding(start = 8.dp), - text = stringResource(id = R.string.action_change_configuration) + text = stringResource(id = R.string.action_change_configuration), + color = LocalContentColor.current, ) } } @@ -275,10 +291,6 @@ private fun ScreenContent( titleResId = R.string.communicating_random_image_title, canDismiss = false, ) - ImageToImageState.Modal.NoSdAiCoins -> NoSdAiCoinsDialog( - onDismissRequest = onDismissScreenDialog, - launchRewarded = onLaunchRewarded, - ) is ImageToImageState.Modal.Error -> ErrorDialog( text = state.screenModal.error, onDismissRequest = onDismissScreenDialog, @@ -369,7 +381,7 @@ private fun InputImageState( .padding(top = 8.dp) .fillMaxWidth() .background( - MaterialTheme.colorScheme.secondaryContainer, + MaterialTheme.colorScheme.surfaceTint, shape = RoundedCornerShape(16.dp) ) .clickable { onRandomPhoto() }, @@ -382,13 +394,11 @@ private fun InputImageState( .padding(8.dp), imageVector = Icons.Default.ArtTrack, contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondaryContainer, ) Text( modifier = Modifier.padding(start = 8.dp), text = stringResource(id = R.string.action_image_picker_random), fontSize = 17.sp, - color = MaterialTheme.colorScheme.onSecondaryContainer, ) } } @@ -404,7 +414,7 @@ private fun ImagePickButtonBox( Column( modifier = modifier .background( - MaterialTheme.colorScheme.secondaryContainer, + MaterialTheme.colorScheme.surfaceTint, shape = RoundedCornerShape(16.dp) ) .clickable { onClick() }, @@ -420,7 +430,6 @@ private fun ImagePickButtonBox( ImagePickButton.CAMERA -> Icons.Default.Camera }, contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondaryContainer, ) Text( modifier = Modifier.padding(top = 8.dp, bottom = 16.dp), @@ -431,7 +440,6 @@ private fun ImagePickButtonBox( } ), fontSize = 17.sp, - color = MaterialTheme.colorScheme.onSecondaryContainer, ) } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageViewModel.kt index b032d51e..5fcacdc5 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageViewModel.kt @@ -1,6 +1,5 @@ package com.shifthackz.aisdv1.presentation.screen.img2img -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider import com.shifthackz.aisdv1.core.common.log.errorLog import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread @@ -14,7 +13,6 @@ import com.shifthackz.aisdv1.domain.entity.HordeProcessStatus import com.shifthackz.aisdv1.domain.feature.analytics.Analytics import com.shifthackz.aisdv1.domain.preference.PreferenceManager import com.shifthackz.aisdv1.domain.usecase.caching.SaveLastResultToCacheUseCase -import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase import com.shifthackz.aisdv1.domain.usecase.generation.GetRandomImageUseCase import com.shifthackz.aisdv1.domain.usecase.generation.ImageToImageUseCase import com.shifthackz.aisdv1.domain.usecase.generation.ObserveHordeProcessStatusUseCase @@ -33,8 +31,6 @@ import io.reactivex.rxjava3.kotlin.subscribeBy class ImageToImageViewModel( getStableDiffusionSamplersUseCase: GetStableDiffusionSamplersUseCase, observeHordeProcessStatusUseCase: ObserveHordeProcessStatusUseCase, - observeCoinsUseCase: ObserveCoinsUseCase, - buildInfoProvider: BuildInfoProvider, generationFormUpdateEvent: GenerationFormUpdateEvent, private val imageToImageUseCase: ImageToImageUseCase, private val saveLastResultToCacheUseCase: SaveLastResultToCacheUseCase, @@ -49,9 +45,7 @@ class ImageToImageViewModel( private val analytics: Analytics, ) : GenerationMviViewModel( schedulersProvider, - buildInfoProvider, preferenceManager, - observeCoinsUseCase, getStableDiffusionSamplersUseCase, observeHordeProcessStatusUseCase, ) { @@ -116,10 +110,10 @@ class ImageToImageViewModel( fun generate() { when (currentState.imageState) { is ImageToImageState.ImageState.Image -> { - if (!currentState.generateButtonEnabled) { - setActiveDialog(ImageToImageState.Modal.NoSdAiCoins) - return - } +// if (!currentState.generateButtonEnabled) { +// setActiveDialog(ImageToImageState.Modal.NoSdAiCoins) +// return +// } !Single .just((currentState.imageState as ImageToImageState.ImageState.Image).bitmap) .doOnSubscribe { setActiveDialog(ImageToImageState.Modal.Communicating()) } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/loader/ConfigurationLoaderViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/loader/ConfigurationLoaderViewModel.kt index f9ce64b8..5df7b256 100755 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/loader/ConfigurationLoaderViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/loader/ConfigurationLoaderViewModel.kt @@ -7,14 +7,12 @@ import com.shifthackz.aisdv1.core.model.asUiText import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel import com.shifthackz.aisdv1.domain.feature.analytics.Analytics import com.shifthackz.aisdv1.domain.usecase.caching.DataPreLoaderUseCase -import com.shifthackz.aisdv1.domain.usecase.features.GetFeatureFlagsUseCase import com.shifthackz.aisdv1.presentation.R import com.shifthackz.aisdv1.presentation.features.ConfigurationLoadFailure import com.shifthackz.aisdv1.presentation.features.ConfigurationLoadSuccess import io.reactivex.rxjava3.kotlin.subscribeBy class ConfigurationLoaderViewModel( - getFeatureFlagsUseCase: GetFeatureFlagsUseCase, dataPreLoaderUseCase: DataPreLoaderUseCase, schedulersProvider: SchedulersProvider, analytics: Analytics, @@ -25,9 +23,7 @@ class ConfigurationLoaderViewModel( ) init { - getFeatureFlagsUseCase() - .ignoreElement() - .andThen(dataPreLoaderUseCase()) + dataPreLoaderUseCase() .doOnSubscribe { setState( ConfigurationLoaderState.StatusNotification( diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsContract.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsContract.kt index 8990841f..03df850c 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsContract.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsContract.kt @@ -4,22 +4,19 @@ import com.shifthackz.aisdv1.core.ui.MviEffect import com.shifthackz.aisdv1.core.ui.MviState sealed interface SettingsEffect : MviEffect { - object RequestStoragePermission : SettingsEffect + data object RequestStoragePermission : SettingsEffect } sealed interface SettingsState : MviState { val screenDialog: Dialog - val bottomSheet: Sheet - object Uninitialized : SettingsState { + data object Uninitialized : SettingsState { override val screenDialog = Dialog.None - override val bottomSheet = Sheet.None } data class Content( override val screenDialog: Dialog = Dialog.None, - override val bottomSheet: Sheet = Sheet.None, val sdModels: List, val sdModelSelected: String, val localUseNNAPI: Boolean, @@ -29,12 +26,8 @@ sealed interface SettingsState : MviState { val formAdvancedOptionsAlwaysShow: Boolean, val appVersion: String, val showLocalUseNNAPI: Boolean, - val showCheckForUpdates: Boolean, - val showRewardedSdAiAd: Boolean, val showSdModelSelector: Boolean, val showMonitorConnectionOption: Boolean, - val showRateGooglePlay: Boolean, - val showGitHubLink: Boolean, ) : SettingsState fun withDialog(value: Dialog): SettingsState = when (this) { @@ -42,20 +35,10 @@ sealed interface SettingsState : MviState { else -> this } - fun withSheet(value: Sheet): SettingsState = when (this) { - is Content -> copy(bottomSheet = value) - else -> this - } - sealed interface Dialog { - object None : Dialog - object Communicating : Dialog - object ClearAppCache : Dialog + data object None : Dialog + data object Communicating : Dialog + data object ClearAppCache : Dialog data class SelectSdModel(val models: List, val selected: String) : Dialog } - - sealed interface Sheet { - object None : Sheet - object SelectLanguage : Sheet - } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsScreen.kt index d7393ea5..c0460b3d 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsScreen.kt @@ -4,13 +4,37 @@ package com.shifthackz.aisdv1.presentation.screen.settings import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material.icons.filled.AccountTree +import androidx.compose.material.icons.filled.AutoFixNormal +import androidx.compose.material.icons.filled.Code +import androidx.compose.material.icons.filled.DeleteForever +import androidx.compose.material.icons.filled.DynamicForm +import androidx.compose.material.icons.filled.Folder +import androidx.compose.material.icons.filled.Gavel +import androidx.compose.material.icons.filled.Help +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.Report +import androidx.compose.material.icons.filled.Save +import androidx.compose.material.icons.filled.SettingsEthernet +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign @@ -32,10 +56,7 @@ import org.koin.core.component.inject class SettingsScreen( private val viewModel: SettingsViewModel, private val launchSetup: () -> Unit = {}, - private val onCheckUpdatesItemClick: () -> Unit = {}, - private val launchInAppReview: () -> Unit = {}, private val launchUrl: (String) -> Unit = {}, - private val launchRewarded: () -> Unit = {}, private val launchDebugMenu: () -> Unit = {}, private val shareLogFile: () -> Unit = {}, private val requestStoragePermissions: () -> Unit, @@ -50,7 +71,6 @@ class SettingsScreen( state = viewModel.state.collectAsStateWithLifecycle().value, onConfigurationItemClick = launchSetup, onSdModelItemClick = viewModel::launchSdModelSelectionDialog, - onLaunchRewarded = launchRewarded, onLocalUseNNAPIChanged = viewModel::changeLocalUseNNAPISetting, onMonitorConnectivityChanged = viewModel::changeMonitorConnectivitySetting, onAutoSaveAiResultChanged = viewModel::changeAutoSaveAiResultSetting, @@ -58,8 +78,6 @@ class SettingsScreen( onFormAdvancedOptionsAlwaysShowChanged = viewModel::changeFormAdvancedOptionsAlwaysShow, onClearAppCacheItemClick = viewModel::launchClearAppCacheDialog, onReportProblemItemClick = shareLogFile, - onCheckUpdatesItemClick = onCheckUpdatesItemClick, - onRateUsItemClick = launchInAppReview, onPolicyItemClick = { launchUrl(linksProvider.privacyPolicyUrl) }, onServerInstructionsItemClick = { launchUrl(linksProvider.setupInstructionsUrl) }, onGetSourceItemClick = { launchUrl(linksProvider.gitHubSourceUrl) }, @@ -67,7 +85,6 @@ class SettingsScreen( onSdModelSelected = viewModel::selectStableDiffusionModel, onClearAppCacheConfirm = viewModel::clearAppCache, onDismissScreenDialog = viewModel::dismissScreenDialog, - onDismissBottomSheet = viewModel::dismissBottomSheet, ) } @@ -85,7 +102,6 @@ private fun ScreenContent( state: SettingsState, onConfigurationItemClick: () -> Unit = {}, onSdModelItemClick: () -> Unit = {}, - onLaunchRewarded: () -> Unit = {}, onLocalUseNNAPIChanged: (Boolean) -> Unit = {}, onMonitorConnectivityChanged: (Boolean) -> Unit = {}, onAutoSaveAiResultChanged: (Boolean) -> Unit = {}, @@ -94,8 +110,6 @@ private fun ScreenContent( onClearAppCacheItemClick: () -> Unit = {}, onReportProblemItemClick: () -> Unit = {}, - onCheckUpdatesItemClick: () -> Unit = {}, - onRateUsItemClick: () -> Unit = {}, onPolicyItemClick: () -> Unit = {}, onServerInstructionsItemClick: () -> Unit = {}, onGetSourceItemClick: () -> Unit = {}, @@ -128,7 +142,6 @@ private fun ScreenContent( state = state, onConfigurationItemClick = onConfigurationItemClick, onSdModelItemClick = onSdModelItemClick, - onLaunchRewarded = onLaunchRewarded, onLocalUseNNAPIChanged = onLocalUseNNAPIChanged, onMonitorConnectivityChanged = onMonitorConnectivityChanged, onAutoSaveAiResultChanged = onAutoSaveAiResultChanged, @@ -136,8 +149,6 @@ private fun ScreenContent( onFormAdvancedOptionsAlwaysShowChanged = onFormAdvancedOptionsAlwaysShowChanged, onClearAppCacheItemClick = onClearAppCacheItemClick, onReportProblemItemClick = onReportProblemItemClick, - onCheckUpdatesItemClick = onCheckUpdatesItemClick, - onRateUsItemClick = onRateUsItemClick, onPolicyItemClick = onPolicyItemClick, onServerInstructionsItemClick = onServerInstructionsItemClick, onGetSourceItemClick = onGetSourceItemClick, @@ -183,14 +194,6 @@ private fun ScreenContent( onConfirmAction = onClearAppCacheConfirm, ) } - when (state.bottomSheet) { - SettingsState.Sheet.None -> Unit - SettingsState.Sheet.SelectLanguage -> ModalBottomSheet( - onDismissRequest = onDismissBottomSheet, - ) { - - } - } } } @@ -200,7 +203,6 @@ private fun ContentSettingsState( state: SettingsState.Content, onConfigurationItemClick: () -> Unit = {}, onSdModelItemClick: () -> Unit = {}, - onLaunchRewarded: () -> Unit = {}, onLocalUseNNAPIChanged: (Boolean) -> Unit = {}, onAutoSaveAiResultChanged: (Boolean) -> Unit = {}, onSaveToMediaStoreChanged: (Boolean) -> Unit = {}, @@ -208,8 +210,6 @@ private fun ContentSettingsState( onMonitorConnectivityChanged: (Boolean) -> Unit = {}, onClearAppCacheItemClick: () -> Unit = {}, onReportProblemItemClick: () -> Unit = {}, - onCheckUpdatesItemClick: () -> Unit = {}, - onRateUsItemClick: () -> Unit = {}, onPolicyItemClick: () -> Unit = {}, onServerInstructionsItemClick: () -> Unit = {}, onGetSourceItemClick: () -> Unit = {}, @@ -241,13 +241,6 @@ private fun ContentSettingsState( endValueText = state.sdModelSelected.asUiText(), onClick = onSdModelItemClick, ) - if (state.showRewardedSdAiAd) SettingsItem( - modifier = itemModifier, - startIcon = Icons.Default.Toll, - text = R.string.settings_item_rewarded.asUiText(), - animateBackground = true, - onClick = onLaunchRewarded, - ) if (state.showLocalUseNNAPI) { SettingsItem( modifier = itemModifier, @@ -346,18 +339,6 @@ private fun ContentSettingsState( text = R.string.settings_item_report_problem.asUiText(), onClick = onReportProblemItemClick, ) - if (state.showCheckForUpdates) SettingsItem( - modifier = itemModifier, - startIcon = Icons.Filled.GetApp, - text = R.string.settings_item_check_updates.asUiText(), - onClick = onCheckUpdatesItemClick, - ) - if (state.showRateGooglePlay) SettingsItem( - modifier = itemModifier, - startIcon = Icons.Filled.Star, - text = R.string.settings_item_rate.asUiText(), - onClick = onRateUsItemClick, - ) SettingsItem( modifier = itemModifier, startIcon = Icons.Default.Gavel, @@ -370,7 +351,7 @@ private fun ContentSettingsState( text = R.string.settings_item_instructions.asUiText(), onClick = onServerInstructionsItemClick, ) - if (state.showGitHubLink) SettingsItem( + SettingsItem( modifier = itemModifier, startIcon = Icons.Default.Code, text = R.string.settings_item_source.asUiText(), @@ -380,20 +361,13 @@ private fun ContentSettingsState( Text( modifier = Modifier .fillMaxWidth() - .padding(top = 16.dp), - text = stringResource(id = R.string.version, state.appVersion), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center, - ) - Text( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp) + .padding(vertical = 16.dp) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null, - ) { onAppVersionClick() }, - text = stringResource(id = R.string.version_postscriptum), + onClick = onAppVersionClick, + ), + text = stringResource(id = R.string.version, state.appVersion), style = MaterialTheme.typography.labelMedium, textAlign = TextAlign.Center, ) @@ -410,16 +384,12 @@ private fun PreviewStateContent() { sdModelSelected = "Stable diffusion v1.5", appVersion = "1.0.0 (10)", localUseNNAPI = false, - showRewardedSdAiAd = true, monitorConnectivity = true, autoSaveAiResults = true, saveToMediaStore = true, formAdvancedOptionsAlwaysShow = false, - showCheckForUpdates = true, showSdModelSelector = true, showMonitorConnectionOption = true, - showRateGooglePlay = true, - showGitHubLink = true, showLocalUseNNAPI = true, ) ) diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsStateProducer.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsStateProducer.kt index df35ea8f..46e91838 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsStateProducer.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsStateProducer.kt @@ -1,7 +1,6 @@ package com.shifthackz.aisdv1.presentation.screen.settings import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider -import com.shifthackz.aisdv1.core.common.appbuild.BuildType import com.shifthackz.aisdv1.domain.entity.ServerSource import com.shifthackz.aisdv1.domain.preference.PreferenceManager import com.shifthackz.aisdv1.domain.usecase.sdmodel.GetStableDiffusionModelsUseCase @@ -34,12 +33,8 @@ class SettingsStateProducer( formAdvancedOptionsAlwaysShow = settings.formAdvancedOptionsAlwaysShow, appVersion = version, showLocalUseNNAPI = settings.source == ServerSource.LOCAL, - showCheckForUpdates = buildInfoProvider.buildType == BuildType.GOOGLE_PLAY, - showRewardedSdAiAd = settings.useSdAiCloud, showSdModelSelector = settings.source == ServerSource.CUSTOM, showMonitorConnectionOption = settings.source == ServerSource.CUSTOM, - showRateGooglePlay = buildInfoProvider.buildType == BuildType.GOOGLE_PLAY, - showGitHubLink = buildInfoProvider.buildType == BuildType.FOSS, ) } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsViewModel.kt index 9c394638..d7105a10 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsViewModel.kt @@ -45,12 +45,6 @@ class SettingsViewModel( fun dismissScreenDialog() = setActiveDialog(SettingsState.Dialog.None) //endregion - //region BOTTOM SHEET LAUNCHER METHODS - fun launchLanguageBottomSheet() = setActiveSheet(SettingsState.Sheet.SelectLanguage) - - fun dismissBottomSheet() = setActiveSheet(SettingsState.Sheet.None) - //endregion - //region BUSINESS LOGIC METHODS fun selectStableDiffusionModel(value: String) = !selectStableDiffusionModelUseCase(value) .andThen(settingsStateProducer()) @@ -117,9 +111,5 @@ class SettingsViewModel( private fun setActiveDialog(dialog: SettingsState.Dialog) = currentState .withDialog(value = dialog) .let(::setState) - - private fun setActiveSheet(sheet: SettingsState.Sheet) = currentState - .withSheet(value = sheet) - .let(::setState) //endregion } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupContract.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupContract.kt index 248502f0..e131d7eb 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupContract.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupContract.kt @@ -1,6 +1,5 @@ package com.shifthackz.aisdv1.presentation.screen.setup -import com.shifthackz.aisdv1.core.common.appbuild.BuildType import com.shifthackz.aisdv1.core.model.UiText import com.shifthackz.aisdv1.core.ui.MviEffect import com.shifthackz.aisdv1.core.ui.MviState @@ -11,13 +10,13 @@ import com.shifthackz.aisdv1.domain.feature.auth.AuthorizationCredentials import com.shifthackz.aisdv1.presentation.utils.Constants sealed interface ServerSetupEffect : MviEffect { - object CompleteSetup : ServerSetupEffect + data object CompleteSetup : ServerSetupEffect } data class ServerSetupState( val showBackNavArrow: Boolean = false, val mode: Mode = Mode.OWN_SERVER, - val allowedModes: List = listOf(Mode.OWN_SERVER), + val allowedModes: List = Mode.entries, val originalMode: Mode = Mode.OWN_SERVER, val screenDialog: Dialog = Dialog.None, val serverUrl: String = "", @@ -79,19 +78,17 @@ data class ServerSetupState( } sealed interface Dialog { - object None : Dialog - object Communicating : Dialog + data object None : Dialog + data object Communicating : Dialog data class Error(val error: UiText) : Dialog } enum class Mode { OWN_SERVER, - SD_AI_CLOUD, HORDE, LOCAL; fun toSource() = when (this) { - SD_AI_CLOUD -> ServerSource.SDAI OWN_SERVER -> ServerSource.CUSTOM HORDE -> ServerSource.HORDE LOCAL -> ServerSource.LOCAL @@ -100,7 +97,6 @@ data class ServerSetupState( companion object { fun fromSource(source: ServerSource) = when (source) { ServerSource.CUSTOM -> OWN_SERVER - ServerSource.SDAI -> SD_AI_CLOUD ServerSource.HORDE -> HORDE ServerSource.LOCAL -> LOCAL } @@ -118,21 +114,10 @@ enum class ServerSetupLaunchSource(val key: Int) { SETTINGS(1); companion object { - fun fromKey(key: Int) = values().firstOrNull { it.key == key } ?: SPLASH + fun fromKey(key: Int) = entries.firstOrNull { it.key == key } ?: SPLASH } } - -val BuildType.allowedModes: List - get() = when (this) { - BuildType.FOSS -> listOf( - ServerSetupState.Mode.OWN_SERVER, - ServerSetupState.Mode.HORDE, - ServerSetupState.Mode.LOCAL, - ) - BuildType.GOOGLE_PLAY -> ServerSetupState.Mode.values().toList() - } - val Configuration.authType: ServerSetupState.AuthType get() { val noCredentials = ServerSetupState.AuthType.ANONYMOUS diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupScreen.kt index e9525785..044d3f66 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupScreen.kt @@ -2,22 +2,55 @@ package com.shifthackz.aisdv1.presentation.screen.setup -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* +import androidx.compose.material.icons.filled.Android +import androidx.compose.material.icons.filled.Api +import androidx.compose.material.icons.filled.Cloud +import androidx.compose.material.icons.filled.Computer +import androidx.compose.material.icons.filled.DeveloperMode +import androidx.compose.material.icons.filled.Help +import androidx.compose.material.icons.filled.Visibility +import androidx.compose.material.icons.filled.VisibilityOff import androidx.compose.material.icons.outlined.ArrowBack -import androidx.compose.material.icons.outlined.Cancel import androidx.compose.material.icons.outlined.FileDownload import androidx.compose.material.icons.outlined.FileDownloadDone import androidx.compose.material.icons.outlined.FileDownloadOff -import androidx.compose.material3.* +import androidx.compose.material3.Button +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.Checkbox +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType @@ -143,7 +176,8 @@ private fun ScreenContent( text = stringResource(id = when (state.mode) { ServerSetupState.Mode.LOCAL -> R.string.action_setup else -> R.string.action_connect - }) + }), + color = LocalContentColor.current, ) } }, @@ -153,6 +187,7 @@ private fun ScreenContent( .verticalScroll(rememberScrollState()) .padding(paddingValues), ) { + Spacer(modifier = Modifier.height(12.dp)) if (state.allowedModes.size > 1) { Column { state.allowedModes.forEach { mode -> @@ -168,7 +203,6 @@ private fun ScreenContent( } } when (state.mode) { - ServerSetupState.Mode.SD_AI_CLOUD -> SdaiCloudSetupTab() ServerSetupState.Mode.OWN_SERVER -> OwnServerSetupTab( state = state, demoModeUrl = demoModeUrl, @@ -246,7 +280,7 @@ private fun OwnServerSetupTab( isError = state.serverUrlValidationError != null && !state.demoMode, supportingText = state.serverUrlValidationError ?.takeIf { !state.demoMode } - ?.let { { Text(it.asString()) } }, + ?.let { { Text(it.asString(), color = MaterialTheme.colorScheme.error) } }, ) if (!state.demoMode) { DropdownTextField( @@ -272,7 +306,7 @@ private fun OwnServerSetupTab( label = { Text(stringResource(id = R.string.hint_login)) }, isError = state.loginValidationError != null, supportingText = state.loginValidationError?.let { - { Text(it.asString()) } + { Text(it.asString(), color = MaterialTheme.colorScheme.error) } }, ) TextField( @@ -285,7 +319,7 @@ private fun OwnServerSetupTab( visualTransformation = if (state.passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), supportingText = state.passwordValidationError?.let { - { Text(it.asString()) } + { Text(it.asString(), color = MaterialTheme.colorScheme.error) } }, trailingIcon = { val image = if (state.passwordVisible) Icons.Filled.Visibility @@ -328,7 +362,6 @@ private fun OwnServerSetupTab( modifier = Modifier.padding(top = 8.dp), text = stringResource(id = R.string.hint_args_warning), style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, ) Text( modifier = Modifier.padding(top = 8.dp, bottom = 16.dp), @@ -337,32 +370,6 @@ private fun OwnServerSetupTab( else R.string.hint_valid_urls, ), style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, - ) - } -} - -@Composable -private fun SdaiCloudSetupTab( - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier.padding(horizontal = 16.dp), - ) { - Text( - modifier = Modifier - .fillMaxWidth() - .padding(top = 32.dp, bottom = 8.dp), - text = stringResource(id = R.string.hint_server_sdai_title), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - fontWeight = FontWeight.Bold, - ) - Text( - modifier = Modifier.padding(vertical = 16.dp), - text = stringResource(id = R.string.hint_server_sdai_sub_title), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, ) } } @@ -392,7 +399,6 @@ private fun HordeAiSetupTab( modifier = Modifier.padding(top = 16.dp), text = stringResource(id = R.string.hint_server_horde_sub_title), style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, ) TextField( modifier = Modifier @@ -406,7 +412,7 @@ private fun HordeAiSetupTab( supportingText = { state.hordeApiKeyValidationError ?.takeIf { !state.hordeDefaultApiKey } - ?.let { Text(it.asString()) } + ?.let { Text(it.asString(), color = MaterialTheme.colorScheme.error) } }, ) Row( @@ -439,7 +445,6 @@ private fun HordeAiSetupTab( modifier = Modifier.padding(bottom = 16.dp, top = 8.dp), text = stringResource(id = R.string.hint_server_horde_usage), style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, ) } } @@ -466,14 +471,13 @@ private fun LocalDiffusionSetupTab( modifier = Modifier.padding(top = 16.dp), text = stringResource(id = R.string.hint_local_diffusion_sub_title), style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, ) Column( modifier = modifier .padding(top = 24.dp) .fillMaxWidth() .clip(RoundedCornerShape(16.dp)) - .background(color = MaterialTheme.colorScheme.primaryContainer) + .background(color = MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.8f)) .defaultMinSize(minHeight = 50.dp), ) { Row( @@ -518,6 +522,7 @@ private fun LocalDiffusionSetupTab( else R.string.download } }), + color = LocalContentColor.current, ) } } @@ -536,7 +541,6 @@ private fun LocalDiffusionSetupTab( .padding(horizontal = 8.dp) .padding(bottom = 8.dp), text = stringResource(id = R.string.error_download_fail), - color = MaterialTheme.colorScheme.error, ) } else -> Unit @@ -546,7 +550,6 @@ private fun LocalDiffusionSetupTab( modifier = Modifier.padding(top = 16.dp), text = stringResource(id = R.string.hint_local_diffusion_warning), style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.secondary, ) } } @@ -561,14 +564,14 @@ private fun ConfigurationModeButton( Row( modifier = modifier .background( - MaterialTheme.colorScheme.secondaryContainer, + color = MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.8f), shape = RoundedCornerShape(16.dp), ) .border( width = 2.dp, shape = RoundedCornerShape(16.dp), - color = if (state.mode == mode) MaterialTheme.colorScheme.secondary - else MaterialTheme.colorScheme.secondaryContainer, + color = if (state.mode == mode) MaterialTheme.colorScheme.primary + else Color.Transparent, ) .clickable { onClick(mode) }, ) { @@ -577,26 +580,24 @@ private fun ConfigurationModeButton( .size(42.dp) .padding(top = 8.dp, bottom = 8.dp), imageVector = when (mode) { - ServerSetupState.Mode.SD_AI_CLOUD -> Icons.Default.Cloud ServerSetupState.Mode.OWN_SERVER -> Icons.Default.Computer ServerSetupState.Mode.HORDE -> Icons.Default.Cloud ServerSetupState.Mode.LOCAL -> Icons.Default.Android }, contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondaryContainer, +// tint = MaterialTheme.colorScheme.onSecondaryContainer, ) Text( modifier = Modifier .align(Alignment.CenterVertically) .padding(top = 8.dp, bottom = 8.dp), text = stringResource(id = when (mode) { - ServerSetupState.Mode.SD_AI_CLOUD -> R.string.srv_type_cloud ServerSetupState.Mode.OWN_SERVER -> R.string.srv_type_own ServerSetupState.Mode.HORDE -> R.string.srv_type_horde ServerSetupState.Mode.LOCAL -> R.string.srv_type_local }), fontSize = 14.sp, - color = MaterialTheme.colorScheme.onSecondaryContainer, +// color = MaterialTheme.colorScheme.onSecondaryContainer, textAlign = TextAlign.Center, lineHeight = 15.sp, ) diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupViewModel.kt index 7c719f56..f042846d 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/setup/ServerSetupViewModel.kt @@ -1,6 +1,5 @@ package com.shifthackz.aisdv1.presentation.screen.setup -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider import com.shifthackz.aisdv1.core.common.log.debugLog import com.shifthackz.aisdv1.core.common.log.errorLog import com.shifthackz.aisdv1.core.common.reactive.retryWithDelay @@ -39,7 +38,6 @@ class ServerSetupViewModel( launchSource: ServerSetupLaunchSource, getConfigurationUseCase: GetConfigurationUseCase, private val demoModeUrl: String, - private val cloudUrl: String, private val urlValidator: UrlValidator, private val stringValidator: CommonStringValidator, private val testConnectivityUseCase: TestConnectivityUseCase, @@ -50,7 +48,6 @@ class ServerSetupViewModel( private val checkDownloadedModelUseCase: CheckDownloadedModelUseCase, private val dataPreLoaderUseCase: DataPreLoaderUseCase, private val schedulersProvider: SchedulersProvider, - private val buildInfoProvider: BuildInfoProvider, private val preferenceManager: PreferenceManager, private val analytics: Analytics, ) : MviRxViewModel() { @@ -67,7 +64,6 @@ class ServerSetupViewModel( .subscribeOnMainThread(schedulersProvider) .subscribeBy(::errorLog) { (configuration, isDownloaded) -> currentState - .copy(allowedModes = buildInfoProvider.buildType.allowedModes) .copy(localModelDownloaded = isDownloaded) .withSource(configuration.source) .withDemoMode(configuration.demoMode) @@ -157,15 +153,11 @@ class ServerSetupViewModel( } } ServerSetupState.Mode.LOCAL -> currentState.localModelDownloaded - else -> true } private fun connectToAutomaticInstance() { val demoMode = currentState.demoMode - val connectUrl = when (currentState.mode) { - ServerSetupState.Mode.SD_AI_CLOUD -> cloudUrl - else -> if (demoMode) demoModeUrl else currentState.serverUrl - } + val connectUrl = if (demoMode) demoModeUrl else currentState.serverUrl val credentials = when (currentState.mode) { ServerSetupState.Mode.OWN_SERVER -> { if (!demoMode) currentState.credentialsDomain() diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageContract.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageContract.kt index 90b44a85..dadab988 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageContract.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageContract.kt @@ -35,14 +35,13 @@ data class TextToImageState( ) : GenerationMviState() { sealed interface Modal { - object None : Modal + data object None : Modal data class Generating(val status: LocalDiffusion.Status? = null) : Modal { val pair: Pair? get() = status?.let { (current, total) -> current to total } } data class Communicating(val hordeProcessStatus: HordeProcessStatus? = null) : Modal - object NoSdAiCoins : Modal - object PromptBottomSheet : Modal + data object PromptBottomSheet : Modal data class Image(val result: AiGenerationResult, val autoSaveEnabled: Boolean) : Modal data class Error(val error: UiText) : Modal } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageScreen.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageScreen.kt index de8844cb..83edb643 100755 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageScreen.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageScreen.kt @@ -2,14 +2,28 @@ package com.shifthackz.aisdv1.presentation.screen.txt2img -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AutoFixNormal import androidx.compose.material.icons.filled.Edit -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.Button +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.res.stringResource @@ -21,17 +35,14 @@ import com.shifthackz.aisdv1.core.ui.MviScreen import com.shifthackz.aisdv1.domain.entity.AiGenerationResult import com.shifthackz.aisdv1.presentation.R import com.shifthackz.aisdv1.presentation.modal.history.InputHistoryScreen -import com.shifthackz.aisdv1.presentation.widget.coins.AvailableCoinsComposable import com.shifthackz.aisdv1.presentation.widget.dialog.ErrorDialog import com.shifthackz.aisdv1.presentation.widget.dialog.GenerationImageResultDialog -import com.shifthackz.aisdv1.presentation.widget.dialog.NoSdAiCoinsDialog import com.shifthackz.aisdv1.presentation.widget.dialog.ProgressDialog import com.shifthackz.aisdv1.presentation.widget.input.GenerationInputForm import org.koin.androidx.compose.koinViewModel class TextToImageScreen( private val viewModel: TextToImageViewModel, - private val launchRewarded: () -> Unit, private val launchGalleryDetail: (Long) -> Unit, ) : MviScreen(viewModel) { @@ -59,7 +70,6 @@ class TextToImageScreen( onOpenPreviousGenerationInput = viewModel::openPreviousGenerationInput, onUpdateFromPreviousAiGeneration = viewModel::updateFormPreviousAiGeneration, onDismissScreenDialog = viewModel::dismissScreenModal, - onLaunchRewarded = launchRewarded, ) } @@ -89,7 +99,6 @@ private fun ScreenContent( onOpenPreviousGenerationInput: () -> Unit = {}, onUpdateFromPreviousAiGeneration: (AiGenerationResult) -> Unit = {}, onDismissScreenDialog: () -> Unit = {}, - onLaunchRewarded: () -> Unit = {}, ) { Box(modifier) { Scaffold( @@ -140,10 +149,6 @@ private fun ScreenContent( }, bottomBar = { Column(Modifier.fillMaxWidth()) { - AvailableCoinsComposable( - modifier = Modifier.fillMaxWidth(), - viewModel = koinViewModel() - ).Build() Button( modifier = Modifier .fillMaxWidth() @@ -159,7 +164,8 @@ private fun ScreenContent( ) Text( modifier = Modifier.padding(start = 8.dp), - text = stringResource(id = R.string.action_generate) + text = stringResource(id = R.string.action_generate), + color = LocalContentColor.current, ) } } @@ -176,10 +182,6 @@ private fun ScreenContent( canDismiss = false, step = state.screenModal.pair, ) - TextToImageState.Modal.NoSdAiCoins -> NoSdAiCoinsDialog( - onDismissRequest = onDismissScreenDialog, - launchRewarded = onLaunchRewarded, - ) is TextToImageState.Modal.Image -> GenerationImageResultDialog( imageBase64 = state.screenModal.result.image, showSaveButton = !state.screenModal.autoSaveEnabled, diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageViewModel.kt index 78132a0e..e1f80620 100755 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageViewModel.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/txt2img/TextToImageViewModel.kt @@ -1,6 +1,5 @@ package com.shifthackz.aisdv1.presentation.screen.txt2img -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider import com.shifthackz.aisdv1.core.common.log.errorLog import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread @@ -13,7 +12,6 @@ import com.shifthackz.aisdv1.domain.feature.analytics.Analytics import com.shifthackz.aisdv1.domain.feature.diffusion.LocalDiffusion import com.shifthackz.aisdv1.domain.preference.PreferenceManager import com.shifthackz.aisdv1.domain.usecase.caching.SaveLastResultToCacheUseCase -import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase import com.shifthackz.aisdv1.domain.usecase.generation.ObserveHordeProcessStatusUseCase import com.shifthackz.aisdv1.domain.usecase.generation.ObserveLocalDiffusionProcessStatusUseCase import com.shifthackz.aisdv1.domain.usecase.generation.SaveGenerationResultUseCase @@ -31,8 +29,6 @@ class TextToImageViewModel( getStableDiffusionSamplersUseCase: GetStableDiffusionSamplersUseCase, observeHordeProcessStatusUseCase: ObserveHordeProcessStatusUseCase, observeLocalDiffusionProcessStatusUseCase: ObserveLocalDiffusionProcessStatusUseCase, - buildInfoProvider: BuildInfoProvider, - observeCoinsUseCase: ObserveCoinsUseCase, generationFormUpdateEvent: GenerationFormUpdateEvent, private val textToImageUseCase: TextToImageUseCase, private val saveLastResultToCacheUseCase: SaveLastResultToCacheUseCase, @@ -44,9 +40,7 @@ class TextToImageViewModel( private val analytics: Analytics, ) : GenerationMviViewModel( schedulersProvider, - buildInfoProvider, preferenceManager, - observeCoinsUseCase, getStableDiffusionSamplersUseCase, observeHordeProcessStatusUseCase, observeLocalDiffusionProcessStatusUseCase, @@ -95,10 +89,6 @@ class TextToImageViewModel( fun dismissScreenModal() = setActiveModal(TextToImageState.Modal.None) fun generate() { - if (!currentState.generateButtonEnabled) { - setActiveModal(TextToImageState.Modal.NoSdAiCoins) - return - } !currentState .mapToPayload() .let(textToImageUseCase::invoke) diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/ColorTheme.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/ColorTheme.kt index 5778bf91..d4eaf220 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/ColorTheme.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/ColorTheme.kt @@ -1,10 +1,13 @@ package com.shifthackz.aisdv1.presentation.theme -import android.os.Build -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.lightColorScheme +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color -val dynamicColorAvailable: () -> Boolean = { Build.VERSION.SDK_INT >= Build.VERSION_CODES.S } - -val LightColors = lightColorScheme() -val DarkColors = darkColorScheme() +@Composable +fun colors( + light: Color, + dark: Color, +): Color { + return if (isSystemInDarkTheme()) dark else light +} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/GlobalTheme.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/GlobalTheme.kt index 1402030f..442a9e60 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/GlobalTheme.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/theme/GlobalTheme.kt @@ -1,22 +1,25 @@ package com.shifthackz.aisdv1.presentation.theme -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext +import com.shifthackz.catppuccin.compose.CatppuccinMaterial +import com.shifthackz.catppuccin.compose.CatppuccinTheme +import com.shifthackz.catppuccin.palette.Catppuccin @Composable fun AiStableDiffusionAppTheme( - useDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit, -) = MaterialTheme( - colorScheme = when { - dynamicColorAvailable() && useDarkTheme -> dynamicDarkColorScheme(LocalContext.current) - dynamicColorAvailable() && !useDarkTheme -> dynamicLightColorScheme(LocalContext.current) - useDarkTheme -> DarkColors - else -> LightColors - }, - content = content -) +) { + return CatppuccinTheme.DarkLightPalette( + darkPalette = CatppuccinMaterial.Frappe( + primary = Catppuccin.Frappe.Mauve, + secondary = Catppuccin.Frappe.Mauve.copy(alpha = 0.5f), + tertiary = Catppuccin.Frappe.Mauve.copy(alpha = 0.5f), + ), + lightPalette = CatppuccinMaterial.Latte( + primary = Catppuccin.Latte.Mauve, + secondary = Catppuccin.Latte.Mauve.copy(alpha = 0.5f), + tertiary = Catppuccin.Latte.Mauve.copy(alpha = 0.5f), + ), + content = content, + ) +} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/ad/AdBanner.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/ad/AdBanner.kt deleted file mode 100644 index 55136b42..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/ad/AdBanner.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.ad - -import android.content.Context -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.viewinterop.AndroidView -import com.shifthackz.aisdv1.domain.feature.ad.AdFeature - -@Composable -fun AdBanner( - modifier: Modifier = Modifier, - adFactory: (Context) -> AdFeature.Ad, -) { - val ad = adFactory(LocalContext.current) - if (ad.isEmpty) return - ad.view?.let { adView -> - AndroidView( - modifier = modifier, - factory = { adView }, - ) - } -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsComposable.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsComposable.kt deleted file mode 100644 index 2897240c..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsComposable.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.coins - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Toll -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.ui.MviScreen - -class AvailableCoinsComposable( - private val modifier: Modifier = Modifier, - private val viewModel: AvailableCoinsViewModel, -) : MviScreen(viewModel) { - - @Composable - override fun Content() { - when (val state = viewModel.state.collectAsStateWithLifecycle().value) { - is AvailableCoinsState.Content -> { - Row( - modifier = modifier.padding(vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - ) { - Icon( - imageVector = Icons.Default.Toll, - contentDescription = "SDAI Coins", - tint = MaterialTheme.colorScheme.primary, - ) - Spacer(modifier = Modifier.width(10.dp)) - Text( - text = "SDAI Coins: ${state.value}", - color = MaterialTheme.colorScheme.primary - ) - } - } - else -> Unit - } - } -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsState.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsState.kt deleted file mode 100644 index 26f3feb1..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsState.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.coins - -import com.shifthackz.aisdv1.core.ui.MviState - -interface AvailableCoinsState : MviState { - object Hidden : AvailableCoinsState - data class Content(val value: Int) : AvailableCoinsState -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsViewModel.kt deleted file mode 100644 index 9e1d08b2..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/coins/AvailableCoinsViewModel.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.coins - -import com.shifthackz.aisdv1.core.common.extensions.EmptyLambda -import com.shifthackz.aisdv1.core.common.log.errorLog -import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider -import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel -import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase -import io.reactivex.rxjava3.kotlin.subscribeBy - -class AvailableCoinsViewModel( - observeAvailableCoinsUseCase: ObserveCoinsUseCase, - schedulersProvider: SchedulersProvider, -) : MviRxViewModel() { - - override val emptyState = AvailableCoinsState.Hidden - - init { - !observeAvailableCoinsUseCase() - .subscribeOnMainThread(schedulersProvider) - .map { result -> - when (result) { - is ObserveCoinsUseCase.Result.Coins -> { - AvailableCoinsState.Content(result.value) - } - else -> AvailableCoinsState.Hidden - } - } - .subscribeBy(::errorLog, EmptyLambda, ::setState) - } -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/connectivity/ConnectivityComposable.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/connectivity/ConnectivityComposable.kt index 9d4a7b22..f46dd3ee 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/connectivity/ConnectivityComposable.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/connectivity/ConnectivityComposable.kt @@ -17,6 +17,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.shifthackz.aisdv1.core.ui.EmptyEffect import com.shifthackz.aisdv1.core.ui.MviScreen import com.shifthackz.aisdv1.presentation.R +import com.shifthackz.aisdv1.presentation.theme.colors +import com.shifthackz.catppuccin.palette.Catppuccin class ConnectivityComposable( private val viewModel: ConnectivityViewModel, @@ -26,7 +28,7 @@ class ConnectivityComposable( override fun Content() { ConnectivityWidgetState( modifier = Modifier.fillMaxWidth(), - state = viewModel.state.collectAsStateWithLifecycle().value, + viewModel.state.collectAsStateWithLifecycle().value, ) } @@ -41,12 +43,14 @@ private fun ConnectivityWidgetState( ) { if (!state.enabled) return val uiColor = when (state) { - is ConnectivityState.Connected -> MaterialTheme.colorScheme.primaryContainer - is ConnectivityState.Disconnected -> MaterialTheme.colorScheme.errorContainer - is ConnectivityState.Uninitialized -> MaterialTheme.colorScheme.secondaryContainer + is ConnectivityState.Connected -> colors(light = Catppuccin.Latte.Green, dark = Catppuccin.Frappe.Green) + is ConnectivityState.Disconnected -> colors(light = Catppuccin.Latte.Red, dark = Catppuccin.Frappe.Red) + is ConnectivityState.Uninitialized -> colors(light = Catppuccin.Latte.Lavender, dark = Catppuccin.Frappe.Lavender) } Column( - modifier = modifier.padding(top = 4.dp), + modifier = modifier + .background(MaterialTheme.colorScheme.surface) + .padding(top = 4.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Text( @@ -60,11 +64,7 @@ private fun ConnectivityWidgetState( is ConnectivityState.Uninitialized -> R.string.status_communicating } ), - color = when (state) { - is ConnectivityState.Connected -> MaterialTheme.colorScheme.onPrimaryContainer - is ConnectivityState.Disconnected -> MaterialTheme.colorScheme.onErrorContainer - is ConnectivityState.Uninitialized -> MaterialTheme.colorScheme.onSurface - } + color = colors(light = Catppuccin.Latte.Base, dark = Catppuccin.Frappe.Base) ) } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ErrorDialog.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ErrorDialog.kt index 6e6b49af..70686bd3 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ErrorDialog.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ErrorDialog.kt @@ -39,7 +39,6 @@ fun ErrorDialog( fontSize = 14.sp, color = AlertDialogDefaults.textContentColor, ) - } ) } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ForceUpdateDialog.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ForceUpdateDialog.kt deleted file mode 100644 index 628bfabf..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ForceUpdateDialog.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.dialog - -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.AlertDialogDefaults -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.DialogProperties -import com.shifthackz.aisdv1.core.common.extensions.EmptyLambda -import com.shifthackz.aisdv1.presentation.R - -@Composable -fun ForceUpdateDialog( - openMarket: () -> Unit = {}, -) { - AlertDialog( - shape = RoundedCornerShape(24.dp), - onDismissRequest = EmptyLambda, - properties = DialogProperties( - dismissOnClickOutside = false, - dismissOnBackPress = false, - ), - confirmButton = { - TextButton(onClick = openMarket) { - Text(text = stringResource(id = R.string.action_update)) - } - }, - title = { - Text( - text = stringResource(id = R.string.update_required_title), - fontSize = 18.sp, - color = AlertDialogDefaults.titleContentColor, - ) - }, - text = { - Text( - text = stringResource(id = R.string.update_required_sub_title), - fontSize = 14.sp, - color = AlertDialogDefaults.textContentColor, - ) - } - ) -} - -@Composable -@Preview -private fun ForceUpdateDialogPreview() { - ForceUpdateDialog() -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/GenerationImageResultDialog.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/GenerationImageResultDialog.kt index 7ffa9dbc..f71ed73c 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/GenerationImageResultDialog.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/GenerationImageResultDialog.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.AlertDialogDefaults import androidx.compose.material3.Button +import androidx.compose.material3.LocalContentColor import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -68,7 +69,8 @@ fun GenerationImageResultDialog( onClick = onSaveRequest, ) { Text( - text = stringResource(id = R.string.action_save) + text = stringResource(id = R.string.action_save), + color = LocalContentColor.current, ) } OutlinedButton( @@ -79,7 +81,8 @@ fun GenerationImageResultDialog( onClick = onDismissRequest, ) { Text( - text = stringResource(id = R.string.action_close) + text = stringResource(id = R.string.action_close), + color = LocalContentColor.current, ) } @@ -92,7 +95,8 @@ fun GenerationImageResultDialog( onClick = onDismissRequest, ) { Text( - text = stringResource(id = R.string.action_close) + text = stringResource(id = R.string.action_close), + color = LocalContentColor.current, ) } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/NoSdAiCoinsDialog.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/NoSdAiCoinsDialog.kt deleted file mode 100644 index 37579741..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/NoSdAiCoinsDialog.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.dialog - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ConfirmationNumber -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.shifthackz.aisdv1.presentation.R - -@Composable -fun NoSdAiCoinsDialog( - onDismissRequest: () -> Unit = {}, - launchRewarded: () -> Unit = {}, -) { - AlertDialog( - shape = RoundedCornerShape(24.dp), - onDismissRequest = onDismissRequest, - confirmButton = { - Button( - onClick = { - onDismissRequest() - launchRewarded() - }, - ) { - Box { - Icon( - imageVector = Icons.Default.ConfirmationNumber, - contentDescription = "free_coins_1", - tint = MaterialTheme.colorScheme.onPrimary, - ) - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "free_coins_2", - tint = MaterialTheme.colorScheme.primary, - ) - } - Text( - modifier = Modifier.padding(start = 10.dp), - text = stringResource(id = R.string.sdai_coins_free), - ) - } - }, - dismissButton = { - OutlinedButton(onClick = onDismissRequest) { - Text(text = stringResource(id = R.string.action_close)) - } - }, - title = { - Text( - text = stringResource(id = R.string.sdai_coins_zero_title), - fontSize = 18.sp, - color = AlertDialogDefaults.titleContentColor, - ) - }, - text = { - Text( - text = stringResource(id = R.string.sdai_coins_zero_sub_title), - fontSize = 14.sp, - color = AlertDialogDefaults.textContentColor, - ) - - } - ) -} - -@Composable -@Preview -private fun NoSdAiCoinsDialogPreview() { - NoSdAiCoinsDialog() -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ProgressDialog.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ProgressDialog.kt index 0c9aed0a..3e0b5b46 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ProgressDialog.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/dialog/ProgressDialog.kt @@ -96,7 +96,6 @@ fun ProgressDialogStatus( style = TextStyle(fontSize = 12.sp), color = AlertDialogDefaults.textContentColor, ) - } } diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/input/GenerationInputForm.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/input/GenerationInputForm.kt index ed94735d..7ce4df9e 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/input/GenerationInputForm.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/input/GenerationInputForm.kt @@ -11,6 +11,7 @@ import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.ArrowDropUp import androidx.compose.material3.Checkbox import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -126,7 +127,7 @@ fun GenerationInputForm( } }, isError = widthValidationError != null, - supportingText = { widthValidationError?.let { Text(it.asString()) } }, + supportingText = { widthValidationError?.let { Text(it.asString(), color = MaterialTheme.colorScheme.error) } }, label = { Text(stringResource(id = R.string.width)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), ) @@ -141,7 +142,7 @@ fun GenerationInputForm( } }, isError = heightValidationError != null, - supportingText = { heightValidationError?.let { Text(it.asString()) } }, + supportingText = { heightValidationError?.let { Text(it.asString(), color = MaterialTheme.colorScheme.error) } }, label = { Text(stringResource(id = R.string.height)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), ) diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/item/SettingsItem.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/item/SettingsItem.kt index 4d70aab7..9dd9093f 100644 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/item/SettingsItem.kt +++ b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/item/SettingsItem.kt @@ -63,7 +63,7 @@ fun SettingsItem( Row( modifier = modifier .clip(RoundedCornerShape(16.dp)) - .background(color = if (animateBackground) colorState.value else MaterialTheme.colorScheme.primaryContainer) + .background(color = if (animateBackground) colorState.value else MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.8f)) .defaultMinSize(minHeight = 50.dp) .clickable { onClick() }, verticalAlignment = Alignment.CenterVertically, diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdComposable.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdComposable.kt deleted file mode 100644 index e90d3f46..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdComposable.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.motd - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.ui.MviScreen - -class MotdComposable( - private val viewModel: MotdViewModel, -) : MviScreen(viewModel) { - - @Composable - override fun Content() { - val state = viewModel.state.collectAsStateWithLifecycle().value - if (state == MotdState.Hidden) return - (state as? MotdState.Content)?.let { (title, subTitle) -> - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 4.dp) - .padding(horizontal = 16.dp) - .background( - color = MaterialTheme.colorScheme.secondaryContainer, - shape = RoundedCornerShape(8.dp), - ), - ) { - val innerDimen = 8.dp - val innerModifier = Modifier.padding(horizontal = innerDimen) - Text( - modifier = innerModifier.padding(top = innerDimen), - text = title, - color = MaterialTheme.colorScheme.onSecondaryContainer, - fontWeight = FontWeight.Bold, - fontSize = MaterialTheme.typography.titleMedium.fontSize, - ) - Text( - modifier = innerModifier.padding(vertical = innerDimen), - text = subTitle, - color = MaterialTheme.colorScheme.onSecondaryContainer, - fontSize = MaterialTheme.typography.bodyMedium.fontSize, - ) - } - } - } -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdState.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdState.kt deleted file mode 100644 index 4645384f..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdState.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.motd - -import com.shifthackz.aisdv1.core.ui.MviState - -sealed interface MotdState : MviState { - - object Hidden : MotdState - - data class Content( - val title: String, - val subTitle: String, - ) : MotdState -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdViewModel.kt deleted file mode 100644 index 42974f48..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/motd/MotdViewModel.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.motd - -import com.shifthackz.aisdv1.core.common.appbuild.BuildInfoProvider -import com.shifthackz.aisdv1.core.common.appbuild.BuildType -import com.shifthackz.aisdv1.core.common.extensions.EmptyLambda -import com.shifthackz.aisdv1.core.common.log.errorLog -import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider -import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel -import com.shifthackz.aisdv1.domain.preference.PreferenceManager -import com.shifthackz.aisdv1.domain.usecase.motd.ObserveMotdUseCase -import io.reactivex.rxjava3.kotlin.subscribeBy - -class MotdViewModel( - private val preferenceManager: PreferenceManager, - observeMotdUseCase: ObserveMotdUseCase, - buildInfoProvider: BuildInfoProvider, - schedulersProvider: SchedulersProvider, -) : MviRxViewModel() { - - override val emptyState = MotdState.Hidden - - init { - if (buildInfoProvider.buildType == BuildType.GOOGLE_PLAY) { - !observeMotdUseCase() - .map { motd -> motd to preferenceManager.useSdAiCloud } - .map { (motd, usingSdAi) -> - if (!usingSdAi) return@map MotdState.Hidden - if (!motd.display || motd.isEmpty) return@map MotdState.Hidden - return@map MotdState.Content(motd.title, motd.subTitle) - } - .onErrorReturn { MotdState.Hidden } - .subscribeOnMainThread(schedulersProvider) - .subscribeBy(::errorLog, EmptyLambda, ::setState) - } - } -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerComposable.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerComposable.kt deleted file mode 100644 index e414930c..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerComposable.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.version - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.AlertDialogDefaults -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.shifthackz.aisdv1.core.model.UiText -import com.shifthackz.aisdv1.core.model.asUiText -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.ui.MviScreen -import com.shifthackz.aisdv1.domain.usecase.version.CheckAppVersionUpdateUseCase -import com.shifthackz.aisdv1.presentation.R -import com.shifthackz.aisdv1.presentation.widget.dialog.DecisionInteractiveDialog -import com.shifthackz.aisdv1.presentation.widget.dialog.ForceUpdateDialog - -class VersionCheckerComposable( - private val viewModel: VersionCheckerViewModel, - private val launchMarket: () -> Unit, -) : MviScreen(viewModel) { - - @Composable - override fun Content() { - val state = viewModel.state.collectAsStateWithLifecycle().value - if (state == VersionCheckerState.Idle) return - Box(Modifier.fillMaxSize()) { - (state as VersionCheckerState.UpdatePopUp) - when (state.result) { - is CheckAppVersionUpdateUseCase.Result.NewVersionAvailable -> { - if (!state.forceUserToUpdate) DecisionInteractiveDialog( - title = R.string.update_title.asUiText(), - text = UiText.Resource( - R.string.update_sub_title, - "${state.result.availableVersion}", - ), - confirmActionResId = R.string.action_update, - dismissActionResId = R.string.action_skip, - onConfirmAction = { - launchMarket() - viewModel.skipUpdate() - }, - onDismissRequest = viewModel::skipUpdate, - ) - else ForceUpdateDialog(openMarket = launchMarket) - } - CheckAppVersionUpdateUseCase.Result.NoUpdateNeeded -> { - AlertDialog( - shape = RoundedCornerShape(24.dp), - onDismissRequest = viewModel::skipUpdate, - confirmButton = { - TextButton(onClick = viewModel::skipUpdate) { - Text(text = stringResource(id = R.string.ok)) - } - }, - title = { - Text( - text = stringResource(id = R.string.update_no_need_title), - fontSize = 18.sp, - color = AlertDialogDefaults.titleContentColor, - ) - }, - text = { - Text( - text = stringResource(id = R.string.update_no_need_sub_title), - fontSize = 14.sp, - color = AlertDialogDefaults.textContentColor, - ) - } - ) - } - } - } - } - - @Composable - override fun ApplySystemUiColors() = Unit -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerState.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerState.kt deleted file mode 100644 index f7ef2fca..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerState.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.version - -import com.shifthackz.aisdv1.core.ui.MviState -import com.shifthackz.aisdv1.domain.usecase.version.CheckAppVersionUpdateUseCase - -interface VersionCheckerState : MviState { - object Idle : VersionCheckerState - data class UpdatePopUp( - val result: CheckAppVersionUpdateUseCase.Result, - val forceUserToUpdate: Boolean, - ) : VersionCheckerState -} diff --git a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerViewModel.kt b/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerViewModel.kt deleted file mode 100644 index 19ac8021..00000000 --- a/presentation/src/main/java/com/shifthackz/aisdv1/presentation/widget/version/VersionCheckerViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.shifthackz.aisdv1.presentation.widget.version - -import com.shifthackz.aisdv1.core.common.log.errorLog -import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider -import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread -import com.shifthackz.aisdv1.core.ui.EmptyEffect -import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel -import com.shifthackz.aisdv1.domain.usecase.version.CheckAppVersionUpdateUseCase -import io.reactivex.rxjava3.kotlin.subscribeBy - -class VersionCheckerViewModel( - private val checkAppVersionUpdateUseCase: CheckAppVersionUpdateUseCase, - private val schedulersProvider: SchedulersProvider, -) : MviRxViewModel() { - - override val emptyState = VersionCheckerState.Idle - - init { - checkForUpdate(forceUserToUpdate = true) - } - - fun checkForUpdate( - notifyIfSame: Boolean = false, - forceUserToUpdate: Boolean = false, - ) = !checkAppVersionUpdateUseCase() - .subscribeOnMainThread(schedulersProvider) - .subscribeBy(::errorLog) { result -> - val state = when (result) { - is CheckAppVersionUpdateUseCase.Result.NewVersionAvailable -> { - VersionCheckerState.UpdatePopUp(result, forceUserToUpdate) - } - CheckAppVersionUpdateUseCase.Result.NoUpdateNeeded -> { - if (notifyIfSame) VersionCheckerState.UpdatePopUp(result, forceUserToUpdate) - else VersionCheckerState.Idle - } - } - setState(state) - } - - fun skipUpdate() = setState(VersionCheckerState.Idle) -} diff --git a/presentation/src/main/res/values-tr/strings.xml b/presentation/src/main/res/values-tr/strings.xml index da7e8c48..d6f0ea8b 100644 --- a/presentation/src/main/res/values-tr/strings.xml +++ b/presentation/src/main/res/values-tr/strings.xml @@ -14,7 +14,6 @@ Araştır Versiyon %1$s - Senin için ❤️\'la 🇺🇦\'da hazırlardı Başlatılıyor… Veri Alınıyor… @@ -44,7 +43,6 @@ Rastgele görüntü Yapılandırmayı değiştir - SDAI Bulut hizmetini kullanmak istiyorum Kendi AUTOMATIC1111 hizmetimi kullanmak istiyorum. Horde AI bulutunu kullanmak istiyorum @@ -71,9 +69,6 @@ This mode allows you to test the application behavior, even if you don\'t have Stable Diffusion WebUI server.\n\nIn demo mode app ignores user prompt, does not use AI server, and returns some mock images. Before connecting ensure that:\n• you are running AUTOMATIC1111 WebUI with flags --api --listen\n• your firewall is not blocking 7860 port\n• phone is on the same WiFi with your PC - SDAI Bulut hizmetine bağlan. - This mode allows to use public SDAI cloud instance.\n\nAs our project is non-profitable, we may include additional rate-limit for some users, or restrict it by certain computing hours. - Horde AI bulutuna bağlanın Horde AI, Görüntü oluşturma çalışanları ve metin oluşturma çalışanlarından oluşan kitle kaynaklı dağıtılmış bir kümedir. Anonim olarak bağlanmak için varsayılan API Anahtarını kullanabilirsiniz. Ancak çok fazla eşzamanlı istek olduğunda anonim hesaplar en düşük önceliğe sahiptir. @@ -179,8 +174,6 @@ SDAI Jetonlarınız Bitti SDAI için bütün jetonlarınız bitti.\nDaha fazla jeton kazanmak için yarın tekrar gelin!\n\nNot: Kendi sunucunuzu çalıştırdığınızda SDAI jetonlarına ihtiyaç duymazsınız. - Ücretsiz jetonlar - Hata Alan boş olamaz Sunucu URL adresi boş olamaz diff --git a/presentation/src/main/res/values-uk/strings.xml b/presentation/src/main/res/values-uk/strings.xml index f87a4186..e2788302 100644 --- a/presentation/src/main/res/values-uk/strings.xml +++ b/presentation/src/main/res/values-uk/strings.xml @@ -14,7 +14,6 @@ Дивитися Версія %1$s - Зроблено для вас з ❤️ в 🇺🇦 Ініціалізація… Завантаження даних… @@ -44,7 +43,6 @@ Випадкове зображення Змінити конфігурацію - Cервер SDAI Власний сервер AUTOMATIC1111 Сервер Horde AI @@ -71,9 +69,6 @@ Цей режим дозволяє перевірити поведінку програми, навіть якщо у вас немає сервера Stable Diffusion WebUI.\n\nУ демонстраційному режимі програма ігнорує параметри генерації, не використовує сервер штучного інтелекту та повертає фіктивні зображення. Перед підключенням переконайтеся, що:\n• ви використовуєте AUTOMATIC1111 WebUI з аргументами --api --listen\n• ваш брандмауер не блокує порт 7860\n• телефон підключено до однієї мережі Wi-Fi з вашим ПК - Підключитися до сервера SDAI - Цей режим дозволяє використовувати загальнодоступний хмарний екземпляр SDAI.\n\nОскільки наш проект є неприбутковим, ми можемо включити додатковий ліміт швидкості для деяких користувачів або обмежити його певними обчислювальними годинами. - Підключитися до Horde AI Horde AI — це краудсорсинговий розподілений кластер нод генерації зображень і тексту. Ви можете використовувати ключ API за замовчуванням для анонімного підключення. Однак анонімні облікові записи мають найнижчий пріоритет, коли надходить забагато одночасних запитів. @@ -179,8 +174,6 @@ Закінчилися монети SDAI Ви витратили всі свої монети SDAI за сьогодні.\nПоверніться завтра, щоб отримати більше монет!\n\nПримітка: вам не потрібно мати монети SDAI, якщо ви використовуєте власний сервер. - Безкоштовні монети - Помилка Поле не може бути порожнім URL-адреса не повинна бути пустою diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index e8f36b0f..29eeebf0 100755 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -18,7 +18,6 @@ Browse Version %1$s - Made for you with ❤️ from 🇺🇦 Initializing… Fetching data… @@ -48,7 +47,6 @@ Random image Change configuration - SDAI cloud AUTOMATIC1111 instance Horde AI cloud Local Diffusion (Beta) @@ -76,9 +74,6 @@ This mode allows you to test the application behavior, even if you don\'t have Stable Diffusion WebUI server.\n\nIn demo mode app ignores user prompt, does not use AI server, and returns some mock images. Before connecting ensure that:\n• you are running AUTOMATIC1111 WebUI with flags --api --listen\n• your firewall is not blocking 7860 port\n• phone is on the same WiFi with your PC - Connect to SDAI cloud - This mode allows to use public SDAI cloud instance.\n\nAs our project is non-profitable, we may include additional rate-limit for some users, or restrict it by certain computing hours. - Connect to Horde AI cloud Horde AI is a crowdsourced distributed cluster of Image generation workers and text generation workers. You can use default API Key to connect anonymously. However anonymous accounts have the lowest priority when there\'s too many concurrent requests. @@ -185,8 +180,6 @@ Out of SDAI coins You spent all your SDAI coins for today.\nCome back tomorrow to receive more coins!\n\nNote: you don\'t need to have SDAI coins in case your are running own server. - Free coins - Error Field can\'t be empty Server URL should not be empty diff --git a/settings.gradle b/settings.gradle index 379d657b..2dc265ed 100755 --- a/settings.gradle +++ b/settings.gradle @@ -25,7 +25,6 @@ def libraries = [ ':data', ':demo', ':domain', - ':feature:ads', ':feature:analytics', ':feature:auth', ':feature:diffusion', diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/CoinDatabase.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/CoinDatabase.kt deleted file mode 100644 index d053962b..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/CoinDatabase.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins - -import androidx.room.Database -import androidx.room.RoomDatabase -import androidx.room.TypeConverters -import com.shifthackz.aisdv1.storage.converters.DateConverters -import com.shifthackz.aisdv1.storage.db.coins.CoinDatabase.Companion.DB_VERSION -import com.shifthackz.aisdv1.storage.db.coins.dao.CoinDao -import com.shifthackz.aisdv1.storage.db.coins.dao.EarnedCoinDao -import com.shifthackz.aisdv1.storage.db.coins.entity.CoinEntity -import com.shifthackz.aisdv1.storage.db.coins.entity.EarnedCoinEntity - -@Database( - version = DB_VERSION, - exportSchema = true, - entities = [ - CoinEntity::class, - EarnedCoinEntity::class, - ], -) -@TypeConverters(DateConverters::class) -internal abstract class CoinDatabase : RoomDatabase() { - abstract fun coinDao(): CoinDao - abstract fun earnedCoinDao(): EarnedCoinDao - - companion object { - const val DB_NAME = "ai_sd_v1_coins_db" - const val DB_VERSION = 2 - } -} diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/contract/CoinContract.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/contract/CoinContract.kt deleted file mode 100644 index f03ca7b5..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/contract/CoinContract.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins.contract - -internal object CoinContract { - const val TABLE = "coins" - - const val ID = "id" - const val DATE = "date" -} \ No newline at end of file diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/contract/EarnedCoinContract.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/contract/EarnedCoinContract.kt deleted file mode 100644 index 0c48e4d8..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/contract/EarnedCoinContract.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins.contract - -internal object EarnedCoinContract { - const val TABLE = "earned_coins" - - const val ID = "id" - const val DATE = "date" -} diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/dao/CoinDao.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/dao/CoinDao.kt deleted file mode 100644 index bcb38d78..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/dao/CoinDao.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.Query -import com.shifthackz.aisdv1.storage.db.coins.contract.CoinContract -import com.shifthackz.aisdv1.storage.db.coins.entity.CoinEntity -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Single - -@Dao -interface CoinDao { - - @Query("SELECT * FROM ${CoinContract.TABLE} WHERE ${CoinContract.DATE} BETWEEN :start AND :end") - fun queryAvailableCoinsForPeriod(start: Long, end: Long): Single> - - @Insert - fun insert(item: CoinEntity): Completable -} diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/dao/EarnedCoinDao.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/dao/EarnedCoinDao.kt deleted file mode 100644 index c35d5d86..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/dao/EarnedCoinDao.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import com.shifthackz.aisdv1.storage.db.coins.contract.EarnedCoinContract -import com.shifthackz.aisdv1.storage.db.coins.entity.EarnedCoinEntity -import io.reactivex.rxjava3.core.Completable -import io.reactivex.rxjava3.core.Single - -@Dao -interface EarnedCoinDao { - - @Query("SELECT COUNT(${EarnedCoinContract.ID}) FROM ${EarnedCoinContract.TABLE}") - fun queryCount(): Single - - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insert(items: List): Completable - - @Query("DELETE FROM ${EarnedCoinContract.TABLE} WHERE ${EarnedCoinContract.ID} = (SELECT MAX(${EarnedCoinContract.ID}) FROM ${EarnedCoinContract.TABLE})") - fun deleteLast(): Completable -} diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/entity/CoinEntity.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/entity/CoinEntity.kt deleted file mode 100644 index 1e65a48b..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/entity/CoinEntity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins.entity - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import com.shifthackz.aisdv1.storage.db.coins.contract.CoinContract -import java.util.* - -@Entity(tableName = CoinContract.TABLE) -data class CoinEntity( - @PrimaryKey(autoGenerate = true) - @ColumnInfo(name = CoinContract.ID) - val id: Long, - @ColumnInfo(name = CoinContract.DATE) - val date: Date, -) diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/entity/EarnedCoinEntity.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/entity/EarnedCoinEntity.kt deleted file mode 100644 index 1496d5ef..00000000 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/db/coins/entity/EarnedCoinEntity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.shifthackz.aisdv1.storage.db.coins.entity - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import com.shifthackz.aisdv1.storage.db.coins.contract.EarnedCoinContract -import java.util.* - -@Entity(tableName = EarnedCoinContract.TABLE) -data class EarnedCoinEntity( - @PrimaryKey(autoGenerate = true) - @ColumnInfo(name = EarnedCoinContract.ID) - val id: Long, - @ColumnInfo(name = EarnedCoinContract.DATE) - val date: Date, -) diff --git a/storage/src/main/java/com/shifthackz/aisdv1/storage/di/DatabaseModule.kt b/storage/src/main/java/com/shifthackz/aisdv1/storage/di/DatabaseModule.kt index 53791d15..02fbc9a7 100755 --- a/storage/src/main/java/com/shifthackz/aisdv1/storage/di/DatabaseModule.kt +++ b/storage/src/main/java/com/shifthackz/aisdv1/storage/di/DatabaseModule.kt @@ -2,7 +2,6 @@ package com.shifthackz.aisdv1.storage.di import androidx.room.Room import com.shifthackz.aisdv1.storage.db.cache.CacheDatabase -import com.shifthackz.aisdv1.storage.db.coins.CoinDatabase import com.shifthackz.aisdv1.storage.db.persistent.PersistentDatabase import com.shifthackz.aisdv1.storage.gateway.GatewayClearCacheDb import com.shifthackz.aisdv1.storage.gateway.GatewayClearPersistentDb @@ -25,17 +24,6 @@ val databaseModule = module { ) .build() } - - single { - Room.databaseBuilder( - androidApplication(), - CoinDatabase::class.java, - CoinDatabase.DB_NAME, - ) - .allowMainThreadQueries() - .fallbackToDestructiveMigration() - .build() - } //endregion //region GATEWAYS @@ -57,9 +45,4 @@ val databaseModule = module { //region PERSISTENT DB DAOs single { get().generationResultDao() } //endregion - - //region COIN DB DAOs - single { get().coinDao() } - single { get().earnedCoinDao() } - //endregion }