Notification policy (#4768)
This was so much work wow. I think it works pretty well and is the best compromise between all the alternative we considered. Yes the pull-to-refreh on the notifications works slightly different now when the new bar is visible, but I don't think there is a way around that. Things I plan to do later, i.e. not as part of this PR or release: - Cache the notification policy summary for better offline behavior and less view shifting when it loads - try to reduce some of the code duplications that are now in there - if there is user demand, add a "legacy mode" setting where this feature is disabled even if the server would support it closes #4331 closes #4550 as won't do closes #4712 as won't do <img src="https://github.com/user-attachments/assets/de322d3c-3775-41e7-be57-28ab7fbaecdf" width="240"/> <img src="https://github.com/user-attachments/assets/1ce958a4-4f15-484c-a337-5ad93f36046c" width="240"/> <img src="https://github.com/user-attachments/assets/98b0482b-1c05-4c99-a371-f7f4d8a69abd" width="240"/>
This commit is contained in:
parent
29914f8fd9
commit
cd57352cbd
42 changed files with 2401 additions and 97 deletions
|
|
@ -0,0 +1,74 @@
|
|||
package com.keylesspalace.tusky.usecase
|
||||
|
||||
import at.connyduck.calladapter.networkresult.NetworkResult
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import at.connyduck.calladapter.networkresult.onSuccess
|
||||
import com.keylesspalace.tusky.entity.NotificationPolicy
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import retrofit2.HttpException
|
||||
|
||||
class NotificationPolicyUsecase @Inject constructor(
|
||||
private val api: MastodonApi
|
||||
) {
|
||||
|
||||
private val _state: MutableStateFlow<NotificationPolicyState> = MutableStateFlow(NotificationPolicyState.Loading)
|
||||
val state: StateFlow<NotificationPolicyState> = _state.asStateFlow()
|
||||
|
||||
suspend fun getNotificationPolicy() {
|
||||
_state.value.let { state ->
|
||||
if (state is NotificationPolicyState.Loaded) {
|
||||
_state.value = state.copy(refreshing = true)
|
||||
} else {
|
||||
_state.value = NotificationPolicyState.Loading
|
||||
}
|
||||
}
|
||||
|
||||
api.notificationPolicy().fold(
|
||||
{ policy ->
|
||||
_state.value = NotificationPolicyState.Loaded(refreshing = false, policy = policy)
|
||||
},
|
||||
{ t ->
|
||||
if (t is HttpException && t.code() == 404) {
|
||||
_state.value = NotificationPolicyState.Unsupported
|
||||
} else {
|
||||
_state.value = NotificationPolicyState.Error(t)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun updatePolicy(
|
||||
forNotFollowing: String? = null,
|
||||
forNotFollowers: String? = null,
|
||||
forNewAccounts: String? = null,
|
||||
forPrivateMentions: String? = null,
|
||||
forLimitedAccounts: String? = null
|
||||
): NetworkResult<NotificationPolicy> {
|
||||
return api.updateNotificationPolicy(
|
||||
forNotFollowing = forNotFollowing,
|
||||
forNotFollowers = forNotFollowers,
|
||||
forNewAccounts = forNewAccounts,
|
||||
forPrivateMentions = forPrivateMentions,
|
||||
forLimitedAccounts = forLimitedAccounts
|
||||
).onSuccess { notificationPolicy ->
|
||||
_state.value = NotificationPolicyState.Loaded(false, notificationPolicy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface NotificationPolicyState {
|
||||
|
||||
data object Loading : NotificationPolicyState
|
||||
data object Unsupported : NotificationPolicyState
|
||||
data class Error(
|
||||
val throwable: Throwable
|
||||
) : NotificationPolicyState
|
||||
data class Loaded(
|
||||
val refreshing: Boolean,
|
||||
val policy: NotificationPolicy
|
||||
) : NotificationPolicyState
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue