mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 01:04:31 +01:00
Code Cleanup and Refactoring
This commit is contained in:
parent
399d22c3cc
commit
04dbff4d7f
@ -60,7 +60,6 @@ import com.shabinder.common.di.preference.PreferenceManager
|
|||||||
import com.shabinder.common.models.*
|
import com.shabinder.common.models.*
|
||||||
import com.shabinder.common.models.PlatformActions.Companion.SharedPreferencesKey
|
import com.shabinder.common.models.PlatformActions.Companion.SharedPreferencesKey
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Analytics
|
|
||||||
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
||||||
import com.shabinder.common.translations.Strings
|
import com.shabinder.common.translations.Strings
|
||||||
import com.shabinder.common.uikit.configurations.SpotiFlyerTheme
|
import com.shabinder.common.uikit.configurations.SpotiFlyerTheme
|
||||||
@ -78,7 +77,6 @@ import kotlinx.coroutines.flow.emitAll
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
import org.matomo.sdk.extra.TrackHelper
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
@ -94,7 +92,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
private var permissionGranted = mutableStateOf(true)
|
private var permissionGranted = mutableStateOf(true)
|
||||||
private val internetAvailability by lazy { ConnectionLiveData(applicationContext) }
|
private val internetAvailability by lazy { ConnectionLiveData(applicationContext) }
|
||||||
|
|
||||||
private val visibleChild get(): SpotiFlyerRoot.Child = root.routerState.value.activeChild.instance
|
// private val visibleChild get(): SpotiFlyerRoot.Child = root.routerState.value.activeChild.instance
|
||||||
|
|
||||||
// Variable for storing instance of our service class
|
// Variable for storing instance of our service class
|
||||||
var foregroundService: ForegroundService? = null
|
var foregroundService: ForegroundService? = null
|
||||||
@ -139,7 +137,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
AnalyticsDialog(
|
AnalyticsDialog(
|
||||||
askForAnalyticsPermission,
|
askForAnalyticsPermission,
|
||||||
enableAnalytics = {
|
enableAnalytics = {
|
||||||
preferenceManager.toggleAnalytics(true)
|
// preferenceManager.toggleAnalytics(true)
|
||||||
|
analyticsManager.giveConsent()
|
||||||
preferenceManager.firstLaunchDone()
|
preferenceManager.firstLaunchDone()
|
||||||
},
|
},
|
||||||
dismissDialog = {
|
dismissDialog = {
|
||||||
@ -257,6 +256,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
override val fetchQuery = this@MainActivity.fetcher
|
override val fetchQuery = this@MainActivity.fetcher
|
||||||
override val dir: Dir = this@MainActivity.dir
|
override val dir: Dir = this@MainActivity.dir
|
||||||
override val preferenceManager = this@MainActivity.preferenceManager
|
override val preferenceManager = this@MainActivity.preferenceManager
|
||||||
|
override val analyticsManager: AnalyticsManager = this@MainActivity.analyticsManager
|
||||||
override val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>> = trackStatusFlow
|
override val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>> = trackStatusFlow
|
||||||
override val actions = object : Actions {
|
override val actions = object : Actions {
|
||||||
|
|
||||||
@ -329,32 +329,12 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun writeMp3Tags(trackDetails: TrackDetails) { /*IMPLEMENTED*/
|
override fun writeMp3Tags(trackDetails: TrackDetails) {
|
||||||
|
/*IMPLEMENTED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isInternetAvailable get() = internetAvailability.value ?: true
|
override val isInternetAvailable get() = internetAvailability.value ?: true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Analytics Will Only Be Sent if User Granted us the Permission
|
|
||||||
* */
|
|
||||||
override val analytics = object : Analytics {
|
|
||||||
override fun appLaunchEvent() {
|
|
||||||
analyticsManager.sendEvent("app_launch")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun homeScreenVisit() {
|
|
||||||
analyticsManager.sendView("home_screen")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun listScreenVisit() {
|
|
||||||
analyticsManager.sendView("list_screen")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun donationDialogVisit() {
|
|
||||||
analyticsManager.sendEvent("open_donation_dialog")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,7 +11,14 @@ interface AnalyticsManager {
|
|||||||
fun revokeConsent()
|
fun revokeConsent()
|
||||||
fun sendView(name: String, extras: Map<String, Any> = emptyMap())
|
fun sendView(name: String, extras: Map<String, Any> = emptyMap())
|
||||||
fun sendEvent(eventName: String, extras: Map<String, Any> = emptyMap())
|
fun sendEvent(eventName: String, extras: Map<String, Any> = emptyMap())
|
||||||
|
fun track(event: AnalyticsAction) = event.track(this)
|
||||||
fun sendCrashReport(error: Throwable, extras: Map<String, Any> = emptyMap())
|
fun sendCrashReport(error: Throwable, extras: Map<String, Any> = emptyMap())
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
abstract class AnalyticsAction {
|
||||||
|
abstract fun track(analyticsManager: AnalyticsManager)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ClassName", "SpellCheckingInspection")
|
@Suppress("ClassName", "SpellCheckingInspection")
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.shabinder.common.di.analytics
|
||||||
|
|
||||||
|
sealed class AnalyticsEvent(private val eventName: String, private val extras: Map<String, Any> = emptyMap()): AnalyticsManager.Companion.AnalyticsAction() {
|
||||||
|
|
||||||
|
override fun track(analyticsManager: AnalyticsManager) = analyticsManager.sendEvent(eventName,extras)
|
||||||
|
|
||||||
|
object AppLaunch: AnalyticsEvent("app_launch")
|
||||||
|
object DonationDialogOpen: AnalyticsEvent("donation_dialog_open")
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.shabinder.common.di.analytics
|
||||||
|
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsManager.Companion.AnalyticsAction
|
||||||
|
|
||||||
|
sealed class AnalyticsView(private val viewName: String, private val extras: Map<String, Any> = emptyMap()) : AnalyticsAction() {
|
||||||
|
override fun track(analyticsManager: AnalyticsManager) = analyticsManager.sendView(viewName,extras)
|
||||||
|
|
||||||
|
object HomeScreen: AnalyticsView("home_screen")
|
||||||
|
object ListScreen: AnalyticsView("list_screen")
|
||||||
|
}
|
@ -3,7 +3,9 @@ package com.shabinder.common.di.preference
|
|||||||
import com.russhwolf.settings.Settings
|
import com.russhwolf.settings.Settings
|
||||||
import com.shabinder.common.models.AudioQuality
|
import com.shabinder.common.models.AudioQuality
|
||||||
|
|
||||||
class PreferenceManager(settings: Settings) : Settings by settings {
|
class PreferenceManager(
|
||||||
|
settings: Settings
|
||||||
|
) : Settings by settings {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DIR_KEY = "downloadDir"
|
const val DIR_KEY = "downloadDir"
|
||||||
@ -14,8 +16,8 @@ class PreferenceManager(settings: Settings) : Settings by settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ANALYTICS */
|
/* ANALYTICS */
|
||||||
// val isAnalyticsEnabled get() = getBooleanOrNull(ANALYTICS_KEY) ?: false
|
val isAnalyticsEnabled get() = getBooleanOrNull(ANALYTICS_KEY) ?: false
|
||||||
// fun toggleAnalytics(enabled: Boolean) = putBoolean(ANALYTICS_KEY, enabled)
|
fun toggleAnalytics(enabled: Boolean) = putBoolean(ANALYTICS_KEY, enabled)
|
||||||
|
|
||||||
/* DOWNLOAD DIRECTORY */
|
/* DOWNLOAD DIRECTORY */
|
||||||
val downloadDir get() = getStringOrNull(DIR_KEY)
|
val downloadDir get() = getStringOrNull(DIR_KEY)
|
||||||
|
@ -25,6 +25,7 @@ import com.shabinder.common.di.Dir
|
|||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
import com.shabinder.common.di.downloadTracks
|
import com.shabinder.common.di.downloadTracks
|
||||||
import com.shabinder.common.di.preference.PreferenceManager
|
import com.shabinder.common.di.preference.PreferenceManager
|
||||||
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.list.SpotiFlyerList.State
|
import com.shabinder.common.list.SpotiFlyerList.State
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
@ -34,14 +35,7 @@ import com.shabinder.common.models.methods
|
|||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
|
|
||||||
internal class SpotiFlyerListStoreProvider(
|
internal class SpotiFlyerListStoreProvider(dependencies: SpotiFlyerList.Dependencies): SpotiFlyerList.Dependencies by dependencies {
|
||||||
private val dir: Dir,
|
|
||||||
private val preferenceManager: PreferenceManager,
|
|
||||||
private val storeFactory: StoreFactory,
|
|
||||||
private val fetchQuery: FetchPlatformQueryResult,
|
|
||||||
private val link: String,
|
|
||||||
private val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>>
|
|
||||||
) {
|
|
||||||
fun provide(): SpotiFlyerListStore =
|
fun provide(): SpotiFlyerListStore =
|
||||||
object :
|
object :
|
||||||
SpotiFlyerListStore,
|
SpotiFlyerListStore,
|
||||||
|
@ -21,6 +21,7 @@ import com.arkivanov.decompose.value.Value
|
|||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.Picture
|
import com.shabinder.common.di.Picture
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsManager
|
||||||
import com.shabinder.common.di.preference.PreferenceManager
|
import com.shabinder.common.di.preference.PreferenceManager
|
||||||
import com.shabinder.common.main.integration.SpotiFlyerMainImpl
|
import com.shabinder.common.main.integration.SpotiFlyerMainImpl
|
||||||
import com.shabinder.common.models.Consumer
|
import com.shabinder.common.models.Consumer
|
||||||
@ -67,6 +68,7 @@ interface SpotiFlyerMain {
|
|||||||
val database: Database?
|
val database: Database?
|
||||||
val dir: Dir
|
val dir: Dir
|
||||||
val preferenceManager: PreferenceManager
|
val preferenceManager: PreferenceManager
|
||||||
|
val analyticsManager: AnalyticsManager
|
||||||
val mainAnalytics: Analytics
|
val mainAnalytics: Analytics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,13 +41,14 @@ internal class SpotiFlyerMainImpl(
|
|||||||
init {
|
init {
|
||||||
instanceKeeper.ensureNeverFrozen()
|
instanceKeeper.ensureNeverFrozen()
|
||||||
lifecycle.doOnResume {
|
lifecycle.doOnResume {
|
||||||
store.accept(Intent.ToggleAnalytics(preferenceManager.isAnalyticsEnabled))
|
store.accept(Intent.ToggleAnalytics(analyticsManager.isTracking()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val store =
|
private val store =
|
||||||
instanceKeeper.getStore {
|
instanceKeeper.getStore {
|
||||||
SpotiFlyerMainStoreProvider(
|
SpotiFlyerMainStoreProvider(
|
||||||
|
analyticsManager = analyticsManager,
|
||||||
preferenceManager = preferenceManager,
|
preferenceManager = preferenceManager,
|
||||||
storeFactory = storeFactory,
|
storeFactory = storeFactory,
|
||||||
database = database,
|
database = database,
|
||||||
|
@ -22,6 +22,7 @@ import com.arkivanov.mvikotlin.core.store.Store
|
|||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsManager
|
||||||
import com.shabinder.common.di.preference.PreferenceManager
|
import com.shabinder.common.di.preference.PreferenceManager
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
import com.shabinder.common.main.SpotiFlyerMain.State
|
import com.shabinder.common.main.SpotiFlyerMain.State
|
||||||
@ -36,12 +37,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
internal class SpotiFlyerMainStoreProvider(
|
internal class SpotiFlyerMainStoreProvider(dependencies: SpotiFlyerMain.Dependencies): SpotiFlyerMain.Dependencies by dependencies {
|
||||||
private val storeFactory: StoreFactory,
|
|
||||||
private val preferenceManager: PreferenceManager,
|
|
||||||
private val dir: Dir,
|
|
||||||
database: Database?
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun provide(): SpotiFlyerMainStore =
|
fun provide(): SpotiFlyerMainStore =
|
||||||
object :
|
object :
|
||||||
@ -76,7 +72,7 @@ internal class SpotiFlyerMainStoreProvider(
|
|||||||
|
|
||||||
private inner class ExecutorImpl : SuspendExecutor<Intent, Unit, State, Result, Nothing>() {
|
private inner class ExecutorImpl : SuspendExecutor<Intent, Unit, State, Result, Nothing>() {
|
||||||
override suspend fun executeAction(action: Unit, getState: () -> State) {
|
override suspend fun executeAction(action: Unit, getState: () -> State) {
|
||||||
dispatch(Result.AnalyticsToggled(preferenceManager.isAnalyticsEnabled))
|
dispatch(Result.AnalyticsToggled(analyticsManager.isTracking()))
|
||||||
updates?.collect {
|
updates?.collect {
|
||||||
dispatch(Result.ItemsLoaded(it))
|
dispatch(Result.ItemsLoaded(it))
|
||||||
}
|
}
|
||||||
@ -91,7 +87,7 @@ internal class SpotiFlyerMainStoreProvider(
|
|||||||
is Intent.SelectCategory -> dispatch(Result.CategoryChanged(intent.category))
|
is Intent.SelectCategory -> dispatch(Result.CategoryChanged(intent.category))
|
||||||
is Intent.ToggleAnalytics -> {
|
is Intent.ToggleAnalytics -> {
|
||||||
dispatch(Result.AnalyticsToggled(intent.enabled))
|
dispatch(Result.AnalyticsToggled(intent.enabled))
|
||||||
preferenceManager.toggleAnalytics(intent.enabled)
|
analyticsManager.giveConsent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.arkivanov.mvikotlin.core.store.Store
|
|||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsManager
|
||||||
import com.shabinder.common.di.preference.PreferenceManager
|
import com.shabinder.common.di.preference.PreferenceManager
|
||||||
import com.shabinder.common.models.Actions
|
import com.shabinder.common.models.Actions
|
||||||
import com.shabinder.common.models.AudioQuality
|
import com.shabinder.common.models.AudioQuality
|
||||||
@ -31,6 +32,7 @@ import com.shabinder.common.preference.store.SpotiFlyerPreferenceStore.Intent
|
|||||||
|
|
||||||
internal class SpotiFlyerPreferenceStoreProvider(
|
internal class SpotiFlyerPreferenceStoreProvider(
|
||||||
private val storeFactory: StoreFactory,
|
private val storeFactory: StoreFactory,
|
||||||
|
private val analyticsManager: AnalyticsManager,
|
||||||
private val preferenceManager: PreferenceManager,
|
private val preferenceManager: PreferenceManager,
|
||||||
private val dir: Dir,
|
private val dir: Dir,
|
||||||
private val actions: Actions
|
private val actions: Actions
|
||||||
@ -55,7 +57,7 @@ internal class SpotiFlyerPreferenceStoreProvider(
|
|||||||
|
|
||||||
private inner class ExecutorImpl : SuspendExecutor<Intent, Unit, State, Result, Nothing>() {
|
private inner class ExecutorImpl : SuspendExecutor<Intent, Unit, State, Result, Nothing>() {
|
||||||
override suspend fun executeAction(action: Unit, getState: () -> State) {
|
override suspend fun executeAction(action: Unit, getState: () -> State) {
|
||||||
dispatch(Result.AnalyticsToggled(preferenceManager.isAnalyticsEnabled))
|
dispatch(Result.AnalyticsToggled(analyticsManager.isTracking()))
|
||||||
dispatch(Result.PreferredAudioQualityChanged(preferenceManager.audioQuality))
|
dispatch(Result.PreferredAudioQualityChanged(preferenceManager.audioQuality))
|
||||||
dispatch(Result.DownloadPathSet(dir.defaultDir()))
|
dispatch(Result.DownloadPathSet(dir.defaultDir()))
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ import com.arkivanov.decompose.value.Value
|
|||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsEvent
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsManager
|
||||||
import com.shabinder.common.di.preference.PreferenceManager
|
import com.shabinder.common.di.preference.PreferenceManager
|
||||||
import com.shabinder.common.list.SpotiFlyerList
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
@ -55,16 +57,9 @@ interface SpotiFlyerRoot {
|
|||||||
val fetchQuery: FetchPlatformQueryResult
|
val fetchQuery: FetchPlatformQueryResult
|
||||||
val dir: Dir
|
val dir: Dir
|
||||||
val preferenceManager: PreferenceManager
|
val preferenceManager: PreferenceManager
|
||||||
|
val analyticsManager: AnalyticsManager
|
||||||
val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>>
|
val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>>
|
||||||
val actions: Actions
|
val actions: Actions
|
||||||
val analytics: Analytics
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Analytics {
|
|
||||||
fun appLaunchEvent()
|
|
||||||
fun homeScreenVisit()
|
|
||||||
fun listScreenVisit()
|
|
||||||
fun donationDialogVisit()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,11 @@ import com.arkivanov.decompose.pop
|
|||||||
import com.arkivanov.decompose.popWhile
|
import com.arkivanov.decompose.popWhile
|
||||||
import com.arkivanov.decompose.push
|
import com.arkivanov.decompose.push
|
||||||
import com.arkivanov.decompose.router
|
import com.arkivanov.decompose.router
|
||||||
import com.arkivanov.decompose.statekeeper.Parcelable
|
|
||||||
import com.arkivanov.decompose.statekeeper.Parcelize
|
|
||||||
import com.arkivanov.decompose.value.Value
|
import com.arkivanov.decompose.value.Value
|
||||||
|
import com.arkivanov.essenty.parcelable.Parcelable
|
||||||
|
import com.arkivanov.essenty.parcelable.Parcelize
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsEvent
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsView
|
||||||
import com.shabinder.common.di.dispatcherIO
|
import com.shabinder.common.di.dispatcherIO
|
||||||
import com.shabinder.common.list.SpotiFlyerList
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
@ -35,7 +37,6 @@ import com.shabinder.common.models.Consumer
|
|||||||
import com.shabinder.common.models.methods
|
import com.shabinder.common.models.methods
|
||||||
import com.shabinder.common.preference.SpotiFlyerPreference
|
import com.shabinder.common.preference.SpotiFlyerPreference
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Analytics
|
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
|
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
|
||||||
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
||||||
@ -45,31 +46,11 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
internal class SpotiFlyerRootImpl(
|
internal class SpotiFlyerRootImpl(
|
||||||
componentContext: ComponentContext,
|
|
||||||
private val main: (ComponentContext, output: Consumer<SpotiFlyerMain.Output>) -> SpotiFlyerMain,
|
|
||||||
private val list: (ComponentContext, link: String, output: Consumer<SpotiFlyerList.Output>) -> SpotiFlyerList,
|
|
||||||
private val preference: (ComponentContext, output: Consumer<SpotiFlyerPreference.Output>) -> SpotiFlyerPreference,
|
|
||||||
private val actions: Actions,
|
|
||||||
private val analytics: Analytics
|
|
||||||
) : SpotiFlyerRoot, ComponentContext by componentContext {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
componentContext: ComponentContext,
|
componentContext: ComponentContext,
|
||||||
dependencies: Dependencies,
|
dependencies: Dependencies,
|
||||||
) : this(
|
) : SpotiFlyerRoot, ComponentContext by componentContext, Dependencies by dependencies, Actions by dependencies.actions {
|
||||||
componentContext = componentContext,
|
|
||||||
main = { childContext, output ->
|
init {
|
||||||
spotiFlyerMain(childContext, output, dependencies)
|
|
||||||
},
|
|
||||||
list = { childContext, link, output ->
|
|
||||||
spotiFlyerList(childContext, link, output, dependencies)
|
|
||||||
},
|
|
||||||
preference = { childContext, output ->
|
|
||||||
spotiFlyerPreference(childContext, output, dependencies)
|
|
||||||
},
|
|
||||||
actions = dependencies.actions.freeze(),
|
|
||||||
analytics = dependencies.analytics
|
|
||||||
) {
|
|
||||||
instanceKeeper.ensureNeverFrozen()
|
instanceKeeper.ensureNeverFrozen()
|
||||||
methods.value = dependencies.actions.freeze()
|
methods.value = dependencies.actions.freeze()
|
||||||
|
|
||||||
@ -102,21 +83,85 @@ internal class SpotiFlyerRootImpl(
|
|||||||
router.push(Configuration.Preference)
|
router.push(Configuration.Preference)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showToast(text: String) { toastState.value = text }
|
override fun showToast(text: String) {
|
||||||
|
toastState.value = text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createChild(configuration: Configuration, componentContext: ComponentContext): Child =
|
private fun createChild(
|
||||||
|
configuration: Configuration,
|
||||||
|
componentContext: ComponentContext,
|
||||||
|
): Child =
|
||||||
when (configuration) {
|
when (configuration) {
|
||||||
is Configuration.Main -> Child.Main(main(componentContext, Consumer(::onMainOutput)))
|
is Configuration.Main -> Child.Main(
|
||||||
is Configuration.List -> Child.List(list(componentContext, configuration.link, Consumer(::onListOutput)))
|
spotiFlyerMain(
|
||||||
is Configuration.Preference -> Child.Preference(preference(componentContext, Consumer(::onPreferenceOutput)),)
|
componentContext,
|
||||||
|
Consumer(::onMainOutput),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
is Configuration.List -> Child.List(
|
||||||
|
spotiFlyerList(
|
||||||
|
componentContext,
|
||||||
|
configuration.link,
|
||||||
|
Consumer(::onListOutput),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
is Configuration.Preference -> Child.Preference(
|
||||||
|
spotiFlyerPreference(
|
||||||
|
componentContext,
|
||||||
|
Consumer(::onPreferenceOutput),
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun spotiFlyerMain(
|
||||||
|
componentContext: ComponentContext,
|
||||||
|
output: Consumer<SpotiFlyerMain.Output>,
|
||||||
|
): SpotiFlyerMain =
|
||||||
|
SpotiFlyerMain(
|
||||||
|
componentContext = componentContext,
|
||||||
|
dependencies = object : SpotiFlyerMain.Dependencies, Dependencies by this {
|
||||||
|
override val mainOutput: Consumer<SpotiFlyerMain.Output> = output
|
||||||
|
override val mainAnalytics = object : SpotiFlyerMain.Analytics {
|
||||||
|
override fun donationDialogVisit() {
|
||||||
|
AnalyticsEvent.DonationDialogOpen.track(analyticsManager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun spotiFlyerList(
|
||||||
|
componentContext: ComponentContext,
|
||||||
|
link: String,
|
||||||
|
output: Consumer<SpotiFlyerList.Output>
|
||||||
|
): SpotiFlyerList =
|
||||||
|
SpotiFlyerList(
|
||||||
|
componentContext = componentContext,
|
||||||
|
dependencies = object : SpotiFlyerList.Dependencies, Dependencies by this {
|
||||||
|
override val link: String = link
|
||||||
|
override val listOutput: Consumer<SpotiFlyerList.Output> = output
|
||||||
|
override val listAnalytics = object : SpotiFlyerList.Analytics {}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun spotiFlyerPreference(
|
||||||
|
componentContext: ComponentContext,
|
||||||
|
output: Consumer<SpotiFlyerPreference.Output>
|
||||||
|
): SpotiFlyerPreference =
|
||||||
|
SpotiFlyerPreference(
|
||||||
|
componentContext = componentContext,
|
||||||
|
dependencies = object : SpotiFlyerPreference.Dependencies, Dependencies by this {
|
||||||
|
override val prefOutput: Consumer<SpotiFlyerPreference.Output> = output
|
||||||
|
override val preferenceAnalytics = object : SpotiFlyerPreference.Analytics {}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
private fun onMainOutput(output: SpotiFlyerMain.Output) =
|
private fun onMainOutput(output: SpotiFlyerMain.Output) =
|
||||||
when (output) {
|
when (output) {
|
||||||
is SpotiFlyerMain.Output.Search -> {
|
is SpotiFlyerMain.Output.Search -> {
|
||||||
router.push(Configuration.List(link = output.link))
|
router.push(Configuration.List(link = output.link))
|
||||||
analytics.listScreenVisit()
|
AnalyticsView.ListScreen.track(analyticsManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +171,10 @@ internal class SpotiFlyerRootImpl(
|
|||||||
if (router.state.value.activeChild.instance is Child.List && router.state.value.backStack.isNotEmpty()) {
|
if (router.state.value.activeChild.instance is Child.List && router.state.value.backStack.isNotEmpty()) {
|
||||||
router.pop()
|
router.pop()
|
||||||
}
|
}
|
||||||
analytics.homeScreenVisit()
|
AnalyticsView.HomeScreen.track(analyticsManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onPreferenceOutput(output: SpotiFlyerPreference.Output): Unit =
|
private fun onPreferenceOutput(output: SpotiFlyerPreference.Output): Unit =
|
||||||
when (output) {
|
when (output) {
|
||||||
is SpotiFlyerPreference.Output.Finished -> {
|
is SpotiFlyerPreference.Output.Finished -> {
|
||||||
@ -142,7 +188,7 @@ internal class SpotiFlyerRootImpl(
|
|||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
private fun initAppLaunchAndAuthenticateSpotify(authenticator: suspend () -> Unit) {
|
private fun initAppLaunchAndAuthenticateSpotify(authenticator: suspend () -> Unit) {
|
||||||
GlobalScope.launch(dispatcherIO) {
|
GlobalScope.launch(dispatcherIO) {
|
||||||
analytics.appLaunchEvent()
|
AnalyticsEvent.AppLaunch.track(analyticsManager)
|
||||||
/*Authenticate Spotify Client*/
|
/*Authenticate Spotify Client*/
|
||||||
authenticator()
|
authenticator()
|
||||||
}
|
}
|
||||||
@ -159,31 +205,3 @@ internal class SpotiFlyerRootImpl(
|
|||||||
data class List(val link: String) : Configuration()
|
data class List(val link: String) : Configuration()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun spotiFlyerMain(componentContext: ComponentContext, output: Consumer<SpotiFlyerMain.Output>, dependencies: Dependencies): SpotiFlyerMain =
|
|
||||||
SpotiFlyerMain(
|
|
||||||
componentContext = componentContext,
|
|
||||||
dependencies = object : SpotiFlyerMain.Dependencies, Dependencies by dependencies {
|
|
||||||
override val mainOutput: Consumer<SpotiFlyerMain.Output> = output
|
|
||||||
override val mainAnalytics = object : SpotiFlyerMain.Analytics, Analytics by analytics {}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun spotiFlyerList(componentContext: ComponentContext, link: String, output: Consumer<SpotiFlyerList.Output>, dependencies: Dependencies): SpotiFlyerList =
|
|
||||||
SpotiFlyerList(
|
|
||||||
componentContext = componentContext,
|
|
||||||
dependencies = object : SpotiFlyerList.Dependencies, Dependencies by dependencies {
|
|
||||||
override val link: String = link
|
|
||||||
override val listOutput: Consumer<SpotiFlyerList.Output> = output
|
|
||||||
override val listAnalytics = object : SpotiFlyerList.Analytics, Analytics by analytics {}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun spotiFlyerPreference(componentContext: ComponentContext, output: Consumer<SpotiFlyerPreference.Output>, dependencies: Dependencies): SpotiFlyerPreference =
|
|
||||||
SpotiFlyerPreference(
|
|
||||||
componentContext = componentContext,
|
|
||||||
dependencies = object : SpotiFlyerPreference.Dependencies, Dependencies by dependencies {
|
|
||||||
override val prefOutput: Consumer<SpotiFlyerPreference.Output> = output
|
|
||||||
override val preferenceAnalytics = object : SpotiFlyerPreference.Analytics, Analytics by analytics {}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
@ -30,6 +30,7 @@ import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
|
|||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.DownloadProgressFlow
|
import com.shabinder.common.di.DownloadProgressFlow
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
|
import com.shabinder.common.di.analytics.AnalyticsManager
|
||||||
import com.shabinder.common.di.initKoin
|
import com.shabinder.common.di.initKoin
|
||||||
import com.shabinder.common.di.isInternetAccessible
|
import com.shabinder.common.di.isInternetAccessible
|
||||||
import com.shabinder.common.di.preference.PreferenceManager
|
import com.shabinder.common.di.preference.PreferenceManager
|
||||||
@ -58,9 +59,6 @@ import javax.swing.JFileChooser.APPROVE_OPTION
|
|||||||
|
|
||||||
private val koin = initKoin(enableNetworkLogs = true).koin
|
private val koin = initKoin(enableNetworkLogs = true).koin
|
||||||
private lateinit var showToast: (String) -> Unit
|
private lateinit var showToast: (String) -> Unit
|
||||||
private val tracker: PiwikTracker by lazy {
|
|
||||||
PiwikTracker("https://matomo.spotiflyer.ml/matomo.php")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
|
||||||
@ -96,6 +94,7 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
|
|||||||
override val dir: Dir = koin.get()
|
override val dir: Dir = koin.get()
|
||||||
override val database: Database? = dir.db
|
override val database: Database? = dir.db
|
||||||
override val preferenceManager: PreferenceManager = koin.get()
|
override val preferenceManager: PreferenceManager = koin.get()
|
||||||
|
override val analyticsManager: AnalyticsManager = koin.get()
|
||||||
override val downloadProgressFlow = DownloadProgressFlow
|
override val downloadProgressFlow = DownloadProgressFlow
|
||||||
override val actions: Actions = object : Actions {
|
override val actions: Actions = object : Actions {
|
||||||
override val platformActions = object : PlatformActions {}
|
override val platformActions = object : PlatformActions {}
|
||||||
@ -159,14 +158,9 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
|
|||||||
override fun appLaunchEvent() {
|
override fun appLaunchEvent() {
|
||||||
if (preferenceManager.isFirstLaunch) {
|
if (preferenceManager.isFirstLaunch) {
|
||||||
// Enable Analytics on First Launch
|
// Enable Analytics on First Launch
|
||||||
preferenceManager.toggleAnalytics(true)
|
analyticsManager.giveConsent()
|
||||||
preferenceManager.firstLaunchDone()
|
preferenceManager.firstLaunchDone()
|
||||||
}
|
}
|
||||||
tracker.trackAsync {
|
|
||||||
eventName = "App Launch"
|
|
||||||
eventAction = "App_Launch"
|
|
||||||
eventCategory = "events"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun homeScreenVisit() {
|
override fun homeScreenVisit() {
|
||||||
|
Loading…
Reference in New Issue
Block a user