Compare commits
174 Commits
v1.1.5+for
...
v1.1.5+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2799fcdff | ||
|
|
8e4f402e21 | ||
|
|
10d2949647 | ||
|
|
30ef23308b | ||
|
|
564132ee82 | ||
|
|
1e527e87df | ||
|
|
9692a04275 | ||
|
|
6ece8eb0c1 | ||
|
|
1f33237e8a | ||
|
|
9209508aac | ||
|
|
f750e6ff7e | ||
|
|
f2eecf774b | ||
|
|
98de4e75e0 | ||
|
|
459e32caf8 | ||
|
|
c4ad325e5c | ||
|
|
f55bd6d6cd | ||
|
|
f1ce700c93 | ||
|
|
c18e1e8456 | ||
|
|
1fcd1924c3 | ||
|
|
a1767f0425 | ||
|
|
44d95ca25f | ||
|
|
7432540c29 | ||
|
|
c289f58351 | ||
|
|
711e041ff5 | ||
|
|
0ac3534585 | ||
|
|
57821e0860 | ||
|
|
0dae798c9a | ||
|
|
732e780fd9 | ||
|
|
5577124b7a | ||
|
|
81b82c75a2 | ||
|
|
b32e322749 | ||
|
|
3031cc4561 | ||
|
|
d60abc648c | ||
|
|
a9a0233bb3 | ||
|
|
f6fa9e5122 | ||
|
|
29b4f7c91a | ||
|
|
0a9ee57233 | ||
|
|
94b69a9c1c | ||
|
|
f0209dd1cc | ||
|
|
366e432c18 | ||
|
|
0075c0e779 | ||
|
|
d99dfd4185 | ||
|
|
0309b3ad25 | ||
|
|
7a85532b73 | ||
|
|
7299d947f7 | ||
|
|
adec7b28f1 | ||
|
|
c2563da056 | ||
|
|
64b9e53916 | ||
|
|
86ab6f7b3d | ||
|
|
ed02733524 | ||
|
|
a99af63f34 | ||
|
|
1d900a66fe | ||
|
|
f29acc217d | ||
|
|
f60164f5c5 | ||
|
|
578cf1f00d | ||
|
|
bca3bc6b4a | ||
|
|
352c813544 | ||
|
|
7d876bddc7 | ||
|
|
43d334259b | ||
|
|
750579b1c2 | ||
|
|
d69221d85b | ||
|
|
a1c80e92cd | ||
|
|
ce1a0d66f1 | ||
|
|
f28057d620 | ||
|
|
8f6dc7e6d2 | ||
|
|
b25a237c20 | ||
|
|
ccb0b59e17 | ||
|
|
14658a2d70 | ||
|
|
5f26878c06 | ||
|
|
df78ae59fe | ||
|
|
47924dfb61 | ||
|
|
3eb442e0f6 | ||
|
|
b309fc09f6 | ||
|
|
a00fe0485b | ||
|
|
a60f65857b | ||
|
|
fe584b58b0 | ||
|
|
91ad2bf66b | ||
|
|
01988a9435 | ||
|
|
51bc8e1b2c | ||
|
|
b28c684bd3 | ||
|
|
42b2cde1e2 | ||
|
|
199a7b816c | ||
|
|
2b8fc6764e | ||
|
|
37f93cda4d | ||
|
|
4114f5b3c2 | ||
|
|
14d45eb759 | ||
|
|
0dfa9d2c2c | ||
|
|
6fce18ffe8 | ||
|
|
956c56c494 | ||
|
|
75e7c6a9eb | ||
|
|
a7fb66d269 | ||
|
|
5f48802357 | ||
|
|
a27488c8da | ||
|
|
b6dbd7512c | ||
|
|
e41386082c | ||
|
|
ae385c139b | ||
|
|
dd2f213a4f | ||
|
|
35f92a6e91 | ||
|
|
ab5648a5d6 | ||
|
|
8a9b59c66a | ||
|
|
a6e0c877b5 | ||
|
|
de5a623a00 | ||
|
|
b0f9ce081f | ||
|
|
e17b6e83a4 | ||
|
|
96f4322f74 | ||
|
|
780f59d666 | ||
|
|
8c5db2eef5 | ||
|
|
5ab004b87e | ||
|
|
1b001bdd4f | ||
|
|
a5fa44213d | ||
|
|
68e9d9d91c | ||
|
|
a14783a275 | ||
|
|
3ce58d2edf | ||
|
|
523efac4fb | ||
|
|
d352aca9cc | ||
|
|
ae6afab01b | ||
|
|
efea405b83 | ||
|
|
ad9262cf0f | ||
|
|
636c268e46 | ||
|
|
06a61f0374 | ||
|
|
4ba7763de5 | ||
|
|
b486542e7b | ||
|
|
f53ce6cbf0 | ||
|
|
b10ff655f1 | ||
|
|
bbc27dbeea | ||
|
|
dadb929afd | ||
|
|
c0f397cdd5 | ||
|
|
b597cf6e18 | ||
|
|
e3bbeb2022 | ||
|
|
cad9fc8977 | ||
|
|
2f191c1f71 | ||
|
|
dc0debce1a | ||
|
|
d96b6f0100 | ||
|
|
16f1901976 | ||
|
|
61d9e4d531 | ||
|
|
aec4479e19 | ||
|
|
ec7235c03a | ||
|
|
f3db153ea9 | ||
|
|
e1c258478f | ||
|
|
1f2e691eb1 | ||
|
|
be9a3a9975 | ||
|
|
8d17ac6f28 | ||
|
|
d9df150cf8 | ||
|
|
667a4aab1a | ||
|
|
862ffd8172 | ||
|
|
eb1dd954ee | ||
|
|
6f2e5a63d7 | ||
|
|
5bf78c5cd2 | ||
|
|
277361a562 | ||
|
|
6697d3d0d5 | ||
|
|
7202aae712 | ||
|
|
6d2c6748f7 | ||
|
|
6c98c9ccf2 | ||
|
|
afc25ec8b3 | ||
|
|
6c9553ba65 | ||
|
|
0fd5ea4689 | ||
|
|
8441208058 | ||
|
|
aa34298771 | ||
|
|
ccacd88f80 | ||
|
|
1f20b21fc8 | ||
|
|
ae7152aca7 | ||
|
|
ba36347f03 | ||
|
|
c0c5e83f31 | ||
|
|
9c05ff2f7c | ||
|
|
0ada05bf3a | ||
|
|
c77b5dfac2 | ||
|
|
673ea40238 | ||
|
|
f7ced7f253 | ||
|
|
6152ec9d0d | ||
|
|
7ed8bb259d | ||
|
|
06882d5bea | ||
|
|
f460456502 | ||
|
|
6ef9f2ff15 | ||
|
|
062af9937f |
19
README.md
19
README.md
@@ -13,16 +13,13 @@
|
||||
> A fork of the [official Mastodon Android app](https://github.com/mastodon/mastodon-android) adding important features that are missing in the official app and possibly won’t ever be implemented, such as the federated timeline, unlisted posting and an image description viewer.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Key features
|
||||
|
||||
### **Unlisted posting**
|
||||
|
||||
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Local”, “Community” and “Posts”).**
|
||||
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Community”, “Federated” and “Posts”).**
|
||||
|
||||
When posting with Unlisted visibility, your posts will still be publicly accessible in your profile. They will also be shown in people’s Home timelines, but only if they follow you or someone they follow reposted/replied to your post.
|
||||
When posting with Unlisted visibility, your posts will still be publicly accessible in your profile. They will also be shown in people’s Home timelines, but only if they follow you or someone they follow reblogged/replied to your post.
|
||||
|
||||
The Mastodon documentation has some more information about [Unlisted posting](https://docs.joinmastodon.org/user/posting/#unlisted) and [Public timelines](https://docs.joinmastodon.org/user/network/#timelines).
|
||||
|
||||
@@ -120,7 +117,7 @@ There's also a handful of custom strings exclusive to this projects that would n
|
||||
* [Implement a bookmark button and list](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/bookmarks) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/22))
|
||||
* [Add “Check for update” button in addition to integrated update checker](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/check-for-update-button)
|
||||
* [Add “Mark media as sensitive” option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/mark-media-as-sensitive)
|
||||
* [Add settings to hide replies and reposts from the timeline](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
|
||||
* [Add settings to hide replies and reblogs from the timeline](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
|
||||
* [Follow and unfollow hashtags](https://github.com/sk22/megalodon/commit/7d38f031f197aa6cefaf53e39d929538689c1e4e) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/233))
|
||||
* [Notification bell for posts](https://github.com/sk22/megalodon/commit/b166ca705eb9169025ef32bbe6315b42491b57ea) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/81))
|
||||
* [Viewing lists and adding/removing users from lists](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:list-timeline-views) based on [@obstsalatschuessel](https://github.com/obstsalatschuessel)'s [Pull request](https://github.com/mastodon/mastodon-android/pull/286)
|
||||
@@ -135,6 +132,8 @@ There's also a handful of custom strings exclusive to this projects that would n
|
||||
* [Add option to allow voting for multiple options on polls](https://github.com/sk22/megalodon/commit/5b28468efd49387b4f8b83f142f3adf3104ca60c)
|
||||
* [Add translate function](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/translate-button)
|
||||
* [Add language selector](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/language-selector)
|
||||
* [Implement deleting notifications](https://github.com/sk22/megalodon/commit/b0f9ce081f69f29ad59658fc00ca41372cd2677d) (disabled by default)
|
||||
* [Long-click boost button to "quote" a post](https://github.com/sk22/megalodon/commit/b25a237c20c6a924ed4d9b357999867c3a32b32b)
|
||||
|
||||
|
||||
### Behavior
|
||||
@@ -152,6 +151,11 @@ There's also a handful of custom strings exclusive to this projects that would n
|
||||
* [Make inline emoji search case-insensitive and don't only search from start of emoji names](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:better-inline-emoji-search) ([Pull request](https://github.com/mastodon/mastodon-android/pull/445))
|
||||
* [Include subject line when sharing e.g. a website to Megalodon](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:external-share-include-subject)
|
||||
* [Improve semantics for voting on polls (radio buttons and checkboxes)](https://github.com/sk22/megalodon/commit/6fd58c96827cb1d2da329cebdc170a1425dd18d7)
|
||||
* [Copy post URL when long-pressing share button](https://github.com/sk22/megalodon/commit/ba36347f03278763ecec617b1ce57ba89db7be72)
|
||||
* [Add option to disable swiping between tabs](https://github.com/sk22/megalodon/commit/1f20b21fc84bf006c1ec14bd2229cbfad5215ec8)
|
||||
* [Resolve Fediverse links in the app](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/open-urls-in-app)
|
||||
* [Preserve whitespaces in HTML](https://github.com/sk22/megalodon/commit/7d876bddc7a07d98f0fecbf62b13bdb9fcce3412)
|
||||
* [Long-click to copy links](https://github.com/sk22/megalodon/commit/b32e32274923a94742a9926ef38785f746d41405)
|
||||
|
||||
|
||||
### Visual
|
||||
@@ -163,8 +167,9 @@ There's also a handful of custom strings exclusive to this projects that would n
|
||||
* [Custom "megalodon" text logo](https://github.com/sk22/megalodon/commit/563afd487ca5c608cfbb00fa3909d3c27384acc0) by [@LucasGGamerM](https://github.com/LucasGGamerM)
|
||||
* [Custom login screen](https://github.com/sk22/megalodon/commit/9bbf8c4618dbe13accaeb3b5482bf3fe88cac4c0)
|
||||
* [More distinct filled boost icon](https://github.com/sk22/megalodon/commits/more-distinct-filled-boost-icon)
|
||||
* [Material You color theme] by [@LucasGGamerM](https://github.com/LucasGGamerM)
|
||||
* Material You color theme by [@LucasGGamerM](https://github.com/LucasGGamerM)
|
||||
* [Animations for interaction buttons](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/animate-buttons)
|
||||
* [Dedicated icons for different notification types](https://github.com/sk22/megalodon/pull/178) by [@florian-obernberger](https://github.com/florian-obernberger)
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
3
fix-metadata-markdown-lists.sh
Executable file
3
fix-metadata-markdown-lists.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
find metadata -name '*.txt' -exec sed -Ei 's/^[–—─•·*]\s+/- /' {} \;
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "org.joinmastodon.android.sk"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 60
|
||||
versionName "1.1.5+fork.60"
|
||||
versionCode 63
|
||||
versionName "1.1.5+fork.63"
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
|
||||
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
@@ -52,7 +52,8 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
||||
|
||||
Intent intent=getIntent();
|
||||
StringBuilder builder=new StringBuilder();
|
||||
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) builder.append(intent.getStringExtra(Intent.EXTRA_SUBJECT)).append("\n\n");
|
||||
String subject = "";
|
||||
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) builder.append(subject = intent.getStringExtra(Intent.EXTRA_SUBJECT)).append("\n\n");
|
||||
if (intent.hasExtra(Intent.EXTRA_TEXT)) builder.append(intent.getStringExtra(Intent.EXTRA_TEXT)).append("\n");
|
||||
String text=builder.toString();
|
||||
List<Uri> mediaUris;
|
||||
@@ -80,6 +81,8 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
||||
args.putString("account", accountID);
|
||||
if(!TextUtils.isEmpty(text))
|
||||
args.putString("prefilledText", text);
|
||||
if(!subject.isBlank())
|
||||
args.putInt("selectionEnd", subject.length());
|
||||
if(mediaUris!=null && !mediaUris.isEmpty())
|
||||
args.putParcelableArrayList("mediaAttachments", toArrayList(mediaUris));
|
||||
Fragment fragment=new ComposeFragment();
|
||||
|
||||
@@ -5,8 +5,6 @@ import static org.joinmastodon.android.api.MastodonAPIController.gson;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@@ -26,7 +24,11 @@ public class GlobalUserPreferences{
|
||||
public static boolean showInteractionCounts;
|
||||
public static boolean alwaysExpandContentWarnings;
|
||||
public static boolean disableMarquee;
|
||||
public static boolean disableSwipe;
|
||||
public static boolean voteButtonForSingleChoice;
|
||||
public static boolean enableDeleteNotifications;
|
||||
public static boolean translateButtonOpenedOnly;
|
||||
public static String publishButtonText;
|
||||
public static ThemePreference theme;
|
||||
public static ColorPreference color;
|
||||
|
||||
@@ -54,7 +56,11 @@ public class GlobalUserPreferences{
|
||||
showInteractionCounts=prefs.getBoolean("showInteractionCounts", false);
|
||||
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
|
||||
disableMarquee=prefs.getBoolean("disableMarquee", false);
|
||||
disableSwipe=prefs.getBoolean("disableSwipe", false);
|
||||
voteButtonForSingleChoice=prefs.getBoolean("voteButtonForSingleChoice", true);
|
||||
enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", false);
|
||||
translateButtonOpenedOnly=prefs.getBoolean("translateButtonOpenedOnly", false);
|
||||
publishButtonText=prefs.getString("publishButtonText", "");
|
||||
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
||||
recentLanguages=fromJson(prefs.getString("recentLanguages", "{}"), recentLanguagesType, new HashMap<>());
|
||||
|
||||
@@ -78,6 +84,10 @@ public class GlobalUserPreferences{
|
||||
.putBoolean("showInteractionCounts", showInteractionCounts)
|
||||
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
|
||||
.putBoolean("disableMarquee", disableMarquee)
|
||||
.putBoolean("disableSwipe", disableSwipe)
|
||||
.putBoolean("enableDeleteNotifications", enableDeleteNotifications)
|
||||
.putBoolean("translateButtonOpenedOnly", translateButtonOpenedOnly)
|
||||
.putString("publishButtonText", publishButtonText)
|
||||
.putInt("theme", theme.ordinal())
|
||||
.putString("color", color.name())
|
||||
.putString("recentLanguages", gson.toJson(recentLanguages))
|
||||
@@ -92,7 +102,6 @@ public class GlobalUserPreferences{
|
||||
BLUE,
|
||||
BROWN,
|
||||
RED,
|
||||
ORANGE,
|
||||
YELLOW
|
||||
}
|
||||
|
||||
|
||||
@@ -137,13 +137,20 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
||||
builder.setContentTitle(pn.title)
|
||||
.setContentText(pn.body)
|
||||
.setStyle(new Notification.BigTextStyle().bigText(pn.body))
|
||||
.setSmallIcon(R.drawable.ic_ntf_logo)
|
||||
.setContentIntent(PendingIntent.getActivity(context, accountID.hashCode() & 0xFFFF, contentIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.setWhen(notification==null ? System.currentTimeMillis() : notification.createdAt.toEpochMilli())
|
||||
.setShowWhen(true)
|
||||
.setCategory(Notification.CATEGORY_SOCIAL)
|
||||
.setAutoCancel(true)
|
||||
.setColor(context.getColor(R.color.primary_700));
|
||||
.setColor(UiUtils.getThemeColor(context, R.attr.colorPrimary700));
|
||||
switch (pn.notificationType) {
|
||||
case FAVORITE -> builder.setSmallIcon(R.drawable.ic_fluent_star_24_filled);
|
||||
case REBLOG -> builder.setSmallIcon(R.drawable.ic_fluent_arrow_repeat_all_24_filled);
|
||||
case FOLLOW -> builder.setSmallIcon(R.drawable.ic_fluent_person_add_24_filled);
|
||||
case MENTION -> builder.setSmallIcon(R.drawable.ic_fluent_mention_24_filled);
|
||||
case POLL -> builder.setSmallIcon(R.drawable.ic_fluent_poll_24_filled);
|
||||
default -> builder.setSmallIcon(R.drawable.ic_ntf_logo);
|
||||
}
|
||||
if(avatar!=null){
|
||||
builder.setLargeIcon(UiUtils.getBitmapFromDrawable(avatar));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.StringRes;
|
||||
@@ -101,9 +102,14 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
||||
}
|
||||
|
||||
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable){
|
||||
return wrapProgress(activity, message, cancelable, null);
|
||||
}
|
||||
|
||||
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable, Consumer<ProgressDialog> transform){
|
||||
progressDialog=new ProgressDialog(activity);
|
||||
progressDialog.setMessage(activity.getString(message));
|
||||
progressDialog.setCancelable(cancelable);
|
||||
if (transform != null) transform.accept(progressDialog);
|
||||
if(cancelable){
|
||||
progressDialog.setOnCancelListener(dialog->cancel());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited;
|
||||
import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
@@ -59,7 +60,7 @@ public class StatusInteractionController{
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
|
||||
public void setReblogged(Status status, boolean reblogged, Consumer<Status> cb){
|
||||
public void setReblogged(Status status, boolean reblogged, StatusPrivacy visibility, Consumer<Status> cb){
|
||||
if(!Looper.getMainLooper().isCurrentThread())
|
||||
throw new IllegalStateException("Can only be called from main thread");
|
||||
|
||||
@@ -67,10 +68,11 @@ public class StatusInteractionController{
|
||||
if(current!=null){
|
||||
current.cancel();
|
||||
}
|
||||
SetStatusReblogged req=(SetStatusReblogged) new SetStatusReblogged(status.id, reblogged)
|
||||
SetStatusReblogged req=(SetStatusReblogged) new SetStatusReblogged(status.id, reblogged, visibility)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Status result){
|
||||
public void onSuccess(Status reblog){
|
||||
Status result = reblog.getContentStatus();
|
||||
runningReblogRequests.remove(status.id);
|
||||
result.reblogsCount = Math.max(0, status.reblogsCount) + (reblogged ? 1 : -1);
|
||||
cb.accept(result);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.joinmastodon.android.api.requests.notifications;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.ApiUtils;
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class DismissNotification extends MastodonAPIRequest<Object>{
|
||||
public DismissNotification(String id){
|
||||
super(HttpMethod.POST, "/notifications/" + (id != null ? id + "/dismiss" : "clear"), Object.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,17 @@ package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
|
||||
public class SetStatusReblogged extends MastodonAPIRequest<Status>{
|
||||
public SetStatusReblogged(String id, boolean reblogged){
|
||||
public SetStatusReblogged(String id, boolean reblogged, StatusPrivacy visibility){
|
||||
super(HttpMethod.POST, "/statuses/"+id+"/"+(reblogged ? "reblog" : "unreblog"), Status.class);
|
||||
setRequestBody(new Object());
|
||||
Request req = new Request();
|
||||
req.visibility = visibility;
|
||||
setRequestBody(req);
|
||||
}
|
||||
|
||||
public static class Request {
|
||||
public StatusPrivacy visibility;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.joinmastodon.android.api.requests.tags;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GetFollowedHashtags extends HeaderPaginationRequest<Hashtag> {
|
||||
public GetFollowedHashtags(String maxID, String minID, int limit, String sinceID){
|
||||
super(HttpMethod.GET, "/followed_tags", new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(minID!=null)
|
||||
addQueryParameter("min_id", minID);
|
||||
if(sinceID!=null)
|
||||
addQueryParameter("since_id", sinceID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", ""+limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import org.joinmastodon.android.BuildConfig;
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.MainActivity;
|
||||
@@ -108,7 +106,7 @@ public class AccountSessionManager{
|
||||
sessions.put(session.getID(), session);
|
||||
lastActiveAccountID=session.getID();
|
||||
writeAccountsFile();
|
||||
updateInstanceEmojis(instance, instance.uri);
|
||||
updateMoreInstanceInfo(instance, instance.uri);
|
||||
if(PushSubscriptionManager.arePushNotificationsAvailable()){
|
||||
session.getPushSubscriptionManager().registerAccountForPush(null);
|
||||
}
|
||||
@@ -327,12 +325,7 @@ public class AccountSessionManager{
|
||||
@Override
|
||||
public void onSuccess(Instance instance){
|
||||
instances.put(domain, instance);
|
||||
updateInstanceEmojis(instance, domain);
|
||||
try {
|
||||
if (Integer.parseInt(instance.version.split("\\.")[0]) >= 4) {
|
||||
updateInstanceInfoV2(domain);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
updateMoreInstanceInfo(instance, domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -343,17 +336,19 @@ public class AccountSessionManager{
|
||||
.execNoAuth(domain);
|
||||
}
|
||||
|
||||
public void updateInstanceInfoV2(String domain) {
|
||||
public void updateMoreInstanceInfo(Instance instance, String domain) {
|
||||
new GetInstance.V2().setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(Instance.V2 v2) {
|
||||
Instance instanceInfo = instances.get(domain);
|
||||
if (instanceInfo != null) instanceInfo.v2 = v2;
|
||||
if (instance != null) instance.v2 = v2;
|
||||
updateInstanceEmojis(instance, domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse errorResponse) {}
|
||||
}).execNoAuth(domain);
|
||||
public void onError(ErrorResponse errorResponse) {
|
||||
updateInstanceEmojis(instance, domain);
|
||||
}
|
||||
}).execNoAuth(instance.uri);
|
||||
}
|
||||
|
||||
private void updateInstanceEmojis(Instance instance, String domain){
|
||||
|
||||
@@ -787,7 +787,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
currentMediaHiddenLayoutsWidth=width;
|
||||
String title=getString(R.string.sensitive_content);
|
||||
TextPaint titlePaint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
titlePaint.setColor(getResources().getColor(R.color.gray_50));
|
||||
titlePaint.setColor(UiUtils.getThemeColor(getContext(), R.attr.colorGray50));
|
||||
titlePaint.setTextSize(V.dp(22));
|
||||
titlePaint.setTypeface(mediumTypeface);
|
||||
mediaHiddenTitleLayout=StaticLayout.Builder.obtain(title, 0, title.length(), titlePaint, width)
|
||||
@@ -798,7 +798,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
.setAlignment(Layout.Alignment.ALIGN_CENTER)
|
||||
.build();
|
||||
TextPaint textPaint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
textPaint.setColor(getResources().getColor(R.color.gray_200));
|
||||
textPaint.setColor(UiUtils.getThemeColor(getContext(), R.attr.colorGray200));
|
||||
textPaint.setTextSize(V.dp(16));
|
||||
String text=getString(R.string.sensitive_content_explain);
|
||||
mediaHiddenTextLayout=StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, width)
|
||||
|
||||
@@ -155,7 +155,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
private int charCount, charLimit, trimmedCharCount;
|
||||
|
||||
private Button publishButton, languageButton;
|
||||
private PopupMenu languagePopup;
|
||||
private PopupMenu languagePopup, visibilityPopup;
|
||||
private ImageButton mediaBtn, pollBtn, emojiBtn, spoilerBtn, visibilityBtn;
|
||||
private ImageView sensitiveIcon;
|
||||
private ComposeMediaLayout attachmentsView;
|
||||
@@ -203,10 +203,14 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
private String language;
|
||||
private MastodonLanguage.LanguageResolver languageResolver;
|
||||
|
||||
private int navigationBarColorBefore;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
navigationBarColorBefore = getActivity().getWindow().getNavigationBarColor();
|
||||
getActivity().getWindow().setNavigationBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLightest));
|
||||
|
||||
accountID=getArguments().getString("account");
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
@@ -246,6 +250,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
UiUtils.removeCallbacks(updateUploadEtaRunnable);
|
||||
updateUploadEtaRunnable=null;
|
||||
}
|
||||
getActivity().getWindow().setNavigationBarColor(navigationBarColorBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,6 +260,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
wm=activity.getSystemService(WindowManager.class);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
|
||||
creatingView=true;
|
||||
@@ -295,7 +301,9 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
pollBtn.setOnClickListener(v->togglePoll());
|
||||
emojiBtn.setOnClickListener(v->emojiKeyboard.toggleKeyboardPopup(mainEditText));
|
||||
spoilerBtn.setOnClickListener(v->toggleSpoiler());
|
||||
visibilityBtn.setOnClickListener(this::onVisibilityClick);
|
||||
buildVisibilityPopup(visibilityBtn);
|
||||
visibilityBtn.setOnClickListener(v->visibilityPopup.show());
|
||||
visibilityBtn.setOnTouchListener(visibilityPopup.getDragToOpenListener());
|
||||
sensitiveItem.setOnClickListener(v->toggleSensitive());
|
||||
emojiKeyboard.setOnIconChangedListener(new PopupKeyboard.OnIconChangeListener(){
|
||||
@Override
|
||||
@@ -385,10 +393,17 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
|
||||
if(editingStatus!=null && editingStatus.visibility!=null) {
|
||||
statusVisibility=editingStatus.visibility;
|
||||
} else {
|
||||
loadDefaultStatusVisibility(savedInstanceState);
|
||||
}
|
||||
|
||||
loadDefaultStatusVisibility(savedInstanceState);
|
||||
updateVisibilityIcon();
|
||||
visibilityPopup.getMenu().findItem(switch(statusVisibility){
|
||||
case PUBLIC -> R.id.vis_public;
|
||||
case UNLISTED -> R.id.vis_unlisted;
|
||||
case PRIVATE -> R.id.vis_followers;
|
||||
case DIRECT -> R.id.vis_private;
|
||||
}).setChecked(true);
|
||||
|
||||
autocompleteViewController=new ComposeAutocompleteViewController(getActivity(), accountID);
|
||||
autocompleteViewController.setCompletionSelectedListener(this::onAutocompleteOptionSelected);
|
||||
@@ -519,7 +534,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
case PUBLIC -> R.drawable.ic_fluent_earth_20_regular;
|
||||
case UNLISTED -> R.drawable.ic_fluent_people_community_20_regular;
|
||||
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
|
||||
case DIRECT -> R.drawable.ic_at_symbol;
|
||||
case DIRECT -> R.drawable.ic_fluent_mention_20_regular;
|
||||
});
|
||||
visibilityIcon.setBounds(0, 0, V.dp(20), V.dp(20));
|
||||
Drawable replyArrow = getActivity().getDrawable(R.drawable.ic_fluent_arrow_reply_20_filled);
|
||||
@@ -592,6 +607,11 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
ignoreSelectionChanges=false;
|
||||
initialText=prefilledText;
|
||||
}
|
||||
if (getArguments().containsKey("selectionStart") || getArguments().containsKey("selectionEnd")) {
|
||||
int selectionStart=getArguments().getInt("selectionStart", 0);
|
||||
int selectionEnd=getArguments().getInt("selectionEnd", selectionStart);
|
||||
mainEditText.setSelection(selectionStart, selectionEnd);
|
||||
}
|
||||
ArrayList<Uri> mediaUris=getArguments().getParcelableArrayList("mediaAttachments");
|
||||
if(mediaUris!=null && !mediaUris.isEmpty()){
|
||||
for(Uri uri:mediaUris){
|
||||
@@ -612,7 +632,14 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
||||
publishButton=new Button(getActivity());
|
||||
publishButton.setText(editingStatus==null || redraftStatus ? R.string.publish : R.string.save);
|
||||
int publishText = editingStatus==null || redraftStatus ? R.string.publish : R.string.save;
|
||||
if (publishText == R.string.publish && !GlobalUserPreferences.publishButtonText.isEmpty()) {
|
||||
publishButton.setText(GlobalUserPreferences.publishButtonText);
|
||||
} else {
|
||||
publishButton.setText(publishText);
|
||||
}
|
||||
publishButton.setSingleLine();
|
||||
publishButton.setEllipsize(TextUtils.TruncateAt.END);
|
||||
publishButton.setOnClickListener(this::onPublishClick);
|
||||
LinearLayout wrap=new LinearLayout(getActivity());
|
||||
wrap.setOrientation(LinearLayout.HORIZONTAL);
|
||||
@@ -657,11 +684,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private Button buildLanguageSelector() {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
getActivity().getTheme().resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
|
||||
|
||||
languageButton=new Button(getActivity());
|
||||
languageButton.setTextColor(typedValue.data);
|
||||
languageButton.setTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorSecondary));
|
||||
languageButton.setBackground(getActivity().getDrawable(R.drawable.bg_text_button));
|
||||
languageButton.setPadding(V.dp(8), 0, V.dp(8), 0);
|
||||
languageButton.setCompoundDrawablesRelativeWithIntrinsicBounds(getActivity().getDrawable(R.drawable.ic_fluent_local_language_16_regular), null, null, null);
|
||||
@@ -1396,19 +1420,13 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
return attachments.size();
|
||||
}
|
||||
|
||||
private void onVisibilityClick(View v){
|
||||
PopupMenu menu=new PopupMenu(getActivity(), v);
|
||||
menu.inflate(R.menu.compose_visibility);
|
||||
Menu m=menu.getMenu();
|
||||
UiUtils.enablePopupMenuIcons(getActivity(), menu);
|
||||
private void buildVisibilityPopup(View v){
|
||||
visibilityPopup=new PopupMenu(getActivity(), v);
|
||||
visibilityPopup.inflate(R.menu.compose_visibility);
|
||||
Menu m=visibilityPopup.getMenu();
|
||||
UiUtils.enablePopupMenuIcons(getActivity(), visibilityPopup);
|
||||
m.setGroupCheckable(0, true, true);
|
||||
m.findItem(switch(statusVisibility){
|
||||
case PUBLIC -> R.id.vis_public;
|
||||
case UNLISTED -> R.id.vis_unlisted;
|
||||
case PRIVATE -> R.id.vis_followers;
|
||||
case DIRECT -> R.id.vis_private;
|
||||
}).setChecked(true);
|
||||
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){
|
||||
visibilityPopup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item){
|
||||
int id=item.getItemId();
|
||||
@@ -1426,7 +1444,6 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
return true;
|
||||
}
|
||||
});
|
||||
menu.show();
|
||||
}
|
||||
|
||||
private void loadDefaultStatusVisibility(Bundle savedInstanceState) {
|
||||
@@ -1467,7 +1484,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
case PUBLIC -> R.drawable.ic_fluent_earth_24_regular;
|
||||
case UNLISTED -> R.drawable.ic_fluent_people_community_24_regular;
|
||||
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_24_regular;
|
||||
case DIRECT -> R.drawable.ic_at_symbol;
|
||||
case DIRECT -> R.drawable.ic_fluent_mention_24_regular;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.tags.GetFollowedHashtags;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||
import me.grishka.appkit.utils.BindableViewHolder;
|
||||
import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public class FollowedHashtagsFragment extends BaseRecyclerFragment<Hashtag> implements ScrollableToTop {
|
||||
private String nextMaxID;
|
||||
private String accountId;
|
||||
|
||||
public FollowedHashtagsFragment() {
|
||||
super(20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Bundle args=getArguments();
|
||||
accountId=args.getString("account");
|
||||
setTitle(R.string.sk_hashtags_you_follow);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShown(){
|
||||
super.onShown();
|
||||
if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading)
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetFollowedHashtags(offset==0 ? null : nextMaxID, null, count, null)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(HeaderPaginationList<Hashtag> result){
|
||||
if(result.nextPageUri!=null)
|
||||
nextMaxID=result.nextPageUri.getQueryParameter("max_id");
|
||||
else
|
||||
nextMaxID=null;
|
||||
onDataLoaded(result, nextMaxID!=null);
|
||||
}
|
||||
})
|
||||
.exec(accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter getAdapter() {
|
||||
return new HashtagsAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollToTop() {
|
||||
smoothScrollRecyclerViewToTop(list);
|
||||
}
|
||||
|
||||
private class HashtagsAdapter extends RecyclerView.Adapter<HashtagViewHolder>{
|
||||
@NonNull
|
||||
@Override
|
||||
public HashtagViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
return new HashtagViewHolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull HashtagViewHolder holder, int position) {
|
||||
holder.bind(data.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
}
|
||||
|
||||
private class HashtagViewHolder extends BindableViewHolder<Hashtag> implements UsableRecyclerView.Clickable{
|
||||
private final TextView title;
|
||||
|
||||
public HashtagViewHolder(){
|
||||
super(getActivity(), R.layout.item_text, list);
|
||||
title=findViewById(R.id.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(Hashtag item) {
|
||||
title.setText(item.name);
|
||||
title.setCompoundDrawablesRelativeWithIntrinsicBounds(itemView.getContext().getDrawable(R.drawable.ic_fluent_number_symbol_24_regular), null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountId, item.name, item.following);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
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.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -23,17 +18,13 @@ import org.joinmastodon.android.model.ListTimeline;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||
import me.grishka.appkit.utils.BindableViewHolder;
|
||||
import me.grishka.appkit.utils.V;
|
||||
import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> implements ScrollableToTop {
|
||||
@@ -159,7 +150,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
||||
private final CheckBox listToggle;
|
||||
|
||||
public ListViewHolder(){
|
||||
super(getActivity(), R.layout.item_list_timeline, list);
|
||||
super(getActivity(), R.layout.item_text, list);
|
||||
title=findViewById(R.id.title);
|
||||
listToggle=findViewById(R.id.list_toggle);
|
||||
}
|
||||
@@ -167,8 +158,10 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
||||
@Override
|
||||
public void onBind(ListTimeline item) {
|
||||
title.setText(item.title);
|
||||
title.setCompoundDrawablesRelativeWithIntrinsicBounds(itemView.getContext().getDrawable(R.drawable.ic_fluent_people_community_24_regular), null, null, null);
|
||||
if (profileAccountId != null) {
|
||||
Boolean checked = userInList.get(item.id);
|
||||
listToggle.setVisibility(View.VISIBLE);
|
||||
listToggle.setChecked(userInList.containsKey(item.id) && checked != null && checked);
|
||||
listToggle.setOnClickListener(this::onClickToggle);
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetFollowRequests;
|
||||
import org.joinmastodon.android.events.FollowRequestHandledEvent;
|
||||
@@ -73,15 +74,25 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
||||
inflater.inflate(R.menu.notifications, menu);
|
||||
menu.findItem(R.id.clear_notifications).setVisible(GlobalUserPreferences.enableDeleteNotifications);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() != R.id.follow_requests) return false;
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), FollowRequestsListFragment.class, args);
|
||||
return true;
|
||||
if (item.getItemId() == R.id.follow_requests) {
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), FollowRequestsListFragment.class, args);
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.clear_notifications) {
|
||||
UiUtils.confirmDeleteNotification(getActivity(), accountID, null, ()->{
|
||||
for (int i = 0; i < tabViews.length; i++) {
|
||||
getFragmentForPage(i).reload();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,6 +120,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
|
||||
tabLayout.setTabTextColors(UiUtils.getThemeColor(getActivity(), R.attr.colorTabInactive), UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
|
||||
|
||||
pager.setOffscreenPageLimit(4);
|
||||
pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe);
|
||||
pager.setAdapter(new DiscoverPagerAdapter());
|
||||
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback(){
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
@@ -10,7 +12,6 @@ import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.NotificationDeletedEvent;
|
||||
import org.joinmastodon.android.events.PollUpdatedEvent;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
@@ -78,9 +79,9 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
case FAVORITE -> getString(R.string.user_favorited);
|
||||
case POLL -> getString(R.string.poll_ended);
|
||||
};
|
||||
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, null, extraText) : null;
|
||||
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, null, extraText, n) : null;
|
||||
if(n.status!=null){
|
||||
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null);
|
||||
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null, n);
|
||||
if(titleItem!=null){
|
||||
for(StatusDisplayItem item:items){
|
||||
if(item instanceof ImageStatusDisplayItem imgItem){
|
||||
@@ -210,7 +211,7 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNotification(Notification n){
|
||||
public void removeNotification(Notification n){
|
||||
data.remove(n);
|
||||
preloadedData.remove(n);
|
||||
int index=-1;
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Outline;
|
||||
@@ -18,6 +19,8 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ImageSpan;
|
||||
@@ -234,6 +237,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
}
|
||||
|
||||
pager.setOffscreenPageLimit(5);
|
||||
pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe);
|
||||
pager.setAdapter(new ProfilePagerAdapter());
|
||||
pager.getLayoutParams().height=getResources().getDisplayMetrics().heightPixels;
|
||||
|
||||
@@ -284,14 +288,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
followingBtn.setOnClickListener(this::onFollowersOrFollowingClick);
|
||||
|
||||
username.setOnLongClickListener(v->{
|
||||
String username=account.acct;
|
||||
if(!username.contains("@")){
|
||||
username+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
|
||||
}
|
||||
getActivity().getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText(null, "@"+username));
|
||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.TIRAMISU){ // Android 13+ SystemUI shows its own thing when you put things into the clipboard
|
||||
Toast.makeText(getActivity(), R.string.text_copied, Toast.LENGTH_SHORT).show();
|
||||
String usernameString=account.acct;
|
||||
if(!usernameString.contains("@")){
|
||||
usernameString+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
|
||||
}
|
||||
UiUtils.copyText(username, '@'+usernameString);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -623,6 +624,10 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
args.putString("profileAccount", profileAccountID);
|
||||
args.putString("profileDisplayUsername", account.getDisplayUsername());
|
||||
Nav.go(getActivity(), ListTimelinesFragment.class, args);
|
||||
}else if(id==R.id.followed_hashtags){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), FollowedHashtagsFragment.class, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
@@ -18,8 +19,11 @@ import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RadioButton;
|
||||
@@ -42,6 +46,7 @@ import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.PushNotification;
|
||||
import org.joinmastodon.android.model.PushSubscription;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
@@ -50,7 +55,6 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
@@ -86,6 +90,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
setTitle(R.string.settings);
|
||||
accountID=getArguments().getString("account");
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
||||
|
||||
if(GithubSelfUpdater.needSelfUpdating()){
|
||||
GithubSelfUpdater updater=GithubSelfUpdater.getInstance();
|
||||
@@ -102,9 +107,58 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
GlobalUserPreferences.disableMarquee=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new ColorPicker());
|
||||
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);
|
||||
popupMenu.inflate(R.menu.color_palettes);
|
||||
popupMenu.getMenu().findItem(R.id.m3_color).setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S);
|
||||
popupMenu.setOnMenuItemClickListener(SettingsFragment.this::onColorPreferenceClick);
|
||||
b.setOnTouchListener(popupMenu.getDragToOpenListener());
|
||||
b.setOnClickListener(v->popupMenu.show());
|
||||
b.setText(switch(GlobalUserPreferences.color){
|
||||
case MATERIAL3 -> R.string.sk_color_palette_material3;
|
||||
case PINK -> R.string.sk_color_palette_pink;
|
||||
case PURPLE -> R.string.sk_color_palette_purple;
|
||||
case GREEN -> R.string.sk_color_palette_green;
|
||||
case BLUE -> R.string.sk_color_palette_blue;
|
||||
case BROWN -> R.string.sk_color_palette_brown;
|
||||
case RED -> R.string.sk_color_palette_red;
|
||||
case YELLOW -> R.string.sk_color_palette_yellow;
|
||||
});
|
||||
}));
|
||||
items.add(new ButtonItem(R.string.sk_settings_publish_button_text, R.drawable.ic_fluent_send_24_regular, b->{
|
||||
updatePublishText(b);
|
||||
|
||||
b.setOnClickListener(l->{
|
||||
FrameLayout inputWrap = new FrameLayout(getContext());
|
||||
EditText input = new EditText(getContext());
|
||||
input.setHint(R.string.publish);
|
||||
input.setText(GlobalUserPreferences.publishButtonText.trim());
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.setMargins(V.dp(16), V.dp(4), V.dp(16), V.dp(16));
|
||||
input.setLayoutParams(params);
|
||||
inputWrap.addView(input);
|
||||
new M3AlertDialogBuilder(getContext()).setTitle(R.string.sk_settings_publish_button_text_title).setView(inputWrap)
|
||||
.setPositiveButton(R.string.save, (d, which) -> {
|
||||
GlobalUserPreferences.publishButtonText = input.getText().toString().trim();
|
||||
GlobalUserPreferences.save();
|
||||
updatePublishText(b);
|
||||
})
|
||||
.setNeutralButton(R.string.clear, (d, which) -> {
|
||||
GlobalUserPreferences.publishButtonText = "";
|
||||
GlobalUserPreferences.save();
|
||||
updatePublishText(b);
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (d, which) -> {})
|
||||
.show();
|
||||
});
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.settings_behavior));
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_federated_timeline, R.drawable.ic_fluent_earth_24_regular, GlobalUserPreferences.showFederatedTimeline, i->{
|
||||
GlobalUserPreferences.showFederatedTimeline=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
needAppRestart=true;
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{
|
||||
GlobalUserPreferences.playGifs=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
@@ -121,6 +175,21 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
GlobalUserPreferences.alwaysExpandContentWarnings=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.sk_tabs_disable_swipe, R.drawable.ic_fluent_swipe_right_24_regular, GlobalUserPreferences.disableSwipe, i->{
|
||||
GlobalUserPreferences.disableSwipe=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_settings_hide_translate_in_timeline, R.drawable.ic_fluent_translate_24_regular, GlobalUserPreferences.translateButtonOpenedOnly, i->{
|
||||
GlobalUserPreferences.translateButtonOpenedOnly=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
needAppRestart=true;
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.home_timeline));
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
||||
@@ -135,11 +204,6 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
GlobalUserPreferences.loadNewPosts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_federated_timeline, R.drawable.ic_fluent_earth_24_regular, GlobalUserPreferences.showFederatedTimeline, i->{
|
||||
GlobalUserPreferences.showFederatedTimeline=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
needAppRestart=true;
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.settings_notifications));
|
||||
items.add(notificationPolicyItem=new NotificationPolicyItem());
|
||||
@@ -147,30 +211,48 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
items.add(new SwitchItem(R.string.notify_favorites, R.drawable.ic_fluent_star_24_regular, pushSubscription.alerts.favourite, i->onNotificationsChanged(PushNotification.Type.FAVORITE, i.checked)));
|
||||
items.add(new SwitchItem(R.string.notify_follow, R.drawable.ic_fluent_person_add_24_regular, pushSubscription.alerts.follow, i->onNotificationsChanged(PushNotification.Type.FOLLOW, i.checked)));
|
||||
items.add(new SwitchItem(R.string.notify_reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, pushSubscription.alerts.reblog, i->onNotificationsChanged(PushNotification.Type.REBLOG, i.checked)));
|
||||
items.add(new SwitchItem(R.string.notify_mention, R.drawable.ic_at_symbol, pushSubscription.alerts.mention, i->onNotificationsChanged(PushNotification.Type.MENTION, i.checked)));
|
||||
items.add(new SwitchItem(R.string.notify_mention, R.drawable.ic_fluent_mention_24_regular, pushSubscription.alerts.mention, i->onNotificationsChanged(PushNotification.Type.MENTION, i.checked)));
|
||||
items.add(new SwitchItem(R.string.sk_notify_posts, R.drawable.ic_fluent_alert_24_regular, pushSubscription.alerts.status, i->onNotificationsChanged(PushNotification.Type.STATUS, i.checked)));
|
||||
|
||||
items.add(new HeaderItem(R.string.settings_boring));
|
||||
items.add(new TextItem(R.string.settings_account, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit")));
|
||||
items.add(new TextItem(R.string.settings_tos, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")));
|
||||
items.add(new TextItem(R.string.settings_privacy_policy, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")));
|
||||
items.add(new HeaderItem(R.string.settings_account));
|
||||
items.add(new TextItem(R.string.sk_settings_profile, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/settings/profile"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.sk_settings_posting, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/settings/preferences/other"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.sk_settings_filters, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/filters"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.sk_settings_auth, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit"), R.drawable.ic_fluent_open_24_regular));
|
||||
|
||||
items.add(new RedHeaderItem(R.string.settings_spicy));
|
||||
String instanceName = UiUtils.getInstanceName(accountID);
|
||||
items.add(new HeaderItem(instanceName));
|
||||
items.add(new TextItem(R.string.sk_settings_rules, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/about"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.settings_tos, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.settings_privacy_policy, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.log_out, this::confirmLogOut, R.drawable.ic_fluent_sign_out_24_regular));
|
||||
boolean translationAvailable = instance.v2 != null && instance.v2.configuration.translation != null && instance.v2.configuration.translation.enabled;
|
||||
items.add(new SmallTextItem(getString(translationAvailable ?
|
||||
R.string.sk_settings_translation_availability_note_available :
|
||||
R.string.sk_settings_translation_availability_note_unavailable, instanceName)));
|
||||
|
||||
|
||||
items.add(new HeaderItem(R.string.sk_settings_about));
|
||||
items.add(new TextItem(R.string.sk_settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/sk22/megalodon"), R.drawable.ic_fluent_open_24_regular));
|
||||
items.add(new TextItem(R.string.sk_settings_donate, ()->UiUtils.launchWebBrowser(getActivity(), "https://ko-fi.com/xsk22"), R.drawable.ic_fluent_heart_24_regular));
|
||||
if (GithubSelfUpdater.needSelfUpdating()) {
|
||||
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/sk22/megalodon")));
|
||||
items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
|
||||
items.add(new TextItem(R.string.sk_clear_recent_languages, ()->UiUtils.showConfirmationAlert(getActivity(), R.string.sk_clear_recent_languages, R.string.sk_confirm_clear_recent_languages, R.string.clear, ()->{
|
||||
GlobalUserPreferences.recentLanguages.remove(accountID);
|
||||
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)));
|
||||
}
|
||||
|
||||
private void updatePublishText(Button btn) {
|
||||
if (GlobalUserPreferences.publishButtonText.isBlank()) btn.setText(R.string.publish);
|
||||
else btn.setText(GlobalUserPreferences.publishButtonText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity){
|
||||
super.onAttach(activity);
|
||||
@@ -433,6 +515,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
this.text=getString(text);
|
||||
}
|
||||
|
||||
public HeaderItem(String text) {
|
||||
this.text=text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewType(){
|
||||
return 0;
|
||||
@@ -467,7 +553,17 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorPicker extends Item{
|
||||
public class ButtonItem extends Item{
|
||||
private int text;
|
||||
private int icon;
|
||||
private Consumer<Button> buttonConsumer;
|
||||
|
||||
public ButtonItem(@StringRes int text, @DrawableRes int icon, Consumer<Button> buttonConsumer) {
|
||||
this.text = text;
|
||||
this.icon = icon;
|
||||
this.buttonConsumer = buttonConsumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewType(){
|
||||
return 8;
|
||||
@@ -490,19 +586,42 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
}
|
||||
}
|
||||
|
||||
private class SmallTextItem extends Item {
|
||||
private String text;
|
||||
|
||||
public SmallTextItem(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewType() {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
private class TextItem extends Item{
|
||||
private String text;
|
||||
private Runnable onClick;
|
||||
private boolean loading;
|
||||
private int icon;
|
||||
|
||||
public TextItem(@StringRes int text, Runnable onClick) {
|
||||
this(text, onClick, false);
|
||||
this(text, onClick, false, 0);
|
||||
}
|
||||
|
||||
public TextItem(@StringRes int text, Runnable onClick, boolean loading){
|
||||
public TextItem(@StringRes int text, Runnable onClick, boolean loading) {
|
||||
this(text, onClick, loading, 0);
|
||||
}
|
||||
|
||||
public TextItem(@StringRes int text, Runnable onClick, @DrawableRes int icon) {
|
||||
this(text, onClick, false, icon);
|
||||
}
|
||||
|
||||
public TextItem(@StringRes int text, Runnable onClick, boolean loading, @DrawableRes int icon){
|
||||
this.text=getString(text);
|
||||
this.onClick=onClick;
|
||||
this.loading=loading;
|
||||
this.icon=icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -558,7 +677,8 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
case 5 -> new HeaderViewHolder(true);
|
||||
case 6 -> new FooterViewHolder();
|
||||
case 7 -> new UpdateViewHolder();
|
||||
case 8 -> new ColorPickerViewHolder();
|
||||
case 8 -> new ButtonViewHolder();
|
||||
case 9 -> new SmallTextViewHolder();
|
||||
default -> throw new IllegalStateException("Unexpected value: "+viewType);
|
||||
};
|
||||
}
|
||||
@@ -687,37 +807,24 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
}
|
||||
}
|
||||
}
|
||||
private class ColorPickerViewHolder extends BindableViewHolder<ColorPicker>{
|
||||
private class ButtonViewHolder extends BindableViewHolder<ButtonItem>{
|
||||
private final Button button;
|
||||
private final PopupMenu popupMenu;
|
||||
private final ImageView icon;
|
||||
private final TextView text;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public ColorPickerViewHolder(){
|
||||
super(getActivity(), R.layout.item_settings_color_picker, list);
|
||||
public ButtonViewHolder(){
|
||||
super(getActivity(), R.layout.item_settings_button, list);
|
||||
text=findViewById(R.id.text);
|
||||
icon=findViewById(R.id.icon);
|
||||
button=findViewById(R.id.color_picker_button);
|
||||
popupMenu=new PopupMenu(getActivity(), button, Gravity.CENTER_HORIZONTAL);
|
||||
popupMenu.inflate(R.menu.color_picker);
|
||||
popupMenu.setOnMenuItemClickListener(SettingsFragment.this::onColorPreferenceClick);
|
||||
button.setOnTouchListener(popupMenu.getDragToOpenListener());
|
||||
button.setOnClickListener(v->popupMenu.show());
|
||||
button=findViewById(R.id.button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(ColorPicker item){
|
||||
icon.setImageResource(R.drawable.ic_fluent_color_24_regular);
|
||||
button.setText(switch(GlobalUserPreferences.color){
|
||||
case MATERIAL3 -> R.string.sk_color_theme_material3;
|
||||
case PINK -> R.string.sk_color_theme_pink;
|
||||
case PURPLE -> R.string.sk_color_theme_purple;
|
||||
case GREEN -> R.string.sk_color_theme_green;
|
||||
case BLUE -> R.string.sk_color_theme_blue;
|
||||
case BROWN -> R.string.sk_color_theme_brown;
|
||||
case RED -> R.string.sk_color_theme_red;
|
||||
case YELLOW -> R.string.sk_color_theme_yellow;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+GlobalUserPreferences.color);
|
||||
});
|
||||
public void onBind(ButtonItem item){
|
||||
text.setText(item.text);
|
||||
icon.setImageResource(item.icon);
|
||||
item.buttonConsumer.accept(button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,17 +874,20 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
private class TextViewHolder extends BindableViewHolder<TextItem> implements UsableRecyclerView.Clickable{
|
||||
private final TextView text;
|
||||
private final ProgressBar progress;
|
||||
private final ImageView icon;
|
||||
|
||||
public TextViewHolder(){
|
||||
super(getActivity(), R.layout.item_settings_text, list);
|
||||
text = itemView.findViewById(R.id.text);
|
||||
progress = itemView.findViewById(R.id.progress);
|
||||
icon = itemView.findViewById(R.id.icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(TextItem item){
|
||||
text.setText(item.text);
|
||||
progress.animate().alpha(item.loading ? 1 : 0);
|
||||
if (item.icon != 0) icon.setImageDrawable(getActivity().getTheme().getDrawable(item.icon));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -786,6 +896,24 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
}
|
||||
}
|
||||
|
||||
private class SmallTextViewHolder extends BindableViewHolder<SmallTextItem> {
|
||||
private final TextView text;
|
||||
;
|
||||
|
||||
public SmallTextViewHolder(){
|
||||
super(getActivity(), R.layout.item_settings_text, list);
|
||||
text = itemView.findViewById(R.id.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(SmallTextItem item){
|
||||
text.setText(item.text);
|
||||
text.setTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorSecondary));
|
||||
text.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
}
|
||||
}
|
||||
|
||||
private class FooterViewHolder extends BindableViewHolder<FooterItem>{
|
||||
private final TextView text;
|
||||
public FooterViewHolder(){
|
||||
|
||||
@@ -54,7 +54,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
||||
|
||||
@Override
|
||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false);
|
||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false, null);
|
||||
int idx=data.indexOf(s);
|
||||
if(idx>=0){
|
||||
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));
|
||||
@@ -139,7 +139,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
||||
action=getString(R.string.edit_multiple_changed);
|
||||
}
|
||||
}
|
||||
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" · "+date, Collections.emptyList(), 0, null));
|
||||
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" · "+date, Collections.emptyList(), 0, null, null));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
protected EventListener eventListener=new EventListener();
|
||||
|
||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, true);
|
||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -189,8 +189,8 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
}
|
||||
}
|
||||
for(Status s:preloadedData){
|
||||
if(s.id.equals(ev.id)){
|
||||
s.update(ev);
|
||||
if(s.getContentStatus().id.equals(ev.id)){
|
||||
s.getContentStatus().update(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
tabLayout.setTabTextColors(UiUtils.getThemeColor(getActivity(), R.attr.colorTabInactive), UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
|
||||
|
||||
pager.setOffscreenPageLimit(4);
|
||||
pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe);
|
||||
pager.setAdapter(new DiscoverPagerAdapter());
|
||||
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback(){
|
||||
@Override
|
||||
|
||||
@@ -75,7 +75,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
return switch(s.type){
|
||||
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
|
||||
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
|
||||
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true);
|
||||
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true, null);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -205,11 +205,6 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
|
||||
|
||||
public InstanceViewHolder(){
|
||||
super(getActivity(), R.layout.item_instance_custom, list);
|
||||
|
||||
// itemView.setPadding(V.dp(16), V.dp(16), V.dp(16), V.dp(16));
|
||||
// TypedValue value = new TypedValue();
|
||||
// getActivity().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
|
||||
// itemView.setBackground(getActivity().getTheme().getDrawable(R.drawable.bg_search_field));
|
||||
title=findViewById(R.id.title);
|
||||
description=findViewById(R.id.description);
|
||||
userCount=findViewById(R.id.user_count);
|
||||
|
||||
@@ -155,7 +155,7 @@ public class SignupFragment extends ToolbarFragment{
|
||||
}
|
||||
|
||||
private void onButtonClick(){
|
||||
if(!password.getText().equals(passwordConfirm.getText())){
|
||||
if(!password.getText().toString().equals(passwordConfirm.getText().toString())){
|
||||
passwordConfirm.setError(getString(R.string.signup_passwords_dont_match));
|
||||
passwordConfirmWrap.setErrorState();
|
||||
return;
|
||||
|
||||
@@ -237,7 +237,7 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{
|
||||
|
||||
@Override
|
||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false);
|
||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false, null);
|
||||
for(StatusDisplayItem item:items){
|
||||
if(item instanceof ImageStatusDisplayItem isdi){
|
||||
isdi.horizontalInset=V.dp(40+32);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class M3AlertDialogBuilder extends AlertDialog.Builder{
|
||||
View title=alert.findViewById(titleID);
|
||||
if(title!=null){
|
||||
int pad=V.dp(24);
|
||||
title.setPadding(pad, pad, pad, pad);
|
||||
title.setPadding(pad, pad, pad, V.dp(18));
|
||||
}
|
||||
}
|
||||
int titleDividerID=getContext().getResources().getIdentifier("titleDividerNoCustom", "id", "android");
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
|
||||
case PUBLIC -> R.drawable.ic_fluent_earth_20_regular;
|
||||
case UNLISTED -> R.drawable.ic_fluent_people_community_20_regular;
|
||||
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
|
||||
case DIRECT -> R.drawable.ic_at_symbol;
|
||||
case DIRECT -> R.drawable.ic_fluent_mention_20_regular;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,39 @@
|
||||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationSet;
|
||||
import android.view.animation.ScaleAnimation;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
import me.grishka.appkit.utils.V;
|
||||
@@ -49,7 +57,10 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
public static class Holder extends StatusDisplayItem.Holder<FooterStatusDisplayItem>{
|
||||
private final TextView reply, boost, favorite, bookmark;
|
||||
private final ImageView share;
|
||||
private static final AnimationSet scaleDown, scaleUp;
|
||||
private static final Animation opacityOut, opacityIn;
|
||||
|
||||
private View touchingView = null;
|
||||
private final Runnable longClickRunnable = () -> { if (touchingView != null) touchingView.performLongClick(); };
|
||||
|
||||
private final View.AccessibilityDelegate buttonAccessibilityDelegate=new View.AccessibilityDelegate(){
|
||||
@Override
|
||||
@@ -61,24 +72,13 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
};
|
||||
|
||||
static {
|
||||
// 20dp to center in middle of icon, because: (icon width = 24dp) / 2 + (paddingStart = 8dp)
|
||||
Animation scaleDownAnim = new ScaleAnimation(1, 0.85f, 1, 0.85f, Animation.ABSOLUTE, V.dp(20), Animation.RELATIVE_TO_SELF, 0.5f);
|
||||
Animation scaleUpAnim = new ScaleAnimation(0.85f, 1, 0.85f, 1, Animation.ABSOLUTE, V.dp(20), Animation.RELATIVE_TO_SELF, 0.5f);
|
||||
Animation opacityOutAnim = new AlphaAnimation(1, 0.75f);
|
||||
Animation opacityInAnim = new AlphaAnimation(0.75f, 1);
|
||||
|
||||
scaleDown = new AnimationSet(true);
|
||||
scaleDown.setDuration(350);
|
||||
scaleDown.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
scaleDown.setFillAfter(true);
|
||||
scaleDown.addAnimation(scaleDownAnim);
|
||||
scaleDown.addAnimation(opacityOutAnim);
|
||||
|
||||
scaleUp = new AnimationSet(true);
|
||||
scaleUp.setDuration(100);
|
||||
scaleUp.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
scaleUp.addAnimation(scaleUpAnim);
|
||||
scaleUp.addAnimation(opacityInAnim);
|
||||
opacityOut = new AlphaAnimation(1, 0.55f);
|
||||
opacityOut.setDuration(300);
|
||||
opacityOut.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
opacityOut.setFillAfter(true);
|
||||
opacityIn = new AlphaAnimation(0.55f, 1);
|
||||
opacityIn.setDuration(300);
|
||||
opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
}
|
||||
|
||||
public Holder(Activity activity, ViewGroup parent){
|
||||
@@ -104,6 +104,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
reply.setAccessibilityDelegate(buttonAccessibilityDelegate);
|
||||
boost.setOnTouchListener(this::onButtonTouch);
|
||||
boost.setOnClickListener(this::onBoostClick);
|
||||
boost.setOnLongClickListener(this::onBoostLongClick);
|
||||
boost.setAccessibilityDelegate(buttonAccessibilityDelegate);
|
||||
favorite.setOnTouchListener(this::onButtonTouch);
|
||||
favorite.setOnClickListener(this::onFavoriteClick);
|
||||
@@ -113,6 +114,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
bookmark.setAccessibilityDelegate(buttonAccessibilityDelegate);
|
||||
share.setOnTouchListener(this::onButtonTouch);
|
||||
share.setOnClickListener(this::onShareClick);
|
||||
share.setOnLongClickListener(this::onShareLongClick);
|
||||
share.setAccessibilityDelegate(buttonAccessibilityDelegate);
|
||||
}
|
||||
|
||||
@@ -138,52 +140,143 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onButtonTouch(View v, MotionEvent event){
|
||||
boolean disabled = !v.isEnabled() || (v instanceof FrameLayout parentFrame &&
|
||||
parentFrame.getChildCount() > 0 && !parentFrame.getChildAt(0).isEnabled());
|
||||
int action = event.getAction();
|
||||
long eventDuration = event.getEventTime() - event.getDownTime();
|
||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
||||
touchingView = null;
|
||||
v.removeCallbacks(longClickRunnable);
|
||||
v.animate().scaleX(1).scaleY(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start();
|
||||
if (disabled) return true;
|
||||
if (action == MotionEvent.ACTION_UP && eventDuration <= ViewConfiguration.getLongPressTimeout()) v.performClick();
|
||||
else v.startAnimation(opacityIn);
|
||||
} else if (action == MotionEvent.ACTION_DOWN) {
|
||||
touchingView = v;
|
||||
// 20dp to center in middle of icon, because: (icon width = 24dp) / 2 + (paddingStart = 8dp)
|
||||
v.setPivotX(V.dp(20));
|
||||
v.animate().scaleX(0.85f).scaleY(0.85f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(75).start();
|
||||
if (disabled) return true;
|
||||
v.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout());
|
||||
v.startAnimation(opacityOut);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onReplyClick(View v){
|
||||
v.startAnimation(scaleUp);
|
||||
v.startAnimation(opacityIn);
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", item.accountID);
|
||||
args.putParcelable("replyTo", Parcels.wrap(item.status));
|
||||
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||
}
|
||||
|
||||
private boolean onButtonTouch(View v, MotionEvent event){
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) v.performClick();
|
||||
else if (event.getAction() == MotionEvent.ACTION_DOWN) v.startAnimation(scaleDown);
|
||||
else if (event.getAction() == MotionEvent.ACTION_CANCEL) v.startAnimation(scaleUp);
|
||||
private void onBoostClick(View v){
|
||||
boost.setSelected(!item.status.reblogged);
|
||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(item.status, !item.status.reblogged, null, r->boostConsumer(v, r));
|
||||
}
|
||||
|
||||
private void boostConsumer(View v, Status r) {
|
||||
v.startAnimation(opacityIn);
|
||||
bindButton(boost, r.reblogsCount);
|
||||
}
|
||||
|
||||
private boolean onBoostLongClick(View v){
|
||||
Context ctx = itemView.getContext();
|
||||
View menu = LayoutInflater.from(ctx).inflate(R.layout.item_boost_menu, null);
|
||||
Dialog dialog = new M3AlertDialogBuilder(ctx).setView(menu).create();
|
||||
AccountSession session = AccountSessionManager.getInstance().getAccount(item.accountID);
|
||||
|
||||
Consumer<StatusPrivacy> doReblog = (visibility) -> {
|
||||
v.startAnimation(opacityOut);
|
||||
session.getStatusInteractionController()
|
||||
.setReblogged(item.status, !item.status.reblogged, visibility, r->boostConsumer(v, r));
|
||||
dialog.dismiss();
|
||||
};
|
||||
|
||||
View separator = menu.findViewById(R.id.separator);
|
||||
TextView reblogHeader = menu.findViewById(R.id.reblog_header);
|
||||
TextView undoReblog = menu.findViewById(R.id.delete_reblog);
|
||||
TextView itemPublic = menu.findViewById(R.id.vis_public);
|
||||
TextView itemUnlisted = menu.findViewById(R.id.vis_unlisted);
|
||||
TextView itemFollowers = menu.findViewById(R.id.vis_followers);
|
||||
|
||||
undoReblog.setVisibility(item.status.reblogged ? View.VISIBLE : View.GONE);
|
||||
separator.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||
reblogHeader.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||
|
||||
itemPublic.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.PUBLIC) ? View.GONE : View.VISIBLE);
|
||||
itemUnlisted.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.UNLISTED) ? View.GONE : View.VISIBLE);
|
||||
itemFollowers.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.PRIVATE) ? View.GONE : View.VISIBLE);
|
||||
|
||||
Drawable checkMark = ctx.getDrawable(R.drawable.ic_fluent_checkmark_circle_20_regular);
|
||||
Drawable publicDrawable = ctx.getDrawable(R.drawable.ic_fluent_earth_24_regular);
|
||||
Drawable unlistedDrawable = ctx.getDrawable(R.drawable.ic_fluent_people_community_24_regular);
|
||||
Drawable followersDrawable = ctx.getDrawable(R.drawable.ic_fluent_people_checkmark_24_regular);
|
||||
|
||||
StatusPrivacy defaultVisibility = session.preferences.postingDefaultVisibility;
|
||||
// e.g. post visibility is unlisted, but default is public
|
||||
// in this case, we want to display the check mark on the most visible visibility
|
||||
if (item.status.visibility.isLessVisibleThan(defaultVisibility)) {
|
||||
for (StatusPrivacy vis : StatusPrivacy.values()) {
|
||||
if (vis.equals(item.status.visibility)) {
|
||||
defaultVisibility = vis;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
itemPublic.setCompoundDrawablesWithIntrinsicBounds(publicDrawable, null, StatusPrivacy.PUBLIC.equals(defaultVisibility) ? checkMark : null, null);
|
||||
itemUnlisted.setCompoundDrawablesWithIntrinsicBounds(unlistedDrawable, null, StatusPrivacy.UNLISTED.equals(defaultVisibility) ? checkMark : null, null);
|
||||
itemFollowers.setCompoundDrawablesWithIntrinsicBounds(followersDrawable, null, StatusPrivacy.PRIVATE.equals(defaultVisibility) ? checkMark : null, null);
|
||||
|
||||
undoReblog.setOnClickListener(c->doReblog.accept(null));
|
||||
itemPublic.setOnClickListener(c->doReblog.accept(StatusPrivacy.PUBLIC));
|
||||
itemUnlisted.setOnClickListener(c->doReblog.accept(StatusPrivacy.UNLISTED));
|
||||
itemFollowers.setOnClickListener(c->doReblog.accept(StatusPrivacy.PRIVATE));
|
||||
|
||||
menu.findViewById(R.id.quote).setOnClickListener(c->{
|
||||
dialog.dismiss();
|
||||
v.startAnimation(opacityIn);
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", item.accountID);
|
||||
args.putString("prefilledText", "\n\n" + item.status.url);
|
||||
args.putInt("selectionStart", 0);
|
||||
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onBoostClick(View v){
|
||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(item.status, !item.status.reblogged, r->{
|
||||
v.startAnimation(scaleUp);
|
||||
boost.setSelected(item.status.reblogged);
|
||||
bindButton(boost, r.reblogsCount);
|
||||
});
|
||||
}
|
||||
|
||||
private void onFavoriteClick(View v){
|
||||
favorite.setSelected(!item.status.favourited);
|
||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setFavorited(item.status, !item.status.favourited, r->{
|
||||
v.startAnimation(scaleUp);
|
||||
favorite.setSelected(r.favourited);
|
||||
v.startAnimation(opacityIn);
|
||||
bindButton(favorite, r.favouritesCount);
|
||||
});
|
||||
}
|
||||
|
||||
private void onBookmarkClick(View v){
|
||||
bookmark.setSelected(!item.status.bookmarked);
|
||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(item.status, !item.status.bookmarked, r->{
|
||||
v.startAnimation(scaleUp);
|
||||
bookmark.setSelected(item.status.bookmarked);
|
||||
v.startAnimation(opacityIn);
|
||||
});
|
||||
}
|
||||
|
||||
private void onShareClick(View v){
|
||||
v.startAnimation(scaleUp);
|
||||
v.startAnimation(opacityIn);
|
||||
Intent intent=new Intent(Intent.ACTION_SEND);
|
||||
intent.setType("text/plain");
|
||||
intent.putExtra(Intent.EXTRA_TEXT, item.status.url);
|
||||
v.getContext().startActivity(Intent.createChooser(intent, v.getContext().getString(R.string.share_toot_title)));
|
||||
}
|
||||
|
||||
private boolean onShareLongClick(View v){
|
||||
UiUtils.copyText(v, item.status.url);
|
||||
return true;
|
||||
}
|
||||
|
||||
private int descriptionForId(int id){
|
||||
if(id==R.id.reply_btn)
|
||||
return R.string.button_reply;
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
@@ -23,14 +24,17 @@ import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||
import org.joinmastodon.android.fragments.NotificationsListFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
@@ -41,6 +45,7 @@ import org.parceler.Parcels;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.APIRequest;
|
||||
@@ -62,8 +67,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
private boolean hasVisibilityToggle;
|
||||
boolean needBottomPadding;
|
||||
private String extraText;
|
||||
private Notification notification;
|
||||
|
||||
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, String extraText){
|
||||
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, String extraText, Notification notification){
|
||||
super(parentID, parentFragment);
|
||||
this.user=user;
|
||||
this.createdAt=createdAt;
|
||||
@@ -71,6 +77,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
this.accountID=accountID;
|
||||
parsedName=new SpannableStringBuilder(user.displayName);
|
||||
this.status=status;
|
||||
this.notification=notification;
|
||||
HtmlParser.parseCustomEmoji(parsedName, user.emojis);
|
||||
emojiHelper.setText(parsedName);
|
||||
if(status!=null){
|
||||
@@ -107,7 +114,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
private final TextView name, username, timestamp, extraText;
|
||||
private final ImageView avatar, more, visibility;
|
||||
private final ImageView avatar, more, visibility, deleteNotification;
|
||||
private final PopupMenu optionsMenu;
|
||||
private Relationship relationship;
|
||||
private APIRequest<?> currentRelationshipRequest;
|
||||
@@ -127,18 +134,37 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
avatar=findViewById(R.id.avatar);
|
||||
more=findViewById(R.id.more);
|
||||
visibility=findViewById(R.id.visibility);
|
||||
deleteNotification=findViewById(R.id.delete_notification);
|
||||
extraText=findViewById(R.id.extra_text);
|
||||
avatar.setOnClickListener(this::onAvaClick);
|
||||
avatar.setOutlineProvider(roundCornersOutline);
|
||||
avatar.setClipToOutline(true);
|
||||
more.setOnClickListener(this::onMoreClick);
|
||||
more.setOnLongClickListener((v) -> {
|
||||
PopupMenu popup = new PopupMenu(itemView.getContext(), v);
|
||||
populateAccountsMenu(popup.getMenu());
|
||||
popup.show();
|
||||
return true;
|
||||
});
|
||||
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
|
||||
deleteNotification.setOnClickListener(v->UiUtils.confirmDeleteNotification(activity, item.parentFragment.getAccountID(), item.notification, ()->{
|
||||
if (item.parentFragment instanceof NotificationsListFragment fragment) {
|
||||
fragment.removeNotification(item.notification);
|
||||
}
|
||||
}));
|
||||
|
||||
optionsMenu=new PopupMenu(activity, more);
|
||||
optionsMenu.inflate(R.menu.post);
|
||||
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
||||
Account account=item.user;
|
||||
int id=menuItem.getItemId();
|
||||
|
||||
SubMenu accountsMenu=id==R.id.open_with_account ? menuItem.getSubMenu() : null;
|
||||
if (accountsMenu != null) {
|
||||
accountsMenu.clear();
|
||||
populateAccountsMenu(accountsMenu);
|
||||
}
|
||||
|
||||
if(id==R.id.edit || id==R.id.delete_and_redraft) {
|
||||
final Bundle args=new Bundle();
|
||||
args.putString("account", item.parentFragment.getAccountID());
|
||||
@@ -179,20 +205,19 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
}
|
||||
}else if(id==R.id.delete){
|
||||
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
||||
}else if(id==R.id.pin || id==R.id.unpin){
|
||||
UiUtils.confirmPinPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, !item.status.pinned, s->{});
|
||||
}else if(id==R.id.mute){
|
||||
UiUtils.confirmToggleMuteUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, relationship!=null && relationship.muting, r->{});
|
||||
}else if(id==R.id.block){
|
||||
UiUtils.confirmToggleBlockUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, relationship!=null && relationship.blocking, r->{});
|
||||
}else if(id==R.id.pin || id==R.id.unpin) {
|
||||
UiUtils.confirmPinPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, !item.status.pinned, s -> {
|
||||
});
|
||||
}else if(id==R.id.report){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", item.parentFragment.getAccountID());
|
||||
args.putParcelable("status", Parcels.wrap(item.status));
|
||||
args.putParcelable("reportAccount", Parcels.wrap(item.status.account));
|
||||
Nav.go(item.parentFragment.getActivity(), ReportReasonChoiceFragment.class, args);
|
||||
}else if(id==R.id.open_in_browser){
|
||||
}else if(id==R.id.open_in_browser) {
|
||||
UiUtils.launchWebBrowser(activity, item.status.url);
|
||||
}else if(id==R.id.copy_link){
|
||||
UiUtils.copyText(parent, item.status.url);
|
||||
}else if(id==R.id.follow){
|
||||
if(relationship==null)
|
||||
return true;
|
||||
@@ -217,6 +242,17 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
});
|
||||
}
|
||||
|
||||
private void populateAccountsMenu(Menu menu) {
|
||||
List<AccountSession> sessions=AccountSessionManager.getInstance().getLoggedInAccounts();
|
||||
sessions.stream().filter(s -> !s.getID().equals(item.accountID)).forEach(s -> {
|
||||
String username = "@"+s.self.username+"@"+s.domain;
|
||||
menu.add(username).setOnMenuItemClickListener(c->{
|
||||
UiUtils.openURL(item.parentFragment.getActivity(), s.getID(), item.status.url, false);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(HeaderStatusDisplayItem item){
|
||||
name.setText(item.parsedName);
|
||||
@@ -226,6 +262,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
else
|
||||
timestamp.setText(item.parentFragment.getString(R.string.edited_timestamp, UiUtils.formatRelativeTimestamp(itemView.getContext(), item.status.editedAt)));
|
||||
visibility.setVisibility(item.hasVisibilityToggle && !item.inset ? View.VISIBLE : View.GONE);
|
||||
deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification!=null && !item.inset ? View.VISIBLE : View.GONE);
|
||||
if(item.hasVisibilityToggle){
|
||||
visibility.setImageResource(item.status.spoilerRevealed ? R.drawable.ic_visibility_off : R.drawable.ic_visibility);
|
||||
visibility.setContentDescription(item.parentFragment.getString(item.status.spoilerRevealed ? R.string.hide_content : R.string.reveal_content));
|
||||
@@ -307,6 +344,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
menu.findItem(R.id.pin).setVisible(item.status!=null && isOwnPost && !item.status.pinned);
|
||||
menu.findItem(R.id.unpin).setVisible(item.status!=null && isOwnPost && item.status.pinned);
|
||||
menu.findItem(R.id.open_in_browser).setVisible(item.status!=null);
|
||||
menu.findItem(R.id.copy_link).setVisible(item.status!=null);
|
||||
MenuItem blockDomain=menu.findItem(R.id.block_domain);
|
||||
MenuItem mute=menu.findItem(R.id.mute);
|
||||
MenuItem block=menu.findItem(R.id.block);
|
||||
@@ -336,12 +374,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
mute.setTitle(item.parentFragment.getString(relationship!=null && relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||
block.setTitle(item.parentFragment.getString(relationship!=null && relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||
report.setTitle(item.parentFragment.getString(R.string.report_user, account.getDisplayUsername()));
|
||||
if(!account.isLocal()){
|
||||
blockDomain.setVisible(true);
|
||||
blockDomain.setTitle(item.parentFragment.getString(relationship!=null && relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
||||
}else{
|
||||
// disabled in megalodon. domain blocks from a post clutters the context menu and looks out of place
|
||||
// if(!account.isLocal()){
|
||||
// blockDomain.setVisible(true);
|
||||
// blockDomain.setTitle(item.parentFragment.getString(relationship!=null && relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
||||
// }else{
|
||||
blockDomain.setVisible(false);
|
||||
}
|
||||
// }
|
||||
follow.setTitle(item.parentFragment.getString(relationship!=null && relationship.following ? R.string.unfollow_user : R.string.follow_user, account.getDisplayUsername()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class LinkCardStatusDisplayItem extends StatusDisplayItem{
|
||||
}
|
||||
|
||||
private void onClick(View v){
|
||||
UiUtils.launchWebBrowser(itemView.getContext(), item.status.card.url);
|
||||
UiUtils.openURL(itemView.getContext(), item.parentFragment.getAccountID(), item.status.card.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.joinmastodon.android.ui.displayitems;
|
||||
import static org.joinmastodon.android.MastodonApp.context;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.SpannableStringBuilder;
|
||||
@@ -14,6 +15,7 @@ import android.widget.TextView;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
@@ -30,10 +32,13 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
private CharSequence text;
|
||||
@DrawableRes
|
||||
private int icon;
|
||||
private StatusPrivacy visibility;
|
||||
@DrawableRes
|
||||
private int iconEnd;
|
||||
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
||||
private View.OnClickListener handleClick;
|
||||
|
||||
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, @Nullable View.OnClickListener handleClick){
|
||||
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, StatusPrivacy visibility, @Nullable View.OnClickListener handleClick){
|
||||
super(parentID, parentFragment);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
|
||||
HtmlParser.parseCustomEmoji(ssb, emojis);
|
||||
@@ -43,6 +48,17 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
this.handleClick=handleClick;
|
||||
TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
|
||||
updateVisibility(visibility);
|
||||
}
|
||||
|
||||
public void updateVisibility(StatusPrivacy visibility) {
|
||||
this.visibility = visibility;
|
||||
this.iconEnd = visibility != null ? switch (visibility) {
|
||||
case PUBLIC -> R.drawable.ic_fluent_earth_20_regular;
|
||||
case UNLISTED -> R.drawable.ic_fluent_people_community_20_regular;
|
||||
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
|
||||
default -> 0;
|
||||
} : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,10 +86,18 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
@Override
|
||||
public void onBind(ReblogOrReplyLineStatusDisplayItem item){
|
||||
text.setText(item.text);
|
||||
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0);
|
||||
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, item.iconEnd, 0);
|
||||
if(item.handleClick!=null) text.setOnClickListener(item.handleClick);
|
||||
text.setEnabled(!item.inset);
|
||||
text.setClickable(!item.inset);
|
||||
Context ctx = itemView.getContext();
|
||||
int visibilityText = item.visibility != null ? switch (item.visibility) {
|
||||
case PUBLIC -> R.string.visibility_public;
|
||||
case UNLISTED -> R.string.sk_visibility_unlisted;
|
||||
case PRIVATE -> R.string.visibility_followers_only;
|
||||
default -> 0;
|
||||
} : 0;
|
||||
if (visibilityText != 0) text.setContentDescription(item.text + " (" + ctx.getString(visibilityText) + ")");
|
||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
||||
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.DisplayItemsParent;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.Poll;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
||||
@@ -73,26 +75,27 @@ public abstract class StatusDisplayItem{
|
||||
};
|
||||
}
|
||||
|
||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter){
|
||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification){
|
||||
String parentID=parentObject.getID();
|
||||
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
||||
Status statusForContent=status.getContentStatus();
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
if(status.reblog!=null){
|
||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20_filled, i->{
|
||||
boolean isOwnPost = AccountSessionManager.getInstance().isSelf(fragment.getAccountID(), status.account);
|
||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20_filled, isOwnPost ? status.visibility : null, i->{
|
||||
args.putParcelable("profileAccount", Parcels.wrap(status.account));
|
||||
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
||||
}));
|
||||
}else if(status.inReplyToAccountId!=null && knownAccounts.containsKey(status.inReplyToAccountId)){
|
||||
Account account=Objects.requireNonNull(knownAccounts.get(status.inReplyToAccountId));
|
||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_fluent_arrow_reply_20_filled, i->{
|
||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_fluent_arrow_reply_20_filled, null, i->{
|
||||
args.putParcelable("profileAccount", Parcels.wrap(account));
|
||||
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
||||
}));
|
||||
}
|
||||
HeaderStatusDisplayItem header;
|
||||
items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null));
|
||||
items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null, notification));
|
||||
if(!TextUtils.isEmpty(statusForContent.content))
|
||||
items.add(new TextStatusDisplayItem(parentID, HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID), fragment, statusForContent));
|
||||
else
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.widget.LinearLayout;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.statuses.TranslateStatus;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
@@ -24,6 +25,7 @@ import org.joinmastodon.android.model.StatusPrivacy;
|
||||
import org.joinmastodon.android.model.TranslatedStatus;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.LinkedTextView;
|
||||
|
||||
import me.grishka.appkit.api.Callback;
|
||||
@@ -31,6 +33,7 @@ import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.MovieDrawable;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
@@ -41,10 +44,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
public final Status status;
|
||||
public boolean translated = false;
|
||||
public TranslatedStatus translation = null;
|
||||
|
||||
private AccountSession session;
|
||||
private Instance instanceInfo;
|
||||
private boolean translateEnabled;
|
||||
|
||||
public TextStatusDisplayItem(String parentID, CharSequence text, BaseStatusListFragment parentFragment, Status status){
|
||||
super(parentID, parentFragment);
|
||||
@@ -57,8 +57,6 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
spoilerEmojiHelper.setText(parsedSpoilerText);
|
||||
}
|
||||
session = AccountSessionManager.getInstance().getAccount(parentFragment.getAccountID());
|
||||
instanceInfo = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
||||
translateEnabled = instanceInfo.v2 != null && instanceInfo.v2.configuration.translation != null && instanceInfo.v2.configuration.translation.enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,7 +83,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
private final LinearLayout spoilerHeader;
|
||||
private final TextView spoilerTitle, spoilerTitleInline, translateInfo;
|
||||
private final View spoilerOverlay, borderTop, borderBottom, textWrap, translateWrap, translateProgress;
|
||||
private final Drawable backgroundColor, borderColor;
|
||||
private final int backgroundColor, borderColor;
|
||||
private final Button translateButton;
|
||||
|
||||
public Holder(Activity activity, ViewGroup parent){
|
||||
@@ -103,14 +101,8 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
translateInfo=findViewById(R.id.translate_info);
|
||||
translateProgress=findViewById(R.id.translate_progress);
|
||||
itemView.setOnClickListener(v->item.parentFragment.onRevealSpoilerClick(this));
|
||||
|
||||
TypedValue outValue=new TypedValue();
|
||||
activity.getTheme().resolveAttribute(R.attr.colorBackgroundLight, outValue, true);
|
||||
backgroundColor=activity.getDrawable(outValue.resourceId);
|
||||
// activity.getTheme().resolveAttribute(R.attr.colorBackgroundLightest, outValue, true);
|
||||
// backgroundColorInset=activity.getDrawable(outValue.resourceId);
|
||||
activity.getTheme().resolveAttribute(R.attr.colorPollVoted, outValue, true);
|
||||
borderColor=activity.getDrawable(outValue.resourceId);
|
||||
backgroundColor=UiUtils.getThemeColor(activity, R.attr.colorBackgroundLight);
|
||||
borderColor=UiUtils.getThemeColor(activity, R.attr.colorPollVoted);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,10 +113,10 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
text.setTextIsSelectable(item.textSelectable);
|
||||
spoilerTitleInline.setTextIsSelectable(item.textSelectable);
|
||||
text.setInvalidateOnEveryFrame(false);
|
||||
spoilerTitleInline.setBackground(item.inset ? null : backgroundColor);
|
||||
spoilerTitleInline.setBackgroundColor(item.inset ? 0 : backgroundColor);
|
||||
spoilerTitleInline.setPadding(spoilerTitleInline.getPaddingLeft(), item.inset ? 0 : V.dp(14), spoilerTitleInline.getPaddingRight(), item.inset ? 0 : V.dp(14));
|
||||
borderTop.setBackground(item.inset ? null : borderColor);
|
||||
borderBottom.setBackground(item.inset ? null : borderColor);
|
||||
borderTop.setBackgroundColor(item.inset ? 0 : borderColor);
|
||||
borderBottom.setBackgroundColor(item.inset ? 0 : borderColor);
|
||||
if(!TextUtils.isEmpty(item.status.spoilerText)){
|
||||
spoilerTitle.setText(item.parsedSpoilerText);
|
||||
spoilerTitleInline.setText(item.parsedSpoilerText);
|
||||
@@ -146,7 +138,12 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
itemView.setClickable(false);
|
||||
}
|
||||
|
||||
translateWrap.setVisibility(item.textSelectable && item.translateEnabled &&
|
||||
Instance instanceInfo = AccountSessionManager.getInstance().getInstanceInfo(item.session.domain);
|
||||
boolean translateEnabled = instanceInfo.v2 != null && instanceInfo.v2.configuration.translation != null && instanceInfo.v2.configuration.translation.enabled;
|
||||
|
||||
translateWrap.setVisibility(
|
||||
(!GlobalUserPreferences.translateButtonOpenedOnly || item.textSelectable) &&
|
||||
translateEnabled &&
|
||||
!item.status.visibility.isLessVisibleThan(StatusPrivacy.UNLISTED) &&
|
||||
item.status.language != null &&
|
||||
(item.session.preferences == null || !item.status.language.equalsIgnoreCase(item.session.preferences.postingDefaultLanguage))
|
||||
@@ -157,6 +154,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
if (item.translation == null) {
|
||||
translateProgress.setVisibility(View.VISIBLE);
|
||||
translateButton.setClickable(false);
|
||||
translateButton.animate().alpha(0.5f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start();
|
||||
new TranslateStatus(item.status.id).setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(TranslatedStatus translatedStatus) {
|
||||
@@ -164,6 +162,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
item.translated = true;
|
||||
translateProgress.setVisibility(View.GONE);
|
||||
translateButton.setClickable(true);
|
||||
translateButton.animate().alpha(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(50).start();
|
||||
rebind();
|
||||
}
|
||||
|
||||
@@ -171,6 +170,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
public void onError(ErrorResponse error) {
|
||||
translateProgress.setVisibility(View.GONE);
|
||||
translateButton.setClickable(true);
|
||||
translateButton.animate().alpha(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(50).start();
|
||||
error.showToast(itemView.getContext());
|
||||
}
|
||||
}).exec(item.parentFragment.getAccountID());
|
||||
|
||||
@@ -10,6 +10,8 @@ import android.text.Layout;
|
||||
import android.text.Spanned;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SoundEffectConstants;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.TextView;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
@@ -20,7 +22,11 @@ public class ClickableLinksDelegate {
|
||||
private Path hlPath;
|
||||
private LinkSpan selectedSpan;
|
||||
private TextView view;
|
||||
|
||||
|
||||
private final Runnable longClickRunnable = () -> {
|
||||
if (selectedSpan != null) selectedSpan.onLongClick(view);
|
||||
};
|
||||
|
||||
public ClickableLinksDelegate(TextView view) {
|
||||
this.view=view;
|
||||
hlPaint=new Paint();
|
||||
@@ -30,6 +36,7 @@ public class ClickableLinksDelegate {
|
||||
}
|
||||
|
||||
public boolean onTouch(MotionEvent event) {
|
||||
long eventDuration = event.getEventTime() - event.getDownTime();
|
||||
if(event.getAction()==MotionEvent.ACTION_DOWN){
|
||||
int line=-1;
|
||||
Rect rect=new Rect();
|
||||
@@ -63,6 +70,7 @@ public class ClickableLinksDelegate {
|
||||
}
|
||||
hlPath=new Path();
|
||||
selectedSpan=span;
|
||||
view.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout());
|
||||
hlPaint.setColor((span.getColor() & 0x00FFFFFF) | 0x33000000);
|
||||
//l.getSelectionPath(start, end, hlPath);
|
||||
for(int j=lstart;j<=lend;j++){
|
||||
@@ -90,8 +98,11 @@ public class ClickableLinksDelegate {
|
||||
}
|
||||
}
|
||||
if(event.getAction()==MotionEvent.ACTION_UP && selectedSpan!=null){
|
||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||
selectedSpan.onClick(view.getContext());
|
||||
if (eventDuration <= ViewConfiguration.getLongPressTimeout()) {
|
||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||
selectedSpan.onClick(view.getContext());
|
||||
}
|
||||
view.removeCallbacks(longClickRunnable);
|
||||
hlPath=null;
|
||||
selectedSpan=null;
|
||||
view.invalidate();
|
||||
@@ -100,6 +111,7 @@ public class ClickableLinksDelegate {
|
||||
if(event.getAction()==MotionEvent.ACTION_CANCEL){
|
||||
hlPath=null;
|
||||
selectedSpan=null;
|
||||
view.removeCallbacks(longClickRunnable);
|
||||
view.invalidate();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -111,14 +111,14 @@ public class HtmlParser{
|
||||
@Override
|
||||
public void head(@NonNull Node node, int depth){
|
||||
if(node instanceof TextNode textNode){
|
||||
ssb.append(textNode.text());
|
||||
ssb.append(textNode.getWholeText());
|
||||
}else if(node instanceof Element el){
|
||||
switch(el.nodeName()){
|
||||
case "a" -> {
|
||||
String href=el.attr("href");
|
||||
LinkSpan.Type linkType;
|
||||
String text=el.text();
|
||||
if(el.hasClass("hashtag")){
|
||||
String text=el.text();
|
||||
if(text.startsWith("#")){
|
||||
linkType=LinkSpan.Type.HASHTAG;
|
||||
href=text.substring(1);
|
||||
@@ -136,7 +136,7 @@ public class HtmlParser{
|
||||
}else{
|
||||
linkType=LinkSpan.Type.URL;
|
||||
}
|
||||
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID), ssb.length(), el));
|
||||
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID, text), ssb.length(), el));
|
||||
}
|
||||
case "br" -> ssb.append('\n');
|
||||
case "span" -> {
|
||||
@@ -182,7 +182,7 @@ public class HtmlParser{
|
||||
ssb.append("…", new DeleteWhenCopiedSpan(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}else if(blockElements.contains(el.nodeName()) && node.nextSibling()!=null){
|
||||
ssb.append("\n"); // line end
|
||||
ssb.append("\n", new RelativeSizeSpan(0.75f), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // margin after block
|
||||
ssb.append("\n", new RelativeSizeSpan(0.65f), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // margin after block
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -260,7 +260,7 @@ public class HtmlParser{
|
||||
String url=matcher.group(3);
|
||||
if(TextUtils.isEmpty(matcher.group(4)))
|
||||
url="http://"+url;
|
||||
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null), matcher.start(3), matcher.end(3), 0);
|
||||
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null, url), matcher.start(3), matcher.end(3), 0);
|
||||
}while(matcher.find()); // Find more URLs
|
||||
return ssb;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.joinmastodon.android.ui.text;
|
||||
import android.content.Context;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.view.View;
|
||||
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
@@ -13,12 +14,14 @@ public class LinkSpan extends CharacterStyle {
|
||||
private String link;
|
||||
private Type type;
|
||||
private String accountID;
|
||||
private String text;
|
||||
|
||||
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID){
|
||||
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID, String text){
|
||||
this.listener=listener;
|
||||
this.link=link;
|
||||
this.type=type;
|
||||
this.accountID=accountID;
|
||||
this.text=text;
|
||||
}
|
||||
|
||||
public int getColor(){
|
||||
@@ -38,6 +41,10 @@ public class LinkSpan extends CharacterStyle {
|
||||
}
|
||||
}
|
||||
|
||||
public void onLongClick(View view) {
|
||||
UiUtils.copyText(view, getType() == Type.URL ? link : text);
|
||||
}
|
||||
|
||||
public String getLink(){
|
||||
return link;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.joinmastodon.android.ui.utils;
|
||||
|
||||
import static org.joinmastodon.android.GlobalUserPreferences.ColorPreference;
|
||||
import static org.joinmastodon.android.GlobalUserPreferences.ThemePreference;
|
||||
import static org.joinmastodon.android.GlobalUserPreferences.theme;
|
||||
import static org.joinmastodon.android.GlobalUserPreferences.trueBlackTheme;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import androidx.annotation.StyleRes;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ColorPalette {
|
||||
public static final Map<GlobalUserPreferences.ColorPreference, ColorPalette> palettes = Map.of(
|
||||
ColorPreference.MATERIAL3, new ColorPalette(R.style.ColorPalette_Material3)
|
||||
.dark(R.style.ColorPalette_Material3_Dark, R.style.ColorPalette_Material3_AutoLightDark),
|
||||
ColorPreference.PINK, new ColorPalette(R.style.ColorPalette_Pink),
|
||||
ColorPreference.PURPLE, new ColorPalette(R.style.ColorPalette_Purple),
|
||||
ColorPreference.GREEN, new ColorPalette(R.style.ColorPalette_Green),
|
||||
ColorPreference.BLUE, new ColorPalette(R.style.ColorPalette_Blue),
|
||||
ColorPreference.BROWN, new ColorPalette(R.style.ColorPalette_Brown),
|
||||
ColorPreference.RED, new ColorPalette(R.style.ColorPalette_Red),
|
||||
ColorPreference.YELLOW, new ColorPalette(R.style.ColorPalette_Yellow)
|
||||
);
|
||||
|
||||
private @StyleRes int base;
|
||||
private @StyleRes int autoDark;
|
||||
private @StyleRes int light;
|
||||
private @StyleRes int dark;
|
||||
private @StyleRes int black;
|
||||
private @StyleRes int autoBlack;
|
||||
|
||||
public ColorPalette(@StyleRes int baseRes) { base = baseRes; }
|
||||
|
||||
public ColorPalette(@StyleRes int lightRes, @StyleRes int darkRes, @StyleRes int autoDarkRes, @StyleRes int blackRes, @StyleRes int autoBlackRes) {
|
||||
light = lightRes;
|
||||
dark = darkRes;
|
||||
autoDark = autoDarkRes;
|
||||
black = blackRes;
|
||||
autoBlack = autoBlackRes;
|
||||
}
|
||||
|
||||
public ColorPalette light(@StyleRes int res) { light = res; return this; }
|
||||
public ColorPalette dark(@StyleRes int res, @StyleRes int auto) { dark = res; autoDark = auto; return this; }
|
||||
public ColorPalette black(@StyleRes int res, @StyleRes int auto) { dark = res; autoBlack = auto; return this; }
|
||||
|
||||
public void apply(Context context) {
|
||||
if (!((dark != 0 && autoDark != 0) || (black != 0 && autoBlack != 0) || light != 0 || base != 0)) {
|
||||
throw new IllegalStateException("Invalid color scheme definition");
|
||||
}
|
||||
|
||||
Resources.Theme t = context.getTheme();
|
||||
if (base != 0) t.applyStyle(base, true);
|
||||
if (light != 0 && theme.equals(ThemePreference.LIGHT)) t.applyStyle(light, true);
|
||||
else if (theme.equals(ThemePreference.DARK)) {
|
||||
if (dark != 0 && !trueBlackTheme) t.applyStyle(dark, true);
|
||||
else if (black != 0 && trueBlackTheme) t.applyStyle(black, true);
|
||||
} else if (theme.equals(ThemePreference.AUTO)) {
|
||||
if (autoDark != 0 && !trueBlackTheme) t.applyStyle(autoDark, true);
|
||||
else if (autoBlack != 0 && trueBlackTheme) t.applyStyle(autoBlack, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,16 @@
|
||||
package org.joinmastodon.android.ui.utils;
|
||||
|
||||
import static org.joinmastodon.android.GlobalUserPreferences.theme;
|
||||
import static org.joinmastodon.android.GlobalUserPreferences.trueBlackTheme;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
@@ -19,10 +26,13 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.provider.Settings;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@@ -42,9 +52,12 @@ import org.joinmastodon.android.api.requests.accounts.SetAccountMuted;
|
||||
import org.joinmastodon.android.api.requests.accounts.SetDomainBlocked;
|
||||
import org.joinmastodon.android.api.requests.accounts.AuthorizeFollowRequest;
|
||||
import org.joinmastodon.android.api.requests.accounts.RejectFollowRequest;
|
||||
import org.joinmastodon.android.api.requests.notifications.DismissNotification;
|
||||
import org.joinmastodon.android.api.requests.search.GetSearchResults;
|
||||
import org.joinmastodon.android.api.requests.statuses.DeleteStatus;
|
||||
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
|
||||
import org.joinmastodon.android.api.requests.statuses.SetStatusPinned;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.events.FollowRequestHandledEvent;
|
||||
@@ -52,16 +65,17 @@ import org.joinmastodon.android.events.NotificationDeletedEvent;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
import org.joinmastodon.android.events.StatusUnpinnedEvent;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ListTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.SearchResults;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
||||
@@ -70,6 +84,8 @@ import org.parceler.Parcels;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
@@ -83,6 +99,7 @@ import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
@@ -458,6 +475,25 @@ public class UiUtils{
|
||||
);
|
||||
}
|
||||
|
||||
public static void confirmDeleteNotification(Activity activity, String accountID, Notification notification, Runnable callback) {
|
||||
showConfirmationAlert(activity,
|
||||
notification == null ? R.string.sk_clear_all_notifications : R.string.sk_delete_notification,
|
||||
notification == null ? R.string.sk_clear_all_notifications_confirm : R.string.sk_delete_notification_confirm,
|
||||
notification == null ? R.string.sk_clear_all_notifications_confirm_action : R.string.sk_delete_notification_confirm_action,
|
||||
()-> new DismissNotification(notification != null ? notification.id : null).setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(Object o) {
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
error.showToast(activity);
|
||||
}
|
||||
}).exec(accountID)
|
||||
);
|
||||
}
|
||||
|
||||
public static void setRelationshipToActionButton(Relationship relationship, Button button){
|
||||
setRelationshipToActionButton(relationship, button, false);
|
||||
}
|
||||
@@ -656,103 +692,91 @@ public class UiUtils{
|
||||
}
|
||||
|
||||
public static void setUserPreferredTheme(Context context){
|
||||
// boolean isDarkTheme = isDarkTheme();
|
||||
switch(GlobalUserPreferences.color){
|
||||
case PINK:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack : R.style.Theme_Mastodon_AutoLightDark;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack : R.style.Theme_Mastodon_Dark;
|
||||
});
|
||||
break;
|
||||
case PURPLE:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Original : R.style.Theme_Mastodon_AutoLightDark_Original;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Original;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Original : R.style.Theme_Mastodon_Dark_Original;
|
||||
});
|
||||
break;
|
||||
case GREEN:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Green : R.style.Theme_Mastodon_AutoLightDark_Green;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Green;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Green : R.style.Theme_Mastodon_Dark_Green;
|
||||
});
|
||||
break;
|
||||
case BLUE:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Blue : R.style.Theme_Mastodon_AutoLightDark_Blue;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Blue;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Blue : R.style.Theme_Mastodon_Dark_Blue;
|
||||
});
|
||||
break;
|
||||
case BROWN:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Brown : R.style.Theme_Mastodon_AutoLightDark_Brown;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Brown;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Brown : R.style.Theme_Mastodon_Dark_Brown;
|
||||
});
|
||||
break;
|
||||
case RED:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Red : R.style.Theme_Mastodon_AutoLightDark_Red;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Red;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Red : R.style.Theme_Mastodon_Dark_Red;
|
||||
});
|
||||
break;
|
||||
case YELLOW:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Yellow : R.style.Theme_Mastodon_AutoLightDark_Yellow;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Yellow;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Yellow : R.style.Theme_Mastodon_Dark_Yellow;
|
||||
});
|
||||
break;
|
||||
case MATERIAL3:
|
||||
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||
case AUTO ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Material3 : R.style.Theme_Mastodon_AutoLightDark_Material3;
|
||||
case LIGHT ->
|
||||
R.style.Theme_Mastodon_Light_Material3;
|
||||
case DARK ->
|
||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Material3 : R.style.Theme_Mastodon_Dark_Material3;
|
||||
});
|
||||
break;
|
||||
}
|
||||
context.setTheme(switch (theme) {
|
||||
case LIGHT -> R.style.Theme_Mastodon_Light;
|
||||
case DARK -> trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack : R.style.Theme_Mastodon_Dark;
|
||||
default -> trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack : R.style.Theme_Mastodon_AutoLightDark;
|
||||
});
|
||||
|
||||
ColorPalette palette = ColorPalette.palettes.get(GlobalUserPreferences.color);
|
||||
if (palette != null) palette.apply(context);
|
||||
}
|
||||
public static boolean isDarkTheme(){
|
||||
if(GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.AUTO)
|
||||
if(theme==GlobalUserPreferences.ThemePreference.AUTO)
|
||||
return (MastodonApp.context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)==Configuration.UI_MODE_NIGHT_YES;
|
||||
return GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.DARK;
|
||||
return theme==GlobalUserPreferences.ThemePreference.DARK;
|
||||
}
|
||||
|
||||
public static void openURL(Context context, @Nullable String accountID, String url){
|
||||
// https://mastodon.foo.bar/@User
|
||||
// https://mastodon.foo.bar/@User/43456787654678
|
||||
// https://pleroma.foo.bar/users/User
|
||||
// https://pleroma.foo.bar/users/9qTHT2ANWUdXzENqC0
|
||||
// https://pleroma.foo.bar/notice/9sBHWIlwwGZi5QGlHc
|
||||
// https://pleroma.foo.bar/objects/d4643c42-3ae0-4b73-b8b0-c725f5819207
|
||||
// https://friendica.foo.bar/profile/user
|
||||
// https://friendica.foo.bar/display/d4643c42-3ae0-4b73-b8b0-c725f5819207
|
||||
// https://misskey.foo.bar/notes/83w6r388br (always lowercase)
|
||||
// https://pixelfed.social/p/connyduck/391263492998670833
|
||||
// https://pixelfed.social/connyduck
|
||||
// https://gts.foo.bar/@goblin/statuses/01GH9XANCJ0TA8Y95VE9H3Y0Q2
|
||||
// https://gts.foo.bar/@goblin
|
||||
// https://foo.microblog.pub/o/5b64045effd24f48a27d7059f6cb38f5
|
||||
//
|
||||
// COPIED FROM https://github.com/tuskyapp/Tusky/blob/develop/app/src/main/java/com/keylesspalace/tusky/util/LinkHelper.kt
|
||||
public static boolean looksLikeMastodonUrl(String urlString) {
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(urlString);
|
||||
} catch (URISyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uri.getQuery() != null || uri.getFragment() != null || uri.getPath() == null) return false;
|
||||
|
||||
String it = uri.getPath();
|
||||
return it.matches("^/@[^/]+$") ||
|
||||
it.matches("^/@[^/]+/\\d+$") ||
|
||||
it.matches("^/users/\\w+$") ||
|
||||
it.matches("^/notice/[a-zA-Z0-9]+$") ||
|
||||
it.matches("^/objects/[-a-f0-9]+$") ||
|
||||
it.matches("^/notes/[a-z0-9]+$") ||
|
||||
it.matches("^/display/[-a-f0-9]+$") ||
|
||||
it.matches("^/profile/\\w+$") ||
|
||||
it.matches("^/p/\\w+/\\d+$") ||
|
||||
it.matches("^/\\w+$") ||
|
||||
it.matches("^/@[^/]+/statuses/[a-zA-Z0-9]+$") ||
|
||||
it.matches("^/users/[^/]+/statuses/[a-zA-Z0-9]+$") ||
|
||||
it.matches("^/o/[a-f0-9]+$");
|
||||
}
|
||||
|
||||
public static String getInstanceName(String accountID) {
|
||||
AccountSession session = AccountSessionManager.getInstance().getAccount(accountID);
|
||||
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
||||
return instance != null && !instance.title.isBlank() ? instance.title : session.domain;
|
||||
}
|
||||
|
||||
public static void openURL(Context context, String accountID, String url) {
|
||||
openURL(context, accountID, url, true);
|
||||
}
|
||||
|
||||
public static void openURL(Context context, String accountID, String url, boolean launchBrowser){
|
||||
Consumer<ProgressDialog> transformDialogForLookup = dialog -> {
|
||||
if (accountID != null) {
|
||||
dialog.setTitle(context.getString(R.string.sk_loading_resource_on_instance_title, getInstanceName(accountID)));
|
||||
} else {
|
||||
dialog.setTitle(R.string.sk_loading_fediverse_resource_title);
|
||||
}
|
||||
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), (d, which) -> d.cancel());
|
||||
dialog.setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.open_in_browser), (d, which) -> {
|
||||
d.cancel();
|
||||
launchWebBrowser(context, url);
|
||||
});
|
||||
};
|
||||
|
||||
Uri uri=Uri.parse(url);
|
||||
if(accountID!=null && "https".equals(uri.getScheme()) && AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority())){
|
||||
List<String> path=uri.getPathSegments();
|
||||
// Match URLs like https://mastodon.social/@Gargron/108132679274083591
|
||||
if(path.size()==2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$")){
|
||||
List<String> path=uri.getPathSegments();
|
||||
if(accountID!=null && "https".equals(uri.getScheme())){
|
||||
if(path.size()==2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$") && AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority())){
|
||||
new GetStatusByID(path.get(1))
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
@@ -766,14 +790,64 @@ public class UiUtils{
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(context);
|
||||
launchWebBrowser(context, url);
|
||||
if (launchBrowser) launchWebBrowser(context, url);
|
||||
}
|
||||
})
|
||||
.wrapProgress((Activity)context, R.string.loading, true)
|
||||
.wrapProgress((Activity)context, R.string.loading, true, transformDialogForLookup)
|
||||
.exec(accountID);
|
||||
return;
|
||||
} else if (looksLikeMastodonUrl(url)) {
|
||||
new GetSearchResults(url, null, true)
|
||||
.setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(SearchResults results) {
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
if (!results.statuses.isEmpty()) {
|
||||
args.putParcelable("status", Parcels.wrap(results.statuses.get(0)));
|
||||
Nav.go((Activity) context, ThreadFragment.class, args);
|
||||
} else if (!results.accounts.isEmpty()) {
|
||||
args.putParcelable("profileAccount", Parcels.wrap(results.accounts.get(0)));
|
||||
Nav.go((Activity) context, ProfileFragment.class, args);
|
||||
} else {
|
||||
if (launchBrowser) launchWebBrowser(context, url);
|
||||
else Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
error.showToast(context);
|
||||
if (launchBrowser) launchWebBrowser(context, url);
|
||||
}
|
||||
})
|
||||
.wrapProgress((Activity)context, R.string.loading, true, transformDialogForLookup)
|
||||
.exec(accountID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
launchWebBrowser(context, url);
|
||||
}
|
||||
|
||||
public static void copyText(View v, String text) {
|
||||
Context context = v.getContext();
|
||||
context.getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText(null, text));
|
||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.TIRAMISU || UiUtils.isMIUI()){ // Android 13+ SystemUI shows its own thing when you put things into the clipboard
|
||||
Toast.makeText(context, R.string.text_copied, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
v.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
|
||||
}
|
||||
|
||||
private static String getSystemProperty(String key){
|
||||
try{
|
||||
Class<?> props=Class.forName("android.os.SystemProperties");
|
||||
Method get=props.getMethod("get", String.class);
|
||||
return (String)get.invoke(null, key);
|
||||
}catch(Exception ignore){}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isMIUI(){
|
||||
return !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.code"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/gray_50"/>
|
||||
<item android:color="?colorGray50"/>
|
||||
</selector>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/gray_800"/>
|
||||
<solid android:color="?colorGray800"/>
|
||||
<corners android:radius="10dp"/>
|
||||
<padding android:top="16dp" android:left="16dp" android:right="16dp" android:bottom="16dp"/>
|
||||
</shape>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/gray_25"/>
|
||||
<solid android:color="?colorGray25"/>
|
||||
<corners android:radius="10dp"/>
|
||||
<padding android:top="16dp" android:left="16dp" android:right="16dp" android:bottom="16dp"/>
|
||||
</shape>
|
||||
@@ -2,7 +2,7 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/highlight_over_dark">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="?colorSearchHint"/>
|
||||
<solid android:color="?colorGray600"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:tint="@color/gray_800">
|
||||
<shape android:tint="?colorGray800">
|
||||
<solid android:color="#CC000000"/>
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<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.0653,14.9329C14.0639,14.9132 14.0475,14.8978 14.0278,14.8978C14.0125,14.8978 13.9987,14.9072 13.993,14.9214C13.6711,15.7244 13.2265,16.3336 12.6594,16.7489C12.0948,17.1603 11.4132,17.366 10.6146,17.366C9.5096,17.366 8.6183,16.9587 7.9407,16.144C7.2632,15.3293 6.9244,14.2202 6.9244,12.8167C6.9244,10.9857 7.3922,9.4773 8.3279,8.2916C9.2716,7.1059 10.4574,6.513 11.8851,6.513C12.4658,6.513 12.9659,6.6421 13.3854,6.9002C13.8048,7.1583 14.0992,7.489 14.2686,7.8923H14.317L14.3417,7.6527C14.3964,7.122 14.8435,6.7187 15.3769,6.7187C15.9898,6.7187 16.4699,7.246 16.4136,7.8562C16.2791,9.3148 16.1731,10.4964 16.0956,11.4011C16.0069,12.5223 15.9625,13.216 15.9625,13.4822C15.9544,14.1839 16.0512,14.7082 16.2529,15.0551C16.4545,15.4019 16.761,15.5753 17.1724,15.5753C17.9226,15.5753 18.5477,15.1276 19.0478,14.2323C19.5479,13.337 19.7979,12.1754 19.7979,10.7477C19.7979,8.7151 19.1446,7.0494 17.8379,5.7508C16.5312,4.4521 14.7284,3.8028 12.4295,3.8028C10.0177,3.8028 8.0415,4.6094 6.5009,6.2226C4.9683,7.8358 4.2021,9.8484 4.2021,12.2601C4.2021,14.6316 4.9159,16.5191 6.3436,17.9226C7.7713,19.318 9.7193,20.0157 12.1875,20.0157C13.1393,20.0157 14.0307,19.923 14.8615,19.7374C15.3602,19.6309 15.8386,19.4953 16.2966,19.3307C16.7909,19.153 17.3563,19.3639 17.5632,19.8467C17.7578,20.3007 17.5634,20.8314 17.1019,21.0073C16.5257,21.2269 15.9039,21.4046 15.2365,21.5402C14.2525,21.75 13.1837,21.8548 12.0302,21.8548C9.0135,21.8548 6.5856,20.9837 4.7465,19.2414C2.9155,17.4991 2,15.1922 2,12.3206C2,9.3765 2.9679,6.9204 4.9038,4.9522C6.8397,2.9841 9.3442,2 12.4174,2C15.2002,2 17.491,2.7985 19.2898,4.3956C21.0966,5.9847 22,8.0738 22,10.663C22,12.6473 21.4878,14.2605 20.4634,15.5027C19.4471,16.7449 18.217,17.366 16.7731,17.366C15.9504,17.366 15.3051,17.1482 14.8373,16.7126C14.3765,16.2837 14.1192,15.6904 14.0653,14.9329ZM12.1512,8.2674C11.2398,8.2674 10.5098,8.707 9.9613,9.5862C9.4128,10.4573 9.1385,11.5342 9.1385,12.8167C9.1385,13.6798 9.32,14.3573 9.683,14.8494C10.054,15.3333 10.542,15.5753 11.147,15.5753C12.0423,15.5753 12.7481,15.1236 13.2644,14.2202C13.7806,13.3087 14.0387,12.0988 14.0387,10.5904C14.0387,9.8403 13.8734,9.2676 13.5426,8.8723C13.2119,8.4691 12.7481,8.2674 12.1512,8.2674Z"
|
||||
android:fillColor="#667085"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
|
||||
<path android:pathData="M10 2c4.418 0 8 3.582 8 8s-3.582 8-8 8-8-3.582-8-8 3.582-8 8-8zm0 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm3.358 4.646c0.174 0.174 0.193 0.443 0.058 0.638l-0.058 0.07-4.005 4.004c-0.173 0.174-0.442 0.193-0.637 0.058l-0.07-0.058-2-2c-0.195-0.195-0.195-0.511 0-0.707C6.82 9.478 7.09 9.46 7.284 9.594l0.07 0.057L9 11.298l3.651-3.652c0.196-0.195 0.512-0.195 0.707 0z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M21.78 3.28c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.768-0.293-1.06 0l-10 10-0.47 1.53 1.53-0.47 10-10zM6.25 3C4.455 3 3 4.455 3 6.25v11.5C3 19.545 4.455 21 6.25 21h11.5c1.795 0 3.25-1.455 3.25-3.25v-8C21 9.336 20.664 9 20.25 9S19.5 9.336 19.5 9.75v8c0 0.966-0.784 1.75-1.75 1.75H6.25c-0.966 0-1.75-0.784-1.75-1.75V6.25c0-0.966 0.784-1.75 1.75-1.75h8C14.664 4.5 15 4.164 15 3.75S14.664 3 14.25 3h-8z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
|
||||
<path android:pathData="M8.5 4h3c0-0.828-0.672-1.5-1.5-1.5S8.5 3.172 8.5 4zm-1 0c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5h5C17.776 4 18 4.224 18 4.5S17.776 5 17.5 5h-1.054l-1.194 10.344C15.077 16.858 13.796 18 12.272 18H7.728c-1.524 0-2.805-1.142-2.98-2.656L3.554 5H2.5C2.224 5 2 4.776 2 4.5S2.224 4 2.5 4h5zM9 8c0-0.276-0.224-0.5-0.5-0.5S8 7.724 8 8v6c0 0.276 0.224 0.5 0.5 0.5S9 14.276 9 14V8zm2.5-0.5C11.224 7.5 11 7.724 11 8v6c0 0.276 0.224 0.5 0.5 0.5S12 14.276 12 14V8c0-0.276-0.224-0.5-0.5-0.5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
|
||||
<path android:pathData="M3.897 4.054L3.97 3.97c0.266-0.267 0.683-0.29 0.976-0.073L5.03 3.97 10 8.939l4.97-4.97c0.266-0.266 0.683-0.29 0.976-0.072L16.03 3.97c0.267 0.266 0.29 0.683 0.073 0.976L16.03 5.03 11.061 10l4.97 4.97c0.266 0.266 0.29 0.683 0.072 0.976L16.03 16.03c-0.266 0.267-0.683 0.29-0.976 0.073L14.97 16.03 10 11.061l-4.97 4.97c-0.266 0.266-0.683 0.29-0.976 0.072L3.97 16.03c-0.267-0.266-0.29-0.683-0.073-0.976L3.97 14.97 8.939 10l-4.97-4.97C3.704 4.764 3.68 4.347 3.898 4.054L3.97 3.97 3.897 4.054z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M12.82 5.58l-0.821 0.822-0.823-0.823c-2.1-2.1-5.503-2.1-7.602 0-2.099 2.099-2.099 5.502 0 7.601l7.896 7.896c0.293 0.293 0.767 0.293 1.06 0l7.902-7.897c2.094-2.106 2.098-5.5-0.002-7.6-2.103-2.102-5.507-2.102-7.61 0zm6.548 6.541L12 19.485 4.635 12.12c-1.513-1.514-1.513-3.967 0-5.48 1.513-1.514 3.967-1.514 5.48 0l1.357 1.357c0.298 0.298 0.783 0.292 1.074-0.013L13.88 6.64c1.517-1.517 3.973-1.517 5.49 0 1.513 1.514 1.51 3.96-0.002 5.481z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -1,3 +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="M20.998 6.25c0-1.795-1.454-3.25-3.25-3.25H6.25C4.455 3 3 4.455 3 6.25v11.499c0 1.795 1.455 3.25 3.25 3.25h4.914l0.356-1.424 0.02-0.076H6.25c-0.204 0-0.4-0.035-0.582-0.1l5.807-5.685 0.083-0.07c0.291-0.213 0.7-0.19 0.966 0.07l2.079 2.036 1.06-1.06-2.09-2.048-0.128-0.116c-0.878-0.738-2.187-0.7-3.02 0.116l-5.822 5.7C4.536 18.157 4.5 17.957 4.5 17.75V6.25c0-0.966 0.783-1.75 1.75-1.75h11.499c0.966 0 1.75 0.784 1.75 1.75v4.983c0.478-0.19 0.993-0.264 1.5-0.22V6.25zm-3.495 2.502c0-1.244-1.008-2.252-2.252-2.252-1.244 0-2.252 1.008-2.252 2.252 0 1.243 1.008 2.252 2.252 2.252 1.244 0 2.252-1.009 2.252-2.252zm-3.004 0C14.499 8.336 14.836 8 15.251 8s0.752 0.336 0.752 0.752c0 0.415-0.337 0.752-0.752 0.752s-0.752-0.337-0.752-0.752zm4.6 3.917l-5.902 5.901c-0.345 0.345-0.589 0.776-0.707 1.248l-0.457 1.83c-0.2 0.797 0.522 1.518 1.318 1.319l1.83-0.458c0.472-0.118 0.904-0.362 1.248-0.706L22.33 15.9c0.892-0.893 0.892-2.34 0-3.232-0.893-0.893-2.34-0.893-3.233 0z" android:fillColor="@color/gray_25"/>
|
||||
<path android:pathData="M20.998 6.25c0-1.795-1.454-3.25-3.25-3.25H6.25C4.455 3 3 4.455 3 6.25v11.499c0 1.795 1.455 3.25 3.25 3.25h4.914l0.356-1.424 0.02-0.076H6.25c-0.204 0-0.4-0.035-0.582-0.1l5.807-5.685 0.083-0.07c0.291-0.213 0.7-0.19 0.966 0.07l2.079 2.036 1.06-1.06-2.09-2.048-0.128-0.116c-0.878-0.738-2.187-0.7-3.02 0.116l-5.822 5.7C4.536 18.157 4.5 17.957 4.5 17.75V6.25c0-0.966 0.783-1.75 1.75-1.75h11.499c0.966 0 1.75 0.784 1.75 1.75v4.983c0.478-0.19 0.993-0.264 1.5-0.22V6.25zm-3.495 2.502c0-1.244-1.008-2.252-2.252-2.252-1.244 0-2.252 1.008-2.252 2.252 0 1.243 1.008 2.252 2.252 2.252 1.244 0 2.252-1.009 2.252-2.252zm-3.004 0C14.499 8.336 14.836 8 15.251 8s0.752 0.336 0.752 0.752c0 0.415-0.337 0.752-0.752 0.752s-0.752-0.337-0.752-0.752zm4.6 3.917l-5.902 5.901c-0.345 0.345-0.589 0.776-0.707 1.248l-0.457 1.83c-0.2 0.797 0.522 1.518 1.318 1.319l1.83-0.458c0.472-0.118 0.904-0.362 1.248-0.706L22.33 15.9c0.892-0.893 0.892-2.34 0-3.232-0.893-0.893-2.34-0.893-3.233 0z" android:fillColor="?colorGray25"/>
|
||||
</vector>
|
||||
|
||||
@@ -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="M22 6.5c0 3.038-2.462 5.5-5.5 5.5S11 9.538 11 6.5 13.462 1 16.5 1 22 3.462 22 6.5zm-7.146-2.354c-0.196-0.195-0.512-0.195-0.708 0-0.195 0.196-0.195 0.512 0 0.708L15.793 6.5l-1.647 1.646c-0.195 0.196-0.195 0.512 0 0.707 0.196 0.196 0.512 0.196 0.708 0L16.5 7.208l1.646 1.647c0.196 0.195 0.512 0.195 0.708 0 0.195-0.196 0.195-0.512 0-0.707L17.207 6.5l1.647-1.646c0.195-0.196 0.195-0.512 0-0.708-0.196-0.195-0.512-0.195-0.708 0L16.5 5.793l-1.646-1.647zM19.5 14v-1.732c0.551-0.287 1.056-0.651 1.5-1.078v7.56c0 1.733-1.357 3.15-3.066 3.245L17.75 22H6.25c-1.733 0-3.15-1.357-3.245-3.066L3 18.75V7.25C3 5.517 4.356 4.1 6.066 4.005L6.25 4h4.248c-0.198 0.474-0.34 0.977-0.422 1.5H6.25c-0.918 0-1.671 0.707-1.744 1.606L4.5 7.25V14H9c0.38 0 0.694 0.282 0.743 0.648L9.75 14.75C9.75 15.993 10.757 17 12 17c1.19 0 2.166-0.925 2.245-2.096l0.005-0.154c0-0.38 0.282-0.694 0.648-0.743L15 14h4.5zm-15 1.5v3.25c0 0.918 0.707 1.671 1.606 1.744L6.25 20.5h11.5c0.918 0 1.671-0.707 1.744-1.607L19.5 18.75V15.5h-3.825c-0.335 1.648-1.75 2.904-3.475 2.995L12 18.5c-1.747 0-3.215-1.195-3.632-2.812L8.325 15.5H4.5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
|
||||
<path android:pathData="M10 2c4.418 0 8 3.582 8 8 0 2.706-1.142 4.5-3 4.5-1.226 0-2.14-0.781-2.62-2.09C11.784 13.393 10.781 14 9.5 14 7.36 14 6 12.307 6 10c0-2.337 1.313-4 3.5-4 1.052 0 1.901 0.385 2.5 1.044V6.5C12 6.224 12.224 6 12.5 6c0.245 0 0.45 0.177 0.492 0.41L13 6.5V10c0 2.223 0.813 3.5 2 3.5s2-1.277 2-3.5c0-3.866-3.134-7-7-7s-7 3.134-7 7 3.134 7 7 7c0.823 0 1.626-0.142 2.383-0.416 0.26-0.094 0.547 0.04 0.64 0.3 0.095 0.26-0.04 0.546-0.3 0.64C11.859 17.838 10.94 18 10 18c-4.418 0-8-3.582-8-8s3.582-8 8-8zM9.5 7C7.924 7 7 8.17 7 10c0 1.797 0.966 3 2.5 3s2.5-1.203 2.5-3c0-1.83-0.924-3-2.5-3z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M12 2c5.43 0 9.848 4.327 9.996 9.72L22 12v1.525c-0.014 2.198-1.8 3.975-4 3.975-1.446 0-2.712-0.767-3.415-1.916-0.8 0.834-1.882 1.35-3.085 1.35-2.515 0-4.5-2.25-4.5-4.967C7 9.25 8.985 7 11.5 7c0.937 0 1.8 0.312 2.514 0.844C14.087 7.366 14.501 7 15 7c0.513 0 0.935 0.386 0.993 0.883L16 8v5.5c0 1.105 0.895 2 2 2 1.054 0 1.918-0.816 1.994-1.85L20 13.474V12c0-4.418-3.582-8-8-8s-8 3.582-8 8 3.582 8 8 8c0.921 0 1.82-0.155 2.67-0.456 0.52-0.184 1.092 0.089 1.276 0.61 0.184 0.52-0.089 1.091-0.61 1.276C14.275 21.806 13.15 22 12 22 6.477 22 2 17.523 2 12S6.477 2 12 2zm-0.35 7.005L11.5 9C10.15 9 9 10.302 9 11.967c0 1.664 1.15 2.966 2.5 2.966 1.3 0 2.415-1.207 2.495-2.783L14 11.93c-0.017-1.586-1.075-2.834-2.35-2.925L11.5 9l0.15 0.005z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M22 12v1.75c0 2.071-1.679 3.75-3.75 3.75-1.504 0-2.802-0.886-3.399-2.164C14.033 16.356 12.84 17 11.5 17 8.992 17 7 14.742 7 12s1.992-5 4.5-5c1.159 0 2.208 0.482 3.001 1.272L14.5 7.75C14.5 7.336 14.836 7 15.25 7c0.38 0 0.694 0.282 0.743 0.648L16 7.75v6c0 1.243 1.007 2.25 2.25 2.25 1.19 0 2.166-0.925 2.245-2.096L20.5 13.75V12c0-4.694-3.806-8.5-8.5-8.5S3.5 7.306 3.5 12s3.806 8.5 8.5 8.5c1.033 0 2.04-0.184 2.985-0.539 0.388-0.145 0.82 0.051 0.966 0.439 0.145 0.388-0.051 0.82-0.439 0.966C14.398 21.783 13.214 22 12 22 6.477 22 2 17.523 2 12S6.477 2 12 2c5.43 0 9.848 4.327 9.996 9.72L22 12v1.75V12zM11.5 8.5c-1.634 0-3 1.548-3 3.5s1.366 3.5 3 3.5 3-1.548 3-3.5-1.366-3.5-3-3.5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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.987 2.89c0.077-0.408-0.19-0.8-0.598-0.877-0.407-0.077-0.799 0.19-0.876 0.598L8.494 7.998 3.75 8C3.335 8 3 8.336 3 8.75 3 9.166 3.336 9.5 3.75 9.5l4.46-0.002-0.946 5L2.75 14.5C2.335 14.5 2 14.836 2 15.25 2 15.665 2.336 16 2.75 16l4.23-0.002-0.967 5.116c-0.077 0.407 0.19 0.8 0.598 0.876 0.407 0.077 0.799-0.19 0.876-0.598l1.02-5.395 5.474-0.002-0.968 5.119c-0.077 0.407 0.19 0.8 0.598 0.876 0.407 0.077 0.799-0.19 0.876-0.598l1.021-5.398 4.742-0.002c0.415 0 0.75-0.336 0.75-0.75 0-0.415-0.336-0.75-0.75-0.75l-4.458 0.002 0.946-5 4.512-0.002c0.415 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75l-4.23 0.002 0.966-5.104c0.077-0.408-0.19-0.8-0.598-0.877-0.407-0.077-0.799 0.19-0.876 0.598l-1.018 5.384-5.474 0.002 0.966-5.107zm-1.25 6.608l5.474-0.003-0.946 5-5.474 0.002 0.946-5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M6.25 4.5C5.283 4.5 4.5 5.284 4.5 6.25v11.5c0 0.966 0.783 1.75 1.75 1.75h11.5c0.966 0 1.75-0.784 1.75-1.75v-4c0-0.414 0.335-0.75 0.75-0.75 0.414 0 0.75 0.336 0.75 0.75v4c0 1.795-1.456 3.25-3.25 3.25H6.25C4.455 21 3 19.545 3 17.75V6.25C3 4.455 4.455 3 6.25 3h4C10.664 3 11 3.336 11 3.75S10.664 4.5 10.25 4.5h-4zM13 3.75C13 3.336 13.335 3 13.75 3h6.5C20.664 3 21 3.336 21 3.75v6.5c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75V5.56l-5.22 5.22c-0.293 0.293-0.768 0.293-1.06 0-0.293-0.293-0.293-0.768 0-1.06l5.22-5.22h-4.69C13.335 4.5 13 4.164 13 3.75z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M11 17.5c0-1.289 0.376-2.49 1.023-3.5h-7.77c-1.242 0-2.25 1.007-2.25 2.25v0.919c0 0.572 0.18 1.13 0.511 1.596C4.056 20.929 6.58 22 10 22c0.932 0 1.797-0.08 2.592-0.24C11.601 20.62 11 19.13 11 17.5zm4-10.495c0-2.761-2.238-5-5-5-2.761 0-5 2.239-5 5s2.239 5 5 5c2.762 0 5-2.239 5-5zM23 17.5c0-3.037-2.462-5.5-5.5-5.5-3.037 0-5.5 2.463-5.5 5.5 0 3.038 2.463 5.5 5.5 5.5 3.038 0 5.5-2.462 5.5-5.5zm-5.59-3.492L17.5 14l0.09 0.008c0.204 0.037 0.365 0.198 0.402 0.402L18 14.5V17h2.504l0.09 0.008c0.204 0.037 0.365 0.198 0.402 0.402l0.008 0.09-0.008 0.09c-0.037 0.204-0.198 0.365-0.402 0.402L20.504 18H18v2.5l-0.008 0.09c-0.037 0.204-0.198 0.365-0.402 0.402L17.5 21l-0.09-0.008c-0.204-0.037-0.364-0.198-0.402-0.402L17 20.5V18h-2.496l-0.09-0.008c-0.204-0.037-0.365-0.198-0.402-0.402l-0.008-0.09 0.008-0.09c0.037-0.204 0.198-0.365 0.402-0.402L14.504 17H17v-2.5l0.008-0.09c0.038-0.204 0.198-0.365 0.402-0.402z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M5.694 12L2.299 3.27C2.063 2.664 2.655 2.083 3.241 2.29l0.093 0.039 18 9c0.518 0.259 0.55 0.968 0.097 1.284l-0.097 0.058-18 9c-0.583 0.291-1.216-0.245-1.065-0.848l0.03-0.095L5.694 12 2.299 3.27 5.694 12zM4.402 4.54l2.61 6.71h6.627c0.38 0 0.693 0.282 0.743 0.648L14.389 12c0 0.38-0.282 0.693-0.649 0.743l-0.1 0.007H7.01l-2.609 6.71L19.322 12 4.401 4.54z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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.502 11.5c0.554 0 1.002 0.448 1.002 1.002 0 0.553-0.448 1.002-1.002 1.002-0.553 0-1.002-0.449-1.002-1.002 0-0.554 0.449-1.003 1.002-1.003zM12 4.353v6.651h7.442L17.72 9.28c-0.267-0.266-0.29-0.683-0.073-0.977L17.72 8.22c0.266-0.266 0.683-0.29 0.976-0.072L18.78 8.22l2.997 2.998c0.266 0.266 0.29 0.682 0.073 0.976l-0.073 0.084-2.996 3.003c-0.293 0.294-0.767 0.294-1.06 0.002-0.267-0.266-0.292-0.683-0.075-0.977l0.073-0.084 1.713-1.717h-7.431L12 19.25c0 0.466-0.421 0.82-0.88 0.738l-8.5-1.501C2.26 18.424 2 18.112 2 17.748V5.75c0-0.368 0.266-0.681 0.628-0.74l8.5-1.396C11.585 3.539 12 3.89 12 4.354zm-1.5 0.883l-7 1.15v10.732l7 1.236V5.237zM13 18.5h0.765l0.102-0.007c0.366-0.05 0.649-0.364 0.648-0.744l-0.007-4.25H13v5zm0.002-8.502L13 8.726V5h0.745c0.38 0 0.693 0.281 0.743 0.647l0.007 0.101L14.502 10h-1.5z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:pathData="M5.997 12c0 0.38 0.282 0.694 0.647 0.743l0.102 0.007H19.44l-2.216 2.22c-0.266 0.266-0.29 0.683-0.073 0.976l0.073 0.084c0.266 0.267 0.682 0.29 0.975 0.073l0.084-0.073 3.497-3.5c0.267-0.266 0.29-0.683 0.073-0.976L21.78 11.47l-3.497-3.5c-0.292-0.293-0.767-0.293-1.06 0-0.265 0.266-0.29 0.683-0.072 0.976l0.073 0.084 2.216 2.22H6.746c-0.414 0-0.75 0.336-0.75 0.75zM2 12c0 2.761 2.237 5 4.996 5 2.143 0 3.972-1.351 4.68-3.25h-1.651C9.42 14.797 8.29 15.5 6.995 15.5 5.066 15.5 3.5 13.933 3.5 12s1.565-3.5 3.497-3.5c1.294 0 2.425 0.704 3.03 1.75h1.651C10.968 8.352 9.14 7 6.996 7 4.236 7 2 9.239 2 12z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -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="M16.961 5.987c0.13-0.394-0.082-0.818-0.475-0.949-0.393-0.13-0.818 0.083-0.948 0.476-0.148 0.445-0.304 1.04-0.42 1.512-0.736 0.026-1.446 0.018-2.067-0.024-0.413-0.028-0.771 0.284-0.8 0.697-0.027 0.413 0.285 0.771 0.698 0.8 0.563 0.038 1.19 0.05 1.844 0.037-0.144 0.765-0.241 1.449-0.3 2.064-1.215 0.642-2.061 1.504-2.539 2.412-0.613 1.166-0.66 2.556 0.206 3.443 0.571 0.584 1.408 0.64 2.129 0.485 0.405-0.087 0.825-0.248 1.24-0.474l0.018 0.046c0.145 0.389 0.577 0.586 0.965 0.44 0.388-0.144 0.585-0.576 0.44-0.964-0.056-0.152-0.114-0.291-0.17-0.424 1.023-0.936 1.915-2.308 2.285-4.047 0.638 0.312 1.07 0.836 1.278 1.4 0.227 0.613 0.213 1.312-0.097 1.952-0.308 0.636-0.933 1.265-2.015 1.681-0.387 0.149-0.58 0.583-0.431 0.97 0.149 0.386 0.582 0.579 0.969 0.43 1.387-0.533 2.33-1.402 2.827-2.427 0.494-1.02 0.518-2.143 0.154-3.127-0.414-1.116-1.3-2.01-2.505-2.424 0.002-0.073 0.003-0.147 0.003-0.222C19.25 9.336 18.914 9 18.5 9c-0.405 0-0.735 0.322-0.75 0.724-0.524-0.005-1.084 0.07-1.672 0.237 0.064-0.455 0.148-0.953 0.257-1.5 1.185-0.089 2.364-0.252 3.337-0.48 0.403-0.095 0.653-0.5 0.558-0.902-0.095-0.404-0.498-0.654-0.902-0.559-0.767 0.18-1.69 0.318-2.637 0.406 0.085-0.33 0.18-0.67 0.27-0.94zm-3.68 7.723c0.227-0.43 0.6-0.886 1.147-1.3 0.017 0.492 0.065 0.926 0.137 1.317 0.094 0.52 0.236 0.974 0.386 1.373-0.306 0.171-0.632 0.3-0.977 0.374-0.485 0.104-0.687-0.012-0.742-0.068-0.24-0.245-0.394-0.853 0.05-1.696zm4.315-2.487c-0.21 0.966-0.7 2.022-1.414 2.848-0.052-0.184-0.1-0.385-0.142-0.612-0.089-0.49-0.14-1.092-0.111-1.866 0.11-0.042 0.222-0.082 0.339-0.12 0.481-0.16 0.924-0.238 1.328-0.25zM7.96 6.53C5.72 5.878 3.958 6.681 3.385 6.997c-0.363 0.2-0.494 0.657-0.294 1.02C3.29 8.378 3.747 8.51 4.11 8.31c0.405-0.223 1.736-0.833 3.43-0.34 0.773 0.227 1.098 0.64 1.264 1.056 0.133 0.332 0.175 0.691 0.188 1.042-0.27-0.075-0.581-0.15-0.923-0.21-1.132-0.202-2.682-0.263-4.122 0.427-1.586 0.76-2.13 2.316-1.902 3.697 0.224 1.356 1.216 2.666 2.8 2.951 1.43 0.258 2.806-0.256 3.757-0.761 0.14-0.074 0.271-0.148 0.396-0.222v0.3c0 0.414 0.335 0.75 0.75 0.75 0.414 0 0.75-0.336 0.75-0.75v-5.79c0-0.454 0-1.236-0.3-1.99-0.331-0.829-1.005-1.578-2.236-1.94H7.96zm-0.153 4.804c0.483 0.086 0.898 0.206 1.19 0.305v2.506l-0.105 0.078C8.653 14.4 8.31 14.63 7.9 14.847c-0.84 0.447-1.85 0.779-2.788 0.61-0.845-0.152-1.445-0.866-1.586-1.72-0.138-0.83 0.179-1.673 1.07-2.1 1.037-0.496 2.226-0.478 3.212-0.303z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -5,5 +5,5 @@
|
||||
android:viewportHeight="4">
|
||||
<path
|
||||
android:pathData="M4,2C4,3.1046 3.1046,4 2,4C0.8954,4 0,3.1046 0,2C0,0.8954 0.8954,0 2,0C3.1046,0 4,0.8954 4,2ZM10,2C10,3.1046 9.1046,4 8,4C6.8954,4 6,3.1046 6,2C6,0.8954 6.8954,0 8,0C9.1046,0 10,0.8954 10,2ZM14,4C15.1046,4 16,3.1046 16,2C16,0.8954 15.1046,0 14,0C12.8954,0 12,0.8954 12,2C12,3.1046 12.8954,4 14,4Z"
|
||||
android:fillColor="@color/gray_500"/>
|
||||
android:fillColor="?colorGray500"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="27dp"/>
|
||||
<stroke android:width="2dp" android:color="@color/gray_25"/>
|
||||
<stroke android:width="2dp" android:color="?colorGray25"/>
|
||||
</shape>
|
||||
@@ -2,14 +2,14 @@
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:gravity="center_vertical">
|
||||
<shape>
|
||||
<solid android:color="@color/gray_500"/>
|
||||
<solid android:color="?colorGray500"/>
|
||||
<corners android:radius="1dp"/>
|
||||
<size android:height="2dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:gravity="center_vertical" android:id="@android:id/secondaryProgress">
|
||||
<clip>
|
||||
<shape android:tint="@color/gray_50">
|
||||
<shape android:tint="?colorGray50">
|
||||
<solid android:color="#40000000"/>
|
||||
<corners android:radius="1dp"/>
|
||||
<size android:height="2dp"/>
|
||||
@@ -19,7 +19,7 @@
|
||||
<item android:gravity="center_vertical" android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="@color/gray_50"/>
|
||||
<solid android:color="?colorGray50"/>
|
||||
<corners android:radius="1dp"/>
|
||||
<size android:height="2dp"/>
|
||||
</shape>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/gray_25"/>
|
||||
<solid android:color="?colorGray25"/>
|
||||
<size android:width="18dp" android:height="18dp"/>
|
||||
</shape>
|
||||
@@ -6,7 +6,7 @@
|
||||
android:shape="ring"
|
||||
android:thickness="4dp"
|
||||
android:useLevel="true">
|
||||
<solid android:color="@color/gray_100"/>
|
||||
<solid android:color="?colorGray100"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -83,7 +83,7 @@
|
||||
android:layout_alignParentTop="true"
|
||||
android:src="@drawable/ic_fluent_dismiss_24_filled"
|
||||
android:contentDescription="@string/cancel"
|
||||
android:tint="@color/gray_100"
|
||||
android:tint="?colorGray100"
|
||||
android:background="@drawable/bg_upload_progress"/>
|
||||
|
||||
<ProgressBar
|
||||
@@ -104,7 +104,7 @@
|
||||
android:layout_height="16dp"
|
||||
android:layout_below="@id/retry_or_cancel_upload"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textColor="@color/gray_200"
|
||||
android:textColor="?colorGray200"
|
||||
android:textSize="14dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:singleLine="true"
|
||||
@@ -119,7 +119,7 @@
|
||||
android:layout_height="32dp"
|
||||
android:layout_below="@id/state_title"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="@color/gray_200"
|
||||
android:textColor="?colorGray200"
|
||||
android:gravity="center_horizontal|top"
|
||||
android:lines="2"
|
||||
android:maxLines="2"
|
||||
|
||||
@@ -14,20 +14,34 @@
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="-6dp"
|
||||
android:layout_marginRight="-8dp"
|
||||
android:layout_marginEnd="-8dp"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/more_options"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_post_more"
|
||||
android:tint="?android:textColorSecondary" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/delete_notification"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginTop="-6dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_toStartOf="@id/more"
|
||||
android:visibility="gone"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/sk_delete_notification"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_fluent_dismiss_20_filled"
|
||||
android:tint="?android:textColorSecondary" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/visibility"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginTop="-6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:layout_toLeftOf="@id/more"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_toStartOf="@id/delete_notification"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_visibility"
|
||||
@@ -45,7 +59,7 @@
|
||||
android:id="@+id/name_wrap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_toStartOf="@id/visibility"
|
||||
android:layout_toEndOf="@id/avatar">
|
||||
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_filled"
|
||||
android:drawableTint="?android:textColorSecondary"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
android:layout_margin="16dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:textColor="@color/gray_50t"
|
||||
android:textColor="?colorGray50t"
|
||||
android:textAllCaps="true"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:textSize="14dp"
|
||||
@@ -241,17 +241,14 @@
|
||||
android:textAppearance="@style/m3_headline_small"
|
||||
tools:text="Eugen" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_below="@id/name"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:textAppearance="@style/m3_title_medium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="\@Gargron" />
|
||||
@@ -262,7 +259,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/username"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:textAppearance="@style/m3_body_large"
|
||||
android:textSize="16sp"
|
||||
@@ -291,7 +287,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/username"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:textAppearance="@style/m3_body_large"
|
||||
android:textSize="16sp"
|
||||
|
||||
95
mastodon/src/main/res/layout/item_boost_menu.xml
Normal file
95
mastodon/src/main/res/layout/item_boost_menu.xml
Normal file
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<TextView
|
||||
android:id="@+id/reblog_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:textColor="?android:colorAccent"
|
||||
android:accessibilityHeading="true"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:text="@string/sk_reblog_with_visibility" />
|
||||
<TextView
|
||||
android:id="@+id/delete_reblog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="36dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:drawablePadding="16dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:text="@string/sk_undo_reblog"
|
||||
android:visibility="gone"
|
||||
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_off_24_regular" />
|
||||
<TextView
|
||||
android:id="@+id/vis_public"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="36dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:drawablePadding="16dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:text="@string/visibility_public"
|
||||
android:drawableStart="@drawable/ic_fluent_earth_24_regular" />
|
||||
<TextView
|
||||
android:id="@+id/vis_unlisted"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="36dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:drawablePadding="16dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:text="@string/sk_visibility_unlisted"
|
||||
android:drawableStart="@drawable/ic_fluent_people_community_24_regular" />
|
||||
<TextView
|
||||
android:id="@+id/vis_followers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="36dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:drawablePadding="16dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:text="@string/visibility_followers_only"
|
||||
android:drawableStart="@drawable/ic_fluent_people_checkmark_24_regular" />
|
||||
<View
|
||||
android:id="@+id/separator"
|
||||
android:layout_height="1dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:background="?colorPollVoted" />
|
||||
<TextView
|
||||
android:id="@+id/quote"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="36dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:drawablePadding="16dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:text="@string/sk_quote_post"
|
||||
android:drawableStart="@drawable/ic_fluent_compose_24_regular" />
|
||||
</LinearLayout>
|
||||
@@ -1,9 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.joinmastodon.android.ui.views.AutoOrientationLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layoutDirection="locale">
|
||||
|
||||
@@ -15,24 +16,27 @@
|
||||
android:layout_marginEnd="32dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="?android:textColorPrimary"
|
||||
tools:src="@drawable/ic_color_theme_preference"/>
|
||||
tools:src="@drawable/ic_fluent_color_24_regular"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/sk_settings_color_picker"/>
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/color_picker_button"
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:layout_weight="0"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxWidth="140dp"
|
||||
android:background="@drawable/bg_inline_button"
|
||||
android:elevation="0dp"
|
||||
android:ellipsize="middle"
|
||||
@@ -41,6 +45,6 @@
|
||||
android:stateListAnimator="@null"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
tools:text="@string/sk_color_theme_pink" />
|
||||
tools:text="@string/sk_color_palette_pink" />
|
||||
|
||||
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -3,7 +3,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layoutDirection="locale">
|
||||
|
||||
@@ -22,10 +23,9 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingVertical="8dp"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="@string/theme_true_black"/>
|
||||
|
||||
<Switch
|
||||
|
||||
@@ -2,23 +2,22 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layoutDirection="locale">
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="48dp"
|
||||
android:paddingRight="16dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="Account settings"/>
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
@@ -27,4 +26,8 @@
|
||||
android:layout_gravity="center"
|
||||
android:alpha="0"
|
||||
/>
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
@@ -35,7 +35,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:textColor="?colorAccentLight"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="14dp"
|
||||
android:paddingLeft="16dp"
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:drawableLeft="@drawable/ic_fluent_people_community_24_regular"
|
||||
android:drawableTint="?android:textColorSecondary"
|
||||
android:drawablePadding="16dp"
|
||||
android:textAppearance="@style/m3_title_medium"
|
||||
@@ -26,6 +25,7 @@
|
||||
android:clickable="false"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:paddingRight="16dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -55,7 +55,7 @@
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="@drawable/ic_pause_24"
|
||||
android:tint="@color/gray_50"
|
||||
android:tint="?colorGray50"
|
||||
android:contentDescription="@string/pause"
|
||||
android:background="?android:selectableItemBackgroundBorderless"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/m3_color" android:title="@string/sk_color_theme_material3"/>
|
||||
<item android:id="@+id/pink_color" android:title="@string/sk_color_theme_pink"/>
|
||||
<item android:id="@+id/purple_color" android:title="@string/sk_color_theme_purple"/>
|
||||
<item android:id="@+id/green_color" android:title="@string/sk_color_theme_green"/>
|
||||
<item android:id="@+id/blue_color" android:title="@string/sk_color_theme_blue"/>
|
||||
<item android:id="@+id/brown_color" android:title="@string/sk_color_theme_brown"/>
|
||||
<item android:id="@+id/red_color" android:title="@string/sk_color_theme_red"/>
|
||||
<item android:id="@+id/yellow_color" android:title="@string/sk_color_theme_yellow"/>
|
||||
<item android:id="@+id/m3_color" android:title="@string/sk_color_palette_material3"/>
|
||||
<item android:id="@+id/pink_color" android:title="@string/sk_color_palette_pink"/>
|
||||
<item android:id="@+id/purple_color" android:title="@string/sk_color_palette_purple"/>
|
||||
<item android:id="@+id/green_color" android:title="@string/sk_color_palette_green"/>
|
||||
<item android:id="@+id/blue_color" android:title="@string/sk_color_palette_blue"/>
|
||||
<item android:id="@+id/brown_color" android:title="@string/sk_color_palette_brown"/>
|
||||
<item android:id="@+id/red_color" android:title="@string/sk_color_palette_red"/>
|
||||
<item android:id="@+id/yellow_color" android:title="@string/sk_color_palette_yellow"/>
|
||||
</menu>
|
||||
@@ -10,6 +10,6 @@
|
||||
android:icon="@drawable/ic_fluent_people_checkmark_24_regular"
|
||||
android:title="@string/visibility_followers_only"/>
|
||||
<item android:id="@+id/vis_private"
|
||||
android:icon="@drawable/ic_at_symbol"
|
||||
android:icon="@drawable/ic_fluent_mention_24_regular"
|
||||
android:title="@string/visibility_private"/>
|
||||
</menu>
|
||||
@@ -3,7 +3,13 @@
|
||||
<item
|
||||
android:id="@+id/follow_requests"
|
||||
android:icon="@drawable/ic_follow_requests_24_badged"
|
||||
android:showAsAction="always"
|
||||
android:showAsAction="ifRoom"
|
||||
android:visible="false"
|
||||
android:title="@string/sk_follow_requests" />
|
||||
<item
|
||||
android:id="@+id/clear_notifications"
|
||||
android:icon="@drawable/ic_fluent_mail_inbox_dismiss_24_regular"
|
||||
android:showAsAction="collapseActionView"
|
||||
android:visible="false"
|
||||
android:title="@string/sk_clear_all_notifications" />
|
||||
</menu>
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/open_with_account" android:title="@string/sk_open_with_account">
|
||||
<menu android:id="@+id/accounts" />
|
||||
</item>
|
||||
<item android:id="@+id/edit" android:title="@string/edit"/>
|
||||
<item android:id="@+id/delete" android:title="@string/delete"/>
|
||||
<item android:id="@+id/delete_and_redraft" android:title="@string/sk_delete_and_redraft"/>
|
||||
@@ -11,5 +14,6 @@
|
||||
<item android:id="@+id/follow" android:title="@string/follow_user"/>
|
||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||
<item android:id="@+id/bookmark" android:title="@string/add_bookmark"/>
|
||||
<item android:id="@+id/copy_link" android:title="@string/sk_copy_link_to_post"/>
|
||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||
</menu>
|
||||
@@ -2,5 +2,6 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<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"/>
|
||||
<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/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular"/>
|
||||
</menu>
|
||||
@@ -40,11 +40,11 @@
|
||||
<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>
|
||||
<string name="sk_settings_color_picker">Color de tema</string>
|
||||
<string name="sk_color_theme_pink">Rosa</string>
|
||||
<string name="sk_color_theme_purple">Lila</string>
|
||||
<string name="sk_color_theme_green">Verd</string>
|
||||
<string name="sk_color_theme_blue">Blau</string>
|
||||
<string name="sk_color_theme_brown">Marró</string>
|
||||
<string name="sk_color_theme_yellow">Groc</string>
|
||||
<string name="sk_settings_color_palette">Color de tema</string>
|
||||
<string name="sk_color_palette_pink">Rosa</string>
|
||||
<string name="sk_color_palette_purple">Lila</string>
|
||||
<string name="sk_color_palette_green">Verd</string>
|
||||
<string name="sk_color_palette_blue">Blau</string>
|
||||
<string name="sk_color_palette_brown">Marró</string>
|
||||
<string name="sk_color_palette_yellow">Groc</string>
|
||||
</resources>
|
||||
@@ -38,15 +38,15 @@
|
||||
<string name="sk_disable_marquee">Laufschrift in Titelleisten deaktivieren</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_settings_color_picker">Farbschema</string>
|
||||
<string name="sk_color_theme_pink">Pink</string>
|
||||
<string name="sk_color_theme_purple">Violett</string>
|
||||
<string name="sk_color_theme_green">Grün</string>
|
||||
<string name="sk_color_theme_brown">Braun</string>
|
||||
<string name="sk_color_theme_yellow">Gelb</string>
|
||||
<string name="sk_notify_posts">Beitrags-Benachrichtigungen</string>
|
||||
<string name="sk_settings_color_palette">Farbschema</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_theme_blue">Blau</string>
|
||||
<string name="sk_color_palette_blue">Blau</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>
|
||||
@@ -58,5 +58,30 @@
|
||||
<string name="sk_clear_recent_languages">Zuletzt verwendete Sprachen leeren</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, bitte gib den Domain-Namen deiner Heim-Instanz unten ein.</string>
|
||||
<string name="sk_welcome_text">Der Hai sagt Hi! Um anzufangen, bitte gib den Domain-Namen deiner Heim-Instanz unten ein.</string>
|
||||
<string name="sk_color_palette_material3">System</string>
|
||||
<string name="sk_color_palette_red">Rot</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>
|
||||
<string name="sk_settings_auth">Sicherheits-Einstellungen</string>
|
||||
<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_confirm_action">Benachrichtigung löschen</string>
|
||||
<string name="sk_delete_notification_confirm">Benachrichtigung wirklich löschen\?</string>
|
||||
<string name="sk_clear_all_notifications_confirm_action">Alle 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_hide_translate_in_timeline">Übersetzen-Button in der Timeline ausblenden</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_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_undo_reblog">Reblog rückgängig machen</string>
|
||||
<string name="sk_reblog_with_visibility">Rebloggen mit Sichtbarkeit</string>
|
||||
</resources>
|
||||
@@ -40,13 +40,13 @@
|
||||
<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_picker">Colores para los temas</string>
|
||||
<string name="sk_color_theme_pink">Rosa</string>
|
||||
<string name="sk_color_theme_purple">Violeta</string>
|
||||
<string name="sk_color_theme_green">Verde</string>
|
||||
<string name="sk_color_theme_blue">Azul</string>
|
||||
<string name="sk_color_theme_brown">Marrón</string>
|
||||
<string name="sk_color_theme_yellow">Amarillo</string>
|
||||
<string name="sk_settings_color_palette">Colores para los temas</string>
|
||||
<string name="sk_color_palette_pink">Rosa</string>
|
||||
<string name="sk_color_palette_purple">Violeta</string>
|
||||
<string name="sk_color_palette_green">Verde</string>
|
||||
<string name="sk_color_palette_blue">Azul</string>
|
||||
<string name="sk_color_palette_brown">Marrón</string>
|
||||
<string name="sk_color_palette_yellow">Amarillo</string>
|
||||
<string name="sk_poll_allow_multiple">Permitir respuesta múltiple</string>
|
||||
<string name="sk_translate_post">Traducir</string>
|
||||
<string name="sk_translate_show_original">Mostrar original</string>
|
||||
@@ -59,5 +59,30 @@
|
||||
<string name="sk_welcome_text">¡El tiburón te saluda! Para empezar, introduzca a continuación el nombre del dominio de su instancia de origen.</string>
|
||||
<string name="sk_example_domain">example.social</string>
|
||||
<string name="sk_welcome_title">¡Bienvenidos!</string>
|
||||
<string name="sk_color_theme_material3">Sistema</string>
|
||||
<string name="sk_color_palette_material3">Sistema</string>
|
||||
<string name="sk_color_palette_red">Rojo</string>
|
||||
<string name="sk_settings_profile">Configurar el perfil</string>
|
||||
<string name="sk_settings_posting">Preferencias de publicación</string>
|
||||
<string name="sk_settings_filters">Configurar los filtros</string>
|
||||
<string name="sk_settings_auth">Ajustes de seguridad</string>
|
||||
<string name="sk_settings_rules">Reglas</string>
|
||||
<string name="sk_settings_about">Acerca de la aplicación</string>
|
||||
<string name="sk_settings_donate">Donar</string>
|
||||
<string name="sk_tabs_disable_swipe">Deshabilitar el deslizamiento entre pestañas</string>
|
||||
<string name="sk_delete_notification">Eliminar la notificación</string>
|
||||
<string name="sk_delete_notification_confirm_action">Eliminar la notificación</string>
|
||||
<string name="sk_delete_notification_confirm">¿Estás seguro de que quieres borrar esta notificación\?</string>
|
||||
<string name="sk_clear_all_notifications">Borrar todas las notificaciones</string>
|
||||
<string name="sk_clear_all_notifications_confirm_action">Borrar todo</string>
|
||||
<string name="sk_enable_delete_notifications">Activar la eliminación de notificaciones</string>
|
||||
<string name="sk_settings_publish_button_text">Publicar el texto del botón</string>
|
||||
<string name="sk_settings_publish_button_text_title">Personalizar el texto del botón Publicar</string>
|
||||
<string name="sk_settings_hide_translate_in_timeline">Ocultar el botón de la traducción en la línea de tiempo</string>
|
||||
<string name="sk_clear_all_notifications_confirm">¿Estás seguro de que quieres borrar todas las notificaciones\?</string>
|
||||
<string name="sk_settings_translation_availability_note_available">¡%s admite traducción!</string>
|
||||
<string name="sk_settings_translation_availability_note_unavailable">%s no parece soportar la traducción.</string>
|
||||
<string name="sk_loading_fediverse_resource_title">Buscándolo en Fediverse…</string>
|
||||
<string name="sk_quote_post">Publicar sobre esto</string>
|
||||
<string name="sk_undo_reblog">Deshacer reblogueo</string>
|
||||
<string name="sk_reblog_with_visibility">Rebloguea con visibilidad</string>
|
||||
</resources>
|
||||
@@ -40,13 +40,13 @@
|
||||
<string name="sk_federated_timeline_info_banner">Ce sont les messages les plus récents des membres de votre fédération.</string>
|
||||
<string name="sk_notification_type_status">Messages</string>
|
||||
<string name="sk_notify_posts">Notifications des messages</string>
|
||||
<string name="sk_color_theme_pink">Rose</string>
|
||||
<string name="sk_color_theme_purple">Violet</string>
|
||||
<string name="sk_color_theme_green">Vert</string>
|
||||
<string name="sk_color_theme_blue">Bleu</string>
|
||||
<string name="sk_color_theme_brown">Marron</string>
|
||||
<string name="sk_color_theme_yellow">Jaune</string>
|
||||
<string name="sk_settings_color_picker">Couleur d\'accentuation</string>
|
||||
<string name="sk_color_palette_pink">Rose</string>
|
||||
<string name="sk_color_palette_purple">Violet</string>
|
||||
<string name="sk_color_palette_green">Vert</string>
|
||||
<string name="sk_color_palette_blue">Bleu</string>
|
||||
<string name="sk_color_palette_brown">Marron</string>
|
||||
<string name="sk_color_palette_yellow">Jaune</string>
|
||||
<string name="sk_settings_color_palette">Couleur d\'accentuation</string>
|
||||
<string name="sk_poll_allow_multiple">Autoriser plusieurs choix</string>
|
||||
<string name="sk_translate_post">Traduire</string>
|
||||
<string name="sk_translate_show_original">Afficher l\'original</string>
|
||||
@@ -59,5 +59,33 @@
|
||||
<string name="sk_example_domain">exemple.social</string>
|
||||
<string name="sk_welcome_title">Bienvenue !</string>
|
||||
<string name="sk_welcome_text">Le requin vous salue ! Pour commencer, veuillez entrer le nom de domaine de votre instance personnelle ci-dessous.</string>
|
||||
<string name="sk_color_theme_material3">Système</string>
|
||||
<string name="sk_color_palette_material3">Système</string>
|
||||
<string name="sk_color_palette_red">Rouge</string>
|
||||
<string name="sk_settings_profile">Configurer le profil</string>
|
||||
<string name="sk_settings_posting">Préférences de publication</string>
|
||||
<string name="sk_settings_filters">Configurer les filtres</string>
|
||||
<string name="sk_settings_auth">Paramètres de sécurité</string>
|
||||
<string name="sk_settings_rules">Règles</string>
|
||||
<string name="sk_settings_about">À propos de l\'application</string>
|
||||
<string name="sk_settings_donate">Donner</string>
|
||||
<string name="sk_tabs_disable_swipe">Désactiver le balayage entre les onglets</string>
|
||||
<string name="sk_delete_notification">Supprimer la notification</string>
|
||||
<string name="sk_delete_notification_confirm_action">Supprimer la notification</string>
|
||||
<string name="sk_delete_notification_confirm">Voulez-vous vraiment supprimer cette notification \?</string>
|
||||
<string name="sk_clear_all_notifications">Supprimer toutes les notifications</string>
|
||||
<string name="sk_clear_all_notifications_confirm_action">Tout supprimer</string>
|
||||
<string name="sk_enable_delete_notifications">Activer la suppression des notifications</string>
|
||||
<string name="sk_settings_publish_button_text_title">Personnaliser le texte du bouton Publier</string>
|
||||
<string name="sk_settings_publish_button_text">Texte du bouton Publier</string>
|
||||
<string name="sk_settings_hide_translate_in_timeline">Masquer le bouton de traduction dans la timeline</string>
|
||||
<string name="sk_settings_translation_availability_note_available">%s prend en charge la traduction !</string>
|
||||
<string name="sk_settings_translation_availability_note_unavailable">%s ne semble pas prendre en charge la traduction.</string>
|
||||
<string name="sk_clear_all_notifications_confirm">Voulez-vous vraiment supprimer toutes les notifications \?</string>
|
||||
<string name="sk_loading_fediverse_resource_title">Le rechercher sur le Fediverse…</string>
|
||||
<string name="sk_reblog_with_visibility">Rebloguer avec visibilité</string>
|
||||
<string name="sk_undo_reblog">Annuler le reblogage</string>
|
||||
<string name="sk_quote_post">Poster à ce sujet</string>
|
||||
<string name="sk_hashtags_you_follow">Hashtags que vous suivez</string>
|
||||
<string name="sk_open_in_account">Ouvrir dans un autre compte</string>
|
||||
<string name="sk_copy_link_to_post">Copier le lien du post</string>
|
||||
</resources>
|
||||
@@ -28,7 +28,7 @@
|
||||
<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">Kontribusi ke Megalodon</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>
|
||||
@@ -40,11 +40,52 @@
|
||||
<string name="sk_settings_show_federated_timeline">Tampilkan lini masa federasi</string>
|
||||
<string name="sk_notification_type_status">Kiriman</string>
|
||||
<string name="sk_notify_posts">Notifikasi kiriman</string>
|
||||
<string name="sk_settings_color_picker">Warna tema</string>
|
||||
<string name="sk_color_theme_pink">Merah muda</string>
|
||||
<string name="sk_color_theme_purple">Ungu</string>
|
||||
<string name="sk_color_theme_green">Hijau</string>
|
||||
<string name="sk_color_theme_blue">Biru</string>
|
||||
<string name="sk_color_theme_brown">Cokelat</string>
|
||||
<string name="sk_color_theme_yellow">Kuning</string>
|
||||
<string name="sk_settings_color_palette">Warna tema</string>
|
||||
<string name="sk_color_palette_pink">Merah Muda</string>
|
||||
<string name="sk_color_palette_purple">Ungu</string>
|
||||
<string name="sk_color_palette_green">Hijau</string>
|
||||
<string name="sk_color_palette_blue">Biru</string>
|
||||
<string name="sk_color_palette_brown">Cokelat</string>
|
||||
<string name="sk_color_palette_yellow">Kuning</string>
|
||||
<string name="sk_poll_allow_multiple">Perbolehkan beberapa pilihan</string>
|
||||
<string name="sk_clear_recent_languages">Hapus bahasa terkini yang digunakan</string>
|
||||
<string name="sk_welcome_title">Selamat datang!</string>
|
||||
<string name="sk_confirm_clear_recent_languages">Apakah Anda yakin ingin menghapus bahasa terkini yang Anda gunakan\?</string>
|
||||
<string name="sk_color_palette_material3">Sistem</string>
|
||||
<string name="sk_available_languages">Bahasa yang tersedia</string>
|
||||
<string name="sk_language_name">%s (%s)</string>
|
||||
<string name="sk_translate_post">Terjemahkan</string>
|
||||
<string name="sk_translate_show_original">Tampilkan yang asli</string>
|
||||
<string name="sk_post_language">Bahasa: %s</string>
|
||||
<string name="sk_example_domain">contoh.social</string>
|
||||
<string name="sk_color_palette_red">Merah</string>
|
||||
<string name="sk_translated_using">Diterjemahkan menggunakan %s</string>
|
||||
<string name="sk_welcome_text">Hiu menyapamu! Untuk memulai, silakan memasukkan nama domain instansi Anda di bawah.</string>
|
||||
<string name="sk_tabs_disable_swipe">Nonaktifkan mengusap antara tab</string>
|
||||
<string name="sk_settings_profile">Atur profil</string>
|
||||
<string name="sk_settings_filters">Atur profil</string>
|
||||
<string name="sk_enable_delete_notifications">Aktifkan menghapus notifikasi</string>
|
||||
<string name="sk_settings_publish_button_text">Teks tombol Terbitkan</string>
|
||||
<string name="sk_settings_publish_button_text_title">Ubah teks tombol Terbitkan</string>
|
||||
<string name="sk_settings_hide_translate_in_timeline">Sembunyikan tombol terjemahkan di lini masa</string>
|
||||
<string name="sk_settings_translation_availability_note_available">%s mendukung penerjemahan!</string>
|
||||
<string name="sk_settings_translation_availability_note_unavailable">%s sepertinya tidak mendukung penerjemahan.</string>
|
||||
<string name="sk_clear_all_notifications_confirm">Apakah Anda yakin ingin menghapus semua notifikasi\?</string>
|
||||
<string name="sk_loading_fediverse_resource_title">Mencari di Fedimesta…</string>
|
||||
<string name="sk_settings_rules">Aturan</string>
|
||||
<string name="sk_settings_about">Tentang aplikasi</string>
|
||||
<string name="sk_settings_donate">Donasi</string>
|
||||
<string name="sk_delete_notification">Hapus notifikasi</string>
|
||||
<string name="sk_delete_notification_confirm_action">Hapus notifikasi</string>
|
||||
<string name="sk_delete_notification_confirm">Apakah kamu yakin ingin menghapus notifikasi ini\?</string>
|
||||
<string name="sk_clear_all_notifications_confirm_action">Hapus semua</string>
|
||||
<string name="sk_settings_posting">Preferensi kiriman</string>
|
||||
<string name="sk_settings_auth">Pengaturan keamanan</string>
|
||||
<string name="sk_clear_all_notifications">Hapus semua notifikasi</string>
|
||||
<string name="sk_undo_reblog">Urungkan pembagian</string>
|
||||
<string name="sk_quote_post">Kirim tentang ini</string>
|
||||
<string name="sk_reblog_with_visibility">Bagikan dengan keterlihatan</string>
|
||||
<string name="sk_copy_link_to_post">Salin tautan ke kiriman</string>
|
||||
<string name="sk_open_in_account">Buka di akun lain</string>
|
||||
<string name="sk_hashtags_you_follow">Tagar yang Anda ikuti</string>
|
||||
</resources>
|
||||
@@ -2,13 +2,13 @@
|
||||
<resources>
|
||||
<string name="sk_notification_type_status">Post</string>
|
||||
<string name="sk_notify_posts">Notifiche post</string>
|
||||
<string name="sk_settings_color_picker">Colore del tema</string>
|
||||
<string name="sk_color_theme_pink">Rosa</string>
|
||||
<string name="sk_color_theme_purple">Viola</string>
|
||||
<string name="sk_color_theme_green">Verde</string>
|
||||
<string name="sk_color_theme_blue">Blu</string>
|
||||
<string name="sk_color_theme_brown">Marrone</string>
|
||||
<string name="sk_color_theme_yellow">Giallo</string>
|
||||
<string name="sk_settings_color_palette">Colore del tema</string>
|
||||
<string name="sk_color_palette_pink">Rosa</string>
|
||||
<string name="sk_color_palette_purple">Viola</string>
|
||||
<string name="sk_color_palette_green">Verde</string>
|
||||
<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">Megalodon</string>
|
||||
<string name="sk_pinned_posts">Fissati</string>
|
||||
<string name="sk_delete_and_redraft">Elimina e riscrivi</string>
|
||||
@@ -49,7 +49,7 @@
|
||||
<string name="sk_reject_follow_request">Rifiuta richiesta di seguirti</string>
|
||||
<string name="sk_translate_post">Traduci</string>
|
||||
<string name="sk_translate_show_original">Mostra originale</string>
|
||||
<string name="sk_translated_using">Tradotto con</string>
|
||||
<string name="sk_translated_using">Tradotto con %s</string>
|
||||
<string name="sk_post_language">Lingua: %s</string>
|
||||
<string name="sk_language_name">%s (%s)</string>
|
||||
<string name="sk_confirm_clear_recent_languages">Sei sicuro di voler cancellare le lingue usate di recente\?</string>
|
||||
@@ -59,5 +59,5 @@
|
||||
<string name="sk_poll_allow_multiple">Consenti scelte multiple</string>
|
||||
<string name="sk_available_languages">Lingue disponibili</string>
|
||||
<string name="sk_welcome_text">Lo squalo ti saluta! Per iniziare inserisci il dominio dell\'istanza a cui sei iscritto.</string>
|
||||
<string name="sk_color_theme_material3">Sistema</string>
|
||||
<string name="sk_color_palette_material3">Sistema</string>
|
||||
</resources>
|
||||
@@ -39,13 +39,13 @@
|
||||
<string name="sk_settings_show_federated_timeline">연합 타임라인 표시</string>
|
||||
<string name="sk_notification_type_status">게시물</string>
|
||||
<string name="sk_notify_posts">게시물 알림</string>
|
||||
<string name="sk_settings_color_picker">테마 색상</string>
|
||||
<string name="sk_color_theme_pink">분홍색</string>
|
||||
<string name="sk_color_theme_purple">보라색</string>
|
||||
<string name="sk_color_theme_green">초록색</string>
|
||||
<string name="sk_color_theme_blue">파란색</string>
|
||||
<string name="sk_color_theme_brown">갈색</string>
|
||||
<string name="sk_color_theme_yellow">노란색</string>
|
||||
<string name="sk_settings_color_palette">테마 색상</string>
|
||||
<string name="sk_color_palette_pink">분홍색</string>
|
||||
<string name="sk_color_palette_purple">보라색</string>
|
||||
<string name="sk_color_palette_green">초록색</string>
|
||||
<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">Megalodon에 기여</string>
|
||||
<string name="sk_poll_allow_multiple">다중 선택 허용</string>
|
||||
<string name="sk_translate_post">번역하기</string>
|
||||
@@ -59,4 +59,27 @@
|
||||
<string name="sk_example_domain">example.social</string>
|
||||
<string name="sk_welcome_title">환영합니다!</string>
|
||||
<string name="sk_welcome_text">상어가 당신을 맞이합니다! 시작하기 위해, 아래에 사용하시는 인스턴스의 도메인 이름을 입력해주세요.</string>
|
||||
<string name="sk_color_palette_material3">시스템</string>
|
||||
<string name="sk_color_palette_red">빨간색</string>
|
||||
<string name="sk_settings_profile">프로필 설정</string>
|
||||
<string name="sk_settings_posting">게시물 설정</string>
|
||||
<string name="sk_settings_filters">필터 설정</string>
|
||||
<string name="sk_settings_auth">보안 설정</string>
|
||||
<string name="sk_settings_rules">서버 규칙</string>
|
||||
<string name="sk_settings_about">이 앱에 관하여</string>
|
||||
<string name="sk_settings_donate">기부</string>
|
||||
<string name="sk_delete_notification_confirm_action">알림 삭제</string>
|
||||
<string name="sk_delete_notification_confirm">정말로 이 알림을 삭제하시겠습니까\?</string>
|
||||
<string name="sk_enable_delete_notifications">알림 삭제 활성화</string>
|
||||
<string name="sk_settings_publish_button_text">게시 버튼 텍스트</string>
|
||||
<string name="sk_settings_publish_button_text_title">게시 버튼 사용자화</string>
|
||||
<string name="sk_settings_hide_translate_in_timeline">타임라인에서 번역 버튼 숨김</string>
|
||||
<string name="sk_delete_notification">알림 삭제</string>
|
||||
<string name="sk_settings_translation_availability_note_available">%s 서버는 번역을 지원합니다!</string>
|
||||
<string name="sk_settings_translation_availability_note_unavailable">%s 서버는 번역을 지원하지 않는 것 같습니다.</string>
|
||||
<string name="sk_clear_all_notifications_confirm">정말로 모든 알림을 삭제하시겠습니까\?</string>
|
||||
<string name="sk_clear_all_notifications_confirm_action">모두 삭제</string>
|
||||
<string name="sk_tabs_disable_swipe">스와이프로 탭간 전환 비활성화</string>
|
||||
<string name="sk_clear_all_notifications">모든 알림 삭제</string>
|
||||
<string name="sk_loading_fediverse_resource_title">연합우주에서 찾아보는 중…</string>
|
||||
</resources>
|
||||
4
mastodon/src/main/res/values-night/palettes.xml
Normal file
4
mastodon/src/main/res/values-night/palettes.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="ColorPalette.Material3.AutoLightDark" parent="ColorPalette.Material3.Dark"/>
|
||||
</resources>
|
||||
@@ -2,22 +2,4 @@
|
||||
<resources>
|
||||
<style name="Theme.Mastodon.AutoLightDark" parent="Theme.Mastodon.Dark"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack" parent="Theme.Mastodon.Dark.TrueBlack"/>
|
||||
|
||||
<style name="Theme.Mastodon.AutoLightDark.Original" parent="Theme.Mastodon.Dark.Original"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack.Original" parent="Theme.Mastodon.Dark.TrueBlack.Original"/>
|
||||
|
||||
<style name="Theme.Mastodon.AutoLightDark.Green" parent="Theme.Mastodon.Dark.Green"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack.Green" parent="Theme.Mastodon.Dark.TrueBlack.Green"/>
|
||||
|
||||
<style name="Theme.Mastodon.AutoLightDark.Blue" parent="Theme.Mastodon.Dark.Blue"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack.Blue" parent="Theme.Mastodon.Dark.TrueBlack.Blue"/>
|
||||
|
||||
<style name="Theme.Mastodon.AutoLightDark.Brown" parent="Theme.Mastodon.Dark.Brown"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack.Brown" parent="Theme.Mastodon.Dark.TrueBlack.Brown"/>
|
||||
|
||||
<style name="Theme.Mastodon.AutoLightDark.Yellow" parent="Theme.Mastodon.Dark.Yellow"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack.Yellow" parent="Theme.Mastodon.Dark.TrueBlack.Yellow"/>
|
||||
|
||||
<style name="Theme.Mastodon.AutoLightDark.Material3" parent="Theme.Mastodon.Dark.Material3"/>
|
||||
<style name="Theme.Mastodon.AutoLightDark.TrueBlack.Material3" parent="Theme.Mastodon.Dark.TrueBlack.Material3"/>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-notnight/palettes.xml
Normal file
3
mastodon/src/main/res/values-notnight/palettes.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -40,13 +40,13 @@
|
||||
<string name="sk_visibility_unlisted">Niewidoczny</string>
|
||||
<string name="sk_notification_type_status">Wpisy</string>
|
||||
<string name="sk_notify_posts">Powiadomienia wpisów</string>
|
||||
<string name="sk_settings_color_picker">Motyw</string>
|
||||
<string name="sk_color_theme_pink">Różowy</string>
|
||||
<string name="sk_color_theme_purple">Fioletowy</string>
|
||||
<string name="sk_color_theme_green">Zielony</string>
|
||||
<string name="sk_color_theme_blue">Niebieski</string>
|
||||
<string name="sk_color_theme_brown">Brązowy</string>
|
||||
<string name="sk_color_theme_yellow">Żółty</string>
|
||||
<string name="sk_settings_color_palette">Motyw</string>
|
||||
<string name="sk_color_palette_pink">Różowy</string>
|
||||
<string name="sk_color_palette_purple">Fioletowy</string>
|
||||
<string name="sk_color_palette_green">Zielony</string>
|
||||
<string name="sk_color_palette_blue">Niebieski</string>
|
||||
<string name="sk_color_palette_brown">Brązowy</string>
|
||||
<string name="sk_color_palette_yellow">Żółty</string>
|
||||
<string name="sk_poll_allow_multiple">Pozwalaj na wybieranie wielu opcji</string>
|
||||
<string name="sk_translate_post">Przetłumacz</string>
|
||||
<string name="sk_translate_show_original">Pokaż oryginał</string>
|
||||
|
||||
@@ -38,14 +38,14 @@
|
||||
<string name="sk_settings_show_federated_timeline">Mostre a linha do tempo federada</string>
|
||||
<string name="sk_visibility_unlisted">Não-listado</string>
|
||||
<string name="sk_settings_show_interaction_counts">Mostrar contagens de interação</string>
|
||||
<string name="sk_color_theme_purple">Roxo</string>
|
||||
<string name="sk_color_theme_green">Verde</string>
|
||||
<string name="sk_color_theme_blue">Azul</string>
|
||||
<string name="sk_color_theme_brown">Marrom</string>
|
||||
<string name="sk_color_theme_yellow">Amarelo</string>
|
||||
<string name="sk_color_theme_pink">Rosa</string>
|
||||
<string name="sk_color_palette_purple">Roxo</string>
|
||||
<string name="sk_color_palette_green">Verde</string>
|
||||
<string name="sk_color_palette_blue">Azul</string>
|
||||
<string name="sk_color_palette_brown">Marrom</string>
|
||||
<string name="sk_color_palette_yellow">Amarelo</string>
|
||||
<string name="sk_color_palette_pink">Rosa</string>
|
||||
<string name="sk_notification_type_status">Postagens</string>
|
||||
<string name="sk_settings_color_picker">Cor do tema</string>
|
||||
<string name="sk_settings_color_palette">Cor do tema</string>
|
||||
<string name="sk_translate_post">Traduzir</string>
|
||||
<string name="sk_translate_show_original">Mostrar original</string>
|
||||
<string name="sk_translated_using">Traduzido usando %s</string>
|
||||
@@ -55,4 +55,10 @@
|
||||
<string name="sk_confirm_clear_recent_languages">Tem certeza de que deseja limpar os idiomas usados recentemente\?</string>
|
||||
<string name="sk_clear_recent_languages">Limpar idiomas usados recentemente</string>
|
||||
<string name="sk_notify_posts">Notificações de posts</string>
|
||||
<string name="sk_poll_allow_multiple">Permitir múltiplas escolhas</string>
|
||||
<string name="sk_welcome_text">O tubarão te cumprimenta! Para começar, por favor, digite abaixo o nome de domínio de sua instância de origem.</string>
|
||||
<string name="sk_example_domain">exemplo.social</string>
|
||||
<string name="sk_welcome_title">Bem vindo!</string>
|
||||
<string name="sk_color_palette_material3">Sistema</string>
|
||||
<string name="sk_color_palette_red">Vermelho</string>
|
||||
</resources>
|
||||
@@ -17,11 +17,11 @@
|
||||
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
|
||||
<string name="sk_notification_type_status">Публикации</string>
|
||||
<string name="sk_notify_posts">Отправляет публикацию</string>
|
||||
<string name="sk_settings_color_picker">Цветовая схема</string>
|
||||
<string name="sk_color_theme_pink">Розовый</string>
|
||||
<string name="sk_color_theme_purple">Фиолетовый</string>
|
||||
<string name="sk_color_theme_brown">Коричневый</string>
|
||||
<string name="sk_color_theme_yellow">Жёлтый</string>
|
||||
<string name="sk_settings_color_palette">Цветовая схема</string>
|
||||
<string name="sk_color_palette_pink">Розовый</string>
|
||||
<string name="sk_color_palette_purple">Фиолетовый</string>
|
||||
<string name="sk_color_palette_brown">Коричневый</string>
|
||||
<string name="sk_color_palette_yellow">Жёлтый</string>
|
||||
<string name="sk_translate_show_original">Показать оригинальную публикацию</string>
|
||||
<string name="sk_translated_using">Переведено через %s</string>
|
||||
<string name="sk_available_languages">Доступные языки</string>
|
||||
@@ -46,11 +46,19 @@
|
||||
<string name="sk_settings_always_reveal_content_warnings">Всегда раскрывать предупреждения о непристойном контенте</string>
|
||||
<string name="sk_settings_contribute">Внести свой код в Megalodon</string>
|
||||
<string name="sk_settings_show_federated_timeline">Показывать федеративную временную шкалу</string>
|
||||
<string name="sk_color_theme_green">Зелёный</string>
|
||||
<string name="sk_color_theme_blue">Синий</string>
|
||||
<string name="sk_color_palette_green">Зелёный</string>
|
||||
<string name="sk_color_palette_blue">Синий</string>
|
||||
<string name="sk_translate_post">Перевести</string>
|
||||
<string name="sk_post_language">Язык: %s</string>
|
||||
<string name="sk_clear_recent_languages">Очистить недавно использованные языки</string>
|
||||
<string name="sk_confirm_clear_recent_languages">Вы точно хотите очистить недавно использованные языки\?</string>
|
||||
<string name="sk_welcome_text">Акула приветствует вас! Чтобы начать, пожалуйста, введите домен своего домашнего сервера (инстанса) ниже.</string>
|
||||
<string name="sk_poll_allow_multiple">Разрешить несколько вариантов ответа</string>
|
||||
<string name="sk_user_post_notifications_on">Уведомления о постах %s включены</string>
|
||||
<string name="sk_user_post_notifications_off">Уведомления о новых постах %s отключены</string>
|
||||
<string name="sk_color_palette_material3">Система</string>
|
||||
<string name="sk_settings_show_boosts">Показать репосты</string>
|
||||
<string name="sk_settings_show_interaction_counts">Показывать количество взаимодействий</string>
|
||||
<string name="sk_disable_marquee">Отключить прокручиваемый текст в заголовках</string>
|
||||
<string name="sk_color_palette_red">Красный</string>
|
||||
</resources>
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="sk_notify_posts">Сповіщення про пости</string>
|
||||
<string name="sk_settings_color_picker">Колірна тема</string>
|
||||
<string name="sk_color_theme_purple">Фіолетовий</string>
|
||||
<string name="sk_color_theme_green">Зелений</string>
|
||||
<string name="sk_color_theme_blue">Синий</string>
|
||||
<string name="sk_color_theme_brown">Коричневий</string>
|
||||
<string name="sk_color_theme_yellow">Жовтий</string>
|
||||
<string name="sk_settings_color_palette">Колірна тема</string>
|
||||
<string name="sk_color_palette_purple">Фіолетовий</string>
|
||||
<string name="sk_color_palette_green">Зелений</string>
|
||||
<string name="sk_color_palette_blue">Синий</string>
|
||||
<string name="sk_color_palette_brown">Коричневий</string>
|
||||
<string name="sk_color_palette_yellow">Жовтий</string>
|
||||
<string name="sk_poll_allow_multiple">Дозволити кілька виборів</string>
|
||||
<string name="sk_translate_post">Перекласти</string>
|
||||
<string name="sk_translate_show_original">Показати оригінал</string>
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="sk_clear_recent_languages">Очистити нещодавно використані мови</string>
|
||||
<string name="sk_settings_always_reveal_content_warnings">Завжди відкривати вміст</string>
|
||||
<string name="sk_notification_type_status">Пости</string>
|
||||
<string name="sk_color_theme_pink">Рожевий</string>
|
||||
<string name="sk_color_palette_pink">Рожевий</string>
|
||||
<string name="sk_confirm_clear_recent_languages">Ви впевнені, що хочете очистити нещодавно використані мови\?</string>
|
||||
<string name="sk_app_name">Megalodon</string>
|
||||
<string name="sk_pinned_posts">Закріплене</string>
|
||||
@@ -59,4 +59,30 @@
|
||||
<string name="sk_example_domain">example.social</string>
|
||||
<string name="sk_welcome_title">Вітаємо!</string>
|
||||
<string name="sk_welcome_text">Акулка вас вітає! Щоб розпочати, введіть нижче доменне ім’я вашого інстансу.</string>
|
||||
<string name="sk_settings_profile">Налаштувати профіль</string>
|
||||
<string name="sk_settings_posting">Налаштувати постинг</string>
|
||||
<string name="sk_settings_filters">Налаштувати фільтри</string>
|
||||
<string name="sk_settings_rules">Правила</string>
|
||||
<string name="sk_settings_about">Про застосунок</string>
|
||||
<string name="sk_settings_donate">Донат</string>
|
||||
<string name="sk_color_palette_material3">Системна</string>
|
||||
<string name="sk_color_palette_red">Червона</string>
|
||||
<string name="sk_delete_notification">Видалити сповіщення</string>
|
||||
<string name="sk_delete_notification_confirm_action">Видалити</string>
|
||||
<string name="sk_delete_notification_confirm">Ви впевнені, що хочете видалити це сповіщення\?</string>
|
||||
<string name="sk_enable_delete_notifications">Увімкнути видалення сповіщень</string>
|
||||
<string name="sk_settings_publish_button_text">Текст кнопки \"опублікувати\"</string>
|
||||
<string name="sk_settings_publish_button_text_title">Змінити текст кнопки \"опублікувати\"</string>
|
||||
<string name="sk_settings_hide_translate_in_timeline">Сховати кнопку \"перекласти\" у стрічці</string>
|
||||
<string name="sk_settings_translation_availability_note_available">%s підтримує переклад!</string>
|
||||
<string name="sk_settings_translation_availability_note_unavailable">%s не підтримує переклад.</string>
|
||||
<string name="sk_clear_all_notifications">Очистити всі сповіщення</string>
|
||||
<string name="sk_clear_all_notifications_confirm">Ви впевнені, що хочете очистити всі сповіщення\?</string>
|
||||
<string name="sk_loading_fediverse_resource_title">Переглядаємо Федісвіт…</string>
|
||||
<string name="sk_undo_reblog">Скасувати репост</string>
|
||||
<string name="sk_reblog_with_visibility">Репост з видимістю</string>
|
||||
<string name="sk_quote_post">Цитувати пост</string>
|
||||
<string name="sk_tabs_disable_swipe">Вимкнути перегортання вкладок</string>
|
||||
<string name="sk_settings_auth">Налаштування безпеці</string>
|
||||
<string name="sk_clear_all_notifications_confirm_action">Видалити все</string>
|
||||
</resources>
|
||||
@@ -1,8 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="navigation_bar_bg">@color/gray_50</color>
|
||||
<color name="green_navigation_bar_bg">@color/green_gray_50</color>
|
||||
<color name="blue_navigation_bar_bg">@color/blue_gray_50</color>
|
||||
<color name="brown_navigation_bar_bg">@color/brown_gray_50</color>
|
||||
<color name="yellow_navigation_bar_bg">@color/yellow_gray_50</color>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user