diff --git a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index a3a16dda8..eee89bf05 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -50,6 +50,7 @@ private object PrefKeys { const val DEFAULT_FILE_SERVER = "defaultFileServer" const val DEFAULT_HOME_FOLLOW_LIST = "defaultHomeFollowList" const val DEFAULT_STORIES_FOLLOW_LIST = "defaultStoriesFollowList" + const val DEFAULT_NOTIFICATION_FOLLOW_LIST = "defaultNotificationFollowList" const val ZAP_PAYMENT_REQUEST_SERVER = "zapPaymentServer" const val LATEST_CONTACT_LIST = "latestContactList" const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog" @@ -203,6 +204,7 @@ object LocalPreferences { putString(PrefKeys.DEFAULT_FILE_SERVER, gson.toJson(account.defaultFileServer)) putString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, account.defaultHomeFollowList) putString(PrefKeys.DEFAULT_STORIES_FOLLOW_LIST, account.defaultStoriesFollowList) + putString(PrefKeys.DEFAULT_NOTIFICATION_FOLLOW_LIST, account.defaultNotificationFollowList) putString(PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, gson.toJson(account.zapPaymentRequest)) putString(PrefKeys.LATEST_CONTACT_LIST, Event.gson.toJson(account.backupContactList)) putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog) @@ -225,6 +227,7 @@ object LocalPreferences { val translateTo = getString(PrefKeys.TRANSLATE_TO, null) ?: Locale.getDefault().language val defaultHomeFollowList = getString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, null) ?: KIND3_FOLLOWS val defaultStoriesFollowList = getString(PrefKeys.DEFAULT_STORIES_FOLLOW_LIST, null) ?: GLOBAL_FOLLOWS + val defaultNotificationFollowList = getString(PrefKeys.DEFAULT_NOTIFICATION_FOLLOW_LIST, null) ?: GLOBAL_FOLLOWS val zapAmountChoices = gson.fromJson( getString(PrefKeys.ZAP_AMOUNTS, "[]"), @@ -288,6 +291,7 @@ object LocalPreferences { defaultFileServer, defaultHomeFollowList, defaultStoriesFollowList, + defaultNotificationFollowList, zapPaymentRequestServer, hideDeleteRequestDialog, hideBlockAlertDialog, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 726d8db7c..2796ed79a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -55,6 +55,7 @@ class Account( var defaultFileServer: ServersAvailable = ServersAvailable.IMGUR, var defaultHomeFollowList: String = KIND3_FOLLOWS, var defaultStoriesFollowList: String = GLOBAL_FOLLOWS, + var defaultNotificationFollowList: String = GLOBAL_FOLLOWS, var zapPaymentRequest: Nip47URI? = null, var hideDeleteRequestDialog: Boolean = false, var hideBlockAlertDialog: Boolean = false, @@ -751,6 +752,12 @@ class Account( saveable.invalidateData() } + fun changeDefaultNotificationFollowList(name: String) { + defaultNotificationFollowList = name + live.invalidateData() + saveable.invalidateData() + } + fun changeZapAmounts(newAmounts: List) { zapAmountChoices = newAmounts live.invalidateData() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt index ba746ebba..ea26abdd3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt @@ -1,6 +1,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account +import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User @@ -18,6 +19,10 @@ object NotificationFeedFilter : AdditiveFeedFilter() { } private fun innerApplyFilter(collection: Collection): Set { + val isGlobal = account.defaultNotificationFollowList == GLOBAL_FOLLOWS + + val followingKeySet = account.selectedUsersFollowList(account.defaultNotificationFollowList) ?: emptySet() + val loggedInUser = account.userProfile() val loggedInUserHex = loggedInUser.pubkeyHex @@ -28,6 +33,7 @@ object NotificationFeedFilter : AdditiveFeedFilter() { it.event !is BadgeDefinitionEvent && it.event !is BadgeProfilesEvent && it.author !== loggedInUser && + (isGlobal || it.author?.pubkeyHex in followingKeySet) && it.event?.isTaggedUser(loggedInUserHex) ?: false && (it.author == null || !account.isHidden(it.author!!.pubkeyHex)) && tagsAnEventByUser(it, loggedInUser) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt index 3cc324086..b18aefcda 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt @@ -81,6 +81,7 @@ fun AppTopBar(navController: NavHostController, scaffoldState: ScaffoldState, ac // Route.Profile.route -> TopBarWithBackButton(navController) Route.Home.base -> HomeTopBar(scaffoldState, accountViewModel) Route.Video.base -> StoriesTopBar(scaffoldState, accountViewModel) + Route.Notification.base -> NotificationTopBar(scaffoldState, accountViewModel) else -> MainTopBar(scaffoldState, accountViewModel) } } @@ -103,6 +104,15 @@ fun HomeTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) } } +@Composable +fun NotificationTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) { + GenericTopBar(scaffoldState, accountViewModel) { account -> + FollowList(account.defaultNotificationFollowList, account.userProfile(), true) { listName -> + account.changeDefaultNotificationFollowList(listName) + } + } +} + @Composable fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) { GenericTopBar(scaffoldState, accountViewModel) { @@ -273,13 +283,13 @@ fun SimpleTextSpinner( ) { val interactionSource = remember { MutableInteractionSource() } var optionsShowing by remember { mutableStateOf(false) } - var currentText by remember { mutableStateOf(placeholder) } + var currentText by remember(placeholder) { mutableStateOf(placeholder) } Box( modifier = modifier, contentAlignment = Alignment.Center ) { - Text(currentText) + Text(placeholder) Box( modifier = Modifier .matchParentSize() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt index defff2d01..70c152010 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt @@ -38,7 +38,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter) : ViewModel() { private var lastAccount: Account? = null private var lastNotes: List? = null - private fun refresh() { + fun refresh() { val scope = CoroutineScope(Job() + Dispatchers.Default) scope.launch { refreshSuspended() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt index 5d7c6265c..658963ab4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt @@ -50,12 +50,12 @@ fun HomeScreen( nip47: String? = null ) { val coroutineScope = rememberCoroutineScope() - val account = accountViewModel.accountLiveData.value?.account ?: return var wantsToAddNip47 by remember { mutableStateOf(nip47) } - val accountState = account.live.observeAsState() + val accountState by accountViewModel.accountLiveData.observeAsState() + val account = accountState?.account ?: return - LaunchedEffect(accountViewModel, accountState.value?.account?.defaultHomeFollowList) { + LaunchedEffect(accountViewModel, account.defaultHomeFollowList) { HomeNewThreadFeedFilter.account = account HomeConversationsFeedFilter.account = account NostrHomeDataSource.resetFilters() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt index 96149588d..9046a1569 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.navigation.NavController +import com.vitorpamplona.amethyst.service.NostrAccountDataSource import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter import com.vitorpamplona.amethyst.ui.navigation.Route import com.vitorpamplona.amethyst.ui.screen.CardFeedView @@ -34,9 +35,11 @@ fun NotificationScreen( notifFeedViewModel.clear() } - LaunchedEffect(accountViewModel) { + LaunchedEffect(account.userProfile().pubkeyHex, account.defaultNotificationFollowList) { + NostrAccountDataSource.resetFilters() NotificationFeedFilter.account = account - notifFeedViewModel.invalidateData() + notifFeedViewModel.clear() + notifFeedViewModel.refresh() } val lifeCycleOwner = LocalLifecycleOwner.current