Compare commits

...

85 Commits

Author SHA1 Message Date
LucasGGamerM
eec547618f Chaging string in title 2023-01-27 14:24:19 -03:00
LucasGGamerM
a3ee174d66 Fixing weird fab behavior on quickly jittering the main screen 2023-01-27 14:19:31 -03:00
LucasGGamerM
45832355a3 Refactoring the enableHideFab option, and increasing the threshold for the fab popping up from 400 to 800 2023-01-26 20:15:50 -03:00
FineFindus
51d4fd63db refactor(compose-fab): code cleanup 2023-01-26 20:11:08 -03:00
FineFindus
ececa7aa2f refactor(compose-fab): show fab after small scroll distance 2023-01-26 20:11:05 -03:00
tygyh
6cf8793efe Translated using Weblate (Swedish)
Currently translated at 38.4% (5 of 13 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/sv/
2023-01-26 19:53:02 -03:00
HudobniVolk
57251d58cb Translated using Weblate (Slovenian)
Currently translated at 46.1% (6 of 13 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/sl/
2023-01-26 19:53:02 -03:00
LamaEpik
cf1f8e8d1a Translated using Weblate (French)
Currently translated at 15.3% (2 of 13 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/fr/
2023-01-26 19:53:02 -03:00
Andrewblasco
c77cb14602 Translated using Weblate (Spanish)
Currently translated at 100.0% (13 of 13 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/es/
2023-01-26 19:53:02 -03:00
tygyh
de864edb33 Translated using Weblate (Swedish)
Currently translated at 31.8% (7 of 22 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/sv/
2023-01-26 19:53:02 -03:00
Andrewblasco
699925ac9b Translated using Weblate (Spanish)
Currently translated at 100.0% (22 of 22 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/es/
2023-01-26 19:53:02 -03:00
Kevin
e367b7711f Translated using Weblate (German)
Currently translated at 100.0% (22 of 22 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/de/
2023-01-26 19:53:02 -03:00
Kevin
b0e4f707aa Translated using Weblate (German)
Currently translated at 100.0% (13 of 13 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/de/
2023-01-26 19:53:01 -03:00
LucasGGamerM
2749ffb6f2 Reverting the other irrelevant thing. 2023-01-26 16:23:54 -03:00
LucasGGamerM
47f57bab17 Testing the hooks for weblate 2023-01-26 14:50:52 -03:00
sk
f1b0f828ac Fixing up name of the setting, and making it disabled by default 2023-01-26 14:42:10 -03:00
LucasGGamerM
5b1188ce97 Merge pull request #55 from FineFindus/feat/profile-menu
feat(profile): move options to overflow menu
2023-01-24 18:16:50 -03:00
LucasGGamerM
c11863388d Putting stuff back to sk_ instead of mo_ on sk strings.
Relevant command: find values*/strings_sk.xml -type f -exec sed -i 's/mo_/sk_/g' {} \;
2023-01-24 17:47:12 -03:00
LucasGGamerM
476b462e86 Fixing a weird crash on the onHidden method added in a commit from upstream 2023-01-24 17:36:15 -03:00
LucasGGamerM
f69b308936 Merge pull request #54
Updated german translation
2023-01-24 17:29:59 -03:00
FineFindus
bdcafd2564 feat(profile): move options to overflow menu 2023-01-24 20:42:41 +01:00
dontobi
3455aab3ba Updated german translation 2023-01-24 11:13:02 +01:00
LucasGGamerM
aac4f412bd Finishing moving all the relevant strings to strings_mo.xml 2023-01-23 18:56:50 -03:00
LucasGGamerM
26831c3375 Updating somethings 2023-01-23 18:49:33 -03:00
LucasGGamerM
d7004824fb Decoupling moshidon strings from megalodon 2023-01-23 18:47:07 -03:00
LucasGGamerM
53d93764b0 Adding an icon and text to the hide compose button while scrolling setting 2023-01-23 17:50:07 -03:00
LucasGGamerM
6a84462b79 Adding an option for enabling/disabling the fab. Still missing an icon and text 2023-01-23 17:39:59 -03:00
Grishka
739d30c887 Save last seen home timeline post via markers API 2023-01-23 17:26:06 -03:00
Grishka
aa3aa8a5f9 Save last seen home timeline post via markers API 2023-01-23 17:20:47 -03:00
Grishka
be48719f52 remove log 2023-01-23 17:19:50 -03:00
Grishka
8e60d107fe Allow viewing alt text on images
closes #100
2023-01-23 17:19:46 -03:00
Grishka
c618feabe9 Workaround to fix #497 2023-01-23 17:19:34 -03:00
Grishka
87164dc469 Minor fixes from our boy grishka himself 2023-01-23 17:18:05 -03:00
sk
4ab1c61262 work around black screen opening notifs
closes sk22#342
2023-01-23 17:08:15 -03:00
LucasGGamerM
fe519f10a1 Failed try to fix the fabled fab problem 2023-01-22 19:41:17 -03:00
LucasGGamerM
901c7c3806 Revert "Fixing the bug of the fab reloading every time the user profile loads"
This reverts commit 211e6cdee2.
2023-01-22 19:08:24 -03:00
LucasGGamerM
211e6cdee2 Fixing the bug of the fab reloading every time the user profile loads 2023-01-22 18:36:31 -03:00
LucasGGamerM
394699c072 Fixing fab behavior on profile page when notes are selected 2023-01-22 18:26:53 -03:00
sk
c9766defff Removing the banners from the local and federated timelines 2023-01-22 18:18:14 -03:00
LucasGGamerM
737aa95bf5 Revert "Making it so the fab doesnt reappear when the notes is in edit mode"
This reverts commit 870ac2b946.
2023-01-22 15:19:52 -03:00
LucasGGamerM
38e035d792 Fixing #53 2023-01-22 13:33:45 -03:00
LucasGGamerM
4aa750c05e Update README.md
Adding a link to the official matrix chatrooom
2023-01-21 17:37:57 -03:00
LucasGGamerM
c3e5f4d254 Changelog for 87 2023-01-21 16:11:14 -03:00
LucasGGamerM
2e5ff452fd Bumping version number 2023-01-21 16:03:52 -03:00
LucasGGamerM
c397c08e40 In the process of trying to make them stack I just couldnt. So I guess this is the new release then 2023-01-21 16:02:11 -03:00
LucasGGamerM
a4d2101f54 a little less broken 2023-01-20 22:12:24 -03:00
sk
f956a17797 Experimental notifications improvement, still a long while to go 2023-01-20 22:06:42 -03:00
sk
1c1d1772a3 Adding needAppRestart to reduceMotion setting 2023-01-20 17:30:12 -03:00
sk
4db87feec4 Making sure it compiles! 2023-01-20 17:30:12 -03:00
sk
bef3c72513 fix "0" reply to ID 2023-01-20 17:30:12 -03:00
sk
4fa641b482 fix null-pointer when switching themes 2023-01-20 17:30:12 -03:00
sk
885b5d781a tweak timeline title animation 2023-01-20 17:30:12 -03:00
sk
2f3bfb3e74 fix clearing notifications
closes sk22#292
2023-01-20 17:30:12 -03:00
sk
2be625fd76 add missing draft params
closes sk22#302
2023-01-20 17:30:12 -03:00
sk
134a371263 only show new posts button at home 2023-01-20 17:30:12 -03:00
sk
8b0eddb8e1 set pivot of timeline title
closes sk22#296
2023-01-20 17:30:12 -03:00
sk
bd2d56b953 remove debug statements 2023-01-20 17:30:12 -03:00
sk
38e429f738 improve multi-line style 2023-01-20 17:30:12 -03:00
sk
de8b15d447 don't cut off multi-line strings 2023-01-20 17:30:12 -03:00
sk
0df1bcce31 fix new posts centered layout 2023-01-20 17:30:12 -03:00
sk
4e17256cfa fix centering button in rtl 2023-01-20 17:30:12 -03:00
sk
e12c3e2d68 fix rtl direction 2023-01-20 17:30:12 -03:00
sk
aec2704f15 restore current tab 2023-01-20 17:30:12 -03:00
sk
31f9173126 don't use old fragments 2023-01-20 17:30:12 -03:00
sk
90196df65d simplify method 2023-01-20 17:30:12 -03:00
sk
6b9fa71806 change crash workaround 2023-01-20 17:30:12 -03:00
sk
130085f804 Revert "work around crash theme switch"
This reverts commit 58fd0c444f30aa5352486b97cab34b2aca6ce8ab.
2023-01-20 17:30:12 -03:00
sk
f4356e74a4 add pager title transition 2023-01-20 17:30:12 -03:00
sk
9c8a4b7a8e Fixing some compile problems 2023-01-20 17:30:12 -03:00
sk22
b7ccf1144c New home layout with public timelines (#288)
* add dummy popup menu
* add pager to home fragment
* reduce pager sensitivity
* remove timelines from discover fragment
* add fabs to timelines
* change info banner color
* add back toolbar functionality
* update icons on navigate
* handle back press
* add lists and hashtags
* use tabs
* improve timeline title
* tweak switcher behavior
* fix show new posts button appearance
* hide show new posts button on reload
* tweak show new posts animations
* work around crash theme switch
* enable disabling federated timeline
Thanks @sk22!
2023-01-20 17:30:11 -03:00
sk
87d5b92a99 change crash workaround 2023-01-20 17:29:23 -03:00
LucasGGamerM
29f8260852 Merge remote-tracking branch 'origin/master' 2023-01-20 11:26:10 -03:00
LucasGGamerM
060745869b Revert "New home layout with public timelines (#288)"
This reverts commit 78d0add808.
2023-01-20 11:19:20 -03:00
LucasGGamerM
1aff3eacd8 Revert "New home layout with public timelines (#288)"
This reverts commit 0207ddb774.
2023-01-20 11:19:16 -03:00
LucasGGamerM
0207ddb774 New home layout with public timelines (#288)
* add dummy popup menu
* add pager to home fragment
* reduce pager sensitivity
* remove timelines from discover fragment
* add fabs to timelines
* change info banner color
* add back toolbar functionality
* update icons on navigate
* handle back press
* add lists and hashtags
* use tabs
* improve timeline title
* tweak switcher behavior
* fix show new posts button appearance
* hide show new posts button on reload
* tweak show new posts animations
* work around crash theme switch
* enable disabling federated timeline
2023-01-20 11:19:09 -03:00
sk22
78d0add808 New home layout with public timelines (#288)
* add dummy popup menu
* add pager to home fragment
* reduce pager sensitivity
* remove timelines from discover fragment
* add fabs to timelines
* change info banner color
* add back toolbar functionality
* update icons on navigate
* handle back press
* add lists and hashtags
* use tabs
* improve timeline title
* tweak switcher behavior
* fix show new posts button appearance
* hide show new posts button on reload
* tweak show new posts animations
* work around crash theme switch
* enable disabling federated timeline
2023-01-20 11:17:26 -03:00
LucasGGamerM
2fa042490a Revert "feat(status/footer): add tooltips to icons"
This reverts commit 707c51e4d6.
2023-01-20 11:09:16 -03:00
LucasGGamerM
885f559092 Revert "Revert "click "replying to" to scroll up""
This reverts commit 77af7ceae3.
2023-01-20 11:01:39 -03:00
sk
77af7ceae3 Revert "click "replying to" to scroll up"
This reverts commit cd0cfba7
2023-01-20 11:00:53 -03:00
sk
09d4188d54 click "replying to" to scroll up
closes #241
2023-01-20 10:59:02 -03:00
LucasGGamerM
1ad03828e3 Merge pull request #49 from dontobi/master
Update german translation
2023-01-19 20:36:22 -03:00
LucasGGamerM
870ac2b946 Making it so the fab doesnt reappear when the notes is in edit mode 2023-01-19 20:19:33 -03:00
FineFindus
394a3eebb1 feat(composeButton): hide when scrolling in profile fragment 2023-01-19 20:01:39 -03:00
FineFindus
95c10a9fea feat(composeButton): hide fab on scroll 2023-01-19 20:00:54 -03:00
dontobi
f0e14c5a13 Update german translation 2023-01-18 21:26:47 +01:00
168 changed files with 2076 additions and 511 deletions

View File

@@ -140,4 +140,6 @@ This project is released under the [GPL-3 License](./LICENSE).
## Links
[Official matrix chatroom:](https://matrix.to/#/#moshidon:matrix.org) https://matrix.to/#/#moshidon:matrix.org
<a rel="me" href="https://floss.social/@moshidon">@moshidon<wbr>@floss.social</a>

View File

@@ -9,8 +9,8 @@ android {
applicationId "org.joinmastodon.android.moshinda"
minSdk 23
targetSdk 33
versionCode 86
versionName "1.1.4+fork.86.moshinda"
versionCode 87
versionName "1.1.4+fork.87.moshinda"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "kab", "ko-rKR", "nl-rNL", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
}

View File

@@ -15,7 +15,7 @@
<application
android:name=".MastodonApp"
android:allowBackup="true"
android:label="@string/app_name"
android:label="@string/mo_app_name"
android:supportsRtl="true"
android:localeConfig="@xml/locales_config"
android:icon="@mipmap/ic_launcher"

View File

@@ -33,6 +33,7 @@ public class GlobalUserPreferences{
public static boolean relocatePublishButton;
public static boolean reduceMotion;
public static boolean keepOnlyLatestNotification;
public static boolean enableFabAutoHide;
public static String publishButtonText;
public static ThemePreference theme;
public static ColorPreference color;
@@ -72,6 +73,7 @@ public class GlobalUserPreferences{
enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", true);
reduceMotion=prefs.getBoolean("reduceMotion", false);
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
enableFabAutoHide =prefs.getBoolean("enableFabAutoHide", true);
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
recentLanguages=fromJson(prefs.getString("recentLanguages", "{}"), recentLanguagesType, new HashMap<>());
recentEmojis=fromJson(prefs.getString("recentEmojis", "{}"), recentEmojisType, new HashMap<>());
@@ -108,6 +110,7 @@ public class GlobalUserPreferences{
.putBoolean("enableDeleteNotifications", enableDeleteNotifications)
.putBoolean("reduceMotion", reduceMotion)
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
.putBoolean("enableFabAutoHide", enableFabAutoHide)
.putString("publishButtonText", publishButtonText)
.putInt("theme", theme.ordinal())
.putString("color", color.name())

View File

@@ -40,12 +40,13 @@ public class MainActivity extends FragmentStackActivity{
AccountSession session;
Bundle args=new Bundle();
Intent intent=getIntent();
if(intent.getBooleanExtra("fromNotification", false)){
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(!intent.hasExtra("notification"))
args.putString("tab", "notifications");
if(!hasNotification) args.putString("tab", "notifications");
}catch(IllegalStateException x){
session=AccountSessionManager.getInstance().getLastActiveAccount();
}
@@ -55,13 +56,13 @@ public class MainActivity extends FragmentStackActivity{
args.putString("account", session.getID());
Fragment fragment=session.activated ? new HomeFragment() : new AccountActivationFragment();
fragment.setArguments(args);
showFragmentClearingBackStack(fragment);
if(intent.getBooleanExtra("fromNotification", false) && intent.hasExtra("notification")){
if(fromNotification && hasNotification){
Notification notification=Parcels.unwrap(intent.getParcelableExtra("notification"));
showFragmentForNotification(notification, session.getID());
}else if(intent.getBooleanExtra("compose", false)){
} else if (intent.getBooleanExtra("compose", false)){
showCompose();
}else{
} else {
showFragmentClearingBackStack(fragment);
maybeRequestNotificationsPermission();
}
}
@@ -140,4 +141,30 @@ public class MainActivity extends FragmentStackActivity{
requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 100);
}
}
/**
* when opening app through a notification: if (thread) fragment "can go back", clear back stack
* and show home fragment. upstream's implementation doesn't require this as it opens home first
* and then immediately switches to the notification's ThreadFragment. this causes a black
* screen in megalodon, for some reason, so i'm working around this that way.
*/
@Override
public void onBackPressed() {
Fragment currentFragment = getFragmentManager().findFragmentById(
(fragmentContainers.get(fragmentContainers.size() - 1)).getId()
);
Bundle currentArgs = currentFragment.getArguments();
if (this.fragmentContainers.size() == 1
&& currentArgs.getBoolean("_can_go_back", false)
&& currentArgs.containsKey("account")) {
Bundle args = new Bundle();
args.putString("account", currentArgs.getString("account"));
args.putString("tab", "notifications");
Fragment fragment=new HomeFragment();
fragment.setArguments(args);
showFragmentClearingBackStack(fragment);
} else {
super.onBackPressed();
}
}
}

View File

@@ -37,6 +37,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
private static final String TAG="PushNotificationReceive";
public static final int NOTIFICATION_ID=178;
private static final int SUMMARY_ID = 791;
private static int notificationId = 0;
@Override
@@ -98,6 +99,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
Account self=AccountSessionManager.getInstance().getAccount(accountID).self;
String accountName="@"+self.username+"@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
Notification.Builder builder;
Notification.Builder summaryNotification;
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
boolean hasGroup=false;
List<NotificationChannelGroup> channelGroups=nm.getNotificationChannelGroups();
@@ -120,10 +122,14 @@ public class PushNotificationReceiver extends BroadcastReceiver{
nm.createNotificationChannels(channels);
}
builder=new Notification.Builder(context, accountID+"_"+pn.notificationType);
// summaryNotification=new Notification.Builder(context, accountID);
}else{
builder=new Notification.Builder(context)
.setPriority(Notification.PRIORITY_DEFAULT)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
summaryNotification=new Notification.Builder(context)
.setPriority(Notification.PRIORITY_DEFAULT)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
}
Drawable avatar=ImageCache.getInstance(context).get(new UrlImageLoaderRequest(pn.icon, V.dp(50), V.dp(50)));
Intent contentIntent=new Intent(context, MainActivity.class);
@@ -134,14 +140,18 @@ public class PushNotificationReceiver extends BroadcastReceiver{
if(notification!=null){
contentIntent.putExtra("notification", Parcels.wrap(notification));
}
builder.setContentTitle(pn.title)
.setContentText(pn.body)
.setStyle(new Notification.BigTextStyle().bigText(pn.body))
.setContentTitle(pn.title)
.setStyle(new Notification.InboxStyle()
.addLine(pn.body))
.setContentIntent(PendingIntent.getActivity(context, notificationId, contentIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT))
.setWhen(notification==null ? System.currentTimeMillis() : notification.createdAt.toEpochMilli())
.setShowWhen(true)
.setCategory(Notification.CATEGORY_SOCIAL)
.setAutoCancel(true)
.setGroup(accountID)
.setColor(context.getColor(R.color.shortcut_icon_background));
if(!GlobalUserPreferences.uniformNotificationIcon){
switch (pn.notificationType) {
@@ -162,6 +172,9 @@ public class PushNotificationReceiver extends BroadcastReceiver{
if(AccountSessionManager.getInstance().getLoggedInAccounts().size()>1){
builder.setSubText(accountName);
}
nm.notify(accountID, GlobalUserPreferences.keepOnlyLatestNotification ? NOTIFICATION_ID : notificationId++, builder.build());
notificationId++;
nm.notify(accountID, GlobalUserPreferences.keepOnlyLatestNotification ? NOTIFICATION_ID : notificationId, builder.build());
}
}

View File

@@ -9,7 +9,7 @@ public class RegisterForPushNotifications extends MastodonAPIRequest<PushSubscri
Request r=new Request();
r.subscription.endpoint="https://app.joinmastodon.org/relay-to/fcm/"+deviceToken+"/"+accountID;
r.data.alerts=alerts;
r.data.policy=policy;
r.policy=policy;
r.subscription.keys.p256dh=encryptionKey;
r.subscription.keys.auth=authKey;
setRequestBody(r);
@@ -18,6 +18,7 @@ public class RegisterForPushNotifications extends MastodonAPIRequest<PushSubscri
private static class Request{
public Subscription subscription=new Subscription();
public Data data=new Data();
public PushSubscription.Policy policy;
private static class Keys{
public String p256dh;
@@ -31,7 +32,6 @@ public class RegisterForPushNotifications extends MastodonAPIRequest<PushSubscri
private static class Data{
public PushSubscription.Alerts alerts;
public PushSubscription.Policy policy;
}
}
}

View File

@@ -3,23 +3,36 @@ package org.joinmastodon.android.api.requests.notifications;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.PushSubscription;
import java.io.IOException;
import okhttp3.Response;
public class UpdatePushSettings extends MastodonAPIRequest<PushSubscription>{
private final PushSubscription.Policy policy;
public UpdatePushSettings(PushSubscription.Alerts alerts, PushSubscription.Policy policy){
super(HttpMethod.PUT, "/push/subscription", PushSubscription.class);
setRequestBody(new Request(alerts, policy));
this.policy=policy;
}
@Override
public void validateAndPostprocessResponse(PushSubscription respObj, Response httpResponse) throws IOException{
super.validateAndPostprocessResponse(respObj, httpResponse);
respObj.policy=policy;
}
private static class Request{
public Data data=new Data();
public PushSubscription.Policy policy;
public Request(PushSubscription.Alerts alerts, PushSubscription.Policy policy){
this.data.alerts=alerts;
this.data.policy=policy;
this.policy=policy;
}
private static class Data{
public PushSubscription.Alerts alerts;
public PushSubscription.Policy policy;
}
}
}

View File

@@ -9,6 +9,10 @@ import org.joinmastodon.android.model.Hashtag;
import java.util.List;
public class GetFollowedHashtags extends HeaderPaginationRequest<Hashtag> {
public GetFollowedHashtags() {
this(null, null, -1, null);
}
public GetFollowedHashtags(String maxID, String minID, int limit, String sinceID){
super(HttpMethod.GET, "/followed_tags", new TypeToken<>(){});
if(maxID!=null)

View File

@@ -3,6 +3,10 @@ package org.joinmastodon.android.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.TranslateAnimation;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
@@ -67,6 +71,7 @@ public class AccountTimelineFragment extends StatusListFragment{
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
fab = ((ProfileFragment) getParentFragment()).getFab();
}
@Override

View File

@@ -16,6 +16,8 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.animation.TranslateAnimation;
import android.widget.ImageButton;
import android.widget.Toolbar;
import org.joinmastodon.android.E;
@@ -71,6 +73,8 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
protected DisplayItemsAdapter adapter;
protected String accountID;
protected PhotoViewer currentPhotoViewer;
protected ImageButton fab;
protected int scrollDiff = 0;
protected HashMap<String, Account> knownAccounts=new HashMap<>();
protected HashMap<String, Relationship> relationships=new HashMap<>();
protected Rect tmpRect=new Rect();
@@ -273,11 +277,46 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
fab=view.findViewById(R.id.fab);
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
if(currentPhotoViewer!=null)
currentPhotoViewer.offsetView(-dx, -dy);
if (fab!=null && GlobalUserPreferences.enableFabAutoHide) {
if(dy > 0){
scrollDiff = 0;
}
if (dy > 0 && fab.getVisibility() == View.VISIBLE) {
TranslateAnimation animate = new TranslateAnimation(
0,
0,
0,
fab.getHeight() * 2);
animate.setDuration(300);
animate.setFillAfter(true);
fab.startAnimation(animate);
fab.setVisibility(View.INVISIBLE);
scrollDiff = 0;
} else if (dy < 0 && fab.getVisibility() != View.VISIBLE) {
if (scrollDiff > 800) {
fab.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0,
0,
fab.getHeight() * 2,
0);
animate.setDuration(300);
animate.setFillAfter(true);
fab.startAnimation(animate);
scrollDiff = 0;
} else {
scrollDiff += Math.abs(dy);
}
}
}
}
});
list.addItemDecoration(new StatusListItemDecoration());

View File

@@ -676,6 +676,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
replyText.setOnClickListener(v->{
scrollView.smoothScrollTo(0, 0);
});
replyText.setOnClickListener(v->{
scrollView.smoothScrollTo(0, 0);
});
ArrayList<String> mentions=new ArrayList<>();
String ownID=AccountSessionManager.getInstance().getAccount(accountID).self.id;
@@ -944,8 +948,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
&& statusVisibility != StatusPrivacy.DIRECT
&& !attachments.stream().allMatch(attachment -> attachment.description != null && !attachment.description.isBlank())) {
new M3AlertDialogBuilder(getActivity())
.setTitle(R.string.sk_no_image_desc_title)
.setMessage(R.string.sk_no_image_desc)
.setTitle(R.string.mo_no_image_desc_title)
.setMessage(R.string.mo_no_image_desc)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.publish, (dialog, i)-> publish())
.show();

View File

@@ -0,0 +1,37 @@
package org.joinmastodon.android.fragments;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import org.joinmastodon.android.R;
import org.joinmastodon.android.ui.utils.UiUtils;
import me.grishka.appkit.Nav;
public abstract class FabStatusListFragment extends StatusListFragment {
protected ImageButton fab;
public FabStatusListFragment() {
setListLayoutId(R.layout.recycler_fragment_with_fab);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fab = view.findViewById(R.id.fab);
fab.setOnClickListener(this::onFabClick);
fab.setOnLongClickListener(this::onFabLongClick);
}
protected void onFabClick(View v){
Bundle args=new Bundle();
args.putString("account", accountID);
Nav.go(getActivity(), ComposeFragment.class, args);
}
protected boolean onFabLongClick(View v) {
return UiUtils.pickAccountForCompose(getActivity(), accountID);
}
}

View File

@@ -16,7 +16,6 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.joinmastodon.android.PushNotificationReceiver;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
@@ -42,7 +41,11 @@ import me.grishka.appkit.views.FragmentRootLinearLayout;
public class HomeFragment extends AppKitFragment implements OnBackPressedListener{
private FragmentRootLinearLayout content;
private HomeTimelineFragment homeTimelineFragment;
private HomeTabFragment homeTabFragment;
// private HomeTimelineFragment homeTimelineFragment;
private NotificationsFragment notificationsFragment;
private DiscoverFragment searchFragment;
private ProfileFragment profileFragment;
@@ -58,7 +61,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
accountID=getArguments().getString("account");
setTitle(R.string.sk_app_name);
setTitle(R.string.mo_app_name);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
setRetainInstance(true);
@@ -66,8 +69,13 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
if(savedInstanceState==null){
Bundle args=new Bundle();
args.putString("account", accountID);
homeTimelineFragment=new HomeTimelineFragment();
homeTimelineFragment.setArguments(args);
homeTabFragment=new HomeTabFragment();
homeTabFragment.setArguments(args);
// homeTimelineFragment=new HomeTimelineFragment();
// homeTimelineFragment.setArguments(args);
args=new Bundle(args);
args.putBoolean("noAutoLoad", true);
searchFragment=new DiscoverFragment();
@@ -111,12 +119,19 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
if(savedInstanceState==null){
getChildFragmentManager().beginTransaction()
.add(R.id.fragment_wrap, homeTimelineFragment)
.add(R.id.fragment_wrap, homeTabFragment)
.add(R.id.fragment_wrap, searchFragment).hide(searchFragment)
.add(R.id.fragment_wrap, notificationsFragment).hide(notificationsFragment)
.add(R.id.fragment_wrap, profileFragment).hide(profileFragment)
.commit();
// getChildFragmentManager().beginTransaction()
// .add(R.id.fragment_wrap, homeTimelineFragment)
// .add(R.id.fragment_wrap, searchFragment).hide(searchFragment)
// .add(R.id.fragment_wrap, notificationsFragment).hide(notificationsFragment)
// .add(R.id.fragment_wrap, profileFragment).hide(profileFragment)
// .commit();
String defaultTab=getArguments().getString("tab");
if("notifications".equals(defaultTab)){
tabBar.selectTab(R.id.tab_notifications);
@@ -137,21 +152,36 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
@Override
public void onViewStateRestored(Bundle savedInstanceState){
super.onViewStateRestored(savedInstanceState);
if(savedInstanceState==null || homeTimelineFragment!=null)
return;
homeTimelineFragment=(HomeTimelineFragment) getChildFragmentManager().getFragment(savedInstanceState, "homeTimelineFragment");
if(savedInstanceState==null) return;
// if(savedInstanceState==null || homeTimelineFragment!=null)
// return;
homeTabFragment=(HomeTabFragment) getChildFragmentManager().getFragment(savedInstanceState, "homeTabFragment");
// homeTimelineFragment=(HomeTimelineFragment) getChildFragmentManager().getFragment(savedInstanceState, "homeTimelineFragment");
searchFragment=(DiscoverFragment) getChildFragmentManager().getFragment(savedInstanceState, "searchFragment");
notificationsFragment=(NotificationsFragment) getChildFragmentManager().getFragment(savedInstanceState, "notificationsFragment");
profileFragment=(ProfileFragment) getChildFragmentManager().getFragment(savedInstanceState, "profileFragment");
currentTab=savedInstanceState.getInt("selectedTab");
Fragment current=fragmentForTab(currentTab);
getChildFragmentManager().beginTransaction()
.hide(homeTimelineFragment)
.hide(homeTabFragment)
.hide(searchFragment)
.hide(notificationsFragment)
.hide(profileFragment)
.show(current)
.commit();
// getChildFragmentManager().beginTransaction()
// .hide(homeTimelineFragment)
// .hide(searchFragment)
// .hide(notificationsFragment)
// .hide(profileFragment)
// .show(current)
// .commit();
maybeTriggerLoading(current);
}
@@ -181,7 +211,11 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
super.onApplyWindowInsets(insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()));
}
WindowInsets topOnlyInsets=insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(), 0, 0);
homeTimelineFragment.onApplyWindowInsets(topOnlyInsets);
homeTabFragment.onApplyWindowInsets(topOnlyInsets);
// homeTimelineFragment.onApplyWindowInsets(topOnlyInsets);
searchFragment.onApplyWindowInsets(topOnlyInsets);
notificationsFragment.onApplyWindowInsets(topOnlyInsets);
profileFragment.onApplyWindowInsets(topOnlyInsets);
@@ -189,7 +223,10 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
private Fragment fragmentForTab(@IdRes int tab){
if(tab==R.id.tab_home){
return homeTimelineFragment;
return homeTabFragment;
// if(tab==R.id.tab_home){
// return homeTimelineFragment;
}else if(tab==R.id.tab_search){
return searchFragment;
}else if(tab==R.id.tab_notifications){
@@ -270,17 +307,24 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
tabBar.selectTab(R.id.tab_home);
onTabSelected(R.id.tab_home);
return true;
} else {
return homeTabFragment.onBackPressed();
}
return false;
}
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putInt("selectedTab", currentTab);
getChildFragmentManager().putFragment(outState, "homeTimelineFragment", homeTimelineFragment);
getChildFragmentManager().putFragment(outState, "searchFragment", searchFragment);
getChildFragmentManager().putFragment(outState, "notificationsFragment", notificationsFragment);
getChildFragmentManager().putFragment(outState, "profileFragment", profileFragment);
if (homeTabFragment.isAdded()) getChildFragmentManager().putFragment(outState, "homeTabFragment", homeTabFragment);
if (searchFragment.isAdded()) getChildFragmentManager().putFragment(outState, "searchFragment", searchFragment);
if (notificationsFragment.isAdded()) getChildFragmentManager().putFragment(outState, "notificationsFragment", notificationsFragment);
if (profileFragment.isAdded()) getChildFragmentManager().putFragment(outState, "profileFragment", profileFragment);
// getChildFragmentManager().putFragment(outState, "homeTimelineFragment", homeTimelineFragment);
// getChildFragmentManager().putFragment(outState, "searchFragment", searchFragment);
// getChildFragmentManager().putFragment(outState, "notificationsFragment", notificationsFragment);
// getChildFragmentManager().putFragment(outState, "profileFragment", profileFragment);
}
}

View File

@@ -0,0 +1,556 @@
package org.joinmastodon.android.fragments;
import static org.joinmastodon.android.GlobalUserPreferences.showFederatedTimeline;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.announcements.GetAnnouncements;
import org.joinmastodon.android.api.requests.lists.GetLists;
import org.joinmastodon.android.api.requests.tags.GetFollowedHashtags;
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
import org.joinmastodon.android.fragments.discover.FederatedTimelineFragment;
import org.joinmastodon.android.fragments.discover.LocalTimelineFragment;
import org.joinmastodon.android.model.Announcement;
import org.joinmastodon.android.model.Hashtag;
import org.joinmastodon.android.model.HeaderPaginationList;
import org.joinmastodon.android.model.ListTimeline;
import org.joinmastodon.android.ui.SimpleViewHolder;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.updater.GithubSelfUpdater;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.fragments.BaseRecyclerFragment;
import me.grishka.appkit.fragments.OnBackPressedListener;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class HomeTabFragment extends MastodonToolbarFragment implements ScrollableToTop, OnBackPressedListener {
private static final int ANNOUNCEMENTS_RESULT = 654;
private String accountID;
private MenuItem announcements;
// private ImageView toolbarLogo;
private Button toolbarShowNewPostsBtn;
private boolean newPostsBtnShown;
private AnimatorSet currentNewPostsAnim;
private ViewPager2 pager;
private final List<Fragment> fragments = new ArrayList<>();
private final List<FrameLayout> tabViews = new ArrayList<>();
private View switcher;
private FrameLayout toolbarFrame;
private ImageView timelineIcon;
private ImageView collapsedChevron;
private TextView timelineTitle;
private PopupMenu switcherPopup;
private final Map<Integer, ListTimeline> listItems = new HashMap<>();
private final Map<Integer, Hashtag> hashtagsItems = new HashMap<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
accountID = getArguments().getString("account");
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
setHasOptionsMenu(true);
}
@Override
public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
FrameLayout view = new FrameLayout(getContext());
pager = new ViewPager2(getContext());
toolbarFrame = (FrameLayout) LayoutInflater.from(getContext()).inflate(R.layout.home_toolbar, getToolbar(), false);
if (fragments.size() == 0) {
Bundle args = new Bundle();
args.putString("account", accountID);
args.putBoolean("__is_tab", true);
fragments.add(new HomeTimelineFragment());
fragments.add(new LocalTimelineFragment());
if (showFederatedTimeline) fragments.add(new FederatedTimelineFragment());
args=new Bundle(args);
args.putBoolean("onlyPosts", true);
NotificationsListFragment postsFragment=new NotificationsListFragment();
postsFragment.setArguments(args);
fragments.add(postsFragment);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
for (int i = 0; i < fragments.size(); i++) {
fragments.get(i).setArguments(args);
FrameLayout tabView = new FrameLayout(getActivity());
tabView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
tabView.setVisibility(View.GONE);
tabView.setId(i + 1);
transaction.add(i + 1, fragments.get(i));
view.addView(tabView);
tabViews.add(tabView);
}
transaction.commit();
}
view.addView(pager, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return view;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
timelineIcon = toolbarFrame.findViewById(R.id.timeline_icon);
timelineTitle = toolbarFrame.findViewById(R.id.timeline_title);
collapsedChevron = toolbarFrame.findViewById(R.id.collapsed_chevron);
switcher = toolbarFrame.findViewById(R.id.switcher_btn);
switcherPopup = new PopupMenu(getContext(), switcher);
switcherPopup.inflate(R.menu.home_switcher);
switcherPopup.setOnMenuItemClickListener(this::onSwitcherItemSelected);
UiUtils.enablePopupMenuIcons(getContext(), switcherPopup);
switcher.setOnClickListener(v->{
updateSwitcherMenu();
switcherPopup.show();
});
View.OnTouchListener listener = switcherPopup.getDragToOpenListener();
switcher.setOnTouchListener((v, m)-> {
updateSwitcherMenu();
return listener.onTouch(v, m);
});
UiUtils.reduceSwipeSensitivity(pager);
pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe);
pager.setAdapter(new HomePagerAdapter());
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback(){
@Override
public void onPageSelected(int position){
updateSwitcherIcon(position);
if (position==0) return;
hideNewPostsButton();
if (fragments.get(position) instanceof BaseRecyclerFragment<?> page){
if(!page.loaded && !page.isDataLoading()) page.loadData();
}
}
});
if (!GlobalUserPreferences.reduceMotion) {
pager.setPageTransformer((v, pos) -> {
if (tabViews.get(pager.getCurrentItem()) != v) return;
float scaleFactor = Math.max(0.85f, 1 - Math.abs(pos) * 0.06f);
switcher.setScaleY(scaleFactor);
switcher.setScaleX(scaleFactor);
switcher.setAlpha(Math.max(0.65f, 1 - Math.abs(pos)));
});
}
updateToolbarLogo();
if(GithubSelfUpdater.needSelfUpdating()){
E.register(this);
updateUpdateState(GithubSelfUpdater.getInstance().getState());
}
new GetLists().setCallback(new Callback<>() {
@Override
public void onSuccess(List<ListTimeline> lists) {
addItemsToMap(lists, listItems);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getContext());
}
}).exec(accountID);
new GetFollowedHashtags().setCallback(new Callback<>() {
@Override
public void onSuccess(HeaderPaginationList<Hashtag> hashtags) {
addItemsToMap(hashtags, hashtagsItems);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getContext());
}
}).exec(accountID);
}
public void updateToolbarLogo(){
Toolbar toolbar = getToolbar();
ViewParent parentView = toolbarFrame.getParent();
if (parentView == toolbar) return;
if (parentView instanceof Toolbar parentToolbar) parentToolbar.removeView(toolbarFrame);
toolbar.addView(toolbarFrame, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
toolbar.setOnClickListener(v->scrollToTop());
toolbar.setNavigationContentDescription(R.string.back);
toolbar.setContentInsetsAbsolute(0, toolbar.getContentInsetRight());
updateSwitcherIcon(pager.getCurrentItem());
// toolbarLogo=new ImageView(getActivity());
// toolbarLogo.setScaleType(ImageView.ScaleType.CENTER);
// toolbarLogo.setImageResource(R.drawable.logo);
// toolbarLogo.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary)));
toolbarShowNewPostsBtn=toolbarFrame.findViewById(R.id.show_new_posts_btn);
toolbarShowNewPostsBtn.setCompoundDrawableTintList(toolbarShowNewPostsBtn.getTextColors());
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N) UiUtils.fixCompoundDrawableTintOnAndroid6(toolbarShowNewPostsBtn);
toolbarShowNewPostsBtn.setOnClickListener(this::onNewPostsBtnClick);
if(newPostsBtnShown){
toolbarShowNewPostsBtn.setVisibility(View.VISIBLE);
collapsedChevron.setVisibility(View.VISIBLE);
collapsedChevron.setAlpha(1f);
timelineTitle.setVisibility(View.GONE);
timelineTitle.setAlpha(0f);
}else{
toolbarShowNewPostsBtn.setVisibility(View.INVISIBLE);
toolbarShowNewPostsBtn.setAlpha(0f);
collapsedChevron.setVisibility(View.GONE);
collapsedChevron.setAlpha(0f);
toolbarShowNewPostsBtn.setScaleX(.8f);
toolbarShowNewPostsBtn.setScaleY(.8f);
timelineTitle.setVisibility(View.VISIBLE);
}
ViewTreeObserver vto = toolbar.getViewTreeObserver();
if (vto.isAlive()) {
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Toolbar t = getToolbar();
if (t == null) return;
int toolbarWidth = t.getWidth();
if (toolbarWidth == 0) return;
t.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int toolbarFrameWidth = toolbarFrame.getWidth();
int padding = toolbarWidth - toolbarFrameWidth;
// toolbar frame goes from screen edge to beginning of right-aligned option buttons.
// centering button by applying the same space on the left
((FrameLayout) toolbarShowNewPostsBtn.getParent()).setPaddingRelative(padding, 0, 0, 0);
toolbarShowNewPostsBtn.setMaxWidth(toolbarWidth - padding * 2);
switcher.setPivotX(V.dp(28)); // padding + half of icon
switcher.setPivotY(switcher.getHeight() / 2f);
timelineTitle.setPivotX(timelineTitle.getWidth() - V.dp(8));
timelineTitle.setPivotY(timelineTitle.getHeight() / 2f);
}
});
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.home, menu);
announcements = menu.findItem(R.id.announcements);
new GetAnnouncements(false).setCallback(new Callback<>() {
@Override
public void onSuccess(List<Announcement> result) {
boolean hasUnread = result.stream().anyMatch(a -> !a.read);
announcements.setIcon(hasUnread ? R.drawable.ic_announcements_24_badged : R.drawable.ic_fluent_megaphone_24_regular);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getActivity());
}
}).exec(accountID);
}
private <T> void addItemsToMap(List<T> addItems, Map<Integer, T> items) {
if (addItems.size() == 0) return;
for (int i = 0; i < addItems.size(); i++) items.put(View.generateViewId(), addItems.get(i));
updateSwitcherMenu();
}
private void updateSwitcherMenu() {
Context context = getContext();
switcherPopup.getMenu().findItem(R.id.federated).setVisible(showFederatedTimeline);
if (!listItems.isEmpty()) {
MenuItem listsItem = switcherPopup.getMenu().findItem(R.id.lists);
listsItem.setVisible(true);
SubMenu listsMenu = listsItem.getSubMenu();
listsMenu.clear();
listItems.forEach((id, list) -> {
MenuItem item = listsMenu.add(Menu.NONE, id, Menu.NONE, list.title);
item.setIcon(R.drawable.ic_fluent_people_list_24_regular);
UiUtils.insetPopupMenuIcon(context, item);
});
}
if (!hashtagsItems.isEmpty()) {
MenuItem hashtagsItem = switcherPopup.getMenu().findItem(R.id.followed_hashtags);
hashtagsItem.setVisible(true);
SubMenu hashtagsMenu = hashtagsItem.getSubMenu();
hashtagsMenu.clear();
hashtagsItems.forEach((id, hashtag) -> {
MenuItem item = hashtagsMenu.add(Menu.NONE, id, Menu.NONE, hashtag.name);
item.setIcon(R.drawable.ic_fluent_number_symbol_24_regular);
UiUtils.insetPopupMenuIcon(context, item);
});
}
}
private boolean onSwitcherItemSelected(MenuItem item) {
int id = item.getItemId();
ListTimeline list;
Hashtag hashtag;
if (id == R.id.home) {
navigateTo(0);
return true;
} else if (id == R.id.local) {
navigateTo(1);
return true;
} else if (id == R.id.federated) {
navigateTo(2);
return true;
} else if (id == R.id.post_notifications) {
navigateTo(showFederatedTimeline ? 3 : 2);
} else if ((list = listItems.get(id)) != null) {
Bundle args = new Bundle();
args.putString("account", accountID);
args.putString("listID", list.id);
args.putString("listTitle", list.title);
args.putInt("repliesPolicy", list.repliesPolicy.ordinal());
Nav.go(getActivity(), ListTimelineFragment.class, args);
} else if ((hashtag = hashtagsItems.get(id)) != null) {
UiUtils.openHashtagTimeline(getActivity(), accountID, hashtag.name, hashtag.following);
}
return false;
}
private void navigateTo(int i) {
navigateTo(i, !GlobalUserPreferences.reduceMotion);
}
private void navigateTo(int i, boolean smooth) {
pager.setCurrentItem(i, smooth);
updateSwitcherIcon(i);
}
private void updateSwitcherIcon(int i) {
// todo: refactor when implementing pinned tabs
if (i == (showFederatedTimeline ? 3 : 2)) {
timelineIcon.setImageResource(R.drawable.ic_fluent_alert_24_regular);
timelineTitle.setText(R.string.sk_notify_posts);
} else {
timelineIcon.setImageResource(switch (i) {
default -> R.drawable.ic_fluent_home_24_regular;
case 1 -> R.drawable.ic_fluent_people_community_24_regular;
case 2 -> R.drawable.ic_fluent_earth_24_regular;
});
timelineTitle.setText(switch (i) {
default -> R.string.sk_timeline_home;
case 1 -> R.string.sk_timeline_local;
case 2 -> R.string.sk_timeline_federated;
});
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
Bundle args=new Bundle();
args.putString("account", accountID);
if (item.getItemId() == R.id.settings) Nav.go(getActivity(), SettingsFragment.class, args);
if (item.getItemId() == R.id.announcements) {
Nav.goForResult(getActivity(), AnnouncementsFragment.class, args, ANNOUNCEMENTS_RESULT, this);
}
return true;
}
@Override
public void scrollToTop(){
((ScrollableToTop) fragments.get(pager.getCurrentItem())).scrollToTop();
}
public void hideNewPostsButton(){
if(!newPostsBtnShown)
return;
newPostsBtnShown=false;
if(currentNewPostsAnim!=null){
currentNewPostsAnim.cancel();
}
timelineTitle.setVisibility(View.VISIBLE);
AnimatorSet set=new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(timelineTitle, View.ALPHA, 1f),
ObjectAnimator.ofFloat(timelineTitle, View.SCALE_X, 1f),
ObjectAnimator.ofFloat(timelineTitle, View.SCALE_Y, 1f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.ALPHA, 0f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_X, .8f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_Y, .8f),
ObjectAnimator.ofFloat(collapsedChevron, View.ALPHA, 0f)
);
set.setDuration(GlobalUserPreferences.reduceMotion ? 0 : 300);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
toolbarShowNewPostsBtn.setVisibility(View.INVISIBLE);
collapsedChevron.setVisibility(View.GONE);
currentNewPostsAnim=null;
}
});
currentNewPostsAnim=set;
set.start();
}
public void showNewPostsButton(){
if(newPostsBtnShown || pager == null || pager.getCurrentItem() != 0)
return;
newPostsBtnShown=true;
if(currentNewPostsAnim!=null){
currentNewPostsAnim.cancel();
}
toolbarShowNewPostsBtn.setVisibility(View.VISIBLE);
collapsedChevron.setVisibility(View.VISIBLE);
AnimatorSet set=new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(timelineTitle, View.ALPHA, 0f),
ObjectAnimator.ofFloat(timelineTitle, View.SCALE_X, .8f),
ObjectAnimator.ofFloat(timelineTitle, View.SCALE_Y, .8f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.ALPHA, 1f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_X, 1f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_Y, 1f),
ObjectAnimator.ofFloat(collapsedChevron, View.ALPHA, 1f)
);
set.setDuration(GlobalUserPreferences.reduceMotion ? 0 : 300);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
timelineTitle.setVisibility(View.GONE);
currentNewPostsAnim=null;
}
});
currentNewPostsAnim=set;
set.start();
}
public boolean isNewPostsBtnShown() {
return newPostsBtnShown;
}
private void onNewPostsBtnClick(View view) {
if(newPostsBtnShown){
hideNewPostsButton();
scrollToTop();
}
}
@Override
public void onFragmentResult(int reqCode, boolean noMoreUnread, Bundle result){
if (reqCode == ANNOUNCEMENTS_RESULT && noMoreUnread) {
announcements.setIcon(R.drawable.ic_fluent_megaphone_24_regular);
}
}
private void updateUpdateState(GithubSelfUpdater.UpdateState state){
if(state!=GithubSelfUpdater.UpdateState.NO_UPDATE && state!=GithubSelfUpdater.UpdateState.CHECKING)
getToolbar().getMenu().findItem(R.id.settings).setIcon(R.drawable.ic_settings_24_badged);
}
@Subscribe
public void onSelfUpdateStateChanged(SelfUpdateStateChangedEvent ev){
updateUpdateState(ev.state);
}
@Override
public boolean onBackPressed(){
if(pager.getCurrentItem() > 0){
navigateTo(0);
return true;
}
return false;
}
@Override
public void onDestroyView(){
super.onDestroyView();
if(GithubSelfUpdater.needSelfUpdating()){
E.unregister(this);
}
}
@Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState == null) return;
navigateTo(savedInstanceState.getInt("selectedTab"), false);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("selectedTab", pager.getCurrentItem());
}
private class HomePagerAdapter extends RecyclerView.Adapter<SimpleViewHolder> {
@NonNull
@Override
public SimpleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
FrameLayout tabView = tabViews.get(viewType % getItemCount());
((ViewGroup)tabView.getParent()).removeView(tabView);
tabView.setVisibility(View.VISIBLE);
return new SimpleViewHolder(tabView);
}
@Override
public void onBindViewHolder(@NonNull SimpleViewHolder holder, int position){}
@Override
public int getItemCount(){
return fragments.size();
}
@Override
public int getItemViewType(int position){
return position;
}
}
}

View File

@@ -1,47 +1,24 @@
package org.joinmastodon.android.fragments;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.E;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.announcements.GetAnnouncements;
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.model.Announcement;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.updater.GithubSelfUpdater;
import org.joinmastodon.android.utils.StatusFilterPredicate;
import java.util.Collections;
@@ -50,33 +27,20 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.api.SimpleCallback;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class HomeTimelineFragment extends StatusListFragment{
private static final int ANNOUNCEMENTS_RESULT = 654;
private ImageButton fab;
private ImageView toolbarLogo;
private Button toolbarShowNewPostsBtn;
private boolean newPostsBtnShown;
private AnimatorSet currentNewPostsAnim;
private MenuItem announcements;
public class HomeTimelineFragment extends FabStatusListFragment {
private HomeTabFragment parent;
private String maxID;
public HomeTimelineFragment(){
setListLayoutId(R.layout.recycler_fragment_with_fab);
}
private String lastSavedMarkerID;
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
setHasOptionsMenu(true);
if (getParentFragment() instanceof HomeTabFragment home) parent = home;
loadData();
}
@@ -108,67 +72,15 @@ public class HomeTimelineFragment extends StatusListFragment{
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
fab=view.findViewById(R.id.fab);
fab.setOnClickListener(this::onFabClick);
fab.setOnLongClickListener(v->UiUtils.pickAccountForCompose(getActivity(), accountID));
updateToolbarLogo();
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
if(newPostsBtnShown && list.getChildAdapterPosition(list.getChildAt(0))<=getMainAdapterOffset()){
hideNewPostsButton();
if(parent != null && parent.isNewPostsBtnShown() && list.getChildAdapterPosition(list.getChildAt(0))<=getMainAdapterOffset()){
parent.hideNewPostsButton();
}
}
});
if(GithubSelfUpdater.needSelfUpdating()){
E.register(this);
updateUpdateState(GithubSelfUpdater.getInstance().getState());
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.home, menu);
announcements = menu.findItem(R.id.announcements);
new GetAnnouncements(false).setCallback(new Callback<>() {
@Override
public void onSuccess(List<Announcement> result) {
boolean hasUnread = result.stream().anyMatch(a -> !a.read);
announcements.setIcon(hasUnread ? R.drawable.ic_announcements_24_badged : R.drawable.ic_fluent_megaphone_24_regular);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getActivity());
}
}).exec(accountID);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
Bundle args=new Bundle();
args.putString("account", accountID);
if (item.getItemId() == R.id.settings) Nav.go(getActivity(), SettingsFragment.class, args);
if (item.getItemId() == R.id.announcements) {
Nav.goForResult(getActivity(), AnnouncementsFragment.class, args, ANNOUNCEMENTS_RESULT, this);
}
return true;
}
@Override
public void onFragmentResult(int reqCode, boolean noMoreUnread, Bundle result){
if (reqCode == ANNOUNCEMENTS_RESULT && noMoreUnread) {
announcements.setIcon(R.drawable.ic_fluent_megaphone_24_regular);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
updateToolbarLogo();
}
@Override
@@ -183,14 +95,31 @@ public class HomeTimelineFragment extends StatusListFragment{
}
}
public void onStatusCreated(StatusCreatedEvent ev){
prependItems(Collections.singletonList(ev.status), true);
@Override
protected void onHidden(){
super.onHidden();
// if(!data.isEmpty()){
// String topPostID=displayItems.get(list.getChildAdapterPosition(list.getChildAt(0))-getMainAdapterOffset()).parentID;
// if(!topPostID.equals(lastSavedMarkerID)){
// lastSavedMarkerID=topPostID;
// new SaveMarkers(topPostID, null)
// .setCallback(new Callback<>(){
// @Override
// public void onSuccess(SaveMarkers.Response result){
// }
//
// @Override
// public void onError(ErrorResponse error){
// lastSavedMarkerID=null;
// }
// })
// .exec(accountID);
// }
// }
}
private void onFabClick(View v){
Bundle args=new Bundle();
args.putString("account", accountID);
Nav.go(getActivity(), ComposeFragment.class, args);
public void onStatusCreated(StatusCreatedEvent ev){
prependItems(Collections.singletonList(ev.status), true);
}
private void loadNewPosts(){
@@ -221,7 +150,7 @@ public class HomeTimelineFragment extends StatusListFragment{
toAdd=toAdd.stream().filter(filterPredicate).collect(Collectors.toList());
if(!toAdd.isEmpty()){
prependItems(toAdd, true);
showNewPostsButton();
if (parent != null) parent.showNewPostsButton();
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(toAdd, false);
}
}
@@ -337,132 +266,10 @@ public class HomeTimelineFragment extends StatusListFragment{
currentRequest=null;
dataLoading=false;
}
if (parent != null) parent.hideNewPostsButton();
super.onRefresh();
}
private void updateToolbarLogo(){
toolbarLogo=new ImageView(getActivity());
toolbarLogo.setScaleType(ImageView.ScaleType.CENTER);
toolbarLogo.setImageResource(R.drawable.logo);
toolbarLogo.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary)));
// toolbarLogo =new TextView(getActivity());
// toolbarLogo.setText(getString(R.string.app_name).toLowerCase(Locale.getDefault()));
// toolbarLogo.setTextAppearance(R.style.app_title);
toolbarShowNewPostsBtn=new Button(getActivity());
toolbarShowNewPostsBtn.setTextAppearance(R.style.m3_title_medium);
toolbarShowNewPostsBtn.setTextColor(0xffffffff);
toolbarShowNewPostsBtn.setStateListAnimator(null);
toolbarShowNewPostsBtn.setBackgroundResource(R.drawable.bg_button_new_posts);
toolbarShowNewPostsBtn.setText(R.string.see_new_posts);
toolbarShowNewPostsBtn.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_fluent_arrow_up_16_filled, 0, 0, 0);
toolbarShowNewPostsBtn.setCompoundDrawableTintList(toolbarShowNewPostsBtn.getTextColors());
toolbarShowNewPostsBtn.setCompoundDrawablePadding(V.dp(8));
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
UiUtils.fixCompoundDrawableTintOnAndroid6(toolbarShowNewPostsBtn);
toolbarShowNewPostsBtn.setOnClickListener(this::onNewPostsBtnClick);
if(newPostsBtnShown){
toolbarShowNewPostsBtn.setVisibility(View.VISIBLE);
toolbarLogo.setVisibility(View.INVISIBLE);
toolbarLogo.setAlpha(0f);
}else{
toolbarShowNewPostsBtn.setVisibility(View.INVISIBLE);
toolbarShowNewPostsBtn.setAlpha(0f);
toolbarShowNewPostsBtn.setScaleX(.8f);
toolbarShowNewPostsBtn.setScaleY(.8f);
toolbarLogo.setVisibility(View.VISIBLE);
}
FrameLayout logoWrap=new FrameLayout(getActivity());
logoWrap.addView(toolbarLogo, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
logoWrap.addView(toolbarShowNewPostsBtn, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, V.dp(32), Gravity.CENTER));
Toolbar toolbar=getToolbar();
toolbar.addView(logoWrap, new Toolbar.LayoutParams(Gravity.CENTER));
}
private void showNewPostsButton(){
if(newPostsBtnShown)
return;
newPostsBtnShown=true;
if(currentNewPostsAnim!=null){
currentNewPostsAnim.cancel();
}
toolbarShowNewPostsBtn.setVisibility(View.VISIBLE);
AnimatorSet set=new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(toolbarLogo, View.ALPHA, 0f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.ALPHA, 1f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_X, 1f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_Y, 1f)
);
set.setDuration(300);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
toolbarLogo.setVisibility(View.INVISIBLE);
currentNewPostsAnim=null;
}
});
currentNewPostsAnim=set;
set.start();
}
private void hideNewPostsButton(){
if(!newPostsBtnShown)
return;
newPostsBtnShown=false;
if(currentNewPostsAnim!=null){
currentNewPostsAnim.cancel();
}
toolbarLogo.setVisibility(View.VISIBLE);
AnimatorSet set=new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(toolbarLogo, View.ALPHA, 1f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.ALPHA, 0f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_X, .8f),
ObjectAnimator.ofFloat(toolbarShowNewPostsBtn, View.SCALE_Y, .8f)
);
set.setDuration(300);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
toolbarShowNewPostsBtn.setVisibility(View.INVISIBLE);
currentNewPostsAnim=null;
}
});
currentNewPostsAnim=set;
set.start();
}
private void onNewPostsBtnClick(View v){
if(newPostsBtnShown){
hideNewPostsButton();
scrollToTop();
}
}
@Override
public void onDestroyView(){
super.onDestroyView();
if(GithubSelfUpdater.needSelfUpdating()){
E.unregister(this);
}
}
private void updateUpdateState(GithubSelfUpdater.UpdateState state){
if(state!=GithubSelfUpdater.UpdateState.NO_UPDATE && state!=GithubSelfUpdater.UpdateState.CHECKING)
getToolbar().getMenu().findItem(R.id.settings).setIcon(R.drawable.ic_settings_24_badged);
}
@Subscribe
public void onSelfUpdateStateChanged(SelfUpdateStateChangedEvent ev){
updateUpdateState(ev.state);
}
@Override
protected boolean shouldRemoveAccountPostsWhenUnfollowing(){
return true;

View File

@@ -102,6 +102,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
tabLayout=view.findViewById(R.id.tabbar);
pager=view.findViewById(R.id.pager);
UiUtils.reduceSwipeSensitivity(pager);
tabViews=new FrameLayout[3];
for(int i=0;i<tabViews.length;i++){

View File

@@ -157,7 +157,7 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
@Override
public void onError(ErrorResponse result) {
Toast.makeText(getActivity(), getString(R.string.sk_personal_note_update_failed), Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(), getString(R.string.mo_personal_note_update_failed), Toast.LENGTH_LONG).show();
}
}).exec(accountID);
}

View File

@@ -28,6 +28,7 @@ import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.inputmethod.InputMethodManager;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
@@ -133,10 +134,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private Uri editNewAvatar, editNewCover;
private String profileAccountID;
private boolean refreshing;
private View fab;
private ImageButton fab;
private WindowInsets childInsets;
private PhotoViewer currentPhotoViewer;
private boolean editModeLoading;
private boolean isScrollingUp = false;
public ProfileFragment(){
super(R.layout.loader_fragment_overlay_toolbar);
@@ -221,13 +223,31 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
noteEdit.setOnFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
fab.setVisibility(View.GONE);
fab.setVisibility(View.INVISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0,
0,
0,
fab.getHeight() * 2);
animate.setDuration(300);
animate.setFillAfter(true);
fab.startAnimation(animate);
noteEditConfirm.setVisibility(View.VISIBLE);
noteEditConfirm.animate()
.alpha(1.0f)
.setDuration(700);
} else {
fab.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0,
0,
fab.getHeight() * 2,
0);
animate.setDuration(300);
animate.setFillAfter(true);
fab.startAnimation(animate);
noteEditConfirm.animate()
.alpha(0.0f)
.setDuration(700);
@@ -270,6 +290,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
tabViews[i]=tabView;
}
UiUtils.reduceSwipeSensitivity(pager);
pager.setOffscreenPageLimit(5);
pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe);
pager.setAdapter(new ProfilePagerAdapter());
@@ -348,7 +369,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
@Override
public void onError(ErrorResponse result) {
Toast.makeText(getActivity(), getString(R.string.sk_personal_note_update_failed), Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(), getString(R.string.mo_personal_note_update_failed), Toast.LENGTH_LONG).show();
}
}).exec(accountID);
}
@@ -620,7 +641,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
return;
inflater.inflate(isOwnProfile ? R.menu.profile_own : R.menu.profile, menu);
if(isOwnProfile){
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.manage_user_lists, R.id.bookmarks, R.id.followed_hashtags, R.id.favorites, R.id.scheduled, R.id.share);
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.scheduled, R.id.bookmarks, R.id.favorites);
}else{
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.bookmarks, R.id.followed_hashtags, R.id.favorites, R.id.scheduled);
}
@@ -762,6 +783,10 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
if (getActivity() != null) notifyButton.setContentDescription(getString(relationship.notifying ? R.string.sk_user_post_notifications_on : R.string.sk_user_post_notifications_off, '@'+account.username));
}
public ImageButton getFab() {
return fab;
}
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
int topBarsH=getToolbar().getHeight()+statusBarHeight;
if(scrollY>avatarBorder.getTop()-topBarsH){

View File

@@ -53,7 +53,6 @@ import org.joinmastodon.android.model.PushSubscription;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.OutlineProviders;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.TextInputFrameLayout;
import org.joinmastodon.android.updater.GithubSelfUpdater;
import org.parceler.Parcels;
@@ -122,6 +121,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
items.add(new SwitchItem(R.string.sk_settings_reduce_motion, R.drawable.ic_fluent_star_emphasis_24_regular, GlobalUserPreferences.reduceMotion, i->{
GlobalUserPreferences.reduceMotion=i.checked;
GlobalUserPreferences.save();
needAppRestart=true;
}));
items.add(new ButtonItem(R.string.sk_settings_color_palette, R.drawable.ic_fluent_color_24_regular, b->{
PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL);
@@ -139,14 +139,14 @@ public class SettingsFragment extends MastodonToolbarFragment{
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.sk_color_palette_nord;
case NORD -> R.string.mo_color_palette_nord;
});
}));
items.add(new ButtonItem(R.string.sk_settings_publish_button_text, R.drawable.ic_fluent_send_24_regular, b-> {
updatePublishText(b);
if (GlobalUserPreferences.relocatePublishButton) {
b.setOnClickListener(l -> {
Toast.makeText(getActivity(), R.string.sk_disable_relocate_publish_button_to_enable_customization,
Toast.makeText(getActivity(), R.string.mo_disable_relocate_publish_button_to_enable_customization,
Toast.LENGTH_LONG).show();
});
} else {
@@ -205,17 +205,22 @@ public class SettingsFragment extends MastodonToolbarFragment{
needAppRestart=true;
}));
// items.add(new SwitchItem(R.string.sk_settings_show_differentiated_notification_icons, R.drawable.ic_ntf_logo, GlobalUserPreferences.showUniformPushNoticationIcons, this::onNotificationStyleChanged));
items.add(new SwitchItem(R.string.sk_disable_dividers, R.drawable.ic_fluent_timeline_24_regular, GlobalUserPreferences.disableDividers, i->{
items.add(new SwitchItem(R.string.mo_disable_dividers, R.drawable.ic_fluent_timeline_24_regular, GlobalUserPreferences.disableDividers, i->{
GlobalUserPreferences.disableDividers=i.checked;
GlobalUserPreferences.save();
needAppRestart=true;
}));
items.add(new SwitchItem(R.string.mo_hide_compose_button_while_scrolling_setting, R.drawable.ic_fluent_edit_24_regular, GlobalUserPreferences.enableFabAutoHide, i->{
GlobalUserPreferences.enableFabAutoHide =i.checked;
GlobalUserPreferences.save();
needAppRestart=true;
}));
// items.add(new SwitchItem(R.string.sk_enable_delete_notifications, R.drawable.ic_fluent_delete_24_regular, GlobalUserPreferences.enableDeleteNotifications, i->{
// GlobalUserPreferences.enableDeleteNotifications=i.checked;
// GlobalUserPreferences.save();
// needAppRestart=true;
// }));
items.add(new SwitchItem(R.string.sk_relocate_publish_button, R.drawable.ic_fluent_arrow_autofit_down_24_regular, GlobalUserPreferences.relocatePublishButton, i->{
items.add(new SwitchItem(R.string.mo_relocate_publish_button, R.drawable.ic_fluent_arrow_autofit_down_24_regular, GlobalUserPreferences.relocatePublishButton, i->{
GlobalUserPreferences.relocatePublishButton=i.checked;
GlobalUserPreferences.save();
}));
@@ -281,7 +286,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
checkForUpdateItem = new TextItem(R.string.sk_check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
items.add(checkForUpdateItem);
}
items.add(new TextItem(R.string.sk_settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/LucasGGamerM/moshidon"), R.drawable.ic_fluent_open_24_regular));
items.add(new TextItem(R.string.mo_settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/LucasGGamerM/moshidon"), R.drawable.ic_fluent_open_24_regular));
items.add(new TextItem(R.string.sk_settings_donate, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/sponsors/LucasGGamerM"), R.drawable.ic_fluent_heart_24_regular));
// items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
clearImageCacheItem = new TextItem(R.string.settings_clear_cache, UiUtils.formatFileSize(getContext(), imageCache.getDiskCache().size(), true), this::clearImageCache, 0);
@@ -290,13 +295,13 @@ public class SettingsFragment extends MastodonToolbarFragment{
GlobalUserPreferences.recentLanguages.remove(accountID);
GlobalUserPreferences.save();
})));
items.add(new TextItem(R.string.sk_clear_recent_emoji, ()-> {
items.add(new TextItem(R.string.mo_clear_recent_emoji, ()-> {
GlobalUserPreferences.recentEmojis.clear();
GlobalUserPreferences.save();
}));
// items.add(new TextItem(R.string.log_out, this::confirmLogOut));
items.add(new FooterItem(getString(R.string.sk_settings_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)));
items.add(new FooterItem(getString(R.string.mo_settings_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)));
}
private void updatePublishText(Button btn) {
@@ -1045,10 +1050,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
if (state == GithubSelfUpdater.UpdateState.CHECKING) return;
GithubSelfUpdater.UpdateInfo info=updater.getUpdateInfo();
if(state!=GithubSelfUpdater.UpdateState.DOWNLOADED){
text.setText(getString(R.string.sk_update_available, info.version));
text.setText(getString(R.string.mo_update_available, info.version));
button.setText(getString(R.string.download_update, UiUtils.formatFileSize(getActivity(), info.size, false)));
}else{
text.setText(getString(R.string.sk_update_ready, info.version));
text.setText(getString(R.string.mo_update_ready, info.version));
button.setText(R.string.install_update);
}
if(state==GithubSelfUpdater.UpdateState.DOWNLOADING){

View File

@@ -1,5 +1,6 @@
package org.joinmastodon.android.fragments;
import android.content.res.Configuration;
import android.os.Bundle;
import com.squareup.otto.Subscribe;
@@ -171,6 +172,12 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
adapter.notifyItemRangeRemoved(index, lastIndex-index);
}
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
if (getParentFragment() instanceof HomeTabFragment home) home.updateToolbarLogo();
}
public class EventListener{
@Subscribe

View File

@@ -81,20 +81,30 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
tabLayout=view.findViewById(R.id.tabbar);
pager=view.findViewById(R.id.pager);
tabViews=new FrameLayout[noFederated ? 6 : 7];
// tabViews=new FrameLayout[noFederated ? 5 : 6];
tabViews=new FrameLayout[4];
for(int i=0;i<tabViews.length;i++){
FrameLayout tabView=new FrameLayout(getActivity());
int switchIndex = noFederated && i > 0 ? i + 1 : i;
tabView.setId(switch(switchIndex){
case 0 -> R.id.discover_local_timeline;
case 1 -> R.id.discover_federated_timeline;
case 2 -> R.id.discover_lists;
case 3 -> R.id.discover_hashtags;
case 4 -> R.id.discover_posts;
case 5 -> R.id.discover_news;
case 6 -> R.id.discover_users;
default -> throw new IllegalStateException("Unexpected value: "+switchIndex);
/// int switchIndex = noFederated && i > 0 ? i + 1 : i;
// tabView.setId(switch(switchIndex){
// case 0 -> R.id.discover_local_timeline;
// case 1 -> R.id.discover_federated_timeline;
// case 2 -> R.id.discover_hashtags;
// case 3 -> R.id.discover_posts;
// case 4 -> R.id.discover_news;
// case 5 -> R.id.discover_users;
// default -> throw new IllegalStateException("Unexpected value: "+switchIndex);
// });
tabView.setId(switch(i){
case 0 -> R.id.discover_hashtags;
case 1 -> R.id.discover_posts;
case 2 -> R.id.discover_news;
case 3 -> R.id.discover_users;
default -> throw new IllegalStateException("Unexpected value: "+i);
});
tabView.setVisibility(View.GONE);
view.addView(tabView); // needed so the fragment manager will have somewhere to restore the tab fragment
tabViews[i]=tabView;
@@ -103,6 +113,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
tabLayout.setTabTextSize(V.dp(16));
tabLayout.setTabTextColors(UiUtils.getThemeColor(getActivity(), R.attr.colorTabInactive), UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
UiUtils.reduceSwipeSensitivity(pager);
pager.setOffscreenPageLimit(4);
pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe);
pager.setAdapter(new DiscoverPagerAdapter());
@@ -119,7 +130,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
}
});
if(localTimelineFragment==null){
if(localTimelineFragment==null || hashtagsFragment==null){
Bundle args=new Bundle();
args.putString("account", accountID);
args.putBoolean("__is_tab", true);
@@ -139,39 +150,56 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
localTimelineFragment=new LocalTimelineFragment();
localTimelineFragment.setArguments(args);
listTimelinesFragment=new ListTimelinesFragment();
listTimelinesFragment.setArguments(args);
// listTimelinesFragment=new ListTimelinesFragment();
// listTimelinesFragment.setArguments(args);
//
// FragmentTransaction transaction = getChildFragmentManager().beginTransaction()
// .add(R.id.discover_posts, postsFragment)
// .add(R.id.discover_local_timeline, localTimelineFragment)
// .add(R.id.discover_hashtags, hashtagsFragment)
// .add(R.id.discover_news, newsFragment)
// .add(R.id.discover_users, accountsFragment)
// .add(R.id.discover_lists, listTimelinesFragment);
//
// if (!noFederated) {
// federatedTimelineFragment=new FederatedTimelineFragment();
// federatedTimelineFragment.setArguments(args);
// transaction.add(R.id.discover_federated_timeline, federatedTimelineFragment);
// }
//
// transaction.commit();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction()
getChildFragmentManager().beginTransaction()
.add(R.id.discover_posts, postsFragment)
.add(R.id.discover_local_timeline, localTimelineFragment)
.add(R.id.discover_hashtags, hashtagsFragment)
.add(R.id.discover_news, newsFragment)
.add(R.id.discover_users, accountsFragment)
.add(R.id.discover_lists, listTimelinesFragment);
if (!noFederated) {
federatedTimelineFragment=new FederatedTimelineFragment();
federatedTimelineFragment.setArguments(args);
transaction.add(R.id.discover_federated_timeline, federatedTimelineFragment);
}
transaction.commit();
.commit();
}
tabLayoutMediator=new TabLayoutMediator(tabLayout, pager, new TabLayoutMediator.TabConfigurationStrategy(){
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position){
if (noFederated && position > 0) position++;
tab.setText(switch(position){
case 0 -> R.string.local_timeline;
case 1 -> R.string.sk_federated_timeline;
case 2 -> R.string.sk_list_timelines;
case 3 -> R.string.hashtags;
case 4 -> R.string.posts;
case 5 -> R.string.news;
case 6 -> R.string.for_you;
// if (noFederated && position > 0) position++;
// tab.setText(switch(position){
// case 0 -> R.string.local_timeline;
// case 1 -> R.string.sk_federated_timeline;
// case 2 -> R.string.sk_list_timelines;
// case 3 -> R.string.hashtags;
// case 4 -> R.string.posts;
// case 5 -> R.string.news;
// case 6 -> R.string.for_you;
//
// default -> throw new IllegalStateException("Unexpected value: "+position);
// });
tab.setText(switch(position){
case 0 -> R.string.hashtags;
case 1 -> R.string.posts;
case 2 -> R.string.news;
case 3 -> R.string.for_you;
default -> throw new IllegalStateException("Unexpected value: "+position);
});
tab.view.textView.setAllCaps(true);
@@ -257,8 +285,11 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
}
public void loadData(){
if(localTimelineFragment!=null && !localTimelineFragment.loaded && !localTimelineFragment.dataLoading)
localTimelineFragment.loadData();
if(hashtagsFragment!=null && !hashtagsFragment.loaded && !hashtagsFragment.dataLoading)
hashtagsFragment.loadData();
// if(localTimelineFragment!=null && !localTimelineFragment.loaded && !localTimelineFragment.dataLoading)
// localTimelineFragment.loadData();
}
private void onSearchEditFocusChanged(View v, boolean hasFocus){
@@ -294,14 +325,23 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
private Fragment getFragmentForPage(int page){
if (noFederated && page > 0) page++;
// return switch(page){
// case 0 -> localTimelineFragment;
// case 1 -> federatedTimelineFragment;
// case 2 -> hashtagsFragment;
// case 3 -> postsFragment;
// case 4 -> newsFragment;
// case 5 -> accountsFragment;
// case 6 -> listTimelinesFragment;
// default -> throw new IllegalStateException("Unexpected value: "+page);
// };
return switch(page){
case 0 -> localTimelineFragment;
case 1 -> federatedTimelineFragment;
case 2 -> hashtagsFragment;
case 3 -> postsFragment;
case 4 -> newsFragment;
case 5 -> accountsFragment;
case 6 -> listTimelinesFragment;
case 0 -> hashtagsFragment;
case 1 -> postsFragment;
case 2 -> newsFragment;
case 3 -> accountsFragment;
default -> throw new IllegalStateException("Unexpected value: "+page);
};
}

View File

@@ -3,7 +3,9 @@ package org.joinmastodon.android.fragments.discover;
import android.os.Bundle;
import android.view.View;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.timelines.GetPublicTimeline;
import org.joinmastodon.android.fragments.FabStatusListFragment;
import org.joinmastodon.android.fragments.StatusListFragment;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
@@ -15,7 +17,7 @@ import java.util.stream.Collectors;
import me.grishka.appkit.api.SimpleCallback;
public class FederatedTimelineFragment extends StatusListFragment{
public class FederatedTimelineFragment extends FabStatusListFragment {
private DiscoverInfoBannerHelper bannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.FEDERATED_TIMELINE);
private String maxID;
@@ -36,6 +38,6 @@ public class FederatedTimelineFragment extends StatusListFragment{
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
bannerHelper.maybeAddBanner(contentWrap);
// bannerHelper.maybeAddBanner(contentWrap);
}
}

View File

@@ -3,7 +3,9 @@ package org.joinmastodon.android.fragments.discover;
import android.os.Bundle;
import android.view.View;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.timelines.GetPublicTimeline;
import org.joinmastodon.android.fragments.FabStatusListFragment;
import org.joinmastodon.android.fragments.StatusListFragment;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
@@ -15,8 +17,8 @@ import java.util.stream.Collectors;
import me.grishka.appkit.api.SimpleCallback;
public class LocalTimelineFragment extends StatusListFragment{
private DiscoverInfoBannerHelper bannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.LOCAL_TIMELINE);
public class LocalTimelineFragment extends FabStatusListFragment {
// private DiscoverInfoBannerHelper bannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.LOCAL_TIMELINE);
private String maxID;
@Override
@@ -36,6 +38,6 @@ public class LocalTimelineFragment extends StatusListFragment{
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
bannerHelper.maybeAddBanner(contentWrap);
// bannerHelper.maybeAddBanner(contentWrap);
}
}

View File

@@ -140,8 +140,8 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
headerView.findViewById(R.id.separator).setVisibility(View.GONE);
headerView.findViewById(R.id.timestamp).setVisibility(View.GONE);
headerView.findViewById(R.id.unread_indicator).setVisibility(View.GONE);
((TextView) headerView.findViewById(R.id.username)).setText(R.string.sk_app_username);
((TextView) headerView.findViewById(R.id.name)).setText(R.string.sk_app_name);
((TextView) headerView.findViewById(R.id.username)).setText(R.string.mo_app_username);
((TextView) headerView.findViewById(R.id.name)).setText(R.string.mo_app_name);
((ImageView) headerView.findViewById(R.id.avatar)).setImageDrawable(getActivity().getDrawable(R.mipmap.ic_launcher));
((FragmentStackActivity) getActivity()).invalidateSystemBarColors(this);

View File

@@ -80,6 +80,7 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
private LinearLayout filtersWrap;
private HorizontalScrollView filtersScroll;
private ImageButton backBtn, clearSearchBtn;
private View focusThing;
private FilterChipView categoryGeneral, categorySpecialInterests;
private List<FilterChipView> regionalFilters;
@@ -285,7 +286,13 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
FilterChipView langFilter=new FilterChipView(getActivity());
langFilter.setDrawableEnd(R.drawable.ic_baseline_arrow_drop_down_18);
langFilter.setText(R.string.server_filter_any_language);
if(currentLanguage==null){
langFilter.setText(R.string.server_filter_any_language);
}else{
Locale locale=Locale.forLanguageTag(currentLanguage);
langFilter.setText(locale.getDisplayLanguage(locale));
langFilter.setSelected(true);
}
langFilterMenu=new PopupMenu(getContext(), langFilter);
langFilter.setOnTouchListener(langFilterMenu.getDragToOpenListener());
langFilter.setOnClickListener(v->langFilterMenu.show());
@@ -301,8 +308,12 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
speedFilterMenu.getMenu().add(0, 2, 0, R.string.server_filter_manual_review);
speedFilter.setOnTouchListener(speedFilterMenu.getDragToOpenListener());
speedFilter.setOnClickListener(v->speedFilterMenu.show());
speedFilter.setText(R.string.server_filter_instant_signup);
speedFilter.setSelected(true);
speedFilter.setText(switch(currentSignupSpeedFilter){
case ANY -> R.string.server_filter_any_signup_speed;
case INSTANT -> R.string.server_filter_instant_signup;
case REVIEWED -> R.string.server_filter_manual_review;
});
speedFilter.setSelected(currentSignupSpeedFilter!=SignupSpeedFilter.ANY);
filtersWrap.addView(speedFilter, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
speedFilterMenu.setOnMenuItemClickListener(item->{
@@ -328,11 +339,13 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
categoryGeneral.setText(R.string.category_general);
categoryGeneral.setTag(CategoryChoice.GENERAL);
categoryGeneral.setOnClickListener(this::onCategoryFilterClick);
categoryGeneral.setSelected(categoryChoice==CategoryChoice.GENERAL);
filtersWrap.addView(categoryGeneral, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
categorySpecialInterests=new FilterChipView(getActivity());
categorySpecialInterests.setText(R.string.category_special_interests);
categorySpecialInterests.setTag(CategoryChoice.SPECIAL);
categorySpecialInterests.setOnClickListener(this::onCategoryFilterClick);
categorySpecialInterests.setSelected(categoryChoice==CategoryChoice.SPECIAL);
filtersWrap.addView(categorySpecialInterests, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
regionalFilters=Arrays.stream(CatalogInstance.Region.values()).map(r->{
@@ -351,6 +364,8 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
filtersWrap.addView(fv, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
return fv;
}).collect(Collectors.toList());
focusThing=view.findViewById(R.id.focus_thing);
focusThing.requestFocus();
}
private void onRegionFilterClick(View v){
@@ -550,7 +565,7 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
searchEdit.setCompoundDrawableTintList(ColorStateList.valueOf(0));
}else{
filtersScroll.setVisibility(View.VISIBLE);
searchEdit.clearFocus();
focusThing.requestFocus();
searchEdit.setText("");
lp.addRule(RelativeLayout.END_OF, R.id.btn_back);
getActivity().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(searchEdit.getWindowToken(), 0);

View File

@@ -23,6 +23,7 @@ public class PushSubscription extends BaseModel implements Cloneable{
", endpoint='"+endpoint+'\''+
", alerts="+alerts+
", serverKey='"+serverKey+'\''+
", policy="+policy+
'}';
}

View File

@@ -99,7 +99,7 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{
Optional<Emoji> element = allAvailableEmojis.stream().filter(e -> e.shortcode.equals(emojiCode)).findFirst();
element.ifPresent(recentEmojiList::add);
}
emojis.add(0, new EmojiCategory(activity.getString(R.string.sk_emoji_recent), recentEmojiList));
emojis.add(0, new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmojiList));
}
for(EmojiCategory category:emojis)

View File

@@ -1,7 +1,18 @@
package org.joinmastodon.android.ui.displayitems;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ScrollView;
import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
@@ -10,6 +21,7 @@ import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
import me.grishka.appkit.utils.CubicBezierInterpolator;
public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
public PhotoStatusDisplayItem(String parentID, Status status, Attachment photo, BaseStatusListFragment parentFragment, int index, int totalPhotos, PhotoLayoutHelper.TiledLayoutResult tiledLayout, PhotoLayoutHelper.TiledLayoutResult.Tile thisTile){
@@ -23,9 +35,109 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
}
public static class Holder extends ImageStatusDisplayItem.Holder<PhotoStatusDisplayItem>{
private final FrameLayout altTextWrapper;
private final TextView altTextButton;
private final View altTextScroller;
private final ImageButton altTextClose;
private final TextView altText;
private boolean altTextShown;
private AnimatorSet currentAnim;
public Holder(Activity activity, ViewGroup parent){
super(activity, R.layout.display_item_photo, parent);
altTextWrapper=findViewById(R.id.alt_text_wrapper);
altTextButton=findViewById(R.id.alt_button);
altTextScroller=findViewById(R.id.alt_text_scroller);
altTextClose=findViewById(R.id.alt_text_close);
altText=findViewById(R.id.alt_text);
altTextButton.setOnClickListener(this::onShowHideClick);
altTextClose.setOnClickListener(this::onShowHideClick);
// altTextScroller.setNestedScrollingEnabled(true);
}
@Override
public void onBind(ImageStatusDisplayItem item){
super.onBind(item);
altTextShown=false;
if(currentAnim!=null)
currentAnim.cancel();
altTextScroller.setVisibility(View.GONE);
altTextClose.setVisibility(View.GONE);
altTextButton.setVisibility(View.VISIBLE);
if(TextUtils.isEmpty(item.attachment.description)){
altTextWrapper.setVisibility(View.GONE);
}else{
altTextWrapper.setVisibility(View.VISIBLE);
altText.setText(item.attachment.description);
}
}
private void onShowHideClick(View v){
boolean show=v.getId()==R.id.alt_button;
if(altTextShown==show)
return;
if(currentAnim!=null)
currentAnim.cancel();
altTextShown=show;
if(show){
altTextScroller.setVisibility(View.VISIBLE);
altTextClose.setVisibility(View.VISIBLE);
}else{
altTextButton.setVisibility(View.VISIBLE);
// Hide these views temporarily so FrameLayout measures correctly
altTextScroller.setVisibility(View.GONE);
altTextClose.setVisibility(View.GONE);
}
// This is the current size...
int prevLeft=altTextWrapper.getLeft();
int prevRight=altTextWrapper.getRight();
int prevTop=altTextWrapper.getTop();
altTextWrapper.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
@Override
public boolean onPreDraw(){
altTextWrapper.getViewTreeObserver().removeOnPreDrawListener(this);
// ...and this is after the layout pass, right now the FrameLayout has its final size, but we animate that change
if(!show){
// Show these views again so they're visible for the duration of the animation.
// No one would notice they were missing during measure/layout.
altTextScroller.setVisibility(View.VISIBLE);
altTextClose.setVisibility(View.VISIBLE);
}
AnimatorSet set=new AnimatorSet();
set.playTogether(
ObjectAnimator.ofInt(altTextWrapper, "left", prevLeft, altTextWrapper.getLeft()),
ObjectAnimator.ofInt(altTextWrapper, "right", prevRight, altTextWrapper.getRight()),
ObjectAnimator.ofInt(altTextWrapper, "top", prevTop, altTextWrapper.getTop()),
ObjectAnimator.ofFloat(altTextButton, View.ALPHA, show ? 1f : 0f, show ? 0f : 1f),
ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f),
ObjectAnimator.ofFloat(altTextClose, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f)
);
set.setDuration(300);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
if(show){
altTextButton.setVisibility(View.GONE);
}else{
altTextScroller.setVisibility(View.GONE);
altTextClose.setVisibility(View.GONE);
}
currentAnim=null;
}
});
set.start();
currentAnim=set;
return true;
}
});
}
}
}

View File

@@ -31,6 +31,7 @@ import android.provider.OpenableColumns;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.Menu;
import android.view.MenuItem;
@@ -87,6 +88,7 @@ import org.joinmastodon.android.ui.text.CustomEmojiSpan;
import org.parceler.Parcels;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
@@ -111,6 +113,8 @@ import androidx.annotation.StringRes;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
@@ -1059,4 +1063,19 @@ public class UiUtils{
case DIRECT -> R.string.visibility_private;
});
}
// https://github.com/tuskyapp/Tusky/pull/3148
public static void reduceSwipeSensitivity(ViewPager2 pager) {
try {
Field recyclerViewField = ViewPager2.class.getDeclaredField("mRecyclerView");
recyclerViewField.setAccessible(true);
RecyclerView recyclerView = (RecyclerView) recyclerViewField.get(pager);
Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop");
touchSlopField.setAccessible(true);
int touchSlop = touchSlopField.getInt(recyclerView);
touchSlopField.set(recyclerView, touchSlop * 3);
} catch (Exception ex) {
Log.e("reduceSwipeSensitivity", Log.getStackTraceString(ex));
}
}
}

View File

@@ -0,0 +1,58 @@
package org.joinmastodon.android.ui.views;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.ScrollView;
public class NestableScrollView extends ScrollView{
private float downY, touchslop;
private boolean didDisallow;
public NestableScrollView(Context context){
super(context);
init();
}
public NestableScrollView(Context context, AttributeSet attrs){
super(context, attrs);
init();
}
public NestableScrollView(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
init();
}
public NestableScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init(){
touchslop=ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@Override
public boolean onTouchEvent(MotionEvent ev){
if(ev.getAction()==MotionEvent.ACTION_DOWN){
if(canScrollVertically(-1) || canScrollVertically(1)){
getParent().requestDisallowInterceptTouchEvent(true);
didDisallow=true;
}else{
didDisallow=false;
}
downY=ev.getY();
}else if(didDisallow && ev.getAction()==MotionEvent.ACTION_MOVE){
if(Math.abs(downY-ev.getY())>=touchslop){
if(!canScrollVertically((int)(downY-ev.getY()))){
didDisallow=false;
getParent().requestDisallowInterceptTouchEvent(false);
}
}
}
return super.onTouchEvent(ev);
}
}

View File

@@ -2,9 +2,9 @@
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/highlight_over_dark">
<item>
<shape>
<solid android:color="?android:colorAccent"/>
<corners android:radius="16dp"/>
<padding android:left="16dp" android:right="16dp"/>
<solid android:color="?colorPrimary800"/>
<corners android:radius="16sp"/>
<padding android:left="16sp" android:right="16sp"/>
</shape>
</item>
</ripple>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#D9000000"/>
<corners android:radius="4dp"/>
</shape>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16">
<path android:pathData="M3.2 5.74C3.482 5.436 3.957 5.419 4.26 5.7L8 9.226 11.74 5.7c0.303-0.281 0.778-0.264 1.06 0.04 0.281 0.303 0.264 0.778-0.04 1.06l-4.25 4c-0.287 0.267-0.733 0.267-1.02 0l-4.25-4C2.936 6.518 2.919 6.043 3.2 5.74z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M10.946 2.047l0.005 0.007C11.296 2.02 11.646 2 12 2c5.522 0 10 4.477 10 10s-4.478 10-10 10c-3.21 0-6.066-1.512-7.896-3.862H4.102v-0.003C2.786 16.441 2 14.312 2 12c0-5.162 3.911-9.41 8.932-9.944l0.014-0.009zM12 3.5c-0.053 0-0.106 0-0.16 0.002 0.123 0.244 0.255 0.532 0.374 0.85 0.347 0.921 0.666 2.28 0.1 3.486-0.522 1.113-1.424 1.4-2.09 1.573L10.14 9.432c-0.657 0.17-0.91 0.235-1.093 0.514-0.17 0.257-0.144 0.582 0.061 1.25l0.046 0.148c0.082 0.258 0.18 0.57 0.23 0.863 0.064 0.364 0.082 0.827-0.152 1.275-0.231 0.444-0.538 0.747-0.9 0.945-0.341 0.185-0.694 0.256-0.958 0.302l-0.093 0.017c-0.515 0.09-0.761 0.134-1 0.39-0.187 0.2-0.307 0.553-0.377 1.079-0.029 0.214-0.046 0.427-0.064 0.646l-0.01 0.117c-0.02 0.242-0.044 0.521-0.099 0.76v0.002c1.554 1.696 3.787 2.76 6.27 2.76 1.576 0 3.053-0.43 4.319-1.178-0.099-0.1-0.205-0.218-0.31-0.35-0.34-0.428-0.786-1.164-0.631-2.033 0.074-0.418 0.298-0.768 0.515-1.036 0.22-0.274 0.486-0.526 0.72-0.74l0.158-0.146c0.179-0.163 0.33-0.301 0.46-0.437 0.172-0.18 0.21-0.262 0.212-0.267 0.068-0.224-0.015-0.384-0.106-0.454-0.046-0.035-0.107-0.06-0.19-0.061-0.084 0-0.22 0.024-0.401 0.14-0.21 0.132-0.515 0.214-0.836 0.085-0.267-0.108-0.415-0.314-0.486-0.432-0.144-0.237-0.225-0.546-0.278-0.772-0.04-0.174-0.08-0.372-0.115-0.553l-0.04-0.206c-0.05-0.25-0.094-0.428-0.134-0.54l-0.02-0.037c-0.014-0.027-0.035-0.062-0.064-0.105-0.058-0.089-0.133-0.192-0.227-0.317l-0.11-0.143c-0.16-0.212-0.353-0.463-0.516-0.712-0.196-0.298-0.417-0.688-0.487-1.104-0.037-0.22-0.036-0.475 0.055-0.734 0.094-0.264 0.265-0.482 0.487-0.649 0.483-0.362 1.193-1.172 1.823-1.959 0.288-0.359 0.544-0.695 0.736-0.95C15.222 3.98 13.667 3.5 12 3.5z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M10.55 2.534c0.837-0.707 2.063-0.707 2.9 0L20.2 8.23C20.708 8.657 21 9.286 21 9.95v9.802c0 0.967-0.784 1.75-1.75 1.75h-3c-0.966 0-1.75-0.783-1.75-1.75v-5c0-0.414-0.336-0.75-0.75-0.75h-3.5c-0.414 0-0.75 0.336-0.75 0.75v5c0 0.967-0.784 1.75-1.75 1.75h-3c-0.966 0-1.75-0.783-1.75-1.75V9.948c0-0.663 0.292-1.292 0.8-1.72l6.75-5.694z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M10.55 2.532c0.837-0.707 2.063-0.707 2.9 0l6.75 5.692c0.507 0.428 0.8 1.057 0.8 1.72v9.803c0 0.966-0.784 1.75-1.75 1.75h-3.5c-0.966 0-1.75-0.784-1.75-1.75v-5.5c0-0.138-0.112-0.25-0.25-0.25h-3.5c-0.138 0-0.25 0.112-0.25 0.25v5.5c0 0.966-0.784 1.75-1.75 1.75h-3.5c-0.966 0-1.75-0.784-1.75-1.75V9.944c0-0.663 0.293-1.293 0.8-1.72l6.75-5.692zm1.933 1.147c-0.279-0.236-0.687-0.236-0.966 0L4.767 9.37C4.596 9.513 4.5 9.723 4.5 9.944v9.803c0 0.138 0.112 0.25 0.25 0.25h3.5c0.138 0 0.25-0.112 0.25-0.25v-5.5c0-0.967 0.784-1.75 1.75-1.75h3.5c0.966 0 1.75 0.783 1.75 1.75v5.5c0 0.138 0.112 0.25 0.25 0.25h3.5c0.138 0 0.25-0.112 0.25-0.25V9.944c0-0.221-0.098-0.43-0.267-0.573l-6.75-5.692z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M14.75 15c0.966 0 1.75 0.784 1.75 1.75l-0.001 0.962c0.117 2.19-1.511 3.297-4.432 3.297-2.91 0-4.567-1.09-4.567-3.259v-1C7.5 15.784 8.284 15 9.25 15h5.5zm-11-5h4.376C8.044 10.32 8 10.655 8 11c0 1.116 0.457 2.124 1.193 2.85L9.355 14H9.25c-0.301 0-0.591 0.049-0.863 0.138-0.864 0.286-1.54 0.988-1.786 1.87L6.567 16.01C3.657 16.009 2 14.919 2 12.75v-1C2 10.784 2.784 10 3.75 10zm16.5 0c0.966 0 1.75 0.784 1.75 1.75l-0.001 0.962c0.117 2.19-1.511 3.297-4.432 3.297l-0.169-0.002c-0.238-0.854-0.88-1.54-1.705-1.841-0.235-0.086-0.486-0.14-0.746-0.16L14.75 14l-0.105 0.001C15.475 13.268 16 12.195 16 11c0-0.345-0.044-0.68-0.126-1h4.376zM12 8c1.657 0 3 1.343 3 3s-1.343 3-3 3-3-1.343-3-3 1.343-3 3-3zM6.5 3c1.657 0 3 1.343 3 3s-1.343 3-3 3-3-1.343-3-3 1.343-3 3-3zm11 0c1.657 0 3 1.343 3 3s-1.343 3-3 3-3-1.343-3-3 1.343-3 3-3z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M8 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm9 0c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM4.25 14C3.007 14 2 15.007 2 16.25v0.25S2 21 8 21c1.855 0 3.136-0.43 4.021-1.024 0.06-0.38 0.242-0.719 0.504-0.976C12.201 18.682 12 18.24 12 17.75s0.201-0.932 0.525-1.25C12.201 16.182 12 15.74 12 15.25c0-0.438 0.161-0.84 0.428-1.146C12.214 14.036 11.986 14 11.75 14h-7.5zm9.5 0.5c-0.414 0-0.75 0.336-0.75 0.75S13.336 16 13.75 16h7.5c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-7.5zm0 2.5C13.336 17 13 17.336 13 17.75s0.336 0.75 0.75 0.75h7.5c0.414 0 0.75-0.336 0.75-0.75S21.664 17 21.25 17h-7.5zm0 2.5c-0.414 0-0.75 0.336-0.75 0.75S13.336 21 13.75 21h7.5c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-7.5z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -19,8 +19,8 @@
<ImageView
android:id="@+id/send_error"
android:tooltipText="@string/sk_sending_error"
android:contentDescription="@string/sk_sending_error"
android:tooltipText="@string/mo_sending_error"
android:contentDescription="@string/mo_sending_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"

View File

@@ -8,7 +8,7 @@
android:layout_gravity="top"
android:elevation="1dp"
android:outlineProvider="background"
android:background="?colorWindowBackground">
android:background="?colorBackgroundLight">
<TextView
android:id="@+id/banner_text"

View File

@@ -20,7 +20,6 @@
android:drawableStart="@drawable/ic_fluent_chat_multiple_24_selector_text"
android:drawablePadding="8dp"
android:drawableTint="?android:textColorSecondary"
android:tooltipText="@string/button_reply"
android:gravity="center_vertical"
android:textAppearance="@style/m3_label_large"
tools:text="123"/>
@@ -68,7 +67,6 @@
android:drawableStart="@drawable/ic_fluent_star_24_selector"
android:drawablePadding="8dp"
android:drawableTint="@color/favorite_icon"
android:tooltipText="@string/button_favorite"
android:textColor="@color/favorite_icon"
android:gravity="center_vertical"
android:textAppearance="@style/m3_label_large"
@@ -94,7 +92,6 @@
android:drawablePadding="8dp"
android:drawableTint="@color/bookmark_icon"
android:gravity="center_vertical"
android:tooltipText="@string/add_bookmark"
android:textAppearance="@style/m3_label_large" />
</FrameLayout>

View File

@@ -124,6 +124,7 @@
android:id="@+id/bot_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:importantForAccessibility="no"
android:layout_marginTop="2dp"
android:src="@drawable/ic_fluent_bot_16_filled" />

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<org.joinmastodon.android.ui.views.ImageAttachmentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -10,4 +11,62 @@
android:layout_gravity="center"
android:scaleType="centerCrop"/>
<!-- This is hidden from screenreaders because that same alt text is set as content description on the ImageView -->
<FrameLayout
android:id="@+id/alt_text_wrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|bottom"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:importantForAccessibility="noHideDescendants"
android:background="@drawable/bg_image_alt_overlay">
<TextView
android:id="@+id/alt_button"
android:layout_width="40dp"
android:layout_height="22dp"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:text="ALT"/>
<ImageButton
android:id="@+id/alt_text_close"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="end|top"
android:src="@drawable/ic_baseline_close_24"
android:tint="#FFF"
android:background="?android:selectableItemBackgroundBorderless"/>
<org.joinmastodon.android.ui.views.NestableScrollView
android:id="@+id/alt_text_scroller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="40dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/alt_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textAppearance="@style/m3_body_medium"
android:textColor="#FFF"
tools:text="Alt text goes here"/>
</LinearLayout>
</org.joinmastodon.android.ui.views.NestableScrollView>
</FrameLayout>
</org.joinmastodon.android.ui.views.ImageAttachmentFrameLayout>

View File

@@ -155,7 +155,7 @@
android:layout_marginBottom="8dp"
android:background="@drawable/bg_poll_option_clickable"
android:outlineProvider="background"
android:contentDescription="@string/sk_poll_option_add"
android:contentDescription="@string/mo_poll_option_add"
android:elevation="2dp">
<ImageView
android:id="@+id/add_poll_option_icon"

View File

@@ -40,6 +40,14 @@
android:backgroundTint="?colorM3SurfaceVariant"
android:hint="@string/search_communities"/>
<View
android:id="@+id/focus_thing"
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:importantForAccessibility="no"/>
<ImageButton
android:id="@+id/btn_back"
android:layout_width="24dp"

View File

@@ -278,7 +278,7 @@
android:paddingHorizontal="16dp"
android:elevation="0dp"
android:visibility="gone"
android:hint="@string/sk_personal_note"/>
android:hint="@string/mo_personal_note"/>
<Button
android:id="@+id/note_edit_confirm"
@@ -289,8 +289,8 @@
android:visibility="invisible"
android:backgroundTint="?colorBackgroundLightest"
android:layout_gravity="right|center_vertical"
android:tooltipText="@string/sk_personal_note_confirm"
android:contentDescription="@string/sk_personal_note_confirm"
android:tooltipText="@string/mo_personal_note_confirm"
android:contentDescription="@string/mo_personal_note_confirm"
android:drawableStart="@drawable/ic_fluent_checkmark_24_regular"
/>
</FrameLayout>
@@ -361,8 +361,8 @@
</org.joinmastodon.android.ui.views.NestedRecyclerScrollView>
<ImageButton
android:tooltipText="@string/sk_fab_compose"
android:contentDescription="@string/sk_fab_compose"
android:tooltipText="@string/mo_fab_compose"
android:contentDescription="@string/mo_fab_compose"
android:id="@+id/fab"
style="@style/Widget.Mastodon.Button.Compose"/>
</FrameLayout>

View File

@@ -27,7 +27,7 @@
android:paddingHorizontal="16dp"
android:elevation="0dp"
android:visibility="gone"
android:hint="@string/sk_personal_note"/>
android:hint="@string/mo_personal_note"/>
<ImageButton
android:id="@+id/note_edit_confirm"
@@ -39,8 +39,8 @@
android:visibility="invisible"
android:layout_marginEnd="20dp"
android:layout_gravity="right|center_vertical"
android:tooltipText="@string/sk_personal_note_confirm"
android:contentDescription="@string/sk_personal_note_confirm" />
android:tooltipText="@string/mo_personal_note_confirm"
android:contentDescription="@string/mo_personal_note_confirm" />
</FrameLayout>

View File

@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:text="@string/sk_welcome_text" />
android:text="@string/mo_welcome_text" />
<View
android:layout_width="match_parent"

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/switcher_btn"
android:background="?android:selectableItemBackgroundBorderless"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:paddingHorizontal="16dp">
<ImageView
android:id="@+id/timeline_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_fluent_home_24_regular" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/collapsed_chevron"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_fluent_chevron_down_16_filled"
android:visibility="gone" />
<TextView
android:id="@+id/timeline_title"
style="?android:attr/titleTextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:drawablePadding="8dp"
android:drawableEnd="@drawable/ic_fluent_chevron_down_16_filled" />
</FrameLayout>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/show_new_posts_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingVertical="2dp"
android:minHeight="32sp"
android:lineSpacingMultiplier="0.8"
android:textAppearance="@style/m3_title_medium"
android:text="@string/see_new_posts"
android:textColor="@color/gray_25"
android:background="@drawable/bg_button_new_posts"
android:drawableStart="@drawable/ic_fluent_arrow_up_16_filled"
android:drawablePadding="8dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>

View File

@@ -29,7 +29,7 @@
android:layout_marginBottom="16dp"
android:layout_weight="1"
android:textAppearance="@style/m3_body_medium"
tools:text="@string/sk_update_available" />
tools:text="@string/mo_update_available" />
<FrameLayout
android:layout_width="wrap_content"

View File

@@ -21,8 +21,8 @@
android:id="@+id/empty"/>
<ImageButton
android:contentDescription="@string/sk_fab_compose"
android:tooltipText="@string/sk_fab_compose"
android:contentDescription="@string/mo_fab_compose"
android:tooltipText="@string/mo_fab_compose"
android:id="@+id/fab"
style="@style/Widget.Mastodon.Button.Compose"/>
</FrameLayout>

View File

@@ -8,5 +8,5 @@
<item android:id="@+id/brown_color" android:title="@string/sk_color_palette_brown"/>
<item android:id="@+id/yellow_color" android:title="@string/sk_color_palette_yellow"/>
<item android:id="@+id/red_color" android:title="@string/sk_color_palette_red"/>
<item android:id="@+id/nord_color" android:title="@string/sk_color_palette_nord"/>
<item android:id="@+id/nord_color" android:title="@string/mo_color_palette_nord"/>
</menu>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/home" android:icon="@drawable/ic_fluent_home_24_regular" android:title="@string/sk_timeline_home" />
<item android:id="@+id/local" android:icon="@drawable/ic_fluent_people_community_24_regular" android:title="@string/sk_timeline_local" />
<item android:id="@+id/federated" android:icon="@drawable/ic_fluent_earth_24_regular" android:title="@string/sk_timeline_federated" />
<item android:id="@+id/post_notifications" android:icon="@drawable/ic_fluent_alert_24_regular" android:title="@string/sk_notify_posts" />
<item android:id="@+id/lists" android:icon="@drawable/ic_fluent_people_list_24_regular" android:title="@string/sk_list_timelines" android:visible="false">
<menu />
</item>
<item android:id="@+id/followed_hashtags" android:icon="@drawable/ic_fluent_number_symbol_24_regular" android:title="@string/sk_hashtags_you_follow" android:visible="false">
<menu />
</item>
</menu>

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/followed_hashtags" android:title="@string/sk_hashtags_you_follow" android:icon="@drawable/ic_fluent_number_symbol_24_regular" android:showAsAction="always"/>
<item android:id="@+id/manage_user_lists" android:title="@string/sk_your_lists" android:icon="@drawable/ic_fluent_people_list_24_regular" android:showAsAction="always"/>
<item android:id="@+id/followed_hashtags" android:title="@string/sk_hashtags_you_follow" android:icon="@drawable/ic_fluent_number_symbol_24_regular" />
<item android:id="@+id/manage_user_lists" android:title="@string/sk_your_lists" android:icon="@drawable/ic_fluent_people_list_24_regular" />
<item android:id="@+id/bookmarks" android:title="@string/bookmarks" android:icon="@drawable/ic_fluent_bookmark_multiple_24_regular" android:showAsAction="always"/>
<item android:id="@+id/favorites" android:title="@string/your_favorites" android:icon="@drawable/ic_fluent_star_24_regular" android:showAsAction="always"/>
<item android:id="@+id/scheduled" android:title="@string/sk_unsent_posts" android:icon="@drawable/ic_fluent_drafts_24_regular" android:showAsAction="always"/>
<item android:id="@+id/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular" android:showAsAction="always"/>
<item android:id="@+id/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular" />
</menu>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,11 +11,11 @@
<string name="sk_settings_load_new_posts">Carrega automàticament les publicacions noves</string>
<string name="sk_federated_timeline">Federació</string>
<string name="sk_federated_timeline_info_banner">Aquestes són les publicacions més recents de gent de la teua federació.</string>
<string name="sk_update_ready">Moshidon %s s\'ha baixat i està preparat per a instal·lar-se.</string>
<string name="sk_update_ready">Megalodon %s s\'ha baixat i està preparat per a instal·lar-se.</string>
<string name="sk_accept_follow_request">Accepta la sol·licitud</string>
<string name="sk_disable_marquee">Desactiva el desplaçament de text a les barres de títol</string>
<string name="sk_user_post_notifications_on">Notificacions activades per a publicacions de: %s</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pin_post">Fixa al perfil</string>
<string name="sk_confirm_pin_post_title">Fixar al perfil</string>
<string name="sk_confirm_delete_and_redraft">Segur que vols eliminar i tornar a escriure aquesta publicació\?</string>
@@ -25,10 +25,10 @@
<string name="sk_visibility_unlisted">No llistat</string>
<string name="sk_settings_show_boosts">Mostra els impulsos</string>
<string name="sk_settings_show_interaction_counts">Mostra el recompte d\'interaccions</string>
<string name="sk_settings_app_version">Moshidon v. %1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v. %1$s (%2$d)</string>
<string name="sk_user_post_notifications_off">Notificacions desactivades per a publicacions de: %s</string>
<string name="sk_mark_media_as_sensitive">Marca el contingut com a sensible</string>
<string name="sk_update_available">Moshidon %s està preparat per a baixar-se.</string>
<string name="sk_update_available">Megalodon %s està preparat per a baixar-se.</string>
<string name="sk_check_for_update">Comprova actualitzacions</string>
<string name="sk_no_update_available">No hi ha cap actualització disponible</string>
<string name="sk_list_timelines">Llistes</string>
@@ -36,7 +36,7 @@
<string name="sk_reject_follow_request">Rebutja la sol·licitud</string>
<string name="sk_lists_with_user">Edita les llistes amb %s</string>
<string name="sk_settings_always_reveal_content_warnings">Mostra sempre els avisos de contingut</string>
<string name="sk_settings_contribute">Contribueix a Moshidon</string>
<string name="sk_settings_contribute">Contribueix a Megalodon</string>
<string name="sk_settings_show_federated_timeline">Mostra la línia de temps federada</string>
<string name="sk_notification_type_status">Publicacions</string>
<string name="sk_notify_posts">Notificacions de publicacions</string>

View File

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

View File

@@ -18,7 +18,7 @@
<string name="sk_confirm_delete_draft">Jste si jistý, že chcete tento navržený příspěvek smazat\?</string>
<string name="sk_confirm_delete_scheduled_post">Určitě chcete tento naplánovaný příspěvek smazat\?</string>
<string name="sk_delete_list_confirm">Opravdu chcete tento seznam odstranit\?</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Připnutý</string>
<string name="sk_delete_and_redraft">vymazat a přepracovat</string>
</resources>

View File

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

View File

@@ -10,7 +10,7 @@
<string name="sk_settings_show_replies">Dangos ymatebion</string>
<string name="sk_list_timelines">Rhestri</string>
<string name="sk_settings_always_reveal_content_warnings">Datguddio rhybuddion cynnwys bob tro</string>
<string name="sk_settings_contribute">Cyfrannu at Moshidon</string>
<string name="sk_settings_contribute">Cyfrannu at Megalodon</string>
<string name="sk_notification_type_status">Negeseuon</string>
<string name="sk_color_palette_material3">System</string>
<string name="sk_color_palette_pink">Pinc</string>
@@ -19,13 +19,13 @@
<string name="sk_color_palette_blue">Glas</string>
<string name="sk_color_palette_brown">Brown</string>
<string name="sk_color_palette_red">Coch</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_confirm_pin_post">Hoffech chi binio\'r neges hon i\'ch proffil\?</string>
<string name="sk_visibility_unlisted">Heb ei restru</string>
<string name="sk_settings_load_new_posts">Llwytho negeseuon newydd yn ddiofyn</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_update_available">Mae Moshidon %s yn barod i\'w lawrlwytho.</string>
<string name="sk_update_ready">Mae Moshidon %s wedi ei lawrlwytho ac yn barod i\'w osod.</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_update_available">Mae Megalodon %s yn barod i\'w lawrlwytho.</string>
<string name="sk_update_ready">Mae Megalodon %s wedi ei lawrlwytho ac yn barod i\'w osod.</string>
<string name="sk_color_palette_yellow">Melyn</string>
<string name="sk_translate_post">Cyfieithu</string>
<string name="sk_translate_show_original">Dangos y gwreiddiol</string>

View File

@@ -13,21 +13,25 @@
<string name="user_boosted">%s hat diesen Beitrag geteilt</string>
<string name="in_reply_to">Als Antwort auf %s</string>
<string name="notifications">Benachrichtigungen</string>
<string name="user_followed_you">folgt dir jetzt</string>
<string name="user_sent_follow_request">hat dir eine Follower-Anfrage gesendet</string>
<string name="user_favorited">favorisierte</string>
<string name="notification_boosted">teilte</string>
<string name="poll_ended">Abstimmung beendet</string>
<string name="time_seconds">vor %d Sekunden</string>
<string name="time_minutes">vor %d Minuten</string>
<string name="time_hours">vor %d Stunden</string>
<string name="time_days">vor %d Tagen</string>
<string name="share_toot_title">Teilen</string>
<string name="settings">Einstellungen</string>
<string name="publish">Veröffentlichen</string>
<string name="discard_draft">Entwurf verwerfen?</string>
<string name="discard">Verwerfen</string>
<string name="cancel">Abbrechen</string>
<plurals name="followers">
<item quantity="one">Follower</item>
<item quantity="other">Follower</item>
@@ -198,6 +202,7 @@
<string name="category_regional">Regional</string>
<string name="category_tech">Technik</string>
<string name="confirm_email_title">Eine letzte Sache noch</string>
<!-- %s is the email address -->
<string name="confirm_email_subtitle">Tippe auf den Link, den wir dir per E-Mail geschickt haben, um dein Konto zu verifizieren.</string>
<string name="confirm_email_didnt_get">Keinen Link bekommen?</string>
<string name="resend">Erneut abschicken</string>
@@ -315,6 +320,7 @@
<string name="manually_approves_followers">Manuelles Genehmigen von Followern</string>
<string name="current_account">Aktuelles Konto</string>
<string name="log_out_account">%s abmelden</string>
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
<plurals name="x_followers">
<item quantity="one">%,d Follower</item>
@@ -393,6 +399,7 @@
<string name="login_title">Willkommen zurück</string>
<string name="login_subtitle">Melde dich mit dem Server an, auf dem du dein Konto erstellt hast.</string>
<string name="server_url">Serveradresse</string>
<!-- {logo} is a placeholder that is replaced with the Mastodon logo image at runtime. Please copy it into your translation as is. -->
<string name="welcome_page1_title">Was ist {logo}?</string>
<string name="welcome_page1_text">Stellen Sie sich vor, Sie haben eine E-Mail-Adresse mit der Endung @example.com.\n\nSie können weiterhin E-Mails von jeder Person senden und empfangen, auch wenn deren E-Mail-Adresse auf @gmail.com oder @icloud.com oder @example.com endet.</string>
<string name="welcome_page2_title">Mastodon ist genau so.</string>
@@ -414,4 +421,4 @@
<string name="category_special_interests">Besondere Interessen</string>
<string name="signup_passwords_dont_match">Passwörter stimmen nicht überein</string>
<string name="loading_fediverse_resource_title">Ich habe im Fediverse nachgeschaut...</string>
</resources>
</resources>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mo_app_name" translatable="false">Moshidon</string>
<string name="mo_color_palette_nord">Nord</string>
<string name="mo_app_username" translatable="false">\@moshidon</string>
<string name="mo_disable_dividers">Beitrags Trennung deaktivieren</string>
<string name="mo_relocate_publish_button">Veröffentlichen-Schaltfläche verschieben</string>
<string name="mo_hide_compose_button_while_scrolling_setting">Veröffentlichen Schaltfläche beim scrollen ausblenden</string>
<string name="mo_welcome_text">Moshidon sagt Hi! gib den Domain-Namen deiner Heimat-Instanz unten ein.</string>
<!-- Setting this as non-translatable as it simply doesnt change with language-->
<string name="mo_settings_app_version" translatable="false">Moshidon v%1$s (%2$d)</string>
<string name="mo_personal_note">Notiz zu diesem Profil hinzufügen</string>
<string name="mo_personal_note_confirm">Änderungen der Notiz bestätigen</string>
<string name="mo_personal_note_update_failed">Speichern der Notiz fehlgeschlagen</string>
<string name="mo_settings_contribute">Zu Megalodon beitragen</string>
<string name="mo_update_available">Moshidon %s ist bereit zum herunterladen.</string>
<string name="mo_update_ready">Moshidon %s ist heruntergeladen und bereit zur Installation.</string>
<string name="mo_no_image_desc_title">Keine Bildbeschreibung</string>
<string name="mo_no_image_desc">Die enthaltenen Bilder haben keine Beschreibung. Bitte füge eine Beschreibung hinzu, damit auch sehbehinderte Personen teilnehmen können.</string>
<string name="mo_emoji_recent">Kürzlich verwendet</string>
<string name="mo_clear_recent_emoji">Kürzlich verwendete Emojis löschen</string>
<string name="mo_disable_relocate_publish_button_to_enable_customization">Deaktiviere die Funktion Veröffentlichen-Schaltfläche verschieben, um eine Anpassung zu ermöglichen</string>
<!-- accessibility labels-->
<string name="mo_poll_option_add">Neue Umfrageoption hinzufügen</string>
<string name="mo_fab_compose">Verfassen</string>
<string name="mo_sending_error">Fehler beim Veröffentlichen</string>
</resources>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Angeheftet</string>
<string name="sk_delete_and_redraft">Löschen und neu erstellen</string>
<string name="sk_confirm_delete_and_redraft_title">Beitrag löschen und neu erstellen</string>
<string name="sk_confirm_delete_and_redraft">Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest?</string>
<string name="sk_confirm_delete_and_redraft">Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest\?</string>
<string name="sk_pin_post">An Profil anheften</string>
<string name="sk_confirm_pin_post_title">Beitrag an Profil anheften</string>
<string name="sk_confirm_pin_post">Möchtest du den Beitrag an dein Profil anheften?</string>
@@ -19,48 +19,50 @@
<string name="sk_settings_show_boosts">Geteilte Beiträge anzeigen</string>
<string name="sk_settings_load_new_posts">Automatisch neue Beiträge laden</string>
<string name="sk_settings_show_interaction_counts">Interaktions-Anzahlen anzeigen</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Medien als sensibel markieren</string>
<string name="sk_user_post_notifications_on">Benachrichtigungen über Beiträge von %s aktiviert</string>
<string name="sk_user_post_notifications_off">Benachrichtigungen über Beiträge von %s deaktiviert</string>
<string name="sk_federated_timeline">Föderation</string>
<string name="sk_federated_timeline_info_banner">Das sind die neuesten Beiträge von Personen, die in der Föderation deines Servers sind.</string>
<string name="sk_update_available">Moshidon %s ist zum Herunterladen bereit.</string>
<string name="sk_update_ready">Moshidon %s wurde heruntergeladen und kann jetzt installiert werden.</string>
<string name="sk_update_available">Megalodon %s ist zum Herunterladen bereit.</string>
<string name="sk_update_ready">Megalodon %s wurde heruntergeladen und kann jetzt installiert werden.</string>
<string name="sk_check_for_update">Auf Update prüfen</string>
<string name="sk_no_update_available">Kein Update verfügbar</string>
<string name="sk_list_timelines">Listen</string>
<string name="sk_follow_requests">Folgeanfragen</string>
<string name="sk_accept_follow_request">Folgeanfrage akzeptieren</string>
<string name="sk_reject_follow_request">Folgeanfrage ablehnen</string>
<string name="sk_lists_with_user">Listen mit %s bearbeiten</string>
<string name="sk_lists_with_user">Listen mit %s</string>
<string name="sk_settings_always_reveal_content_warnings">Inhaltswarnungen immer ausklappen</string>
<string name="sk_disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
<string name="sk_settings_contribute">Zu Moshidon beitragen</string>
<string name="sk_settings_contribute">Zu Megalodon beitragen</string>
<string name="sk_settings_show_federated_timeline">Föderierte Timeline anzeigen</string>
<string name="sk_notify_posts">Beitrags-Benachrichtigungen</string>
<string name="sk_notification_type_status">Beiträge</string>
<string name="sk_notify_posts">Beitrags Benachrichtigungen</string>
<string name="sk_settings_color_palette">Farbschema</string>
<string name="sk_color_palette_material3">System</string>
<string name="sk_color_palette_pink">Pink</string>
<string name="sk_color_palette_purple">Violett</string>
<string name="sk_color_palette_green">Grün</string>
<string name="sk_color_palette_brown">Braun</string>
<string name="sk_color_palette_yellow">Gelb</string>
<string name="sk_notification_type_status">Beiträge</string>
<string name="sk_color_palette_blue">Blau</string>
<string name="sk_color_palette_brown">Braun</string>
<string name="sk_color_palette_red">Rot</string>
<string name="sk_color_palette_yellow">Gelb</string>
<string name="sk_poll_allow_multiple">Mehrfachantworten erlauben</string>
<string name="sk_translated_using">Übersetzt mit %s</string>
<string name="sk_post_language">Sprache: %s</string>
<string name="sk_language_name">%s (%s)</string>
<string name="sk_confirm_clear_recent_languages">Sicher, dass du die Liste der zuletzt verwendeten Sprachen leeren willst\?</string>
<string name="sk_translate_post">Übersetzen</string>
<string name="sk_translate_show_original">Original anzeigen</string>
<string name="sk_post_language">Sprache: %s</string>
<string name="sk_available_languages">Verfügbare Sprachen</string>
<string name="sk_language_name">%s (%s)</string>
<string name="sk_clear_recent_languages">Zuletzt verwendete Sprachen leeren</string>
<string name="sk_confirm_clear_recent_languages">Sicher, dass du die Liste der zuletzt verwendeten Sprachen leeren willst\?</string>
<string name="sk_welcome_title">Willkommen!</string>
<string name="sk_example_domain">beispiel.social</string>
<string name="sk_welcome_text">Der Hai sagt Hi! Um anzufangen, gib den Domain-Namen deiner Heimat-Instanz unten ein.</string>
<string name="sk_color_palette_material3">System</string>
<string name="sk_color_palette_red">Rot</string>
<string name="sk_example_domain">beispiel.social</string>
<string name="sk_tabs_disable_swipe">Wischen zwischen Tabs deaktivieren</string>
<string name="sk_settings_profile">Profil einrichten</string>
<string name="sk_settings_posting">Einstellungen für Beiträge</string>
<string name="sk_settings_filters">Filter konfigurieren</string>
@@ -68,20 +70,20 @@
<string name="sk_settings_rules">Regelwerk</string>
<string name="sk_settings_about">Über die App</string>
<string name="sk_settings_donate">Spenden</string>
<string name="sk_tabs_disable_swipe">Wischen zwischen Tabs deaktivieren</string>
<string name="sk_delete_notification">Benachrichtigung löschen</string>
<string name="sk_delete_notification_confirm_action">Benachrichtigung löschen</string>
<string name="sk_delete_notification_confirm">Benachrichtigung wirklich löschen\?</string>
<string name="sk_clear_all_notifications">Alle Benachrichtigungen löschen</string>
<string name="sk_clear_all_notifications_confirm_action">Alle löschen</string>
<string name="sk_clear_all_notifications_confirm">Wirklich alle Benachrichtigungen löschen\?</string>
<string name="sk_enable_delete_notifications">Löschen von Benachrichtigungen aktivieren</string>
<string name="sk_settings_publish_button_text">Veröffentlichen-Button-Text</string>
<string name="sk_settings_translate_only_opened">Nur geöffnete Beiträge übersetzen</string>
<string name="sk_delete_notification">Benachrichtigung löschen</string>
<string name="sk_clear_all_notifications">Alle Benachrichtigungen löschen</string>
<string name="sk_settings_publish_button_text_title">Veröffentlichen-Button-Text anpassen</string>
<string name="sk_clear_all_notifications_confirm">Wirklich alle Benachrichtigungen löschen\?</string>
<string name="sk_settings_translate_only_opened">Nur geöffnete Beiträge übersetzen</string>
<string name="sk_settings_translation_availability_note_available">%s unterstützt Übersetzung!</string>
<string name="sk_settings_translation_availability_note_unavailable">%s scheint keine Übersetzung zu unterstützen.</string>
<string name="sk_loading_fediverse_resource_title">Suche im Fediverse</string>
<string name="sk_loading_resource_on_instance_title">Suche auf %s</string>
<string name="sk_undo_reblog">Reblog rückgängig machen</string>
<string name="sk_reblog_with_visibility">Rebloggen mit Sichtbarkeit</string>
<string name="sk_quote_post">Drüberkommentieren</string>
@@ -89,7 +91,6 @@
<string name="sk_copy_link_to_post">Link zum Beitrag kopieren</string>
<string name="sk_open_with_account">Mit anderem Konto öffnen</string>
<string name="sk_resource_not_found">Ressource nicht gefunden</string>
<string name="sk_loading_resource_on_instance_title">Suche auf %s</string>
<string name="sk_bookmark_as">Lesezeichen mit anderem Konto</string>
<string name="sk_bookmarked_as">Lesezeichen gesetzt als %s</string>
<string name="sk_already_bookmarked">Bereits in den Lesezeichen</string>
@@ -116,16 +117,18 @@
<string name="sk_post_scheduled">Beitrag geplant</string>
<string name="sk_scheduled_too_soon_title">Geplante Zeit ist zu früh</string>
<string name="sk_scheduled_too_soon">Der Beitrag muss mindestens 10 Minuten in der Zukunft eingeplant werden.</string>
<string name="sk_confirm_save_changes">Änderungen speichern\?</string>
<string name="sk_schedule_post">Beitrag planen</string>
<string name="sk_confirm_save_draft">Entwurf speichern\?</string>
<string name="sk_confirm_save_changes">Änderungen speichern\?</string>
<string name="sk_mark_as_draft">Als Entwurf markieren</string>
<string name="sk_schedule_post">Beitrag planen</string>
<string name="sk_schedule_or_draft">Planen oder Vorlage</string>
<string name="sk_compose_no_schedule">Nicht planen</string>
<string name="sk_compose_no_draft">Nicht entwerfen</string>
<string name="sk_settings_reduce_motion">Bewegung in Animationen reduzieren</string>
<string name="sk_announcements">Ankündigungen</string>
<string name="sk_mark_as_read">Als gelesen markieren</string>
<string name="sk_settings_about_instance">Über die Instanz</string>
<string name="sk_settings_single_notification">Nur eine Benachrichtigung anzeigen</string>
<string name="sk_create">Erstellen</string>
<string name="sk_create_list_title">Liste erstellen</string>
<string name="sk_list_name_hint">Name der Liste</string>
@@ -134,18 +137,101 @@
<string name="sk_list_replies_policy_followed">gefolgten User_innen</string>
<string name="sk_list_replies_policy_none">niemandem</string>
<string name="sk_delete_list">Liste löschen</string>
<string name="sk_delete_list_confirm">Liste “%s” wirklich löschen\?</string>
<string name="sk_edit_list_title">Liste bearbeiten</string>
<string name="sk_your_lists">Deine Listen</string>
<string name="sk_announcements">Ankündigungen</string>
<string name="sk_settings_single_notification">Nur eine Benachrichtigung anzeigen</string>
<string name="sk_delete_list_confirm">Liste “%s” wirklich löschen\?</string>
<string name="sk_timeline_home">Start</string>
<string name="sk_timeline_local">Lokal</string>
<string name="sk_timeline_federated">Föderiert</string>
<string name="sk_recent_searches_placeholder">Tippe, um die Suche zu starten</string>
<string name="sk_remove_follower">Nicht mehr folgen lassen</string>
<string name="sk_remove_follower_confirm">%s als Follower_in entfernen\? Die Person wird dabei blockiert und gleich wieder freigegeben.</string>
<string name="sk_do_remove_follower">Entfernen</string>
<string name="sk_remove_follower_success">Follower_in erfolgreich entfernt</string>
<string name="sk_changelog">Änderungsverlauf</string>
<string name="sk_remove_follower">Nicht mehr folgen lassen</string>
<string name="sk_remove_follower_confirm">%s als Follower_in entfernen\? Die Person wird dabei blockiert und gleich wieder freigegeben.</string>
<string name="sk_alt_text_missing_title">Fehlende Bildbeschreibung</string>
<string name="sk_alt_text_missing">Mindestens ein Anhang hat keine Beschreibung.</string>
<string name="sk_publish_anyway">Trotzdem publizieren</string>
<string name="sk_settings_disable_alt_text_reminder">Bildbeschreibungs-Erinnerung deaktivieren</string>
<string name="sk_notify_posts_info_banner">Wenn du Beitrags Benachrichtigungen für jemanden aktiviert hast, erscheinen seine neuen Beiträge hier.</string>
<string name="sk_timelines">Timelines</string>
<string name="sk_timeline_posts">Beiträge</string>
<string name="sk_timelines_add">Hinzufügen</string>
<string name="sk_timeline">Timeline</string>
<string name="sk_list">Liste</string>
<string name="sk_hashtag">Hashtag</string>
<string name="sk_pin_timeline">Timeline anpinnen</string>
<string name="sk_unpin_timeline">Timeline lösen</string>
<string name="sk_pinned_timeline">An Start anpinnen</string>
<string name="sk_unpinned_timeline">Von Start lösen</string>
<string name="sk_remove">Entfernen</string>
<string name="sk_timeline_icon">Icon</string>
<string name="sk_icon_heart">Herz</string>
<string name="sk_icon_star">Stern</string>
<string name="sk_icon_city">Stadt</string>
<string name="sk_icon_cat">Katze</string>
<string name="sk_icon_dog">Hund</string>
<string name="sk_icon_rabbit">Hase</string>
<string name="sk_icon_turtle">Schildkröte</string>
<string name="sk_icon_balloon">Ballon</string>
<string name="sk_icon_image">Bild</string>
<string name="sk_icon_bot">Bot</string>
<string name="sk_icon_language">Sprache</string>
<string name="sk_icon_location">Standort</string>
<string name="sk_icon_megaphone">Megaphon</string>
<string name="sk_icon_microphone">Mikrophon</string>
<string name="sk_icon_microscope">Mikroskop</string>
<string name="sk_icon_keyboard">Tastatur</string>
<string name="sk_icon_coffee">Kaffee</string>
<string name="sk_icon_laugh">Lachen</string>
<string name="sk_icon_news">Nachrichten</string>
<string name="sk_icon_pi">Pi</string>
<string name="sk_icon_color_palette">Farbpalette</string>
<string name="sk_icon_academic_cap">Doktorhut</string>
<string name="sk_icon_tag">Etikett</string>
<string name="sk_icon_stethoscope">Stethoskop</string>
<string name="sk_icon_weather">Wetter</string>
<string name="sk_icon_games">Spiele</string>
<string name="sk_icon_code">Code</string>
<string name="sk_icon_light_bulb">Leuchtmittel</string>
<string name="sk_icon_train">Zug</string>
<string name="sk_icon_clapper_board">Filmklappe</string>
<string name="sk_icon_leaves">Blätter</string>
<string name="sk_icon_sport">Sport</string>
<string name="sk_icon_aperture">Blende</string>
<string name="sk_icon_music">Musik</string>
<string name="sk_icon_people">Personen</string>
<string name="sk_icon_health">Gesundheit</string>
<string name="sk_icon_important">Wichtig</string>
<string name="sk_icon_chat">Unterhaltung</string>
<string name="sk_icon_shield">Schild</string>
<string name="sk_icon_book">Buch</string>
<string name="sk_icon_bicycle">Fahrrad</string>
<string name="sk_icon_map">Karte</string>
<string name="sk_icon_math_formula">Formel</string>
<string name="sk_icon_backpack">Rucksack</string>
<string name="sk_icon_briefcase">Aktenkoffer</string>
<string name="sk_icon_fire">Feuer</string>
<string name="sk_icon_bug">Käfer</string>
<string name="sk_icon_pizza">Pizza</string>
<string name="sk_icon_gavel">Hammer</string>
<string name="sk_icon_gauge">Gage</string>
<string name="sk_icon_headphones">Kopfhörer</string>
<string name="sk_icon_human">Mensch</string>
<string name="sk_icon_globe">Globus</string>
<string name="sk_icon_pin">Pin</string>
<string name="sk_edit_timeline">Timeline bearbeiten</string>
<string name="sk_edit_timelines">Timelines bearbeiten</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">bearbeitet</string>
<string name="sk_notification_type_update">Bearbeitete Beiträge</string>
<string name="sk_notify_update">Bearbeitet einen geteilten Beitrag</string>
<string name="sk_attach_file">Datein anhängen</string>
<string name="sk_searching">Suche…</string>
<string name="sk_no_results">Keine Ergebnisse</string>
<string name="sk_save_draft">Entwurf speichern\?</string>
<string name="sk_save_draft_message">Möchtest du die Änderungen an diesem Entwurf speichern oder jetzt veröffentlichen\?</string>
<string name="sk_no_alt_text">Kein Bildbeschreibung verfügbar</string>
<string name="sk_settings_show_alt_indicator">Indikator für Bildbeschreibungen</string>
<string name="sk_settings_show_no_alt_indicator">Indikator für fehlende Bildbeschreibungen</string>
</resources>

View File

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

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mo_color_palette_nord">Nord</string>
<string name="mo_disable_dividers">Desactivar divisores de publicaciones</string>
<string name="mo_relocate_publish_button">Recolocar botón de publicación</string>
<string name="mo_hide_compose_button_while_scrolling_setting">Esconder botón de escritura al deslizar</string>
<string name="mo_welcome_text">Para empezar introduce el nombre del dominio de tu instancia debajo, por favor.</string>
<string name="mo_personal_note">Añade una nota sobre este perfil</string>
<string name="mo_personal_note_confirm">Confirmar cambios en la nota</string>
<string name="mo_personal_note_update_failed">Fallo al guardar la nota</string>
<string name="mo_update_available">Moshidon %s se puede descargar.</string>
<string name="mo_update_ready">Moshidon %s se ha descargado y se puede instalar.</string>
<string name="mo_no_image_desc_title">Sin descripción de imagen</string>
<string name="mo_emoji_recent">Usados recientemente</string>
<string name="mo_clear_recent_emoji">Borrar emojis usados recientemente</string>
<string name="mo_disable_relocate_publish_button_to_enable_customization">Desactiva \"Recolocar botón de publicación\" para poder personalizar</string>
<string name="mo_poll_option_add">Añadir nueva opción en la encuesta</string>
<string name="mo_fab_compose">Componer</string>
<string name="mo_sending_error">Error al publicar</string>
<string name="mo_settings_contribute">Contribuir en Moshidon</string>
<string name="mo_no_image_desc">Las imágenes incluidas no tienen descripción. Por favor, piénsate añadir una para permitir a las personas con discapacidad participar.</string>
</resources>

View File

@@ -11,7 +11,7 @@
<string name="sk_unpin_post">Desanclar del perfil</string>
<string name="sk_confirm_unpin_post_title">Desanclar publicación del perfil</string>
<string name="sk_confirm_unpin_post">¿Confirma que quiere desanclar esta publicación\?</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_unpinning">Desanclando publicación…</string>
<string name="sk_image_description">Descripción de la imagen</string>
<string name="sk_visibility_unlisted">Descatalogada</string>
@@ -24,8 +24,8 @@
<string name="sk_user_post_notifications_off">Desactivadas las notificaciones de posts para %s</string>
<string name="sk_federated_timeline">Federación</string>
<string name="sk_federated_timeline_info_banner">Estas son las publicaciones más recientes de las personas de su federación.</string>
<string name="sk_update_available">Moshidon %s está listo para descargar.</string>
<string name="sk_update_ready">Moshidon %s se ha descargado y está listo para instalarse.</string>
<string name="sk_update_available">Megalodon %s está listo para descargar.</string>
<string name="sk_update_ready">Megalodon %s se ha descargado y está listo para instalarse.</string>
<string name="sk_check_for_update">Buscar actualizaciones</string>
<string name="sk_no_update_available">No hay actualizaciones disponibles</string>
<string name="sk_list_timelines">Listas</string>
@@ -35,9 +35,9 @@
<string name="sk_lists_with_user">Editar listas con %s</string>
<string name="sk_settings_always_reveal_content_warnings">Mostrar siempre advertencias de contenido</string>
<string name="sk_disable_marquee">Desactivar desplazamiento de texto en barras del título</string>
<string name="sk_settings_contribute">Contribuir a Moshidon</string>
<string name="sk_settings_contribute">Contribuir a Megalodon</string>
<string name="sk_settings_show_federated_timeline">Mostrar cronología federada</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_notification_type_status">Publicaciones</string>
<string name="sk_notify_posts">Publicar notificaciones</string>
<string name="sk_settings_color_palette">Colores para los temas</string>

View File

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

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_delete_and_redraft">Ezabatu eta editatu</string>
<string name="sk_confirm_delete_and_redraft_title">Argitalpena ezabatu eta editatu</string>
<string name="sk_pin_post">Profilean finkatu</string>
@@ -15,12 +15,12 @@
<string name="sk_settings_show_replies">Erakutsi erantzunak</string>
<string name="sk_settings_show_boosts">Erakutsi bultzadak</string>
<string name="sk_settings_show_interaction_counts">Erakutsi interakzio zenbaketak</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Markatu multimedia sentikor gisa</string>
<string name="sk_user_post_notifications_on">Gaitu %s-en argitalpen jakinarazpenak</string>
<string name="sk_federated_timeline">Federatua</string>
<string name="sk_federated_timeline_info_banner">Hauek dira zure federazioko pertsonen argitalpen berrienak.</string>
<string name="sk_update_available">Moshidon %s deskargatzeko prest dago.</string>
<string name="sk_update_available">Megalodon %s deskargatzeko prest dago.</string>
<string name="sk_check_for_update">Eguneraketak egiaztatu</string>
<string name="sk_no_update_available">Ez dago eguneraketarik eskuragarri</string>
<string name="sk_list_timelines">Zerrendak</string>
@@ -32,7 +32,7 @@
<string name="sk_lists_with_user">%s-ekin zerrendatu</string>
<string name="sk_settings_always_reveal_content_warnings">Erakutsi beti edukiaren abisua</string>
<string name="sk_disable_marquee">Desgaitu izenburu-barretako testuaren desplazamendua</string>
<string name="sk_settings_contribute">Lagundu Moshidon</string>
<string name="sk_settings_contribute">Lagundu Megalodon</string>
<string name="sk_translated_using">%s-ekin itzulia</string>
<string name="sk_post_language">Hizkuntza: %s</string>
<string name="sk_language_name">%s (%s)</string>
@@ -88,7 +88,7 @@
<string name="sk_confirm_unpin_post_title">Argitalpen finkatua kendu profiletik</string>
<string name="sk_settings_load_new_posts">Kargatu automatikoki argitalpen berriak</string>
<string name="sk_user_post_notifications_off">Desgaitu %s-en argitalpen jakinarazpenak</string>
<string name="sk_update_ready">Moshidon %s deskargatuta eta instalatzeko prest dago.</string>
<string name="sk_update_ready">Megalodon %s deskargatuta eta instalatzeko prest dago.</string>
<string name="sk_accept_follow_request">Onartu jarraitzeko eskaerak</string>
<string name="sk_reject_follow_request">Alboratu jarraitzeko eskaerak</string>
<string name="sk_settings_show_federated_timeline">Erakutsi federatutako denbora-lerroa</string>

View File

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

View File

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

View File

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

View File

@@ -13,12 +13,12 @@
<string name="sk_settings_show_replies">Afficher les réponses</string>
<string name="sk_settings_show_boosts">Afficher les boosts</string>
<string name="sk_settings_load_new_posts">Charger automatiquement les nouveaux messages</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Marquer le média comme sensible</string>
<string name="sk_user_post_notifications_on">Notifications de message activées pour %s</string>
<string name="sk_user_post_notifications_off">Désactivation des notifications de message pour %s</string>
<string name="sk_update_available">Moshidon %s est prête à être téléchargée.</string>
<string name="sk_update_ready">Moshidon %s est téléchargée et prête à être installée.</string>
<string name="sk_update_available">Megalodon %s est prête à être téléchargée.</string>
<string name="sk_update_ready">Megalodon %s est téléchargée et prête à être installée.</string>
<string name="sk_check_for_update">Vérifier les mises à jour</string>
<string name="sk_no_update_available">Pas de mise a jour disponible</string>
<string name="sk_list_timelines">Listes</string>
@@ -28,9 +28,9 @@
<string name="sk_lists_with_user">Modifier les listes avec %s</string>
<string name="sk_settings_always_reveal_content_warnings">Toujours afficher les avertissements de contenu</string>
<string name="sk_disable_marquee">Désactiver le défilement du texte dans les barres de titre</string>
<string name="sk_settings_contribute">Contribuez à Moshidon</string>
<string name="sk_settings_contribute">Contribuez à Megalodon</string>
<string name="sk_settings_show_federated_timeline">Afficher la timeline fédérée</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_delete_and_redraft">Supprimer et rééditer</string>
<string name="sk_pin_post">Épingler au profil</string>
<string name="sk_confirm_pin_post_title">Épingler le message au profil</string>

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_delete_and_redraft">Eliminar e rescribir</string>
<string name="sk_confirm_delete_and_redraft">Tes a certeza de querere eliminar e rescribir esta publicación\?</string>
<string name="sk_pinned_posts">Fixado</string>
@@ -20,14 +20,14 @@
<string name="sk_settings_show_boosts">Mostrar promocións</string>
<string name="sk_settings_load_new_posts">Cargar automáticamente novas publicacións</string>
<string name="sk_settings_show_interaction_counts">Mostrar contadores de interaccións</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Marcar multimedia como sensible</string>
<string name="sk_user_post_notifications_on">Acender notificación de publicación para %s</string>
<string name="sk_user_post_notifications_off">Apagar notificación de publicación para %s</string>
<string name="sk_federated_timeline">Federación</string>
<string name="sk_federated_timeline_info_banner">Estas son as publicacións máis recentes das persoas da túa federación.</string>
<string name="sk_update_available">Moshidon %s está lista para descargar.</string>
<string name="sk_update_ready">Moshidon %s foi descargada e está lista para instalar.</string>
<string name="sk_update_available">Megalodon %s está lista para descargar.</string>
<string name="sk_update_ready">Megalodon %s foi descargada e está lista para instalar.</string>
<string name="sk_check_for_update">Comprobar actualizacións</string>
<string name="sk_no_update_available">Non hai actualizacións</string>
<string name="sk_list_timelines">Listas</string>

View File

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

View File

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

View File

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

View File

@@ -19,14 +19,14 @@
<string name="sk_unpinning">Unpinning poszt…</string>
<string name="sk_settings_show_replies">Válaszok megjelenítése</string>
<string name="sk_visibility_unlisted">Felsorolatlan</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_settings_load_new_posts">Automatikusan töltse be az új hozzászólásokat</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_user_post_notifications_on">Bekapcsoltuk a postai értesítéseket %s számára</string>
<string name="sk_user_post_notifications_off">Kikapcsoltam a postai értesítéseket %s számára</string>
<string name="sk_mark_media_as_sensitive">A média érzékenynek jelölése</string>
<string name="sk_federated_timeline">Föderáció</string>
<string name="sk_update_ready">A Moshidon %s letöltődött és telepítésre kész.</string>
<string name="sk_update_ready">A Megalodon %s letöltődött és telepítésre kész.</string>
<string name="sk_disable_marquee">A görgethető szöveg kikapcsolása a címsorokban</string>
<string name="sk_check_for_update">Frissítés ellenőrzése</string>
<string name="sk_no_update_available">Nincs frissítés elérhető</string>
@@ -35,7 +35,7 @@
<string name="sk_accept_follow_request">Követési kérés elfogadása</string>
<string name="sk_lists_with_user">%s-t tartalmazó listák</string>
<string name="sk_settings_always_reveal_content_warnings">Mindig fedje fel a tartalmi figyelmeztetéseket</string>
<string name="sk_settings_contribute">Hozzájárulni Moshidon</string>
<string name="sk_settings_contribute">Hozzájárulni Megalodon</string>
<string name="sk_settings_show_federated_timeline">Összevont idővonal megjelenítése</string>
<string name="sk_confirm_clear_recent_languages">Biztos, hogy törölni szeretné a nemrég használt nyelveket\?</string>
<string name="sk_available_languages">Elérhető nyelvek</string>
@@ -115,7 +115,7 @@
<string name="sk_welcome_text">A cápa tiszteleg előtted! A kezdéshez kérjük, adja meg az alábbiakban az otthoni domain nevét.</string>
<string name="sk_federated_timeline_info_banner">Ezek a szövetséged tagjainak legfrissebb bejegyzései.</string>
<string name="sk_confirm_delete_and_redraft">Biztos, hogy törölni és újrafogalmazni akarod ezt a hozzászólást\?</string>
<string name="sk_update_available">Moshidon %s készen áll a letöltésre.</string>
<string name="sk_update_available">Megalodon %s készen áll a letöltésre.</string>
<string name="sk_confirm_delete_and_redraft_title">Törlés és újraszövegezés Hozzászólás</string>
<string name="sk_image_description">Kép leírása</string>
<string name="sk_settings_show_boosts">Show boostok</string>

View File

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

View File

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

View File

@@ -12,23 +12,23 @@
<string name="sk_settings_show_boosts">Lihat boost</string>
<string name="sk_settings_load_new_posts">Muat kiriman baru secara otomatis</string>
<string name="sk_settings_show_interaction_counts">Tampilkan jumlah interaksi</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_user_post_notifications_on">Nyalakan notifikasi kiriman untuk %s</string>
<string name="sk_user_post_notifications_off">Matikan notifikasi kiriman untuk %s</string>
<string name="sk_federated_timeline">Federasi</string>
<string name="sk_federated_timeline_info_banner">Kiriman terbaru dari orang-orang di federasi anda.</string>
<string name="sk_update_available">Moshidon %s siap untuk diunduh.</string>
<string name="sk_update_ready">Moshidon %s telah diunduh dan siap dipasang.</string>
<string name="sk_update_available">Megalodon %s siap untuk diunduh.</string>
<string name="sk_update_ready">Megalodon %s telah diunduh dan siap dipasang.</string>
<string name="sk_check_for_update">Periksa pembaruan</string>
<string name="sk_no_update_available">Tidak ada pembaruan</string>
<string name="sk_list_timelines">Daftar</string>
<string name="sk_unpinning">Menghapus sematan kiriman…</string>
<string name="sk_accept_follow_request">Terima permintaan pengikut</string>
<string name="sk_reject_follow_request">Tolak permintaan pengikut</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_confirm_delete_and_redraft">Hapus dan tulis ulang kiriman ini\?</string>
<string name="sk_confirm_unpin_post">Apakah Anda yakin untuk menghapus sematan kiriman ini\?</string>
<string name="sk_settings_contribute">Berkontribusi ke Moshidon</string>
<string name="sk_settings_contribute">Berkontribusi ke Megalodon</string>
<string name="sk_pinned_posts">Disematkan</string>
<string name="sk_pin_post">Sematkan ke profil</string>
<string name="sk_visibility_unlisted">Tidak terdaftar</string>

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
<string name="sk_color_palette_blue">Blu</string>
<string name="sk_color_palette_brown">Marrone</string>
<string name="sk_color_palette_yellow">Giallo</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Fissati</string>
<string name="sk_delete_and_redraft">Elimina e riscrivi</string>
<string name="sk_user_post_notifications_on">Attivate notifiche per i post di %s</string>
@@ -32,18 +32,18 @@
<string name="sk_settings_show_boosts">Mostra boost</string>
<string name="sk_settings_load_new_posts">Carica automaticamente nuovi post</string>
<string name="sk_settings_show_interaction_counts">Mostra conteggi interazioni</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Segnala media come sensibile</string>
<string name="sk_federated_timeline">Federata</string>
<string name="sk_federated_timeline_info_banner">Questi sono i post più recenti dalle persone nella tua federazione.</string>
<string name="sk_update_available">Moshidon %s è pronto da scaricare.</string>
<string name="sk_update_ready">Moshidon %s è scaricato e pronto da installare.</string>
<string name="sk_update_available">Megalodon %s è pronto da scaricare.</string>
<string name="sk_update_ready">Megalodon %s è scaricato e pronto da installare.</string>
<string name="sk_check_for_update">Verifica aggiornamenti</string>
<string name="sk_no_update_available">Non ci sono aggiornamenti disponibili</string>
<string name="sk_list_timelines">Liste</string>
<string name="sk_settings_always_reveal_content_warnings">Apri sempre contenuti segnalati come sensibili</string>
<string name="sk_lists_with_user">Modifica liste con %s</string>
<string name="sk_settings_contribute">Contribuisci a Moshidon</string>
<string name="sk_settings_contribute">Contribuisci a Megalodon</string>
<string name="sk_settings_show_federated_timeline">Mostra timeline federata</string>
<string name="sk_disable_marquee">Disabilita scorrimento titoli</string>
<string name="sk_reject_follow_request">Rifiuta richiesta di seguirti</string>

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,10 +32,10 @@
<string name="sk_lists_with_user">%s 님이 포함된 리스트 수정</string>
<string name="sk_settings_always_reveal_content_warnings">열람주의 게시물을 항상 펼치기</string>
<string name="sk_disable_marquee">제목 표시줄의 텍스트 스크롤 비활성화</string>
<string name="sk_app_name">Moshidon</string>
<string name="sk_settings_app_version">Moshidon v%1$s (%2$d)</string>
<string name="sk_update_available">Moshidon %s 버전을 다운로드할 수 있습니다.</string>
<string name="sk_update_ready">Moshidon %s 버전을 다운로드하였으며 설치할 수 있습니다.</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_update_available">Megalodon %s 버전을 다운로드할 수 있습니다.</string>
<string name="sk_update_ready">Megalodon %s 버전을 다운로드하였으며 설치할 수 있습니다.</string>
<string name="sk_settings_show_federated_timeline">연합 타임라인 표시</string>
<string name="sk_notification_type_status">게시물</string>
<string name="sk_notify_posts">게시물 알림</string>
@@ -46,7 +46,7 @@
<string name="sk_color_palette_blue">파란색</string>
<string name="sk_color_palette_brown">갈색</string>
<string name="sk_color_palette_yellow">노란색</string>
<string name="sk_settings_contribute">Moshidon에 기여</string>
<string name="sk_settings_contribute">Megalodon에 기여</string>
<string name="sk_poll_allow_multiple">다중 선택 허용</string>
<string name="sk_translate_post">번역하기</string>
<string name="sk_translate_show_original">원본 보기</string>

View File

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

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">Moshidon</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_delete_and_redraft">ဖျက်ပြီး ပြန်ရေးမည်</string>
<string name="sk_pin_post">ပရိုဖိုင်းတွင် ပင်တွဲမည်</string>
<string name="sk_pinning">ပင်တွဲနေသည်…</string>
@@ -10,12 +10,12 @@
<string name="sk_image_description">ပုံတွင်ပါဝင်သော အကြောင်းအရာ</string>
<string name="sk_visibility_unlisted">စာရင်းမလုပ်</string>
<string name="sk_settings_show_boosts">Boost များကို ပြသမည်</string>
<string name="sk_settings_app_version">Moshidon - ဗားရှင်း %1$s (%2$d)</string>
<string name="sk_settings_app_version">Megalodon - ဗားရှင်း %1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">ပုံ/ဗီဒီယိုအား ထိရှလွယ်သည်အဖြစ် မှတ်သားသည်</string>
<string name="sk_user_post_notifications_off">%s အတွက် ပို့စ်နိုတီများကို ပိတ်လိုက်သည်</string>
<string name="sk_federated_timeline">ဖက်ဒရေးရှင်း</string>
<string name="sk_update_available">Moshidon %s ကို ဒေါင်းလုဒ်ဆွဲလို့ရပါပြီ။</string>
<string name="sk_update_ready">Moshidon %s ကို ဒေါင်းလုဒ်ဆွဲပြီးပြီမလို့ အင်စတောလုပ်နိုင်ပါပြီ။</string>
<string name="sk_update_available">Megalodon %s ကို ဒေါင်းလုဒ်ဆွဲလို့ရပါပြီ။</string>
<string name="sk_update_ready">Megalodon %s ကို ဒေါင်းလုဒ်ဆွဲပြီးပြီမလို့ အင်စတောလုပ်နိုင်ပါပြီ။</string>
<string name="sk_no_update_available">မည်သည့်အပ်ဒိတ်မျှ မရှိသေးပါ</string>
<string name="sk_follow_requests">ဖော်လိုဝါအဖြစ် တောင်းဆိုမှုများ</string>
<string name="sk_accept_follow_request">ဖော်လိုဝါအဖြစ်တောင်းဆိုမှုကို လက်ခံမည်</string>

View File

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

Some files were not shown because too many files have changed in this diff Show More