Skip to content
Merged
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
2 changes: 1 addition & 1 deletion app/src/main/java/one/mixin/android/db/ConversationDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface ConversationDao : BaseDao<Conversation> {
mu.full_name AS senderFullName,
pu.full_name AS participantFullName, pu.user_id AS participantUserId,
(SELECT count(1) FROM message_mentions me WHERE me.conversation_id = c.conversation_id AND me.has_read = 0) as mentionCount,
mm.mentions AS mentions, ou.membership AS membership
mm.mentions AS mentions, ou.membership AS membership, c.expire_in AS expireIn
FROM conversations c
INNER JOIN users ou ON ou.user_id = c.owner_id
LEFT JOIN messages m ON c.last_message_id = m.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ fun convertToConversationItems(cursor: Cursor?): List<ConversationItem> {
val cursorIndexOfMentionCount = getColumnIndexOrThrow(cursor, "mentionCount")
val cursorIndexOfMentions = getColumnIndexOrThrow(cursor, "mentions")
val cursorIndexOfMembership = getColumnIndexOrThrow(cursor, "membership")
val cursorIndexOfExpireIn = getColumnIndexOrThrow(cursor, "expireIn")
val res = ArrayList<ConversationItem>(cursor.count)
while (cursor.moveToNext()) {
val item: ConversationItem
Expand Down Expand Up @@ -111,6 +112,12 @@ fun convertToConversationItems(cursor: Cursor?): List<ConversationItem> {
}
val tmpMentions = cursor.getString(cursorIndexOfMentions)
val tmpMembership = cursor.getString(cursorIndexOfMembership)
val tmpExpireIn =
if (cursor.isNull(cursorIndexOfExpireIn)) {
null
} else {
cursor.getLong(cursorIndexOfExpireIn)
}
item =
ConversationItem(
tmpConversationId,
Expand Down Expand Up @@ -141,6 +148,7 @@ fun convertToConversationItems(cursor: Cursor?): List<ConversationItem> {
tmpMentions,
tmpMentionCount,
membershipConverter.revertData(tmpMembership),
tmpExpireIn,
)
res.add(item)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private const val OBSERVE_CONVERSATIONS_BY_CIRCLE_PREFIX_SQL =
mu.full_name AS senderFullName,
pu.full_name AS participantFullName, pu.user_id AS participantUserId,
(SELECT count(1) FROM message_mentions me WHERE me.conversation_id = c.conversation_id AND me.has_read = 0) AS mentionCount,
mm.mentions AS mentions, ou.membership AS membership
mm.mentions AS mentions, ou.membership AS membership, c.expire_in AS expireIn
FROM circle_conversations cc
INNER JOIN conversations c ON cc.conversation_id = c.conversation_id
INNER JOIN circles ci ON ci.circle_id = cc.circle_id
Expand Down
132 changes: 85 additions & 47 deletions app/src/main/java/one/mixin/android/ui/common/DisappearingFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import one.mixin.android.R
import one.mixin.android.api.handleMixinResponse
import one.mixin.android.databinding.FragmentDisappearingBinding
import one.mixin.android.extension.highlightStarTag
import one.mixin.android.extension.withArgs
import one.mixin.android.session.Session
import one.mixin.android.ui.conversation.ConversationViewModel
import one.mixin.android.util.ErrorHandler
import one.mixin.android.util.viewBinding
import one.mixin.android.vo.ParticipantRole
import one.mixin.android.vo.isGroupConversation
import one.mixin.android.widget.picker.INTERVAL_DAY
import one.mixin.android.widget.picker.INTERVAL_MONTH
import one.mixin.android.widget.picker.INTERVAL_WEEK
import one.mixin.android.widget.picker.toTimeInterval
import one.mixin.android.widget.picker.toTimeIntervalIndex
import timber.log.Timber
Expand Down Expand Up @@ -46,44 +55,36 @@ class DisappearingFragment : BaseFragment(R.layout.fragment_disappearing) {

private val viewModel by viewModels<ConversationViewModel>()
private val binding by viewBinding(FragmentDisappearingBinding::bind)
private val checkGroup by lazy {
binding.run {
private val checkGroup
get() = binding.run {
listOf(
disappearingOffIv,
disappearingOption1Iv,
disappearingOption2Iv,
disappearingOption3Iv,
disappearingOption4Iv,
disappearingOption5Iv,
disappearingOption6Iv,
)
}
}

private val pbGroup by lazy {
binding.run {
private val pbGroup
get() = binding.run {
listOf(
disappearingOffPb,
disappearingOption1Pb,
disappearingOption2Pb,
disappearingOption3Pb,
disappearingOption4Pb,
disappearingOption5Pb,
disappearingOption6Pb,
)
}
}

private fun Long?.initOption() {
when {
this == null || this <= 0 -> updateOptionCheck(0)
this == 30L -> updateOptionCheck(1)
this == 600L -> updateOptionCheck(2)
this == 7200L -> updateOptionCheck(3)
this == 86400L -> updateOptionCheck(4)
this == 604800L -> updateOptionCheck(5)
this == INTERVAL_DAY -> updateOptionCheck(1)
this == INTERVAL_WEEK -> updateOptionCheck(2)
this == INTERVAL_MONTH -> updateOptionCheck(3)
else -> {
updateOptionCheck(6)
updateOptionCheck(4)
binding.disappearingOption6Interval.text = toTimeInterval(this)
}
}
Expand All @@ -93,53 +94,61 @@ class DisappearingFragment : BaseFragment(R.layout.fragment_disappearing) {
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)
canEdit = false
updating = false
binding.titleView.leftIb.setOnClickListener {
activity?.onBackPressedDispatcher?.onBackPressed()
}
val info = getString(R.string.disappearing_message_hint)
val learnUrl = getString(R.string.disappearing_message_url)
binding.tipTv.highlightStarTag(info, arrayOf(learnUrl))
val intervalPicker = parentFragmentManager.findFragmentByTag(DisappearingIntervalBottomFragment.TAG) as? DisappearingIntervalBottomFragment
intervalPicker?.onSetCallback(null)
val options = binding.run {
listOf(disappearingOff, disappearingOption1, disappearingOption2, disappearingOption3, disappearingOption6)
}
options.forEach { it.isEnabled = false }

lifecycleScope.launch {
viewLifecycleOwner.lifecycleScope.launch {
val conversation = viewModel.getConversation(conversationId)
conversation?.expireIn.initOption()
canEdit = if (conversation?.isGroupConversation() == true) {
val role = withContext(Dispatchers.IO) {
Session.getAccountId()?.let { viewModel.findParticipantById(conversationId, it)?.role }
}
role == ParticipantRole.OWNER.name || role == ParticipantRole.ADMIN.name
} else {
conversation != null || userId != null
}
timeInterval = conversation?.expireIn
timeInterval.initOption()
options.forEach {
it.isEnabled = canEdit
it.isFocusable = canEdit
}
if (!canEdit) {
intervalPicker?.dismissAllowingStateLoss()
return@launch
}
intervalPicker?.onSetCallback(::onIntervalSelected)
binding.apply {
disappearingOff.setOnClickListener {
updateUI(0, 0L)
}
disappearingOption1.setOnClickListener {
updateUI(1, 30L)
updateUI(1, INTERVAL_DAY)
}
disappearingOption2.setOnClickListener {
updateUI(2, 600L)
updateUI(2, INTERVAL_WEEK)
}
disappearingOption3.setOnClickListener {
updateUI(3, 7200L)
}
disappearingOption4.setOnClickListener {
updateUI(4, 86400L)
}
disappearingOption5.setOnClickListener {
updateUI(5, 604800L)
updateUI(3, INTERVAL_MONTH)
}

disappearingOption6.setOnClickListener {
DisappearingIntervalBottomFragment.newInstance(timeInterval)
.apply {
onSetCallback {
this@DisappearingFragment.lifecycleScope.launch {
disappearingOption6Iv.isVisible = false
disappearingOption6Interval.isVisible = false
disappearingOption6Arrow.isVisible = false
updateUI(6, it)
disappearingOption6Interval.text = toTimeInterval(it)
Timber.e(
"Set interval ${toTimeInterval(it)} ${
toTimeIntervalIndex(
it,
)
}",
)
}
}
onSetCallback(::onIntervalSelected)
}
.showNow(parentFragmentManager, DisappearingIntervalBottomFragment.TAG)
}
Expand All @@ -149,15 +158,43 @@ class DisappearingFragment : BaseFragment(R.layout.fragment_disappearing) {

private var timeInterval: Long? = null
private var updating = false
private var canEdit = false

override fun onDestroyView() {
canEdit = false
(parentFragmentManager.findFragmentByTag(DisappearingIntervalBottomFragment.TAG) as? DisappearingIntervalBottomFragment)
?.onSetCallback(null)
super.onDestroyView()
}

private fun onIntervalSelected(interval: Long) {
if (!canEdit) return
val index = when (interval) {
INTERVAL_DAY -> 1
INTERVAL_WEEK -> 2
INTERVAL_MONTH -> 3
else -> 4
}
if (interval == timeInterval) {
updateOptionCheck(index)
return
}
binding.disappearingOption6Iv.isVisible = false
binding.disappearingOption6Interval.isVisible = false
binding.disappearingOption6Arrow.isVisible = false
updateUI(index, interval)
binding.disappearingOption6Interval.text = toTimeInterval(interval)
Timber.e("Set interval ${toTimeInterval(interval)} ${toTimeIntervalIndex(interval)}")
}

private fun updateUI(
index: Int,
interval: Long,
) {
if (timeInterval == interval || updating) {
if (!canEdit || timeInterval == interval || updating) {
return
}
lifecycleScope.launch(ErrorHandler.errorHandler) {
viewLifecycleOwner.lifecycleScope.launch(ErrorHandler.errorHandler) {
pbGroup[index].isVisible = true
updating = true
val conversation = viewModel.getConversation(conversationId)
Expand Down Expand Up @@ -191,6 +228,7 @@ class DisappearingFragment : BaseFragment(R.layout.fragment_disappearing) {
updating = false
},
defaultExceptionHandle = {
if (it is CancellationException) throw it
ErrorHandler.handleError(it)
pbGroup[index].isVisible = false
updating = false
Expand All @@ -203,7 +241,7 @@ class DisappearingFragment : BaseFragment(R.layout.fragment_disappearing) {
for ((i, iv) in checkGroup.withIndex()) {
iv.isVisible = index == i
}
binding.disappearingOption6Arrow.isVisible = index != 6
binding.disappearingOption6Interval.isVisible = index == 6
binding.disappearingOption6Arrow.isVisible = canEdit && index != 4
binding.disappearingOption6Interval.isVisible = index == 4
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ import one.mixin.android.tip.Tip
import one.mixin.android.ui.call.CallActivity
import one.mixin.android.ui.call.GroupUsersBottomSheetDialogFragment
import one.mixin.android.ui.call.GroupUsersBottomSheetDialogFragment.Companion.GROUP_VOICE_MAX_COUNT
import one.mixin.android.ui.common.DisappearingFragment
import one.mixin.android.ui.common.GroupBottomSheetDialogFragment
import one.mixin.android.ui.common.LinkFragment
import one.mixin.android.ui.common.UserBottomSheetDialogFragment
Expand Down Expand Up @@ -402,7 +403,7 @@ class ConversationFragment() :
lifecycleScope.launch {
val (_, data) = messageFetcher.initMessages(conversationId, null, true)
messageAdapter.refreshData(data)
messageLayoutManager.scrollWithOffset(messageAdapter.itemCount - 1, messageRvOffset)
messageLayoutManager.scrollToPositionWithOffset(messageAdapter.itemCount - 1, messageRvOffset)
}
}
}
Expand Down Expand Up @@ -713,6 +714,14 @@ class ConversationFragment() :
url.openAsUrlOrWeb(requireContext(), conversationId, parentFragmentManager, lifecycleScope)
}

override fun onDisappearingMessagesClick() {
activity?.addFragment(
this@ConversationFragment,
DisappearingFragment.newInstance(conversationId, recipient?.userId),
DisappearingFragment.TAG,
)
}

override fun onInscriptionClick(
conversationId: String,
messageId: String,
Expand Down Expand Up @@ -1453,7 +1462,7 @@ class ConversationFragment() :
}

fun scroll() {
val targetPosition = messageAdapter.itemCount
val targetPosition = messageAdapter.itemCount - 1
findFirstVisibleItemPosition().let { firstPosition ->
if (abs(targetPosition - firstPosition) > MessageFetcher.PAGE_SIZE) {
scrollToPositionWithOffset(targetPosition - MessageFetcher.PAGE_SIZE / 2, 0)
Expand Down Expand Up @@ -2009,6 +2018,11 @@ class ConversationFragment() :
keyword = keyword,
)
binding.messageRv.adapter = messageAdapter
chatViewModel.observeConversation(conversationId).observe(viewLifecycleOwner) { conversation ->
val expireIn = conversation?.expireIn ?: 0L
binding.actionBar.setExpireIconVisible(expireIn > 0L)
messageAdapter.expireIn = expireIn
}
binding.messageRv.addItemDecoration(decoration)
binding.messageRv.itemAnimator = null
binding.messageRv.layoutManager = messageLayoutManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ class ConversationViewModel
conversationRepository.getConversation(id)
}

fun observeConversation(id: String) =
conversationRepository.getConversationById(id)

fun findUserById(conversationId: String): LiveData<User?> =
userRepository.findUserById(conversationId)

Expand Down
Loading
Loading