From 074d1b555ee887814274d2375d708a036b96c972 Mon Sep 17 00:00:00 2001 From: Marco Gomiero Date: Wed, 11 Sep 2024 22:05:11 +0200 Subject: [PATCH] Create a new flavor to publish on fdroid --- .github/workflows/android-alpha-release.yaml | 2 +- .github/workflows/code-checks.yaml | 2 +- androidApp/build.gradle.kts | 26 +++++++++++++++++-- .../feedflow/android/CrashlyticsHelper.kt | 7 +++++ .../feedflow/android/CrashlyticsHelper.kt | 12 +++++++++ .../prof18/feedflow/android/FeedFlowApp.kt | 22 +++++++++++----- .../android/settings/SettingsScreen.kt | 21 ++++++++++----- .../prof18/feedflow/core/utils/AppConfig.kt | 7 +++++ .../com/prof18/feedflow/shared/di/Koin.kt | 13 +++++----- .../com/prof18/feedflow/shared/di/KoinIOS.kt | 7 ++++- .../prof18/feedflow/shared/di/KoinDesktop.kt | 7 ++++- 11 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 androidApp/src/fdroid/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt create mode 100644 androidApp/src/googlePlay/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt create mode 100644 core/src/commonMain/kotlin/com/prof18/feedflow/core/utils/AppConfig.kt diff --git a/.github/workflows/android-alpha-release.yaml b/.github/workflows/android-alpha-release.yaml index 00b9248d..3a0fb8b9 100644 --- a/.github/workflows/android-alpha-release.yaml +++ b/.github/workflows/android-alpha-release.yaml @@ -54,4 +54,4 @@ jobs: PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG }} - name: Distribute app to Alpha track - run: ./gradlew :androidApp:bundleRelease :androidApp:publishBundle + run: ./gradlew :androidApp:bundleGooglePlayRelease :androidApp:publishGooglePlayReleaseBundle diff --git a/.github/workflows/code-checks.yaml b/.github/workflows/code-checks.yaml index 3ceed2a4..7172d7a4 100644 --- a/.github/workflows/code-checks.yaml +++ b/.github/workflows/code-checks.yaml @@ -69,7 +69,7 @@ jobs: mv androidApp/src/release/dummy-google-services.json androidApp/src/release/google-services.json - name: Build Android Sample - run: ./gradlew :androidApp:assembleDebug + run: ./gradlew :androidApp:assembleGooglePlayDebug build-desktop-app: name: Build Desktop App diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index bf493197..3dcd78aa 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -1,3 +1,4 @@ +import java.util.Locale import java.util.Properties plugins { @@ -22,6 +23,7 @@ val dropboxAppKey: String = local.getProperty("dropbox_key").orEmpty() if (dropboxAppKey.isEmpty()) { println("Dropbox key not set in keystore.properties. Please add it to the file with the key 'dropbox_key'") } + android { namespace = "com.prof18.feedflow.android" compileSdk = libs.versions.android.compile.sdk.get().toInt() @@ -80,6 +82,18 @@ android { buildConfigField("String", "DROPBOX_APP_KEY", "\"$dropboxAppKey\"") } } + + flavorDimensions += "version" + productFlavors { + create("fdroid") { + dimension = "version" + } + + create("googlePlay") { + dimension = "version" + isDefault = true + } + } } tasks.withType().configureEach { @@ -104,8 +118,7 @@ dependencies { implementation(libs.bundles.compose) implementation(libs.bundles.about.libraries) - implementation(platform(libs.firebase.bom)) - implementation(libs.firebase.crashlytics) + implementation(libs.material.window.size) implementation(libs.androidx.browser) implementation(libs.compose.webview) @@ -120,6 +133,9 @@ dependencies { implementation(libs.workmanager) implementation(libs.androidx.lifecycle.process) + "googlePlayImplementation"(platform(libs.firebase.bom)) + "googlePlayImplementation"(libs.firebase.crashlytics) + debugImplementation(compose.uiTooling) testImplementation(libs.koin.test) @@ -145,3 +161,9 @@ fun getVersionName(): String = .asText.get() .trim() .replace("-android", "") + +android.applicationVariants.configureEach { + val name = name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + val googleTask = tasks.findByName("process${name}GoogleServices") + googleTask?.enabled = !name.contains("fdroid") +} diff --git a/androidApp/src/fdroid/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt b/androidApp/src/fdroid/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt new file mode 100644 index 00000000..6c9afbd1 --- /dev/null +++ b/androidApp/src/fdroid/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt @@ -0,0 +1,7 @@ +package com.prof18.feedflow.android + +class CrashlyticsHelper { + fun initCrashlytics() { + // no-op + } +} diff --git a/androidApp/src/googlePlay/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt b/androidApp/src/googlePlay/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt new file mode 100644 index 00000000..6756194a --- /dev/null +++ b/androidApp/src/googlePlay/kotlin/com/prof18/feedflow/android/CrashlyticsHelper.kt @@ -0,0 +1,12 @@ +package com.prof18.feedflow.android + +import com.google.firebase.crashlytics.ktx.crashlytics +import com.google.firebase.ktx.Firebase +import com.prof18.feedflow.shared.utils.enableKmpCrashlytics + +class CrashlyticsHelper { + fun initCrashlytics() { + Firebase.crashlytics.setCrashlyticsCollectionEnabled(true) + enableKmpCrashlytics() + } +} diff --git a/androidApp/src/main/kotlin/com/prof18/feedflow/android/FeedFlowApp.kt b/androidApp/src/main/kotlin/com/prof18/feedflow/android/FeedFlowApp.kt index 0081ee37..91abf101 100644 --- a/androidApp/src/main/kotlin/com/prof18/feedflow/android/FeedFlowApp.kt +++ b/androidApp/src/main/kotlin/com/prof18/feedflow/android/FeedFlowApp.kt @@ -5,15 +5,13 @@ import android.content.Context import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner -import com.google.firebase.crashlytics.ktx.crashlytics -import com.google.firebase.ktx.Firebase import com.prof18.feedflow.android.readermode.ReaderModeViewModel +import com.prof18.feedflow.core.utils.AppConfig import com.prof18.feedflow.core.utils.AppEnvironment import com.prof18.feedflow.shared.di.getWith import com.prof18.feedflow.shared.di.initKoin import com.prof18.feedflow.shared.domain.feedsync.FeedSyncRepository import com.prof18.feedflow.shared.ui.utils.coilImageLoader -import com.prof18.feedflow.shared.utils.enableKmpCrashlytics import org.koin.android.ext.android.inject import org.koin.androidx.workmanager.koin.workManagerFactory import org.koin.core.module.dsl.viewModel @@ -26,19 +24,28 @@ class FeedFlowApp : Application() { override fun onCreate() { super.onCreate() + val isGooglePlayFlavor = when (BuildConfig.FLAVOR) { + "googlePlay" -> true + else -> false + } val appEnvironment = if (BuildConfig.DEBUG) { AppEnvironment.Debug } else { AppEnvironment.Release } + val appConfig = AppConfig( + appEnvironment = appEnvironment, + isLoggingEnabled = isGooglePlayFlavor, + isDropboxSyncEnabled = isGooglePlayFlavor, + ) - if (appEnvironment.isRelease()) { - Firebase.crashlytics.setCrashlyticsCollectionEnabled(true) - enableKmpCrashlytics() + if (isGooglePlayFlavor && appEnvironment.isRelease()) { + val crashlyticsHelper = CrashlyticsHelper() + crashlyticsHelper.initCrashlytics() } initKoin( - appEnvironment = appEnvironment, + appConfig = appConfig, platformSetup = { workManagerFactory() }, @@ -59,6 +66,7 @@ class FeedFlowApp : Application() { debug = appEnvironment.isDebug(), ) } + single { appConfig } viewModel { ReaderModeViewModel( readerModeExtractor = get(), diff --git a/androidApp/src/main/kotlin/com/prof18/feedflow/android/settings/SettingsScreen.kt b/androidApp/src/main/kotlin/com/prof18/feedflow/android/settings/SettingsScreen.kt index 9bd80716..f1ca2432 100644 --- a/androidApp/src/main/kotlin/com/prof18/feedflow/android/settings/SettingsScreen.kt +++ b/androidApp/src/main/kotlin/com/prof18/feedflow/android/settings/SettingsScreen.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.platform.testTag import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.prof18.feedflow.android.BrowserManager import com.prof18.feedflow.android.settings.components.BrowserSelectionDialog +import com.prof18.feedflow.core.utils.AppConfig import com.prof18.feedflow.core.utils.TestingTag import com.prof18.feedflow.shared.domain.model.Browser import com.prof18.feedflow.shared.presentation.SettingsViewModel @@ -69,6 +70,7 @@ fun SettingsScreen( val browserManager = koinInject() val settingsViewModel = koinViewModel() + val appConfig = koinInject() val browserListState by browserManager.browserListState.collectAsStateWithLifecycle() val settingState by settingsViewModel.settingsState.collectAsStateWithLifecycle() @@ -85,6 +87,7 @@ fun SettingsScreen( isShowReadItemEnabled = settingState.isShowReadItemsEnabled, isReaderModeEnabled = settingState.isReaderModeEnabled, isRemoveTitleFromDescriptionEnabled = settingState.isRemoveTitleFromDescriptionEnabled, + showAccounts = appConfig.isDropboxSyncEnabled, onBrowserSelected = { browser -> browserManager.setFavouriteBrowser(browser) }, @@ -124,6 +127,7 @@ private fun SettingsScreenContent( isShowReadItemEnabled: Boolean, isReaderModeEnabled: Boolean, isRemoveTitleFromDescriptionEnabled: Boolean, + showAccounts: Boolean, onFeedListClick: () -> Unit, onAddFeedClick: () -> Unit, onBrowserSelected: (Browser) -> Unit, @@ -181,6 +185,7 @@ private fun SettingsScreenContent( setReaderMode = setReaderMode, isRemoveTitleFromDescriptionEnabled = isRemoveTitleFromDescriptionEnabled, setRemoveTitleFromDescription = setRemoveTitleFromDescription, + showAccounts = showAccounts, ) } } @@ -191,6 +196,7 @@ private fun SettingsList( isShowReadItemEnabled: Boolean, isReaderModeEnabled: Boolean, isRemoveTitleFromDescriptionEnabled: Boolean, + showAccounts: Boolean, onFeedListClick: () -> Unit, onAddFeedClick: () -> Unit, onBrowserSelectionClick: () -> Unit, @@ -242,12 +248,14 @@ private fun SettingsList( ) } - item { - SettingItem( - title = LocalFeedFlowStrings.current.settingsAccounts, - icon = Icons.Outlined.Sync, - onClick = navigateToAccounts, - ) + if (showAccounts) { + item { + SettingItem( + title = LocalFeedFlowStrings.current.settingsAccounts, + icon = Icons.Outlined.Sync, + onClick = navigateToAccounts, + ) + } } item { @@ -508,6 +516,7 @@ private fun SettingsScreenPreview() { isShowReadItemEnabled = false, isReaderModeEnabled = false, isRemoveTitleFromDescriptionEnabled = false, + showAccounts = true, onFeedListClick = {}, onAddFeedClick = {}, onBrowserSelected = {}, diff --git a/core/src/commonMain/kotlin/com/prof18/feedflow/core/utils/AppConfig.kt b/core/src/commonMain/kotlin/com/prof18/feedflow/core/utils/AppConfig.kt new file mode 100644 index 00000000..5a0fc273 --- /dev/null +++ b/core/src/commonMain/kotlin/com/prof18/feedflow/core/utils/AppConfig.kt @@ -0,0 +1,7 @@ +package com.prof18.feedflow.core.utils + +data class AppConfig( + val appEnvironment: AppEnvironment, + val isLoggingEnabled: Boolean, + val isDropboxSyncEnabled: Boolean, +) diff --git a/shared/src/commonMain/kotlin/com/prof18/feedflow/shared/di/Koin.kt b/shared/src/commonMain/kotlin/com/prof18/feedflow/shared/di/Koin.kt index f61c53d6..efb06d04 100644 --- a/shared/src/commonMain/kotlin/com/prof18/feedflow/shared/di/Koin.kt +++ b/shared/src/commonMain/kotlin/com/prof18/feedflow/shared/di/Koin.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel import co.touchlab.kermit.Logger import co.touchlab.kermit.StaticConfig import co.touchlab.kermit.platformLogWriter +import com.prof18.feedflow.core.utils.AppConfig import com.prof18.feedflow.core.utils.AppEnvironment import com.prof18.feedflow.database.DatabaseHelper import com.prof18.feedflow.feedsync.database.di.getFeedSyncModule @@ -47,7 +48,7 @@ import org.koin.core.scope.Scope import org.koin.dsl.module fun initKoin( - appEnvironment: AppEnvironment, + appConfig: AppConfig, modules: List, platformSetup: KoinApplication.() -> Unit = {}, ): KoinApplication { @@ -56,18 +57,18 @@ fun initKoin( modules + coreModule + dropboxModule + - getLoggingModule(appEnvironment) + - getPlatformModule(appEnvironment) + - getFeedSyncModule(appEnvironment), + getLoggingModule(appConfig) + + getPlatformModule(appConfig.appEnvironment) + + getFeedSyncModule(appConfig.appEnvironment), ) platformSetup() } } -private fun getLoggingModule(appEnvironment: AppEnvironment): Module = +private fun getLoggingModule(appConfig: AppConfig): Module = module { val loggers = mutableListOf(platformLogWriter()) - if (appEnvironment.isRelease()) { + if (appConfig.appEnvironment.isRelease() && appConfig.isLoggingEnabled) { loggers.add(crashReportingLogWriter()) } diff --git a/shared/src/iosMain/kotlin/com/prof18/feedflow/shared/di/KoinIOS.kt b/shared/src/iosMain/kotlin/com/prof18/feedflow/shared/di/KoinIOS.kt index 7de7d8e7..c23c7a67 100644 --- a/shared/src/iosMain/kotlin/com/prof18/feedflow/shared/di/KoinIOS.kt +++ b/shared/src/iosMain/kotlin/com/prof18/feedflow/shared/di/KoinIOS.kt @@ -2,6 +2,7 @@ package com.prof18.feedflow.shared.di import app.cash.sqldelight.db.SqlDriver import co.touchlab.kermit.Logger +import com.prof18.feedflow.core.utils.AppConfig import com.prof18.feedflow.core.utils.AppEnvironment import com.prof18.feedflow.core.utils.DispatcherProvider import com.prof18.feedflow.database.createDatabaseDriver @@ -46,7 +47,11 @@ fun initKoinIos( regionCode: String?, dropboxDataSource: DropboxDataSource, ): KoinApplication = initKoin( - appEnvironment = appEnvironment, + appConfig = AppConfig( + appEnvironment = appEnvironment, + isLoggingEnabled = true, + isDropboxSyncEnabled = true, + ), modules = listOf( module { factory { htmlParser } diff --git a/shared/src/jvmMain/kotlin/com/prof18/feedflow/shared/di/KoinDesktop.kt b/shared/src/jvmMain/kotlin/com/prof18/feedflow/shared/di/KoinDesktop.kt index 59d7ce1d..423e08bf 100644 --- a/shared/src/jvmMain/kotlin/com/prof18/feedflow/shared/di/KoinDesktop.kt +++ b/shared/src/jvmMain/kotlin/com/prof18/feedflow/shared/di/KoinDesktop.kt @@ -1,6 +1,7 @@ package com.prof18.feedflow.shared.di import app.cash.sqldelight.db.SqlDriver +import com.prof18.feedflow.core.utils.AppConfig import com.prof18.feedflow.core.utils.AppEnvironment import com.prof18.feedflow.core.utils.DispatcherProvider import com.prof18.feedflow.database.createDatabaseDriver @@ -26,7 +27,11 @@ fun initKoinDesktop( appEnvironment: AppEnvironment, modules: List, ): KoinApplication = initKoin( - appEnvironment = appEnvironment, + appConfig = AppConfig( + appEnvironment = appEnvironment, + isLoggingEnabled = true, + isDropboxSyncEnabled = true, + ), modules = modules + getDatabaseModule(appEnvironment), )