mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 01:38:44 +01:00
feat: edge to edge contents (#398)
* chore: setup * feat: update post list * feat: update community detail * feat: update multi-community * feat: update user detail * feat: update profile * feat: add option in settings * feat: persistence and db migration * chore: add translations closes #311
This commit is contained in:
parent
b59e5426dd
commit
0ec23f943d
@ -39,4 +39,5 @@ data class SettingsModel(
|
||||
val commentBarTheme: Int = 0,
|
||||
val replyColor: Int? = null,
|
||||
val searchPostTitleOnly: Boolean = false,
|
||||
val edgeToEdge: Boolean = true,
|
||||
) : JavaSerializable
|
||||
|
@ -45,6 +45,7 @@ private object KeyStoreKeys {
|
||||
const val ReplyColor = "replyColor"
|
||||
const val SearchPostTitleOnly = "searchPostTitleOnly"
|
||||
const val ContentFontFamily = "contentFontFamily"
|
||||
const val EdgeToEdge = "edgeToEdge"
|
||||
}
|
||||
|
||||
internal class DefaultSettingsRepository(
|
||||
@ -92,6 +93,7 @@ internal class DefaultSettingsRepository(
|
||||
replyColor = settings.replyColor?.toLong(),
|
||||
searchPostTitleOnly = if (settings.searchPostTitleOnly) 1 else 0,
|
||||
contentFontFamily = settings.contentFontFamily.toLong(),
|
||||
edgeToEdge = if (settings.edgeToEdge) 1 else 0,
|
||||
)
|
||||
}
|
||||
|
||||
@ -134,6 +136,7 @@ internal class DefaultSettingsRepository(
|
||||
replyColor = if (!keyStore.containsKey(KeyStoreKeys.ReplyColor)) null else keyStore[KeyStoreKeys.ReplyColor, 0],
|
||||
searchPostTitleOnly = keyStore[KeyStoreKeys.SearchPostTitleOnly, false],
|
||||
contentFontFamily = keyStore[KeyStoreKeys.ContentFontFamily, 0],
|
||||
edgeToEdge = keyStore[KeyStoreKeys.EdgeToEdge, true],
|
||||
)
|
||||
} else {
|
||||
val entity = db.settingsQueries.getBy(accountId).executeAsOneOrNull()
|
||||
@ -220,6 +223,7 @@ internal class DefaultSettingsRepository(
|
||||
settings.searchPostTitleOnly,
|
||||
)
|
||||
keyStore.save(KeyStoreKeys.ContentFontFamily, settings.contentFontFamily)
|
||||
keyStore.save(KeyStoreKeys.EdgeToEdge, settings.edgeToEdge)
|
||||
} else {
|
||||
db.settingsQueries.update(
|
||||
theme = settings.theme?.toLong(),
|
||||
@ -255,6 +259,7 @@ internal class DefaultSettingsRepository(
|
||||
replyColor = settings.replyColor?.toLong(),
|
||||
searchPostTitleOnly = if (settings.searchPostTitleOnly) 1L else 0L,
|
||||
contentFontFamily = settings.contentFontFamily.toLong(),
|
||||
edgeToEdge = if (settings.edgeToEdge) 1L else 0L,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -298,4 +303,5 @@ private fun GetBy.toModel() = SettingsModel(
|
||||
replyColor = replyColor?.toInt(),
|
||||
searchPostTitleOnly = searchPostTitleOnly != 0L,
|
||||
contentFontFamily = contentFontFamily.toInt(),
|
||||
edgeToEdge = edgeToEdge != 0L,
|
||||
)
|
||||
|
@ -32,6 +32,7 @@ CREATE TABLE SettingsEntity (
|
||||
replyColor INTEGER DEFAULT NULL,
|
||||
searchPostTitleOnly INTEGER NOT NULL DEFAULT 0,
|
||||
contentFontFamily INTEGER NOT NULL DEFAULT 0,
|
||||
edgeToEdge INTEGER NOT NULL DEFAULT 1,
|
||||
account_id INTEGER,
|
||||
FOREIGN KEY (account_id) REFERENCES AccountEntity(id) ON DELETE CASCADE,
|
||||
UNIQUE(account_id)
|
||||
@ -71,6 +72,7 @@ INSERT OR IGNORE INTO SettingsEntity (
|
||||
replyColor,
|
||||
searchPostTitleOnly,
|
||||
contentFontFamily,
|
||||
edgeToEdge,
|
||||
account_id
|
||||
) VALUES (
|
||||
?,
|
||||
@ -105,6 +107,7 @@ INSERT OR IGNORE INTO SettingsEntity (
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?
|
||||
);
|
||||
|
||||
@ -141,7 +144,8 @@ SET theme = ?,
|
||||
commentBarTheme = ?,
|
||||
replyColor = ?,
|
||||
searchPostTitleOnly = ?,
|
||||
contentFontFamily = ?
|
||||
contentFontFamily = ?,
|
||||
edgeToEdge = ?
|
||||
WHERE account_id = ?;
|
||||
|
||||
getBy:
|
||||
@ -178,6 +182,7 @@ SELECT
|
||||
commentBarTheme,
|
||||
replyColor,
|
||||
searchPostTitleOnly,
|
||||
contentFontFamily
|
||||
contentFontFamily,
|
||||
edgeToEdge
|
||||
FROM SettingsEntity
|
||||
WHERE account_id = ?;
|
@ -0,0 +1,2 @@
|
||||
ALTER TABLE SettingsEntity
|
||||
ADD COLUMN edgeToEdge INTEGER NOT NULL DEFAULT 1;
|
@ -3,6 +3,7 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.profile.main
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.icons.Icons
|
||||
@ -15,6 +16,7 @@ import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
@ -22,6 +24,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
@ -32,6 +36,7 @@ import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Dimensions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getDrawerCoordinator
|
||||
@ -65,7 +70,8 @@ internal object ProfileMainScreen : Tab {
|
||||
val model = getScreenModel<ProfileMainMviModel>()
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
@ -80,7 +86,18 @@ internal object ProfileMainScreen : Tab {
|
||||
val title by remember(lang) {
|
||||
mutableStateOf(staticString(MR.strings.navigation_profile.desc()))
|
||||
}
|
||||
val maxTopInset = Dimensions.topBarHeight.value.toInt()
|
||||
var topInset by remember { mutableStateOf(maxTopInset) }
|
||||
snapshotFlow { topAppBarState.collapsedFraction }.onEach {
|
||||
topInset = (maxTopInset * (1 - it)).toInt()
|
||||
}.launchIn(scope)
|
||||
|
||||
TopAppBar(
|
||||
windowInsets = if (settings.edgeToEdge) {
|
||||
WindowInsets(0, topInset, 0, 0)
|
||||
} else {
|
||||
TopAppBarDefaults.windowInsets
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = {
|
||||
Image(
|
||||
|
@ -51,6 +51,7 @@ interface SettingsMviModel :
|
||||
data class ChangeMarkAsReadWhileScrolling(val value: Boolean) : Intent
|
||||
data class ChangeDefaultInboxUnreadOnly(val value: Boolean) : Intent
|
||||
data class ChangeSearchPostTitleOnly(val value: Boolean) : Intent
|
||||
data class ChangeEdgeToEdge(val value: Boolean) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
@ -91,6 +92,7 @@ interface SettingsMviModel :
|
||||
val availableSortTypesForComments: List<SortType> = emptyList(),
|
||||
val commentBarTheme: CommentBarTheme = CommentBarTheme.Blue,
|
||||
val searchPostTitleOnly: Boolean = false,
|
||||
val edgeToEdge: Boolean = true,
|
||||
)
|
||||
|
||||
sealed interface Effect
|
||||
|
@ -442,6 +442,17 @@ class SettingsScreen : Screen {
|
||||
title = stringResource(MR.strings.settings_section_behaviour),
|
||||
)
|
||||
|
||||
// edge to edge
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_edge_to_edge),
|
||||
value = uiState.edgeToEdge,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeEdgeToEdge(value)
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
// mark as read while scrolling
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_mark_as_read_while_scrolling),
|
||||
|
@ -212,6 +212,7 @@ class SettingsViewModel(
|
||||
zombieModeScrollAmount = settings.zombieModeScrollAmount,
|
||||
markAsReadWhileScrolling = settings.markAsReadWhileScrolling,
|
||||
searchPostTitleOnly = settings.searchPostTitleOnly,
|
||||
edgeToEdge = settings.edgeToEdge,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -345,6 +346,10 @@ class SettingsViewModel(
|
||||
is SettingsMviModel.Intent.ChangeSearchPostTitleOnly -> {
|
||||
changeSearchPostTitleOnly(intent.value)
|
||||
}
|
||||
|
||||
is SettingsMviModel.Intent.ChangeEdgeToEdge -> {
|
||||
changeEdgeToEdge(intent.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -678,6 +683,16 @@ class SettingsViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeEdgeToEdge(value: Boolean) {
|
||||
mvi.updateState { it.copy(edgeToEdge = value) }
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
val settings = settingsRepository.currentSettings.value.copy(
|
||||
edgeToEdge = value
|
||||
)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveSettings(settings: SettingsModel) {
|
||||
val accountId = accountRepository.getActive()?.id
|
||||
settingsRepository.updateSettings(settings, accountId)
|
||||
|
@ -303,4 +303,5 @@
|
||||
<string name="settings_manage_ban">الحظر والمرشحات</string>
|
||||
<string name="settings_manage_ban_action_unban">إزالة الحظر</string>
|
||||
<string name="settings_manage_ban_section_instances">المثيلات</string>
|
||||
<string name="settings_edge_to_edge">محتويات الحافة إلى الحافة</string>
|
||||
</resources>
|
@ -334,4 +334,5 @@
|
||||
<string name="settings_manage_ban">Bans and filters</string>
|
||||
<string name="settings_manage_ban_action_unban">Unban</string>
|
||||
<string name="settings_manage_ban_section_instances">Instances</string>
|
||||
<string name="settings_edge_to_edge">Edge to edge contents</string>
|
||||
</resources>
|
@ -313,4 +313,5 @@
|
||||
<string name="settings_manage_ban">Забрани и филтри</string>
|
||||
<string name="settings_manage_ban_action_unban">Премахване на забраната</string>
|
||||
<string name="settings_manage_ban_section_instances">Инстанции</string>
|
||||
<string name="settings_edge_to_edge">Съдържание от край до край</string>
|
||||
</resources>
|
@ -305,4 +305,5 @@
|
||||
<string name="settings_manage_ban">Zákazy a filtry</string>
|
||||
<string name="settings_manage_ban_action_unban">Odstranit zákaz</string>
|
||||
<string name="settings_manage_ban_section_instances">Instance</string>
|
||||
<string name="settings_edge_to_edge">Obsah od okraje k okraji</string>
|
||||
</resources>
|
@ -305,4 +305,5 @@
|
||||
<string name="settings_manage_ban">Forbud og filtre</string>
|
||||
<string name="settings_manage_ban_action_unban">Fjern forbuddet</string>
|
||||
<string name="settings_manage_ban_section_instances">Forekomster</string>
|
||||
<string name="settings_edge_to_edge">Indhold fra kant til kant</string>
|
||||
</resources>
|
@ -313,4 +313,5 @@
|
||||
<string name="settings_manage_ban">Verbote und Filter</string>
|
||||
<string name="settings_manage_ban_action_unban">Verbot aufheben</string>
|
||||
<string name="settings_manage_ban_section_instances">Instanzen</string>
|
||||
<string name="settings_edge_to_edge">Rand-zu-Rand-Inhalte</string>
|
||||
</resources>
|
@ -316,4 +316,5 @@
|
||||
<string name="settings_manage_ban">Απαγορεύσεις και φίλτρα</string>
|
||||
<string name="settings_manage_ban_action_unban">Κατάργηση απαγόρευσης</string>
|
||||
<string name="settings_manage_ban_section_instances">Περιπτώσεις</string>
|
||||
<string name="settings_edge_to_edge">Περιεχόμενα από άκρη σε άκρη</string>
|
||||
</resources>
|
@ -304,4 +304,5 @@
|
||||
<string name="settings_manage_ban">Malpermesoj kaj filtriloj</string>
|
||||
<string name="settings_manage_ban_action_unban">Forigi malpermeson</string>
|
||||
<string name="settings_manage_ban_section_instances">Ekzemploj</string>
|
||||
<string name="settings_edge_to_edge">Enhavo de rando al rando</string>
|
||||
</resources>
|
@ -310,4 +310,5 @@
|
||||
<string name="settings_manage_ban">Prohibiciones y filtros</string>
|
||||
<string name="settings_manage_ban_action_unban">Eliminar prohibición</string>
|
||||
<string name="settings_manage_ban_section_instances">Instancias</string>
|
||||
<string name="settings_edge_to_edge">Contenidos de borde a borde</string>
|
||||
</resources>
|
@ -305,4 +305,5 @@
|
||||
<string name="settings_manage_ban">Keelud ja filtrid</string>
|
||||
<string name="settings_manage_ban_action_unban">Eemalda keeld</string>
|
||||
<string name="settings_manage_ban_section_instances">Juhtumid</string>
|
||||
<string name="settings_edge_to_edge">Servast servani sisu</string>
|
||||
</resources>
|
@ -305,4 +305,5 @@
|
||||
<string name="settings_manage_ban">Kiellot ja suodattimet</string>
|
||||
<string name="settings_manage_ban_action_unban">Poista kielto</string>
|
||||
<string name="settings_manage_ban_section_instances">Esineet</string>
|
||||
<string name="settings_edge_to_edge">Reunasta reunaan sisältö</string>
|
||||
</resources>
|
@ -310,4 +310,5 @@
|
||||
<string name="settings_manage_ban">Interdictions et filtres</string>
|
||||
<string name="settings_manage_ban_action_unban">Supprimer interdiction</string>
|
||||
<string name="settings_manage_ban_section_instances">Instances</string>
|
||||
<string name="settings_edge_to_edge">Contenu bord à bord</string>
|
||||
</resources>
|
@ -314,4 +314,5 @@
|
||||
<string name="settings_manage_ban">Toirmisc agus scagairí</string>
|
||||
<string name="settings_manage_ban_action_unban">Bain toirmeasc</string>
|
||||
<string name="settings_manage_ban_section_instances">Cásanna</string>
|
||||
<string name="settings_edge_to_edge">Ábhar imeall go himeall</string>
|
||||
</resources>
|
@ -310,4 +310,5 @@
|
||||
<string name="settings_manage_ban">Zabrane i filteri</string>
|
||||
<string name="settings_manage_ban_action_unban">Ukloni zabranu</string>
|
||||
<string name="settings_manage_ban_section_instances">Instance</string>
|
||||
<string name="settings_edge_to_edge">Sadržaj od ruba do ruba</string>
|
||||
</resources>
|
@ -309,4 +309,5 @@
|
||||
<string name="settings_manage_ban">Tiltások és szűrők</string>
|
||||
<string name="settings_manage_ban_action_unban">Távolítsa el a tiltást</string>
|
||||
<string name="settings_manage_ban_section_instances">Példányok</string>
|
||||
<string name="settings_edge_to_edge">Éltől szélig tartalom</string>
|
||||
</resources>
|
@ -309,4 +309,5 @@
|
||||
<string name="settings_manage_ban">Ban e filtri</string>
|
||||
<string name="settings_manage_ban_action_unban">Rimuovi ban</string>
|
||||
<string name="settings_manage_ban_section_instances">Istanze</string>
|
||||
<string name="settings_edge_to_edge">Contenuti da margine a margine</string>
|
||||
</resources>
|
@ -307,4 +307,5 @@
|
||||
<string name="settings_manage_ban">Draudimai ir filtrai</string>
|
||||
<string name="settings_manage_ban_action_unban">Pašalinti draudimą</string>
|
||||
<string name="settings_manage_ban_section_instances">Atvejai</string>
|
||||
<string name="settings_edge_to_edge">Turinys nuo krašto iki krašto</string>
|
||||
</resources>
|
@ -309,4 +309,5 @@
|
||||
<string name="settings_manage_ban">Aizliegumi un filtri</string>
|
||||
<string name="settings_manage_ban_action_unban">Noņemt aizliegumu</string>
|
||||
<string name="settings_manage_ban_section_instances">Gadījumi</string>
|
||||
<string name="settings_edge_to_edge">Saturs no malas līdz malai</string>
|
||||
</resources>
|
@ -310,4 +310,5 @@
|
||||
<string name="settings_manage_ban">Projbizzjonijiet u filtri</string>
|
||||
<string name="settings_manage_ban_action_unban">Neħħi l-projbizzjoni</string>
|
||||
<string name="settings_manage_ban_section_instances">Każijiet</string>
|
||||
<string name="settings_edge_to_edge">Kontenut tarf sa tarf</string>
|
||||
</resources>
|
@ -308,4 +308,5 @@
|
||||
<string name="settings_manage_ban">Verboden en filters</string>
|
||||
<string name="settings_manage_ban_action_unban">Verwijder verbod</string>
|
||||
<string name="settings_manage_ban_section_instances">Instanties</string>
|
||||
<string name="settings_edge_to_edge">Inhoud van rand tot rand</string>
|
||||
</resources>
|
@ -307,4 +307,5 @@
|
||||
<string name="settings_manage_ban">Forbud og filtre</string>
|
||||
<string name="settings_manage_ban_action_unban">Fjern forbudet</string>
|
||||
<string name="settings_manage_ban_section_instances">Forekomster</string>
|
||||
<string name="settings_edge_to_edge">Kant til kant innhold</string>
|
||||
</resources>
|
@ -308,4 +308,5 @@
|
||||
<string name="settings_manage_ban">Zakazy i filtry</string>
|
||||
<string name="settings_manage_ban_action_unban">Usuń zakaz</string>
|
||||
<string name="settings_manage_ban_section_instances">Instancje</string>
|
||||
<string name="settings_edge_to_edge">Zawartość od krawędzi do krawędzi</string>
|
||||
</resources>
|
@ -307,4 +307,5 @@
|
||||
<string name="settings_manage_ban">Proibições e filtros</string>
|
||||
<string name="settings_manage_ban_action_unban">Remover proibição</string>
|
||||
<string name="settings_manage_ban_section_instances">Instâncias</string>
|
||||
<string name="settings_edge_to_edge">Conteúdo de ponta a ponta</string>
|
||||
</resources>
|
@ -306,4 +306,5 @@
|
||||
<string name="settings_manage_ban">Interdicții și filtre</string>
|
||||
<string name="settings_manage_ban_action_unban">Elimină interdicția</string>
|
||||
<string name="settings_manage_ban_section_instances">Instanțe</string>
|
||||
<string name="settings_edge_to_edge">Conținut de la margine la margine</string>
|
||||
</resources>
|
@ -309,4 +309,5 @@
|
||||
<string name="settings_manage_ban">Баны и фильтры</string>
|
||||
<string name="settings_manage_ban_action_unban">Снять бан</string>
|
||||
<string name="settings_manage_ban_section_instances">Экземпляры</string>
|
||||
<string name="settings_edge_to_edge">Содержимое от края до края</string>
|
||||
</resources>
|
@ -306,4 +306,5 @@
|
||||
<string name="settings_manage_ban">Förbud och filter</string>
|
||||
<string name="settings_manage_ban_action_unban">Ta bort förbudet</string>
|
||||
<string name="settings_manage_ban_section_instances">Instanser</string>
|
||||
<string name="settings_edge_to_edge">Kant till kant innehåll</string>
|
||||
</resources>
|
@ -307,4 +307,5 @@
|
||||
<string name="settings_manage_ban">Zákazy a filtre</string>
|
||||
<string name="settings_manage_ban_action_unban">Odstrániť zákaz</string>
|
||||
<string name="settings_manage_ban_section_instances">Inštancie</string>
|
||||
<string name="settings_edge_to_edge">Obsah od okraja k okraju</string>
|
||||
</resources>
|
@ -305,4 +305,5 @@
|
||||
<string name="settings_manage_ban">Prepovedi in filtri</string>
|
||||
<string name="settings_manage_ban_action_unban">Odstrani prepoved</string>
|
||||
<string name="settings_manage_ban_section_instances">Primerki</string>
|
||||
<string name="settings_edge_to_edge">Vsebina od roba do roba</string>
|
||||
</resources>
|
@ -311,4 +311,5 @@
|
||||
<string name="settings_manage_ban">Ndalimet dhe filtrat</string>
|
||||
<string name="settings_manage_ban_action_unban">Hiq ndalimin</string>
|
||||
<string name="settings_manage_ban_section_instances">Instancat</string>
|
||||
<string name="settings_edge_to_edge">Përmbajtja buzë në skaj</string>
|
||||
</resources>
|
@ -308,4 +308,5 @@
|
||||
<string name="settings_manage_ban">Yasaklar ve filtreler</string>
|
||||
<string name="settings_manage_ban_action_unban">Yasağı kaldır</string>
|
||||
<string name="settings_manage_ban_section_instances">Örnekler</string>
|
||||
<string name="settings_edge_to_edge">Uçtan uca içerikler</string>
|
||||
</resources>
|
@ -307,4 +307,5 @@
|
||||
<string name="settings_manage_ban">Заборони та фільтри</string>
|
||||
<string name="settings_manage_ban_action_unban">Зняти бан</string>
|
||||
<string name="settings_manage_ban_section_instances">Примірники</string>
|
||||
<string name="settings_edge_to_edge">Вміст від краю до краю</string>
|
||||
</resources>
|
@ -223,6 +223,7 @@ fun App(onLoadingFinished: () -> Unit = {}) {
|
||||
theme = currentTheme,
|
||||
contentFontScale = fontScale,
|
||||
useDynamicColors = useDynamicColors,
|
||||
transparent = true,
|
||||
) {
|
||||
val lang by languageRepository.currentLanguage.collectAsState()
|
||||
LaunchedEffect(lang) {}
|
||||
|
@ -32,6 +32,7 @@ import cafe.adriel.voyager.koin.getScreenModel
|
||||
import cafe.adriel.voyager.navigator.tab.CurrentTab
|
||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.DrawerEvent
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.TabNavigationSection
|
||||
@ -188,7 +189,12 @@ internal object MainScreen : Screen {
|
||||
y = -uiState.bottomBarOffsetHeightPx.roundToInt()
|
||||
)
|
||||
},
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
contentPadding = PaddingValues(
|
||||
start = 0.dp,
|
||||
top = 0.dp,
|
||||
end = 0.dp,
|
||||
bottom = Spacing.m,
|
||||
),
|
||||
backgroundColor = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
TabNavigationItem(HomeTab, withText = titleVisible)
|
||||
|
@ -10,6 +10,7 @@ import androidx.compose.foundation.gestures.animateScrollBy
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -57,6 +58,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
@ -72,6 +74,7 @@ import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.core.screen.ScreenKey
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Dimensions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomDropDown
|
||||
@ -208,7 +211,18 @@ class CommunityDetailScreen(
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.padding(Spacing.xs),
|
||||
topBar = {
|
||||
val maxTopInset = Dimensions.topBarHeight.value.toInt()
|
||||
var topInset by remember { mutableStateOf(maxTopInset) }
|
||||
snapshotFlow { topAppBarState.collapsedFraction }.onEach {
|
||||
topInset = (maxTopInset * (1 - it)).toInt()
|
||||
}.launchIn(scope)
|
||||
|
||||
TopAppBar(
|
||||
windowInsets = if (settings.edgeToEdge) {
|
||||
WindowInsets(0, topInset, 0, 0)
|
||||
} else {
|
||||
TopAppBarDefaults.windowInsets
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
title = {
|
||||
Text(
|
||||
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -42,8 +43,11 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -56,6 +60,7 @@ import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Dimensions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenu
|
||||
@ -83,6 +88,8 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.createreport.CreateReportSc
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.web.WebViewScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.zoomableimage.ZoomableImageScreen
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MultiCommunityScreen(
|
||||
@ -116,7 +123,17 @@ class MultiCommunityScreen(
|
||||
Scaffold(
|
||||
topBar = {
|
||||
val sortType = uiState.sortType
|
||||
val maxTopInset = Dimensions.topBarHeight.value.toInt()
|
||||
var topInset by remember { mutableStateOf(maxTopInset) }
|
||||
snapshotFlow { topAppBarState.collapsedFraction }.onEach {
|
||||
topInset = (maxTopInset * (1 - it)).toInt()
|
||||
}.launchIn(scope)
|
||||
TopAppBar(
|
||||
windowInsets = if (settings.edgeToEdge) {
|
||||
WindowInsets(0, topInset, 0, 0)
|
||||
} else {
|
||||
TopAppBarDefaults.windowInsets
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = community.name,
|
||||
|
@ -69,7 +69,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.PostCardPl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.di.getFabNestedScrollConnection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.BlockBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.ListingTypeBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.RawContentDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.ShareBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SortBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.TabNavigationSection
|
||||
@ -84,6 +83,7 @@ import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.createpost.CreatePostScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.createreport.CreateReportScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.RawContentDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.web.WebViewScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.zoomableimage.ZoomableImageScreen
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
@ -165,6 +165,8 @@ class PostListScreen : Screen {
|
||||
listingType = uiState.listingType,
|
||||
sortType = uiState.sortType,
|
||||
scrollBehavior = scrollBehavior,
|
||||
topAppBarState = topAppBarState,
|
||||
edgeToEdge = settings.edgeToEdge,
|
||||
onHamburgerTapped = rememberCallback {
|
||||
scope.launch {
|
||||
drawerCoordinator.toggleDrawer()
|
||||
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
@ -14,10 +15,19 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.material3.TopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Dimensions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
@ -29,29 +39,46 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toIcon
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toReadableName
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
internal fun PostsTopBar(
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
topAppBarState: TopAppBarState,
|
||||
currentInstance: String,
|
||||
listingType: ListingType?,
|
||||
sortType: SortType?,
|
||||
edgeToEdge: Boolean = true,
|
||||
onSelectListingType: (() -> Unit)? = null,
|
||||
onSelectSortType: (() -> Unit)? = null,
|
||||
onHamburgerTapped: (() -> Unit)? = null,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val maxTopInset = Dimensions.topBarHeight.value.toInt()
|
||||
var topInset by remember { mutableStateOf(maxTopInset) }
|
||||
snapshotFlow { topAppBarState.collapsedFraction }.onEach {
|
||||
topInset = (maxTopInset * (1 - it)).toInt()
|
||||
}.launchIn(scope)
|
||||
|
||||
TopAppBar(
|
||||
windowInsets = if (edgeToEdge) {
|
||||
WindowInsets(0, topInset, 0, 0)
|
||||
} else {
|
||||
TopAppBarDefaults.windowInsets
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = {
|
||||
when {
|
||||
onHamburgerTapped != null -> {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
onHamburgerTapped()
|
||||
},
|
||||
),
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
onHamburgerTapped()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.Menu,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
@ -60,11 +87,12 @@ internal fun PostsTopBar(
|
||||
|
||||
listingType != null -> {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
onSelectListingType?.invoke()
|
||||
},
|
||||
),
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
onSelectListingType?.invoke()
|
||||
},
|
||||
),
|
||||
imageVector = listingType.toIcon(),
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
@ -116,11 +144,12 @@ internal fun PostsTopBar(
|
||||
}
|
||||
if (sortType != null) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
onSelectSortType?.invoke()
|
||||
},
|
||||
),
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
onSelectSortType?.invoke()
|
||||
},
|
||||
),
|
||||
imageVector = sortType.toIcon(),
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -51,6 +52,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
@ -67,6 +69,7 @@ import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.core.screen.ScreenKey
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Dimensions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomDropDown
|
||||
@ -185,7 +188,18 @@ class UserDetailScreen(
|
||||
topBar = {
|
||||
val userName = user.name
|
||||
val userHost = user.host
|
||||
val maxTopInset = Dimensions.topBarHeight.value.toInt()
|
||||
var topInset by remember { mutableStateOf(maxTopInset) }
|
||||
snapshotFlow { topAppBarState.collapsedFraction }.onEach {
|
||||
topInset = (maxTopInset * (1 - it)).toInt()
|
||||
}.launchIn(scope)
|
||||
|
||||
TopAppBar(
|
||||
windowInsets = if (settings.edgeToEdge) {
|
||||
WindowInsets(0, topInset, 0, 0)
|
||||
} else {
|
||||
TopAppBarDefaults.windowInsets
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
title = {
|
||||
Text(
|
||||
|
Loading…
x
Reference in New Issue
Block a user