Created
October 11, 2023 06:30
-
-
Save VIkash2601/4313bea0c239719624c91076744e86e2 to your computer and use it in GitHub Desktop.
Frag Chat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.annotation.SuppressLint | |
import android.app.Activity | |
import android.app.Dialog | |
import android.content.ClipData | |
import android.content.ClipboardManager | |
import android.content.Context | |
import android.content.Intent | |
import android.graphics.Bitmap | |
import android.graphics.Rect | |
import android.net.Uri | |
import android.os.Build | |
import android.os.Bundle | |
import android.text.Html | |
import android.text.SpannableString | |
import android.text.style.ForegroundColorSpan | |
import android.util.Log | |
import android.view.Gravity | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.widget.ImageView | |
import android.widget.LinearLayout | |
import android.widget.PopupWindow | |
import androidx.fragment.app.Fragment | |
import androidx.recyclerview.widget.RecyclerView | |
import com.app.spinnr.R | |
import com.app.spinnr.act.ActHome | |
import com.app.spinnr.databinding.DialogChatOptionBinding | |
import com.app.spinnr.databinding.DialogReactionsBinding | |
import com.app.spinnr.databinding.ItemChatBinding | |
import com.app.spinnr.frag.ReactedUser | |
import com.app.spinnr.frag.chat.FragChat | |
import com.app.spinnr.frag.profile.FragProfileView | |
import com.app.spinnr.frag.squad.SquadRepo | |
import com.app.spinnr.helper.Constant | |
import com.app.spinnr.listener.ItemSelectListener | |
import com.app.spinnr.model.MessageModel | |
import com.app.spinnr.model.SquadImpl | |
import com.app.spinnr.util.* | |
import com.app.spinnr.util.Preference.Companion.preferenceInstance | |
import com.bumptech.glide.Glide | |
import com.bumptech.glide.load.engine.DiskCacheStrategy | |
import com.google.firebase.firestore.Source | |
import com.google.firebase.firestore.ktx.firestore | |
import com.google.firebase.ktx.Firebase | |
import com.google.firebase.storage.ktx.storage | |
import dev.leonardpark.emoji.EmojiManager | |
import dev.leonardpark.emoji.EmojiPopup | |
import dev.leonardpark.emoji.emoji.Emoji | |
import dev.leonardpark.emoji.emojicompat.EmojiImageView | |
import dev.leonardpark.emoji.listeners.OnEmojiClickListener | |
import io.github.ponnamkarthik.richlinkpreview.MetaData | |
import io.github.ponnamkarthik.richlinkpreview.RichLinkListener | |
import io.github.ponnamkarthik.richlinkpreview.RichLinkView | |
import io.github.ponnamkarthik.richlinkpreview.ViewListener | |
import kotlinx.coroutines.CoroutineScope | |
import kotlinx.coroutines.Dispatchers | |
import kotlinx.coroutines.launch | |
import kotlinx.coroutines.withContext | |
class ChatAdapter( | |
val ctx: Context, | |
val frag: Fragment, | |
val inflater: LayoutInflater, | |
val username: String, | |
val data: MutableList<MessageModel>, | |
val listener: ItemSelectListener, | |
val replyListener: ReplyListener, | |
var clickListener: ScrollListener | |
) : RecyclerView.Adapter<ChatAdapter.MyViewHolder>() { | |
inner class MyViewHolder(val binding: ItemChatBinding) : RecyclerView.ViewHolder(binding.root) { | |
fun bind(item: MessageModel) { | |
if (item.type == "missedCall") { | |
binding.right.visibility = View.GONE | |
binding.left.visibility = View.GONE | |
binding.llMissedCall.visibility = View.VISIBLE | |
binding.missedCallTime.text = item.chatMessageTimeFormat() | |
if (item.username == FragChat.USERNAME) { | |
binding.missedCallTitle.text = setCustomText(item.content, item.username == preferenceInstance.readString(Preference.USERNAME)) | |
} else { | |
binding.missedCallTitle.text = setCustomText(item.content, item.username == preferenceInstance.readString(Preference.USERNAME)) | |
} | |
} else { | |
binding.llMissedCall.visibility = View.GONE | |
if (item.username == FragChat.USERNAME) { | |
binding.left.visibility = View.GONE | |
binding.right.visibility = View.VISIBLE | |
if (item.type == "squadInvite") { | |
binding.rightMsg.text = | |
"You invited ${FragChat.username} to the\n${item.text} squad" | |
} else { | |
binding.rightMsg.text = item.text | |
} | |
binding.rightTime.text = | |
item.chatMessageTimeFormat() + if (item.isEdited) " (Edited)" else "" | |
binding.rightThumb1.visibility = | |
if (item.type == "video" || item.type == "photo") View.VISIBLE else View.GONE | |
binding.rightThumb2.visibility = | |
if (item.type == "video" || item.type == "photo") View.VISIBLE else View.GONE | |
binding.rightThumb2Container.visibility = | |
if (item.type == "video" || item.type == "photo") View.VISIBLE else View.GONE | |
binding.rightMediaContainer.visibility = | |
if (item.type == "groupMedia") View.VISIBLE else View.GONE | |
binding.rightVideoIcon.visibility = | |
if (item.type == "video") View.VISIBLE else View.GONE | |
binding.rightAudio.visibility = | |
if (item.type == "audio") View.VISIBLE else View.GONE | |
binding.rightGifContainer.visibility = View.GONE | |
binding.rightMsg.visibility = View.VISIBLE; | |
binding.rightLinkPreviewContainer.visibility = View.VISIBLE; | |
var urls = extractUrls(item.text); | |
if (urls != null) { | |
binding.rightLinkPreviewContainer.removeAllViews(); | |
if (urls.size > 0) { | |
if (urls.size == 1) { | |
if (item.text.trim().length == urls[0].trim().length) { | |
binding.rightMsg.visibility = View.GONE; | |
} | |
} | |
for (urlsObj in urls) { | |
if (urlsObj.contains("giphy.com")) { | |
binding.rightThumb1.visibility = View.GONE | |
binding.rightLinkPreviewContainer.visibility = View.GONE | |
if (item.text.contains("&ratio=") && item.text.split("&ratio=").last().isNotBlank()) { | |
binding.rightGif.layoutParams.height = (binding.rightGif.layoutParams.width / item.text.split("&ratio=").last().toFloat()).toInt() | |
} | |
binding.rightGif.loadGif(item.text) | |
binding.rightGifLink.text = item.text | |
binding.rightGifContainer.visibility = View.VISIBLE | |
} else { | |
var richLinkView = RichLinkView(ctx); | |
if (item.linkThumb == null) | |
richLinkView.setLink(makeValidUrl(urlsObj), object : | |
ViewListener { | |
override fun onSuccess(status: Boolean) {} | |
override fun onError(e: Exception) {} | |
}); | |
var metaData = MetaData() | |
metaData.originalUrl = makeValidUrl(urlsObj); | |
metaData.title = item.linkTitle ?: ""; | |
metaData.description = item.linkDescription ?: ""; | |
metaData.imageurl = item.linkThumb ?: ""; | |
if (item.linkThumb != null) | |
richLinkView.setLinkFromMeta(metaData); | |
binding.rightLinkPreviewContainer.addView(richLinkView); | |
} | |
} | |
} else { | |
binding.rightLinkPreviewContainer.visibility = View.GONE; | |
} | |
} | |
if (item.type == "video") { | |
binding.rightThumb1.load(item.thumb.ifEmpty { item.content }) | |
binding.rightThumb2.load(item.thumb.ifEmpty { item.content }) | |
} else if (item.type == "photo") { | |
binding.rightThumb1.load(item.content) | |
binding.rightThumb2.load(item.content) | |
} else if (item.type == "groupMedia") { | |
if (item.mediaFiles.size > 2) | |
binding.rightGroupMediaCount.visibility = View.VISIBLE | |
else binding.rightGroupMediaCount.visibility = View.GONE | |
binding.rightGroupMediaCount.text = | |
String.format("+%s", (item.mediaFiles.size - 2).toString()) | |
binding.rightThumbGroupMedia1.load(item.mediaFiles[0]?.content) | |
binding.rightThumbGroupMedia2.load(item.mediaFiles[1]?.content) | |
} else if (item.type == "gif") { | |
binding.rightThumb1.visibility = View.GONE | |
binding.rightLinkPreviewContainer.visibility = View.GONE | |
if (item.text.contains("&ratio=") && item.text.split("&ratio=").last().isNotBlank()) { | |
binding.rightGif.layoutParams.height = (binding.rightGif.layoutParams.width / item.text.split("&ratio=").last().toFloat()).toInt() | |
} | |
binding.rightGif.loadGif(item.text) | |
binding.rightGifLink.text = item.text | |
binding.rightGifContainer.visibility = View.VISIBLE | |
} else if (item.type == "squadInvite" || item.type == "eventInvite") { | |
binding.rightLinkPreviewContainer.visibility = View.VISIBLE; | |
binding.rightLinkPreviewContainer.removeAllViews(); | |
var richLinkView = RichLinkView(ctx); | |
richLinkView.setDefaultClickListener(false) | |
richLinkView.setClickListener(object : RichLinkListener { | |
override fun onClicked(view: View?, meta: MetaData?) { | |
binding.rightFrame.performClick() | |
} | |
}) | |
richLinkView.setLinkFromMeta(MetaData().apply { | |
var squadId = "" | |
var squadDetail: SquadImpl? = null | |
for (a in 0 until SquadRepo.all.size) | |
if (SquadRepo.all[a].detail.name == item.text) { | |
squadDetail = SquadRepo.all[a] | |
squadId = SquadRepo.all[a].squadid | |
} | |
imageurl = | |
if (item.type == "eventInvite") item.thumb else Constant.PROFILE_IMG_URL + squadId + ".jpeg" | |
title = item.text | |
squadDetail?.let { squadImpl -> | |
description = squadImpl.detail.description | |
} | |
}) | |
binding.rightLinkPreviewContainer.addView(richLinkView) | |
} | |
binding.rightLike.visibility = View.GONE | |
binding.rightLove.visibility = View.GONE | |
binding.rightHappy.visibility = View.GONE | |
binding.rightWow.visibility = View.GONE | |
binding.rightSad.visibility = View.GONE | |
binding.rightAngry.visibility = View.GONE | |
binding.rightReactionText.visibility = View.GONE | |
binding.rightReaction.visibility = View.GONE | |
val values = item.reaction?.values?.filter { it.isNotEmpty() }?.toMutableList() | |
val set = values?.toMutableSet()?.sorted() | |
binding.rightReactionText.text = "" | |
set?.forEach { a -> | |
binding.rightReactionText.visibility = View.VISIBLE | |
binding.rightReactionText.append(a) | |
binding.rightReaction.visibility = View.VISIBLE | |
} | |
binding.rightReactionText.append(values?.size.toString() + " ") | |
/*values.forEachIndexed { i, s -> | |
*//*when(i) { | |
0 -> { | |
binding.rightLike.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.rightLike.setEmoji(it) | |
} | |
} | |
1 -> { | |
binding.rightLove.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.rightLove.setEmoji(it) | |
} | |
} | |
2 -> { | |
binding.rightHappy.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.rightHappy.setEmoji(it) | |
} | |
} | |
3 -> { | |
binding.rightWow.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.rightWow.setEmoji(it) | |
} | |
} | |
4-> { | |
binding.rightSad.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.rightSad.setEmoji(it) | |
} | |
} | |
5 -> { | |
binding.rightAngry.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.rightAngry.setEmoji(it) | |
} | |
} | |
}*//* | |
}*/ | |
if (!values.isNullOrEmpty()) | |
binding.rightReaction.setOnClickListener { | |
ReactedUser( | |
frag, | |
item.reaction ?: mutableMapOf(), | |
"spinnr-chat/${FragChat.collection}/messages/${item.documentID}/" | |
).show( | |
frag.childFragmentManager, | |
"ReactedUser" | |
) | |
} | |
if (!item.tag.isNullOrBlank()) { | |
Firebase | |
.firestore | |
.document("spinnr-chat/${FragChat.collection}/messages/${item.tag}/") | |
.get(Source.CACHE).addOnSuccessListener { | |
val tag = | |
it.toObject(MessageModel::class.java) ?: return@addOnSuccessListener | |
binding.rightReplyContainer.visibility = View.VISIBLE | |
binding.rightReplyOrigin.text = | |
if (tag.username == FragChat.USERNAME) "You" else tag.username | |
binding.rightReplyContent.text = when (tag.type) { | |
"gif" -> "\uD83C\uDFA5 GIF" | |
"video" -> "\uD83C\uDFA5 Video" | |
"photo" -> "\uD83D\uDCF7 Photo" | |
"groupMedia" -> "\uD83C\uDFA5 Media" | |
"audio" -> "\uD83C\uDFA4 Audio" | |
else -> tag.text | |
} | |
if (tag.type == "text" || tag.type == "audio") { | |
binding.rightReplyPreview.visibility = View.GONE | |
} else { | |
binding.rightReplyPreview.visibility = View.VISIBLE | |
when (tag.type) { | |
"video" -> binding.rightReplyPreview.load(tag.thumb, 10f) | |
"photo" -> binding.rightReplyPreview.load(tag.content, 10f) | |
"gif" -> binding.rightReplyPreview.load( | |
tag.linkThumb ?: tag.text, 10f | |
) | |
"groupMedia" -> binding.rightReplyPreview.load( | |
tag.mediaFiles[0]?.content, | |
10f | |
) | |
"eventInvite" -> binding.rightReplyPreview.load(tag.thumb, 10f) | |
"squadInvite" -> binding.rightReplyPreview.load("${Constant.PROFILE_IMG_URL}${tag.content}.jpeg", 10f) | |
} | |
} | |
} | |
} else if (item.repliedTo != null) { | |
binding.rightReplyContainer.visibility = View.VISIBLE | |
binding.rightReplyOrigin.text = | |
if (item.repliedTo?.username == FragChat.USERNAME) "You" else item.repliedTo?.username | |
binding.rightReplyContent.text = when (item.repliedTo!!.type) { | |
"gif" -> "\uD83C\uDFA5 GIF" | |
"video" -> "\uD83C\uDFA5 Video" | |
"photo" -> "\uD83D\uDCF7 Photo" | |
"groupMedia" -> "\uD83C\uDFA5 Media" | |
"audio" -> "\uD83C\uDFA4 Audio" | |
else -> item.repliedTo!!.type | |
} | |
if (item.repliedTo?.thumb == null) { | |
binding.rightReplyPreview.visibility = View.GONE | |
} else { | |
binding.rightReplyPreview.load(item.repliedTo?.thumb, 10f) | |
binding.rightReplyPreview.visibility = View.VISIBLE | |
} | |
} else | |
binding.rightReplyContainer.visibility = View.GONE | |
binding.rightReplyContainer.setOnClickListener { | |
clickListener.onScroll(item.tag ?: "") | |
} | |
} else { | |
binding.right.visibility = View.GONE | |
binding.left.visibility = View.VISIBLE | |
if (item.type == "squadInvite") { | |
binding.leftMsg.text = | |
"${FragChat.username} invited you to the\n${item.text} squad" | |
} else { | |
binding.leftMsg.text = item.text | |
} | |
binding.leftTime.text = item.chatMessageTimeFormat() | |
binding.leftThumb1.visibility = | |
if (item.type == "video" || item.type == "photo") View.VISIBLE else View.GONE | |
binding.leftThumb2.visibility = | |
if (item.type == "video" || item.type == "photo") View.VISIBLE else View.GONE | |
binding.leftThumb2Container.visibility = | |
if (item.type == "video" || item.type == "photo") View.VISIBLE else View.GONE | |
binding.leftVideoIcon.visibility = | |
if (item.type == "video") View.VISIBLE else View.GONE | |
binding.leftMediaContainer.visibility = | |
if (item.type == "groupMedia") View.VISIBLE else View.GONE | |
binding.leftAudio.visibility = if (item.type == "audio") View.VISIBLE else View.GONE | |
binding.profile.keyProfile(username) | |
binding.leftGifContainer.visibility = View.GONE | |
binding.leftMsg.visibility = View.VISIBLE; | |
binding.leftLinkPreviewContainer.visibility = View.VISIBLE; | |
var urls = extractUrls(item.text) | |
if (urls != null) { | |
binding.leftLinkPreviewContainer.removeAllViews(); | |
if (urls.size > 0) { | |
if (urls.size == 1) { | |
if (item.text.trim().length == urls[0].trim().length) { | |
binding.leftMsg.visibility = View.GONE; | |
} | |
} | |
for (urlsObj in urls) { | |
if (urlsObj.contains("giphy.com")) { | |
binding.leftThumb1.visibility = View.GONE | |
binding.leftThumb2.visibility = View.GONE | |
binding.leftLinkPreviewContainer.visibility = View.GONE | |
if (item.text.contains("&ratio=") && item.text.split("&ratio=").last().isNotBlank()) { | |
binding.leftGif.layoutParams.height = (binding.leftGif.layoutParams.width / item.text.split("&ratio=").last().toFloat()).toInt() | |
} | |
binding.leftGif.loadGif(item.text) | |
binding.leftGifLink.text = item.text | |
binding.leftGifContainer.visibility = View.VISIBLE | |
} else { | |
var richLinkView = RichLinkView(ctx); | |
if (item.linkThumb == null) | |
richLinkView.setLink(makeValidUrl(urlsObj), object : | |
ViewListener { | |
override fun onSuccess(status: Boolean) {} | |
override fun onError(e: Exception) {} | |
}); | |
var metaData = MetaData() | |
metaData.originalUrl = makeValidUrl(urlsObj); | |
metaData.title = item.linkTitle ?: ""; | |
metaData.description = item.linkDescription ?: ""; | |
metaData.imageurl = item.linkThumb ?: ""; | |
if (item.linkThumb != null) | |
richLinkView.setLinkFromMeta(metaData); | |
binding.leftLinkPreviewContainer.addView(richLinkView); | |
} | |
} | |
} else { | |
binding.leftLinkPreviewContainer.visibility = View.GONE; | |
} | |
} | |
if (item.type == "video") { | |
binding.leftThumb1.load(item.thumb.ifEmpty { item.content }) | |
binding.leftThumb2.load(item.thumb.ifEmpty { item.content }) | |
} else if (item.type == "photo") { | |
binding.leftThumb1.load(item.content) | |
binding.leftThumb2.load(item.content) | |
} else if (item.type == "groupMedia") { | |
if (item.mediaFiles.size > 2) | |
binding.leftGroupMediaCount.visibility = View.VISIBLE | |
else binding.leftGroupMediaCount.visibility = View.GONE | |
binding.leftGroupMediaCount.text = | |
String.format("+%s", (item.mediaFiles.size - 2).toString()) | |
binding.leftThumbGroupMedia1.load(item.mediaFiles[0]?.content) | |
binding.leftThumbGroupMedia2.load(item.mediaFiles[1]?.content) | |
} else if (item.type == "gif"/* && !item.text.contains(Patterns.WEB_URL.toRegex())*/) { | |
binding.leftThumb1.visibility = View.GONE | |
binding.leftThumb2.visibility = View.GONE | |
binding.leftLinkPreviewContainer.visibility = View.GONE | |
if (item.text.contains("&ratio=") && item.text.split("&ratio=").last().isNotBlank()) { | |
binding.leftGif.layoutParams.height = (binding.leftGif.layoutParams.width / item.text.split("&ratio=").last().toFloat()).toInt() | |
} | |
binding.leftGif.loadGif(item.text) | |
binding.leftGifLink.text = item.text | |
binding.leftGifContainer.visibility = View.VISIBLE | |
} else if (item.type == "squadInvite" || item.type == "eventInvite") { | |
binding.leftLinkPreviewContainer.visibility = View.VISIBLE; | |
binding.leftLinkPreviewContainer.removeAllViews(); | |
var richLinkView = RichLinkView(ctx); | |
richLinkView.setDefaultClickListener(false) | |
richLinkView.setClickListener(object : RichLinkListener { | |
override fun onClicked(view: View?, meta: MetaData?) { | |
binding.leftFrame.performClick() | |
} | |
}) | |
richLinkView.setLinkFromMeta(MetaData().apply { | |
var squadId = "" | |
var squadDetail: SquadImpl? = null | |
for (a in 0 until SquadRepo.all.size) | |
if (SquadRepo.all[a].detail.name == item.text) { | |
squadDetail = SquadRepo.all[a] | |
squadId = SquadRepo.all[a].squadid | |
} | |
imageurl = | |
if (item.type == "eventInvite") item.thumb else Constant.PROFILE_IMG_URL + squadId + ".jpeg" | |
title = item.text | |
squadDetail?.let { squadImpl -> | |
description = squadImpl.detail.description | |
} | |
}) | |
binding.leftLinkPreviewContainer.addView(richLinkView) | |
} | |
binding.leftLike.visibility = View.GONE | |
binding.leftLove.visibility = View.GONE | |
binding.leftHappy.visibility = View.GONE | |
binding.leftWow.visibility = View.GONE | |
binding.leftSad.visibility = View.GONE | |
binding.leftAngry.visibility = View.GONE | |
binding.leftReactionText.visibility = View.GONE | |
binding.leftReaction.visibility = View.GONE | |
val values = item.reaction?.values?.filter { it.isNotEmpty() }?.toMutableList() | |
val set = values?.toMutableSet()?.sorted() | |
binding.leftReactionText.text = "" | |
set?.forEach { a -> | |
binding.leftReactionText.visibility = View.VISIBLE | |
binding.leftReaction.visibility = View.VISIBLE | |
binding.leftReactionText.append(a) | |
} | |
binding.leftReactionText.append(values?.size.toString() + " ") | |
/*values.forEachIndexed { i, s -> | |
*//*when(i) { | |
0 -> { | |
binding.leftLike.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.leftLike.setEmoji(it) | |
} | |
} | |
1 -> { | |
binding.leftLove.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.leftLove.setEmoji(it) | |
} | |
} | |
2 -> { | |
binding.leftHappy.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.leftHappy.setEmoji(it) | |
} | |
} | |
3 -> { | |
binding.leftWow.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.leftWow.setEmoji(it) | |
} | |
} | |
4-> { | |
binding.leftSad.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.leftSad.setEmoji(it) | |
} | |
} | |
5 -> { | |
binding.leftAngry.visibility = View.VISIBLE | |
EmojiManager.getInstance().findEmoji(s)?.let { | |
binding.leftAngry.setEmoji(it) | |
} | |
} | |
}*//* | |
}*/ | |
if (!values.isNullOrEmpty()) | |
binding.leftReaction.setOnClickListener { | |
ReactedUser( | |
frag, | |
item.reaction ?: mutableMapOf(), | |
"spinnr-chat/${FragChat.collection}/messages/${item.documentID}/" | |
).show( | |
frag.childFragmentManager, | |
"ReactedUser" | |
) | |
} | |
if (!item.tag.isNullOrBlank()) { | |
Firebase | |
.firestore | |
.document("spinnr-chat/${FragChat.collection}/messages/${item.tag}/") | |
.get().addOnSuccessListener { | |
val tag = | |
it.toObject(MessageModel::class.java) ?: return@addOnSuccessListener | |
binding.leftReplyContainer.visibility = View.VISIBLE | |
binding.leftReplyOrigin.text = | |
if (tag.username == FragChat.USERNAME) "You" else tag.username | |
binding.leftReplyContent.text = when (tag.type) { | |
"gif" -> "\uD83C\uDFA5 GIF" | |
"video" -> "\uD83C\uDFA5 Video" | |
"photo" -> "\uD83D\uDCF7 Photo" | |
"groupMedia" -> "\uD83C\uDFA5 Media" | |
"audio" -> "\uD83C\uDFA4 Audio" | |
else -> tag.text | |
} | |
if (tag.type == "text" || tag.type == "audio") { | |
binding.leftReplyPreview.visibility = View.GONE | |
} else { | |
binding.leftReplyPreview.visibility = View.VISIBLE | |
when (tag.type) { | |
"video" -> binding.leftReplyPreview.load(tag.thumb, 10f) | |
"photo" -> binding.leftReplyPreview.load(tag.content, 10f) | |
"gif" -> binding.leftReplyPreview.load( | |
tag.linkThumb ?: tag.text, 10f | |
) | |
"groupMedia" -> binding.leftReplyPreview.load( | |
tag.mediaFiles[0]?.content, | |
10f | |
) | |
"eventInvite" -> binding.leftReplyPreview.load(tag.thumb, 10f) | |
"squadInvite" -> binding.leftReplyPreview.load("${Constant.PROFILE_IMG_URL}${tag.content}.jpeg", 10f) | |
} | |
} | |
} | |
} else if (item.repliedTo != null) { | |
binding.leftReplyContainer.visibility = View.VISIBLE | |
binding.leftReplyOrigin.text = | |
if (item.repliedTo?.username == FragChat.USERNAME) "You" else item.repliedTo?.username | |
binding.leftReplyContent.text = when (item.repliedTo!!.type) { | |
"gif" -> "\uD83C\uDFA5 GIF" | |
"video" -> "\uD83C\uDFA5 Video" | |
"photo" -> "\uD83D\uDCF7 Photo" | |
"groupMedia" -> "\uD83C\uDFA5 Media" | |
"audio" -> "\uD83C\uDFA4 Audio" | |
else -> item.repliedTo!!.type | |
} | |
if (item.repliedTo?.thumb == null) { | |
binding.leftReplyPreview.visibility = View.GONE | |
} else { | |
binding.leftReplyPreview.load(item.repliedTo?.thumb, 10f) | |
binding.leftReplyPreview.visibility = View.VISIBLE | |
} | |
} else | |
binding.leftReplyContainer.visibility = View.GONE | |
binding.leftReplyContainer.setOnClickListener { | |
clickListener.onScroll(item.tag ?: "") | |
} | |
} | |
} | |
} | |
} | |
private fun setCustomText(content: String, isLoggedInUser: Boolean): SpannableString? { | |
val isVoice = content.equals("voice", true) | |
val string = SpannableString("${if (isLoggedInUser) username else "You"} missed a $content call from ${if (isLoggedInUser) "you" else username} ${if(isVoice) "☎️" else "\uD83C\uDFA5"}") | |
string.setSpan(object: ForegroundColorSpan(ctx.getColor(R.color.profile_username)){}, 0, if (isLoggedInUser) username.length else 3, 0) | |
return string | |
} | |
private fun ImageView.load(uri: String, enableCache: Boolean = true) { | |
try { | |
Glide | |
.with(ctx) | |
.asDrawable() | |
.load(uri) | |
.diskCacheStrategy(if (enableCache) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE) | |
.thumbnail( | |
Glide | |
.with(ctx) | |
.load(R.mipmap.gif_loader) | |
) | |
.into(this) | |
} catch (ignored: Exception) { | |
} | |
} | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { | |
val binding = ItemChatBinding.inflate(inflater, parent, false) | |
return MyViewHolder(binding) | |
} | |
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { | |
CoroutineScope(Dispatchers.Default).launch { | |
val item = data[holder.absoluteAdapterPosition] | |
withContext(Dispatchers.Main) { | |
holder.bind(item) | |
holder.binding.root.setOnLongClickListener { | |
if (item.type == "missedCall") | |
return@setOnLongClickListener false | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.rightGifContainer.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.rightGif.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.leftMediaContainer.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.rightMediaContainer.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.rightGif.setOnClickListener { | |
ctx.startActivity(Intent(Intent.ACTION_VIEW).apply { | |
data = Uri.parse([email protected][holder.absoluteAdapterPosition].text) | |
}) | |
} | |
holder.binding.leftGifContainer.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.leftGif.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.leftGif.setOnClickListener { | |
ctx.startActivity(Intent(Intent.ACTION_VIEW).apply { | |
data = Uri.parse([email protected][holder.absoluteAdapterPosition].text) | |
}) | |
} | |
holder.binding.leftFrame.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.rightFrame.setOnLongClickListener { | |
popup(holder) | |
return@setOnLongClickListener true | |
} | |
holder.binding.profile.setOnClickListener { | |
if (FragChat.username == "spinny" || FragChat.username == "spinnr") return@setOnClickListener | |
val frag = FragProfileView() | |
frag.arguments = Bundle().apply { | |
putString("guid", data[holder.absoluteAdapterPosition].guid) | |
putString("username", data[holder.absoluteAdapterPosition].username) | |
} | |
(inflater.context as ActHome).navigateTo(frag) | |
} | |
holder.binding.leftFrame.setOnClickListener { | |
listener.onItemSelect(holder.absoluteAdapterPosition) | |
} | |
holder.binding.leftMediaContainer.setOnClickListener { | |
listener.onItemSelect(holder.absoluteAdapterPosition) | |
} | |
holder.binding.rightFrame.setOnClickListener { | |
listener.onItemSelect(holder.absoluteAdapterPosition) | |
} | |
holder.binding.rightMediaContainer.setOnClickListener { | |
listener.onItemSelect(holder.absoluteAdapterPosition) | |
} | |
} | |
} | |
} | |
private fun popup(holder: MyViewHolder) { | |
if (currentSeconds() > 0) { | |
options(holder) | |
return | |
} | |
(ctx as ActHome).hideKeyboard() | |
val item = data[holder.absoluteAdapterPosition] | |
val popupBinding = DialogChatOptionBinding.inflate(inflater) | |
if (item.username == FragChat.USERNAME) { | |
popupBinding.previewLeft.visibility = View.GONE | |
holder.binding.rightFrame.buildDrawingCache() | |
val bitmap = holder.binding.rightFrame.drawingCache | |
popupBinding.previewRight.setImageBitmap(bitmap) | |
} else { | |
holder.binding.leftFrame.buildDrawingCache() | |
val bitmap = holder.binding.leftFrame.drawingCache | |
popupBinding.previewLeft.setImageBitmap(bitmap) | |
popupBinding.divider.visibility = View.GONE | |
popupBinding.delete.visibility = View.GONE | |
} | |
val y = if (item.username == FragChat.USERNAME) { | |
holder.binding.root.y.toInt() | |
} else { | |
(holder.binding.root.y + ctx.toPx(35f)).toInt() | |
} | |
val x = if (item.username == FragChat.USERNAME) { | |
(ctx.width() * .45f - ctx.toPx(10f)).toInt() | |
} else { | |
ctx.toPx(50f).toInt() | |
} | |
FragChat.showBlur = true | |
FragChat.startBlur() | |
val popup = PopupWindow( | |
popupBinding.root, | |
(ctx.width() * .55f).toInt(), | |
LinearLayout.LayoutParams.WRAP_CONTENT, | |
true | |
) | |
popupBinding.delete.setOnClickListener { | |
Firebase | |
.firestore | |
.document("spinnr-chat/" + FragChat.collection + "/messages/${item.documentID}") | |
.delete().addOnSuccessListener { | |
try { | |
if (item.type != "text") { | |
item.fileRefPath?.let { it1 -> | |
Firebase | |
.storage | |
.getReference(it1) | |
.delete() | |
} | |
if (item.type == "video") { | |
item.thumbRefPath?.let { it1 -> | |
Firebase | |
.storage | |
.getReference(it1) | |
.delete() | |
} | |
} | |
Firebase | |
.firestore | |
.document("media-collection/${item.mediaDocumentPath}") | |
.delete() | |
} | |
} catch (e: java.lang.Exception) { | |
} | |
} | |
popup.dismiss() | |
} | |
popupBinding.copy.setOnClickListener { | |
val cm = ctx.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager | |
val clip = ClipData.newPlainText("423u5", item.text) | |
cm.setPrimaryClip(clip) | |
popup.dismiss() | |
if (item.text.isNotBlank()) | |
(ctx as Activity).showSnackBar("Copied!") | |
} | |
popupBinding.root.setOnClickListener { | |
popup.dismiss() | |
} | |
popup.setOnDismissListener { | |
FragChat.showBlur = false | |
} | |
popup.showAtLocation(holder.binding.left, Gravity.NO_GRAVITY, x, y) | |
} | |
private var emojiPopup: EmojiPopup? = null | |
@SuppressLint("ClickableViewAccessibility") | |
private fun options(holder: MyViewHolder) { | |
val item = data[holder.absoluteAdapterPosition] | |
val rect = Rect() | |
val binding = DialogReactionsBinding.inflate(LayoutInflater.from(ctx)) | |
val dialog = Dialog(ctx) | |
var bitmap1: Bitmap? = null | |
if (item.username == FragChat.USERNAME) { | |
//left | |
holder.binding.rightFrame2.getGlobalVisibleRect(rect) | |
holder.binding.rightFrame2.buildDrawingCache() | |
val bitmap = holder.binding.rightFrame2.drawingCache | |
bitmap1 = bitmap | |
binding.container1.setImageBitmap(bitmap) | |
binding.container1.setBackgroundResource(R.drawable.bg_chat_right) | |
binding.leftSupport.visibility = View.VISIBLE | |
(binding.container1.layoutParams as LinearLayout.LayoutParams).gravity = Gravity.END | |
if (item.type != "text" || item.text.contains("giphy.com")) { | |
binding.edit.visibility = View.GONE | |
binding.divider0.visibility = View.GONE | |
} | |
} else { | |
//right | |
holder.binding.leftFrame2.getGlobalVisibleRect(rect) | |
holder.binding.leftFrame2.buildDrawingCache() | |
val bitmap = holder.binding.leftFrame2.drawingCache | |
bitmap1 = bitmap | |
binding.container1.setImageBitmap(bitmap) | |
binding.container1.setBackgroundResource(R.drawable.bg_chat_left) | |
binding.rightSupport.visibility = View.VISIBLE | |
binding.divider.visibility = View.GONE | |
binding.delete.visibility = View.GONE | |
binding.divider0.visibility = View.GONE | |
binding.edit.visibility = View.GONE | |
} | |
if (preferenceInstance.readString("emoji_1").isBlank()) { | |
preferenceInstance.writeString("emoji_1", "\uD83D\uDC4D") | |
} | |
if (preferenceInstance.readString("emoji_2").isBlank()) { | |
preferenceInstance.writeString("emoji_2", "❤") | |
} | |
if (preferenceInstance.readString("emoji_3").isBlank()) { | |
preferenceInstance.writeString("emoji_3", "\uD83D\uDE06") | |
} | |
if (preferenceInstance.readString("emoji_4").isBlank()) { | |
preferenceInstance.writeString("emoji_4", "\uD83D\uDE32") | |
} | |
if (preferenceInstance.readString("emoji_5").isBlank()) { | |
preferenceInstance.writeString("emoji_5", "\uD83D\uDE25") | |
} | |
if (preferenceInstance.readString("emoji_6").isBlank()) { | |
preferenceInstance.writeString("emoji_6", "\uD83D\uDE21") | |
} | |
EmojiManager.getInstance() | |
.findEmoji(preferenceInstance.readString("emoji_1", "\uD83D\uDC4D"))?.let { | |
binding.like.setEmoji(it) | |
} | |
EmojiManager.getInstance().findEmoji(preferenceInstance.readString("emoji_2", "❤"))?.let { | |
binding.love.setEmoji(it) | |
} | |
EmojiManager.getInstance() | |
.findEmoji(preferenceInstance.readString("emoji_3", "\uD83D\uDE06"))?.let { | |
binding.happy.setEmoji(it) | |
} | |
EmojiManager.getInstance() | |
.findEmoji(preferenceInstance.readString("emoji_4", "\uD83D\uDE32"))?.let { | |
binding.wow.setEmoji(it) | |
} | |
EmojiManager.getInstance() | |
.findEmoji(preferenceInstance.readString("emoji_5", "\uD83D\uDE25"))?.let { | |
binding.sad.setEmoji(it) | |
} | |
EmojiManager.getInstance() | |
.findEmoji(preferenceInstance.readString("emoji_6", "\uD83D\uDE21"))?.let { | |
binding.angry.setEmoji(it) | |
} | |
binding.like.setOnClickListener { | |
dialog.dismiss() | |
react( | |
item.documentID, | |
preferenceInstance.readString("emoji_1"), | |
item.reaction?.get(FragChat.USERNAME) == preferenceInstance.readString("emoji_1") | |
) | |
} | |
binding.love.setOnClickListener { | |
dialog.dismiss() | |
react( | |
item.documentID, | |
preferenceInstance.readString("emoji_2"), | |
item.reaction?.get(FragChat.USERNAME) == preferenceInstance.readString("emoji_2") | |
) | |
} | |
binding.happy.setOnClickListener { | |
dialog.dismiss() | |
react( | |
item.documentID, | |
preferenceInstance.readString("emoji_3"), | |
item.reaction?.get(FragChat.USERNAME) == preferenceInstance.readString("emoji_3") | |
) | |
} | |
binding.wow.setOnClickListener { | |
dialog.dismiss() | |
react( | |
item.documentID, | |
preferenceInstance.readString("emoji_4"), | |
item.reaction?.get(FragChat.USERNAME) == preferenceInstance.readString("emoji_4") | |
) | |
} | |
binding.sad.setOnClickListener { | |
dialog.dismiss() | |
react( | |
item.documentID, | |
preferenceInstance.readString("emoji_5"), | |
item.reaction?.get(FragChat.USERNAME) == preferenceInstance.readString("emoji_5") | |
) | |
} | |
binding.angry.setOnClickListener { | |
dialog.dismiss() | |
react( | |
item.documentID, | |
preferenceInstance.readString("emoji_6"), | |
item.reaction?.get(FragChat.USERNAME) == preferenceInstance.readString("emoji_6") | |
) | |
} | |
binding.edit.setOnClickListener { | |
dialog.dismiss() | |
if (item.type == "text") { | |
(frag as FragChat).binding.input.setText(item.text) | |
(frag as FragChat).binding.input.setSelection(item.text.length) | |
(frag as FragChat).editMessage = item | |
} | |
} | |
binding.add.setOnClickListener { | |
dialog.dismiss() | |
FragChat.popup = EmojiPopup.Builder | |
.fromRootView(frag.requireView()) | |
.setOnEmojiClickListener(object : OnEmojiClickListener { | |
override fun onEmojiClick(imageView: EmojiImageView, emoji: Emoji) { | |
swapWith(emoji.getUnicode()) | |
react( | |
item.documentID, | |
emoji.getUnicode(), | |
item.reaction?.get(FragChat.USERNAME) == emoji.getUnicode() | |
) | |
emojiPopup?.dismiss() | |
FragChat.popup?.dismiss() | |
} | |
}) | |
.build() | |
FragChat.popup?.showAtBottom() | |
} | |
binding.copy.setOnClickListener { | |
val cm = ctx.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager | |
val clip = ClipData.newPlainText("423u5", item.text) | |
cm.setPrimaryClip(clip) | |
dialog.dismiss() | |
if (item.text.isNotBlank()) | |
(ctx as Activity).showSnackBar("Copied!") | |
} | |
binding.delete.setOnClickListener { | |
dialog.dismiss() | |
frag.showOptionDialog( | |
"Delete Message", | |
when (item.type) { | |
"video" -> "Are you sure want to delete this video?" | |
"audio" -> "Are you sure want to delete this audio?" | |
"photo" -> "Are you sure want to delete this image?" | |
else -> "Are you sure you want to delete this message?" | |
}, | |
"Cancel", "Delete", true | |
) { | |
if (it == 1) | |
Firebase | |
.firestore | |
.document("spinnr-chat/" + FragChat.collection + "/messages/${item.documentID}") | |
.delete().addOnSuccessListener { | |
try { | |
if (item.type != "text") { | |
item.fileRefPath?.let { it1 -> | |
Firebase | |
.storage | |
.getReference(it1) | |
.delete() | |
} | |
if (item.type == "video") { | |
item.thumbRefPath?.let { it1 -> | |
Firebase | |
.storage | |
.getReference(it1) | |
.delete() | |
} | |
} | |
Firebase | |
.firestore | |
.document("media-collection/${item.mediaDocumentPath}") | |
.delete() | |
} | |
} catch (e: Exception) { | |
} | |
} | |
} | |
} | |
binding.reply.setOnClickListener { | |
replyListener.onReply(item) | |
dialog.dismiss() | |
} | |
/*binding.like.setBackgroundResource(if (item.reaction[FragChat.USERNAME] == "like") R.mipmap.img_reaction_select_bg else R.color.transparent) | |
binding.love.setBackgroundResource(if (item.reaction[FragChat.USERNAME] == "love") R.mipmap.img_reaction_select_bg else R.color.transparent) | |
binding.happy.setBackgroundResource(if (item.reaction[FragChat.USERNAME] == "happy") R.mipmap.img_reaction_select_bg else R.color.transparent) | |
binding.wow.setBackgroundResource(if (item.reaction[FragChat.USERNAME] == "surprise") R.mipmap.img_reaction_select_bg else R.color.transparent) | |
binding.sad.setBackgroundResource(if (item.reaction[FragChat.USERNAME] == "sad") R.mipmap.img_reaction_select_bg else R.color.transparent) | |
binding.angry.setBackgroundResource(if (item.reaction[FragChat.USERNAME] == "angry") R.mipmap.img_reaction_select_bg else R.color.transparent)*/ | |
dialog.setContentView(binding.root) | |
dialog.window?.setBackgroundDrawable(null) | |
dialog.window?.setDimAmount(0f) | |
dialog.window?.attributes?.apply { | |
gravity = Gravity.TOP or Gravity.START | |
x = if (item.username == FragChat.USERNAME) | |
rect.right - binding.root.width | |
else | |
rect.left | |
y = rect.top - (ctx.toPx(56f) * 1.7f).toInt() | |
} | |
dialog.setOnDismissListener { | |
emojiPopup?.dismiss() | |
FragChat.showBlur = false | |
} | |
FragChat.showBlur = true | |
FragChat.startBlur() | |
dialog.show() | |
} | |
private fun swapWith(new: String) { | |
if ( | |
preferenceInstance.readString("emoji_1") == new || | |
preferenceInstance.readString("emoji_2") == new || | |
preferenceInstance.readString("emoji_3") == new || | |
preferenceInstance.readString("emoji_4") == new || | |
preferenceInstance.readString("emoji_5") == new || | |
preferenceInstance.readString("emoji_6") == new | |
) return | |
preferenceInstance.writeString("emoji_6", preferenceInstance.readString("emoji_5")) | |
preferenceInstance.writeString("emoji_5", preferenceInstance.readString("emoji_4")) | |
preferenceInstance.writeString("emoji_4", preferenceInstance.readString("emoji_3")) | |
preferenceInstance.writeString("emoji_3", preferenceInstance.readString("emoji_2")) | |
preferenceInstance.writeString("emoji_2", preferenceInstance.readString("emoji_1")) | |
preferenceInstance.writeString("emoji_1", new) | |
} | |
private fun react(id: String, reaction: String, remove: Boolean) { | |
FragChat.positionListener?.onComplete() | |
if (!remove) | |
(frag as FragChat).reactionNotification(reaction) | |
Firebase | |
.firestore | |
.document("spinnr-chat/${FragChat.collection}/messages/$id/") | |
.update("reaction.${FragChat.USERNAME}", /*if (remove) "" else*/ reaction) | |
} | |
override fun getItemCount() = data.size | |
} | |
fun interface ReplyListener { | |
fun onReply(bitmap: MessageModel) | |
} | |
fun interface ScrollListener { | |
fun onScroll(id: String) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<FrameLayout 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="match_parent" | |
android:background="@color/primaryBackground" | |
android:orientation="vertical" | |
tools:context=".frag.chat.FragChat"> | |
<LinearLayout | |
android:id="@+id/ll" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<ImageView | |
android:id="@+id/back" | |
android:layout_width="@dimen/dimen_50_dp" | |
android:layout_height="@dimen/dimen_50_dp" | |
android:layout_marginStart="@dimen/dimen_12_dp" | |
android:contentDescription="@string/app_name" | |
android:padding="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_back" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
<FrameLayout | |
android:id="@+id/fm" | |
android:layout_width="@dimen/dimen_50_dp" | |
android:layout_height="@dimen/dimen_50_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintStart_toEndOf="@id/back" | |
app:layout_constraintTop_toTopOf="parent"> | |
<de.hdodenhof.circleimageview.CircleImageView | |
android:id="@+id/profile" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_margin="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_profile_placeholder" | |
app:civ_border_color="@color/purpleDark" | |
app:civ_border_width=".9dp" /> | |
<View | |
android:id="@+id/online" | |
android:layout_width="@dimen/dimen_14_dp" | |
android:layout_height="@dimen/dimen_14_dp" | |
android:layout_gravity="end" | |
android:layout_margin="@dimen/dimen_5_dp" | |
android:background="@drawable/bg_online" | |
android:visibility="gone" /> | |
</FrameLayout> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/clTitle" | |
android:layout_width="@dimen/dimen_0_dp" | |
android:layout_height="@dimen/dimen_50_dp" | |
android:layout_weight="1" | |
android:gravity="center_vertical" | |
android:orientation="vertical" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/audioCall" | |
app:layout_constraintStart_toEndOf="@id/fm" | |
app:layout_constraintTop_toTopOf="parent"> | |
<TextView | |
android:id="@+id/title" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:ellipsize="end" | |
android:fontFamily="@font/hellix_bold" | |
android:gravity="center_vertical" | |
android:maxLines="1" | |
android:paddingTop="@dimen/dimen_2_dp" | |
android:text="@string/app_name" | |
android:textColor="@color/profile_username" | |
app:layout_constraintBottom_toTopOf="@id/status" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<TextView | |
android:id="@+id/status" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_medium" | |
android:gravity="center_vertical" | |
android:paddingVertical="@dimen/dimen_2_dp" | |
android:text="@string/typing" | |
android:textColor="@color/primaryDark" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/title" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<ImageView | |
android:id="@+id/audioCall" | |
android:layout_width="@dimen/dimen_50_dp" | |
android:layout_height="@dimen/dimen_50_dp" | |
android:contentDescription="@string/app_name" | |
android:padding="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_audio_call" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/videoCall" | |
app:layout_constraintStart_toEndOf="@id/clTitle" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
<ImageView | |
android:id="@+id/videoCall" | |
android:layout_width="@dimen/dimen_50_dp" | |
android:layout_height="@dimen/dimen_50_dp" | |
android:contentDescription="@string/app_name" | |
android:padding="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_video_call" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/option" | |
app:layout_constraintStart_toEndOf="@id/audioCall" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
<ImageView | |
android:id="@+id/option" | |
android:layout_width="@dimen/dimen_50_dp" | |
android:layout_height="@dimen/dimen_50_dp" | |
android:contentDescription="@string/app_name" | |
android:padding="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_more" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toEndOf="@id/videoCall" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<com.app.spinnr.helper.CustomRecyclerView | |
android:id="@+id/rv" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_weight="1" | |
android:clipToPadding="false" | |
android:paddingTop="@dimen/dimen_10_dp" | |
android:scrollbars="vertical" | |
tools:listitem="@layout/item_chat" /> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/bottomParent" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_10_dp" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/globalChatMsg" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_regular" | |
android:gravity="center" | |
android:lineSpacingExtra="@dimen/dimen_5_dp" | |
android:paddingVertical="@dimen/dimen_15_dp" | |
android:text="@string/global_chat_msg" | |
android:textColor="@color/primaryDark" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/replyContainer" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginHorizontal="@dimen/dimen_10_dp" | |
android:layout_marginTop="@dimen/dimen_10_dp" | |
android:background="@mipmap/img_left_reply_bg" | |
android:paddingStart="@dimen/dimen_10_dp" | |
android:visibility="gone" | |
app:layout_constraintBottom_toTopOf="@id/inputLL" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent"> | |
<TextView | |
android:id="@+id/replyOrigin" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:text="You" | |
android:textColor="@color/primaryDark" | |
android:textSize="16sp" | |
app:layout_constraintBottom_toTopOf="@id/replyContent" | |
app:layout_constraintEnd_toStartOf="@id/fm1" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<TextView | |
android:id="@+id/replyContent" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="@dimen/dimen_4_dp" | |
android:ellipsize="end" | |
android:maxLines="2" | |
android:textColor="@color/color_date_text" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/fm1" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/replyOrigin" /> | |
<FrameLayout | |
android:id="@+id/fm1" | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toEndOf="@id/replyOrigin" | |
app:layout_constraintTop_toTopOf="parent"> | |
<com.google.android.material.imageview.ShapeableImageView | |
android:id="@+id/replyPreview" | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp" | |
android:scaleType="centerCrop" | |
android:src="@mipmap/ic_launcher" | |
android:visibility="gone" | |
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.DifferentCornerSize.PreviewImage" /> | |
<View | |
android:layout_width="@dimen/dimen_9_dp" | |
android:layout_height="@dimen/dimen_9_dp" | |
android:layout_gravity="end" | |
android:background="@color/white" /> | |
<ImageView | |
android:id="@+id/replyClose" | |
android:layout_width="@dimen/dimen_25_dp" | |
android:layout_height="@dimen/dimen_25_dp" | |
android:layout_gravity="end" | |
android:paddingStart="@dimen/dimen_7_dp" | |
android:paddingBottom="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_close_bg" /> | |
</FrameLayout> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/inputLL" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginVertical="@dimen/dimen_10_dp" | |
app:layout_constraintBottom_toTopOf="@id/media" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/replyContainer"> | |
<EditText | |
android:id="@+id/input" | |
android:layout_width="@dimen/dimen_0_dp" | |
android:layout_height="wrap_content" | |
android:layout_marginStart="@dimen/dimen_10_dp" | |
android:layout_marginEnd="@dimen/dimen_10_dp" | |
android:layout_weight="1" | |
android:background="@drawable/bg_chat_input" | |
android:gravity="center_vertical" | |
android:hint="@string/type_a_message" | |
android:importantForAutofill="no" | |
android:includeFontPadding="false" | |
android:inputType="textMultiLine|text|textNoSuggestions" | |
android:maxLines="6" | |
android:minHeight="@dimen/dimen_47_dp" | |
android:paddingHorizontal="@dimen/dimen_10_dp" | |
android:paddingVertical="@dimen/dimen_5_dp" | |
android:textSize="15sp" | |
android:verticalScrollbarPosition="defaultPosition" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/send" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<TextView | |
android:id="@+id/spinnyMessage" | |
android:layout_width="0dp" | |
android:layout_height="0dp" | |
android:text="Please wait while Spinny is in progress!" | |
android:background="@drawable/bg_chat_input" | |
android:backgroundTint="@color/input_color" | |
android:gravity="center" | |
android:visibility="gone" | |
android:textColor="@color/profile_list_icon" | |
app:layout_constraintBottom_toBottomOf="@id/input" | |
app:layout_constraintEnd_toEndOf="@id/input" | |
app:layout_constraintStart_toStartOf="@id/input" | |
app:layout_constraintTop_toTopOf="@id/input" /> | |
<ImageView | |
android:id="@+id/send" | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp" | |
android:layout_gravity="bottom" | |
android:layout_marginEnd="@dimen/dimen_10_dp" | |
android:background="@drawable/circle_white" | |
android:backgroundTint="@color/profile_username" | |
android:fontFamily="@font/hellix_regular" | |
android:gravity="center" | |
android:src="@mipmap/img_message_send" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toEndOf="@id/input" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<ImageView | |
android:id="@+id/spinny" | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp" | |
android:layout_gravity="bottom" | |
android:layout_marginEnd="@dimen/dimen_10_dp" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toEndOf="@id/input" | |
app:layout_constraintTop_toTopOf="parent" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<View | |
android:id="@+id/mediaSpace" | |
android:layout_width="match_parent" | |
android:layout_height="@dimen/dimen_10_dp" | |
android:visibility="gone" | |
app:layout_constraintBottom_toTopOf="@id/media" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/inputLL" /> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/media" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center_vertical" | |
android:paddingHorizontal="@dimen/dimen_10_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/mediaSpace" | |
tools:ignore="ContentDescription"> | |
<ImageView | |
android:id="@+id/gallery" | |
android:layout_width="@dimen/dimen_38_dp" | |
android:layout_height="@dimen/dimen_38_dp" | |
android:padding="@dimen/dimen_10_dp" | |
android:src="@mipmap/img_gallery" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/recordVideo" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
<ImageView | |
android:id="@+id/recordVideo" | |
android:layout_width="@dimen/dimen_38_dp" | |
android:layout_height="@dimen/dimen_38_dp" | |
android:padding="@dimen/dimen_10_dp" | |
android:src="@mipmap/img_video" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/recordAudio" | |
app:layout_constraintStart_toEndOf="@id/gallery" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
<ImageView | |
android:id="@+id/recordAudio" | |
android:layout_width="@dimen/dimen_38_dp" | |
android:layout_height="@dimen/dimen_38_dp" | |
android:padding="@dimen/dimen_10_dp" | |
android:src="@mipmap/img_record_audio" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/gif" | |
app:layout_constraintStart_toEndOf="@id/recordVideo" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
<ImageView | |
android:id="@+id/gif" | |
android:layout_width="@dimen/dimen_38_dp" | |
android:layout_height="@dimen/dimen_38_dp" | |
android:padding="@dimen/dimen_10_dp" | |
android:src="@mipmap/ic_gif" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintStart_toEndOf="@id/recordAudio" | |
app:layout_constraintTop_toTopOf="parent" | |
app:tint="@color/profile_username" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</LinearLayout> | |
<ImageView | |
android:id="@+id/preview" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" /> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.Manifest | |
import android.annotation.SuppressLint | |
import android.app.Activity | |
import android.app.Dialog | |
import android.content.Context | |
import android.content.Intent | |
import android.content.pm.PackageManager | |
import android.graphics.Bitmap | |
import android.graphics.BitmapFactory | |
import android.graphics.Color | |
import android.graphics.Matrix | |
import android.media.MediaMetadataRetriever | |
import android.media.MediaMetadataRetriever.METADATA_KEY_DURATION | |
import android.net.Uri | |
import android.os.* | |
import android.provider.MediaStore | |
import android.provider.Settings | |
import android.text.Editable | |
import android.text.TextWatcher | |
import android.util.DisplayMetrics | |
import android.util.Log | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.view.WindowManager | |
import android.widget.ImageView | |
import androidx.activity.result.contract.ActivityResultContracts | |
import androidx.core.content.ContextCompat | |
import androidx.core.content.FileProvider | |
import androidx.exifinterface.media.ExifInterface | |
import androidx.fragment.app.Fragment | |
import androidx.lifecycle.lifecycleScope | |
import androidx.recyclerview.widget.LinearLayoutManager | |
import androidx.recyclerview.widget.LinearSmoothScroller | |
import androidx.recyclerview.widget.RecyclerView | |
import com.andremion.louvre.Louvre | |
import com.andremion.louvre.home.GalleryActivity | |
import com.app.spinnr.App | |
import com.app.spinnr.App.Companion.getStr | |
import com.app.spinnr.R | |
import com.app.spinnr.act.ActHome | |
import com.app.spinnr.act.ActHome.Companion.timeDx | |
import com.app.spinnr.act.ActVideoCall | |
import com.app.spinnr.act.ActVoiceCall | |
import com.app.spinnr.adapter.ChatAdapter | |
import com.app.spinnr.adapter.ReplyListener | |
import com.app.spinnr.adapter.ScrollListener | |
import com.app.spinnr.databinding.DialogInactiveUserChatBinding | |
import com.app.spinnr.databinding.FragChatBinding | |
import com.app.spinnr.frag.* | |
import com.app.spinnr.frag.chat.vik.flow.ChatRepository | |
import com.app.spinnr.frag.chat.vik.viewmodel.ChatViewModel | |
import com.app.spinnr.frag.profile.FragProfileView | |
import com.app.spinnr.frag.squad.FragSquadInfo | |
import com.app.spinnr.frag.squad.SquadRepo | |
import com.app.spinnr.frag.video.FragCreateVideo | |
import com.app.spinnr.frag.video.FragTrimVideo | |
import com.app.spinnr.helper.Constant | |
import com.app.spinnr.listener.CompleteListener | |
import com.app.spinnr.listener.ItemSelectListener | |
import com.app.spinnr.model.* | |
import com.app.spinnr.service.ANotification | |
import com.app.spinnr.service.ApiClient.Companion.getClient | |
import com.app.spinnr.service.ApiClient.Companion.getClient2 | |
import com.app.spinnr.service.ResponseBean | |
import com.app.spinnr.service.ResponseListBean | |
import com.app.spinnr.util.* | |
import com.app.spinnr.util.Preference.Companion.FALSE | |
import com.app.spinnr.util.Preference.Companion.FTP_CAMERA | |
import com.app.spinnr.util.Preference.Companion.TRUE | |
import com.app.spinnr.util.Preference.Companion.preferenceInstance | |
import com.app.spinnr.util.imageUtil.Blur | |
import com.appsflyer.AppsFlyerLib | |
import com.giphy.sdk.core.models.Media | |
import com.giphy.sdk.core.models.enums.MediaType | |
import com.giphy.sdk.core.models.enums.RatingType | |
import com.giphy.sdk.core.models.enums.RenditionType | |
import com.giphy.sdk.ui.GPHContentType | |
import com.giphy.sdk.ui.GPHSettings | |
import com.giphy.sdk.ui.Giphy | |
import com.giphy.sdk.ui.pagination.GPHContent | |
import com.giphy.sdk.ui.utils.aspectRatio | |
import com.giphy.sdk.ui.utils.videoAspectRatio | |
import com.giphy.sdk.ui.views.GiphyDialogFragment | |
import com.google.firebase.firestore.DocumentSnapshot | |
import com.google.firebase.firestore.FieldValue | |
import com.google.firebase.firestore.ListenerRegistration | |
import com.google.firebase.firestore.ktx.firestore | |
import com.google.firebase.firestore.ktx.getField | |
import com.google.firebase.ktx.Firebase | |
import com.google.firebase.storage.ktx.storage | |
import com.google.gson.JsonElement | |
import dev.leonardpark.emoji.EmojiPopup | |
import io.github.ponnamkarthik.richlinkpreview.* | |
import kotlinx.coroutines.Dispatchers | |
import kotlinx.coroutines.flow.collectLatest | |
import kotlinx.coroutines.launch | |
import org.json.JSONObject | |
import kotlinx.coroutines.withContext | |
import retrofit2.Call | |
import retrofit2.Callback | |
import retrofit2.Response | |
import java.io.File | |
import java.io.FileInputStream | |
import java.io.FileOutputStream | |
import java.lang.StringBuilder | |
import java.net.HttpURLConnection | |
import java.net.URL | |
import java.text.SimpleDateFormat | |
import java.util.* | |
@Suppress("DEPRECATION") | |
@SuppressLint("StaticFieldLeak") | |
class FragChat( | |
private val me: Boolean = true, | |
private val global: Boolean = false, | |
) : Fragment() { | |
companion object { | |
var showBlur = false | |
var target: ImageView? = null | |
var source: View? = null | |
var collection: String = "" | |
var USERNAME: String = "" // me | |
var GUID: String = "" // me | |
var username: String = "" // other | |
var guid: String = "" // other | |
fun startBlur() { | |
if (!showBlur) { | |
target?.setImageBitmap(null) | |
return | |
} | |
source?.buildDrawingCache() | |
Blur.doBlur( | |
source?.drawingCache, 14, Color.argb(10, 0, 0, 0) | |
) { bmp -> | |
Handler(Looper.getMainLooper()).post { | |
source?.destroyDrawingCache() | |
target?.setImageBitmap(bmp) | |
startBlur() | |
} | |
} | |
} | |
var callListener: CompleteListener? = null | |
var positionListener: CompleteListener? = null | |
var popup: EmojiPopup? = null | |
} | |
private var filesUploadedCount = 0 | |
private var uploadedFilesReference = "" | |
private val LOUVRE_REQUEST_CODE = 1020 | |
private var mSelection: MutableList<Uri?> = mutableListOf() | |
private lateinit var ctx: Context | |
lateinit var binding: FragChatBinding | |
private lateinit var adapter: ChatAdapter | |
private val data = mutableListOf<MessageModel>() | |
private var mediaFiles = mutableListOf<MediaFile?>() | |
//private var guid = "" | |
//private var username = "" | |
private var position = -1 | |
private var unreadCount = 0 | |
private var recordsToFetch = 25L | |
private lateinit var linearLayoutManager: LinearLayoutManager | |
private lateinit var lastVisible: DocumentSnapshot | |
private var isLastMessageReached = false | |
private var isLoadMore = false | |
private lateinit var repository: ChatRepository | |
private lateinit var chatViewModel: ChatViewModel | |
private var from = 1 | |
private var loaded = false | |
private var detailSubscriber: ListenerRegistration? = null | |
private var typingSubscriber: ListenerRegistration? = null | |
private var subscriber: ListenerRegistration? = null | |
private var onlineStatusSubscriber: ListenerRegistration? = null | |
private var loader: Loader? = null | |
private var isResumed = false | |
private var typingTimer: CountDownTimer? = null | |
private val handler = Handler(Looper.getMainLooper()) | |
private lateinit var giphyDialog: GiphyDialogFragment | |
override fun onDestroy() { | |
Blur.destroy() | |
callListener = null | |
typingSubscriber?.remove() | |
detailSubscriber?.remove() | |
subscriber?.remove() | |
onlineStatusSubscriber?.remove() | |
super.onDestroy() | |
} | |
override fun onCreateView( | |
inflater: LayoutInflater, container: ViewGroup?, | |
savedInstanceState: Bundle? | |
): View { | |
if (loaded) return binding.root | |
loaded = true | |
ctx = requireContext() | |
Giphy.configure(ctx, "bj87yysRtVcTfGw0bfmSX7kh4PvS6HyK") | |
binding = FragChatBinding.inflate(inflater, container, false) | |
(ctx as ActHome).changeUi(this) | |
postDelayed({ setup() }, 250) | |
/*if ((ctx as ActHome).systemDarkMode == AppCompatDelegate.MODE_NIGHT_YES) | |
binding.bottomParent.background = null*/ | |
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) | |
callListener = CompleteListener { | |
val i = preferenceInstance.readInt("callStatus") | |
} | |
positionListener = CompleteListener { | |
position = | |
(binding.rv.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() | |
Log.i("423u5-position", ">>> $position") | |
} | |
/*GIPHY SDK Start*/ | |
/*GIPHY SDK End*/ | |
return binding.root | |
} | |
override fun onResume() { | |
paused = false | |
Blur.init(ctx) | |
ANotification.chatUsername = username | |
super.onResume() | |
postDelayed({ | |
if (collection.isNotBlank()) | |
Firebase.firestore.document("spinnr-chat/$collection/").get().addOnSuccessListener { | |
if (it.toObject(MessageImpl::class.java) == null) binding.back.performClick() | |
} | |
}, 100) | |
} | |
override fun onPause() { | |
paused = true | |
ANotification.chatUsername = "" | |
updateTyping(false) | |
popup?.dismiss() | |
super.onPause() | |
} | |
private fun setup() { | |
target = binding.preview | |
source = binding.ll | |
guid = arguments?.getString("guid") ?: "" | |
username = arguments?.getString("username") ?: "" | |
if (me) { | |
USERNAME = preferenceInstance.readString(Preference.USERNAME) | |
GUID = preferenceInstance.readString(Preference.GUID) | |
} | |
ANotification.chatUsername = username | |
val a0 = arrayOf(USERNAME, username).sorted() | |
collection = "${a0.first()}-${a0.last()}" | |
if (global) collection = "spinnr-global" | |
binding.back.setOnClickListener(clickListener) | |
binding.audioCall.setOnClickListener(clickListener) | |
binding.videoCall.setOnClickListener(clickListener) | |
binding.option.setOnClickListener(clickListener) | |
binding.gallery.setOnClickListener(clickListener) | |
binding.recordVideo.setOnClickListener(clickListener) | |
binding.recordAudio.setOnClickListener(clickListener) | |
binding.gif.setOnClickListener(clickListener) | |
binding.send.setOnClickListener(clickListener) | |
binding.input.addTextChangedListener(textChangeListener) | |
binding.profile.setOnClickListener(clickListener) | |
binding.spinnyMessage.setOnClickListener { Log.i("423u5", "lol....") } | |
binding.title.text = username | |
adapter = ChatAdapter( | |
ctx, | |
this, | |
LayoutInflater.from(ctx), | |
username, | |
data, | |
messageClickListener, | |
replyListener, | |
lickListsner | |
) | |
linearLayoutManager = object : LinearLayoutManager(ctx) { | |
override fun smoothScrollToPosition( | |
recyclerView: RecyclerView, | |
state: RecyclerView.State, | |
position: Int | |
) { | |
val smoothScroller: LinearSmoothScroller = object : LinearSmoothScroller(ctx) { | |
private val SPEED = 300f // Change this value (default=25f) | |
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float { | |
return SPEED / displayMetrics.densityDpi | |
} | |
} | |
smoothScroller.targetPosition = position | |
startSmoothScroll(smoothScroller) | |
} | |
} | |
binding.rv.layoutManager = linearLayoutManager | |
binding.rv.setHasFixedSize(true) | |
binding.rv.itemAnimator = null | |
binding.rv.setItemViewCacheSize(100) | |
binding.rv.adapter = adapter | |
(binding.rv.layoutManager as LinearLayoutManager).apply { | |
stackFromEnd = true | |
} | |
if (username == "spinny") { | |
binding.mediaSpace.visibility = View.VISIBLE | |
binding.audioCall.visibility = View.GONE | |
binding.videoCall.visibility = View.GONE | |
binding.option.visibility = View.GONE | |
binding.media.visibility = View.GONE | |
binding.status.visibility = View.VISIBLE | |
binding.status.text = "Your personal A.I. friend to chat with!" | |
binding.spinny.load(Constant.SPINNY_LOADING, enableCache = true) | |
} else if (username == "spinnr") { | |
binding.audioCall.visibility = View.GONE | |
binding.videoCall.visibility = View.GONE | |
binding.option.visibility = View.GONE | |
binding.media.visibility = View.GONE | |
binding.inputLL.visibility = View.GONE | |
binding.globalChatMsg.visibility = View.VISIBLE | |
binding.status.visibility = View.VISIBLE | |
binding.status.text = "Global Chat" | |
} else { | |
binding.mediaSpace.visibility = View.GONE | |
binding.audioCall.visibility = View.VISIBLE | |
binding.videoCall.visibility = View.VISIBLE | |
binding.option.visibility = View.VISIBLE | |
binding.media.visibility = View.VISIBLE | |
} | |
binding.profile.keyProfile(username, update = true) | |
if (requireArguments().getBoolean("initChat")) initChat() | |
else chatData() | |
binding.root.setOnTouchListener { v, event -> | |
popup?.dismiss() | |
return@setOnTouchListener false | |
} | |
loader = showLoader() | |
getProfile() | |
} | |
private fun initChat() { | |
var sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") | |
sdf.timeZone = TimeZone.getTimeZone("UTC") | |
var time = sdf.format(Date()) | |
var sdf1 = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") | |
sdf1.timeZone = TimeZone.getTimeZone("UTC") | |
var time1 = (sdf1.parse(time)!!.time / 1000) | |
val data = MessageImpl( | |
collection, time1, mutableListOf(USERNAME, username), mutableListOf( | |
MemberDetail(GUID, USERNAME), | |
MemberDetail(guid, username), | |
), mutableMapOf( | |
username to 0, USERNAME to 0 | |
), MessageModel( | |
"", | |
preferenceInstance.readString(Preference.GUID), | |
preferenceInstance.readString(Preference.USERNAME), | |
"text", | |
System.currentTimeMillis() + timeDx, | |
text = "Let's chat!" | |
), false | |
) | |
Firebase.firestore.document("spinnr-chat/$collection/").set(data).addOnFailureListener { | |
showMessage("${it.message}") { | |
binding.back.performClick() | |
} | |
} | |
chatData() | |
val value = requireArguments().getString("value") ?: "" | |
sendMessage( | |
if (value.startsWith("http")) value else value.decodeMessage(), | |
if (value.startsWith("http")) "video" else "text", | |
me = false, | |
) | |
} | |
private var paused = false | |
private fun chatData() { | |
/*subscriber = Firebase.firestore.collection("spinnr-chat/$collection/messages/") | |
.orderBy("createdAt", Query.Direction.DESCENDING) | |
.limit(recordsToFetch) | |
.addSnapshotListener { value, _ -> | |
if (value == null) return@addSnapshotListener | |
data.clear() | |
isLastMessageReached = false | |
value.forEach { | |
try { | |
val item = it.toObject(MessageModel::class.java) | |
data.add(item) | |
data.forEach { msg -> if (msg.createdAt.toString().length == 10) msg.createdAt *= 1000 } | |
data.sortBy { a -> a.createdAt } | |
} catch (e: Exception) { | |
try { | |
Firebase.firestore.document("spinnr-chat/$collection/messages/${it.id}") | |
.delete() | |
} catch (e: Exception) { | |
Log.e("vi26", "chatData: $e") | |
} | |
Log.i("423u5", ">>> ${it.data}") | |
e.printStackTrace() | |
} | |
} | |
if (data.size != 0) Firebase.firestore.document("spinnr-chat/$collection/") | |
.update("lastMessage", data.last()) | |
binding.rv.adapter = ChatAdapter( | |
ctx, | |
this, | |
LayoutInflater.from(ctx), | |
username, | |
data, | |
messageClickListener, | |
replyListener, | |
lickListsner | |
) | |
if (position != -1) { | |
binding.rv.post { | |
binding.rv.smoothScrollToPosition(position) | |
position = -1 | |
} | |
} | |
if (data.isNotEmpty()) updateMessageCount(true, data.last().username) | |
if (value.size() > 0 && value.documents.isNotEmpty()) | |
lastVisible = value.documents[value.size() - 1] | |
val onScrollListener = object : RecyclerView.OnScrollListener() { | |
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { | |
super.onScrolled(recyclerView, dx, dy) | |
val firstVisibleItemPosition = | |
linearLayoutManager.findFirstVisibleItemPosition() | |
if (dy < 0 && firstVisibleItemPosition - 5 < 0 && !isLastMessageReached) { | |
val nextQuery = Firebase.firestore | |
.collection("spinnr-chat/$collection/messages/") | |
.orderBy("createdAt", Query.Direction.DESCENDING) | |
.startAfter(lastVisible) | |
.limit(recordsToFetch) | |
nextQuery.addSnapshotListener { nextValue, _ -> | |
if (nextValue != null) { | |
if (nextValue.size() > 0 && nextValue.documents.isNotEmpty()) | |
if (nextValue.documents[nextValue.size() - 1].id != lastVisible.id) { | |
nextValue.forEach { | |
try { | |
val item = it.toObject(MessageModel::class.java) | |
data.add(0, item) | |
data.forEach { msg -> if (msg.createdAt.toString().length == 10) msg.createdAt *= 1000 } | |
data.sortBy { a -> a.createdAt } | |
} catch (e: Exception) { | |
try { | |
Firebase.firestore.document("spinnr-chat/$collection/messages/${it.id}") | |
.delete() | |
} catch (e: Exception) { | |
Log.e("vi26", "onScrolled: $e") | |
} | |
Log.i("423u5", ">>> ${it.data}") | |
e.printStackTrace() | |
} | |
} | |
} | |
adapter.notifyItemRangeInserted(0, nextValue.documents.size) | |
if (nextValue.documents.isNotEmpty()) | |
lastVisible = nextValue.documents[nextValue.size() - 1] | |
if (nextValue.size() < recordsToFetch) { | |
isLastMessageReached = true | |
} | |
} | |
} | |
} | |
} | |
} | |
binding.rv.addOnScrollListener(onScrollListener) | |
}*/ | |
repository = ChatRepository("spinnr-chat/$collection/messages/") | |
chatViewModel = ChatViewModel(repository) | |
lifecycleScope.launch(Dispatchers.IO) { | |
chatViewModel._retrieveMessages().collect { value -> | |
if (value == null || !updateData) { | |
updateData = true | |
return@collect | |
} | |
val items = mutableListOf<MessageModel>() | |
isLastMessageReached = false | |
var select = 0 | |
value.forEach { | |
Log.e("423u5-aa", "${++select} >> ${it.data}") | |
try { | |
items.add(it.toObject(MessageModel::class.java)) | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
} | |
items.forEach { msg -> if (msg.createdAt.toString().length == 10) msg.createdAt *= 1000 } | |
items.sortBy { a -> a.createdAt } | |
if (items.size != 0) | |
Firebase.firestore.document("spinnr-chat/$collection/").update("lastMessage", items.last()) | |
withContext(Dispatchers.Main) { | |
data.clear() | |
data.addAll(items) | |
adapter.notifyDataSetChanged() | |
position = adapter.itemCount - 1 | |
if (position != -1) { | |
binding.rv.post { | |
binding.rv.scrollToPosition(position) | |
position = -1 | |
} | |
} | |
} | |
if (data.isNotEmpty()) updateMessageCount(true, data.last().username) | |
if (value.size() > 0 && value.documents.isNotEmpty()) | |
lastVisible = value.documents[value.size() - 1] | |
} | |
} | |
val onScrollListener = object : RecyclerView.OnScrollListener() { | |
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { | |
super.onScrolled(recyclerView, dx, dy) | |
if (!isLastMessageReached) { | |
val firstVisibleItemPosition = | |
linearLayoutManager.findFirstVisibleItemPosition() | |
if (dy < 0 && firstVisibleItemPosition < 10 && !isLoadMore) { | |
// Load more data when the user scrolls to the top | |
isLoadMore = true | |
lifecycleScope.launch(Dispatchers.IO) { | |
chatViewModel._retrieveMessages(lastVisible) | |
.collectLatest { nextValue -> | |
Log.d("423u5-aa", "onScrolled: ${nextValue?.documents}") | |
if (nextValue == null) return@collectLatest | |
if (nextValue.size() > 0 && nextValue.documents.isNotEmpty()) { | |
val newDatam = mutableListOf<MessageModel>() | |
if (nextValue.documents[nextValue.size() - 1].id != lastVisible.id) { | |
nextValue.forEach { | |
try { | |
newDatam.add(it.toObject(MessageModel::class.java)) | |
} catch (e: Exception) { | |
} | |
} | |
newDatam.forEach { msg -> if (msg.createdAt.toString().length == 10) msg.createdAt *= 1000 } | |
newDatam.sortBy { a -> a.createdAt } | |
} | |
withContext(Dispatchers.Main) { | |
val size = data.size | |
data.addAll(0, newDatam) | |
adapter.notifyItemRangeInserted(0, newDatam.size) | |
} | |
} | |
isLoadMore = false | |
if (nextValue.documents.isNotEmpty()) | |
lastVisible = nextValue.documents[nextValue.size() - 1] | |
if (nextValue.documents.size < recordsToFetch) { | |
isLastMessageReached = true | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
binding.rv.addOnScrollListener(onScrollListener) | |
detailSubscriber = Firebase.firestore.document("spinnr-chat/$collection/") | |
.addSnapshotListener { value, _ -> | |
if (value == null || paused) return@addSnapshotListener | |
val raw = value.toObject(MessageImpl::class.java) | |
if (raw == null) { | |
binding.back.performClick() | |
return@addSnapshotListener | |
} | |
unreadCount = raw.unreadCount?.get(username) ?: 0 | |
} | |
typingSubscriber = Firebase.firestore.collection("spinnr-chat/$collection/typing-info") | |
.addSnapshotListener { value, _ -> | |
if (value == null || username == "spinny" || username == "spinnr") return@addSnapshotListener | |
for (a in value) | |
if (a.id == username) { | |
binding.status.visibility = if (a.getBoolean("typing") == true) View.VISIBLE | |
else View.GONE | |
break | |
} | |
} | |
if (binding.title.text == "spinny" || binding.title.text == "spinnr") { | |
binding.online.visibility = View.VISIBLE | |
return | |
} | |
onlineStatusSubscriber = Firebase.firestore | |
.document("users/$username") | |
.addSnapshotListener { value, _ -> | |
Log.i("423u5-online-profile", value?.data.toString()) | |
if (value == null || value.data == null || netNotConnected()) | |
binding.online.visibility = View.GONE | |
else { | |
val onlineStatus = value.getField<ActHome.OnlineStatus>("onlineStatus") | |
val isOnline = onlineStatus?.status == true && onlineStatus.updatedAt.seconds > currentSeconds() / 1000 | |
binding.online.visibility = if (isOnline) View.VISIBLE else View.GONE | |
} | |
} | |
} | |
var linkTitle: String? = null | |
var linkDescription: String? = null | |
var linkThumb: String? = null | |
fun decodeMessageLink(text: String) { | |
var urls = extractUrls(text) | |
if (urls != null) { | |
//binding.rightLinkPreviewContainer.removeAllViews(); | |
if (urls.size > 0) { | |
if (urls.size == 1) { | |
if (text.trim().length == urls[0].trim().length) { | |
//binding.rightMsg.visibility = View.GONE; | |
} | |
} | |
loader = showLoader() | |
var ww = RichPreview(object : ResponseListener { | |
override fun onData(metaData: MetaData?) { | |
//TODO("Not yet implemented") | |
loader?.dismiss() | |
linkTitle = metaData?.title | |
linkDescription = metaData?.description | |
linkThumb = metaData?.imageurl | |
message = text | |
filterMessage(text) { | |
sendMessage(message, "text") | |
} | |
} | |
override fun onError(e: java.lang.Exception?) { | |
//TODO("Not yet implemented") | |
loader?.dismiss() | |
} | |
}); | |
ww.getPreview(makeValidUrl(urls[0])) | |
for (urlsObj in urls) { | |
Log.i("here text", text); | |
Log.i("here urls", urlsObj); | |
var richLinkView = RichLinkView(ctx); | |
richLinkView.setLink(makeValidUrl(urlsObj), object : ViewListener { | |
override fun onSuccess(status: Boolean) {} | |
override fun onError(e: Exception) {} | |
}); | |
//binding.rightLinkPreviewContainer.addView(richLinkView); | |
} | |
} else { | |
//binding.rightLinkPreviewContainer.visibility = View.GONE; | |
message = text | |
filterMessage(text) { | |
sendMessage(message, "text") | |
} | |
} | |
} else { | |
message = text | |
filterMessage(text) { | |
sendMessage(message, "text") | |
} | |
} | |
} | |
private var message: String = "" | |
private fun filterMessage(v: String, listner: CompleteListener) { | |
System.currentTimeMillis() | |
message = convertOffendString(v) | |
System.currentTimeMillis() | |
sendMessage(message, "text") | |
} | |
var editMessage: MessageModel? = null | |
private fun sendMessage( | |
value: String, | |
type: String, | |
me: Boolean = true, | |
thumb: String = "", | |
storageRef: String = "", | |
storageThumbRef: String = "" | |
) { | |
if (App.netNotConnected()) { | |
showSnackBar(getStr(R.string.no_internet)) | |
return | |
} | |
if (editMessage != null) { | |
if (type == "text") editMessage?.let { | |
it.text = value | |
it.isEdited = true | |
it.linkTitle = linkTitle | |
it.linkDescription = linkDescription | |
it.linkThumb = linkThumb | |
linkTitle = null | |
linkDescription = null | |
linkThumb = null | |
Firebase.firestore.document("spinnr-chat/$collection/messages/${it.documentID}") | |
.set(it) | |
} | |
editMessage = null | |
binding.input.setText("") | |
return | |
} | |
val msgId = Firebase.firestore.collection("spinnr-chat/$collection/messages").document().id | |
var sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") | |
sdf.timeZone = TimeZone.getTimeZone("UTC") | |
var time = sdf.format(Date()) | |
var sdf1 = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") | |
sdf1.timeZone = TimeZone.getTimeZone("UTC") | |
var time1 = (sdf1.parse(time)!!.time) | |
val message = MessageModel( | |
msgId, | |
if (me) GUID else guid, | |
if (me) USERNAME else username, | |
type, | |
time1 + timeDx, | |
tag = null | |
) | |
replyMsg?.let { | |
message.repliedTo = | |
RepliedTo( | |
it.documentID, | |
it.username, | |
it.guid, | |
it.type, | |
when (it.type) { | |
"text" -> it.text | |
else -> it.content | |
}, | |
when (it.type) { | |
"photo" -> it.content | |
"video" -> it.thumb | |
"gif" -> it.linkThumb | |
"groupMedia" -> { | |
var athumb: String? = null | |
it.mediaFiles.first()?.let { m-> | |
athumb = if (m.type == "photo") | |
m.content | |
else | |
m.reference | |
} | |
athumb | |
} | |
else -> null | |
} | |
) | |
} | |
replyMsg?.let { | |
App.appsFlyerEvent("Chat_Reply") | |
} | |
when (message.type) { | |
"missedCall" -> { | |
message.content = value | |
} | |
"text" -> { | |
message.text = value | |
val eventValues = HashMap<String, Any>() | |
eventValues["customer_user_id"] = | |
Preference.preferenceInstance.readString(Preference.USERNAME) | |
eventValues["datetime"] = Calendar.getInstance().time.toString() | |
if (data.size == 1 && binding.title.text != "spinny") AppsFlyerLib.getInstance() | |
.logEvent(ctx, "Chat_Message", eventValues) | |
if (data.size == 1 && binding.title.text != "spinny") | |
App.appsFlyerEvent("Chat_Message") | |
} | |
"gif" -> { | |
message.text = value | |
linkThumb = value | |
message.linkThumb = value | |
val eventValues = HashMap<String, Any>() | |
eventValues["customer_user_id"] = | |
Preference.preferenceInstance.readString(Preference.USERNAME) | |
eventValues["datetime"] = Calendar.getInstance().time.toString() | |
if (data.size == 1 && binding.title.text != "spinny") AppsFlyerLib.getInstance() | |
.logEvent(ctx, "Chat_Gif", eventValues) | |
App.appsFlyerEvent("Chat_GIF") | |
} | |
"video" -> { | |
message.content = value | |
message.thumb = thumb | |
App.appsFlyerEvent("Chat_Video") | |
} | |
"photo" -> { | |
message.content = value | |
App.appsFlyerEvent("Chat_Photo") | |
} | |
"groupMedia" -> { | |
message.mediaFiles = mediaFiles | |
filesUploadedCount = 0 | |
App.appsFlyerEvent("Chat_Media") | |
} | |
"audio" -> { | |
message.content = value | |
App.appsFlyerEvent("Chat_Audio") | |
} | |
} | |
message.linkTitle = linkTitle | |
message.linkDescription = linkDescription | |
message.linkThumb = linkThumb | |
linkTitle = null | |
linkDescription = null | |
linkThumb = null | |
if (type != "text" && type != "gif") { | |
val mediaId = Firebase.firestore.collection("media-collection").document().id | |
val mediaDetail = MediaDetail( | |
mediaId, | |
msgId, | |
message.createdAt, | |
message.content, | |
message.thumb, | |
message.type, | |
USERNAME, | |
GUID, | |
username, | |
guid, | |
storageRef, | |
storageThumbRef, | |
mediaFiles | |
) | |
Firebase.firestore.document("media-collection/$mediaId").set(mediaDetail) | |
if (!message.type.equals("groupMedia", true)) | |
message.fileRefPath = storageRef | |
message.thumbRefPath = storageThumbRef | |
message.mediaDocumentPath = mediaId | |
Log.i("423u5", ">> $mediaDetail") | |
} | |
if (me) | |
updateMessageCount() | |
binding.replyClose.performClick() | |
binding.input.text.clear() | |
//(ctx as ActHome).hideKeyboard() | |
Firebase.firestore.document("spinnr-chat/$collection/messages/$msgId").set(message) | |
.addOnFailureListener { showSnackBar("${it.message}") } | |
Firebase.firestore.document("spinnr-chat/$collection/").update("lastMessage", message) | |
if (me) | |
sendPush( | |
NEW_CHAT_MESSAGE, guid, 15, "New chat message ${ | |
when (type) { | |
"audio" -> "\uD83D\uDD08" | |
"video" -> "\uD83C\uDFA5" | |
"photo" -> "\uD83D\uDCF8" | |
"groupMedia" -> "\uD83C\uDFA5" | |
else -> "\uD83D\uDCAC" | |
} | |
}", "You have a new chat message from $USERNAME!", collection | |
) | |
if (me && username == "spinny") { | |
ChatRepo.spinnyQuestions(message) | |
autoMessageV2(value) | |
} | |
} | |
private val messageClickListener = ItemSelectListener { | |
try { | |
when (data[it].type) { | |
"photo" -> ctx.showImage(data[it].content) | |
"groupMedia" -> ctx.showImages(data[it].mediaFiles) | |
"audio" -> { | |
val frag = FragVideoPreview() | |
frag.arguments = Bundle().apply { | |
putString("title", "Audio") | |
putString("path", data[it].content) | |
} | |
(ctx as ActHome).navigateTo(frag, true) | |
} | |
"video" -> { | |
val frag = FragVideoPreview() | |
frag.arguments = Bundle().apply { | |
putString("title", "Video") | |
putString("path", data[it].content) | |
} | |
(ctx as ActHome).navigateTo(frag, true) | |
} | |
"eventInvite" -> { | |
FragEventDetail.event = EventsImpl.EventsModel() | |
FragEventDetail.event.id = data[it].content | |
(ctx as ActHome).navigateTo(FragEventDetail(), true) | |
} | |
"squadInvite" -> { | |
var squadId = "" | |
for (a in 0 until SquadRepo.all.size) | |
if (SquadRepo.all[a].squadid == data[it].content) | |
squadId = SquadRepo.all[a].squadid | |
(ctx as ActHome).navigateTo(FragSquadInfo().apply { | |
arguments = Bundle().apply { | |
putString("id", squadId) | |
} | |
}) | |
} | |
} | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
} | |
private fun isCallAllow(audio: Boolean) { | |
loader = showLoader() | |
getClient().getUserNotificationSettings(mapOf("username" to username, "guid" to guid)) | |
.enqueue(object : Callback<NotificationSettingImpl> { | |
override fun onResponse(call: Call<NotificationSettingImpl>, response: Response<NotificationSettingImpl>) { | |
loader?.dismiss() | |
var notAllow = true | |
if (response.body()?.code == "1") { | |
response.body()?.data?.forEach { | |
if (it.pushnotificationId == "10") | |
notAllow = false | |
} | |
} | |
if (notAllow) { | |
showSnackBar("$username has \"do not disturb\" turned on") | |
return | |
} | |
if (audio) { | |
App.appsFlyerEvent("Chat_Audio_Call") | |
ActVoiceCall.type = 33 | |
ActVoiceCall.username = username | |
startActivityForResult(Intent(ctx, ActVoiceCall::class.java), 10920) | |
} else { | |
ActVideoCall.type = 33 | |
ActVideoCall.username = username | |
App.appsFlyerEvent("Chat_Video_Call") | |
if (!preferenceInstance.readBoolean("accept_video_call")) | |
FragVideoCallAccept() { | |
startActivityForResult(Intent(ctx, ActVideoCall::class.java), 10920) | |
}.show(childFragmentManager, "anything") | |
else | |
startActivityForResult(Intent(ctx, ActVideoCall::class.java), 10920) | |
} | |
} | |
override fun onFailure(call: Call<NotificationSettingImpl>, t: Throwable) { loader?.dismiss() } | |
}) | |
} | |
private val clickListener = View.OnClickListener { | |
it.isEnabled = false | |
postDelayed({ | |
it.isEnabled = true | |
}, 300) | |
when (it) { | |
binding.back -> { | |
(ctx as ActHome).backPress() | |
} | |
binding.audioCall -> isCallAllow(true) | |
binding.videoCall -> isCallAllow(false) | |
binding.profile -> { | |
if (username == "spinny" || username == "spinnr") return@OnClickListener | |
val frag = FragProfileView() | |
frag.arguments = Bundle().apply { | |
putString("guid", guid) | |
putString("username", username) | |
} | |
(ctx as ActHome).navigateTo(frag) | |
} | |
binding.option -> { | |
BottomSheetDialog( | |
"Choose action", mutableListOf( | |
BottomSheetModel( | |
"Report Member", R.mipmap.img_report_member | |
), BottomSheetModel( | |
"Block Member", R.mipmap.img_block_member | |
) | |
) | |
) { i1 -> | |
if (i1 == 0) | |
showOptionDialog( | |
getString(R.string.report_person), | |
getString(R.string.report_person_desc) | |
) { i2 -> if (i2 == 1) reportUser() } | |
else if (i1 == 1) | |
showOptionDialog( | |
getString(R.string.block_person), getString(R.string.block_person_desc) | |
) { i2 -> if (i2 == 1) updateUserFlag("F") } | |
}.show(childFragmentManager, BottomSheetDialog::class.java.simpleName) | |
} | |
binding.gallery -> { | |
showBottomSheetOptionDialog( | |
mutableListOf( | |
getString(R.string.take_photo), | |
getString(R.string.photo_library), | |
) | |
) { a0 -> | |
if (a0 == 0) { | |
if (ContextCompat.checkSelfPermission( | |
ctx, | |
Manifest.permission.CAMERA | |
) == PackageManager.PERMISSION_DENIED | |
) { | |
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) || | |
preferenceInstance.readBoolean(FTP_CAMERA, TRUE) | |
) { | |
preferenceInstance.writeBoolean(FTP_CAMERA, FALSE) | |
(ctx as Activity).requestPermissions( | |
arrayOf(Manifest.permission.CAMERA), | |
3001 | |
) | |
} else { | |
showOptionDialog( | |
getString(R.string.permission_alert), | |
getString(R.string.capture_permission), | |
getString(R.string.cancel), | |
getString(R.string.setting) | |
) { z -> | |
if (z == 1) { | |
val i = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) | |
val uri = Uri.fromParts("package", ctx.packageName, null) | |
i.data = uri | |
startActivity(i) | |
} | |
} | |
} | |
return@showBottomSheetOptionDialog | |
} | |
val file = File("${ctx.cacheDir}/temp.jpeg") | |
val uri = FileProvider.getUriForFile(ctx, "com.app.spinnr.provider", file) | |
val i = Intent(MediaStore.ACTION_IMAGE_CAPTURE) | |
i.putExtra(MediaStore.EXTRA_OUTPUT, uri) | |
from = 1 | |
launcher.launch(i) | |
} else if (a0 == 1) { | |
from = 2 | |
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && | |
ContextCompat.checkSelfPermission( | |
ctx, Manifest.permission.READ_MEDIA_IMAGES | |
) != PackageManager.PERMISSION_GRANTED | |
) { | |
showOptionDialog( | |
getString(R.string.permission_alert), | |
getString(R.string.capture_permission), | |
getString(R.string.cancel), | |
getString(R.string.setting) | |
) { z -> | |
if (z == 1) { | |
val i = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) | |
val uri = Uri.fromParts("package", ctx.packageName, null) | |
i.data = uri | |
startActivity(i) | |
} | |
} | |
} else { | |
Louvre.init(this).setMaxSelection(10) | |
.setMediaTypeFilter(Louvre.IMAGE_TYPE_JPEG, Louvre.IMAGE_TYPE_PNG) | |
.setRequestCode(LOUVRE_REQUEST_CODE).open() | |
}*/ | |
Louvre.init(this).setMaxSelection(10) | |
.setMediaTypeFilter(Louvre.IMAGE_TYPE_JPEG, Louvre.IMAGE_TYPE_PNG) | |
.setRequestCode(LOUVRE_REQUEST_CODE).open() | |
} | |
} | |
} | |
binding.recordVideo -> { | |
BottomSheetDialog( | |
"Please select an option", | |
mutableListOf( | |
BottomSheetModel( | |
"Record Video", | |
R.mipmap.img_record_video, | |
), | |
BottomSheetModel( | |
"Video Library", | |
R.mipmap.img_choose_intro_video, | |
) | |
) | |
) { a0 -> | |
if (a0 == 0) { | |
val frag = FragCreateVideo { _, p -> | |
loader = showLoader() | |
uploadFile(p, "video") | |
}.apply { | |
arguments = Bundle().apply { | |
putString("category", "chat") | |
} | |
} | |
(ctx as ActHome).navigateTo(frag) | |
} else if (a0 == 1) { | |
from = 4 | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | |
//fromCamera = false | |
launcher.launch(Intent(MediaStore.ACTION_PICK_IMAGES).apply { | |
type = "video/*" | |
}) | |
} else { | |
if (ContextCompat.checkSelfPermission( | |
ctx, | |
Manifest.permission.READ_EXTERNAL_STORAGE | |
) != PackageManager.PERMISSION_GRANTED | |
) | |
showOptionDialog( | |
getString(R.string.permission_alert), | |
getString(R.string.capture_permission), | |
getString(R.string.cancel), | |
getString(R.string.setting) | |
) { z -> | |
if (z == 1) { | |
val i = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) | |
val uri = Uri.fromParts("package", ctx.packageName, null) | |
i.data = uri | |
startActivity(i) | |
} | |
} else | |
//fromCamera = false | |
launcher.launch(Intent(Intent.ACTION_GET_CONTENT).apply { | |
type = "video/*" | |
}) | |
} | |
} | |
}.show(childFragmentManager, BottomSheetDialog::class.java.simpleName) | |
} | |
binding.gif -> { | |
val settings = GPHSettings() | |
// Option to select only mentioned Content Types | |
settings.mediaTypeConfig = arrayOf(GPHContentType.gif) | |
// Option to select the default Content Type to open | |
settings.selectedContentType = GPHContentType.gif | |
settings.renditionType = RenditionType.downsizedSmall | |
settings.clipsPreviewRenditionType = RenditionType.downsizedLarge | |
settings.confirmationRenditionType = RenditionType.original | |
GPHContent.trending(MediaType.gif, RatingType.pg13) | |
giphyDialog = | |
GiphyDialogFragment.newInstance(settings.copy(selectedContentType = GPHContentType.gif)) | |
giphyDialog.gifSelectionListener = this.gifSelectionListener | |
giphyDialog.show(childFragmentManager, "giphy_dialog") | |
} | |
binding.recordAudio -> { | |
val frag = FragAudio(username) { a1, a2 -> | |
if (a1 == "result") { | |
loader = showLoader() | |
uploadFile(a2, "audio") | |
} | |
} | |
frag.show(childFragmentManager, FragAudio::class.java.simpleName) | |
} | |
binding.send -> { | |
if (binding.input.text.toString().isBlank()) return@OnClickListener | |
decodeMessageLink(binding.input.text.toString()) | |
} | |
} | |
} | |
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
if (requestCode == LOUVRE_REQUEST_CODE && resultCode == Activity.RESULT_OK) { | |
mSelection.clear() | |
mediaFiles.clear() | |
GalleryActivity.getSelection(data).also { mSelection = it } | |
if (mSelection.size > 1) { | |
loader = showLoader() | |
mSelection.forEach { uri -> | |
if (uri != null && !uri.path.isNullOrEmpty()) uploadFiles(uri.path!!) | |
} | |
} else if (mSelection.size == 1) { | |
mSelection[0].let { uri -> | |
loader = showLoader() | |
Thread { | |
try { | |
var bitmap = | |
BitmapFactory.decodeStream(ctx.contentResolver.openInputStream(uri!!)) | |
val cachePath = "${ctx.cacheDir}/temp.jpeg" | |
val path = UriHelper.getInstance(ctx).getPath(uri) ?: return@Thread | |
val exifOrientation = ExifInterface(path).getAttributeInt( | |
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL | |
) | |
val orientation = when (exifOrientation) { | |
ExifInterface.ORIENTATION_ROTATE_270 -> 270f | |
ExifInterface.ORIENTATION_ROTATE_180 -> 180f | |
ExifInterface.ORIENTATION_ROTATE_90 -> 90f | |
else -> 0f | |
} | |
val mat = Matrix() | |
mat.postRotate(orientation) | |
bitmap = Bitmap.createBitmap( | |
bitmap, 0, 0, bitmap.width, bitmap.height, mat, false | |
) | |
handler.post { | |
val frag = FragImageEditor(bitmap, false) { _, bitmap -> | |
loader = showLoader() | |
val fos = FileOutputStream(cachePath) | |
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos) | |
uploadFile(cachePath, "photo") | |
} | |
loader?.dismiss() | |
(ctx as ActHome).navigateTo(frag) | |
} | |
} catch (e: Exception) { | |
handler.post { | |
loader?.dismiss() | |
showSnackBar("${e.message}") | |
} | |
} | |
}.start() | |
} | |
} | |
return | |
} | |
if (requestCode == 10920 && resultCode == Activity.RESULT_OK) { | |
val userName = data?.getStringExtra(Preference.USERNAME) | |
val isDeclined = data?.getBooleanExtra("isDeclined", false) | |
val content = data?.getStringExtra("content") | |
sendMessage(content ?: "", "missedCall") | |
} | |
super.onActivityResult(requestCode, resultCode, data) | |
} | |
private val gifSelectionListener = object : GiphyDialogFragment.GifSelectionListener { | |
override fun didSearchTerm(term: String) { | |
} | |
override fun onDismissed(selectedContentType: GPHContentType) { | |
} | |
override fun onGifSelected( | |
media: Media, | |
searchTerm: String?, | |
selectedContentType: GPHContentType | |
) { | |
Log.i("TAG", "onGifSelected: ${media.images.downsizedLarge?.gifUrl}") | |
if (media.images.downsizedLarge?.gifUrl.isNullOrEmpty()) return | |
message = media.images.downsizedLarge?.gifUrl ?: "" | |
if (message.isEmpty()) return | |
message += "&ratio=${media.aspectRatio}" | |
linkThumb = message | |
sendMessage(message, "gif") | |
} | |
} | |
private val textChangeListener = object : TextWatcher { | |
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} | |
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} | |
override fun afterTextChanged(s: Editable?) { | |
if (s.toString().isNotEmpty()) | |
updateTyping(true) | |
typingTimer?.cancel() | |
typingTimer = object : CountDownTimer(2000, 1000) { | |
override fun onTick(millisUntilFinished: Long) {} | |
override fun onFinish() { | |
updateTyping(false) | |
} | |
}.start() | |
} | |
} | |
private fun reportUser() { | |
inputDialog( | |
desc = getString(R.string.reporting_reason_desc), | |
hint = getString(R.string.reason), | |
noBtn = getString(R.string.cancel), | |
yesBtn = getString(R.string.send), | |
enableEmoji = false | |
) { a0, a1 -> | |
if (a0 == "yes" && a1.isBlank()) | |
showOptionMessage(getString(R.string.reason_should_net_be_blank)) { reportUser() } | |
else if (a0 == "yes") | |
updateUserFlag("R", a1.trim()) | |
} | |
} | |
private fun updateUserFlag(type: String, desc: String = "") { | |
if (netNotConnected()) { | |
showSnackBar(getString(R.string.no_internet)) | |
return | |
} | |
loader = showLoader() | |
getClient() | |
.updateUserFlag( | |
GUID, | |
guid, type, desc | |
) | |
.enqueue(object : Callback<ResponseBean<ProfileModel>> { | |
override fun onResponse( | |
call: Call<ResponseBean<ProfileModel>>, | |
response: Response<ResponseBean<ProfileModel>> | |
) { | |
loader?.dismiss() | |
if (response.body()?.code == 0) | |
when (type) { | |
"R" -> { | |
subscriber?.remove() | |
detailSubscriber?.remove() | |
typingSubscriber?.remove() | |
Firebase | |
.firestore | |
.document("spinnr-chat/$collection/") | |
.update("isDeleted", true) | |
Firebase | |
.firestore | |
.collection("spinnr-chat/") | |
.document(collection) | |
.delete() | |
(ctx as ActHome).backPress() | |
App.appsFlyerEvent("Chat_Report") | |
showSnackBar(getString(R.string.successfully_reported_person)) | |
} | |
"F" -> { | |
subscriber?.remove() | |
detailSubscriber?.remove() | |
typingSubscriber?.remove() | |
Firebase | |
.firestore | |
.document("spinnr-chat/$collection/") | |
.update("isDeleted", true) | |
Firebase | |
.firestore | |
.collection("spinnr-chat/") | |
.document(collection) | |
.delete() | |
App.appsFlyerEvent("Chat_Block") | |
showSnackBar(getString(R.string.successfully_blocked_person)) | |
(ctx as ActHome).backPress() | |
} | |
} | |
else if (response.body()?.code == 1) | |
showSnackBar("${response.body()?.msg}") | |
} | |
override fun onFailure(call: Call<ResponseBean<ProfileModel>>, t: Throwable) { | |
loader?.dismiss() | |
} | |
}) | |
} | |
private val lickListsner = ScrollListener { id -> | |
val x = data.indexOfFirst { it.documentID == id } | |
if (x > -1 && x < data.size) | |
binding.rv.scrollToPosition(x) | |
} | |
private var replyMsg: MessageModel? = null | |
private val replyListener = ReplyListener { | |
replyMsg = it | |
binding.replyContainer.visibility = View.VISIBLE | |
binding.replyContainer.setBackgroundResource(if (it.username == USERNAME) R.mipmap.img_right_reply_bg else R.mipmap.img_left_reply_bg) | |
binding.replyOrigin.text = if (it.username == USERNAME) "You" else it.username | |
binding.replyContent.text = when (it.type) { | |
"gif" -> "\uD83C\uDFA5 GIF" | |
"video" -> "\uD83C\uDFA5 Video" | |
"photo" -> "\uD83D\uDCF7 Photo" | |
"groupMedia" -> "\uD83C\uDFA5 Media" | |
"audio" -> "\uD83C\uDFA4 Audio" | |
else -> it.text | |
} | |
binding.replyClose.setOnClickListener { | |
replyMsg = null | |
binding.replyContainer.visibility = View.GONE | |
} | |
if (it.type == "text" || it.type == "audio") { | |
binding.replyPreview.visibility = View.GONE | |
return@ReplyListener | |
} else { | |
binding.replyPreview.visibility = View.VISIBLE | |
when (it.type) { | |
"video" -> binding.replyPreview.load(it.thumb, 10f) | |
"photo" -> binding.replyPreview.load(it.content, 10f) | |
"gif" -> binding.replyPreview.load(it.linkThumb ?: it.text, 10f) | |
"groupMedia" -> binding.replyPreview.load( | |
it.mediaFiles[0]?.content, | |
10f | |
) | |
"eventInvite" -> binding.replyPreview.load(it.thumb, 10f) | |
"squadInvite" -> binding.replyPreview.load( | |
"${Constant.PROFILE_IMG_URL}${it.content}.jpeg", | |
10f | |
) | |
} | |
} | |
} | |
private val launcher = | |
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { | |
if (it == null || it.resultCode == Activity.RESULT_CANCELED) return@registerForActivityResult | |
if (from == 1) { | |
loader = showLoader() | |
Thread { | |
try { | |
val path = "${ctx.cacheDir}/temp.jpeg" | |
var bitmap = BitmapFactory.decodeFile(path) | |
val exifOrientation = ExifInterface(path).getAttributeInt( | |
ExifInterface.TAG_ORIENTATION, | |
ExifInterface.ORIENTATION_NORMAL | |
) | |
val orientation = when (exifOrientation) { | |
ExifInterface.ORIENTATION_ROTATE_270 -> 270f | |
ExifInterface.ORIENTATION_ROTATE_180 -> 180f | |
ExifInterface.ORIENTATION_ROTATE_90 -> 90f | |
else -> 0f | |
} | |
val mat = Matrix() | |
mat.postRotate(orientation) | |
bitmap = Bitmap.createBitmap( | |
bitmap, | |
0, | |
0, | |
bitmap.width, | |
bitmap.height, | |
mat, | |
false | |
) | |
handler.post { | |
val frag = FragImageEditor(bitmap, false) { _, bitmap -> | |
loader = showLoader() | |
val fos = FileOutputStream(path) | |
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos) | |
uploadFile(path, "photo") | |
} | |
loader?.dismiss() | |
(ctx as ActHome).navigateTo(frag) | |
} | |
} catch (e: Exception) { | |
handler.post { | |
loader?.dismiss() | |
showSnackBar("${e.message}") | |
} | |
} | |
}.start() | |
} else if (from == 2) { | |
it.data?.data?.let { uri -> | |
loader = showLoader() | |
Thread { | |
try { | |
var bitmap = | |
BitmapFactory.decodeStream(ctx.contentResolver.openInputStream(uri)) | |
val cachePath = "${ctx.cacheDir}/temp.jpeg" | |
val path = UriHelper.getInstance(ctx).getPath(uri) ?: return@Thread | |
val exifOrientation = ExifInterface(path).getAttributeInt( | |
ExifInterface.TAG_ORIENTATION, | |
ExifInterface.ORIENTATION_NORMAL | |
) | |
val orientation = when (exifOrientation) { | |
ExifInterface.ORIENTATION_ROTATE_270 -> 270f | |
ExifInterface.ORIENTATION_ROTATE_180 -> 180f | |
ExifInterface.ORIENTATION_ROTATE_90 -> 90f | |
else -> 0f | |
} | |
val mat = Matrix() | |
mat.postRotate(orientation) | |
bitmap = Bitmap.createBitmap( | |
bitmap, 0, 0, | |
bitmap.width, | |
bitmap.height, | |
mat, false | |
) | |
handler.post { | |
val frag = FragImageEditor(bitmap, false) { _, bitmap -> | |
loader = showLoader() | |
val fos = FileOutputStream(cachePath) | |
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos) | |
uploadFile(cachePath, "photo") | |
} | |
loader?.dismiss() | |
(ctx as ActHome).navigateTo(frag) | |
} | |
} catch (e: Exception) { | |
handler.post { | |
loader?.dismiss() | |
showSnackBar("${e.message}") | |
} | |
} | |
}.start() | |
} | |
} else if (from == 3 || from == 4) { | |
it.data?.data?.let { uri -> | |
Thread { | |
handler.post { | |
loader = showLoader() | |
} | |
val path = UriHelper.getInstance(ctx).getPath(uri) ?: return@Thread | |
val retriever = MediaMetadataRetriever() | |
retriever.setDataSource(path) | |
val length = | |
retriever.extractMetadata(METADATA_KEY_DURATION) ?: return@Thread | |
retriever.release() | |
val frag = FragTrimVideo { a1, a2 -> | |
if (a1 == "result") { | |
loader = showLoader() | |
uploadFile(a2, "video") | |
} | |
} | |
frag.arguments = Bundle().apply { | |
putString("category", "chat") | |
putString("path", path) | |
putLong("length", length.toLong()) | |
} | |
handler.post { | |
loader?.dismiss() | |
(ctx as ActHome).navigateTo(frag, true) | |
} | |
}.start() | |
} | |
} | |
} | |
private fun updateTyping(isTyping: Boolean) { | |
val data = mutableMapOf( | |
"username" to USERNAME, | |
"typing" to isTyping | |
) | |
if (collection.isNotBlank()) | |
Firebase | |
.firestore | |
.document("spinnr-chat/$collection/typing-info/$USERNAME") | |
.set(data) | |
} | |
private fun updateMessageCount(makeRead: Boolean = false, sender: String = "") { | |
if (sender == username && makeRead) | |
Firebase | |
.firestore | |
.document("spinnr-chat/$collection/") | |
.update("unreadCount.$USERNAME", 0) | |
else if (!makeRead) | |
Firebase | |
.firestore | |
.document("spinnr-chat/$collection/") | |
.update("unreadCount.${username}", unreadCount + 1) | |
} | |
private fun uploadFile(path: String, type: String) { | |
if (App.netNotConnected()) { | |
showSnackBar(getStr(R.string.no_internet)) | |
loader?.dismiss() | |
return | |
} | |
val name = System.currentTimeMillis().toString() | |
val ref = "$USERNAME/$name.${path.substringAfterLast(".")}" | |
Firebase | |
.storage | |
.getReference(ref) | |
.putStream(FileInputStream(path)) | |
.addOnSuccessListener { | |
Firebase | |
.storage | |
.getReference(ref) | |
.downloadUrl.addOnSuccessListener { | |
if (type == "video") | |
uploadThumb(path, name, "$it", ref) | |
else | |
sendMessage("$it", type, storageRef = ref) | |
} | |
} | |
.addOnCompleteListener { | |
if (type != "video") loader?.dismiss() | |
} | |
} | |
private fun uploadFiles(path: String) { | |
if (App.netNotConnected()) { | |
showSnackBar(getStr(R.string.no_internet)) | |
loader?.dismiss() | |
return | |
} | |
val name = System.currentTimeMillis().toString() | |
uploadedFilesReference = "$USERNAME/$name.${path.substringAfterLast("/")}" | |
val storageRef = Firebase.storage.getReference(uploadedFilesReference) | |
val uploadTask = storageRef.putStream(FileInputStream(path)) | |
uploadTask.addOnSuccessListener { | |
storageRef.downloadUrl.addOnSuccessListener { uri -> | |
Log.i("vi26", "uploadFiles: File $uri uploaded") | |
val mediaFile = MediaFile( | |
uploadedFilesReference, | |
"photo", | |
uri.toString() | |
) | |
synchronized(mediaFiles) { // Synchronize access to mediaFiles | |
mediaFiles.add(mediaFile) // Add at the correct index | |
} | |
filesUploadedCount++ | |
if (filesUploadedCount == mSelection.size) { | |
sendMessage("", "groupMedia", storageRef = uploadedFilesReference) | |
loader?.dismiss() | |
} | |
} | |
}.addOnFailureListener { exception -> | |
// Handle the failure here | |
Log.w("vi26", "uploadFiles: File upload failed: ${exception.localizedMessage}") | |
} | |
} | |
private fun uploadThumb(path: String, thumbName: String, content: String, storageRef: String) { | |
val thumb = MediaMetadataRetriever().apply { setDataSource(path) } | |
val bitmap = thumb.getFrameAtTime(1, MediaMetadataRetriever.OPTION_CLOSEST) | |
val ref = "$USERNAME/${thumbName}_VideoThumb.jpeg" | |
if (bitmap == null) { | |
sendMessage(content, "video") | |
loader?.dismiss() | |
return | |
} | |
val thumbPath = "${ctx.cacheDir}/temp.jpeg" | |
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, FileOutputStream(thumbPath)) | |
Firebase | |
.storage | |
.getReference(ref) | |
.putStream(FileInputStream(thumbPath)) | |
.addOnSuccessListener { | |
Firebase | |
.storage | |
.getReference(ref) | |
.downloadUrl.addOnSuccessListener { | |
sendMessage( | |
content, | |
"video", | |
thumb = "$it", | |
storageRef = storageRef, | |
storageThumbRef = ref | |
) | |
} | |
} | |
.addOnCompleteListener { | |
loader?.dismiss() | |
} | |
} | |
private var updateData = true | |
private fun autoMessageV2(body: String) { | |
val handler = Handler(Looper.getMainLooper()) | |
binding.send.isEnabled = false | |
binding.send.visibility = View.INVISIBLE | |
binding.spinnyMessage.visibility = View.VISIBLE | |
binding.spinny.visibility = View.VISIBLE | |
adapter.notifyItemChanged(data.size - 1) | |
Thread { | |
try { | |
val guid = guid | |
val username = username | |
val collection = collection | |
val connection = URL("https://spinnrweb.com:5555/api/ChatGPTWebAPIStream").openConnection() as HttpURLConnection | |
connection.requestMethod = "POST" | |
connection.setRequestProperty("Accept", "application/json") | |
connection.setRequestProperty("Content-Type", "application/json") | |
connection.doOutput = true | |
connection.outputStream.write("{\"question\": \"$body\"}".toByteArray()) | |
handler.post { loader?.dismiss() } | |
if (connection.responseCode == HttpURLConnection.HTTP_OK) { | |
val bytes = ByteArray(256) | |
var length: Int | |
val string = StringBuilder() | |
handler.post { | |
data.add(MessageModel("", guid, username, "text", System.currentTimeMillis(), tag = null, text = "")) | |
adapter.notifyItemInserted(data.size - 1) | |
binding.rv.post { binding.rv.scrollBy(0, 20) } | |
} | |
while (connection.inputStream.read(bytes, 0, bytes.size).also { length = it } != -1) { | |
val obj = JSONObject(String(bytes, 0, length)) | |
if (!obj.has("content")) continue | |
val value = obj.getString("content") | |
string.append(value) | |
handler.post { | |
try { | |
data[data.size - 1].text = string.toString() | |
adapter.notifyItemChanged(data.size - 1) | |
binding.rv.post { | |
val lastView = linearLayoutManager.findViewByPosition(data.size - 1) | |
if (lastView != null) { | |
val scrollY = lastView.bottom - binding.rv.height + lastView.height | |
binding.rv.scrollBy(0, scrollY) | |
} | |
} | |
}catch(e:Exception){} | |
} | |
} | |
handler.post { | |
if (context == null) { | |
val msgId = Firebase.firestore.collection("spinnr-chat/$collection/messages").document().id | |
val message = MessageModel(msgId, username, guid, "text", System.currentTimeMillis(), text = string.toString()) | |
Firebase.firestore.document("spinnr-chat/$collection/").update("unreadCount.${username}", FieldValue.increment(1)) | |
Firebase.firestore.document("spinnr-chat/$collection/messages/$msgId").set(message) | |
Firebase.firestore.document("spinnr-chat/$collection/").update("lastMessage", message) | |
} else { | |
updateData = false | |
binding.send.isEnabled = true | |
binding.send.visibility = View.VISIBLE | |
binding.spinnyMessage.visibility = View.GONE | |
binding.spinny.visibility = View.GONE | |
sendMessage(string.toString(), "text", false) | |
} | |
} | |
} else { handler.post { | |
showSnackBar(connection.responseMessage) | |
binding.send.isEnabled = true | |
binding.send.visibility = View.VISIBLE | |
binding.spinnyMessage.visibility = View.GONE | |
binding.spinny.visibility = View.GONE | |
loader?.dismiss() } | |
} | |
connection.disconnect() | |
} catch (e: Exception) { handler.post { | |
showSnackBar("${e.localizedMessage}") | |
binding.send.isEnabled = true | |
binding.send.visibility = View.VISIBLE | |
binding.spinnyMessage.visibility = View.GONE | |
binding.spinny.visibility = View.GONE | |
loader?.dismiss() } | |
} | |
}.start() | |
} | |
data class ChatGptQuestion(val question: String) | |
private fun autoMessageV1(body: String) { | |
loader = showLoader() | |
getClient() | |
.chatGpt( | |
"https://spinnrweb.com:5555/api/ChatGPTWebAPI", | |
ChatGptQuestion(body) | |
) | |
.enqueue(object : Callback<JsonElement> { | |
override fun onResponse(call: Call<JsonElement>, response: Response<JsonElement>) { | |
if (response.body()?.asJsonObject?.get("status")?.asString == "success") | |
sendMessage("${response.body()?.asJsonObject?.get("answer")?.asString}", "text", false) | |
else | |
showSnackBar("${response.body()?.asJsonObject?.get("reason")?.asString}") | |
loader?.dismiss() | |
} | |
override fun onFailure(call: Call<JsonElement>, t: Throwable) { | |
loader?.dismiss() | |
} | |
}) | |
} | |
fun reactionNotification(reaction: String) { | |
App.appsFlyerEvent("Chat_Reaction") | |
sendPush( | |
"", | |
guid, | |
15, | |
"New chat reaction", | |
"You have a new chat reaction $reaction from $USERNAME!", | |
collection, | |
topic = "/topics/$username-member-reaction" | |
) | |
} | |
fun getProfile() { | |
if (username == "spinnr" || username == "spinny" || username.isBlank()) { | |
loader?.dismiss() | |
return | |
} | |
getClient2().getProfile(username) | |
.enqueue(object : Callback<ResponseListBean<ProfileStatusModel>> { | |
override fun onResponse(call: Call<ResponseListBean<ProfileStatusModel>>, response: Response<ResponseListBean<ProfileStatusModel>>) { | |
loader?.dismiss() | |
postDelayed({ getProfile() }, 1500) | |
if (response.body()?.data?.first()?.statusid != "2" && !paused) | |
inactiveUser() | |
else | |
activateDialog?.dismiss() | |
} | |
override fun onFailure(call: Call<ResponseListBean<ProfileStatusModel>>, t: Throwable) { | |
loader?.dismiss() | |
postDelayed({ getProfile() }, 1500) | |
if (netConnected()) | |
(ctx as ActHome).backPress() | |
} | |
}) | |
} | |
private var activateDialog: Dialog? = null | |
private fun inactiveUser() { | |
if (context == null || activateDialog?.isShowing == true) return | |
val binding = DialogInactiveUserChatBinding.inflate(layoutInflater, null, false) | |
activateDialog = Dialog(requireContext()) | |
binding.noCollection.load(Constant.NO_COLLECTION_PICTURE, enableCache = true) | |
binding.close.setOnClickListener { | |
(ctx as ActHome).backPress() | |
activateDialog?.dismiss() | |
} | |
activateDialog?.setCancelable(false) | |
activateDialog?.setContentView(binding.root) | |
activateDialog?.window?.setLayout(-1, -1) | |
activateDialog?.window?.setBackgroundDrawable(null) | |
activateDialog?.show() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:paddingHorizontal="@dimen/dimen_10_dp" | |
android:paddingVertical="@dimen/dimen_6_dp" | |
tools:ignore="contentDescription"> | |
<LinearLayout | |
android:id="@+id/llMissedCall" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center_horizontal" | |
android:background="@drawable/bg_missed_call" | |
android:gravity="center_vertical" | |
android:orientation="horizontal" | |
android:visibility="gone"> | |
<LinearLayout | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:orientation="vertical" | |
android:paddingHorizontal="@dimen/dimen_12_dp" | |
android:paddingVertical="@dimen/dimen_5_dp"> | |
<TextView | |
android:id="@+id/missedCallTitle" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_medium" | |
android:layout_gravity="center_horizontal" | |
android:includeFontPadding="true" | |
android:layout_marginHorizontal="@dimen/dimen_5_dp" | |
android:textColor="@color/purpleDark" | |
android:textSize="14sp" /> | |
<TextView | |
android:id="@+id/missedCallTime" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:includeFontPadding="true" | |
android:layout_gravity="center_horizontal" | |
android:layout_marginHorizontal="@dimen/dimen_5_dp" | |
android:fontFamily="@font/hellix_regular" | |
android:textColor="@color/color_date_text" | |
android:textSize="13sp" /> | |
</LinearLayout> | |
</LinearLayout> | |
<LinearLayout | |
android:id="@+id/left" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical" | |
android:visibility="gone" | |
app:layout_constraintTop_toTopOf="parent"> | |
<LinearLayout | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content"> | |
<de.hdodenhof.circleimageview.CircleImageView | |
android:id="@+id/profile" | |
android:layout_width="@dimen/dimen_28_dp" | |
android:layout_height="@dimen/dimen_28_dp" | |
android:background="@drawable/circle_white" | |
android:backgroundTint="@color/grey" /> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/leftFrame" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginStart="@dimen/dimen_10_dp" | |
android:layout_marginEnd="@dimen/dimen_50_dp"> | |
<LinearLayout | |
android:id="@+id/leftFrame3" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:background="@drawable/bg_chat_left" | |
android:minWidth="@dimen/dimen_80_dp" | |
android:orientation="vertical" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent"> | |
<LinearLayout | |
android:id="@+id/leftReplyContainer" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginHorizontal="@dimen/dimen_5_dp" | |
android:layout_marginTop="@dimen/dimen_5_dp" | |
android:background="@mipmap/img_left_reply_bg" | |
android:orientation="horizontal" | |
android:paddingStart="@dimen/dimen_10_dp" | |
android:visibility="gone"> | |
<LinearLayout | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/leftReplyOrigin" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_medium" | |
android:maxLines="1" | |
android:textColor="@color/primaryDark" | |
android:textSize="16sp" /> | |
<TextView | |
android:id="@+id/leftReplyContent" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="@dimen/dimen_2_dp" | |
android:ellipsize="end" | |
android:fontFamily="@font/hellix_regular" | |
android:maxLines="2" | |
android:textColor="#CCFFFFFF" /> | |
</LinearLayout> | |
<FrameLayout | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp"> | |
<com.google.android.material.imageview.ShapeableImageView | |
android:id="@+id/leftReplyPreview" | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp" | |
android:scaleType="centerCrop" | |
android:visibility="gone" | |
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.DifferentCornerSize.PreviewImage" /> | |
<View | |
android:layout_width="@dimen/dimen_9_dp" | |
android:layout_height="@dimen/dimen_9_dp" | |
android:layout_gravity="end" | |
android:background="@color/white" | |
android:visibility="gone" /> | |
<ImageView | |
android:id="@+id/leftReplyClose" | |
android:layout_width="@dimen/dimen_25_dp" | |
android:layout_height="@dimen/dimen_25_dp" | |
android:layout_gravity="end" | |
android:paddingStart="@dimen/dimen_7_dp" | |
android:paddingBottom="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_close_bg" | |
android:visibility="gone" /> | |
</FrameLayout> | |
</LinearLayout> | |
<FrameLayout | |
android:id="@+id/leftFrame2" | |
android:layout_width="fill_parent" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center_vertical" | |
android:orientation="vertical"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/leftGifContainer" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:visibility="gone"> | |
<ImageView | |
android:id="@+id/ivLeftPoweredByGiphy" | |
android:layout_width="50dp" | |
android:layout_height="14dp" | |
android:layout_margin="@dimen/dimen_5_dp" | |
android:elevation="14dp" | |
android:src="@drawable/poweredbygiphy_100px" | |
app:layout_constraintEnd_toEndOf="@id/leftGif" | |
app:layout_constraintTop_toTopOf="@id/leftGif" /> | |
<com.giphy.sdk.ui.views.GPHMediaView | |
android:id="@+id/leftGif" | |
android:layout_width="210dp" | |
android:layout_height="140dp" | |
android:layout_margin="@dimen/dimen_10_dp" | |
android:elevation="4dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<TextView | |
android:id="@+id/leftGifLink" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:background="@color/pink2" | |
android:ellipsize="end" | |
android:fontFamily="@font/hellix_regular" | |
android:maxLines="1" | |
android:padding="@dimen/dimen_9_dp" | |
android:textColor="@color/white" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="@id/leftGif" | |
app:layout_constraintEnd_toEndOf="@id/leftGif" | |
app:layout_constraintStart_toStartOf="@id/leftGif" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<TextView | |
android:id="@+id/leftMsg" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_regular" | |
android:lineSpacingExtra="3.5dp" | |
android:padding="@dimen/dimen_9_dp" | |
android:text="@string/space" | |
android:textColor="#220b2a" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<LinearLayout | |
android:id="@+id/leftLinkPreviewContainer" | |
android:layout_width="@dimen/dimen_250_dp" | |
android:layout_height="wrap_content" | |
android:layout_marginVertical="@dimen/dimen_12_dp" | |
android:layout_marginStart="@dimen/dimen_12_dp" | |
android:layout_marginEnd="@dimen/dimen_8_dp" | |
android:gravity="center_vertical" | |
android:orientation="vertical" | |
android:visibility="gone" /> | |
</LinearLayout> | |
<FrameLayout | |
android:id="@+id/leftThumb2Container" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:layout_margin="@dimen/dimen_8_dp" | |
android:visibility="gone"> | |
<com.google.android.material.imageview.ShapeableImageView | |
android:id="@+id/leftThumb2" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_marginTop="@dimen/dimen_10_dp" | |
android:layout_marginEnd="@dimen/dimen_10_dp" | |
android:scaleType="centerCrop" | |
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.DifferentCornerSize.LeftImage" /> | |
</FrameLayout> | |
<androidx.cardview.widget.CardView | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_8_dp" | |
android:visibility="gone" | |
app:cardCornerRadius="@dimen/dimen_9_dp" | |
app:cardElevation="@dimen/dimen_0_dp"> | |
<ImageView | |
android:id="@+id/leftThumb1" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:scaleType="centerCrop" /> | |
</androidx.cardview.widget.CardView> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/leftMediaContainer" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginHorizontal="@dimen/dimen_8_dp" | |
android:layout_marginVertical="@dimen/dimen_4_dp" | |
android:visibility="gone"> | |
<androidx.cardview.widget.CardView | |
android:id="@+id/cvLeftThumbGroupMedia1" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_4_dp" | |
app:cardCornerRadius="@dimen/dimen_9_dp" | |
app:cardElevation="@dimen/dimen_0_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/cvLeftThumbGroupMedia2" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent"> | |
<ImageView | |
android:id="@+id/leftThumbGroupMedia1" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:scaleType="centerCrop" /> | |
</androidx.cardview.widget.CardView> | |
<androidx.cardview.widget.CardView | |
android:id="@+id/cvLeftThumbGroupMedia2" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_4_dp" | |
app:cardCornerRadius="@dimen/dimen_9_dp" | |
app:cardElevation="@dimen/dimen_0_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toEndOf="@id/cvLeftThumbGroupMedia1" | |
app:layout_constraintTop_toTopOf="parent"> | |
<ImageView | |
android:id="@+id/leftThumbGroupMedia2" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:scaleType="centerCrop" /> | |
</androidx.cardview.widget.CardView> | |
<TextView | |
android:id="@+id/leftGroupMediaCount" | |
android:layout_width="0dp" | |
android:layout_height="0dp" | |
android:background="@drawable/bg_media_count" | |
android:fontFamily="@font/hellix_bold" | |
android:gravity="center" | |
android:letterSpacing=".1" | |
android:textColor="@color/white" | |
android:textSize="18sp" | |
app:layout_constraintBottom_toBottomOf="@id/cvLeftThumbGroupMedia2" | |
app:layout_constraintEnd_toEndOf="@id/cvLeftThumbGroupMedia2" | |
app:layout_constraintStart_toStartOf="@id/cvLeftThumbGroupMedia2" | |
app:layout_constraintTop_toTopOf="@id/cvLeftThumbGroupMedia2" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<ImageView | |
android:id="@+id/leftVideoIcon" | |
android:layout_width="@dimen/dimen_30_dp" | |
android:layout_height="@dimen/dimen_30_dp" | |
android:layout_gravity="center" | |
android:src="@mipmap/img_play_hollow" | |
android:visibility="gone" | |
app:tint="@color/white" /> | |
<LinearLayout | |
android:id="@+id/leftAudio" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center_vertical" | |
android:paddingVertical="@dimen/dimen_12_dp" | |
android:paddingStart="@dimen/dimen_12_dp" | |
android:paddingEnd="@dimen/dimen_8_dp" | |
android:visibility="gone"> | |
<ImageView | |
android:layout_width="@dimen/dimen_22_dp" | |
android:layout_height="@dimen/dimen_22_dp" | |
android:layout_gravity="center_vertical" | |
android:src="@mipmap/img_play_hollow" | |
app:tint="@color/purpleDark" /> | |
<View | |
android:layout_width="@dimen/dimen_22_dp" | |
android:layout_height="@dimen/dimen_22_dp" | |
android:layout_marginStart="@dimen/dimen_4_dp" | |
android:background="@drawable/circle_white" | |
android:backgroundTint="@color/purpleDark" | |
android:elevation="@dimen/dimen_1_dp" /> | |
<View | |
android:layout_width="@dimen/dimen_115_dp" | |
android:layout_height="@dimen/dimen_4_dp" | |
android:layout_marginStart="-4dp" | |
android:background="@drawable/audio_line" /> | |
</LinearLayout> | |
</FrameLayout> | |
</LinearLayout> | |
<LinearLayout | |
android:id="@+id/leftReaction" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:elevation="@dimen/dimen_2_dp" | |
android:paddingHorizontal="@dimen/dimen_10_dp" | |
android:paddingTop="@dimen/dimen_10_dp" | |
android:paddingBottom="@dimen/dimen_5_dp" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="@id/leftFrame3" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="1" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/leftFrame3"> | |
<TextView | |
android:id="@+id/leftReactionText" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:background="@drawable/reaction_bg" | |
android:fontFamily="@font/hellix_medium" | |
android:letterSpacing=".1" | |
android:padding="@dimen/dimen_2_dp" | |
android:textColor="@color/reaction_count_color" | |
android:textSize="14sp" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/leftLike" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_like" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/leftLove" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_heart" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/leftHappy" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_happy" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/leftWow" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_surprise" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/leftSad" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_sad" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/leftAngry" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_angry" /> | |
</LinearLayout> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</LinearLayout> | |
<TextView | |
android:id="@+id/leftTime" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginStart="@dimen/dimen_38_dp" | |
android:layout_marginTop="@dimen/dimen_5_dp" | |
android:fontFamily="@font/hellix_regular" | |
android:textColor="@color/color_date_text" | |
android:textSize="12sp" /> | |
</LinearLayout> | |
<LinearLayout | |
android:id="@+id/right" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="end" | |
android:orientation="vertical" | |
android:visibility="visible" | |
app:layout_constraintTop_toTopOf="parent"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/rightFrame" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginStart="@dimen/dimen_55_dp"> | |
<LinearLayout | |
android:id="@+id/rightFrame3" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:background="@drawable/bg_chat_right" | |
android:minWidth="@dimen/dimen_80_dp" | |
android:orientation="vertical" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="1" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent"> | |
<LinearLayout | |
android:id="@+id/rightReplyContainer" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginHorizontal="@dimen/dimen_5_dp" | |
android:layout_marginTop="@dimen/dimen_5_dp" | |
android:background="@mipmap/img_right_reply_bg" | |
android:paddingStart="@dimen/dimen_10_dp" | |
android:visibility="gone"> | |
<LinearLayout | |
android:layout_width="@dimen/dimen_0_dp" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center_vertical" | |
android:layout_weight="1" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/rightReplyOrigin" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_medium" | |
android:maxLines="1" | |
android:text="You" | |
android:textColor="@color/purpleDark" | |
android:textSize="16sp" /> | |
<TextView | |
android:id="@+id/rightReplyContent" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="@dimen/dimen_2_dp" | |
android:ellipsize="end" | |
android:fontFamily="@font/hellix_regular" | |
android:maxLines="2" | |
android:textColor="@color/white" /> | |
</LinearLayout> | |
<FrameLayout | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp"> | |
<com.google.android.material.imageview.ShapeableImageView | |
android:id="@+id/rightReplyPreview" | |
android:layout_width="@dimen/dimen_47_dp" | |
android:layout_height="@dimen/dimen_47_dp" | |
android:scaleType="centerCrop" | |
android:visibility="gone" | |
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.DifferentCornerSize.PreviewImage" /> | |
<View | |
android:layout_width="@dimen/dimen_9_dp" | |
android:layout_height="@dimen/dimen_9_dp" | |
android:layout_gravity="end" | |
android:background="@color/white" | |
android:visibility="gone" /> | |
<ImageView | |
android:id="@+id/rightReplyClose" | |
android:layout_width="@dimen/dimen_25_dp" | |
android:layout_height="@dimen/dimen_25_dp" | |
android:layout_gravity="end" | |
android:paddingStart="@dimen/dimen_7_dp" | |
android:paddingBottom="@dimen/dimen_7_dp" | |
android:src="@mipmap/img_close_bg" | |
android:visibility="gone" /> | |
</FrameLayout> | |
</LinearLayout> | |
<FrameLayout | |
android:id="@+id/rightFrame2" | |
android:layout_width="fill_parent" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center_vertical" | |
android:orientation="vertical"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/rightGifContainer" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:visibility="gone"> | |
<ImageView | |
android:id="@+id/ivRightPoweredByGiphy" | |
android:layout_width="50dp" | |
android:layout_height="14dp" | |
android:layout_margin="@dimen/dimen_5_dp" | |
android:elevation="14dp" | |
android:src="@drawable/poweredbygiphy_100px" | |
app:layout_constraintEnd_toEndOf="@id/rightGif" | |
app:layout_constraintTop_toTopOf="@id/rightGif" /> | |
<com.giphy.sdk.ui.views.GPHMediaView | |
android:id="@+id/rightGif" | |
android:layout_width="210dp" | |
android:layout_height="140dp" | |
android:layout_margin="@dimen/dimen_10_dp" | |
android:elevation="4dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<TextView | |
android:id="@+id/rightGifLink" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:background="@color/pink2" | |
android:elevation="14dp" | |
android:ellipsize="end" | |
android:fontFamily="@font/hellix_regular" | |
android:maxLines="1" | |
android:padding="@dimen/dimen_9_dp" | |
android:textColor="@color/white" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="@id/rightGif" | |
app:layout_constraintEnd_toEndOf="@id/rightGif" | |
app:layout_constraintStart_toStartOf="@id/rightGif" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<TextView | |
android:id="@+id/rightMsg" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:fontFamily="@font/hellix_regular" | |
android:lineSpacingExtra="3.5dp" | |
android:padding="@dimen/dimen_9_dp" | |
android:text="@string/space" | |
android:textColor="@color/white" /> | |
<LinearLayout | |
android:id="@+id/rightLinkPreviewContainer" | |
android:layout_width="@dimen/dimen_230_dp" | |
android:layout_height="wrap_content" | |
android:layout_marginVertical="@dimen/dimen_12_dp" | |
android:layout_marginStart="@dimen/dimen_8_dp" | |
android:layout_marginEnd="@dimen/dimen_12_dp" | |
android:gravity="center_vertical" | |
android:orientation="vertical" | |
android:visibility="gone" /> | |
</LinearLayout> | |
<FrameLayout | |
android:id="@+id/rightThumb2Container" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:layout_margin="@dimen/dimen_8_dp" | |
android:visibility="gone"> | |
<com.google.android.material.imageview.ShapeableImageView | |
android:id="@+id/rightThumb2" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_marginStart="@dimen/dimen_10_dp" | |
android:layout_marginTop="@dimen/dimen_10_dp" | |
android:scaleType="centerCrop" | |
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.DifferentCornerSize.RightImage" /> | |
</FrameLayout> | |
<androidx.cardview.widget.CardView | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_8_dp" | |
android:visibility="gone" | |
app:cardCornerRadius="@dimen/dimen_9_dp" | |
app:cardElevation="@dimen/dimen_0_dp"> | |
<ImageView | |
android:id="@+id/rightThumb1" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:scaleType="centerCrop" /> | |
</androidx.cardview.widget.CardView> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/rightMediaContainer" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginHorizontal="@dimen/dimen_8_dp" | |
android:layout_marginVertical="@dimen/dimen_4_dp" | |
android:visibility="gone"> | |
<androidx.cardview.widget.CardView | |
android:id="@+id/cvRightThumbGroupMedia1" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_4_dp" | |
app:cardCornerRadius="@dimen/dimen_9_dp" | |
app:cardElevation="@dimen/dimen_0_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@id/cvRightThumbGroupMedia2" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent"> | |
<ImageView | |
android:id="@+id/rightThumbGroupMedia1" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:scaleType="centerCrop" /> | |
</androidx.cardview.widget.CardView> | |
<androidx.cardview.widget.CardView | |
android:id="@+id/cvRightThumbGroupMedia2" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="@dimen/dimen_4_dp" | |
app:cardCornerRadius="@dimen/dimen_9_dp" | |
app:cardElevation="@dimen/dimen_0_dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toEndOf="@id/cvRightThumbGroupMedia1" | |
app:layout_constraintTop_toTopOf="parent"> | |
<ImageView | |
android:id="@+id/rightThumbGroupMedia2" | |
android:layout_width="@dimen/dimen_135_dp" | |
android:layout_height="@dimen/dimen_100_dp" | |
android:scaleType="centerCrop" /> | |
</androidx.cardview.widget.CardView> | |
<TextView | |
android:id="@+id/rightGroupMediaCount" | |
android:layout_width="0dp" | |
android:layout_height="0dp" | |
android:background="@drawable/bg_media_count" | |
android:fontFamily="@font/hellix_bold" | |
android:gravity="center" | |
android:letterSpacing=".1" | |
android:textColor="@color/white" | |
android:textSize="18sp" | |
app:layout_constraintBottom_toBottomOf="@id/cvRightThumbGroupMedia2" | |
app:layout_constraintEnd_toEndOf="@id/cvRightThumbGroupMedia2" | |
app:layout_constraintStart_toStartOf="@id/cvRightThumbGroupMedia2" | |
app:layout_constraintTop_toTopOf="@id/cvRightThumbGroupMedia2" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<ImageView | |
android:id="@+id/rightVideoIcon" | |
android:layout_width="@dimen/dimen_30_dp" | |
android:layout_height="@dimen/dimen_30_dp" | |
android:layout_gravity="center" | |
android:src="@mipmap/img_play_hollow" | |
android:visibility="gone" | |
app:tint="@color/white" /> | |
<LinearLayout | |
android:id="@+id/rightAudio" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center_vertical" | |
android:paddingVertical="@dimen/dimen_12_dp" | |
android:paddingStart="@dimen/dimen_12_dp" | |
android:paddingEnd="@dimen/dimen_8_dp" | |
android:visibility="gone"> | |
<ImageView | |
android:layout_width="@dimen/dimen_22_dp" | |
android:layout_height="@dimen/dimen_22_dp" | |
android:layout_gravity="center_vertical" | |
android:src="@mipmap/img_play_hollow" | |
app:tint="@color/white" /> | |
<View | |
android:layout_width="@dimen/dimen_22_dp" | |
android:layout_height="@dimen/dimen_22_dp" | |
android:layout_marginStart="@dimen/dimen_4_dp" | |
android:background="@drawable/circle_white" | |
android:elevation="@dimen/dimen_1_dp" /> | |
<View | |
android:layout_width="@dimen/dimen_115_dp" | |
android:layout_height="@dimen/dimen_4_dp" | |
android:layout_marginStart="-4dp" | |
android:background="@drawable/audio_line" | |
android:backgroundTint="#B3FFFFFF" /> | |
</LinearLayout> | |
</FrameLayout> | |
</LinearLayout> | |
<LinearLayout | |
android:id="@+id/rightReaction" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:elevation="@dimen/dimen_2_dp" | |
android:paddingHorizontal="@dimen/dimen_10_dp" | |
android:paddingTop="@dimen/dimen_10_dp" | |
android:paddingBottom="@dimen/dimen_5_dp" | |
android:visibility="gone" | |
app:layout_constraintBottom_toBottomOf="@id/rightFrame3" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/rightFrame3"> | |
<TextView | |
android:id="@+id/rightReactionText" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:background="@drawable/reaction_bg" | |
android:fontFamily="@font/hellix_medium" | |
android:letterSpacing=".1" | |
android:padding="@dimen/dimen_2_dp" | |
android:textColor="@color/reaction_count_color" | |
android:textSize="14sp" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/rightLike" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_like" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/rightLove" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_heart" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/rightHappy" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_happy" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/rightWow" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_surprise" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/rightSad" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_sad" /> | |
<dev.leonardpark.emoji.emojicompat.EmojiImageView | |
android:id="@+id/rightAngry" | |
android:layout_width="@dimen/dimen_18_dp" | |
android:layout_height="@dimen/dimen_18_dp" | |
android:layout_marginHorizontal="@dimen/dimen_1_dp" | |
android:src="@drawable/ic_angry" /> | |
</LinearLayout> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
<TextView | |
android:id="@+id/rightTime" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="@dimen/dimen_5_dp" | |
android:fontFamily="@font/hellix_regular" | |
android:textColor="@color/color_date_text" | |
android:textSize="12sp" /> | |
</LinearLayout> | |
</FrameLayout> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment