pull/58/head
Niels Andriesse 5 years ago
parent f4360bddc7
commit 5f1fe4da68

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/cell_selected">
<item>
<color android:color="@color/compose_view_background" />
</item>
</ripple>

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.loki.MentionCandidateSelectionViewCell
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="52dp"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center_vertical"
android:background="?attr/conversation_list_item_background">
<RelativeLayout
android:layout_width="36dp"
android:layout_height="38dp"
android:layout_marginTop="1dp">
<!-- The frame layout below is a workaround for an avatar image view bug -->
<FrameLayout
android:id="@+id/profilePictureImageViewContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/profilePictureImageView"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginBottom="2dp" />
</FrameLayout>
<ImageView
android:id="@+id/moderatorIconImageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginEnd="1.5dp"
android:src="@drawable/icon_crown"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
<TextView
android:id="@+id/displayNameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
style="@style/Signal.Text.Body"
android:ellipsize="end" />
</org.thoughtcrime.securesms.loki.MentionCandidateSelectionViewCell>

@ -126,7 +126,26 @@
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false"> android:clipToPadding="false">
<include layout="@layout/view_mention_candidate_selection" /> <LinearLayout
android:id="@+id/mentionCandidateSelectionViewContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<include layout="@layout/view_mention_candidate_selection" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
</LinearLayout>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="44dp"
android:orientation="horizontal"
android:paddingStart="@dimen/medium_spacing"
android:paddingEnd="@dimen/medium_spacing"
android:gravity="center_vertical"
android:background="@drawable/mention_candidate_view_background">
<RelativeLayout
android:layout_width="26dp"
android:layout_height="32dp">
<org.thoughtcrime.securesms.loki.redesign.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/icon_crown"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
<TextView
android:id="@+id/displayNameTextView"
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" />
</org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateView>

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.loki.MentionCandidateSelectionView <org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateSelectionView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/userSelectionView" android:id="@+id/userSelectionView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:paddingTop="6dp"
android:listSelector="@color/transparent" /> android:listSelector="@color/transparent" />

@ -15,6 +15,7 @@
<dimen name="small_button_height">34dp</dimen> <dimen name="small_button_height">34dp</dimen>
<dimen name="medium_button_height">44dp</dimen> <dimen name="medium_button_height">44dp</dimen>
<dimen name="accent_line_thickness">4dp</dimen> <dimen name="accent_line_thickness">4dp</dimen>
<dimen name="very_small_profile_picture_size">26dp</dimen>
<dimen name="small_profile_picture_size">36dp</dimen> <dimen name="small_profile_picture_size">36dp</dimen>
<dimen name="medium_profile_picture_size">46dp</dimen> <dimen name="medium_profile_picture_size">46dp</dimen>
<dimen name="large_profile_picture_size">76dp</dimen> <dimen name="large_profile_picture_size">76dp</dimen>

@ -159,7 +159,7 @@ import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate; import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate;
import org.thoughtcrime.securesms.loki.LokiUserDatabase; import org.thoughtcrime.securesms.loki.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.MentionCandidateSelectionView; import org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateSelectionView;
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate; import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
@ -355,6 +355,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private String messageStatus = null; private String messageStatus = null;
// Mentions // Mentions
private View mentionCandidateSelectionViewContainer;
private MentionCandidateSelectionView mentionCandidateSelectionView; private MentionCandidateSelectionView mentionCandidateSelectionView;
private int currentMentionStartIndex = -1; private int currentMentionStartIndex = -1;
private ArrayList<Mention> mentions = new ArrayList<>(); private ArrayList<Mention> mentions = new ArrayList<>();
@ -420,6 +421,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} }
composeText.setSelection(composeText.length(), composeText.length()); composeText.setSelection(composeText.length(), composeText.length());
composeText.addTextChangedListener(mentionTextWatcher); composeText.addTextChangedListener(mentionTextWatcher);
mentionCandidateSelectionView.setGlide(glideRequests);
mentionCandidateSelectionView.setOnMentionCandidateSelected( mentionCandidate -> { mentionCandidateSelectionView.setOnMentionCandidateSelected( mentionCandidate -> {
mentions.add(mentionCandidate); mentions.add(mentionCandidate);
String oldText = composeText.getText().toString(); String oldText = composeText.getText().toString();
@ -1617,6 +1619,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
inlineAttachmentToggle = ViewUtil.findById(this, R.id.inline_attachment_container); inlineAttachmentToggle = ViewUtil.findById(this, R.id.inline_attachment_container);
inputPanel = ViewUtil.findById(this, R.id.bottom_panel); inputPanel = ViewUtil.findById(this, R.id.bottom_panel);
searchNav = ViewUtil.findById(this, R.id.conversation_search_nav); searchNav = ViewUtil.findById(this, R.id.conversation_search_nav);
mentionCandidateSelectionViewContainer = ViewUtil.findById(this, R.id.mentionCandidateSelectionViewContainer);
mentionCandidateSelectionView = ViewUtil.findById(this, R.id.userSelectionView); mentionCandidateSelectionView = ViewUtil.findById(this, R.id.userSelectionView);
messageStatusProgressBar = ViewUtil.findById(this, R.id.messageStatusProgressBar); messageStatusProgressBar = ViewUtil.findById(this, R.id.messageStatusProgressBar);
actionBarSubtitleTextView = ViewUtil.findById(this, R.id.subtitleTextView); actionBarSubtitleTextView = ViewUtil.findById(this, R.id.subtitleTextView);
@ -2865,6 +2868,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (isBackspace) { if (isBackspace) {
currentMentionStartIndex = -1; currentMentionStartIndex = -1;
mentionCandidateSelectionView.hide(); mentionCandidateSelectionView.hide();
mentionCandidateSelectionViewContainer.setVisibility(View.GONE);
ArrayList<Mention> mentionsToRemove = new ArrayList<>(); ArrayList<Mention> mentionsToRemove = new ArrayList<>();
for (Mention mention : mentions) { for (Mention mention : mentions) {
if (!text.contains(mention.getDisplayName())) { if (!text.contains(mention.getDisplayName())) {
@ -2889,14 +2893,17 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (lastCharacter == '@' && Character.isWhitespace(secondToLastCharacter)) { if (lastCharacter == '@' && Character.isWhitespace(secondToLastCharacter)) {
List<Mention> mentionCandidates = LokiAPI.Companion.getMentionCandidates("", threadId, userHexEncodedPublicKey, threadDatabase, userDatabase); List<Mention> mentionCandidates = LokiAPI.Companion.getMentionCandidates("", threadId, userHexEncodedPublicKey, threadDatabase, userDatabase);
currentMentionStartIndex = lastCharacterIndex; currentMentionStartIndex = lastCharacterIndex;
mentionCandidateSelectionViewContainer.setVisibility(View.VISIBLE);
mentionCandidateSelectionView.show(mentionCandidates, threadId); mentionCandidateSelectionView.show(mentionCandidates, threadId);
} else if (Character.isWhitespace(lastCharacter)) { } else if (Character.isWhitespace(lastCharacter)) {
currentMentionStartIndex = -1; currentMentionStartIndex = -1;
mentionCandidateSelectionView.hide(); mentionCandidateSelectionView.hide();
mentionCandidateSelectionViewContainer.setVisibility(View.GONE);
} else { } else {
if (currentMentionStartIndex != -1) { if (currentMentionStartIndex != -1) {
String query = text.substring(currentMentionStartIndex + 1); // + 1 to get rid of the @ String query = text.substring(currentMentionStartIndex + 1); // + 1 to get rid of the @
List<Mention> mentionCandidates = LokiAPI.Companion.getMentionCandidates(query, threadId, userHexEncodedPublicKey, threadDatabase, userDatabase); List<Mention> mentionCandidates = LokiAPI.Companion.getMentionCandidates(query, threadId, userHexEncodedPublicKey, threadDatabase, userDatabase);
mentionCandidateSelectionViewContainer.setVisibility(View.VISIBLE);
mentionCandidateSelectionView.show(mentionCandidates, threadId); mentionCandidateSelectionView.show(mentionCandidates, threadId);
} }
} }

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.views
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
@ -8,11 +8,15 @@ import android.view.ViewGroup
import android.widget.BaseAdapter import android.widget.BaseAdapter
import android.widget.ListView import android.widget.ListView
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.toPx
import org.thoughtcrime.securesms.mms.GlideRequests
import org.whispersystems.signalservice.loki.messaging.Mention import org.whispersystems.signalservice.loki.messaging.Mention
class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) { class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) {
private var mentionCandidates = listOf<Mention>() private var mentionCandidates = listOf<Mention>()
set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.mentionCandidates = newValue } set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.mentionCandidates = newValue }
var glide: GlideRequests? = null
set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.glide = newValue }
var publicChatServer: String? = null var publicChatServer: String? = null
set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.publicChatServer = publicChatServer } set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.publicChatServer = publicChatServer }
var publicChatChannel: Long? = null var publicChatChannel: Long? = null
@ -24,6 +28,7 @@ class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defS
private class Adapter(private val context: Context) : BaseAdapter() { private class Adapter(private val context: Context) : BaseAdapter() {
var mentionCandidates = listOf<Mention>() var mentionCandidates = listOf<Mention>()
set(newValue) { field = newValue; notifyDataSetChanged() } set(newValue) { field = newValue; notifyDataSetChanged() }
var glide: GlideRequests? = null
var publicChatServer: String? = null var publicChatServer: String? = null
var publicChatChannel: Long? = null var publicChatChannel: Long? = null
@ -40,8 +45,9 @@ class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defS
} }
override fun getView(position: Int, cellToBeReused: View?, parent: ViewGroup): View { override fun getView(position: Int, cellToBeReused: View?, parent: ViewGroup): View {
val cell = cellToBeReused as MentionCandidateSelectionViewCell? ?: MentionCandidateSelectionViewCell.inflate(LayoutInflater.from(context), parent) val cell = cellToBeReused as MentionCandidateView? ?: MentionCandidateView.inflate(LayoutInflater.from(context), parent)
val mentionCandidate = getItem(position) val mentionCandidate = getItem(position)
cell.glide = glide
cell.mentionCandidate = mentionCandidate cell.mentionCandidate = mentionCandidate
cell.publicChatServer = publicChatServer cell.publicChatServer = publicChatServer
cell.publicChatChannel = publicChatChannel cell.publicChatChannel = publicChatChannel
@ -53,6 +59,7 @@ class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defS
constructor(context: Context) : this(context, null) constructor(context: Context) : this(context, null)
init { init {
clipToOutline = true
adapter = mentionCandidateSelectionViewAdapter adapter = mentionCandidateSelectionViewAdapter
mentionCandidateSelectionViewAdapter.mentionCandidates = mentionCandidates mentionCandidateSelectionViewAdapter.mentionCandidates = mentionCandidates
setOnItemClickListener { _, _, position, _ -> setOnItemClickListener { _, _, position, _ ->
@ -68,7 +75,7 @@ class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defS
} }
this.mentionCandidates = mentionCandidates this.mentionCandidates = mentionCandidates
val layoutParams = this.layoutParams as ViewGroup.LayoutParams val layoutParams = this.layoutParams as ViewGroup.LayoutParams
layoutParams.height = toPx(6 + Math.min(mentionCandidates.count(), 4) * 52, resources) layoutParams.height = toPx(Math.min(mentionCandidates.count(), 4) * 44, resources)
this.layoutParams = layoutParams this.layoutParams = layoutParams
} }

@ -1,21 +1,21 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.views
import android.content.Context import android.content.Context
import android.graphics.Outline
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewOutlineProvider
import android.widget.LinearLayout import android.widget.LinearLayout
import kotlinx.android.synthetic.main.cell_mention_candidate_selection_view.view.* import kotlinx.android.synthetic.main.view_mention_candidate.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.mms.GlideRequests
import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI
import org.whispersystems.signalservice.loki.messaging.Mention import org.whispersystems.signalservice.loki.messaging.Mention
class MentionCandidateSelectionViewCell(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) { class MentionCandidateView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) {
var mentionCandidate = Mention("", "") var mentionCandidate = Mention("", "")
set(newValue) { field = newValue; update() } set(newValue) { field = newValue; update() }
var glide: GlideRequests? = null
var publicChatServer: String? = null var publicChatServer: String? = null
var publicChatChannel: Long? = null var publicChatChannel: Long? = null
@ -24,25 +24,18 @@ class MentionCandidateSelectionViewCell(context: Context, attrs: AttributeSet?,
companion object { companion object {
fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup): MentionCandidateSelectionViewCell { fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup): MentionCandidateView {
return layoutInflater.inflate(R.layout.cell_mention_candidate_selection_view, parent, false) as MentionCandidateSelectionViewCell return layoutInflater.inflate(R.layout.view_mention_candidate, parent, false) as MentionCandidateView
} }
} }
override fun onFinishInflate() {
super.onFinishInflate()
profilePictureImageViewContainer.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setOval(0, 0, view.width, view.height)
}
}
profilePictureImageViewContainer.clipToOutline = true
}
private fun update() { private fun update() {
displayNameTextView.text = mentionCandidate.displayName displayNameTextView.text = mentionCandidate.displayName
profilePictureImageView.update(mentionCandidate.hexEncodedPublicKey) profilePictureView.hexEncodedPublicKey = mentionCandidate.hexEncodedPublicKey
profilePictureView.additionalHexEncodedPublicKey = null
profilePictureView.isRSSFeed = false
profilePictureView.glide = glide!!
profilePictureView.update()
if (publicChatServer != null && publicChatChannel != null) { if (publicChatServer != null && publicChatChannel != null) {
val isUserModerator = LokiPublicChatAPI.isUserModerator(mentionCandidate.hexEncodedPublicKey, publicChatChannel!!, publicChatServer!!) val isUserModerator = LokiPublicChatAPI.isUserModerator(mentionCandidate.hexEncodedPublicKey, publicChatChannel!!, publicChatServer!!)
moderatorIconImageView.visibility = if (isUserModerator) View.VISIBLE else View.GONE moderatorIconImageView.visibility = if (isUserModerator) View.VISIBLE else View.GONE
Loading…
Cancel
Save