added read only sticker support

This commit is contained in:
Mariotaku Lee 2017-02-10 14:17:48 +08:00
parent bf4f686d7d
commit 723592f016
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
17 changed files with 297 additions and 55 deletions

View File

@ -168,6 +168,7 @@ public interface IntentConstants {
String EXTRA_ALPHA_SLIDER = "alpha_slider";
String EXTRA_OPEN_ACCOUNTS_DRAWER = "open_accounts_drawer";
String EXTRA_RECIPIENT_ID = "recipient_id";
String EXTRA_CONVERSATION_ID = "conversation_id";
String EXTRA_OFFICIAL_KEY_ONLY = "official_key_only";
String EXTRA_SEARCH_ID = "search_id";
String EXTRA_CLEAR_BUTTON = "clear_button";

View File

@ -23,15 +23,24 @@ package org.mariotaku.twidere.model.message;
import android.os.Parcelable;
import com.bluelinelabs.logansquare.LoganSquare;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import org.mariotaku.twidere.model.ParcelableMessage.MessageType;
import java.io.IOException;
/**
* Created by mariotaku on 2017/2/9.
*/
@JsonObject
public abstract class MessageExtras implements Parcelable {
public static MessageExtras parse(final String messageType, final String json) {
public static MessageExtras parse(final String messageType, final String json) throws IOException {
switch (messageType) {
case MessageType.STICKER:
return LoganSquare.parse(json, StickerExtras.class);
}
return null;
}
}

View File

@ -33,12 +33,8 @@ import java.io.InputStream;
* Created by mariotaku on 15/8/28.
*/
public class ReadOnlyDiskLRUNameCache extends BaseDiskCache {
public ReadOnlyDiskLRUNameCache(File cacheDir) {
super(cacheDir);
}
public ReadOnlyDiskLRUNameCache(File cacheDir, File reserveCacheDir) {
super(cacheDir, reserveCacheDir);
public ReadOnlyDiskLRUNameCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator) {
super(cacheDir, reserveCacheDir, fileNameGenerator);
}
@Override
@ -71,8 +67,4 @@ public class ReadOnlyDiskLRUNameCache extends BaseDiskCache {
}
return new File(dir, fileName);
}
public ReadOnlyDiskLRUNameCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator) {
super(cacheDir, reserveCacheDir, fileNameGenerator);
}
}

View File

@ -486,25 +486,25 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
}
var userHost: String? = null
var isAccountIdRequired = true
var accountRequired = true
when (linkId) {
LINK_ID_ACCOUNTS -> {
isAccountIdRequired = false
accountRequired = false
fragment = AccountsManagerFragment()
}
LINK_ID_DRAFTS -> {
isAccountIdRequired = false
accountRequired = false
fragment = DraftsFragment()
}
LINK_ID_FILTERS -> {
isAccountIdRequired = false
accountRequired = false
fragment = FiltersFragment()
}
LINK_ID_PROFILE_EDITOR -> {
fragment = UserProfileEditorFragment()
}
LINK_ID_MAP -> {
isAccountIdRequired = false
accountRequired = false
if (!args.containsKey(EXTRA_LATITUDE) && !args.containsKey(EXTRA_LONGITUDE)) {
val lat = uri.getQueryParameter(QUERY_PARAM_LAT).toDouble(Double.NaN)
val lng = uri.getQueryParameter(QUERY_PARAM_LNG).toDouble(Double.NaN)
@ -616,14 +616,9 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
}
LINK_ID_DIRECT_MESSAGES_CONVERSATION -> {
fragment = MessagesConversationFragment()
isAccountIdRequired = false
val paramRecipientId = uri.getQueryParameter(QUERY_PARAM_CONVERSATION_ID)
val paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME)
if (paramRecipientId != null) {
args.putString(EXTRA_RECIPIENT_ID, paramRecipientId)
} else if (paramScreenName != null) {
args.putString(EXTRA_SCREEN_NAME, paramScreenName)
}
accountRequired = true
val conversationId = uri.getQueryParameter(QUERY_PARAM_CONVERSATION_ID) ?: return null
args.putString(EXTRA_CONVERSATION_ID, conversationId)
}
LINK_ID_DIRECT_MESSAGES -> {
fragment = MessagesEntriesFragment()
@ -736,7 +731,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
fragment = IncomingFriendshipsFragment()
}
LINK_ID_ITEMS -> {
isAccountIdRequired = false
accountRequired = false
fragment = ItemsListFragment()
}
LINK_ID_STATUS_RETWEETERS -> {
@ -771,7 +766,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
}
LINK_ID_FILTERS_SUBSCRIPTIONS -> {
fragment = FiltersSubscriptionsFragment()
isAccountIdRequired = false
accountRequired = false
}
LINK_ID_FILTERS_SUBSCRIPTIONS_ADD -> {
val url = uri.getQueryParameter("url") ?: return null
@ -780,7 +775,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
args.putString(IntentConstants.EXTRA_ACTION, FiltersSubscriptionsFragment.ACTION_ADD_URL_SUBSCRIPTION)
args.putString(FiltersSubscriptionsFragment.EXTRA_ADD_SUBSCRIPTION_URL, url)
args.putString(FiltersSubscriptionsFragment.EXTRA_ADD_SUBSCRIPTION_NAME, name)
isAccountIdRequired = false
accountRequired = false
}
else -> {
return null
@ -802,7 +797,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
}
}
if (isAccountIdRequired && accountKey == null) {
if (accountRequired && accountKey == null) {
val exception = Utils.NoAccountException()
exception.accountHost = userHost
throw exception

View File

@ -0,0 +1,96 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
import org.mariotaku.twidere.model.ItemCounts
import org.mariotaku.twidere.model.ParcelableMessage
import org.mariotaku.twidere.model.ParcelableMessage.MessageType
import org.mariotaku.twidere.view.holder.message.AbsMessageViewHolder
import org.mariotaku.twidere.view.holder.message.MessageViewHolder
import org.mariotaku.twidere.view.holder.message.StickerMessageViewHolder
class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
IItemCountsAdapter {
override val itemCounts: ItemCounts = ItemCounts(1)
var messages: List<ParcelableMessage>? = null
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
when (viewType) {
ITEM_TYPE_TEXT_MESSAGE -> {
val view = inflater.inflate(MessageViewHolder.layoutResource, parent, false)
return MessageViewHolder(view, this)
}
ITEM_TYPE_STICKER_MESSAGE -> {
val view = inflater.inflate(StickerMessageViewHolder.layoutResource, parent, false)
return StickerMessageViewHolder(view, this)
}
}
throw UnsupportedOperationException()
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder.itemViewType) {
ITEM_TYPE_TEXT_MESSAGE, ITEM_TYPE_STICKER_MESSAGE -> {
(holder as AbsMessageViewHolder).display(getMessage(position)!!)
}
}
}
override fun getItemCount(): Int {
itemCounts[0] = messages?.size ?: 0
return itemCounts.itemCount
}
fun getMessage(position: Int): ParcelableMessage? {
return messages?.get(position - itemCounts.getItemStartPosition(0))
}
override fun getItemViewType(position: Int): Int {
when (itemCounts.getItemCountIndex(position)) {
0 -> {
when (getMessage(position)!!.message_type) {
MessageType.STICKER -> {
return ITEM_TYPE_STICKER_MESSAGE
}
else -> return ITEM_TYPE_TEXT_MESSAGE
}
}
}
throw UnsupportedOperationException()
}
companion object {
const val ITEM_TYPE_TEXT_MESSAGE = 1
const val ITEM_TYPE_STICKER_MESSAGE = 2
}
}

View File

@ -7,13 +7,13 @@ import android.view.ViewGroup
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
import org.mariotaku.twidere.model.ItemCounts
import org.mariotaku.twidere.model.ParcelableMessageConversation
import org.mariotaku.twidere.view.holder.message.MessageConversationViewHolder
import org.mariotaku.twidere.view.holder.message.MessageEntryViewHolder
/**
* Created by mariotaku on 2017/2/9.
*/
class MessagesConversationsAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
class MessagesEntriesAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
IItemCountsAdapter {
override val itemCounts: ItemCounts = ItemCounts(1)
@ -40,15 +40,15 @@ class MessagesConversationsAdapter(context: Context) : LoadMoreSupportAdapter<Re
when (holder.itemViewType) {
ITEM_TYPE_MESSAGE_ENTRY -> {
val conversation = getConversation(position)!!
(holder as MessageConversationViewHolder).display(conversation)
(holder as MessageEntryViewHolder).display(conversation)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val itemView = inflater.inflate(MessageConversationViewHolder.layoutResource, parent, false)
return MessageConversationViewHolder(itemView, this)
val itemView = inflater.inflate(MessageEntryViewHolder.layoutResource, parent, false)
return MessageEntryViewHolder(itemView, this)
}
override fun getItemViewType(position: Int): Int {

View File

@ -1,19 +1,62 @@
package org.mariotaku.twidere.fragment
import android.os.Bundle
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.support.v7.widget.FixedLinearLayoutManager
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.sqliteqb.library.OrderBy
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesConversationAdapter
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_CONVERSATION_ID
import org.mariotaku.twidere.loader.ObjectCursorLoader
import org.mariotaku.twidere.model.ParcelableMessage
import org.mariotaku.twidere.model.ParcelableMessageCursorIndices
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
class MessagesConversationFragment : BaseFragment() {
class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbacks<List<ParcelableMessage>?> {
private lateinit var adapter: MessagesConversationAdapter
private val accountKey: UserKey get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY)
private val conversationId: String get() = arguments.getString(EXTRA_CONVERSATION_ID)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter = MessagesConversationAdapter(context)
recyclerView.adapter = adapter
recyclerView.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
loaderManager.initLoader(0, null, this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_messages_conversation, container, false)
}
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ParcelableMessage>?> {
val loader = ObjectCursorLoader(context, ParcelableMessageCursorIndices::class.java)
loader.uri = Messages.CONTENT_URI
loader.projection = Messages.COLUMNS
loader.selection = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
Expression.equalsArgs(Messages.CONVERSATION_ID)).sql
loader.selectionArgs = arrayOf(accountKey.toString(), conversationId)
loader.sortOrder = OrderBy(Messages.LOCAL_TIMESTAMP, true).sql
return loader
}
override fun onLoaderReset(loader: Loader<List<ParcelableMessage>?>) {
adapter.messages = null
}
override fun onLoadFinished(loader: Loader<List<ParcelableMessage>?>, data: List<ParcelableMessage>?) {
adapter.messages = data
}
}

View File

@ -7,7 +7,7 @@ import android.support.v4.content.Loader
import org.mariotaku.kpreferences.get
import org.mariotaku.sqliteqb.library.OrderBy
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesConversationsAdapter
import org.mariotaku.twidere.adapter.MessagesEntriesAdapter
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.extension.model.user
import org.mariotaku.twidere.loader.ObjectCursorLoader
@ -24,8 +24,8 @@ import org.mariotaku.twidere.util.Utils
/**
* Created by mariotaku on 16/3/28.
*/
class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesConversationsAdapter>(),
LoaderManager.LoaderCallbacks<List<ParcelableMessageConversation>?>, MessagesConversationsAdapter.MessageConversationClickListener {
class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntriesAdapter>(),
LoaderManager.LoaderCallbacks<List<ParcelableMessageConversation>?>, MessagesEntriesAdapter.MessageConversationClickListener {
private val accountKeys: Array<UserKey>
get() = Utils.getAccountKeys(context, arguments) ?: DataStoreUtils.getActivatedAccountKeys(context)
@ -56,8 +56,8 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesConve
showContentOrError()
}
override fun onCreateAdapter(context: Context): MessagesConversationsAdapter {
return MessagesConversationsAdapter(context)
override fun onCreateAdapter(context: Context): MessagesEntriesAdapter {
return MessagesEntriesAdapter(context)
}
override fun triggerRefresh(): Boolean {

View File

@ -52,7 +52,7 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
.resetViewBeforeLoading(true)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.ARGB_8888)
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
private val dashboardProfileImageDisplayOptions = DisplayImageOptions.Builder()
@ -77,6 +77,14 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
.build()
private val stickerDisplayOptions = DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.showImageOnLoading(android.R.color.transparent)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.ARGB_8888)
.build()
fun displayPreviewImage(view: ImageView, url: String?) {
imageLoader.displayImage(url, view, previewDisplayOptions)
}
@ -172,6 +180,11 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
imageLoader.displayImage(url, view)
}
fun displayStickerImage(view: ImageView, url: String?) {
imageLoader.displayImage(url, view, stickerDisplayOptions)
}
fun displayProfileImage(view: ImageView, url: String?, listener: ImageLoadingListener) {
imageLoader.displayImage(url, view, profileImageDisplayOptions, listener)
}

View File

@ -21,13 +21,14 @@ package org.mariotaku.twidere.view.holder.message
import android.support.v7.widget.RecyclerView
import android.view.View
import org.mariotaku.twidere.adapter.MessagesConversationAdapter
import org.mariotaku.twidere.model.ParcelableMessage
/**
* Created by mariotaku on 2017/2/9.
*/
abstract class AbsMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
abstract class AbsMessageViewHolder(itemView: View, val adapter: MessagesConversationAdapter) : RecyclerView.ViewHolder(itemView) {
open fun display(message: ParcelableMessage) {
}

View File

@ -23,7 +23,7 @@ import android.support.v7.widget.RecyclerView
import android.view.View
import kotlinx.android.synthetic.main.list_item_message_entry.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesConversationsAdapter
import org.mariotaku.twidere.adapter.MessagesEntriesAdapter
import org.mariotaku.twidere.extension.model.getConversationName
import org.mariotaku.twidere.extension.model.getSummaryText
import org.mariotaku.twidere.extension.model.timestamp
@ -35,7 +35,7 @@ import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationTyp
* Created by mariotaku on 2017/2/9.
*/
class MessageConversationViewHolder(itemView: View, val adapter: MessagesConversationsAdapter) : RecyclerView.ViewHolder(itemView) {
class MessageEntryViewHolder(itemView: View, val adapter: MessagesEntriesAdapter) : RecyclerView.ViewHolder(itemView) {
private val content by lazy { itemView.content }
private val time by lazy { itemView.time }

View File

@ -19,25 +19,57 @@
package org.mariotaku.twidere.view.holder.message
import android.support.v4.view.GravityCompat
import android.view.View
import android.widget.FrameLayout
import kotlinx.android.synthetic.main.list_item_message_conversation_text.view.*
import org.mariotaku.ktextension.isNullOrEmpty
import org.mariotaku.messagebubbleview.library.MessageBubbleView
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesConversationAdapter
import org.mariotaku.twidere.extension.model.timestamp
import org.mariotaku.twidere.model.ParcelableMessage
/**
* Created by mariotaku on 2017/2/9.
*/
class MessageViewHolder(itemView: View) : AbsMessageViewHolder(itemView) {
class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) : AbsMessageViewHolder(itemView, adapter) {
private val text by lazy { itemView.text }
private val time by lazy { itemView.time }
private val mediaPreview by lazy { itemView.mediaPreview }
private val messageContent by lazy { itemView.messageContent }
override fun display(message: ParcelableMessage) {
super.display(message)
setOutgoingStatus(messageContent, message.is_outgoing)
text.text = message.text_unescaped
time.time = message.timestamp
if (message.media.isNullOrEmpty()) {
mediaPreview.visibility = View.GONE
} else {
mediaPreview.visibility = View.VISIBLE
mediaPreview.displayMedia(adapter.mediaLoader, message.media, message.account_key,
withCredentials = true)
}
}
companion object {
const val layoutResource = R.layout.list_item_message_conversation_text
fun setOutgoingStatus(view: MessageBubbleView, outgoing: Boolean) {
view.setCaretPosition(if (outgoing) MessageBubbleView.BOTTOM_END else MessageBubbleView.BOTTOM_START)
setMessageContentGravity(view, outgoing)
}
fun setMessageContentGravity(view: View, outgoing: Boolean) {
val lp = view.layoutParams
when (lp) {
is FrameLayout.LayoutParams -> {
lp.gravity = if (outgoing) GravityCompat.END else GravityCompat.START
}
}
}
}
}

View File

@ -20,11 +20,29 @@
package org.mariotaku.twidere.view.holder.message
import android.view.View
import kotlinx.android.synthetic.main.list_item_message_conversation_sticker.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesConversationAdapter
import org.mariotaku.twidere.model.ParcelableMessage
import org.mariotaku.twidere.model.message.StickerExtras
/**
* Created by mariotaku on 2017/2/9.
*/
class StickerMessageViewHolder(itemView: View) : AbsMessageViewHolder(itemView) {
class StickerMessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) : AbsMessageViewHolder(itemView, adapter) {
private val messageContent by lazy { itemView.messageContent }
private val stickerIcon by lazy { itemView.stickerIcon }
override fun display(message: ParcelableMessage) {
super.display(message)
MessageViewHolder.setMessageContentGravity(messageContent, message.is_outgoing)
val extras = message.extras as StickerExtras
adapter.mediaLoader.displayStickerImage(stickerIcon, extras.url)
}
companion object {
const val layoutResource = R.layout.list_item_message_conversation_sticker
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/element_spacing_normal">
<RelativeLayout
android:id="@+id/messageContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/stickerIcon"
android:layout_width="96dp"
android:layout_height="96dp"
android:contentDescription="@string/content_description_sticker"
android:scaleType="fitCenter"/>
</RelativeLayout>
</FrameLayout>

View File

@ -17,20 +17,20 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:padding="@dimen/element_spacing_normal">
<org.mariotaku.messagebubbleview.library.MessageBubbleView
android:id="@+id/messageContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
app:bubbleColor="?colorAccent"
app:bubbleColor="?android:colorBackground"
app:caretHeight="8dp"
app:caretPosition="topStart"
app:caretWidth="8dp"
@ -43,7 +43,8 @@
<org.mariotaku.twidere.view.CardMediaContainer
android:id="@+id/mediaPreview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:visibility="gone">
<include layout="@layout/layout_card_media_preview"/>
@ -52,7 +53,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/media_preview_container"
android:layout_below="@+id/mediaPreview"
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
@ -64,7 +65,7 @@
android:textColor="?android:attr/textColorSecondary"
tools:text="@string/sample_status_text"/>
<org.mariotaku.twidere.view.FixedTextView
<org.mariotaku.twidere.view.ShortTimeView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -75,4 +76,4 @@
</RelativeLayout>
</org.mariotaku.messagebubbleview.library.MessageBubbleView>
</RelativeLayout>
</FrameLayout>

View File

@ -31,7 +31,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
app:ignorePadding="true"
tools:context=".adapter.MessagesConversationsAdapter">
tools:context=".adapter.MessagesEntriesAdapter">
<org.mariotaku.twidere.view.ProfileImageView
android:id="@+id/profileImage"

View File

@ -325,6 +325,7 @@
<string name="content">Content</string>
<string name="content_and_storage">Content &amp; Storage</string>
<string name="content_description_sticker">Sticker</string>
<string name="content_to_notify">Content to notify</string>
<string name="content_to_refresh">Content to refresh</string>