mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-12 06:43:39 +00:00
Add mention candidates view
This commit is contained in:
parent
7c3b1b22d7
commit
efc752e3a1
@ -6,13 +6,11 @@ import android.content.res.Resources
|
||||
import android.database.Cursor
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.ActionMode
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.marginBottom
|
||||
import androidx.loader.app.LoaderManager
|
||||
import androidx.loader.content.Loader
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@ -23,15 +21,17 @@ import kotlinx.android.synthetic.main.view_input_bar.view.*
|
||||
import kotlinx.android.synthetic.main.view_input_bar_recording.*
|
||||
import kotlinx.android.synthetic.main.view_input_bar_recording.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.messaging.mentions.MentionsManager
|
||||
import org.session.libsession.messaging.mentions.MentionsManager.getMentionCandidates
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton
|
||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
|
||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarRecordingViewDelegate
|
||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.mentions.MentionCandidatesView
|
||||
import org.thoughtcrime.securesms.conversation.v2.menus.ConversationActionModeCallback
|
||||
import org.thoughtcrime.securesms.conversation.v2.menus.ConversationMenuHelper
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.loki.utilities.toDp
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import kotlin.math.abs
|
||||
@ -152,9 +152,15 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
|
||||
// region Updating
|
||||
override fun inputBarHeightChanged(newValue: Int) {
|
||||
// Recycler view
|
||||
val recyclerViewLayoutParams = conversationRecyclerView.layoutParams as RelativeLayout.LayoutParams
|
||||
recyclerViewLayoutParams.bottomMargin = newValue
|
||||
recyclerViewLayoutParams.bottomMargin = newValue + inputBarAdditionalContentContainer.height
|
||||
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
|
||||
// Input bar additional content container
|
||||
val inputBarAdditionalContentContainerLayoutParams = inputBarAdditionalContentContainer.layoutParams as RelativeLayout.LayoutParams
|
||||
inputBarAdditionalContentContainerLayoutParams.bottomMargin = newValue
|
||||
inputBarAdditionalContentContainer.layoutParams = inputBarAdditionalContentContainerLayoutParams
|
||||
// Attachment options
|
||||
val attachmentButtonHeight = inputBar.attachmentsButtonContainer.height
|
||||
val bottomMargin = (newValue - attachmentButtonHeight) / 2
|
||||
val margin = toPx(8, resources)
|
||||
@ -163,6 +169,22 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
attachmentOptionsContainer.layoutParams = attachmentOptionsContainerLayoutParams
|
||||
}
|
||||
|
||||
override fun inputBarEditTextContentChanged(newContent: CharSequence) {
|
||||
// TODO: Work this out further
|
||||
if (newContent.contains("@")) {
|
||||
showMentionCandidates()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showMentionCandidates() {
|
||||
inputBarAdditionalContentContainer.removeAllViews()
|
||||
val mentionCandidatesView = MentionCandidatesView(this)
|
||||
mentionCandidatesView.glide = glide
|
||||
inputBarAdditionalContentContainer.addView(mentionCandidatesView)
|
||||
val mentionCandidates = MentionsManager.getMentionCandidates("", threadID, thread.isOpenGroupRecipient)
|
||||
mentionCandidatesView.show(mentionCandidates, threadID)
|
||||
}
|
||||
|
||||
override fun toggleAttachmentOptions() {
|
||||
val targetAlpha = if (isShowingAttachmentOptions) 0.0f else 1.0f
|
||||
val allButtons = listOf( cameraButtonContainer, libraryButtonContainer, documentButtonContainer, gifButtonContainer)
|
||||
|
@ -52,6 +52,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate {
|
||||
override fun inputBarEditTextContentChanged(text: CharSequence) {
|
||||
sendButton.isVisible = text.isNotEmpty()
|
||||
microphoneButton.isVisible = text.isEmpty()
|
||||
delegate?.inputBarEditTextContentChanged(text)
|
||||
}
|
||||
|
||||
override fun inputBarEditTextHeightChanged(newValue: Int) {
|
||||
@ -76,6 +77,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate {
|
||||
interface InputBarDelegate {
|
||||
|
||||
fun inputBarHeightChanged(newValue: Int)
|
||||
fun inputBarEditTextContentChanged(newContent: CharSequence)
|
||||
fun toggleAttachmentOptions()
|
||||
fun showVoiceMessageUI()
|
||||
fun onMicrophoneButtonMove(event: MotionEvent)
|
||||
|
@ -0,0 +1,47 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.input_bar.mentions
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import kotlinx.android.synthetic.main.view_mention_candidate.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.messaging.mentions.Mention
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
|
||||
class MentionCandidateView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : RelativeLayout(context, attrs, defStyleAttr) {
|
||||
var candidate = Mention("", "")
|
||||
set(newValue) { field = newValue; update() }
|
||||
var glide: GlideRequests? = null
|
||||
var openGroupServer: String? = null
|
||||
var openGroupRoom: String? = null
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
constructor(context: Context) : this(context, null)
|
||||
|
||||
companion object {
|
||||
|
||||
fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup): MentionCandidateView {
|
||||
return layoutInflater.inflate(R.layout.view_mention_candidate_v2, parent, false) as MentionCandidateView
|
||||
}
|
||||
}
|
||||
|
||||
private fun update() {
|
||||
mentionCandidateNameTextView.text = candidate.displayName
|
||||
profilePictureView.publicKey = candidate.publicKey
|
||||
profilePictureView.displayName = candidate.displayName
|
||||
profilePictureView.additionalPublicKey = null
|
||||
profilePictureView.glide = glide!!
|
||||
profilePictureView.update()
|
||||
if (openGroupServer != null && openGroupRoom != null) {
|
||||
val isUserModerator = OpenGroupAPIV2.isUserModerator(candidate.publicKey, openGroupRoom!!, openGroupServer!!)
|
||||
moderatorIconImageView.visibility = if (isUserModerator) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
moderatorIconImageView.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.input_bar.mentions
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.ListView
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.session.libsession.messaging.mentions.Mention
|
||||
|
||||
class MentionCandidatesView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) {
|
||||
private var candidates = listOf<Mention>()
|
||||
set(newValue) { field = newValue; snAdapter.mentionCandidates = newValue }
|
||||
var glide: GlideRequests? = null
|
||||
set(newValue) { field = newValue; snAdapter.glide = newValue }
|
||||
var openGroupServer: String? = null
|
||||
set(newValue) { field = newValue; snAdapter.openGroupServer = openGroupServer }
|
||||
var openGroupRoom: String? = null
|
||||
set(newValue) { field = newValue; snAdapter.openGroupRoom = openGroupRoom }
|
||||
var onCandidateSelected: ((Mention) -> Unit)? = null
|
||||
|
||||
private val snAdapter by lazy { Adapter(context) }
|
||||
|
||||
private class Adapter(private val context: Context) : BaseAdapter() {
|
||||
var mentionCandidates = listOf<Mention>()
|
||||
set(newValue) { field = newValue; notifyDataSetChanged() }
|
||||
var glide: GlideRequests? = null
|
||||
var openGroupServer: String? = null
|
||||
var openGroupRoom: String? = null
|
||||
|
||||
override fun getCount(): Int { return mentionCandidates.count() }
|
||||
override fun getItemId(position: Int): Long { return position.toLong() }
|
||||
override fun getItem(position: Int): Mention { return mentionCandidates[position] }
|
||||
|
||||
override fun getView(position: Int, cellToBeReused: View?, parent: ViewGroup): View {
|
||||
val cell = cellToBeReused as MentionCandidateView? ?: MentionCandidateView.inflate(LayoutInflater.from(context), parent)
|
||||
val mentionCandidate = getItem(position)
|
||||
cell.glide = glide
|
||||
cell.candidate = mentionCandidate
|
||||
cell.openGroupServer = openGroupServer
|
||||
cell.openGroupRoom = openGroupRoom
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
constructor(context: Context) : this(context, null)
|
||||
|
||||
init {
|
||||
clipToOutline = true
|
||||
adapter = snAdapter
|
||||
snAdapter.mentionCandidates = candidates
|
||||
setOnItemClickListener { _, _, position, _ ->
|
||||
onCandidateSelected?.invoke(candidates[position])
|
||||
}
|
||||
}
|
||||
|
||||
fun show(mentionCandidates: List<Mention>, threadID: Long) {
|
||||
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID)
|
||||
if (openGroup != null) {
|
||||
openGroupServer = openGroup.server
|
||||
openGroupRoom = openGroup.room
|
||||
}
|
||||
this.candidates = mentionCandidates
|
||||
val layoutParams = this.layoutParams as ViewGroup.LayoutParams
|
||||
layoutParams.height = toPx(Math.min(mentionCandidates.count(), 4) * 44, resources)
|
||||
this.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
val layoutParams = this.layoutParams as ViewGroup.LayoutParams
|
||||
layoutParams.height = 0
|
||||
this.layoutParams = layoutParams
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ class MentionCandidateView(context: Context, attrs: AttributeSet?, defStyleAttr:
|
||||
}
|
||||
|
||||
private fun update() {
|
||||
btnGroupNameDisplay.text = mentionCandidate.displayName
|
||||
mentionCandidateNameTextView.text = mentionCandidate.displayName
|
||||
profilePictureView.publicKey = mentionCandidate.publicKey
|
||||
profilePictureView.displayName = mentionCandidate.displayName
|
||||
profilePictureView.additionalPublicKey = null
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/cell_selected">
|
||||
android:color="@color/mention_candidates_view_background_ripple">
|
||||
|
||||
<item>
|
||||
<color android:color="@color/compose_view_background" />
|
||||
<color android:color="@color/mention_candidates_view_background" />
|
||||
</item>
|
||||
</ripple>
|
@ -18,6 +18,13 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/inputBarAdditionalContentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="@dimen/input_bar_height" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/attachmentOptionsContainer"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -30,7 +30,7 @@
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnGroupNameDisplay"
|
||||
android:id="@+id/mentionCandidateNameTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
|
54
app/src/main/res/layout/view_mention_candidate_v2.xml
Normal file
54
app/src/main/res/layout/view_mention_candidate_v2.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.conversation.v2.input_bar.mentions.MentionCandidateView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="44dp"
|
||||
android:background="@drawable/mention_candidate_view_background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="@dimen/medium_spacing"
|
||||
android:paddingEnd="@dimen/medium_spacing"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="32dp">
|
||||
|
||||
<org.thoughtcrime.securesms.loki.views.ProfilePictureView
|
||||
android:id="@+id/profilePictureView"
|
||||
android:layout_width="@dimen/very_small_profile_picture_size"
|
||||
android:layout_height="@dimen/very_small_profile_picture_size"
|
||||
android:layout_marginTop="3dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/moderatorIconImageView"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:src="@drawable/ic_crown"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mentionCandidateNameTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textColor="@color/text"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@color/separator" />
|
||||
|
||||
</org.thoughtcrime.securesms.conversation.v2.input_bar.mentions.MentionCandidateView>
|
@ -10,7 +10,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:textColor="@color/text"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textSize="@dimen/very_small_font_size"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center" />
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
<color name="input_bar_button_background_opaque_border">#33000000</color>
|
||||
<color name="input_bar_lock_view_background">#FCFCFC</color>
|
||||
<color name="input_bar_lock_view_border">#66000000</color>
|
||||
<color name="mention_candidates_view_background">#FCFCFC</color>
|
||||
<color name="mention_candidates_view_background_ripple">#DFDFDF</color>
|
||||
|
||||
<color name="default_background_start">#ffffff</color>
|
||||
<color name="default_background_end">#fcfcfc</color>
|
||||
|
@ -33,6 +33,8 @@
|
||||
<color name="input_bar_button_background_opaque_border">#33FFFFFF</color>
|
||||
<color name="input_bar_lock_view_background">#171717</color>
|
||||
<color name="input_bar_lock_view_border">#66FFFFFF</color>
|
||||
<color name="mention_candidates_view_background">#171717</color>
|
||||
<color name="mention_candidates_view_background_ripple">#0C0C0C</color>
|
||||
|
||||
<array name="profile_picture_placeholder_colors">
|
||||
<item>#5ff8b0</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user