Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • circles/circles-android
1 result
Show changes
Commits on Source (9)
Showing
with 391 additions and 44 deletions
...@@ -23,19 +23,16 @@ import org.futo.circles.core.model.MediaType ...@@ -23,19 +23,16 @@ import org.futo.circles.core.model.MediaType
import org.futo.circles.core.model.PostContent import org.futo.circles.core.model.PostContent
import org.futo.circles.databinding.DialogFragmentDmTimelineBinding import org.futo.circles.databinding.DialogFragmentDmTimelineBinding
import org.futo.circles.feature.direct.timeline.list.DMTimelineAdapter import org.futo.circles.feature.direct.timeline.list.DMTimelineAdapter
import org.futo.circles.feature.direct.timeline.listeners.DmOptionsListener
import org.futo.circles.feature.direct.timeline.listeners.SendDmMessageListener import org.futo.circles.feature.direct.timeline.listeners.SendDmMessageListener
import org.futo.circles.feature.timeline.list.PostOptionsListener
import org.futo.circles.feature.timeline.post.create.PostSentListener
import org.futo.circles.feature.timeline.post.emoji.EmojiPickerListener import org.futo.circles.feature.timeline.post.emoji.EmojiPickerListener
import org.futo.circles.feature.timeline.post.menu.PostMenuListener
import org.futo.circles.model.RemovePost import org.futo.circles.model.RemovePost
@AndroidEntryPoint @AndroidEntryPoint
class DMTimelineDialogFragment : class DMTimelineDialogFragment :
BaseFullscreenDialogFragment<DialogFragmentDmTimelineBinding>(DialogFragmentDmTimelineBinding::inflate), BaseFullscreenDialogFragment<DialogFragmentDmTimelineBinding>(DialogFragmentDmTimelineBinding::inflate),
PostOptionsListener, PostMenuListener, EmojiPickerListener, PostSentListener, EmojiPickerListener, SendDmMessageListener, DmOptionsListener {
SendDmMessageListener {
private val args: DMTimelineDialogFragmentArgs by navArgs() private val args: DMTimelineDialogFragmentArgs by navArgs()
private val viewModel by viewModels<DMTimelineViewModel>() private val viewModel by viewModels<DMTimelineViewModel>()
...@@ -86,7 +83,6 @@ class DMTimelineDialogFragment : ...@@ -86,7 +83,6 @@ class DMTimelineDialogFragment :
clipToPadding = false clipToPadding = false
setPadding(paddingLeft, paddingTop, paddingRight, context.dpToPx(70)) setPadding(paddingLeft, paddingTop, paddingRight, context.dpToPx(70))
} }
//addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
addPageEndListener { viewModel.loadMore() } addPageEndListener { viewModel.loadMore() }
} }
...@@ -115,66 +111,46 @@ class DMTimelineDialogFragment : ...@@ -115,66 +111,46 @@ class DMTimelineDialogFragment :
viewModel.unSendReactionLiveData.observeResponse(this) viewModel.unSendReactionLiveData.observeResponse(this)
} }
override fun onPostSent() { override fun onShowMenuClicked(eventId: String) {
scrollToTopOnMyNewPostAdded()
}
override fun onShowMenuClicked(roomId: String, eventId: String) {
if (showNoInternetConnection()) return if (showNoInternetConnection()) return
//navigator.navigatePostMenu(roomId, eventId) navigator.navigateToDmMenu(args.roomId, eventId)
} }
override fun onUserClicked(userId: String) { override fun onShowPreview(eventId: String) {
//navigator.navigateToUserDialogFragment(userId) navigator.navigateToShowMediaPreview(args.roomId, eventId)
} }
override fun onShowPreview(roomId: String, eventId: String) { override fun onShowEmoji(eventId: String, onAddEmoji: (String) -> Unit) {
//navigator.navigateToShowMediaPreview(roomId, eventId)
}
override fun onShowEmoji(roomId: String, eventId: String, onAddEmoji: (String) -> Unit) {
if (showNoInternetConnection()) return if (showNoInternetConnection()) return
//if (showErrorIfNotAbleToPost()) return
onLocalAddEmojiCallback = onAddEmoji onLocalAddEmojiCallback = onAddEmoji
//navigator.navigateToShowEmoji(roomId, eventId) navigator.navigateToEmojiPicker(args.roomId, eventId)
} }
override fun onReply(roomId: String, eventId: String) { override fun onReply(eventId: String) {
} }
override fun onShare(content: PostContent, view: View) { override fun onShare(content: PostContent, view: View) {
viewModel.sharePostContent(content, view) viewModel.sharePostContent(content, view)
} }
override fun onRemove(roomId: String, eventId: String) { override fun onRemove(eventId: String) {
withConfirmation(RemovePost()) { viewModel.removeMessage(roomId, eventId) } withConfirmation(RemovePost()) { viewModel.removeMessage(args.roomId, eventId) }
}
override fun onIgnore(senderId: String) {
} }
override fun onSaveToDevice(content: PostContent) { override fun onSaveToDevice(content: PostContent) {
viewModel.saveToDevice(content) viewModel.saveToDevice(content)
} }
override fun onEmojiChipClicked( override fun onEmojiChipClicked(eventId: String, emoji: String, isUnSend: Boolean) {
roomId: String, eventId: String, emoji: String, isUnSend: Boolean
) {
if (showNoInternetConnection()) return if (showNoInternetConnection()) return
//if (showErrorIfNotAbleToPost()) return if (isUnSend) viewModel.unSendReaction(args.roomId, eventId, emoji)
if (isUnSend) viewModel.unSendReaction(roomId, eventId, emoji) else viewModel.sendReaction(args.roomId, eventId, emoji)
else viewModel.sendReaction(roomId, eventId, emoji)
} }
override fun onPollOptionSelected(roomId: String, eventId: String, optionId: String) {
}
override fun endPoll(roomId: String, eventId: String) {
}
private fun stopVideoOnNewScreenOpen() { private fun stopVideoOnNewScreenOpen() {
findNavController().addOnDestinationChangedListener { _, destination, _ -> findNavController().addOnDestinationChangedListener { _, destination, _ ->
if (destination.id != R.id.timelineFragment) listAdapter.stopVideoPlayback() if (destination.id != R.id.DMTimelineDialogFragment) listAdapter.stopVideoPlayback()
} }
} }
...@@ -185,7 +161,13 @@ class DMTimelineDialogFragment : ...@@ -185,7 +161,13 @@ class DMTimelineDialogFragment :
} }
override fun onEmojiSelected(roomId: String?, eventId: String?, emoji: String) { override fun onEmojiSelected(roomId: String?, eventId: String?, emoji: String) {
binding.vSendMessage.insertEmojiIntoMessage(emoji) eventId?.let {
onLocalAddEmojiCallback?.invoke(emoji)
onLocalAddEmojiCallback = null
viewModel.sendReaction(args.roomId, eventId, emoji)
} ?: run {
binding.vSendMessage.insertEmojiIntoMessage(emoji)
}
} }
override fun onAddEmojiToMessageClicked() { override fun onAddEmojiToMessageClicked() {
......
...@@ -11,9 +11,21 @@ class DMTimelineNavigator(private val fragment: DMTimelineDialogFragment) { ...@@ -11,9 +11,21 @@ class DMTimelineNavigator(private val fragment: DMTimelineDialogFragment) {
) )
} }
fun navigateToEmojiPicker() { fun navigateToEmojiPicker(roomId: String? = null, eventId: String? = null) {
fragment.findNavController().navigateSafe( fragment.findNavController().navigateSafe(
DMTimelineDialogFragmentDirections.toEmojiBottomSheet(null,null) DMTimelineDialogFragmentDirections.toEmojiBottomSheet(roomId, eventId)
)
}
fun navigateToShowMediaPreview(roomId: String, eventId: String) {
fragment.findNavController().navigateSafe(
DMTimelineDialogFragmentDirections.toMediaPreviewDialogFragment(roomId, eventId)
)
}
fun navigateToDmMenu(roomId: String, eventId: String) {
fragment.findNavController().navigateSafe(
DMTimelineDialogFragmentDirections.toDmMenuBottomSheet(roomId, eventId)
) )
} }
} }
\ No newline at end of file
...@@ -8,9 +8,11 @@ import org.futo.circles.core.model.TimelineLoadingItem ...@@ -8,9 +8,11 @@ import org.futo.circles.core.model.TimelineLoadingItem
import org.futo.circles.feature.direct.timeline.list.holder.DmMyImageMessageViewHolder import org.futo.circles.feature.direct.timeline.list.holder.DmMyImageMessageViewHolder
import org.futo.circles.feature.direct.timeline.list.holder.DmMyTextMessageViewHolder import org.futo.circles.feature.direct.timeline.list.holder.DmMyTextMessageViewHolder
import org.futo.circles.feature.direct.timeline.list.holder.DmMyVideoMessageViewHolder import org.futo.circles.feature.direct.timeline.list.holder.DmMyVideoMessageViewHolder
import org.futo.circles.feature.direct.timeline.list.holder.DmNotMessageEventViewHolder
import org.futo.circles.feature.direct.timeline.list.holder.DmOtherImageMessageViewHolder import org.futo.circles.feature.direct.timeline.list.holder.DmOtherImageMessageViewHolder
import org.futo.circles.feature.direct.timeline.list.holder.DmOtherTextMessageViewHolder import org.futo.circles.feature.direct.timeline.list.holder.DmOtherTextMessageViewHolder
import org.futo.circles.feature.direct.timeline.list.holder.DmOtherVideoMessageViewHolder import org.futo.circles.feature.direct.timeline.list.holder.DmOtherVideoMessageViewHolder
import org.futo.circles.feature.direct.timeline.listeners.DmOptionsListener
import org.futo.circles.feature.timeline.base.BaseTimelineAdapter import org.futo.circles.feature.timeline.base.BaseTimelineAdapter
import org.futo.circles.feature.timeline.base.TimelineListItemViewHolder import org.futo.circles.feature.timeline.base.TimelineListItemViewHolder
import org.futo.circles.feature.timeline.list.PostOptionsListener import org.futo.circles.feature.timeline.list.PostOptionsListener
...@@ -25,7 +27,7 @@ private enum class DmTimelineViewType { ...@@ -25,7 +27,7 @@ private enum class DmTimelineViewType {
} }
class DMTimelineAdapter( class DMTimelineAdapter(
private val postOptionsListener: PostOptionsListener, private val dmOptionsListener: DmOptionsListener,
private val videoPlayer: ExoPlayer private val videoPlayer: ExoPlayer
) : BaseTimelineAdapter() { ) : BaseTimelineAdapter() {
...@@ -69,7 +71,7 @@ class DMTimelineAdapter( ...@@ -69,7 +71,7 @@ class DMTimelineAdapter(
this this
) )
DmTimelineViewType.OTHER -> OtherEventPostViewHolder(parent, postOptionsListener) DmTimelineViewType.OTHER -> DmNotMessageEventViewHolder(parent)
DmTimelineViewType.LOADING -> TimelineLoadingViewHolder(parent) DmTimelineViewType.LOADING -> TimelineLoadingViewHolder(parent)
} }
} }
......
package org.futo.circles.feature.direct.timeline.list.holder
import android.text.format.DateFormat
import android.view.ViewGroup
import org.futo.circles.core.base.list.ViewBindingHolder
import org.futo.circles.core.model.OtherEventContent
import org.futo.circles.core.model.Post
import org.futo.circles.core.model.PostListItem
import org.futo.circles.databinding.ListItemDmNotMessageEventBinding
import org.futo.circles.feature.timeline.base.TimelineListItemViewHolder
import java.util.Date
class DmNotMessageEventViewHolder(parent: ViewGroup) : TimelineListItemViewHolder(
inflate(parent, ListItemDmNotMessageEventBinding::inflate)
) {
private companion object : ViewBindingHolder
private val binding = baseBinding as ListItemDmNotMessageEventBinding
override fun bind(item: PostListItem) {
val post = (item as? Post) ?: return
val content = (post.content as? OtherEventContent) ?: return
binding.tvMessage.text = content.eventType
binding.tvTime.text =
DateFormat.format("MMM dd, h:mm a", Date(post.postInfo.getLastModifiedTimestamp()))
}
}
\ No newline at end of file
package org.futo.circles.feature.direct.timeline.listeners
import android.view.View
import org.futo.circles.core.model.PostContent
interface DmOptionsListener {
fun onShowMenuClicked(eventId: String)
fun onShare(content: PostContent, view: View)
fun onReply(eventId: String)
fun onShowPreview(eventId: String)
fun onShowEmoji(eventId: String, onAddEmoji: (String) -> Unit)
fun onEmojiChipClicked(eventId: String, emoji: String, isUnSend: Boolean)
fun onSaveToDevice(content: PostContent)
fun onRemove(eventId: String)
fun onEdit(eventId: String)
}
\ No newline at end of file
package org.futo.circles.feature.direct.timeline.menu
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import dagger.hilt.android.AndroidEntryPoint
import org.futo.circles.core.base.fragment.TransparentBackgroundBottomSheetDialogFragment
import org.futo.circles.core.extensions.navigateSafe
import org.futo.circles.core.extensions.setIsVisible
import org.futo.circles.core.provider.PreferencesProvider
import org.futo.circles.databinding.BottomSheetDmMenuBinding
import org.futo.circles.feature.direct.timeline.listeners.DmOptionsListener
import org.futo.circles.feature.timeline.post.menu.PostMenuViewModel
@AndroidEntryPoint
class DmMenuBottomSheet : TransparentBackgroundBottomSheetDialogFragment() {
private var binding: BottomSheetDmMenuBinding? = null
private val args: DmMenuBottomSheetArgs by navArgs()
private val viewModel by viewModels<PostMenuViewModel>()
private val preferencesProvider by lazy { PreferencesProvider(requireContext()) }
private var menuListener: DmOptionsListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
menuListener =
parentFragmentManager.fragments.firstOrNull { it is DmOptionsListener } as? DmOptionsListener
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
binding = BottomSheetDmMenuBinding.inflate(inflater, container, false)
return binding?.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupViews()
}
private fun setupViews() {
binding?.let {
with(it) {
tvDelete.apply {
setIsVisible(viewModel.isMyPost())
setOnClickListener {
menuListener?.onRemove(args.eventId)
dismiss()
}
}
tvEdit.apply {
setIsVisible(viewModel.isMyPost())
setOnClickListener {
menuListener?.onEdit(args.eventId)
dismiss()
}
}
tvSaveToDevice.apply {
setIsVisible(viewModel.isMediaPost())
setOnClickListener {
viewModel.getPostContent()?.let { menuListener?.onSaveToDevice(it) }
dismiss()
}
}
tvReact.apply {
setIsVisible(viewModel.isMyPost().not())
setOnClickListener {
findNavController().navigateSafe(
DmMenuBottomSheetDirections.toEmojiBottomSheet(
args.roomId,
args.eventId
)
)
}
}
tvReply.apply {
setIsVisible(viewModel.isMyPost().not())
setOnClickListener {
menuListener?.onReply(args.eventId)
dismiss()
}
}
tvInfo.apply {
setIsVisible(preferencesProvider.isDeveloperModeEnabled())
setOnClickListener {
findNavController().navigateSafe(
DmMenuBottomSheetDirections.toPostInfoDialogFragment(
args.roomId,
args.eventId
)
)
}
}
}
}
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingBottom="16dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/post_card_background_color"
app:cardCornerRadius="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="4dp">
<View
android:layout_width="48dp"
android:layout_height="2dp"
android:layout_gravity="center_horizontal"
android:background="@color/divider_color" />
<org.futo.circles.core.view.SettingsMenuItemView
android:id="@+id/tvInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:optionIcon="@drawable/ic_info"
app:optionName="@string/info" />
<org.futo.circles.core.view.SettingsMenuItemView
android:id="@+id/tvReply"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:optionIcon="@drawable/ic_reply"
app:optionName="@string/reply" />
<org.futo.circles.core.view.SettingsMenuItemView
android:id="@+id/tvReact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:optionIcon="@drawable/ic_emoji"
app:optionName="@string/react" />
<org.futo.circles.core.view.SettingsMenuItemView
android:id="@+id/tvEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:optionIcon="@drawable/ic_edit"
app:optionName="@string/edit" />
<org.futo.circles.core.view.SettingsMenuItemView
android:id="@+id/tvSaveToDevice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:optionIcon="@drawable/ic_download"
app:optionName="@string/save_to_device" />
<org.futo.circles.core.view.SettingsMenuItemView
android:id="@+id/tvDelete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:optionIcon="@drawable/ic_delete"
app:optionName="@string/delete" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@color/divider_color">
<TextView
android:id="@+id/tvMessage"
style="@style/body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:autoLink="web"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="sadasdasdasdasdasdasdasdasdasd" />
<TextView
android:id="@+id/tvTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:paddingBottom="4dp"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvMessage"
tools:text="sadasdasdasdasdasdasdasdasdasd" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -33,6 +33,25 @@ ...@@ -33,6 +33,25 @@
android:id="@+id/to_emojiBottomSheet" android:id="@+id/to_emojiBottomSheet"
app:destination="@id/emojiBottomSheet" /> app:destination="@id/emojiBottomSheet" />
<action
android:id="@+id/to_mediaPreviewDialogFragment"
app:destination="@id/mediaPreviewDialogFragment">
<argument
android:name="roomId"
app:argType="string"
app:nullable="false" />
<argument
android:name="eventId"
app:argType="string"
app:nullable="false" />
</action>
<action
android:id="@+id/to_dmMenuBottomSheet"
app:destination="@id/dmMenuBottomSheet" />
</dialog> </dialog>
<include app:graph="@navigation/user_nav_graph" /> <include app:graph="@navigation/user_nav_graph" />
...@@ -54,4 +73,66 @@ ...@@ -54,4 +73,66 @@
app:nullable="true" /> app:nullable="true" />
</dialog> </dialog>
<dialog
android:id="@+id/mediaPreviewDialogFragment"
android:name="org.futo.circles.feature.timeline.preview.TimelineMediaPreviewDialogFragment"
tools:layout="@layout/dialog_fragment_timeline_media_preview">
<argument
android:name="roomId"
app:argType="string"
app:nullable="false" />
<argument
android:name="eventId"
app:argType="string"
app:nullable="false" />
</dialog>
<dialog
android:id="@+id/dmMenuBottomSheet"
android:name="org.futo.circles.feature.direct.timeline.menu.DmMenuBottomSheet"
tools:layout="@layout/bottom_sheet_dm_menu">
<argument
android:name="roomId"
app:argType="string"
app:nullable="false" />
<argument
android:name="eventId"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/to_emojiBottomSheet"
app:destination="@id/emojiBottomSheet"
app:popUpTo="@+id/dmMenuBottomSheet"
app:popUpToInclusive="true" />
<action
android:id="@+id/to_postInfoDialogFragment"
app:destination="@id/postInfoDialogFragment"
app:popUpTo="@+id/dmMenuBottomSheet"
app:popUpToInclusive="true" />
</dialog>
<dialog
android:id="@+id/postInfoDialogFragment"
android:name="org.futo.circles.feature.timeline.post.info.PostInfoDialogFragment"
tools:layout="@layout/dialog_fragment_debug_info">
<argument
android:name="roomId"
app:argType="string"
app:nullable="false" />
<argument
android:name="eventId"
app:argType="string"
app:nullable="false" />
</dialog>
</navigation> </navigation>
\ No newline at end of file
...@@ -75,6 +75,8 @@ ...@@ -75,6 +75,8 @@
<string name="create_your_first_circle_to_be_able_to_accept_invite">Create your first Circle to be able to accept invite</string> <string name="create_your_first_circle_to_be_able_to_accept_invite">Create your first Circle to be able to accept invite</string>
<string name="show_more">Show more</string> <string name="show_more">Show more</string>
<string name="edit">Edit</string> <string name="edit">Edit</string>
<string name="reply">Reply</string>
<string name="react">React</string>
<string name="edit_post">Edit post</string> <string name="edit_post">Edit post</string>
<string name="edited_label">(Edited)</string> <string name="edited_label">(Edited)</string>
<string name="edit_poll">Edit poll</string> <string name="edit_poll">Edit poll</string>
......