Skip to content

Commit

Permalink
Merge branch 'feature/notifications_refresh_p1' into issue/20040-noti…
Browse files Browse the repository at this point in the history
…fications-add-tracks-event

# Conflicts:
#	WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListViewModel.kt
  • Loading branch information
Antonis Lilis committed Feb 15, 2024
2 parents 9ca2497 + 6c0ef89 commit 1e4cbe0
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 69 deletions.
12 changes: 12 additions & 0 deletions WordPress/src/main/java/org/wordpress/android/models/Note.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.wordpress.android.fluxc.model.CommentStatus;
import org.wordpress.android.ui.notifications.utils.NotificationsUtilsWrapper;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.DateTimeUtils;
import org.wordpress.android.util.DateUtils;
import org.wordpress.android.util.JSONUtils;
Expand Down Expand Up @@ -522,6 +523,17 @@ public boolean hasLikedComment() {
return !(jsonActions == null || jsonActions.length() == 0) && jsonActions.optBoolean(ACTION_KEY_LIKE);
}

public void setLikedComment(boolean liked) {
JSONObject jsonActions = getCommentActions();
if (jsonActions != null) {
try {
jsonActions.put(ACTION_KEY_LIKE, liked);
} catch (JSONException e) {
AppLog.e(T.NOTIFS, "Failed to set 'like' property for the note", e);
}
}
}

public String getUrl() {
return queryJSON("url", "");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ sealed class Notification {
NoteType.Like -> Like(url = rawNote.url, title = rawNote.title)
NoteType.Reblog -> Reblog(url= rawNote.url, title = rawNote.title)
NoteType.NewPost -> NewPost(url= rawNote.url, title = rawNote.title)
NoteType.Comment -> Comment
else -> Unknown
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import javax.inject.Inject
class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_list_fragment_page),
OnScrollToTopListener,
DataLoadedListener {
private var notesAdapter: NotesAdapter? = null
private lateinit var notesAdapter: NotesAdapter
private var swipeToRefreshHelper: SwipeToRefreshHelper? = null
private var isAnimatingOutNewNotificationsBar = false
private var shouldRefreshNotifications = false
Expand Down Expand Up @@ -100,17 +100,6 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
fun onClickNote(noteId: String?)
}

@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val adapter = createOrGetNotesAdapter()
binding?.notificationsList?.adapter = adapter
if (savedInstanceState != null) {
tabPosition = savedInstanceState.getInt(KEY_TAB_POSITION, All.ordinal)
}
(TabPosition.values().getOrNull(tabPosition) ?: All).let { adapter.setFilter(it.filter) }
}

@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == RequestCodes.NOTE_DETAIL) {
Expand All @@ -136,21 +125,32 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
arguments?.let {
tabPosition = it.getInt(KEY_TAB_POSITION, All.ordinal)
}
notesAdapter = NotesAdapter( requireActivity(), this, null,
inlineActionEvents = viewModel.inlineActionEvents).apply {
this.setOnNoteClickListener(mOnNoteClickListener)
viewModel.inlineActionEvents.flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
.onEach(::handleInlineActionEvent)
.launchIn(viewLifecycleOwner.lifecycleScope)
}
binding = NotificationsListFragmentPageBinding.bind(view).apply {
notificationsList.layoutManager = LinearLayoutManager(activity)
notificationsList.adapter = notesAdapter
swipeToRefreshHelper = WPSwipeToRefreshHelper.buildSwipeToRefreshHelper(notificationsRefresh) {
hideNewNotificationsBar()
fetchNotesFromRemote()
}
layoutNewNotificatons.visibility = View.GONE
layoutNewNotificatons.setOnClickListener { onScrollToTop() }
(TabPosition.values().getOrNull(tabPosition) ?: All).let { notesAdapter.setFilter(it.filter) }
}
viewModel.updatedNote.observe(viewLifecycleOwner) {
notesAdapter.updateNote(it)
}
}

override fun onDestroyView() {
super.onDestroyView()
notesAdapter?.cancelReloadNotesTask()
notesAdapter = null
notesAdapter.cancelReloadNotesTask()
swipeToRefreshHelper = null
binding?.notificationsList?.adapter = null
binding?.notificationsList?.removeCallbacks(showNewUnseenNotificationsRunnable)
Expand Down Expand Up @@ -187,7 +187,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
binding?.hideNewNotificationsBar()
EventBus.getDefault().post(NotificationsUnseenStatus(false))
if (accountStore.hasAccessToken()) {
notesAdapter!!.reloadNotesFromDBAsync()
notesAdapter.reloadNotesFromDBAsync()
if (shouldRefreshNotifications) {
fetchNotesFromRemote()
}
Expand Down Expand Up @@ -234,7 +234,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l

// Open the latest version of this note in case it has changed, which can happen if the note was tapped
// from the list after it was updated by another fragment (such as NotificationsDetailListFragment).
openNoteForReply(activity, noteId, false, null, notesAdapter!!.currentFilter, false)
openNoteForReply(activity, noteId, false, null, notesAdapter.currentFilter, false)
}
}
private val mOnScrollListener: OnScrollListener = object : OnScrollListener() {
Expand All @@ -253,7 +253,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
}

private fun fetchNotesFromRemote() {
if (!isAdded || notesAdapter == null) {
if (!isAdded) {
return
}
if (!NetworkUtils.isNetworkAvailable(activity)) {
Expand Down Expand Up @@ -414,17 +414,6 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
}
}

private fun createOrGetNotesAdapter(): NotesAdapter {
return notesAdapter ?: NotesAdapter( requireActivity(), this, null,
inlineActionEvents = viewModel.inlineActionEvents).apply {
notesAdapter = this
this.setOnNoteClickListener(mOnNoteClickListener)
viewModel.inlineActionEvents.flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
.onEach(::handleInlineActionEvent)
.launchIn(viewLifecycleOwner.lifecycleScope)
}
}

private fun handleInlineActionEvent(actionEvent: InlineActionEvent) {
analyticsTrackerWrapper.track(NOTIFICATIONS_INLINE_ACTION_TAPPED, mapOf(
InlineActionEvent.KEY_INLINE_ACTION to actionEvent::class.simpleName
Expand All @@ -435,6 +424,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
ActivityLauncher.openShareIntent(it, postNotification.url, postNotification.title)
}
}
is InlineActionEvent.LikeCommentButtonTapped -> viewModel.likeComment(actionEvent.note, actionEvent.liked)
}
}

Expand All @@ -443,7 +433,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
* Mark notifications as read in CURRENT tab, use filteredNotes instead of notes
*/
fun markAllNotesAsRead() {
viewModel.markNoteAsRead(requireContext(), createOrGetNotesAdapter().filteredNotes)
viewModel.markNoteAsRead(requireContext(), notesAdapter.filteredNotes)
}

@Subscribe(sticky = true, threadMode = MAIN)
Expand All @@ -468,7 +458,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
if (!isAdded) {
return
}
notesAdapter!!.reloadNotesFromDBAsync()
notesAdapter.reloadNotesFromDBAsync()
if (event.hasUnseenNotes) {
binding?.showNewUnseenNotificationsUI()
}
Expand All @@ -480,7 +470,7 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
return
}
swipeToRefreshHelper?.isRefreshing = false
notesAdapter!!.addAll(event.notes, true)
notesAdapter.addAll(event.notes, true)
}

@Suppress("unused", "UNUSED_PARAMETER")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,46 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
import org.greenrobot.eventbus.EventBus
import org.wordpress.android.datasets.NotificationsTable
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.store.CommentsStore
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.models.Note
import org.wordpress.android.models.Notification.PostNotification
import org.wordpress.android.modules.UI_THREAD
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.push.GCMMessageHandler
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalOverlayUtil
import org.wordpress.android.ui.jetpackoverlay.JetpackOverlayConnectedFeature.NOTIFICATIONS
import org.wordpress.android.ui.notifications.NotificationEvents.NotificationsChanged
import org.wordpress.android.ui.notifications.utils.NotificationsActions
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.util.JetpackBrandingUtils
import org.wordpress.android.viewmodel.Event
import org.wordpress.android.viewmodel.ScopedViewModel
import javax.inject.Inject
import javax.inject.Named

@HiltViewModel
class NotificationsListViewModel @Inject constructor(
@Named(UI_THREAD) mainDispatcher: CoroutineDispatcher,
@Named(BG_THREAD) bgDispatcher: CoroutineDispatcher,
private val appPrefsWrapper: AppPrefsWrapper,
private val jetpackBrandingUtils: JetpackBrandingUtils,
private val jetpackFeatureRemovalOverlayUtil: JetpackFeatureRemovalOverlayUtil,
private val gcmMessageHandler: GCMMessageHandler

) : ScopedViewModel(mainDispatcher) {
private val gcmMessageHandler: GCMMessageHandler,
private val siteStore: SiteStore,
private val commentStore: CommentsStore
) : ScopedViewModel(bgDispatcher) {
private val _showJetpackPoweredBottomSheet = MutableLiveData<Event<Boolean>>()
val showJetpackPoweredBottomSheet: LiveData<Event<Boolean>> = _showJetpackPoweredBottomSheet

private val _showJetpackOverlay = MutableLiveData<Event<Boolean>>()
val showJetpackOverlay: LiveData<Event<Boolean>> = _showJetpackOverlay

private val _updatedNote = MutableLiveData<Note>()
val updatedNote: LiveData<Note> = _updatedNote

val inlineActionEvents = MutableSharedFlow<InlineActionEvent>()

val isNotificationsPermissionsWarningDismissed
get() = appPrefsWrapper.notificationPermissionsWarningDismissed

init {
if (jetpackBrandingUtils.shouldShowJetpackPoweredBottomSheet()) showJetpackPoweredBottomSheet()
}

private fun showJetpackPoweredBottomSheet() {
// _showJetpackPoweredBottomSheet.value = Event(true)
}

fun onResume() {
if (jetpackFeatureRemovalOverlayUtil.shouldShowFeatureSpecificJetpackOverlay(NOTIFICATIONS))
showJetpackOverlay()
Expand Down Expand Up @@ -81,8 +78,22 @@ class NotificationsListViewModel @Inject constructor(
}
}

fun likeComment(note: Note, liked: Boolean) = launch {
val site = siteStore.getSiteBySiteId(note.siteId.toLong()) ?: SiteModel().apply {
siteId = note.siteId.toLong()
setIsWPCom(true)
}
note.setLikedComment(liked)
_updatedNote.postValue(note)
val result = commentStore.likeComment(site, note.commentId, null, liked)
if (result.isError.not()) {
NotificationsTable.saveNote(note)
}
}

sealed class InlineActionEvent {
data class SharePostButtonTapped(val notification: PostNotification): InlineActionEvent()
data class SharePostButtonTapped(val notification: PostNotification) : InlineActionEvent()
class LikeCommentButtonTapped(val note: Note, val liked: Boolean) : InlineActionEvent()

companion object {
const val KEY_INLINE_ACTION = "inline_action"
Expand Down
Loading

0 comments on commit 1e4cbe0

Please sign in to comment.