diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 57119ef94983e12cbfa9c24626bd7705ee1abfd2..0c685e6df4ce92ec7983404f4090e247f93ddca3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -146,6 +146,11 @@ dependencies { implementation("com.afollestad.material-dialogs", "core", version) implementation("com.afollestad.material-dialogs", "commons", version) } + withVersion("4.6.1") { + implementation("com.github.bumptech.glide", "glide", version) + implementation("com.github.bumptech.glide", "recyclerview-integration", version) + kapt("com.github.bumptech.glide", "compiler", version) + } implementation("com.mikhaellopez", "circularimageview", "3.0.2") implementation("me.saket", "better-link-movement-method", "2.1.0") implementation(project(":slidingpanel")) diff --git a/app/src/main/java/de/kuschku/quasseldroid/QuasseldroidGlideModule.kt b/app/src/main/java/de/kuschku/quasseldroid/QuasseldroidGlideModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..1f9c88d883d18ac20b8e9baa7b18901a787f067e --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/QuasseldroidGlideModule.kt @@ -0,0 +1,7 @@ +package de.kuschku.quasseldroid + +import com.bumptech.glide.annotation.GlideModule +import com.bumptech.glide.module.AppGlideModule + +@GlideModule +class QuasseldroidGlideModule : AppGlideModule() \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt index ad6401441368012da2f2c5db0e546d7d959975bf..67d488f269cadbe761b59cb1605b17cbf3a88262 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt @@ -1,6 +1,7 @@ package de.kuschku.quasseldroid.ui.chat.messages import de.kuschku.libquassel.protocol.MsgId +import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.quasseldroid.persistence.QuasselDatabase data class DisplayMessage( @@ -17,4 +18,9 @@ data class DisplayMessage( ) val tag = Tag(content.messageId, isSelected, isExpanded, isMarkerLine) + val avatarUrl = content.sender.let { + Regex("[us]id(\\d+)").matchEntire(HostmaskHelper.user(it))?.groupValues?.lastOrNull()?.let { + "https://www.irccloud.com/avatar-redirect/$it" + } + } } \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt index 9ed9d1799ff592962804b3477fcb0f52ee1ad0ad..14f411ac93199f065563485a4069f6f33039d1a9 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt @@ -8,14 +8,17 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView +import android.widget.Space import android.widget.TextView import butterknife.BindView import butterknife.ButterKnife +import com.bumptech.glide.request.RequestOptions import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Flags import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.protocol.Message_Types import de.kuschku.libquassel.util.hasFlag +import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.QuasselDatabase import de.kuschku.quasseldroid.util.helper.getOrPut @@ -104,11 +107,11 @@ class MessageAdapter( selectionListener: ((FormattedMessage) -> Unit)? = null, expansionListener: ((QuasselDatabase.DatabaseMessage) -> Unit)? = null ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.timeLeft) + @BindView(R.id.time_left) @JvmField var timeLeft: TextView? = null - @BindView(R.id.timeRight) + @BindView(R.id.time_right) @JvmField var timeRight: TextView? = null @@ -116,6 +119,10 @@ class MessageAdapter( @JvmField var avatar: ImageView? = null + @BindView(R.id.avatar_placeholder) + @JvmField + var avatarPlaceholder: Space? = null + @BindView(R.id.name) @JvmField var name: TextView? = null @@ -176,6 +183,14 @@ class MessageAdapter( markerline?.visibleIf(message.isMarkerLine) this.itemView.isSelected = message.isSelected + + avatar?.let { avatarView -> + GlideApp.with(itemView) + .load(message.avatarUrl) + .apply(RequestOptions.circleCropTransform()) + .placeholder(message.fallbackDrawable) + .into(avatarView) + } } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt index eafe08b53c2421d58728ead11a295dfe15e73e2c..75fa1faf8e7aea77b71384bad84b3ea1ff82c491 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt @@ -25,9 +25,7 @@ import de.kuschku.quasseldroid.persistence.findByBufferIdPagedWithDayChange import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.BacklogSettings import de.kuschku.quasseldroid.settings.MessageSettings -import de.kuschku.quasseldroid.settings.Settings import de.kuschku.quasseldroid.util.helper.* -import de.kuschku.quasseldroid.util.irc.format.ContentFormatter import de.kuschku.quasseldroid.util.service.ServiceBoundFragment import de.kuschku.quasseldroid.util.ui.SpanFormatter import io.reactivex.BackpressureStrategy @@ -313,6 +311,25 @@ class MessageListFragment : ServiceBoundFragment() { messageList.layoutManager.onRestoreInstanceState(getParcelable(KEY_STATE_LIST)) } + /* + val avatar_size = resources.getDimensionPixelSize(R.dimen.avatar_size) + + val sizeProvider = FixedPreloadSizeProvider<String>(avatar_size, avatar_size) + + val preloadModelProvider = object : ListPreloader.PreloadModelProvider<String> { + override fun getPreloadItems(position: Int) = adapter[position]?.avatarUrl?.let { + mutableListOf(it) + } ?: mutableListOf() + + override fun getPreloadRequestBuilder(item: String) = + GlideApp.with(this@MessageListFragment).load(item).override(avatar_size) + } + + val preloader = RecyclerViewPreloader(Glide.with(this), preloadModelProvider, sizeProvider, 10) + + messageList.addOnScrollListener(preloader) + */ + return view } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt index cccaa521a6eb68ae97f7f4ca7bdcabf2ee01c1ff..99aadeed13b6d5c44f3c37aee7889b89bb210ba4 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt @@ -12,6 +12,7 @@ import de.kuschku.libquassel.protocol.Message.MessageType.* import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.util.hasFlag +import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.QuasselDatabase import de.kuschku.quasseldroid.settings.MessageSettings @@ -22,6 +23,7 @@ import de.kuschku.quasseldroid.util.helper.visibleIf import de.kuschku.quasseldroid.util.irc.format.ContentFormatter import de.kuschku.quasseldroid.util.quassel.IrcUserUtils import de.kuschku.quasseldroid.util.ui.SpanFormatter +import de.kuschku.quasseldroid.util.ui.TextDrawable import de.kuschku.quasseldroid.viewmodel.data.FormattedMessage import org.threeten.bp.ZoneId import org.threeten.bp.format.DateTimeFormatter @@ -50,6 +52,7 @@ class QuasselMessageRenderer @Inject constructor( } private lateinit var senderColors: IntArray + private var selfColor: Int = 0 private val zoneId = ZoneId.systemDefault() @@ -92,7 +95,8 @@ class QuasselMessageRenderer @Inject constructor( viewHolder.combined?.typeface = if (viewHolder.combined?.typeface?.isItalic == true) monospaceItalic else Typeface.MONOSPACE } - viewHolder.avatar?.visibleIf(messageSettings.showAvatars) + viewHolder.avatar?.visibleIf(messageSettings.showAvatars || true) + viewHolder.avatarPlaceholder?.visibleIf(messageSettings.showAvatars || true) val separateLine = viewHolder.content != null && viewHolder.name != null && messageSettings.nicksOnNewLine viewHolder.name?.visibleIf(separateLine) viewHolder.content?.visibleIf(separateLine) @@ -121,11 +125,13 @@ class QuasselMessageRenderer @Inject constructor( R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3, R.attr.senderColor4, R.attr.senderColor5, R.attr.senderColor6, R.attr.senderColor7, R.attr.senderColor8, R.attr.senderColor9, R.attr.senderColorA, R.attr.senderColorB, - R.attr.senderColorC, R.attr.senderColorD, R.attr.senderColorE, R.attr.senderColorF + R.attr.senderColorC, R.attr.senderColorD, R.attr.senderColorE, R.attr.senderColorF, + R.attr.colorForegroundSecondary ) { senderColors = IntArray(16) { getColor(it, 0) } + selfColor = getColor(16, 0) } val self = Message_Flag.of(message.content.flag).hasFlag(Message_Flag.Self) @@ -138,12 +144,23 @@ class QuasselMessageRenderer @Inject constructor( formatNick(message.content.sender, self, highlight, false) ) val content = contentFormatter.format(context, message.content.content, highlight) + val nickName = HostmaskHelper.nick(message.content.sender) + val senderColorIndex = IrcUserUtils.senderColor(nickName) + val initial = nickName.trimStart('-', '_', '[', ']', '{', '}', '|', '`', '^', '.', '\\') + .firstOrNull()?.toUpperCase().toString() + val senderColor = if (Message_Flag.of(message.content.flag).hasFlag(Message_Flag.Self)) + selfColor + else + senderColors[senderColorIndex] + FormattedMessage( id = message.content.messageId, time = timeFormatter.format(message.content.time.atZone(zoneId)), name = nick, content = content, combined = SpanFormatter.format("%s: %s", nick, content), + avatarUrl = message.avatarUrl, + fallbackDrawable = TextDrawable.builder().buildRound(initial, senderColor), isMarkerLine = message.isMarkerLine, isExpanded = message.isExpanded, isSelected = message.isSelected diff --git a/app/src/main/java/com/robobunny/SeekBarPreference.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/SeekBarPreference.kt similarity index 90% rename from app/src/main/java/com/robobunny/SeekBarPreference.kt rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/SeekBarPreference.kt index ba5496d66f5643c2d6450347011b8307a1ae2166..d5635f39dd6bd7ebbca8838959e519750f2748a4 100644 --- a/app/src/main/java/com/robobunny/SeekBarPreference.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/SeekBarPreference.kt @@ -1,4 +1,4 @@ -package com.robobunny +package de.kuschku.quasseldroid.util.ui import android.content.Context import android.content.res.TypedArray @@ -75,9 +75,12 @@ class SeekBarPreference : Preference, SeekBar.OnSeekBarChangeListener { private fun setValuesFromXml(attrs: AttributeSet) { maxValue = attrs.getAttributeIntValue(NAMESPACE_ANDROID, "max", 100) minValue = attrs.getAttributeIntValue(NAMESPACE_ROBOBUNNY, "min", 0) - unitsLeftText = getAttributeStringValue(attrs, NAMESPACE_ROBOBUNNY, "unitsLeft", "") - val units = getAttributeStringValue(attrs, NAMESPACE_ROBOBUNNY, "units", "") - unitsRightText = getAttributeStringValue(attrs, NAMESPACE_ROBOBUNNY, "unitsRight", units) + unitsLeftText = getAttributeStringValue(attrs, + NAMESPACE_ROBOBUNNY, "unitsLeft", "") + val units = getAttributeStringValue(attrs, + NAMESPACE_ROBOBUNNY, "units", "") + unitsRightText = getAttributeStringValue(attrs, + NAMESPACE_ROBOBUNNY, "unitsRight", units) try { val newInterval = attrs.getAttributeValue(NAMESPACE_ROBOBUNNY, "interval") if (newInterval != null) @@ -126,7 +129,8 @@ class SeekBarPreference : Preference, SeekBar.OnSeekBarChangeListener { override fun onStartTrackingTouch(seekBar: SeekBar) = Unit override fun onStopTrackingTouch(seekBar: SeekBar) = notifyChanged() - override fun onGetDefaultValue(ta: TypedArray, index: Int) = ta.getInt(index, DEFAULT_VALUE) + override fun onGetDefaultValue(ta: TypedArray, index: Int) = ta.getInt(index, + DEFAULT_VALUE) override fun onSetInitialValue(restoreValue: Boolean, defaultValue: Any?) { if (restoreValue) { currentValue = getPersistedInt(currentValue) diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/TextDrawable.java b/app/src/main/java/de/kuschku/quasseldroid/util/ui/TextDrawable.java new file mode 100644 index 0000000000000000000000000000000000000000..7938d6c385c527733d01125558539209dabb45bc --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/TextDrawable.java @@ -0,0 +1,310 @@ +package de.kuschku.quasseldroid.util.ui; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Typeface; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.OvalShape; +import android.graphics.drawable.shapes.RectShape; +import android.graphics.drawable.shapes.RoundRectShape; + +/** + * @author amulya + * @datetime 14 Oct 2014, 3:53 PM + */ +public class TextDrawable extends ShapeDrawable { + + private static final float SHADE_FACTOR = 0.9f; + private final Paint textPaint; + private final Paint borderPaint; + private final String text; + private final int color; + private final RectShape shape; + private final int height; + private final int width; + private final int fontSize; + private final float radius; + private final int borderThickness; + + private TextDrawable(Builder builder) { + super(builder.shape); + + // shape properties + shape = builder.shape; + height = builder.height; + width = builder.width; + radius = builder.radius; + + // text and color + text = builder.toUpperCase ? builder.text.toUpperCase() : builder.text; + color = builder.color; + + // text paint settings + fontSize = builder.fontSize; + textPaint = new Paint(); + textPaint.setColor(builder.textColor); + textPaint.setAntiAlias(true); + textPaint.setFakeBoldText(builder.isBold); + textPaint.setStyle(Paint.Style.FILL); + textPaint.setTypeface(builder.font); + textPaint.setTextAlign(Paint.Align.CENTER); + textPaint.setStrokeWidth(builder.borderThickness); + + // border paint settings + borderThickness = builder.borderThickness; + borderPaint = new Paint(); + borderPaint.setColor(getDarkerShade(color)); + borderPaint.setStyle(Paint.Style.STROKE); + borderPaint.setStrokeWidth(borderThickness); + + // drawable paint color + Paint paint = getPaint(); + paint.setColor(color); + + } + + public static IShapeBuilder builder() { + return new Builder(); + } + + private int getDarkerShade(int color) { + return Color.rgb((int) (SHADE_FACTOR * Color.red(color)), + (int) (SHADE_FACTOR * Color.green(color)), + (int) (SHADE_FACTOR * Color.blue(color))); + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + Rect r = getBounds(); + + + // draw border + if (borderThickness > 0) { + drawBorder(canvas); + } + + int count = canvas.save(); + canvas.translate(r.left, r.top); + + // draw text + int width = this.width < 0 ? r.width() : this.width; + int height = this.height < 0 ? r.height() : this.height; + int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize; + textPaint.setTextSize(fontSize); + canvas.drawText(text, width / 2, height / 2 - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint); + + canvas.restoreToCount(count); + + } + + private void drawBorder(Canvas canvas) { + RectF rect = new RectF(getBounds()); + rect.inset(borderThickness / 2, borderThickness / 2); + + if (shape instanceof OvalShape) { + canvas.drawOval(rect, borderPaint); + } else if (shape instanceof RoundRectShape) { + canvas.drawRoundRect(rect, radius, radius, borderPaint); + } else { + canvas.drawRect(rect, borderPaint); + } + } + + @Override + public void setAlpha(int alpha) { + textPaint.setAlpha(alpha); + } + + @Override + public void setColorFilter(ColorFilter cf) { + textPaint.setColorFilter(cf); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public int getIntrinsicWidth() { + return width; + } + + @Override + public int getIntrinsicHeight() { + return height; + } + + public interface IConfigBuilder { + public IConfigBuilder width(int width); + + public IConfigBuilder height(int height); + + public IConfigBuilder textColor(int color); + + public IConfigBuilder withBorder(int thickness); + + public IConfigBuilder useFont(Typeface font); + + public IConfigBuilder fontSize(int size); + + public IConfigBuilder bold(); + + public IConfigBuilder toUpperCase(); + + public IShapeBuilder endConfig(); + } + + public static interface IBuilder { + + public TextDrawable build(String text, int color); + } + + public static interface IShapeBuilder { + + public IConfigBuilder beginConfig(); + + public IBuilder rect(); + + public IBuilder round(); + + public IBuilder roundRect(int radius); + + public TextDrawable buildRect(String text, int color); + + public TextDrawable buildRoundRect(String text, int color, int radius); + + public TextDrawable buildRound(String text, int color); + } + + public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder { + + public int textColor; + public float radius; + private String text; + private int color; + private int borderThickness; + private int width; + private int height; + private Typeface font; + private RectShape shape; + private int fontSize; + private boolean isBold; + private boolean toUpperCase; + + private Builder() { + text = ""; + color = Color.GRAY; + textColor = Color.WHITE; + borderThickness = 0; + width = -1; + height = -1; + shape = new RectShape(); + font = Typeface.create("sans-serif-light", Typeface.NORMAL); + fontSize = -1; + isBold = false; + toUpperCase = false; + } + + public IConfigBuilder width(int width) { + this.width = width; + return this; + } + + public IConfigBuilder height(int height) { + this.height = height; + return this; + } + + public IConfigBuilder textColor(int color) { + this.textColor = color; + return this; + } + + public IConfigBuilder withBorder(int thickness) { + this.borderThickness = thickness; + return this; + } + + public IConfigBuilder useFont(Typeface font) { + this.font = font; + return this; + } + + public IConfigBuilder fontSize(int size) { + this.fontSize = size; + return this; + } + + public IConfigBuilder bold() { + this.isBold = true; + return this; + } + + public IConfigBuilder toUpperCase() { + this.toUpperCase = true; + return this; + } + + @Override + public IConfigBuilder beginConfig() { + return this; + } + + @Override + public IShapeBuilder endConfig() { + return this; + } + + @Override + public IBuilder rect() { + this.shape = new RectShape(); + return this; + } + + @Override + public IBuilder round() { + this.shape = new OvalShape(); + return this; + } + + @Override + public IBuilder roundRect(int radius) { + this.radius = radius; + float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius}; + this.shape = new RoundRectShape(radii, null, null); + return this; + } + + @Override + public TextDrawable buildRect(String text, int color) { + rect(); + return build(text, color); + } + + @Override + public TextDrawable buildRoundRect(String text, int color, int radius) { + roundRect(radius); + return build(text, color); + } + + @Override + public TextDrawable buildRound(String text, int color) { + round(); + return build(text, color); + } + + @Override + public TextDrawable build(String text, int color) { + this.color = color; + this.text = text; + return new TextDrawable(this); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/widget_chatmessage_action.xml b/app/src/main/res/layout/widget_chatmessage_action.xml index 9094dadffc8a7c438280cd7bd95c514391030910..86b9479b3fb230a56bbdbd98fca11d3e1d5b0523 100644 --- a/app/src/main/res/layout/widget_chatmessage_action.xml +++ b/app/src/main/res/layout/widget_chatmessage_action.xml @@ -19,7 +19,7 @@ android:paddingTop="@dimen/message_vertical"> <TextView - android:id="@+id/timeLeft" + android:id="@+id/time_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" @@ -29,14 +29,12 @@ android:typeface="monospace" tools:text="@sample/messages.json/data/time" /> - <ImageView - android:id="@+id/avatar" + <Space + android:id="@+id/avatar_placeholder" android:layout_width="40dp" android:layout_height="match_parent" - android:layout_marginBottom="@dimen/message_vertical" android:layout_marginEnd="@dimen/message_horizontal" android:layout_marginRight="@dimen/message_horizontal" - android:layout_marginTop="@dimen/message_vertical" android:visibility="gone" /> <de.kuschku.quasseldroid.ui.chat.messages.RipplePassthroughTextView @@ -49,7 +47,7 @@ tools:text="@sample/messages.json/data/message" /> <TextView - android:id="@+id/timeRight" + android:id="@+id/time_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" diff --git a/app/src/main/res/layout/widget_chatmessage_error.xml b/app/src/main/res/layout/widget_chatmessage_error.xml index 144ef1cd0e1af908dfa31ec90ea3f9fa620934c5..ae61a603494fa5ee985ee65599c099608897e2a9 100644 --- a/app/src/main/res/layout/widget_chatmessage_error.xml +++ b/app/src/main/res/layout/widget_chatmessage_error.xml @@ -19,7 +19,7 @@ android:paddingTop="@dimen/message_vertical"> <TextView - android:id="@+id/timeLeft" + android:id="@+id/time_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/message_horizontal" @@ -28,14 +28,12 @@ android:typeface="monospace" tools:text="@sample/messages.json/data/time" /> - <ImageView - android:id="@+id/avatar" + <Space + android:id="@+id/avatar_placeholder" android:layout_width="40dp" android:layout_height="match_parent" - android:layout_marginBottom="@dimen/message_vertical" android:layout_marginEnd="@dimen/message_horizontal" android:layout_marginRight="@dimen/message_horizontal" - android:layout_marginTop="@dimen/message_vertical" android:visibility="gone" /> <de.kuschku.quasseldroid.ui.chat.messages.RipplePassthroughTextView @@ -47,7 +45,7 @@ tools:text="@sample/messages.json/data/message" /> <TextView - android:id="@+id/timeRight" + android:id="@+id/time_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" diff --git a/app/src/main/res/layout/widget_chatmessage_info.xml b/app/src/main/res/layout/widget_chatmessage_info.xml index 0130f18519b609b0b2bb8abda41e1cfd96ca5c9c..ff9c13fc6a9bc9a8f888a1652e5cc50cd78ca64c 100644 --- a/app/src/main/res/layout/widget_chatmessage_info.xml +++ b/app/src/main/res/layout/widget_chatmessage_info.xml @@ -19,7 +19,7 @@ android:paddingTop="@dimen/message_vertical"> <TextView - android:id="@+id/timeLeft" + android:id="@+id/time_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/message_horizontal" @@ -28,14 +28,12 @@ android:textColor="?attr/colorForegroundSecondary" tools:text="@sample/messages.json/data/time" /> - <ImageView - android:id="@+id/avatar" + <Space + android:id="@+id/avatar_placeholder" android:layout_width="40dp" android:layout_height="match_parent" - android:layout_marginBottom="@dimen/message_vertical" android:layout_marginEnd="@dimen/message_horizontal" android:layout_marginRight="@dimen/message_horizontal" - android:layout_marginTop="@dimen/message_vertical" android:visibility="gone" /> <de.kuschku.quasseldroid.ui.chat.messages.RipplePassthroughTextView @@ -48,7 +46,7 @@ tools:text="@sample/messages.json/data/message" /> <TextView - android:id="@+id/timeRight" + android:id="@+id/time_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" diff --git a/app/src/main/res/layout/widget_chatmessage_notice.xml b/app/src/main/res/layout/widget_chatmessage_notice.xml index 4b202600ce76101d5736f5321e593032274b9c59..f66865be86522c7e5bf1f77ae59918c336f75f07 100644 --- a/app/src/main/res/layout/widget_chatmessage_notice.xml +++ b/app/src/main/res/layout/widget_chatmessage_notice.xml @@ -19,7 +19,7 @@ android:paddingTop="@dimen/message_vertical"> <TextView - android:id="@+id/timeLeft" + android:id="@+id/time_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/message_horizontal" @@ -28,14 +28,12 @@ android:textColor="?attr/colorForegroundNotice" tools:text="@sample/messages.json/data/time" /> - <ImageView - android:id="@+id/avatar" + <Space + android:id="@+id/avatar_placeholder" android:layout_width="40dp" android:layout_height="match_parent" - android:layout_marginBottom="@dimen/message_vertical" android:layout_marginEnd="@dimen/message_horizontal" android:layout_marginRight="@dimen/message_horizontal" - android:layout_marginTop="@dimen/message_vertical" android:visibility="gone" /> <de.kuschku.quasseldroid.ui.chat.messages.RipplePassthroughTextView @@ -47,7 +45,7 @@ tools:text="@sample/messages.json/data/message" /> <TextView - android:id="@+id/timeRight" + android:id="@+id/time_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" diff --git a/app/src/main/res/layout/widget_chatmessage_plain.xml b/app/src/main/res/layout/widget_chatmessage_plain.xml index 384606afd7fc411116f5ca74e0c4e52451dfb855..73b01707bd896d6beaaa33c76c6da1645124c71c 100644 --- a/app/src/main/res/layout/widget_chatmessage_plain.xml +++ b/app/src/main/res/layout/widget_chatmessage_plain.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" @@ -20,7 +19,7 @@ android:paddingTop="@dimen/message_vertical"> <TextView - android:id="@+id/timeLeft" + android:id="@+id/time_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" @@ -30,7 +29,7 @@ android:typeface="monospace" tools:text="@sample/messages.json/data/time" /> - <com.mikhaellopez.circularimageview.CircularImageView + <ImageView android:id="@+id/avatar" android:layout_width="40dp" android:layout_height="40dp" @@ -38,9 +37,7 @@ android:layout_marginEnd="@dimen/message_horizontal" android:layout_marginRight="@dimen/message_horizontal" android:layout_marginTop="@dimen/message_vertical" - android:src="@drawable/profile" - android:visibility="gone" - app:civ_border_width="0dip" /> + android:visibility="gone" /> <LinearLayout android:layout_width="0dip" @@ -76,7 +73,7 @@ </LinearLayout> <TextView - android:id="@+id/timeRight" + android:id="@+id/time_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" diff --git a/app/src/main/res/layout/widget_chatmessage_server.xml b/app/src/main/res/layout/widget_chatmessage_server.xml index f03e1a0a850de8350760b9eadee9eb5d6a2bb650..f29a42e2ea43296604c9e73d25401569db173176 100644 --- a/app/src/main/res/layout/widget_chatmessage_server.xml +++ b/app/src/main/res/layout/widget_chatmessage_server.xml @@ -19,7 +19,7 @@ android:paddingTop="@dimen/message_vertical"> <TextView - android:id="@+id/timeLeft" + android:id="@+id/time_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/message_horizontal" @@ -28,14 +28,12 @@ android:typeface="monospace" tools:text="@sample/messages.json/data/time" /> - <ImageView - android:id="@+id/avatar" + <Space + android:id="@+id/avatar_placeholder" android:layout_width="40dp" android:layout_height="match_parent" - android:layout_marginBottom="@dimen/message_vertical" android:layout_marginEnd="@dimen/message_horizontal" android:layout_marginRight="@dimen/message_horizontal" - android:layout_marginTop="@dimen/message_vertical" android:visibility="gone" /> <de.kuschku.quasseldroid.ui.chat.messages.RipplePassthroughTextView @@ -47,7 +45,7 @@ tools:text="@sample/messages.json/data/message" /> <TextView - android:id="@+id/timeRight" + android:id="@+id/time_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" diff --git a/app/src/main/res/values-de/strings_preferences.xml b/app/src/main/res/values-de/strings_preferences.xml index fffdaaaf2c0dd030aace93af919075d4ee09ab9d..1d19db80f08dd0e0abd5157e01ace25de614f7cb 100644 --- a/app/src/main/res/values-de/strings_preferences.xml +++ b/app/src/main/res/values-de/strings_preferences.xml @@ -49,11 +49,11 @@ <string name="preference_nicks_on_new_line_title">Separate Spitznamen</string> <string name="preference_nicks_on_new_line_summary">Zeigt Spitznamen in einer eigenen Zeile an</string> + <string name="preference_show_avatars_title">Benutzerbilder anzeigen</string> + <string name="preference_time_at_end_title">Rechts-Ausgerichtete Zeit</string> <string name="preference_time_at_end_summary">Zeigt die Zeit rechts in Nachrichten an</string> - <string name="preference_show_avatars_title">Benutzerbilder anzeigen</string> - <string name="preference_autocomplete_title">Autovervollständigung</string> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 1d94a3e670bf1b3493a4603475000e55670df39c..6e63d72cc6b480e38560e06e2d1e2bdadf492dbe 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -12,4 +12,5 @@ <dimen name="button_corner_radius">2dp</dimen> <dimen name="colorchooser_circlesize">56dp</dimen> + <dimen name="avatar_size">40dp</dimen> </resources> diff --git a/app/src/main/res/values/strings_preferences.xml b/app/src/main/res/values/strings_preferences.xml index ddcf32373da6e7e8b70ecd846c23d7146b998346..66e4ee509731cbf0c1863e6f75e3d384ed43d5f2 100644 --- a/app/src/main/res/values/strings_preferences.xml +++ b/app/src/main/res/values/strings_preferences.xml @@ -107,13 +107,13 @@ <string name="preference_nicks_on_new_line_title">Separate Nicknames</string> <string name="preference_nicks_on_new_line_summary">Shows nicknames on a separate line</string> + <string name="preference_show_avatars_key" translatable="false">show_avatars</string> + <string name="preference_show_avatars_title">Show Avatars</string> + <string name="preference_time_at_end_key" translatable="false">time_at_end</string> <string name="preference_time_at_end_title">Right-Aligned Timestamps</string> <string name="preference_time_at_end_summary">Aligns timestamps at the end of each message</string> - <string name="preference_show_avatars_key" translatable="false">show_avatars</string> - <string name="preference_show_avatars_title">Show Avatars</string> - <string name="preference_autocomplete_title">Autocomplete</string> <string name="preference_autocomplete_button_key" translatable="false">autocomplete_button</string> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 880ce39e082b62bc84368134ae8ba782d60f09e0..1d67cdc48cbbca0cd9a577f939b01ecdc0683a00 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -30,7 +30,7 @@ android:key="@string/preference_monospace_key" android:title="@string/preference_monospace_title" /> - <com.robobunny.SeekBarPreference + <de.kuschku.quasseldroid.util.ui.SeekBarPreference android:defaultValue="14" android:key="@string/preference_textsize_key" android:max="24" @@ -69,15 +69,14 @@ <SwitchPreference android:defaultValue="false" - android:key="@string/preference_time_at_end_key" - android:summary="@string/preference_time_at_end_summary" - android:title="@string/preference_time_at_end_title" /> + android:dependency="@string/preference_nicks_on_new_line_summary" + android:key="@string/preference_show_avatars_key" /> - <!-- <SwitchPreference android:defaultValue="false" - android:key="@string/preference_show_avatars_key" /> - --> + android:key="@string/preference_time_at_end_key" + android:summary="@string/preference_time_at_end_summary" + android:title="@string/preference_time_at_end_title" /> </PreferenceCategory> <PreferenceCategory android:title="@string/preference_autocomplete_title"> diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt index b933e85e2647905713143f57da514dce0d4a41d1..fd7c7865b90276fd6f68e6822a7d4cf57709874c 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt @@ -1,11 +1,15 @@ package de.kuschku.quasseldroid.viewmodel.data +import android.graphics.drawable.Drawable + class FormattedMessage( val id: Int, val time: CharSequence, val name: CharSequence? = null, val content: CharSequence? = null, val combined: CharSequence, + val fallbackDrawable: Drawable? = null, + val avatarUrl: String? = null, val isSelected: Boolean, val isExpanded: Boolean, val isMarkerLine: Boolean