fix: rc10 reports (#159)

* enhancement(app): initialization and settings loading

* enhancement(common-ui): prevent keyboard from closing when scrolling in create text fields

* fix(drawer): improve navigation content
This commit is contained in:
Diego Beraldin 2023-11-25 14:23:11 +01:00 committed by GitHub
parent 86fe4f5379
commit 95da52b23c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 148 additions and 181 deletions

View File

@ -36,12 +36,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
@ -106,18 +101,6 @@ class CreateCommentScreen(
)
}
val commentFocusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val keyboardScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(
available: Offset,
source: NestedScrollSource,
): Offset {
focusManager.clearFocus()
return Offset.Zero
}
}
}
val topAppBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topAppBarState)
@ -158,7 +141,6 @@ class CreateCommentScreen(
}
Scaffold(
modifier = Modifier.nestedScroll(keyboardScrollConnection),
topBar = {
TopAppBar(
scrollBehavior = scrollBehavior,

View File

@ -41,11 +41,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.ImeAction
@ -131,17 +127,6 @@ class CreatePostScreen(
}
}
var openSelectCommunity by remember { mutableStateOf(false) }
val keyboardScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(
available: Offset,
source: NestedScrollSource,
): Offset {
focusManager.clearFocus()
return Offset.Zero
}
}
}
val topAppBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topAppBarState)
@ -200,7 +185,6 @@ class CreatePostScreen(
}
Scaffold(
modifier = Modifier.nestedScroll(keyboardScrollConnection),
topBar = {
TopAppBar(
scrollBehavior = scrollBehavior,

View File

@ -149,21 +149,21 @@ object ModalDrawerContent : Tab {
bottom = Spacing.s,
)
)
val pullRefreshState = rememberPullRefreshState(
refreshing = uiState.refreshing,
onRefresh = rememberCallback(model) {
model.reduce(ModalDrawerMviModel.Intent.Refresh)
},
)
Box(
modifier = Modifier.weight(1f).pullRefresh(pullRefreshState),
) {
LazyColumn(
modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.xxs),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
if (uiState.user != null) {
val pullRefreshState = rememberPullRefreshState(
refreshing = uiState.refreshing,
onRefresh = rememberCallback(model) {
model.reduce(ModalDrawerMviModel.Intent.Refresh)
},
)
Box(
modifier = Modifier.weight(1f).pullRefresh(pullRefreshState),
) {
if (uiState.user != null) {
LazyColumn(
modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.xxs),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
item {
DrawerShortcut(
title = stringResource(MR.strings.navigation_drawer_title_subscriptions),
@ -185,50 +185,50 @@ object ModalDrawerContent : Tab {
}
})
}
}
items(uiState.multiCommunities) { community ->
MultiCommunityItem(
modifier = Modifier.fillMaxWidth().onClick(
onClick = rememberCallback {
scope.launch {
coordinator.toggleDrawer()
coordinator.sendEvent(
DrawerEvent.OpenMultiCommunity(community),
)
}
},
),
community = community,
small = true,
autoLoadImages = uiState.autoLoadImages,
)
}
items(uiState.communities) { community ->
CommunityItem(
modifier = Modifier.fillMaxWidth().onClick(
onClick = rememberCallback {
scope.launch {
coordinator.toggleDrawer()
coordinator.sendEvent(
DrawerEvent.OpenCommunity(community),
)
}
},
),
community = community,
small = true,
autoLoadImages = uiState.autoLoadImages,
)
items(uiState.multiCommunities) { community ->
MultiCommunityItem(
modifier = Modifier.fillMaxWidth().onClick(
onClick = rememberCallback {
scope.launch {
coordinator.toggleDrawer()
coordinator.sendEvent(
DrawerEvent.OpenMultiCommunity(community),
)
}
},
),
community = community,
small = true,
autoLoadImages = uiState.autoLoadImages,
)
}
items(uiState.communities) { community ->
CommunityItem(
modifier = Modifier.fillMaxWidth().onClick(
onClick = rememberCallback {
scope.launch {
coordinator.toggleDrawer()
coordinator.sendEvent(
DrawerEvent.OpenCommunity(community),
)
}
},
),
community = community,
small = true,
autoLoadImages = uiState.autoLoadImages,
)
}
}
PullRefreshIndicator(
refreshing = uiState.refreshing,
state = pullRefreshState,
modifier = Modifier.align(Alignment.TopCenter),
backgroundColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
)
}
PullRefreshIndicator(
refreshing = uiState.refreshing,
state = pullRefreshState,
modifier = Modifier.align(Alignment.TopCenter),
backgroundColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
)
}
}

View File

@ -46,6 +46,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.AppTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.ic_launcher_background
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.md_theme_dark_onPrimary
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.getCommunityFromUrl
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.getPostFromUrl
@ -81,10 +82,32 @@ fun App() {
val accountRepository = remember { getAccountRepository() }
val settingsRepository = remember { getSettingsRepository() }
val settings by settingsRepository.currentSettings.collectAsState()
var hasBeenInitialized by remember { mutableStateOf(false) }
val apiConfigurationRepository = remember { getApiConfigurationRepository() }
val crashReportSender = remember { getCrashReportSender() }
val crashReportConfiguration = remember { getCrashReportConfiguration() }
val themeRepository = remember { getThemeRepository() }
val defaultLocale = stringResource(MR.strings.lang)
val languageRepository = remember { getLanguageRepository() }
val locale by derivedStateOf { settings.locale }
val defaultTheme = if (isSystemInDarkTheme()) {
UiTheme.Dark.toInt()
} else {
UiTheme.Light.toInt()
}
val currentTheme by themeRepository.uiTheme.collectAsState()
val useDynamicColors by themeRepository.dynamicColors.collectAsState()
val fontScale by themeRepository.contentFontScale.collectAsState()
val uiFontScale by themeRepository.uiFontScale.collectAsState()
val navigationCoordinator = remember { getNavigationCoordinator() }
val scope = rememberCoroutineScope()
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val drawerCoordinator = remember { getDrawerCoordinator() }
val drawerGestureEnabled by drawerCoordinator.gesturesEnabled.collectAsState()
var isInitialized by remember { mutableStateOf(false) }
languageRepository.currentLanguage.onEach { lang ->
StringDesc.localeType = StringDesc.LocaleType.Custom(lang)
}.launchIn(scope)
LaunchedEffect(Unit) {
val accountId = accountRepository.getActive()?.id
@ -95,52 +118,32 @@ fun App() {
if (lastInstance != null) {
apiConfigurationRepository.changeInstance(lastInstance)
}
crashReportSender.initialize()
crashReportSender.setEnabled(crashReportConfiguration.isEnabled())
hasBeenInitialized = true
}
with(crashReportSender) {
initialize()
setEnabled(crashReportConfiguration.isEnabled())
}
val defaultTheme = if (isSystemInDarkTheme()) {
UiTheme.Dark.toInt()
} else {
UiTheme.Light.toInt()
}
with(themeRepository) {
changeUiTheme((currentSettings.theme ?: defaultTheme).toUiTheme())
changeNavItemTitles(currentSettings.navigationTitlesVisible)
changeDynamicColors(currentSettings.dynamicColors)
changeCustomSeedColor(currentSettings.customSeedColor?.let { Color(it) })
changePostLayout(currentSettings.postLayout.toPostLayout())
changeContentFontScale(currentSettings.contentFontScale)
changeUiFontScale(currentSettings.uiFontScale)
changeUiFontFamily(currentSettings.uiFontFamily.toUiFontFamily())
val defaultLocale = stringResource(MR.strings.lang)
val languageRepository = remember { getLanguageRepository() }
val locale by derivedStateOf { settings.locale }
with(themeRepository) {
changeUpvoteColor(currentSettings.upvoteColor?.let { Color(it) })
changeDownvoteColor(currentSettings.downvoteColor?.let { Color(it) })
}
}
isInitialized = true
}
LaunchedEffect(locale) {
languageRepository.changeLanguage(locale ?: defaultLocale)
}
val scope = rememberCoroutineScope()
languageRepository.currentLanguage.onEach { lang ->
StringDesc.localeType = StringDesc.LocaleType.Custom(lang)
}.launchIn(scope)
val themeRepository = remember { getThemeRepository() }
LaunchedEffect(settings) {
with(themeRepository) {
changeUiTheme((settings.theme ?: defaultTheme).toUiTheme())
changeNavItemTitles(settings.navigationTitlesVisible)
changeDynamicColors(settings.dynamicColors)
changeCustomSeedColor(settings.customSeedColor?.let { Color(it) })
changePostLayout(settings.postLayout.toPostLayout())
changeContentFontScale(settings.contentFontScale)
changeUiFontScale(settings.uiFontScale)
changeUiFontFamily(settings.uiFontFamily.toUiFontFamily())
with(themeRepository) {
changeUpvoteColor(settings.upvoteColor?.let { Color(it) })
changeDownvoteColor(settings.downvoteColor?.let { Color(it) })
}
}
}
val currentTheme by themeRepository.uiTheme.collectAsState()
val useDynamicColors by themeRepository.dynamicColors.collectAsState()
val fontScale by themeRepository.contentFontScale.collectAsState()
val uiFontScale by themeRepository.uiFontScale.collectAsState()
val navigationCoordinator = remember { getNavigationCoordinator() }
LaunchedEffect(navigationCoordinator) {
navigationCoordinator.deepLinkUrl.debounce(750).onEach { url ->
val community = getCommunityFromUrl(url)
@ -176,10 +179,6 @@ fun App() {
}
}.launchIn(this)
}
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val drawerCoordinator = remember { getDrawerCoordinator() }
val drawerGestureEnabled by drawerCoordinator.gesturesEnabled.collectAsState()
LaunchedEffect(drawerCoordinator) {
drawerCoordinator.toggleEvents.onEach { evt ->
when (evt) {
@ -227,57 +226,59 @@ fun App() {
fontScale = uiFontScale,
),
) {
BottomSheetNavigator(
sheetShape = RoundedCornerShape(
topStart = CornerSize.xl, topEnd = CornerSize.xl
),
sheetBackgroundColor = MaterialTheme.colorScheme.background,
) { bottomNavigator ->
navigationCoordinator.setBottomNavigator(bottomNavigator)
if (isInitialized) {
BottomSheetNavigator(
sheetShape = RoundedCornerShape(
topStart = CornerSize.xl, topEnd = CornerSize.xl
),
sheetBackgroundColor = MaterialTheme.colorScheme.background,
) { bottomNavigator ->
navigationCoordinator.setBottomNavigator(bottomNavigator)
ModalNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = drawerGestureEnabled,
drawerContent = {
ModalDrawerSheet {
TabNavigator(ModalDrawerContent)
}
},
) {
Navigator(screen = MainScreen, onBackPressed = {
val callback = navigationCoordinator.getCanGoBackCallback()
callback?.let { it() } ?: true
}) { navigator ->
LaunchedEffect(Unit) {
navigationCoordinator.setRootNavigator(navigator)
}
if (hasBeenInitialized) {
CurrentScreen()
} else {
Box(
modifier = Modifier
.fillMaxSize()
.background(color = ic_launcher_background),
contentAlignment = Alignment.Center,
) {
Column(
modifier = Modifier.padding(top = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
Image(
painter = painterResource(MR.images.icon),
contentDescription = null,
)
CircularProgressIndicator(
color = MaterialTheme.colorScheme.onPrimary,
)
}
ModalNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = drawerGestureEnabled,
drawerContent = {
ModalDrawerSheet {
TabNavigator(ModalDrawerContent)
}
},
) {
Navigator(screen = MainScreen, onBackPressed = {
val callback = navigationCoordinator.getCanGoBackCallback()
callback?.let { it() } ?: true
}) { navigator ->
LaunchedEffect(Unit) {
navigationCoordinator.setRootNavigator(navigator)
}
CurrentScreen()
}
}
}
} else {
Box(
modifier = Modifier
.fillMaxSize()
.background(color = ic_launcher_background),
contentAlignment = Alignment.Center,
) {
Column(
modifier = Modifier.padding(top = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
Image(
painter = painterResource(MR.images.icon),
contentDescription = null,
)
CircularProgressIndicator(
color = md_theme_dark_onPrimary,
)
}
}
}
}
}