parent
7522bf04eb
commit
f665318eb6
|
@ -23,17 +23,20 @@ import android.content.Context
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import org.apache.commons.lang3.time.DateUtils
|
||||||
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
|
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
|
||||||
|
import org.mariotaku.twidere.extension.model.timestamp
|
||||||
import org.mariotaku.twidere.model.ItemCounts
|
import org.mariotaku.twidere.model.ItemCounts
|
||||||
import org.mariotaku.twidere.model.ParcelableMessage
|
import org.mariotaku.twidere.model.ParcelableMessage
|
||||||
import org.mariotaku.twidere.model.ParcelableMessage.MessageType
|
import org.mariotaku.twidere.model.ParcelableMessage.MessageType
|
||||||
import org.mariotaku.twidere.view.holder.message.AbsMessageViewHolder
|
import org.mariotaku.twidere.view.holder.message.AbsMessageViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.message.MessageViewHolder
|
import org.mariotaku.twidere.view.holder.message.MessageViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.message.StickerMessageViewHolder
|
import org.mariotaku.twidere.view.holder.message.StickerMessageViewHolder
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
|
class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
|
||||||
IItemCountsAdapter {
|
IItemCountsAdapter {
|
||||||
|
private val calendars = Pair(Calendar.getInstance(), Calendar.getInstance())
|
||||||
override val itemCounts: ItemCounts = ItemCounts(1)
|
override val itemCounts: ItemCounts = ItemCounts(1)
|
||||||
var messages: List<ParcelableMessage>? = null
|
var messages: List<ParcelableMessage>? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -59,14 +62,24 @@ class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<Rec
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
when (holder.itemViewType) {
|
when (holder.itemViewType) {
|
||||||
ITEM_TYPE_TEXT_MESSAGE, ITEM_TYPE_STICKER_MESSAGE -> {
|
ITEM_TYPE_TEXT_MESSAGE, ITEM_TYPE_STICKER_MESSAGE -> {
|
||||||
(holder as AbsMessageViewHolder).display(getMessage(position)!!)
|
val message = getMessage(position)!!
|
||||||
|
// Display date for oldest item
|
||||||
|
var showDate = true
|
||||||
|
// ... or if current message is > 1 day newer than previous one
|
||||||
|
if (position < itemCounts.getItemStartPosition(ITEM_START_MESSAGE)
|
||||||
|
+ itemCounts[ITEM_START_MESSAGE] - 1) {
|
||||||
|
calendars.first.timeInMillis = getMessage(position + 1)!!.timestamp
|
||||||
|
calendars.second.timeInMillis = message.timestamp
|
||||||
|
showDate = !DateUtils.isSameDay(calendars.first, calendars.second)
|
||||||
|
}
|
||||||
|
(holder as AbsMessageViewHolder).display(message, showDate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
itemCounts[0] = messages?.size ?: 0
|
itemCounts[ITEM_START_MESSAGE] = messages?.size ?: 0
|
||||||
return itemCounts.itemCount
|
return itemCounts.itemCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +89,7 @@ class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<Rec
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
when (itemCounts.getItemCountIndex(position)) {
|
when (itemCounts.getItemCountIndex(position)) {
|
||||||
0 -> {
|
ITEM_START_MESSAGE -> {
|
||||||
when (getMessage(position)!!.message_type) {
|
when (getMessage(position)!!.message_type) {
|
||||||
MessageType.STICKER -> {
|
MessageType.STICKER -> {
|
||||||
return ITEM_TYPE_STICKER_MESSAGE
|
return ITEM_TYPE_STICKER_MESSAGE
|
||||||
|
@ -89,6 +102,8 @@ class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<Rec
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val ITEM_START_MESSAGE = 0
|
||||||
|
|
||||||
const val ITEM_TYPE_TEXT_MESSAGE = 1
|
const val ITEM_TYPE_TEXT_MESSAGE = 1
|
||||||
const val ITEM_TYPE_STICKER_MESSAGE = 2
|
const val ITEM_TYPE_STICKER_MESSAGE = 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ fun ParcelableMessageConversation.setFrom(message: ParcelableMessage, details: A
|
||||||
message_type = message.message_type
|
message_type = message.message_type
|
||||||
message_timestamp = message.message_timestamp
|
message_timestamp = message.message_timestamp
|
||||||
local_timestamp = message.local_timestamp
|
local_timestamp = message.local_timestamp
|
||||||
|
sort_id = message.sort_id
|
||||||
text_unescaped = message.text_unescaped
|
text_unescaped = message.text_unescaped
|
||||||
media = message.media
|
media = message.media
|
||||||
spans = message.spans
|
spans = message.spans
|
||||||
|
|
|
@ -31,7 +31,7 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
adapter = MessagesConversationAdapter(context)
|
adapter = MessagesConversationAdapter(context)
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
recyclerView.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
recyclerView.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
||||||
loaderManager.initLoader(0, null, this)
|
loaderManager.initLoader(0, null, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac
|
||||||
loader.selection = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
|
loader.selection = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
|
||||||
Expression.equalsArgs(Messages.CONVERSATION_ID)).sql
|
Expression.equalsArgs(Messages.CONVERSATION_ID)).sql
|
||||||
loader.selectionArgs = arrayOf(accountKey.toString(), conversationId)
|
loader.selectionArgs = arrayOf(accountKey.toString(), conversationId)
|
||||||
loader.sortOrder = OrderBy(Messages.LOCAL_TIMESTAMP, true).sql
|
loader.sortOrder = OrderBy(Messages.SORT_ID, false).sql
|
||||||
return loader
|
return loader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
|
||||||
loader.selection = Expression.inArgs(Conversations.ACCOUNT_KEY, accountKeys.size).sql
|
loader.selection = Expression.inArgs(Conversations.ACCOUNT_KEY, accountKeys.size).sql
|
||||||
loader.selectionArgs = accountKeys.toStringArray()
|
loader.selectionArgs = accountKeys.toStringArray()
|
||||||
loader.projection = Conversations.COLUMNS
|
loader.projection = Conversations.COLUMNS
|
||||||
loader.sortOrder = OrderBy(Conversations.LOCAL_TIMESTAMP, false).sql
|
loader.sortOrder = OrderBy(Conversations.SORT_ID, false).sql
|
||||||
return loader
|
return loader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.mariotaku.twidere.model.util
|
package org.mariotaku.twidere.model.util
|
||||||
|
|
||||||
|
import android.support.annotation.FloatRange
|
||||||
import org.mariotaku.microblog.library.twitter.model.DirectMessage
|
import org.mariotaku.microblog.library.twitter.model.DirectMessage
|
||||||
import org.mariotaku.twidere.model.ParcelableMessage
|
import org.mariotaku.twidere.model.ParcelableMessage
|
||||||
import org.mariotaku.twidere.model.UserKey
|
import org.mariotaku.twidere.model.UserKey
|
||||||
|
@ -11,15 +12,23 @@ import org.mariotaku.twidere.util.InternalTwitterContentUtils
|
||||||
* Created by mariotaku on 2017/2/9.
|
* Created by mariotaku on 2017/2/9.
|
||||||
*/
|
*/
|
||||||
object ParcelableMessageUtils {
|
object ParcelableMessageUtils {
|
||||||
fun incomingMessage(accountKey: UserKey, message: DirectMessage): ParcelableMessage {
|
fun incomingMessage(
|
||||||
val result = message(accountKey, message)
|
accountKey: UserKey,
|
||||||
|
message: DirectMessage,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) sortIdAdj: Double = 0.0
|
||||||
|
): ParcelableMessage {
|
||||||
|
val result = message(accountKey, message, sortIdAdj)
|
||||||
result.is_outgoing = false
|
result.is_outgoing = false
|
||||||
result.conversation_id = incomingConversationId(message.senderId, message.recipientId)
|
result.conversation_id = incomingConversationId(message.senderId, message.recipientId)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun outgoingMessage(accountKey: UserKey, message: DirectMessage): ParcelableMessage {
|
fun outgoingMessage(
|
||||||
val result = message(accountKey, message)
|
accountKey: UserKey,
|
||||||
|
message: DirectMessage,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) sortIdAdj: Double = 0.0
|
||||||
|
): ParcelableMessage {
|
||||||
|
val result = message(accountKey, message, sortIdAdj)
|
||||||
result.is_outgoing = true
|
result.is_outgoing = true
|
||||||
result.conversation_id = outgoingConversationId(message.senderId, message.recipientId)
|
result.conversation_id = outgoingConversationId(message.senderId, message.recipientId)
|
||||||
return result
|
return result
|
||||||
|
@ -33,7 +42,11 @@ object ParcelableMessageUtils {
|
||||||
return "$senderId-$recipientId"
|
return "$senderId-$recipientId"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun message(accountKey: UserKey, message: DirectMessage): ParcelableMessage {
|
private fun message(
|
||||||
|
accountKey: UserKey,
|
||||||
|
message: DirectMessage,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) sortIdAdj: Double = 0.0
|
||||||
|
): ParcelableMessage {
|
||||||
val result = ParcelableMessage()
|
val result = ParcelableMessage()
|
||||||
result.account_key = accountKey
|
result.account_key = accountKey
|
||||||
result.id = message.id
|
result.id = message.id
|
||||||
|
@ -41,6 +54,7 @@ object ParcelableMessageUtils {
|
||||||
result.recipient_key = UserKeyUtils.fromUser(message.recipient)
|
result.recipient_key = UserKeyUtils.fromUser(message.recipient)
|
||||||
result.message_timestamp = message.createdAt.time
|
result.message_timestamp = message.createdAt.time
|
||||||
result.local_timestamp = result.message_timestamp
|
result.local_timestamp = result.message_timestamp
|
||||||
|
result.sort_id = result.message_timestamp + (499 * sortIdAdj).toLong()
|
||||||
|
|
||||||
val (type, extras) = typeAndExtras(accountKey, message)
|
val (type, extras) = typeAndExtras(accountKey, message)
|
||||||
val (text, spans) = InternalTwitterContentUtils.formatDirectMessageText(message)
|
val (text, spans) = InternalTwitterContentUtils.formatDirectMessageText(message)
|
||||||
|
|
|
@ -31,8 +31,10 @@ import org.mariotaku.twidere.util.content.ContentResolverUtils
|
||||||
* Created by mariotaku on 2017/2/8.
|
* Created by mariotaku on 2017/2/8.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Unit, (Boolean) -> Unit>(context) {
|
class GetMessagesTask(
|
||||||
override fun doLongOperation(param: RefreshTaskParam) {
|
context: Context
|
||||||
|
) : BaseAbstractTask<GetMessagesTask.RefreshMessagesTaskParam, Unit, (Boolean) -> Unit>(context) {
|
||||||
|
override fun doLongOperation(param: RefreshMessagesTaskParam) {
|
||||||
val accountKeys = param.accountKeys
|
val accountKeys = param.accountKeys
|
||||||
val am = AccountManager.get(context)
|
val am = AccountManager.get(context)
|
||||||
accountKeys.forEachIndexed { i, accountKey ->
|
accountKeys.forEachIndexed { i, accountKey ->
|
||||||
|
@ -121,13 +123,13 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
||||||
|
|
||||||
conversations.addLocalConversations(accountKey, conversationIds)
|
conversations.addLocalConversations(accountKey, conversationIds)
|
||||||
|
|
||||||
received.forEach { dm ->
|
received.forEachIndexed { i, dm ->
|
||||||
val message = ParcelableMessageUtils.incomingMessage(accountKey, dm)
|
val message = ParcelableMessageUtils.incomingMessage(accountKey, dm, 1.0 - (i.toDouble() / received.size))
|
||||||
insertMessages.add(message)
|
insertMessages.add(message)
|
||||||
conversations.addConversation(details, message, dm.sender, dm.recipient)
|
conversations.addConversation(details, message, dm.sender, dm.recipient)
|
||||||
}
|
}
|
||||||
sent.forEach { dm ->
|
sent.forEachIndexed { i, dm ->
|
||||||
val message = ParcelableMessageUtils.outgoingMessage(accountKey, dm)
|
val message = ParcelableMessageUtils.outgoingMessage(accountKey, dm, 1.0 - (i.toDouble() / sent.size))
|
||||||
insertMessages.add(message)
|
insertMessages.add(message)
|
||||||
conversations.addConversation(details, message, dm.sender, dm.recipient)
|
conversations.addConversation(details, message, dm.sender, dm.recipient)
|
||||||
}
|
}
|
||||||
|
@ -225,7 +227,6 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
||||||
getAccountKeys: () -> Array<UserKey>
|
getAccountKeys: () -> Array<UserKey>
|
||||||
) : RefreshMessagesTaskParam(context, getAccountKeys) {
|
) : RefreshMessagesTaskParam(context, getAccountKeys) {
|
||||||
|
|
||||||
|
|
||||||
override val sinceIds: Array<String?>?
|
override val sinceIds: Array<String?>?
|
||||||
get() {
|
get() {
|
||||||
val keys = accounts.map { account ->
|
val keys = accounts.map { account ->
|
||||||
|
@ -252,7 +253,6 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
||||||
getAccountKeys: () -> Array<UserKey>
|
getAccountKeys: () -> Array<UserKey>
|
||||||
) : RefreshMessagesTaskParam(context, getAccountKeys) {
|
) : RefreshMessagesTaskParam(context, getAccountKeys) {
|
||||||
|
|
||||||
|
|
||||||
override val maxIds: Array<String?>?
|
override val maxIds: Array<String?>?
|
||||||
get() {
|
get() {
|
||||||
val keys = accounts.map { account ->
|
val keys = accounts.map { account ->
|
||||||
|
@ -279,6 +279,11 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
||||||
val getAccountKeys: () -> Array<UserKey>
|
val getAccountKeys: () -> Array<UserKey>
|
||||||
) : SimpleRefreshTaskParam() {
|
) : SimpleRefreshTaskParam() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `conversationId` has value, load messages in conversationId
|
||||||
|
*/
|
||||||
|
open var conversationId: String? = null
|
||||||
|
|
||||||
protected val accounts: Array<AccountDetails?> by lazy {
|
protected val accounts: Array<AccountDetails?> by lazy {
|
||||||
AccountUtils.getAllAccountDetails(AccountManager.get(context), accountKeys, false)
|
AccountUtils.getAllAccountDetails(AccountManager.get(context), accountKeys, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ class AsyncTwitterWrapper(
|
||||||
TaskStarter.execute<Any, Unit, Any>(task)
|
TaskStarter.execute<Any, Unit, Any>(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMessagesAsync(param: RefreshTaskParam) {
|
fun getMessagesAsync(param: GetMessagesTask.RefreshMessagesTaskParam) {
|
||||||
val task = GetMessagesTask(context)
|
val task = GetMessagesTask(context)
|
||||||
task.params = param
|
task.params = param
|
||||||
TaskStarter.execute(task)
|
TaskStarter.execute(task)
|
||||||
|
@ -293,9 +293,7 @@ class AsyncTwitterWrapper(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (preferences.getBoolean(SharedPreferenceConstants.KEY_HOME_REFRESH_DIRECT_MESSAGES)) {
|
if (preferences.getBoolean(SharedPreferenceConstants.KEY_HOME_REFRESH_DIRECT_MESSAGES)) {
|
||||||
getMessagesAsync(object : SimpleRefreshTaskParam() {
|
getMessagesAsync(GetMessagesTask.RefreshMessagesTaskParam(context, action))
|
||||||
override val accountKeys: Array<UserKey> by lazy { action() }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if (preferences.getBoolean(SharedPreferenceConstants.KEY_HOME_REFRESH_SAVED_SEARCHES)) {
|
if (preferences.getBoolean(SharedPreferenceConstants.KEY_HOME_REFRESH_SAVED_SEARCHES)) {
|
||||||
getSavedSearchesAsync(action())
|
getSavedSearchesAsync(action())
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.mariotaku.twidere.util
|
package org.mariotaku.twidere.util
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.TextUtils.isEmpty
|
import android.text.TextUtils.isEmpty
|
||||||
import okhttp3.ConnectionPool
|
import okhttp3.ConnectionPool
|
||||||
|
@ -34,7 +33,6 @@ object HttpClientFactory {
|
||||||
DebugModeUtils.initForOkHttpClient(builder)
|
DebugModeUtils.initForOkHttpClient(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SSLCertificateSocketFactoryGetInsecure")
|
|
||||||
internal fun updateHttpClientConfiguration(builder: OkHttpClient.Builder,
|
internal fun updateHttpClientConfiguration(builder: OkHttpClient.Builder,
|
||||||
conf: HttpClientConfiguration, dns: Dns,
|
conf: HttpClientConfiguration, dns: Dns,
|
||||||
connectionPool: ConnectionPool) {
|
connectionPool: ConnectionPool) {
|
||||||
|
|
|
@ -29,7 +29,8 @@ import org.mariotaku.twidere.model.ParcelableMessage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class AbsMessageViewHolder(itemView: View, val adapter: MessagesConversationAdapter) : RecyclerView.ViewHolder(itemView) {
|
abstract class AbsMessageViewHolder(itemView: View, val adapter: MessagesConversationAdapter) : RecyclerView.ViewHolder(itemView) {
|
||||||
open fun display(message: ParcelableMessage) {
|
|
||||||
|
open fun display(message: ParcelableMessage, showDate: Boolean) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,10 @@
|
||||||
package org.mariotaku.twidere.view.holder.message
|
package org.mariotaku.twidere.view.holder.message
|
||||||
|
|
||||||
import android.support.v4.view.GravityCompat
|
import android.support.v4.view.GravityCompat
|
||||||
|
import android.text.format.DateUtils
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.LinearLayout
|
||||||
import kotlinx.android.synthetic.main.list_item_message_conversation_text.view.*
|
import kotlinx.android.synthetic.main.list_item_message_conversation_text.view.*
|
||||||
import org.mariotaku.ktextension.isNullOrEmpty
|
import org.mariotaku.ktextension.isNullOrEmpty
|
||||||
import org.mariotaku.messagebubbleview.library.MessageBubbleView
|
import org.mariotaku.messagebubbleview.library.MessageBubbleView
|
||||||
|
@ -36,16 +38,32 @@ import org.mariotaku.twidere.model.ParcelableMessage
|
||||||
|
|
||||||
class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) : AbsMessageViewHolder(itemView, adapter) {
|
class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) : AbsMessageViewHolder(itemView, adapter) {
|
||||||
|
|
||||||
|
private val date by lazy { itemView.date }
|
||||||
private val text by lazy { itemView.text }
|
private val text by lazy { itemView.text }
|
||||||
private val time by lazy { itemView.time }
|
private val time by lazy { itemView.time }
|
||||||
private val mediaPreview by lazy { itemView.mediaPreview }
|
private val mediaPreview by lazy { itemView.mediaPreview }
|
||||||
private val messageContent by lazy { itemView.messageContent }
|
private val messageContent by lazy { itemView.messageContent }
|
||||||
|
|
||||||
override fun display(message: ParcelableMessage) {
|
init {
|
||||||
super.display(message)
|
val textSize = adapter.textSize
|
||||||
|
text.textSize = textSize
|
||||||
|
time.textSize = textSize * 0.8f
|
||||||
|
date.textSize = textSize * 0.9f
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun display(message: ParcelableMessage, showDate: Boolean) {
|
||||||
|
super.display(message, showDate)
|
||||||
setOutgoingStatus(messageContent, message.is_outgoing)
|
setOutgoingStatus(messageContent, message.is_outgoing)
|
||||||
text.text = message.text_unescaped
|
text.text = message.text_unescaped
|
||||||
time.time = message.timestamp
|
if (showDate) {
|
||||||
|
date.visibility = View.VISIBLE
|
||||||
|
date.text = DateUtils.getRelativeTimeSpanString(message.timestamp, System.currentTimeMillis(),
|
||||||
|
DateUtils.DAY_IN_MILLIS, DateUtils.FORMAT_SHOW_DATE)
|
||||||
|
} else {
|
||||||
|
date.visibility = View.GONE
|
||||||
|
}
|
||||||
|
time.text = DateUtils.formatDateTime(adapter.context, message.timestamp,
|
||||||
|
DateUtils.FORMAT_SHOW_TIME)
|
||||||
if (message.media.isNullOrEmpty()) {
|
if (message.media.isNullOrEmpty()) {
|
||||||
mediaPreview.visibility = View.GONE
|
mediaPreview.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,6 +87,9 @@ class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) :
|
||||||
is FrameLayout.LayoutParams -> {
|
is FrameLayout.LayoutParams -> {
|
||||||
lp.gravity = if (outgoing) GravityCompat.END else GravityCompat.START
|
lp.gravity = if (outgoing) GravityCompat.END else GravityCompat.START
|
||||||
}
|
}
|
||||||
|
is LinearLayout.LayoutParams -> {
|
||||||
|
lp.gravity = if (outgoing) GravityCompat.END else GravityCompat.START
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,8 @@ class StickerMessageViewHolder(itemView: View, adapter: MessagesConversationAdap
|
||||||
private val messageContent by lazy { itemView.messageContent }
|
private val messageContent by lazy { itemView.messageContent }
|
||||||
private val stickerIcon by lazy { itemView.stickerIcon }
|
private val stickerIcon by lazy { itemView.stickerIcon }
|
||||||
|
|
||||||
override fun display(message: ParcelableMessage) {
|
override fun display(message: ParcelableMessage, showDate: Boolean) {
|
||||||
super.display(message)
|
super.display(message, showDate)
|
||||||
MessageViewHolder.setMessageContentGravity(messageContent, message.is_outgoing)
|
MessageViewHolder.setMessageContentGravity(messageContent, message.is_outgoing)
|
||||||
val extras = message.extras as StickerExtras
|
val extras = message.extras as StickerExtras
|
||||||
adapter.mediaLoader.displayStickerImage(stickerIcon, extras.url)
|
adapter.mediaLoader.displayStickerImage(stickerIcon, extras.url)
|
||||||
|
|
|
@ -17,14 +17,25 @@
|
||||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<FrameLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
android:padding="@dimen/element_spacing_normal">
|
android:padding="@dimen/element_spacing_normal">
|
||||||
|
|
||||||
|
<org.mariotaku.twidere.view.FixedTextView
|
||||||
|
android:id="@+id/date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:padding="@dimen/element_spacing_normal"
|
||||||
|
android:textAppearance="?android:textAppearanceSmall"
|
||||||
|
android:textColor="?android:textColorTertiary"
|
||||||
|
tools:text="Yesterday"/>
|
||||||
|
|
||||||
<org.mariotaku.messagebubbleview.library.MessageBubbleView
|
<org.mariotaku.messagebubbleview.library.MessageBubbleView
|
||||||
android:id="@+id/messageContent"
|
android:id="@+id/messageContent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -63,18 +74,18 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
tools:text="@string/sample_status_text"/>
|
tools:text="@string/sample_status_text"/>
|
||||||
|
|
||||||
<org.mariotaku.twidere.view.ShortTimeView
|
<org.mariotaku.twidere.view.FixedTextView
|
||||||
android:id="@+id/time"
|
android:id="@+id/time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/element_spacing_small"
|
android:layout_marginTop="@dimen/element_spacing_small"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorTertiary"
|
||||||
tools:text="12:00"/>
|
tools:text="12:00"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</org.mariotaku.messagebubbleview.library.MessageBubbleView>
|
</org.mariotaku.messagebubbleview.library.MessageBubbleView>
|
||||||
|
|
||||||
</FrameLayout>
|
</LinearLayout>
|
Loading…
Reference in New Issue