diff --git a/mastodon/src/main/assets/blocks.txt b/mastodon/src/main/assets/blocks.txt index 8f0627503..e7cf9991f 100644 --- a/mastodon/src/main/assets/blocks.txt +++ b/mastodon/src/main/assets/blocks.txt @@ -1,56 +1,43 @@ 13bells.com 1611.social 4aem.com +5dollah.click adachi.party -anime.website +adtension.com annihilation.social anon-kenkai.com asbestos.cafe bae.st -bajax.us banepo.st -baraag.net bassam.social +battlepenguin.video beefyboys.win -beepboop.ga -berserker.town -bikeshed.party -boks.moe boymoder.biz brainsoap.net breastmilk.club brighteon.social -bungle.online +cachapa.xyz +canary.fedinuke.example.com +catgirl.life cawfee.club +childlove.space clew.lol clubcyberia.co -collapsitarian.io -comfyboy.club contrapointsfan.club +crucible.world cum.camp cum.salon -darknight-coffee.org decayable.ink dembased.xyz -desupost.soy detroitriotcity.com -eatthebugs.social +djsumdog.com eientei.org -elementality.org eveningzoo.club -firedragonstudios.com -firefaithfellowship.com fluf.club -foxfam.club freak.university freeatlantis.com -freedomstrike.org -freesoftwareextremist.com -freespeech.group freespeechextremist.com -freetalklive.com froth.zone -fulltermprivacy.com gameliberty.club gearlandia.haus genderheretics.xyz @@ -59,42 +46,34 @@ gleasonator.com glee.li glindr.org goyim.app -goyslop.cafe +h5q.net haeder.net handholding.io hitchhiker.social -hunk.city iddqd.social -intkos.link -justicewarrior.social -kawa-kun.com kitsunemimi.club kiwifarms.cc -kompost.cz kurosawa.moe +kyaruc.moe leafposter.club -leftychan.net lewdieheaven.com liberdon.com ligma.pro lolicon.rocks +lolison.network lolison.top lovingexpressions.net -mahodou.moe makemysarcophagus.com -maladaptive.art marsey.moe -masochi.st mastinator.com merovingian.club midwaytrades.com mirr0r.city -moa.st +morale.ch mouse.services mugicha.club narrativerry.xyz natehiggers.online -neckbeard.xyz needs.vodka neenster.org nicecrew.digital @@ -103,18 +82,18 @@ noagendasocial.com noagendasocial.nl noagendatube.com nobodyhasthe.biz -nukem.biz -obo.sh +norwoodzero.net +nyanide.com onionfarms.org pawlicker.com pawoo.net pedo.school +peervideo.club piazza.today pibvt.net pieville.net pisskey.io plagu.ee -pmth.us poa.st poast.org poast.tv @@ -123,17 +102,18 @@ prospeech.space quodverum.com r18.social rakket.app +rapemeat.express rapemeat.solutions -rdrama.cc +rayci.st rebelbase.site -retardedniggers.forsale -rojogato.com ryona.agency +sad.cab schwartzwelt.xyz seal.cafe +shaw.app shigusegubu.club shitpost.cloud -shota.house +shortstacksran.ch silliness.observer skinheads.eu skinheads.io @@ -148,23 +128,20 @@ sneed.social sonichu.com spinster.xyz springbo.cc -starnix.network strelizia.net -syspxl.xyz tastingtraffic.net teci.world theapex.social +thechimp.zone +thenobody.club thepostearthdestination.com tkammer.de trumpislovetrumpis.life truthsocial.co.in -urchan.org +usualsuspects.lol varishangout.net -whinge.house -whinge.town -wideboys.org +vtuberfan.social wolfgirl.bar xn--p1abe3d.xn--80asehdb yggdrasil.social youjo.love -zztails.gay diff --git a/mastodon/src/main/java/org/joinmastodon/android/AudioPlayerService.java b/mastodon/src/main/java/org/joinmastodon/android/AudioPlayerService.java index 362c2fb02..d7b185642 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/AudioPlayerService.java +++ b/mastodon/src/main/java/org/joinmastodon/android/AudioPlayerService.java @@ -281,7 +281,7 @@ public class AudioPlayerService extends Service{ if(playerReady){ boolean isPlaying=player.isPlaying(); - bldr.addAction(new Notification.Action.Builder(Icon.createWithResource(this, isPlaying ? R.drawable.ic_pause_24 : R.drawable.ic_play_24), + bldr.addAction(new Notification.Action.Builder(Icon.createWithResource(this, isPlaying ? R.drawable.ic_fluent_pause_24_filled : R.drawable.ic_fluent_play_24_filled), getString(isPlaying ? R.string.pause : R.string.play), PendingIntent.getBroadcast(this, 2, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_IMMUTABLE)) .build()); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java index 96e145d01..382456256 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java @@ -32,7 +32,6 @@ public class ExternalShareActivity extends FragmentStackActivity{ UiUtils.setUserPreferredTheme(this); super.onCreate(savedInstanceState); if(savedInstanceState==null){ - Optional text = Optional.ofNullable(getIntent().getStringExtra(Intent.EXTRA_TEXT)); Optional>> fediHandle = text.flatMap(UiUtils::parseFediverseHandle); boolean isFediUrl = text.map(UiUtils::looksLikeFediverseUrl).orElse(false); diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index c53ed561b..8a855fd03 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -26,8 +26,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import androidx.annotation.StringRes; - public class GlobalUserPreferences{ private static final String TAG="GlobalUserPreferences"; @@ -58,12 +56,12 @@ public class GlobalUserPreferences{ public static boolean allowRemoteLoading; public static boolean forwardReportDefault; public static AutoRevealMode autoRevealEqualSpoilers; - public static ColorPreference color; public static boolean disableM3PillActiveIndicator; public static boolean showNavigationLabels; public static boolean displayPronounsInTimelines, displayPronounsInThreads, displayPronounsInUserListings; public static boolean overlayMedia; public static boolean showSuicideHelp; + public static boolean underlinedLinks; // MOSHIDON public static boolean showDividers; @@ -133,12 +131,13 @@ public class GlobalUserPreferences{ autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name())); forwardReportDefault=prefs.getBoolean("forwardReportDefault", true); disableM3PillActiveIndicator=prefs.getBoolean("disableM3PillActiveIndicator", false); - showNavigationLabels=prefs.getBoolean("showNavigationLabels", true); + showNavigationLabels=prefs.getBoolean("showNavigationLabels", false); displayPronounsInTimelines=prefs.getBoolean("displayPronounsInTimelines", true); displayPronounsInThreads=prefs.getBoolean("displayPronounsInThreads", true); displayPronounsInUserListings=prefs.getBoolean("displayPronounsInUserListings", true); overlayMedia=prefs.getBoolean("overlayMedia", false); showSuicideHelp=prefs.getBoolean("showSuicideHelp", true); + underlinedLinks=prefs.getBoolean("underlinedLinks", true); // MOSHIDON uniformNotificationIcon=prefs.getBoolean("uniformNotificationIcon", false); @@ -169,18 +168,13 @@ public class GlobalUserPreferences{ .apply(); } - try { - if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){ - color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.MATERIAL3.name())); - }else{ - color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.PURPLE.name())); - } - } catch (IllegalArgumentException|ClassCastException ignored) { - // invalid color name or color was previously saved as integer - color=ColorPreference.PURPLE; - } - - if(prefs.getInt("migrationLevel", 0) < 61) migrateToUpstreamVersion61(); + int migrationLevel=prefs.getInt("migrationLevel", BuildConfig.VERSION_CODE); + if(migrationLevel < 61) + migrateToUpstreamVersion61(); + if(migrationLevel < 102) + migrateToVersion102(); + if(migrationLevel < BuildConfig.VERSION_CODE) + prefs.edit().putInt("migrationLevel", BuildConfig.VERSION_CODE).apply(); } public static void save(){ @@ -211,7 +205,6 @@ public class GlobalUserPreferences{ .putBoolean("spectatorMode", spectatorMode) .putBoolean("autoHideFab", autoHideFab) .putBoolean("compactReblogReplyLine", compactReblogReplyLine) - .putString("color", color.name()) .putBoolean("allowRemoteLoading", allowRemoteLoading) .putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name()) .putBoolean("forwardReportDefault", forwardReportDefault) @@ -222,6 +215,7 @@ public class GlobalUserPreferences{ .putBoolean("displayPronounsInUserListings", displayPronounsInUserListings) .putBoolean("overlayMedia", overlayMedia) .putBoolean("showSuicideHelp", showSuicideHelp) + .putBoolean("underlinedLinks", underlinedLinks) // MOSHIDON .putBoolean("defaultToUnlistedReplies", defaultToUnlistedReplies) @@ -240,11 +234,49 @@ public class GlobalUserPreferences{ .putBoolean("showPostsWithoutAlt", showPostsWithoutAlt) .putBoolean("showMediaPreview", showMediaPreview) - .putInt("theme", theme.ordinal()) - .apply(); } + public enum ThemePreference{ + AUTO, + LIGHT, + DARK + } + + public enum AutoRevealMode { + NEVER, + THREADS, + DISCUSSIONS + } + + public enum PrefixRepliesMode { + NEVER, + ALWAYS, + TO_OTHERS + } + + + //region preferences migrations + + private static void migrateToVersion102(){ + Log.d(TAG, "Migrating preferences to version 102!! (copy current theme to local preferences)"); + + SharedPreferences prefs=getPrefs(); + // only migrate if global prefs even contains a color (but like.. it should) + if(prefs.contains("color")){ + AccountSessionManager asm=AccountSessionManager.getInstance(); + for(AccountSession session : asm.getLoggedInAccounts()){ + if(session.getRawLocalPreferences().contains("color")) continue; + AccountLocalPreferences localPrefs=session.getLocalPreferences(); + localPrefs.color=AccountLocalPreferences.ColorPreference.valueOf(prefs.getString( + "color", AccountLocalPreferences.ColorPreference.MATERIAL3.name() + )); + localPrefs.save(); + } + prefs.edit().remove("color").apply(); + } + } + private static void migrateToUpstreamVersion61(){ Log.d(TAG, "Migrating preferences to upstream version 61!!"); @@ -291,53 +323,8 @@ public class GlobalUserPreferences{ localPrefs.save(); } - - prefs.edit().putInt("migrationLevel", 61).apply(); } - public enum ColorPreference{ - MATERIAL3, - PURPLE, - PINK, - GREEN, - BLUE, - BROWN, - RED, - YELLOW, - NORD, - WHITE; + //endregion - public @StringRes int getName() { - return switch(this){ - case MATERIAL3 -> R.string.sk_color_palette_material3; - case PINK -> R.string.sk_color_palette_pink; - case PURPLE -> R.string.sk_color_palette_purple; - case GREEN -> R.string.sk_color_palette_green; - case BLUE -> R.string.sk_color_palette_blue; - case BROWN -> R.string.sk_color_palette_brown; - case RED -> R.string.sk_color_palette_red; - case YELLOW -> R.string.sk_color_palette_yellow; - case NORD -> R.string.mo_color_palette_nord; - case WHITE -> R.string.mo_color_palette_black_and_white; - }; - } - } - - public enum ThemePreference{ - AUTO, - LIGHT, - DARK - } - - public enum AutoRevealMode { - NEVER, - THREADS, - DISCUSSIONS - } - - public enum PrefixRepliesMode { - NEVER, - ALWAYS, - TO_OTHERS - } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/MainActivity.java b/mastodon/src/main/java/org/joinmastodon/android/MainActivity.java index 3da691e00..cb06d87a4 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/MainActivity.java +++ b/mastodon/src/main/java/org/joinmastodon/android/MainActivity.java @@ -47,7 +47,8 @@ import me.grishka.appkit.api.ErrorResponse; public class MainActivity extends FragmentStackActivity implements ProvidesAssistContent { @Override protected void onCreate(@Nullable Bundle savedInstanceState){ - UiUtils.setUserPreferredTheme(this); + AccountSession session=getCurrentSession(); + UiUtils.setUserPreferredTheme(this, session); super.onCreate(savedInstanceState); if(savedInstanceState==null){ @@ -243,6 +244,36 @@ public class MainActivity extends FragmentStackActivity implements ProvidesAssis if (fragment != null) callFragmentToProvideAssistContent(fragment, assistContent); } + public AccountSession getCurrentSession(){ + AccountSession session; + Bundle args=new Bundle(); + Intent intent=getIntent(); + if(intent.hasExtra("fromExternalShare")) { + return AccountSessionManager.getInstance() + .getAccount(intent.getStringExtra("account")); + } + + boolean fromNotification = intent.getBooleanExtra("fromNotification", false); + boolean hasNotification = intent.hasExtra("notification"); + if(fromNotification){ + String accountID=intent.getStringExtra("accountID"); + try{ + session=AccountSessionManager.getInstance().getAccount(accountID); + if(!hasNotification) args.putString("tab", "notifications"); + }catch(IllegalStateException x){ + session=AccountSessionManager.getInstance().getLastActiveAccount(); + } + }else{ + session=AccountSessionManager.getInstance().getLastActiveAccount(); + } + return session; + } + + public void restartActivity(){ + finish(); + startActivity(new Intent(this, MainActivity.class)); + } + public void restartHomeFragment(){ if(AccountSessionManager.getInstance().getLoggedInAccounts().isEmpty()){ showFragmentClearingBackStack(new CustomWelcomeFragment()); diff --git a/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java b/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java index c8f340fc0..ffb16c4df 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java +++ b/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java @@ -28,6 +28,7 @@ import org.joinmastodon.android.api.requests.statuses.CreateStatus; import org.joinmastodon.android.api.requests.statuses.SetStatusBookmarked; import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited; import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Account; @@ -164,6 +165,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{ private void notify(Context context, PushNotification pn, String accountID, org.joinmastodon.android.model.Notification notification){ NotificationManager nm=context.getSystemService(NotificationManager.class); AccountSession session=AccountSessionManager.get(accountID); + AccountLocalPreferences lp=session.getLocalPreferences(); Account self=session.self; String accountName="@"+self.username+"@"+AccountSessionManager.getInstance().getAccount(accountID).domain; Notification.Builder builder; @@ -218,7 +220,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{ if (!GlobalUserPreferences.uniformNotificationIcon) { builder.setSmallIcon(switch (pn.notificationType) { - case FAVORITE -> R.drawable.ic_fluent_star_24_filled; + case FAVORITE -> lp.likeIcon ? R.drawable.ic_fluent_heart_24_filled : R.drawable.ic_fluent_star_24_filled; case REBLOG -> R.drawable.ic_fluent_arrow_repeat_all_24_filled; case FOLLOW -> R.drawable.ic_fluent_person_add_24_filled; case MENTION -> R.drawable.ic_fluent_mention_24_filled; diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java b/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java index 79cf1c680..cc65eb682 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java @@ -74,7 +74,6 @@ public class CacheController{ result.add(status); }while(cursor.moveToNext()); String _newMaxID=newMaxID; - AccountSessionManager.get(accountID).filterStatuses(result, FilterContext.HOME); uiHandler.post(()->callback.onSuccess(new CacheablePaginatedResponse<>(result, _newMaxID, true))); return; } @@ -86,9 +85,7 @@ public class CacheController{ .setCallback(new Callback<>(){ @Override public void onSuccess(List result){ - ArrayList filtered=new ArrayList<>(result); - AccountSessionManager.get(accountID).filterStatuses(filtered, FilterContext.HOME); - callback.onSuccess(new CacheablePaginatedResponse<>(filtered, result.isEmpty() ? null : result.get(result.size()-1).id, false)); + callback.onSuccess(new CacheablePaginatedResponse<>(result, result.isEmpty() ? null : result.get(result.size()-1).id, false)); putHomeTimeline(result, maxID==null); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/PushSubscriptionManager.java b/mastodon/src/main/java/org/joinmastodon/android/api/PushSubscriptionManager.java index 44cbeac9f..046c55531 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/PushSubscriptionManager.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/PushSubscriptionManager.java @@ -97,7 +97,7 @@ public class PushSubscriptionManager{ deviceToken=getPrefs().getString("deviceToken", null); int tokenVersion=getPrefs().getInt("version", 0); if(!TextUtils.isEmpty(deviceToken) && tokenVersion==BuildConfig.VERSION_CODE){ - registerAllAccountsForPush(true); // TODO: revert this before release + registerAllAccountsForPush(false); return; } Log.i(TAG, "tryRegisterFCM: no token found or app was updated. Trying to get push token..."); diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/notifications/PleromaMarkNotificationsRead.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/notifications/PleromaMarkNotificationsRead.java index 6e9fe23e7..384843b99 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/requests/notifications/PleromaMarkNotificationsRead.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/notifications/PleromaMarkNotificationsRead.java @@ -13,7 +13,7 @@ import okhttp3.MultipartBody; import okhttp3.RequestBody; public class PleromaMarkNotificationsRead extends MastodonAPIRequest> { - private String maxID; + private final String maxID; public PleromaMarkNotificationsRead(String maxID) { super(HttpMethod.POST, "/pleroma/notifications/read", new TypeToken<>(){}); this.maxID = maxID; diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java index fef1c2681..eb2ffdebf 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java @@ -6,10 +6,14 @@ import static org.joinmastodon.android.api.MastodonAPIController.gson; import android.content.SharedPreferences; +import androidx.annotation.StringRes; + import com.google.gson.reflect.TypeToken; +import org.joinmastodon.android.R; import org.joinmastodon.android.model.ContentType; import org.joinmastodon.android.model.Emoji; +import org.joinmastodon.android.model.Emoji; import org.joinmastodon.android.model.PushSubscription; import org.joinmastodon.android.model.TimelineDefinition; @@ -41,16 +45,19 @@ public class AccountLocalPreferences{ public String publishButtonText; public String timelineReplyVisibility; // akkoma-only public boolean keepOnlyLatestNotification; - public boolean emojiReactionsEnabled; public ShowEmojiReactions showEmojiReactions; + public ColorPreference color; + public boolean likeIcon; + public ArrayList recentCustomEmoji; - private final static Type recentLanguagesType = new TypeToken>() {}.getType(); - private final static Type timelinesType = new TypeToken>() {}.getType(); + private final static Type recentLanguagesType=new TypeToken>() {}.getType(); + private final static Type timelinesType=new TypeToken>() {}.getType(); + private final static Type recentCustomEmojiType=new TypeToken>() {}.getType(); // MOSHIDON - private final static Type recentEmojisType = new TypeToken>() {}.getType(); - public Map recentEmojis; +// private final static Type recentEmojisType = new TypeToken>() {}.getType(); +// public Map recentEmojis; private final static Type notificationFiltersType = new TypeToken() {}.getType(); public PushSubscription.Alerts notificationFilters; @@ -77,9 +84,12 @@ public class AccountLocalPreferences{ keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false); emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", session.getInstance().isPresent() && session.getInstance().get().isAkkoma()); showEmojiReactions=ShowEmojiReactions.valueOf(prefs.getString("showEmojiReactions", ShowEmojiReactions.HIDE_EMPTY.name())); + color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.MATERIAL3.name())); + likeIcon=prefs.getBoolean("likeIcon", false); + recentCustomEmoji=fromJson(prefs.getString("recentCustomEmoji", null), recentCustomEmojiType, new ArrayList<>()); // MOSHIDON - recentEmojis=fromJson(prefs.getString("recentEmojis", "{}"), recentEmojisType, new HashMap<>()); +// recentEmojis=fromJson(prefs.getString("recentEmojis", "{}"), recentEmojisType, new HashMap<>()); notificationFilters=fromJson(prefs.getString("notificationFilters", gson.toJson(PushSubscription.Alerts.ofAll())), notificationFiltersType, PushSubscription.Alerts.ofAll()); } @@ -114,13 +124,40 @@ public class AccountLocalPreferences{ .putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification) .putBoolean("emojiReactionsEnabled", emojiReactionsEnabled) .putString("showEmojiReactions", showEmojiReactions.name()) + .putString("color", color.name()) + .putBoolean("likeIcon", likeIcon) + .putString("recentCustomEmoji", gson.toJson(recentCustomEmoji)) // MOSHIDON - .putString("recentEmojis", gson.toJson(recentEmojis)) +// .putString("recentEmojis", gson.toJson(recentEmojis)) .putString("notificationFilters", gson.toJson(notificationFilters)) .apply(); } + public enum ColorPreference{ + MATERIAL3, + PINK, + PURPLE, + GREEN, + BLUE, + BROWN, + RED, + YELLOW; + + public @StringRes int getName() { + return switch(this){ + case MATERIAL3 -> R.string.sk_color_palette_material3; + case PINK -> R.string.sk_color_palette_pink; + case PURPLE -> R.string.sk_color_palette_purple; + case GREEN -> R.string.sk_color_palette_green; + case BLUE -> R.string.sk_color_palette_blue; + case BROWN -> R.string.sk_color_palette_brown; + case RED -> R.string.sk_color_palette_red; + case YELLOW -> R.string.sk_color_palette_yellow; + }; + } + } + public enum ShowEmojiReactions{ HIDE_EMPTY, ONLY_OPENED, diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountSession.java b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountSession.java index c4c7fe09e..225e6bc4c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountSession.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountSession.java @@ -40,7 +40,6 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Predicate; import me.grishka.appkit.api.Callback; import me.grishka.appkit.api.ErrorResponse; @@ -255,52 +254,62 @@ public class AccountSession{ filterStatusContainingObjects(objects, extractor, context, null); } - public void filterStatusContainingObjects(List objects, Function extractor, FilterContext context, Account profile){ - Predicate statusIsOnOwnProfile = (s) -> self != null && profile != null && s.account != null + private boolean statusIsOnOwnProfile(Status s, Account profile){ + return self != null && profile != null && s.account != null && Objects.equals(self.id, profile.id) && Objects.equals(self.id, s.account.id); + } - if(getLocalPreferences().serverSideFiltersSupported){ - // Even with server-side filters, clients are expected to remove statuses that match a filter that hides them - objects.removeIf(o->{ - Status s=extractor.apply(o); - if(s==null) - return false; - if(s.filtered==null) - return false; - // don't hide own posts in own profile - if (statusIsOnOwnProfile.test(s)) - return false; - for(FilterResult filter:s.filtered){ - if(filter.filter.isActive() && filter.filter.filterAction==FilterAction.HIDE) - return true; - } - return false; - }); - return; - } - if(wordFilters==null) - return; - for(T obj:objects){ + private boolean isFilteredType(Status s){ + return (!localPreferences.showReplies && s.inReplyToId != null) + || (!localPreferences.showBoosts && s.reblog != null); + } + + public void filterStatusContainingObjects(List objects, Function extractor, FilterContext context, Account profile){ + if(!localPreferences.serverSideFiltersSupported) for(T obj:objects){ Status s=extractor.apply(obj); if(s!=null && s.filtered!=null){ - getLocalPreferences().serverSideFiltersSupported=true; - getLocalPreferences().save(); - return; + localPreferences.serverSideFiltersSupported=true; + localPreferences.save(); } } - objects.removeIf(o->{ - Status s=extractor.apply(o); - if(s==null) - return false; - // don't hide own posts in own profile - if (statusIsOnOwnProfile.test(s)) - return false; - for(LegacyFilter filter:wordFilters){ + + List removeUs=new ArrayList<>(); + for(int i=0; i 0){ + Status prev=extractor.apply(objects.get(i - 1)); + if(prev!=null) prev.hasGapAfter=true; + } + } + } + objects.removeAll(removeUs); + } + + public boolean filterStatusContainingObject(T object, Function extractor, FilterContext context, Account profile){ + Status s=extractor.apply(object); + if(s==null) + return false; + // don't hide own posts in own profile + if(statusIsOnOwnProfile(s, profile)) + return false; + if(isFilteredType(s) && (context == FilterContext.HOME || context == FilterContext.PUBLIC)) + return true; + // Even with server-side filters, clients are expected to remove statuses that match a filter that hides them + if(localPreferences.serverSideFiltersSupported){ + for(FilterResult filter : s.filtered){ + if(filter.filter.isActive() && filter.filter.filterAction==FilterAction.HIDE) + return true; + } + }else if(wordFilters!=null){ + for(LegacyFilter filter : wordFilters){ if(filter.context.contains(context) && filter.matches(s) && filter.isActive()) return true; } - return false; - }); + } + return false; } public void updateAccountInfo(){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/AccountTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/AccountTimelineFragment.java index 3451eb9a4..333e385ad 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/AccountTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/AccountTimelineFragment.java @@ -9,19 +9,16 @@ import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.RemoveAccountPostsEvent; -import org.joinmastodon.android.events.StatusCreatedEvent; import org.joinmastodon.android.events.StatusUnpinnedEvent; import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem; -import org.joinmastodon.android.utils.StatusFilterPredicate; import org.parceler.Parcels; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import me.grishka.appkit.api.SimpleCallback; @@ -55,15 +52,14 @@ public class AccountTimelineFragment extends StatusListFragment{ @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetAccountStatuses(user.id, offset>0 ? getMaxID() : null, null, count, filter) + currentRequest=new GetAccountStatuses(user.id, getMaxID(), null, count, filter) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ if(getActivity()==null) return; - AccountSessionManager asm = AccountSessionManager.getInstance(); - boolean empty=result.isEmpty(); + boolean more=applyMaxID(result); AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext(), user); - onDataLoaded(result, !empty); + onDataLoaded(result, more); } }) .exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java index ad9f48781..b376f24dc 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java @@ -97,7 +97,7 @@ public class AnnouncementsFragment extends BaseStatusListFragment .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - if (getActivity() == null) return; + if(getActivity()==null) return; // get unread items first List data = result.stream().filter(a -> !a.read).collect(toList()); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java index d78771c06..317c5d6a7 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -9,7 +9,6 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; -import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; @@ -100,6 +99,7 @@ public abstract class BaseStatusListFragment exten protected TypedObjectPool previewlessAttachmentViewsPool=new TypedObjectPool<>(this::makeNewPreviewlessMediaAttachmentView); protected boolean currentlyScrolling; + protected String maxID; public BaseStatusListFragment(){ super(20); @@ -166,6 +166,8 @@ public abstract class BaseStatusListFragment exten } protected String getMaxID(){ + if(refreshing) return null; + if(maxID!=null) return maxID; if(!preloadedData.isEmpty()) return preloadedData.get(preloadedData.size()-1).getID(); else if(!data.isEmpty()) @@ -174,6 +176,12 @@ public abstract class BaseStatusListFragment exten return null; } + protected boolean applyMaxID(List result){ + boolean empty=result.isEmpty(); + if(!empty) maxID=result.get(result.size()-1).id; + return !empty; + } + protected abstract List buildDisplayItems(T s); protected abstract void addAccountToKnown(T s); @@ -642,12 +650,12 @@ public abstract class BaseStatusListFragment exten // to do this if the media grid is not bound, tho - so, doing it ourselves here status.sensitiveRevealed = !status.sensitiveRevealed; } - holder.rebind(); + if(holder.getItem().hasVisibilityToggle) holder.animateVisibilityToggle(false); } public void onSensitiveRevealed(MediaGridStatusDisplayItem.Holder holder) { HeaderStatusDisplayItem.Holder header = findHolderOfType(holder.getItemID(), HeaderStatusDisplayItem.Holder.class); - if(header != null) header.rebind(); + if(header != null && header.getItem().hasVisibilityToggle) header.animateVisibilityToggle(true); } protected void toggleSpoiler(Status status, String itemID){ @@ -695,15 +703,6 @@ public abstract class BaseStatusListFragment exten if (header != null) header.rebind(); } - public void updateEmojiReactions(Status status, String itemID){ - EmojiReactionsStatusDisplayItem.Holder reactions=findHolderOfType(itemID, EmojiReactionsStatusDisplayItem.Holder.class); - if(reactions != null){ - reactions.getItem().status.reactions.clear(); - reactions.getItem().status.reactions.addAll(status.reactions); - reactions.rebind(); - } - } - public void onGapClick(GapStatusDisplayItem.Holder item, boolean downwards){} public void onWarningClick(WarningFilteredStatusDisplayItem.Holder warning){ @@ -937,7 +936,7 @@ public abstract class BaseStatusListFragment exten if(getContext()==null) return; super.onDataLoaded(d, more); // more available, but the page isn't even full yet? seems wrong, let's load some more - if(more && d.size() < itemsPerPage){ + if(more && data.size() < itemsPerPage){ preloader.onScrolledToLastItem(); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java index 9c2f37980..3831bb4e4 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java @@ -28,7 +28,7 @@ public class BookmarkedStatusListFragment extends StatusListFragment{ .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(HeaderPaginationList result){ - if (getActivity() == null) return; + if(getActivity()==null) return; if(result.nextPageUri!=null) nextMaxID=result.nextPageUri.getQueryParameter("max_id"); else diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java index f947bbf37..6384e5750 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java @@ -177,7 +177,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr private int charCount, charLimit, trimmedCharCount; private Button publishButton, languageButton, scheduleTimeBtn; - private PopupMenu languagePopup, contentTypePopup, visibilityPopup, draftOptionsPopup; + private PopupMenu contentTypePopup, visibilityPopup, draftOptionsPopup; private ImageButton publishButtonRelocated, mediaBtn, pollBtn, emojiBtn, spoilerBtn, draftsBtn, scheduleDraftDismiss, contentTypeBtn; private View sensitiveBtn; private TextView replyText; @@ -313,7 +313,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr @Override public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ creatingView=true; - emojiKeyboard=new CustomEmojiPopupKeyboard(getActivity(), customEmojis, instanceDomain, getAccountID()); + emojiKeyboard=new CustomEmojiPopupKeyboard(getActivity(), accountID, customEmojis, instanceDomain); emojiKeyboard.setListener(new CustomEmojiPopupKeyboard.Listener(){ @Override public void onEmojiSelected(Emoji emoji){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java index 5e53cb728..ef03a45ac 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java @@ -26,12 +26,12 @@ import android.widget.ImageView; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.api.MastodonAPIController; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Attachment; import org.joinmastodon.android.ui.M3AlertDialogBuilder; import org.joinmastodon.android.ui.photoviewer.PhotoViewer; import org.joinmastodon.android.ui.utils.ColorPalette; import org.joinmastodon.android.ui.utils.UiUtils; -import org.joinmastodon.android.ui.views.FixedAspectRatioImageView; import java.util.Collections; @@ -54,16 +54,16 @@ public class ComposeImageDescriptionFragment extends MastodonToolbarFragment imp @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); - accountID=getArguments().getString("account"); - attachmentID=getArguments().getString("attachment"); setHasOptionsMenu(true); } @Override public void onAttach(Activity activity){ super.onAttach(activity); + accountID=getArguments().getString("account"); + attachmentID=getArguments().getString("attachment"); themeWrapper=new ContextThemeWrapper(activity, R.style.Theme_Mastodon_Dark); - ColorPalette.palettes.get(GlobalUserPreferences.color).apply(themeWrapper, GlobalUserPreferences.ThemePreference.DARK); + ColorPalette.palettes.get(AccountSessionManager.get(accountID).getLocalPreferences().color).apply(themeWrapper, GlobalUserPreferences.ThemePreference.DARK); setTitle(R.string.add_alt_text); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/EditTimelinesFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/EditTimelinesFragment.java index 1b08ae27b..3243244df 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/EditTimelinesFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/EditTimelinesFragment.java @@ -201,7 +201,7 @@ public class EditTimelinesFragment extends MastodonRecyclerFragment(this){ @Override public void onSuccess(HeaderPaginationList result){ - if (getActivity() == null) return; + if(getActivity()==null) return; if(result.nextPageUri!=null) nextMaxID=result.nextPageUri.getQueryParameter("max_id"); else diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java index d93c19fb3..2a443e436 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java @@ -83,7 +83,7 @@ public class FollowRequestsListFragment extends MastodonRecyclerFragment(this){ @Override public void onSuccess(HeaderPaginationList result){ - if (getActivity() == null) return; + if(getActivity()==null) return; if(result.nextPageUri!=null) nextMaxID=result.nextPageUri.getQueryParameter("max_id"); else diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowedHashtagsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowedHashtagsFragment.java index b6551f75a..22739fc6d 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowedHashtagsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowedHashtagsFragment.java @@ -56,7 +56,7 @@ public class FollowedHashtagsFragment extends MastodonRecyclerFragment .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(HeaderPaginationList result){ - if (getActivity() == null) return; + if(getActivity()==null) return; if(result.nextPageUri!=null) nextMaxID=result.nextPageUri.getQueryParameter("max_id"); else diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java index 273a0bc0e..d7eb43a65 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java @@ -29,6 +29,7 @@ import org.joinmastodon.android.api.requests.tags.SetTagFollowed; import org.joinmastodon.android.api.requests.timelines.GetHashtagTimeline; import org.joinmastodon.android.model.Filter; import org.joinmastodon.android.model.FilterAction; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.FilterKeyword; import org.joinmastodon.android.model.Hashtag; @@ -153,11 +154,14 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{ @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetHashtagTimeline(hashtagName, offset==0 ? null : getMaxID(), null, count, any, all, none, localOnly, getLocalPrefs().timelineReplyVisibility) + currentRequest=new GetHashtagTimeline(hashtagName, getMaxID(), null, count, any, all, none, localOnly, getLocalPrefs().timelineReplyVisibility) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - onDataLoaded(result, !result.isEmpty()); + if(getActivity()==null) return; + boolean more=applyMaxID(result); + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); + onDataLoaded(result, more); } }) .exec(accountID); @@ -285,6 +289,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{ followMenuItem=optionsMenu.findItem(R.id.follow_hashtag); pinMenuItem=optionsMenu.findItem(R.id.pin); followMenuItem.setVisible(toolbarContentVisible); + pinMenuItem.setShowAsAction(toolbarContentVisible ? MenuItem.SHOW_AS_ACTION_NEVER : MenuItem.SHOW_AS_ACTION_ALWAYS); super.updatePinButton(pinMenuItem); muteMenuItem = optionsMenu.findItem(R.id.mute_hashtag); @@ -339,7 +344,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{ } private void updateHeader(){ - if(hashtag==null) + if(hashtag==null || getActivity()==null) return; if(hashtag.history!=null && !hashtag.history.isEmpty()){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java index 19c7951ee..7735ecbed 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java @@ -291,7 +291,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab new GetAnnouncements(false).setCallback(new Callback<>() { @Override public void onSuccess(List result) { - if (getActivity() == null) return; + if(getActivity()==null) return; if (result.stream().anyMatch(a -> !a.read)) { announcementsBadged = true; announcements.setVisible(false); @@ -385,7 +385,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab } private void updateOverflowMenu() { - if (getActivity() == null) return; + if(getActivity()==null) return; Menu m = overflowPopup.getMenu(); m.clear(); overflowPopup.inflate(R.menu.home_overflow); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java index 92d0bb076..51f79de7f 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.RecyclerView; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.api.requests.markers.SaveMarkers; import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline; -import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.CacheablePaginatedResponse; import org.joinmastodon.android.model.FilterContext; @@ -20,6 +19,7 @@ import org.joinmastodon.android.model.TimelineMarkers; import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -49,16 +49,6 @@ public class HomeTimelineFragment extends StatusListFragment { loadData(); } - private boolean typeFilterPredicate(Status s) { - AccountLocalPreferences lp=getLocalPrefs(); - return (lp.showReplies || s.inReplyToId == null) && - (lp.showBoosts || s.reblog == null); - } - - private List filterPosts(List items) { - return items.stream().filter(this::typeFilterPredicate).collect(Collectors.toList()); - } - @Override protected void doLoadData(int offset, int count){ AccountSessionManager.getInstance() @@ -66,10 +56,11 @@ public class HomeTimelineFragment extends StatusListFragment { .getHomeTimeline(offset>0 ? maxID : null, count, refreshing, new SimpleCallback<>(this){ @Override public void onSuccess(CacheablePaginatedResponse> result){ - if (getActivity() == null) return; - List filteredItems = filterPosts(result.items); + if(getActivity()==null) return; + boolean empty=result.items.isEmpty(); maxID=result.maxID; - onDataLoaded(filteredItems, !result.items.isEmpty()); + AccountSessionManager.get(accountID).filterStatuses(result.items, getFilterContext()); + onDataLoaded(result.items, !empty); if(result.isFromCache()) loadNewPosts(); } @@ -142,23 +133,26 @@ public class HomeTimelineFragment extends StatusListFragment { public void onSuccess(List result){ currentRequest=null; dataLoading=false; - result = filterPosts(result); if(result.isEmpty() || getActivity()==null) return; Status last=result.get(result.size()-1); List toAdd; if(!data.isEmpty() && last.id.equals(data.get(0).id)){ // This part intersects with the existing one - toAdd=result.subList(0, result.size()-1); // Remove the already known last post + toAdd=new ArrayList<>(result.subList(0, result.size()-1)); // Remove the already known last post }else{ result.get(result.size()-1).hasGapAfter=true; toAdd=result; } + List existingIds=data.stream().map(Status::getID).collect(Collectors.toList()); + toAdd.removeIf(s->existingIds.contains(s.getID())); + List toAddUnfiltered=new ArrayList<>(toAdd); AccountSessionManager.get(accountID).filterStatuses(toAdd, getFilterContext()); if(!toAdd.isEmpty()){ prependItems(toAdd, true); - if (parent != null && GlobalUserPreferences.showNewPostsButton) parent.showNewPostsButton(); - AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(toAdd, false); + if(parent != null && GlobalUserPreferences.showNewPostsButton) parent.showNewPostsButton(); } + if(toAddUnfiltered.isEmpty()) + AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(toAddUnfiltered, false); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ListTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ListTimelineFragment.java index aaa6e83f1..fb357d991 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ListTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ListTimelineFragment.java @@ -16,6 +16,7 @@ import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.lists.GetList; import org.joinmastodon.android.api.requests.lists.UpdateList; import org.joinmastodon.android.api.requests.timelines.GetListTimeline; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.ListDeletedEvent; import org.joinmastodon.android.events.ListUpdatedCreatedEvent; import org.joinmastodon.android.model.FilterContext; @@ -25,10 +26,8 @@ import org.joinmastodon.android.model.TimelineDefinition; import org.joinmastodon.android.ui.M3AlertDialogBuilder; import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.ui.views.ListEditor; -import org.joinmastodon.android.utils.StatusFilterPredicate; import java.util.List; -import java.util.stream.Collectors; import me.grishka.appkit.Nav; import me.grishka.appkit.api.Callback; @@ -63,7 +62,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment { new GetList(listID).setCallback(new Callback<>() { @Override public void onSuccess(ListTimeline listTimeline) { - if (getActivity() == null) return; + if(getActivity()==null) return; // TODO: save updated info if (!listTimeline.title.equals(listTitle)) setTitle(listTimeline.title); if (listTimeline.repliesPolicy != null && !listTimeline.repliesPolicy.equals(repliesPolicy)) { @@ -101,7 +100,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment { new UpdateList(listID, newTitle, editor.isExclusive(), editor.getRepliesPolicy()).setCallback(new Callback<>() { @Override public void onSuccess(ListTimeline list) { - if (getActivity() == null) return; + if(getActivity()==null) return; setTitle(list.title); listTitle = list.title; repliesPolicy = list.repliesPolicy; @@ -134,13 +133,14 @@ public class ListTimelineFragment extends PinnableStatusListFragment { @Override protected void doLoadData(int offset, int count) { - currentRequest=new GetListTimeline(listID, offset==0 ? null : getMaxID(), null, count, null, getLocalPrefs().timelineReplyVisibility) + currentRequest=new GetListTimeline(listID, getMaxID(), null, count, null, getLocalPrefs().timelineReplyVisibility) .setCallback(new SimpleCallback<>(this) { @Override public void onSuccess(List result) { - if (getActivity() == null) return; - result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList()); - onDataLoaded(result, !result.isEmpty()); + if(getActivity()==null) return; + boolean more=applyMaxID(result); + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); + onDataLoaded(result, more); } }) .exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ListsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ListsFragment.java index 15aba415a..8e92bb5ea 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ListsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ListsFragment.java @@ -140,7 +140,7 @@ public class ListsFragment extends MastodonRecyclerFragment implem .setCallback(new SimpleCallback<>(this) { @Override public void onSuccess(List lists) { - if (getActivity() == null) return; + if(getActivity()==null) return; for (ListTimeline l : lists) userInListBefore.put(l.id, true); userInList.putAll(userInListBefore); if (profileAccountId == null || !lists.isEmpty()) onDataLoaded(lists, false); @@ -149,7 +149,7 @@ public class ListsFragment extends MastodonRecyclerFragment implem currentRequest=new GetLists().setCallback(new SimpleCallback<>(ListsFragment.this) { @Override public void onSuccess(List allLists) { - if (getActivity() == null) return; + if(getActivity()==null) return; List newLists = new ArrayList<>(); for (ListTimeline l : allLists) { if (lists.stream().noneMatch(e -> e.id.equals(l.id))) newLists.add(l); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java index cf103de63..0b5681093 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java @@ -327,7 +327,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc new GetFollowRequests(null, 1).setCallback(new Callback<>() { @Override public void onSuccess(HeaderPaginationList accounts) { - if (getActivity() == null) return; + if(getActivity()==null) return; getToolbar().getMenu().findItem(R.id.follow_requests).setVisible(!accounts.isEmpty()); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java index b2da041b8..b9ff00b14 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java @@ -178,6 +178,7 @@ public class NotificationsListFragment extends BaseStatusListFragmentn.type!=null).collect(Collectors.toList()), !result.items.isEmpty()); + if(bannerHelper!=null) bannerHelper.onBannerBecameVisible(); reloadingFromCache=false; if (getParentFragment() instanceof NotificationsFragment nf) { nf.updateMarkAllReadButton(); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java index 53c44d36d..ff6b16780 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java @@ -5,6 +5,7 @@ import android.os.Bundle; import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.Status; @@ -35,6 +36,8 @@ public class PinnedPostsListFragment extends StatusListFragment{ .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ + if(getActivity()==null) return; + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); onDataLoaded(result, false); } }).exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java index 5afb46c56..b3917c769 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java @@ -138,6 +138,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList private ImageView avatar; private CoverImageView cover; private View avatarBorder; + private View usernameWrap; private TextView name, username, bio, followersCount, followersLabel, followingCount, followingLabel; private ImageView lockIcon, botIcon; private ProgressBarButton actionButton, notifyButton; @@ -241,6 +242,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList cover=content.findViewById(R.id.cover); avatarBorder=content.findViewById(R.id.avatar_border); name=content.findViewById(R.id.name); + usernameWrap=content.findViewById(R.id.username_wrap); username=content.findViewById(R.id.username); lockIcon=content.findViewById(R.id.lock_icon); botIcon=content.findViewById(R.id.bot_icon); @@ -563,7 +565,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(Account result){ - if (getActivity() == null) return; + if(getActivity()==null) return; onAccountLoaded(result); } }) @@ -984,7 +986,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList } private void updateRelationship(){ - if (getActivity() == null) return; + if(getActivity()==null) return; invalidateOptionsMenu(); actionButton.setVisibility(View.VISIBLE); notifyButton.setVisibility(relationship.following ? View.VISIBLE : View.GONE); @@ -1272,6 +1274,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList imm.hideSoftInputFromWindow(content.getWindowToken(), 0); V.setVisibilityAnimated(fab, View.VISIBLE); bindHeaderView(); + V.setVisibilityAnimated(fab, View.VISIBLE); } private void saveAndExitEditMode(){ @@ -1286,7 +1289,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList savingEdits=false; account=result; AccountSessionManager.getInstance().updateAccountInfo(accountID, account); - if (getActivity() == null) return; + if(getActivity()==null) return; exitEditMode(); setActionProgressVisible(false); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ScheduledStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ScheduledStatusListFragment.java index 9705497df..a0af95395 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ScheduledStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ScheduledStatusListFragment.java @@ -130,7 +130,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment(this){ @Override public void onSuccess(List result){ + if(getActivity()==null) return; Collections.sort(result, Comparator.comparing((Status s)->s.createdAt).reversed()); - if (getActivity() == null) return; onDataLoaded(result, false); } }) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java index 1340f649f..d408aa2be 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java @@ -45,10 +45,12 @@ public abstract class StatusListFragment extends BaseStatusListFragment boolean isMainThreadStatus = this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id); int flags = 0; AccountLocalPreferences lp=getLocalPrefs(); - if (GlobalUserPreferences.spectatorMode) + if(GlobalUserPreferences.spectatorMode) flags |= StatusDisplayItem.FLAG_NO_FOOTER; - if (!lp.emojiReactionsEnabled || lp.showEmojiReactions==ONLY_OPENED) + if(!lp.emojiReactionsEnabled || lp.showEmojiReactions==ONLY_OPENED) flags |= StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS; + if(GlobalUserPreferences.translateButtonOpenedOnly) + flags |= StatusDisplayItem.FLAG_NO_TRANSLATE; if(!GlobalUserPreferences.showMediaPreview) flags |= StatusDisplayItem.FLAG_NO_MEDIA_PREVIEW; return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, getFilterContext(), isMainThreadStatus ? 0 : flags); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java index 0a2249fb6..1cb61970f 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -35,7 +35,6 @@ import org.joinmastodon.android.ui.displayitems.WarningFilteredStatusDisplayItem import org.joinmastodon.android.ui.text.HtmlParser; import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.utils.ProvidesAssistContent; -import org.joinmastodon.android.utils.StatusFilterPredicate; import org.parceler.Parcels; import java.util.ArrayDeque; @@ -221,8 +220,8 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist // TODO: figure out how this code works if (isInstanceAkkoma()) sortStatusContext(mainStatus, result); - result.descendants=filterStatuses(result.descendants); - result.ancestors=filterStatuses(result.ancestors); + filterStatuses(result.descendants); + filterStatuses(result.ancestors); restoreStatusStates(result.descendants, oldData); restoreStatusStates(result.ancestors, oldData); @@ -358,11 +357,8 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist .collect(Collectors.toList()); } - private List filterStatuses(List statuses){ - StatusFilterPredicate statusFilterPredicate=new StatusFilterPredicate(accountID,getFilterContext()); - return statuses.stream() - .filter(statusFilterPredicate) - .collect(Collectors.toList()); + private void filterStatuses(List statuses){ + AccountSessionManager.get(accountID).filterStatuses(statuses, getFilterContext()); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java index cdd1022cb..ca95f4697 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java @@ -83,7 +83,7 @@ public abstract class BaseAccountListFragment extends MastodonRecyclerFragment extends BaseAccountListFra nextMaxID=result.nextPageUri.getQueryParameter("max_id"); else nextMaxID=null; - if (getActivity() == null) return; + if(getActivity()==null) return; List items = result.stream() .filter(a -> d.size() > 1000 || d.stream() .noneMatch(i -> i.account.url.equals(a.url))) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/BubbleTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/BubbleTimelineFragment.java index 079c799c7..e0cc248f6 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/BubbleTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/BubbleTimelineFragment.java @@ -6,21 +6,19 @@ import android.os.Bundle; import androidx.recyclerview.widget.RecyclerView; import org.joinmastodon.android.api.requests.timelines.GetBubbleTimeline; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.StatusListFragment; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper; -import org.joinmastodon.android.utils.StatusFilterPredicate; import java.util.List; -import java.util.stream.Collectors; import me.grishka.appkit.api.SimpleCallback; import me.grishka.appkit.utils.MergeRecyclerAdapter; public class BubbleTimelineFragment extends StatusListFragment { private DiscoverInfoBannerHelper bannerHelper; - private String maxID; @Override public void onCreate(Bundle savedInstanceState){ @@ -36,15 +34,15 @@ public class BubbleTimelineFragment extends StatusListFragment { @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetBubbleTimeline(refreshing ? null : maxID, count, getLocalPrefs().timelineReplyVisibility) + currentRequest=new GetBubbleTimeline(getMaxID(), count, getLocalPrefs().timelineReplyVisibility) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - if(!result.isEmpty()) - maxID=result.get(result.size()-1).id; - if (getActivity() == null) return; - result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList()); - onDataLoaded(result, !result.isEmpty()); + if(getActivity()==null) return; + boolean more=applyMaxID(result); + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); + onDataLoaded(result, more); + bannerHelper.onBannerBecameVisible(); } }) .exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java index 5ef113732..793b948f3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java @@ -77,7 +77,7 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment(this){ @Override public void onSuccess(List result){ - if (getActivity() == null) return; + if(getActivity()==null) return; onDataLoaded(result.stream().map(fs->new AccountWrapper(fs.account)).collect(Collectors.toList()), false); loadRelationships(); } @@ -112,7 +112,7 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment result){ relationshipsRequest=null; relationships=result.stream().collect(Collectors.toMap(rel->rel.id, Function.identity())); - if (getActivity() == null) return; + if(getActivity()==null) return; if(list==null) return; for(int i=0;i page){ if(!page.loaded && !page.isDataLoading()) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverPostsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverPostsFragment.java index a25473514..fb25819ed 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverPostsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverPostsFragment.java @@ -4,6 +4,7 @@ import android.net.Uri; import android.os.Bundle; import org.joinmastodon.android.api.requests.trends.GetTrendingStatuses; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.StatusListFragment; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.Status; @@ -17,6 +18,7 @@ import me.grishka.appkit.utils.MergeRecyclerAdapter; public class DiscoverPostsFragment extends StatusListFragment{ private DiscoverInfoBannerHelper bannerHelper; + private int offset; @Override public void onCreate(Bundle savedInstanceState){ @@ -26,12 +28,17 @@ public class DiscoverPostsFragment extends StatusListFragment{ @Override - protected void doLoadData(int offset, int count){ + protected void doLoadData(int o, int count){ + if(refreshing) offset=0; currentRequest=new GetTrendingStatuses(offset, count) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - onDataLoaded(result, !result.isEmpty()); + if(getActivity()==null) return; + boolean empty=result.isEmpty(); + offset+=result.size(); + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); + onDataLoaded(result, !empty); bannerHelper.onBannerBecameVisible(); } }).exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/FederatedTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/FederatedTimelineFragment.java index 0c61f8c8d..5ff063738 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/FederatedTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/FederatedTimelineFragment.java @@ -29,15 +29,14 @@ public class FederatedTimelineFragment extends StatusListFragment{ @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetPublicTimeline(false, false, refreshing ? null : maxID, count, getLocalPrefs().timelineReplyVisibility) + currentRequest=new GetPublicTimeline(false, false, getMaxID(), count, getLocalPrefs().timelineReplyVisibility) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - if(!result.isEmpty()) - maxID=result.get(result.size()-1).id; - boolean empty=result.isEmpty(); - AccountSessionManager.get(accountID).filterStatuses(result, FilterContext.PUBLIC); - onDataLoaded(result, !empty); + if(getActivity()==null) return; + boolean more=applyMaxID(result); + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); + onDataLoaded(result, more); bannerHelper.onBannerBecameVisible(); } }) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java index 2ae94c3d0..aae59908c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java @@ -2,7 +2,6 @@ package org.joinmastodon.android.fragments.discover; import android.net.Uri; import android.os.Bundle; -import android.view.View; import org.joinmastodon.android.api.requests.timelines.GetPublicTimeline; import org.joinmastodon.android.api.session.AccountSessionManager; @@ -30,15 +29,14 @@ public class LocalTimelineFragment extends StatusListFragment{ @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetPublicTimeline(true, false, refreshing ? null : maxID, count, getLocalPrefs().timelineReplyVisibility) + currentRequest=new GetPublicTimeline(true, false, getMaxID(), count, getLocalPrefs().timelineReplyVisibility) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - if(!result.isEmpty()) - maxID=result.get(result.size()-1).id; - boolean empty=result.isEmpty(); - AccountSessionManager.get(accountID).filterStatuses(result, FilterContext.PUBLIC); - onDataLoaded(result, !empty); + if(getActivity()==null) return; + boolean more=applyMaxID(result); + AccountSessionManager.get(accountID).filterStatuses(result, getFilterContext()); + onDataLoaded(result, more); bannerHelper.onBannerBecameVisible(); } }) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/report/ReportAddPostsChoiceFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/report/ReportAddPostsChoiceFragment.java index dad96fa4f..34e65cdfa 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/report/ReportAddPostsChoiceFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/report/ReportAddPostsChoiceFragment.java @@ -83,10 +83,11 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{ @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetAccountStatuses(reportAccount.id, offset>0 ? getMaxID() : null, null, count, GetAccountStatuses.Filter.OWN_POSTS_AND_REPLIES) + currentRequest=new GetAccountStatuses(reportAccount.id, getMaxID(), null, count, GetAccountStatuses.Filter.OWN_POSTS_AND_REPLIES) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ + if(getActivity()==null) return; for(Status s:result){ s.sensitive=true; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/FilterWordsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/FilterWordsFragment.java index 52c4f1955..8ce67f89f 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/FilterWordsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/FilterWordsFragment.java @@ -97,7 +97,7 @@ public class FilterWordsFragment extends BaseSettingsFragment imp public void onViewCreated(View view, Bundle savedInstanceState){ super.onViewCreated(view, savedInstanceState); fab=view.findViewById(R.id.fab); - fab.setImageResource(R.drawable.ic_add_24px); + fab.setImageResource(R.drawable.ic_fluent_add_24_regular); fab.setContentDescription(getString(R.string.add_muted_word)); fab.setOnClickListener(v->onFabClick()); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java index 036c3084d..4fd7b3098 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java @@ -18,6 +18,7 @@ import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.MastodonApp; import org.joinmastodon.android.R; import org.joinmastodon.android.api.session.AccountLocalPreferences; +import org.joinmastodon.android.api.session.AccountLocalPreferences.ColorPreference; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent; @@ -38,7 +39,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ private CheckableListItem revealCWsItem, hideSensitiveMediaItem, interactionCountsItem, emojiInNamesItem; // MEGALODON - private CheckableListItem trueBlackModeItem, marqueeItem, disableSwipeItem, reduceMotionItem, altIndicatorItem, noAltIndicatorItem, collapsePostsItem, spectatorModeItem, hideFabItem, translateOpenedItem, disablePillItem, showNavigationLabelsItem; + private CheckableListItem trueBlackModeItem, marqueeItem, disableSwipeItem, reduceMotionItem, altIndicatorItem, noAltIndicatorItem, collapsePostsItem, spectatorModeItem, hideFabItem, translateOpenedItem, disablePillItem, showNavigationLabelsItem, likeIconItem, underlinedLinksItem; private ListItem colorItem, publishTextItem, autoRevealCWsItem; private CheckableListItem pronounsInUserListingsItem, pronounsInTimelinesItem, pronounsInThreadsItem; @@ -76,6 +77,8 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ spectatorModeItem=new CheckableListItem<>(R.string.sk_settings_hide_interaction, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.spectatorMode, R.drawable.ic_fluent_star_off_24_regular, ()->toggleCheckableItem(spectatorModeItem)), hideFabItem=new CheckableListItem<>(R.string.sk_settings_hide_fab, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.autoHideFab, R.drawable.ic_fluent_edit_24_regular, ()->toggleCheckableItem(hideFabItem)), translateOpenedItem=new CheckableListItem<>(R.string.sk_settings_translate_only_opened, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.translateButtonOpenedOnly, R.drawable.ic_fluent_translate_24_regular, ()->toggleCheckableItem(translateOpenedItem)), + likeIconItem=new CheckableListItem<>(R.string.sk_settings_like_icon, 0, CheckableListItem.Style.SWITCH, lp.likeIcon, R.drawable.ic_fluent_heart_24_regular, ()->toggleCheckableItem(likeIconItem)), + underlinedLinksItem=new CheckableListItem<>(R.string.sk_settings_underlined_links, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.underlinedLinks, R.drawable.ic_fluent_text_underline_24_regular, ()->toggleCheckableItem(underlinedLinksItem)), showPostDividersItem=new CheckableListItem<>(R.string.mo_enable_dividers, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showDividers, R.drawable.ic_fluent_timeline_24_regular, ()->toggleCheckableItem(showPostDividersItem)), disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, ()->toggleCheckableItem(disablePillItem)), showNavigationLabelsItem=new CheckableListItem<>(R.string.sk_settings_show_labels_in_navigation_bar, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNavigationLabels, R.drawable.ic_fluent_tag_24_regular, ()->toggleCheckableItem(showNavigationLabelsItem), true), @@ -106,6 +109,8 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ boolean restartPlease= GlobalUserPreferences.disableM3PillActiveIndicator!=disablePillItem.checked || GlobalUserPreferences.showNavigationLabels!=showNavigationLabelsItem.checked || + lp.likeIcon!=likeIconItem.checked; + GlobalUserPreferences.showNavigationLabels!=showNavigationLabelsItem.checked || GlobalUserPreferences.showMediaPreview !=showMediaPreviewItem.checked || GlobalUserPreferences.showDividers!=showPostDividersItem.checked; @@ -113,6 +118,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ lp.hideSensitiveMedia=hideSensitiveMediaItem.checked; lp.showInteractionCounts=interactionCountsItem.checked; lp.customEmojiInNames=emojiInNamesItem.checked; + lp.likeIcon=likeIconItem.checked; lp.save(); GlobalUserPreferences.toolbarMarquee=marqueeItem.checked; GlobalUserPreferences.relocatePublishButton=relocatePublishButtonItem.checked; @@ -126,6 +132,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ GlobalUserPreferences.spectatorMode=spectatorModeItem.checked; GlobalUserPreferences.autoHideFab=hideFabItem.checked; GlobalUserPreferences.translateButtonOpenedOnly=translateOpenedItem.checked; + GlobalUserPreferences.underlinedLinks=underlinedLinksItem.checked; GlobalUserPreferences.showDividers=showPostDividersItem.checked; GlobalUserPreferences.disableM3PillActiveIndicator=disablePillItem.checked; GlobalUserPreferences.showNavigationLabels=showNavigationLabelsItem.checked; @@ -147,7 +154,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ } private @StringRes int getColorPaletteValue(){ - return switch(GlobalUserPreferences.color){ + return switch(AccountSessionManager.get(accountID).getLocalPreferences().color){ case MATERIAL3 -> R.string.sk_color_palette_material3; case PINK -> R.string.sk_color_palette_pink; case PURPLE -> R.string.sk_color_palette_purple; @@ -214,18 +221,18 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ } private void onColorClick(){ - int selected=GlobalUserPreferences.color.ordinal(); + int selected=lp.color.ordinal(); int[] newSelected={selected}; - String[] names=Arrays.stream(GlobalUserPreferences.ColorPreference.values()).map(GlobalUserPreferences.ColorPreference::getName).map(this::getString).toArray(String[]::new); + String[] names=Arrays.stream(ColorPreference.values()).map(ColorPreference::getName).map(this::getString).toArray(String[]::new); new M3AlertDialogBuilder(getActivity()) - .setTitle(R.string.settings_theme) + .setTitle(R.string.sk_settings_color_palette) .setSingleChoiceItems(names, selected, (dlg, item)->newSelected[0]=item) .setPositiveButton(R.string.ok, (dlg, item)->{ - GlobalUserPreferences.ColorPreference pref=GlobalUserPreferences.ColorPreference.values()[newSelected[0]]; - if(pref!=GlobalUserPreferences.color){ - GlobalUserPreferences.ColorPreference prev=GlobalUserPreferences.color; - GlobalUserPreferences.color=pref; + ColorPreference pref=ColorPreference.values()[newSelected[0]]; + if(pref!=lp.color){ + ColorPreference prev=lp.color; + lp.color=pref; GlobalUserPreferences.save(); colorItem.subtitleRes=getColorPaletteValue(); rebindItem(colorItem); @@ -275,17 +282,17 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ .show(); } - private void maybeApplyNewThemeRightNow(GlobalUserPreferences.ThemePreference prevTheme, GlobalUserPreferences.ColorPreference prevColor, Boolean prevTrueBlack){ + private void maybeApplyNewThemeRightNow(GlobalUserPreferences.ThemePreference prevTheme, ColorPreference prevColor, Boolean prevTrueBlack){ if(prevTheme==null) prevTheme=GlobalUserPreferences.theme; if(prevTrueBlack==null) prevTrueBlack=GlobalUserPreferences.trueBlackTheme; - if(prevColor==null) prevColor=GlobalUserPreferences.color; + if(prevColor==null) prevColor=lp.color; boolean isCurrentDark=prevTheme==GlobalUserPreferences.ThemePreference.DARK || (prevTheme==GlobalUserPreferences.ThemePreference.AUTO && Build.VERSION.SDK_INT>=30 && getResources().getConfiguration().isNightModeActive()); boolean isNewDark=GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.DARK || (GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.AUTO && Build.VERSION.SDK_INT>=30 && getResources().getConfiguration().isNightModeActive()); boolean isNewBlack=GlobalUserPreferences.trueBlackTheme; - if(isCurrentDark!=isNewDark || prevColor!=GlobalUserPreferences.color || (isNewDark && prevTrueBlack!=isNewBlack)){ + if(isCurrentDark!=isNewDark || prevColor!=lp.color || (isNewDark && prevTrueBlack!=isNewBlack)){ restartActivityToApplyNewTheme(); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsFiltersFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsFiltersFragment.java index 39082755c..2a6399e98 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsFiltersFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsFiltersFragment.java @@ -55,7 +55,7 @@ public class SettingsFiltersFragment extends BaseSettingsFragment{ MergeRecyclerAdapter adapter=new MergeRecyclerAdapter(); adapter.addAdapter(super.getAdapter()); adapter.addAdapter(new GenericListItemsAdapter<>(Collections.singletonList( - new ListItem(R.string.settings_add_filter, 0, R.drawable.ic_add_24px, this::onAddFilterClick) + new ListItem(R.string.settings_add_filter, 0, R.drawable.ic_fluent_add_24_regular, this::onAddFilterClick) ))); return adapter; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index 88a608def..d211b25f1 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -64,7 +64,7 @@ public class SettingsMainFragment extends BaseSettingsFragment{ Instance instance = AccountSessionManager.getInstance().getInstanceInfo(account.domain); if (!instance.isAkkoma()) - data.add(2, new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick)); + data.add(3, new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick)); if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){ data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_fluent_wrench_screwdriver_24_regular, ()->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true)); @@ -163,7 +163,7 @@ public class SettingsMainFragment extends BaseSettingsFragment{ .setMessage(getString(R.string.confirm_log_out, session.getFullUsername())) .setPositiveButton(R.string.log_out, (dialog, which)->account.logOut(getActivity(), ()->{ loggedOut=true; - ((MainActivity)getActivity()).restartHomeFragment(); + ((MainActivity)getActivity()).restartActivity(); })) .setNegativeButton(R.string.cancel, null) .show(); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsPrivacyFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsPrivacyFragment.java index 743dd97ab..2a54013d0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsPrivacyFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsPrivacyFragment.java @@ -18,8 +18,8 @@ public class SettingsPrivacyFragment extends BaseSettingsFragment{ setTitle(R.string.settings_privacy); Account self=AccountSessionManager.get(accountID).self; onDataLoaded(List.of( - discoverableItem=new CheckableListItem<>(R.string.settings_discoverable, 0, CheckableListItem.Style.SWITCH, self.discoverable, R.drawable.ic_thumbs_up_down_24px, ()->toggleCheckableItem(discoverableItem)), - indexableItem=new CheckableListItem<>(R.string.settings_indexable, 0, CheckableListItem.Style.SWITCH, self.source.indexable!=null ? self.source.indexable : true, R.drawable.ic_search_24px, ()->toggleCheckableItem(indexableItem)) + discoverableItem=new CheckableListItem<>(R.string.settings_discoverable, 0, CheckableListItem.Style.SWITCH, self.discoverable, R.drawable.ic_fluent_thumb_like_dislike_24_regular, ()->toggleCheckableItem(discoverableItem)), + indexableItem=new CheckableListItem<>(R.string.settings_indexable, 0, CheckableListItem.Style.SWITCH, self.source.indexable!=null ? self.source.indexable : true, R.drawable.ic_fluent_search_24_regular, ()->toggleCheckableItem(indexableItem)) )); if(self.source.indexable==null) indexableItem.isEnabled=false; diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Attachment.java b/mastodon/src/main/java/org/joinmastodon/android/model/Attachment.java index 2e45cd1a1..6fbcc6712 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Attachment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Attachment.java @@ -68,6 +68,14 @@ public class Attachment extends BaseModel{ return 1080; } + public boolean hasKnownDimensions(){ + return meta!=null && ( + (meta.height>0 && meta.width>0) + || (meta.original!=null && meta.original.height>0 && meta.original.width>0) + || (meta.small!=null && meta.small.height>0 && meta.small.width>0) + ); + } + public double getDuration(){ if(meta==null) return 0; diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/FilterResult.java b/mastodon/src/main/java/org/joinmastodon/android/model/FilterResult.java index 8a705eba7..e6d1599be 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/FilterResult.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/FilterResult.java @@ -14,7 +14,7 @@ public class FilterResult extends BaseModel { @Override public void postprocess() throws ObjectValidationException { super.postprocess(); - if(filter!=null) filter.postprocess(); + if(filter!=null) filter.postprocess(); if(keywordMatches==null) keywordMatches=List.of(); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java b/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java index 7e0b1a2ff..ed5e60576 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java @@ -148,8 +148,7 @@ public class AccountSwitcherSheet extends BottomSheet{ private void logOut(String accountID){ AccountSessionManager.get(accountID).logOut(activity, ()->{ - dismiss(); - ((MainActivity)activity).restartHomeFragment(); + ((MainActivity)activity).restartActivity(); }); } @@ -318,14 +317,14 @@ public class AccountSwitcherSheet extends BottomSheet{ @Override public void onClick(){ setOnDismissListener(null); - dismiss(); if (onClick != null) { + dismiss(); onClick.accept(item.getID(), false); return; } if(AccountSessionManager.getInstance().tryGetAccount(item.getID())!=null){ AccountSessionManager.getInstance().setLastActiveAccountID(item.getID()); - ((MainActivity)activity).restartHomeFragment(); + ((MainActivity)activity).restartActivity(); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java b/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java index 1e32291f2..51de87f65 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java @@ -12,6 +12,7 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.Gravity; +import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -24,24 +25,22 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import com.squareup.otto.Subscribe; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.EmojiUpdatedEvent; -import org.joinmastodon.android.fragments.HasAccountID; import org.joinmastodon.android.model.Emoji; import org.joinmastodon.android.model.EmojiCategory; import org.joinmastodon.android.ui.utils.UiUtils; import java.util.ArrayList; -import java.util.ArrayList; -import java.util.Comparator; +import java.util.Iterator; import java.util.List; -import java.util.Optional; +import java.util.Objects; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -59,32 +58,31 @@ import me.grishka.appkit.utils.MergeRecyclerAdapter; import me.grishka.appkit.utils.V; import me.grishka.appkit.views.UsableRecyclerView; -public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccountID{ - //determines how many emoji need to be clicked, before it disappears from the recent emojis - private static final int NEW_RECENT_VALUE=15; +public class CustomEmojiPopupKeyboard extends PopupKeyboard{ private List emojis; private UsableRecyclerView list; private ListImageLoaderWrapper imgLoader; private MergeRecyclerAdapter adapter=new MergeRecyclerAdapter(); private String domain; - private String accountID; private int spanCount=6; private Listener listener; private boolean forReaction; // Generated using https://github.com/mathiasbynens/emoji-test-regex-pattern private static Pattern emojiRegex = Pattern.compile("[#*0-9]\\x{FE0F}?\\x{20E3}|[\\xA9\\xAE\\x{203C}\\x{2049}\\x{2122}\\x{2139}\\x{2194}-\\x{2199}\\x{21A9}\\x{21AA}\\x{231A}\\x{231B}\\x{2328}\\x{23CF}\\x{23ED}-\\x{23EF}\\x{23F1}\\x{23F2}\\x{23F8}-\\x{23FA}\\x{24C2}\\x{25AA}\\x{25AB}\\x{25B6}\\x{25C0}\\x{25FB}\\x{25FC}\\x{25FE}\\x{2600}-\\x{2604}\\x{260E}\\x{2611}\\x{2614}\\x{2615}\\x{2618}\\x{2620}\\x{2622}\\x{2623}\\x{2626}\\x{262A}\\x{262E}\\x{262F}\\x{2638}-\\x{263A}\\x{2640}\\x{2642}\\x{2648}-\\x{2653}\\x{265F}\\x{2660}\\x{2663}\\x{2665}\\x{2666}\\x{2668}\\x{267B}\\x{267E}\\x{267F}\\x{2692}\\x{2694}-\\x{2697}\\x{2699}\\x{269B}\\x{269C}\\x{26A0}\\x{26A7}\\x{26AA}\\x{26B0}\\x{26B1}\\x{26BD}\\x{26BE}\\x{26C4}\\x{26C8}\\x{26CF}\\x{26D1}\\x{26E9}\\x{26F0}-\\x{26F5}\\x{26F7}\\x{26F8}\\x{26FA}\\x{2702}\\x{2708}\\x{2709}\\x{270F}\\x{2712}\\x{2714}\\x{2716}\\x{271D}\\x{2721}\\x{2733}\\x{2734}\\x{2744}\\x{2747}\\x{2757}\\x{2763}\\x{27A1}\\x{2934}\\x{2935}\\x{2B05}-\\x{2B07}\\x{2B1B}\\x{2B1C}\\x{2B55}\\x{3030}\\x{303D}\\x{3297}\\x{3299}\\x{1F004}\\x{1F170}\\x{1F171}\\x{1F17E}\\x{1F17F}\\x{1F202}\\x{1F237}\\x{1F321}\\x{1F324}-\\x{1F32C}\\x{1F336}\\x{1F37D}\\x{1F396}\\x{1F397}\\x{1F399}-\\x{1F39B}\\x{1F39E}\\x{1F39F}\\x{1F3CD}\\x{1F3CE}\\x{1F3D4}-\\x{1F3DF}\\x{1F3F5}\\x{1F3F7}\\x{1F43F}\\x{1F4FD}\\x{1F549}\\x{1F54A}\\x{1F56F}\\x{1F570}\\x{1F573}\\x{1F576}-\\x{1F579}\\x{1F587}\\x{1F58A}-\\x{1F58D}\\x{1F5A5}\\x{1F5A8}\\x{1F5B1}\\x{1F5B2}\\x{1F5BC}\\x{1F5C2}-\\x{1F5C4}\\x{1F5D1}-\\x{1F5D3}\\x{1F5DC}-\\x{1F5DE}\\x{1F5E1}\\x{1F5E3}\\x{1F5E8}\\x{1F5EF}\\x{1F5F3}\\x{1F5FA}\\x{1F6CB}\\x{1F6CD}-\\x{1F6CF}\\x{1F6E0}-\\x{1F6E5}\\x{1F6E9}\\x{1F6F0}\\x{1F6F3}]\\x{FE0F}?|[\\x{261D}\\x{270C}\\x{270D}\\x{1F574}\\x{1F590}][\\x{FE0F}\\x{1F3FB}-\\x{1F3FF}]?|[\\x{26F9}\\x{1F3CB}\\x{1F3CC}\\x{1F575}][\\x{FE0F}\\x{1F3FB}-\\x{1F3FF}]?(?:\\x{200D}[\\x{2640}\\x{2642}]\\x{FE0F}?)?|[\\x{270A}\\x{270B}\\x{1F385}\\x{1F3C2}\\x{1F3C7}\\x{1F442}\\x{1F443}\\x{1F446}-\\x{1F450}\\x{1F466}\\x{1F467}\\x{1F46B}-\\x{1F46D}\\x{1F472}\\x{1F474}-\\x{1F476}\\x{1F478}\\x{1F47C}\\x{1F483}\\x{1F485}\\x{1F48F}\\x{1F491}\\x{1F4AA}\\x{1F57A}\\x{1F595}\\x{1F596}\\x{1F64C}\\x{1F64F}\\x{1F6C0}\\x{1F6CC}\\x{1F90C}\\x{1F90F}\\x{1F918}-\\x{1F91F}\\x{1F930}-\\x{1F934}\\x{1F936}\\x{1F977}\\x{1F9B5}\\x{1F9B6}\\x{1F9BB}\\x{1F9D2}\\x{1F9D3}\\x{1F9D5}\\x{1FAC3}-\\x{1FAC5}\\x{1FAF0}\\x{1FAF2}-\\x{1FAF8}][\\x{1F3FB}-\\x{1F3FF}]?|[\\x{1F3C3}\\x{1F6B6}\\x{1F9CE}][\\x{1F3FB}-\\x{1F3FF}]?(?:\\x{200D}(?:[\\x{2640}\\x{2642}]\\x{FE0F}?(?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|\\x{27A1}\\x{FE0F}?))?|[\\x{1F3C4}\\x{1F3CA}\\x{1F46E}\\x{1F470}\\x{1F471}\\x{1F473}\\x{1F477}\\x{1F481}\\x{1F482}\\x{1F486}\\x{1F487}\\x{1F645}-\\x{1F647}\\x{1F64B}\\x{1F64D}\\x{1F64E}\\x{1F6A3}\\x{1F6B4}\\x{1F6B5}\\x{1F926}\\x{1F935}\\x{1F937}-\\x{1F939}\\x{1F93D}\\x{1F93E}\\x{1F9B8}\\x{1F9B9}\\x{1F9CD}\\x{1F9CF}\\x{1F9D4}\\x{1F9D6}-\\x{1F9DD}][\\x{1F3FB}-\\x{1F3FF}]?(?:\\x{200D}[\\x{2640}\\x{2642}]\\x{FE0F}?)?|[\\x{1F46F}\\x{1F9DE}\\x{1F9DF}](?:\\x{200D}[\\x{2640}\\x{2642}]\\x{FE0F}?)?|[\\x{23E9}-\\x{23EC}\\x{23F0}\\x{23F3}\\x{25FD}\\x{2693}\\x{26A1}\\x{26AB}\\x{26C5}\\x{26CE}\\x{26D4}\\x{26EA}\\x{26FD}\\x{2705}\\x{2728}\\x{274C}\\x{274E}\\x{2753}-\\x{2755}\\x{2795}-\\x{2797}\\x{27B0}\\x{27BF}\\x{2B50}\\x{1F0CF}\\x{1F18E}\\x{1F191}-\\x{1F19A}\\x{1F201}\\x{1F21A}\\x{1F22F}\\x{1F232}-\\x{1F236}\\x{1F238}-\\x{1F23A}\\x{1F250}\\x{1F251}\\x{1F300}-\\x{1F320}\\x{1F32D}-\\x{1F335}\\x{1F337}-\\x{1F343}\\x{1F345}-\\x{1F34A}\\x{1F34C}-\\x{1F37C}\\x{1F37E}-\\x{1F384}\\x{1F386}-\\x{1F393}\\x{1F3A0}-\\x{1F3C1}\\x{1F3C5}\\x{1F3C6}\\x{1F3C8}\\x{1F3C9}\\x{1F3CF}-\\x{1F3D3}\\x{1F3E0}-\\x{1F3F0}\\x{1F3F8}-\\x{1F407}\\x{1F409}-\\x{1F414}\\x{1F416}-\\x{1F425}\\x{1F427}-\\x{1F43A}\\x{1F43C}-\\x{1F43E}\\x{1F440}\\x{1F444}\\x{1F445}\\x{1F451}-\\x{1F465}\\x{1F46A}\\x{1F479}-\\x{1F47B}\\x{1F47D}-\\x{1F480}\\x{1F484}\\x{1F488}-\\x{1F48E}\\x{1F490}\\x{1F492}-\\x{1F4A9}\\x{1F4AB}-\\x{1F4FC}\\x{1F4FF}-\\x{1F53D}\\x{1F54B}-\\x{1F54E}\\x{1F550}-\\x{1F567}\\x{1F5A4}\\x{1F5FB}-\\x{1F62D}\\x{1F62F}-\\x{1F634}\\x{1F637}-\\x{1F641}\\x{1F643}\\x{1F644}\\x{1F648}-\\x{1F64A}\\x{1F680}-\\x{1F6A2}\\x{1F6A4}-\\x{1F6B3}\\x{1F6B7}-\\x{1F6BF}\\x{1F6C1}-\\x{1F6C5}\\x{1F6D0}-\\x{1F6D2}\\x{1F6D5}-\\x{1F6D7}\\x{1F6DC}-\\x{1F6DF}\\x{1F6EB}\\x{1F6EC}\\x{1F6F4}-\\x{1F6FC}\\x{1F7E0}-\\x{1F7EB}\\x{1F7F0}\\x{1F90D}\\x{1F90E}\\x{1F910}-\\x{1F917}\\x{1F920}-\\x{1F925}\\x{1F927}-\\x{1F92F}\\x{1F93A}\\x{1F93F}-\\x{1F945}\\x{1F947}-\\x{1F976}\\x{1F978}-\\x{1F9B4}\\x{1F9B7}\\x{1F9BA}\\x{1F9BC}-\\x{1F9CC}\\x{1F9D0}\\x{1F9E0}-\\x{1F9FF}\\x{1FA70}-\\x{1FA7C}\\x{1FA80}-\\x{1FA88}\\x{1FA90}-\\x{1FABD}\\x{1FABF}-\\x{1FAC2}\\x{1FACE}-\\x{1FADB}\\x{1FAE0}-\\x{1FAE8}]|\\x{26D3}\\x{FE0F}?(?:\\x{200D}\\x{1F4A5})?|\\x{2764}\\x{FE0F}?(?:\\x{200D}[\\x{1F525}\\x{1FA79}])?|\\x{1F1E6}[\\x{1F1E8}-\\x{1F1EC}\\x{1F1EE}\\x{1F1F1}\\x{1F1F2}\\x{1F1F4}\\x{1F1F6}-\\x{1F1FA}\\x{1F1FC}\\x{1F1FD}\\x{1F1FF}]|\\x{1F1E7}[\\x{1F1E6}\\x{1F1E7}\\x{1F1E9}-\\x{1F1EF}\\x{1F1F1}-\\x{1F1F4}\\x{1F1F6}-\\x{1F1F9}\\x{1F1FB}\\x{1F1FC}\\x{1F1FE}\\x{1F1FF}]|\\x{1F1E8}[\\x{1F1E6}\\x{1F1E8}\\x{1F1E9}\\x{1F1EB}-\\x{1F1EE}\\x{1F1F0}-\\x{1F1F5}\\x{1F1F7}\\x{1F1FA}-\\x{1F1FF}]|\\x{1F1E9}[\\x{1F1EA}\\x{1F1EC}\\x{1F1EF}\\x{1F1F0}\\x{1F1F2}\\x{1F1F4}\\x{1F1FF}]|\\x{1F1EA}[\\x{1F1E6}\\x{1F1E8}\\x{1F1EA}\\x{1F1EC}\\x{1F1ED}\\x{1F1F7}-\\x{1F1FA}]|\\x{1F1EB}[\\x{1F1EE}-\\x{1F1F0}\\x{1F1F2}\\x{1F1F4}\\x{1F1F7}]|\\x{1F1EC}[\\x{1F1E6}\\x{1F1E7}\\x{1F1E9}-\\x{1F1EE}\\x{1F1F1}-\\x{1F1F3}\\x{1F1F5}-\\x{1F1FA}\\x{1F1FC}\\x{1F1FE}]|\\x{1F1ED}[\\x{1F1F0}\\x{1F1F2}\\x{1F1F3}\\x{1F1F7}\\x{1F1F9}\\x{1F1FA}]|\\x{1F1EE}[\\x{1F1E8}-\\x{1F1EA}\\x{1F1F1}-\\x{1F1F4}\\x{1F1F6}-\\x{1F1F9}]|\\x{1F1EF}[\\x{1F1EA}\\x{1F1F2}\\x{1F1F4}\\x{1F1F5}]|\\x{1F1F0}[\\x{1F1EA}\\x{1F1EC}-\\x{1F1EE}\\x{1F1F2}\\x{1F1F3}\\x{1F1F5}\\x{1F1F7}\\x{1F1FC}\\x{1F1FE}\\x{1F1FF}]|\\x{1F1F1}[\\x{1F1E6}-\\x{1F1E8}\\x{1F1EE}\\x{1F1F0}\\x{1F1F7}-\\x{1F1FB}\\x{1F1FE}]|\\x{1F1F2}[\\x{1F1E6}\\x{1F1E8}-\\x{1F1ED}\\x{1F1F0}-\\x{1F1FF}]|\\x{1F1F3}[\\x{1F1E6}\\x{1F1E8}\\x{1F1EA}-\\x{1F1EC}\\x{1F1EE}\\x{1F1F1}\\x{1F1F4}\\x{1F1F5}\\x{1F1F7}\\x{1F1FA}\\x{1F1FF}]|\\x{1F1F4}\\x{1F1F2}|\\x{1F1F5}[\\x{1F1E6}\\x{1F1EA}-\\x{1F1ED}\\x{1F1F0}-\\x{1F1F3}\\x{1F1F7}-\\x{1F1F9}\\x{1F1FC}\\x{1F1FE}]|\\x{1F1F6}\\x{1F1E6}|\\x{1F1F7}[\\x{1F1EA}\\x{1F1F4}\\x{1F1F8}\\x{1F1FA}\\x{1F1FC}]|\\x{1F1F8}[\\x{1F1E6}-\\x{1F1EA}\\x{1F1EC}-\\x{1F1F4}\\x{1F1F7}-\\x{1F1F9}\\x{1F1FB}\\x{1F1FD}-\\x{1F1FF}]|\\x{1F1F9}[\\x{1F1E6}\\x{1F1E8}\\x{1F1E9}\\x{1F1EB}-\\x{1F1ED}\\x{1F1EF}-\\x{1F1F4}\\x{1F1F7}\\x{1F1F9}\\x{1F1FB}\\x{1F1FC}\\x{1F1FF}]|\\x{1F1FA}[\\x{1F1E6}\\x{1F1EC}\\x{1F1F2}\\x{1F1F3}\\x{1F1F8}\\x{1F1FE}\\x{1F1FF}]|\\x{1F1FB}[\\x{1F1E6}\\x{1F1E8}\\x{1F1EA}\\x{1F1EC}\\x{1F1EE}\\x{1F1F3}\\x{1F1FA}]|\\x{1F1FC}[\\x{1F1EB}\\x{1F1F8}]|\\x{1F1FD}\\x{1F1F0}|\\x{1F1FE}[\\x{1F1EA}\\x{1F1F9}]|\\x{1F1FF}[\\x{1F1E6}\\x{1F1F2}\\x{1F1FC}]|\\x{1F344}(?:\\x{200D}\\x{1F7EB})?|\\x{1F34B}(?:\\x{200D}\\x{1F7E9})?|\\x{1F3F3}\\x{FE0F}?(?:\\x{200D}(?:\\x{26A7}\\x{FE0F}?|\\x{1F308}))?|\\x{1F3F4}(?:\\x{200D}\\x{2620}\\x{FE0F}?|\\x{E0067}\\x{E0062}(?:\\x{E0065}\\x{E006E}\\x{E0067}|\\x{E0073}\\x{E0063}\\x{E0074}|\\x{E0077}\\x{E006C}\\x{E0073})\\x{E007F})?|\\x{1F408}(?:\\x{200D}\\x{2B1B})?|\\x{1F415}(?:\\x{200D}\\x{1F9BA})?|\\x{1F426}(?:\\x{200D}[\\x{2B1B}\\x{1F525}])?|\\x{1F43B}(?:\\x{200D}\\x{2744}\\x{FE0F}?)?|\\x{1F441}\\x{FE0F}?(?:\\x{200D}\\x{1F5E8}\\x{FE0F}?)?|\\x{1F468}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F468}\\x{1F469}]\\x{200D}(?:\\x{1F466}(?:\\x{200D}\\x{1F466})?|\\x{1F467}(?:\\x{200D}[\\x{1F466}\\x{1F467}])?)|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F468}|\\x{1F466}(?:\\x{200D}\\x{1F466})?|\\x{1F467}(?:\\x{200D}[\\x{1F466}\\x{1F467}])?)|\\x{1F3FB}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F468}[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F468}[\\x{1F3FC}-\\x{1F3FF}]))?|\\x{1F3FC}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F468}[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F468}[\\x{1F3FB}\\x{1F3FD}-\\x{1F3FF}]))?|\\x{1F3FD}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F468}[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F468}[\\x{1F3FB}\\x{1F3FC}\\x{1F3FE}\\x{1F3FF}]))?|\\x{1F3FE}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F468}[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F468}[\\x{1F3FB}-\\x{1F3FD}\\x{1F3FF}]))?|\\x{1F3FF}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F468}[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F468}[\\x{1F3FB}-\\x{1F3FE}]))?)?|\\x{1F469}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?[\\x{1F468}\\x{1F469}]|\\x{1F466}(?:\\x{200D}\\x{1F466})?|\\x{1F467}(?:\\x{200D}[\\x{1F466}\\x{1F467}])?|\\x{1F469}\\x{200D}(?:\\x{1F466}(?:\\x{200D}\\x{1F466})?|\\x{1F467}(?:\\x{200D}[\\x{1F466}\\x{1F467}])?))|\\x{1F3FB}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:[\\x{1F468}\\x{1F469}]|\\x{1F48B}\\x{200D}[\\x{1F468}\\x{1F469}])[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}[\\x{1F468}\\x{1F469}][\\x{1F3FC}-\\x{1F3FF}]))?|\\x{1F3FC}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:[\\x{1F468}\\x{1F469}]|\\x{1F48B}\\x{200D}[\\x{1F468}\\x{1F469}])[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}[\\x{1F468}\\x{1F469}][\\x{1F3FB}\\x{1F3FD}-\\x{1F3FF}]))?|\\x{1F3FD}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:[\\x{1F468}\\x{1F469}]|\\x{1F48B}\\x{200D}[\\x{1F468}\\x{1F469}])[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}[\\x{1F468}\\x{1F469}][\\x{1F3FB}\\x{1F3FC}\\x{1F3FE}\\x{1F3FF}]))?|\\x{1F3FE}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:[\\x{1F468}\\x{1F469}]|\\x{1F48B}\\x{200D}[\\x{1F468}\\x{1F469}])[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}[\\x{1F468}\\x{1F469}][\\x{1F3FB}-\\x{1F3FD}\\x{1F3FF}]))?|\\x{1F3FF}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:[\\x{1F468}\\x{1F469}]|\\x{1F48B}\\x{200D}[\\x{1F468}\\x{1F469}])[\\x{1F3FB}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}[\\x{1F468}\\x{1F469}][\\x{1F3FB}-\\x{1F3FE}]))?)?|\\x{1F62E}(?:\\x{200D}\\x{1F4A8})?|\\x{1F635}(?:\\x{200D}\\x{1F4AB})?|\\x{1F636}(?:\\x{200D}\\x{1F32B}\\x{FE0F}?)?|\\x{1F642}(?:\\x{200D}[\\x{2194}\\x{2195}]\\x{FE0F}?)?|\\x{1F93C}(?:[\\x{1F3FB}-\\x{1F3FF}]|\\x{200D}[\\x{2640}\\x{2642}]\\x{FE0F}?)?|\\x{1F9D1}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F384}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{1F91D}\\x{200D}\\x{1F9D1}|\\x{1F9D1}\\x{200D}\\x{1F9D2}(?:\\x{200D}\\x{1F9D2})?|\\x{1F9D2}(?:\\x{200D}\\x{1F9D2})?)|\\x{1F3FB}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F384}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F9D1}[\\x{1F3FC}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FF}]))?|\\x{1F3FC}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F384}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F9D1}[\\x{1F3FB}\\x{1F3FD}-\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FF}]))?|\\x{1F3FD}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F384}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F9D1}[\\x{1F3FB}\\x{1F3FC}\\x{1F3FE}\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FF}]))?|\\x{1F3FE}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F384}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FD}\\x{1F3FF}]|\\x{1F91D}\\x{200D}\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FF}]))?|\\x{1F3FF}(?:\\x{200D}(?:[\\x{2695}\\x{2696}\\x{2708}]\\x{FE0F}?|[\\x{1F9AF}\\x{1F9BC}\\x{1F9BD}](?:\\x{200D}\\x{27A1}\\x{FE0F}?)?|[\\x{1F33E}\\x{1F373}\\x{1F37C}\\x{1F384}\\x{1F393}\\x{1F3A4}\\x{1F3A8}\\x{1F3EB}\\x{1F3ED}\\x{1F4BB}\\x{1F4BC}\\x{1F527}\\x{1F52C}\\x{1F680}\\x{1F692}\\x{1F9B0}-\\x{1F9B3}]|\\x{2764}\\x{FE0F}?\\x{200D}(?:\\x{1F48B}\\x{200D})?\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FE}]|\\x{1F91D}\\x{200D}\\x{1F9D1}[\\x{1F3FB}-\\x{1F3FF}]))?)?|\\x{1FAF1}(?:\\x{1F3FB}(?:\\x{200D}\\x{1FAF2}[\\x{1F3FC}-\\x{1F3FF}])?|\\x{1F3FC}(?:\\x{200D}\\x{1FAF2}[\\x{1F3FB}\\x{1F3FD}-\\x{1F3FF}])?|\\x{1F3FD}(?:\\x{200D}\\x{1FAF2}[\\x{1F3FB}\\x{1F3FC}\\x{1F3FE}\\x{1F3FF}])?|\\x{1F3FE}(?:\\x{200D}\\x{1FAF2}[\\x{1F3FB}-\\x{1F3FD}\\x{1F3FF}])?|\\x{1F3FF}(?:\\x{200D}\\x{1FAF2}[\\x{1F3FB}-\\x{1F3FE}])?)?"); private final boolean playGifs; + private final AccountLocalPreferences lp; + private EmojiCategory recentEmojiCategory; - public CustomEmojiPopupKeyboard(Activity activity, List emojis, String domain, String accountID){ - this(activity, emojis, domain, false, accountID); + public CustomEmojiPopupKeyboard(Activity activity, String accountID, List emojis, String domain){ + this(activity, accountID, emojis, domain, false); } - public CustomEmojiPopupKeyboard(Activity activity, List emojis, String domain, boolean forReaction, String accountID){ + public CustomEmojiPopupKeyboard(Activity activity, String accountID, List emojis, String domain, boolean forReaction){ super(activity); this.emojis=emojis; this.domain=domain; - this.accountID=accountID; this.forReaction=forReaction; + lp=AccountSessionManager.get(accountID).getLocalPreferences(); playGifs=GlobalUserPreferences.playGifs; } @@ -113,16 +111,9 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun list.setPadding(V.dp(16), 0, V.dp(16), 0); imgLoader=new ListImageLoaderWrapper(activity, list, new RecyclerViewDelegate(list), null); - // inject category with last used emojis - if (!getLocalPrefs().recentEmojis.isEmpty()) { - List allAvailableEmojis = emojis.stream().flatMap(category -> category.emojis.stream()).collect(Collectors.toList()); - List recentEmojiList = new ArrayList<>(); - for (String emojiCode : getLocalPrefs().recentEmojis.keySet().stream().sorted(Comparator.comparingInt(getLocalPrefs().recentEmojis::get).reversed()).collect(Collectors.toList())) { - Optional element = allAvailableEmojis.stream().filter(e -> e.shortcode.equals(emojiCode)).findFirst(); - element.ifPresent(recentEmojiList::add); - } - emojis.add(0, new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmojiList)); - } + List recentEmoji=new ArrayList<>(lp.recentCustomEmoji); + if(!recentEmoji.isEmpty()) + adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji))); for(EmojiCategory category:emojis) adapter.addAdapter(new SingleCategoryAdapter(category)); @@ -166,7 +157,7 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun topPanel.setPadding(V.dp(16), V.dp(12), V.dp(16), V.dp(12)); topPanel.setBackgroundResource(R.drawable.bg_m3_surface2); ll.addView(topPanel, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - + InputMethodManager imm=(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); EditText input=new EditText(activity); input.setHint(R.string.sk_enter_emoji_hint); @@ -222,11 +213,6 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun bottomPanel.addView(backspace, new FrameLayout.LayoutParams(V.dp(48), V.dp(48), Gravity.END | Gravity.CENTER_VERTICAL)); } - //remove recently used afterwards, it would get duplicated otherwise - if (!getLocalPrefs().recentEmojis.isEmpty()) { - emojis.remove(0); - } - return ll; } @@ -243,11 +229,6 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun } } - @Override - public String getAccountID(){ - return accountID; - } - private class SingleCategoryAdapter extends UsableRecyclerView.Adapter implements ImageLoaderRecyclerAdapter, Filterable{ private EmojiCategory category; @@ -264,7 +245,7 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){ - return viewType==0 ? new SectionHeaderViewHolder() : new EmojiViewHolder(); + return viewType==0 ? new SectionHeaderViewHolder() : new EmojiViewHolder(category==recentEmojiCategory, requests); } @Override @@ -358,22 +339,12 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun } } - private void increaseEmojiCount(Emoji emoji) { - Integer usageCount = getLocalPrefs().recentEmojis.get(emoji.shortcode); - if (usageCount != null) { - getLocalPrefs().recentEmojis.put(emoji.shortcode, usageCount + 1); - } else { - getLocalPrefs().recentEmojis.put(emoji.shortcode, NEW_RECENT_VALUE); - } - - getLocalPrefs().recentEmojis.entrySet().removeIf(e -> e.getValue() <= 0); - getLocalPrefs().recentEmojis.replaceAll((k, v) -> v - 1); - getLocalPrefs().save(); - } - - private class EmojiViewHolder extends BindableViewHolder implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{ + private class EmojiViewHolder extends BindableViewHolder implements ImageLoaderViewHolder, UsableRecyclerView.Clickable, UsableRecyclerView.LongClickable{ public int positionWithinCategory; - public EmojiViewHolder(){ + public final boolean isRecentEmojiCategory; + private List requests; + + public EmojiViewHolder(boolean isRecentEmojiCategory, List requests){ super(new ImageView(activity)); ImageView img=(ImageView) itemView; img.setLayoutParams(new RecyclerView.LayoutParams(V.dp(48), V.dp(48))); @@ -381,6 +352,8 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun int pad=V.dp(6); img.setPadding(pad, pad, pad, pad); img.setBackgroundResource(R.drawable.bg_custom_emoji); + this.isRecentEmojiCategory=isRecentEmojiCategory; + this.requests=requests; } @Override @@ -400,9 +373,29 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun ((ImageView)itemView).setImageDrawable(null); } + @Override + public boolean onLongClick(){ + if(!isRecentEmojiCategory) return false; + requests.remove(getAbsoluteAdapterPosition()-1); + getBindingAdapter().notifyItemRemoved(getAbsoluteAdapterPosition()); + getBindingAdapter().notifyItemChanged(0); + recentEmojiCategory.emojis.remove(item); + imgLoader.updateImages(); + itemView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + lp.recentCustomEmoji.remove(item); + lp.save(); + return true; + } + @Override public void onClick(){ - increaseEmojiCount(item); + Iterator iterator=lp.recentCustomEmoji.iterator(); + while(iterator.hasNext()) + if(Objects.equals(iterator.next().shortcode, item.shortcode)) + iterator.remove(); + if(lp.recentCustomEmoji.size() < 21) + lp.recentCustomEmoji.add(0, item); + lp.save(); listener.onEmojiSelected(item); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java index a87ccdde1..e360d803b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java @@ -170,12 +170,14 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem { @Override public void onBind(EmojiReactionsStatusDisplayItem item) { if(emojiKeyboard != null) root.removeView(emojiKeyboard.getView()); + addButton.setSelected(false); AccountSession session=item.parentFragment.getSession(); item.status.reactions.forEach(r->r.request=r.getUrl(item.playGifs)!=null ? new UrlImageLoaderRequest(r.getUrl(item.playGifs), V.sp(24), V.sp(24)) : null); emojiKeyboard=new CustomEmojiPopupKeyboard( (Activity) item.parentFragment.getContext(), + item.accountID, AccountSessionManager.getInstance().getCustomEmojis(session.domain), session.domain, true, item.accountID); emojiKeyboard.setListener(this); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java index b0fa6ad69..7cee2053c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java @@ -14,6 +14,8 @@ import android.widget.ImageView; import android.widget.TextView; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.session.AccountSession; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.BaseStatusListFragment; import org.joinmastodon.android.fragments.StatusEditHistoryFragment; @@ -75,6 +77,9 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{ @Override public void onBind(ExtendedFooterStatusDisplayItem item){ Status s=item.status; + AccountSession session=AccountSessionManager.get(item.accountID); + boolean like=session!=null && session.getLocalPreferences().likeIcon; + favorites.setCompoundDrawablesRelativeWithIntrinsicBounds(like ? R.drawable.ic_fluent_heart_20_regular : R.drawable.ic_fluent_star_20_regular, 0, 0, 0); favorites.setText(context.getResources().getQuantityString(R.plurals.x_favorites, (int)(s.favouritesCount%1000), s.favouritesCount)); reblogs.setText(context.getResources().getQuantityString(R.plurals.x_reblogs, (int) (s.reblogsCount % 1000), s.reblogsCount)); reblogs.setVisibility(s.visibility != StatusPrivacy.DIRECT ? View.VISIBLE : View.GONE); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java index 92a5b7f1f..ecb1741e9 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java @@ -1,12 +1,10 @@ package org.joinmastodon.android.ui.displayitems; -import static org.joinmastodon.android.ui.utils.UiUtils.opacityIn; -import static org.joinmastodon.android.ui.utils.UiUtils.opacityOut; - import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.Intent; +import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; @@ -25,6 +23,7 @@ import android.view.animation.AnimationSet; import android.view.animation.RotateAnimation; import android.widget.Button; import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.TextView; import org.joinmastodon.android.GlobalUserPreferences; @@ -65,6 +64,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ public static class Holder extends StatusDisplayItem.Holder{ private final TextView replies, boosts, favorites; private final View reply, boost, favorite, share, bookmark; + private final ImageView favIcon; private static final Animation opacityOut, opacityIn; private static AnimationSet animSet; @@ -74,7 +74,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ private final Runnable longClickRunnable = () -> { longClickPerformed = touchingView != null && touchingView.performLongClick(); if (longClickPerformed && touchingView != null) { - touchingView.startAnimation(opacityIn); + UiUtils.opacityIn(touchingView); touchingView.animate().scaleX(1).scaleY(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start(); } }; @@ -88,27 +88,6 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ } }; - private static final float ALPHA_PRESSED=0.55f; - - static { - opacityOut = new AlphaAnimation(1, ALPHA_PRESSED); - opacityOut.setDuration(300); - opacityOut.setInterpolator(CubicBezierInterpolator.DEFAULT); - opacityOut.setFillAfter(true); - opacityIn = new AlphaAnimation(ALPHA_PRESSED, 1); - opacityIn.setDuration(400); - opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT); - Animation spin = new RotateAnimation(0, 360, - Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, - 0.5f); - - animSet = new AnimationSet(true); - animSet.setInterpolator(CubicBezierInterpolator.DEFAULT); - animSet.addAnimation(spin); - animSet.addAnimation(opacityIn); - animSet.setDuration(400); - } - public Holder(Activity activity, ViewGroup parent){ super(activity, R.layout.display_item_footer, parent); @@ -121,6 +100,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ favorite=findViewById(R.id.favorite_btn); share=findViewById(R.id.share_btn); bookmark=findViewById(R.id.bookmark_btn); + favIcon=findViewById(R.id.favorite_icon); reply.setOnTouchListener(this::onButtonTouch); reply.setOnClickListener(this::onReplyClick); @@ -164,6 +144,16 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ boolean condenseBottom = !item.isMainStatus && item.hasDescendantNeighbor && !nextIsWarning; + + AccountSession session=AccountSessionManager.get(item.accountID); + boolean like=session!=null && session.getLocalPreferences().likeIcon; + ColorStateList color=item.parentFragment.getResources().getColorStateList( + like ? R.color.like_icon : R.color.favorite_icon, item.parentFragment.getContext().getTheme() + ); + favIcon.setImageResource(like ? R.drawable.ic_fluent_heart_24_selector : R.drawable.ic_fluent_star_24_selector); + favIcon.setImageTintList(color); + favorites.setTextColor(color); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) itemView.getLayoutParams(); params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, condenseBottom ? V.dp(-5) : 0); @@ -192,7 +182,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ if (!longClickPerformed) v.animate().scaleX(1).scaleY(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start(); if (disabled) return true; if (action == MotionEvent.ACTION_UP && !longClickPerformed) v.performClick(); - else if (!longClickPerformed) v.startAnimation(opacityIn); + else if (!longClickPerformed) UiUtils.opacityIn(v); } else if (action == MotionEvent.ACTION_DOWN) { longClickPerformed = false; touchingView = v; @@ -200,7 +190,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ v.animate().scaleX(0.85f).scaleY(0.85f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(75).start(); if (disabled) return true; v.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout()); - v.startAnimation(opacityOut); + UiUtils.opacityOut(v); } return true; } @@ -219,7 +209,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ ); return; } - v.startAnimation(opacityIn); + UiUtils.opacityIn(v); Bundle args=new Bundle(); args.putString("account", item.accountID); args.putParcelable("replyTo", Parcels.wrap(item.status)); @@ -243,7 +233,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ private void onBoostClick(View v){ if (GlobalUserPreferences.confirmBoost) { - v.startAnimation(opacityIn); + UiUtils.opacityIn(v); onBoostLongClick(v); return; } @@ -266,7 +256,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ } private void boostConsumer(View v, Status r) { - v.startAnimation(opacityIn); + UiUtils.opacityIn(v); bindText(boosts, r.reblogsCount); } @@ -277,7 +267,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ AccountSession session = AccountSessionManager.getInstance().getAccount(item.accountID); Consumer doReblog = (visibility) -> { - v.startAnimation(opacityOut); + UiUtils.opacityOut(v); if(item.status.isRemote){ UiUtils.lookupStatus(v.getContext(), item.status, item.accountID, null, @@ -343,7 +333,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ menu.findViewById(R.id.quote).setOnClickListener(c->{ dialog.dismiss(); - v.startAnimation(opacityIn); + UiUtils.opacityIn(v); Bundle args=new Bundle(); args.putString("account", item.accountID); AccountSession accountSession=AccountSessionManager.getInstance().getAccount(item.accountID); @@ -407,7 +397,8 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ R.string.sk_favorite_as, R.string.sk_favorited_as, R.string.sk_already_favorited, - R.drawable.ic_fluent_star_28_regular + AccountSessionManager.get(item.accountID).getLocalPreferences().likeIcon ? + R.drawable.ic_fluent_heart_28_regular : R.drawable.ic_fluent_star_28_regular ); return true; } @@ -431,7 +422,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ bookmark.setSelected(!item.status.bookmarked); vibrateForAction(bookmark, !item.status.bookmarked); AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(item.status, !item.status.bookmarked, r->{ - v.startAnimation(opacityIn); + UiUtils.opacityIn(v); }); } @@ -439,7 +430,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ if (AccountSessionManager.getInstance().getLoggedInAccounts().size() < 2) return false; UiUtils.pickInteractAs(v.getContext(), item.accountID, item.status, - s -> s.bookmarked, + s -> s.bookmarked,w (ic, status, consumer) -> ic.setBookmarked(status, true, consumer), R.string.sk_bookmark_as, R.string.sk_bookmarked_as, @@ -450,7 +441,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ } private void onShareClick(View v){ - v.startAnimation(opacityIn); + UiUtils.opacityIn(v); Intent intent=new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, item.status.url); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/GapStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/GapStatusDisplayItem.java index 1009bb148..9615b2b33 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/GapStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/GapStatusDisplayItem.java @@ -72,7 +72,7 @@ public class GapStatusDisplayItem extends StatusDisplayItem{ private void onViewClick(View v){ if(item.loading) return; boolean isTop=v==top; - (isTop ? textTop : textBottom).startAnimation(UiUtils.opacityOut); + UiUtils.opacityOut(isTop ? textTop : textBottom); V.setVisibilityAnimated((isTop ? progressTop : progressBottom), View.VISIBLE); item.parentFragment.onGapClick(this, isTop); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java index 582233d0c..50d60bb1a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java @@ -68,6 +68,7 @@ import me.grishka.appkit.api.ErrorResponse; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest; +import me.grishka.appkit.utils.CubicBezierInterpolator; import me.grishka.appkit.utils.V; public class HeaderStatusDisplayItem extends StatusDisplayItem{ @@ -78,7 +79,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{ private CustomEmojiHelper emojiHelper=new CustomEmojiHelper(); private SpannableStringBuilder parsedName; public final Status status; - private boolean hasVisibilityToggle; + public boolean hasVisibilityToggle; boolean needBottomPadding; private CharSequence extraText; private Notification notification; @@ -298,17 +299,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{ UiUtils.enablePopupMenuIcons(activity, optionsMenu); } - private void populateAccountsMenu(Menu menu) { - List sessions=AccountSessionManager.getInstance().getLoggedInAccounts(); - sessions.stream().filter(s -> !s.getID().equals(item.accountID)).forEach(s -> { - String username = "@"+s.self.username+"@"+s.domain; - menu.add(username).setOnMenuItemClickListener(c->{ - UiUtils.openURL(item.parentFragment.getActivity(), s.getID(), item.status.url, false); - return true; - }); - }); - } - @SuppressLint("SetTextI18n") @Override public void onBind(HeaderStatusDisplayItem item){ @@ -335,23 +325,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{ botIcon.setColorFilter(username.getCurrentTextColor()); deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification!=null && !item.inset ? View.VISIBLE : View.GONE); + visibility.setVisibility(item.hasVisibilityToggle ? View.VISIBLE : View.GONE); if (item.hasVisibilityToggle){ - boolean hidden = !item.status.sensitiveRevealed || (item.status.hasSpoiler() && !item.status.spoilerRevealed); - - // doing this because V.setVisibilityAnimated ignores changes between INVISIBLE and GONE - int newVis=hidden ? View.INVISIBLE : View.VISIBLE; - if(newVis==View.INVISIBLE && visibility.getVisibility()==View.GONE) - visibility.setVisibility(newVis); - else - V.setVisibilityAnimated(visibility, newVis); - - visibility.setEnabled(!hidden); - visibility.setContentDescription(item.parentFragment.getString(item.status.sensitiveRevealed ? R.string.spoiler_hide : R.string.spoiler_show)); - if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){ - visibility.setTooltipText(visibility.getContentDescription()); - } - } else { - visibility.setVisibility(View.GONE); + boolean visible = item.status.sensitiveRevealed && (!item.status.hasSpoiler() || item.status.spoilerRevealed); + visibility.setAlpha(visible ? 1 : 0f); + visibility.setScaleY(visible ? 1 : 0.8f); + visibility.setScaleX(visible ? 1 : 0.8f); + visibility.setEnabled(visible); } itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0); if(TextUtils.isEmpty(item.extraText)){ @@ -416,6 +396,16 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{ item.inset ? V.dp(10) : V.dp(4), itemView.getPaddingBottom()); } + public void animateVisibilityToggle(boolean visible){ + visibility.animate() + .alpha(visible ? 1 : 0) + .scaleX(visible ? 1 : 0.8f) + .scaleY(visible ? 1 : 0.8f) + .setInterpolator(CubicBezierInterpolator.DEFAULT) + .start(); + visibility.setEnabled(visible); + } + @Override public void setImage(int index, Drawable drawable){ if(index>0){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/NotificationHeaderStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/NotificationHeaderStatusDisplayItem.java index f85f71007..6586ea103 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/NotificationHeaderStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/NotificationHeaderStatusDisplayItem.java @@ -1,7 +1,6 @@ package org.joinmastodon.android.ui.displayitems; import static org.joinmastodon.android.MastodonApp.context; -import static org.joinmastodon.android.model.Notification.Type.PLEROMA_EMOJI_REACTION; import static org.joinmastodon.android.ui.utils.UiUtils.generateFormattedString; import android.annotation.SuppressLint; @@ -9,7 +8,6 @@ import android.app.Activity; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.text.Html; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.util.TypedValue; @@ -20,9 +18,11 @@ import android.widget.TextView; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.BaseStatusListFragment; +import org.joinmastodon.android.fragments.NotificationsListFragment; import org.joinmastodon.android.fragments.ProfileFragment; import org.joinmastodon.android.model.Emoji; import org.joinmastodon.android.model.Notification; @@ -46,11 +46,15 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{ private final String accountID; private final CustomEmojiHelper emojiHelper=new CustomEmojiHelper(); private final CharSequence text; + private final CharSequence timestamp; + private final AccountLocalPreferences lp; public NotificationHeaderStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Notification notification, String accountID){ super(parentID, parentFragment); this.notification=notification; this.accountID=accountID; + this.timestamp=notification.createdAt==null ? null : UiUtils.formatRelativeTimestamp(context, notification.createdAt); + this.lp=AccountSessionManager.get(accountID).getLocalPreferences(); if(notification.type==Notification.Type.POLL){ text=parentFragment.getString(R.string.poll_ended); @@ -111,17 +115,25 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{ } public static class Holder extends StatusDisplayItem.Holder implements ImageLoaderViewHolder{ - private final ImageView icon, avatar; - private final TextView text; + private final ImageView icon, avatar, deleteNotification; + private final TextView text, timestamp; + private final int selectableItemBackground; public Holder(Activity activity, ViewGroup parent){ super(activity, R.layout.display_item_notification_header, parent); icon=findViewById(R.id.icon); avatar=findViewById(R.id.avatar); text=findViewById(R.id.text); + timestamp=findViewById(R.id.timestamp); + deleteNotification=findViewById(R.id.delete_notification); avatar.setOutlineProvider(OutlineProviders.roundedRect(8)); avatar.setClipToOutline(true); + deleteNotification.setOnClickListener(v->UiUtils.confirmDeleteNotification(activity, item.parentFragment.getAccountID(), item.notification, ()->{ + if (item.parentFragment instanceof NotificationsListFragment fragment) { + fragment.removeNotification(item.notification); + } + })); icon.setOnClickListener(this::onItemClick); avatar.setOnClickListener(this::onItemClick); @@ -149,9 +161,10 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{ @Override public void onBind(NotificationHeaderStatusDisplayItem item){ text.setText(item.text); + timestamp.setText(item.timestamp); avatar.setVisibility(item.notification.type==Notification.Type.POLL ? View.GONE : View.VISIBLE); icon.setImageResource(switch(item.notification.type){ - case FAVORITE -> R.drawable.ic_fluent_star_24_filled; + case FAVORITE -> item.lp.likeIcon ? R.drawable.ic_fluent_heart_24_filled : R.drawable.ic_fluent_star_24_filled; case REBLOG -> R.drawable.ic_fluent_arrow_repeat_all_24_filled; case FOLLOW, FOLLOW_REQUEST -> R.drawable.ic_fluent_person_add_24_filled; case POLL -> R.drawable.ic_fluent_poll_24_filled; @@ -162,11 +175,12 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{ default -> throw new IllegalStateException("Unexpected value: "+item.notification.type); }); icon.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(item.parentFragment.getActivity(), switch(item.notification.type){ - case FAVORITE -> R.attr.colorFavorite; + case FAVORITE -> item.lp.likeIcon ? R.attr.colorLike : R.attr.colorFavorite; case REBLOG -> R.attr.colorBoost; case POLL -> R.attr.colorPoll; default -> android.R.attr.colorAccent; }))); + deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification != null ? View.VISIBLE : View.GONE); itemView.setBackgroundResource(0); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PollOptionStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PollOptionStatusDisplayItem.java index 2a62af3c3..d9ee96a78 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PollOptionStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PollOptionStatusDisplayItem.java @@ -69,7 +69,7 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{ private final TextView text, percent; private final View button; private final ImageView icon; - private final Drawable progressBg, progressBgInset; + private final Drawable progressBg; public Holder(Activity activity, ViewGroup parent){ super(activity, R.layout.display_item_poll_option, parent); @@ -78,7 +78,6 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{ icon=findViewById(R.id.icon); button=findViewById(R.id.button); progressBg=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted, activity.getTheme()).mutate(); - progressBgInset=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted_inset, activity.getTheme()).mutate(); itemView.setOnClickListener(this::onButtonClick); button.setOutlineProvider(OutlineProviders.roundedRect(20)); button.setClipToOutline(true); @@ -94,22 +93,17 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{ item.showResults ? R.drawable.ic_poll_option_button : R.drawable.ic_fluent_radio_button_24_selector )); if(item.showResults){ - Drawable bg=item.inset ? progressBgInset : progressBg; + Drawable bg=progressBg; bg.setLevel(Math.round(10000f*item.votesFraction)); button.setBackground(bg); itemView.setSelected(item.poll.ownVotes!=null && item.poll.ownVotes.contains(item.optionIndex)); percent.setText(String.format(Locale.getDefault(), "%d%%", Math.round(item.votesFraction*100f))); }else{ itemView.setSelected(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option)); - button.setBackgroundResource(item.inset ? R.drawable.bg_poll_option_clickable_inset : R.drawable.bg_poll_option_clickable); - } - if(item.inset){ - text.setTextColor(itemView.getContext().getColorStateList(R.color.poll_option_text_inset)); - percent.setTextColor(itemView.getContext().getColorStateList(R.color.poll_option_text_inset)); - }else{ - text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), android.R.attr.textColorPrimary)); - percent.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSecondaryContainer)); + button.setBackgroundResource(R.drawable.bg_poll_option_clickable); } + text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), android.R.attr.textColorPrimary)); + percent.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSecondaryContainer)); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java index 80baea9aa..9c7188c3e 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java @@ -30,6 +30,7 @@ import org.joinmastodon.android.model.LegacyFilter; import org.joinmastodon.android.model.FilterAction; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.FilterResult; +import org.joinmastodon.android.model.Notification; import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.ScheduledStatus; import org.joinmastodon.android.model.Status; @@ -147,7 +148,7 @@ public abstract class StatusDisplayItem{ Status statusForContent=status.getContentStatus(); Bundle args=new Bundle(); args.putString("account", accountID); - ScheduledStatus scheduledStatus = parentObject instanceof ScheduledStatus ? (ScheduledStatus) parentObject : null; + ScheduledStatus scheduledStatus = parentObject instanceof ScheduledStatus s ? s : null; HeaderStatusDisplayItem header=null; boolean hideCounts=!AccountSessionManager.get(accountID).getLocalPreferences().showInteractionCounts; @@ -206,14 +207,15 @@ public abstract class StatusDisplayItem{ if((flags & FLAG_CHECKABLE)!=0) items.add(header=new CheckableHeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null)); else - items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null, null, scheduledStatus)); + items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null, parentObject instanceof Notification n ? n : null, scheduledStatus)); } - boolean filtered=false; + LegacyFilter applyingFilter=null; if(status.filtered!=null){ for(FilterResult filter:status.filtered){ - if(filter.filter.isActive()){ - filtered=true; + LegacyFilter f=filter.filter; + if(f.isActive() && filterContext != null && f.context.contains(filterContext)){ + applyingFilter=f; break; } } @@ -276,14 +278,14 @@ public abstract class StatusDisplayItem{ contentItems.add(new AudioStatusDisplayItem(parentID, fragment, statusForContent, att)); } if(att.type==Attachment.Type.UNKNOWN){ - contentItems.add(new FileStatusDisplayItem(parentID, fragment, att, statusForContent)); + contentItems.add(new FileStatusDisplayItem(parentID, fragment, att)); } } if(statusForContent.poll!=null){ - buildPollItems(parentID, fragment, statusForContent.poll, contentItems, statusForContent); + buildPollItems(parentID, fragment, statusForContent.poll, contentItems); } if(statusForContent.card!=null && statusForContent.mediaAttachments.isEmpty()){ - contentItems.add(new LinkCardStatusDisplayItem(parentID, fragment, statusForContent, (flags & FLAG_NO_MEDIA_PREVIEW)==0)); + contentItems.add(new LinkCardStatusDisplayItem(parentID, fragment, statusForContent)); } if(contentItems!=items && statusForContent.spoilerRevealed){ items.addAll(contentItems); @@ -324,18 +326,11 @@ public abstract class StatusDisplayItem{ } } - LegacyFilter applyingFilter = null; - if (!statusForContent.filterRevealed) { - StatusFilterPredicate predicate = new StatusFilterPredicate(accountID, filterContext, FilterAction.WARN); - statusForContent.filterRevealed = predicate.test(status); - applyingFilter = predicate.getApplyingFilter(); - } - // Hide statuses that have a filter action of hide if(!new StatusFilterPredicate(accountID, filterContext, FilterAction.HIDE).test(status)) return new ArrayList() ; - return statusForContent.filterRevealed ? items : + return applyingFilter==null ? items : new ArrayList<>(List.of(new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items, applyingFilter))); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/TextStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/TextStatusDisplayItem.java index 22c8497bd..d6f390338 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/TextStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/TextStatusDisplayItem.java @@ -1,7 +1,5 @@ package org.joinmastodon.android.ui.displayitems; -import static org.joinmastodon.android.ui.utils.UiUtils.opacityIn; - import android.app.Activity; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; @@ -33,6 +31,7 @@ import me.grishka.appkit.api.ErrorResponse; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; import me.grishka.appkit.imageloader.MovieDrawable; import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; +import me.grishka.appkit.utils.CubicBezierInterpolator; import me.grishka.appkit.utils.V; public class TextStatusDisplayItem extends StatusDisplayItem{ @@ -116,7 +115,8 @@ public class TextStatusDisplayItem extends StatusDisplayItem{ }else{ text.setText(item.text); } - text.setTextIsSelectable(item.textSelectable); + text.setTextIsSelectable(false); + if(item.textSelectable) itemView.post(() -> text.setTextIsSelectable(true)); text.setInvalidateOnEveryFrame(false); itemView.setClickable(false); itemView.setPadding(itemView.getPaddingLeft(), item.reduceTopPadding ? V.dp(6) : V.dp(12), itemView.getPaddingRight(), itemView.getPaddingBottom()); @@ -204,17 +204,20 @@ public class TextStatusDisplayItem extends StatusDisplayItem{ translationProgress=findViewById(R.id.translation_progress); translationButton.setOnClickListener(v->item.parentFragment.togglePostTranslation(item.status, item.parentID)); } + if(translationButton!=null) translationButton.animate().cancel(); if(item.status.translationState==Status.TranslationState.HIDDEN){ if(updateText) text.setText(item.text); if(translationFooter==null) return; translationFooter.setVisibility(translateEnabled ? View.VISIBLE : View.GONE); translationProgress.setVisibility(View.GONE); Translation existingTrans=item.status.getContentStatus().translation; - String lang=existingTrans!=null ? existingTrans.detectedSourceLanguage : null; - String displayLang=Locale.forLanguageTag(lang!=null ? lang : (item.status.getContentStatus().language != null ? item.status.getContentStatus().language : AccountSessionManager.get(item.parentFragment.getAccountID()).preferences.postingDefaultLanguage)).getDisplayLanguage(); + String existingTransLang=existingTrans!=null ? existingTrans.detectedSourceLanguage : null; + String lang=existingTransLang!=null ? existingTransLang : item.status.getContentStatus().language; + String displayLang=Locale.forLanguageTag(lang != null ? lang + : AccountSessionManager.get(item.parentFragment.getAccountID()).preferences.postingDefaultLanguage).getDisplayLanguage(); translationButton.setText(item.parentFragment.getString(R.string.translate_post, !displayLang.isBlank() ? displayLang : lang)); - translationButton.setEnabled(true); - translationButton.setAlpha(1); + translationButton.setClickable(true); + translationButton.animate().alpha(1).setDuration(100).start(); translationInfo.setVisibility(View.GONE); UiUtils.beginLayoutTransition((ViewGroup) translationButtonWrap); }else{ @@ -222,8 +225,8 @@ public class TextStatusDisplayItem extends StatusDisplayItem{ if(item.status.translationState==Status.TranslationState.SHOWN){ translationProgress.setVisibility(View.GONE); translationButton.setText(R.string.translation_show_original); - translationButton.setEnabled(true); - translationButton.setAlpha(1); + translationButton.setClickable(true); + translationButton.animate().alpha(1).setDuration(200).start(); translationInfo.setVisibility(View.VISIBLE); translationButton.setVisibility(View.VISIBLE); String displayLang=Locale.forLanguageTag(item.status.translation.detectedSourceLanguage).getDisplayLanguage(); @@ -237,8 +240,8 @@ public class TextStatusDisplayItem extends StatusDisplayItem{ } }else{ // LOADING translationProgress.setVisibility(View.VISIBLE); - translationButton.setEnabled(false); - translationButton.setAlpha(0.5f); + translationButton.setClickable(false); + translationButton.animate().alpha(UiUtils.ALPHA_PRESSED).setStartDelay(50).setDuration(300).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); translationInfo.setVisibility(View.INVISIBLE); UiUtils.beginLayoutTransition((ViewGroup) translationButton.getParent()); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/drawables/BlurhashCrossfadeDrawable.java b/mastodon/src/main/java/org/joinmastodon/android/ui/drawables/BlurhashCrossfadeDrawable.java index c909fcb8d..e33c612ab 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/drawables/BlurhashCrossfadeDrawable.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/drawables/BlurhashCrossfadeDrawable.java @@ -66,6 +66,10 @@ public class BlurhashCrossfadeDrawable extends Drawable{ public void setImageDrawable(Drawable imageDrawable){ this.imageDrawable=imageDrawable; + if(imageDrawable!=null){ + width=imageDrawable.getIntrinsicWidth(); + height=imageDrawable.getIntrinsicHeight(); + } invalidateSelf(); } @@ -99,11 +103,15 @@ public class BlurhashCrossfadeDrawable extends Drawable{ @Override public int getIntrinsicWidth(){ + if(width==0) + return imageDrawable==null ? 1920 : imageDrawable.getIntrinsicWidth(); return width; } @Override public int getIntrinsicHeight(){ + if(height==0) + return imageDrawable==null ? 1080 : imageDrawable.getIntrinsicHeight(); return height; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/PhotoViewer.java b/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/PhotoViewer.java index 721ee3dc9..d4fe07cc2 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/PhotoViewer.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/PhotoViewer.java @@ -564,7 +564,7 @@ public class PhotoViewer implements ZoomPanView.Listener{ if(player==null || !player.isPlaying()) return; player.pause(); - videoPlayPauseButton.setImageResource(R.drawable.ic_play_24); + videoPlayPauseButton.setImageResource(R.drawable.ic_fluent_play_24_filled); videoPlayPauseButton.setContentDescription(activity.getString(R.string.play)); stopUpdatingVideoPosition(); windowView.removeCallbacks(uiAutoHider); @@ -575,7 +575,7 @@ public class PhotoViewer implements ZoomPanView.Listener{ if(player==null || player.isPlaying()) return; player.start(); - videoPlayPauseButton.setImageResource(R.drawable.ic_pause_24); + videoPlayPauseButton.setImageResource(R.drawable.ic_fluent_pause_24_filled); videoPlayPauseButton.setContentDescription(activity.getString(R.string.pause)); startUpdatingVideoPosition(player); } @@ -734,9 +734,18 @@ public class PhotoViewer implements ZoomPanView.Listener{ public void onBind(Attachment item){ super.onBind(item); FrameLayout.LayoutParams params=(FrameLayout.LayoutParams) imageView.getLayoutParams(); - params.width=item.getWidth(); - params.height=item.getHeight(); - ViewImageLoader.load(this, listener.getPhotoViewCurrentDrawable(getAbsoluteAdapterPosition()), new UrlImageLoaderRequest(item.url), false); + Drawable currentDrawable=listener.getPhotoViewCurrentDrawable(getAbsoluteAdapterPosition()); + if(item.hasKnownDimensions()){ + params.width=item.getWidth(); + params.height=item.getHeight(); + }else if(currentDrawable!=null){ + params.width=currentDrawable.getIntrinsicWidth(); + params.height=currentDrawable.getIntrinsicHeight(); + }else{ + params.width=1920; + params.height=1080; + } + ViewImageLoader.load(this, currentDrawable, new UrlImageLoaderRequest(item.url), false); } @Override @@ -778,9 +787,18 @@ public class PhotoViewer implements ZoomPanView.Listener{ super.onBind(item); playerReady=false; FrameLayout.LayoutParams params=(FrameLayout.LayoutParams) wrap.getLayoutParams(); - params.width=item.getWidth(); - params.height=item.getHeight(); - wrap.setBackground(listener.getPhotoViewCurrentDrawable(getAbsoluteAdapterPosition())); + Drawable currentDrawable=listener.getPhotoViewCurrentDrawable(getAbsoluteAdapterPosition()); + if(item.hasKnownDimensions()){ + params.width=item.getWidth(); + params.height=item.getHeight(); + }else if(currentDrawable!=null){ + params.width=currentDrawable.getIntrinsicWidth(); + params.height=currentDrawable.getIntrinsicHeight(); + }else{ + params.width=1920; + params.height=1080; + } + wrap.setBackground(currentDrawable); progressBar.setVisibility(item.type==Attachment.Type.VIDEO ? View.VISIBLE : View.GONE); if(itemView.isAttachedToWindow()){ reset(); @@ -841,7 +859,9 @@ public class PhotoViewer implements ZoomPanView.Listener{ @Override public boolean onError(MediaPlayer mp, int what, int extra){ Log.e(TAG, "video player onError() called with: mp = ["+mp+"], what = ["+what+"], extra = ["+extra+"]"); - return false; + Toast.makeText(activity, R.string.error_playing_video, Toast.LENGTH_SHORT).show(); + onStartSwipeToDismissTransition(0f); + return true; } public void prepareAndStartPlayer(){ @@ -862,6 +882,8 @@ public class PhotoViewer implements ZoomPanView.Listener{ player.prepareAsync(); }catch(IOException x){ Log.w(TAG, "Error initializing gif player", x); + Toast.makeText(activity, R.string.error_playing_video, Toast.LENGTH_SHORT).show(); + onStartSwipeToDismissTransition(0f); } } @@ -918,7 +940,7 @@ public class PhotoViewer implements ZoomPanView.Listener{ @Override public void onCompletion(MediaPlayer mp){ - videoPlayPauseButton.setImageResource(R.drawable.ic_play_24); + videoPlayPauseButton.setImageResource(R.drawable.ic_fluent_play_24_filled); videoPlayPauseButton.setContentDescription(activity.getString(R.string.play)); stopUpdatingVideoPosition(); if(!uiVisible) diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/ZoomPanView.java b/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/ZoomPanView.java index ac9f5fbaa..5425c095a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/ZoomPanView.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/photoviewer/ZoomPanView.java @@ -119,8 +119,10 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS int width=right-left; int height=bottom-top; - if(width==0 || height==0) + if(width==0 || height==0 || child.getWidth()==0 || child.getWidth()==0){ + matrix.reset(); return; + } float scale=Math.min(width/(float)child.getWidth(), height/(float)child.getHeight()); minScale=scale; diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java b/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java index 4689a8fdd..f654f6b34 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java @@ -5,6 +5,7 @@ import android.text.TextPaint; import android.text.style.CharacterStyle; import android.view.View; +import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.model.Hashtag; import org.joinmastodon.android.ui.utils.UiUtils; @@ -34,7 +35,7 @@ public class LinkSpan extends CharacterStyle { @Override public void updateDrawState(TextPaint tp) { tp.setColor(color=tp.linkColor); - tp.setUnderlineText(true); + tp.setUnderlineText(GlobalUserPreferences.underlinedLinks); } public void onClick(Context context){ @@ -45,7 +46,7 @@ public class LinkSpan extends CharacterStyle { if(linkObject instanceof Hashtag ht) UiUtils.openHashtagTimeline(context, accountID, ht); else - UiUtils.openHashtagTimeline(context, accountID, text); + UiUtils.openHashtagTimeline(context, accountID, link); } case CUSTOM -> listener.onLinkClick(this); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/ColorPalette.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/ColorPalette.java index 02e637582..3b5562f01 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/ColorPalette.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/ColorPalette.java @@ -1,8 +1,8 @@ package org.joinmastodon.android.ui.utils; -import static org.joinmastodon.android.GlobalUserPreferences.ColorPreference; import static org.joinmastodon.android.GlobalUserPreferences.ThemePreference; import static org.joinmastodon.android.GlobalUserPreferences.trueBlackTheme; +import static org.joinmastodon.android.api.session.AccountLocalPreferences.ColorPreference.*; import android.content.Context; import android.content.res.Resources; @@ -11,23 +11,25 @@ import androidx.annotation.StyleRes; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import java.util.Map; public class ColorPalette { - public static final Map palettes = Map.of( - ColorPreference.MATERIAL3, new ColorPalette(R.style.ColorPalette_Material3) + public static final Map palettes = Map.of( + MATERIAL3, new ColorPalette(R.style.ColorPalette_Material3) .dark(R.style.ColorPalette_Material3_Dark, R.style.ColorPalette_Material3_AutoLightDark), - ColorPreference.PINK, new ColorPalette(R.style.ColorPalette_Pink), - ColorPreference.PURPLE, new ColorPalette(R.style.ColorPalette_Purple), - ColorPreference.GREEN, new ColorPalette(R.style.ColorPalette_Green), - ColorPreference.BLUE, new ColorPalette(R.style.ColorPalette_Blue), - ColorPreference.BROWN, new ColorPalette(R.style.ColorPalette_Brown), - ColorPreference.RED, new ColorPalette(R.style.ColorPalette_Red), - ColorPreference.YELLOW, new ColorPalette(R.style.ColorPalette_Yellow), - ColorPreference.NORD, new ColorPalette(R.style.ColorPalette_Nord), - ColorPreference.WHITE, new ColorPalette(R.style.ColorPalette_White) - ); + PINK, new ColorPalette(R.style.ColorPalette_Pink), + PURPLE, new ColorPalette(R.style.ColorPalette_Purple), + GREEN, new ColorPalette(R.style.ColorPalette_Green), + BLUE, new ColorPalette(R.style.ColorPalette_Blue), + BROWN, new ColorPalette(R.style.ColorPalette_Brown), + RED, new ColorPalette(R.style.ColorPalette_Red), + YELLOW, new ColorPalette(R.style.ColorPalette_Yellow) + NORD, new ColorPalette(R.style.ColorPalette_Nord), + WHITE, new ColorPalette(R.style.ColorPalette_White) + + ); private @StyleRes int base; private @StyleRes int autoDark; diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/MediaAttachmentViewController.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/MediaAttachmentViewController.java index 2c073a591..b652bdfd0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/MediaAttachmentViewController.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/MediaAttachmentViewController.java @@ -28,6 +28,7 @@ public class MediaAttachmentViewController{ private final Context context; private boolean didClear; private Status status; + private Attachment attachment; public MediaAttachmentViewController(Context context, MediaGridStatusDisplayItem.GridItemType type){ view=context.getSystemService(LayoutInflater.class).inflate(switch(type){ @@ -54,6 +55,7 @@ public class MediaAttachmentViewController{ public void bind(Attachment attachment, Status status){ this.status=status; + this.attachment=attachment; crossfadeDrawable.setSize(attachment.getWidth(), attachment.getHeight()); crossfadeDrawable.setBlurhashDrawable(attachment.blurhashPlaceholder); crossfadeDrawable.setCrossfadeAlpha(0f); @@ -76,6 +78,11 @@ public class MediaAttachmentViewController{ crossfadeDrawable.setImageDrawable(drawable); if(didClear) crossfadeDrawable.animateAlpha(0f); + // Make sure the image is not stretched if the server returned wrong dimensions + if(drawable!=null && (drawable.getIntrinsicWidth()!=attachment.getWidth() || drawable.getIntrinsicHeight()!=attachment.getHeight())){ + photo.setImageDrawable(null); + photo.setImageDrawable(crossfadeDrawable); + } } public void clearImage(){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java index 8cab117d7..41739c791 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java @@ -1,6 +1,7 @@ package org.joinmastodon.android.ui.utils; import static android.view.Menu.NONE; +import static org.joinmastodon.android.GlobalUserPreferences.ThemePreference.*; import static org.joinmastodon.android.GlobalUserPreferences.theme; import static org.joinmastodon.android.GlobalUserPreferences.trueBlackTheme; @@ -53,9 +54,8 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.view.WindowInsets; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; import android.webkit.MimeTypeMap; import android.widget.Button; import android.widget.ImageView; @@ -86,6 +86,7 @@ import org.joinmastodon.android.api.requests.statuses.DeleteStatus; import org.joinmastodon.android.api.requests.statuses.GetStatusByID; import org.joinmastodon.android.api.requests.statuses.SetStatusMuted; import org.joinmastodon.android.api.requests.statuses.SetStatusPinned; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.StatusMuteChangedEvent; @@ -178,17 +179,6 @@ public class UiUtils { public static int MAX_WIDTH, SCROLL_TO_TOP_DELTA; public static final float ALPHA_PRESSED=0.55f; - public static final Animation opacityOut, opacityIn; - - static { - opacityOut = new AlphaAnimation(1, ALPHA_PRESSED); - opacityOut.setDuration(300); - opacityOut.setInterpolator(CubicBezierInterpolator.DEFAULT); - opacityOut.setFillAfter(true); - opacityIn = new AlphaAnimation(ALPHA_PRESSED, 1); - opacityIn.setDuration(400); - opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT); - } private UiUtils() { } @@ -1032,14 +1022,20 @@ public class UiUtils { } public static void setUserPreferredTheme(Context context) { - context.setTheme(switch (theme) { + setUserPreferredTheme(context, null); + } + + public static void setUserPreferredTheme(Context context, @Nullable AccountSession session) { + context.setTheme(switch(theme) { case LIGHT -> R.style.Theme_Mastodon_Light; case DARK -> R.style.Theme_Mastodon_Dark; default -> R.style.Theme_Mastodon_AutoLightDark; }); - ColorPalette palette = ColorPalette.palettes.get(GlobalUserPreferences.color); - if (palette != null) palette.apply(context); + AccountLocalPreferences prefs=session != null ? session.getLocalPreferences() : null; + AccountLocalPreferences.ColorPreference color=prefs != null ? prefs.color : AccountLocalPreferences.ColorPreference.MATERIAL3; + ColorPalette palette = ColorPalette.palettes.get(color); + if (palette != null) palette.apply(context, theme); Resources res = context.getResources(); MAX_WIDTH = (int) res.getDimension(R.dimen.layout_max_width); @@ -1056,9 +1052,9 @@ public class UiUtils { } public static boolean isDarkTheme() { - if (theme == GlobalUserPreferences.ThemePreference.AUTO) + if (theme == AUTO) return (MastodonApp.context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; - return theme == GlobalUserPreferences.ThemePreference.DARK; + return theme == DARK; } public static Optional>> parseFediverseHandle(String maybeFediHandle) { @@ -1801,4 +1797,16 @@ public class UiUtils { .filter(Objects::nonNull) .findFirst(); } + + public static void opacityIn(View v){ + v.animate().alpha(1).setDuration(400).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); + } + + public static void opacityOut(View v){ + opacityOut(v, ALPHA_PRESSED).start(); + } + + public static ViewPropertyAnimator opacityOut(View v, float alpha){ + return v.animate().alpha(alpha).setDuration(300).setInterpolator(CubicBezierInterpolator.DEFAULT); + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposeLanguageAlertViewController.java b/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposeLanguageAlertViewController.java index e2821cb0d..53016ffa1 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposeLanguageAlertViewController.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposeLanguageAlertViewController.java @@ -18,6 +18,7 @@ import android.widget.TextView; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.api.MastodonAPIController; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.ui.DividerItemDecoration; @@ -66,7 +67,7 @@ public class ComposeLanguageAlertViewController{ .collect(Collectors.toList()); if(!TextUtils.isEmpty(preferred)){ - MastodonLanguage lang = resolver.fromOrFallback(preferred); + MastodonLanguage lang=resolver.fromOrFallback(preferred); specialLocales.add(new SpecialLocaleInfo( lang, lang.getDisplayName(context), @@ -75,7 +76,7 @@ public class ComposeLanguageAlertViewController{ } if(!Locale.getDefault().getLanguage().equals(preferred)){ - MastodonLanguage lang = resolver.getDefault(); + MastodonLanguage lang=resolver.getDefault(); specialLocales.add(new SpecialLocaleInfo( lang, lang.getDisplayName(context), @@ -91,8 +92,18 @@ public class ComposeLanguageAlertViewController{ detectLanguage(detected, postText); } - if (session!=null && session.getLocalPreferences().bottomEncoding) { - specialLocales.add(new SpecialLocaleInfo(null, "\uD83E\uDD7A\uD83D\uDC49\uD83D\uDC48", "bottom")); + AccountLocalPreferences lp=session==null ? null : session.getLocalPreferences(); + if(lp!=null){ + for(String tag : lp.recentLanguages){ + if(specialLocales.stream().anyMatch(l->l.language!=null && l.language.languageTag!=null + && l.language.languageTag.equals(tag))) continue; + resolver.from(tag).ifPresent(lang->specialLocales.add(new SpecialLocaleInfo( + lang, lang.getDisplayName(context), null + ))); + } + if(lp.bottomEncoding) { + specialLocales.add(new SpecialLocaleInfo(null, "\uD83E\uDD7A\uD83D\uDC49\uD83D\uDC48", "bottom")); + } } if(previouslySelected!=null){ @@ -323,7 +334,7 @@ public class ComposeLanguageAlertViewController{ public void onClick(){ selectItem(getAbsoluteAdapterPosition()); selectedLocale=item.language; - selectedEncoding = item.title.equals("bottom") ? "bottom" : null; + selectedEncoding=item.title != null && item.title.equals("bottom") ? "bottom" : null; } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java b/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java index 53fce5007..1e2fedcab 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java @@ -1,9 +1,11 @@ package org.joinmastodon.android.ui.views; import android.content.Context; +import android.graphics.Typeface; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; +import android.widget.TextView; import java.util.function.IntConsumer; import java.util.function.IntPredicate; @@ -45,9 +47,7 @@ public class TabBar extends LinearLayout{ listener.accept(v.getId()); if(v.getId()==selectedTabID) return; - findViewById(selectedTabID).setSelected(false); - v.setSelected(true); - selectedTabID=v.getId(); + selectTab(v.getId()); } private boolean onChildLongClick(View v){ @@ -60,8 +60,17 @@ public class TabBar extends LinearLayout{ } public void selectTab(int id){ - findViewById(selectedTabID).setSelected(false); + toggleSelected(selectedTabID, false); selectedTabID=id; - findViewById(selectedTabID).setSelected(true); + toggleSelected(id, true); + } + + private void toggleSelected(int selectedTabID, boolean selected){ + LinearLayout tab=findViewById(selectedTabID); + tab.setSelected(selected); + View v=tab.findViewWithTag("label"); + if(v instanceof TextView text){ + text.setTypeface(Typeface.create(text.getTypeface(), selected ? Typeface.BOLD : Typeface.NORMAL)); + } } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/utils/MastodonLanguage.java b/mastodon/src/main/java/org/joinmastodon/android/utils/MastodonLanguage.java index 06ad03956..bcf588ec8 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/utils/MastodonLanguage.java +++ b/mastodon/src/main/java/org/joinmastodon/android/utils/MastodonLanguage.java @@ -26,7 +26,7 @@ public class MastodonLanguage { // On an up-to-date Mastodon instance: // copy(JSON.stringify(JSON.stringify(JSON.parse(document.getElementById('initial-state').textContent).languages))) public static String languagesJson = - "[[\"aa\",\"Afar\",\"Afaraf\"],[\"ab\",\"Abkhaz\",\"аҧсуа бызшәа\"],[\"ae\",\"Avestan\",\"avesta\"],[\"af\",\"Afrikaans\",\"Afrikaans\"],[\"ak\",\"Akan\",\"Akan\"],[\"am\",\"Amharic\",\"አማርኛ\"],[\"an\",\"Aragonese\",\"aragonés\"],[\"ar\",\"Arabic\",\"اللغة العربية\"],[\"as\",\"Assamese\",\"অসমীয়া\"],[\"av\",\"Avaric\",\"авар мацӀ\"],[\"ay\",\"Aymara\",\"aymar aru\"],[\"az\",\"Azerbaijani\",\"azərbaycan dili\"],[\"ba\",\"Bashkir\",\"башҡорт теле\"],[\"be\",\"Belarusian\",\"беларуская мова\"],[\"bg\",\"Bulgarian\",\"български език\"],[\"bh\",\"Bihari\",\"भोजपुरी\"],[\"bi\",\"Bislama\",\"Bislama\"],[\"bm\",\"Bambara\",\"bamanankan\"],[\"bn\",\"Bengali\",\"বাংলা\"],[\"bo\",\"Tibetan\",\"བོད་ཡིག\"],[\"br\",\"Breton\",\"brezhoneg\"],[\"bs\",\"Bosnian\",\"bosanski jezik\"],[\"ca\",\"Catalan\",\"Català\"],[\"ce\",\"Chechen\",\"нохчийн мотт\"],[\"ch\",\"Chamorro\",\"Chamoru\"],[\"co\",\"Corsican\",\"corsu\"],[\"cr\",\"Cree\",\"ᓀᐦᐃᔭᐍᐏᐣ\"],[\"cs\",\"Czech\",\"čeština\"],[\"cu\",\"Old Church Slavonic\",\"ѩзыкъ словѣньскъ\"],[\"cv\",\"Chuvash\",\"чӑваш чӗлхи\"],[\"cy\",\"Welsh\",\"Cymraeg\"],[\"da\",\"Danish\",\"dansk\"],[\"de\",\"German\",\"Deutsch\"],[\"dv\",\"Divehi\",\"Dhivehi\"],[\"dz\",\"Dzongkha\",\"རྫོང་ཁ\"],[\"ee\",\"Ewe\",\"Eʋegbe\"],[\"el\",\"Greek\",\"Ελληνικά\"],[\"en\",\"English\",\"English\"],[\"eo\",\"Esperanto\",\"Esperanto\"],[\"es\",\"Spanish\",\"Español\"],[\"et\",\"Estonian\",\"eesti\"],[\"eu\",\"Basque\",\"euskara\"],[\"fa\",\"Persian\",\"فارسی\"],[\"ff\",\"Fula\",\"Fulfulde\"],[\"fi\",\"Finnish\",\"suomi\"],[\"fj\",\"Fijian\",\"Vakaviti\"],[\"fo\",\"Faroese\",\"føroyskt\"],[\"fr\",\"French\",\"Français\"],[\"fy\",\"Western Frisian\",\"Frysk\"],[\"ga\",\"Irish\",\"Gaeilge\"],[\"gd\",\"Scottish Gaelic\",\"Gàidhlig\"],[\"gl\",\"Galician\",\"galego\"],[\"gu\",\"Gujarati\",\"ગુજરાતી\"],[\"gv\",\"Manx\",\"Gaelg\"],[\"ha\",\"Hausa\",\"هَوُسَ\"],[\"he\",\"Hebrew\",\"עברית\"],[\"hi\",\"Hindi\",\"हिन्दी\"],[\"ho\",\"Hiri Motu\",\"Hiri Motu\"],[\"hr\",\"Croatian\",\"Hrvatski\"],[\"ht\",\"Haitian\",\"Kreyòl ayisyen\"],[\"hu\",\"Hungarian\",\"magyar\"],[\"hy\",\"Armenian\",\"Հայերեն\"],[\"hz\",\"Herero\",\"Otjiherero\"],[\"ia\",\"Interlingua\",\"Interlingua\"],[\"id\",\"Indonesian\",\"Bahasa Indonesia\"],[\"ie\",\"Interlingue\",\"Interlingue\"],[\"ig\",\"Igbo\",\"Asụsụ Igbo\"],[\"ii\",\"Nuosu\",\"ꆈꌠ꒿ Nuosuhxop\"],[\"ik\",\"Inupiaq\",\"Iñupiaq\"],[\"io\",\"Ido\",\"Ido\"],[\"is\",\"Icelandic\",\"Íslenska\"],[\"it\",\"Italian\",\"Italiano\"],[\"iu\",\"Inuktitut\",\"ᐃᓄᒃᑎᑐᑦ\"],[\"ja\",\"Japanese\",\"日本語\"],[\"jv\",\"Javanese\",\"basa Jawa\"],[\"ka\",\"Georgian\",\"ქართული\"],[\"kg\",\"Kongo\",\"Kikongo\"],[\"ki\",\"Kikuyu\",\"Gĩkũyũ\"],[\"kj\",\"Kwanyama\",\"Kuanyama\"],[\"kk\",\"Kazakh\",\"қазақ тілі\"],[\"kl\",\"Kalaallisut\",\"kalaallisut\"],[\"km\",\"Khmer\",\"ខេមរភាសា\"],[\"kn\",\"Kannada\",\"ಕನ್ನಡ\"],[\"ko\",\"Korean\",\"한국어\"],[\"kr\",\"Kanuri\",\"Kanuri\"],[\"ks\",\"Kashmiri\",\"कश्मीरी\"],[\"ku\",\"Kurmanji (Kurdish)\",\"Kurmancî\"],[\"kv\",\"Komi\",\"коми кыв\"],[\"kw\",\"Cornish\",\"Kernewek\"],[\"ky\",\"Kyrgyz\",\"Кыргызча\"],[\"la\",\"Latin\",\"latine\"],[\"lb\",\"Luxembourgish\",\"Lëtzebuergesch\"],[\"lg\",\"Ganda\",\"Luganda\"],[\"li\",\"Limburgish\",\"Limburgs\"],[\"ln\",\"Lingala\",\"Lingála\"],[\"lo\",\"Lao\",\"ລາວ\"],[\"lt\",\"Lithuanian\",\"lietuvių kalba\"],[\"lu\",\"Luba-Katanga\",\"Tshiluba\"],[\"lv\",\"Latvian\",\"latviešu valoda\"],[\"mg\",\"Malagasy\",\"fiteny malagasy\"],[\"mh\",\"Marshallese\",\"Kajin M̧ajeļ\"],[\"mi\",\"Māori\",\"te reo Māori\"],[\"mk\",\"Macedonian\",\"македонски јазик\"],[\"ml\",\"Malayalam\",\"മലയാളം\"],[\"mn\",\"Mongolian\",\"Монгол хэл\"],[\"mr\",\"Marathi\",\"मराठी\"],[\"ms\",\"Malay\",\"Bahasa Melayu\"],[\"mt\",\"Maltese\",\"Malti\"],[\"my\",\"Burmese\",\"ဗမာစာ\"],[\"na\",\"Nauru\",\"Ekakairũ Naoero\"],[\"nb\",\"Norwegian Bokmål\",\"Norsk bokmål\"],[\"nd\",\"Northern Ndebele\",\"isiNdebele\"],[\"ne\",\"Nepali\",\"नेपाली\"],[\"ng\",\"Ndonga\",\"Owambo\"],[\"nl\",\"Dutch\",\"Nederlands\"],[\"nn\",\"Norwegian Nynorsk\",\"Norsk Nynorsk\"],[\"no\",\"Norwegian\",\"Norsk\"],[\"nr\",\"Southern Ndebele\",\"isiNdebele\"],[\"nv\",\"Navajo\",\"Diné bizaad\"],[\"ny\",\"Chichewa\",\"chiCheŵa\"],[\"oc\",\"Occitan\",\"occitan\"],[\"oj\",\"Ojibwe\",\"ᐊᓂᔑᓈᐯᒧᐎᓐ\"],[\"om\",\"Oromo\",\"Afaan Oromoo\"],[\"or\",\"Oriya\",\"ଓଡ଼ିଆ\"],[\"os\",\"Ossetian\",\"ирон æвзаг\"],[\"pa\",\"Panjabi\",\"ਪੰਜਾਬੀ\"],[\"pi\",\"Pāli\",\"पाऴि\"],[\"pl\",\"Polish\",\"Polski\"],[\"ps\",\"Pashto\",\"پښتو\"],[\"pt\",\"Portuguese\",\"Português\"],[\"qu\",\"Quechua\",\"Runa Simi\"],[\"rm\",\"Romansh\",\"rumantsch grischun\"],[\"rn\",\"Kirundi\",\"Ikirundi\"],[\"ro\",\"Romanian\",\"Română\"],[\"ru\",\"Russian\",\"Русский\"],[\"rw\",\"Kinyarwanda\",\"Ikinyarwanda\"],[\"sa\",\"Sanskrit\",\"संस्कृतम्\"],[\"sc\",\"Sardinian\",\"sardu\"],[\"sd\",\"Sindhi\",\"सिन्धी\"],[\"se\",\"Northern Sami\",\"Davvisámegiella\"],[\"sg\",\"Sango\",\"yângâ tî sängö\"],[\"si\",\"Sinhala\",\"සිංහල\"],[\"sk\",\"Slovak\",\"slovenčina\"],[\"sl\",\"Slovenian\",\"slovenščina\"],[\"sn\",\"Shona\",\"chiShona\"],[\"so\",\"Somali\",\"Soomaaliga\"],[\"sq\",\"Albanian\",\"Shqip\"],[\"sr\",\"Serbian\",\"српски језик\"],[\"ss\",\"Swati\",\"SiSwati\"],[\"st\",\"Southern Sotho\",\"Sesotho\"],[\"su\",\"Sundanese\",\"Basa Sunda\"],[\"sv\",\"Swedish\",\"Svenska\"],[\"sw\",\"Swahili\",\"Kiswahili\"],[\"ta\",\"Tamil\",\"தமிழ்\"],[\"te\",\"Telugu\",\"తెలుగు\"],[\"tg\",\"Tajik\",\"тоҷикӣ\"],[\"th\",\"Thai\",\"ไทย\"],[\"ti\",\"Tigrinya\",\"ትግርኛ\"],[\"tk\",\"Turkmen\",\"Türkmen\"],[\"tl\",\"Tagalog\",\"Wikang Tagalog\"],[\"tn\",\"Tswana\",\"Setswana\"],[\"to\",\"Tonga\",\"faka Tonga\"],[\"tr\",\"Turkish\",\"Türkçe\"],[\"ts\",\"Tsonga\",\"Xitsonga\"],[\"tt\",\"Tatar\",\"татар теле\"],[\"tw\",\"Twi\",\"Twi\"],[\"ty\",\"Tahitian\",\"Reo Tahiti\"],[\"ug\",\"Uyghur\",\"ئۇيغۇرچە‎\"],[\"uk\",\"Ukrainian\",\"Українська\"],[\"ur\",\"Urdu\",\"اردو\"],[\"uz\",\"Uzbek\",\"Ўзбек\"],[\"ve\",\"Venda\",\"Tshivenḓa\"],[\"vi\",\"Vietnamese\",\"Tiếng Việt\"],[\"vo\",\"Volapük\",\"Volapük\"],[\"wa\",\"Walloon\",\"walon\"],[\"wo\",\"Wolof\",\"Wollof\"],[\"xh\",\"Xhosa\",\"isiXhosa\"],[\"yi\",\"Yiddish\",\"ייִדיש\"],[\"yo\",\"Yoruba\",\"Yorùbá\"],[\"za\",\"Zhuang\",\"Saɯ cueŋƅ\"],[\"zh\",\"Chinese\",\"中文\"],[\"zu\",\"Zulu\",\"isiZulu\"],[\"ast\",\"Asturian\",\"Asturianu\"],[\"ckb\",\"Sorani (Kurdish)\",\"سۆرانی\"],[\"cnr\",\"Montenegrin\",\"crnogorski\"],[\"jbo\",\"Lojban\",\"la .lojban.\"],[\"kab\",\"Kabyle\",\"Taqbaylit\"],[\"kmr\",\"Kurmanji (Kurdish)\",\"Kurmancî\"],[\"ldn\",\"Láadan\",\"Láadan\"],[\"lfn\",\"Lingua Franca Nova\",\"lingua franca nova\"],[\"sco\",\"Scots\",\"Scots\"],[\"sma\",\"Southern Sami\",\"Åarjelsaemien Gïele\"],[\"smj\",\"Lule Sami\",\"Julevsámegiella\"],[\"szl\",\"Silesian\",\"ślůnsko godka\"],[\"tok\",\"Toki Pona\",\"toki pona\"],[\"zba\",\"Balaibalan\",\"باليبلن\"],[\"zgh\",\"Standard Moroccan Tamazight\",\"ⵜⴰⵎⴰⵣⵉⵖⵜ\"]]"; + "[[\"aa\",\"Afar\",\"Afaraf\"],[\"ab\",\"Abkhaz\",\"аҧсуа бызшәа\"],[\"ae\",\"Avestan\",\"avesta\"],[\"af\",\"Afrikaans\",\"Afrikaans\"],[\"ak\",\"Akan\",\"Akan\"],[\"am\",\"Amharic\",\"አማርኛ\"],[\"an\",\"Aragonese\",\"aragonés\"],[\"ar\",\"Arabic\",\"اللغة العربية\"],[\"as\",\"Assamese\",\"অসমীয়া\"],[\"av\",\"Avaric\",\"авар мацӀ\"],[\"ay\",\"Aymara\",\"aymar aru\"],[\"az\",\"Azerbaijani\",\"azərbaycan dili\"],[\"ba\",\"Bashkir\",\"башҡорт теле\"],[\"be\",\"Belarusian\",\"беларуская мова\"],[\"bg\",\"Bulgarian\",\"български език\"],[\"bh\",\"Bihari\",\"भोजपुरी\"],[\"bi\",\"Bislama\",\"Bislama\"],[\"bm\",\"Bambara\",\"bamanankan\"],[\"bn\",\"Bengali\",\"বাংলা\"],[\"bo\",\"Tibetan\",\"བོད་ཡིག\"],[\"br\",\"Breton\",\"brezhoneg\"],[\"bs\",\"Bosnian\",\"bosanski jezik\"],[\"ca\",\"Catalan\",\"Català\"],[\"ce\",\"Chechen\",\"нохчийн мотт\"],[\"ch\",\"Chamorro\",\"Chamoru\"],[\"co\",\"Corsican\",\"corsu\"],[\"cr\",\"Cree\",\"ᓀᐦᐃᔭᐍᐏᐣ\"],[\"cs\",\"Czech\",\"čeština\"],[\"cu\",\"Old Church Slavonic\",\"ѩзыкъ словѣньскъ\"],[\"cv\",\"Chuvash\",\"чӑваш чӗлхи\"],[\"cy\",\"Welsh\",\"Cymraeg\"],[\"da\",\"Danish\",\"dansk\"],[\"de\",\"German\",\"Deutsch\"],[\"dv\",\"Divehi\",\"Dhivehi\"],[\"dz\",\"Dzongkha\",\"རྫོང་ཁ\"],[\"ee\",\"Ewe\",\"Eʋegbe\"],[\"el\",\"Greek\",\"Ελληνικά\"],[\"en\",\"English\",\"English\"],[\"eo\",\"Esperanto\",\"Esperanto\"],[\"es\",\"Spanish\",\"Español\"],[\"et\",\"Estonian\",\"eesti\"],[\"eu\",\"Basque\",\"euskara\"],[\"fa\",\"Persian\",\"فارسی\"],[\"ff\",\"Fula\",\"Fulfulde\"],[\"fi\",\"Finnish\",\"suomi\"],[\"fj\",\"Fijian\",\"Vakaviti\"],[\"fo\",\"Faroese\",\"føroyskt\"],[\"fr\",\"French\",\"Français\"],[\"fy\",\"Western Frisian\",\"Frysk\"],[\"ga\",\"Irish\",\"Gaeilge\"],[\"gd\",\"Scottish Gaelic\",\"Gàidhlig\"],[\"gl\",\"Galician\",\"galego\"],[\"gu\",\"Gujarati\",\"ગુજરાતી\"],[\"gv\",\"Manx\",\"Gaelg\"],[\"ha\",\"Hausa\",\"هَوُسَ\"],[\"he\",\"Hebrew\",\"עברית\"],[\"hi\",\"Hindi\",\"हिन्दी\"],[\"ho\",\"Hiri Motu\",\"Hiri Motu\"],[\"hr\",\"Croatian\",\"Hrvatski\"],[\"ht\",\"Haitian\",\"Kreyòl ayisyen\"],[\"hu\",\"Hungarian\",\"magyar\"],[\"hy\",\"Armenian\",\"Հայերեն\"],[\"hz\",\"Herero\",\"Otjiherero\"],[\"ia\",\"Interlingua\",\"Interlingua\"],[\"id\",\"Indonesian\",\"Bahasa Indonesia\"],[\"ie\",\"Interlingue\",\"Interlingue\"],[\"ig\",\"Igbo\",\"Asụsụ Igbo\"],[\"ii\",\"Nuosu\",\"ꆈꌠ꒿ Nuosuhxop\"],[\"ik\",\"Inupiaq\",\"Iñupiaq\"],[\"io\",\"Ido\",\"Ido\"],[\"is\",\"Icelandic\",\"Íslenska\"],[\"it\",\"Italian\",\"Italiano\"],[\"iu\",\"Inuktitut\",\"ᐃᓄᒃᑎᑐᑦ\"],[\"ja\",\"Japanese\",\"日本語\"],[\"jv\",\"Javanese\",\"basa Jawa\"],[\"ka\",\"Georgian\",\"ქართული\"],[\"kg\",\"Kongo\",\"Kikongo\"],[\"ki\",\"Kikuyu\",\"Gĩkũyũ\"],[\"kj\",\"Kwanyama\",\"Kuanyama\"],[\"kk\",\"Kazakh\",\"қазақ тілі\"],[\"kl\",\"Kalaallisut\",\"kalaallisut\"],[\"km\",\"Khmer\",\"ខេមរភាសា\"],[\"kn\",\"Kannada\",\"ಕನ್ನಡ\"],[\"ko\",\"Korean\",\"한국어\"],[\"kr\",\"Kanuri\",\"Kanuri\"],[\"ks\",\"Kashmiri\",\"कश्मीरी\"],[\"ku\",\"Kurmanji (Kurdish)\",\"Kurmancî\"],[\"kv\",\"Komi\",\"коми кыв\"],[\"kw\",\"Cornish\",\"Kernewek\"],[\"ky\",\"Kyrgyz\",\"Кыргызча\"],[\"la\",\"Latin\",\"latine\"],[\"lb\",\"Luxembourgish\",\"Lëtzebuergesch\"],[\"lg\",\"Ganda\",\"Luganda\"],[\"li\",\"Limburgish\",\"Limburgs\"],[\"ln\",\"Lingala\",\"Lingála\"],[\"lo\",\"Lao\",\"ລາວ\"],[\"lt\",\"Lithuanian\",\"lietuvių kalba\"],[\"lu\",\"Luba-Katanga\",\"Tshiluba\"],[\"lv\",\"Latvian\",\"latviešu valoda\"],[\"mg\",\"Malagasy\",\"fiteny malagasy\"],[\"mh\",\"Marshallese\",\"Kajin M̧ajeļ\"],[\"mi\",\"Māori\",\"te reo Māori\"],[\"mk\",\"Macedonian\",\"македонски јазик\"],[\"ml\",\"Malayalam\",\"മലയാളം\"],[\"mn\",\"Mongolian\",\"Монгол хэл\"],[\"mr\",\"Marathi\",\"मराठी\"],[\"ms\",\"Malay\",\"Bahasa Melayu\"],[\"mt\",\"Maltese\",\"Malti\"],[\"my\",\"Burmese\",\"ဗမာစာ\"],[\"na\",\"Nauru\",\"Ekakairũ Naoero\"],[\"nb\",\"Norwegian Bokmål\",\"Norsk bokmål\"],[\"nd\",\"Northern Ndebele\",\"isiNdebele\"],[\"ne\",\"Nepali\",\"नेपाली\"],[\"ng\",\"Ndonga\",\"Owambo\"],[\"nl\",\"Dutch\",\"Nederlands\"],[\"nn\",\"Norwegian Nynorsk\",\"Norsk Nynorsk\"],[\"no\",\"Norwegian\",\"Norsk\"],[\"nr\",\"Southern Ndebele\",\"isiNdebele\"],[\"nv\",\"Navajo\",\"Diné bizaad\"],[\"ny\",\"Chichewa\",\"chiCheŵa\"],[\"oc\",\"Occitan\",\"occitan\"],[\"oj\",\"Ojibwe\",\"ᐊᓂᔑᓈᐯᒧᐎᓐ\"],[\"om\",\"Oromo\",\"Afaan Oromoo\"],[\"or\",\"Oriya\",\"ଓଡ଼ିଆ\"],[\"os\",\"Ossetian\",\"ирон æвзаг\"],[\"pa\",\"Panjabi\",\"ਪੰਜਾਬੀ\"],[\"pi\",\"Pāli\",\"पाऴि\"],[\"pl\",\"Polish\",\"Polski\"],[\"ps\",\"Pashto\",\"پښتو\"],[\"pt\",\"Portuguese\",\"Português\"],[\"qu\",\"Quechua\",\"Runa Simi\"],[\"rm\",\"Romansh\",\"rumantsch grischun\"],[\"rn\",\"Kirundi\",\"Ikirundi\"],[\"ro\",\"Romanian\",\"Română\"],[\"ru\",\"Russian\",\"Русский\"],[\"rw\",\"Kinyarwanda\",\"Ikinyarwanda\"],[\"sa\",\"Sanskrit\",\"संस्कृतम्\"],[\"sc\",\"Sardinian\",\"sardu\"],[\"sd\",\"Sindhi\",\"सिन्धी\"],[\"se\",\"Northern Sami\",\"Davvisámegiella\"],[\"sg\",\"Sango\",\"yângâ tî sängö\"],[\"si\",\"Sinhala\",\"සිංහල\"],[\"sk\",\"Slovak\",\"slovenčina\"],[\"sl\",\"Slovenian\",\"slovenščina\"],[\"sn\",\"Shona\",\"chiShona\"],[\"so\",\"Somali\",\"Soomaaliga\"],[\"sq\",\"Albanian\",\"Shqip\"],[\"sr\",\"Serbian\",\"српски језик\"],[\"ss\",\"Swati\",\"SiSwati\"],[\"st\",\"Southern Sotho\",\"Sesotho\"],[\"su\",\"Sundanese\",\"Basa Sunda\"],[\"sv\",\"Swedish\",\"Svenska\"],[\"sw\",\"Swahili\",\"Kiswahili\"],[\"ta\",\"Tamil\",\"தமிழ்\"],[\"te\",\"Telugu\",\"తెలుగు\"],[\"tg\",\"Tajik\",\"тоҷикӣ\"],[\"th\",\"Thai\",\"ไทย\"],[\"ti\",\"Tigrinya\",\"ትግርኛ\"],[\"tk\",\"Turkmen\",\"Türkmen\"],[\"tl\",\"Tagalog\",\"Wikang Tagalog\"],[\"tn\",\"Tswana\",\"Setswana\"],[\"to\",\"Tonga\",\"faka Tonga\"],[\"tr\",\"Turkish\",\"Türkçe\"],[\"ts\",\"Tsonga\",\"Xitsonga\"],[\"tt\",\"Tatar\",\"татар теле\"],[\"tw\",\"Twi\",\"Twi\"],[\"ty\",\"Tahitian\",\"Reo Tahiti\"],[\"ug\",\"Uyghur\",\"ئۇيغۇرچە‎\"],[\"uk\",\"Ukrainian\",\"Українська\"],[\"ur\",\"Urdu\",\"اردو\"],[\"uz\",\"Uzbek\",\"Ўзбек\"],[\"ve\",\"Venda\",\"Tshivenḓa\"],[\"vi\",\"Vietnamese\",\"Tiếng Việt\"],[\"vo\",\"Volapük\",\"Volapük\"],[\"wa\",\"Walloon\",\"walon\"],[\"wo\",\"Wolof\",\"Wollof\"],[\"xh\",\"Xhosa\",\"isiXhosa\"],[\"yi\",\"Yiddish\",\"ייִדיש\"],[\"yo\",\"Yoruba\",\"Yorùbá\"],[\"za\",\"Zhuang\",\"Saɯ cueŋƅ\"],[\"zh\",\"Chinese\",\"中文\"],[\"zu\",\"Zulu\",\"isiZulu\"],[\"zh-CN\",\"Chinese (China)\",\"简体中文\"],[\"zh-HK\",\"Chinese (Hong Kong)\",\"繁體中文(香港)\"],[\"zh-TW\",\"Chinese (Taiwan)\",\"繁體中文(臺灣)\"],[\"zh-YUE\",\"Cantonese\",\"廣東話\"],[\"ast\",\"Asturian\",\"Asturianu\"],[\"chr\",\"Cherokee\",\"ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ\"],[\"ckb\",\"Sorani (Kurdish)\",\"سۆرانی\"],[\"cnr\",\"Montenegrin\",\"crnogorski\"],[\"jbo\",\"Lojban\",\"la .lojban.\"],[\"kab\",\"Kabyle\",\"Taqbaylit\"],[\"ldn\",\"Láadan\",\"Láadan\"],[\"lfn\",\"Lingua Franca Nova\",\"lingua franca nova\"],[\"sco\",\"Scots\",\"Scots\"],[\"sma\",\"Southern Sami\",\"Åarjelsaemien Gïele\"],[\"smj\",\"Lule Sami\",\"Julevsámegiella\"],[\"szl\",\"Silesian\",\"ślůnsko godka\"],[\"tok\",\"Toki Pona\",\"toki pona\"],[\"xal\",\"Kalmyk\",\"Хальмг келн\"],[\"zba\",\"Balaibalan\",\"باليبلن\"],[\"zgh\",\"Standard Moroccan Tamazight\",\"ⵜⴰⵎⴰⵣⵉⵖⵜ\"]]"; public static final List allLanguages; public static final MastodonLanguage ENGLISH = new MastodonLanguage("en", "English", "English"); diff --git a/mastodon/src/main/res/color/bookmark_icon.xml b/mastodon/src/main/res/color/bookmark_icon.xml index 8f0180be7..2b6f9dd7d 100644 --- a/mastodon/src/main/res/color/bookmark_icon.xml +++ b/mastodon/src/main/res/color/bookmark_icon.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/mastodon/src/main/res/color/boost_icon.xml b/mastodon/src/main/res/color/boost_icon.xml index 1f913314a..e5d690f47 100644 --- a/mastodon/src/main/res/color/boost_icon.xml +++ b/mastodon/src/main/res/color/boost_icon.xml @@ -1,6 +1,6 @@ - - + + \ No newline at end of file diff --git a/mastodon/src/main/res/color/favorite_icon.xml b/mastodon/src/main/res/color/favorite_icon.xml index a55dd6c32..a459076eb 100644 --- a/mastodon/src/main/res/color/favorite_icon.xml +++ b/mastodon/src/main/res/color/favorite_icon.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/mastodon/src/main/res/color/like_icon.xml b/mastodon/src/main/res/color/like_icon.xml new file mode 100644 index 000000000..242d79986 --- /dev/null +++ b/mastodon/src/main/res/color/like_icon.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/color/poll_option_progress_inset.xml b/mastodon/src/main/res/color/poll_option_progress_inset.xml deleted file mode 100644 index 3fd78b91e..000000000 --- a/mastodon/src/main/res/color/poll_option_progress_inset.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/color/poll_option_text_inset.xml b/mastodon/src/main/res/color/poll_option_text_inset.xml deleted file mode 100644 index ef1f151e6..000000000 --- a/mastodon/src/main/res/color/poll_option_text_inset.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/bg_filter_warning.xml b/mastodon/src/main/res/drawable/bg_filter_warning.xml new file mode 100644 index 000000000..f9259297d --- /dev/null +++ b/mastodon/src/main/res/drawable/bg_filter_warning.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mastodon/src/main/res/drawable/bg_poll_option_clickable_inset.xml b/mastodon/src/main/res/drawable/bg_poll_option_clickable_inset.xml deleted file mode 100644 index 29dd2b1fc..000000000 --- a/mastodon/src/main/res/drawable/bg_poll_option_clickable_inset.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/bg_poll_option_voted_inset.xml b/mastodon/src/main/res/drawable/bg_poll_option_voted_inset.xml deleted file mode 100644 index 1bc8c099b..000000000 --- a/mastodon/src/main/res/drawable/bg_poll_option_voted_inset.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_actionmode_close.xml b/mastodon/src/main/res/drawable/ic_actionmode_close.xml deleted file mode 100644 index 222363cd5..000000000 --- a/mastodon/src/main/res/drawable/ic_actionmode_close.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_add_24px.xml b/mastodon/src/main/res/drawable/ic_add_24px.xml deleted file mode 100644 index b234bf84a..000000000 --- a/mastodon/src/main/res/drawable/ic_add_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_add_photo_alternate_24px.xml b/mastodon/src/main/res/drawable/ic_add_photo_alternate_24px.xml deleted file mode 100644 index e7f7a2d13..000000000 --- a/mastodon/src/main/res/drawable/ic_add_photo_alternate_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_add_photo_alternate_48px.xml b/mastodon/src/main/res/drawable/ic_add_photo_alternate_48px.xml deleted file mode 100644 index e7ffd70e0..000000000 --- a/mastodon/src/main/res/drawable/ic_add_photo_alternate_48px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_add_photo_alternate_48px_dark_on_surface.xml b/mastodon/src/main/res/drawable/ic_add_photo_alternate_48px_dark_on_surface.xml deleted file mode 100644 index bd82949cb..000000000 --- a/mastodon/src/main/res/drawable/ic_add_photo_alternate_48px_dark_on_surface.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_alt_24px.xml b/mastodon/src/main/res/drawable/ic_alt_24px.xml deleted file mode 100644 index ce9c3b96a..000000000 --- a/mastodon/src/main/res/drawable/ic_alt_24px.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/mastodon/src/main/res/drawable/ic_alternate_email_20px.xml b/mastodon/src/main/res/drawable/ic_alternate_email_20px.xml deleted file mode 100644 index 9846ae685..000000000 --- a/mastodon/src/main/res/drawable/ic_alternate_email_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_animation_24px.xml b/mastodon/src/main/res/drawable/ic_animation_24px.xml deleted file mode 100644 index 2ebcb150a..000000000 --- a/mastodon/src/main/res/drawable/ic_animation_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_apk_install_24px.xml b/mastodon/src/main/res/drawable/ic_apk_install_24px.xml deleted file mode 100644 index 19fba8f74..000000000 --- a/mastodon/src/main/res/drawable/ic_apk_install_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_app_badging_24px.xml b/mastodon/src/main/res/drawable/ic_app_badging_24px.xml deleted file mode 100644 index c626b4980..000000000 --- a/mastodon/src/main/res/drawable/ic_app_badging_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_backspace_24px.xml b/mastodon/src/main/res/drawable/ic_backspace_24px.xml deleted file mode 100644 index fd76984d2..000000000 --- a/mastodon/src/main/res/drawable/ic_backspace_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_block_20px.xml b/mastodon/src/main/res/drawable/ic_block_20px.xml deleted file mode 100644 index 7136c4c45..000000000 --- a/mastodon/src/main/res/drawable/ic_block_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_bookmark_24px.xml b/mastodon/src/main/res/drawable/ic_bookmark_24px.xml deleted file mode 100644 index 53de975b3..000000000 --- a/mastodon/src/main/res/drawable/ic_bookmark_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_check_20px.xml b/mastodon/src/main/res/drawable/ic_check_20px.xml deleted file mode 100644 index 59e22ef80..000000000 --- a/mastodon/src/main/res/drawable/ic_check_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_check_24px.xml b/mastodon/src/main/res/drawable/ic_check_24px.xml deleted file mode 100644 index 2e04d2a5e..000000000 --- a/mastodon/src/main/res/drawable/ic_check_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_check_small_16px.xml b/mastodon/src/main/res/drawable/ic_check_small_16px.xml deleted file mode 100644 index 44bf16801..000000000 --- a/mastodon/src/main/res/drawable/ic_check_small_16px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_compose_cw.xml b/mastodon/src/main/res/drawable/ic_compose_cw.xml deleted file mode 100644 index 48958d6bc..000000000 --- a/mastodon/src/main/res/drawable/ic_compose_cw.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_compose_emoji.xml b/mastodon/src/main/res/drawable/ic_compose_emoji.xml deleted file mode 100644 index fd423c918..000000000 --- a/mastodon/src/main/res/drawable/ic_compose_emoji.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_compose_poll.xml b/mastodon/src/main/res/drawable/ic_compose_poll.xml deleted file mode 100644 index 7aed17f47..000000000 --- a/mastodon/src/main/res/drawable/ic_compose_poll.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_dark_mode_24px.xml b/mastodon/src/main/res/drawable/ic_dark_mode_24px.xml deleted file mode 100644 index ca5cc6a7d..000000000 --- a/mastodon/src/main/res/drawable/ic_dark_mode_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_dns_24px.xml b/mastodon/src/main/res/drawable/ic_dns_24px.xml deleted file mode 100644 index dcc0d4e6d..000000000 --- a/mastodon/src/main/res/drawable/ic_dns_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_download_24px.xml b/mastodon/src/main/res/drawable/ic_download_24px.xml deleted file mode 100644 index 29ecb8fc6..000000000 --- a/mastodon/src/main/res/drawable/ic_download_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_drag_indicator_20px.xml b/mastodon/src/main/res/drawable/ic_drag_indicator_20px.xml deleted file mode 100644 index 1b7960aa8..000000000 --- a/mastodon/src/main/res/drawable/ic_drag_indicator_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_edit_24px.xml b/mastodon/src/main/res/drawable/ic_edit_24px.xml deleted file mode 100644 index 173e2c954..000000000 --- a/mastodon/src/main/res/drawable/ic_edit_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_emoticon_24px.xml b/mastodon/src/main/res/drawable/ic_emoticon_24px.xml deleted file mode 100644 index f492a2541..000000000 --- a/mastodon/src/main/res/drawable/ic_emoticon_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_feed_24px.xml b/mastodon/src/main/res/drawable/ic_feed_24px.xml deleted file mode 100644 index e1610f757..000000000 --- a/mastodon/src/main/res/drawable/ic_feed_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_filter_alt_24px.xml b/mastodon/src/main/res/drawable/ic_filter_alt_24px.xml deleted file mode 100644 index 006d21e4e..000000000 --- a/mastodon/src/main/res/drawable/ic_filter_alt_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_fluent_heart_20_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_heart_20_regular.xml new file mode 100644 index 000000000..1b70180f0 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_heart_20_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_heart_24_filled.xml b/mastodon/src/main/res/drawable/ic_fluent_heart_24_filled.xml new file mode 100644 index 000000000..8dc20bdeb --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_heart_24_filled.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_heart_24_selector.xml b/mastodon/src/main/res/drawable/ic_fluent_heart_24_selector.xml new file mode 100644 index 000000000..80231c3e4 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_heart_24_selector.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_heart_28_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_heart_28_regular.xml new file mode 100644 index 000000000..275f7b506 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_heart_28_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_password_24_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_password_24_regular.xml new file mode 100644 index 000000000..5f28f07fa --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_password_24_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_pause_24_filled.xml b/mastodon/src/main/res/drawable/ic_fluent_pause_24_filled.xml new file mode 100644 index 000000000..294d5219a --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_pause_24_filled.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_play_24_filled.xml b/mastodon/src/main/res/drawable/ic_fluent_play_24_filled.xml new file mode 100644 index 000000000..f1bdd659e --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_play_24_filled.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_re_order_dots_vertical_20_filled.xml b/mastodon/src/main/res/drawable/ic_fluent_re_order_dots_vertical_20_filled.xml new file mode 100644 index 000000000..6de7fef41 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_re_order_dots_vertical_20_filled.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_search_20_filled.xml b/mastodon/src/main/res/drawable/ic_fluent_search_20_filled.xml new file mode 100644 index 000000000..a17f0cfd5 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_search_20_filled.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_text_underline_24_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_text_underline_24_regular.xml new file mode 100644 index 000000000..fab41cb2c --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_text_underline_24_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_fluent_thumb_like_dislike_24_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_thumb_like_dislike_24_regular.xml new file mode 100644 index 000000000..71e65105a --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_thumb_like_dislike_24_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_follow_selector.xml b/mastodon/src/main/res/drawable/ic_follow_selector.xml deleted file mode 100644 index 8cd4d4e92..000000000 --- a/mastodon/src/main/res/drawable/ic_follow_selector.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/mastodon/src/main/res/drawable/ic_group_20px.xml b/mastodon/src/main/res/drawable/ic_group_20px.xml deleted file mode 100644 index a9fe3ba78..000000000 --- a/mastodon/src/main/res/drawable/ic_group_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_group_24px.xml b/mastodon/src/main/res/drawable/ic_group_24px.xml deleted file mode 100644 index 21147d83c..000000000 --- a/mastodon/src/main/res/drawable/ic_group_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_group_add_24px.xml b/mastodon/src/main/res/drawable/ic_group_add_24px.xml deleted file mode 100644 index 532b60ced..000000000 --- a/mastodon/src/main/res/drawable/ic_group_add_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_help_16px.xml b/mastodon/src/main/res/drawable/ic_help_16px.xml deleted file mode 100644 index 7890fdb8e..000000000 --- a/mastodon/src/main/res/drawable/ic_help_16px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_help_24px.xml b/mastodon/src/main/res/drawable/ic_help_24px.xml deleted file mode 100644 index 89da8f73d..000000000 --- a/mastodon/src/main/res/drawable/ic_help_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_help_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_help_fill1_24px.xml deleted file mode 100644 index 6bb3099e7..000000000 --- a/mastodon/src/main/res/drawable/ic_help_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_help_selectable.xml b/mastodon/src/main/res/drawable/ic_help_selectable.xml deleted file mode 100644 index a7e8ad04c..000000000 --- a/mastodon/src/main/res/drawable/ic_help_selectable.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_history_24px.xml b/mastodon/src/main/res/drawable/ic_history_24px.xml deleted file mode 100644 index 3afbd448c..000000000 --- a/mastodon/src/main/res/drawable/ic_history_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_home_24px.xml b/mastodon/src/main/res/drawable/ic_home_24px.xml deleted file mode 100644 index 4acca4f84..000000000 --- a/mastodon/src/main/res/drawable/ic_home_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_info_24px.xml b/mastodon/src/main/res/drawable/ic_info_24px.xml deleted file mode 100644 index 367c171e1..000000000 --- a/mastodon/src/main/res/drawable/ic_info_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_insert_chart_24px.xml b/mastodon/src/main/res/drawable/ic_insert_chart_24px.xml deleted file mode 100644 index 72ef007db..000000000 --- a/mastodon/src/main/res/drawable/ic_insert_chart_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_insert_chart_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_insert_chart_fill1_24px.xml deleted file mode 100644 index d9cf28ce4..000000000 --- a/mastodon/src/main/res/drawable/ic_insert_chart_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_keyboard_hide_24px.xml b/mastodon/src/main/res/drawable/ic_keyboard_hide_24px.xml deleted file mode 100644 index d9e619add..000000000 --- a/mastodon/src/main/res/drawable/ic_keyboard_hide_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_language_24px.xml b/mastodon/src/main/res/drawable/ic_language_24px.xml deleted file mode 100644 index 3b4871287..000000000 --- a/mastodon/src/main/res/drawable/ic_language_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_link_24px.xml b/mastodon/src/main/res/drawable/ic_link_24px.xml deleted file mode 100644 index af8304e40..000000000 --- a/mastodon/src/main/res/drawable/ic_link_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_logout_24px.xml b/mastodon/src/main/res/drawable/ic_logout_24px.xml deleted file mode 100644 index a02592125..000000000 --- a/mastodon/src/main/res/drawable/ic_logout_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_m3_cancel.xml b/mastodon/src/main/res/drawable/ic_m3_cancel.xml deleted file mode 100644 index 258e402fb..000000000 --- a/mastodon/src/main/res/drawable/ic_m3_cancel.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_m3_search.xml b/mastodon/src/main/res/drawable/ic_m3_search.xml deleted file mode 100644 index 1b2a144a7..000000000 --- a/mastodon/src/main/res/drawable/ic_m3_search.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_mail_24px.xml b/mastodon/src/main/res/drawable/ic_mail_24px.xml deleted file mode 100644 index ad21d51d6..000000000 --- a/mastodon/src/main/res/drawable/ic_mail_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_mood_20px.xml b/mastodon/src/main/res/drawable/ic_mood_20px.xml deleted file mode 100644 index a99bd218f..000000000 --- a/mastodon/src/main/res/drawable/ic_mood_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_mood_24px.xml b/mastodon/src/main/res/drawable/ic_mood_24px.xml deleted file mode 100644 index d2f257618..000000000 --- a/mastodon/src/main/res/drawable/ic_mood_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_mood_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_mood_fill1_24px.xml deleted file mode 100644 index 482ba44fc..000000000 --- a/mastodon/src/main/res/drawable/ic_mood_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_more_vert_20px.xml b/mastodon/src/main/res/drawable/ic_more_vert_20px.xml deleted file mode 100644 index b2acc7fe5..000000000 --- a/mastodon/src/main/res/drawable/ic_more_vert_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_no_adult_content_24px.xml b/mastodon/src/main/res/drawable/ic_no_adult_content_24px.xml deleted file mode 100644 index acc691029..000000000 --- a/mastodon/src/main/res/drawable/ic_no_adult_content_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_notifications_24px.xml b/mastodon/src/main/res/drawable/ic_notifications_24px.xml deleted file mode 100644 index 49817f4e1..000000000 --- a/mastodon/src/main/res/drawable/ic_notifications_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_notifications_paused_24px.xml b/mastodon/src/main/res/drawable/ic_notifications_paused_24px.xml deleted file mode 100644 index c0c55d00e..000000000 --- a/mastodon/src/main/res/drawable/ic_notifications_paused_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_open_in_browser_24px.xml b/mastodon/src/main/res/drawable/ic_open_in_browser_24px.xml deleted file mode 100644 index 2e7b8d015..000000000 --- a/mastodon/src/main/res/drawable/ic_open_in_browser_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_outline_email_24.xml b/mastodon/src/main/res/drawable/ic_outline_email_24.xml deleted file mode 100644 index 033a1e043..000000000 --- a/mastodon/src/main/res/drawable/ic_outline_email_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_outline_link_24.xml b/mastodon/src/main/res/drawable/ic_outline_link_24.xml deleted file mode 100644 index 346a9f7b0..000000000 --- a/mastodon/src/main/res/drawable/ic_outline_link_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_outline_password_24.xml b/mastodon/src/main/res/drawable/ic_outline_password_24.xml deleted file mode 100644 index dca893e46..000000000 --- a/mastodon/src/main/res/drawable/ic_outline_password_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_outline_person_24.xml b/mastodon/src/main/res/drawable/ic_outline_person_24.xml deleted file mode 100644 index 57423412f..000000000 --- a/mastodon/src/main/res/drawable/ic_outline_person_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_pause_24.xml b/mastodon/src/main/res/drawable/ic_pause_24.xml deleted file mode 100644 index 9c312c98e..000000000 --- a/mastodon/src/main/res/drawable/ic_pause_24.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_pause_48px.xml b/mastodon/src/main/res/drawable/ic_pause_48px.xml deleted file mode 100644 index a6b14ed8a..000000000 --- a/mastodon/src/main/res/drawable/ic_pause_48px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_person_24px.xml b/mastodon/src/main/res/drawable/ic_person_24px.xml deleted file mode 100644 index 87f358efb..000000000 --- a/mastodon/src/main/res/drawable/ic_person_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_person_add_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_person_add_fill1_24px.xml deleted file mode 100644 index 0939052ea..000000000 --- a/mastodon/src/main/res/drawable/ic_person_add_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_person_remove_20px.xml b/mastodon/src/main/res/drawable/ic_person_remove_20px.xml deleted file mode 100644 index 9f22dcc71..000000000 --- a/mastodon/src/main/res/drawable/ic_person_remove_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_person_remove_24px.xml b/mastodon/src/main/res/drawable/ic_person_remove_24px.xml deleted file mode 100644 index abe856461..000000000 --- a/mastodon/src/main/res/drawable/ic_person_remove_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_play_24.xml b/mastodon/src/main/res/drawable/ic_play_24.xml deleted file mode 100644 index 8986c1d04..000000000 --- a/mastodon/src/main/res/drawable/ic_play_24.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_play_arrow_48px.xml b/mastodon/src/main/res/drawable/ic_play_arrow_48px.xml deleted file mode 100644 index 4bd70b88f..000000000 --- a/mastodon/src/main/res/drawable/ic_play_arrow_48px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_poll_check.xml b/mastodon/src/main/res/drawable/ic_poll_check.xml deleted file mode 100644 index d74e61ba8..000000000 --- a/mastodon/src/main/res/drawable/ic_poll_check.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_privacy_tip_24px.xml b/mastodon/src/main/res/drawable/ic_privacy_tip_24px.xml deleted file mode 100644 index 47e3c09ed..000000000 --- a/mastodon/src/main/res/drawable/ic_privacy_tip_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_public_20px.xml b/mastodon/src/main/res/drawable/ic_public_20px.xml deleted file mode 100644 index 68f0bcbcc..000000000 --- a/mastodon/src/main/res/drawable/ic_public_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_repeat_20px.xml b/mastodon/src/main/res/drawable/ic_repeat_20px.xml deleted file mode 100644 index 377d13d08..000000000 --- a/mastodon/src/main/res/drawable/ic_repeat_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_repeat_24px.xml b/mastodon/src/main/res/drawable/ic_repeat_24px.xml deleted file mode 100644 index 7bf54f969..000000000 --- a/mastodon/src/main/res/drawable/ic_repeat_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_repeat_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_repeat_fill1_24px.xml deleted file mode 100644 index 7bf54f969..000000000 --- a/mastodon/src/main/res/drawable/ic_repeat_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_repeat_selector.xml b/mastodon/src/main/res/drawable/ic_repeat_selector.xml deleted file mode 100644 index f0da541ec..000000000 --- a/mastodon/src/main/res/drawable/ic_repeat_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_repeat_wght700grad200fill1_20px.xml b/mastodon/src/main/res/drawable/ic_repeat_wght700grad200fill1_20px.xml deleted file mode 100644 index 1b57f8d6e..000000000 --- a/mastodon/src/main/res/drawable/ic_repeat_wght700grad200fill1_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_reply_20px.xml b/mastodon/src/main/res/drawable/ic_reply_20px.xml deleted file mode 100644 index 22b557ba5..000000000 --- a/mastodon/src/main/res/drawable/ic_reply_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_restart_alt_24px.xml b/mastodon/src/main/res/drawable/ic_restart_alt_24px.xml deleted file mode 100644 index f955eb41a..000000000 --- a/mastodon/src/main/res/drawable/ic_restart_alt_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_save_24px.xml b/mastodon/src/main/res/drawable/ic_save_24px.xml deleted file mode 100644 index 55f8fb1a9..000000000 --- a/mastodon/src/main/res/drawable/ic_save_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_search_20px.xml b/mastodon/src/main/res/drawable/ic_search_20px.xml deleted file mode 100644 index 6758775ad..000000000 --- a/mastodon/src/main/res/drawable/ic_search_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_search_24px.xml b/mastodon/src/main/res/drawable/ic_search_24px.xml deleted file mode 100644 index 34e7ace3f..000000000 --- a/mastodon/src/main/res/drawable/ic_search_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_send_24px.xml b/mastodon/src/main/res/drawable/ic_send_24px.xml deleted file mode 100644 index a704c3fc1..000000000 --- a/mastodon/src/main/res/drawable/ic_send_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_settings_24px.xml b/mastodon/src/main/res/drawable/ic_settings_24px.xml deleted file mode 100644 index 0559faf5d..000000000 --- a/mastodon/src/main/res/drawable/ic_settings_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_settings_updateready_24px.xml b/mastodon/src/main/res/drawable/ic_settings_updateready_24px.xml deleted file mode 100644 index 0b39cd71f..000000000 --- a/mastodon/src/main/res/drawable/ic_settings_updateready_24px.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/mastodon/src/main/res/drawable/ic_share_20px.xml b/mastodon/src/main/res/drawable/ic_share_20px.xml deleted file mode 100644 index 037117e6d..000000000 --- a/mastodon/src/main/res/drawable/ic_share_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_share_24px.xml b/mastodon/src/main/res/drawable/ic_share_24px.xml deleted file mode 100644 index 3e3613ca3..000000000 --- a/mastodon/src/main/res/drawable/ic_share_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_social_leaderboard_24px.xml b/mastodon/src/main/res/drawable/ic_social_leaderboard_24px.xml deleted file mode 100644 index 801cefa99..000000000 --- a/mastodon/src/main/res/drawable/ic_social_leaderboard_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_star_20px.xml b/mastodon/src/main/res/drawable/ic_star_20px.xml deleted file mode 100644 index 885f71dde..000000000 --- a/mastodon/src/main/res/drawable/ic_star_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_star_24px.xml b/mastodon/src/main/res/drawable/ic_star_24px.xml deleted file mode 100644 index f44bd0d08..000000000 --- a/mastodon/src/main/res/drawable/ic_star_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_star_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_star_fill1_24px.xml deleted file mode 100644 index a3fce1e22..000000000 --- a/mastodon/src/main/res/drawable/ic_star_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_star_selector.xml b/mastodon/src/main/res/drawable/ic_star_selector.xml deleted file mode 100644 index 001d9b623..000000000 --- a/mastodon/src/main/res/drawable/ic_star_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_star_wght700grad200fill1_20px.xml b/mastodon/src/main/res/drawable/ic_star_wght700grad200fill1_20px.xml deleted file mode 100644 index a2ad3c349..000000000 --- a/mastodon/src/main/res/drawable/ic_star_wght700grad200fill1_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_stream_24px.xml b/mastodon/src/main/res/drawable/ic_stream_24px.xml deleted file mode 100644 index 6a519c07d..000000000 --- a/mastodon/src/main/res/drawable/ic_stream_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_style_24px.xml b/mastodon/src/main/res/drawable/ic_style_24px.xml deleted file mode 100644 index 2e47386f1..000000000 --- a/mastodon/src/main/res/drawable/ic_style_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_tag_24px.xml b/mastodon/src/main/res/drawable/ic_tag_24px.xml deleted file mode 100644 index f4f0e39a0..000000000 --- a/mastodon/src/main/res/drawable/ic_tag_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_thumbs_up_down_24px.xml b/mastodon/src/main/res/drawable/ic_thumbs_up_down_24px.xml deleted file mode 100644 index 160569608..000000000 --- a/mastodon/src/main/res/drawable/ic_thumbs_up_down_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_unfold_more_24px.xml b/mastodon/src/main/res/drawable/ic_unfold_more_24px.xml deleted file mode 100644 index b32d759f3..000000000 --- a/mastodon/src/main/res/drawable/ic_unfold_more_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_verified_24px.xml b/mastodon/src/main/res/drawable/ic_verified_24px.xml deleted file mode 100644 index ba30a40b8..000000000 --- a/mastodon/src/main/res/drawable/ic_verified_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_visibility_off_24px.xml b/mastodon/src/main/res/drawable/ic_visibility_off_24px.xml deleted file mode 100644 index cd9469b18..000000000 --- a/mastodon/src/main/res/drawable/ic_visibility_off_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_volume_off_20px.xml b/mastodon/src/main/res/drawable/ic_volume_off_20px.xml deleted file mode 100644 index 94d8bec08..000000000 --- a/mastodon/src/main/res/drawable/ic_volume_off_20px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_warning_24px.xml b/mastodon/src/main/res/drawable/ic_warning_24px.xml deleted file mode 100644 index c5e52a4c1..000000000 --- a/mastodon/src/main/res/drawable/ic_warning_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_warning_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_warning_fill1_24px.xml deleted file mode 100644 index 7ceeae25d..000000000 --- a/mastodon/src/main/res/drawable/ic_warning_fill1_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/ic_whatshot_24px.xml b/mastodon/src/main/res/drawable/ic_whatshot_24px.xml deleted file mode 100644 index 5886a00bd..000000000 --- a/mastodon/src/main/res/drawable/ic_whatshot_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/drawable/splash_logo.xml b/mastodon/src/main/res/drawable/splash_logo.xml deleted file mode 100644 index 71195de3f..000000000 --- a/mastodon/src/main/res/drawable/splash_logo.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - diff --git a/mastodon/src/main/res/drawable/thread_end_mark.xml b/mastodon/src/main/res/drawable/thread_end_mark.xml deleted file mode 100644 index 15afde530..000000000 --- a/mastodon/src/main/res/drawable/thread_end_mark.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/mastodon/src/main/res/layout/compose_poll_option.xml b/mastodon/src/main/res/layout/compose_poll_option.xml index 62675c6f9..307636f9d 100644 --- a/mastodon/src/main/res/layout/compose_poll_option.xml +++ b/mastodon/src/main/res/layout/compose_poll_option.xml @@ -33,7 +33,7 @@ android:tint="?colorM3OnSurfaceVariant" android:contentDescription="@string/reorder" android:paddingStart="4dp" - android:src="@drawable/ic_drag_indicator_20px" + android:src="@drawable/ic_fluent_re_order_dots_vertical_20_filled" tools:ignore="RtlSymmetry" /> \ No newline at end of file diff --git a/mastodon/src/main/res/layout/display_item_filter_warning.xml b/mastodon/src/main/res/layout/display_item_filter_warning.xml index 038e278af..dae144d30 100644 --- a/mastodon/src/main/res/layout/display_item_filter_warning.xml +++ b/mastodon/src/main/res/layout/display_item_filter_warning.xml @@ -3,8 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:id="@+id/warning_wrap" - android:background="@drawable/bg_timeline_gap"> + android:background="@drawable/bg_filter_warning"> diff --git a/mastodon/src/main/res/layout/display_item_header.xml b/mastodon/src/main/res/layout/display_item_header.xml index f3d18d939..28444aac6 100644 --- a/mastodon/src/main/res/layout/display_item_header.xml +++ b/mastodon/src/main/res/layout/display_item_header.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingRight="16dp" - android:paddingLeft="16dp"> + android:paddingHorizontal="16dp"> + @@ -70,6 +72,17 @@ + + - - + + + + + + + + + + + + + + + + + + + + android:id="@+id/delete_notification" + android:layout_width="36dp" + android:layout_height="48dp" + android:visibility="gone" + android:background="?android:actionBarItemBackground" + android:contentDescription="@string/sk_delete_notification" + android:tooltipText="@string/sk_delete_notification" + android:scaleType="center" + android:src="@drawable/ic_fluent_dismiss_20_filled" + android:tint="?colorM3OnSurfaceVariant" /> - - - - - \ No newline at end of file + diff --git a/mastodon/src/main/res/layout/fragment_compose.xml b/mastodon/src/main/res/layout/fragment_compose.xml index 13cda41d9..c9a6c34e8 100644 --- a/mastodon/src/main/res/layout/fragment_compose.xml +++ b/mastodon/src/main/res/layout/fragment_compose.xml @@ -237,7 +237,7 @@ android:layout_height="40dp" android:layout_marginStart="4dp" android:layout_marginEnd="20dp" - android:src="@drawable/ic_add_24px" + android:src="@drawable/ic_fluent_add_24_filled" android:tint="@color/button_text_m3_tonal" android:background="@drawable/bg_button_m3_tonal" android:contentDescription="@string/add_poll_option"/> diff --git a/mastodon/src/main/res/layout/fragment_onboarding_common.xml b/mastodon/src/main/res/layout/fragment_onboarding_common.xml index 4cad26f59..e70080edd 100644 --- a/mastodon/src/main/res/layout/fragment_onboarding_common.xml +++ b/mastodon/src/main/res/layout/fragment_onboarding_common.xml @@ -30,7 +30,7 @@ android:paddingBottom="0dp" android:paddingStart="12dp" android:paddingEnd="40dp" - android:drawableStart="@drawable/ic_m3_search" + android:drawableStart="@drawable/ic_fluent_search_20_filled" android:drawablePadding="8dp" android:drawableTint="?colorM3OnSurfaceVariant" android:gravity="center_vertical" @@ -72,7 +72,7 @@ android:contentDescription="@string/clear" android:tint="?colorM3OnSurfaceVariant" android:visibility="gone" - android:src="@drawable/ic_m3_cancel"/> + android:src="@drawable/ic_fluent_dismiss_20_filled"/> + android:background="@drawable/ic_fluent_person_24_regular"/> @@ -124,7 +124,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="12dp" android:backgroundTint="?colorM3OnSurfaceVariant" - android:background="@drawable/ic_outline_email_24"/> + android:background="@drawable/ic_fluent_mail_24_regular"/> @@ -160,7 +160,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="12dp" android:backgroundTint="?colorM3OnSurfaceVariant" - android:background="@drawable/ic_outline_password_24"/> + android:background="@drawable/ic_fluent_password_24_regular"/> diff --git a/mastodon/src/main/res/layout/fragment_splash.xml b/mastodon/src/main/res/layout/fragment_splash.xml index 392b8977c..3b6bb2bee 100644 --- a/mastodon/src/main/res/layout/fragment_splash.xml +++ b/mastodon/src/main/res/layout/fragment_splash.xml @@ -91,13 +91,13 @@ android:clipToPadding="false" android:orientation="vertical"> - + + + + + + + + android:src="@drawable/ic_fluent_search_20_filled"/> + android:src="@drawable/ic_fluent_dismiss_20_filled"/> diff --git a/mastodon/src/main/res/layout/item_privacy_policy_link.xml b/mastodon/src/main/res/layout/item_privacy_policy_link.xml index 3e864f010..d05908bdc 100644 --- a/mastodon/src/main/res/layout/item_privacy_policy_link.xml +++ b/mastodon/src/main/res/layout/item_privacy_policy_link.xml @@ -13,7 +13,7 @@ android:layout_width="24dp" android:layout_height="24dp" android:backgroundTint="?colorM3Primary" - android:background="@drawable/ic_outline_link_24"/> + android:background="@drawable/ic_fluent_link_24_regular"/> diff --git a/mastodon/src/main/res/layout/tab_bar.xml b/mastodon/src/main/res/layout/tab_bar.xml index fff505bfb..dfaa5b626 100644 --- a/mastodon/src/main/res/layout/tab_bar.xml +++ b/mastodon/src/main/res/layout/tab_bar.xml @@ -23,6 +23,7 @@ android:layout_marginEnd="8dp" android:paddingTop="12dp" android:paddingBottom="16dp" + android:tooltipText="@string/sk_tab_home" android:orientation="vertical"> + android:contentDescription="@string/sk_tab_home"> @@ -65,6 +67,7 @@ android:layout_marginEnd="8dp" android:paddingTop="12dp" android:paddingBottom="16dp" + android:tooltipText="@string/sk_tab_search" android:orientation="vertical"> + android:contentDescription="@string/sk_tab_search"> @@ -107,6 +111,7 @@ android:layout_marginEnd="8dp" android:paddingTop="12dp" android:paddingBottom="16dp" + android:tooltipText="@string/sk_tab_notifications" android:orientation="vertical"> + android:contentDescription="@string/sk_tab_notifications"> + android:minWidth="16dp" + tools:text="222"/> @@ -155,6 +160,7 @@ android:maxLines="1" android:layout_marginTop="4dp" android:textColor="@color/m3_on_surface_selector" + android:tag="label" android:text="@string/sk_tab_notifications" /> @@ -167,6 +173,7 @@ android:layout_marginEnd="8dp" android:paddingTop="12dp" android:paddingBottom="16dp" + android:tooltipText="@string/sk_tab_profile" android:orientation="vertical"> + android:contentDescription="@string/sk_tab_profile"> diff --git a/mastodon/src/main/res/values-ar/strings_sk.xml b/mastodon/src/main/res/values-ar/strings_sk.xml index 9eafdf22e..763ca2bfa 100644 --- a/mastodon/src/main/res/values-ar/strings_sk.xml +++ b/mastodon/src/main/res/values-ar/strings_sk.xml @@ -316,4 +316,10 @@ هذه هي أحدث المنشورات للأعضاء في فديراليتك. هذه هي أحدث المنشورات على الشبكة والتي انتقاها مُدراء خادمكم. برمجة أو تحرير مُسودّة + لوحة الألوان + الحسابات المحظورة + معلومات مثيل الخادم غير متوفرة في الحين + الحسابات المكتومة + السماح للوسائط المشغَّلَة بالفعل بالاستمرار في التشغيل، مع تراكب التشغيل الجديد + تراكُب صوتي \ No newline at end of file diff --git a/mastodon/src/main/res/values-de-rDE/strings_sk.xml b/mastodon/src/main/res/values-de-rDE/strings_sk.xml index ab1de2978..b6d7f1e0c 100644 --- a/mastodon/src/main/res/values-de-rDE/strings_sk.xml +++ b/mastodon/src/main/res/values-de-rDE/strings_sk.xml @@ -359,7 +359,7 @@ Wenn du auf ein Zeichen wartest, keinen Suizid zu begehen – das hier ist es. Bitte ziehe in Erwägung, eine Suizid-Hotline zu kontaktieren, wenn du Hilfe brauchst. Leere Emoji-Reaktionen verbergen Hinzufügen-Button immer anzeigen - Emoji zum Reagieren eintippen + Emoji eintippen oder suchen Unbestimmt 5 Minuten 30 Minuten @@ -385,4 +385,25 @@ https://findahelpline.com Ältere Beiträge laden Neuere Beiträge laden + + %d Sekunde + %d Sekunden + + + %d Stunde + %d Stunden + + Herz als Favorisieren-Symbol verwenden + Blockierte Konten + + %d Tag + %d Tage + + Stummgeschaltete Konten + Diese Beiträge sind im Fediverse gerade beliebt. + + %d Minute + %d Minuten + + Über diese Nachrichten wird im Fediverse gerade gesprochen. \ No newline at end of file diff --git a/mastodon/src/main/res/values-es-rES/strings_sk.xml b/mastodon/src/main/res/values-es-rES/strings_sk.xml index 86e7bc327..34930c529 100644 --- a/mastodon/src/main/res/values-es-rES/strings_sk.xml +++ b/mastodon/src/main/res/values-es-rES/strings_sk.xml @@ -367,7 +367,7 @@ %1$,d usuarios reaccionaron con %2$s Por favor, introduce un emoticono - Escribe para reaccionar con un emoticono + Escribe un emoticono o busca un emoticono personalizado Activar reacciones con emoticonos Muestra las reacciones con emoticonos a las publicaciones y te permite añadir las tuyas. Varias instancias del Fediverso lo soportan, pero Mastodon no. Las reacciones con los emoticonos deben mostrarse en las líneas de tiempo. Si esta opción está desactivada, las reacciones con los emoticonos solo se mostrarán al ver un hilo. @@ -401,4 +401,6 @@ Cargar publicaciones más recientes Estos son los posts que ganan popularidad en tu servidor. Estas son las noticias de las que se habla en tu servidor. + Cuentas bloqueadas + Cuentas silenciadas \ No newline at end of file diff --git a/mastodon/src/main/res/values-eu-rES/strings_sk.xml b/mastodon/src/main/res/values-eu-rES/strings_sk.xml index bc6a1a34a..268f0fe4f 100644 --- a/mastodon/src/main/res/values-eu-rES/strings_sk.xml +++ b/mastodon/src/main/res/values-eu-rES/strings_sk.xml @@ -283,7 +283,26 @@ Markdown bezalako eduki-mota ezartzea ahalbidetzen du bidalketa bat sortzerakoan. Gogoan izan instantzia guztiek ez dutela hau baimentzen. Eduki-mota lehenetsia Berretsi bultzatu aurretik - %s bezala erreakzionatuta - erreakzionatuta + %1$s-(e)k honela erreakzionatu du: %2$s + %s-(e)k erreakzionatu du Burbuila + Sartu traolak… + Gehitu denbora-lerroa + Jakin eragiketa hauek zerbitzariak kudeatzen dituela. Litekeena da konbinazioetarako euskarririk ez izatea. + Banatzaile bat instalatu behar duzu UnifiedPush jakinarazpenek funtzionatzeko. Informazio gehiago: https://unifiedpush.org/ + Jarioa + Traola hau duten tootak… + Egiaztatua + Erakutsi toot lokalak soilik\? + Euritakoa + Ez da banatzailerik aurkitu + ...edo hauetako edozein + ...eta hauek guztiak + Diamantea + Sartu traola… + ...baina hauetako bat ere ez + Aukeratu banatzaile bat + Zakarrontzia + Hauek dira zure zerbitzarian komentatzen ari diren albisteak + Traola ezin da hutsik egon \ No newline at end of file diff --git a/mastodon/src/main/res/values-fi-rFI/strings.xml b/mastodon/src/main/res/values-fi-rFI/strings.xml index 80be06d17..d9d8cf239 100644 --- a/mastodon/src/main/res/values-fi-rFI/strings.xml +++ b/mastodon/src/main/res/values-fi-rFI/strings.xml @@ -9,7 +9,7 @@ Valmistellaan todennusta… Viimeistellään todennusta… %s tehosti - Vastauksessa %s + Vastaus käyttäjälle %s Ilmoitukset %s seurasi sinua %s lähetti sinulle seurauspyynnön @@ -228,7 +228,7 @@ Tehosta Suosikki Jaa - Kuva ilma kuvausta + Kuva ilman kuvausta Lisää mediatiedosto Lisää kysely Emoji @@ -240,8 +240,8 @@ Seuraat nyt käyttäjää %s Käyttäjän %s seuraamista pyydetty Avaa selaimessa - Piilota käyttäjän @%s tehostukset - Näytä tehostukset käyttäjältä @%s + Piilota käyttäjän %s tehostukset + Näytä tehostukset käyttäjältä %s Miksi haluat liittyä? Tämä auttaa meitä arvioimaan hakemustasi. Tyhjennä @@ -270,11 +270,11 @@ Hyväksyy seuraajat käsin - %d seuraaja - %d seuraajaa + %,d seuraaja + %,d seuraajaa - %d seurattu + %,d seurattu %d seurattua @@ -351,7 +351,7 @@ Aasia Oseania Ei hyväksy uusia jäseniä - Erityiset Kiinnostukset + Erityiset kiinnostuksen kohteet Salasanat eivät täsmää Valitse minulle Lisää rivi @@ -385,7 +385,7 @@ tai Lue lisää Tervetuloa Mastodoniin - Mastodon on hajautettu sosiaalinen verkosto, joka tarkoittaa sitä, ettei sitä hallitse mikään yksittäinen yritys. Se koostuu monista itsenäisesti ylläpidetyistä palvelimista, jotka on liitetty yhteen. + Mastodon on hajautettu sosiaalinen verkosto, mikä tarkoittaa sitä, ettei sitä hallitse mikään yksittäinen yritys. Se koostuu monista itsenäisesti ylläpidetyistä palvelimista, jotka on liitetty yhteen. Mitä palvelimet ovat? Jokainen Mastodon tili isännöi palvelimella - kullakin on omat arvot, säännöt, & ylläpitäjät. Riippumatta siitä, minkä valitset, voit seurata ja olla vuorovaikutuksessa ihmisten kanssa millä tahansa palvelimella. Avataan linkki… @@ -583,11 +583,14 @@ %dh sitten %dd sitten - Käännetty kielestä %s + Käännä kielestä %s Käännetty kielestä %1$s käyttäen %2$s Näytä alkuperäinen Käännös epäonnistui. Ehkä järjestelmänvalvoja ei ole ottanut käyttöön käännöksiä tällä palvelimella tai tällä palvelimella on käynnissä vanhempi versio Mastodonista, jossa käännöksiä ei vielä tueta. + Yksityisyys ja tavoittavuus + Nosta profiili ja julkaisut esille löytämisalgoritmeissa + Sisällytä julkiset julkaisut hakutuloksiin %d osallistuja %d osallistujaa @@ -596,4 +599,5 @@ %,d viesti tänään %,d viestiä tänään + Virhe videon toistossa diff --git a/mastodon/src/main/res/values-fi-rFI/strings_sk.xml b/mastodon/src/main/res/values-fi-rFI/strings_sk.xml index c7b8573f6..5430fbc47 100644 --- a/mastodon/src/main/res/values-fi-rFI/strings_sk.xml +++ b/mastodon/src/main/res/values-fi-rFI/strings_sk.xml @@ -8,8 +8,8 @@ Näytetäänkö emojireaktiot aikajanoissa. Jos tämä on pois käytöstä, emojireaktiot näkyvät vain lankaa katsottaessa. Reagoi emojilla Järjestelmän näppäimistö seuraavalla painalluksella - Tähän tarvitaan emoji - Kirjoita vastataksesi emojilla + Lisää emoji + Lisää emoji tai etsi Kesto Loputon 5 minuuttia @@ -42,7 +42,7 @@ Avaa automaattisesti samat sisältövaroitukset vastauksissa Ei koskaan Saman tilin vastauksissa - Kaikkien vastauksissa + Kaikkien vastaukset Käännä vain avatut viestit Näytä alkuperäinen Käytettävissä olevat kielet @@ -69,7 +69,7 @@ Hae tietoa etäinstansseista Lähetä edelleen kohteeseen %s Julkaisemattomat viestit - Vastauksissa kaikille + Vastaus kenelle tahansa Ei koskaan Tallenna luonnos\? Tallenna muutokset\? @@ -97,7 +97,7 @@ Tietoja instanssista Näytä vain yksi ilmoitus Luo - Vastauksena + Vastaus Oletko varma että haluat poistaa listan \"%s\"\? Poista seuraajista Kissa @@ -132,7 +132,7 @@ Vastauksen näkyvyys Kaikki vastaukset Näytä lanka - \"Vastauksena\" -rivi käyttäjäkuvakkeen yläpuolella + \"Vastaus\" -rivi käyttäjäkuvakkeen yläpuolella Tiivistetty tehostus/vastaus-rivi Yksi käyttäjä reagoi näin: %2$s @@ -282,7 +282,7 @@ Korjataanko liitteet\? BBCode MFM - Vain vastauksissa muille + Vastaukset muille Erillinen lista Tee listasta erillinen Erillisen listan jäsenet eivät näy kotiaikajanallasi – jos instanssisi tukee tätä. @@ -359,7 +359,7 @@ Julkaisu on ajastettava vähintään 10 minuuttia tulevaisuuteen. Oletko varma että haluat irrottaa tämän viestin\? On asennettava jakelijaohjelma jotta UnifiedPush-ilmoitukset toimivat. Lisätietoja: https://unifiedpush.org/ - Näyttää viestien emojireaktiot ja mahdollistaa vuorovaikutuksen niiden kanssa. Jotkin Mastodonin muokatut versiot tukevat tätä, mutta Mastodon ei. + Näyttää viestien emojireaktiot ja mahdollistaa omien lisäämisen. Jotkin Mastodonin muokatut versiot tukevat tätä, mutta Mastodon ei. Hae kirjoittamalla tähän Selitys puuttuu vähintään yhdestä liitteestä. Kiinnitetty kotinäyttöön @@ -375,4 +375,38 @@ Palvelin tukee paikallista julkaisemista Anna mediatoiston jatkua lisäten uusi raita Lainaus %s + + %d sekunti + %d sekuntia + + Vain kun julkaisu on avattu + + %d tunti + %d tuntia + + Piilota tyhjät emojireaktiot + Näytä emojireaktiot aikajanoissa + Estetyt tilit + Itsemurha + Lataa uudempia julkaisuja + + %d päivä + %d päivää + + Näytä lisäyspainike aina + Löydä kriisipuhelin + Hiljennetyt tilit + Älä näytä toista kertaa + https://mieli.fi/tukea-ja-apua/kriisipuhelin/ + Nämä julkaisut ovat saamassa vetoa Fediversumissa. + Lataa vanhempia julkaisuja + Jos tarvitset apua… + + %d minuutti + %d minuuttia + + Jos haluat merkin siitä, että elämää kannattaa jatkaa, tämä on se. Jos olet hädässä, voit ottaa yhteyttä paikalliseen kriisipuhelimeen. + Näistä uutisjutuista keskustellaan Fediversumissa. + Julkaisussa on mediaa + Käytä sydäntä suosikkikuvakkeena \ No newline at end of file diff --git a/mastodon/src/main/res/values-fr-rFR/strings_sk.xml b/mastodon/src/main/res/values-fr-rFR/strings_sk.xml index 141066168..d11e7bbd8 100644 --- a/mastodon/src/main/res/values-fr-rFR/strings_sk.xml +++ b/mastodon/src/main/res/values-fr-rFR/strings_sk.xml @@ -372,7 +372,7 @@ Réagissez avec des emojis Appuyez à nouveau pour le clavier système - Tapez pour réagir avec un emoji + Tapez un emoji ou effectuez une recherche Veuillez saisir un emoji message @@ -393,12 +393,15 @@ Suicide Dans le cas où vous seriez en détresse… Si vous cherchez un signe pour ne pas vous suicider, le voici. Si vous êtes en détresse et/ou avez des pensées suicidaires, si vous voulez aider une personne en souffrance, vous pouvez contacter une ligne d\'assistance de prévention du suicide. - Ce sont les actualités dont on parle sur votre serveur. + Ces actualités font parler d’elles dans tout le Fediverse. Charger les messages les plus récents Charger les anciens messages %d secondes %d minutes %d heures %d jours - Ce sont les publications qui gagnent du terrain sur votre serveur. + Ces publications gagnent actuellement du terrain sur le Fediverse. + Comptes bloqués + Comptes silenciés + Utiliser le cœur comme icône pour les favoris \ No newline at end of file diff --git a/mastodon/src/main/res/values-hy-rAM/strings.xml b/mastodon/src/main/res/values-hy-rAM/strings.xml index 48b1644f7..4c133ca6e 100644 --- a/mastodon/src/main/res/values-hy-rAM/strings.xml +++ b/mastodon/src/main/res/values-hy-rAM/strings.xml @@ -13,6 +13,7 @@ %s հետեւելու հարցում է ուղարկել %s-ը հավանեց ձեր գրառումը %s տարածեց ձեր գրառումը + Տեսեք ձեր քվեարկած հարցման արդյունքները Տարածել Կարգավորումներ Հրապարակել @@ -102,6 +103,7 @@ Ջնջում… Նվագարկել Դադար տալ + Ելք Ավելացնել հաշիվ Որոնել Պիտակներ diff --git a/mastodon/src/main/res/values-in-rID/strings.xml b/mastodon/src/main/res/values-in-rID/strings.xml index 80680fa33..f980da916 100644 --- a/mastodon/src/main/res/values-in-rID/strings.xml +++ b/mastodon/src/main/res/values-in-rID/strings.xml @@ -554,5 +554,18 @@ %dj yang lalu %dh yang lalu + Terjemahkan dari bahasa %s + Diterjemahkan dari bahasa %1$s menggunakan %2$s + Tampilkan yang asli + Terjemahan gagal. Administrator mungkin belum mengaktifkan terjemahan di server ini atau server ini menjalankan Mastodon versi lama yang belum mendukung terjemahan. + Privasi dan jangkauan + Fiturkan profil dan kiriman dalam algoritma penjelajahan + Sertakan kiriman publik dalam hasil pencarian + + %,d peserta + + + %,d kiriman hari ini + diff --git a/mastodon/src/main/res/values-in-rID/strings_sk.xml b/mastodon/src/main/res/values-in-rID/strings_sk.xml index 213cb3f83..216147f98 100644 --- a/mastodon/src/main/res/values-in-rID/strings_sk.xml +++ b/mastodon/src/main/res/values-in-rID/strings_sk.xml @@ -366,7 +366,7 @@ %1$,d pengguna bereaksi dengan %2$s Silakan ketik emoji - Ketik untuk bereaksi dengan sebuah emoji + Ketik emoji atau cari Aktifkan reaksi emoji Menampilkan reaksi emoji di kiriman dan memungkinkan Anda untuk menambahkan sendiri. Banyak server Fediverse yang mendukung ini, tetapi Mastodon tidak mendukungnya. "Menentukan apakah reaksi emoji ditampilkan di lini masa. Jika opsi ini mati, reaksi emoji hanya akan ditampilkan ketika melihat sebuah utas." @@ -387,11 +387,14 @@ Temukan hotline Jangan tampilkan lagi https://findahelpline.com/id - Di bawah adalah kiriman yang mendapatkan daya tarik di server Anda. + Kiriman berikut mendapatkan daya tarik di Fediverse. Muat kiriman lama Jika Anda dalam kesulitan… %d menit Jika Anda mencari tanda untuk tidak melakukan bunuh diri, ini adalah tanda itu. Tolong pertimbangkan untuk menghubungi hotline bunuh diri lokal jika Anda dalam kesulitan. - Di bawah adalah berita yang dibicarakan di server Anda. + Berita berikut sedang dibicarakan di Fediverse. Kiriman berisi media + Akun yang diblokir + Akun yang dibisukan + Gunakam hati sebagai ikon favorit \ No newline at end of file diff --git a/mastodon/src/main/res/values-is-rIS/strings.xml b/mastodon/src/main/res/values-is-rIS/strings.xml index 0f8f22474..0a381602a 100644 --- a/mastodon/src/main/res/values-is-rIS/strings.xml +++ b/mastodon/src/main/res/values-is-rIS/strings.xml @@ -599,4 +599,5 @@ %,d færsla í dag %,d færslur í dag + Villa við að spila myndskeið diff --git a/mastodon/src/main/res/values-it-rIT/strings.xml b/mastodon/src/main/res/values-it-rIT/strings.xml index 67b70f50f..ace77920e 100644 --- a/mastodon/src/main/res/values-it-rIT/strings.xml +++ b/mastodon/src/main/res/values-it-rIT/strings.xml @@ -588,6 +588,8 @@ Tradotto da %1$s utilizzando %2$s Mostra originale Traduzione fallita. Forse l\'amministratore non ha abilitato le traduzioni su questo server, o su questo server è in esecuzione una versione precedente di Mastodon in cui le traduzioni non sono ancora supportate. + Privacy e copertura + Include il profilo e i post negli algoritmi di scoperta Includi i post pubblici nei risultati di ricerca %,d participante @@ -597,4 +599,5 @@ %,d post oggi %,d post oggi + Errore nella riproduzione del video diff --git a/mastodon/src/main/res/values-ja-rJP/strings.xml b/mastodon/src/main/res/values-ja-rJP/strings.xml index 1fa201e22..5e2bf447d 100644 --- a/mastodon/src/main/res/values-ja-rJP/strings.xml +++ b/mastodon/src/main/res/values-ja-rJP/strings.xml @@ -568,4 +568,5 @@ 今日の投稿 %,d 件 + 動画再生に失敗しました diff --git a/mastodon/src/main/res/values-pt-rBR/strings.xml b/mastodon/src/main/res/values-pt-rBR/strings.xml index f6a4a8127..f8e304352 100644 --- a/mastodon/src/main/res/values-pt-rBR/strings.xml +++ b/mastodon/src/main/res/values-pt-rBR/strings.xml @@ -572,5 +572,15 @@ %dh atrás %dd atrás + Traduzido de %s + Traduzido de %1$s usando %2$s + Mostrar original + A tradução falhou. Talvez o administrador não tenha habilitado as traduções neste servidor ou este servidor esteja executando uma versão mais antiga do Mastodon onde as traduções ainda não são suportadas. + Privacidade e alcance + Incluir publicações públicas nos resultados de pesquisa + + %,d participante + %,d participantes + diff --git a/mastodon/src/main/res/values-ro-rRO/strings_sk.xml b/mastodon/src/main/res/values-ro-rRO/strings_sk.xml index 06a7bb385..a6a212c06 100644 --- a/mastodon/src/main/res/values-ro-rRO/strings_sk.xml +++ b/mastodon/src/main/res/values-ro-rRO/strings_sk.xml @@ -379,7 +379,7 @@ %d zile Afișați mereu butonul adăugare Găsiți o linie de asistență telefonică - Scrieți pentru a reacționa cu un emoji + Scrieți un emoji sau căutați emoji personalizat Nu mai afișați din nou http://www.antisuicid.com/ Vă rugăm scrieți un emoji @@ -397,4 +397,6 @@ Dacă sunteți în căutarea unui semn pentru a nu vă sinucide, acesta este. Vă rugăm să luați în considerare posibilitatea de a apela la o linie telefonică locală de urgență pentru suicid dacă vă aflați în dificultate. Acestea sunt știrile despre care se vorbește pe serverul tău. Postare conține media + Conturi blocate + Conturi amuțite \ No newline at end of file diff --git a/mastodon/src/main/res/values-ru-rRU/strings.xml b/mastodon/src/main/res/values-ru-rRU/strings.xml index 2e5bb9bfd..ec6eeeb2b 100644 --- a/mastodon/src/main/res/values-ru-rRU/strings.xml +++ b/mastodon/src/main/res/values-ru-rRU/strings.xml @@ -661,4 +661,5 @@ %,d постов сегодня %,d постов сегодня + Ошибка воспроизведения видео diff --git a/mastodon/src/main/res/values-ru-rRU/strings_sk.xml b/mastodon/src/main/res/values-ru-rRU/strings_sk.xml index 00e4b355f..6996024ba 100644 --- a/mastodon/src/main/res/values-ru-rRU/strings_sk.xml +++ b/mastodon/src/main/res/values-ru-rRU/strings_sk.xml @@ -250,7 +250,7 @@ Версия сервера: %s Итоги голосования Для работы этой функции ваш инстанс должен поддерживать локальные публикации. Большинство модифицированных версий Mastodon это поддерживают, но сам Mastodon нет. - Префикс ответа CW с “re:” + Префикс CW с \"re:\" при ответе Отфильтровано: %s Развернуть Свернуть @@ -331,4 +331,84 @@ Только в ответ другим Распределители не найдены Позволяет устанавливать тип содержимого вроде Markdown при создании поста. Имейте в виду, что это поддерживается не на всех серверах. + Пробовать получить более точные данные о подписчиках, избранных и продвижениях, загрузив информацию из экземпляра происхождения. + Это позволяет предварительно выбирать тип содержимого при создании новых публикаций, переопределяя значение, установленное в “Параметры публикации”. + Эти посты набирают обороты на вашем сервере. + Позволять продолжить воспроизведение уже проигрываемого медиа, накладывая его на новое воспроизведение + Наложение аудио + Это новости, которые обсуждаются на вашем сервере. + Отключить индикатор активной вкладки в виде таблетки + Профиль + + %d секунда + %d секунды + %d секунд + %d секунд + + Длительность + Только когда пост открыт + + %d час + %d часа + %d часов + %d часов + + Главная + Скрывать пустые реакции эмодзи + Отображать реакции эмодзи в лентах + + пост + поста + постов + постов + + Вы были упомянуты %s + Включить реакции эмодзи + Суицид, Самоубийство + 5 минут + Загрузить более новые посты + Отображать местоимения в лентах + + %d день + %d дня + %d дней + %d дней + + Отображать ярлыки вкладок на панели навигации + Поиск + Всегда показывать кнопку добавить + Бессрочно + Найти службу помощи + 1 час + 6 часов + Введите эмодзи или найдете + 7 дней + Абсолютно черный режим + Не показывать снова + Отображать местоимения в ответах + Пожалуйста введите эмодзи + 30 минут + Отображать местоимения в списках пользователей + Отреагировать с эмодзи + 1 день + Загрузить более старые посты + Отображает реакции эмодзи на посты и позволяет добавлять свои. Различные серверы Fediverse поддерживают эту функцию, но Mastodon нет. + 3 дня + В случае, если вы попали в беду… + + %d минута + %d минуты + %d минут + %d минут + + + Один пользователь отреагировал с %2$s + %1$,d пользователей отреагировали с %2$s + %1$,d пользователей отреагировали с %2$s + %1$,d пользователей отреагировали с %2$s + + Если вы ищете знак, чтобы не совершить самоубийство, то это он. Если вы попали в беду, обратитесь в местную службу помощи самоубийцам. + Пост содержит медиа + Уведомления + Участники эксклюзивного списка не будут отображаться в вашей домашней ленте - если ваш экземпляр поддерживает такую возможность. \ No newline at end of file diff --git a/mastodon/src/main/res/values-si-rLK/strings.xml b/mastodon/src/main/res/values-si-rLK/strings.xml index d26a76f2a..e7218851d 100644 --- a/mastodon/src/main/res/values-si-rLK/strings.xml +++ b/mastodon/src/main/res/values-si-rLK/strings.xml @@ -11,7 +11,7 @@ ඉවතලන්න අවලංගු මාධ්‍ය - පිලිබඳව + පිළිබඳව පැතිකඩ සංස්කරණය %s නිහඬ %s නොනිහඬ diff --git a/mastodon/src/main/res/values-sv-rSE/strings.xml b/mastodon/src/main/res/values-sv-rSE/strings.xml index 1fecf3424..870f2c74c 100644 --- a/mastodon/src/main/res/values-sv-rSE/strings.xml +++ b/mastodon/src/main/res/values-sv-rSE/strings.xml @@ -12,7 +12,9 @@ Som svar på %s Notiser %s följde dig + %s skickade en förfrågan om att följa dig %s favoritmarkerade ditt inlägg + %s boostade ditt inlägg Dela Inställningar Publicera diff --git a/mastodon/src/main/res/values-th-rTH/strings.xml b/mastodon/src/main/res/values-th-rTH/strings.xml index 7acb8fb8a..8e28885d1 100644 --- a/mastodon/src/main/res/values-th-rTH/strings.xml +++ b/mastodon/src/main/res/values-th-rTH/strings.xml @@ -568,4 +568,5 @@ %,d โพสต์วันนี้ + เกิดข้อผิดพลาดในการเล่นวิดีโอ diff --git a/mastodon/src/main/res/values-uk-rUA/strings.xml b/mastodon/src/main/res/values-uk-rUA/strings.xml index d2080f40e..ff28c113a 100644 --- a/mastodon/src/main/res/values-uk-rUA/strings.xml +++ b/mastodon/src/main/res/values-uk-rUA/strings.xml @@ -661,4 +661,5 @@ %,d дописів сьогодні %,d дописа сьогодні + Помилка відтворення відео diff --git a/mastodon/src/main/res/values-uk-rUA/strings_sk.xml b/mastodon/src/main/res/values-uk-rUA/strings_sk.xml index 90c045e93..dcc901d8b 100644 --- a/mastodon/src/main/res/values-uk-rUA/strings_sk.xml +++ b/mastodon/src/main/res/values-uk-rUA/strings_sk.xml @@ -71,9 +71,9 @@ Видалити сповіщення Ви впевнені, що хочете видалити це сповіщення\? Увімкнути видалення сповіщень - Текст кнопки \"опублікувати\" - Змінити текст кнопки \"опублікувати\" - Сховати кнопку \"перекласти\" у стрічці + Текст кнопки «Опублікувати» + Змінити текст кнопки «Опублікувати» + Сховати кнопку «Перекласти» у стрічці %s підтримує переклад! %s не підтримує переклад. Очистити всі сповіщення @@ -304,7 +304,7 @@ Відповіді будь-кому Ніколи Лише у відповідь іншим - Усталений перемикач “Пересилати звіт” + Усталений перемикач «Пересилати звіт» Стрічка Список виключення Створити список виключень @@ -328,7 +328,7 @@ Діамант Парасолька Додати стрічку - Вимова + Займенники Перемкнути стрічку Сервер Абсолютно чорний режим @@ -372,7 +372,7 @@ Увімкнути реакції з емоджі Показує реакції емоджі на дописи та дає змогу додавати свої. Різні сервери Fediverse підтримують цю функцію, але Mastodon не підтримує. Введіть емоджі - Введіть, щоб відреагувати з емоджі + Введіть або знайдіть власний емоджі Чи відображати реакції емоджі у стрічках. Якщо цю опцію вимкнено, реакції емоджі показуватимуться лише під час перегляду гілки. допис @@ -389,7 +389,7 @@ Спочатку найдавніші (за зростанням) Показувати реакції емоджі у стрічках Сховати реакції без емоджі - Завжди показувати кнопку Додати + Завжди показувати кнопку «Додати» Самогубство Якщо ви потрапили в біду… Якщо ви шукаєте знак, щоб не накладати на себе руки, то це він. Якщо ви перебуваєте у скрутному становищі, зверніться на місцеву гарячу лінію з питань самогубств. @@ -402,4 +402,6 @@ %d секунд Це дописи, які набирають популярність на вашому сервері. %d днів + Заблоковані облікові записи + Ігноровані облікові записи \ No newline at end of file diff --git a/mastodon/src/main/res/values-zh-rCN/strings_sk.xml b/mastodon/src/main/res/values-zh-rCN/strings_sk.xml index 2b48f1656..3b8726f72 100644 --- a/mastodon/src/main/res/values-zh-rCN/strings_sk.xml +++ b/mastodon/src/main/res/values-zh-rCN/strings_sk.xml @@ -325,7 +325,7 @@ 用表情回应 再次点击以打开系统键盘 请输入一个表情 - 输入一个表情以回应 + 输入表情符号或搜索自定义表情 持续时间 无限期 5分钟 @@ -393,4 +393,6 @@ 如果你正在寻找一个不自杀的迹象,这就是。如果你遇到困难,请考虑拨打当地的自杀热线。 这些是你的服务器上正在谈论的新闻故事。 嘟文包含媒体 + 已屏蔽账号 + 已静音账号 \ No newline at end of file diff --git a/mastodon/src/main/res/values-zh-rTW/strings.xml b/mastodon/src/main/res/values-zh-rTW/strings.xml index b0575fe38..c935227a8 100644 --- a/mastodon/src/main/res/values-zh-rTW/strings.xml +++ b/mastodon/src/main/res/values-zh-rTW/strings.xml @@ -568,4 +568,5 @@ 本日共 %,d 則嘟文 + 播放影片時發生錯誤 diff --git a/mastodon/src/main/res/values/attrs.xml b/mastodon/src/main/res/values/attrs.xml index edbbf8e24..3ee77461d 100644 --- a/mastodon/src/main/res/values/attrs.xml +++ b/mastodon/src/main/res/values/attrs.xml @@ -31,6 +31,7 @@ + diff --git a/mastodon/src/main/res/values/colors.xml b/mastodon/src/main/res/values/colors.xml index d6411cc7b..28b17a685 100644 --- a/mastodon/src/main/res/values/colors.xml +++ b/mastodon/src/main/res/values/colors.xml @@ -95,6 +95,7 @@ #30FFFFFF @color/success_500 + @color/error_500 #282C37 @color/primary_400 diff --git a/mastodon/src/main/res/values/palettes.xml b/mastodon/src/main/res/values/palettes.xml index ea671425d..7c1cbbbe1 100644 --- a/mastodon/src/main/res/values/palettes.xml +++ b/mastodon/src/main/res/values/palettes.xml @@ -20,7 +20,6 @@ @color/gray_700 @color/gray_600 @color/gray_500 - @color/gray_400 @color/gray_300 @color/gray_200 @@ -34,7 +33,6 @@ @color/gray_700 @color/gray_600 @color/gray_500 - @color/gray_400 @color/gray_300 @color/gray_200 @@ -70,6 +68,8 @@ ?colorGray100 ?colorPrimary200 + @color/favorite_selected + @color/like_selected ?colorM3Primary @color/bookmark_selected #14000000 @@ -261,7 +261,7 @@ @color/m3_neutral2_10 - @@ -89,6 +90,7 @@ ?colorM3OnSurface ?colorM3OnSurface ?colorM3OnSurfaceVariant + @style/Widget.Mastodon.ActionButton.Overflow @style/empty_text