Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "show results" for polls #4980

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
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 @@ -114,6 +114,7 @@ public static class Key {
private final RecyclerView pollOptions;
private final TextView pollDescription;
private final Button pollButton;
private final Button pollResultsButton;

private final MaterialCardView cardView;
private final LinearLayout cardLayout;
Expand Down Expand Up @@ -173,6 +174,7 @@ protected StatusBaseViewHolder(@NonNull View itemView) {
pollOptions = itemView.findViewById(R.id.status_poll_options);
pollDescription = itemView.findViewById(R.id.status_poll_description);
pollButton = itemView.findViewById(R.id.status_poll_button);
pollResultsButton = itemView.findViewById(R.id.status_poll_results_button);

cardView = itemView.findViewById(R.id.status_card_view);
cardLayout = itemView.findViewById(R.id.status_card_layout);
Expand Down Expand Up @@ -321,6 +323,7 @@ private void setTextVisible(boolean sensitive,

private void hidePoll() {
pollButton.setVisibility(View.GONE);
pollResultsButton.setVisibility(View.GONE);
pollDescription.setVisibility(View.GONE);
pollOptions.setVisibility(View.GONE);
}
Expand Down Expand Up @@ -1078,6 +1081,7 @@ private void setupPoll(PollViewData poll, List<Emoji> emojis,
);

pollButton.setVisibility(View.GONE);
pollResultsButton.setVisibility(View.GONE);
} else {
// voting possible
pollAdapter.setup(
Expand All @@ -1091,6 +1095,7 @@ private void setupPoll(PollViewData poll, List<Emoji> emojis,
);

pollButton.setVisibility(View.VISIBLE);
pollResultsButton.setVisibility(View.VISIBLE);

pollButton.setOnClickListener(v -> {

Expand All @@ -1106,6 +1111,14 @@ private void setupPoll(PollViewData poll, List<Emoji> emojis,
}

});

pollResultsButton.setOnClickListener(v -> {
int position = getBindingAdapterPosition();

if (position != RecyclerView.NO_POSITION) {
listener.onShowPollResults(position);
}
});
}

pollDescription.setVisibility(View.VISIBLE);
Expand Down Expand Up @@ -1314,6 +1327,7 @@ public void showStatusContent(boolean show) {
mediaContainer.setVisibility(visibility);
pollOptions.setVisibility(visibility);
pollButton.setVisibility(visibility);
pollResultsButton.setVisibility(visibility);
pollDescription.setVisibility(visibility);
replyButton.setVisibility(visibility);
reblogButton.setVisibility(visibility);
Expand Down
17 changes: 3 additions & 14 deletions app/src/main/java/com/keylesspalace/tusky/appstore/CacheUpdater.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package com.keylesspalace.tusky.appstore

import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.db.AppDatabase
import com.keylesspalace.tusky.entity.Poll
import com.squareup.moshi.Moshi
import com.squareup.moshi.adapter
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -16,7 +14,6 @@ import kotlinx.coroutines.launch
* Updates the database cache in response to events.
* This is important for the home timeline and notifications to be up to date.
*/
@OptIn(ExperimentalStdlibApi::class)
class CacheUpdater @Inject constructor(
eventHub: EventHub,
accountManager: AccountManager,
Expand All @@ -35,14 +32,8 @@ class CacheUpdater @Inject constructor(
eventHub.events.collect { event ->
val tuskyAccountId = accountManager.activeAccount?.id ?: return@collect
when (event) {
is StatusChangedEvent -> statusDao.update(
tuskyAccountId = tuskyAccountId,
status = event.status,
moshi = moshi
)

is StatusChangedEvent -> statusDao.update(tuskyAccountId = tuskyAccountId, status = event.status)
is UnfollowEvent -> timelineDao.removeStatusesAndReblogsByUser(tuskyAccountId, event.accountId)

is BlockEvent -> removeAllByUser(tuskyAccountId, event.accountId)
is MuteEvent -> removeAllByUser(tuskyAccountId, event.accountId)

Expand All @@ -56,10 +47,8 @@ class CacheUpdater @Inject constructor(
notificationsDao.deleteAllWithStatus(tuskyAccountId, event.statusId)
}

is PollVoteEvent -> {
val pollString = moshi.adapter<Poll>().toJson(event.poll)
statusDao.setVoted(tuskyAccountId, event.statusId, pollString)
}
is PollVoteEvent -> statusDao.setVoted(tuskyAccountId, event.statusId, event.poll)
is PollShowResultsEvent -> statusDao.setShowResults(tuskyAccountId, event.statusId)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ data class StatusScheduledEvent(val scheduledStatusId: String) : Event
data class ProfileEditedEvent(val newProfileData: Account) : Event
data class PreferenceChangedEvent(val preferenceKey: String) : Event
data class PollVoteEvent(val statusId: String, val poll: Poll) : Event
data class PollShowResultsEvent(val statusId: String) : Event
data class DomainMuteEvent(val instance: String) : Event
data class AnnouncementReadEvent(val announcementId: String) : Event
data class FilterUpdatedEvent(val filterContext: List<String>) : Event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,12 @@ class ConversationsFragment :
}
}

override fun onShowPollResults(position: Int) {
adapter?.peek(position)?.let { conversation ->
viewModel.showPollResults(conversation)
}
}

override fun clearWarningAction(position: Int) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ class ConversationsViewModel @Inject constructor(
}
}

fun showPollResults(conversation: ConversationViewData) = viewModelScope.launch {
conversation.lastStatus.status.poll?.let { poll ->
conversation.toEntity(accountId = accountId, poll = poll.copy(voted = true)).let {
saveConversationToDb(it)
}
}
}

fun expandHiddenStatus(expanded: Boolean, conversation: ConversationViewData) {
viewModelScope.launch {
val newConversation = conversation.toEntity(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,12 @@ class NotificationsFragment :
viewModel.voteInPoll(choices, status)
}

override fun onShowPollResults(position: Int) {
notificationsAdapter?.peek(position)?.asStatusOrNull()?.let { status ->
viewModel.showPollResults(status)
}
}

override fun clearWarningAction(position: Int) {
val status = notificationsAdapter?.peek(position)?.asStatusOrNull() ?: return
viewModel.clearWarning(status)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ class NotificationsViewModel @Inject constructor(
}
}

fun showPollResults(status: StatusViewData.Concrete) = viewModelScope.launch {
timelineCases.showPollResults(status.actionableId)
}

fun changeExpanded(expanded: Boolean, status: StatusViewData.Concrete) {
viewModelScope.launch {
db.timelineStatusDao()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ class NotificationRequestDetailsFragment : SFragment(R.layout.fragment_notificat
viewModel.voteInPoll(choices, status)
}

override fun onShowPollResults(position: Int) {
adapter?.peek(position)?.asStatusOrNull()?.let { status ->
viewModel.showPollResults(status)
}
}

override fun clearWarningAction(position: Int) {
// not applicable here
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ class NotificationRequestDetailsViewModel @AssistedInject constructor(
}
}

fun showPollResults(status: StatusViewData.Concrete) = viewModelScope.launch {
timelineCases.showPollResults(status.actionableId)
}

suspend fun translate(status: StatusViewData.Concrete): NetworkResult<Unit> {
updateStatusViewData(status.id) { viewData ->
viewData.copy(translation = TranslationViewData.Loading)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ class SearchViewModel @Inject constructor(
}
}

fun showPollResults(status: StatusViewData.Concrete) = viewModelScope.launch {
timelineCases.showPollResults(status.actionableId)
}

fun favorite(statusViewData: StatusViewData.Concrete, isFavorited: Boolean) {
updateStatus(statusViewData.status.copy(favourited = isFavorited))
viewModelScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
}
}

override fun onShowPollResults(position: Int) {
adapter?.peek(position)?.asStatusOrNull()?.let { status ->
viewModel.showPollResults(status)
}
}

override fun clearWarningAction(position: Int) {}

private fun removeItem(position: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,12 @@ class TimelineFragment :
viewModel.voteInPoll(choices, status)
}

override fun onShowPollResults(position: Int) {
adapter?.peek(position)?.asStatusOrNull()?.let { status ->
viewModel.showPollResults(status)
}
}

override fun clearWarningAction(position: Int) {
val status = adapter?.peek(position)?.asStatusOrNull() ?: return
viewModel.clearWarning(status)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.keylesspalace.tusky.appstore.DomainMuteEvent
import com.keylesspalace.tusky.appstore.Event
import com.keylesspalace.tusky.appstore.EventHub
import com.keylesspalace.tusky.appstore.MuteEvent
import com.keylesspalace.tusky.appstore.PollShowResultsEvent
import com.keylesspalace.tusky.appstore.PollVoteEvent
import com.keylesspalace.tusky.appstore.StatusChangedEvent
import com.keylesspalace.tusky.appstore.StatusDeletedEvent
Expand Down Expand Up @@ -118,6 +119,7 @@ class NetworkTimelineViewModel @Inject constructor(
when (event) {
is StatusChangedEvent -> handleStatusChangedEvent(event.status)
is PollVoteEvent -> handlePollVote(event.statusId, event.poll)
is PollShowResultsEvent -> handlePollShowResults(event.statusId)
is UnfollowEvent -> {
if (kind == Kind.HOME) {
val id = event.accountId
Expand Down Expand Up @@ -299,6 +301,12 @@ class NetworkTimelineViewModel @Inject constructor(
}
}

private fun handlePollShowResults(statusId: String) {
updateStatusByActionableId(statusId) { status ->
status.copy(poll = status.poll?.copy(voted = true))
}
}

override fun fullReload() {
nextKey = statusData.firstOrNull { it is StatusViewData.Concrete }?.asStatusOrNull()?.id
statusData.clear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ abstract class TimelineViewModel(
}
}

fun showPollResults(status: StatusViewData.Concrete) = viewModelScope.launch {
timelineCases.showPollResults(status.actionableId)
}

abstract fun changeExpanded(expanded: Boolean, status: StatusViewData.Concrete)

abstract fun changeContentShowing(isShowing: Boolean, status: StatusViewData.Concrete)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,12 @@ class ViewThreadFragment :
viewModel.voteInPoll(choices, status)
}

override fun onShowPollResults(position: Int) {
adapter?.currentList?.getOrNull(position)?.let { status ->
viewModel.showPollResults(status)
}
}

override fun onShowEdits(position: Int) {
val status = adapter?.currentList?.getOrNull(position) ?: return
val viewEditsFragment = ViewEditsFragment.newInstance(status.actionableId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import com.keylesspalace.tusky.usecase.TimelineCases
import com.keylesspalace.tusky.util.toViewData
import com.keylesspalace.tusky.viewdata.StatusViewData
import com.keylesspalace.tusky.viewdata.TranslationViewData
import com.squareup.moshi.Moshi
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.Job
Expand All @@ -65,7 +64,6 @@ class ViewThreadViewModel @Inject constructor(
eventHub: EventHub,
private val accountManager: AccountManager,
private val db: AppDatabase,
private val moshi: Moshi
) : ViewModel() {

private val activeAccount = accountManager.activeAccount!!
Expand Down Expand Up @@ -140,11 +138,7 @@ class ViewThreadViewModel @Inject constructor(
// failed. Update the database when the fetch was successful.
if (statusAndAccount != null) {
api.status(id).onSuccess { result ->
db.timelineStatusDao().update(
tuskyAccountId = activeAccount.id,
status = result,
moshi = moshi
)
db.timelineStatusDao().update(tuskyAccountId = activeAccount.id, status = result)
detailedStatus = result.toViewData(isDetailed = true)
}
}
Expand Down Expand Up @@ -247,6 +241,10 @@ class ViewThreadViewModel @Inject constructor(
}
}

fun showPollResults(status: StatusViewData.Concrete) = viewModelScope.launch {
updateStatus(status.id) { it.copy(poll = it.poll?.copy(voted = true)) }
}

fun removeStatus(statusToRemove: StatusViewData.Concrete) {
updateSuccess { uiState ->
uiState.copy(
Expand Down
Loading