From e0c94e114cf0d01c61f993848054967e8cf6f6ff Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Jul 2022 09:33:34 +0200 Subject: [PATCH 01/14] Fix some bad behaviors with span --- .../fedilab/android/client/entities/api/Account.java | 6 +++++- .../app/fedilab/android/client/entities/api/Poll.java | 2 +- .../android/ui/drawer/NotificationAdapter.java | 11 +++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Account.java b/app/src/main/java/app/fedilab/android/client/entities/api/Account.java index 4b2392d8..fd444d4d 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Account.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Account.java @@ -83,7 +83,11 @@ public class Account implements Serializable { if (display_name == null || display_name.isEmpty()) { display_name = username; } - return SpannableHelper.convert(context, display_name, null, this, null, true, viewWeakReference); + return SpannableHelper.convert(context, display_name, null, this, null, false, viewWeakReference); + } + + public synchronized Spannable getSpanDisplayNameTitle(Context context, WeakReference viewWeakReference, String title) { + return SpannableHelper.convert(context, title, null, this, null, false, viewWeakReference); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java b/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java index a91a9361..3bf9c479 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java @@ -61,7 +61,7 @@ public class Poll implements Serializable { public transient Spannable span_title; public Spannable getSpanTitle(Context context, Status status, WeakReference viewWeakReference) { - span_title = SpannableHelper.convert(context, title, status, null, null, true, viewWeakReference); + span_title = SpannableHelper.convert(context, title, status, null, null, false, viewWeakReference); return span_title; } } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java index dc354fd5..3a77b2b5 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java @@ -224,10 +224,9 @@ public class NotificationAdapter extends RecyclerView.Adapter(holderStatus.bindingNotification.status.displayName)), + notification.account.getSpanDisplayNameTitle(context, + new WeakReference<>(holderStatus.bindingNotification.status.displayName), title), TextView.BufferType.SPANNABLE); holderStatus.bindingNotification.status.username.setText(String.format("@%s", notification.account.acct)); holderStatus.bindingNotification.containerTransparent.setAlpha(.1f); @@ -295,10 +294,10 @@ public class NotificationAdapter extends RecyclerView.Adapter(holderStatus.bindingNotification.status.displayName)), + notification.account.getSpanDisplayNameTitle(context, + new WeakReference<>(holderStatus.bindingNotification.status.displayName), title), TextView.BufferType.SPANNABLE); holderStatus.bindingNotification.status.displayName.setText(title, TextView.BufferType.SPANNABLE); holderStatus.bindingNotification.status.username.setText(String.format("@%s", notification.account.acct)); From c97c2e465bc7c7a89d17b8f843b6c1588ae525f2 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Jul 2022 09:42:16 +0200 Subject: [PATCH 02/14] Fix preview with focus issue --- .../java/app/fedilab/android/ui/drawer/StatusAdapter.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) 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 628f39d8..3559fa5c 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 @@ -75,7 +75,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestBuilder; -import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; import com.github.stom79.mytransl.MyTransL; @@ -1131,8 +1130,7 @@ public class StatusAdapter extends RecyclerView.Adapter if (!mediaObfuscated(statusToDeal) || expand_media) { layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24); RequestBuilder requestBuilder = Glide.with(layoutMediaBinding.media.getContext()) - .load(statusToDeal.media_attachments.get(0).preview_url) - .apply(new RequestOptions().transform(new GlideFocus(focusX, focusY))); + .load(statusToDeal.media_attachments.get(0).preview_url); if (!fullAttachement) { requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY))); } @@ -1185,8 +1183,7 @@ public class StatusAdapter extends RecyclerView.Adapter if (!mediaObfuscated(statusToDeal) || expand_media) { layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24); RequestBuilder requestBuilder = Glide.with(layoutMediaBinding.media.getContext()) - .load(attachment.preview_url) - .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners((int) Helper.convertDpToPixel(3, context)))); + .load(attachment.preview_url); if (!fullAttachement) { requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY))); } From 10e66a3e7e2e000269352b438b143cb28256fd97 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Jul 2022 10:10:59 +0200 Subject: [PATCH 03/14] Fix issue #262 - Long press to store media --- .../app/fedilab/android/helper/Helper.java | 1 + .../android/ui/drawer/StatusAdapter.java | 27 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 +- app/src/main/res/xml/pref_timelines.xml | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index 99be394d..b8351169 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -1748,4 +1748,5 @@ public class Helper { } return null; } + } 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 3559fa5c..2a45f7c8 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 @@ -128,6 +128,7 @@ import app.fedilab.android.helper.GlideFocus; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.LongClickLinkMovementMethod; import app.fedilab.android.helper.MastodonHelper; +import app.fedilab.android.helper.MediaHelper; import app.fedilab.android.helper.SpannableHelper; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.ui.fragment.timeline.FragmentMastodonContext; @@ -323,6 +324,7 @@ public class StatusAdapter extends RecyclerView.Adapter boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true); boolean fullAttachement = sharedpreferences.getBoolean(context.getString(R.string.SET_FULL_PREVIEW), false); boolean displayBookmark = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_BOOKMARK), false); + boolean long_press_media = sharedpreferences.getBoolean(context.getString(R.string.SET_LONG_PRESS_STORE_MEDIA), false); if (MainActivity.currentAccount != null && MainActivity.currentAccount.api == Account.API.PLEROMA) { holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE); @@ -1120,6 +1122,19 @@ public class StatusAdapter extends RecyclerView.Adapter } else { layoutMediaBinding.playMusic.setVisibility(View.GONE); } + String finalUrl; + if (statusToDeal.media_attachments.get(0).url == null) { + finalUrl = statusToDeal.media_attachments.get(0).remote_url; + } else { + finalUrl = statusToDeal.media_attachments.get(0).url; + } + layoutMediaBinding.media.setOnLongClickListener(v -> { + if (long_press_media) { + MediaHelper.manageMove(context, finalUrl, false); + } + return true; + }); + float focusX = 0.f; float focusY = 0.f; if (statusToDeal.media_attachments.get(0).meta != null && statusToDeal.media_attachments.get(0).meta.focus != null) { @@ -1162,6 +1177,18 @@ public class StatusAdapter extends RecyclerView.Adapter focusY = statusToDeal.media_attachments.get(0).meta.focus.y; } + String finalUrl; + if (attachment.url == null) { + finalUrl = attachment.remote_url; + } else { + finalUrl = attachment.url; + } + layoutMediaBinding.media.setOnLongClickListener(v -> { + if (long_press_media) { + MediaHelper.manageMove(context, finalUrl, false); + } + return true; + }); if (fullAttachement) { lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 32a3f6d8..05a4af2d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -848,7 +848,7 @@ - SET_LONG_PRESS_MEDIA + SET_LONG_PRESS_STORE_MEDIA SET_UNFOLLOW_VALIDATION SET_DISPLAY_ADMIN_STATUSES SET_LED_COLOUR_VAL diff --git a/app/src/main/res/xml/pref_timelines.xml b/app/src/main/res/xml/pref_timelines.xml index 1b9a9c73..bf408875 100644 --- a/app/src/main/res/xml/pref_timelines.xml +++ b/app/src/main/res/xml/pref_timelines.xml @@ -43,7 +43,7 @@ app:iconSpaceReserved="false" android:defaultValue="false" app:singleLineTitle="false" - app:key="@string/SET_LONG_PRESS_MEDIA" + app:key="@string/SET_LONG_PRESS_STORE_MEDIA" app:title="@string/set_long_press_media" /> Date: Tue, 19 Jul 2022 19:03:12 +0000 Subject: [PATCH 04/14] Translated using Weblate (Turkish) Currently translated at 100.0% (729 of 729 strings) Translation: Fedilab/Strings Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/ --- app/src/main/res/values-tr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 37cb1b2d..f4d574a2 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -727,4 +727,5 @@ Diğer zaman çizelgeleri için önbellekteki mesajlar Taslaklarda saklanan mesajlar Öntanımlı sistem dilini kullan + Mesajlar için dil \ No newline at end of file From 71aaaadccb648c4fb51738c32bfe15a00a2a65e3 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Jul 2022 12:07:44 +0200 Subject: [PATCH 05/14] Set instance max chars --- .../app/fedilab/android/BaseMainActivity.java | 7 +- .../android/activities/InstanceActivity.java | 85 ++++++---- .../android/helper/MastodonHelper.java | 18 +++ .../android/ui/drawer/ComposeAdapter.java | 9 +- app/src/main/res/layout/activity_instance.xml | 73 +++++++-- .../main/res/menu/activity_main_drawer.xml | 152 ++++++++++-------- app/src/main/res/menu/main.xml | 7 +- app/src/main/res/values/strings.xml | 7 + 8 files changed, 235 insertions(+), 123 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 6a490eb2..57a3544c 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -516,6 +516,9 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt } else if (id == R.id.nav_cache) { Intent intent = new Intent(BaseMainActivity.this, CacheActivity.class); startActivity(intent); + } else if (id == R.id.nav_about_instance) { + Intent intent = new Intent(BaseMainActivity.this, InstanceActivity.class); + startActivity(intent); } binding.drawerLayout.close(); return false; @@ -677,10 +680,6 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt AlertDialog alert = alt_bld.create(); alert.show(); return true; - } else if (itemId == R.id.action_about_instance) { - Intent intent = new Intent(BaseMainActivity.this, InstanceActivity.class); - startActivity(intent); - return true; } else if (itemId == R.id.action_proxy) { Intent intent = new Intent(BaseMainActivity.this, ProxyActivity.class); startActivity(intent); diff --git a/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java b/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java index eeea8b6a..057bc3f0 100644 --- a/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java @@ -16,6 +16,7 @@ package app.fedilab.android.activities; import android.content.Intent; +import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -23,9 +24,9 @@ import android.text.Html; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; import androidx.lifecycle.ViewModelProvider; +import androidx.preference.PreferenceManager; import com.bumptech.glide.Glide; @@ -35,13 +36,13 @@ import app.fedilab.android.client.entities.api.Instance; import app.fedilab.android.databinding.ActivityInstanceBinding; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.viewmodel.mastodon.InstancesVM; -import es.dmoral.toasty.Toasty; public class InstanceActivity extends BaseActivity { ActivityInstanceBinding binding; + private boolean applyMaxChar = false; @Override protected void onCreate(Bundle savedInstanceState) { @@ -54,8 +55,26 @@ public class InstanceActivity extends BaseActivity { getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); if (getSupportActionBar() != null) getSupportActionBar().hide(); + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(InstanceActivity.this); + binding.close.setOnClickListener( - binding.close.setOnClickListener(view -> finish()); + view -> { + if (applyMaxChar) { + String max_char = binding.maxChar.getText().toString(); + + SharedPreferences.Editor editor = sharedpreferences.edit(); + if (!max_char.isEmpty()) { + try { + editor.putInt(getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, Integer.parseInt(max_char)); + editor.apply(); + } catch (Exception ignored) { + } + } + } + finish(); + } + + ); if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); @@ -66,33 +85,41 @@ public class InstanceActivity extends BaseActivity { instancesVM.getInstance(BaseMainActivity.currentInstance).observe(InstanceActivity.this, instanceInfo -> { binding.instanceContainer.setVisibility(View.VISIBLE); binding.loader.setVisibility(View.GONE); - if (instanceInfo == null || instanceInfo.info == null) { - Toasty.error(InstanceActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); - return; - } - Instance instance = instanceInfo.info; - binding.instanceTitle.setText(instance.title); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - binding.instanceDescription.setText(Html.fromHtml(instance.description, Html.FROM_HTML_MODE_LEGACY)); - else - binding.instanceDescription.setText(Html.fromHtml(instance.description)); - if (instance.description == null || instance.description.trim().length() == 0) - binding.instanceDescription.setText(getString(R.string.instance_no_description)); - binding.instanceVersion.setText(instance.version); - binding.instanceUri.setText(instance.uri); - if (instance.email == null) { - binding.instanceContact.hide(); - } - Glide.with(InstanceActivity.this) - .asBitmap() - .load(instance.thumbnail) - .into(binding.backGroundImage); - binding.instanceContact.setOnClickListener(v -> { - Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", instance.email, null)); - emailIntent.putExtra(Intent.EXTRA_SUBJECT, "[Mastodon] - " + instance.uri); - startActivity(Intent.createChooser(emailIntent, getString(R.string.send_email))); - }); + if (instanceInfo == null || instanceInfo.info == null || instanceInfo.info.description == null) { + binding.maxCharContainer.setVisibility(View.VISIBLE); + binding.instanceContainer.setVisibility(View.GONE); + int val = sharedpreferences.getInt(getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, -1); + if (val != -1) { + binding.maxChar.setText(String.valueOf(val)); + } + applyMaxChar = true; + + } else { + Instance instance = instanceInfo.info; + binding.instanceTitle.setText(instance.title); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + binding.instanceDescription.setText(Html.fromHtml(instance.description, Html.FROM_HTML_MODE_LEGACY)); + else + binding.instanceDescription.setText(Html.fromHtml(instance.description)); + if (instance.description == null || instance.description.trim().length() == 0) + binding.instanceDescription.setText(getString(R.string.instance_no_description)); + binding.instanceVersion.setText(instance.version); + binding.instanceUri.setText(instance.uri); + if (instance.email == null) { + binding.instanceContact.hide(); + } + Glide.with(InstanceActivity.this) + .asBitmap() + .load(instance.thumbnail) + .into(binding.backGroundImage); + + binding.instanceContact.setOnClickListener(v -> { + Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", instance.email, null)); + emailIntent.putExtra(Intent.EXTRA_SUBJECT, "[Mastodon] - " + instance.uri); + startActivity(Intent.createChooser(emailIntent, getString(R.string.send_email))); + }); + } }); } diff --git a/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java b/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java index 65ba9802..cc0e78e7 100644 --- a/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java @@ -15,6 +15,8 @@ package app.fedilab.android.helper; * see . */ +import static app.fedilab.android.BaseMainActivity.instanceInfo; + import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; @@ -51,6 +53,7 @@ import java.util.regex.Pattern; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; +import app.fedilab.android.activities.MainActivity; import app.fedilab.android.client.entities.api.Account; import app.fedilab.android.client.entities.api.Pagination; import app.fedilab.android.client.entities.api.RelationShip; @@ -499,4 +502,19 @@ public class MastodonHelper { void onTimedMute(RelationShip relationShip); } + public static int getInstanceMaxChars(Context context) { + int max_car; + if (instanceInfo != null) { + max_car = instanceInfo.max_toot_chars != null ? Integer.parseInt(instanceInfo.max_toot_chars) : instanceInfo.configuration.statusesConf.max_characters; + } else { + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + int val = sharedpreferences.getInt(context.getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, -1); + if (val != -1) { + return val; + } else { + max_car = 500; + } + } + return max_car; + } } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java index db2aba5e..25230ab3 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java @@ -712,12 +712,7 @@ public class ComposeAdapter extends RecyclerView.Adapter max_car + 1) { int from = max_car - holder.binding.contentSpoiler.getText().length(); int to = (currentLength - holder.binding.contentSpoiler.getText().length()); @@ -1246,7 +1241,7 @@ public class ComposeAdapter extends RecyclerView.Adapter + android:layout_height="wrap_content"> - + android:scaleType="centerCrop" + tools:src="@tools:sample/backgrounds/scenic" /> - - - - - - - + - + + + + + + + + + + + - + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 4ab3fc40..ab161c77 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -3,74 +3,100 @@ xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view"> - + + + + + + + + + + + + + + + + + - - + - + + + + + android:id="@+id/nav_app" + android:title="@string/my_app"> + + + + + + + - + + + + - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml index cbdc7117..b1dda381 100644 --- a/app/src/main/res/menu/main.xml +++ b/app/src/main/res/menu/main.xml @@ -1,11 +1,8 @@ - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 05a4af2d..1177a0ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -922,6 +922,9 @@ REPLACE_WIKIPEDIA_HOST wikiless.org LAST_NOTIFICATION_ID + SET_MAX_INSTANCE_CHAR + + Type of notifications Chose the type of notifications Notification sounds @@ -982,6 +985,10 @@ Are you sure you want to delete cache? If you have drafts with media, the attached media will be lost. Use the default system language Language for messages + My instance + My app + My account + Set your max char count From abbfb1a57317713e8551d85a21b19b231edb7472 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Wed, 20 Jul 2022 09:42:26 +0000 Subject: [PATCH 06/14] Translated using Weblate (Sardinian) Currently translated at 100.0% (729 of 729 strings) Translation: Fedilab/Strings Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/sc/ --- app/src/main/res/values-sc/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 59ce3110..5fee265b 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -721,4 +721,5 @@ Ses seguru de bòlere isboidare sa memòria temporànea\? Si tenes abbotzos cun cuntenutos multimediales as a pèrdere sos cuntenutos alligados. Isbòida sa memòria temporànea Imprea sa limba predefinida de sistema + Limba pro sos messàgios \ No newline at end of file From 6876b753663c123c3247853b408d847a5e286eb3 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Jul 2022 14:24:09 +0200 Subject: [PATCH 07/14] Fix issue #267 - Crash with reactions --- .../fedilab/android/ui/drawer/StatusAdapter.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) 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 2a45f7c8..0b5d18d7 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 @@ -345,6 +345,9 @@ public class StatusAdapter extends RecyclerView.Adapter }).setOnEmojiClickListener((emoji, imageView) -> { String emojiStr = imageView.getUnicode(); boolean alreadyAdded = false; + if (status.pleroma == null || status.pleroma.emoji_reactions == null) { + return; + } for (Reaction reaction : status.pleroma.emoji_reactions) { if (reaction.name.compareTo(emojiStr) == 0) { alreadyAdded = true; @@ -387,12 +390,14 @@ public class StatusAdapter extends RecyclerView.Adapter GridView gridView = new GridView(context); gridView.setAdapter(new EmojiAdapter(emojis.get(BaseMainActivity.currentInstance))); gridView.setNumColumns(5); - AlertDialog finalAlertDialogEmoji = alertDialogEmoji; gridView.setOnItemClickListener((parent, view, index, id) -> { String emojiStr = emojis.get(BaseMainActivity.currentInstance).get(index).shortcode; String url = emojis.get(BaseMainActivity.currentInstance).get(index).url; String static_url = emojis.get(BaseMainActivity.currentInstance).get(index).static_url; boolean alreadyAdded = false; + if (status.pleroma == null || status.pleroma.emoji_reactions == null) { + return; + } for (Reaction reaction : status.pleroma.emoji_reactions) { if (reaction.name.compareTo(emojiStr) == 0) { alreadyAdded = true; @@ -420,9 +425,6 @@ public class StatusAdapter extends RecyclerView.Adapter } else { actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr); } - if (finalAlertDialogEmoji != null) { - finalAlertDialogEmoji.dismiss(); - } }); gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp); builder.setView(gridView); @@ -432,7 +434,7 @@ public class StatusAdapter extends RecyclerView.Adapter textView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp); builder.setView(textView); } - alertDialogEmoji = builder.show(); + builder.show(); }); } @@ -893,7 +895,9 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.username.setCompoundDrawables(null, null, null, null); } + if (statusToDeal.account.bot) { + holder.binding.botIcon.setVisibility(View.VISIBLE); } else { holder.binding.botIcon.setVisibility(View.GONE); } From c033064d13a81960b1f9e83aeb18e68d1553e1e4 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Jul 2022 17:13:07 +0200 Subject: [PATCH 08/14] Fix issue #263 - Custom emoji for Friendica --- .../android/activities/InstanceActivity.java | 21 +++++++- .../android/helper/SpannableHelper.java | 30 +++++++++++ app/src/main/res/layout/activity_instance.xml | 50 ++++++++----------- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java b/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java index 057bc3f0..9f515608 100644 --- a/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/InstanceActivity.java @@ -17,6 +17,7 @@ package app.fedilab.android.activities; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -25,10 +26,14 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProvider; import androidx.preference.PreferenceManager; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; @@ -89,6 +94,7 @@ public class InstanceActivity extends BaseActivity { if (instanceInfo == null || instanceInfo.info == null || instanceInfo.info.description == null) { binding.maxCharContainer.setVisibility(View.VISIBLE); binding.instanceContainer.setVisibility(View.GONE); + binding.instanceContact.setVisibility(View.GONE); int val = sharedpreferences.getInt(getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, -1); if (val != -1) { binding.maxChar.setText(String.valueOf(val)); @@ -110,9 +116,20 @@ public class InstanceActivity extends BaseActivity { binding.instanceContact.hide(); } Glide.with(InstanceActivity.this) - .asBitmap() + .asDrawable() .load(instance.thumbnail) - .into(binding.backGroundImage); + .into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { + binding.background.setAlpha(0.2f); + binding.background.setBackground(resource); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); binding.instanceContact.setOnClickListener(v -> { Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", instance.email, null)); diff --git a/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java b/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java index c9c45c7b..e786f473 100644 --- a/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java @@ -54,6 +54,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -89,6 +90,17 @@ public class SpannableHelper { if (text == null) { return null; } + Pattern imgPattern = Pattern.compile("]*src=\"([^\"]+)\"[^>]*>"); + Matcher matcherImg = imgPattern.matcher(text); + HashMap imagesToReplace = new LinkedHashMap<>(); + int inc = 0; + while (matcherImg.find()) { + String replacement = "[FEDI_IMG_" + inc + "]"; + imagesToReplace.put(replacement, matcherImg.group(1)); + inc++; + text = text.replaceAll(Pattern.quote(matcherImg.group()), replacement); + } + SpannableStringBuilder content; View view = viewWeakReference.get(); List mentionList = null; @@ -148,6 +160,24 @@ public class SpannableHelper { } } } + + if (imagesToReplace.size() > 0) { + for (Map.Entry entry : imagesToReplace.entrySet()) { + String key = entry.getKey(); + String url = entry.getValue(); + Matcher matcher = Pattern.compile(key, Pattern.LITERAL) + .matcher(content); + while (matcher.find()) { + CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view)); + content.setSpan(customEmoji, matcher.start(), matcher.end(), 0); + Glide.with(view) + .asDrawable() + .load(url) + .into(customEmoji.getTarget(true)); + } + } + + } return trimSpannable(new SpannableStringBuilder(content)); } diff --git a/app/src/main/res/layout/activity_instance.xml b/app/src/main/res/layout/activity_instance.xml index a2500c21..8661017b 100644 --- a/app/src/main/res/layout/activity_instance.xml +++ b/app/src/main/res/layout/activity_instance.xml @@ -22,31 +22,19 @@ - - - - + android:layout_height="match_parent" /> - + @@ -142,7 +122,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="420dp" android:gravity="center" tools:visibility="visible" android:visibility="gone"> @@ -153,6 +133,18 @@ android:indeterminate="true" /> + + + \ No newline at end of file From 348879552022e27e09de10d0f27fdfb1744467ad Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 21 Jul 2022 09:01:17 +0200 Subject: [PATCH 09/14] Add release notes --- app/src/main/assets/release_notes/notes.json | 47 +++++++ .../app/fedilab/android/BaseMainActivity.java | 7 + .../client/entities/app/ReleaseNote.java | 39 ++++++ .../app/fedilab/android/helper/Helper.java | 120 ++++++++++++++++++ .../android/helper/SpannableHelper.java | 6 +- .../android/ui/drawer/ReleaseNoteAdapter.java | 119 +++++++++++++++++ .../res/drawable/ic_baseline_notes_24.xml | 11 ++ .../res/drawable/ic_baseline_translate_24.xml | 10 ++ .../main/res/layout/drawer_release_note.xml | 86 +++++++++++++ .../main/res/layout/popup_release_notes.xml | 111 ++++++++++++++++ .../main/res/menu/activity_main_drawer.xml | 5 +- app/src/main/res/values/strings.xml | 2 + 12 files changed, 559 insertions(+), 4 deletions(-) create mode 100644 app/src/main/assets/release_notes/notes.json create mode 100644 app/src/main/java/app/fedilab/android/client/entities/app/ReleaseNote.java create mode 100644 app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java create mode 100644 app/src/main/res/drawable/ic_baseline_notes_24.xml create mode 100644 app/src/main/res/drawable/ic_baseline_translate_24.xml create mode 100644 app/src/main/res/layout/drawer_release_note.xml create mode 100644 app/src/main/res/layout/popup_release_notes.xml diff --git a/app/src/main/assets/release_notes/notes.json b/app/src/main/assets/release_notes/notes.json new file mode 100644 index 00000000..3a73fa6b --- /dev/null +++ b/app/src/main/assets/release_notes/notes.json @@ -0,0 +1,47 @@ +[ + { + "version": "3.0.9", + "code": "399", + "note": "Added:\n- Set compose language (from compose menu -> three vertical dots)\n- Add reactions support for Pleroma\n- Add privacy indicator at the top right\n\nChanged\n- Improve the scrolling behaviour\n- Scroll to top (tab reselection) will fetch new messages and then scroll to top\n\nFixed:\n- Empty tag timelines\n- Remove focus point for fit media preview\n- Fix cannot share with one account\n- Fix black theme\n- Theme cannot be selected\n- Fix some button colors" + }, + { + "version": "3.0.8", + "code": "398", + "note": "- Keep improving the scroll behaviour\n- Scroll to top (tab reselection) will fetch new messages and then scroll to top\n- Remove focus point for fit media preview\n- Fix cannot share with one account\n- Fix black theme\n- Fix some button colors" + }, + { + "version": "3.0.7", + "code": "397", + "note": "- Fix some bugs reported." + }, + { + "version": "3.0.6", + "code": "396", + "note": "Added:\n- Allow to set a focus point on previews (media editor)\n- Respect the focus point with previews\n- Pagination with the fetch more button support reading up or down\n- Add trends\n\nFixed:\n- Only last push notification is displayed (not grouped)\n- Bad behavior with the right/left scroll\n- Fix long profiles not fully displayed\n- Issues with some polls\n- Some crashes\n- Some bad behaviors" + }, + { + "version": "3.0.5", + "code": "395", + "note": "- Fix some bugs\n- Allow to share with the app" + }, + { + "version": "3.0.4", + "code": "394", + "note": "- Fix crashes for some Pleroma instances" + }, + { + "version": "3.0.2", + "code": "393", + "note": "- Some bug fixes\n- Improve pinned timelines" + }, + { + "version": "3.0.1", + "code": "391", + "note": "Some quick fixes" + }, + { + "version": "3.0.0", + "code": "390", + "note": "New version of Fedilab with new feature.\n- You can now compose threads\n- See the whole thread when replying\n- Cache support\n- New design" + } +] \ No newline at end of file diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 57a3544c..779f5c3f 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -18,6 +18,7 @@ import static app.fedilab.android.BaseMainActivity.status.DISCONNECTED; import static app.fedilab.android.BaseMainActivity.status.UNKNOWN; import static app.fedilab.android.helper.CacheHelper.deleteDir; import static app.fedilab.android.helper.Helper.PREF_USER_TOKEN; +import static app.fedilab.android.helper.Helper.displayReleaseNotesIfNeeded; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; @@ -504,6 +505,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt } else if (id == R.id.nav_about) { Intent intent = new Intent(this, AboutActivity.class); startActivity(intent); + } else if (id == R.id.nav_release_notes) { + displayReleaseNotesIfNeeded(BaseMainActivity.this, true); } else if (id == R.id.nav_partnership) { Intent intent = new Intent(this, PartnerShipActivity.class); startActivity(intent); @@ -523,6 +526,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt binding.drawerLayout.close(); return false; }); + + headerMainBinding.instanceInfo.setOnClickListener(v -> startActivity(new Intent(BaseMainActivity.this, InstanceHealthActivity.class))); headerMainBinding.accountProfilePicture.setOnClickListener(v -> { Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class); @@ -758,6 +763,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt currentInstance = currentAccount.instance; currentUserID = currentAccount.user_id; + show_boosts = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_BOOSTS) + currentUserID + currentInstance, true); show_replies = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_REPLIES) + currentUserID + currentInstance, true); regex_home = sharedpreferences.getString(getString(R.string.SET_FILTER_REGEX_HOME) + currentUserID + currentInstance, null); @@ -798,6 +804,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt .observe(BaseMainActivity.this, mastodonAccount -> { //Initialize static var currentAccount.mastodon_account = mastodonAccount; + displayReleaseNotesIfNeeded(BaseMainActivity.this, false); new Thread(() -> { try { //Update account in db diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/ReleaseNote.java b/app/src/main/java/app/fedilab/android/client/entities/app/ReleaseNote.java new file mode 100644 index 00000000..224d54fe --- /dev/null +++ b/app/src/main/java/app/fedilab/android/client/entities/app/ReleaseNote.java @@ -0,0 +1,39 @@ +package app.fedilab.android.client.entities.app; +/* Copyright 2022 Thomas Schneider + * + * 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 com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.List; + + +public class ReleaseNote implements Serializable { + + @SerializedName("languages") + public List ReleaseNotes; + + + public static class Note implements Serializable { + @SerializedName("code") + public String code; + @SerializedName("version") + public String version; + @SerializedName("note") + public String note; + @SerializedName("noteTranslated") + public String noteTranslated; + } +} diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index b8351169..1b3e82b5 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -74,6 +74,7 @@ import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import androidx.core.app.ActivityOptionsCompat; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; @@ -81,10 +82,12 @@ import androidx.core.graphics.drawable.DrawableCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelStoreOwner; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.LinearLayoutManager; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestBuilder; @@ -95,6 +98,7 @@ import com.bumptech.glide.request.RequestOptions; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; @@ -115,10 +119,12 @@ import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.security.Security; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.LinkedHashMap; @@ -133,19 +139,26 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import app.fedilab.android.BaseMainActivity; +import app.fedilab.android.BuildConfig; import app.fedilab.android.MainApplication; import app.fedilab.android.R; import app.fedilab.android.activities.ComposeActivity; import app.fedilab.android.activities.LoginActivity; import app.fedilab.android.activities.MainActivity; +import app.fedilab.android.activities.ProfileActivity; import app.fedilab.android.activities.WebviewActivity; import app.fedilab.android.broadcastreceiver.ToastMessage; import app.fedilab.android.client.entities.api.Attachment; +import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; import app.fedilab.android.client.entities.app.BaseAccount; +import app.fedilab.android.client.entities.app.ReleaseNote; +import app.fedilab.android.databinding.PopupReleaseNotesBinding; import app.fedilab.android.exception.DBException; import app.fedilab.android.interfaces.OnDownloadInterface; import app.fedilab.android.sqlite.Sqlite; +import app.fedilab.android.ui.drawer.ReleaseNoteAdapter; +import app.fedilab.android.viewmodel.mastodon.AccountsVM; import app.fedilab.android.viewmodel.mastodon.OauthVM; import app.fedilab.android.watermark.androidwm.WatermarkBuilder; import app.fedilab.android.watermark.androidwm.bean.WatermarkText; @@ -1749,4 +1762,111 @@ public class Helper { return null; } + + public static void displayReleaseNotesIfNeeded(Activity activity, boolean forced) { + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity); + int lastReleaseNoteRead = sharedpreferences.getInt(activity.getString(R.string.SET_POPUP_RELEASE_NOTES), 0); + int versionCode = BuildConfig.VERSION_CODE; + if (lastReleaseNoteRead != versionCode || forced) { + try { + InputStream is = activity.getAssets().open("release_notes/notes.json"); + int size; + size = is.available(); + byte[] buffer = new byte[size]; + is.read(buffer); + is.close(); + String json = new String(buffer, StandardCharsets.UTF_8); + Gson gson = new Gson(); + AlertDialog.Builder dialogBuilderOptin = new AlertDialog.Builder(activity, Helper.dialogStyle()); + PopupReleaseNotesBinding binding = PopupReleaseNotesBinding.inflate(activity.getLayoutInflater()); + dialogBuilderOptin.setView(binding.getRoot()); + try { + List releaseNotes = gson.fromJson(json, new TypeToken>() { + }.getType()); + if (releaseNotes != null && releaseNotes.size() > 0) { + ReleaseNoteAdapter adapter = new ReleaseNoteAdapter(releaseNotes); + binding.releasenotes.setAdapter(adapter); + binding.releasenotes.setLayoutManager(new LinearLayoutManager(activity)); + } + } catch (Exception ignored) { + } + if (BuildConfig.DONATIONS) { + binding.aboutSupport.setVisibility(View.VISIBLE); + binding.aboutSupportPaypal.setVisibility(View.VISIBLE); + } else { + binding.aboutSupport.setVisibility(View.GONE); + binding.aboutSupportPaypal.setVisibility(View.GONE); + } + binding.accountFollow.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(activity)); + binding.accountFollow.setImageResource(R.drawable.ic_baseline_person_add_24); + binding.aboutSupport.setOnClickListener(v -> { + Intent intentLiberapay = new Intent(Intent.ACTION_VIEW); + intentLiberapay.setData(Uri.parse("https://liberapay.com/tom79")); + try { + activity.startActivity(intentLiberapay); + } catch (Exception e) { + Helper.openBrowser(activity, "https://liberapay.com/tom79"); + } + }); + binding.aboutSupportPaypal.setOnClickListener(v -> Helper.openBrowser(activity, "https://www.paypal.me/Mastalab")); + CrossActionHelper.fetchRemoteAccount(activity, "@apps@toot.fedilab.app", new CrossActionHelper.Callback() { + @Override + public void federatedStatus(Status status) { + + } + + @Override + public void federatedAccount(app.fedilab.android.client.entities.api.Account account) { + if (account != null && account.username.equalsIgnoreCase("apps")) { + + MastodonHelper.loadPPMastodon(binding.accountPp, account); + binding.accountDn.setText(account.display_name); + binding.accountUn.setText(account.acct); + binding.accountPp.setOnClickListener(v -> { + Intent intent = new Intent(activity, ProfileActivity.class); + Bundle b = new Bundle(); + b.putSerializable(Helper.ARG_ACCOUNT, account); + intent.putExtras(b); + ActivityOptionsCompat options = ActivityOptionsCompat + .makeSceneTransitionAnimation(activity, binding.accountPp, activity.getString(R.string.activity_porfile_pp)); + activity.startActivity(intent, options.toBundle()); + }); + + AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) activity).get(AccountsVM.class); + List ids = new ArrayList<>(); + ids.add(account.id); + accountsVM.getRelationships(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, ids) + .observe((LifecycleOwner) activity, relationShips -> { + if (relationShips != null && relationShips.size() > 0) { + if (!relationShips.get(0).following) { + binding.acccountContainer.setVisibility(View.VISIBLE); + binding.accountFollow.setVisibility(View.VISIBLE); + binding.accountFollow.setOnClickListener(v -> accountsVM.follow(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account.id, true, false) + .observe((LifecycleOwner) activity, relationShip -> binding.accountFollow.setVisibility(View.GONE))); + } + } + }); + } + } + }); + dialogBuilderOptin.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss()); + try { + Handler handler = new Handler(); + handler.postDelayed(() -> { + if (!activity.isFinishing()) { + dialogBuilderOptin.show(); + } + }, 1000); + } catch (Exception e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putInt(activity.getString(R.string.SET_POPUP_RELEASE_NOTES), versionCode); + editor.apply(); + } + } } diff --git a/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java b/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java index e786f473..c23c7f03 100644 --- a/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java @@ -144,9 +144,9 @@ public class SpannableHelper { } else { content = new SpannableStringBuilder(text); } + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false); if (emojiList != null && emojiList.size() > 0) { - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false); for (Emoji emoji : emojiList) { Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL) .matcher(content); @@ -173,7 +173,7 @@ public class SpannableHelper { Glide.with(view) .asDrawable() .load(url) - .into(customEmoji.getTarget(true)); + .into(customEmoji.getTarget(animate)); } } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java new file mode 100644 index 00000000..7d32d3cb --- /dev/null +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java @@ -0,0 +1,119 @@ +package app.fedilab.android.ui.drawer; +/* Copyright 2022 Thomas Schneider + * + * 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.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.github.stom79.mytransl.MyTransL; +import com.github.stom79.mytransl.client.HttpsConnectionException; +import com.github.stom79.mytransl.client.Results; +import com.github.stom79.mytransl.translate.Params; +import com.github.stom79.mytransl.translate.Translate; + +import java.util.List; +import java.util.Locale; + +import app.fedilab.android.R; +import app.fedilab.android.client.entities.app.ReleaseNote; +import app.fedilab.android.databinding.DrawerReleaseNoteBinding; +import es.dmoral.toasty.Toasty; + + +public class ReleaseNoteAdapter extends RecyclerView.Adapter { + + private final List notes; + private Context context; + + public ReleaseNoteAdapter(List notes) { + this.notes = notes; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public int getItemCount() { + return notes.size(); + } + + @NonNull + @Override + public ReleaseNoteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + context = parent.getContext(); + DrawerReleaseNoteBinding itemBinding = DrawerReleaseNoteBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); + return new ReleaseNoteViewHolder(itemBinding); + } + + @Override + public void onBindViewHolder(@NonNull ReleaseNoteViewHolder holder, int position) { + ReleaseNote.Note note = notes.get(position); + holder.binding.note.setText(note.note); + holder.binding.version.setText(String.format(Locale.getDefault(), "%s (%s)", note.version, note.code)); + if (note.noteTranslated != null) { + holder.binding.noteTranslated.setText(note.noteTranslated); + holder.binding.containerTrans.setVisibility(View.VISIBLE); + holder.binding.translate.setVisibility(View.GONE); + } else { + holder.binding.containerTrans.setVisibility(View.GONE); + holder.binding.translate.setVisibility(View.VISIBLE); + } + holder.binding.translate.setOnClickListener(v -> { + MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE; + final MyTransL myTransL = MyTransL.getInstance(et); + myTransL.setObfuscation(true); + Params params = new Params(); + params.setSplit_sentences(false); + params.setFormat(Params.fType.TEXT); + params.setSource_lang("auto"); + myTransL.setLibretranslateDomain("translate.fedilab.app"); + myTransL.translate(note.note, MyTransL.getLocale(), params, new Results() { + @Override + public void onSuccess(Translate translate) { + if (translate.getTranslatedContent() != null) { + note.noteTranslated = translate.getTranslatedContent(); + notifyItemChanged(holder.getBindingAdapterPosition()); + } else { + Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onFail(HttpsConnectionException httpsConnectionException) { + Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); + } + }); + }); + } + + + public static class ReleaseNoteViewHolder extends RecyclerView.ViewHolder { + DrawerReleaseNoteBinding binding; + + ReleaseNoteViewHolder(DrawerReleaseNoteBinding itemView) { + super(itemView.getRoot()); + binding = itemView; + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_baseline_notes_24.xml b/app/src/main/res/drawable/ic_baseline_notes_24.xml new file mode 100644 index 00000000..5b99d33d --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_notes_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_translate_24.xml b/app/src/main/res/drawable/ic_baseline_translate_24.xml new file mode 100644 index 00000000..4b6b9b36 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_translate_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/drawer_release_note.xml b/app/src/main/res/layout/drawer_release_note.xml new file mode 100644 index 00000000..168d5db2 --- /dev/null +++ b/app/src/main/res/layout/drawer_release_note.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/popup_release_notes.xml b/app/src/main/res/layout/popup_release_notes.xml new file mode 100644 index 00000000..3156a61b --- /dev/null +++ b/app/src/main/res/layout/popup_release_notes.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index ab161c77..21f0af4c 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -89,7 +89,10 @@ android:id="@+id/nav_about" android:icon="@drawable/ic_baseline_info_24" android:title="@string/action_about" /> - + wikiless.org LAST_NOTIFICATION_ID SET_MAX_INSTANCE_CHAR + SET_POPUP_RELEASE_NOTES Type of notifications @@ -989,6 +990,7 @@ My app My account Set your max char count + Release notes From c788a9fb2b815db48e4f71c2c1ba892932600274 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Wed, 20 Jul 2022 10:23:43 +0000 Subject: [PATCH 10/14] Translated using Weblate (Sardinian) Currently translated at 100.0% (734 of 734 strings) Translation: Fedilab/Strings Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/sc/ --- app/src/main/res/values-sc/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 5fee265b..8d6429f5 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -722,4 +722,8 @@ Isbòida sa memòria temporànea Imprea sa limba predefinida de sistema Limba pro sos messàgios + S\'istàntzia mea + S\'aplicatzione mea + Imposta su nùmeru màssimu de caràteres tuo + Su contu meu \ No newline at end of file From 0b11783232e1dd1a97a6bb2a3f42d742c1475d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Wed, 20 Jul 2022 15:17:51 +0000 Subject: [PATCH 11/14] Translated using Weblate (Turkish) Currently translated at 100.0% (734 of 734 strings) Translation: Fedilab/Strings Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/ --- app/src/main/res/values-tr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index f4d574a2..9141f5f4 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -728,4 +728,8 @@ Taslaklarda saklanan mesajlar Öntanımlı sistem dilini kullan Mesajlar için dil + Sunucum + Uygulamam + Hesabım + Azami karakter sayınızı ayarlayın \ No newline at end of file From 1f332dbf3a64340121767c630d649b4558ccd43b Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 21 Jul 2022 10:31:52 +0200 Subject: [PATCH 12/14] Add Emoji keyboard for compose --- .../android/ui/drawer/ComposeAdapter.java | 21 +++++++++++++++++++ .../ic_baseline_insert_emoticon_24.xml | 2 +- .../main/res/layout/drawer_status_compose.xml | 17 +++++++++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java index 25230ab3..d922cda2 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java @@ -15,6 +15,7 @@ package app.fedilab.android.ui.drawer; * see . */ +import static android.content.Context.INPUT_METHOD_SERVICE; import static app.fedilab.android.BaseMainActivity.currentAccount; import static app.fedilab.android.BaseMainActivity.emojis; import static app.fedilab.android.BaseMainActivity.instanceInfo; @@ -45,6 +46,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.GridView; @@ -71,6 +73,9 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; +import com.vanniktech.emoji.EmojiManager; +import com.vanniktech.emoji.EmojiPopup; +import com.vanniktech.emoji.one.EmojiOneProvider; import java.io.File; import java.lang.ref.WeakReference; @@ -1073,6 +1078,22 @@ public class ComposeAdapter extends RecyclerView.Adapter { + InputMethodManager imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(holder.binding.buttonEmojiOne.getWindowToken(), 0); + EmojiManager.install(new EmojiOneProvider()); + final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(holder.binding.buttonEmojiOne).setOnEmojiPopupDismissListener(() -> { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + }).build(holder.binding.content); + emojiPopup.toggle(); + }); + } else { + holder.binding.buttonEmojiOne.setVisibility(View.GONE); + } + int newInputType = holder.binding.content.getInputType() & (holder.binding.content.getInputType() ^ InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); holder.binding.content.setInputType(newInputType); diff --git a/app/src/main/res/drawable/ic_baseline_insert_emoticon_24.xml b/app/src/main/res/drawable/ic_baseline_insert_emoticon_24.xml index 51f98877..cb1fa12f 100644 --- a/app/src/main/res/drawable/ic_baseline_insert_emoticon_24.xml +++ b/app/src/main/res/drawable/ic_baseline_insert_emoticon_24.xml @@ -1,7 +1,7 @@ + + @@ -167,7 +180,7 @@ android:layout_height="12dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/button_post" - app:layout_constraintStart_toEndOf="@id/button_emoji" + app:layout_constraintStart_toEndOf="@id/button_emoji_one" app:layout_constraintTop_toBottomOf="@id/character_count" /> Date: Thu, 21 Jul 2022 14:33:37 +0200 Subject: [PATCH 13/14] Fix non updated counter with cache --- .../app/fedilab/android/activities/ContextActivity.java | 6 ++---- app/src/main/java/app/fedilab/android/helper/Helper.java | 4 ++-- .../ui/fragment/timeline/FragmentMastodonContext.java | 3 +++ .../ui/fragment/timeline/FragmentMastodonNotification.java | 3 +++ .../ui/fragment/timeline/FragmentMastodonTimeline.java | 3 +++ 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/activities/ContextActivity.java b/app/src/main/java/app/fedilab/android/activities/ContextActivity.java index 0287e4d9..c9eb7ecc 100644 --- a/app/src/main/java/app/fedilab/android/activities/ContextActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ContextActivity.java @@ -53,14 +53,12 @@ public class ContextActivity extends BaseActivity { public static boolean displayCW; public static Resources.Theme theme; Fragment currentFragment; - private Status focusedStatus; - private ActivityConversationBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ThemeHelper.applyTheme(this); - binding = ActivityConversationBinding.inflate(getLayoutInflater()); + app.fedilab.android.databinding.ActivityConversationBinding binding = ActivityConversationBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); ActionBar actionBar = getSupportActionBar(); @@ -78,7 +76,7 @@ public class ContextActivity extends BaseActivity { Bundle b = getIntent().getExtras(); final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(ContextActivity.this); displayCW = sharedpreferences.getBoolean(getString(R.string.SET_EXPAND_CW), false); - focusedStatus = null; // or other values + Status focusedStatus = null; // or other values if (b != null) focusedStatus = (Status) b.getSerializable(Helper.ARG_STATUS); if (focusedStatus == null || currentAccount == null || currentAccount.mastodon_account == null) { diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index 1b3e82b5..65e48196 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -1474,11 +1474,11 @@ public class Helper { } NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_notification).setTicker(message); - if (notifType == NotifType.MENTION) { + /* if (notifType == NotifType.MENTION) { if (message.length() > 500) { message = message.substring(0, 499) + "…"; } - } + }*/ notificationBuilder.setGroup(account.mastodon_account.acct + "@" + account.instance) .setContentIntent(pIntent) .setContentText(message); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java index 1ce3b38d..a5138f52 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java @@ -69,8 +69,11 @@ public class FragmentMastodonContext extends Fragment { int position = getPosition(receivedStatus); if (position >= 0) { statuses.get(position).reblog = receivedStatus.reblog; + statuses.get(position).reblogged = receivedStatus.reblogged; statuses.get(position).favourited = receivedStatus.favourited; statuses.get(position).bookmarked = receivedStatus.bookmarked; + statuses.get(position).reblogs_count = receivedStatus.reblogs_count; + statuses.get(position).favourites_count = receivedStatus.favourites_count; statusAdapter.notifyItemChanged(position); } } else if (delete_statuses_for_user != null && statusAdapter != null) { diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java index 6d3ce11f..47d06170 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java @@ -76,8 +76,11 @@ public class FragmentMastodonNotification extends Fragment implements Notificati if (position >= 0) { if (notificationList.get(position).status != null) { notificationList.get(position).status.reblog = receivedStatus.reblog; + notificationList.get(position).status.reblogged = receivedStatus.reblogged; notificationList.get(position).status.favourited = receivedStatus.favourited; notificationList.get(position).status.bookmarked = receivedStatus.bookmarked; + notificationList.get(position).status.favourites_count = receivedStatus.favourites_count; + notificationList.get(position).status.reblogs_count = receivedStatus.reblogs_count; notificationAdapter.notifyItemChanged(position); } } diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java index 53fd1aae..034dbbe3 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java @@ -92,8 +92,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. int position = getPosition(receivedStatus); if (position >= 0) { statuses.get(position).reblog = receivedStatus.reblog; + statuses.get(position).reblogged = receivedStatus.reblogged; statuses.get(position).favourited = receivedStatus.favourited; statuses.get(position).bookmarked = receivedStatus.bookmarked; + statuses.get(position).reblogs_count = receivedStatus.reblogs_count; + statuses.get(position).favourites_count = receivedStatus.favourites_count; statusAdapter.notifyItemChanged(position); } } else if (delete_statuses_for_user != null && statusAdapter != null) { From 07a819a9c2c0102f97079b8c483f9babfa46bb37 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 21 Jul 2022 14:46:56 +0200 Subject: [PATCH 14/14] Release 3.0.10 --- app/build.gradle | 4 ++-- app/src/main/assets/release_notes/notes.json | 5 +++++ .../fastlane/metadata/android/en/changelogs/400.txt | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/fdroid/fastlane/metadata/android/en/changelogs/400.txt diff --git a/app/build.gradle b/app/build.gradle index 4899929e..f12def81 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { defaultConfig { minSdk 21 targetSdk 31 - versionCode 399 - versionName "3.0.9" + versionCode 400 + versionName "3.0.10" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } flavorDimensions "default" diff --git a/app/src/main/assets/release_notes/notes.json b/app/src/main/assets/release_notes/notes.json index 3a73fa6b..4efd0691 100644 --- a/app/src/main/assets/release_notes/notes.json +++ b/app/src/main/assets/release_notes/notes.json @@ -1,4 +1,9 @@ [ + { + "version": "3.0.10", + "code": "400", + "note": "Added:\n- Allow to define the max chars count when not detected (In about the instance)\n- Add emoji one picker when composing (must be enabled in settings)\n- Add release notes with the ability to translate them\n\nFixed:\n- Friendica custom emojis not displayed\n- Long press to store media\n- Some bug fixes" + }, { "version": "3.0.9", "code": "399", diff --git a/src/fdroid/fastlane/metadata/android/en/changelogs/400.txt b/src/fdroid/fastlane/metadata/android/en/changelogs/400.txt new file mode 100644 index 00000000..41446c8b --- /dev/null +++ b/src/fdroid/fastlane/metadata/android/en/changelogs/400.txt @@ -0,0 +1,9 @@ +Added: +- Allow to define the max chars count when not detected (In about the instance) +- Add emoji one picker when composing (must be enabled in settings) +- Add release notes with the ability to translate them + +Fixed: +- Friendica custom emojis not displayed +- Long press to store media +- Some bug fixes \ No newline at end of file