Compare commits
231 Commits
v2.0.1+for
...
v2.0.3+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
937304f27b | ||
|
|
6b4ce0ea69 | ||
|
|
7f0c4860f8 | ||
|
|
9b4c70a5ed | ||
|
|
49137273ae | ||
|
|
647e3e5e85 | ||
|
|
4920bf63e3 | ||
|
|
0afcdb2cdf | ||
|
|
d96c3c3c8a | ||
|
|
f5e5408d70 | ||
|
|
d62899c990 | ||
|
|
e5bdeba1d7 | ||
|
|
8d7db7774f | ||
|
|
78d22c670c | ||
|
|
0a679109f5 | ||
|
|
e843142b7e | ||
|
|
72e728f655 | ||
|
|
ef56792f56 | ||
|
|
504a6959e8 | ||
|
|
6054a3d65c | ||
|
|
f50eac02d8 | ||
|
|
9634db9061 | ||
|
|
97e3e283dd | ||
|
|
f1e233569b | ||
|
|
04dd637fa9 | ||
|
|
c48a4105a9 | ||
|
|
aac53d949b | ||
|
|
9bb4e5b467 | ||
|
|
fb0391d5cd | ||
|
|
e4d898c903 | ||
|
|
da222f75bb | ||
|
|
25fbd91eb3 | ||
|
|
d458cca7bf | ||
|
|
3933a61b5a | ||
|
|
29092bbf36 | ||
|
|
a33d2578c9 | ||
|
|
9afe4b5ac6 | ||
|
|
6782006b05 | ||
|
|
90bdbefd48 | ||
|
|
b7bcf1082e | ||
|
|
ba9bbc5b6e | ||
|
|
0fecfbd50c | ||
|
|
0031dc6119 | ||
|
|
79e606698e | ||
|
|
3c9fc43780 | ||
|
|
adb9b7394a | ||
|
|
6191fdfaef | ||
|
|
446754e8a6 | ||
|
|
30c67b0b39 | ||
|
|
1043ea7b11 | ||
|
|
b449bcd006 | ||
|
|
a9d513b564 | ||
|
|
5cef527810 | ||
|
|
8bb907747d | ||
|
|
9c889f8df3 | ||
|
|
cbc164d844 | ||
|
|
b8e3060887 | ||
|
|
1aa1ede421 | ||
|
|
480dba7629 | ||
|
|
9b9c66a149 | ||
|
|
0f5eb923ee | ||
|
|
7f521b3129 | ||
|
|
9ce217d1f2 | ||
|
|
7b1bd3ccad | ||
|
|
13b1cbde6b | ||
|
|
8d898a1a78 | ||
|
|
51c2890ede | ||
|
|
03642faa9c | ||
|
|
084c6e1e59 | ||
|
|
90ed28e7a0 | ||
|
|
d2b45c1c84 | ||
|
|
a119ba5f80 | ||
|
|
8c1191a08f | ||
|
|
4275d596e6 | ||
|
|
2709d5226d | ||
|
|
8f613e3255 | ||
|
|
6831e846cf | ||
|
|
034eb9427d | ||
|
|
f73c325db3 | ||
|
|
5e2b11c504 | ||
|
|
ec13133431 | ||
|
|
a8a56a3ed8 | ||
|
|
4e9c7c4de2 | ||
|
|
ffb7894098 | ||
|
|
0d9520ac45 | ||
|
|
be852e57df | ||
|
|
157b38b8ae | ||
|
|
83196a1a0d | ||
|
|
306225b054 | ||
|
|
6efc71d8d2 | ||
|
|
cc4cd4d3f8 | ||
|
|
00e3292205 | ||
|
|
316952423c | ||
|
|
61c2abd014 | ||
|
|
ee5f299b90 | ||
|
|
f153846381 | ||
|
|
0656db0858 | ||
|
|
7f250cb8df | ||
|
|
a1e73eca89 | ||
|
|
1dc6936da6 | ||
|
|
0431d80a8d | ||
|
|
eaa78093f7 | ||
|
|
25b7151fde | ||
|
|
0438b579b6 | ||
|
|
afa50a4e8c | ||
|
|
85bdb0067b | ||
|
|
760cbc7f9a | ||
|
|
d0e34fcd90 | ||
|
|
da434b9a9b | ||
|
|
48863dd510 | ||
|
|
2ca34278f9 | ||
|
|
a79779f813 | ||
|
|
cc83f2baf3 | ||
|
|
728496b831 | ||
|
|
bbc99162c6 | ||
|
|
eed3af9e3e | ||
|
|
50187ff376 | ||
|
|
5f30919fb4 | ||
|
|
14c3cfac85 | ||
|
|
e978f02765 | ||
|
|
8d877c480f | ||
|
|
c53efee9a1 | ||
|
|
148c461e86 | ||
|
|
fcadb9883d | ||
|
|
bb6491e10a | ||
|
|
6248ccf376 | ||
|
|
c9e08f36fa | ||
|
|
10b95d753b | ||
|
|
c3989083cf | ||
|
|
01db585094 | ||
|
|
cc67cb330c | ||
|
|
52ed3c5a04 | ||
|
|
5976f6230a | ||
|
|
3553f03a95 | ||
|
|
d6e2d889c3 | ||
|
|
a777b3b450 | ||
|
|
9957efbea0 | ||
|
|
22e7b9730f | ||
|
|
91470b8509 | ||
|
|
c9d5327328 | ||
|
|
1aa61b72e5 | ||
|
|
3ca5edc3fc | ||
|
|
a092ebaeb3 | ||
|
|
5b9e84c255 | ||
|
|
9c058b926f | ||
|
|
4f2d2ae6e8 | ||
|
|
75aa26a018 | ||
|
|
0f795254e5 | ||
|
|
33592f0a83 | ||
|
|
d6fd01eaca | ||
|
|
1cdc58378a | ||
|
|
584b11fce3 | ||
|
|
fe2039062b | ||
|
|
0269756b52 | ||
|
|
df1a6cf764 | ||
|
|
6d2385b6b3 | ||
|
|
44eaa36cef | ||
|
|
50b40c4a07 | ||
|
|
ee6e0ff26c | ||
|
|
4d9574bf38 | ||
|
|
813be9a2be | ||
|
|
cc76ebfafb | ||
|
|
7989ee0243 | ||
|
|
3aa1997cfd | ||
|
|
c3da15552e | ||
|
|
a014fe9443 | ||
|
|
92551d4ca3 | ||
|
|
8010858e85 | ||
|
|
4efb4875b0 | ||
|
|
c5d041e46d | ||
|
|
53c2223aae | ||
|
|
25034ac0ae | ||
|
|
ac9de72b75 | ||
|
|
1f48ad93f2 | ||
|
|
38f7f7aa00 | ||
|
|
fe8175c63a | ||
|
|
2d9e01bbc1 | ||
|
|
022a227b08 | ||
|
|
a2228259f1 | ||
|
|
a61af7c56f | ||
|
|
5d6a646976 | ||
|
|
628d0d7492 | ||
|
|
b76c8745ec | ||
|
|
51e67bc441 | ||
|
|
8887f75b70 | ||
|
|
9436a838c0 | ||
|
|
ef120fa36f | ||
|
|
8c6385e2c5 | ||
|
|
0bd85d9905 | ||
|
|
ce0dab7b28 | ||
|
|
bdcebf1576 | ||
|
|
ddcc5670ce | ||
|
|
86afa184e2 | ||
|
|
77f341f139 | ||
|
|
918b5d99c2 | ||
|
|
7a098d6eff | ||
|
|
239b6f8202 | ||
|
|
8404c79148 | ||
|
|
5b2d04e09d | ||
|
|
6bd13f99d2 | ||
|
|
2e8e12c1c8 | ||
|
|
17929a6b2d | ||
|
|
9455eaf820 | ||
|
|
cc054487ba | ||
|
|
e2df320d00 | ||
|
|
d74313f996 | ||
|
|
b3cab67049 | ||
|
|
996f0b22b9 | ||
|
|
67952ea98e | ||
|
|
7a02ca435f | ||
|
|
71f81283f5 | ||
|
|
058c7c3c33 | ||
|
|
870e33879b | ||
|
|
3ca82bdfc5 | ||
|
|
4721bad286 | ||
|
|
f040cf2f07 | ||
|
|
8d50717c90 | ||
|
|
2512ad3c95 | ||
|
|
8d55f62da9 | ||
|
|
bc7e007634 | ||
|
|
1f3c87e0c7 | ||
|
|
ee0048a406 | ||
|
|
14dcc769f2 | ||
|
|
f2e6255eb3 | ||
|
|
7d392e20fb | ||
|
|
73e08faee9 | ||
|
|
02dc7711e4 | ||
|
|
67b4d80e5b | ||
|
|
5168d2bb39 | ||
|
|
57190a75bf | ||
|
|
f10e865895 |
16
README.md
16
README.md
@@ -54,9 +54,15 @@ You can create drafts, edit them, send them manually later or set a scheduled da
|
||||
|
||||
## Installation
|
||||
|
||||
### IzzyOnDroid
|
||||
### Google Play Store
|
||||
|
||||
[apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk](https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk)
|
||||
[https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk](https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk)
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk"><img height="50" alt="Get it on Google Play" src="img/google-play-badge.png"></a>
|
||||
|
||||
### F-Droid via IzzyOnDroid
|
||||
|
||||
[https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk](https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk)
|
||||
|
||||
<a href="https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk"><img height="50" alt="Get it on IzzyOnDroid" src="img/izzy-badge.png"></a>
|
||||
|
||||
@@ -64,11 +70,11 @@ Note that you'll need to add Izzy's F-Droid repository to your F-Droid app first
|
||||
|
||||
[`https://apt.izzysoft.de/fdroid/repo`](https://apt.izzysoft.de/fdroid/repo)
|
||||
|
||||
### Google Play Store
|
||||
### F-Droid via saunarepo
|
||||
|
||||
[play.google.com/store/apps/details?id=org.joinmastodon.android.sk](https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk)
|
||||
[https://repo.the-sauna.icu](https://repo.the-sauna.icu/)
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk"><img height="50" alt="Get it on Google Play" src="img/google-play-badge.png"></a>
|
||||
<a href="https://repo.the-sauna.icu"><img height="28" alt="Get it on SaunaRepo" src="img/saunarepo-badge.svg"></a>
|
||||
|
||||
### F-Droid
|
||||
|
||||
|
||||
@@ -3,6 +3,12 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url "https://www.jitpack.io"
|
||||
content {
|
||||
includeModule 'com.github.UnifiedPush', 'android-connector'
|
||||
}
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.0.0'
|
||||
|
||||
1
img/saunarepo-badge.svg
Normal file
1
img/saunarepo-badge.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="124.25" height="28" role="img" aria-label="SAUNAREPO"><title>SAUNAREPO</title><g shape-rendering="crispEdges"><rect width="124.25" height="28" fill="#fb8441"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="100"><image x="9" y="7" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkFuZHJvaWQ8L3RpdGxlPjxwYXRoIGQ9Ik0xNy41MjMgMTUuMzQxNGMtLjU1MTEgMC0uOTk5My0uNDQ4Ni0uOTk5My0uOTk5N3MuNDQ4My0uOTk5My45OTkzLS45OTkzYy41NTExIDAgLjk5OTMuNDQ4My45OTkzLjk5OTMuMDAwMS41NTExLS40NDgyLjk5OTctLjk5OTMuOTk5N20tMTEuMDQ2IDBjLS41NTExIDAtLjk5OTMtLjQ0ODYtLjk5OTMtLjk5OTdzLjQ0ODItLjk5OTMuOTk5My0uOTk5M2MuNTUxMSAwIC45OTkzLjQ0ODMuOTk5My45OTkzIDAgLjU1MTEtLjQ0ODMuOTk5Ny0uOTk5My45OTk3bTExLjQwNDUtNi4wMmwxLjk5NzMtMy40NTkyYS40MTYuNDE2IDAgMDAtLjE1MjEtLjU2NzYuNDE2LjQxNiAwIDAwLS41Njc2LjE1MjFsLTIuMDIyMyAzLjUwM0MxNS41OTAyIDguMjQzOSAxMy44NTMzIDcuODUwOCAxMiA3Ljg1MDhzLTMuNTkwMi4zOTMxLTUuMTM2NyAxLjA5ODlMNC44NDEgNS40NDY3YS40MTYxLjQxNjEgMCAwMC0uNTY3Ny0uMTUyMS40MTU3LjQxNTcgMCAwMC0uMTUyMS41Njc2bDEuOTk3MyAzLjQ1OTJDMi42ODg5IDExLjE4NjcuMzQzMiAxNC42NTg5IDAgMTguNzYxaDI0Yy0uMzQzNS00LjEwMjEtMi42ODkyLTcuNTc0My02LjExODUtOS40Mzk2Ii8+PC9zdmc+"/><text transform="scale(.1)" x="721.25" y="175" textLength="802.5" fill="#fff" font-weight="bold">SAUNAREPO</text></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -15,8 +15,8 @@ android {
|
||||
applicationId "org.joinmastodon.android.sk"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 96
|
||||
versionName "2.0.1+fork.96"
|
||||
versionCode 97
|
||||
versionName "2.0.3+fork.97"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
|
||||
}
|
||||
@@ -34,6 +34,7 @@ android {
|
||||
}
|
||||
githubRelease { initWith release }
|
||||
playRelease { initWith release }
|
||||
fdroidRelease { initWith release }
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
@@ -78,6 +79,7 @@ dependencies {
|
||||
implementation 'com.github.bottom-software-foundation:bottom-java:2.1.0'
|
||||
annotationProcessor 'org.parceler:parceler:1.1.12'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||
implementation 'com.github.UnifiedPush:android-connector:2.1.1'
|
||||
|
||||
androidTestImplementation 'androidx.test:core:1.5.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
@@ -36,18 +37,6 @@
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:scheme="https" android:host="mastodon.social" android:pathPrefix="/@"/>
|
||||
</intent-filter>
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:scheme="https" android:host="mastodon.online" android:pathPrefix="/@"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".PanicResponderActivity"
|
||||
@@ -57,7 +46,6 @@
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
<intent-filter>
|
||||
<action android:name="info.guardianproject.panic.action.TRIGGER" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@@ -100,6 +88,15 @@
|
||||
<category android:name="me.grishka.fcmtest"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:exported="true" android:enabled="true" android:name=".UnifiedPushNotificationReceiver"
|
||||
tools:ignore="ExportedReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.android.connector.MESSAGE"/>
|
||||
<action android:name="org.unifiedpush.android.connector.UNREGISTERED"/>
|
||||
<action android:name="org.unifiedpush.android.connector.NEW_ENDPOINT"/>
|
||||
<action android:name="org.unifiedpush.android.connector.REGISTRATION_FAILED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
</application>
|
||||
|
||||
|
||||
@@ -169,7 +169,8 @@ public class AudioPlayerService extends Service{
|
||||
}
|
||||
|
||||
updateNotification(false, false);
|
||||
getSystemService(AudioManager.class).requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
||||
int audiofocus = GlobalUserPreferences.overlayMedia ? AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK : AudioManager.AUDIOFOCUS_GAIN;
|
||||
getSystemService(AudioManager.class).requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, audiofocus);
|
||||
|
||||
player=new MediaPlayer();
|
||||
player.setOnPreparedListener(this::onPlayerPrepared);
|
||||
|
||||
@@ -57,6 +57,9 @@ public class GlobalUserPreferences{
|
||||
public static AutoRevealMode autoRevealEqualSpoilers;
|
||||
public static ColorPreference color;
|
||||
public static boolean disableM3PillActiveIndicator;
|
||||
public static boolean showNavigationLabels;
|
||||
public static boolean displayPronounsInTimelines, displayPronounsInThreads, displayPronounsInUserListings;
|
||||
public static boolean overlayMedia;
|
||||
|
||||
private static SharedPreferences getPrefs(){
|
||||
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
|
||||
@@ -111,6 +114,11 @@ public class GlobalUserPreferences{
|
||||
autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name()));
|
||||
forwardReportDefault=prefs.getBoolean("forwardReportDefault", true);
|
||||
disableM3PillActiveIndicator=prefs.getBoolean("disableM3PillActiveIndicator", false);
|
||||
showNavigationLabels=prefs.getBoolean("showNavigationLabels", true);
|
||||
displayPronounsInTimelines=prefs.getBoolean("displayPronounsInTimelines", true);
|
||||
displayPronounsInThreads=prefs.getBoolean("displayPronounsInThreads", true);
|
||||
displayPronounsInUserListings=prefs.getBoolean("displayPronounsInUserListings", true);
|
||||
overlayMedia=prefs.getBoolean("overlayMedia", false);
|
||||
|
||||
if (prefs.contains("prefixRepliesWithRe")) {
|
||||
prefixReplies = prefs.getBoolean("prefixRepliesWithRe", false)
|
||||
@@ -164,6 +172,11 @@ public class GlobalUserPreferences{
|
||||
.putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name())
|
||||
.putBoolean("forwardReportDefault", forwardReportDefault)
|
||||
.putBoolean("disableM3PillActiveIndicator", disableM3PillActiveIndicator)
|
||||
.putBoolean("showNavigationLabels", showNavigationLabels)
|
||||
.putBoolean("displayPronounsInTimelines", displayPronounsInTimelines)
|
||||
.putBoolean("displayPronounsInThreads", displayPronounsInThreads)
|
||||
.putBoolean("displayPronounsInUserListings", displayPronounsInUserListings)
|
||||
.putBoolean("overlayMedia", overlayMedia)
|
||||
.apply();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -32,6 +33,7 @@ import org.joinmastodon.android.model.Preferences;
|
||||
import org.joinmastodon.android.model.PushNotification;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
@@ -58,7 +60,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
||||
|
||||
private static final int SUMMARY_ID = 791;
|
||||
private static int notificationId = 0;
|
||||
private static Map<String, Integer> notificationIdsForAccounts = new HashMap<>();
|
||||
private static final Map<String, Integer> notificationIdsForAccounts = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent){
|
||||
@@ -148,6 +150,11 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyUnifiedPush(Context context, String accountID, org.joinmastodon.android.model.Notification notification) {
|
||||
// push notifications are only created from the official push notification, so we create a fake from by transforming the notification
|
||||
PushNotificationReceiver.this.notify(context, PushNotification.fromNotification(context, notification), accountID, notification);
|
||||
}
|
||||
|
||||
private void notify(Context context, PushNotification pn, String accountID, org.joinmastodon.android.model.Notification notification){
|
||||
NotificationManager nm=context.getSystemService(NotificationManager.class);
|
||||
AccountSession session=AccountSessionManager.get(accountID);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.joinmastodon.android;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joinmastodon.android.api.MastodonAPIController;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.PaginatedResponse;
|
||||
import org.unifiedpush.android.connector.MessagingReceiver;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
|
||||
public class UnifiedPushNotificationReceiver extends MessagingReceiver{
|
||||
private static final String TAG="UnifiedPushNotificationReceiver";
|
||||
|
||||
public UnifiedPushNotificationReceiver() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewEndpoint(@NotNull Context context, @NotNull String endpoint, @NotNull String instance) {
|
||||
// Called when a new endpoint be used for sending push messages
|
||||
Log.d(TAG, "onNewEndpoint: New Endpoint " + endpoint + " for "+ instance);
|
||||
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
if (account != null)
|
||||
account.getPushSubscriptionManager().registerAccountForPush(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegistrationFailed(@NotNull Context context, @NotNull String instance) {
|
||||
// called when the registration is not possible, eg. no network
|
||||
Log.d(TAG, "onRegistrationFailed: " + instance);
|
||||
//re-register for gcm
|
||||
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
if (account != null)
|
||||
account.getPushSubscriptionManager().registerAccountForPush(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnregistered(@NotNull Context context, @NotNull String instance) {
|
||||
// called when this application is unregistered from receiving push messages
|
||||
Log.d(TAG, "onUnregistered: " + instance);
|
||||
//re-register for gcm
|
||||
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
if (account != null)
|
||||
account.getPushSubscriptionManager().registerAccountForPush(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(@NotNull Context context, @NotNull byte[] message, @NotNull String instance) {
|
||||
// Called when a new message is received. The message contains the full POST body of the push message
|
||||
AccountSession account = AccountSessionManager.getInstance().getAccount(instance);
|
||||
|
||||
//this is stupid
|
||||
// Mastodon stores the info to decrypt the message in the HTTP headers, which are not accessible in UnifiedPush,
|
||||
// thus it is not possible to decrypt them. SO we need to re-request them from the server and transform them later on
|
||||
// The official uses fcm and moves the headers to extra data, see
|
||||
// https://github.com/mastodon/webpush-fcm-relay/blob/cac95b28d5364b0204f629283141ac3fb749e0c5/webpush-fcm-relay.go#L116
|
||||
// https://github.com/tuskyapp/Tusky/pull/2303#issue-1112080540
|
||||
account.getCacheController().getNotifications(null, 1, false, false, true, new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(PaginatedResponse<List<Notification>> result){
|
||||
result.items
|
||||
.stream()
|
||||
.findFirst()
|
||||
.ifPresent(value->MastodonAPIController.runInBackground(()->new PushNotificationReceiver().notifyUnifiedPush(context, instance, value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
//professional error handling
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -121,13 +121,13 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
||||
.orElseGet(() -> this.execNoAuth(domain));
|
||||
}
|
||||
|
||||
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable){
|
||||
return wrapProgress(activity, message, cancelable, null);
|
||||
public MastodonAPIRequest<T> wrapProgress(Context context, @StringRes int message, boolean cancelable){
|
||||
return wrapProgress(context, 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));
|
||||
public MastodonAPIRequest<T> wrapProgress(Context context, @StringRes int message, boolean cancelable, Consumer<ProgressDialog> transform){
|
||||
progressDialog=new ProgressDialog(context);
|
||||
progressDialog.setMessage(context.getString(message));
|
||||
progressDialog.setCancelable(cancelable);
|
||||
if (transform != null) transform.accept(progressDialog);
|
||||
if(cancelable){
|
||||
|
||||
@@ -120,9 +120,22 @@ public class PushSubscriptionManager{
|
||||
return !TextUtils.isEmpty(deviceToken);
|
||||
}
|
||||
|
||||
|
||||
public void registerAccountForPush(PushSubscription subscription){
|
||||
// this function is used for registering push notifications using FCM
|
||||
// to avoid NonFreeNet in F-Droid, this registration is disabled in it
|
||||
// see https://github.com/LucasGGamerM/moshidon/issues/206 for more context
|
||||
if(BuildConfig.BUILD_TYPE.equals("fdroidRelease"))
|
||||
return;
|
||||
|
||||
if(TextUtils.isEmpty(deviceToken))
|
||||
throw new IllegalStateException("No device push token available");
|
||||
String endpoint = "https://app.joinmastodon.org/relay-to/fcm/"+deviceToken+"/"+accountID;
|
||||
registerAccountForPush(subscription, endpoint);
|
||||
}
|
||||
|
||||
public void registerAccountForPush(PushSubscription subscription, String endpoint){
|
||||
|
||||
MastodonAPIController.runInBackground(()->{
|
||||
Log.d(TAG, "registerAccountForPush: started for "+accountID);
|
||||
String encodedPublicKey, encodedAuthKey, pushAccountID;
|
||||
@@ -151,12 +164,11 @@ public class PushSubscriptionManager{
|
||||
Log.e(TAG, "registerAccountForPush: error generating encryption key", e);
|
||||
return;
|
||||
}
|
||||
new RegisterForPushNotifications(deviceToken,
|
||||
new RegisterForPushNotifications(endpoint,
|
||||
encodedPublicKey,
|
||||
encodedAuthKey,
|
||||
subscription==null ? PushSubscription.Alerts.ofAll() : subscription.alerts,
|
||||
subscription==null ? PushSubscription.Policy.ALL : subscription.policy,
|
||||
pushAccountID)
|
||||
subscription==null ? PushSubscription.Policy.ALL : subscription.policy)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(PushSubscription result){
|
||||
|
||||
@@ -4,8 +4,15 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
|
||||
public class SetAccountMuted extends MastodonAPIRequest<Relationship>{
|
||||
public SetAccountMuted(String id, boolean muted){
|
||||
public SetAccountMuted(String id, boolean muted, long duration){
|
||||
super(HttpMethod.POST, "/accounts/"+id+"/"+(muted ? "mute" : "unmute"), Relationship.class);
|
||||
setRequestBody(new Object());
|
||||
setRequestBody(new Request(duration));
|
||||
}
|
||||
|
||||
private static class Request{
|
||||
public long duration;
|
||||
public Request(long duration){
|
||||
this.duration=duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.announcements;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class AddAnnouncementReaction extends MastodonAPIRequest<Object> {
|
||||
public AddAnnouncementReaction(String id, String emoji) {
|
||||
super(HttpMethod.PUT, "/announcements/" + id + "/reactions/" + emoji, Object.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.joinmastodon.android.api.requests.announcements;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
|
||||
public class DeleteAnnouncementReaction extends MastodonAPIRequest<Object> {
|
||||
public DeleteAnnouncementReaction(String id, String emoji) {
|
||||
super(HttpMethod.DELETE, "/announcements/" + id + "/reactions/" + emoji, Object.class);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.PushSubscription;
|
||||
|
||||
public class RegisterForPushNotifications extends MastodonAPIRequest<PushSubscription>{
|
||||
public RegisterForPushNotifications(String deviceToken, String encryptionKey, String authKey, PushSubscription.Alerts alerts, PushSubscription.Policy policy, String accountID){
|
||||
public RegisterForPushNotifications(String endpoint, String encryptionKey, String authKey, PushSubscription.Alerts alerts, PushSubscription.Policy policy){
|
||||
super(HttpMethod.POST, "/push/subscription", PushSubscription.class);
|
||||
Request r=new Request();
|
||||
r.subscription.endpoint="https://app.joinmastodon.org/relay-to/fcm/"+deviceToken+"/"+accountID;
|
||||
r.subscription.endpoint=endpoint;
|
||||
r.data.alerts=alerts;
|
||||
r.policy=policy;
|
||||
r.subscription.keys.p256dh=encryptionKey;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class AddStatusReaction extends MastodonAPIRequest<Status> {
|
||||
public AddStatusReaction(String id, String emoji) {
|
||||
super(HttpMethod.POST, "/statuses/" + id + "/react/" + emoji, Status.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class DeleteStatusReaction extends MastodonAPIRequest<Status> {
|
||||
public DeleteStatusReaction(String id, String emoji) {
|
||||
super(HttpMethod.POST, "/statuses/" + id + "/unreact/" + emoji, Status.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class PleromaAddStatusReaction extends MastodonAPIRequest<Status> {
|
||||
public PleromaAddStatusReaction(String id, String emoji) {
|
||||
super(HttpMethod.PUT, "/pleroma/statuses/" + id + "/reactions/" + emoji, Status.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class PleromaDeleteStatusReaction extends MastodonAPIRequest<Status> {
|
||||
public PleromaDeleteStatusReaction(String id, String emoji) {
|
||||
super(HttpMethod.DELETE, "/pleroma/statuses/" + id + "/reactions/" + emoji, Status.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.EmojiReaction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PleromaGetStatusReactions extends MastodonAPIRequest<List<EmojiReaction>> {
|
||||
public PleromaGetStatusReactions(String id, String emoji) {
|
||||
super(HttpMethod.GET, "/pleroma/statuses/" + id + "/reactions/" + (emoji != null ? emoji : ""), new TypeToken<>(){});
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,9 @@ public class AccountLocalPreferences{
|
||||
public String timelineReplyVisibility; // akkoma-only
|
||||
public boolean keepOnlyLatestNotification;
|
||||
|
||||
public boolean emojiReactionsEnabled;
|
||||
public boolean showEmojiReactionsInLists;
|
||||
|
||||
private final static Type recentLanguagesType = new TypeToken<ArrayList<String>>() {}.getType();
|
||||
private final static Type timelinesType = new TypeToken<ArrayList<TimelineDefinition>>() {}.getType();
|
||||
|
||||
@@ -62,6 +65,8 @@ public class AccountLocalPreferences{
|
||||
publishButtonText=prefs.getString("publishButtonText", null);
|
||||
timelineReplyVisibility=prefs.getString("timelineReplyVisibility", null);
|
||||
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
|
||||
emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", session.getInstance().isPresent() && session.getInstance().get().isAkkoma());
|
||||
showEmojiReactionsInLists=prefs.getBoolean("showEmojiReactionsInLists", false);
|
||||
}
|
||||
|
||||
public long getNotificationsPauseEndTime(){
|
||||
@@ -93,6 +98,8 @@ public class AccountLocalPreferences{
|
||||
.putString("publishButtonText", publishButtonText)
|
||||
.putString("timelineReplyVisibility", timelineReplyVisibility)
|
||||
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
|
||||
.putBoolean("emojiReactionsEnabled", emojiReactionsEnabled)
|
||||
.putBoolean("showEmojiReactionsInLists", showEmojiReactionsInLists)
|
||||
.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
package org.joinmastodon.android.events;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.api.CacheController;
|
||||
import org.joinmastodon.android.model.EmojiReaction;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StatusCountersUpdatedEvent{
|
||||
public String id;
|
||||
public long favorites, reblogs, replies;
|
||||
public boolean favorited, reblogged, bookmarked, pinned;
|
||||
public List<EmojiReaction> reactions;
|
||||
public Status status;
|
||||
public RecyclerView.ViewHolder viewHolder;
|
||||
|
||||
public StatusCountersUpdatedEvent(Status s){
|
||||
this(s, null);
|
||||
}
|
||||
|
||||
public StatusCountersUpdatedEvent(Status s, RecyclerView.ViewHolder vh){
|
||||
id=s.id;
|
||||
status=s;
|
||||
favorites=s.favouritesCount;
|
||||
@@ -19,5 +31,7 @@ public class StatusCountersUpdatedEvent{
|
||||
reblogged=s.reblogged;
|
||||
bookmarked=s.bookmarked;
|
||||
pinned=s.pinned;
|
||||
reactions=new ArrayList<>(s.reactions);
|
||||
viewHolder=vh;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.ScheduledStatus;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.displayitems.DummyStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
||||
@@ -71,7 +73,8 @@ public class AnnouncementsFragment extends BaseStatusListFragment<Announcement>
|
||||
textItem.textSelectable = true;
|
||||
return List.of(
|
||||
HeaderStatusDisplayItem.fromAnnouncement(a, fakeStatus, instanceUser, this, accountID, this::onMarkAsRead),
|
||||
textItem
|
||||
textItem,
|
||||
new EmojiReactionsStatusDisplayItem(a.id, this, fakeStatus, accountID, false, true)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
|
||||
@@ -607,6 +608,15 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
if (header != null) header.rebind();
|
||||
}
|
||||
|
||||
public void updateEmojiReactions(Status status, String itemID){
|
||||
EmojiReactionsStatusDisplayItem.Holder reactions=findHolderOfType(itemID, EmojiReactionsStatusDisplayItem.Holder.class);
|
||||
if(reactions != null){
|
||||
reactions.getItem().status.reactions.clear();
|
||||
reactions.getItem().status.reactions.addAll(status.reactions);
|
||||
reactions.rebind();
|
||||
}
|
||||
}
|
||||
|
||||
public void onGapClick(GapStatusDisplayItem.Holder item){}
|
||||
|
||||
public void onWarningClick(WarningFilteredStatusDisplayItem.Holder warning){
|
||||
@@ -782,6 +792,10 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollBy(int x, int y) {
|
||||
list.scrollBy(x, y);
|
||||
}
|
||||
|
||||
protected class DisplayItemsAdapter extends UsableRecyclerView.Adapter<BindableViewHolder<StatusDisplayItem>> implements ImageLoaderRecyclerAdapter{
|
||||
|
||||
public DisplayItemsAdapter(){
|
||||
|
||||
@@ -300,6 +300,13 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
onCustomEmojiClick(emoji);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiSelected(String emoji){
|
||||
if(getActivity().getCurrentFocus() instanceof EditText edit && edit == mainEditText){
|
||||
edit.getText().replace(edit.getSelectionStart(), edit.getSelectionEnd(), emoji);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackspace(){
|
||||
getActivity().dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
|
||||
@@ -449,7 +456,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
} else if (getArguments().containsKey("sourceContentType")) {
|
||||
try {
|
||||
String val = getArguments().getString("sourceContentType");
|
||||
contentType = val == null ? null : ContentType.valueOf(val);
|
||||
if (val != null) contentType = ContentType.valueOf(val);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
|
||||
@@ -1435,8 +1442,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
}
|
||||
|
||||
private void updateHeaders() {
|
||||
UiUtils.setExtraTextInfo(getContext(), selfExtraText, null, false, localOnly || statusVisibility==StatusPrivacy.LOCAL, null);
|
||||
if (replyTo != null) UiUtils.setExtraTextInfo(getContext(), extraText, pronouns, false, replyTo.localOnly || replyTo.visibility==StatusPrivacy.LOCAL, replyTo.account);
|
||||
UiUtils.setExtraTextInfo(getContext(), selfExtraText, null, false, false, localOnly || statusVisibility==StatusPrivacy.LOCAL, null);
|
||||
if (replyTo != null) UiUtils.setExtraTextInfo(getContext(), extraText, pronouns, true, false, replyTo.localOnly || replyTo.visibility==StatusPrivacy.LOCAL, replyTo.account);
|
||||
}
|
||||
|
||||
private void buildVisibilityPopup(View v){
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
|
||||
import android.app.Fragment;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.assist.AssistContent;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
@@ -126,12 +127,31 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
tabBarWrap=content.findViewById(R.id.tabbar_wrap);
|
||||
|
||||
// this one's for the pill haters (https://m3.material.io/components/navigation-bar/overview)
|
||||
if (GlobalUserPreferences.disableM3PillActiveIndicator) {
|
||||
for(int i=0; i<tabBar.getChildCount(); i++){
|
||||
ViewGroup f=(ViewGroup) tabBar.getChildAt(i);
|
||||
f.setBackgroundResource(R.drawable.bg_tabbar_tab_ripple);
|
||||
if(GlobalUserPreferences.disableM3PillActiveIndicator){
|
||||
tabBar.findViewById(R.id.tab_home_pill).setBackground(null);
|
||||
tabBar.findViewById(R.id.tab_search_pill).setBackground(null);
|
||||
tabBar.findViewById(R.id.tab_notifications_pill).setBackground(null);
|
||||
tabBar.findViewById(R.id.tab_profile_pill).setBackgroundResource(R.drawable.bg_tab_profile);
|
||||
|
||||
View[] tabs={
|
||||
tabBar.findViewById(R.id.tab_home),
|
||||
tabBar.findViewById(R.id.tab_search),
|
||||
tabBar.findViewById(R.id.tab_notifications),
|
||||
tabBar.findViewById(R.id.tab_profile)
|
||||
};
|
||||
|
||||
for(View tab : tabs){
|
||||
tab.setBackgroundResource(R.drawable.bg_tabbar_tab_ripple);
|
||||
((RippleDrawable) tab.getBackground())
|
||||
.setRadius(V.dp(GlobalUserPreferences.showNavigationLabels ? 56 : 42));
|
||||
}
|
||||
tabBar.findViewById(R.id.tab_profile).setBackgroundResource(R.drawable.bg_tab_profile);
|
||||
}
|
||||
|
||||
if(!GlobalUserPreferences.showNavigationLabels){
|
||||
tabBar.findViewById(R.id.tab_home_label).setVisibility(View.GONE);
|
||||
tabBar.findViewById(R.id.tab_search_label).setVisibility(View.GONE);
|
||||
tabBar.findViewById(R.id.tab_notifications_label).setVisibility(View.GONE);
|
||||
tabBar.findViewById(R.id.tab_profile_label).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
tabBarAvatar=tabBar.findViewById(R.id.tab_profile_ava);
|
||||
|
||||
@@ -62,6 +62,7 @@ import org.joinmastodon.android.utils.ElevationOnScrollListener;
|
||||
import org.joinmastodon.android.utils.ProvidesAssistContent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -336,11 +337,13 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
||||
hashtagsMenu.clear();
|
||||
hashtagsMenu.getItem().setVisible(hashtagsItems.size() > 0);
|
||||
UiUtils.insetPopupMenuIcon(ctx, UiUtils.makeBackItem(hashtagsMenu));
|
||||
hashtagsItems.forEach((id, hashtag) -> {
|
||||
MenuItem item = hashtagsMenu.add(Menu.NONE, id, Menu.NONE, hashtag.name);
|
||||
item.setIcon(R.drawable.ic_fluent_number_symbol_24_regular);
|
||||
UiUtils.insetPopupMenuIcon(ctx, item);
|
||||
});
|
||||
hashtagsItems.entrySet().stream()
|
||||
.sorted(Comparator.comparing(x -> x.getValue().name, String.CASE_INSENSITIVE_ORDER))
|
||||
.forEach(entry -> {
|
||||
MenuItem item = hashtagsMenu.add(Menu.NONE, entry.getKey(), Menu.NONE, entry.getValue().name);
|
||||
item.setIcon(R.drawable.ic_fluent_number_symbol_24_regular);
|
||||
UiUtils.insetPopupMenuIcon(ctx, item);
|
||||
});
|
||||
}
|
||||
|
||||
public void updateToolbarLogo(){
|
||||
|
||||
@@ -12,8 +12,8 @@ import android.view.View;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.PollUpdatedEvent;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
@@ -22,6 +22,7 @@ import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.PaginatedResponse;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.NotificationHeaderStatusDisplayItem;
|
||||
@@ -99,7 +100,11 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
return items;
|
||||
}
|
||||
if(n.status!=null){
|
||||
int flags=titleItem==null ? 0 : (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET); // | StatusDisplayItem.FLAG_NO_HEADER);
|
||||
int flags=titleItem==null ? 0 : (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS); // | StatusDisplayItem.FLAG_NO_HEADER);
|
||||
if (GlobalUserPreferences.spectatorMode)
|
||||
flags |= StatusDisplayItem.FLAG_NO_FOOTER;
|
||||
if (!getLocalPrefs().showEmojiReactionsInLists)
|
||||
flags |= StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS;
|
||||
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, null, flags);
|
||||
if(titleItem!=null)
|
||||
items.add(0, titleItem);
|
||||
@@ -254,6 +259,8 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
footer.rebind();
|
||||
}else if(holder instanceof ExtendedFooterStatusDisplayItem.Holder footer && footer.getItem().status==n.status.getContentStatus()){
|
||||
footer.rebind();
|
||||
}else if(holder instanceof EmojiReactionsStatusDisplayItem.Holder reactions && ev.viewHolder!=holder){
|
||||
reactions.rebind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import static org.joinmastodon.android.fragments.ProfileAboutFragment.MAX_FIELDS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -175,6 +173,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
private MenuItem editSaveMenuItem;
|
||||
private boolean savingEdits;
|
||||
|
||||
private int maxFields = ProfileAboutFragment.MAX_FIELDS;
|
||||
|
||||
// from ProfileAboutFragment
|
||||
public UsableRecyclerView list;
|
||||
private AboutAdapter adapter;
|
||||
@@ -200,6 +200,9 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
loaded=true;
|
||||
if(!isOwnProfile)
|
||||
loadRelationship();
|
||||
else if (isInstanceAkkoma()) {
|
||||
maxFields = getInstance().get().pleroma.metadata.fieldsLimits.maxFields;
|
||||
}
|
||||
}else{
|
||||
profileAccountID=getArguments().getString("profileAccountID");
|
||||
if(!getArguments().getBoolean("noAutoLoad", false))
|
||||
@@ -1073,6 +1076,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
);
|
||||
|
||||
name.setVisibility(View.GONE);
|
||||
rolesView.setVisibility(View.GONE);
|
||||
username.setVisibility(View.GONE);
|
||||
bio.setVisibility(View.GONE);
|
||||
countersLayout.setVisibility(View.GONE);
|
||||
@@ -1121,6 +1125,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
nameEditWrap.setVisibility(View.GONE);
|
||||
bioEditWrap.setVisibility(View.GONE);
|
||||
name.setVisibility(View.VISIBLE);
|
||||
rolesView.setVisibility(View.VISIBLE);
|
||||
username.setVisibility(View.VISIBLE);
|
||||
bio.setVisibility(View.VISIBLE);
|
||||
countersLayout.setVisibility(View.VISIBLE);
|
||||
@@ -1385,7 +1390,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
public int getItemCount(){
|
||||
if(isInEditMode){
|
||||
int size=fields.size();
|
||||
if(size<MAX_FIELDS)
|
||||
if(size<maxFields)
|
||||
size++;
|
||||
return size;
|
||||
}
|
||||
@@ -1510,7 +1515,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
@Override
|
||||
public void onClick(){
|
||||
fields.add(new AccountField());
|
||||
if(fields.size()==MAX_FIELDS){ // replace this row with new row
|
||||
if(fields.size()==maxFields){ // replace this row with new row
|
||||
adapter.notifyItemChanged(fields.size()-1);
|
||||
}else{
|
||||
adapter.notifyItemInserted(fields.size()-1);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
|
||||
|
||||
@Override
|
||||
protected List<StatusDisplayItem> buildDisplayItems(ScheduledStatus s) {
|
||||
return StatusDisplayItem.buildItems(this, s.toStatus(), accountID, s, knownAccounts, false, false, true, null);
|
||||
return StatusDisplayItem.buildItems(this, s.toStatus(), accountID, s, knownAccounts, false, false, false, true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,7 +57,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
||||
|
||||
@Override
|
||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, null, StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET);
|
||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, null, StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS);
|
||||
int idx=data.indexOf(s);
|
||||
if(idx>=0){
|
||||
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
import org.joinmastodon.android.events.StatusUpdatedEvent;
|
||||
import org.joinmastodon.android.model.FilterContext;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||
@@ -33,9 +34,13 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>
|
||||
protected EventListener eventListener=new EventListener();
|
||||
|
||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||
boolean addFooter = !GlobalUserPreferences.spectatorMode ||
|
||||
(this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id));
|
||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, getFilterContext(), addFooter ? 0 : StatusDisplayItem.FLAG_NO_FOOTER);
|
||||
boolean isMainThreadStatus = this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id);
|
||||
int flags = 0;
|
||||
if (GlobalUserPreferences.spectatorMode)
|
||||
flags |= StatusDisplayItem.FLAG_NO_FOOTER;
|
||||
if (!getLocalPrefs().showEmojiReactionsInLists)
|
||||
flags |= StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS;
|
||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, getFilterContext(), isMainThreadStatus ? 0 : flags);
|
||||
}
|
||||
|
||||
protected abstract FilterContext getFilterContext();
|
||||
@@ -218,6 +223,8 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>
|
||||
footer.rebind();
|
||||
}else if(holder instanceof ExtendedFooterStatusDisplayItem.Holder footer && footer.getItem().status==s.getContentStatus()){
|
||||
footer.rebind();
|
||||
}else if(holder instanceof EmojiReactionsStatusDisplayItem.Holder reactions && reactions.getItem().status==s.getContentStatus() && ev.viewHolder!=holder){
|
||||
reactions.rebind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,6 +417,10 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public Status getMainStatus(){
|
||||
return mainStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemEnabled(String id){
|
||||
return !id.equals(mainStatus.id) || !mainStatus.filterRevealed;
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.joinmastodon.android.model.viewmodel.AccountViewModel;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.grishka.appkit.api.Callback;
|
||||
@@ -136,6 +137,10 @@ public abstract class PaginatedAccountListFragment<T> extends BaseAccountListFra
|
||||
List<AccountViewModel> items = result.stream()
|
||||
.filter(a -> d.size() > 1000 || d.stream()
|
||||
.noneMatch(i -> i.account.url.equals(a.url)))
|
||||
.peek(account ->{
|
||||
if (account.getDomainFromURL().equals(getRemoteDomain()))
|
||||
account.acct=account.getFullyQualifiedName();
|
||||
})
|
||||
.map(a->new AccountViewModel(a, accountID))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.joinmastodon.android.fragments.account_list;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.View;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.statuses.PleromaGetStatusReactions;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.EmojiReaction;
|
||||
import org.joinmastodon.android.model.viewmodel.AccountViewModel;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
|
||||
public class StatusEmojiReactionsListFragment extends BaseAccountListFragment {
|
||||
private String id;
|
||||
private String emojiName;
|
||||
private String url;
|
||||
private int count;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
id = getArguments().getString("statusID");
|
||||
emojiName = getArguments().getString("emoji");
|
||||
url = getArguments().getString("url");
|
||||
count = getArguments().getInt("count");
|
||||
|
||||
SpannableStringBuilder title = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.sk_users_reacted_with, count,
|
||||
count, url == null ? emojiName : ":"+emojiName+":"));
|
||||
if (url != null) {
|
||||
Emoji emoji = new Emoji();
|
||||
emoji.shortcode = emojiName;
|
||||
emoji.url = url;
|
||||
HtmlParser.parseCustomEmoji(title, Collections.singletonList(emoji));
|
||||
}
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (url != null) {
|
||||
UiUtils.loadCustomEmojiInTextView(toolbarTitleView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dataLoaded() {
|
||||
super.dataLoaded();
|
||||
footerProgress.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest = new PleromaGetStatusReactions(id, emojiName)
|
||||
.setCallback(new SimpleCallback<>(StatusEmojiReactionsListFragment.this){
|
||||
@Override
|
||||
public void onSuccess(List<EmojiReaction> result) {
|
||||
if (getActivity() == null)
|
||||
return;
|
||||
|
||||
List<AccountViewModel> items = result.get(0).accounts.stream()
|
||||
.map(a -> new AccountViewModel(a, accountID))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
onDataLoaded(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
super.onError(error);
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
if(!loaded && !dataLoading)
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getWebUri(Uri.Builder base) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,8 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
private String accountID;
|
||||
private String currentQuery;
|
||||
|
||||
private boolean disableDiscover;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -155,6 +157,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
}
|
||||
});
|
||||
|
||||
disableDiscover=getArguments().getBoolean("disableDiscover");
|
||||
searchView=view.findViewById(R.id.search_fragment);
|
||||
if(searchFragment==null){
|
||||
searchFragment=new SearchFragment();
|
||||
@@ -170,8 +173,9 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
searchBack.setOnClickListener(v->{
|
||||
if(searchActive) exitSearch(); else openSearch();
|
||||
});
|
||||
if(searchActive){
|
||||
searchBack.setImageResource(R.drawable.ic_fluent_arrow_left_24_regular);
|
||||
if(searchActive) searchBack.setImageResource(R.drawable.ic_fluent_arrow_left_24_regular);
|
||||
else searchBack.setEnabled(false);
|
||||
if(searchActive || disableDiscover){
|
||||
pager.setVisibility(View.GONE);
|
||||
tabLayout.setVisibility(View.GONE);
|
||||
searchView.setVisibility(View.VISIBLE);
|
||||
@@ -211,8 +215,8 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
}
|
||||
|
||||
public void loadData(){
|
||||
if(postsFragment!=null && !postsFragment.loaded && !postsFragment.dataLoading)
|
||||
postsFragment.loadData();
|
||||
if(hashtagsFragment!=null && !hashtagsFragment.loaded && !hashtagsFragment.dataLoading)
|
||||
hashtagsFragment.loadData();
|
||||
}
|
||||
|
||||
private void enterSearch(){
|
||||
@@ -232,15 +236,18 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
if(!searchActive)
|
||||
return;
|
||||
searchActive=false;
|
||||
pager.setVisibility(View.VISIBLE);
|
||||
tabLayout.setVisibility(View.VISIBLE);
|
||||
searchView.setVisibility(View.GONE);
|
||||
searchText.setText(R.string.sk_search_fediverse);
|
||||
searchBack.setImageResource(R.drawable.ic_fluent_search_24_regular);
|
||||
searchBack.setEnabled(false);
|
||||
searchBack.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||
tabsDivider.setVisibility(View.VISIBLE);
|
||||
currentQuery=null;
|
||||
searchFragment.clear();
|
||||
|
||||
if(disableDiscover) return;
|
||||
pager.setVisibility(View.VISIBLE);
|
||||
tabLayout.setVisibility(View.VISIBLE);
|
||||
searchView.setVisibility(View.GONE);
|
||||
tabsDivider.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private Fragment getFragmentForPage(int page){
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.search.GetSearchResults;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
@@ -54,7 +55,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
super.onCreate(savedInstanceState);
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
|
||||
setRetainInstance(true);
|
||||
setEmptyText(R.string.no_search_results);
|
||||
setEmptyText(R.string.sk_recent_searches_placeholder);
|
||||
loadData();
|
||||
}
|
||||
|
||||
@@ -69,7 +70,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, FilterContext.PUBLIC, 0);
|
||||
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, FilterContext.PUBLIC, !getLocalPrefs().showEmojiReactionsInLists ? StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS : 0);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -173,13 +174,16 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
}
|
||||
|
||||
public void setQuery(String q, SearchResult.Type filter){
|
||||
if(q.isBlank())
|
||||
if(q.isBlank()) {
|
||||
setEmptyText(R.string.sk_recent_searches_placeholder);
|
||||
return;
|
||||
}
|
||||
if(currentRequest!=null){
|
||||
currentRequest.cancel();
|
||||
currentRequest=null;
|
||||
}
|
||||
currentQuery=q;
|
||||
setEmptyText(R.string.no_search_results);
|
||||
if(filter==null)
|
||||
currentFilter=EnumSet.allOf(SearchResult.Type.class);
|
||||
else
|
||||
@@ -221,6 +225,13 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
data.clear();
|
||||
preloadedData.clear();
|
||||
adapter.notifyDataSetChanged();
|
||||
V.setVisibilityAnimated(content, View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getWebUri(Uri.Builder base) {
|
||||
Uri.Builder searchUri = base.path("/search");
|
||||
|
||||
@@ -102,7 +102,6 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{
|
||||
selectedIDs.remove(id);
|
||||
else
|
||||
selectedIDs.add(id);
|
||||
btn.setEnabled(!selectedIDs.isEmpty());
|
||||
CheckableHeaderStatusDisplayItem.Holder holder=findHolderOfType(id, CheckableHeaderStatusDisplayItem.Holder.class);
|
||||
if(holder!=null)
|
||||
holder.rebind();
|
||||
@@ -112,7 +111,6 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{
|
||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
btn=view.findViewById(R.id.btn_next);
|
||||
btn.setEnabled(!selectedIDs.isEmpty());
|
||||
btn.setOnClickListener(this::onButtonClick);
|
||||
buttonBar=view.findViewById(R.id.button_bar);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
// MEGALODON
|
||||
private MastodonLanguage.LanguageResolver languageResolver;
|
||||
private ListItem<Void> prefixRepliesItem, replyVisibilityItem;
|
||||
private CheckableListItem<Void> forwardReportsItem, remoteLoadingItem, showBoostsItem, showRepliesItem, loadNewPostsItem, seeNewPostsBtnItem;
|
||||
private CheckableListItem<Void> forwardReportsItem, remoteLoadingItem, showBoostsItem, showRepliesItem, loadNewPostsItem, seeNewPostsBtnItem, overlayMediaItem;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
@@ -47,6 +47,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
languageItem=new ListItem<>(getString(R.string.default_post_language), postLanguage!=null ? postLanguage.getDisplayName(getContext()) : null, R.drawable.ic_fluent_local_language_24_regular, this::onDefaultLanguageClick),
|
||||
altTextItem=new CheckableListItem<>(R.string.settings_alt_text_reminders, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.altTextReminders, R.drawable.ic_fluent_image_alt_text_24_regular, ()->toggleCheckableItem(altTextItem)),
|
||||
playGifsItem=new CheckableListItem<>(R.string.settings_gif, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.playGifs, R.drawable.ic_fluent_gif_24_regular, ()->toggleCheckableItem(playGifsItem)),
|
||||
overlayMediaItem=new CheckableListItem<>(R.string.sk_settings_continues_playback, R.string.sk_settings_continues_playback_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.overlayMedia, R.drawable.ic_fluent_play_circle_hint_24_regular, ()->toggleCheckableItem(overlayMediaItem)),
|
||||
customTabsItem=new CheckableListItem<>(R.string.settings_custom_tabs, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.useCustomTabs, R.drawable.ic_fluent_link_24_regular, ()->toggleCheckableItem(customTabsItem)),
|
||||
confirmUnfollowItem=new CheckableListItem<>(R.string.settings_confirm_unfollow, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmUnfollow, R.drawable.ic_fluent_person_delete_24_regular, ()->toggleCheckableItem(confirmUnfollowItem)),
|
||||
confirmBoostItem=new CheckableListItem<>(R.string.settings_confirm_boost, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmBoost, R.drawable.ic_fluent_arrow_repeat_all_24_regular, ()->toggleCheckableItem(confirmBoostItem)),
|
||||
@@ -162,6 +163,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
GlobalUserPreferences.playGifs=playGifsItem.checked;
|
||||
GlobalUserPreferences.overlayMedia=overlayMediaItem.checked;
|
||||
GlobalUserPreferences.useCustomTabs=customTabsItem.checked;
|
||||
GlobalUserPreferences.altTextReminders=altTextItem.checked;
|
||||
GlobalUserPreferences.confirmUnfollow=customTabsItem.checked;
|
||||
|
||||
@@ -37,8 +37,9 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
private CheckableListItem<Void> revealCWsItem, hideSensitiveMediaItem, interactionCountsItem, emojiInNamesItem;
|
||||
|
||||
// MEGALODON
|
||||
private CheckableListItem<Void> trueBlackModeItem, marqueeItem, disableSwipeItem, reduceMotionItem, altIndicatorItem, noAltIndicatorItem, collapsePostsItem, spectatorModeItem, hideFabItem, translateOpenedItem, disablePillItem;
|
||||
private CheckableListItem<Void> trueBlackModeItem, marqueeItem, disableSwipeItem, reduceMotionItem, altIndicatorItem, noAltIndicatorItem, collapsePostsItem, spectatorModeItem, hideFabItem, translateOpenedItem, disablePillItem, showNavigationLabelsItem;
|
||||
private ListItem<Void> colorItem, publishTextItem, autoRevealCWsItem;
|
||||
private CheckableListItem<Void> pronounsInUserListingsItem, pronounsInTimelinesItem, pronounsInThreadsItem;
|
||||
|
||||
private AccountLocalPreferences lp;
|
||||
|
||||
@@ -67,7 +68,11 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
spectatorModeItem=new CheckableListItem<>(R.string.sk_settings_hide_interaction, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.spectatorMode, R.drawable.ic_fluent_star_off_24_regular, ()->toggleCheckableItem(spectatorModeItem)),
|
||||
hideFabItem=new CheckableListItem<>(R.string.sk_settings_hide_fab, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.autoHideFab, R.drawable.ic_fluent_edit_24_regular, ()->toggleCheckableItem(hideFabItem)),
|
||||
translateOpenedItem=new CheckableListItem<>(R.string.sk_settings_translate_only_opened, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.translateButtonOpenedOnly, R.drawable.ic_fluent_translate_24_regular, ()->toggleCheckableItem(translateOpenedItem)),
|
||||
disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, ()->toggleCheckableItem(disablePillItem))
|
||||
disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, ()->toggleCheckableItem(disablePillItem)),
|
||||
showNavigationLabelsItem=new CheckableListItem<>(R.string.sk_settings_show_labels_in_navigation_bar, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNavigationLabels, R.drawable.ic_fluent_tag_24_regular, ()->toggleCheckableItem(showNavigationLabelsItem), true),
|
||||
pronounsInTimelinesItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_timelines, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInTimelines, 0, ()->toggleCheckableItem(pronounsInTimelinesItem)),
|
||||
pronounsInThreadsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_threads, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInThreads, 0, ()->toggleCheckableItem(pronounsInThreadsItem)),
|
||||
pronounsInUserListingsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_user_listings, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInUserListings, 0, ()->toggleCheckableItem(pronounsInUserListingsItem))
|
||||
));
|
||||
trueBlackModeItem.checkedChangeListener=checked->onTrueBlackModeClick();
|
||||
}
|
||||
@@ -90,7 +95,8 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
super.onHidden();
|
||||
|
||||
boolean restartPlease=
|
||||
GlobalUserPreferences.disableM3PillActiveIndicator!=disablePillItem.checked;
|
||||
GlobalUserPreferences.disableM3PillActiveIndicator!=disablePillItem.checked ||
|
||||
GlobalUserPreferences.showNavigationLabels!=showNavigationLabelsItem.checked;
|
||||
|
||||
lp.revealCWs=revealCWsItem.checked;
|
||||
lp.hideSensitiveMedia=hideSensitiveMediaItem.checked;
|
||||
@@ -107,6 +113,10 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
GlobalUserPreferences.autoHideFab=hideFabItem.checked;
|
||||
GlobalUserPreferences.translateButtonOpenedOnly=translateOpenedItem.checked;
|
||||
GlobalUserPreferences.disableM3PillActiveIndicator=disablePillItem.checked;
|
||||
GlobalUserPreferences.showNavigationLabels=showNavigationLabelsItem.checked;
|
||||
GlobalUserPreferences.displayPronounsInTimelines=pronounsInTimelinesItem.checked;
|
||||
GlobalUserPreferences.displayPronounsInThreads=pronounsInThreadsItem.checked;
|
||||
GlobalUserPreferences.displayPronounsInUserListings=pronounsInUserListingsItem.checked;
|
||||
GlobalUserPreferences.save();
|
||||
if(restartPlease) restartActivityToApplyNewTheme();
|
||||
else E.post(new StatusDisplaySettingsChangedEvent(accountID));
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
import me.grishka.appkit.Nav;
|
||||
|
||||
public class SettingsInstanceFragment extends BaseSettingsFragment<Void> implements HasAccountID{
|
||||
private CheckableListItem<Void> contentTypesItem, localOnlyItem, glitchModeItem;
|
||||
private CheckableListItem<Void> contentTypesItem, emojiReactionsItem, emojiReactionsInListsItem, localOnlyItem, glitchModeItem;
|
||||
private ListItem<Void> defaultContentTypeItem;
|
||||
private AccountLocalPreferences lp;
|
||||
|
||||
@@ -36,11 +36,15 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
new ListItem<>(R.string.sk_settings_auth, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/auth/edit"), 0, true),
|
||||
contentTypesItem=new CheckableListItem<>(R.string.sk_settings_content_types, R.string.sk_settings_content_types_explanation, CheckableListItem.Style.SWITCH, lp.contentTypesEnabled, R.drawable.ic_fluent_text_edit_style_24_regular, this::onContentTypeClick),
|
||||
defaultContentTypeItem=new ListItem<>(R.string.sk_settings_default_content_type, lp.defaultContentType.getName(), R.drawable.ic_fluent_text_bold_24_regular, this::onDefaultContentTypeClick),
|
||||
emojiReactionsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions, R.string.sk_settings_emoji_reactions_explanation, CheckableListItem.Style.SWITCH, lp.emojiReactionsEnabled, R.drawable.ic_fluent_emoji_laugh_24_regular, this::onEmojiReactionsClick),
|
||||
emojiReactionsInListsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions_in_lists, R.string.sk_settings_emoji_reactions_in_lists_explanation, CheckableListItem.Style.SWITCH, lp.showEmojiReactionsInLists, R.drawable.ic_fluent_emoji_24_regular, ()->toggleCheckableItem(emojiReactionsInListsItem)),
|
||||
localOnlyItem=new CheckableListItem<>(R.string.sk_settings_support_local_only, R.string.sk_settings_local_only_explanation, CheckableListItem.Style.SWITCH, lp.localOnlySupported, R.drawable.ic_fluent_eye_24_regular, this::onLocalOnlyClick),
|
||||
glitchModeItem=new CheckableListItem<>(R.string.sk_settings_glitch_instance, R.string.sk_settings_glitch_mode_explanation, CheckableListItem.Style.SWITCH, lp.glitchInstance, R.drawable.ic_fluent_eye_24_filled, ()->toggleCheckableItem(glitchModeItem))
|
||||
));
|
||||
contentTypesItem.checkedChangeListener=checked->onContentTypeClick();
|
||||
defaultContentTypeItem.isEnabled=contentTypesItem.checked;
|
||||
emojiReactionsItem.checkedChangeListener=checked->onEmojiReactionsClick();
|
||||
emojiReactionsInListsItem.isEnabled=emojiReactionsItem.checked;
|
||||
localOnlyItem.checkedChangeListener=checked->onLocalOnlyClick();
|
||||
glitchModeItem.isEnabled=localOnlyItem.checked;
|
||||
}
|
||||
@@ -52,6 +56,8 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
lp.contentTypesEnabled=contentTypesItem.checked;
|
||||
lp.emojiReactionsEnabled=emojiReactionsItem.checked;
|
||||
lp.showEmojiReactionsInLists=emojiReactionsInListsItem.checked;
|
||||
lp.localOnlySupported=localOnlyItem.checked;
|
||||
lp.glitchInstance=glitchModeItem.checked;
|
||||
lp.save();
|
||||
@@ -101,6 +107,13 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onEmojiReactionsClick(){
|
||||
toggleCheckableItem(emojiReactionsItem);
|
||||
emojiReactionsInListsItem.checked=false;
|
||||
emojiReactionsInListsItem.isEnabled=emojiReactionsItem.checked;
|
||||
rebindItem(emojiReactionsInListsItem);
|
||||
}
|
||||
|
||||
private void onLocalOnlyClick(){
|
||||
toggleCheckableItem(localOnlyItem);
|
||||
glitchModeItem.checked=localOnlyItem.checked && !isInstanceAkkoma();
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.joinmastodon.android.R;
|
||||
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.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
@@ -29,6 +30,7 @@ import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||
|
||||
public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
private AccountSession account;
|
||||
private boolean loggedOut;
|
||||
private HideableSingleViewRecyclerAdapter bannerAdapter;
|
||||
private Button updateButton1, updateButton2;
|
||||
@@ -47,23 +49,27 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
account = AccountSessionManager.get(accountID);
|
||||
setTitle(R.string.settings);
|
||||
setSubtitle(AccountSessionManager.get(accountID).getFullUsername());
|
||||
setSubtitle(account.getFullUsername());
|
||||
onDataLoaded(List.of(
|
||||
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_fluent_settings_24_regular, this::onBehaviorClick),
|
||||
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_fluent_color_24_regular, this::onDisplayClick),
|
||||
new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick),
|
||||
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_fluent_alert_24_regular, this::onNotificationsClick),
|
||||
new ListItem<>(R.string.sk_settings_instance, 0, R.drawable.ic_fluent_server_24_regular, this::onInstanceClick),
|
||||
new ListItem<>(getString(R.string.about_app, getString(R.string.sk_app_name)), null, R.drawable.ic_fluent_info_24_regular, this::onAboutClick, null, 0, true),
|
||||
new ListItem<>(R.string.log_out, 0, R.drawable.ic_fluent_sign_out_24_regular, this::onLogOutClick, R.attr.colorM3Error, false)
|
||||
));
|
||||
|
||||
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(account.domain);
|
||||
if (!instance.isAkkoma())
|
||||
data.add(2, new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick));
|
||||
|
||||
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
|
||||
data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_fluent_wrench_screwdriver_24_regular, ()->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
||||
}
|
||||
|
||||
AccountSessionManager.get(accountID).reloadPreferences(null);
|
||||
account.reloadPreferences(null);
|
||||
E.register(this);
|
||||
}
|
||||
|
||||
@@ -80,7 +86,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
if(!loggedOut)
|
||||
AccountSessionManager.get(accountID).savePreferencesIfPending();
|
||||
account.savePreferencesIfPending();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,7 +153,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setMessage(getString(R.string.confirm_log_out, session.getFullUsername()))
|
||||
.setPositiveButton(R.string.log_out, (dialog, which)->AccountSessionManager.get(accountID).logOut(getActivity(), ()->{
|
||||
.setPositiveButton(R.string.log_out, (dialog, which)->account.logOut(getActivity(), ()->{
|
||||
loggedOut=true;
|
||||
getActivity().finish();
|
||||
Intent intent=new Intent(getActivity(), MainActivity.class);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import static org.unifiedpush.android.connector.UnifiedPush.getDistributor;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Intent;
|
||||
@@ -25,8 +27,11 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.unifiedpush.android.connector.RegistrationDialogContent;
|
||||
import org.unifiedpush.android.connector.UnifiedPush;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
@@ -52,7 +57,8 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
private boolean notificationsAllowed=true;
|
||||
|
||||
// MEGALODON
|
||||
private CheckableListItem<Void> uniformIconItem, deleteItem, onlyLatestItem;
|
||||
private boolean useUnifiedPush = false;
|
||||
private CheckableListItem<Void> uniformIconItem, deleteItem, onlyLatestItem, unifiedPushItem;
|
||||
private CheckableListItem<Void> postsItem, updateItem;
|
||||
|
||||
private AccountLocalPreferences lp;
|
||||
@@ -64,6 +70,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
lp=AccountSessionManager.get(accountID).getLocalPreferences();
|
||||
|
||||
getPushSubscription();
|
||||
useUnifiedPush=!getDistributor(getContext()).isEmpty();
|
||||
|
||||
onDataLoaded(List.of(
|
||||
pauseItem=new CheckableListItem<>(getString(R.string.pause_all_notifications), getPauseItemSubtitle(), CheckableListItem.Style.SWITCH, false, R.drawable.ic_fluent_alert_snooze_24_regular, ()->onPauseNotificationsClick(false)),
|
||||
@@ -79,9 +86,16 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
|
||||
uniformIconItem=new CheckableListItem<>(R.string.sk_settings_uniform_icon_for_notifications, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.uniformNotificationIcon, R.drawable.ic_ntf_logo, ()->toggleCheckableItem(uniformIconItem)),
|
||||
deleteItem=new CheckableListItem<>(R.string.sk_settings_enable_delete_notifications, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.enableDeleteNotifications, R.drawable.ic_fluent_mail_inbox_dismiss_24_regular, ()->toggleCheckableItem(deleteItem)),
|
||||
onlyLatestItem=new CheckableListItem<>(R.string.sk_settings_single_notification, 0, CheckableListItem.Style.SWITCH, lp.keepOnlyLatestNotification, R.drawable.ic_fluent_convert_range_24_regular, ()->toggleCheckableItem(onlyLatestItem), true)
|
||||
onlyLatestItem=new CheckableListItem<>(R.string.sk_settings_single_notification, 0, CheckableListItem.Style.SWITCH, lp.keepOnlyLatestNotification, R.drawable.ic_fluent_convert_range_24_regular, ()->toggleCheckableItem(onlyLatestItem), true),
|
||||
unifiedPushItem=new CheckableListItem<>(R.string.sk_settings_unifiedpush, 0, CheckableListItem.Style.SWITCH, useUnifiedPush, R.drawable.ic_fluent_alert_arrow_up_24_regular, this::onUnifiedPush, true)
|
||||
));
|
||||
|
||||
//only enable when distributors, who can receive notifications, are available
|
||||
unifiedPushItem.isEnabled=!UnifiedPush.getDistributors(getContext(), new ArrayList<>()).isEmpty();
|
||||
if (!unifiedPushItem.isEnabled) {
|
||||
unifiedPushItem.subtitleRes=R.string.sk_settings_unifiedpush_no_distributor_body;
|
||||
}
|
||||
|
||||
typeItems=List.of(mentionsItem, boostsItem, favoritesItem, followersItem, pollsItem, updateItem, postsItem);
|
||||
pauseItem.checkedChangeListener=checked->onPauseNotificationsClick(true);
|
||||
updatePolicyItem(null);
|
||||
@@ -312,4 +326,38 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
bannerAdapter.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onUnifiedPush(){
|
||||
if(getDistributor(getContext()).isEmpty()){
|
||||
List<String> distributors = UnifiedPush.getDistributors(getContext(), new ArrayList<>());
|
||||
showUnifiedPushRegisterDialog(distributors);
|
||||
return;
|
||||
}
|
||||
|
||||
UnifiedPush.unregisterApp(
|
||||
getContext(),
|
||||
accountID
|
||||
);
|
||||
|
||||
//re-register to fcm
|
||||
AccountSessionManager.getInstance().getAccount(accountID).getPushSubscriptionManager().registerAccountForPush(getPushSubscription());
|
||||
unifiedPushItem.toggle();
|
||||
rebindItem(unifiedPushItem);
|
||||
}
|
||||
|
||||
private void showUnifiedPushRegisterDialog(List<String> distributors){
|
||||
new M3AlertDialogBuilder(getContext()).setTitle(R.string.sk_settings_unifiedpush_choose).setItems(distributors.toArray(String[]::new),
|
||||
(dialog, which) ->{
|
||||
String userDistrib = distributors.get(which);
|
||||
UnifiedPush.saveDistributor(getContext(), userDistrib);
|
||||
UnifiedPush.registerApp(
|
||||
getContext(),
|
||||
accountID,
|
||||
new ArrayList<>(),
|
||||
getContext().getPackageName()
|
||||
);
|
||||
unifiedPushItem.toggle();
|
||||
rebindItem(unifiedPushItem);
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -24,6 +25,7 @@ import android.widget.Toast;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIController;
|
||||
import org.joinmastodon.android.api.requests.instance.GetInstanceExtendedDescription;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.viewmodel.AccountViewModel;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
@@ -126,6 +128,8 @@ public class SettingsServerAboutFragment extends LoaderFragment{
|
||||
hlp.leftMargin=hlp.rightMargin=V.dp(16);
|
||||
scrollingLayout.addView(heading, hlp);
|
||||
|
||||
// if a remote instance is shown, the account is remote and need to be loaded accordingly when shown
|
||||
instance.contactAccount.isRemote=!AccountSessionManager.get(accountID).domain.equals(instance.normalizedUri);
|
||||
AccountViewModel model=new AccountViewModel(instance.contactAccount, accountID);
|
||||
AccountViewHolder holder=new AccountViewHolder(this, scrollingLayout, null);
|
||||
holder.setStyle(AccountViewHolder.AccessoryType.NONE, false);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
import org.parceler.Parcel;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Parcel
|
||||
@@ -20,6 +22,7 @@ public class Announcement extends BaseModel implements DisplayItemsParent {
|
||||
public Instant updatedAt;
|
||||
public boolean read;
|
||||
public List<Emoji> emojis;
|
||||
public List<EmojiReaction> reactions;
|
||||
public List<Mention> mentions;
|
||||
public List<Hashtag> tags;
|
||||
|
||||
@@ -41,10 +44,17 @@ public class Announcement extends BaseModel implements DisplayItemsParent {
|
||||
'}';
|
||||
}
|
||||
|
||||
public Status toStatus() {
|
||||
Status s = Status.ofFake(id, content, publishedAt);
|
||||
s.createdAt = startsAt != null ? startsAt : publishedAt;
|
||||
if (updatedAt != null) s.editedAt = updatedAt;
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
if(reactions==null) reactions=new ArrayList<>();
|
||||
}
|
||||
|
||||
public Status toStatus() {
|
||||
Status s=Status.ofFake(id, content, publishedAt);
|
||||
s.createdAt=startsAt != null ? startsAt : publishedAt;
|
||||
s.reactions=reactions;
|
||||
if(updatedAt != null) s.editedAt=updatedAt;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.joinmastodon.android.model;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@@ -45,26 +46,26 @@ public class Attachment extends BaseModel{
|
||||
|
||||
public int getWidth(){
|
||||
if(meta==null)
|
||||
return 1920;
|
||||
return 0;
|
||||
if(meta.width>0)
|
||||
return meta.width;
|
||||
if(meta.original!=null && meta.original.width>0)
|
||||
return meta.original.width;
|
||||
if(meta.small!=null && meta.small.width>0)
|
||||
return meta.small.width;
|
||||
return 1920;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getHeight(){
|
||||
if(meta==null)
|
||||
return 1080;
|
||||
return 0;
|
||||
if(meta.height>0)
|
||||
return meta.height;
|
||||
if(meta.original!=null && meta.original.height>0)
|
||||
return meta.original.height;
|
||||
if(meta.small!=null && meta.small.height>0)
|
||||
return meta.small.height;
|
||||
return 1080;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getDuration(){
|
||||
@@ -77,6 +78,13 @@ public class Attachment extends BaseModel{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean hasSound() {
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
retriever.setDataSource(url);
|
||||
String hasAudioStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO);
|
||||
return "yes".equals(hasAudioStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.parceler.Parcel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
@Parcel
|
||||
public class EmojiReaction {
|
||||
public List<Account> accounts;
|
||||
public List<String> accountIds;
|
||||
public int count;
|
||||
public boolean me;
|
||||
public String name;
|
||||
public String url;
|
||||
public String staticUrl;
|
||||
|
||||
public transient ImageLoaderRequest request;
|
||||
|
||||
public static EmojiReaction of(Emoji info, Account me){
|
||||
EmojiReaction reaction=new EmojiReaction();
|
||||
reaction.me=true;
|
||||
reaction.count=1;
|
||||
reaction.name=info.shortcode;
|
||||
reaction.url=info.url;
|
||||
reaction.staticUrl=info.staticUrl;
|
||||
reaction.accounts=new ArrayList<>(Collections.singleton(me));
|
||||
reaction.accountIds=new ArrayList<>(Collections.singleton(me.id));
|
||||
reaction.request=new UrlImageLoaderRequest(info.url, V.sp(24), V.sp(24));
|
||||
return reaction;
|
||||
}
|
||||
|
||||
public static EmojiReaction of(String emoji, Account me){
|
||||
EmojiReaction reaction=new EmojiReaction();
|
||||
reaction.me=true;
|
||||
reaction.count=1;
|
||||
reaction.name=emoji;
|
||||
reaction.accounts=new ArrayList<>(Collections.singleton(me));
|
||||
reaction.accountIds=new ArrayList<>(Collections.singleton(me.id));
|
||||
return reaction;
|
||||
}
|
||||
|
||||
public void add(Account self){
|
||||
if(accounts==null) accounts=new ArrayList<>();
|
||||
if(accountIds==null) accountIds=new ArrayList<>();
|
||||
count++;
|
||||
me=true;
|
||||
accounts.add(self);
|
||||
accountIds.add(self.id);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ public class Instance extends BaseModel{
|
||||
ci.domain=uri;
|
||||
ci.normalizedDomain=IDN.toUnicode(uri);
|
||||
ci.description=Html.fromHtml(shortDescription).toString().trim();
|
||||
if(languages!=null && languages.size() > 0){
|
||||
if(languages!=null&&languages.size()>0){
|
||||
ci.language=languages.get(0);
|
||||
ci.languages=languages;
|
||||
}else{
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
@@ -20,6 +23,40 @@ public class PushNotification extends BaseModel{
|
||||
@RequiredField
|
||||
public String body;
|
||||
|
||||
public static PushNotification fromNotification(Context context, Notification notification){
|
||||
PushNotification pushNotification = new PushNotification();
|
||||
pushNotification.notificationType = switch(notification.type) {
|
||||
case FOLLOW -> PushNotification.Type.FOLLOW;
|
||||
case MENTION -> PushNotification.Type.MENTION;
|
||||
case REBLOG -> PushNotification.Type.REBLOG;
|
||||
case FAVORITE -> PushNotification.Type.FAVORITE;
|
||||
case POLL -> PushNotification.Type.POLL;
|
||||
case STATUS -> PushNotification.Type.STATUS;
|
||||
case UPDATE -> PushNotification.Type.UPDATE;
|
||||
case SIGN_UP -> PushNotification.Type.SIGN_UP;
|
||||
case REPORT -> PushNotification.Type.REPORT;
|
||||
//Follow request, and reactions are not supported by the API
|
||||
default -> throw new IllegalStateException("Unexpected value: "+notification.type);
|
||||
};
|
||||
|
||||
String notificationTitle = context.getString(switch(notification.type){
|
||||
case FOLLOW -> R.string.user_followed_you;
|
||||
case MENTION -> R.string.sk_notification_mention;
|
||||
case REBLOG -> R.string.notification_boosted;
|
||||
case FAVORITE -> R.string.user_favorited;
|
||||
case POLL -> R.string.poll_ended;
|
||||
case UPDATE -> R.string.sk_post_edited;
|
||||
case SIGN_UP -> R.string.sk_signed_up;
|
||||
case REPORT -> R.string.sk_reported;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+notification.type);
|
||||
});
|
||||
|
||||
pushNotification.title = UiUtils.generateFormattedString(notificationTitle, notification.account.displayName).toString();
|
||||
pushNotification.icon = notification.status.account.avatarStatic;
|
||||
pushNotification.body = notification.status.getStrippedText();
|
||||
return pushNotification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "PushNotification{"+
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.parceler.Parcel;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Parcel
|
||||
@@ -74,6 +75,9 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
|
||||
public Status quote; // can be boolean in calckey
|
||||
|
||||
public List<EmojiReaction> reactions;
|
||||
protected List<EmojiReaction> emojiReactions; // akkoma
|
||||
|
||||
public transient boolean filterRevealed;
|
||||
public transient boolean spoilerRevealed;
|
||||
public transient boolean sensitiveRevealed;
|
||||
@@ -96,7 +100,7 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
t.postprocess();
|
||||
for(Emoji e:emojis)
|
||||
e.postprocess();
|
||||
if (mediaAttachments == null) mediaAttachments = List.of();
|
||||
if (mediaAttachments == null) mediaAttachments=List.of();
|
||||
for(Attachment a:mediaAttachments)
|
||||
a.postprocess();
|
||||
account.postprocess();
|
||||
@@ -110,10 +114,12 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
for(FilterResult fr:filtered)
|
||||
fr.postprocess();
|
||||
|
||||
if (!TextUtils.isEmpty(spoilerText)) sensitive = true;
|
||||
if(!TextUtils.isEmpty(spoilerText)) sensitive=true;
|
||||
spoilerRevealed=TextUtils.isEmpty(spoilerText);
|
||||
sensitiveRevealed=!sensitive;
|
||||
if (visibility.equals(StatusPrivacy.LOCAL)) localOnly = true;
|
||||
if(visibility.equals(StatusPrivacy.LOCAL)) localOnly=true;
|
||||
if(emojiReactions!=null) reactions=emojiReactions;
|
||||
if(reactions==null) reactions=new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,6 +175,7 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
reblogged=ev.reblogged;
|
||||
bookmarked=ev.bookmarked;
|
||||
pinned=ev.pinned;
|
||||
reactions=ev.reactions;
|
||||
}
|
||||
|
||||
public Status getContentStatus(){
|
||||
@@ -194,17 +201,18 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
}
|
||||
|
||||
public static Status ofFake(String id, String text, Instant createdAt) {
|
||||
Status s = new Status();
|
||||
s.id = id;
|
||||
s.mediaAttachments = List.of();
|
||||
s.createdAt = createdAt;
|
||||
s.content = s.text = text;
|
||||
s.spoilerText = "";
|
||||
s.visibility = StatusPrivacy.PUBLIC;
|
||||
s.mentions = List.of();
|
||||
s.tags = List.of();
|
||||
s.emojis = List.of();
|
||||
s.filtered = List.of();
|
||||
Status s=new Status();
|
||||
s.id=id;
|
||||
s.mediaAttachments=List.of();
|
||||
s.createdAt=createdAt;
|
||||
s.content=s.text=text;
|
||||
s.spoilerText="";
|
||||
s.visibility=StatusPrivacy.PUBLIC;
|
||||
s.reactions=List.of();
|
||||
s.mentions=List.of();
|
||||
s.tags =List.of();
|
||||
s.emojis=List.of();
|
||||
s.filtered=List.of();
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -216,21 +224,21 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
public static class StatusDeserializer implements JsonDeserializer<Status> {
|
||||
@Override
|
||||
public Status deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObject obj = json.getAsJsonObject();
|
||||
JsonObject obj=json.getAsJsonObject();
|
||||
|
||||
Status quote = null;
|
||||
Status quote=null;
|
||||
if (obj.has("quote") && obj.get("quote").isJsonObject())
|
||||
quote = gson.fromJson(obj.get("quote"), Status.class);
|
||||
quote=gson.fromJson(obj.get("quote"), Status.class);
|
||||
obj.remove("quote");
|
||||
|
||||
Status reblog = null;
|
||||
Status reblog=null;
|
||||
if (obj.has("reblog"))
|
||||
reblog = gson.fromJson(obj.get("reblog"), Status.class);
|
||||
reblog=gson.fromJson(obj.get("reblog"), Status.class);
|
||||
obj.remove("reblog");
|
||||
|
||||
Status status = gsonWithoutDeserializer.fromJson(json, Status.class);
|
||||
status.quote = quote;
|
||||
status.reblog = reblog;
|
||||
Status status=gsonWithoutDeserializer.fromJson(json, Status.class);
|
||||
status.quote=quote;
|
||||
status.reblog=reblog;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,18 +3,17 @@ package org.joinmastodon.android.ui.displayitems;
|
||||
import android.content.Context;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Space;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class InsetDummyStatusDisplayItem extends StatusDisplayItem {
|
||||
private final boolean addMediaGridMargin;
|
||||
public class DummyStatusDisplayItem extends StatusDisplayItem {
|
||||
|
||||
public InsetDummyStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, boolean addMediaGridMargin) {
|
||||
public DummyStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment) {
|
||||
super(parentID, parentFragment);
|
||||
this.addMediaGridMargin = addMediaGridMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -22,20 +21,22 @@ public class InsetDummyStatusDisplayItem extends StatusDisplayItem {
|
||||
return Type.DUMMY;
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<InsetDummyStatusDisplayItem> {
|
||||
public static class Holder extends StatusDisplayItem.Holder<DummyStatusDisplayItem> {
|
||||
private final RecyclerView.LayoutParams params;
|
||||
|
||||
public Holder(Context context) {
|
||||
super(new Space(context));
|
||||
}
|
||||
params=new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
|
||||
|
||||
@Override
|
||||
public void onBind(InsetDummyStatusDisplayItem item) {
|
||||
// BetterItemAnimator appears not to handle InsetStatusItemDecoration's getItemOffsets
|
||||
// correctly, causing removed inset views to jump while animating. i don't quite
|
||||
// understand it, but this workaround appears to work.
|
||||
// see InsetStatusItemDecoration#getItemOffsets
|
||||
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
|
||||
params.setMargins(0, item.addMediaGridMargin ? V.dp(4) : 0, 0, V.dp(16));
|
||||
params.setMargins(0, 0, 0, V.dp(16));
|
||||
itemView.setLayoutParams(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(DummyStatusDisplayItem item) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.requests.announcements.AddAnnouncementReaction;
|
||||
import org.joinmastodon.android.api.requests.announcements.DeleteAnnouncementReaction;
|
||||
import org.joinmastodon.android.api.requests.statuses.AddStatusReaction;
|
||||
import org.joinmastodon.android.api.requests.statuses.DeleteStatusReaction;
|
||||
import org.joinmastodon.android.api.requests.statuses.PleromaAddStatusReaction;
|
||||
import org.joinmastodon.android.api.requests.statuses.PleromaDeleteStatusReaction;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.account_list.StatusEmojiReactionsListFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Announcement;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.EmojiReaction;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.CustomEmojiPopupKeyboard;
|
||||
import org.joinmastodon.android.ui.utils.TextDrawable;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.ProgressBarButton;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.ListImageLoaderWrapper;
|
||||
import me.grishka.appkit.imageloader.RecyclerViewDelegate;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.BindableViewHolder;
|
||||
import me.grishka.appkit.utils.V;
|
||||
import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
|
||||
public final Status status;
|
||||
private final Drawable placeholder;
|
||||
private final boolean hideAdd, forAnnouncement;
|
||||
private final String accountID;
|
||||
private boolean hidden;
|
||||
|
||||
public EmojiReactionsStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, String accountID, boolean hideAdd, boolean forAnnouncement) {
|
||||
super(parentID, parentFragment);
|
||||
this.status=status;
|
||||
this.hideAdd=hideAdd;
|
||||
this.forAnnouncement=forAnnouncement;
|
||||
this.accountID=accountID;
|
||||
placeholder=parentFragment.getContext().getDrawable(R.drawable.image_placeholder).mutate();
|
||||
placeholder.setBounds(0, 0, V.sp(24), V.sp(24));
|
||||
updateHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageCount(){
|
||||
return (int) status.reactions.stream().filter(r->r.url != null).count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
return status.reactions.get(index).request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType(){
|
||||
return Type.EMOJI_REACTIONS;
|
||||
}
|
||||
|
||||
public boolean isHidden(){
|
||||
return hidden;
|
||||
}
|
||||
|
||||
private void updateHidden(){
|
||||
hidden=status.reactions.isEmpty() && hideAdd;
|
||||
}
|
||||
|
||||
// borrowed from ProfileFragment
|
||||
private void setActionProgressVisible(Holder.EmojiReactionViewHolder vh, boolean visible){
|
||||
if(vh==null) return;
|
||||
vh.progress.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
if(visible)
|
||||
vh.progress.setIndeterminateTintList(vh.btn.getTextColors());
|
||||
vh.btn.setClickable(!visible);
|
||||
}
|
||||
|
||||
private MastodonAPIRequest<?> createRequest(String name, int count, boolean delete, Holder.EmojiReactionViewHolder vh, Runnable cb){
|
||||
setActionProgressVisible(vh, true);
|
||||
boolean ak=parentFragment.isInstanceAkkoma();
|
||||
boolean keepSpinning=delete && count == 1;
|
||||
if(forAnnouncement){
|
||||
MastodonAPIRequest<Object> req=delete
|
||||
? new DeleteAnnouncementReaction(status.id, name)
|
||||
: new AddAnnouncementReaction(status.id, name);
|
||||
return req.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Object result){
|
||||
if(!keepSpinning) setActionProgressVisible(vh, false);
|
||||
cb.run();
|
||||
}
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
setActionProgressVisible(vh, false);
|
||||
error.showToast(parentFragment.getContext());
|
||||
}
|
||||
});
|
||||
}else{
|
||||
MastodonAPIRequest<Status> req=delete
|
||||
? (ak ? new PleromaDeleteStatusReaction(status.id, name) : new DeleteStatusReaction(status.id, name))
|
||||
: (ak ? new PleromaAddStatusReaction(status.id, name) : new AddStatusReaction(status.id, name));
|
||||
return req.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Status result){
|
||||
if(!keepSpinning) setActionProgressVisible(vh, false);
|
||||
cb.run();
|
||||
}
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
setActionProgressVisible(vh, false);
|
||||
error.showToast(parentFragment.getContext());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<EmojiReactionsStatusDisplayItem> implements ImageLoaderViewHolder, CustomEmojiPopupKeyboard.Listener {
|
||||
private final UsableRecyclerView list;
|
||||
private final LinearLayout root, line;
|
||||
private CustomEmojiPopupKeyboard emojiKeyboard;
|
||||
private final View space;
|
||||
private final ImageButton addButton;
|
||||
private final EmojiReactionsAdapter adapter;
|
||||
private final ListImageLoaderWrapper imgLoader;
|
||||
|
||||
public Holder(Activity activity, ViewGroup parent) {
|
||||
super(activity, R.layout.display_item_emoji_reactions, parent);
|
||||
root=(LinearLayout) itemView;
|
||||
line=findViewById(R.id.line);
|
||||
list=findViewById(R.id.list);
|
||||
imgLoader=new ListImageLoaderWrapper(activity, list, new RecyclerViewDelegate(list), null);
|
||||
list.setAdapter(adapter=new EmojiReactionsAdapter(this, imgLoader));
|
||||
addButton=findViewById(R.id.add_btn);
|
||||
addButton.setOnClickListener(this::onReactClick);
|
||||
space=findViewById(R.id.space);
|
||||
list.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(EmojiReactionsStatusDisplayItem item) {
|
||||
if(emojiKeyboard != null) root.removeView(emojiKeyboard.getView());
|
||||
AccountSession session=item.parentFragment.getSession();
|
||||
item.status.reactions.forEach(r->
|
||||
r.request=r.url != null ? new UrlImageLoaderRequest(r.url, V.sp(24), V.sp(24)) : null);
|
||||
emojiKeyboard=new CustomEmojiPopupKeyboard(
|
||||
(Activity) item.parentFragment.getContext(),
|
||||
AccountSessionManager.getInstance().getCustomEmojis(session.domain),
|
||||
session.domain, true);
|
||||
emojiKeyboard.setListener(this);
|
||||
space.setVisibility(View.GONE);
|
||||
root.addView(emojiKeyboard.getView());
|
||||
item.updateHidden();
|
||||
root.setVisibility(item.hidden ? View.GONE : View.VISIBLE);
|
||||
line.setVisibility(item.hidden ? View.GONE : View.VISIBLE);
|
||||
line.setPadding(
|
||||
list.getPaddingLeft(),
|
||||
item.hidden ? 0 : V.dp(8),
|
||||
list.getPaddingRight(),
|
||||
item.forAnnouncement ? V.dp(8) : 0
|
||||
);
|
||||
imgLoader.updateImages();
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void hideEmojiKeyboard(){
|
||||
space.setVisibility(View.GONE);
|
||||
addButton.setSelected(false);
|
||||
if(emojiKeyboard.isVisible()) emojiKeyboard.toggleKeyboardPopup(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiSelected(Emoji emoji) {
|
||||
addEmojiReaction(emoji.shortcode, emoji);
|
||||
hideEmojiKeyboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiSelected(String emoji){
|
||||
addEmojiReaction(emoji, null);
|
||||
hideEmojiKeyboard();
|
||||
}
|
||||
|
||||
private void addEmojiReaction(String emoji, Emoji info) {
|
||||
if(item.status.reactions.stream().filter(r->r.name.equals(emoji) && r.me).findAny().isPresent()) return;
|
||||
|
||||
Account me=AccountSessionManager.get(item.accountID).self;
|
||||
EmojiReaction existing=null;
|
||||
for(int i=0; i<item.status.reactions.size(); i++){
|
||||
EmojiReaction r=item.status.reactions.get(i);
|
||||
if(r.name.equals(emoji)){
|
||||
existing=r;
|
||||
r.add(me);
|
||||
adapter.notifyItemChanged(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(existing==null){
|
||||
item.status.reactions.add(0, info!=null ? EmojiReaction.of(info, me) : EmojiReaction.of(emoji, me));
|
||||
adapter.notifyItemRangeInserted(0, 1);
|
||||
}
|
||||
E.post(new StatusCountersUpdatedEvent(item.status, adapter.parentHolder));
|
||||
item.createRequest(emoji, existing==null ? 1 : existing.count, false, null, ()->{}).exec(item.accountID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackspace() {}
|
||||
|
||||
private void onReactClick(View v){
|
||||
emojiKeyboard.toggleKeyboardPopup(null);
|
||||
v.setSelected(emojiKeyboard.isVisible());
|
||||
space.setVisibility(emojiKeyboard.isVisible() ? View.VISIBLE : View.GONE);
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
int[] locationOnScreen = new int[2];
|
||||
((Activity) v.getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
v.getLocationOnScreen(locationOnScreen);
|
||||
double fromScreenTop = (double) locationOnScreen[1] / displayMetrics.heightPixels;
|
||||
if (fromScreenTop > 0.75) {
|
||||
item.parentFragment.scrollBy(0, (int) (displayMetrics.heightPixels * 0.3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable image){
|
||||
View child=list.getChildAt(index);
|
||||
if(child==null) return;
|
||||
((EmojiReactionViewHolder) list.getChildViewHolder(child)).setImage(index, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
if(item.status.reactions.get(index).url==null) return;
|
||||
setImage(index, item.placeholder);
|
||||
}
|
||||
|
||||
private class EmojiReactionsAdapter extends UsableRecyclerView.Adapter<EmojiReactionViewHolder> implements ImageLoaderRecyclerAdapter{
|
||||
ListImageLoaderWrapper imgLoader;
|
||||
Holder parentHolder;
|
||||
|
||||
public EmojiReactionsAdapter(Holder parentHolder, ListImageLoaderWrapper imgLoader){
|
||||
super(imgLoader);
|
||||
this.parentHolder=parentHolder;
|
||||
this.imgLoader=imgLoader;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public EmojiReactionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
return new EmojiReactionViewHolder(parent.getContext(), list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(EmojiReactionViewHolder holder, int position){
|
||||
holder.bind(Pair.create(item, item.status.reactions.get(position)));
|
||||
super.onBindViewHolder(holder, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount(){
|
||||
return item.status.reactions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageCountForItem(int position){
|
||||
return item.status.reactions.get(position).url == null ? 0 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int position, int image){
|
||||
return item.status.reactions.get(position).request;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EmojiReactionViewHolder extends BindableViewHolder<Pair<EmojiReactionsStatusDisplayItem, EmojiReaction>> implements ImageLoaderViewHolder{
|
||||
private final ProgressBarButton btn;
|
||||
private final ProgressBar progress;
|
||||
|
||||
public EmojiReactionViewHolder(Context context, RecyclerView list){
|
||||
super(context, R.layout.item_emoji_reaction, list);
|
||||
btn=findViewById(R.id.btn);
|
||||
progress=findViewById(R.id.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable drawable){
|
||||
drawable.setBounds(0, 0, V.sp(24), V.sp(24));
|
||||
btn.setCompoundDrawablesRelative(drawable, null, null, null);
|
||||
if(drawable instanceof Animatable) ((Animatable) drawable).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
setImage(index, item.first.placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(Pair<EmojiReactionsStatusDisplayItem, EmojiReaction> item){
|
||||
item.first.setActionProgressVisible(this, false);
|
||||
EmojiReactionsStatusDisplayItem parent=item.first;
|
||||
EmojiReaction reaction=item.second;
|
||||
btn.setText(UiUtils.abbreviateNumber(reaction.count));
|
||||
btn.setContentDescription(reaction.name);
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) btn.setTooltipText(reaction.name);
|
||||
if(reaction.url==null){
|
||||
Paint p=new Paint();
|
||||
p.setTextSize(V.sp(18));
|
||||
TextDrawable drawable=new TextDrawable(p, reaction.name);
|
||||
btn.setCompoundDrawablesRelative(drawable, null, null, null);
|
||||
}else{
|
||||
btn.setCompoundDrawablesRelative(item.first.placeholder, null, null, null);
|
||||
}
|
||||
btn.setSelected(reaction.me);
|
||||
btn.setOnClickListener(e->{
|
||||
boolean deleting=reaction.me;
|
||||
parent.createRequest(reaction.name, reaction.count, deleting, this, ()->{
|
||||
EmojiReactionsAdapter adapter = (EmojiReactionsAdapter) getBindingAdapter();
|
||||
for(int i=0; i<parent.status.reactions.size(); i++){
|
||||
EmojiReaction r=parent.status.reactions.get(i);
|
||||
if(!r.name.equals(reaction.name)) continue;
|
||||
if(deleting && r.count==1) {
|
||||
parent.status.reactions.remove(i);
|
||||
adapter.notifyItemRemoved(i);
|
||||
break;
|
||||
}
|
||||
r.me=!deleting;
|
||||
if(deleting) r.count--;
|
||||
else r.count++;
|
||||
adapter.notifyItemChanged(i);
|
||||
break;
|
||||
}
|
||||
|
||||
E.post(new StatusCountersUpdatedEvent(parent.status, adapter.parentHolder));
|
||||
adapter.parentHolder.imgLoader.updateImages();
|
||||
}).exec(parent.parentFragment.getAccountID());
|
||||
});
|
||||
|
||||
if (parent.parentFragment.isInstanceAkkoma()) {
|
||||
// glitch-soc doesn't have this, afaik
|
||||
btn.setOnLongClickListener(e->{
|
||||
EmojiReaction emojiReaction=parent.status.reactions.get(getAbsoluteAdapterPosition());
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", parent.parentFragment.getAccountID());
|
||||
args.putString("statusID", parent.status.id);
|
||||
int atSymbolIndex = emojiReaction.name.indexOf("@");
|
||||
args.putString("emoji", atSymbolIndex != -1 ? emojiReaction.name.substring(0, atSymbolIndex) : emojiReaction.name);
|
||||
args.putString("url", emojiReaction.url);
|
||||
args.putInt("count", emojiReaction.count);
|
||||
Nav.go(parent.parentFragment.getActivity(), StatusEmojiReactionsListFragment.class, args);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,18 +77,21 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
}
|
||||
};
|
||||
|
||||
private static final float ALPHA_PRESSED=0.55f;
|
||||
|
||||
static {
|
||||
opacityOut = new AlphaAnimation(1, 0.55f);
|
||||
opacityOut = new AlphaAnimation(1, ALPHA_PRESSED);
|
||||
opacityOut.setDuration(300);
|
||||
opacityOut.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
opacityOut.setFillAfter(true);
|
||||
opacityIn = new AlphaAnimation(0.55f, 1);
|
||||
opacityIn = new AlphaAnimation(ALPHA_PRESSED, 1);
|
||||
opacityIn.setDuration(400);
|
||||
opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
}
|
||||
|
||||
public Holder(Activity activity, ViewGroup parent){
|
||||
super(activity, R.layout.display_item_footer, parent);
|
||||
|
||||
replies=findViewById(R.id.reply);
|
||||
boosts=findViewById(R.id.boost);
|
||||
favorites=findViewById(R.id.favorite);
|
||||
|
||||
@@ -171,7 +171,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
optionsMenu=new PopupMenu(activity, more);
|
||||
optionsMenu.inflate(R.menu.post);
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.P)
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.P && !UiUtils.isEMUI())
|
||||
optionsMenu.getMenu().setGroupDividerEnabled(true);
|
||||
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
||||
Account account=item.user;
|
||||
@@ -337,7 +337,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
|
||||
if(TextUtils.isEmpty(item.extraText)){
|
||||
if (item.status != null) {
|
||||
UiUtils.setExtraTextInfo(item.parentFragment.getContext(), extraText, pronouns, item.status.visibility==StatusPrivacy.DIRECT, item.status.localOnly || item.status.visibility==StatusPrivacy.LOCAL, item.status.account);
|
||||
boolean displayPronouns=item.parentFragment instanceof ThreadFragment ? GlobalUserPreferences.displayPronounsInThreads : GlobalUserPreferences.displayPronounsInTimelines;
|
||||
UiUtils.setExtraTextInfo(item.parentFragment.getContext(), extraText, pronouns, displayPronouns, item.status.visibility==StatusPrivacy.DIRECT, item.status.localOnly || item.status.visibility==StatusPrivacy.LOCAL, item.status.account);
|
||||
}
|
||||
}else{
|
||||
extraText.setVisibility(View.VISIBLE);
|
||||
|
||||
@@ -242,6 +242,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||
if(altTextAnimator!=null)
|
||||
altTextAnimator.cancel();
|
||||
// V.setVisibilityAnimated(hideSensitiveButton, View.GONE);
|
||||
V.cancelVisibilityAnimation(altTextWrapper);
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
int index=(Integer)v.getTag();
|
||||
altTextIndex=index;
|
||||
@@ -254,7 +255,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||
noAltText.setVisibility(!hasAltText && showNoAltIndicator ? View.VISIBLE : View.GONE);
|
||||
altText.setText(att.description);
|
||||
altTextWrapper.setVisibility(View.VISIBLE);
|
||||
altTextWrapper.setBackgroundResource(hasAltText ? R.drawable.bg_image_alt_overlay : R.drawable.bg_image_no_alt_overlay);
|
||||
altTextWrapper.setBackgroundResource(hasAltText ? R.drawable.bg_image_alt_text_overlay : R.drawable.bg_image_no_alt_overlay);
|
||||
altTextWrapper.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
|
||||
@Override
|
||||
public boolean onPreDraw(){
|
||||
@@ -317,6 +318,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||
altTextAnimator.cancel();
|
||||
|
||||
// V.setVisibilityAnimated(hideSensitiveButton, item.status.sensitive ? View.VISIBLE : View.GONE);
|
||||
V.cancelVisibilityAnimation(altTextWrapper);
|
||||
View btn=controllers.get(altTextIndex).btnsWrap;
|
||||
int i=0;
|
||||
for(MediaAttachmentViewController c:controllers){
|
||||
@@ -365,8 +367,8 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation){
|
||||
altTextAnimator=null;
|
||||
altTextWrapper.setVisibility(View.GONE);
|
||||
btn.setVisibility(View.VISIBLE);
|
||||
V.setVisibilityAnimated(altTextWrapper, View.GONE);
|
||||
V.setVisibilityAnimated(btn, View.VISIBLE);
|
||||
btn.setAlpha(1);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
private int iconEnd;
|
||||
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper(), fullTextEmojiHelper;
|
||||
private View.OnClickListener handleClick;
|
||||
boolean belowHeader, needBottomPadding;
|
||||
public boolean needBottomPadding;
|
||||
ReblogOrReplyLineStatusDisplayItem extra;
|
||||
CharSequence fullText;
|
||||
|
||||
@@ -131,7 +131,6 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
if (visibilityText != 0) text.setContentDescription(item.text + " (" + ctx.getString(visibilityText) + ")");
|
||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
||||
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
||||
text.setTextAppearance(item.belowHeader ? R.style.m3_label_large : R.style.m3_title_small);
|
||||
text.setCompoundDrawableTintList(text.getTextColors());
|
||||
}
|
||||
|
||||
@@ -141,10 +140,6 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
if (item.extra != null) bindLine(item.extra, extraText);
|
||||
extraText.setVisibility(item.extra == null ? View.GONE : View.VISIBLE);
|
||||
separator.setVisibility(item.extra == null ? View.GONE : View.VISIBLE);
|
||||
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.bottomMargin = item.belowHeader ? V.dp(-6) : V.dp(-12);
|
||||
params.topMargin = item.belowHeader ? V.dp(-6) : 0;
|
||||
itemView.setLayoutParams(params);
|
||||
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
|
||||
layoutLine();
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{
|
||||
itemView.getPaddingLeft(),
|
||||
itemView.getPaddingTop(),
|
||||
itemView.getPaddingRight(),
|
||||
item.inset || GlobalUserPreferences.spectatorMode ? itemView.getPaddingTop() : 0
|
||||
item.inset ? itemView.getPaddingTop() : 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.joinmastodon.android.ui.displayitems;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
@@ -17,6 +18,7 @@ import org.joinmastodon.android.fragments.HashtagTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.HomeTabFragment;
|
||||
import org.joinmastodon.android.fragments.ListTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ScheduledStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
@@ -25,12 +27,12 @@ import org.joinmastodon.android.model.LegacyFilter;
|
||||
import org.joinmastodon.android.model.FilterAction;
|
||||
import org.joinmastodon.android.model.FilterContext;
|
||||
import org.joinmastodon.android.model.FilterResult;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.Poll;
|
||||
import org.joinmastodon.android.model.ScheduledStatus;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.viewholders.AccountViewHolder;
|
||||
import org.joinmastodon.android.utils.StatusFilterPredicate;
|
||||
import org.parceler.Parcels;
|
||||
@@ -48,7 +50,7 @@ import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public abstract class StatusDisplayItem{
|
||||
public final String parentID;
|
||||
public final BaseStatusListFragment parentFragment;
|
||||
public final BaseStatusListFragment<?> parentFragment;
|
||||
public boolean inset;
|
||||
public int index;
|
||||
public boolean
|
||||
@@ -63,6 +65,7 @@ public abstract class StatusDisplayItem{
|
||||
public static final int FLAG_MEDIA_FORCE_HIDDEN=1 << 3;
|
||||
public static final int FLAG_NO_HEADER=1 << 4;
|
||||
public static final int FLAG_NO_TRANSLATE=1 << 5;
|
||||
public static final int FLAG_NO_EMOJI_REACTIONS=1 << 6;
|
||||
|
||||
public void setAncestryInfo(
|
||||
boolean hasDescendantNeighbor,
|
||||
@@ -76,7 +79,7 @@ public abstract class StatusDisplayItem{
|
||||
this.isDirectDescendant = isDirectDescendant;
|
||||
}
|
||||
|
||||
public StatusDisplayItem(String parentID, BaseStatusListFragment parentFragment){
|
||||
public StatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment){
|
||||
this.parentID=parentID;
|
||||
this.parentFragment=parentFragment;
|
||||
}
|
||||
@@ -101,6 +104,7 @@ public abstract class StatusDisplayItem{
|
||||
case POLL_OPTION -> new PollOptionStatusDisplayItem.Holder(activity, parent);
|
||||
case POLL_FOOTER -> new PollFooterStatusDisplayItem.Holder(activity, parent);
|
||||
case CARD -> new LinkCardStatusDisplayItem.Holder(activity, parent);
|
||||
case EMOJI_REACTIONS -> new EmojiReactionsStatusDisplayItem.Holder(activity, parent);
|
||||
case FOOTER -> new FooterStatusDisplayItem.Holder(activity, parent);
|
||||
case ACCOUNT_CARD -> new AccountCardStatusDisplayItem.Holder(activity, parent);
|
||||
case ACCOUNT -> new AccountStatusDisplayItem.Holder(new AccountViewHolder(parentFragment, parent, null));
|
||||
@@ -113,11 +117,11 @@ public abstract class StatusDisplayItem{
|
||||
case SPOILER, FILTER_SPOILER -> new SpoilerStatusDisplayItem.Holder(activity, parent, type);
|
||||
case SECTION_HEADER -> null; // new SectionHeaderStatusDisplayItem.Holder(activity, parent);
|
||||
case NOTIFICATION_HEADER -> new NotificationHeaderStatusDisplayItem.Holder(activity, parent);
|
||||
case DUMMY -> new InsetDummyStatusDisplayItem.Holder(activity);
|
||||
case DUMMY -> new DummyStatusDisplayItem.Holder(activity);
|
||||
};
|
||||
}
|
||||
|
||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, boolean disableTranslate, FilterContext filterContext) {
|
||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean showReactions, boolean addFooter, boolean disableTranslate, FilterContext filterContext) {
|
||||
int flags=0;
|
||||
if(inset)
|
||||
flags|=FLAG_INSET;
|
||||
@@ -125,6 +129,8 @@ public abstract class StatusDisplayItem{
|
||||
flags|=FLAG_NO_FOOTER;
|
||||
if (disableTranslate)
|
||||
flags|=FLAG_NO_TRANSLATE;
|
||||
if (!showReactions)
|
||||
flags|=FLAG_NO_EMOJI_REACTIONS;
|
||||
return buildItems(fragment, status, accountID, parentObject, knownAccounts, filterContext, flags);
|
||||
}
|
||||
|
||||
@@ -203,7 +209,7 @@ public abstract class StatusDisplayItem{
|
||||
items.add(replyLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if((flags & FLAG_CHECKABLE)!=0)
|
||||
items.add(header=new CheckableHeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null));
|
||||
else
|
||||
@@ -240,17 +246,26 @@ public abstract class StatusDisplayItem{
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasSpoiler=!TextUtils.isEmpty(statusForContent.spoilerText);
|
||||
if(!TextUtils.isEmpty(statusForContent.content)){
|
||||
SpannableStringBuilder parsedText=HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID);
|
||||
HtmlParser.applyFilterHighlights(fragment.getActivity(), parsedText, status.filtered);
|
||||
TextStatusDisplayItem text=new TextStatusDisplayItem(parentID, HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID), fragment, statusForContent, (flags & FLAG_NO_TRANSLATE) != 0);
|
||||
contentItems.add(text);
|
||||
} else if (header!=null){
|
||||
}else if(!hasSpoiler && header!=null){
|
||||
header.needBottomPadding=true;
|
||||
}else if(hasSpoiler){
|
||||
contentItems.add(new DummyStatusDisplayItem(parentID, fragment));
|
||||
}
|
||||
|
||||
List<Attachment> imageAttachments=statusForContent.mediaAttachments.stream().filter(att->att.type.isImage()).collect(Collectors.toList());
|
||||
if(!imageAttachments.isEmpty()){
|
||||
int color = UiUtils.getThemeColor(fragment.getContext(), R.attr.colorM3SurfaceVariant);
|
||||
for (Attachment att : imageAttachments) {
|
||||
if (att.blurhashPlaceholder == null) {
|
||||
att.blurhashPlaceholder = new ColorDrawable(color);
|
||||
}
|
||||
}
|
||||
PhotoLayoutHelper.TiledLayoutResult layout=PhotoLayoutHelper.processThumbs(imageAttachments);
|
||||
MediaGridStatusDisplayItem mediaGrid=new MediaGridStatusDisplayItem(parentID, fragment, layout, imageAttachments, statusForContent);
|
||||
if((flags & FLAG_MEDIA_FORCE_HIDDEN)!=0)
|
||||
@@ -276,8 +291,14 @@ public abstract class StatusDisplayItem{
|
||||
if(contentItems!=items && statusForContent.spoilerRevealed){
|
||||
items.addAll(contentItems);
|
||||
}
|
||||
if((flags & FLAG_NO_EMOJI_REACTIONS)==0
|
||||
&& AccountSessionManager.get(accountID).getLocalPreferences().emojiReactionsEnabled){
|
||||
boolean isMainStatus=fragment instanceof ThreadFragment t && t.getMainStatus().id.equals(statusForContent.id);
|
||||
items.add(new EmojiReactionsStatusDisplayItem(parentID, fragment, statusForContent, accountID, !isMainStatus, false));
|
||||
}
|
||||
FooterStatusDisplayItem footer=null;
|
||||
if((flags & FLAG_NO_FOOTER)==0){
|
||||
FooterStatusDisplayItem footer=new FooterStatusDisplayItem(parentID, fragment, statusForContent, accountID);
|
||||
footer=new FooterStatusDisplayItem(parentID, fragment, statusForContent, accountID);
|
||||
footer.hideCounts=hideCounts;
|
||||
items.add(footer);
|
||||
if(status.hasGapAfter && !(fragment instanceof ThreadFragment))
|
||||
@@ -286,10 +307,12 @@ public abstract class StatusDisplayItem{
|
||||
int i=1;
|
||||
boolean inset=(flags & FLAG_INSET)!=0;
|
||||
// add inset dummy so last content item doesn't clip out of inset bounds
|
||||
if (inset) {
|
||||
items.add(new InsetDummyStatusDisplayItem(parentID, fragment,
|
||||
!contentItems.isEmpty() && contentItems
|
||||
.get(contentItems.size() - 1) instanceof MediaGridStatusDisplayItem));
|
||||
if(inset || footer==null){
|
||||
items.add(new DummyStatusDisplayItem(parentID, fragment));
|
||||
// in case we ever need the dummy to display a margin for the media grid again:
|
||||
// (i forgot why we apparently don't need this anymore)
|
||||
// !contentItems.isEmpty() && contentItems
|
||||
// .get(contentItems.size() - 1) instanceof MediaGridStatusDisplayItem));
|
||||
}
|
||||
for(StatusDisplayItem item:items){
|
||||
item.inset=inset;
|
||||
@@ -330,6 +353,7 @@ public abstract class StatusDisplayItem{
|
||||
POLL_OPTION,
|
||||
POLL_FOOTER,
|
||||
CARD,
|
||||
EMOJI_REACTIONS,
|
||||
FOOTER,
|
||||
ACCOUNT_CARD,
|
||||
ACCOUNT,
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.joinmastodon.android.api.requests.statuses.TranslateStatus;
|
||||
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.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
@@ -31,6 +32,8 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.LinkedTextView;
|
||||
import org.joinmastodon.android.utils.StatusTextEncoder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -194,12 +197,23 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
readMore.setText(item.status.textExpanded ? R.string.sk_collapse : R.string.sk_expand);
|
||||
|
||||
// remove additional padding when (transparently padded) translate button is visible
|
||||
int nextPos = getAbsoluteAdapterPosition() + 1;
|
||||
boolean nextIsFooter = item.parentFragment.getDisplayItems().size() > nextPos &&
|
||||
item.parentFragment.getDisplayItems().get(nextPos) instanceof FooterStatusDisplayItem;
|
||||
int bottomPadding = (translateVisible && nextIsFooter) ? 0
|
||||
: nextIsFooter ? V.dp(6)
|
||||
: V.dp(12);
|
||||
int nextPos=getAbsoluteAdapterPosition() + 1;
|
||||
int bottomPadding=V.dp(12);
|
||||
List<StatusDisplayItem> displayItems=item.parentFragment.getDisplayItems();
|
||||
if(displayItems.size() > nextPos){
|
||||
StatusDisplayItem next=displayItems.get(nextPos);
|
||||
if(next instanceof EmojiReactionsStatusDisplayItem e && e.isHidden()){
|
||||
next=displayItems.size() > ++nextPos ? displayItems.get(nextPos) : null;
|
||||
}
|
||||
|
||||
if(next instanceof FooterStatusDisplayItem){
|
||||
bottomPadding=V.dp(6);
|
||||
// why does java code always end up looking like this
|
||||
} else if((!item.inset && next instanceof DummyStatusDisplayItem) ||
|
||||
next instanceof EmojiReactionsStatusDisplayItem e && !e.isHidden()){
|
||||
bottomPadding=0;
|
||||
}
|
||||
}
|
||||
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), bottomPadding);
|
||||
|
||||
if (!GlobalUserPreferences.collapseLongPosts) {
|
||||
@@ -235,7 +249,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
// compensate for spoiler's bottom margin
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) itemView.getLayoutParams();
|
||||
params.setMargins(params.leftMargin, (item.inset || GlobalUserPreferences.spectatorMode) && hasSpoiler ? V.dp(-16) : 0,
|
||||
params.setMargins(params.leftMargin, item.inset && hasSpoiler ? V.dp(-16) : 0,
|
||||
params.rightMargin, params.bottomMargin);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,11 +99,15 @@ public class BlurhashCrossfadeDrawable extends Drawable{
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth(){
|
||||
if(width==0)
|
||||
return imageDrawable==null ? 1920 : imageDrawable.getIntrinsicWidth();
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight(){
|
||||
if(height==0)
|
||||
return imageDrawable==null ? 1080 : imageDrawable.getIntrinsicHeight();
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.Toolbar;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIController;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
@@ -418,7 +419,8 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
WindowManager.LayoutParams wlp=(WindowManager.LayoutParams) windowView.getLayoutParams();
|
||||
wlp.flags|=WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
wm.updateViewLayout(windowView, wlp);
|
||||
activity.getSystemService(AudioManager.class).requestAudioFocus(audioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
||||
int audiofocus = GlobalUserPreferences.overlayMedia ? AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK : AudioManager.AUDIOFOCUS_GAIN;
|
||||
activity.getSystemService(AudioManager.class).requestAudioFocus(audioFocusListener, AudioManager.STREAM_MUSIC, audiofocus);
|
||||
}
|
||||
screenOnRefCount++;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
|
||||
|
||||
public InsetStatusItemDecoration(BaseStatusListFragment<?> listFragment){
|
||||
this.listFragment=listFragment;
|
||||
bgColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3SurfaceVariant);
|
||||
bgColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3Surface);
|
||||
borderColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3OutlineVariant);
|
||||
}
|
||||
|
||||
@@ -65,13 +65,13 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
|
||||
paint.setColor(bgColor);
|
||||
rect.left=V.dp(12);
|
||||
rect.right=list.getWidth()-V.dp(12);
|
||||
rect.inset(V.dp(4), V.dp(4));
|
||||
c.drawRoundRect(rect, V.dp(4), V.dp(4), paint);
|
||||
rect.inset(V.dp(4), V.dp(0));
|
||||
c.drawRoundRect(rect, V.dp(12), V.dp(12), paint);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(V.dp(1));
|
||||
paint.setColor(borderColor);
|
||||
rect.inset(paint.getStrokeWidth()/2f, paint.getStrokeWidth()/2f);
|
||||
c.drawRoundRect(rect, V.dp(4), V.dp(4), paint);
|
||||
c.drawRoundRect(rect, V.dp(12), V.dp(12), paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,10 +85,10 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
|
||||
boolean topSiblingInset=pos>0 && displayItems.get(pos-1).inset;
|
||||
boolean bottomSiblingInset=pos<displayItems.size()-1 && displayItems.get(pos+1).inset;
|
||||
int pad;
|
||||
if(holder instanceof MediaGridStatusDisplayItem.Holder || holder instanceof LinkCardStatusDisplayItem.Holder)
|
||||
// if(holder instanceof MediaGridStatusDisplayItem.Holder || holder instanceof LinkCardStatusDisplayItem.Holder)
|
||||
pad=V.dp(16);
|
||||
else
|
||||
pad=V.dp(12);
|
||||
// else
|
||||
// pad=V.dp(12);
|
||||
boolean insetLeft=true, insetRight=true;
|
||||
if(insetLeft)
|
||||
outRect.left=pad;
|
||||
@@ -97,7 +97,7 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
|
||||
|
||||
// had to comment this out because animations with offsets aren't handled properly.
|
||||
// can be worked around by manually applying top margins to items
|
||||
// see InsetDummyStatusDisplayItem#onBinds
|
||||
// see InsetDummyStatusDisplayItem#onBind
|
||||
// if(!topSiblingInset)
|
||||
// outRect.top=pad;
|
||||
// if(!bottomSiblingInset)
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
package org.joinmastodon.android.ui.utils;
|
||||
|
||||
/*
|
||||
* Copyright 2016 Ali Muzaffar
|
||||
* <p/>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class TextDrawable extends Drawable implements TextWatcher {
|
||||
private WeakReference<TextView> ref;
|
||||
private String mText;
|
||||
private Paint mPaint;
|
||||
private Rect mHeightBounds;
|
||||
private boolean mBindToViewPaint = false;
|
||||
private float mPrevTextSize = 0;
|
||||
private boolean mInitFitText = false;
|
||||
private boolean mFitTextEnabled = false;
|
||||
|
||||
/**
|
||||
* Create a TextDrawable using the given paint object and string
|
||||
*
|
||||
* @param paint
|
||||
* @param s
|
||||
*/
|
||||
public TextDrawable(Paint paint, String s) {
|
||||
mText = s;
|
||||
mPaint = new Paint(paint);
|
||||
mHeightBounds = new Rect();
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TextDrawable. This uses the given TextView to initialize paint and has initial text
|
||||
* that will be drawn. Initial text can also be useful for reserving space that may otherwise
|
||||
* not be available when setting compound drawables.
|
||||
*
|
||||
* @param tv The TextView / EditText using to initialize this drawable
|
||||
* @param initialText Optional initial text to display
|
||||
* @param bindToViewsText Should this drawable mirror the text in the TextView
|
||||
* @param bindToViewsPaint Should this drawable mirror changes to Paint in the TextView, like textColor, typeface, alpha etc.
|
||||
* Note, this will override any changes made using setColorFilter or setAlpha.
|
||||
*/
|
||||
public TextDrawable(TextView tv, String initialText, boolean bindToViewsText, boolean bindToViewsPaint) {
|
||||
this(tv.getPaint(), initialText);
|
||||
ref = new WeakReference<>(tv);
|
||||
if (bindToViewsText || bindToViewsPaint) {
|
||||
if (bindToViewsText) {
|
||||
tv.addTextChangedListener(this);
|
||||
}
|
||||
mBindToViewPaint = bindToViewsPaint;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TextDrawable. This uses the given TextView to initialize paint and the text that
|
||||
* will be drawn.
|
||||
*
|
||||
* @param tv The TextView / EditText using to initialize this drawable
|
||||
* @param bindToViewsText Should this drawable mirror the text in the TextView
|
||||
* @param bindToViewsPaint Should this drawable mirror changes to Paint in the TextView, like textColor, typeface, alpha etc.
|
||||
* Note, this will override any changes made using setColorFilter or setAlpha.
|
||||
*/
|
||||
public TextDrawable(TextView tv, boolean bindToViewsText, boolean bindToViewsPaint) {
|
||||
this(tv, tv.getText().toString(), bindToViewsText, bindToViewsPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided TextView/EditText to initialize the drawable.
|
||||
* The Drawable will copy the Text and the Paint properties, however it will from that
|
||||
* point on be independant of the TextView.
|
||||
*
|
||||
* @param tv a TextView or EditText or any of their children.
|
||||
*/
|
||||
public TextDrawable(TextView tv) {
|
||||
this(tv, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided TextView/EditText to initialize the drawable.
|
||||
* The Drawable will copy the Paint properties, and use the provided text to initialise itself.
|
||||
*
|
||||
* @param tv a TextView or EditText or any of their children.
|
||||
* @param s The String to draw
|
||||
*/
|
||||
public TextDrawable(TextView tv, String s) {
|
||||
this(tv, s, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (mBindToViewPaint && ref.get() != null) {
|
||||
Paint p = ref.get().getPaint();
|
||||
canvas.drawText(mText, 0, getBounds().height(), p);
|
||||
} else {
|
||||
if (mInitFitText) {
|
||||
fitTextAndInit();
|
||||
}
|
||||
canvas.drawText(mText, 0, getBounds().height(), mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
mPaint.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
int alpha = mPaint.getAlpha();
|
||||
if (alpha == 0) {
|
||||
return PixelFormat.TRANSPARENT;
|
||||
} else if (alpha == 255) {
|
||||
return PixelFormat.OPAQUE;
|
||||
} else {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Rect bounds = getBounds();
|
||||
//We want to use some character to determine the max height of the text.
|
||||
//Otherwise if we draw something like "..." they will appear centered
|
||||
//Here I'm just going to use the entire alphabet to determine max height.
|
||||
mPaint.getTextBounds("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 0, 1, mHeightBounds);
|
||||
//This doesn't account for leading or training white spaces.
|
||||
//mPaint.getTextBounds(mText, 0, mText.length(), bounds);
|
||||
float width = mPaint.measureText(mText);
|
||||
bounds.top = mHeightBounds.top;
|
||||
bounds.bottom = mHeightBounds.bottom;
|
||||
bounds.right = (int) width;
|
||||
bounds.left = 0;
|
||||
setBounds(bounds);
|
||||
}
|
||||
|
||||
public void setPaint(Paint paint) {
|
||||
mPaint = new Paint(paint);
|
||||
//Since this can change the font used, we need to recalculate bounds.
|
||||
if (mFitTextEnabled && !mInitFitText) {
|
||||
fitTextAndInit();
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
public Paint getPaint() {
|
||||
return mPaint;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
mText = text;
|
||||
//Since this can change the bounds of the text, we need to recalculate.
|
||||
if (mFitTextEnabled && !mInitFitText) {
|
||||
fitTextAndInit();
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return mText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
setText(s.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the TextDrawable match the width of the View it's associated with.
|
||||
* <p/>
|
||||
* Note: While this option will not work if bindToViewPaint is true.
|
||||
*
|
||||
* @param fitText
|
||||
*/
|
||||
public void setFillText(boolean fitText) {
|
||||
mFitTextEnabled = fitText;
|
||||
if (fitText) {
|
||||
mPrevTextSize = mPaint.getTextSize();
|
||||
if (ref.get() != null) {
|
||||
if (ref.get().getWidth() > 0) {
|
||||
fitTextAndInit();
|
||||
} else {
|
||||
mInitFitText = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mPrevTextSize > 0) {
|
||||
mPaint.setTextSize(mPrevTextSize);
|
||||
}
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
private void fitTextAndInit() {
|
||||
float fitWidth = ref.get().getWidth();
|
||||
float textWidth = mPaint.measureText(mText);
|
||||
float multi = fitWidth / textWidth;
|
||||
mPaint.setTextSize(mPaint.getTextSize() * multi);
|
||||
mInitFitText = false;
|
||||
init();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,9 @@ import android.transition.TransitionManager;
|
||||
import android.transition.TransitionSet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
@@ -73,6 +75,7 @@ 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.instance.GetInstance;
|
||||
import org.joinmastodon.android.api.requests.lists.DeleteList;
|
||||
import org.joinmastodon.android.api.requests.notifications.DismissNotification;
|
||||
import org.joinmastodon.android.api.requests.search.GetSearchResults;
|
||||
@@ -93,6 +96,8 @@ import org.joinmastodon.android.fragments.ComposeFragment;
|
||||
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.fragments.settings.SettingsServerAboutFragment;
|
||||
import org.joinmastodon.android.fragments.settings.SettingsServerFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.AccountField;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
@@ -103,7 +108,6 @@ import org.joinmastodon.android.model.ScheduledStatus;
|
||||
import org.joinmastodon.android.model.SearchResults;
|
||||
import org.joinmastodon.android.model.Searchable;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
@@ -115,6 +119,7 @@ import java.lang.reflect.Method;
|
||||
import java.net.IDN;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
@@ -132,6 +137,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
@@ -528,31 +534,70 @@ public class UiUtils {
|
||||
.exec(accountID);
|
||||
});
|
||||
}
|
||||
public static void confirmToggleMuteUser(Context context, String accountID, Account account, boolean currentlyMuted, Consumer<Relationship> resultCallback){
|
||||
View durationView=LayoutInflater.from(context).inflate(R.layout.mute_user_dialog, null);
|
||||
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.setMargins(0, V.dp(-12), 0, 0);
|
||||
durationView.setLayoutParams(params);
|
||||
Button button=durationView.findViewById(R.id.button);
|
||||
((TextView) durationView.findViewById(R.id.message)).setText(context.getString(R.string.confirm_mute, account.displayName));
|
||||
|
||||
public static void confirmToggleMuteUser(Activity activity, String accountID, Account account, boolean currentlyMuted, Consumer<Relationship> resultCallback) {
|
||||
showConfirmationAlert(activity, activity.getString(currentlyMuted ? R.string.confirm_unmute_title : R.string.confirm_mute_title),
|
||||
activity.getString(currentlyMuted ? R.string.confirm_unmute : R.string.confirm_mute, account.displayName),
|
||||
activity.getString(currentlyMuted ? R.string.do_unmute : R.string.do_mute),
|
||||
currentlyMuted ? R.drawable.ic_fluent_speaker_0_28_regular : R.drawable.ic_fluent_speaker_off_28_regular,
|
||||
() -> {
|
||||
new SetAccountMuted(account.id, !currentlyMuted)
|
||||
.setCallback(new Callback<>() {
|
||||
AtomicReference<Duration> muteDuration=new AtomicReference<>(Duration.ZERO);
|
||||
|
||||
PopupMenu popupMenu=new PopupMenu(context, button, Gravity.CENTER_HORIZONTAL);
|
||||
popupMenu.inflate(R.menu.mute_duration);
|
||||
popupMenu.setOnMenuItemClickListener(item->{
|
||||
int id=item.getItemId();
|
||||
if(id==R.id.duration_indefinite)
|
||||
muteDuration.set(Duration.ZERO);
|
||||
else if(id==R.id.duration_minutes_5){
|
||||
muteDuration.set(Duration.ofMinutes(5));
|
||||
}else if(id==R.id.duration_minutes_30){
|
||||
muteDuration.set(Duration.ofMinutes(30));
|
||||
}else if(id==R.id.duration_hours_1){
|
||||
muteDuration.set(Duration.ofHours(1));
|
||||
}else if(id==R.id.duration_hours_6){
|
||||
muteDuration.set(Duration.ofHours(6));
|
||||
}else if(id==R.id.duration_days_1){
|
||||
muteDuration.set(Duration.ofDays(1));
|
||||
}else if(id==R.id.duration_days_3){
|
||||
muteDuration.set(Duration.ofDays(3));
|
||||
}else if(id==R.id.duration_days_7){
|
||||
muteDuration.set(Duration.ofDays(7));
|
||||
}
|
||||
button.setText(item.getTitle());
|
||||
return true;
|
||||
});
|
||||
button.setOnTouchListener(popupMenu.getDragToOpenListener());
|
||||
button.setOnClickListener(v->popupMenu.show());
|
||||
button.setText(popupMenu.getMenu().getItem(0).getTitle());
|
||||
|
||||
new M3AlertDialogBuilder(context)
|
||||
.setTitle(context.getString(currentlyMuted ? R.string.confirm_unmute_title : R.string.confirm_mute_title))
|
||||
.setMessage(currentlyMuted ? context.getString(R.string.confirm_unmute, account.displayName) : null)
|
||||
.setView(currentlyMuted ? null : durationView)
|
||||
.setPositiveButton(context.getString(currentlyMuted ? R.string.do_unmute : R.string.do_mute), (dlg, i)->{
|
||||
new SetAccountMuted(account.id, !currentlyMuted, muteDuration.get().getSeconds())
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result) {
|
||||
public void onSuccess(Relationship result){
|
||||
resultCallback.accept(result);
|
||||
if (!currentlyMuted) {
|
||||
if(!currentlyMuted){
|
||||
E.post(new RemoveAccountPostsEvent(accountID, account.id, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
error.showToast(activity);
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(context);
|
||||
}
|
||||
})
|
||||
.wrapProgress(activity, R.string.loading, false)
|
||||
.wrapProgress(context, R.string.loading, false)
|
||||
.exec(accountID);
|
||||
});
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setIcon(currentlyMuted ? R.drawable.ic_fluent_speaker_0_28_regular : R.drawable.ic_fluent_speaker_off_28_regular)
|
||||
.show();
|
||||
}
|
||||
|
||||
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback) {
|
||||
@@ -1028,13 +1073,11 @@ public class UiUtils {
|
||||
return back;
|
||||
}
|
||||
|
||||
public static boolean setExtraTextInfo(Context ctx, TextView extraText, TextView pronouns, boolean mentionedOnly, boolean localOnly, @Nullable Account account) {
|
||||
public static boolean setExtraTextInfo(Context ctx, TextView extraText, TextView pronouns, boolean displayPronouns, boolean mentionedOnly, boolean localOnly, @Nullable Account account) {
|
||||
List<String> extraParts = new ArrayList<>();
|
||||
Optional<String> p=pronouns==null ? Optional.empty() : extractPronouns(ctx, account);
|
||||
boolean setPronouns=false;
|
||||
Optional<String> p=pronouns==null || !displayPronouns ? Optional.empty() : extractPronouns(ctx, account);
|
||||
if(p.isPresent()) {
|
||||
HtmlParser.setTextWithCustomEmoji(pronouns, p.get(), account.emojis);
|
||||
setPronouns=true;
|
||||
pronouns.setVisibility(View.VISIBLE);
|
||||
}else if(pronouns!=null){
|
||||
pronouns.setVisibility(View.GONE);
|
||||
@@ -1241,6 +1284,23 @@ public class UiUtils {
|
||||
}
|
||||
})
|
||||
.exec(accountID));
|
||||
} else if (uri.getPath() != null && uri.getPath().matches("^/about$")) {
|
||||
return Optional.of(new GetInstance()
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Instance result){
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable("instance", Parcels.wrap(result));
|
||||
args.putString("account", accountID);
|
||||
go.accept(SettingsServerFragment.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
go.accept(null, bundleError(error));
|
||||
}
|
||||
})
|
||||
.execNoAuth(uri.getHost()));
|
||||
} else if (looksLikeFediverseUrl(url)) {
|
||||
return Optional.of(new GetSearchResults(url, null, true)
|
||||
.setCallback(new Callback<>() {
|
||||
@@ -1586,7 +1646,7 @@ public class UiUtils {
|
||||
private static String extractPronounsFromField(String localizedPronouns, AccountField field) {
|
||||
if(!field.name.toLowerCase().contains(localizedPronouns) &&
|
||||
!field.name.toLowerCase().contains("pronouns")) return null;
|
||||
String text=HtmlParser.strip(field.value);
|
||||
String text=HtmlParser.text(field.value);
|
||||
if(field.value.toLowerCase().contains("https://")){
|
||||
for(String pronounUrl : pronounsUrls){
|
||||
int index=text.indexOf(pronounUrl);
|
||||
|
||||
@@ -74,10 +74,17 @@ public class ComposePollViewController{
|
||||
pollWrap=view.findViewById(R.id.poll_wrap);
|
||||
|
||||
Instance instance=fragment.instance;
|
||||
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
|
||||
maxPollOptions=instance.configuration.polls.maxOptions;
|
||||
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
|
||||
maxPollOptionLength=instance.configuration.polls.maxCharactersPerOption;
|
||||
if (!instance.isAkkoma()) {
|
||||
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
|
||||
maxPollOptions=instance.configuration.polls.maxOptions;
|
||||
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
|
||||
maxPollOptionLength=instance.configuration.polls.maxCharactersPerOption;
|
||||
} else {
|
||||
if (instance.pollLimits!=null && instance.pollLimits.maxOptions>0)
|
||||
maxPollOptions=instance.pollLimits.maxOptions;
|
||||
if(instance.pollLimits!=null && instance.pollLimits.maxOptionChars>0)
|
||||
maxPollOptionLength=instance.pollLimits.maxOptionChars;
|
||||
}
|
||||
|
||||
pollOptionsView=pollWrap.findViewById(R.id.poll_options);
|
||||
addPollOptionBtn=pollWrap.findViewById(R.id.add_poll_option);
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.widget.ProgressBar;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
@@ -124,7 +125,8 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
|
||||
}
|
||||
|
||||
// you know what's cooler than followers or verified links? yep. pronouns
|
||||
Optional<String> pronounsString = UiUtils.extractPronouns(itemView.getContext(), item.account);
|
||||
Optional<String> pronounsString=GlobalUserPreferences.displayPronounsInUserListings
|
||||
? UiUtils.extractPronouns(itemView.getContext(), item.account) : Optional.empty();
|
||||
pronouns.setVisibility(pronounsString.isPresent() ? View.VISIBLE : View.GONE);
|
||||
pronounsString.ifPresent(p -> HtmlParser.setTextWithCustomEmoji(pronouns, p, item.account.emojis));
|
||||
|
||||
@@ -188,7 +190,10 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
|
||||
}
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelable("profileAccount", Parcels.wrap(item.account));
|
||||
if (item.account.isRemote)
|
||||
args.putParcelable("remoteAccount", Parcels.wrap(item.account));
|
||||
else
|
||||
args.putParcelable("profileAccount", Parcels.wrap(item.account));
|
||||
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public class EmojiReactionsRecyclerView extends UsableRecyclerView{
|
||||
public EmojiReactionsRecyclerView(Context context){
|
||||
super(context);
|
||||
}
|
||||
|
||||
public EmojiReactionsRecyclerView(Context context, AttributeSet attrs){
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public EmojiReactionsRecyclerView(Context context, AttributeSet attrs, int defStyle){
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e){
|
||||
super.onTouchEvent(e);
|
||||
// to pass through touch events (i.e. clicking the status) to the parent view
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/55372837/is-there-a-way-to-make-recyclerview-requiresfadingedge-unaffected-by-paddingtop
|
||||
@Override
|
||||
protected boolean isPaddingOffsetRequired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLeftPaddingOffset(){
|
||||
return -getPaddingLeft();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRightPaddingOffset() {
|
||||
return getPaddingRight();
|
||||
}
|
||||
}
|
||||
6
mastodon/src/main/res/color/m3_on_surface_selector.xml
Normal file
6
mastodon/src/main/res/color/m3_on_surface_selector.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?colorM3OnSurfaceVariant" android:state_enabled="false" />
|
||||
<item android:color="?colorM3OnSurfaceVariant" android:state_selected="false" />
|
||||
<item android:color="?colorM3OnSurface" />
|
||||
</selector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:pathData="M63.26,36.4C67.49,37.02 71.06,40.24 71.61,44.32C71.85,46.75 71.73,50.4 71.67,52.17C71.65,52.61 71.64,52.94 71.64,53.1C71.64,53.34 71.61,55.51 71.6,55.74C71.22,61.58 67.58,63.88 63.75,64.62C63.7,64.63 63.66,64.64 63.61,64.65C63.6,64.65 63.58,64.65 63.57,64.65C61.14,65.13 58.54,65.25 56.07,65.32C55.48,65.34 54.89,65.34 54.3,65.34C51.85,65.34 49.4,65.05 47.01,64.47C47,64.47 46.99,64.47 46.97,64.47C46.96,64.48 46.95,64.48 46.94,64.49C46.93,64.5 46.92,64.51 46.92,64.52C46.91,64.53 46.91,64.55 46.91,64.56C46.98,65.33 47.14,66.1 47.41,66.83C47.74,67.68 48.9,69.71 53.19,69.71C55.69,69.71 58.17,69.42 60.6,68.84C60.61,68.84 60.63,68.84 60.64,68.84C60.65,68.85 60.66,68.85 60.67,68.86C60.68,68.87 60.69,68.88 60.7,68.89C60.7,68.9 60.7,68.91 60.7,68.93V71.79C60.7,71.8 60.7,71.82 60.69,71.83C60.69,71.84 60.68,71.85 60.67,71.86C59.91,72.41 58.89,72.73 58,73.01C57.96,73.02 57.91,73.04 57.88,73.05C57.47,73.18 57.06,73.29 56.64,73.39C52.85,74.25 48.9,74.04 45.22,72.79C41.79,71.58 38.28,68.64 37.42,65.1C36.95,63.18 36.63,61.23 36.44,59.27C36.25,57.12 36.18,54.97 36.11,52.82C36.09,52.01 36.06,51.2 36.03,50.38C35.95,48.32 36,46.06 36.44,44.03C37.35,39.89 41.1,37 45.21,36.4C45.3,36.38 45.39,36.37 45.5,36.35C46.31,36.21 48.01,35.91 53.53,35.91H53.58C59.84,35.91 62.55,36.29 63.26,36.4ZM65.39,58.94V48.84C65.39,46.78 64.86,45.14 63.81,43.93C62.71,42.72 61.29,42.09 59.51,42.09C57.47,42.09 55.92,42.88 54.88,44.45L53.88,46.12L52.88,44.45C51.85,42.88 50.3,42.09 48.25,42.09C46.47,42.09 45.05,42.72 43.96,43.93C42.9,45.14 42.37,46.78 42.37,48.84V58.94H46.38V49.14C46.38,47.08 47.25,46.03 48.99,46.03C50.92,46.03 51.89,47.27 51.89,49.73V55.09H55.87V49.73C55.87,47.27 56.84,46.03 58.76,46.03C60.52,46.03 61.38,47.08 61.38,49.14V58.94H65.39Z"
|
||||
android:fillColor="#4A454E"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#B2000000"/>
|
||||
<solid android:color="#69000000"/>
|
||||
<corners android:radius="4dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#D0000000"/>
|
||||
<corners android:radius="4dp"/>
|
||||
</shape>
|
||||
@@ -1,21 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<ripple
|
||||
android:color="@color/m3_on_surface_variant_overlay"
|
||||
android:radius="42dp" />
|
||||
</item>
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<layer-list>
|
||||
<item android:gravity="center" android:width="28dp" android:height="28dp">
|
||||
<shape android:shape="oval">
|
||||
<stroke android:color="?colorM3OnSecondaryContainer" android:width="2dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true">
|
||||
<layer-list>
|
||||
<item android:gravity="center" android:width="28dp" android:height="28dp">
|
||||
<shape android:shape="oval">
|
||||
<stroke android:color="?colorM3OnSecondaryContainer" android:width="2dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
</layer-list>
|
||||
</item>
|
||||
</layer-list>
|
||||
</selector>
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/m3_on_surface_variant_overlay"
|
||||
android:radius="42dp" />
|
||||
android:radius="56dp" />
|
||||
@@ -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:fillColor="@android:color/white"
|
||||
android:pathData="M4,15V13H20V15ZM4,11V9H20V11Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,12 @@
|
||||
<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,1.996C16.05,1.996 19.357,5.191 19.496,9.245L19.5,9.496V13.593L20.88,16.749C20.949,16.907 20.985,17.077 20.985,17.25C20.985,17.94 20.425,18.5 19.735,18.5L15,18.501C15,20.158 13.657,21.501 12,21.501C10.402,21.501 9.096,20.252 9.005,18.678L9,18.499L4.275,18.5C4.104,18.5 3.934,18.465 3.777,18.396C3.144,18.121 2.853,17.385 3.128,16.752L4.5,13.594V9.496C4.501,5.341 7.852,1.996 12,1.996ZM13.5,18.499L10.5,18.501C10.5,19.33 11.172,20.001 12,20.001C12.78,20.001 13.421,19.406 13.493,18.646L13.5,18.499ZM12,3.496C8.68,3.496 6.001,6.17 6,9.496V13.906L4.656,17H19.353L18,13.907L18,9.509L17.997,9.284C17.885,6.05 15.242,3.496 12,3.496Z"
|
||||
android:fillColor="#212121"/>
|
||||
<path
|
||||
android:pathData="M8.083,9.969A0.508,0.508 0,0 0,8.807 10.682L11.494,7.955L11.494,14.897a0.508,0.508 0,1 0,1.016 0L12.509,7.958L15.193,10.682A0.508,0.508 45,0 0,15.917 9.969L12.452,6.453a0.635,0.635 0,0 0,-0.904 0z"
|
||||
android:fillColor="#212121"/>
|
||||
</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 2c-0.667 0-1.32 0.065-1.95 0.19-0.407 0.08-0.671 0.475-0.591 0.882 0.08 0.406 0.475 0.67 0.881 0.59C10.877 3.556 11.431 3.5 12 3.5s1.123 0.056 1.66 0.162c0.406 0.08 0.8-0.184 0.881-0.59 0.08-0.407-0.184-0.801-0.59-0.882C13.319 2.065 12.667 2 12 2zM7.278 4.931c0.344-0.23 0.436-0.696 0.206-1.04-0.23-0.344-0.697-0.437-1.04-0.206-1.09 0.73-2.03 1.668-2.76 2.758-0.23 0.345-0.137 0.81 0.207 1.04 0.344 0.231 0.81 0.139 1.04-0.205 0.621-0.927 1.42-1.726 2.347-2.347zm10.279-1.246c-0.345-0.23-0.81-0.138-1.04 0.206-0.231 0.344-0.139 0.81 0.205 1.04 0.927 0.621 1.726 1.42 2.347 2.347 0.23 0.344 0.696 0.436 1.04 0.206 0.344-0.23 0.437-0.697 0.206-1.04-0.73-1.09-1.668-2.03-2.758-2.76zm4.253 6.364c-0.08-0.406-0.475-0.67-0.882-0.59-0.406 0.08-0.67 0.475-0.59 0.881 0.106 0.537 0.162 1.091 0.162 1.66s-0.056 1.123-0.162 1.66c-0.08 0.406 0.184 0.8 0.59 0.881 0.407 0.08 0.801-0.184 0.882-0.59C21.935 13.319 22 12.667 22 12s-0.065-1.32-0.19-1.95zM3.662 10.34c0.08-0.406-0.184-0.8-0.59-0.881-0.407-0.08-0.801 0.184-0.882 0.59C2.065 10.681 2 11.333 2 12s0.065 1.32 0.19 1.95c0.08 0.407 0.475 0.671 0.882 0.591 0.406-0.08 0.67-0.475 0.59-0.881C3.556 13.123 3.5 12.569 3.5 12s0.056-1.123 0.162-1.66zm1.27 6.382C4.7 16.378 4.234 16.286 3.89 16.516s-0.437 0.697-0.206 1.04c0.73 1.09 1.668 2.03 2.758 2.76 0.345 0.23 0.81 0.137 1.04-0.207 0.231-0.344 0.139-0.81-0.205-1.04-0.927-0.621-1.726-1.42-2.347-2.347zm15.383 0.835c0.23-0.345 0.138-0.81-0.206-1.04-0.344-0.231-0.81-0.139-1.04 0.205-0.621 0.927-1.42 1.726-2.347 2.347-0.344 0.23-0.436 0.696-0.206 1.04 0.23 0.344 0.697 0.437 1.04 0.206 1.09-0.73 2.03-1.668 2.76-2.758zm-9.975 2.781c-0.406-0.08-0.8 0.184-0.881 0.59-0.08 0.407 0.184 0.801 0.59 0.882C10.681 21.935 11.333 22 12 22s1.32-0.065 1.95-0.19c0.407-0.08 0.671-0.475 0.591-0.882-0.08-0.406-0.475-0.67-0.881-0.59C13.123 20.444 12.569 20.5 12 20.5s-1.123-0.056-1.66-0.162zM9 9.248c0-0.952 1.023-1.554 1.856-1.093l5.757 3.186C16.852 11.473 17 11.724 17 11.997c0 0.272-0.148 0.523-0.387 0.655l-5.757 3.187C10.023 16.299 9 15.697 9 14.745V9.247z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -24,7 +24,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:textColor="?colorGray25"
|
||||
android:textColor="?colorM3DarkOnSurface"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:paddingHorizontal="6dp"
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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="wrap_content">
|
||||
<LinearLayout
|
||||
android:id="@+id/line"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/add_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:minHeight="48dp"
|
||||
android:minWidth="48dp"
|
||||
android:background="@drawable/bg_button_m3_tonal_circle"
|
||||
android:tooltipText="@string/sk_button_react"
|
||||
android:contentDescription="@string/sk_button_react"
|
||||
android:src="@drawable/ic_fluent_add_24_filled" />
|
||||
|
||||
<org.joinmastodon.android.ui.views.EmojiReactionsRecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="-4dp"
|
||||
android:paddingStart="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:requiresFadingEdge="horizontal"
|
||||
android:fadingEdgeLength="24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Space
|
||||
android:id="@+id/space"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -7,156 +7,171 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="11sp">
|
||||
<!-- avatar width (46sp) / 2 - button width (24sp) / 2 -->
|
||||
android:rowCount="2"
|
||||
android:columnCount="1">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/reply_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:src="@drawable/ic_fluent_chat_multiple_24_selector_text"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:gravity="center_vertical" />
|
||||
<TextView
|
||||
android:id="@+id/reply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:minWidth="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="123"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="11sp">
|
||||
<!-- avatar width (46sp) / 2 - button width (24sp) / 2 -->
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/boost_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:foregroundTint="@color/boost_icon"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:src="@drawable/ic_boost"
|
||||
android:tint="@color/boost_icon"
|
||||
android:gravity="center_vertical" />
|
||||
<TextView
|
||||
android:id="@+id/boost"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:minWidth="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:textColor="@color/boost_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="123"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/favorite_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:src="@drawable/ic_fluent_star_24_selector"
|
||||
android:tint="@color/favorite_icon"
|
||||
android:gravity="center_vertical" />
|
||||
<TextView
|
||||
android:id="@+id/favorite"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:minWidth="16dp"
|
||||
android:textColor="@color/favorite_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="123"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<FrameLayout
|
||||
android:id="@+id/bookmark_btn"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/reply_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:src="@drawable/ic_fluent_chat_multiple_24_selector_text"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:gravity="center_vertical" />
|
||||
<TextView
|
||||
android:id="@+id/reply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:minWidth="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="123"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/boost_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:foregroundTint="@color/boost_icon"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:src="@drawable/ic_boost"
|
||||
android:tint="@color/boost_icon"
|
||||
android:gravity="center_vertical" />
|
||||
<TextView
|
||||
android:id="@+id/boost"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:minWidth="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:textColor="@color/boost_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="123"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/favorite_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:src="@drawable/ic_fluent_star_24_selector"
|
||||
android:tint="@color/favorite_icon"
|
||||
android:gravity="center_vertical" />
|
||||
<TextView
|
||||
android:id="@+id/favorite"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:minWidth="16dp"
|
||||
android:textColor="@color/favorite_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="123"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
<FrameLayout
|
||||
android:id="@+id/bookmark_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:id="@+id/bookmark"
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:src="@drawable/ic_fluent_bookmark_24_selector"
|
||||
android:tint="@color/bookmark_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/share_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:id="@+id/bookmark"
|
||||
android:id="@+id/share"
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:src="@drawable/ic_fluent_bookmark_24_selector"
|
||||
android:tint="@color/bookmark_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/m3_label_large" />
|
||||
android:src="@drawable/ic_fluent_share_24_regular"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:gravity="center_vertical"/>
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/share_btn"
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="12dp">
|
||||
<ImageView
|
||||
android:id="@+id/share"
|
||||
android:layout_width="24sp"
|
||||
android:layout_height="24sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:src="@drawable/ic_fluent_share_24_regular"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:gravity="center_vertical"/>
|
||||
</FrameLayout>
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/footer_emoji_keyboard_container"
|
||||
android:orientation="vertical">
|
||||
</LinearLayout>
|
||||
</GridLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</org.joinmastodon.android.ui.views.MaxWidthFrameLayout>
|
||||
@@ -33,7 +33,7 @@
|
||||
android:layout_marginEnd="4dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:textColor="#FFF"
|
||||
android:textColor="?colorM3DarkOnSurface"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:background="@drawable/bg_image_alt_overlay"
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:layout_marginBottom="-12dp">
|
||||
android:layout_marginBottom="-4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/extra_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
android:drawableStart="@drawable/ic_fluent_arrow_reply_20sp_filled"
|
||||
@@ -40,7 +39,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_filled"
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
android:layout_marginEnd="4dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:textColor="#FFF"
|
||||
android:textColor="?colorM3DarkOnSurface"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:background="@drawable/bg_image_alt_overlay"
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/avatar_border"
|
||||
android:layout_width="104dp"
|
||||
android:layout_height="104dp"
|
||||
android:layout_width="108dp"
|
||||
android:layout_height="108dp"
|
||||
android:layout_below="@id/cover"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginStart="12dp"
|
||||
@@ -67,8 +67,8 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="96dp"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/profile_picture"
|
||||
android:scaleType="centerCrop"
|
||||
|
||||
27
mastodon/src/main/res/layout/item_emoji_reaction.xml
Normal file
27
mastodon/src/main/res/layout/item_emoji_reaction.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="8dp"
|
||||
tools:ignore="RtlSymmetry">
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:elevation="10dp"
|
||||
android:indeterminate="true"
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone"/>
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/btn"
|
||||
style="@style/Widget.Mastodon.M3.Button.Outlined.Icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTint="@null"
|
||||
android:drawableStart="@drawable/image_placeholder"
|
||||
android:background="@drawable/bg_button_m3_tonal"/>
|
||||
</FrameLayout>
|
||||
47
mastodon/src/main/res/layout/mute_user_dialog.xml
Normal file
47
mastodon/src/main/res/layout/mute_user_dialog.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?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="wrap_content"
|
||||
android:paddingHorizontal="24dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:text="@string/confirm_mute"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<org.joinmastodon.android.ui.views.AutoOrientationLinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layoutDirection="locale">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:text="@string/sk_mute_label"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
style="@style/Widget.Mastodon.M3.Button.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_button_m3_tonal"
|
||||
android:ellipsize="none"
|
||||
android:singleLine="true"
|
||||
android:stateListAnimator="@null"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -1,28 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout 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="wrap_content"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:clipToPadding="false"
|
||||
android:background="?colorM3Background">
|
||||
android:background="?colorM3Background"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dragger_thingy"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:scaleType="center"
|
||||
android:tint="?colorM3OnSurface"
|
||||
android:contentDescription="@string/reorder"
|
||||
android:src="@drawable/ic_drag_handle_24px"/>
|
||||
android:src="@drawable/ic_fluent_re_order_dots_vertical_24_regular"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/delete"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="8dp"
|
||||
android:scaleType="center"
|
||||
@@ -31,32 +32,37 @@
|
||||
android:contentDescription="@string/delete"
|
||||
android:src="@drawable/ic_fluent_delete_24_regular"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_toEndOf="@id/dragger_thingy"
|
||||
android:layout_toStartOf="@id/delete"
|
||||
style="@style/Widget.Mastodon.M3.EditText"
|
||||
android:inputType="textCapSentences"
|
||||
android:hint="@string/field_content"
|
||||
android:saveEnabled="false"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:layout_toEndOf="@id/dragger_thingy"
|
||||
android:layout_toStartOf="@id/delete"
|
||||
android:layout_below="@id/content"
|
||||
style="@style/Widget.Mastodon.M3.EditText"
|
||||
android:inputType="textCapSentences"
|
||||
android:hint="@string/field_label"
|
||||
android:saveEnabled="false"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/dragger_thingy"
|
||||
android:layout_toStartOf="@id/delete"
|
||||
android:layout_below="@id/title"
|
||||
style="@style/Widget.Mastodon.M3.EditText"
|
||||
android:inputType="textCapSentences"
|
||||
android:hint="@string/field_content"
|
||||
android:saveEnabled="false"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@id/content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="?colorM3SurfaceVariant"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -7,7 +7,7 @@
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_margin="12dp"
|
||||
android:importantForAccessibility="noHideDescendants"
|
||||
android:background="@drawable/bg_image_alt_overlay">
|
||||
android:background="@drawable/bg_image_alt_text_overlay">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/no_alt_button"
|
||||
@@ -22,7 +22,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:textColor="?colorGray25"
|
||||
android:textColor="?colorM3DarkOnSurface"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:paddingHorizontal="6dp"
|
||||
@@ -36,7 +36,7 @@
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="end|top"
|
||||
android:src="@drawable/ic_baseline_close_24"
|
||||
android:tint="#FFF"
|
||||
android:tint="?colorM3DarkOnSurface"
|
||||
android:background="?android:actionBarItemBackground"/>
|
||||
|
||||
<org.joinmastodon.android.ui.views.NestableScrollView
|
||||
@@ -58,7 +58,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:textAppearance="@style/m3_body_medium"
|
||||
android:textColor="#FFF"
|
||||
android:textColor="?colorM3DarkOnSurface"
|
||||
tools:text="Alt text goes here"/>
|
||||
|
||||
<TextView
|
||||
@@ -69,7 +69,7 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:textColor="?colorGray25"
|
||||
android:textColor="?colorM3DarkOnSurface"
|
||||
android:text="@string/sk_no_alt_text"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -12,110 +12,187 @@
|
||||
<org.joinmastodon.android.ui.views.TabBar
|
||||
android:id="@+id/tabbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp">
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingHorizontal="8dp">
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_home"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/home_timeline">
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_home_24_selector"/>
|
||||
<FrameLayout
|
||||
android:id="@+id/tab_home_pill"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/home_timeline">
|
||||
|
||||
</FrameLayout>
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_home_24_selector"/>
|
||||
|
||||
<FrameLayout
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tab_home_label"
|
||||
style="@style/m3_label_medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/m3_on_surface_selector"
|
||||
android:text="@string/sk_tab_home" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_search"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/search_hint">
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_search_24_selector"/>
|
||||
<FrameLayout
|
||||
android:id="@+id/tab_search_pill"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/search_hint">
|
||||
|
||||
</FrameLayout>
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_search_24_selector"/>
|
||||
|
||||
<RelativeLayout
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tab_search_label"
|
||||
style="@style/m3_label_medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/m3_on_surface_selector"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/sk_tab_search" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_notifications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/notifications">
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/tab_notifications_pill"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/notifications">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/notifications_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_alert_24_selector"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notifications_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_alignTop="@id/notifications_icon"
|
||||
android:layout_toEndOf="@id/notifications_icon"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:layout_marginStart="-12dp"
|
||||
android:background="@drawable/bg_tabbar_badge"
|
||||
android:textColor="?colorM3OnPrimary"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:textAppearance="@style/m3_label_small"
|
||||
android:minWidth="16dp"
|
||||
tools:text="222"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/notifications_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_alert_24_selector"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notifications_badge"
|
||||
android:id="@+id/tab_notifications_label"
|
||||
style="@style/m3_label_medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_alignTop="@id/notifications_icon"
|
||||
android:layout_toEndOf="@id/notifications_icon"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:layout_marginStart="-12dp"
|
||||
android:background="@drawable/bg_tabbar_badge"
|
||||
android:textColor="?colorM3OnPrimary"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:textAppearance="@style/m3_label_small"
|
||||
android:minWidth="16dp"
|
||||
tools:text="222"/>
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/m3_on_surface_selector"
|
||||
android:text="@string/sk_tab_notifications" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_profile"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/my_profile">
|
||||
<ImageView
|
||||
android:id="@+id/tab_profile_ava"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@null"/>
|
||||
<ImageView
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="22dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:scaleType="center"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_chevron_up_down_16_regular"/>
|
||||
</FrameLayout>
|
||||
android:layout_marginEnd="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/tab_profile_pill"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/bg_tabbar_tab"
|
||||
android:contentDescription="@string/my_profile">
|
||||
<ImageView
|
||||
android:id="@+id/tab_profile_ava"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@null"/>
|
||||
<ImageView
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="22dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:scaleType="center"
|
||||
android:tint="@color/tab_bar_icon"
|
||||
android:src="@drawable/ic_fluent_chevron_up_down_16_regular"/>
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tab_profile_label"
|
||||
style="@style/m3_label_medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/m3_on_surface_selector"
|
||||
android:text="@string/sk_tab_profile" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</org.joinmastodon.android.ui.views.TabBar>
|
||||
|
||||
</FrameLayout>
|
||||
11
mastodon/src/main/res/menu/mute_duration.xml
Normal file
11
mastodon/src/main/res/menu/mute_duration.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/duration_indefinite" android:title="@string/sk_duration_indefinite" />
|
||||
<item android:id="@+id/duration_minutes_5" android:title="@string/sk_duration_minutes_5"/>
|
||||
<item android:id="@+id/duration_minutes_30" android:title="@string/sk_duration_minutes_30"/>
|
||||
<item android:id="@+id/duration_hours_1" android:title="@string/sk_duration_hours_1"/>
|
||||
<item android:id="@+id/duration_hours_6" android:title="@string/sk_duration_hours_6"/>
|
||||
<item android:id="@+id/duration_days_1" android:title="@string/sk_duration_days_1"/>
|
||||
<item android:id="@+id/duration_days_3" android:title="@string/sk_duration_days_3"/>
|
||||
<item android:id="@+id/duration_days_7" android:title="@string/sk_duration_days_7"/>
|
||||
</menu>
|
||||
@@ -4,11 +4,18 @@
|
||||
<string name="next">التالي</string>
|
||||
<string name="loading_instance">جارٍ جلب معلومات الخادم…</string>
|
||||
<string name="error">خطأ</string>
|
||||
<string name="not_a_mastodon_instance">لا يبدو أنّ %s كخادم ماستدون.</string>
|
||||
<string name="ok">حسنًا</string>
|
||||
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
||||
<string name="finishing_auth">يُنهي المصادقة…</string>
|
||||
<string name="user_boosted">%s إعادة نشر</string>
|
||||
<string name="in_reply_to">ردًا على %s</string>
|
||||
<string name="notifications">الإشعارات</string>
|
||||
<string name="user_followed_you">%s بَدَأ بِمُتابَعَتِك</string>
|
||||
<string name="user_sent_follow_request">%s أرسَلَ طَلَبًا لِمُتابَعَتِك</string>
|
||||
<string name="user_favorited">%s أعجَبه منشورك</string>
|
||||
<string name="notification_boosted">قام %s بإعادة نشر منشورك</string>
|
||||
<string name="poll_ended">الاطلاع على نتائج استطلاع الرأي الذي صوّت فيه</string>
|
||||
<string name="share_toot_title">شارك</string>
|
||||
<string name="settings">الإعدادات</string>
|
||||
<string name="publish">انشر</string>
|
||||
@@ -37,7 +44,8 @@
|
||||
<string name="profile_about">حَول</string>
|
||||
<string name="button_follow">تابِع</string>
|
||||
<string name="button_following">مُتابَع</string>
|
||||
<string name="edit_profile">حرّر الملف الشخصي</string>
|
||||
<string name="edit_profile">تعديل الملف الشخصي</string>
|
||||
<string name="share_user">شارك الصفحة الشخصية</string>
|
||||
<string name="mute_user">كَتمُ %s</string>
|
||||
<string name="unmute_user">إلغاء الكَتم عن @%s</string>
|
||||
<string name="block_user">حَظرُ %s</string>
|
||||
@@ -117,8 +125,16 @@
|
||||
<item quantity="many">تبقى %d يومًا</item>
|
||||
<item quantity="other">تبقى %d يوم</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">انتهى</string>
|
||||
<string name="confirm_mute_title">اكتم الحساب</string>
|
||||
<plurals name="x_votes">
|
||||
<item quantity="zero">%,d صوت</item>
|
||||
<item quantity="one">%,d صوت واحد</item>
|
||||
<item quantity="two">صوتين</item>
|
||||
<item quantity="few">%,d أصوات</item>
|
||||
<item quantity="many">%,d صوتا</item>
|
||||
<item quantity="other">%,d صوتا</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">مغلق</string>
|
||||
<string name="confirm_mute_title">كتم الحساب</string>
|
||||
<string name="confirm_mute">أكّد كتم %s</string>
|
||||
<string name="do_mute">اكتم</string>
|
||||
<string name="confirm_unmute_title">ارفع الكتم عن الحساب</string>
|
||||
@@ -135,17 +151,20 @@
|
||||
<string name="button_blocked">محجوب</string>
|
||||
<string name="action_vote">صَوّت</string>
|
||||
<string name="delete">احذف</string>
|
||||
<string name="confirm_delete_title">احذف المنشور</string>
|
||||
<string name="confirm_delete">أمتأكد من حذف هذا المنشور؟</string>
|
||||
<string name="deleting">يحذف…</string>
|
||||
<string name="notification_channel_audio_player">تشغيل الصوت</string>
|
||||
<string name="play">شغّل</string>
|
||||
<string name="pause">ألبث</string>
|
||||
<string name="log_out">الخروج</string>
|
||||
<string name="add_account">أضف حساباً</string>
|
||||
<string name="search_hint">ابحث</string>
|
||||
<string name="hashtags">وُسُوم</string>
|
||||
<string name="news">الأخبار</string>
|
||||
<string name="for_you">لأجلك</string>
|
||||
<string name="mentions">الذِكر</string>
|
||||
<string name="all_notifications">كلها</string>
|
||||
<string name="mentions">الإشارات</string>
|
||||
<plurals name="x_people_talking">
|
||||
<item quantity="zero">لا أحد يتحدث</item>
|
||||
<item quantity="one">شخص واحد يتحدث</item>
|
||||
@@ -155,11 +174,16 @@
|
||||
<item quantity="other">%d شخص يتحدثون</item>
|
||||
</plurals>
|
||||
<string name="report_title">بلّغ عن %s</string>
|
||||
<string name="report_choose_reason">ما المُشكِلَةُ فِي هَذَا المَنشُور؟</string>
|
||||
<string name="report_choose_reason_account">ما المُشكِلَة مَعَ %s؟</string>
|
||||
<string name="report_choose_reason_subtitle">اختر أفضل تطابق</string>
|
||||
<string name="report_reason_personal">لا يعجبني</string>
|
||||
<string name="report_reason_personal_subtitle">ألا ترغب برؤيته</string>
|
||||
<string name="report_reason_spam">إنه غير مرغوب فيه</string>
|
||||
<string name="report_reason_spam_subtitle">روابط خبيثة أو تفاعل كاذب أو ردود متكررة</string>
|
||||
<string name="report_reason_violation">ينتهك قواعد الخادم</string>
|
||||
<string name="report_reason_violation_subtitle">تعلم أنه ينتهك قواعد محددة</string>
|
||||
<string name="report_reason_other">إنَّهُ شَيءٌ آخَر</string>
|
||||
<string name="report_reason_other_subtitle">لا تندرج هذه المشكلة ضمن فئات أخرى</string>
|
||||
<string name="report_choose_rule">ما هي القواعد المنتهكة؟</string>
|
||||
<string name="report_choose_rule_subtitle">اختر كل ما ينطبق</string>
|
||||
@@ -168,8 +192,14 @@
|
||||
<string name="report_comment_title">هل لديك شيء آخر لتخبرنا به؟</string>
|
||||
<string name="report_comment_hint">تعليقات إضافية</string>
|
||||
<string name="sending_report">يرسل البلاغ…</string>
|
||||
<string name="report_sent_title">شُكرًا لَكَ على الإبلاغ، سَوفَ نتحرى عن الأمر.</string>
|
||||
<string name="report_sent_subtitle">في أثناء مراجعتنا للبلاغ، يمكنك اتخاذ إجراء ضد %s:</string>
|
||||
<string name="unfollow_user">ألغ متابعة %s</string>
|
||||
<string name="unfollow">ألغ المتابعة</string>
|
||||
<string name="mute_user_explain">لن ترى مشاركاتهم. لكن لا يزال بإمكانهم متابعتك ورؤية مشاركاتك ولن يعرفوا أنه تم كتم صوتها.</string>
|
||||
<string name="block_user_explain">لن ترى مشاركاتهم. ولن يتمكنوا من رؤية مشاركاتك أو متابعتك. سيكونون قادرين على معرفة أنهم محظورون.</string>
|
||||
<string name="report_personal_title">لا تريد أن ترى هذا؟</string>
|
||||
<string name="report_personal_subtitle">فيما يلي خياراتك للتحكم بما يُعرَض عليك في ماستدون:</string>
|
||||
<string name="back">العودة</string>
|
||||
<string name="search_communities">اسم الخادم أو عنوان URL</string>
|
||||
<string name="instance_rules_title">قواعد الخادم</string>
|
||||
@@ -196,23 +226,39 @@
|
||||
<string name="category_tech">تقني</string>
|
||||
<string name="confirm_email_title">تحقق من صندوق الوارد الخاص بك</string>
|
||||
<!-- %s is the email address -->
|
||||
<string name="confirm_email_subtitle">اضغط على الرابط الذي أرسلناه إليك للتحقق من %s. سننتظر هنا.</string>
|
||||
<string name="confirm_email_didnt_get">ألم تحصل على رابط؟</string>
|
||||
<string name="resend">أعد الإرسال</string>
|
||||
<string name="open_email_app">افتح تطبيق البريد الإلكتروني</string>
|
||||
<string name="resent_email">أُرسلت رسالة التأكيد</string>
|
||||
<string name="compose_hint">عَبِّر عَمَّ يَجُولُ فِي ذِهنِك</string>
|
||||
<string name="content_warning">تحذير من المحتوى</string>
|
||||
<string name="save">احفظ</string>
|
||||
<string name="add_alt_text">أضف نصًا بديلًا</string>
|
||||
<string name="visibility_public">علني</string>
|
||||
<string name="visibility_followers_only">للمُتابِعينَ فقط</string>
|
||||
<string name="visibility_private">للمشار إليهم فقط</string>
|
||||
<string name="recent_searches">الحديثة</string>
|
||||
<string name="skip">تخطى</string>
|
||||
<string name="notification_type_follow">متابعُون جُدُد</string>
|
||||
<string name="notification_type_favorite">المفضلة</string>
|
||||
<string name="notification_type_mention">الذِكر</string>
|
||||
<string name="notification_type_reblog">المشاركات</string>
|
||||
<string name="notification_type_mention">الإشارات</string>
|
||||
<string name="notification_type_poll">استطلاع رأي</string>
|
||||
<string name="choose_account">اختر حسابًا</string>
|
||||
<string name="err_not_logged_in">يرجى تسجيل الدخول إلى حساب ماستدون أولًا</string>
|
||||
<plurals name="cant_add_more_than_x_attachments">
|
||||
<item quantity="zero">لا يمكن إرفاق أكثر من ملف واحد</item>
|
||||
<item quantity="one">لا يمكن إرفاق أكثر من ملف واحد</item>
|
||||
<item quantity="two">لا يمكنك إرفاق أكثر من %d ملفين</item>
|
||||
<item quantity="few">لا يمكن إرفاق أكثر من %d ملفات</item>
|
||||
<item quantity="many">لا يمكن إرفاق أكثر من %d ملفات</item>
|
||||
<item quantity="other">لا يمكن إرفاق أكثر من %d ملف</item>
|
||||
</plurals>
|
||||
<string name="media_attachment_unsupported_type">نوع الملف %s غير مدعوم</string>
|
||||
<string name="media_attachment_too_big">الملف %1$s يتجاوز حدّ %2$s مب</string>
|
||||
<string name="settings_theme">المظهر</string>
|
||||
<string name="theme_auto">استخدام مظهر الجهاز</string>
|
||||
<string name="theme_light">فاتح</string>
|
||||
<string name="theme_dark">داكن</string>
|
||||
<string name="settings_behavior">السلوك</string>
|
||||
@@ -225,9 +271,13 @@
|
||||
<string name="settings_clear_cache">امسح التخزين المؤقت للوسائط</string>
|
||||
<string name="settings_app_version">تطبيق ماستدون لأندرويد نسخة %1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">مُسح التخزين المؤقت للوسائط</string>
|
||||
<string name="confirm_log_out">تسجيل الخروج من %s؟</string>
|
||||
<string name="sensitive_content_explain">وصف المؤلف هذه الوسائط بأنها حساسة.</string>
|
||||
<string name="avatar_description">انتقل إلى الصفحة الشخصية لـ %s</string>
|
||||
<string name="more_options">مزيد من الخيارات</string>
|
||||
<string name="new_post">منشور جديد</string>
|
||||
<string name="button_reply">ردّ</string>
|
||||
<string name="button_reblog">شارك</string>
|
||||
<string name="button_favorite">فضّل</string>
|
||||
<string name="button_share">شارك</string>
|
||||
<string name="media_no_description">وسائط بدون وصف</string>
|
||||
@@ -239,7 +289,11 @@
|
||||
<string name="media_viewer">عارض الوسائط</string>
|
||||
<string name="follow_user">تابع %s</string>
|
||||
<string name="unfollowed_user">ألغ متابعة %s</string>
|
||||
<string name="followed_user">أنت تتابع الآن %s</string>
|
||||
<string name="following_user_requested">طَلَبَ %s مُتابَعتك</string>
|
||||
<string name="open_in_browser">افتح في المتصفح</string>
|
||||
<string name="hide_boosts_from_user">اخف مشاركات %s</string>
|
||||
<string name="show_boosts_from_user">أظهر مشاركات %s</string>
|
||||
<string name="signup_reason">لماذا تريد الانضمام؟</string>
|
||||
<string name="signup_reason_note">هذا سوف يساعدنا في مراجعة تطبيقك.</string>
|
||||
<string name="clear">امسح</string>
|
||||
@@ -253,7 +307,13 @@
|
||||
<string name="error_saving_file">خطأ أثناء حفظ الملف</string>
|
||||
<string name="file_saved">حُفظ الملف</string>
|
||||
<string name="downloading">ينزّل…</string>
|
||||
<string name="no_app_to_handle_action">لا يوجد تطبيق لمعالجة هذا الإجراء</string>
|
||||
<string name="local_timeline">المحلي</string>
|
||||
<string name="trending_posts_info_banner">هذه هي المشاركات التي تكتسب شعبية عبر ماستدون.</string>
|
||||
<string name="trending_links_info_banner">هذه هي القصص الإخبارية التي يُتحدّث عنها على ماستدون.</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="local_timeline_info_banner">هذه هي جميع المشاركات من جميع المستخدمين في الخادم الخاص بك (%s).</string>
|
||||
<string name="recommended_accounts_info_banner">قد تعجبك هذه الحسابات استنادا إلى حسابات أخرى تتابعها.</string>
|
||||
<string name="see_new_posts">استعرض المنشورات الجديدة</string>
|
||||
<string name="load_missing_posts">حمّل المَنشورات المَفقودَة</string>
|
||||
<string name="follow_back">رُدّ المتابعة</string>
|
||||
@@ -285,6 +345,14 @@
|
||||
<item quantity="many">%,d تفضيلًا</item>
|
||||
<item quantity="other">%,d تفضيل</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="zero">%,d إعادة نشر</item>
|
||||
<item quantity="one">إعادة نشر واحدة</item>
|
||||
<item quantity="two">أعيد نشره مرّتان</item>
|
||||
<item quantity="few">أعيد نشره %,d مرة</item>
|
||||
<item quantity="many">أعيد نشره %,d مرات</item>
|
||||
<item quantity="other">أعيد نشره %,d مرات</item>
|
||||
</plurals>
|
||||
<string name="timestamp_via_app">%1$s عبر %2$s</string>
|
||||
<string name="time_now">الآن</string>
|
||||
<string name="edit_history">تاريخ التعديل</string>
|
||||
@@ -347,6 +415,7 @@
|
||||
<string name="login_title">مرحبا بك مجددًا</string>
|
||||
<string name="login_subtitle">قم بتسجيل الدخول باستخدام الخادم حيث قمتَ بإنشاء حسابك فيه.</string>
|
||||
<string name="server_url">رابط الخادم</string>
|
||||
<string name="signup_random_server_explain">سوف نختار خادماً بناءً على لغتك إذا قمت بالمتابعة دون إجراء إختيار.</string>
|
||||
<string name="server_filter_any_language">أي لغة</string>
|
||||
<string name="server_filter_instant_signup">تسجيل فوري</string>
|
||||
<string name="server_filter_manual_review">مراجعة يدوية</string>
|
||||
@@ -359,6 +428,7 @@
|
||||
<string name="server_filter_region_oceania">أوقيانوسيا</string>
|
||||
<string name="not_accepting_new_members">لا يقبل استقبال أعضاء جدد</string>
|
||||
<string name="category_special_interests">المصالح الخاصة</string>
|
||||
<string name="signup_passwords_dont_match">كلمات المرور غير متطابقة</string>
|
||||
<string name="pick_server_for_me">اختر لي</string>
|
||||
<string name="profile_add_row">إضافة صف</string>
|
||||
<string name="profile_setup">إعداد الملف الشخصي</string>
|
||||
@@ -367,21 +437,265 @@
|
||||
<string name="popular_on_mastodon">مشهور على ماستدون</string>
|
||||
<string name="follow_all">اتبع الكل</string>
|
||||
<string name="server_rules_disagree">لا أوافق</string>
|
||||
<string name="privacy_policy_explanation">بالمختصر: نحن لا نجمع أو نعالج أي شيء.</string>
|
||||
<!-- %s is server domain -->
|
||||
<string name="server_policy_disagree">لا أوافق %s</string>
|
||||
<string name="profile_bio">نبذة عنك</string>
|
||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||
<string name="sending_follows">متابعة المستخدمين…</string>
|
||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||
<string name="signup_email_domain_blocked">%1$s لا يسمح بالاشتراكات من %2$s. جرب خادما واحدا أو <a>اختر خادما مختلفا</a>.</string>
|
||||
<string name="spoiler_show">إظهاره على أي حال</string>
|
||||
<string name="spoiler_hide">إعادة الإخفاء</string>
|
||||
<string name="poll_multiple_choice">اختر واحدا أو أكثر</string>
|
||||
<string name="save_changes">حفظ التغييرات</string>
|
||||
<string name="profile_featured">المميزة</string>
|
||||
<string name="profile_timeline">الخيط</string>
|
||||
<string name="view_all">عرض الكل</string>
|
||||
<string name="profile_endorsed_accounts">الحسابات</string>
|
||||
<string name="verified_link">رابط متحقق منه</string>
|
||||
<string name="show">إظهار</string>
|
||||
<string name="hide">إخفاء</string>
|
||||
<string name="join_default_server">الانضمام إلى %s</string>
|
||||
<string name="pick_server">اختر خادما آخر</string>
|
||||
<string name="signup_or_login">أو</string>
|
||||
<string name="learn_more">تعلم المزيد</string>
|
||||
<string name="welcome_to_mastodon">أهلًا بك على ماستدون</string>
|
||||
<string name="welcome_paragraph1">ماستدون شبكة اجتماعية لامركزية، بمعنى أنه ليس هناك شركة واحدة تتحكم فيها. وهي تتألف من العديد من الخوادم التي تدار بشكل مستقل، وجميعها متصلة معا.</string>
|
||||
<string name="what_are_servers">ما هي الخوادم؟</string>
|
||||
<string name="welcome_paragraph2"><![CDATA[تتم استضافة كل حساب ماستدون على خادم - ولكل منها قيمه وقواعده ومسؤوليه الخاصين. بغض النظر عن الشخص الذي تختاره ، يمكنك متابعة الأشخاص والتفاعل معهم على أي خادم.]]></string>
|
||||
<string name="opening_link">رابط الافتتاح…</string>
|
||||
<string name="link_not_supported">هذا الرابط غير مدعوم في التطبيق</string>
|
||||
<string name="log_out_all_accounts">تسجيل الخروج من جميع الحسابات</string>
|
||||
<string name="confirm_log_out_all_accounts">أتريد تسجيل الخروج من جميع الحسابات؟</string>
|
||||
<string name="retry">حاول مجددًا</string>
|
||||
<string name="post_failed">أخفق في الإرسال</string>
|
||||
<!-- %s is formatted file size ("467 KB image") -->
|
||||
<string name="attachment_description_image">صورة %s</string>
|
||||
<string name="attachment_description_video">فيديو %s</string>
|
||||
<string name="attachment_description_audio">مقطع صوتي %s</string>
|
||||
<string name="attachment_description_unknown">ملف %s</string>
|
||||
<string name="attachment_type_image">صورة</string>
|
||||
<string name="attachment_type_video">فيديو</string>
|
||||
<string name="attachment_type_audio">مقطع صوتي</string>
|
||||
<string name="attachment_type_gif">GIF</string>
|
||||
<string name="attachment_type_unknown">ملف</string>
|
||||
<string name="attachment_x_percent_uploaded">%d%% تم الرفع</string>
|
||||
<string name="add_poll_option">إضافة خيار للاستطلاع</string>
|
||||
<string name="poll_length">مدة الاستطلاع</string>
|
||||
<string name="poll_style">النوع</string>
|
||||
<string name="compose_poll_single_choice">اختر واحدا</string>
|
||||
<string name="compose_poll_multiple_choice">خيارات متعددة</string>
|
||||
<string name="delete_poll_option">حذف خيار من الاستطلاع</string>
|
||||
<string name="poll_style_title">نمط الاستطلاع</string>
|
||||
<string name="alt_text">نص بديل</string>
|
||||
<string name="help">المساعدة</string>
|
||||
<string name="what_is_alt_text">ما هو النص البديل؟</string>
|
||||
<string name="alt_text_help">يوفر النص البديل أوصافا للصور للأشخاص الذين يعانون من إعاقات بصرية أو اتصالات ذات نطاق ترددي منخفض أو أولئك الذين يبحثون عن سياق إضافي.\n\nيمكنك تحسين إمكانية الوصول والفهم للجميع من خلال كتابة نص بديل واضح وموجز وموضوعي.\n\n التقاط العناصر المهمة\n<ul><li>تلخيص النص في الصور</li>\n<li>استخدام بنية الجملة العادية</li>\n<li>تجنب المعلومات الزائدة</li>\n<li>التركيز على الاتجاهات والنتائج الرئيسية في العناصر المرئية المعقدة (مثل الرسوم البيانية أو الخرائط)</li><li></li></ul></string>
|
||||
<string name="edit_post">تعديل المنشور</string>
|
||||
<string name="no_verified_link">لم يتم التحقق من الرابط</string>
|
||||
<string name="compose_autocomplete_emoji_empty">تصفح الرموز التعبيرية</string>
|
||||
<string name="compose_autocomplete_users_empty">العثور على الأشخاص الذين تبحث عنهم</string>
|
||||
<string name="no_search_results">تعذر العثور على أي نتائج لمصطلحات البحث هذه</string>
|
||||
<string name="language">اللغة</string>
|
||||
<string name="language_default">الافتراضية</string>
|
||||
<string name="language_system">النظام</string>
|
||||
<string name="language_detecting">اكتشاف اللغة</string>
|
||||
<string name="language_cant_detect">تعذر اكتشاف اللغة</string>
|
||||
<string name="language_detected">الكشف عن</string>
|
||||
<string name="media_hidden">وسائط مخفية</string>
|
||||
<string name="post_hidden">منشور مخفي</string>
|
||||
<string name="report_title_post">الإبلاغ عن المنشور</string>
|
||||
<string name="forward_report_explanation">الحساب من خادم آخر. هل تودّ إرسال نسخة مجهولة المصدر من هذا التقرير هناك أيضا؟</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="forward_report_to_server">تحويله إلى %s</string>
|
||||
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->
|
||||
<string name="reported">تم الإبلاغ عنه</string>
|
||||
<string name="report_unfollow_explanation">لعدم رؤية مشاركاتهم في خلاصة ملخصك بعد الآن، ألغِ متابعتهم.</string>
|
||||
<string name="muted_user">كتم %s</string>
|
||||
<string name="report_sent_already_blocked">لقد حظرت هذا المستخدم من قبل، لذلك لا يوجد شيء آخر عليك القيام به خلال مراجعة بلاغك.</string>
|
||||
<string name="report_personal_already_blocked">لقد قمت بالفعل بحظر هذا المستخدم، لذلك لا يوجد شيء آخر عليك القيام به.\n\nشكرا للمساعدة في الحفاظ على ماستدون مكانا آمنا للجميع!</string>
|
||||
<string name="blocked_user">حظر %s</string>
|
||||
<string name="mark_all_notifications_read">اعتبار الكل كمقروء</string>
|
||||
<string name="settings_display">الشاشة</string>
|
||||
<string name="settings_filters">عوامل التصفية</string>
|
||||
<string name="settings_server_explanation">نظرة عامة وقواعد ومشرفين</string>
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<string name="about_app">عن %s</string>
|
||||
<string name="default_post_language">اللغة الافتراضية للمنشور</string>
|
||||
<string name="settings_alt_text_reminders">إضافة تذكير بالنصوص البديلة</string>
|
||||
<string name="settings_confirm_unfollow">السؤال قبل إلغاء متابعة شخص ما</string>
|
||||
<string name="settings_confirm_boost">اسأل قبل إعادة النشر</string>
|
||||
<string name="settings_confirm_delete_post">السؤال قبل حذف المشاركات</string>
|
||||
<string name="pause_all_notifications">إيقاف الكل</string>
|
||||
<string name="pause_notifications_off">إيقاف</string>
|
||||
<string name="notifications_policy_anyone">أيا كان</string>
|
||||
<string name="notifications_policy_followed">الأشخاص الذين تتابعهم</string>
|
||||
<string name="notifications_policy_follower">الأشخاص الذين تتابعهم</string>
|
||||
<string name="notifications_policy_no_one">لا أحد</string>
|
||||
<string name="settings_notifications_policy">تلقي الإشعارات من</string>
|
||||
<string name="notification_type_mentions_and_replies">الإشارات والردود</string>
|
||||
<string name="pause_all_notifications_title">إيقاف جميع الإشعارات مؤقتًا</string>
|
||||
<plurals name="x_weeks">
|
||||
<item quantity="zero">%d أسبوع</item>
|
||||
<item quantity="one">أسبوع واحد</item>
|
||||
<item quantity="two">أسبوعان</item>
|
||||
<item quantity="few">%d أسابيع</item>
|
||||
<item quantity="many">%d أسبوعًا</item>
|
||||
<item quantity="other">%d أسابيع</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the date (may be relative, e.g. "today" or "yesterday"), %2$s is the time. You can reorder these placeholders if that works better for your language -->
|
||||
<string name="date_at_time">%1$s في %2$s</string>
|
||||
<string name="today">اليوم</string>
|
||||
<string name="yesterday">أمس</string>
|
||||
<string name="tomorrow">غدًا</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_ends">ينتهي %s</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_banner">سيتم استئناف الإشعارات %s.</string>
|
||||
<string name="resume_notifications_now">استأنف الآن</string>
|
||||
<string name="open_system_notification_settings">الانتقال إلى إعدادات الإشعارات</string>
|
||||
<string name="about_server">عن</string>
|
||||
<string name="server_rules">القواعد</string>
|
||||
<string name="server_administrator">المدير</string>
|
||||
<string name="send_email_to_server_admin">للاتصال بالمدير</string>
|
||||
<string name="notifications_disabled_in_system">شغل الإشعارات من إعدادات جهازك لرؤية التحديثات من أي مكان.</string>
|
||||
<string name="settings_even_more">المزيد من الإعدادات</string>
|
||||
<string name="settings_show_cws">إظهار تحذيرات المحتوى</string>
|
||||
<string name="settings_hide_sensitive_media">فلرتة الوسائط التي تم وضع علامة عليها على أنها حساسة</string>
|
||||
<string name="settings_show_interaction_counts">عدد التفاعل مع المنشورات</string>
|
||||
<string name="settings_show_emoji_in_names">رموز تعبيرية مخصصة في أسماء العرض</string>
|
||||
<plurals name="in_x_seconds">
|
||||
<item quantity="zero">في %d ثانية</item>
|
||||
<item quantity="one">في ثانية واحدة</item>
|
||||
<item quantity="two">في ثانيتين</item>
|
||||
<item quantity="few">في %d ثوانٍ</item>
|
||||
<item quantity="many">في %d ثانية</item>
|
||||
<item quantity="other">في %d ثوان</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_minutes">
|
||||
<item quantity="zero">في %d دقيقة</item>
|
||||
<item quantity="one">في دقيقة واحدة</item>
|
||||
<item quantity="two">في دقيقتين</item>
|
||||
<item quantity="few">في %d دقائق</item>
|
||||
<item quantity="many">في %d دقيقة</item>
|
||||
<item quantity="other">في %d دقائق</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="zero">في %d ساعة</item>
|
||||
<item quantity="one">خلال ساعة واحدة</item>
|
||||
<item quantity="two">خلال ساعتان</item>
|
||||
<item quantity="few">خلال %d ساعات</item>
|
||||
<item quantity="many">خلال %d ساعة</item>
|
||||
<item quantity="other">خلال %d ساعات</item>
|
||||
</plurals>
|
||||
<plurals name="x_hours_ago">
|
||||
<item quantity="zero">منذ %d ساعات</item>
|
||||
<item quantity="one">منذ ساعة واحدة</item>
|
||||
<item quantity="two">منذ ساعتان</item>
|
||||
<item quantity="few">منذ %d ساعات</item>
|
||||
<item quantity="many">منذ %d ساعة</item>
|
||||
<item quantity="other">منذ %d ساعات</item>
|
||||
</plurals>
|
||||
<string name="alt_text_reminder_title">تفتقد الوسائط إلى نص بديل</string>
|
||||
<plurals name="alt_text_reminder_x_images">
|
||||
<item quantity="zero">%s من صورك يفتقر إلى نص بديل. أتردد النشر على أي حال؟</item>
|
||||
<item quantity="one">%s من صورك يفتقر إلى نص بديل. أتردد النشر على أي حال؟</item>
|
||||
<item quantity="two">%s من صورك يفتقر إلى نص بديل. أتردد النشر على أي حال؟</item>
|
||||
<item quantity="few">%s من صورك يفتقر إلى نص بديل. أتردد النشر على أي حال؟</item>
|
||||
<item quantity="many">%s من صورك يفتقر إلى نص بديل. أتردد النشر على أي حال؟</item>
|
||||
<item quantity="other">%s من صورك يفتقر إلى نص بديل. أتردد النشر على أي حال؟</item>
|
||||
</plurals>
|
||||
<plurals name="alt_text_reminder_x_attachments">
|
||||
<item quantity="zero">%s من مرفقات الوسائط الخاصة بك يفتقر لنص بديل. نشر على أي حال؟</item>
|
||||
<item quantity="one">%s من مرفقات الوسائط الخاصة بك يفتقر لنص بديل. نشر على أي حال؟</item>
|
||||
<item quantity="two">%s من مرفقات الوسائط الخاصة بك يفتقر لنص بديل. نشر على أي حال؟</item>
|
||||
<item quantity="few">%s من مرفقات الوسائط الخاصة بك يفتقر لنص بديل. نشر على أي حال؟</item>
|
||||
<item quantity="many">%s من مرفقات الوسائط الخاصة بك يفتقر لنص بديل. نشر على أي حال؟</item>
|
||||
<item quantity="other">%s من مرفقات الوسائط الخاصة بك يفتقر لنص بديل. نشر على أي حال؟</item>
|
||||
</plurals>
|
||||
<string name="count_one">واحد</string>
|
||||
<string name="count_two">اثنان</string>
|
||||
<string name="count_three">ثلاثة</string>
|
||||
<string name="count_four">أربعة</string>
|
||||
<string name="alt_text_reminder_post_anyway">مَنشور</string>
|
||||
<!-- %s is the username -->
|
||||
<string name="unfollow_confirmation">أتريد إلغاء متابعة %s؟</string>
|
||||
<string name="filter_active">نشِط</string>
|
||||
<string name="filter_inactive">خامل</string>
|
||||
<string name="settings_add_filter">إضافة عامل تصفية</string>
|
||||
<string name="settings_edit_filter">تعديل عامل التصفية</string>
|
||||
<string name="settings_filter_duration">المدة</string>
|
||||
<string name="settings_filter_muted_words">الكلمات المحظورة</string>
|
||||
<string name="settings_filter_context">كتم الصوت من</string>
|
||||
<string name="settings_filter_show_cw">عرض مع تحذير المحتوى</string>
|
||||
<string name="settings_filter_show_cw_explanation">الاستمرار في عرض المشاركات التي تطابق هذا الفلتر، ولكن خلف تحذير حول المحتوى</string>
|
||||
<string name="settings_delete_filter">حذف عامل التصفية</string>
|
||||
<string name="filter_duration_forever">إلى الأبد</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="settings_filter_ends">ينتهي %s</string>
|
||||
<plurals name="settings_x_muted_words">
|
||||
<item quantity="zero">%d كلمة أو عبارة مكتومة</item>
|
||||
<item quantity="one">%d كلمة أو عبارة مكتومة</item>
|
||||
<item quantity="two">%d كلمتان أو عبارتان مكتومتان</item>
|
||||
<item quantity="few">%d كلمة أو عبارة مكتومة</item>
|
||||
<item quantity="many">%d كلمة أو عبارة مكتومة</item>
|
||||
<item quantity="other">%d كلمة أو عبارة مكتومة</item>
|
||||
</plurals>
|
||||
<string name="selection_2_options">%1$s و %2$s</string>
|
||||
<string name="selection_3_options">%1$s و %2$s و %3$s</string>
|
||||
<string name="selection_4_or_more">%1$s, %2$s, و %3$d والمزيد</string>
|
||||
<string name="filter_context_home_lists">الخيط الزمني الرئيسي والقوائم</string>
|
||||
<string name="filter_context_notifications">الإشعارات</string>
|
||||
<string name="filter_context_public_timelines">الخيوط الزمنية العامة</string>
|
||||
<string name="filter_context_threads_replies">سلاسل المحادثات والردود</string>
|
||||
<string name="filter_context_profiles">الصفحات التعريفية</string>
|
||||
<string name="settings_filter_title">العنوان</string>
|
||||
<string name="settings_delete_filter_title">حذف عامل التصفية \"%s\"؟</string>
|
||||
<string name="settings_delete_filter_confirmation">سيتم حذف هذا الفلتر من حسابك على جميع الأجهزة.</string>
|
||||
<string name="add_muted_word">إضافة كلمة مكتومة</string>
|
||||
<string name="edit_muted_word">تحرير كلمة مكتومة</string>
|
||||
<string name="add">إضافة</string>
|
||||
<string name="filter_word_or_phrase">كلمة أو عبارة</string>
|
||||
<string name="filter_add_word_help">الكلمات غير حساسة لحالة الأحرف وتتطابق مع الكلمات الكاملة فقط.\n\nإذا قمت بتصفية الكلمة الرئيسية \"Apple\" ، فستخفي المشاركات التي تحتوي على \"apple\" أو \"aPpLe\" ولكن ليس \"pineapple.\"</string>
|
||||
<string name="settings_delete_filter_word">حذف الكلمة \"%s\"؟</string>
|
||||
<string name="enter_selection_mode">اختر</string>
|
||||
<string name="select_all">اختيار الكل</string>
|
||||
<string name="settings_filter_duration_title">مدة التصفية</string>
|
||||
<string name="filter_duration_custom">مخصص</string>
|
||||
<plurals name="settings_delete_x_filter_words">
|
||||
<item quantity="zero">حذف %d كلمات؟</item>
|
||||
<item quantity="one">حذف كلمة واحدة؟</item>
|
||||
<item quantity="two">حذف كلمتان؟</item>
|
||||
<item quantity="few">حذف %d كلمات؟</item>
|
||||
<item quantity="many">حذف %d كلمة؟</item>
|
||||
<item quantity="other">حذف %d كلمات؟</item>
|
||||
</plurals>
|
||||
<plurals name="x_items_selected">
|
||||
<item quantity="zero">تم تحديد %d</item>
|
||||
<item quantity="one">تم تحديد %d</item>
|
||||
<item quantity="two">%d تم تحديدها</item>
|
||||
<item quantity="few">%d تم تحديدها</item>
|
||||
<item quantity="many">%d تم تحديدها</item>
|
||||
<item quantity="other">%d تم تحديدها</item>
|
||||
</plurals>
|
||||
<string name="required_form_field_blank">لا يمكن أن يكون فارغاً</string>
|
||||
<string name="filter_word_already_in_list">موجود بالفعل في القائمة</string>
|
||||
<string name="app_update_ready">تحديث التطبيق جاهز</string>
|
||||
<string name="app_update_version">الإصدار %s</string>
|
||||
<string name="downloading_update">جارٍ التنزيل (%d%%)</string>
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<string name="post_matches_filter_x">تطابق عامل التصفية \"%s\"</string>
|
||||
<string name="search_mastodon">البحث في ماستدون</string>
|
||||
<string name="clear_all">امسح الكل</string>
|
||||
<string name="search_open_url">فتح الرابط التشعبي في ماستدون</string>
|
||||
<string name="posts_matching_hashtag">منشورات تحتوي على “%s”</string>
|
||||
<string name="search_go_to_account">الانتقال إلى %s</string>
|
||||
<string name="posts_matching_string">منشورات تحتوي على “%s”</string>
|
||||
<string name="accounts_matching_string">أشخاص لديهم \"%s\"</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<string name="time_seconds_ago_short">مُنذُ %dث</string>
|
||||
<string name="time_minutes_ago_short">مُنذُ %dش</string>
|
||||
<string name="time_hours_ago_short">مُنذُ %dس</string>
|
||||
<string name="time_days_ago_short">مُنذُ %dي</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,8 +7,11 @@
|
||||
<string name="preparing_auth">প্রমাণীকরণের জন্য প্রস্তুত হচ্ছে...</string>
|
||||
<string name="in_reply_to">%s কে উত্তর দিন</string>
|
||||
<string name="notifications">নোটিফিকেশন</string>
|
||||
<string name="user_followed_you">%s আপনাকে ফলো করেছেন</string>
|
||||
<string name="user_sent_follow_request">%s আপনাকে ফলো করার অনুরোধ পাঠিয়েছেন</string>
|
||||
<string name="share_toot_title">শেয়ার করুন</string>
|
||||
<string name="settings">সেটিংস</string>
|
||||
<string name="discard">বাতিল করুন</string>
|
||||
<string name="cancel">বাতিল করুন</string>
|
||||
<plurals name="followers">
|
||||
<item quantity="one">জন ফলোয়ার</item>
|
||||
@@ -92,9 +95,18 @@
|
||||
<item quantity="one">%d জন ব্যক্তি বলছেন</item>
|
||||
<item quantity="other">%d jon ব্যক্তিরা বলছেন</item>
|
||||
</plurals>
|
||||
<string name="report_title">%s -এর নামে অভিযোগ করুন</string>
|
||||
<string name="report_choose_reason">এই পোস্টে ভুল কি?</string>
|
||||
<string name="report_reason_personal">আমার এটি ভালো লাগছে না</string>
|
||||
<string name="report_reason_spam">এটি স্প্যাম</string>
|
||||
<string name="report_reason_violation">এটি সার্ভারের নিয়ম ভাঙছে</string>
|
||||
<string name="report_reason_other">এটি অন্য কিছু</string>
|
||||
<string name="report_choose_rule">কোন নিয়মটা ভেঙেছে?</string>
|
||||
<string name="sending_report">রিপোর্ট পাঠানো হচ্ছে…</string>
|
||||
<string name="report_sent_title">রিপোর্ট করার জন্য আপনাকে ধন্যবাদ, আমরা এটি শীঘ্রই দেখব.</string>
|
||||
<string name="report_sent_subtitle">আমরা যতক্ষণে আপনার রিপোর্ট পুনর্বিবেচনা করছি, আপনি %s এর বিরুদ্ধে ব্যবস্থা নিতে পারেন:</string>
|
||||
<string name="unfollow_user">%s -কে আনফলো করুন</string>
|
||||
<string name="unfollow">আনফলো করুন</string>
|
||||
<string name="report_personal_title">আপনি এটি আর দেখতে চান না?</string>
|
||||
<string name="back">ফিরে যান</string>
|
||||
<string name="search_communities">সার্ভারের নাম বা লিঙ্ক</string>
|
||||
|
||||
@@ -105,6 +105,12 @@
|
||||
<item quantity="many">Zbývá %d dní</item>
|
||||
<item quantity="other">Zbývá %d dní</item>
|
||||
</plurals>
|
||||
<plurals name="x_votes">
|
||||
<item quantity="one">%,d hlas</item>
|
||||
<item quantity="few">%,d hlasující</item>
|
||||
<item quantity="many">%,d hlasujících</item>
|
||||
<item quantity="other">%,d hlasů</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">Uzavřeno</string>
|
||||
<string name="confirm_mute_title">Skrýt účet</string>
|
||||
<string name="confirm_mute">Potvrdit skrytí %s</string>
|
||||
@@ -217,6 +223,12 @@
|
||||
<string name="notification_type_poll">Ankety</string>
|
||||
<string name="choose_account">Vybrat účet</string>
|
||||
<string name="err_not_logged_in">Nejprve se přihlaste do Mastodonu</string>
|
||||
<plurals name="cant_add_more_than_x_attachments">
|
||||
<item quantity="one">Nelze přidat více než %d multimediální přílohu</item>
|
||||
<item quantity="few">Nelze přidat více než %d multimediální přílohy</item>
|
||||
<item quantity="many">Nelze přidat více než %d multimediálních příloh</item>
|
||||
<item quantity="other">Nelze přidat více než %d multimediálních příloh</item>
|
||||
</plurals>
|
||||
<string name="media_attachment_unsupported_type">Soubor %s nepatří mezi podporované typy</string>
|
||||
<string name="media_attachment_too_big">Soubor %1$s překračuje limit velikosti %2$s MB</string>
|
||||
<string name="settings_theme">Vzhled</string>
|
||||
@@ -301,6 +313,12 @@
|
||||
<item quantity="many">%,d oblíbení</item>
|
||||
<item quantity="other">%,d oblíbení</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="one">%,d boost</item>
|
||||
<item quantity="few">%,d boosty</item>
|
||||
<item quantity="many">%,d boostů</item>
|
||||
<item quantity="other">%,d boostů</item>
|
||||
</plurals>
|
||||
<string name="timestamp_via_app">%1$s přes %2$s</string>
|
||||
<string name="time_now">teď</string>
|
||||
<string name="edit_history">Historie úprav</string>
|
||||
@@ -480,6 +498,12 @@
|
||||
<string name="settings_notifications_policy">Dostávat oznámení od</string>
|
||||
<string name="notification_type_mentions_and_replies">Zmínění a odpovědi</string>
|
||||
<string name="pause_all_notifications_title">Pozastavit všechna oznámení</string>
|
||||
<plurals name="x_weeks">
|
||||
<item quantity="one">%d týden</item>
|
||||
<item quantity="few">%d týdny</item>
|
||||
<item quantity="many">%d týdnů</item>
|
||||
<item quantity="other">%d týdnů</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the date (may be relative, e.g. "today" or "yesterday"), %2$s is the time. You can reorder these placeholders if that works better for your language -->
|
||||
<string name="date_at_time">%1$s v %2$s</string>
|
||||
<string name="today">dnes</string>
|
||||
@@ -501,7 +525,43 @@
|
||||
<string name="settings_hide_sensitive_media">Zakrýt média označená jako citlivá</string>
|
||||
<string name="settings_show_interaction_counts">Počet interakcí příspěvku</string>
|
||||
<string name="settings_show_emoji_in_names">Vlastní emoji v zobrazených jménech</string>
|
||||
<plurals name="in_x_seconds">
|
||||
<item quantity="one">za %d vteřinu</item>
|
||||
<item quantity="few">za %d vteřiny</item>
|
||||
<item quantity="many">za %d vteřin</item>
|
||||
<item quantity="other">za %d vteřin</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_minutes">
|
||||
<item quantity="one">za %d minutu</item>
|
||||
<item quantity="few">za %d minuty</item>
|
||||
<item quantity="many">za %d minut</item>
|
||||
<item quantity="other">za %d minut</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="one">za %d hodinu</item>
|
||||
<item quantity="few">za %d hodiny</item>
|
||||
<item quantity="many">za %d hodin</item>
|
||||
<item quantity="other">za %d hodin</item>
|
||||
</plurals>
|
||||
<plurals name="x_hours_ago">
|
||||
<item quantity="one">před %d hodinou</item>
|
||||
<item quantity="few">před %d hodinami</item>
|
||||
<item quantity="many">před %d hodinami</item>
|
||||
<item quantity="other">před %d hodinami</item>
|
||||
</plurals>
|
||||
<string name="alt_text_reminder_title">Média nemají alternativní text</string>
|
||||
<plurals name="alt_text_reminder_x_images">
|
||||
<item quantity="one">%s z vašich obrázků nemá alternativní text. Přesto odeslat?</item>
|
||||
<item quantity="few">%s z vašich obrázků nemají alternativní text. Přesto odeslat?</item>
|
||||
<item quantity="many">%s z vašich obrázků nemá alternativní text. Přesto odeslat?</item>
|
||||
<item quantity="other">%s z vašich obrázků nemá alternativní text. Přesto odeslat?</item>
|
||||
</plurals>
|
||||
<plurals name="alt_text_reminder_x_attachments">
|
||||
<item quantity="one">%s z vašich multimediálních příloh nemá alternativní text. Přesto odeslat?</item>
|
||||
<item quantity="few">%s z vašich multimediálních příloh nemají alternativní text. Přesto odeslat?</item>
|
||||
<item quantity="many">%s z vašich multimediálních příloh nemá alternativní text. Přesto odeslat?</item>
|
||||
<item quantity="other">%s z vašich multimediálních příloh nemá alternativní text. Přesto odeslat?</item>
|
||||
</plurals>
|
||||
<string name="count_one">Jeden</string>
|
||||
<string name="count_two">Dva</string>
|
||||
<string name="count_three">Tři</string>
|
||||
@@ -522,6 +582,12 @@
|
||||
<string name="filter_duration_forever">Napořád</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="settings_filter_ends">Končí %s</string>
|
||||
<plurals name="settings_x_muted_words">
|
||||
<item quantity="one">%d ztišené slovo nebo fráze</item>
|
||||
<item quantity="few">%d ztišená slova nebo fráze</item>
|
||||
<item quantity="many">%d ztišených slov nebo frází</item>
|
||||
<item quantity="other">%d ztišených slov nebo fráze</item>
|
||||
</plurals>
|
||||
<string name="selection_2_options">%1$s a %2$s</string>
|
||||
<string name="selection_3_options">%1$s, %2$s a %3$s</string>
|
||||
<string name="selection_4_or_more">%1$s, %2$s a %3$d další</string>
|
||||
@@ -543,6 +609,18 @@
|
||||
<string name="select_all">Vybrat vše</string>
|
||||
<string name="settings_filter_duration_title">Doba použití filtru</string>
|
||||
<string name="filter_duration_custom">Vlastní</string>
|
||||
<plurals name="settings_delete_x_filter_words">
|
||||
<item quantity="one">Smazat %d slovo?</item>
|
||||
<item quantity="few">Smazat %d slova?</item>
|
||||
<item quantity="many">Smazat %d slov?</item>
|
||||
<item quantity="other">Smazat %d slov?</item>
|
||||
</plurals>
|
||||
<plurals name="x_items_selected">
|
||||
<item quantity="one">%d vybráno</item>
|
||||
<item quantity="few">%d vybrány</item>
|
||||
<item quantity="many">%d vybraných</item>
|
||||
<item quantity="other">%d vybraných</item>
|
||||
</plurals>
|
||||
<string name="required_form_field_blank">Nemůže být prázdné</string>
|
||||
<string name="filter_word_already_in_list">Již v seznamu</string>
|
||||
<string name="app_update_ready">Je připravena aktualizace aplikace</string>
|
||||
|
||||
@@ -4,18 +4,24 @@
|
||||
<string name="next">Næste</string>
|
||||
<string name="loading_instance">Henter serverinfo…</string>
|
||||
<string name="error">Fejl</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="not_a_mastodon_instance">%s lader ikke til at være en Mastodon-server.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="preparing_auth">Forbereder godkendelse…</string>
|
||||
<string name="finishing_auth">Afslutter godkendelse…</string>
|
||||
<string name="user_boosted">%s fremhævede</string>
|
||||
<string name="in_reply_to">Som svar til %s</string>
|
||||
<string name="notifications">Meddelelser</string>
|
||||
<string name="notifications">Notifikationer</string>
|
||||
<string name="user_followed_you">%s begyndte at følge dig</string>
|
||||
<string name="user_sent_follow_request">%s har sendt dig en følgeanmodning</string>
|
||||
<string name="user_favorited">%s favoritmarkerede dit indlæg</string>
|
||||
<string name="notification_boosted">%s boostede dit indlæg</string>
|
||||
<string name="poll_ended">Se resultaterne af en afstemning, hvori du deltog</string>
|
||||
<string name="share_toot_title">Del</string>
|
||||
<string name="settings">Indstillinger</string>
|
||||
<string name="publish">Offentliggør</string>
|
||||
<string name="publish">Publicér</string>
|
||||
<string name="discard_draft">Kassér kladde?</string>
|
||||
<string name="discard">Kassér</string>
|
||||
<string name="cancel">Fortryd</string>
|
||||
<string name="cancel">Afbryd</string>
|
||||
<plurals name="followers">
|
||||
<item quantity="one">følger</item>
|
||||
<item quantity="other">følgere</item>
|
||||
@@ -31,13 +37,14 @@
|
||||
<string name="button_follow">Følg</string>
|
||||
<string name="button_following">Følger</string>
|
||||
<string name="edit_profile">Redigér profil</string>
|
||||
<string name="mute_user">Skjul %s (mute)</string>
|
||||
<string name="unmute_user">Vis %s igen (unmute)</string>
|
||||
<string name="block_user">Bloker %s</string>
|
||||
<string name="unblock_user">Fjern blokering af %s</string>
|
||||
<string name="report_user">Indberet %s</string>
|
||||
<string name="block_domain">Bloker %s</string>
|
||||
<string name="unblock_domain">Fjern blokering af %s</string>
|
||||
<string name="share_user">Del profil</string>
|
||||
<string name="mute_user">Gør tavs %s</string>
|
||||
<string name="unmute_user">Vis %s igen</string>
|
||||
<string name="block_user">Blokér %s</string>
|
||||
<string name="unblock_user">Afblokér %s</string>
|
||||
<string name="report_user">Anmeld %s</string>
|
||||
<string name="block_domain">Blokér %s</string>
|
||||
<string name="unblock_domain">Afblokér %s</string>
|
||||
<plurals name="x_posts">
|
||||
<item quantity="one">%,d indlæg</item>
|
||||
<item quantity="other">%,d indlæg</item>
|
||||
@@ -45,7 +52,7 @@
|
||||
<string name="profile_joined">Tilmeldt</string>
|
||||
<string name="done">Udført</string>
|
||||
<string name="loading">Indlæser…</string>
|
||||
<string name="field_label">Mærkat</string>
|
||||
<string name="field_label">Etiket</string>
|
||||
<string name="field_content">Indhold</string>
|
||||
<string name="saving">Gemmer…</string>
|
||||
<string name="post_from_user">Indlæg fra %s</string>
|
||||
@@ -78,66 +85,84 @@
|
||||
<item quantity="one">%d dag tilbage</item>
|
||||
<item quantity="other">%d dage tilbage</item>
|
||||
</plurals>
|
||||
<plurals name="x_votes">
|
||||
<item quantity="one">%,d stemme</item>
|
||||
<item quantity="other">%,d stemmer</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">Lukket</string>
|
||||
<string name="confirm_mute_title">Skjul konto</string>
|
||||
<string name="confirm_mute">Bekræft at du vil skjule %s</string>
|
||||
<string name="do_mute">Skjul (mute)</string>
|
||||
<string name="confirm_unmute_title">Vis bruger igen (unmute)</string>
|
||||
<string name="confirm_unmute">Bekræft at du vil se %s igen</string>
|
||||
<string name="do_unmute">Vis igen (unmute)</string>
|
||||
<string name="confirm_block_title">Bloker bruger</string>
|
||||
<string name="confirm_block_domain_title">Bloker domæne</string>
|
||||
<string name="confirm_block">Bekræft at du vil blokere %s</string>
|
||||
<string name="do_block">Bloker</string>
|
||||
<string name="confirm_unblock_title">Fjern blokering af bruger</string>
|
||||
<string name="confirm_unblock_domain_title">Fjern blokering af domæne</string>
|
||||
<string name="confirm_unblock">Bekræft at du vil fjerne blokering af %s</string>
|
||||
<string name="do_unblock">Fjern blokering</string>
|
||||
<string name="confirm_mute_title">Tavsgør konto</string>
|
||||
<string name="confirm_mute">Bekræft tavsgørelse af %s</string>
|
||||
<string name="do_mute">Tavsgør</string>
|
||||
<string name="confirm_unmute_title">Vis konto igen</string>
|
||||
<string name="confirm_unmute">Bekræft, at %s ikke længere er tavsgjort</string>
|
||||
<string name="do_unmute">Ophæv tavsgørelse</string>
|
||||
<string name="confirm_block_title">Blokér konto</string>
|
||||
<string name="confirm_block_domain_title">Blokér domæne</string>
|
||||
<string name="confirm_block">Bekræft blokering af %s</string>
|
||||
<string name="do_block">Blokér</string>
|
||||
<string name="confirm_unblock_title">Afblokér konto</string>
|
||||
<string name="confirm_unblock_domain_title">Afblokér domæne</string>
|
||||
<string name="confirm_unblock">Bekræft afblokeringen af %s</string>
|
||||
<string name="do_unblock">Afblokér</string>
|
||||
<string name="button_blocked">Blokeret</string>
|
||||
<string name="action_vote">Stem</string>
|
||||
<string name="delete">Slet</string>
|
||||
<string name="confirm_delete">Er du sikker på, at du vil slette dette indlæg?</string>
|
||||
<string name="confirm_delete_title">Slet indlæg</string>
|
||||
<string name="confirm_delete">Sikker på, at dette indlæg skal slettes?</string>
|
||||
<string name="deleting">Sletter…</string>
|
||||
<string name="notification_channel_audio_player">Afspilning af lyd</string>
|
||||
<string name="notification_channel_audio_player">Lydafspilning</string>
|
||||
<string name="play">Afspil</string>
|
||||
<string name="pause">Sæt på pause</string>
|
||||
<string name="pause">Pausér</string>
|
||||
<string name="log_out">Log ud</string>
|
||||
<string name="add_account">Tilføj konto</string>
|
||||
<string name="search_hint">Søg</string>
|
||||
<string name="hashtags">Hashtags</string>
|
||||
<string name="news">Nyheder</string>
|
||||
<string name="for_you">Til dig</string>
|
||||
<string name="all_notifications">Alt</string>
|
||||
<string name="mentions">Omtaler</string>
|
||||
<plurals name="x_people_talking">
|
||||
<item quantity="one">%d person deltager</item>
|
||||
<item quantity="other">%d personer deltager</item>
|
||||
<item quantity="one">%d person taler</item>
|
||||
<item quantity="other">%d personer taler</item>
|
||||
</plurals>
|
||||
<string name="report_title">Indberet %s</string>
|
||||
<string name="report_choose_reason_subtitle">Vælg en passende grund</string>
|
||||
<string name="report_title">Anmeld %s</string>
|
||||
<string name="report_choose_reason">Hvad er der galt med dette indlæg?</string>
|
||||
<string name="report_choose_reason_account">Hvad er der galt med %s?</string>
|
||||
<string name="report_choose_reason_subtitle">Vælg bedste match</string>
|
||||
<string name="report_reason_personal">Bryder mig ikke om det</string>
|
||||
<string name="report_reason_personal_subtitle">Det er ikke noget, man ønsker at se</string>
|
||||
<string name="report_reason_spam_subtitle">Ondsindede links, falske interaktioner, eller gentagne svar</string>
|
||||
<string name="report_reason_violation">Det overtræder serverreglerne</string>
|
||||
<string name="report_reason_violation_subtitle">Du kender til specifikke regler som det er i strid med</string>
|
||||
<string name="report_reason_other_subtitle">Problemet passer ikke ind i andre kategorier</string>
|
||||
<string name="report_reason_spam">Det er spam</string>
|
||||
<string name="report_reason_spam_subtitle">Ondsindede links, falske interaktioner eller gentagne svar</string>
|
||||
<string name="report_reason_violation">Det overtræder serverregler</string>
|
||||
<string name="report_reason_violation_subtitle">Du er bekendt med, at det overtræder bestemte regler</string>
|
||||
<string name="report_reason_other">Drejer sig om noget andet</string>
|
||||
<string name="report_reason_other_subtitle">Ingen kategori modsvarer problematikken</string>
|
||||
<string name="report_choose_rule">Hvilke regler overtrædes?</string>
|
||||
<string name="report_choose_rule_subtitle">Vælg alle relevante</string>
|
||||
<string name="report_choose_posts">Er der indlæg, som kan bekræfte denne anmeldelse?</string>
|
||||
<string name="report_choose_posts">Er der indlæg, som understøtter denne anmeldelse?</string>
|
||||
<string name="report_choose_posts_subtitle">Vælg alle relevante</string>
|
||||
<string name="report_comment_title">Er der andet, vi bør vide?</string>
|
||||
<string name="report_comment_hint">Yderligere kommentarer</string>
|
||||
<string name="sending_report">Sender rapport…</string>
|
||||
<string name="sending_report">Indsender rapport…</string>
|
||||
<string name="report_sent_title">Tak for anmeldelsen. Vi vil se nærmere på dette.</string>
|
||||
<string name="report_sent_subtitle">Mens vi gennemgår anmeldelsen, kan du tage skridt mod %s:</string>
|
||||
<string name="unfollow_user">Følg ikke længere %s</string>
|
||||
<string name="unfollow">Følg ikke længere</string>
|
||||
<string name="back">Tilbage</string>
|
||||
<string name="search_communities">Server-navn eller URL</string>
|
||||
<string name="mute_user_explain">Du vil ikke se indlæg fra vedkommende, der dog stadig kan se dine indlæg og følge dig, men ikke være bekendt med tavsgørelsen.</string>
|
||||
<string name="block_user_explain">Du vil ikke se indlæg fra vedkommende, der hverken kan se dine indlæg eller følge dig, men vil være bekendt med blokeringen.</string>
|
||||
<string name="report_personal_title">Ønsker du ikke at se dette?</string>
|
||||
<string name="report_personal_subtitle">Her er mulighederne for at styre, hvad du ser på Mastodon:</string>
|
||||
<string name="back">Retur</string>
|
||||
<string name="search_communities">Servernavn eller -URL</string>
|
||||
<string name="instance_rules_title">Serverregler</string>
|
||||
<string name="instance_rules_subtitle">Ved at fortsætte accepterer du at følge følgende regler, der er vedtaget og håndhævet af %ss moderatorer.</string>
|
||||
<string name="instance_rules_subtitle">Ved at fortsætte accepterer du at overholde flg. regler, som angivet og håndhævet af %s moderatorerne.</string>
|
||||
<string name="signup_title">Opret konto</string>
|
||||
<string name="display_name">Navn</string>
|
||||
<string name="username">Brugernavn</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="password">Adgangskode</string>
|
||||
<string name="confirm_password">Bekræft adgangskode</string>
|
||||
<string name="password_note">Inkluder store bogstaver, specialtegn og tal for at gøre din adgangskode stærkere.</string>
|
||||
<string name="password_note">Benyt majuskler, specialtegn og tal for at øge adgangskodens styrke.</string>
|
||||
<string name="category_academia">Forskning og højere uddannelser</string>
|
||||
<string name="category_activism">Aktivisme</string>
|
||||
<string name="category_all">Alt</string>
|
||||
@@ -153,41 +178,55 @@
|
||||
<string name="category_tech">Teknologi</string>
|
||||
<string name="confirm_email_title">Tjek din indbakke</string>
|
||||
<!-- %s is the email address -->
|
||||
<string name="confirm_email_subtitle">Tryk på det modtage link for at bekræfte %s. Vi venter her så længe.</string>
|
||||
<string name="confirm_email_didnt_get">Modtog intet link?</string>
|
||||
<string name="resend">Send igen</string>
|
||||
<string name="open_email_app">Åben email-app</string>
|
||||
<string name="resent_email">Bekræftelses-email sendt</string>
|
||||
<string name="open_email_app">Åbn e-mail app</string>
|
||||
<string name="resent_email">Bekræftelsesmail sendt</string>
|
||||
<string name="compose_hint">Angiv eller indsæt, hvad du tænker på</string>
|
||||
<string name="content_warning">Indholdsadvarsel</string>
|
||||
<string name="save">Gem</string>
|
||||
<string name="add_alt_text">Tilføj alternativ tekst</string>
|
||||
<string name="visibility_public">Offentlig</string>
|
||||
<string name="visibility_followers_only">Kun følgere</string>
|
||||
<string name="skip">Spring over</string>
|
||||
<string name="notification_type_follow">Nye følgere</string>
|
||||
<string name="visibility_followers_only">Kun Følgere</string>
|
||||
<string name="visibility_private">Kun nævnte personer</string>
|
||||
<string name="recent_searches">Nylige</string>
|
||||
<string name="skip">Overspring</string>
|
||||
<string name="notification_type_follow">Nye Følgere</string>
|
||||
<string name="notification_type_favorite">Favoritmarkeringer</string>
|
||||
<string name="notification_type_reblog">Fremhævninger</string>
|
||||
<string name="notification_type_mention">Omtaler</string>
|
||||
<string name="notification_type_poll">Afstemninger</string>
|
||||
<string name="choose_account">Vælg konto</string>
|
||||
<string name="err_not_logged_in">Log venligst ind på Mastodon først</string>
|
||||
<string name="media_attachment_unsupported_type">Filen %s er af en type der ikke understøttes</string>
|
||||
<string name="media_attachment_too_big">Størrelsen på filen %1$s overskrider grænsen på %2$s MB</string>
|
||||
<string name="err_not_logged_in">Log ind på Mastodon først</string>
|
||||
<plurals name="cant_add_more_than_x_attachments">
|
||||
<item quantity="one">Maks. %d medievedhæftning kan tilføjes</item>
|
||||
<item quantity="other">Maks. %d medievedhæftninger kan tilføjes</item>
|
||||
</plurals>
|
||||
<string name="media_attachment_unsupported_type">Filen %s er af en uunderstøttet type</string>
|
||||
<string name="media_attachment_too_big">Filen %1$s overskrider begrænsningen på %2$s MB</string>
|
||||
<string name="settings_theme">Udseende</string>
|
||||
<string name="theme_auto">Brug enhedens indstillinger for udseende</string>
|
||||
<string name="theme_light">Lys</string>
|
||||
<string name="theme_dark">Mørk</string>
|
||||
<string name="settings_behavior">Opførsel</string>
|
||||
<string name="settings_gif">Spil animerede avatarer og emoji</string>
|
||||
<string name="settings_behavior">Adfærd</string>
|
||||
<string name="settings_gif">Afspil animerede avatarer og emojier</string>
|
||||
<string name="settings_custom_tabs">Benyt in-app browser</string>
|
||||
<string name="settings_notifications">Meddelelser</string>
|
||||
<string name="settings_notifications">Notifikationer</string>
|
||||
<string name="settings_contribute">Bidrag til Mastodon</string>
|
||||
<string name="settings_tos">Vilkår og Betingelser</string>
|
||||
<string name="settings_privacy_policy">Privatlivspolitik</string>
|
||||
<string name="settings_tos">Tjenestevilkår</string>
|
||||
<string name="settings_privacy_policy">Fortrolighedspolitik</string>
|
||||
<string name="settings_clear_cache">Ryd mediecache</string>
|
||||
<string name="settings_app_version">Mastodon til Android v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Mediecache ryddet</string>
|
||||
<string name="confirm_log_out">Log ud af %s?</string>
|
||||
<string name="sensitive_content_explain">Forfatteren markerede dette medie som sensitivt.</string>
|
||||
<string name="avatar_description">Gå til %ss profil</string>
|
||||
<string name="more_options">Flere muligheder</string>
|
||||
<string name="new_post">Nyt indlæg</string>
|
||||
<string name="button_reply">Svar</string>
|
||||
<string name="button_reblog">Fremhæv</string>
|
||||
<string name="button_favorite">Favorit</string>
|
||||
<string name="button_favorite">Gør til favorit</string>
|
||||
<string name="button_share">Del</string>
|
||||
<string name="media_no_description">Medier uden beskrivelse</string>
|
||||
<string name="add_media">Tilføj medier</string>
|
||||
@@ -198,6 +237,7 @@
|
||||
<string name="media_viewer">Mediefremviser</string>
|
||||
<string name="follow_user">Følg %s</string>
|
||||
<string name="unfollowed_user">Følg ikke længere %s</string>
|
||||
<string name="followed_user">Du følger nu %s</string>
|
||||
<string name="following_user_requested">Anmodede om at følge %s</string>
|
||||
<string name="open_in_browser">Åbn i browser</string>
|
||||
<string name="hide_boosts_from_user">Skjul fremhævninger fra %s</string>
|
||||
@@ -207,7 +247,7 @@
|
||||
<string name="clear">Ryd</string>
|
||||
<string name="profile_header">Overskriftsbillede</string>
|
||||
<string name="profile_picture">Profilbillede</string>
|
||||
<string name="reorder">Omarranger</string>
|
||||
<string name="reorder">Omarrangér</string>
|
||||
<string name="download">Download</string>
|
||||
<string name="permission_required">Tilladelse kræves</string>
|
||||
<string name="storage_permission_to_download">Appen skal have adgang til din lagerplads for at gemme denne fil.</string>
|
||||
@@ -215,7 +255,13 @@
|
||||
<string name="error_saving_file">Fejl under lagring af fil</string>
|
||||
<string name="file_saved">Fil gemt</string>
|
||||
<string name="downloading">Downloader…</string>
|
||||
<string name="no_app_to_handle_action">Ingen app til at håndtere denne handling</string>
|
||||
<string name="local_timeline">Lokalt</string>
|
||||
<string name="trending_posts_info_banner">Her er de indlæg, som vinder indpas på tværs af Mastodon.</string>
|
||||
<string name="trending_links_info_banner">Her er de nyheder, der bliver talt om på Mastodon.</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="local_timeline_info_banner">Disse er alle indlæg fra alle brugere på din server (%s).</string>
|
||||
<string name="recommended_accounts_info_banner">Baseret på andre, du følger, vil du måske synes om disse konti.</string>
|
||||
<string name="see_new_posts">Se nye indlæg</string>
|
||||
<string name="load_missing_posts">Indlæs manglende indlæg</string>
|
||||
<string name="follow_back">Følg Tilbage</string>
|
||||
@@ -236,14 +282,14 @@
|
||||
<item quantity="other">%,d favoritmarkeringer</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="one">%,d indlæg</item>
|
||||
<item quantity="other">%,d indlæg</item>
|
||||
<item quantity="one">%,d fremhævning</item>
|
||||
<item quantity="other">%,d fremhævninger</item>
|
||||
</plurals>
|
||||
<string name="timestamp_via_app">%1$s via %2$s</string>
|
||||
<string name="time_now">nu</string>
|
||||
<string name="edit_history">Rediger historik</string>
|
||||
<string name="last_edit_at_x">Senest ændret: %s</string>
|
||||
<string name="time_just_now">lige nu</string>
|
||||
<string name="time_just_now">netop nu</string>
|
||||
<plurals name="x_seconds_ago">
|
||||
<item quantity="one">%d sekund siden</item>
|
||||
<item quantity="other">%d sekunder siden</item>
|
||||
@@ -252,11 +298,11 @@
|
||||
<item quantity="one">%d minut siden</item>
|
||||
<item quantity="other">%d minutter siden</item>
|
||||
</plurals>
|
||||
<string name="edited_timestamp">redigerede %s</string>
|
||||
<string name="edited_timestamp">redigeret %s</string>
|
||||
<string name="edit_original_post">Oprindeligt indlæg</string>
|
||||
<string name="edit_text_edited">Tekst redigeret</string>
|
||||
<string name="edit_spoiler_added">Indholdsadvarsel tilføjet</string>
|
||||
<string name="edit_spoiler_edited">Indholdsadvarsel tilføjet</string>
|
||||
<string name="edit_spoiler_edited">Indholdsadvarsel redigeret</string>
|
||||
<string name="edit_spoiler_removed">Indholdsadvarsel fjernet</string>
|
||||
<string name="edit_poll_added">Afstemning tilføjet</string>
|
||||
<string name="edit_poll_edited">Afstemning redigeret</string>
|
||||
@@ -264,11 +310,11 @@
|
||||
<string name="edit_media_added">Medier tilføjet</string>
|
||||
<string name="edit_media_removed">Medier fjernet</string>
|
||||
<string name="edit_media_reordered">Medie omarrangeret</string>
|
||||
<string name="edit_marked_sensitive">Marker som følsom</string>
|
||||
<string name="edit_marked_not_sensitive">Markeret ikke følsom</string>
|
||||
<string name="edit_marked_sensitive">Markeret sensitivt</string>
|
||||
<string name="edit_marked_not_sensitive">Markeret ikke-sensitivt</string>
|
||||
<string name="edit_multiple_changed">Indlæg redigeret</string>
|
||||
<string name="edit">Rediger</string>
|
||||
<string name="discard_changes">Fortryd ændringer?</string>
|
||||
<string name="edit">Redigér</string>
|
||||
<string name="discard_changes">Kassér ændringer?</string>
|
||||
<string name="upload_failed">Upload mislykkedes</string>
|
||||
<string name="file_size_bytes">%d bytes</string>
|
||||
<string name="file_size_kb">%.2f KB</string>
|
||||
@@ -279,20 +325,21 @@
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<!-- %s is file size -->
|
||||
<string name="download_update">Download (%s)</string>
|
||||
<string name="install_update">Installer</string>
|
||||
<string name="privacy_policy_title">Dit privatliv</string>
|
||||
<string name="privacy_policy_subtitle">Selvom Mastodon-appen ikke indsamler data, kan den server du tilmelder dig gennem, have en anden politik.\n\nHvis du er uenig i politikken for %s, kan du gå tilbage og vælge en anden server.</string>
|
||||
<string name="install_update">Installér</string>
|
||||
<string name="privacy_policy_title">Din fortrolighed</string>
|
||||
<string name="privacy_policy_subtitle">Selvom Mastodon-appen ikke indsamler data, kan serveren, via hvilken man tilmelder sig, have en anden politik.\n\nEr man uenig i politikken for %s, kan man gå tilbage og vælge en anden server.</string>
|
||||
<string name="i_agree">Jeg accepterer</string>
|
||||
<string name="empty_list">Denne liste er tom</string>
|
||||
<string name="instance_signup_closed">Denne server er ikke åben for nye tilmeldinger.</string>
|
||||
<string name="instance_signup_closed">Denne server accepterer ikke nye tilmeldinger.</string>
|
||||
<string name="text_copied">Kopieret til udklipsholderen</string>
|
||||
<string name="add_bookmark">Bogmærk</string>
|
||||
<string name="remove_bookmark">Fjern bogmærke</string>
|
||||
<string name="bookmarks">Bogmærker</string>
|
||||
<string name="your_favorites">Dine Favoritter</string>
|
||||
<string name="login_title">Velkommen tilbage</string>
|
||||
<string name="login_subtitle">Log ind med serveren hvor du oprettede din bruger.</string>
|
||||
<string name="login_subtitle">Log ind med serveren, på hvilken din konto blev oprettet.</string>
|
||||
<string name="server_url">Server-URL</string>
|
||||
<string name="signup_random_server_explain">En server baseret på dit sprog vælges, hvis du fortsætter uden selv at vælge.</string>
|
||||
<string name="server_filter_any_language">Hvilket som helst sprog</string>
|
||||
<string name="server_filter_instant_signup">Øjeblikkelig tilmelding</string>
|
||||
<string name="server_filter_manual_review">Manuel evaluering</string>
|
||||
@@ -305,6 +352,7 @@
|
||||
<string name="server_filter_region_oceania">Oceania</string>
|
||||
<string name="not_accepting_new_members">Ikke åben for nye medlemmer</string>
|
||||
<string name="category_special_interests">Særlige Interesser</string>
|
||||
<string name="signup_passwords_dont_match">Adgangskoder matcher ikke</string>
|
||||
<string name="pick_server_for_me">Vælg for mig</string>
|
||||
<string name="profile_add_row">Tilføj række</string>
|
||||
<string name="profile_setup">Profilopsætning</string>
|
||||
@@ -313,12 +361,14 @@
|
||||
<string name="popular_on_mastodon">Populært på Mastodon</string>
|
||||
<string name="follow_all">Følg alle</string>
|
||||
<string name="server_rules_disagree">Ikke enig</string>
|
||||
<string name="privacy_policy_explanation">TL;DR: Vi indsamler eller behandler ikke noget.</string>
|
||||
<!-- %s is server domain -->
|
||||
<string name="server_policy_disagree">Uenig med %s</string>
|
||||
<string name="profile_bio">Biografi</string>
|
||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||
<string name="sending_follows">Følger brugere …</string>
|
||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||
<string name="signup_email_domain_blocked">%1$s tillader ikke tilmeldinger fra %2$s. Prøv en anden eller <a>vælg en anden server</a>.</string>
|
||||
<string name="spoiler_show">Vis alligevel</string>
|
||||
<string name="spoiler_hide">Genskjul</string>
|
||||
<string name="poll_multiple_choice">Vælg en eller flere</string>
|
||||
@@ -331,21 +381,127 @@
|
||||
<string name="show">Vis</string>
|
||||
<string name="hide">Skjul</string>
|
||||
<string name="join_default_server">Tilmeld dig %s</string>
|
||||
<string name="pick_server">Vælg en anden server</string>
|
||||
<string name="signup_or_login">eller</string>
|
||||
<string name="learn_more">Få mere at vide</string>
|
||||
<string name="welcome_to_mastodon">Velkommen til Mastodon</string>
|
||||
<string name="welcome_paragraph1">Mastodon er et decentraliseret socialt netværk, hvilket betyder at ingen enkelt virksomhed styrer det. Det består af mange uafhængige servere, alle forbundet sammen.</string>
|
||||
<string name="what_are_servers">Hvad er servere?</string>
|
||||
<string name="welcome_paragraph2"><![CDATA[Alle Mastodon-konti har plads på en server. Hver server har sine egne værdier, regler og administratorer. Ligegyldigt hvilken server du vælger, kan du følge og interagere med folk på alle andre servere.]]></string>
|
||||
<string name="opening_link">Åbner link…</string>
|
||||
<string name="link_not_supported">Linket er ikke understøttet i appen</string>
|
||||
<string name="log_out_all_accounts">Log ud af alle konti</string>
|
||||
<string name="confirm_log_out_all_accounts">Log ud af alle konti?</string>
|
||||
<string name="retry">Forsøg igen</string>
|
||||
<string name="post_failed">Mislykkedes at indsende indlæg</string>
|
||||
<!-- %s is formatted file size ("467 KB image") -->
|
||||
<string name="attachment_description_image">%s billede</string>
|
||||
<string name="attachment_description_video">%s video</string>
|
||||
<string name="attachment_description_audio">%s lyd</string>
|
||||
<string name="attachment_description_unknown">%s fil</string>
|
||||
<string name="attachment_type_image">Billede</string>
|
||||
<string name="attachment_type_video">Video</string>
|
||||
<string name="attachment_type_audio">Lyd</string>
|
||||
<string name="attachment_type_gif">GIF</string>
|
||||
<string name="attachment_type_unknown">Fil</string>
|
||||
<string name="attachment_x_percent_uploaded">%d%% uploadet</string>
|
||||
<string name="add_poll_option">Tilføj afstemningsmulighed</string>
|
||||
<string name="poll_length">Afstemningslængde</string>
|
||||
<string name="poll_style">Stil</string>
|
||||
<string name="compose_poll_single_choice">Vælg én</string>
|
||||
<string name="compose_poll_multiple_choice">Multivalg</string>
|
||||
<string name="delete_poll_option">Slet afstemningsvalg</string>
|
||||
<string name="poll_style_title">Afstemningsstil</string>
|
||||
<string name="alt_text">Alt text</string>
|
||||
<string name="help">Hjælp</string>
|
||||
<string name="what_is_alt_text">Hvad er alt tekst?</string>
|
||||
<string name="alt_text_help">Alt tekst vil sige billedbeskrivelser til personer med synshandikap, forbindelser med lav båndbredde eller dem, som søger ekstra kontekst.\n\nMan kan forbedre tilgængelighed og forståelse for alle ved at skrive klar, kortfattet og objektiv alt-tekst.\n\n<ul><li>Fang vigtige elementer</li>\n<li>Opsummér tekst i billeder</li>\n<li>Brug regulær sætningsstruktur</li>\n<li>Undgå overflødig information</li>\n<li>Fokus på tendenser og vigtige fund i kompleks grafik (såsom diagrammer/kort)</li></ul></string>
|
||||
<string name="edit_post">Redigere opslag</string>
|
||||
<string name="no_verified_link">Intet bekræftet link</string>
|
||||
<string name="compose_autocomplete_emoji_empty">Gennemse emoji</string>
|
||||
<string name="compose_autocomplete_users_empty">Find den, man leder efter</string>
|
||||
<string name="no_search_results">Ingen resultater for disse søgeord</string>
|
||||
<string name="language">Sprog</string>
|
||||
<string name="language_default">Standard</string>
|
||||
<string name="language_system">System</string>
|
||||
<string name="language_detecting">Detektere sprog</string>
|
||||
<string name="language_cant_detect">Kan ikke detektere sprog</string>
|
||||
<string name="language_detected">Detekteret</string>
|
||||
<string name="media_hidden">Medie skjult</string>
|
||||
<string name="post_hidden">Indlæg skjult</string>
|
||||
<string name="report_title_post">Anmeld indlæg</string>
|
||||
<string name="forward_report_explanation">Kontoen er fra en anden server. Send også en anonymiseret kopi af anmeldelsen dertil?</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="forward_report_to_server">Videresend til %s</string>
|
||||
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->
|
||||
<string name="reported">Anmeldt</string>
|
||||
<string name="report_unfollow_explanation">For ikke længere at se vedkommendes indlæg i hjemmefeedet, ophør med at følge.</string>
|
||||
<string name="muted_user">Tavsgjorde %s</string>
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<!-- %1$s is the date (may be relative, e.g. "today" or "yesterday"), %2$s is the time. You can reorder these placeholders if that works better for your language -->
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="count_three">Tre</string>
|
||||
<string name="count_four">Fire</string>
|
||||
<string name="alt_text_reminder_post_anyway">Indlæg</string>
|
||||
<!-- %s is the username -->
|
||||
<string name="unfollow_confirmation">Følg ikke længere %s?</string>
|
||||
<string name="filter_active">Aktiv</string>
|
||||
<string name="filter_inactive">Inaktiv</string>
|
||||
<string name="settings_add_filter">Tilføj filter</string>
|
||||
<string name="settings_edit_filter">Redigér filter</string>
|
||||
<string name="settings_filter_duration">Varighed</string>
|
||||
<string name="settings_filter_muted_words">Tavsgjorte (skjulte) ord</string>
|
||||
<string name="settings_filter_context">Tavsgør fra</string>
|
||||
<string name="settings_filter_show_cw">Vis med indholdsadvarsel</string>
|
||||
<string name="settings_filter_show_cw_explanation">Viser stadig indlæg matchende dette filter, men bag en indholdsadvarsel</string>
|
||||
<string name="settings_delete_filter">Slet filter</string>
|
||||
<string name="filter_duration_forever">For evigt</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="settings_filter_ends">Slutter %s</string>
|
||||
<plurals name="settings_x_muted_words">
|
||||
<item quantity="one">%d tavsgjort (skjult) ord/sætning</item>
|
||||
<item quantity="other">%d tavsgjorte (skjulte) ord/sætninger</item>
|
||||
</plurals>
|
||||
<string name="selection_2_options">%1$s og %2$s</string>
|
||||
<string name="selection_3_options">%1$s, %2$s og %3$s</string>
|
||||
<string name="selection_4_or_more">%1$s, %2$s og %3$d flere</string>
|
||||
<string name="filter_context_home_lists">Hjem og lister</string>
|
||||
<string name="filter_context_notifications">Notifikationer</string>
|
||||
<string name="filter_context_public_timelines">Offentlige tidslinjer</string>
|
||||
<string name="filter_context_threads_replies">Tråde og svar</string>
|
||||
<string name="filter_context_profiles">Profiler</string>
|
||||
<string name="settings_filter_title">Titel</string>
|
||||
<string name="settings_delete_filter_title">Slet filter “%s”?</string>
|
||||
<string name="settings_delete_filter_confirmation">Dette filter slettes fra din konto på alle enheder.</string>
|
||||
<string name="add_muted_word">Tilføj tavsgjort (skjult) ord</string>
|
||||
<string name="edit_muted_word">Redigér tavsgjort (skjult) ord</string>
|
||||
<string name="add">Tilføj</string>
|
||||
<string name="filter_word_or_phrase">Ord/sætning</string>
|
||||
<string name="filter_add_word_help">Ord er versalfølsomme og matcher kun fulde ord.\n\nFiltreres nøgleordet “Apple,” vil det skjule indlæg indeholdende “apple” eller “aPpLe”, men ikke “pineapple”.</string>
|
||||
<string name="settings_delete_filter_word">Slet ordet “%s”?</string>
|
||||
<string name="enter_selection_mode">Vælg</string>
|
||||
<string name="select_all">Vælg alle</string>
|
||||
<string name="settings_filter_duration_title">Filtervarighed</string>
|
||||
<string name="filter_duration_custom">Tilpasset</string>
|
||||
<plurals name="settings_delete_x_filter_words">
|
||||
<item quantity="one">Slet %d ord?</item>
|
||||
<item quantity="other">Slet %d ord?</item>
|
||||
</plurals>
|
||||
<plurals name="x_items_selected">
|
||||
<item quantity="one">%d valgt</item>
|
||||
<item quantity="other">%d valgt</item>
|
||||
</plurals>
|
||||
<string name="required_form_field_blank">Obligatorisk felt</string>
|
||||
<string name="filter_word_already_in_list">Allerede på listen</string>
|
||||
<string name="app_update_ready">App-opdatering klar</string>
|
||||
<string name="app_update_version">Version %s</string>
|
||||
<string name="downloading_update">Downloader (%d%%)</string>
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<string name="post_matches_filter_x">Matcher filter “%s”</string>
|
||||
<string name="search_mastodon">Søg i Mastodon</string>
|
||||
<string name="clear_all">Ryd alle</string>
|
||||
<string name="search_open_url">Åbn URL i Mastodon</string>
|
||||
<string name="posts_matching_hashtag">Indlæg med “%s”</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
</resources>
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<string name="not_a_mastodon_instance">%s scheint kein Mastodon-Server zu sein.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="preparing_auth">Authentifizierung wird vorbereitet …</string>
|
||||
<string name="finishing_auth">Authentifizierung wird abgeschlossen …</string>
|
||||
<string name="user_boosted">%s hat geteilt</string>
|
||||
<string name="finishing_auth">Authentisierung wird abgeschlossen …</string>
|
||||
<string name="user_boosted">%s teilte</string>
|
||||
<string name="in_reply_to">Als Antwort auf %s</string>
|
||||
<string name="notifications">Benachrichtigungen</string>
|
||||
<string name="user_followed_you">%s folgt dir jetzt</string>
|
||||
@@ -143,7 +143,7 @@
|
||||
<string name="report_choose_posts_subtitle">Alles Zutreffende auswählen</string>
|
||||
<string name="report_comment_title">Gibt es weitere Anmerkungen, von denen wir wissen sollten?</string>
|
||||
<string name="report_comment_hint">Ergänzende Hinweise</string>
|
||||
<string name="sending_report">Meldung wird verschickt …</string>
|
||||
<string name="sending_report">Meldung wird gesendet …</string>
|
||||
<string name="report_sent_title">Danke für deine Meldung, wir werden uns damit beschäftigen.</string>
|
||||
<string name="report_sent_subtitle">Während wir den Vorfall überprüfen, kannst du gegen %s weitere Maßnahmen ergreifen:</string>
|
||||
<string name="unfollow_user">%s entfolgen</string>
|
||||
@@ -240,7 +240,7 @@
|
||||
<string name="followed_user">Du folgst nun %s</string>
|
||||
<string name="following_user_requested">Deine Follower-Anfrage an %s wurde gesendet</string>
|
||||
<string name="open_in_browser">Im Browser öffnen</string>
|
||||
<string name="hide_boosts_from_user">Geteilte Beiträge von %s verstecken</string>
|
||||
<string name="hide_boosts_from_user">Geteilte Beiträge von %s ausblenden</string>
|
||||
<string name="show_boosts_from_user">Geteilte Beiträge von %s anzeigen</string>
|
||||
<string name="signup_reason">Warum möchtest du beitreten?</string>
|
||||
<string name="signup_reason_note">Das erleichtert uns die Prüfung deiner Anmeldung.</string>
|
||||
@@ -250,7 +250,7 @@
|
||||
<string name="reorder">Neu sortieren</string>
|
||||
<string name="download">Herunterladen</string>
|
||||
<string name="permission_required">Berechtigung erforderlich</string>
|
||||
<string name="storage_permission_to_download">Die App benötigt Zugriff auf den Speicher deines Gerätes, um diese Datei zu speichern.</string>
|
||||
<string name="storage_permission_to_download">Die App benötigt Zugriff auf den Speicher deines Geräts, um diese Datei zu speichern.</string>
|
||||
<string name="open_settings">Einstellungen öffnen</string>
|
||||
<string name="error_saving_file">Fehler beim Speichern der Datei</string>
|
||||
<string name="file_saved">Datei gespeichert</string>
|
||||
@@ -278,8 +278,8 @@
|
||||
<item quantity="other">%,d folge ich</item>
|
||||
</plurals>
|
||||
<plurals name="x_favorites">
|
||||
<item quantity="one">%,d × favorisiert</item>
|
||||
<item quantity="other">%,d × favorisiert</item>
|
||||
<item quantity="one">einmal favorisiert</item>
|
||||
<item quantity="other">%,d-mal favorisiert</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="one">%,d geteilter Beitrag</item>
|
||||
@@ -332,7 +332,7 @@
|
||||
<string name="empty_list">Diese Liste ist leer</string>
|
||||
<string name="instance_signup_closed">Dieser Server akzeptiert keine neuen Registrierungen.</string>
|
||||
<string name="text_copied">In die Zwischenablage kopiert</string>
|
||||
<string name="add_bookmark">Lesezeichen hinzufügen</string>
|
||||
<string name="add_bookmark">Lesezeichen setzen</string>
|
||||
<string name="remove_bookmark">Lesezeichen entfernen</string>
|
||||
<string name="bookmarks">Lesezeichen</string>
|
||||
<string name="your_favorites">Deine Favoriten</string>
|
||||
|
||||
@@ -329,10 +329,23 @@
|
||||
<string name="sk_hashtag_timeline_local_only_switch">Nur lokale Beiträge anzeigen\?</string>
|
||||
<string name="sk_add_timeline_tag_error_empty">Hashtag darf nicht leer sein</string>
|
||||
<string name="sk_advanced_options_hide">Erweiterte Optionen ausblenden</string>
|
||||
<string name="sk_search_fediverse">Fediverse durchsuchen</string>
|
||||
<string name="sk_search_fediverse">Fediverse durchsuchen</string>
|
||||
<string name="sk_switch_timeline">Timeline wechseln</string>
|
||||
<string name="sk_settings_instance">Instanz</string>
|
||||
<string name="sk_disable_pill_shaped_active_indicator">Pillen-förmigen Indikator für aktiven Tab deaktivieren</string>
|
||||
<string name="sk_settings_true_black">Stockfinster-Modus</string>
|
||||
<string name="sk_gif_badge">GIF</string>
|
||||
<string name="sk_settings_unifiedpush">UnifiedPush verwenden</string>
|
||||
<string name="sk_settings_unifiedpush_no_distributor">Kein Verteiler gefunden</string>
|
||||
<string name="sk_settings_unifiedpush_no_distributor_body">Damit UnifiedPush-Benachrichtigungen funktionieren, muss ein Verteiler installiert sein. Mehr Informationen auf https://unifiedpush.org</string>
|
||||
<string name="sk_settings_display_pronouns_in_timelines">Pronomen in der Timeline anzeigen</string>
|
||||
<string name="sk_settings_continues_playback">Tonwiedergabe überlagern</string>
|
||||
<string name="sk_settings_continues_playback_summary">Musik im Hintergrund nicht pausieren, wenn in der App Medien abgespielt werden</string>
|
||||
<string name="sk_settings_unifiedpush_choose">Verteiler auswählen</string>
|
||||
<string name="sk_settings_display_pronouns_in_threads">Pronomen in Threads anzeigen</string>
|
||||
<string name="sk_settings_display_pronouns_in_user_listings">Pronomen in User-Auflistungen anzeigen</string>
|
||||
<string name="sk_tab_home">Start</string>
|
||||
<string name="sk_tab_search">Suche</string>
|
||||
<string name="sk_tab_notifications">Benachrichtigungen</string>
|
||||
<string name="sk_tab_profile">Profil</string>
|
||||
</resources>
|
||||
@@ -4,12 +4,18 @@
|
||||
<string name="next">Siguiente</string>
|
||||
<string name="loading_instance">Recuperando información del servidor…</string>
|
||||
<string name="error">Error</string>
|
||||
<string name="not_a_mastodon_instance">%s no parece ser un servidor de Mastodon.</string>
|
||||
<string name="ok">Aceptar</string>
|
||||
<string name="preparing_auth">Preparando para autenticación…</string>
|
||||
<string name="finishing_auth">Finalizando autenticación…</string>
|
||||
<string name="user_boosted">%s retooteó</string>
|
||||
<string name="in_reply_to">En respuesta a %s</string>
|
||||
<string name="notifications">Notificaciones</string>
|
||||
<string name="user_followed_you">%s te ha seguido</string>
|
||||
<string name="user_sent_follow_request">%s te envió una solicitud de seguimiento</string>
|
||||
<string name="user_favorited">%s ha marcado tu publicación como favorita</string>
|
||||
<string name="notification_boosted">%s ha impulsado tu publicación</string>
|
||||
<string name="poll_ended">Ver los resultados de una encuesta en la que votaste</string>
|
||||
<string name="share_toot_title">Compartir</string>
|
||||
<string name="settings">Ajustes</string>
|
||||
<string name="publish">Publicar</string>
|
||||
@@ -31,6 +37,7 @@
|
||||
<string name="button_follow">Seguir</string>
|
||||
<string name="button_following">Siguiendo</string>
|
||||
<string name="edit_profile">Editar perfil</string>
|
||||
<string name="share_user">Compartir perfil</string>
|
||||
<string name="mute_user">Silenciar a %s</string>
|
||||
<string name="unmute_user">Dejar de silenciar a %s</string>
|
||||
<string name="block_user">Bloquear a %s</string>
|
||||
@@ -78,6 +85,10 @@
|
||||
<item quantity="one">%d día restante</item>
|
||||
<item quantity="other">%d días restantes</item>
|
||||
</plurals>
|
||||
<plurals name="x_votes">
|
||||
<item quantity="one">%,d voto</item>
|
||||
<item quantity="other">%,d votos</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">Cerrado</string>
|
||||
<string name="confirm_mute_title">Silenciar cuenta</string>
|
||||
<string name="confirm_mute">Confirmar para silenciar a %s</string>
|
||||
@@ -96,27 +107,35 @@
|
||||
<string name="button_blocked">Bloqueado</string>
|
||||
<string name="action_vote">Votar</string>
|
||||
<string name="delete">Eliminar</string>
|
||||
<string name="confirm_delete_title">Eliminar publicación</string>
|
||||
<string name="confirm_delete">¿Confirma que quiere eliminar esta publicación?</string>
|
||||
<string name="deleting">Eliminando…</string>
|
||||
<string name="notification_channel_audio_player">Reproducción de audio</string>
|
||||
<string name="play">Reproducir</string>
|
||||
<string name="pause">Pausar</string>
|
||||
<string name="log_out">Cerrar sesión</string>
|
||||
<string name="add_account">Añadir cuenta</string>
|
||||
<string name="search_hint">Buscar</string>
|
||||
<string name="hashtags">Etiquetas</string>
|
||||
<string name="news">Noticias</string>
|
||||
<string name="for_you">Para ti</string>
|
||||
<string name="all_notifications">Todo</string>
|
||||
<string name="mentions">Menciones</string>
|
||||
<plurals name="x_people_talking">
|
||||
<item quantity="one">%d persona está hablando</item>
|
||||
<item quantity="other">%d personas están hablando</item>
|
||||
</plurals>
|
||||
<string name="report_title">Denunciar a %s</string>
|
||||
<string name="report_choose_reason">¿Qué hay de malo en esta publicación?</string>
|
||||
<string name="report_choose_reason_account">¿Qué hay de malo con %s?</string>
|
||||
<string name="report_choose_reason_subtitle">Seleccione la mejor opción</string>
|
||||
<string name="report_reason_personal">No me gusta</string>
|
||||
<string name="report_reason_personal_subtitle">No es algo que quieras ver</string>
|
||||
<string name="report_reason_spam">Es spam</string>
|
||||
<string name="report_reason_spam_subtitle">Enlaces maliciosos, interacciones falsas o respuestas repetitivas</string>
|
||||
<string name="report_reason_violation">Viola las reglas del servidor</string>
|
||||
<string name="report_reason_violation_subtitle">Eres consciente de que infringe normas específicas</string>
|
||||
<string name="report_reason_other">Es otra cosa</string>
|
||||
<string name="report_reason_other_subtitle">El problema no encaja en otras categorías</string>
|
||||
<string name="report_choose_rule">¿Qué normas se están violando?</string>
|
||||
<string name="report_choose_rule_subtitle">Selecciona todos los que correspondan</string>
|
||||
@@ -125,8 +144,14 @@
|
||||
<string name="report_comment_title">¿Hay algo más que deberíamos saber?</string>
|
||||
<string name="report_comment_hint">Comentarios adicionales</string>
|
||||
<string name="sending_report">Enviando denuncia…</string>
|
||||
<string name="report_sent_title">Gracias por reportar, lo revisaremos.</string>
|
||||
<string name="report_sent_subtitle">Mientras revisamos esto, puedes tomar medidas contra %s:</string>
|
||||
<string name="unfollow_user">Dejar de seguir a %s</string>
|
||||
<string name="unfollow">Dejar de seguir</string>
|
||||
<string name="mute_user_explain">No verás sus mensajes. Todavía pueden seguirte y ver tus mensajes y no sabrán que están silenciados.</string>
|
||||
<string name="block_user_explain">No verás sus mensajes. No podrán ver tus publicaciones ni seguirte. Podrán decir que están bloqueados.</string>
|
||||
<string name="report_personal_title">¿No quiere ver esto?</string>
|
||||
<string name="report_personal_subtitle">Aquí están tus opciones para controlar lo que ves en Mastodon:</string>
|
||||
<string name="back">Atrás</string>
|
||||
<string name="search_communities">Nombre del servidor o URL</string>
|
||||
<string name="instance_rules_title">Reglas del servidor</string>
|
||||
@@ -153,14 +178,19 @@
|
||||
<string name="category_tech">Tecnología</string>
|
||||
<string name="confirm_email_title">Revisa tu bandeja de entrada</string>
|
||||
<!-- %s is the email address -->
|
||||
<string name="confirm_email_subtitle">Pulsa el enlace que te hemos enviado para verificar %s. Esperaremos aquí mismo.</string>
|
||||
<string name="confirm_email_didnt_get">¿No recibiste un enlace?</string>
|
||||
<string name="resend">Reenviar</string>
|
||||
<string name="open_email_app">Abrir aplicación de email</string>
|
||||
<string name="resent_email">Correo de confirmación enviado</string>
|
||||
<string name="compose_hint">Escribe o pega lo que tengas en mente</string>
|
||||
<string name="content_warning">Advertencia de contenido</string>
|
||||
<string name="save">Guardar</string>
|
||||
<string name="add_alt_text">Añadir texto alternativo</string>
|
||||
<string name="visibility_public">Público</string>
|
||||
<string name="visibility_followers_only">Sólo seguidores</string>
|
||||
<string name="visibility_private">Solo personas mencionadas</string>
|
||||
<string name="recent_searches">Recientes</string>
|
||||
<string name="skip">Saltar</string>
|
||||
<string name="notification_type_follow">Nuevos seguidores</string>
|
||||
<string name="notification_type_favorite">Favoritos</string>
|
||||
@@ -169,8 +199,14 @@
|
||||
<string name="notification_type_poll">Encuestas</string>
|
||||
<string name="choose_account">Elegir cuenta</string>
|
||||
<string name="err_not_logged_in">Por favor inicie sesión primero en Mastodon</string>
|
||||
<plurals name="cant_add_more_than_x_attachments">
|
||||
<item quantity="one">No puede añadir más de %d archivo adjunto</item>
|
||||
<item quantity="other">No puede añadir más de %d archivos adjuntos</item>
|
||||
</plurals>
|
||||
<string name="media_attachment_unsupported_type">El archivo %s es de un tipo no compatible</string>
|
||||
<string name="media_attachment_too_big">El archivo %1$s supera el límite de tamaño de %2$s MB</string>
|
||||
<string name="settings_theme">Apariencia</string>
|
||||
<string name="theme_auto">Usar apariencia del dispositivo</string>
|
||||
<string name="theme_light">Claro</string>
|
||||
<string name="theme_dark">Oscuro</string>
|
||||
<string name="settings_behavior">Comportamiento</string>
|
||||
@@ -183,6 +219,9 @@
|
||||
<string name="settings_clear_cache">Limpiar caché multimedia</string>
|
||||
<string name="settings_app_version">Mastodon para Android -%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Caché multimedia borrada</string>
|
||||
<string name="confirm_log_out">¿Cerrar sesión de %s?</string>
|
||||
<string name="sensitive_content_explain">El autor ha marcado este medio como sensible.</string>
|
||||
<string name="avatar_description">Ir al perfil de %s</string>
|
||||
<string name="more_options">Más opciones</string>
|
||||
<string name="new_post">Nuevo post</string>
|
||||
<string name="button_reply">Responder</string>
|
||||
@@ -198,6 +237,7 @@
|
||||
<string name="media_viewer">Visor de medios</string>
|
||||
<string name="follow_user">Seguir a %s</string>
|
||||
<string name="unfollowed_user">No sigues a %s</string>
|
||||
<string name="followed_user">Ahora estás siguiendo a %s</string>
|
||||
<string name="following_user_requested">%s solicitó seguirte</string>
|
||||
<string name="open_in_browser">Abrir en el navegador</string>
|
||||
<string name="hide_boosts_from_user">Ocultar retoots de %s</string>
|
||||
@@ -215,7 +255,13 @@
|
||||
<string name="error_saving_file">Error al guardar el archivo</string>
|
||||
<string name="file_saved">Archivo guardado</string>
|
||||
<string name="downloading">Descargando…</string>
|
||||
<string name="no_app_to_handle_action">No hay ninguna aplicación para manejar esta acción</string>
|
||||
<string name="local_timeline">Local</string>
|
||||
<string name="trending_posts_info_banner">Estas son las publicaciones que están ganando tracción a través de Mastodon.</string>
|
||||
<string name="trending_links_info_banner">Estas son las noticias de las que se habla en Mastodon.</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="local_timeline_info_banner">Estos son todos los mensajes de todos los usuarios de tu servidor (%s).</string>
|
||||
<string name="recommended_accounts_info_banner">Es posible que te gusten estas cuentas basadas en otras que sigues.</string>
|
||||
<string name="see_new_posts">Ver nuevas publicaciones</string>
|
||||
<string name="load_missing_posts">Cargar publicaciones faltantes</string>
|
||||
<string name="follow_back">Seguir de vuelta</string>
|
||||
@@ -293,6 +339,7 @@
|
||||
<string name="login_title">Qué bueno verle de nuevo</string>
|
||||
<string name="login_subtitle">Inicie sesión con el servidor donde creó su cuenta.</string>
|
||||
<string name="server_url">URL del servidor</string>
|
||||
<string name="signup_random_server_explain">Seleccionaremos un servidor basado en tu idioma si continúas sin hacer una selección.</string>
|
||||
<string name="server_filter_any_language">Cualquier idioma</string>
|
||||
<string name="server_filter_instant_signup">Registro instantáneo</string>
|
||||
<string name="server_filter_manual_review">Revisión manual</string>
|
||||
@@ -305,6 +352,7 @@
|
||||
<string name="server_filter_region_oceania">Oceanía</string>
|
||||
<string name="not_accepting_new_members">No se aceptan nuevos miembros</string>
|
||||
<string name="category_special_interests">Intereses especiales</string>
|
||||
<string name="signup_passwords_dont_match">Las contraseñas no coinciden</string>
|
||||
<string name="pick_server_for_me">Elegir por mí</string>
|
||||
<string name="profile_add_row">Añadir fila</string>
|
||||
<string name="profile_setup">Configuración del perfil</string>
|
||||
@@ -313,12 +361,14 @@
|
||||
<string name="popular_on_mastodon">Popular en Mastodon</string>
|
||||
<string name="follow_all">Seguir a todos</string>
|
||||
<string name="server_rules_disagree">En desacuerdo</string>
|
||||
<string name="privacy_policy_explanation">Resumen: No recogemos ni procesamos nada.</string>
|
||||
<!-- %s is server domain -->
|
||||
<string name="server_policy_disagree">En desacuerdo con %s</string>
|
||||
<string name="profile_bio">Biografía</string>
|
||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||
<string name="sending_follows">Siguiendo usuarios…</string>
|
||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||
<string name="signup_email_domain_blocked">%1$s no permite registros de %2$s. Prueba uno diferente o <a>elige un servidor diferente</a>.</string>
|
||||
<string name="spoiler_show">Mostrar de todos modos</string>
|
||||
<string name="spoiler_hide">Volver a ocultar</string>
|
||||
<string name="poll_multiple_choice">Escoge una o más</string>
|
||||
@@ -338,15 +388,190 @@
|
||||
<string name="welcome_paragraph1">Mastodon es una red social descentralizada, lo que significa que no la controla una sola compañía. Está formada por muchos servidores independientes, todos juntos conectados.</string>
|
||||
<string name="what_are_servers">¿Qué son los servidores?</string>
|
||||
<string name="welcome_paragraph2"><![CDATA[Cada cuenta de Mastodon está alojada en un servidor — cada uno con sus propios valores, reglas y administradores. No importa cual elijas, puede seguir e interactuar con personas en cualquier servidor.]]></string>
|
||||
<string name="opening_link">Abriendo enlace…</string>
|
||||
<string name="link_not_supported">Este enlace no es compatible con la aplicación</string>
|
||||
<string name="log_out_all_accounts">Cerrar sesión en todas las cuentas</string>
|
||||
<string name="confirm_log_out_all_accounts">¿Cerrar sesión de todas las cuentas?</string>
|
||||
<string name="retry">Reintentar</string>
|
||||
<string name="post_failed">Error al enviar la publicación</string>
|
||||
<!-- %s is formatted file size ("467 KB image") -->
|
||||
<string name="attachment_description_image">Imagen %s</string>
|
||||
<string name="attachment_description_video">Vídeo %s</string>
|
||||
<string name="attachment_description_audio">Audio %s</string>
|
||||
<string name="attachment_description_unknown">Archivo %s</string>
|
||||
<string name="attachment_type_image">Imagen</string>
|
||||
<string name="attachment_type_video">Vídeo</string>
|
||||
<string name="attachment_type_audio">Audio</string>
|
||||
<string name="attachment_type_gif">GIF</string>
|
||||
<string name="attachment_type_unknown">Archivo</string>
|
||||
<string name="attachment_x_percent_uploaded">%d%% subido</string>
|
||||
<string name="add_poll_option">Añadir opción de encuesta</string>
|
||||
<string name="poll_length">Longitud de la encuesta</string>
|
||||
<string name="poll_style">Estilo</string>
|
||||
<string name="compose_poll_single_choice">Elige uno</string>
|
||||
<string name="compose_poll_multiple_choice">Múltiples opciones</string>
|
||||
<string name="delete_poll_option">Borrar opción de encuesta</string>
|
||||
<string name="poll_style_title">Estilo de encuesta</string>
|
||||
<string name="alt_text">Texto alternativo</string>
|
||||
<string name="help">Ayuda</string>
|
||||
<string name="what_is_alt_text">¿Qué es el texto alternativo?</string>
|
||||
<string name="edit_post">Editar publicación</string>
|
||||
<string name="no_verified_link">Enlace no verificado</string>
|
||||
<string name="compose_autocomplete_emoji_empty">Explorar emojis</string>
|
||||
<string name="compose_autocomplete_users_empty">Encuentra quién estás buscando</string>
|
||||
<string name="no_search_results">No se pudo encontrar nada para estos términos de búsqueda</string>
|
||||
<string name="language">Idioma</string>
|
||||
<string name="language_default">Predeterminado</string>
|
||||
<string name="language_system">Sistema</string>
|
||||
<string name="language_detecting">Detectando idioma</string>
|
||||
<string name="language_cant_detect">No se puede detectar el idioma</string>
|
||||
<string name="language_detected">Detectado</string>
|
||||
<string name="media_hidden">Medios ocultos</string>
|
||||
<string name="post_hidden">Publicación ocultada</string>
|
||||
<string name="report_title_post">Reportar publicación</string>
|
||||
<string name="forward_report_explanation">La cuenta es de otro servidor. ¿Enviar también una copia anónima de este informe?</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="forward_report_to_server">Reenviar a %s</string>
|
||||
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->
|
||||
<string name="reported">Reportado</string>
|
||||
<string name="muted_user">Silenciado %s</string>
|
||||
<string name="report_sent_already_blocked">Ya has bloqueado a este usuario, así que no tienes nada más que hacer mientras revisamos tu informe.</string>
|
||||
<string name="report_personal_already_blocked">Ya has bloqueado a este usuario, así que no tienes nada más que hacer.\n\n¡Gracias por ayudar a mantener Mastodon un lugar seguro para todos!</string>
|
||||
<string name="blocked_user">Bloqueado %s</string>
|
||||
<string name="mark_all_notifications_read">Marcar todo como leído</string>
|
||||
<string name="settings_display">Visualización</string>
|
||||
<string name="settings_filters">Filtros</string>
|
||||
<string name="settings_server_explanation">Resumen, reglas, moderadores</string>
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<string name="about_app">Acerca de %s</string>
|
||||
<string name="default_post_language">Idioma predeterminado de la publicación</string>
|
||||
<string name="settings_alt_text_reminders">Añadir recordatorios de texto alt</string>
|
||||
<string name="settings_confirm_unfollow">Preguntar antes de dejar de seguir a alguien</string>
|
||||
<string name="settings_confirm_boost">Preguntar antes de impulsar</string>
|
||||
<string name="settings_confirm_delete_post">Preguntar antes de eliminar mensajes</string>
|
||||
<string name="pause_all_notifications">Pausar todo</string>
|
||||
<string name="pause_notifications_off">Apagado</string>
|
||||
<string name="notifications_policy_anyone">Cualquiera</string>
|
||||
<string name="notifications_policy_followed">Personas que te siguen</string>
|
||||
<string name="notifications_policy_follower">Personas que sigues</string>
|
||||
<string name="notifications_policy_no_one">Nadie</string>
|
||||
<string name="settings_notifications_policy">Recibir notificaciones de</string>
|
||||
<string name="notification_type_mentions_and_replies">Menciones y respuestas</string>
|
||||
<string name="pause_all_notifications_title">Pausar todas las notificaciones</string>
|
||||
<plurals name="x_weeks">
|
||||
<item quantity="one">%d semana</item>
|
||||
<item quantity="other">%d semanas</item>
|
||||
</plurals>
|
||||
<!-- %1$s is the date (may be relative, e.g. "today" or "yesterday"), %2$s is the time. You can reorder these placeholders if that works better for your language -->
|
||||
<string name="date_at_time">%1$s en %2$s</string>
|
||||
<string name="today">hoy</string>
|
||||
<string name="yesterday">ayer</string>
|
||||
<string name="tomorrow">mañana</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_ends">Termina %s</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_banner">Las notificaciones se reanudarán %s.</string>
|
||||
<string name="resume_notifications_now">Reanudar ahora</string>
|
||||
<string name="open_system_notification_settings">Ir a la configuración de notificaciones</string>
|
||||
<string name="about_server">Acerca de</string>
|
||||
<string name="server_rules">Reglas</string>
|
||||
<string name="server_administrator">Administrador</string>
|
||||
<string name="notifications_disabled_in_system">Active las notificaciones desde la configuración de su dispositivo para ver actualizaciones desde cualquier lugar.</string>
|
||||
<string name="settings_even_more">Aún más ajustes</string>
|
||||
<string name="settings_show_cws">Mostrar advertencias de contenido</string>
|
||||
<plurals name="in_x_seconds">
|
||||
<item quantity="one">en %d segundo</item>
|
||||
<item quantity="other">en %d segundos</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_minutes">
|
||||
<item quantity="one">en %d minuto</item>
|
||||
<item quantity="other">en %d minutos</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="one">en %d hora</item>
|
||||
<item quantity="other">en %d horas</item>
|
||||
</plurals>
|
||||
<plurals name="x_hours_ago">
|
||||
<item quantity="one">hace %d hora</item>
|
||||
<item quantity="other">hace %d horas</item>
|
||||
</plurals>
|
||||
<string name="alt_text_reminder_title">Falta el texto alt de los medios</string>
|
||||
<plurals name="alt_text_reminder_x_images">
|
||||
<item quantity="one">%s de tus imágenes no tiene texto alternativo. ¿Publicar de todos modos?</item>
|
||||
<item quantity="other">%s de tus imágenes no tienen texto alternativo. ¿Publicar de todos modos?</item>
|
||||
</plurals>
|
||||
<plurals name="alt_text_reminder_x_attachments">
|
||||
<item quantity="one">%s de tus archivos adjuntos multimedia carece de texto alternativo. ¿Publicar de todos modos?</item>
|
||||
<item quantity="other">%s de tus archivos adjuntos no tienen texto alternativo. ¿Publicar de todos modos?</item>
|
||||
</plurals>
|
||||
<string name="count_one">Uno</string>
|
||||
<string name="count_two">Dos</string>
|
||||
<string name="count_three">Tres</string>
|
||||
<string name="count_four">Cuatro</string>
|
||||
<string name="alt_text_reminder_post_anyway">Publicar</string>
|
||||
<!-- %s is the username -->
|
||||
<string name="unfollow_confirmation">¿Dejar de seguir a %s?</string>
|
||||
<string name="filter_active">Activo</string>
|
||||
<string name="filter_inactive">Inactivo</string>
|
||||
<string name="settings_add_filter">Añadir filtro</string>
|
||||
<string name="settings_edit_filter">Editar filtro</string>
|
||||
<string name="settings_filter_duration">Duración</string>
|
||||
<string name="settings_filter_muted_words">Palabras silenciadas</string>
|
||||
<string name="settings_filter_context">Silenciar de</string>
|
||||
<string name="settings_filter_show_cw">Mostrar con advertencia de contenido</string>
|
||||
<string name="settings_filter_show_cw_explanation">Sigue mostrando mensajes que coinciden con este filtro, pero detrás de una advertencia de contenido</string>
|
||||
<string name="settings_delete_filter">Eliminar filtro</string>
|
||||
<string name="filter_duration_forever">Siempre</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="settings_filter_ends">Termina %s</string>
|
||||
<plurals name="settings_x_muted_words">
|
||||
<item quantity="one">%d palabra o frase silenciada</item>
|
||||
<item quantity="other">%d palabras o frases silenciadas</item>
|
||||
</plurals>
|
||||
<string name="selection_2_options">%1$s y %2$s</string>
|
||||
<string name="selection_3_options">%1$s, %2$s, y %3$s</string>
|
||||
<string name="selection_4_or_more">%1$s, %2$s, y %3$d más</string>
|
||||
<string name="filter_context_home_lists">Inicio y listas</string>
|
||||
<string name="filter_context_notifications">Notificaciones</string>
|
||||
<string name="filter_context_threads_replies">Hilos y respuestas</string>
|
||||
<string name="filter_context_profiles">Profiles</string>
|
||||
<string name="settings_filter_title">Título</string>
|
||||
<string name="settings_delete_filter_title">¿Eliminar filtro “%s”?</string>
|
||||
<string name="settings_delete_filter_confirmation">Este filtro se eliminará de su cuenta en todos sus dispositivos.</string>
|
||||
<string name="add_muted_word">Añadir palabra silenciada</string>
|
||||
<string name="edit_muted_word">Editar palabra silenciada</string>
|
||||
<string name="add">Añadir</string>
|
||||
<string name="filter_word_or_phrase">Palabra o frase</string>
|
||||
<string name="settings_delete_filter_word">¿Eliminar palabra “%s”?</string>
|
||||
<string name="enter_selection_mode">Seleccionar</string>
|
||||
<string name="select_all">Seleccionar todo</string>
|
||||
<string name="settings_filter_duration_title">Duración del filtro</string>
|
||||
<string name="filter_duration_custom">Personalizado</string>
|
||||
<plurals name="settings_delete_x_filter_words">
|
||||
<item quantity="one">¿Eliminar palabra %d?</item>
|
||||
<item quantity="other">¿Eliminar palabras %d?</item>
|
||||
</plurals>
|
||||
<plurals name="x_items_selected">
|
||||
<item quantity="one">%d seleccionado</item>
|
||||
<item quantity="other">%d seleccionados</item>
|
||||
</plurals>
|
||||
<string name="required_form_field_blank">No puede estar en blanco</string>
|
||||
<string name="filter_word_already_in_list">Ya está en la lista</string>
|
||||
<string name="app_update_ready">Actualización de aplicación lista</string>
|
||||
<string name="app_update_version">Versión %s</string>
|
||||
<string name="downloading_update">Descargando (%d%%)</string>
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<string name="post_matches_filter_x">Coincide con el filtro “%s”</string>
|
||||
<string name="search_mastodon">Buscar en Mastodon</string>
|
||||
<string name="clear_all">Limpiar todo</string>
|
||||
<string name="search_open_url">Abrir URL en Mastodon</string>
|
||||
<string name="posts_matching_hashtag">Publicaciones con “%s”</string>
|
||||
<string name="search_go_to_account">Ir a %s</string>
|
||||
<string name="posts_matching_string">Publicaciones con “%s”</string>
|
||||
<string name="accounts_matching_string">Personas con “%s”</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<string name="time_seconds_ago_short">hace %ds</string>
|
||||
<string name="time_minutes_ago_short">hace %dm</string>
|
||||
<string name="time_hours_ago_short">hace %dh</string>
|
||||
<string name="time_days_ago_short">hace %dd</string>
|
||||
</resources>
|
||||
|
||||
@@ -256,7 +256,7 @@
|
||||
<string name="sk_settings_collapse_long_posts">Minimizar publicaciones largas</string>
|
||||
<string name="sk_unfinished_attachments">¿Corregir adjuntos\?</string>
|
||||
<string name="sk_unfinished_attachments_message">Algunos adjuntos no han terminado de subirse.</string>
|
||||
<string name="sk_settings_prefix_reply_cw_with_re">Añadir \"re:\" a Advertencias de Contenido para</string>
|
||||
<string name="sk_settings_prefix_reply_cw_with_re">Prefijo CW con \"re:\" al responder</string>
|
||||
<string name="sk_spectator_mode">Modo espectador</string>
|
||||
<string name="sk_settings_hide_interaction">Ocultar los botones de interacción</string>
|
||||
<string name="sk_follow_as">Seguir desde otra cuenta</string>
|
||||
@@ -273,8 +273,8 @@
|
||||
<string name="sk_show_thread">Mostrar hilo</string>
|
||||
<string name="sk_compact_reblog_reply_line">Línea compacta compartida/respondida</string>
|
||||
<string name="sk_settings_confirm_before_reblog">Confirmación antes de impulsar</string>
|
||||
<string name="sk_reacted_with">reaccionó con %s</string>
|
||||
<string name="sk_reacted">reaccionó</string>
|
||||
<string name="sk_reacted_with">%1$s reaccionó con %2$s</string>
|
||||
<string name="sk_reacted">%s reaccionó</string>
|
||||
<string name="sk_content_type">Tipo del contenido</string>
|
||||
<string name="sk_content_type_unspecified">Sin especificar</string>
|
||||
<string name="sk_content_type_plain">Texto sin formato</string>
|
||||
@@ -292,18 +292,18 @@
|
||||
<string name="sk_external_share_or_open_title">Compartir o abrir con una cuenta</string>
|
||||
<string name="sk_open_in_app">Abrir en la app</string>
|
||||
<string name="sk_external_share_title">Compartir con una cuenta</string>
|
||||
<string name="sk_settings_auto_reveal_equal_spoilers">Mostrar Avisos de Contenido para respuestas de</string>
|
||||
<string name="sk_settings_auto_reveal_nobody">nadie</string>
|
||||
<string name="sk_settings_auto_reveal_author">autor</string>
|
||||
<string name="sk_settings_auto_reveal_anyone">todos</string>
|
||||
<string name="sk_settings_auto_reveal_equal_spoilers">Revelar automáticamente los CW iguales en las respuestas</string>
|
||||
<string name="sk_settings_auto_reveal_nobody">Nunca</string>
|
||||
<string name="sk_settings_auto_reveal_author">Respuestas del mismo autor</string>
|
||||
<string name="sk_settings_auto_reveal_anyone">Respuestas de todos</string>
|
||||
<string name="sk_open_in_app_failed">No se pudo abrir en la aplicación</string>
|
||||
<string name="sk_no_remote_info_hint">no hay información remota disponible</string>
|
||||
<string name="sk_error_loading_profile">No se pudo cargar el perfil a través de %s</string>
|
||||
<string name="sk_settings_allow_remote_loading">Cargar la información desde las instancias remotas</string>
|
||||
<string name="sk_settings_allow_remote_loading_explanation">Intenta obtener listas más precisas de seguidores, Me gusta y promociones cargando la información desde la instancia de origen.</string>
|
||||
<string name="sk_settings_prefix_replies_always">Todas</string>
|
||||
<string name="sk_settings_prefix_replies_never">Ninguna</string>
|
||||
<string name="sk_settings_prefix_replies_to_others">A otros</string>
|
||||
<string name="sk_settings_prefix_replies_always">Responder a cualquiera</string>
|
||||
<string name="sk_settings_prefix_replies_never">Nunca</string>
|
||||
<string name="sk_settings_prefix_replies_to_others">Solo en respuesta a otros</string>
|
||||
<string name="sk_settings_forward_report_default">\"Reenviar denuncia\" activado por defecto</string>
|
||||
<string name="sk_list_exclusive_switch">Hacer una lista exclusiva</string>
|
||||
<string name="sk_icon_feed">Cronología</string>
|
||||
@@ -328,4 +328,49 @@
|
||||
<string name="sk_edit_timeline_tags_explanation">Por favor, ten en cuenta que es el servidor el gestiona estas operaciones. Puede que no sea factible combinarlas.</string>
|
||||
<string name="sk_icon_beaker">Ciencia</string>
|
||||
<string name="sk_icon_bed">Cama</string>
|
||||
<string name="sk_gif_badge">GIF</string>
|
||||
<string name="sk_spoiler_show">Mostrar el contenido</string>
|
||||
<string name="sk_pronouns_label">Pronombres</string>
|
||||
<string name="sk_switch_timeline">Cambiar la línea de tiempo</string>
|
||||
<string name="sk_settings_instance">Instancia</string>
|
||||
<string name="sk_disable_pill_shaped_active_indicator">Desactivar el indicador de pestaña activa en forma de pastilla</string>
|
||||
<string name="sk_settings_true_black">Modo negro intenso</string>
|
||||
<string name="sk_search_fediverse">Buscar en el Fediverso</string>
|
||||
<string name="sk_settings_unifiedpush_choose">Selecciona un distribuidor</string>
|
||||
<string name="sk_settings_unifiedpush_no_distributor">No se ha encontrado ningún distribuidor</string>
|
||||
<string name="sk_settings_display_pronouns_in_user_listings">Mostrar pronombres en los listados de usuarios</string>
|
||||
<string name="sk_tab_home">Inicio</string>
|
||||
<string name="sk_tab_search">Buscar</string>
|
||||
<string name="sk_tab_notifications">Notificaciones</string>
|
||||
<string name="sk_tab_profile">Perfil</string>
|
||||
<string name="sk_mute_label">Duración</string>
|
||||
<string name="sk_duration_indefinite">Indefinido</string>
|
||||
<string name="sk_duration_minutes_5">5 minutos</string>
|
||||
<string name="sk_duration_minutes_30">30 minutos</string>
|
||||
<string name="sk_duration_hours_1">1 hora</string>
|
||||
<string name="sk_duration_hours_6">6 horas</string>
|
||||
<string name="sk_duration_days_1">1 día</string>
|
||||
<string name="sk_duration_days_3">3 días</string>
|
||||
<string name="sk_duration_days_7">7 días</string>
|
||||
<string name="sk_notification_mention">Has sido mencionado por %s</string>
|
||||
<string name="sk_settings_continues_playback">Superposición del audio</string>
|
||||
<string name="sk_settings_continues_playback_summary">Permitir que los medios que ya se están reproduciendo sigan reproduciéndose, superponiéndose a la nueva reproducción</string>
|
||||
<string name="sk_settings_unifiedpush">Usar UnifiedPush</string>
|
||||
<string name="sk_settings_unifiedpush_no_distributor_body">Es necesario instalar un distribuidor para que funcionen las notificaciones de UnifiedPush. Para obtener más información, visita https://unifiedpush.org/</string>
|
||||
<string name="sk_settings_display_pronouns_in_timelines">Mostrar pronombres en líneas de tiempo</string>
|
||||
<string name="sk_settings_display_pronouns_in_threads">Mostrar pronombres en los hilos</string>
|
||||
<string name="sk_settings_show_labels_in_navigation_bar">Mostrar las etiquetas de las pestañas en la barra de navegación</string>
|
||||
<string name="sk_settings_emoji_reactions_in_lists">Mostrar las reacciones con los emoticonos en las líneas de tiempo</string>
|
||||
<plurals name="sk_users_reacted_with">
|
||||
<item quantity="one">Un usuario reaccionó con %2$s</item>
|
||||
<item quantity="many">%1$,d usuarios reaccionaron con %2$s</item>
|
||||
<item quantity="other">%1$,d usuarios reaccionaron con %2$s</item>
|
||||
</plurals>
|
||||
<string name="sk_enter_emoji_toast">Necesitas escribir un emoticono</string>
|
||||
<string name="sk_enter_emoji_hint">Escribe para reaccionar con un emoticono</string>
|
||||
<string name="sk_settings_emoji_reactions">Activar las reacciones con los emoticonos</string>
|
||||
<string name="sk_settings_emoji_reactions_explanation">Muestra las reacciones con los emoticonos a los mensajes y te permite interactuar con ellos. Algunas versiones modificadas de Mastodon lo soportan, pero Mastodon no.</string>
|
||||
<string name="sk_settings_emoji_reactions_in_lists_explanation">Las reacciones con los emoticonos deben mostrarse en las líneas de tiempo. Si esta opción está desactivada, las reacciones con los emoticonos solo se mostrarán al ver un hilo.</string>
|
||||
<string name="sk_button_react">Reacciona con un emoticono</string>
|
||||
<string name="sk_again_for_system_keyboard">Pulsa de nuevo para el Teclado del sistema</string>
|
||||
</resources>
|
||||
@@ -4,9 +4,11 @@
|
||||
<string name="next">Hurrengoa</string>
|
||||
<string name="loading_instance">Zerbitzariaren informazioa berreskuratzen…</string>
|
||||
<string name="error">Errorea</string>
|
||||
<string name="not_a_mastodon_instance">%s(e)k ez dirudi Mastodon instantzia bat denik.</string>
|
||||
<string name="ok">Ados</string>
|
||||
<string name="preparing_auth">Autentifikaziorako prestatzen…</string>
|
||||
<string name="finishing_auth">Autentikazioa bukatzen…</string>
|
||||
<string name="user_boosted">%s(e)k bultzatu du</string>
|
||||
<string name="in_reply_to">%s-(r)i erantzunez</string>
|
||||
<string name="notifications">Jakinarazpenak</string>
|
||||
<string name="share_toot_title">Partekatu</string>
|
||||
@@ -95,27 +97,35 @@
|
||||
<string name="button_blocked">Blokeatuta</string>
|
||||
<string name="action_vote">Bozkatu</string>
|
||||
<string name="delete">Ezabatu</string>
|
||||
<string name="confirm_delete_title">Ezabatu bidalketa</string>
|
||||
<string name="confirm_delete">Ziur bidalketa hau ezabatu nahi duzula?</string>
|
||||
<string name="deleting">Ezabatzen…</string>
|
||||
<string name="notification_channel_audio_player">Audioa erreproduzitzen</string>
|
||||
<string name="play">Jo</string>
|
||||
<string name="pause">Pausatu</string>
|
||||
<string name="log_out">Itxi saioa</string>
|
||||
<string name="add_account">Gehitu kontua</string>
|
||||
<string name="search_hint">Bilatu</string>
|
||||
<string name="hashtags">Traolak</string>
|
||||
<string name="news">Berriak</string>
|
||||
<string name="for_you">Zuretzat</string>
|
||||
<string name="all_notifications">Dena</string>
|
||||
<string name="mentions">Aipamenak</string>
|
||||
<plurals name="x_people_talking">
|
||||
<item quantity="one">Pertsona %d hizketan</item>
|
||||
<item quantity="other">%d pertsona hizketan</item>
|
||||
</plurals>
|
||||
<string name="report_title">Salatu %s</string>
|
||||
<string name="report_choose_reason">Zer du txarra argitalpen honek?</string>
|
||||
<string name="report_choose_reason_account">Zer du txarra %s?</string>
|
||||
<string name="report_choose_reason_subtitle">Aukeratu egokiena</string>
|
||||
<string name="report_reason_personal">Ez dut gustukoa</string>
|
||||
<string name="report_reason_personal_subtitle">Ikusi nahi ez dudan zerbait da</string>
|
||||
<string name="report_reason_spam">Spama da</string>
|
||||
<string name="report_reason_spam_subtitle">Esteka maltzurrak, gezurrezko elkarrekintzak edo erantzun errepikakorrak</string>
|
||||
<string name="report_reason_violation">Zerbitzariaren arauak hausten ditu</string>
|
||||
<string name="report_reason_violation_subtitle">Arau zehatzak urratzen dituela badakizu</string>
|
||||
<string name="report_reason_other">Beste zerbait da</string>
|
||||
<string name="report_reason_other_subtitle">Arazoa ezin da beste kategorietan sailkatu</string>
|
||||
<string name="report_choose_rule">Ze arau hautsi ditu?</string>
|
||||
<string name="report_choose_rule_subtitle">Hautatu dagozkion guztiak</string>
|
||||
@@ -124,8 +134,11 @@
|
||||
<string name="report_comment_title">Beste zerbait jakin beharko genuke?</string>
|
||||
<string name="report_comment_hint">Iruzkin gehigarriak</string>
|
||||
<string name="sending_report">Txostena bidaltzen…</string>
|
||||
<string name="report_sent_title">Mila esker salaketagatik, berrikusiko dugu.</string>
|
||||
<string name="unfollow_user">%s jarraitzeari utzi</string>
|
||||
<string name="unfollow">Utzi jarraitzeari</string>
|
||||
<string name="report_personal_title">Ez duzu hau ikusi nahi?</string>
|
||||
<string name="report_personal_subtitle">Hemen dituzu Mastodonen ikusiko duzuna kontrolatzeko aukerak:</string>
|
||||
<string name="back">Atzera</string>
|
||||
<string name="search_communities">Zerbitzari izena edo URLa</string>
|
||||
<string name="instance_rules_title">Zerbitzariaren arauak</string>
|
||||
@@ -151,23 +164,34 @@
|
||||
<string name="category_tech">Teknologia</string>
|
||||
<string name="confirm_email_title">Egiaztatu zure sarrerako ontzia</string>
|
||||
<!-- %s is the email address -->
|
||||
<string name="confirm_email_didnt_get">Ez duzu estekarik jaso?</string>
|
||||
<string name="resend">Berbidali</string>
|
||||
<string name="open_email_app">Ireki eposta aplikazioa</string>
|
||||
<string name="resent_email">Berretzi eposta bidaltzea</string>
|
||||
<string name="compose_hint">Idatzi edo itsatsi buruan duzuna</string>
|
||||
<string name="content_warning">Edukiaren abisua</string>
|
||||
<string name="save">Gorde</string>
|
||||
<string name="add_alt_text">Gehitu ordezko testua</string>
|
||||
<string name="visibility_public">Publikoa</string>
|
||||
<string name="visibility_followers_only">Jarraitzaileak soilik</string>
|
||||
<string name="visibility_private">Aipatzen dudan jendea soilik</string>
|
||||
<string name="recent_searches">Azkenaldikoak</string>
|
||||
<string name="skip">Saltatu</string>
|
||||
<string name="notification_type_follow">Jarraitzaile berriak</string>
|
||||
<string name="notification_type_favorite">Gogokoak</string>
|
||||
<string name="notification_type_reblog">Bultzadak</string>
|
||||
<string name="notification_type_mention">Aipamenak</string>
|
||||
<string name="notification_type_poll">Inkestak</string>
|
||||
<string name="choose_account">Aukeratu kontua</string>
|
||||
<string name="err_not_logged_in">Mesedez, hasi saioa lehenengo Mastodonen</string>
|
||||
<plurals name="cant_add_more_than_x_attachments">
|
||||
<item quantity="one">Ezin duzu multimedia fitxategi %d baino gehiago gehitu</item>
|
||||
<item quantity="other">Ezin dituzu %d baino multimedia fitxategi gehiago gehitu</item>
|
||||
</plurals>
|
||||
<string name="media_attachment_unsupported_type">%s fitxategi mota ez da bateragarria</string>
|
||||
<string name="media_attachment_too_big">%1$s fitxategiak %2$s MB-eko tamainaren muga gainditzen du</string>
|
||||
<string name="settings_theme">Itxura</string>
|
||||
<string name="theme_auto">Erabili sistemaren diseinua</string>
|
||||
<string name="theme_light">Argia</string>
|
||||
<string name="theme_dark">Iluna</string>
|
||||
<string name="settings_behavior">Jokabidea</string>
|
||||
@@ -180,9 +204,13 @@
|
||||
<string name="settings_clear_cache">Garbitu multimediaren cachea</string>
|
||||
<string name="settings_app_version">Mastodon Android-entzat v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Multimediaren cachea garbitua</string>
|
||||
<string name="confirm_log_out">Itxi saioa %s?</string>
|
||||
<string name="sensitive_content_explain">Egileak multimedia hau hunkigarritzat markatu du.</string>
|
||||
<string name="avatar_description">Joan %s-(r)en profilera</string>
|
||||
<string name="more_options">Aukera gehiago</string>
|
||||
<string name="new_post">Bidalketa berria</string>
|
||||
<string name="button_reply">Erantzun</string>
|
||||
<string name="button_reblog">Bultzada</string>
|
||||
<string name="button_favorite">Gogokoa</string>
|
||||
<string name="button_share">Partekatu</string>
|
||||
<string name="media_no_description">Deskribapenik gabeko multimedia</string>
|
||||
@@ -194,6 +222,7 @@
|
||||
<string name="media_viewer">Multimedia ikuskatzailea</string>
|
||||
<string name="follow_user">Jarraitu %s</string>
|
||||
<string name="unfollowed_user">Utzi %s jarraitzeari</string>
|
||||
<string name="followed_user">%s jarraitzen ari zara</string>
|
||||
<string name="open_in_browser">Ireki nabigatzailean</string>
|
||||
<string name="signup_reason">Zergatik elkartu nahi duzu?</string>
|
||||
<string name="signup_reason_note">Honek zure eskaera berrikustean lagunduko digu.</string>
|
||||
@@ -208,6 +237,9 @@
|
||||
<string name="error_saving_file">Errorea fitxategia gordetzerakoan</string>
|
||||
<string name="file_saved">Fitxategia gorde da</string>
|
||||
<string name="downloading">Jeisten…</string>
|
||||
<string name="no_app_to_handle_action">Ez dago ekintza hau kudeatu dezkeen aplikaziorik</string>
|
||||
<string name="local_timeline">Lokala</string>
|
||||
<string name="trending_posts_info_banner">Hauek dira zure Mastodon txokoan beraien lekua hartzen ari diren argitalpenak.</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="see_new_posts">Ikusi bidalketa berriak</string>
|
||||
<string name="load_missing_posts">Falta diren bidalketak kargatu</string>
|
||||
@@ -290,22 +322,118 @@
|
||||
<string name="server_filter_region_asia">Asia</string>
|
||||
<string name="server_filter_region_oceania">Ozeania</string>
|
||||
<string name="not_accepting_new_members">Ez da kide berririk onartzen</string>
|
||||
<string name="signup_passwords_dont_match">Pasahitzak ez datoz bat</string>
|
||||
<string name="pick_server_for_me">Aukeratu niretzat</string>
|
||||
<string name="profile_add_row">Gehitu errenkada</string>
|
||||
<string name="popular_on_mastodon">Mastodonen pil-pilean</string>
|
||||
<string name="follow_all">Jarraitu denak</string>
|
||||
<string name="server_rules_disagree">Ez ados</string>
|
||||
<!-- %s is server domain -->
|
||||
<string name="profile_bio">Biografia</string>
|
||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||
<string name="spoiler_show">Erakutsi hala ere</string>
|
||||
<string name="poll_multiple_choice">Aukeratu bat edo gehiago</string>
|
||||
<string name="save_changes">Gorde aldaketak</string>
|
||||
<string name="profile_featured">Nabarmenak</string>
|
||||
<string name="profile_timeline">Denbora-lerroa</string>
|
||||
<string name="view_all">Ikusi guztia</string>
|
||||
<string name="profile_endorsed_accounts">Kontuak</string>
|
||||
<string name="show">Erakutsi</string>
|
||||
<string name="hide">Ezkutatu</string>
|
||||
<string name="pick_server">Aukeratu beste zerbitzari bat</string>
|
||||
<string name="signup_or_login">edo</string>
|
||||
<string name="learn_more">Ikasi gehiago</string>
|
||||
<string name="welcome_to_mastodon">Ongi etorri Mastodon-era</string>
|
||||
<string name="what_are_servers">Zer dira zerbitzariak?</string>
|
||||
<string name="opening_link">Lotura irekitzen…</string>
|
||||
<string name="retry">Berriro saiatu</string>
|
||||
<!-- %s is formatted file size ("467 KB image") -->
|
||||
<string name="attachment_type_image">Irudia</string>
|
||||
<string name="attachment_type_video">Bideoa</string>
|
||||
<string name="attachment_type_audio">Audioa</string>
|
||||
<string name="attachment_type_gif">GIF-a</string>
|
||||
<string name="attachment_type_unknown">Fitxategia</string>
|
||||
<string name="add_poll_option">Gehitu inkesta aukera</string>
|
||||
<string name="poll_style">Estiloa</string>
|
||||
<string name="compose_poll_single_choice">Aukeratu bat</string>
|
||||
<string name="compose_poll_multiple_choice">Aukera anitza</string>
|
||||
<string name="delete_poll_option">Ezabatu inkesta aukera</string>
|
||||
<string name="help">Laguntza</string>
|
||||
<string name="edit_post">Editatu argitalpena</string>
|
||||
<string name="compose_autocomplete_emoji_empty">Esploratu emojiak</string>
|
||||
<string name="language">Hizkuntza</string>
|
||||
<string name="language_default">Lehenetsia</string>
|
||||
<string name="language_system">Sistema</string>
|
||||
<string name="language_detecting">Hizkuntza detektatzen</string>
|
||||
<string name="language_cant_detect">Ezin da hizkuntza detektatu</string>
|
||||
<string name="language_detected">Detektatuta</string>
|
||||
<string name="media_hidden">Multimedia ezkutatua</string>
|
||||
<!-- %s is the server domain -->
|
||||
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->
|
||||
<string name="reported">Salatua</string>
|
||||
<string name="muted_user">Mututu %s</string>
|
||||
<string name="blocked_user">Blokeatu %s</string>
|
||||
<string name="mark_all_notifications_read">Markatu denak irakurrita bezala</string>
|
||||
<string name="settings_display">Bistaratzea</string>
|
||||
<string name="settings_filters">Iragazkiak</string>
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<string name="about_app">%s(r)i buruz</string>
|
||||
<string name="pause_all_notifications">Pausatu denak</string>
|
||||
<string name="pause_notifications_off">Itzali</string>
|
||||
<string name="notifications_policy_anyone">Edozein</string>
|
||||
<string name="notifications_policy_followed">Zu jarraitzen zaituzten pertsonak</string>
|
||||
<string name="notifications_policy_follower">Zuk jarraitzen dituzun pertsonak</string>
|
||||
<string name="notifications_policy_no_one">Bat ere ez</string>
|
||||
<string name="pause_all_notifications_title">Pausatu jakinarazpen guztiak</string>
|
||||
<!-- %1$s is the date (may be relative, e.g. "today" or "yesterday"), %2$s is the time. You can reorder these placeholders if that works better for your language -->
|
||||
<string name="today">gaur</string>
|
||||
<string name="yesterday">atzo</string>
|
||||
<string name="tomorrow">bihar</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="about_server">Honi buruz</string>
|
||||
<string name="server_rules">Arauak</string>
|
||||
<string name="server_administrator">Administratzailea</string>
|
||||
<string name="settings_show_cws">Erakutsi eduki abisuak</string>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="one">Ordu %d barru</item>
|
||||
<item quantity="other">%d ordu barru</item>
|
||||
</plurals>
|
||||
<string name="count_one">Bat</string>
|
||||
<string name="count_two">Bi</string>
|
||||
<string name="count_three">Hiru</string>
|
||||
<string name="count_four">Lau</string>
|
||||
<string name="alt_text_reminder_post_anyway">Bidalketa</string>
|
||||
<!-- %s is the username -->
|
||||
<string name="unfollow_confirmation">%s jarraitzeari utzi?</string>
|
||||
<string name="filter_active">Aktiboa</string>
|
||||
<string name="filter_inactive">Ez aktiboa</string>
|
||||
<string name="settings_add_filter">Gehitu iragazkia</string>
|
||||
<string name="settings_edit_filter">Editatu iragazkia</string>
|
||||
<string name="settings_filter_duration">Iraupena</string>
|
||||
<string name="settings_filter_muted_words">Mutututako hitzak</string>
|
||||
<string name="settings_filter_show_cw">Erakutsi eduki abisuarekin</string>
|
||||
<string name="settings_delete_filter">Ezabatu iragazkia</string>
|
||||
<string name="filter_duration_forever">Betirakoa</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="selection_2_options">%1$s eta %2$s</string>
|
||||
<string name="selection_3_options">%1$s, %2$s, eta %3$s</string>
|
||||
<string name="selection_4_or_more">%1$s, %2$s, eta beste %3$d</string>
|
||||
<string name="filter_context_notifications">Jakinarazpenak</string>
|
||||
<string name="filter_context_public_timelines">Denbora-lerro publikoak</string>
|
||||
<string name="filter_context_profiles">Profilak</string>
|
||||
<string name="settings_filter_title">Izenburua</string>
|
||||
<string name="settings_delete_filter_title">Ezabatu \"%s\" iragazkia”?</string>
|
||||
<string name="add">Gehitu</string>
|
||||
<string name="enter_selection_mode">Hautatu</string>
|
||||
<string name="select_all">Hautatu dena</string>
|
||||
<string name="filter_duration_custom">Pertsonalizatua</string>
|
||||
<string name="required_form_field_blank">Ezin da hutsik egon</string>
|
||||
<string name="app_update_version">Bertsioa: %s</string>
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<string name="search_mastodon">Bilatu Mastodonen</string>
|
||||
<string name="clear_all">Garbitu dena</string>
|
||||
<string name="search_open_url">Ireki URLa Mastodonen</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
</resources>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<string name="cancel">لغو</string>
|
||||
<plurals name="followers">
|
||||
<item quantity="one">پیگیر</item>
|
||||
<item quantity="other">پیگیران</item>
|
||||
<item quantity="other">پیگیرندگان</item>
|
||||
</plurals>
|
||||
<plurals name="following">
|
||||
<item quantity="one">پیگرفته</item>
|
||||
@@ -188,11 +188,11 @@
|
||||
<string name="save">ذخیره</string>
|
||||
<string name="add_alt_text">اضافه کردن متن جایگزین</string>
|
||||
<string name="visibility_public">عمومی</string>
|
||||
<string name="visibility_followers_only">فقط پیگیران</string>
|
||||
<string name="visibility_followers_only">فقط پیگیرندگان</string>
|
||||
<string name="visibility_private">فقط افرادی نامبرده</string>
|
||||
<string name="recent_searches">اخیر</string>
|
||||
<string name="skip">بعدی</string>
|
||||
<string name="notification_type_follow">پیگیران جدید</string>
|
||||
<string name="notification_type_follow">پیگیرندگان جدید</string>
|
||||
<string name="notification_type_favorite">برگزیدهها</string>
|
||||
<string name="notification_type_reblog">تقویتها</string>
|
||||
<string name="notification_type_mention">نامبردنها</string>
|
||||
@@ -271,7 +271,7 @@
|
||||
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
|
||||
<plurals name="x_followers">
|
||||
<item quantity="one">%,d پیگیر</item>
|
||||
<item quantity="other">%,d پیگیران</item>
|
||||
<item quantity="other">%,d پیگیرندگان</item>
|
||||
</plurals>
|
||||
<plurals name="x_following">
|
||||
<item quantity="one">%,d پیگیرنده</item>
|
||||
@@ -419,6 +419,7 @@
|
||||
<string name="edit_post">ویرایش فرسته</string>
|
||||
<string name="no_verified_link">پیوند تأییدشدهای وجود ندارد</string>
|
||||
<string name="compose_autocomplete_emoji_empty">مرور ایموجی</string>
|
||||
<string name="compose_autocomplete_users_empty">پیدا کنید آنچه را که به دنبال آن هستید</string>
|
||||
<string name="no_search_results">چیزی برای این عبارت جستوجو یافت نشد</string>
|
||||
<string name="language">زبان</string>
|
||||
<string name="language_default">پیشگزیده</string>
|
||||
@@ -479,7 +480,10 @@
|
||||
<string name="server_administrator">مدیر</string>
|
||||
<string name="send_email_to_server_admin">ادمین پیام بده</string>
|
||||
<string name="notifications_disabled_in_system">آگاهیها را از تنظیمات دستگاهتان روشن کنید تا بهروزرسانیها را از هر کجا ببینید.</string>
|
||||
<string name="settings_even_more">تنظیمات بیشتر</string>
|
||||
<string name="settings_show_cws">نمایش هشدارهای محتوا</string>
|
||||
<string name="settings_hide_sensitive_media">تصویرهایی را که به عنوان حساس علامت زده شدهاند پنهان کن</string>
|
||||
<string name="settings_show_interaction_counts">تعامل شمارش پست</string>
|
||||
<string name="settings_show_emoji_in_names">ایموجیهای سفارشی در نام های نمایشی</string>
|
||||
<plurals name="in_x_seconds">
|
||||
<item quantity="one">در %d ثانیه</item>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user