mirror of
https://github.com/oxen-io/session-android.git
synced 2023-12-14 02:53:01 +01:00
Implement user selection view
This commit is contained in:
parent
25bd1073b0
commit
9207e479a6
9 changed files with 186 additions and 7 deletions
50
res/layout/cell_user_selection_view.xml
Normal file
50
res/layout/cell_user_selection_view.xml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.loki.UserSelectionViewCell
|
||||||
|
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">
|
||||||
|
|
||||||
|
<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.UserSelectionViewCell>
|
|
@ -71,17 +71,26 @@
|
||||||
android:inflatedId="@+id/attachment_editor"
|
android:inflatedId="@+id/attachment_editor"
|
||||||
android:layout="@layout/conversation_activity_attachment_editor_stub" />
|
android:layout="@layout/conversation_activity_attachment_editor_stub" />
|
||||||
|
|
||||||
<FrameLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clipChildren="false"
|
android:orientation="vertical">
|
||||||
android:clipToPadding="false">
|
|
||||||
|
|
||||||
<include layout="@layout/conversation_input_panel" />
|
<include layout="@layout/view_user_selection" />
|
||||||
|
|
||||||
<include layout="@layout/conversation_search_nav" />
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false">
|
||||||
|
|
||||||
</FrameLayout>
|
<include layout="@layout/conversation_input_panel" />
|
||||||
|
|
||||||
|
<include layout="@layout/conversation_search_nav" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/register_button"
|
android:id="@+id/register_button"
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
tools:visibility="invisible"
|
tools:visibility="invisible"
|
||||||
tools:hint="Send TextSecure message" >
|
tools:hint="Send TextSecure message" >
|
||||||
<requestFocus />
|
<requestFocus />
|
||||||
|
|
||||||
</org.thoughtcrime.securesms.components.ComposeText>
|
</org.thoughtcrime.securesms.components.ComposeText>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
|
7
res/layout/view_user_selection.xml
Normal file
7
res/layout/view_user_selection.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.loki.UserSelectionView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/userSelectionView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:paddingTop="6dp" />
|
|
@ -19,6 +19,7 @@ import android.view.ViewOutlineProvider;
|
||||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
||||||
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.loki.JazzIdenticonDrawable;
|
import org.thoughtcrime.securesms.loki.JazzIdenticonDrawable;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
@ -123,6 +124,10 @@ public class AvatarImageView extends AppCompatImageView {
|
||||||
setImageDrawable(image);
|
setImageDrawable(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(String hexEncodedPublicKey) {
|
||||||
|
this.recipient = Recipient.from(getContext(), Address.fromSerialized(hexEncodedPublicKey), false);
|
||||||
|
}
|
||||||
|
|
||||||
public void setAvatar(@NonNull GlideRequests requestManager, @Nullable Recipient recipient, boolean quickContactEnabled) {
|
public void setAvatar(@NonNull GlideRequests requestManager, @Nullable Recipient recipient, boolean quickContactEnabled) {
|
||||||
this.recipient = recipient;
|
this.recipient = recipient;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -158,6 +158,8 @@ import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
|
import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
|
||||||
import org.thoughtcrime.securesms.loki.LokiAPIUtilities;
|
import org.thoughtcrime.securesms.loki.LokiAPIUtilities;
|
||||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate;
|
import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate;
|
||||||
|
import org.thoughtcrime.securesms.loki.LokiUserDatabase;
|
||||||
|
import org.thoughtcrime.securesms.loki.UserSelectionView;
|
||||||
import org.thoughtcrime.securesms.mediasend.Media;
|
import org.thoughtcrime.securesms.mediasend.Media;
|
||||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
|
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
|
||||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||||
|
@ -225,6 +227,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiAPI;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||||
import org.whispersystems.signalservice.loki.utilities.Analytics;
|
import org.whispersystems.signalservice.loki.utilities.Analytics;
|
||||||
|
@ -396,6 +399,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
});
|
});
|
||||||
|
|
||||||
LokiAPIUtilities.INSTANCE.populateUserIDCacheIfNeeded(threadId, this);
|
LokiAPIUtilities.INSTANCE.populateUserIDCacheIfNeeded(threadId, this);
|
||||||
|
UserSelectionView userSelectionView = findViewById(R.id.userSelectionView);
|
||||||
|
LokiUserDatabase userDatabase = DatabaseFactory.getLokiUserDatabase(this);
|
||||||
|
userSelectionView.setHasGroupContext(true);
|
||||||
|
userSelectionView.setUsers(LokiAPI.Companion.getUserIDs("", threadId, userDatabase));
|
||||||
|
|
||||||
if (this.recipient.isGroupRecipient()) {
|
if (this.recipient.isGroupRecipient()) {
|
||||||
if (this.recipient.getName().equals("Loki Public Chat")) {
|
if (this.recipient.getName().equals("Loki Public Chat")) {
|
||||||
|
|
|
@ -214,7 +214,7 @@ public class ConversationItem extends LinearLayout
|
||||||
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
||||||
this.alertView = findViewById(R.id.indicators_parent);
|
this.alertView = findViewById(R.id.indicators_parent);
|
||||||
this.contactPhoto = findViewById(R.id.contact_photo);
|
this.contactPhoto = findViewById(R.id.contact_photo);
|
||||||
this.moderatorIconImageView = findViewById(R.id.moderator_icon_image_view);
|
this.moderatorIconImageView = findViewById(R.id.moderator_icon_image_view);
|
||||||
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
|
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
|
||||||
this.bodyBubble = findViewById(R.id.body_bubble);
|
this.bodyBubble = findViewById(R.id.body_bubble);
|
||||||
this.mediaThumbnailStub = new Stub<>(findViewById(R.id.image_view_stub));
|
this.mediaThumbnailStub = new Stub<>(findViewById(R.id.image_view_stub));
|
||||||
|
|
52
src/org/thoughtcrime/securesms/loki/UserSelectionView.kt
Normal file
52
src/org/thoughtcrime/securesms/loki/UserSelectionView.kt
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package org.thoughtcrime.securesms.loki
|
||||||
|
|
||||||
|
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 nl.komponents.kovenant.combine.Tuple2
|
||||||
|
|
||||||
|
class UserSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) {
|
||||||
|
var users = listOf<Tuple2<String, String>>()
|
||||||
|
set(newValue) { field = newValue; userSelectionViewAdapter.users = newValue }
|
||||||
|
var hasGroupContext = false
|
||||||
|
|
||||||
|
private val userSelectionViewAdapter by lazy { Adapter(context) }
|
||||||
|
|
||||||
|
private class Adapter(private val context: Context) : BaseAdapter() {
|
||||||
|
var users = listOf<Tuple2<String, String>>()
|
||||||
|
set(newValue) { field = newValue; notifyDataSetChanged() }
|
||||||
|
var hasGroupContext = false
|
||||||
|
|
||||||
|
override fun getCount(): Int {
|
||||||
|
return users.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long {
|
||||||
|
return position.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(position: Int): Tuple2<String, String> {
|
||||||
|
return users[position]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getView(position: Int, cellToBeReused: View?, parent: ViewGroup): View {
|
||||||
|
val cell = cellToBeReused as UserSelectionViewCell? ?: UserSelectionViewCell.inflate(LayoutInflater.from(context), parent)
|
||||||
|
val user = getItem(position)
|
||||||
|
cell.user = user
|
||||||
|
cell.hasGroupContext = hasGroupContext
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||||
|
constructor(context: Context) : this(context, null)
|
||||||
|
|
||||||
|
init {
|
||||||
|
adapter = userSelectionViewAdapter
|
||||||
|
userSelectionViewAdapter.users = users
|
||||||
|
}
|
||||||
|
}
|
48
src/org/thoughtcrime/securesms/loki/UserSelectionViewCell.kt
Normal file
48
src/org/thoughtcrime/securesms/loki/UserSelectionViewCell.kt
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package org.thoughtcrime.securesms.loki
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Outline
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewOutlineProvider
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import kotlinx.android.synthetic.main.cell_user_selection_view.view.*
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import nl.komponents.kovenant.combine.Tuple2
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI
|
||||||
|
|
||||||
|
class UserSelectionViewCell(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) {
|
||||||
|
var user = Tuple2("", "")
|
||||||
|
set(newValue) { field = newValue; update() }
|
||||||
|
var hasGroupContext = false
|
||||||
|
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||||
|
constructor(context: Context) : this(context, null)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup): UserSelectionViewCell {
|
||||||
|
return layoutInflater.inflate(R.layout.cell_user_selection_view, parent, false) as UserSelectionViewCell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
displayNameTextView.text = user.second
|
||||||
|
profilePictureImageView.update(user.first)
|
||||||
|
val isUserModerator = LokiGroupChatAPI.isUserModerator(user.first, LokiGroupChatAPI.publicChatServerID, LokiGroupChatAPI.publicChatServer)
|
||||||
|
moderatorIconImageView.visibility = if (isUserModerator && hasGroupContext) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue