emojireactions: Implement adding and removing on existing reactions
Based on 7bb0f1955d
by a1ba.
This commit is contained in:
parent
8d0a1f0927
commit
5d09d9a77c
|
@ -23,3 +23,4 @@ data class PollVoteEvent(val statusId: String, val poll: Poll) : Event
|
||||||
data class DomainMuteEvent(val instance: String) : Event
|
data class DomainMuteEvent(val instance: String) : Event
|
||||||
data class AnnouncementReadEvent(val announcementId: String) : Event
|
data class AnnouncementReadEvent(val announcementId: String) : Event
|
||||||
data class PinEvent(val statusId: String, val pinned: Boolean) : Event
|
data class PinEvent(val statusId: String, val pinned: Boolean) : Event
|
||||||
|
data class EmojiReactEvent(val newStatus: Status) : Event
|
||||||
|
|
|
@ -28,6 +28,7 @@ import androidx.paging.map
|
||||||
import androidx.room.withTransaction
|
import androidx.room.withTransaction
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
||||||
|
import com.keylesspalace.tusky.appstore.EmojiReactEvent
|
||||||
import com.keylesspalace.tusky.appstore.EventHub
|
import com.keylesspalace.tusky.appstore.EventHub
|
||||||
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
||||||
import com.keylesspalace.tusky.appstore.PinEvent
|
import com.keylesspalace.tusky.appstore.PinEvent
|
||||||
|
@ -269,6 +270,10 @@ class CachedTimelineViewModel @Inject constructor(
|
||||||
// handled by CacheUpdater
|
// handled by CacheUpdater
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun handleEmojiReactEvent(emojiReactionEvent: EmojiReactEvent) {
|
||||||
|
// handled by CacheUpdater
|
||||||
|
}
|
||||||
|
|
||||||
override fun fullReload() {
|
override fun fullReload() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val activeAccount = accountManager.activeAccount!!
|
val activeAccount = accountManager.activeAccount!!
|
||||||
|
|
|
@ -24,6 +24,7 @@ import androidx.paging.PagingConfig
|
||||||
import androidx.paging.cachedIn
|
import androidx.paging.cachedIn
|
||||||
import androidx.paging.filter
|
import androidx.paging.filter
|
||||||
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
||||||
|
import com.keylesspalace.tusky.appstore.EmojiReactEvent
|
||||||
import com.keylesspalace.tusky.appstore.EventHub
|
import com.keylesspalace.tusky.appstore.EventHub
|
||||||
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
||||||
import com.keylesspalace.tusky.appstore.PinEvent
|
import com.keylesspalace.tusky.appstore.PinEvent
|
||||||
|
@ -243,6 +244,12 @@ class NetworkTimelineViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun handleEmojiReactEvent(emojiReactionEvent: EmojiReactEvent) {
|
||||||
|
updateActionableStatusById(emojiReactionEvent.newStatus.actionableId) {
|
||||||
|
it.copy(pleroma = emojiReactionEvent.newStatus.actionableStatus.pleroma)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun fullReload() {
|
override fun fullReload() {
|
||||||
nextKey = statusData.firstOrNull { it is StatusViewData.Concrete }?.asStatusOrNull()?.id
|
nextKey = statusData.firstOrNull { it is StatusViewData.Concrete }?.asStatusOrNull()?.id
|
||||||
statusData.clear()
|
statusData.clear()
|
||||||
|
|
|
@ -26,6 +26,7 @@ import at.connyduck.calladapter.networkresult.getOrThrow
|
||||||
import com.keylesspalace.tusky.appstore.BlockEvent
|
import com.keylesspalace.tusky.appstore.BlockEvent
|
||||||
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
||||||
import com.keylesspalace.tusky.appstore.DomainMuteEvent
|
import com.keylesspalace.tusky.appstore.DomainMuteEvent
|
||||||
|
import com.keylesspalace.tusky.appstore.EmojiReactEvent
|
||||||
import com.keylesspalace.tusky.appstore.Event
|
import com.keylesspalace.tusky.appstore.Event
|
||||||
import com.keylesspalace.tusky.appstore.EventHub
|
import com.keylesspalace.tusky.appstore.EventHub
|
||||||
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
||||||
|
@ -178,6 +179,8 @@ abstract class TimelineViewModel(
|
||||||
|
|
||||||
abstract fun handlePinEvent(pinEvent: PinEvent)
|
abstract fun handlePinEvent(pinEvent: PinEvent)
|
||||||
|
|
||||||
|
abstract fun handleEmojiReactEvent(emojiReactionEvent: EmojiReactEvent)
|
||||||
|
|
||||||
abstract fun fullReload()
|
abstract fun fullReload()
|
||||||
|
|
||||||
abstract fun clearWarning(status: StatusViewData.Concrete)
|
abstract fun clearWarning(status: StatusViewData.Concrete)
|
||||||
|
@ -241,6 +244,7 @@ abstract class TimelineViewModel(
|
||||||
is ReblogEvent -> handleReblogEvent(event)
|
is ReblogEvent -> handleReblogEvent(event)
|
||||||
is BookmarkEvent -> handleBookmarkEvent(event)
|
is BookmarkEvent -> handleBookmarkEvent(event)
|
||||||
is PinEvent -> handlePinEvent(event)
|
is PinEvent -> handlePinEvent(event)
|
||||||
|
is EmojiReactEvent -> handleEmojiReactEvent(event)
|
||||||
is MuteConversationEvent -> fullReload()
|
is MuteConversationEvent -> fullReload()
|
||||||
is UnfollowEvent -> {
|
is UnfollowEvent -> {
|
||||||
if (kind == Kind.HOME) {
|
if (kind == Kind.HOME) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import at.connyduck.calladapter.networkresult.getOrThrow
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.keylesspalace.tusky.appstore.BlockEvent
|
import com.keylesspalace.tusky.appstore.BlockEvent
|
||||||
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
||||||
|
import com.keylesspalace.tusky.appstore.EmojiReactEvent
|
||||||
import com.keylesspalace.tusky.appstore.EventHub
|
import com.keylesspalace.tusky.appstore.EventHub
|
||||||
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
||||||
import com.keylesspalace.tusky.appstore.PinEvent
|
import com.keylesspalace.tusky.appstore.PinEvent
|
||||||
|
@ -94,6 +95,7 @@ class ViewThreadViewModel @Inject constructor(
|
||||||
is StatusComposedEvent -> handleStatusComposedEvent(event)
|
is StatusComposedEvent -> handleStatusComposedEvent(event)
|
||||||
is StatusDeletedEvent -> handleStatusDeletedEvent(event)
|
is StatusDeletedEvent -> handleStatusDeletedEvent(event)
|
||||||
is StatusEditedEvent -> handleStatusEditedEvent(event)
|
is StatusEditedEvent -> handleStatusEditedEvent(event)
|
||||||
|
is EmojiReactEvent -> handleEmojiReactEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,6 +303,12 @@ class ViewThreadViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleEmojiReactEvent(event: EmojiReactEvent) {
|
||||||
|
updateStatus(event.newStatus.id) { status ->
|
||||||
|
status.copy(pleroma = event.newStatus.pleroma)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun removeAllByAccountId(accountId: String) {
|
private fun removeAllByAccountId(accountId: String) {
|
||||||
updateSuccess { uiState ->
|
updateSuccess { uiState ->
|
||||||
uiState.copy(
|
uiState.copy(
|
||||||
|
|
|
@ -145,6 +145,14 @@ abstract class SFragment : Fragment(), Injectable {
|
||||||
popup.inflate(R.menu.emoji_reaction_more)
|
popup.inflate(R.menu.emoji_reaction_more)
|
||||||
popup.setOnMenuItemClickListener { item: MenuItem ->
|
popup.setOnMenuItemClickListener { item: MenuItem ->
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
|
R.id.emoji_react -> {
|
||||||
|
onEmojiReact(statusId, reaction.name, true)
|
||||||
|
return@setOnMenuItemClickListener true
|
||||||
|
}
|
||||||
|
R.id.emoji_unreact -> {
|
||||||
|
onEmojiReact(statusId, reaction.name, false)
|
||||||
|
return@setOnMenuItemClickListener true
|
||||||
|
}
|
||||||
R.id.emoji_reacted_by -> {
|
R.id.emoji_reacted_by -> {
|
||||||
val intent = newIntent(requireContext(), AccountListActivity.Type.REACTED, statusId, false /* FIXME */, reaction.name)
|
val intent = newIntent(requireContext(), AccountListActivity.Type.REACTED, statusId, false /* FIXME */, reaction.name)
|
||||||
(requireActivity() as BaseActivity).startActivityWithSlideInAnimation(intent)
|
(requireActivity() as BaseActivity).startActivityWithSlideInAnimation(intent)
|
||||||
|
@ -426,6 +434,16 @@ abstract class SFragment : Fragment(), Injectable {
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun onEmojiReact(id: String, emoji: String, react: Boolean) {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
val result = timelineCases.react(id, emoji, react).exceptionOrNull()
|
||||||
|
if (result != null) {
|
||||||
|
Log.w("SFragment", "error reacting status", result)
|
||||||
|
Toast.makeText(context, R.string.error_generic, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun editStatus(id: String, status: Status) {
|
private fun editStatus(id: String, status: Status) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
mastodonApi.statusSource(id).fold(
|
mastodonApi.statusSource(id).fold(
|
||||||
|
|
|
@ -22,6 +22,7 @@ import at.connyduck.calladapter.networkresult.onFailure
|
||||||
import at.connyduck.calladapter.networkresult.onSuccess
|
import at.connyduck.calladapter.networkresult.onSuccess
|
||||||
import com.keylesspalace.tusky.appstore.BlockEvent
|
import com.keylesspalace.tusky.appstore.BlockEvent
|
||||||
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
import com.keylesspalace.tusky.appstore.BookmarkEvent
|
||||||
|
import com.keylesspalace.tusky.appstore.EmojiReactEvent
|
||||||
import com.keylesspalace.tusky.appstore.EventHub
|
import com.keylesspalace.tusky.appstore.EventHub
|
||||||
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
import com.keylesspalace.tusky.appstore.FavoriteEvent
|
||||||
import com.keylesspalace.tusky.appstore.MuteConversationEvent
|
import com.keylesspalace.tusky.appstore.MuteConversationEvent
|
||||||
|
@ -68,6 +69,16 @@ class TimelineCases @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun react(statusId: String, emoji: String, react: Boolean): NetworkResult<Status> {
|
||||||
|
return if (react) {
|
||||||
|
mastodonApi.reactWithEmoji(statusId, emoji)
|
||||||
|
} else {
|
||||||
|
mastodonApi.unreactWithEmoji(statusId, emoji)
|
||||||
|
}.onSuccess {
|
||||||
|
eventHub.dispatch(EmojiReactEvent(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun bookmark(statusId: String, bookmark: Boolean): NetworkResult<Status> {
|
suspend fun bookmark(statusId: String, bookmark: Boolean): NetworkResult<Status> {
|
||||||
return if (bookmark) {
|
return if (bookmark) {
|
||||||
mastodonApi.bookmarkStatus(statusId)
|
mastodonApi.bookmarkStatus(statusId)
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/emoji_react"
|
||||||
|
android:title="@string/action_emoji_react" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/emoji_unreact"
|
||||||
|
android:title="@string/action_emoji_unreact" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/emoji_reacted_by"
|
android:id="@+id/emoji_reacted_by"
|
||||||
android:title="@string/action_emoji_reacted_by" />
|
android:title="@string/action_emoji_reacted_by" />
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
<string name="admin">Admin</string>
|
<string name="admin">Admin</string>
|
||||||
<string name="moderator">Moderator</string>
|
<string name="moderator">Moderator</string>
|
||||||
|
|
||||||
|
<string name="action_emoji_react">Add reaction</string>
|
||||||
|
<string name="action_emoji_unreact">Remove reaction</string>
|
||||||
<string name="action_emoji_reacted_by">Who reacted</string>
|
<string name="action_emoji_reacted_by">Who reacted</string>
|
||||||
<string name="title_emoji_reacted_by">%s reacted by</string>
|
<string name="title_emoji_reacted_by">%s reacted by</string>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue