Code Cleanup and Refactoring

This commit is contained in:
shabinder 2021-08-21 01:06:05 +05:30
parent 399d22c3cc
commit 04dbff4d7f
13 changed files with 136 additions and 126 deletions

View File

@ -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")
}
}
} }
) )

View File

@ -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")

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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)

View File

@ -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,

View File

@ -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
} }

View File

@ -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,

View File

@ -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()
} }
} }
} }

View File

@ -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()))
} }

View File

@ -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()
} }
} }

View File

@ -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
@ -46,30 +47,10 @@ import kotlinx.coroutines.launch
internal class SpotiFlyerRootImpl( internal class SpotiFlyerRootImpl(
componentContext: ComponentContext, componentContext: ComponentContext,
private val main: (ComponentContext, output: Consumer<SpotiFlyerMain.Output>) -> SpotiFlyerMain, dependencies: Dependencies,
private val list: (ComponentContext, link: String, output: Consumer<SpotiFlyerList.Output>) -> SpotiFlyerList, ) : SpotiFlyerRoot, ComponentContext by componentContext, Dependencies by dependencies, Actions by dependencies.actions {
private val preference: (ComponentContext, output: Consumer<SpotiFlyerPreference.Output>) -> SpotiFlyerPreference,
private val actions: Actions,
private val analytics: Analytics
) : SpotiFlyerRoot, ComponentContext by componentContext {
constructor( init {
componentContext: ComponentContext,
dependencies: Dependencies,
) : this(
componentContext = componentContext,
main = { childContext, output ->
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 {}
}
)

View File

@ -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() {