refactor: bottom sheet overhaul • part 2 (#38)

* remove screen classes

* allow passing null duration for "never" option

* update inbox screen

* update advanced settings screen

* update Gradle scripts
This commit is contained in:
akesi seli 2024-10-21 22:39:12 +02:00 committed by GitHub
parent b53ec2023d
commit 50590d14f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 216 additions and 437 deletions

View File

@ -1,82 +0,0 @@
package com.livefast.eattrash.raccoonforlemmy.core.commonui.modals
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import cafe.adriel.voyager.core.screen.Screen
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing
import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.BottomSheetHeader
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsRow
import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.resources.di.getCoreResources
import com.livefast.eattrash.raccoonforlemmy.core.utils.appicon.AppIconVariant
import com.livefast.eattrash.raccoonforlemmy.core.utils.appicon.toInt
import com.livefast.eattrash.raccoonforlemmy.core.utils.appicon.toReadableName
class AppIconBottomSheet : Screen {
@Composable
override fun Content() {
val navigationCoordinator = remember { getNavigationCoordinator() }
val notificationCenter = remember { getNotificationCenter() }
val coreResources = remember { getCoreResources() }
Surface {
Column(
modifier =
Modifier
.windowInsetsPadding(WindowInsets.navigationBars)
.padding(
top = Spacing.s,
start = Spacing.s,
end = Spacing.s,
bottom = Spacing.m,
),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
BottomSheetHeader(LocalStrings.current.settingsAppIcon)
val values =
listOf(
AppIconVariant.Default,
AppIconVariant.Alt1,
AppIconVariant.Alt2,
)
Column(
modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
for (value in values) {
SettingsRow(
modifier = Modifier.padding(vertical = Spacing.xxs),
title = value.toReadableName(),
painter =
when (value) {
AppIconVariant.Alt2 -> coreResources.appIconAlt2
AppIconVariant.Alt1 -> coreResources.appIconAlt1
else -> coreResources.appIconDefault
},
onTap = {
navigationCoordinator.hideBottomSheet()
notificationCenter.send(
NotificationCenterEvent.AppIconVariantSelected(value.toInt()),
)
},
)
}
}
}
}
}
}

View File

@ -1,90 +0,0 @@
package com.livefast.eattrash.raccoonforlemmy.core.commonui.modals
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import cafe.adriel.voyager.core.screen.Screen
import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.UiBarTheme
import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.toReadableName
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.CornerSize
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing
import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.BottomSheetHeader
import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.utils.compose.onClick
class BarThemeBottomSheet : Screen {
@Composable
override fun Content() {
val navigationCoordinator = remember { getNavigationCoordinator() }
val notificationCenter = remember { getNotificationCenter() }
Surface {
Column(
modifier =
Modifier
.windowInsetsPadding(WindowInsets.navigationBars)
.padding(
top = Spacing.s,
start = Spacing.s,
end = Spacing.s,
bottom = Spacing.m,
),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
BottomSheetHeader(LocalStrings.current.settingsBarTheme)
val values =
listOf(
UiBarTheme.Transparent,
UiBarTheme.Opaque,
)
Column(
modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
for (value in values) {
Row(
modifier =
Modifier
.clip(RoundedCornerShape(CornerSize.xxl))
.onClick(
onClick = {
notificationCenter.send(
NotificationCenterEvent.ChangeSystemBarTheme(value),
)
navigationCoordinator.hideBottomSheet()
},
).padding(
horizontal = Spacing.s,
vertical = Spacing.s,
).fillMaxWidth(),
) {
Text(
text = value.toReadableName(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
)
}
}
}
}
}
}
}

View File

@ -1,123 +0,0 @@
package com.livefast.eattrash.raccoonforlemmy.core.commonui.modals
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import cafe.adriel.voyager.core.screen.Screen
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.CornerSize
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing
import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.BottomSheetHeader
import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.utils.compose.onClick
import com.livefast.eattrash.raccoonforlemmy.core.utils.datetime.getPrettyDuration
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
enum class DurationBottomSheetType {
ZOMBIE_MODE_INTERVAL,
INBOX_CHECK_PERIOD,
}
class DurationBottomSheet(
private val values: List<Duration> =
listOf(
1.seconds,
2.seconds,
3.seconds,
5.seconds,
10.seconds,
),
private val type: DurationBottomSheetType = DurationBottomSheetType.ZOMBIE_MODE_INTERVAL,
) : Screen {
@Composable
override fun Content() {
val navigationCoordinator = remember { getNavigationCoordinator() }
val notificationCenter = remember { getNotificationCenter() }
Surface {
Column(
modifier =
Modifier
.windowInsetsPadding(WindowInsets.navigationBars)
.padding(
top = Spacing.s,
start = Spacing.s,
end = Spacing.s,
bottom = Spacing.m,
),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
val title =
when (type) {
DurationBottomSheetType.ZOMBIE_MODE_INTERVAL -> LocalStrings.current.settingsZombieModeInterval
DurationBottomSheetType.INBOX_CHECK_PERIOD -> LocalStrings.current.settingsInboxBackgroundCheckPeriod
}
BottomSheetHeader(title)
Column(
modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
for (value in values) {
Row(
modifier =
Modifier
.clip(RoundedCornerShape(CornerSize.xxl))
.onClick(
onClick = {
val event =
when (type) {
DurationBottomSheetType.ZOMBIE_MODE_INTERVAL ->
NotificationCenterEvent.ChangeZombieInterval(
value,
)
DurationBottomSheetType.INBOX_CHECK_PERIOD ->
NotificationCenterEvent.ChangeInboxBackgroundCheckPeriod(
value,
)
}
notificationCenter.send(event)
navigationCoordinator.hideBottomSheet()
},
).padding(
horizontal = Spacing.s,
vertical = Spacing.s,
).fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text =
value.getPrettyDuration(
secondsLabel = LocalStrings.current.postSecondShort,
minutesLabel = LocalStrings.current.postMinuteShort,
hoursLabel = LocalStrings.current.postHourShort,
),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
)
}
}
}
}
}
}
}

View File

@ -1,107 +0,0 @@
package com.livefast.eattrash.raccoonforlemmy.core.commonui.modals
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import cafe.adriel.voyager.core.screen.Screen
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.CornerSize
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing
import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.BottomSheetHeader
import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.utils.compose.onClick
class InboxTypeSheet : Screen {
@Composable
override fun Content() {
val navigationCoordinator = remember { getNavigationCoordinator() }
val notificationCenter = remember { getNotificationCenter() }
Surface {
Column(
modifier =
Modifier
.windowInsetsPadding(WindowInsets.navigationBars)
.padding(
top = Spacing.s,
start = Spacing.s,
end = Spacing.s,
bottom = Spacing.m,
),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
BottomSheetHeader(LocalStrings.current.inboxListingTypeTitle)
Column(
modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
Row(
modifier =
Modifier
.clip(RoundedCornerShape(CornerSize.xxl))
.onClick(
onClick = {
notificationCenter.send(
NotificationCenterEvent.ChangeInboxType(true),
)
navigationCoordinator.hideBottomSheet()
},
).padding(
horizontal = Spacing.s,
vertical = Spacing.s,
).fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = LocalStrings.current.inboxListingTypeUnread,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
)
}
Row(
modifier =
Modifier
.clip(RoundedCornerShape(CornerSize.xxl))
.fillMaxWidth()
.padding(
horizontal = Spacing.s,
vertical = Spacing.s,
).onClick(
onClick = {
notificationCenter.send(
NotificationCenterEvent.ChangeInboxType(false),
)
navigationCoordinator.hideBottomSheet()
},
),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = LocalStrings.current.inboxListingTypeAll,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
)
}
}
}
}
}
}

View File

@ -69,7 +69,7 @@ sealed interface NotificationCenterEvent {
) : NotificationCenterEvent ) : NotificationCenterEvent
data class ChangeInboxBackgroundCheckPeriod( data class ChangeInboxBackgroundCheckPeriod(
val value: Duration, val value: Duration?,
) : NotificationCenterEvent ) : NotificationCenterEvent
data class ChangeLanguage( data class ChangeLanguage(

View File

@ -20,8 +20,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import cafe.adriel.voyager.koin.getScreenModel import cafe.adriel.voyager.koin.getScreenModel
@ -32,10 +34,13 @@ import cafe.adriel.voyager.navigator.tab.TabNavigator
import cafe.adriel.voyager.navigator.tab.TabOptions import cafe.adriel.voyager.navigator.tab.TabOptions
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing
import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.SectionSelector import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.SectionSelector
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.InboxTypeSheet import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.CustomModalBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.CustomModalBottomSheetItem
import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getDrawerCoordinator import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getDrawerCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.persistence.di.getSettingsRepository import com.livefast.eattrash.raccoonforlemmy.core.persistence.di.getSettingsRepository
import com.livefast.eattrash.raccoonforlemmy.core.utils.compose.onClick import com.livefast.eattrash.raccoonforlemmy.core.utils.compose.onClick
import com.livefast.eattrash.raccoonforlemmy.unit.mentions.InboxMentionsScreen import com.livefast.eattrash.raccoonforlemmy.unit.mentions.InboxMentionsScreen
@ -63,6 +68,8 @@ object InboxScreen : Tab {
val settingsRepository = remember { getSettingsRepository() } val settingsRepository = remember { getSettingsRepository() }
val settings by settingsRepository.currentSettings.collectAsState() val settings by settingsRepository.currentSettings.collectAsState()
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val notificationCenter = remember { getNotificationCenter() }
var inboxTypeBottomSheetOpened by remember { mutableStateOf(false) }
val inboxReadAllSuccessMessage = LocalStrings.current.messageReadAllInboxSuccess val inboxReadAllSuccessMessage = LocalStrings.current.messageReadAllInboxSuccess
LaunchedEffect(model) { LaunchedEffect(model) {
@ -108,8 +115,7 @@ object InboxScreen : Tab {
.padding(horizontal = Spacing.s) .padding(horizontal = Spacing.s)
.onClick( .onClick(
onClick = { onClick = {
val sheet = InboxTypeSheet() inboxTypeBottomSheetOpened = true
navigationCoordinator.showBottomSheet(sheet)
}, },
), ),
) { ) {
@ -251,5 +257,28 @@ object InboxScreen : Tab {
else -> Unit else -> Unit
} }
} }
if (inboxTypeBottomSheetOpened) {
val values =
listOf(
LocalStrings.current.inboxListingTypeUnread,
LocalStrings.current.inboxListingTypeAll,
)
CustomModalBottomSheet(
title = LocalStrings.current.inboxListingTypeTitle,
items =
values.map { value ->
CustomModalBottomSheetItem(label = value)
},
onSelected = { index ->
inboxTypeBottomSheetOpened = false
if (index != null) {
notificationCenter.send(
NotificationCenterEvent.ChangeInboxType(unreadOnly = index == 0),
)
}
},
)
}
} }
} }

View File

@ -54,6 +54,7 @@ kotlin {
implementation(projects.core.notifications) implementation(projects.core.notifications)
implementation(projects.core.persistence) implementation(projects.core.persistence)
implementation(projects.core.preferences) implementation(projects.core.preferences)
implementation(projects.core.resources)
implementation(projects.core.utils) implementation(projects.core.utils)
implementation(projects.domain.lemmy.data) implementation(projects.domain.lemmy.data)

View File

@ -1,5 +1,6 @@
package com.livefast.eattrash.raccoonforlemmy.feature.settings.advanced package com.livefast.eattrash.raccoonforlemmy.feature.settings.advanced
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -8,6 +9,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@ -44,16 +46,14 @@ import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel import cafe.adriel.voyager.koin.getScreenModel
import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.UiBarTheme import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.UiBarTheme
import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.toReadableName import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.toReadableName
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.IconSize
import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing import com.livefast.eattrash.raccoonforlemmy.core.appearance.theme.Spacing
import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.ProgressHud import com.livefast.eattrash.raccoonforlemmy.core.commonui.components.ProgressHud
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsHeader import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsHeader
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsRow import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsRow
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsSwitchRow import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.SettingsSwitchRow
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.AppIconBottomSheet import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.CustomModalBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.BarThemeBottomSheet import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.CustomModalBottomSheetItem
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.DurationBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.DurationBottomSheetType
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.InboxTypeSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.ListingTypeBottomSheet import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.ListingTypeBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.ResultTypeBottomSheet import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.ResultTypeBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.SelectLanguageDialog import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.SelectLanguageDialog
@ -62,6 +62,12 @@ import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.SelectNumberBo
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.SliderBottomSheet import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.SliderBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings import com.livefast.eattrash.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator import com.livefast.eattrash.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.resources.di.getCoreResources
import com.livefast.eattrash.raccoonforlemmy.core.utils.appicon.AppIconVariant
import com.livefast.eattrash.raccoonforlemmy.core.utils.appicon.toInt
import com.livefast.eattrash.raccoonforlemmy.core.utils.appicon.toReadableName
import com.livefast.eattrash.raccoonforlemmy.core.utils.datetime.getPrettyDuration import com.livefast.eattrash.raccoonforlemmy.core.utils.datetime.getPrettyDuration
import com.livefast.eattrash.raccoonforlemmy.core.utils.fs.getFileSystemManager import com.livefast.eattrash.raccoonforlemmy.core.utils.fs.getFileSystemManager
import com.livefast.eattrash.raccoonforlemmy.core.utils.toLocalDp import com.livefast.eattrash.raccoonforlemmy.core.utils.toLocalDp
@ -73,6 +79,7 @@ import kotlinx.coroutines.launch
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
private const val SETTINGS_MIME_TYPE = "application/json" private const val SETTINGS_MIME_TYPE = "application/json"
private const val SETTINGS_FILE_NAME = "raccoon_settings.json" private const val SETTINGS_FILE_NAME = "raccoon_settings.json"
@ -87,15 +94,22 @@ class AdvancedSettingsScreen : Screen {
val topAppBarState = rememberTopAppBarState() val topAppBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState) val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
val notificationCenter = remember { getNotificationCenter() }
var screenWidth by remember { mutableStateOf(0f) } var screenWidth by remember { mutableStateOf(0f) }
var languageDialogOpened by remember { mutableStateOf(false) }
val snackbarHostState = remember { SnackbarHostState() } val snackbarHostState = remember { SnackbarHostState() }
val successMessage = LocalStrings.current.messageOperationSuccessful val successMessage = LocalStrings.current.messageOperationSuccessful
val errorMessage = LocalStrings.current.messageGenericError val errorMessage = LocalStrings.current.messageGenericError
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val fileSystemManager = remember { getFileSystemManager() } val fileSystemManager = remember { getFileSystemManager() }
val coreResources = remember { getCoreResources() }
var languageDialogOpened by remember { mutableStateOf(false) }
var fileInputOpened by remember { mutableStateOf(false) } var fileInputOpened by remember { mutableStateOf(false) }
var settingsContent by remember { mutableStateOf<String?>(null) } var settingsContent by remember { mutableStateOf<String?>(null) }
var appIconBottomSheetOpened by remember { mutableStateOf(false) }
var barThemeBottomSheetOpened by remember { mutableStateOf(false) }
var zombieModeDurationBottomSheetOpened by remember { mutableStateOf(false) }
var inboxCheckDurationBottomSheetOpened by remember { mutableStateOf(false) }
var inboxTypeBottomSheetOpened by remember { mutableStateOf(false) }
LaunchedEffect(model) { LaunchedEffect(model) {
model.effects model.effects
@ -201,8 +215,7 @@ class AdvancedSettingsScreen : Screen {
title = LocalStrings.current.settingsBarTheme, title = LocalStrings.current.settingsBarTheme,
value = barThemeName, value = barThemeName,
onTap = { onTap = {
val sheet = BarThemeBottomSheet() barThemeBottomSheetOpened = true
navigationCoordinator.showBottomSheet(sheet)
}, },
) )
} }
@ -285,8 +298,7 @@ class AdvancedSettingsScreen : Screen {
LocalStrings.current.inboxListingTypeAll LocalStrings.current.inboxListingTypeAll
}, },
onTap = { onTap = {
val sheet = InboxTypeSheet() inboxTypeBottomSheetOpened = true
navigationCoordinator.showBottomSheet(sheet)
}, },
) )
@ -395,11 +407,7 @@ class AdvancedSettingsScreen : Screen {
hoursLabel = LocalStrings.current.homeSortTypeTop6Hours, hoursLabel = LocalStrings.current.homeSortTypeTop6Hours,
), ),
onTap = { onTap = {
val sheet = zombieModeDurationBottomSheetOpened = true
DurationBottomSheet(
type = DurationBottomSheetType.ZOMBIE_MODE_INTERVAL,
)
navigationCoordinator.showBottomSheet(sheet)
}, },
) )
@ -548,19 +556,7 @@ class AdvancedSettingsScreen : Screen {
) ?: LocalStrings.current.never ) ?: LocalStrings.current.never
}, },
onTap = { onTap = {
val sheet = inboxCheckDurationBottomSheetOpened = true
DurationBottomSheet(
values =
listOf(
15.minutes,
30.minutes,
1.hours,
2.hours,
5.hours,
),
type = DurationBottomSheetType.INBOX_CHECK_PERIOD,
)
navigationCoordinator.showBottomSheet(sheet)
}, },
) )
} }
@ -575,8 +571,7 @@ class AdvancedSettingsScreen : Screen {
append(LocalStrings.current.requiresRestart) append(LocalStrings.current.requiresRestart)
}, },
onTap = { onTap = {
val sheet = AppIconBottomSheet() appIconBottomSheetOpened = true
navigationCoordinator.showBottomSheet(sheet)
}, },
) )
} }
@ -642,6 +637,162 @@ class AdvancedSettingsScreen : Screen {
} }
} }
if (appIconBottomSheetOpened) {
val values =
listOf(
AppIconVariant.Default,
AppIconVariant.Alt1,
AppIconVariant.Alt2,
)
CustomModalBottomSheet(
title = LocalStrings.current.settingsAppIcon,
items =
values.map { value ->
CustomModalBottomSheetItem(
leadingContent = {
val painter =
when (value) {
AppIconVariant.Alt2 -> coreResources.appIconAlt2
AppIconVariant.Alt1 -> coreResources.appIconAlt1
else -> coreResources.appIconDefault
}
Image(
modifier = Modifier.size(IconSize.m),
painter = painter,
contentDescription = null,
)
},
label = value.toReadableName(),
)
},
onSelected = { index ->
appIconBottomSheetOpened = false
if (index != null) {
val value = values[index]
notificationCenter.send(
NotificationCenterEvent.AppIconVariantSelected(value.toInt()),
)
}
},
)
}
if (barThemeBottomSheetOpened) {
val values =
listOf(
UiBarTheme.Transparent,
UiBarTheme.Opaque,
)
CustomModalBottomSheet(
title = LocalStrings.current.settingsBarTheme,
items =
values.map { value ->
CustomModalBottomSheetItem(label = value.toReadableName())
},
onSelected = { index ->
barThemeBottomSheetOpened = false
if (index != null) {
val value = values[index]
notificationCenter.send(
NotificationCenterEvent.ChangeSystemBarTheme(value),
)
}
},
)
}
if (zombieModeDurationBottomSheetOpened) {
val values =
listOf(
1.seconds,
2.seconds,
3.seconds,
5.seconds,
10.seconds,
)
CustomModalBottomSheet(
title = LocalStrings.current.settingsZombieModeInterval,
items =
values.map { value ->
CustomModalBottomSheetItem(
label =
value.getPrettyDuration(
secondsLabel = LocalStrings.current.postSecondShort,
minutesLabel = LocalStrings.current.postMinuteShort,
hoursLabel = LocalStrings.current.postHourShort,
),
)
},
onSelected = { index ->
zombieModeDurationBottomSheetOpened = false
if (index != null) {
val value = values[index]
notificationCenter.send(
NotificationCenterEvent.ChangeZombieInterval(value),
)
}
},
)
}
if (inboxCheckDurationBottomSheetOpened) {
val values =
listOf(
null,
15.minutes,
30.minutes,
1.hours,
2.hours,
5.hours,
)
CustomModalBottomSheet(
title = LocalStrings.current.settingsInboxBackgroundCheckPeriod,
items =
values.map { value ->
CustomModalBottomSheetItem(
label =
value?.getPrettyDuration(
secondsLabel = LocalStrings.current.postSecondShort,
minutesLabel = LocalStrings.current.postMinuteShort,
hoursLabel = LocalStrings.current.postHourShort,
) ?: LocalStrings.current.never,
)
},
onSelected = { index ->
inboxCheckDurationBottomSheetOpened = false
if (index != null) {
val value = values[index]
notificationCenter.send(
NotificationCenterEvent.ChangeInboxBackgroundCheckPeriod(value),
)
}
},
)
}
if (inboxTypeBottomSheetOpened) {
val values =
listOf(
LocalStrings.current.inboxListingTypeUnread,
LocalStrings.current.inboxListingTypeAll,
)
CustomModalBottomSheet(
title = LocalStrings.current.inboxListingTypeTitle,
items =
values.map { value ->
CustomModalBottomSheetItem(label = value)
},
onSelected = { index ->
inboxTypeBottomSheetOpened = false
if (index != null) {
notificationCenter.send(
NotificationCenterEvent.ChangeInboxType(unreadOnly = index == 0),
)
}
},
)
}
settingsContent?.also { content -> settingsContent?.also { content ->
fileSystemManager.writeToFile( fileSystemManager.writeToFile(
mimeType = SETTINGS_MIME_TYPE, mimeType = SETTINGS_MIME_TYPE,

View File

@ -381,7 +381,7 @@ class AdvancedSettingsViewModel(
} }
} }
private fun changeInboxBackgroundCheckPeriod(value: Duration) { private fun changeInboxBackgroundCheckPeriod(value: Duration?) {
screenModelScope.launch { screenModelScope.launch {
updateState { it.copy(inboxBackgroundCheckPeriod = value) } updateState { it.copy(inboxBackgroundCheckPeriod = value) }
val settings = val settings =