mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 17:14:32 +01:00
Analytics Row and Toggle Added
This commit is contained in:
parent
f52a0b9ab9
commit
6252a5b18c
@ -125,7 +125,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
AnalyticsDialog(
|
AnalyticsDialog(
|
||||||
askForAnalyticsPermission,
|
askForAnalyticsPermission,
|
||||||
enableAnalytics = {
|
enableAnalytics = {
|
||||||
dir.enableAnalytics()
|
dir.toggleAnalytics(true)
|
||||||
dir.firstLaunchDone()
|
dir.firstLaunchDone()
|
||||||
},
|
},
|
||||||
dismissDialog = {
|
dismissDialog = {
|
||||||
|
@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.AlertDialog
|
import androidx.compose.material.AlertDialog
|
||||||
|
import androidx.compose.material.ButtonDefaults
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.OutlinedButton
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextButton
|
import androidx.compose.material.TextButton
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@ -42,31 +44,38 @@ fun AnalyticsDialog(
|
|||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = dismissDialog,
|
onDismissRequest = dismissDialog,
|
||||||
title = {
|
title = {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.SpaceBetween) {
|
Row(verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
Icon(Icons.Rounded.Insights,"Analytics", Modifier.size(32.dp))
|
Icon(Icons.Rounded.Insights,"Analytics", Modifier.size(42.dp))
|
||||||
Spacer(Modifier.padding(horizontal = 8.dp))
|
Spacer(Modifier.padding(horizontal = 8.dp))
|
||||||
Text("Grant Analytics",style = SpotiFlyerTypography.h5,textAlign = TextAlign.Center)
|
Text("Grant Analytics",style = SpotiFlyerTypography.h5,textAlign = TextAlign.Center)
|
||||||
Spacer(Modifier.padding(horizontal = 8.dp))
|
|
||||||
Column {
|
|
||||||
Icon(Icons.Rounded.Close,"Decline Analytics", Modifier.size(24.dp).clickable {
|
|
||||||
dismissDialog()
|
|
||||||
})
|
|
||||||
Spacer(Modifier.padding(vertical = 8.dp))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
backgroundColor = Color.DarkGray,
|
backgroundColor = Color.DarkGray,
|
||||||
buttons = {
|
buttons = {
|
||||||
TextButton(
|
Column {
|
||||||
{
|
OutlinedButton(
|
||||||
dismissDialog()
|
onClick = dismissDialog,
|
||||||
enableAnalytics()
|
Modifier.padding(horizontal = 8.dp).fillMaxWidth()
|
||||||
},
|
.background(Color.DarkGray, shape = SpotiFlyerShapes.medium)
|
||||||
Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp).fillMaxWidth()
|
.padding(horizontal = 8.dp),
|
||||||
.background(colorPrimary, shape = SpotiFlyerShapes.medium)
|
shape = SpotiFlyerShapes.medium,
|
||||||
.padding(horizontal = 8.dp),
|
colors = ButtonDefaults.buttonColors(backgroundColor = Color(0xFF303030))
|
||||||
) {
|
) {
|
||||||
Text("Sure!",color = Color.Black,fontSize = 18.sp,textAlign = TextAlign.Center)
|
Text("Nope",color = colorPrimary,fontSize = 18.sp,textAlign = TextAlign.Center)
|
||||||
|
}
|
||||||
|
Spacer(Modifier.padding(vertical = 4.dp))
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
dismissDialog()
|
||||||
|
enableAnalytics()
|
||||||
|
},
|
||||||
|
Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp).fillMaxWidth()
|
||||||
|
.background(colorPrimary, shape = SpotiFlyerShapes.medium)
|
||||||
|
.padding(horizontal = 8.dp),
|
||||||
|
shape = SpotiFlyerShapes.medium
|
||||||
|
) {
|
||||||
|
Text("Sure",color = Color.Black,fontSize = 18.sp,textAlign = TextAlign.Center)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
|
@ -46,6 +46,8 @@ import androidx.compose.material.Card
|
|||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.OutlinedButton
|
import androidx.compose.material.OutlinedButton
|
||||||
|
import androidx.compose.material.Switch
|
||||||
|
import androidx.compose.material.SwitchDefaults
|
||||||
import androidx.compose.material.Tab
|
import androidx.compose.material.Tab
|
||||||
import androidx.compose.material.TabPosition
|
import androidx.compose.material.TabPosition
|
||||||
import androidx.compose.material.TabRow
|
import androidx.compose.material.TabRow
|
||||||
@ -59,6 +61,7 @@ import androidx.compose.material.icons.outlined.Info
|
|||||||
import androidx.compose.material.icons.rounded.CardGiftcard
|
import androidx.compose.material.icons.rounded.CardGiftcard
|
||||||
import androidx.compose.material.icons.rounded.Edit
|
import androidx.compose.material.icons.rounded.Edit
|
||||||
import androidx.compose.material.icons.rounded.Flag
|
import androidx.compose.material.icons.rounded.Flag
|
||||||
|
import androidx.compose.material.icons.rounded.Insights
|
||||||
import androidx.compose.material.icons.rounded.Share
|
import androidx.compose.material.icons.rounded.Share
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@ -102,7 +105,11 @@ fun SpotiFlyerMainContent(component: SpotiFlyerMain) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
when (model.selectedCategory) {
|
when (model.selectedCategory) {
|
||||||
HomeCategory.About -> AboutColumn { component.analytics.donationDialogVisit() }
|
HomeCategory.About -> AboutColumn(
|
||||||
|
analyticsEnabled = model.isAnalyticsEnabled,
|
||||||
|
donationDialogOpenEvent = { component.analytics.donationDialogVisit() },
|
||||||
|
toggleAnalytics = component::toggleAnalytics
|
||||||
|
)
|
||||||
HomeCategory.History -> HistoryColumn(
|
HomeCategory.History -> HistoryColumn(
|
||||||
model.records.sortedByDescending { it.id },
|
model.records.sortedByDescending { it.id },
|
||||||
component::loadImage,
|
component::loadImage,
|
||||||
@ -223,7 +230,9 @@ fun SearchPanel(
|
|||||||
@Composable
|
@Composable
|
||||||
fun AboutColumn(
|
fun AboutColumn(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
donationDialogOpenEvent: () -> Unit
|
analyticsEnabled:Boolean,
|
||||||
|
donationDialogOpenEvent: () -> Unit,
|
||||||
|
toggleAnalytics: (enabled: Boolean) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Box {
|
Box {
|
||||||
@ -398,6 +407,35 @@ fun AboutColumn(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
||||||
|
.clickable(
|
||||||
|
onClick = {
|
||||||
|
toggleAnalytics(!analyticsEnabled)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(Icons.Rounded.Insights, "Analytics Status", Modifier.size(32.dp))
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column(
|
||||||
|
Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Analytics",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Your Data is Anonymized and never shared with 3rd party service",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Switch(
|
||||||
|
checked = analyticsEnabled,
|
||||||
|
onCheckedChange = null,
|
||||||
|
colors = SwitchDefaults.colors(uncheckedThumbColor = colorOffWhite)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ expect class Dir(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val Dir.isAnalyticsEnabled get() = settings.getBooleanOrNull(AnalyticsKey) ?: false
|
val Dir.isAnalyticsEnabled get() = settings.getBooleanOrNull(AnalyticsKey) ?: false
|
||||||
fun Dir.enableAnalytics() = settings.putBoolean(AnalyticsKey, true)
|
fun Dir.toggleAnalytics(enabled: Boolean) = settings.putBoolean(AnalyticsKey, enabled)
|
||||||
|
|
||||||
fun Dir.setDownloadDirectory(newBasePath: String) = settings.putString(DirKey, newBasePath)
|
fun Dir.setDownloadDirectory(newBasePath: String) = settings.putString(DirKey, newBasePath)
|
||||||
|
|
||||||
|
@ -48,6 +48,11 @@ interface SpotiFlyerMain {
|
|||||||
* */
|
* */
|
||||||
fun selectCategory(category: HomeCategory)
|
fun selectCategory(category: HomeCategory)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* change TabBar Selected Category
|
||||||
|
* */
|
||||||
|
fun toggleAnalytics(enabled: Boolean)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load Image from cache/Internet and cache it
|
* Load Image from cache/Internet and cache it
|
||||||
* */
|
* */
|
||||||
@ -72,7 +77,8 @@ interface SpotiFlyerMain {
|
|||||||
data class State(
|
data class State(
|
||||||
val records: List<DownloadRecord> = emptyList(),
|
val records: List<DownloadRecord> = emptyList(),
|
||||||
val link: String = "",
|
val link: String = "",
|
||||||
val selectedCategory: HomeCategory = HomeCategory.About
|
val selectedCategory: HomeCategory = HomeCategory.About,
|
||||||
|
val isAnalyticsEnabled: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class HomeCategory {
|
enum class HomeCategory {
|
||||||
|
@ -45,7 +45,8 @@ internal class SpotiFlyerMainImpl(
|
|||||||
instanceKeeper.getStore {
|
instanceKeeper.getStore {
|
||||||
SpotiFlyerMainStoreProvider(
|
SpotiFlyerMainStoreProvider(
|
||||||
storeFactory = storeFactory,
|
storeFactory = storeFactory,
|
||||||
database = database
|
database = database,
|
||||||
|
dir = dir
|
||||||
).provide()
|
).provide()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +72,10 @@ internal class SpotiFlyerMainImpl(
|
|||||||
store.accept(Intent.SelectCategory(category))
|
store.accept(Intent.SelectCategory(category))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toggleAnalytics(enabled: Boolean) {
|
||||||
|
store.accept(Intent.ToggleAnalytics(enabled))
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun loadImage(url: String): Picture {
|
override suspend fun loadImage(url: String): Picture {
|
||||||
return cache.get(url) {
|
return cache.get(url) {
|
||||||
dir.loadImage(url, 150, 150)
|
dir.loadImage(url, 150, 150)
|
||||||
|
@ -25,6 +25,7 @@ internal interface SpotiFlyerMainStore : Store<Intent, SpotiFlyerMain.State, Not
|
|||||||
data class OpenPlatform(val platformID: String, val platformLink: String) : Intent()
|
data class OpenPlatform(val platformID: String, val platformLink: String) : Intent()
|
||||||
data class SetLink(val link: String) : Intent()
|
data class SetLink(val link: String) : Intent()
|
||||||
data class SelectCategory(val category: SpotiFlyerMain.HomeCategory) : Intent()
|
data class SelectCategory(val category: SpotiFlyerMain.HomeCategory) : Intent()
|
||||||
|
data class ToggleAnalytics(val enabled: Boolean) : Intent()
|
||||||
object GiveDonation : Intent()
|
object GiveDonation : Intent()
|
||||||
object ShareApp : Intent()
|
object ShareApp : Intent()
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ import com.arkivanov.mvikotlin.core.store.SimpleBootstrapper
|
|||||||
import com.arkivanov.mvikotlin.core.store.Store
|
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.isAnalyticsEnabled
|
||||||
|
import com.shabinder.common.di.toggleAnalytics
|
||||||
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
|
||||||
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
||||||
@ -36,7 +39,8 @@ import kotlinx.coroutines.flow.map
|
|||||||
|
|
||||||
internal class SpotiFlyerMainStoreProvider(
|
internal class SpotiFlyerMainStoreProvider(
|
||||||
private val storeFactory: StoreFactory,
|
private val storeFactory: StoreFactory,
|
||||||
private val database: Database?
|
private val dir: Dir,
|
||||||
|
database: Database?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun provide(): SpotiFlyerMainStore =
|
fun provide(): SpotiFlyerMainStore =
|
||||||
@ -67,10 +71,12 @@ internal class SpotiFlyerMainStoreProvider(
|
|||||||
data class ItemsLoaded(val items: List<DownloadRecord>) : Result()
|
data class ItemsLoaded(val items: List<DownloadRecord>) : Result()
|
||||||
data class CategoryChanged(val category: SpotiFlyerMain.HomeCategory) : Result()
|
data class CategoryChanged(val category: SpotiFlyerMain.HomeCategory) : Result()
|
||||||
data class LinkChanged(val link: String) : Result()
|
data class LinkChanged(val link: String) : Result()
|
||||||
|
data class ToggleAnalytics(val isEnabled: Boolean) : Result()
|
||||||
}
|
}
|
||||||
|
|
||||||
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.ToggleAnalytics(dir.isAnalyticsEnabled))
|
||||||
updates?.collect {
|
updates?.collect {
|
||||||
dispatch(Result.ItemsLoaded(it))
|
dispatch(Result.ItemsLoaded(it))
|
||||||
}
|
}
|
||||||
@ -83,6 +89,10 @@ internal class SpotiFlyerMainStoreProvider(
|
|||||||
is Intent.ShareApp -> methods.value.shareApp()
|
is Intent.ShareApp -> methods.value.shareApp()
|
||||||
is Intent.SetLink -> dispatch(Result.LinkChanged(link = intent.link))
|
is Intent.SetLink -> dispatch(Result.LinkChanged(link = intent.link))
|
||||||
is Intent.SelectCategory -> dispatch(Result.CategoryChanged(intent.category))
|
is Intent.SelectCategory -> dispatch(Result.CategoryChanged(intent.category))
|
||||||
|
is Intent.ToggleAnalytics -> {
|
||||||
|
dispatch(Result.ToggleAnalytics(intent.enabled))
|
||||||
|
dir.toggleAnalytics(intent.enabled)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,6 +103,7 @@ internal class SpotiFlyerMainStoreProvider(
|
|||||||
is Result.ItemsLoaded -> copy(records = result.items)
|
is Result.ItemsLoaded -> copy(records = result.items)
|
||||||
is Result.LinkChanged -> copy(link = result.link)
|
is Result.LinkChanged -> copy(link = result.link)
|
||||||
is Result.CategoryChanged -> copy(selectedCategory = result.category)
|
is Result.CategoryChanged -> copy(selectedCategory = result.category)
|
||||||
|
is Result.ToggleAnalytics -> copy(isAnalyticsEnabled = result.isEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user