mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-22 07:57:30 +00:00
Hook up home screen logic
This commit is contained in:
parent
95dc4e6590
commit
ded709a58b
@ -27,6 +27,7 @@ apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'witness'
|
||||
apply plugin: 'io.fabric'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@ -112,6 +113,7 @@ dependencies {
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
|
||||
implementation 'com.github.bumptech.glide:glide:4.5.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.5.0'
|
||||
kapt 'com.github.bumptech.glide:compiler:4.5.0'
|
||||
implementation 'com.makeramen:roundedimageview:2.1.0'
|
||||
implementation 'com.pnikosis:materialish-progress:1.5'
|
||||
implementation 'org.greenrobot:eventbus:3.0.0'
|
||||
|
7
res/drawable/ic_circle_check.xml
Normal file
7
res/drawable/ic_circle_check.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<vector android:height="24dp" android:viewportHeight="15"
|
||||
android:viewportWidth="15" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#00000000"
|
||||
android:pathData="M7.5,7.5m-6.5,0a6.5,6.5 0,1 1,13 0a6.5,6.5 0,1 1,-13 0"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="1"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M4.77,7.61c-0.15,-0.15 -0.38,-0.15 -0.53,0c-0.15,0.15 -0.15,0.38 0,0.53l1.88,1.88c0.15,0.15 0.38,0.15 0.53,0l4.13,-4.12c0.15,-0.15 0.15,-0.38 0,-0.53c-0.15,-0.15 -0.38,-0.15 -0.53,0L6.38,9.22L4.77,7.61z"/>
|
||||
</vector>
|
7
res/drawable/ic_circle_dot_dot_dot.xml
Normal file
7
res/drawable/ic_circle_dot_dot_dot.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<vector android:height="24dp" android:viewportHeight="15"
|
||||
android:viewportWidth="15" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#00000000"
|
||||
android:pathData="M7.5,7.5m-6.5,0a6.5,6.5 0,1 1,13 0a6.5,6.5 0,1 1,-13 0"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="1"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M4.76,7.47c0,-0.32 0.26,-0.57 0.57,-0.57c0.32,0 0.57,0.25 0.57,0.57c0,0.31 -0.25,0.57 -0.57,0.57C5.02,8.04 4.76,7.78 4.76,7.47zM7.04,7.47c0,-0.32 0.26,-0.57 0.57,-0.57c0.32,0 0.57,0.25 0.57,0.57c0,0.31 -0.25,0.57 -0.57,0.57C7.3,8.04 7.04,7.78 7.04,7.47zM9.32,7.47c0,-0.32 0.26,-0.57 0.57,-0.57c0.32,0 0.57,0.25 0.57,0.57c0,0.31 -0.25,0.57 -0.57,0.57C9.58,8.04 9.32,7.78 9.32,7.47z"/>
|
||||
</vector>
|
5
res/drawable/ic_filled_circle_check.xml
Normal file
5
res/drawable/ic_filled_circle_check.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:viewportHeight="13"
|
||||
android:viewportWidth="13" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M6.5,6.5m-6.5,0a6.5,6.5 0,1 1,13 0a6.5,6.5 0,1 1,-13 0"/>
|
||||
<path android:fillColor="#231F20" android:pathData="M3.77,6.61c-0.15,-0.15 -0.38,-0.15 -0.53,0c-0.15,0.15 -0.15,0.38 0,0.53l1.88,1.88c0.15,0.15 0.38,0.15 0.53,0L9.78,4.9c0.15,-0.15 0.15,-0.38 0,-0.53c-0.15,-0.15 -0.38,-0.15 -0.53,0L5.38,8.22L3.77,6.61z"/>
|
||||
</vector>
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@drawable/conversation_view_background"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
@ -70,22 +70,35 @@
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/snippetTextView"
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/medium_font_size"
|
||||
android:textColor="@color/text"
|
||||
android:text="Sorry, gotta go fight crime again" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/snippetTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/medium_font_size"
|
||||
android:textColor="@color/text"
|
||||
android:text="Sorry, gotta go fight crime again" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.TypingIndicatorView
|
||||
android:id="@+id/typingIndicatorView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
app:typingIndicator_tint="@color/text" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View
|
||||
<ImageView
|
||||
android:id="@+id/statusIndicatorImageView"
|
||||
android:layout_width="@dimen/conversation_view_status_indicator_size"
|
||||
android:layout_height="@dimen/conversation_view_status_indicator_size"
|
||||
|
@ -78,7 +78,7 @@ private class CreatePrivateChatActivityAdapter(val activity: CreatePrivateChatAc
|
||||
1 -> {
|
||||
val result = ScanQRCodeWrapperFragment()
|
||||
result.delegate = activity
|
||||
result.message = "Users can share their QR code by going into their account settings and tapping "Share QR Code""
|
||||
result.message = "Users can share their QR code by going into their account settings and tapping \"Share QR Code\""
|
||||
result
|
||||
}
|
||||
else -> throw IllegalStateException()
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.activities
|
||||
|
||||
import android.arch.lifecycle.Observer
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
@ -14,9 +15,12 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.push
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
|
||||
class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener {
|
||||
private lateinit var glide: GlideRequests
|
||||
|
||||
// region Lifecycle
|
||||
constructor() : super()
|
||||
@ -27,14 +31,25 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
setContentView(R.layout.activity_home)
|
||||
// Set title
|
||||
supportActionBar!!.title = "Messages"
|
||||
// Set up Glide
|
||||
glide = GlideApp.with(this)
|
||||
// Set up recycler view
|
||||
val cursor = DatabaseFactory.getThreadDatabase(this).conversationList
|
||||
val conversationAdapter = HomeAdapter(this, cursor)
|
||||
conversationAdapter.conversationClickListener = this
|
||||
recyclerView.adapter = conversationAdapter
|
||||
val homeAdapter = HomeAdapter(this, cursor)
|
||||
homeAdapter.glide = glide
|
||||
homeAdapter.conversationClickListener = this
|
||||
recyclerView.adapter = homeAdapter
|
||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
// Set up new conversation button
|
||||
newConversationButton.setOnClickListener { createPrivateChat() }
|
||||
// Set up typing observer
|
||||
ApplicationContext.getInstance(this).typingStatusRepository.typingThreads.observe(this, object : Observer<Set<Long>> {
|
||||
|
||||
override fun onChanged(threadIDs: Set<Long>?) {
|
||||
val adapter = recyclerView.adapter as HomeAdapter
|
||||
adapter.typingThreadIDs = threadIDs ?: setOf()
|
||||
}
|
||||
})
|
||||
// Set up public chats and RSS feeds if needed
|
||||
if (TextSecurePreferences.getLocalNumber(this) != null) {
|
||||
val application = ApplicationContext.getInstance(this)
|
||||
|
@ -8,9 +8,13 @@ import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
|
||||
class HomeAdapter(context: Context, cursor: Cursor) : CursorRecyclerViewAdapter<HomeAdapter.ViewHolder>(context, cursor) {
|
||||
private val threadDatabase = DatabaseFactory.getThreadDatabase(context)
|
||||
lateinit var glide: GlideRequests
|
||||
var typingThreadIDs = setOf<Long>()
|
||||
set(value) { field = value; notifyDataSetChanged() }
|
||||
var conversationClickListener: ConversationClickListener? = null
|
||||
|
||||
class ViewHolder(val view: ConversationView) : RecyclerView.ViewHolder(view)
|
||||
@ -26,7 +30,9 @@ class HomeAdapter(context: Context, cursor: Cursor) : CursorRecyclerViewAdapter<
|
||||
}
|
||||
|
||||
override fun onBindItemViewHolder(viewHolder: ViewHolder, cursor: Cursor) {
|
||||
viewHolder.view.bind(getThread(cursor)!!)
|
||||
val thread = getThread(cursor)!!
|
||||
val isTyping = typingThreadIDs.contains(thread.threadId)
|
||||
viewHolder.view.bind(thread, isTyping, glide)
|
||||
}
|
||||
|
||||
private fun getThread(cursor: Cursor): ThreadRecord? {
|
||||
|
@ -11,6 +11,7 @@ import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.loki.LokiAPIUtilities.populateUserHexEncodedPublicKeyCacheIfNeeded
|
||||
import org.thoughtcrime.securesms.loki.MentionUtilities.highlightMentions
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.whispersystems.signalservice.loki.api.LokiAPI
|
||||
import java.util.*
|
||||
@ -43,7 +44,7 @@ class ConversationView : LinearLayout {
|
||||
// endregion
|
||||
|
||||
// region Updating
|
||||
fun bind(thread: ThreadRecord) {
|
||||
fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) {
|
||||
this.thread = thread
|
||||
populateUserHexEncodedPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a terrible place to do this
|
||||
unreadMessagesIndicatorView.visibility = if (thread.unreadCount > 0) View.VISIBLE else View.INVISIBLE
|
||||
@ -58,6 +59,7 @@ class ConversationView : LinearLayout {
|
||||
profilePictureView.additionalHexEncodedPublicKey = null
|
||||
profilePictureView.isRSSFeed = false
|
||||
}
|
||||
profilePictureView.glide = glide
|
||||
profilePictureView.update()
|
||||
val senderDisplayName = if (thread.recipient.isLocalNumber) context.getString(R.string.note_to_self) else thread.recipient.name
|
||||
displayNameTextView.text = senderDisplayName
|
||||
@ -66,6 +68,21 @@ class ConversationView : LinearLayout {
|
||||
val snippet = highlightMentions(rawSnippet, thread.threadId, context)
|
||||
snippetTextView.text = snippet
|
||||
snippetTextView.typeface = if (thread.unreadCount > 0) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
|
||||
snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE
|
||||
if (isTyping) {
|
||||
typingIndicatorView.startAnimation()
|
||||
} else {
|
||||
typingIndicatorView.stopAnimation()
|
||||
}
|
||||
typingIndicatorView.visibility = if (isTyping) View.VISIBLE else View.GONE
|
||||
statusIndicatorImageView.visibility = View.VISIBLE
|
||||
when {
|
||||
!thread.isOutgoing || thread.isVerificationStatusChange -> statusIndicatorImageView.visibility = View.GONE
|
||||
thread.isFailed -> statusIndicatorImageView.setImageResource(R.drawable.ic_error)
|
||||
thread.isPending -> statusIndicatorImageView.setImageResource(R.drawable.ic_circle_dot_dot_dot)
|
||||
thread.isRemoteRead -> statusIndicatorImageView.setImageResource(R.drawable.ic_filled_circle_check)
|
||||
else -> statusIndicatorImageView.setImageResource(R.drawable.ic_circle_check)
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
@ -4,11 +4,17 @@ import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import kotlinx.android.synthetic.main.view_profile_picture.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.database.Address
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
class ProfilePictureView : RelativeLayout {
|
||||
lateinit var glide: GlideRequests
|
||||
var hexEncodedPublicKey: String? = null
|
||||
var additionalHexEncodedPublicKey: String? = null
|
||||
var isRSSFeed = false
|
||||
@ -44,6 +50,22 @@ class ProfilePictureView : RelativeLayout {
|
||||
doubleModeImageViewContainer.visibility = if (additionalHexEncodedPublicKey != null && !isRSSFeed) View.VISIBLE else View.INVISIBLE
|
||||
singleModeImageView.visibility = if (additionalHexEncodedPublicKey == null && !isRSSFeed) View.VISIBLE else View.INVISIBLE
|
||||
rssTextView.visibility = if (isRSSFeed) View.VISIBLE else View.INVISIBLE
|
||||
fun setProfilePictureIfNeeded(imageView: ImageView, hexEncodedPublicKey: String) {
|
||||
glide.clear(imageView)
|
||||
if (hexEncodedPublicKey.isNotEmpty()) {
|
||||
val signalProfilePicture = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).contactPhoto
|
||||
if (signalProfilePicture != null) {
|
||||
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView)
|
||||
} else {
|
||||
imageView.setImageDrawable(null)
|
||||
}
|
||||
} else {
|
||||
imageView.setImageDrawable(null)
|
||||
}
|
||||
}
|
||||
setProfilePictureIfNeeded(singleModeImageView, hexEncodedPublicKey)
|
||||
setProfilePictureIfNeeded(doubleModeImageView1, hexEncodedPublicKey)
|
||||
setProfilePictureIfNeeded(doubleModeImageView2, additionalHexEncodedPublicKey ?: "")
|
||||
}
|
||||
// endregion
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user