diff --git a/app/src/main/java/app/fedilab/android/helper/RecyclerViewThreadLines.kt b/app/src/main/java/app/fedilab/android/helper/RecyclerViewThreadLines.kt deleted file mode 100644 index bfad6bf8..00000000 --- a/app/src/main/java/app/fedilab/android/helper/RecyclerViewThreadLines.kt +++ /dev/null @@ -1,144 +0,0 @@ -package app.fedilab.android.helper -/* - * This file is a part of Fedilab - * - * 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. - * - * Fedilab 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 Fedilab; if not, - * see . */ - -import android.content.Context -import android.content.res.Resources -import android.graphics.* -import android.view.View -import androidx.core.content.res.ResourcesCompat -import androidx.preference.PreferenceManager -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.RecyclerView -import app.fedilab.android.R -import app.fedilab.android.helper.RecyclerViewThreadLines.LineInfo -import app.fedilab.android.client.entities.api.Context as StatusContext - -class RecyclerViewThreadLines(context: Context, private val lineInfoList: List) : DividerItemDecoration(context, VERTICAL) { - private val lineColors = threadLineColors.map { ResourcesCompat.getColor(context.resources, it, context.theme) } - private val dashPathEffect = DashPathEffect(floatArrayOf(3.dpToPx, 3.dpToPx), 0F) - private val borderColor = lineColors[0] - private val commonPaint = Paint().apply { - isDither = false - strokeWidth = 1.5F.dpToPx - strokeCap = Paint.Cap.BUTT - strokeJoin = Paint.Join.MITER - color = borderColor - } - private val maxLevel = lineColors.size - private val fontScale = PreferenceManager.getDefaultSharedPreferences(context).getFloat(context.getString(R.string.SET_FONT_SCALE), 1.1f).toInt() - private val baseMargin: Int = 6.dpToPx.toInt() - private val margin: Int = baseMargin * fontScale - - override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { - val position = parent.getChildAdapterPosition(view) - if (position < 0 || position >= lineInfoList.size) return - val level = lineInfoList[position].level - val startMargin = margin * level + margin * fontScale - if (parent.layoutDirection == View.LAYOUT_DIRECTION_LTR) outRect.left = startMargin else outRect.right = startMargin - } - - override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { - val childCount = parent.childCount - for (i in 0 until childCount) { - val view = parent.getChildAt(i) - val position = parent.getChildAdapterPosition(view) - if (position < 0 || position >= lineInfoList.size) return - val lineInfo = lineInfoList[position] - val level = lineInfo.level - - for (j in 0..level) { - val lineMargin = margin * j.coerceAtLeast(1) + 3.dpToPx - val lineStart = if (parent.layoutDirection == View.LAYOUT_DIRECTION_LTR) lineMargin else c.width - lineMargin - var lineTop: Float = (view.top - baseMargin).toFloat() - val paint = Paint(commonPaint) - paint.color = if (j > 0) lineColors[j - 1] else Color.GRAY - - // draw lines for below statuses - if (j != level && lineInfo.lines.contains(j)) - c.drawLine(lineStart, lineTop, lineStart, view.bottom.toFloat(), paint) - - // draw vertical line for current statuses - if (j == level && position != 0) { - // top the line starts at the middle of the above status - if (i > 0) lineTop -= parent.getChildAt(i - 1).height / 2 - 1 // '- 1' is to prevent overlapping with above horizontal line - - // bottom of the line ends at the middle of the current status - var lineBottom = view.bottom.toFloat() - view.height / 2 - - // if below status has a full line for current level, extend the line to the bottom - if (position < lineInfoList.lastIndex && lineInfoList[position + 1].lines.contains(level) && j != maxLevel) - lineBottom = view.bottom.toFloat() - - // if level is max, use a dashed line - if (j == maxLevel) paint.pathEffect = dashPathEffect - - c.drawLine(lineStart, lineTop, lineStart, lineBottom, paint) - } - - // draw horizontal line for current statuses - if (j == level) { - lineTop = view.bottom.toFloat() - view.height / 2 - val lineEnd = lineStart + margin * 2 - c.drawLine(lineStart - 1, lineTop, lineEnd, lineTop, paint) // 'lineStart - 1' is to properly connect with the vertical line - } - } - } - } - - data class LineInfo(var level: Int, var lines: List) - - private val Int.dpToPx: Float - get() = this * Resources.getSystem().displayMetrics.density - - private val Float.dpToPx: Float - get() = this * Resources.getSystem().displayMetrics.density - - companion object { - val threadLineColors = listOf(R.color.decoration_1, R.color.decoration_2, R.color.decoration_3, R.color.decoration_4, R.color.decoration_5) - } -} - -fun getThreadDecorationInfo(statusContext: StatusContext): MutableList { - val lineInfoList = mutableListOf() - repeat(statusContext.ancestors.size) { lineInfoList.add(LineInfo(0, listOf(0))) } - lineInfoList.add(LineInfo(0, listOf(0))) - val descendantsLineInfoList = List(statusContext.descendants.size) { LineInfo(0, listOf()) } - for (i in statusContext.descendants.indices) { - statusContext.descendants[i].let { status -> - var level = 0 - if (status.in_reply_to_id != null) { - var replyToId: String? = status.in_reply_to_id - while (replyToId != null && level < RecyclerViewThreadLines.threadLineColors.size) { - level += 1 - replyToId = statusContext.descendants.firstOrNull { it.id == replyToId }?.in_reply_to_id - } - } - descendantsLineInfoList[i].level = level - } - } - for (i in descendantsLineInfoList.indices.reversed()) { - val lines: MutableList = mutableListOf() - val lineInfo = descendantsLineInfoList[i] - lines.add(lineInfo.level) - if (i < descendantsLineInfoList.lastIndex) { - val belowLineInfo = descendantsLineInfoList[i + 1] - lines.addAll(belowLineInfo.lines.filter { it < lineInfo.level }) - } - descendantsLineInfoList[i].lines = lines - } - - lineInfoList.addAll(descendantsLineInfoList) - return lineInfoList -} diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java index 76833930..d27904f1 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java @@ -142,7 +142,7 @@ public class StatusAdapter extends RecyclerView.Adapter } - private static boolean isVisble(Timeline.TimeLineEnum timelineType, Status status) { + private static boolean isVisible(Timeline.TimeLineEnum timelineType, Status status) { if (timelineType == Timeline.TimeLineEnum.HOME && !show_boosts && status.reblog != null) { return false; } @@ -316,9 +316,10 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.translationLabel.setBackgroundColor(theme_statuses_color); } if (theme_boost_header_color != -1 && status.reblog != null) { - holder.binding.headerContainer.setBackgroundColor(theme_boost_header_color); + holder.binding.statusBoosterInfo.setBackgroundColor(theme_boost_header_color); + } else { - holder.binding.headerContainer.setBackgroundColor(0); + holder.binding.statusBoosterInfo.setBackgroundColor(0); } if (theme_text_color != -1) { holder.binding.statusContent.setTextColor(theme_text_color); @@ -750,9 +751,19 @@ public class StatusAdapter extends RecyclerView.Adapter //--- BOOSTER INFO --- if (status.reblog != null) { MastodonHelper.loadPPMastodon(holder.binding.statusBoosterAvatar, status.account); + holder.binding.statusBoosterDisplayName.setText(status.account.span_display_name, TextView.BufferType.SPANNABLE); holder.binding.statusBoosterInfo.setVisibility(View.VISIBLE); + holder.binding.boosterDivider.setVisibility(View.VISIBLE); + if (theme_text_header_1_line != -1) { + holder.binding.statusBoosterDisplayName.setTextColor(theme_text_header_1_line); + } + holder.binding.statusBoosterUsername.setText(String.format("@%s", status.account.acct)); + if (theme_text_header_2_line != -1) { + holder.binding.statusBoosterUsername.setTextColor(theme_text_header_2_line); + } } else { holder.binding.statusBoosterInfo.setVisibility(View.GONE); + holder.binding.boosterDivider.setVisibility(View.GONE); } //--- BOOST VISIBILITY --- switch (status.visibility) { @@ -1171,6 +1182,9 @@ public class StatusAdapter extends RecyclerView.Adapter return false; }); if (!minified) { + holder.binding.mainContainer.setOnClickListener(v -> { + holder.binding.statusContent.callOnClick(); + }); holder.binding.statusContent.setOnClickListener(v -> { if (status.isFocused || v.getTag() == SpannableHelper.CLICKABLE_SPAN) { if (v.getTag() == SpannableHelper.CLICKABLE_SPAN) { @@ -1568,7 +1582,7 @@ public class StatusAdapter extends RecyclerView.Adapter if (timelineType == Timeline.TimeLineEnum.ART) { return STATUS_ART; } else { - return isVisble(timelineType, statusList.get(position)) ? STATUS_VISIBLE : STATUS_HIDDEN; + return isVisible(timelineType, statusList.get(position)) ? STATUS_VISIBLE : STATUS_HIDDEN; } } diff --git a/app/src/main/res/layout/drawer_status.xml b/app/src/main/res/layout/drawer_status.xml index 65a127cc..22b4d111 100644 --- a/app/src/main/res/layout/drawer_status.xml +++ b/app/src/main/res/layout/drawer_status.xml @@ -30,10 +30,58 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="6dp" + android:id="@+id/main_container" android:clipChildren="false" android:clipToPadding="false" android:orientation="vertical"> + + + + + + + + + + + + + + tools:src="@tools:sample/avatars" /> - + android:orientation="vertical"> + + + + + + + + + + + + + - - - - - - - - - @@ -125,27 +176,29 @@ android:id="@+id/spoiler" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="6dp" + android:layout_marginStart="48dp" android:layout_marginTop="6dp" + android:layout_marginEnd="6dp" tools:text="Warning: Lorem Ipsum below" /> - + android:textColor="@color/cyanea_accent_dark_reference" /> @@ -158,20 +211,22 @@ android:layout_gravity="center" android:drawableEnd="@drawable/ic_display_more" android:gravity="center_vertical" - app:strokeColor="@color/cyanea_accent_dark_reference" android:singleLine="true" android:text="@string/display_toot_truncate" - app:iconTint="@color/cyanea_accent_reference" android:textAllCaps="false" + app:iconTint="@color/cyanea_accent_reference" + app:strokeColor="@color/cyanea_accent_dark_reference" /> - /> + + layout="@layout/layout_poll" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="48dp" + android:layout_marginTop="6dp" + android:layout_marginEnd="6dp" /> @@ -472,20 +539,11 @@ android:layout_height="wrap_content" android:layout_weight="1" /> - - @@ -493,4 +551,4 @@ - \ No newline at end of file + diff --git a/app/src/main/res/layout/drawer_status_compact.xml b/app/src/main/res/layout/drawer_status_compact.xml new file mode 100644 index 00000000..9f9b3821 --- /dev/null +++ b/app/src/main/res/layout/drawer_status_compact.xml @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file