Add support for muting conversations (#1732)

* Add support for muting conversations
Implements #1731

* Fix CI

* Apply code review feedback
This commit is contained in:
Levi Bard 2020-03-24 21:06:04 +01:00 committed by GitHub
commit 8cb83050ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 904 additions and 19 deletions

View file

@ -157,6 +157,7 @@ data class ConversationStatusEntity(
mentions = mentions,
application = null,
pinned = false,
muted = false,
poll = poll,
card = null)
}

View file

@ -213,6 +213,18 @@ class SearchViewModel @Inject constructor(
search(currentQuery)
}
fun muteConversation(status: Pair<Status, StatusViewData.Concrete>, mute: Boolean) {
val idx = loadedStatuses.indexOf(status)
if (idx >= 0) {
val newPair = Pair(status.first, StatusViewData.Builder(status.second).setMuted(mute).createStatusViewData())
loadedStatuses[idx] = newPair
repoResultStatus.value?.refresh?.invoke()
}
timelineCases.muteConversation(status.first, mute)
.onErrorReturnItem(status.first)
.subscribe()
.autoDispose()
}
companion object {
private const val TAG = "SearchViewModel"

View file

@ -49,6 +49,7 @@ import com.keylesspalace.tusky.components.search.adapter.SearchStatusesAdapter
import com.keylesspalace.tusky.db.AccountEntity
import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.entity.Status.Mention
import com.keylesspalace.tusky.interfaces.AccountSelectionListener
import com.keylesspalace.tusky.interfaces.StatusActionListener
import com.keylesspalace.tusky.util.CardViewMode
@ -228,12 +229,9 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
val loggedInAccountId = viewModel.activeAccount?.accountId
val popup = PopupMenu(view.context, view)
val statusIsByCurrentUser = loggedInAccountId?.equals(accountId) == true
// Give a different menu depending on whether this is the user's own toot or not.
if (loggedInAccountId == null || loggedInAccountId != accountId) {
popup.inflate(R.menu.status_more)
val menu = popup.menu
menu.findItem(R.id.status_download_media).isVisible = status.attachments.isNotEmpty()
} else {
if (statusIsByCurrentUser) {
popup.inflate(R.menu.status_more_for_user)
val menu = popup.menu
menu.findItem(R.id.status_open_as).isVisible = !statusUrl.isNullOrBlank()
@ -251,6 +249,10 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
Status.Visibility.UNKNOWN, Status.Visibility.DIRECT -> {
} //Ignore
}
} else {
popup.inflate(R.menu.status_more)
val menu = popup.menu
menu.findItem(R.id.status_download_media).isVisible = status.attachments.isNotEmpty()
}
val openAsItem = popup.menu.findItem(R.id.status_open_as)
@ -266,6 +268,19 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
}
openAsItem.title = openAsTitle
val mutable = statusIsByCurrentUser || accountIsInMentions(viewModel.activeAccount, status.mentions)
val muteConversationItem = popup.menu.findItem(R.id.status_mute_conversation).apply {
isVisible = mutable
}
if (mutable) {
muteConversationItem.setTitle(
if (status.muted == true) {
R.string.action_unmute_conversation
} else {
R.string.action_mute_conversation
})
}
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.status_share_content -> {
@ -303,6 +318,12 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
requestDownloadAllMedia(status)
return@setOnMenuItemClickListener true
}
R.id.status_mute_conversation -> {
searchAdapter.getItem(position)?.let { foundStatus ->
viewModel.muteConversation(foundStatus, status.muted != true)
}
return@setOnMenuItemClickListener true
}
R.id.status_mute -> {
viewModel.muteAcount(accountId)
return@setOnMenuItemClickListener true
@ -341,6 +362,12 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
popup.show()
}
private fun accountIsInMentions(account: AccountEntity?, mentions: Array<Mention>): Boolean {
return mentions.firstOrNull {
account?.username == it.username && account.domain == Uri.parse(it.url)?.host
} != null
}
private fun showOpenAsDialog(statusUrl: String, dialogTitle: CharSequence) {
bottomSheetActivity?.showAccountChooserDialog(dialogTitle, false, object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {