Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

@Singleton
class PreferencesManager @Inject constructor(
@ApplicationContext private val context: Context

Check warning on line 22 in app/src/main/java/pub/hackers/android/data/local/PreferencesManager.kt

View workflow job for this annotation

GitHub Actions / lint

This annotation is currently applied to the value parameter only, but in the future it will also be applied to field.
) {
companion object {
private val CONFIRM_BEFORE_DELETE = booleanPreferencesKey("confirm_before_delete")
Expand All @@ -29,6 +29,7 @@
private val FONT_SIZE_MULTIPLIER = intPreferencesKey("font_size_multiplier") // stored as percentage (100 = 1.0x)
private val RECENT_SEARCHES = stringPreferencesKey("recent_searches")
private val THEME_MODE = stringPreferencesKey("theme_mode")
private val SHOW_LANGUAGE_FILTER = booleanPreferencesKey("show_language_filter")
private const val MAX_RECENT_SEARCHES = 10
}

Expand Down Expand Up @@ -74,6 +75,16 @@
}
}

val showLanguageFilter: Flow<Boolean> = context.preferencesDataStore.data.map { prefs ->
prefs[SHOW_LANGUAGE_FILTER] ?: false
}

suspend fun setShowLanguageFilter(value: Boolean) {
context.preferencesDataStore.edit { prefs ->
prefs[SHOW_LANGUAGE_FILTER] = value
}
}

suspend fun setConfirmBeforeDelete(value: Boolean) {
context.preferencesDataStore.edit { prefs ->
prefs[CONFIRM_BEFORE_DELETE] = value
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/pub/hackers/android/ui/HackersPubApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,13 @@
navigationIntent: pub.hackers.android.NavigationIntent? = null,
onDeepLinkConsumed: () -> Unit = {},
onNavigationIntentConsumed: () -> Unit = {},
viewModel: AppViewModel = hiltViewModel()

Check warning on line 179 in app/src/main/java/pub/hackers/android/ui/HackersPubApp.kt

View workflow job for this annotation

GitHub Actions / lint

'fun <reified VM : ViewModel> hiltViewModel(viewModelStoreOwner: ViewModelStoreOwner = ..., key: String? = ...): VM' is deprecated. Moved to package: androidx.hilt.lifecycle.viewmodel.compose.
) {
val navController = rememberNavController()
val isLoggedInState by viewModel.isLoggedIn.collectAsState(initial = null as Boolean?)

val fontSizePercent by viewModel.preferencesManager.fontSizePercent.collectAsState(initial = 100)
val showLanguageFilter by viewModel.preferencesManager.showLanguageFilter.collectAsState(initial = false)
val hasUnread by viewModel.hasUnread.collectAsState()
var selectedHomeFeed by remember { mutableStateOf(HomeFeed.TIMELINE) }

Expand Down Expand Up @@ -364,6 +365,7 @@
.collectAsState()
TimelineScreen(
tabRetapped = tabRetapped,
showLanguageFilter = showLanguageFilter,
selectedHomeFeed = selectedHomeFeed,
onHomeFeedSelected = ::navigateHomeFeed,
onPostClick = { postId ->
Expand Down Expand Up @@ -419,6 +421,7 @@

composable(Screen.Explore.route) {
ExploreScreen(
showLanguageFilter = showLanguageFilter,
onPostClick = { postId ->
navController.navigate(DetailScreen.PostDetail.createRoute(postId))
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
onEditClick: (String) -> Unit = {},
onSignInClick: () -> Unit,
isLoggedIn: Boolean,
showLanguageFilter: Boolean = false,
viewModel: ExploreViewModel = hiltViewModel()

Check warning on line 63 in app/src/main/java/pub/hackers/android/ui/screens/explore/ExploreScreen.kt

View workflow job for this annotation

GitHub Actions / lint

'fun <reified VM : ViewModel> hiltViewModel(viewModelStoreOwner: ViewModelStoreOwner = ..., key: String? = ...): VM' is deprecated. Moved to package: androidx.hilt.lifecycle.viewmodel.compose.
) {
val items = viewModel.posts.collectAsLazyPagingItems()
val newerPosts by viewModel.newerPosts.collectAsState()
Expand All @@ -72,6 +73,11 @@
val colors = LocalAppColors.current
val typography = LocalAppTypography.current

// A language selected before the filter row was hidden would otherwise keep filtering invisibly.
LaunchedEffect(showLanguageFilter) {
if (!showLanguageFilter) viewModel.selectLanguage(null)
}

// Scroll to top when tab changes.
LaunchedEffect(selectedTab) {
listState.scrollToItem(0)
Expand Down Expand Up @@ -162,13 +168,15 @@
modifier = Modifier.padding(horizontal = 16.dp)
)

LanguageFilterRow(
languages = uiState.suggestedFilterLanguages,
selectedLanguage = uiState.selectedLanguage,
onLanguageSelected = viewModel::selectLanguage,
)
if (showLanguageFilter) {
LanguageFilterRow(
languages = uiState.suggestedFilterLanguages,
selectedLanguage = uiState.selectedLanguage,
onLanguageSelected = viewModel::selectLanguage,
)

HorizontalDivider(color = colors.divider)
HorizontalDivider(color = colors.divider)
}

Box(modifier = Modifier.fillMaxSize()) {
val refresh = items.loadState.refresh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Fingerprint
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Language
import androidx.compose.material.icons.filled.Login
import androidx.compose.material.icons.filled.Palette
import androidx.compose.material3.AlertDialog
Expand All @@ -37,6 +38,7 @@
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -71,7 +73,7 @@
onBookmarksClick: () -> Unit = {},
onLicensesClick: () -> Unit = {},
isLoggedIn: Boolean,
viewModel: SettingsViewModel = hiltViewModel()

Check warning on line 76 in app/src/main/java/pub/hackers/android/ui/screens/settings/SettingsScreen.kt

View workflow job for this annotation

GitHub Actions / lint

'fun <reified VM : ViewModel> hiltViewModel(viewModelStoreOwner: ViewModelStoreOwner = ..., key: String? = ...): VM' is deprecated. Moved to package: androidx.hilt.lifecycle.viewmodel.compose.
) {
val uiState by viewModel.uiState.collectAsState()
val snackbarHostState = remember { SnackbarHostState() }
Expand Down Expand Up @@ -346,7 +348,7 @@
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Filled.Login,

Check warning on line 351 in app/src/main/java/pub/hackers/android/ui/screens/settings/SettingsScreen.kt

View workflow job for this annotation

GitHub Actions / lint

'val Icons.Filled.Login: ImageVector' is deprecated. Use the AutoMirrored version at Icons.AutoMirrored.Filled.Login.
contentDescription = null,
tint = colors.textSecondary
)
Expand Down Expand Up @@ -390,6 +392,39 @@

HorizontalDivider(color = colors.divider, thickness = 1.dp)

Row(
modifier = Modifier
.fillMaxWidth()
.clickable { viewModel.setShowLanguageFilter(!uiState.showLanguageFilter) }
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Filled.Language,
contentDescription = null,
tint = colors.textSecondary
)
Spacer(modifier = Modifier.width(16.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = stringResource(R.string.settings_show_language_filter),
style = typography.bodyLarge,
color = colors.textPrimary
)
Text(
text = stringResource(R.string.settings_show_language_filter_description),
style = typography.bodyMedium,
color = colors.textSecondary
)
}
Switch(
checked = uiState.showLanguageFilter,
onCheckedChange = viewModel::setShowLanguageFilter
)
}

HorizontalDivider(color = colors.divider, thickness = 1.dp)

Row(
modifier = Modifier
.fillMaxWidth()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
val useInAppBrowser: Boolean = true,
val fontSizePercent: Int = 100,
val themeMode: ThemeMode = ThemeMode.SYSTEM,
val showLanguageFilter: Boolean = false,
val passkeys: List<Passkey> = emptyList(),
val accountId: String? = null,
val isLoadingPasskeys: Boolean = false,
Expand All @@ -61,7 +62,7 @@
private val passkeyManager: PasskeyManager,
private val fcmTokenManager: FcmTokenManager,
private val workManager: WorkManager,
@ApplicationContext private val context: Context

Check warning on line 65 in app/src/main/java/pub/hackers/android/ui/screens/settings/SettingsViewModel.kt

View workflow job for this annotation

GitHub Actions / lint

This annotation is currently applied to the value parameter only, but in the future it will also be applied to field.
) : ViewModel() {

private val _uiState = MutableStateFlow(SettingsUiState())
Expand Down Expand Up @@ -112,6 +113,7 @@
val inAppBrowser = preferencesManager.useInAppBrowser.first()
val fontSize = preferencesManager.fontSizePercent.first()
val theme = preferencesManager.themeMode.first()
val showLanguageFilter = preferencesManager.showLanguageFilter.first()

_uiState.update {
it.copy(
Expand All @@ -120,7 +122,8 @@
timelineMaxLength = maxLength,
useInAppBrowser = inAppBrowser,
fontSizePercent = fontSize,
themeMode = theme
themeMode = theme,
showLanguageFilter = showLanguageFilter
)
}
}
Expand Down Expand Up @@ -156,6 +159,11 @@
viewModelScope.launch { preferencesManager.setThemeMode(value) }
}

fun setShowLanguageFilter(value: Boolean) {
_uiState.update { it.copy(showLanguageFilter = value) }
viewModelScope.launch { preferencesManager.setShowLanguageFilter(value) }
}

fun signOut() {
viewModelScope.launch {
fcmTokenManager.unregisterCurrentToken()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@
selectedHomeFeed: HomeFeed = HomeFeed.TIMELINE,
onHomeFeedSelected: (HomeFeed) -> Unit = {},
tabRetapped: Long = 0L,
showLanguageFilter: Boolean = false,
userAvatarUrl: String? = null,
viewModel: TimelineViewModel = hiltViewModel()

Check warning on line 78 in app/src/main/java/pub/hackers/android/ui/screens/timeline/TimelineScreen.kt

View workflow job for this annotation

GitHub Actions / lint

'fun <reified VM : ViewModel> hiltViewModel(viewModelStoreOwner: ViewModelStoreOwner = ..., key: String? = ...): VM' is deprecated. Moved to package: androidx.hilt.lifecycle.viewmodel.compose.
) {
val uiState by viewModel.uiState.collectAsState()
val items = viewModel.posts.collectAsLazyPagingItems()
Expand All @@ -85,6 +86,11 @@
val bookmarkRemovedMessage = stringResource(R.string.bookmark_removed)
val colors = LocalAppColors.current

// A language selected before the filter row was hidden would otherwise keep filtering invisibly.
LaunchedEffect(showLanguageFilter) {
if (!showLanguageFilter) viewModel.selectLanguage(null)
}

// Refresh draft count when screen becomes visible (e.g., returning from Drafts)
LaunchedEffect(Unit) {
viewModel.loadDraftCount()
Expand Down Expand Up @@ -233,12 +239,14 @@
.fillMaxSize()
.padding(paddingValues)
) {
LanguageFilterRow(
languages = uiState.suggestedFilterLanguages,
selectedLanguage = uiState.selectedLanguage,
onLanguageSelected = viewModel::selectLanguage,
)
HorizontalDivider(color = colors.divider)
if (showLanguageFilter) {
LanguageFilterRow(
languages = uiState.suggestedFilterLanguages,
selectedLanguage = uiState.selectedLanguage,
onLanguageSelected = viewModel::selectLanguage,
)
HorizontalDivider(color = colors.divider)
}

Box(modifier = Modifier.weight(1f)) {
val refresh = items.loadState.refresh
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<string name="verification_description">Enter the verification code sent to your email.</string>
<string name="send_code">Send Code</string>
<string name="verify">Verify</string>
<string name="account_not_found">Account not found</string>

Check warning on line 20 in app/src/main/res/values/strings.xml

View workflow job for this annotation

GitHub Actions / lint

The resource `R.string.account_not_found` appears to be unused [UnusedResources]
<string name="or">or</string>
<string name="sign_in_with_passkey">Sign in with Passkey</string>
<string name="passkeys">Passkeys</string>
Expand All @@ -32,7 +32,7 @@
<string name="asset_statements" translatable="false">[{\"include\":\"https://hackers.pub/.well-known/assetlinks.json\"}]</string>

<!-- Timeline -->
<string name="local_timeline">Hackers\' Pub</string>

Check warning on line 35 in app/src/main/res/values/strings.xml

View workflow job for this annotation

GitHub Actions / lint

The resource `R.string.local_timeline` appears to be unused [UnusedResources]
<string name="global_timeline">Fediverse</string>
<string name="personal_timeline">Home</string>
<string name="home_feed_selector_expanded">Home feed selector expanded</string>
Expand All @@ -40,7 +40,7 @@
<string name="news_order_popular">Popular</string>
<string name="news_order_newest">Newest</string>
<string name="news_order_all_time">All-time</string>
<string name="news_discussion_count">%1$d comments</string>

Check warning on line 43 in app/src/main/res/values/strings.xml

View workflow job for this annotation

GitHub Actions / lint

Formatting %d followed by words ("comments"): This should probably be a plural rather than a string [PluralsCandidate]
<string name="news_empty">No news stories yet</string>
<string name="all_languages">All languages</string>
<string name="no_posts">No posts yet</string>
Expand Down Expand Up @@ -208,6 +208,8 @@
<string name="settings_timeline_max_length">Post preview length</string>
<string name="settings_timeline_unlimited">Unlimited</string>
<string name="settings_theme">Theme</string>
<string name="settings_show_language_filter">Show language filter</string>
<string name="settings_show_language_filter_description">Show language chips above the Home and Explore feeds</string>
<string name="settings_theme_system">Follow system</string>
<string name="settings_theme_light">Light</string>
<string name="settings_theme_dark">Dark</string>
Expand Down
Loading