Skip to content

Commit

Permalink
Merge pull request #20178 from wordpress-mobile/issue/20040-notificat…
Browse files Browse the repository at this point in the history
…ions-share-an-own-published-post

Add notifications inline action for share an own published post
  • Loading branch information
mkevins authored Feb 13, 2024
2 parents 515b11f + 69a3392 commit a9a0972
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
package org.wordpress.android.models

import org.wordpress.android.models.Notification.PostNotification.Like
import org.wordpress.android.models.Notification.PostNotification.Reblog
import org.wordpress.android.models.Notification.PostNotification.NewPost

val Note.type
get() = NoteType.from(rawType)

sealed class Notification {
data class Like(val url: String, val title: String): Notification()
sealed class PostNotification: Notification() {
abstract val url: String
abstract val title: String
data class Like(override val url: String, override val title: String): PostNotification()
data class Reblog(override val url: String, override val title: String): PostNotification()
data class NewPost(override val url: String, override val title: String): PostNotification()
}
data object Comment: Notification()
data object Unknown: Notification()

companion object {
fun from(rawNote: Note) = when(rawNote.type) {
NoteType.Like -> Like(url= rawNote.url, title = rawNote.title)
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)
else -> Unknown
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import android.view.animation.Animation.AnimationListener
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode.MAIN
Expand Down Expand Up @@ -45,6 +49,8 @@ import org.wordpress.android.ui.notifications.NotificationsListFragment.Companio
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Follow
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Like
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Unread
import org.wordpress.android.ui.notifications.NotificationsListViewModel.InlineActionEvent
import org.wordpress.android.ui.notifications.NotificationsListViewModel.InlineActionEvent.SharePostButtonTapped
import org.wordpress.android.ui.notifications.adapters.NotesAdapter
import org.wordpress.android.ui.notifications.adapters.NotesAdapter.DataLoadedListener
import org.wordpress.android.ui.notifications.adapters.NotesAdapter.FILTERS
Expand Down Expand Up @@ -404,12 +410,27 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
}

private fun createOrGetNotesAdapter(): NotesAdapter {
return notesAdapter ?: NotesAdapter(requireActivity(), this, null).apply {
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) {
when (actionEvent) {
is SharePostButtonTapped -> actionEvent.notification.let { postNotification ->
context?.let {
ActivityLauncher.openShareIntent(it, postNotification.url, postNotification.title)
}
}
}
}


/**
* Mark notifications as read in CURRENT tab, use filteredNotes instead of notes
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
import org.greenrobot.eventbus.EventBus
import org.wordpress.android.datasets.NotificationsTable
import org.wordpress.android.models.Note
import org.wordpress.android.models.Notification.PostNotification
import org.wordpress.android.modules.UI_THREAD
import org.wordpress.android.push.GCMMessageHandler
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalOverlayUtil
Expand Down Expand Up @@ -36,6 +38,8 @@ class NotificationsListViewModel @Inject constructor(
private val _showJetpackOverlay = MutableLiveData<Event<Boolean>>()
val showJetpackOverlay: LiveData<Event<Boolean>> = _showJetpackOverlay

val inlineActionEvents = MutableSharedFlow<InlineActionEvent>()

val isNotificationsPermissionsWarningDismissed
get() = appPrefsWrapper.notificationPermissionsWarningDismissed

Expand Down Expand Up @@ -76,4 +80,8 @@ class NotificationsListViewModel @Inject constructor(
EventBus.getDefault().post(NotificationsChanged())
}
}

sealed class InlineActionEvent {
data class SharePostButtonTapped(val notification: PostNotification): InlineActionEvent()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,23 @@ import androidx.core.text.BidiFormatter
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import org.wordpress.android.R
import org.wordpress.android.WordPress
import org.wordpress.android.datasets.NotificationsTable
import org.wordpress.android.models.Note
import org.wordpress.android.models.Note.NoteTimeGroup
import org.wordpress.android.models.Note.TimeStampComparator
import org.wordpress.android.models.NoteType
import org.wordpress.android.models.type
import org.wordpress.android.models.Notification
import org.wordpress.android.models.Notification.Comment
import org.wordpress.android.models.Notification.PostNotification
import org.wordpress.android.models.Notification.Unknown
import org.wordpress.android.ui.comments.CommentUtils
import org.wordpress.android.ui.notifications.NotificationsListFragmentPage.OnNoteClickListener
import org.wordpress.android.ui.notifications.NotificationsListViewModel.InlineActionEvent
import org.wordpress.android.ui.notifications.adapters.NotesAdapter.NoteViewHolder
import org.wordpress.android.ui.notifications.blocks.NoteBlockClickableSpan
import org.wordpress.android.ui.notifications.utils.NotificationsUtilsWrapper
Expand All @@ -40,7 +47,8 @@ import javax.inject.Inject

class NotesAdapter(
context: Context, dataLoadedListener: DataLoadedListener,
onLoadMoreListener: OnLoadMoreListener?
onLoadMoreListener: OnLoadMoreListener?,
private val inlineActionEvents: MutableSharedFlow<InlineActionEvent>,
) : RecyclerView.Adapter<NoteViewHolder>() {
private val avatarSize: Int
private val textIndentSize: Int
Expand Down Expand Up @@ -265,31 +273,6 @@ class NotesAdapter(

private fun Note.shouldShowMultipleAvatars() = isFollowType || isLikeType || isCommentLikeType

@Suppress("ForbiddenComment")
private fun NoteViewHolder.bindInlineActionIconsForNote(note: Note) {
when (note.type) {
NoteType.Comment -> {
actionIcon.setImageResource(R.drawable.star_empty)
actionIcon.isVisible = true
actionIcon.setOnClickListener {
// TODO: handle tap on comment's inline action icon (the star)
}
}
NoteType.NewPost,
NoteType.Reblog,
NoteType.Like -> {
// TODO: Use the icon from the Figma design
actionIcon.setImageResource(R.drawable.gb_ic_share)
actionIcon.isVisible = true
actionIcon.setOnClickListener {
// TODO: handle tap on comment's inline action icon (the share icon)
}
}
else -> {
actionIcon.isVisible = false
}
}
}

private fun handleMaxLines(subject: TextView, detail: TextView) {
subject.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
Expand Down Expand Up @@ -352,6 +335,8 @@ class NotesAdapter(
val unreadNotificationView: View
val actionIcon: ImageView

val coroutineScope = CoroutineScope(Dispatchers.Main)

init {
contentView = checkNotNull(view.findViewById(R.id.note_content_container))
headerText = checkNotNull(view.findViewById(R.id.header_text))
Expand All @@ -370,6 +355,33 @@ class NotesAdapter(
actionIcon = checkNotNull(view.findViewById(R.id.action))
contentView.setOnClickListener(onClickListener)
}

@Suppress("ForbiddenComment")
fun bindInlineActionIconsForNote(note: Note) = Notification.from(note).let { notification ->
when (notification) {
Comment -> {
actionIcon.setImageResource(R.drawable.star_empty)
actionIcon.isVisible = true
actionIcon.setOnClickListener {
// TODO: handle tap on comment's inline action icon (the star)
}
}
is PostNotification -> {
actionIcon.setImageResource(R.drawable.block_share)
actionIcon.isVisible = true
actionIcon.setOnClickListener {
coroutineScope.launch {
inlineActionEvents.emit(
InlineActionEvent.SharePostButtonTapped(notification)
)
}
}
}
is Unknown -> {
actionIcon.isVisible = false
}
}
}
}

private val onClickListener = View.OnClickListener { view ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import androidx.core.app.ActivityOptionsCompat;
import androidx.fragment.app.Fragment;

import org.wordpress.android.R;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.models.ReaderPost;
import org.wordpress.android.models.ReaderTag;
Expand Down Expand Up @@ -403,13 +402,7 @@ public static void openPost(Context context, ReaderPost post) {

public static void sharePost(Context context, ReaderPost post) throws ActivityNotFoundException {
String url = (post.hasShortUrl() ? post.getShortUrl() : post.getUrl());

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, url);
intent.putExtra(Intent.EXTRA_SUBJECT, post.getTitle());

context.startActivity(Intent.createChooser(intent, context.getString(R.string.share_link)));
ActivityLauncher.openShareIntent(context, url, post.getTitle());
}

public static void openUrl(Context context, String url, OpenUrlType openUrlType) {
Expand Down
15 changes: 15 additions & 0 deletions WordPress/src/main/res/drawable/block_share.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,2.5L12,15.5M9,5.5L12,2.5L15,5.5"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#1E1E1E"/>
<path
android:pathData="M8.5,9H7C5.895,9 5,9.895 5,11V18C5,19.105 5.895,20 7,20H17C18.105,20 19,19.105 19,18V11C19,9.895 18.105,9 17,9H15.5V10.5H17C17.276,10.5 17.5,10.724 17.5,11V18C17.5,18.276 17.276,18.5 17,18.5H7C6.724,18.5 6.5,18.276 6.5,18V11C6.5,10.724 6.724,10.5 7,10.5H8.5V9Z"
android:fillColor="#1E1E1E"
android:fillType="evenOdd"/>
</vector>
1 change: 1 addition & 0 deletions WordPress/src/main/res/layout/notifications_list_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
app:layout_constraintBottom_toBottomOf="@+id/note_avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/note_avatar"
app:tint="?attr/wpColorOnSurfaceMedium"
tools:src="@drawable/star_empty" />

<FrameLayout
Expand Down

0 comments on commit a9a0972

Please sign in to comment.