Compare commits

...

26 commits

Author SHA1 Message Date
claleb
56cd4f38eb
Translated using Weblate (German)
Currently translated at 100.0% (1085 of 1085 strings)

Co-authored-by: claleb <weblate@claleb.de>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/de/
Translation: Fedilab/Strings
2023-02-08 07:37:08 +01:00
Lukáš Jelínek
abc301b7dd
Translated using Weblate (Czech)
Currently translated at 99.9% (1084 of 1085 strings)

Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/cs/
Translation: Fedilab/Strings
2023-02-08 07:37:07 +01:00
Thomas
a3a3d9350e Fix a bug with media not available 2023-02-07 16:01:05 +01:00
Thomas
34a8a4ee85 Merge remote-tracking branch 'origin/develop' into develop 2023-02-07 15:34:38 +01:00
Thomas
70783bb532 Fix a crash when composing 2023-02-07 15:34:14 +01:00
Thomas
413d11b3c3 Height of media depends of screen size 2023-02-07 15:29:58 +01:00
Poesty Li
8686d16db6
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1085 of 1085 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-02-06 18:50:02 +01:00
Oğuz Ersen
4106802f4a
Translated using Weblate (Turkish)
Currently translated at 100.0% (1085 of 1085 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/
Translation: Fedilab/Strings
2023-02-06 18:50:02 +01:00
Thomas
c2e15c2bfb Add blurhash when available 2023-02-06 18:16:53 +01:00
Thomas
37bc798e38 Fix some crashes 2023-02-06 17:42:00 +01:00
Thomas
5c73717373 Fix some crashes 2023-02-06 14:48:45 +01:00
Thomas
4837afcfb0 Merge pull request 'Fix unpin_tag string used in place of pin_tag.' (#783) from trem/Fedilab:develop into develop
Reviewed-on: https://codeberg.org/tom79/Fedilab/pulls/783
2023-02-06 09:27:56 +00:00
Thomas
810b2e9864 Fix issue #782 - Overlapped texts with "About my instance" 2023-02-06 10:16:45 +01:00
Thomas
2fcb02ea4f Fix issue #780 - Add descriptions to images for drafts 2023-02-06 09:48:37 +01:00
Thomas
3db9d22e48 Fix issue #779 - Focus view for accessibility with visibility when composing 2023-02-06 09:41:53 +01:00
Thomas
f817fd0797 Merge remote-tracking branch 'origin/develop' into develop 2023-02-06 09:34:02 +01:00
Thomas
8bbac74334 Fix issue #778 - Add description to remove button for fields. 2023-02-06 09:33:56 +01:00
SevicheCC
fd13861603
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1080 of 1080 strings)

Co-authored-by: SevicheCC <me@seviche.cc>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-02-06 09:30:25 +01:00
Poesty Li
8177ffd4f3
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1080 of 1080 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-02-06 09:30:25 +01:00
Oğuz Ersen
82d85168d5
Translated using Weblate (Turkish)
Currently translated at 100.0% (1080 of 1080 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/
Translation: Fedilab/Strings
2023-02-06 09:30:25 +01:00
Ajeje Brazorf
4721b185aa
Translated using Weblate (Sardinian)
Currently translated at 99.2% (1072 of 1080 strings)

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/sc/
Translation: Fedilab/Strings
2023-02-06 09:30:25 +01:00
claleb
8e9cb798b7
Translated using Weblate (German)
Currently translated at 100.0% (1080 of 1080 strings)

Co-authored-by: claleb <weblate@claleb.de>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/de/
Translation: Fedilab/Strings
2023-02-06 09:30:25 +01:00
Lukáš Jelínek
e204faed0e
Translated using Weblate (Czech)
Currently translated at 99.9% (1079 of 1080 strings)

Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/cs/
Translation: Fedilab/Strings
2023-02-06 09:30:25 +01:00
Thomas
d78235cb11 Fix issue #777 2023-02-06 09:30:16 +01:00
Thomas
1af2ba3822 Fix issue #776 2023-02-06 09:24:15 +01:00
trem
ad28ddd6b2 Fix unpin_tag string used in place of pin_tag. 2023-02-05 22:02:12 +01:00
20 changed files with 257 additions and 29 deletions

View file

@ -355,7 +355,7 @@ public class HashTagActivity extends BaseActivity {
pin.setIcon(R.drawable.tag_pin_off); pin.setIcon(R.drawable.tag_pin_off);
pin.setTitle(getString(R.string.unpin_tag)); pin.setTitle(getString(R.string.unpin_tag));
} else { } else {
pin.setTitle(getString(R.string.unpin_tag)); pin.setTitle(getString(R.string.pin_tag));
pin.setIcon(R.drawable.tag_pin); pin.setIcon(R.drawable.tag_pin);
} }
} else { } else {

View file

@ -0,0 +1,127 @@
package app.fedilab.android.mastodon.helper
import android.graphics.Bitmap
import android.graphics.Color
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.withSign
class BlurHashDecoder {
fun decode(blurHash: String?, width: Int, height: Int, punch: Float = 1f): Bitmap? {
require(width > 0) { "Width must be greater than zero" }
require(height > 0) { "height must be greater than zero" }
if (blurHash == null || blurHash.length < 6) {
return null
}
val numCompEnc = decode83(blurHash, 0, 1)
val numCompX = (numCompEnc % 9) + 1
val numCompY = (numCompEnc / 9) + 1
if (blurHash.length != 4 + 2 * numCompX * numCompY) {
return null
}
val maxAcEnc = decode83(blurHash, 1, 2)
val maxAc = (maxAcEnc + 1) / 166f
val colors = Array(numCompX * numCompY) { i ->
if (i == 0) {
val colorEnc = decode83(blurHash, 2, 6)
decodeDc(colorEnc)
} else {
val from = 4 + i * 2
val colorEnc = decode83(blurHash, from, from + 2)
decodeAc(colorEnc, maxAc * punch)
}
}
return composeBitmap(width, height, numCompX, numCompY, colors)
}
private fun decode83(str: String, from: Int = 0, to: Int = str.length): Int {
var result = 0
for (i in from until to) {
val index = charMap[str[i]] ?: -1
if (index != -1) {
result = result * 83 + index
}
}
return result
}
private fun decodeDc(colorEnc: Int): FloatArray {
val r = colorEnc shr 16
val g = (colorEnc shr 8) and 255
val b = colorEnc and 255
return floatArrayOf(srgbToLinear(r), srgbToLinear(g), srgbToLinear(b))
}
private fun srgbToLinear(colorEnc: Int): Float {
val v = colorEnc / 255f
return if (v <= 0.04045f) {
(v / 12.92f)
} else {
((v + 0.055f) / 1.055f).pow(2.4f)
}
}
private fun decodeAc(value: Int, maxAc: Float): FloatArray {
val r = value / (19 * 19)
val g = (value / 19) % 19
val b = value % 19
return floatArrayOf(
signedPow2((r - 9) / 9.0f) * maxAc,
signedPow2((g - 9) / 9.0f) * maxAc,
signedPow2((b - 9) / 9.0f) * maxAc
)
}
private fun signedPow2(value: Float) = value.pow(2f).withSign(value)
private fun composeBitmap(
width: Int,
height: Int,
numCompX: Int,
numCompY: Int,
colors: Array<FloatArray>
): Bitmap {
val imageArray = IntArray(width * height)
for (y in 0 until height) {
for (x in 0 until width) {
var r = 0f
var g = 0f
var b = 0f
for (j in 0 until numCompY) {
for (i in 0 until numCompX) {
val basis = (cos(PI * x * i / width) * cos(PI * y * j / height)).toFloat()
val color = colors[j * numCompX + i]
r += color[0] * basis
g += color[1] * basis
b += color[2] * basis
}
}
imageArray[x + width * y] =
Color.rgb(linearToSrgb(r), linearToSrgb(g), linearToSrgb(b))
}
}
return Bitmap.createBitmap(imageArray, width, height, Bitmap.Config.ARGB_8888)
}
private fun linearToSrgb(value: Float): Int {
val v = value.coerceIn(0f, 1f)
return if (v <= 0.0031308f) {
(v * 12.92f * 255f + 0.5f).toInt()
} else {
((1.055f * v.pow(1 / 2.4f) - 0.055f) * 255 + 0.5f).toInt()
}
}
private val charMap = listOf(
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '#', '$', '%', '*', '+', ',',
'-', '.', ':', ';', '=', '?', '@', '[', ']', '^', '_', '{', '|', '}', '~'
)
.mapIndexed { i, c -> c to i }
.toMap()
}

View file

@ -130,8 +130,12 @@ public class MastodonHelper {
* @return Pagination * @return Pagination
*/ */
public static Pagination getPagination(Headers headers) { public static Pagination getPagination(Headers headers) {
String link = headers.get("Link");
Pagination pagination = new Pagination(); Pagination pagination = new Pagination();
if (headers == null) {
return pagination;
}
String link = headers.get("Link");
if (link != null) { if (link != null) {
Pattern patternMaxId = Pattern.compile("max_id=([0-9a-zA-Z]+).*"); Pattern patternMaxId = Pattern.compile("max_id=([0-9a-zA-Z]+).*");
Matcher matcherMaxId = patternMaxId.matcher(link); Matcher matcherMaxId = patternMaxId.matcher(link);

View file

@ -49,6 +49,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -1506,6 +1507,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
holder.binding.buttonCloseAttachmentPanel.setOnClickListener(v -> holder.binding.attachmentChoicesPanel.setVisibility(View.GONE)); holder.binding.buttonCloseAttachmentPanel.setOnClickListener(v -> holder.binding.attachmentChoicesPanel.setVisibility(View.GONE));
holder.binding.buttonVisibility.setOnClickListener(v -> { holder.binding.buttonVisibility.setOnClickListener(v -> {
holder.binding.visibilityPanel.setVisibility(View.VISIBLE); holder.binding.visibilityPanel.setVisibility(View.VISIBLE);
holder.binding.visibilityGroup.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
holder.binding.buttonVisibility.setChecked(false); holder.binding.buttonVisibility.setChecked(false);
}); });
holder.binding.buttonCloseVisibilityPanel.setOnClickListener(v -> holder.binding.visibilityPanel.setVisibility(View.GONE)); holder.binding.buttonCloseVisibilityPanel.setOnClickListener(v -> holder.binding.visibilityPanel.setVisibility(View.GONE));
@ -1587,7 +1589,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
if (!mentionsAtTop) { if (!mentionsAtTop) {
holder.binding.content.setSelection(statusDraft.cursorPosition); holder.binding.content.setSelection(statusDraft.cursorPosition);
} else { } else {
if (capitalize && !statusDraft.text.endsWith("\n")) { if (capitalize && statusDraft.text != null && !statusDraft.text.endsWith("\n")) {
statusDraft.text += "\n"; statusDraft.text += "\n";
holder.binding.content.setText(statusDraft.text); holder.binding.content.setText(statusDraft.text);
} }

View file

@ -39,8 +39,10 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -138,6 +140,7 @@ import app.fedilab.android.mastodon.client.entities.app.StatusCache;
import app.fedilab.android.mastodon.client.entities.app.StatusDraft; import app.fedilab.android.mastodon.client.entities.app.StatusDraft;
import app.fedilab.android.mastodon.client.entities.app.Timeline; import app.fedilab.android.mastodon.client.entities.app.Timeline;
import app.fedilab.android.mastodon.exception.DBException; import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.helper.BlurHashDecoder;
import app.fedilab.android.mastodon.helper.CrossActionHelper; import app.fedilab.android.mastodon.helper.CrossActionHelper;
import app.fedilab.android.mastodon.helper.GlideApp; import app.fedilab.android.mastodon.helper.GlideApp;
import app.fedilab.android.mastodon.helper.GlideFocus; import app.fedilab.android.mastodon.helper.GlideFocus;
@ -1111,15 +1114,23 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} }
int ressource = R.drawable.ic_baseline_public_24; int ressource = R.drawable.ic_baseline_public_24;
holder.binding.visibility.setContentDescription(context.getString(R.string.v_public));
holder.binding.visibilitySmall.setContentDescription(context.getString(R.string.v_public));
switch (status.visibility) { switch (status.visibility) {
case "unlisted": case "unlisted":
holder.binding.visibility.setContentDescription(context.getString(R.string.v_unlisted));
holder.binding.visibilitySmall.setContentDescription(context.getString(R.string.v_unlisted));
ressource = R.drawable.ic_baseline_lock_open_24; ressource = R.drawable.ic_baseline_lock_open_24;
break; break;
case "private": case "private":
ressource = R.drawable.ic_baseline_lock_24; ressource = R.drawable.ic_baseline_lock_24;
holder.binding.visibility.setContentDescription(context.getString(R.string.v_private));
holder.binding.visibilitySmall.setContentDescription(context.getString(R.string.v_private));
break; break;
case "direct": case "direct":
ressource = R.drawable.ic_baseline_mail_24; ressource = R.drawable.ic_baseline_mail_24;
holder.binding.visibility.setContentDescription(context.getString(R.string.v_direct));
holder.binding.visibilitySmall.setContentDescription(context.getString(R.string.v_direct));
break; break;
} }
@ -1277,6 +1288,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.actionButtonBoost.setVisibility(View.GONE); holder.binding.actionButtonBoost.setVisibility(View.GONE);
break; break;
} }
//--- MAIN CONTENT --- //--- MAIN CONTENT ---
holder.binding.statusContent.setText( holder.binding.statusContent.setText(
statusToDeal.getSpanContent(context, statusToDeal.getSpanContent(context,
@ -2128,7 +2140,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
//We hide the button //We hide the button
status.isFetchMore = false; status.isFetchMore = false;
String fromId; String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) { if (status.positionFetchMore == Status.PositionFetchMore.TOP || holder.getBindingAdapterPosition() == 0) {
fromId = statusList.get(holder.getBindingAdapterPosition()).id; fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else { } else {
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id; fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
@ -2149,7 +2161,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
statusIdMin = status.id; statusIdMin = status.id;
} }
} }
if (status.positionFetchMore == Status.PositionFetchMore.TOP) { if (status.positionFetchMore == Status.PositionFetchMore.TOP || holder.getBindingAdapterPosition() == 0) {
statusIdMax = statusList.get(holder.getBindingAdapterPosition()).id; statusIdMax = statusList.get(holder.getBindingAdapterPosition()).id;
} else { } else {
statusIdMax = statusList.get(holder.getBindingAdapterPosition() - 1).id; statusIdMax = statusList.get(holder.getBindingAdapterPosition() - 1).id;
@ -2202,13 +2214,24 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
boolean expand_media = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_MEDIA), false); boolean expand_media = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_MEDIA), false);
RequestBuilder<Drawable> requestBuilder; RequestBuilder<Drawable> requestBuilder;
GlideRequests glideRequests = GlideApp.with(context); GlideRequests glideRequests = GlideApp.with(context);
Bitmap placeholder = null;
if (attachment.blurhash != null) {
placeholder = new BlurHashDecoder().decode(attachment.blurhash, 32, 32, 1f);
}
if (!isSensitive || expand_media) { if (!isSensitive || expand_media) {
requestBuilder = glideRequests.asDrawable(); requestBuilder = glideRequests.asDrawable();
if (!fullAttachement) { if (!fullAttachement) {
if (placeholder != null) {
requestBuilder = requestBuilder.placeholder(new BitmapDrawable(context.getResources(), placeholder));
}
requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY))); requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
requestBuilder = requestBuilder.dontAnimate(); requestBuilder = requestBuilder.dontAnimate();
} else {
if (placeholder != null) {
requestBuilder = requestBuilder.placeholder(new BitmapDrawable(context.getResources(), placeholder));
} else { } else {
requestBuilder = requestBuilder.placeholder(R.color.transparent_grey); requestBuilder = requestBuilder.placeholder(R.color.transparent_grey);
}
requestBuilder = requestBuilder.dontAnimate(); requestBuilder = requestBuilder.dontAnimate();
requestBuilder = requestBuilder.apply(new RequestOptions().override((int) mediaW, (int) mediaH)); requestBuilder = requestBuilder.apply(new RequestOptions().override((int) mediaW, (int) mediaH));
requestBuilder = requestBuilder.fitCenter(); requestBuilder = requestBuilder.fitCenter();
@ -2234,14 +2257,19 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
boolean expand_media = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_MEDIA), false); boolean expand_media = sharedpreferences.getBoolean(context.getString(R.string.SET_EXPAND_MEDIA), false);
LinearLayout.LayoutParams lp; LinearLayout.LayoutParams lp;
int defaultHeight = (int) Helper.convertDpToPixel(200, context);
if (measuredWidth > 0) {
defaultHeight = (int) (measuredWidth * 3) / 4;
}
if (fullAttachement && mediaH > 0 && (!statusToDeal.sensitive || expand_media)) { if (fullAttachement && mediaH > 0 && (!statusToDeal.sensitive || expand_media)) {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (mediaH * ratio)); lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (mediaH * ratio));
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER); layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER);
} else { } else {
if (singleImage) { if (singleImage) {
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) Helper.convertDpToPixel(200, context)); lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, defaultHeight);
} else { } else {
lp = new LinearLayout.LayoutParams((int) Helper.convertDpToPixel(200, context), (int) Helper.convertDpToPixel(200, context)); //noinspection SuspiciousNameCombination
lp = new LinearLayout.LayoutParams(defaultHeight, defaultHeight);
} }
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.CENTER_CROP); layoutMediaBinding.media.setScaleType(ImageView.ScaleType.CENTER_CROP);
} }
@ -2461,6 +2489,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
public List<Attachment> getPreloadItems(int position) { public List<Attachment> getPreloadItems(int position) {
List<Attachment> attachments = new ArrayList<>(); List<Attachment> attachments = new ArrayList<>();
int max_size = statusList.size(); int max_size = statusList.size();
if (max_size == 0) {
return attachments;
}
int siblings = 3; int siblings = 3;
int from = Math.max((position - siblings), 0); int from = Math.max((position - siblings), 0);
if (from > max_size - 1) { if (from > max_size - 1) {
@ -2637,7 +2668,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
status.isFetchMore = false; status.isFetchMore = false;
notifyItemChanged(holder.getBindingAdapterPosition()); notifyItemChanged(holder.getBindingAdapterPosition());
String fromId; String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) { if (status.positionFetchMore == Status.PositionFetchMore.TOP || holder.getBindingAdapterPosition() == 0) {
fromId = statusList.get(holder.getBindingAdapterPosition()).id; fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else { } else {
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id; fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
@ -2655,7 +2686,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
minId = status.id; minId = status.id;
} }
} }
if (status.positionFetchMore == Status.PositionFetchMore.TOP) { if (status.positionFetchMore == Status.PositionFetchMore.TOP || holder.getBindingAdapterPosition() == 0) {
maxId = statusList.get(holder.getBindingAdapterPosition()).id; maxId = statusList.get(holder.getBindingAdapterPosition()).id;
} else { } else {
maxId = statusList.get(holder.getBindingAdapterPosition() - 1).id; maxId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
@ -2693,7 +2724,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
//We hide the button //We hide the button
status.isFetchMore = false; status.isFetchMore = false;
String fromId; String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) { if (status.positionFetchMore == Status.PositionFetchMore.TOP || holder.getBindingAdapterPosition() == 0) {
fromId = statusList.get(holder.getBindingAdapterPosition()).id; fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else { } else {
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id; fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;

View file

@ -132,6 +132,7 @@ public class FragmentMedia extends Fragment {
binding.pbarInf.setScaleY(1f); binding.pbarInf.setScaleY(1f);
binding.pbarInf.setIndeterminate(true); binding.pbarInf.setIndeterminate(true);
binding.loader.setVisibility(View.VISIBLE); binding.loader.setVisibility(View.VISIBLE);
scheduleStartPostponedTransition(binding.mediaPicture);
if (Helper.isValidContextForGlide(requireActivity()) && isAdded()) { if (Helper.isValidContextForGlide(requireActivity()) && isAdded()) {
Glide.with(requireActivity()) Glide.with(requireActivity())
.asBitmap() .asBitmap()
@ -144,7 +145,7 @@ public class FragmentMedia extends Fragment {
return; return;
} }
binding.mediaPicture.setImageBitmap(resource); binding.mediaPicture.setImageBitmap(resource);
scheduleStartPostponedTransition(binding.mediaPicture);
if (attachment.type.equalsIgnoreCase("image") && !attachment.url.toLowerCase().endsWith(".gif")) { if (attachment.type.equalsIgnoreCase("image") && !attachment.url.toLowerCase().endsWith(".gif")) {
binding.mediaPicture.setVisibility(View.VISIBLE); binding.mediaPicture.setVisibility(View.VISIBLE);
final Handler handler = new Handler(); final Handler handler = new Handler();

View file

@ -96,9 +96,11 @@ public class FragmentMediaProfile extends Fragment {
accountsVM.getAccountStatuses(tempInstance, null, accountId, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity())) accountsVM.getAccountStatuses(tempInstance, null, accountId, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statuses -> initializeStatusesCommonView(statuses)); .observe(getViewLifecycleOwner(), statuses -> initializeStatusesCommonView(statuses));
} else { } else {
if (isAdded() && !requireActivity().isFinishing()) {
Toasty.error(requireActivity(), getString(R.string.toast_fetch_error), Toasty.LENGTH_LONG).show(); Toasty.error(requireActivity(), getString(R.string.toast_fetch_error), Toasty.LENGTH_LONG).show();
} }
} }
}
}); });
} else { } else {
tempToken = BaseMainActivity.currentToken; tempToken = BaseMainActivity.currentToken;

View file

@ -39,12 +39,13 @@
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/remove" android:id="@+id/remove"
style="@style/Widget.Material3.Button.OutlinedButton" style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_margin="6dp" android:layout_margin="6dp"
android:insetTop="0dp" android:insetTop="0dp"
android:insetBottom="0dp" android:insetBottom="0dp"
android:contentDescription="@string/delete_field"
android:padding="0dp" android:padding="0dp"
android:textColor="?colorError" android:textColor="?colorError"
app:icon="@drawable/ic_compose_attachment_remove" app:icon="@drawable/ic_compose_attachment_remove"

View file

@ -48,11 +48,18 @@
android:layout_marginHorizontal="6dp" android:layout_marginHorizontal="6dp"
android:textAlignment="center" android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge" android:textAppearance="@style/TextAppearance.Material3.TitleLarge"
app:layout_constraintBottom_toTopOf="@id/description" app:layout_constraintBottom_toTopOf="@id/description_container"
app:layout_constraintTop_toTopOf="@id/background_image" app:layout_constraintTop_toTopOf="@id/background_image"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
tools:text="Instance" /> tools:text="Instance" />
<androidx.core.widget.NestedScrollView
android:id="@+id/description_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/version"
app:layout_constraintTop_toBottomOf="@id/name">
<com.google.android.material.textview.MaterialTextView <com.google.android.material.textview.MaterialTextView
android:id="@+id/description" android:id="@+id/description"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,10 +68,10 @@
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:textAlignment="center" android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.LabelMedium" android:textAppearance="@style/TextAppearance.Material3.LabelMedium"
app:layout_constraintBottom_toTopOf="@id/version"
app:layout_constraintTop_toBottomOf="@id/name"
tools:maxLines="6" tools:maxLines="6"
tools:text="@tools:sample/lorem/random" /> tools:text="@tools:sample/lorem/random" />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.textview.MaterialTextView <com.google.android.material.textview.MaterialTextView
android:id="@+id/version" android:id="@+id/version"
@ -74,7 +81,7 @@
android:textAlignment="center" android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.LabelMedium" android:textAppearance="@style/TextAppearance.Material3.LabelMedium"
app:layout_constraintBottom_toTopOf="@id/uri" app:layout_constraintBottom_toTopOf="@id/uri"
app:layout_constraintTop_toBottomOf="@id/description" app:layout_constraintTop_toBottomOf="@id/description_container"
tools:text="4.0" /> tools:text="4.0" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
@ -106,7 +113,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
app:constraint_referenced_ids="name,description,version,uri,contact" app:constraint_referenced_ids="name,description_container,version,uri,contact"
tools:visibility="visible" /> tools:visibility="visible" />
<com.google.android.material.progressindicator.CircularProgressIndicator <com.google.android.material.progressindicator.CircularProgressIndicator

View file

@ -57,6 +57,7 @@
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/status_boost_icon" android:id="@+id/status_boost_icon"
android:contentDescription="@string/reblog"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerInside" android:scaleType="centerInside"
@ -64,6 +65,7 @@
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/status_booster_avatar" android:id="@+id/status_booster_avatar"
android:contentDescription="@string/profile_picture"
android:layout_width="20dp" android:layout_width="20dp"
android:layout_height="20dp" android:layout_height="20dp"
android:scaleType="centerInside" android:scaleType="centerInside"
@ -114,6 +116,7 @@
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:scaleType="centerInside" android:scaleType="centerInside"
android:contentDescription="@string/profile_picture"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -139,6 +142,7 @@
android:layout_width="20dp" android:layout_width="20dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/reply"
android:src="@drawable/ic_baseline_reply_16" android:src="@drawable/ic_baseline_reply_16"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
@ -152,6 +156,7 @@
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:src="@drawable/ic_baseline_android_24" android:src="@drawable/ic_baseline_android_24"
android:visibility="gone" android:visibility="gone"
android:contentDescription="@string/bot"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
tools:visibility="visible" /> tools:visibility="visible" />
@ -178,6 +183,7 @@
android:id="@+id/visibility_small" android:id="@+id/visibility_small"
android:layout_width="20dp" android:layout_width="20dp"
android:layout_height="20dp" android:layout_height="20dp"
android:contentDescription="@string/visibility"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
android:src="@drawable/ic_baseline_public_24" /> android:src="@drawable/ic_baseline_public_24" />
@ -211,6 +217,7 @@
android:layout_height="20dp" android:layout_height="20dp"
android:layout_gravity="center" android:layout_gravity="center"
android:scaleType="centerInside" android:scaleType="centerInside"
android:contentDescription="@string/pinned"
android:src="@drawable/ic_baseline_push_pin_24" android:src="@drawable/ic_baseline_push_pin_24"
android:visibility="gone" /> android:visibility="gone" />
@ -357,6 +364,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="150dp" android:layout_height="150dp"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:contentDescription="@string/card_picture"
android:padding="1dp" android:padding="1dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:visibility="gone" android:visibility="gone"
@ -375,6 +383,7 @@
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:padding="1dp" android:padding="1dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:contentDescription="@string/card_picture"
android:visibility="gone" android:visibility="gone"
tools:src="@tools:sample/backgrounds/scenic" tools:src="@tools:sample/backgrounds/scenic"
tools:visibility="visible" /> tools:visibility="visible" />
@ -531,6 +540,7 @@
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/repeat_info" android:id="@+id/repeat_info"
android:contentDescription="@string/reblog"
android:layout_width="20dp" android:layout_width="20dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
@ -554,6 +564,7 @@
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/fav_info" android:id="@+id/fav_info"
android:layout_width="20dp" android:layout_width="20dp"
android:contentDescription="@string/favourite"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
app:srcCompat="@drawable/ic_star_outline" /> app:srcCompat="@drawable/ic_star_outline" />
@ -573,6 +584,7 @@
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/visibility" android:id="@+id/visibility"
android:contentDescription="@string/visibility"
android:layout_width="20dp" android:layout_width="20dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"

View file

@ -335,6 +335,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/visibility_group"
android:padding="6dp" android:padding="6dp"
app:singleSelection="true"> app:singleSelection="true">

View file

@ -50,6 +50,7 @@
android:id="@+id/number_of_messages" android:id="@+id/number_of_messages"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/number_of_replies"
android:layout_weight="2" android:layout_weight="2"
android:drawablePadding="5dp" android:drawablePadding="5dp"
app:drawableStartCompat="@drawable/ic_baseline_message_24" /> app:drawableStartCompat="@drawable/ic_baseline_message_24" />
@ -58,6 +59,7 @@
android:id="@+id/number_of_media" android:id="@+id/number_of_media"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/number_of_media"
android:layout_weight="2" android:layout_weight="2"
android:drawablePadding="5dp" android:drawablePadding="5dp"
app:drawableStartCompat="@drawable/ic_baseline_perm_media_24" /> app:drawableStartCompat="@drawable/ic_baseline_perm_media_24" />
@ -66,6 +68,7 @@
android:id="@+id/date" android:id="@+id/date"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/update_date"
android:layout_weight="1" android:layout_weight="1"
android:drawablePadding="5dp" android:drawablePadding="5dp"
app:drawableStartCompat="@drawable/ic_baseline_access_time_24" /> app:drawableStartCompat="@drawable/ic_baseline_access_time_24" />

View file

@ -8,6 +8,7 @@
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/media" android:id="@+id/media"
android:adjustViewBounds="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
</resources> </resources>

View file

@ -1006,4 +1006,11 @@
<string name="set_fetch_home">Automaticky načítat domácí zprávy</string> <string name="set_fetch_home">Automaticky načítat domácí zprávy</string>
<string name="fetch_home_messages">Načíst domácí zprávy</string> <string name="fetch_home_messages">Načíst domácí zprávy</string>
<string name="auto_fetch_missing">Automaticky načítat chybějící zprávy</string> <string name="auto_fetch_missing">Automaticky načítat chybějící zprávy</string>
<string name="set_mention_at_top">Zmínky nahoře</string>
<string name="set_mention_at_top_indication">Při odpovídání budou zmínky vždy přidány na začátek zprávy</string>
<string name="pinned">Připnuto</string>
<string name="number_of_media">Počet médií</string>
<string name="number_of_replies">Počet odpovědí</string>
<string name="update_date">Datum aktualizace</string>
<string name="card_picture">Obrázek karty</string>
</resources> </resources>

View file

@ -996,4 +996,11 @@
<string name="otp_message">Zwei-Faktor-Authentifizierungstoken</string> <string name="otp_message">Zwei-Faktor-Authentifizierungstoken</string>
<string name="home_cache">Cache der Startseite</string> <string name="home_cache">Cache der Startseite</string>
<string name="fetch_home_messages">Beiträge auf der Startseite abrufen</string> <string name="fetch_home_messages">Beiträge auf der Startseite abrufen</string>
<string name="set_mention_at_top">Erwähnungen am Anfang</string>
<string name="set_mention_at_top_indication">Beim Antworten werden alle Erwähnungen dem Anfang des Beitrags hinzugefügt</string>
<string name="number_of_media">Medienanzahl</string>
<string name="number_of_replies">Anzahl von Antworten</string>
<string name="update_date">Datum der Aktualisierung</string>
<string name="pinned">Angeheftet</string>
<string name="card_picture">Bild der Karte</string>
</resources> </resources>

View file

@ -987,4 +987,6 @@
<string name="home_cache">Memòria temporànea lìnia printzipale</string> <string name="home_cache">Memòria temporànea lìnia printzipale</string>
<string name="type_of_home_delay_title">Tempus de recùperu de sa lìnia printzipale</string> <string name="type_of_home_delay_title">Tempus de recùperu de sa lìnia printzipale</string>
<string name="set_fetch_home">Recùpera in automàticu is messàgios de sa lìnia printzipale</string> <string name="set_fetch_home">Recùpera in automàticu is messàgios de sa lìnia printzipale</string>
<string name="set_mention_at_top">Mentovos in pitzos</string>
<string name="set_mention_at_top_indication">Rispondende, is mentovos s\'ant a annànghere a su cumintzu de su messàgiu</string>
</resources> </resources>

View file

@ -994,4 +994,11 @@
<string name="home_cache">Ana sayfa önbelleği</string> <string name="home_cache">Ana sayfa önbelleği</string>
<string name="auto_fetch_missing">Eksik mesajları otomatik olarak al</string> <string name="auto_fetch_missing">Eksik mesajları otomatik olarak al</string>
<string name="fetch_home_messages">Ana sayfa mesajlarını al</string> <string name="fetch_home_messages">Ana sayfa mesajlarını al</string>
<string name="set_mention_at_top">Bahsedilenler üstte</string>
<string name="set_mention_at_top_indication">Yanıtlarken, bahsedenlerin tümü mesajın başına eklenecektir</string>
<string name="card_picture">Kart resmi</string>
<string name="number_of_media">Medya sayısı</string>
<string name="number_of_replies">Yanıt sayısı</string>
<string name="pinned">Sabitlendi</string>
<string name="update_date">Güncelleme tarihi</string>
</resources> </resources>

View file

@ -942,7 +942,7 @@
<string name="type_of_notifications_delay_title">通知获取时间</string> <string name="type_of_notifications_delay_title">通知获取时间</string>
<string name="set_dynamic_color_indication">与您个人壁纸的配色方案色调一致。</string> <string name="set_dynamic_color_indication">与您个人壁纸的配色方案色调一致。</string>
<string name="type_default_theme_light">默认浅色主题</string> <string name="type_default_theme_light">默认浅色主题</string>
<string name="set_cardview">高架卡</string> <string name="set_cardview">悬浮卡片</string>
<string name="set_customize_light">自定义浅色主题</string> <string name="set_customize_light">自定义浅色主题</string>
<string name="set_customize_light_indication">允许为浅色主题自定义消息中的一些元素。</string> <string name="set_customize_light_indication">允许为浅色主题自定义消息中的一些元素。</string>
<string name="set_customize_dark">自定义深色主题</string> <string name="set_customize_dark">自定义深色主题</string>
@ -994,4 +994,11 @@
<string name="type_of_home_delay_title">主页获取延迟</string> <string name="type_of_home_delay_title">主页获取延迟</string>
<string name="fetch_home_every">获取主页消息每隔</string> <string name="fetch_home_every">获取主页消息每隔</string>
<string name="auto_fetch_missing">自动获取缺失的消息</string> <string name="auto_fetch_missing">自动获取缺失的消息</string>
<string name="set_mention_at_top">置顶提及</string>
<string name="set_mention_at_top_indication">回复时提及将全部添加到消息的开头</string>
<string name="pinned">已置顶</string>
<string name="card_picture">卡片图像</string>
<string name="number_of_replies">回复数</string>
<string name="update_date">更新日期</string>
<string name="number_of_media">媒体数</string>
</resources> </resources>

View file

@ -2044,6 +2044,8 @@
<string name="action_unpin">Unpin message</string> <string name="action_unpin">Unpin message</string>
<string name="toast_unpin">The message is no longer pinned!</string> <string name="toast_unpin">The message is no longer pinned!</string>
<string name="toast_pin">The message has been pinned</string> <string name="toast_pin">The message has been pinned</string>
<string name="pinned">Pinned</string>
<string name="card_picture">Card picture</string>
<string name="set_live_translate_title">Translate messages</string> <string name="set_live_translate_title">Translate messages</string>
<string name="set_live_translate">Force translation to a specific language. Choose first value to reset to device settings</string> <string name="set_live_translate">Force translation to a specific language. Choose first value to reset to device settings</string>
<string name="edit_message">Edit message</string> <string name="edit_message">Edit message</string>
@ -2249,4 +2251,9 @@
<string name="set_mention_at_top">Mentions at the top</string> <string name="set_mention_at_top">Mentions at the top</string>
<string name="set_mention_at_top_indication">When replying mentions will all be added to the beginning of the message</string> <string name="set_mention_at_top_indication">When replying mentions will all be added to the beginning of the message</string>
<string name="number_of_media">Number of media</string>
<string name="number_of_replies">Number of replies</string>
<string name="update_date">Update date</string>
</resources> </resources>