Compare commits
87 Commits
v1.1.4+for
...
v1.1.4+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0b9006c55 | ||
|
|
4bc14ef797 | ||
|
|
47d2cee3f1 | ||
|
|
088f53f5a9 | ||
|
|
fee660bf6c | ||
|
|
e97ecb89a9 | ||
|
|
1ab6a4532b | ||
|
|
b43ddd0d8b | ||
|
|
d0c4c2d594 | ||
|
|
e0ae079ea0 | ||
|
|
dfddbd15a9 | ||
|
|
29242c45a1 | ||
|
|
7ff0e59f4d | ||
|
|
2d0fe57a47 | ||
|
|
ba2b87749b | ||
|
|
0806af1261 | ||
|
|
09e92f3a18 | ||
|
|
eb5d0bb795 | ||
|
|
a8afba4067 | ||
|
|
7d66141c37 | ||
|
|
b6f3ea2eec | ||
|
|
2570445133 | ||
|
|
acbd22cf22 | ||
|
|
ef251b040a | ||
|
|
6c5bb69ba9 | ||
|
|
7599406449 | ||
|
|
670e4c8538 | ||
|
|
30458b115c | ||
|
|
da8933ec58 | ||
|
|
dc8ac51c83 | ||
|
|
c4747fdc72 | ||
|
|
58ba748ade | ||
|
|
c0d51ad58a | ||
|
|
a0da73f76f | ||
|
|
34b8888c8f | ||
|
|
74ad40f67c | ||
|
|
a7a29db8d5 | ||
|
|
86a938d31d | ||
|
|
d8d0830631 | ||
|
|
bba3b7476a | ||
|
|
4880c642fe | ||
|
|
76ad896461 | ||
|
|
b49159f9e0 | ||
|
|
5f3645f716 | ||
|
|
5af96597d5 | ||
|
|
c2baf4e05f | ||
|
|
9e7923bc50 | ||
|
|
851bf94c90 | ||
|
|
ae80b7d098 | ||
|
|
e6bb319d8b | ||
|
|
3101f1ad17 | ||
|
|
4416dfcae3 | ||
|
|
924b974b4b | ||
|
|
5d1dc97ac3 | ||
|
|
5cce8ca72c | ||
|
|
f2a0680af0 | ||
|
|
6203ded864 | ||
|
|
17f1eb88e4 | ||
|
|
9a52cc033a | ||
|
|
4b16262a1a | ||
|
|
10e7cbf022 | ||
|
|
531b8ead04 | ||
|
|
4b2c94ab52 | ||
|
|
a98becf2f4 | ||
|
|
54f9eace67 | ||
|
|
e4c9eb089a | ||
|
|
0e635aec23 | ||
|
|
dc90c09cea | ||
|
|
06cb335a0a | ||
|
|
5a681d3557 | ||
|
|
4200486aeb | ||
|
|
62411a563f | ||
|
|
2cabe94ba0 | ||
|
|
4a6baae97a | ||
|
|
bb12a66781 | ||
|
|
efa9f524f9 | ||
|
|
be0c7777b7 | ||
|
|
92652f6fbd | ||
|
|
4ee781dfd5 | ||
|
|
bf8ac4bc69 | ||
|
|
a8e7840c04 | ||
|
|
c91ebda1ff | ||
|
|
e7dc5030d5 | ||
|
|
4cf55e23ba | ||
|
|
8159af0b58 | ||
|
|
5d056d5bea | ||
|
|
f500cc7ebf |
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Screenshots and screen recordings**
|
||||
If applicable, add screenshots (and screen recordings, if possible) to help explain your problem.
|
||||
|
||||
**Version**
|
||||
Megalodon version: [e.g. v1.1.4+fork.#]
|
||||
|
||||
**Additional context**
|
||||
- Does this issue also occur with the respective upstream release? (Please test using the respective `upstream-xxxxxx.apk` provided in [Releases](https://github.com/sk22/megalodon/releases)) No / Yes (`mastodon#…`)
|
||||
|
||||
> In this case, please consider filing an [upstream bug report](https://github.com/mastodon/mastodon-android/issues) instead. If this bug is seriously impacting your usage or you think I might want to try to fix it for Megalodon, feel free to still create this issue!
|
||||
|
||||
**Crash log**
|
||||
If you know your way around Android development tools, please consider attaching a crash log, if possible.
|
||||
20
.github/ISSUE_TEMPLATE/feature-ui-request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature-ui-request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature/UI request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
If applicable: a clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
10
.github/ISSUE_TEMPLATE/something-else.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/something-else.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: It's something else…
|
||||
about: Issues that can't be categorized as feature requests or bug reports
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
27
README.md
27
README.md
@@ -2,9 +2,11 @@
|
||||
|
||||
# Megalodon
|
||||
|
||||
[](https://translate.codeberg.org/engage/megalodon/)
|
||||
|
||||
> A fork of the [official Mastodon Android app](https://github.com/mastodon/mastodon-android) adding important features that are missing in the official app and possibly won’t ever be implemented, such as the federated timeline, unlisted posting, bookmarks and an image description viewer.
|
||||
|
||||
**Warning! [The latest version's integrated updater is broken](https://github.com/sk22/megalodon/issues/106) – I'll publish a fixed version ASAP! If you're not updating through Izzy's F-Droid repository (more sources to come, hopefully!), you'll have to download the upcoming release manually. Sorry about that!**
|
||||
**Warning! [A previous version's integrated updater was broken](https://github.com/sk22/megalodon/issues/106) – I already published a fixed version! If you're not updating through Izzy's F-Droid repository (more sources to come, hopefully!), you'll have to download the current release manually. Sorry about that!**
|
||||
|
||||
[](https://github.com/sk22/megalodon/releases/latest/download/megalodon.apk)
|
||||
|
||||
@@ -23,7 +25,7 @@ The Mastodon documentation has some more information about [Unlisted posting](ht
|
||||
|
||||
### **Federated timeline**
|
||||
|
||||
**This allows you to chronologically see all Public posts from people on all other Fediverse instances your home instance is connected to.**
|
||||
**This allows you to chronologically see all Public posts from people on all other Fediverse neighborhoods your home instance is connected to.**
|
||||
|
||||
Despite being one of the main features of federated social media, the Federated timeline wasn’t included in the official Mastodon app – supposedly, because this conflicts with Google’s safety requirements for apps on the Play Store.
|
||||
|
||||
@@ -49,7 +51,9 @@ To bookmark a post, press the button between the Favorite and Share buttons on t
|
||||
|
||||
## Installation
|
||||
|
||||
**Press the download button above to download the APK. Open the downloaded file on your Android device to install it. Megalodon will automatically notify you about new updates inside the app.**
|
||||
**In short: Press the download button to download the APK. Open the downloaded file on your Android device to install it. Megalodon will automatically notify you about new updates inside the app.**
|
||||
|
||||
[](https://github.com/sk22/megalodon/releases/latest/download/megalodon.apk)
|
||||
|
||||
To install this app on your Android device, download the [latest release from GitHub](https://github.com/sk22/megalodon/releases/latest/download/megalodon.apk) and open it. You might have to accept installing APK files from your browser when trying to install it. You can also take a look at all releases on the [Releases](https://github.com/sk22/megalodon/releases) page.
|
||||
|
||||
@@ -66,8 +70,6 @@ Megalodon makes use of [Mastodon for Android](https://github.com/mastodon/mastod
|
||||
|
||||
All downloads can be found on the [Releases](https://github.com/sk22/megalodon/releases) page.
|
||||
|
||||
**Warning! [The latest version's integrated updater is broken](https://github.com/sk22/megalodon/issues/106) – I'll publish a fixed version ASAP! If you're not updating through Izzy's F-Droid repository (more sources to come, hopefully!), you'll have to download the upcoming release manually. Sorry about that!**
|
||||
|
||||
**`megalodon.apk`**
|
||||
|
||||
Variant with an integrated updater. If you download Megalodon from here (and not from an app store), just download the regular `megalodon.apk`.
|
||||
@@ -80,6 +82,19 @@ This is an **unmodified version** of the official [Mastodon for Android](https:/
|
||||
|
||||
Variant without the integrated updater. This is the variant to be published to F-Droid.org where an integrated updater is not necessary. -->
|
||||
|
||||
---
|
||||
|
||||
## Contribution
|
||||
|
||||
### Translation
|
||||
|
||||
As with the source code, the translation is sourced from the official project, which you can contribute to on the official “**Mastodon for Android**” Crowdin project: https://crowdin.com/project/mastodon-for-android
|
||||
|
||||
There's also a handful of custom strings exclusive to this projects that would need to be translated. You can help translate **Megalodon** on Weblate: https://translate.codeberg.org/projects/megalodon/
|
||||
|
||||
[](https://translate.codeberg.org/engage/megalodon/)
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -106,7 +121,7 @@ Variant without the integrated updater. This is the variant to be published to F
|
||||
* [Add notifications tab for posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/posts-notifications-tab)
|
||||
* [Show visibility of original post when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/display-reply-visibility)
|
||||
* [Clickable reply/boost line above posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:clickable-boost-reply-line)
|
||||
* [Long-click to copy username from profile](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/copy-username)
|
||||
* [Clickable reply line while replying to open original post](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/clickable-reply-line-compose)
|
||||
|
||||
|
||||
### Behavior
|
||||
|
||||
@@ -6,7 +6,6 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
git rev-parse --short --verify upstream/master
|
||||
@@ -1,16 +1,16 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
defaultConfig {
|
||||
archivesBaseName = "megalodon"
|
||||
applicationId "org.joinmastodon.android.sk"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 50
|
||||
versionName "1.1.4+fork.50"
|
||||
versionCode 55
|
||||
versionName "1.1.4+fork.55"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
resConfigs "en", "ar-rSA", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES",
|
||||
"eu-rES", "fi-rFI", "fr-rFR", "gl-rES", "hr-rHR", "hy-rAM", "it-rIT", "iw-rIL",
|
||||
@@ -29,19 +29,15 @@ android {
|
||||
versionNameSuffix '-debug'
|
||||
applicationIdSuffix '.debug'
|
||||
}
|
||||
appcenterPrivateBeta{
|
||||
initWith release
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
versionNameSuffix "-priv-beta"
|
||||
}
|
||||
appcenterPublicBeta{
|
||||
initWith release
|
||||
versionNameSuffix "-beta"
|
||||
}
|
||||
githubRelease{
|
||||
initWith release
|
||||
}
|
||||
playRelease{
|
||||
initWith release
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
versionNameSuffix '-play'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
@@ -49,12 +45,6 @@ android {
|
||||
coreLibraryDesugaringEnabled true
|
||||
}
|
||||
sourceSets{
|
||||
appcenterPrivateBeta{
|
||||
setRoot "src/appcenter"
|
||||
}
|
||||
appcenterPublicBeta{
|
||||
setRoot "src/appcenter"
|
||||
}
|
||||
githubRelease{
|
||||
setRoot "src/github"
|
||||
}
|
||||
@@ -86,12 +76,6 @@ dependencies {
|
||||
annotationProcessor 'org.parceler:parceler:1.1.12'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
def appCenterSdkVersion = "4.4.2"
|
||||
appcenterPrivateBetaImplementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
|
||||
appcenterPrivateBetaImplementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
|
||||
appcenterPublicBetaImplementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
|
||||
appcenterPublicBetaImplementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
|
||||
|
||||
androidTestImplementation 'androidx.test:core:1.4.1-alpha05'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4-alpha05'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.0-alpha02'
|
||||
|
||||
6
mastodon/proguard-rules.pro
vendored
6
mastodon/proguard-rules.pro
vendored
@@ -40,12 +40,6 @@
|
||||
@com.squareup.otto.Subscribe <methods>;
|
||||
}
|
||||
|
||||
-keep class com.microsoft.appcenter.** {
|
||||
*;
|
||||
}
|
||||
|
||||
-keep class org.joinmastodon.android.AppCenterWrapper { *; }
|
||||
|
||||
-keepattributes LineNumberTable
|
||||
|
||||
# Parceler library
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package org.joinmastodon.android;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import com.microsoft.appcenter.AppCenter;
|
||||
import com.microsoft.appcenter.crashes.Crashes;
|
||||
import com.microsoft.appcenter.distribute.Distribute;
|
||||
import com.microsoft.appcenter.distribute.UpdateTrack;
|
||||
|
||||
public class AppCenterWrapper{
|
||||
private static final String TAG="AppCenterWrapper";
|
||||
|
||||
public static void init(Application app){
|
||||
if(AppCenter.isConfigured())
|
||||
return;
|
||||
Log.i(TAG, "initializing AppCenter SDK, build type is "+BuildConfig.BUILD_TYPE);
|
||||
|
||||
if(BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta"))
|
||||
Distribute.setUpdateTrack(UpdateTrack.PRIVATE);
|
||||
AppCenter.start(app, BuildConfig.appCenterKey, Distribute.class, Crashes.class);
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,13 @@
|
||||
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
|
||||
|
||||
<application
|
||||
android:name=".MastodonApp"
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:label="@string/sk_app_name"
|
||||
android:supportsRtl="true"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@@ -34,7 +33,7 @@
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:scheme="mastodon-android-auth" android:host="callback"/>
|
||||
<data android:scheme="megalodon-android-auth" android:host="callback"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ExternalShareActivity" android:exported="true" android:configChanges="orientation|screenSize" android:windowSoftInputMode="adjustResize">
|
||||
|
||||
@@ -10,6 +10,7 @@ public class GlobalUserPreferences{
|
||||
public static boolean showReplies;
|
||||
public static boolean showBoosts;
|
||||
public static boolean loadNewPosts;
|
||||
public static boolean showFederatedTimeline;
|
||||
public static boolean showInteractionCounts;
|
||||
public static boolean alwaysExpandContentWarnings;
|
||||
public static boolean disableMarquee;
|
||||
@@ -27,6 +28,7 @@ public class GlobalUserPreferences{
|
||||
showReplies=prefs.getBoolean("showReplies", true);
|
||||
showBoosts=prefs.getBoolean("showBoosts", true);
|
||||
loadNewPosts=prefs.getBoolean("loadNewPosts", true);
|
||||
showFederatedTimeline=prefs.getBoolean("showFederatedTimeline", !BuildConfig.BUILD_TYPE.equals("playRelease"));
|
||||
showInteractionCounts=prefs.getBoolean("showInteractionCounts", false);
|
||||
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
|
||||
disableMarquee=prefs.getBoolean("disableMarquee", false);
|
||||
@@ -40,6 +42,7 @@ public class GlobalUserPreferences{
|
||||
.putBoolean("showReplies", showReplies)
|
||||
.putBoolean("showBoosts", showBoosts)
|
||||
.putBoolean("loadNewPosts", loadNewPosts)
|
||||
.putBoolean("showFederatedTimeline", showFederatedTimeline)
|
||||
.putBoolean("trueBlackTheme", trueBlackTheme)
|
||||
.putBoolean("showInteractionCounts", showInteractionCounts)
|
||||
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package org.joinmastodon.android;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Application;
|
||||
import android.app.Fragment;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInstaller;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@@ -24,8 +22,6 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import me.grishka.appkit.FragmentStackActivity;
|
||||
|
||||
@@ -70,12 +66,7 @@ public class MainActivity extends FragmentStackActivity{
|
||||
}
|
||||
}
|
||||
|
||||
if(BuildConfig.BUILD_TYPE.startsWith("appcenter")){
|
||||
// Call the appcenter SDK wrapper through reflection because it is only present in beta builds
|
||||
try{
|
||||
Class.forName("org.joinmastodon.android.AppCenterWrapper").getMethod("init", Application.class).invoke(null, getApplication());
|
||||
}catch(ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException ignore){}
|
||||
}else if(GithubSelfUpdater.needSelfUpdating()){
|
||||
if(GithubSelfUpdater.needSelfUpdating()){
|
||||
GithubSelfUpdater.getInstance().maybeCheckForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import android.content.Context;
|
||||
|
||||
import org.joinmastodon.android.api.PushSubscriptionManager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import me.grishka.appkit.imageloader.ImageCache;
|
||||
import me.grishka.appkit.utils.NetworkUtils;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.joinmastodon.android.api;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -26,7 +27,10 @@ public class JsonObjectRequestBody extends RequestBody{
|
||||
public void writeTo(BufferedSink sink) throws IOException{
|
||||
try{
|
||||
OutputStreamWriter writer=new OutputStreamWriter(sink.outputStream(), StandardCharsets.UTF_8);
|
||||
MastodonAPIController.gson.toJson(obj, writer);
|
||||
if(obj instanceof JsonElement)
|
||||
writer.write(obj.toString());
|
||||
else
|
||||
MastodonAPIController.gson.toJson(obj, writer);
|
||||
writer.flush();
|
||||
}catch(JsonIOException x){
|
||||
throw new IOException(x);
|
||||
|
||||
@@ -365,6 +365,8 @@ public class PushSubscriptionManager{
|
||||
}
|
||||
|
||||
private static void registerAllAccountsForPush(boolean forceReRegister){
|
||||
if(!arePushNotificationsAvailable())
|
||||
return;
|
||||
for(AccountSession session:AccountSessionManager.getInstance().getLoggedInAccounts()){
|
||||
if(session.pushSubscription==null || forceReRegister)
|
||||
session.getPushSubscriptionManager().registerAccountForPush(session.pushSubscription);
|
||||
|
||||
@@ -63,36 +63,6 @@ public class StatusInteractionController{
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
|
||||
public void setBookmarked(Status status, boolean bookmarked){
|
||||
if(!Looper.getMainLooper().isCurrentThread())
|
||||
throw new IllegalStateException("Can only be called from main thread");
|
||||
|
||||
SetStatusBookmarked current=runningBookmarkRequests.remove(status.id);
|
||||
if(current!=null){
|
||||
current.cancel();
|
||||
}
|
||||
SetStatusBookmarked req=(SetStatusBookmarked) new SetStatusBookmarked(status.id, bookmarked)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Status result){
|
||||
runningBookmarkRequests.remove(status.id);
|
||||
E.post(new StatusCountersUpdatedEvent(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
runningBookmarkRequests.remove(status.id);
|
||||
error.showToast(MastodonApp.context);
|
||||
status.bookmarked=!bookmarked;
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
runningBookmarkRequests.put(status.id, req);
|
||||
status.bookmarked=bookmarked;
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
|
||||
public void setReblogged(Status status, boolean reblogged){
|
||||
if(!Looper.getMainLooper().isCurrentThread())
|
||||
throw new IllegalStateException("Can only be called from main thread");
|
||||
@@ -130,4 +100,34 @@ public class StatusInteractionController{
|
||||
status.reblogsCount--;
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
|
||||
public void setBookmarked(Status status, boolean bookmarked){
|
||||
if(!Looper.getMainLooper().isCurrentThread())
|
||||
throw new IllegalStateException("Can only be called from main thread");
|
||||
|
||||
SetStatusBookmarked current=runningBookmarkRequests.remove(status.id);
|
||||
if(current!=null){
|
||||
current.cancel();
|
||||
}
|
||||
SetStatusBookmarked req=(SetStatusBookmarked) new SetStatusBookmarked(status.id, bookmarked)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Status result){
|
||||
runningBookmarkRequests.remove(status.id);
|
||||
E.post(new StatusCountersUpdatedEvent(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
runningBookmarkRequests.remove(status.id);
|
||||
error.showToast(MastodonApp.context);
|
||||
status.bookmarked=!bookmarked;
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
runningBookmarkRequests.put(status.id, req);
|
||||
status.bookmarked=bookmarked;
|
||||
E.post(new StatusCountersUpdatedEvent(status));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,21 @@ public class IsoInstantTypeAdapter extends TypeAdapter<Instant>{
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try{
|
||||
return DateTimeFormatter.ISO_INSTANT.parse(in.nextString(), Instant::from);
|
||||
}catch(DateTimeParseException x){
|
||||
String nextString;
|
||||
try {
|
||||
nextString = in.nextString();
|
||||
}catch(Exception e){
|
||||
return null;
|
||||
}
|
||||
|
||||
try{
|
||||
return DateTimeFormatter.ISO_INSTANT.parse(nextString, Instant::from);
|
||||
}catch(DateTimeParseException x){}
|
||||
|
||||
try{
|
||||
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(nextString, Instant::from);
|
||||
}catch(DateTimeParseException x){}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.joinmastodon.android.api.gson;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
public class JsonArrayBuilder{
|
||||
private JsonArray arr=new JsonArray();
|
||||
|
||||
public JsonArrayBuilder add(JsonElement el){
|
||||
arr.add(el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonArrayBuilder add(String el){
|
||||
arr.add(el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonArrayBuilder add(Number el){
|
||||
arr.add(el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonArrayBuilder add(boolean el){
|
||||
arr.add(el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonArrayBuilder add(JsonObjectBuilder el){
|
||||
arr.add(el.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonArrayBuilder add(JsonArrayBuilder el){
|
||||
arr.add(el.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonArray build(){
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.joinmastodon.android.api.gson;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class JsonObjectBuilder{
|
||||
private JsonObject obj=new JsonObject();
|
||||
|
||||
public JsonObjectBuilder add(String key, JsonElement el){
|
||||
obj.add(key, el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder add(String key, String el){
|
||||
obj.addProperty(key, el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder add(String key, Number el){
|
||||
obj.addProperty(key, el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder add(String key, boolean el){
|
||||
obj.addProperty(key, el);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder add(String key, JsonObjectBuilder el){
|
||||
obj.add(key, el.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder add(String key, JsonArrayBuilder el){
|
||||
obj.add(key, el.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObject build(){
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package org.joinmastodon.android.api.requests.accounts;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.Response;
|
||||
|
||||
public class GetBookmarks extends MastodonAPIRequest<List<Status>>{
|
||||
private String maxId;
|
||||
|
||||
public GetBookmarks(String maxID, String minID, int limit){
|
||||
super(HttpMethod.GET, "/bookmarks", new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(minID!=null)
|
||||
addQueryParameter("min_id", minID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", ""+limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateAndPostprocessResponse(List<Status> respObj, Response httpResponse) throws IOException {
|
||||
super.validateAndPostprocessResponse(respObj, httpResponse);
|
||||
// <https://mastodon.social/api/v1/bookmarks?max_id=268962>; rel="next",
|
||||
// <https://mastodon.social/api/v1/bookmarks?min_id=268981>; rel="prev"
|
||||
String link=httpResponse.header("link");
|
||||
// parsing link header by hand; using a library would be cleaner
|
||||
// (also, the functionality should be part of the max id logics and implemented in MastodonAPIRequest)
|
||||
if(link==null) return;
|
||||
String maxIdEq="max_id=";
|
||||
for(String s : link.split(",")) {
|
||||
if(s.contains("rel=\"next\"")) {
|
||||
int start=s.indexOf(maxIdEq)+maxIdEq.length();
|
||||
int end=s.indexOf('>');
|
||||
if(start<0 || start>end) return;
|
||||
this.maxId=s.substring(start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMaxId() {
|
||||
return maxId;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package org.joinmastodon.android.api.requests.accounts;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.Response;
|
||||
|
||||
public class GetFavourites extends MastodonAPIRequest<List<Status>>{
|
||||
private String maxId;
|
||||
|
||||
public GetFavourites(String maxID, String minID, int limit){
|
||||
super(HttpMethod.GET, "/favourites", new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(minID!=null)
|
||||
addQueryParameter("min_id", minID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", ""+limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateAndPostprocessResponse(List<Status> respObj, Response httpResponse) throws IOException {
|
||||
super.validateAndPostprocessResponse(respObj, httpResponse);
|
||||
// <https://mastodon.social/api/v1/bookmarks?max_id=268962>; rel="next",
|
||||
// <https://mastodon.social/api/v1/bookmarks?min_id=268981>; rel="prev"
|
||||
String link=httpResponse.header("link");
|
||||
// parsing link header by hand; using a library would be cleaner
|
||||
// (also, the functionality should be part of the max id logics and implemented in MastodonAPIRequest)
|
||||
if(link==null) return;
|
||||
String maxIdEq="max_id=";
|
||||
for(String s : link.split(",")) {
|
||||
if(s.contains("rel=\"next\"")) {
|
||||
int start=s.indexOf(maxIdEq)+maxIdEq.length();
|
||||
int end=s.indexOf('>');
|
||||
if(start<0 || start>end) return;
|
||||
this.maxId=s.substring(start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMaxId() {
|
||||
return maxId;
|
||||
}
|
||||
}
|
||||
@@ -2,49 +2,15 @@ package org.joinmastodon.android.api.requests.accounts;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.FollowSuggestion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.Response;
|
||||
|
||||
public class GetFollowRequests extends MastodonAPIRequest<List<Account>>{
|
||||
private String maxId;
|
||||
|
||||
public GetFollowRequests(String maxID, String minID, int limit){
|
||||
public class GetFollowRequests extends HeaderPaginationRequest<Account>{
|
||||
public GetFollowRequests(String maxID, int limit){
|
||||
super(HttpMethod.GET, "/follow_requests", new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(minID!=null)
|
||||
addQueryParameter("min_id", minID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", ""+limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateAndPostprocessResponse(List<Account> respObj, Response httpResponse) throws IOException {
|
||||
super.validateAndPostprocessResponse(respObj, httpResponse);
|
||||
// <https://mastodon.social/api/v1/follow_requests?max_id=268962>; rel="next",
|
||||
// <https://mastodon.social/api/v1/follow_requests?min_id=268981>; rel="prev"
|
||||
String link=httpResponse.header("link");
|
||||
// parsing link header by hand; using a library would be cleaner
|
||||
// (also, the functionality should be part of the max id logics and implemented in MastodonAPIRequest)
|
||||
if(link==null) return;
|
||||
String maxIdEq="max_id=";
|
||||
for(String s : link.split(",")) {
|
||||
if(s.contains("rel=\"next\"")) {
|
||||
int start=s.indexOf(maxIdEq)+maxIdEq.length();
|
||||
int end=s.indexOf('>');
|
||||
if(start<0 || start>end) return;
|
||||
this.maxId=s.substring(start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMaxId() {
|
||||
return maxId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.joinmastodon.android.api.requests.markers;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.gson.JsonObjectBuilder;
|
||||
import org.joinmastodon.android.model.Marker;
|
||||
|
||||
public class SaveMarkers extends MastodonAPIRequest<SaveMarkers.Response>{
|
||||
public SaveMarkers(String lastSeenHomePostID, String lastSeenNotificationID){
|
||||
super(HttpMethod.POST, "/markers", Response.class);
|
||||
JsonObjectBuilder builder=new JsonObjectBuilder();
|
||||
if(lastSeenHomePostID!=null)
|
||||
builder.add("home", new JsonObjectBuilder().add("last_read_id", lastSeenHomePostID));
|
||||
if(lastSeenNotificationID!=null)
|
||||
builder.add("notifications", new JsonObjectBuilder().add("last_read_id", lastSeenNotificationID));
|
||||
setRequestBody(builder.build());
|
||||
}
|
||||
|
||||
public static class Response{
|
||||
public Marker home, notifications;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class GetBookmarkedStatuses extends HeaderPaginationRequest<Status>{
|
||||
public GetBookmarkedStatuses(String maxID, int limit){
|
||||
super(HttpMethod.GET, "/bookmarks", new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", limit+"");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class GetFavoritedStatuses extends HeaderPaginationRequest<Status>{
|
||||
public GetFavoritedStatuses(String maxID, int limit){
|
||||
super(HttpMethod.GET, "/favourites", new TypeToken<>(){});
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(limit>0)
|
||||
addQueryParameter("limit", limit+"");
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ import me.grishka.appkit.api.ErrorResponse;
|
||||
public class AccountSessionManager{
|
||||
private static final String TAG="AccountSessionManager";
|
||||
public static final String SCOPE="read write follow push";
|
||||
public static final String REDIRECT_URI="mastodon-android-auth://callback";
|
||||
public static final String REDIRECT_URI="megalodon-android-auth://callback";
|
||||
|
||||
private static final AccountSessionManager instance=new AccountSessionManager();
|
||||
|
||||
@@ -211,7 +211,7 @@ public class AccountSessionManager{
|
||||
.path("/oauth/authorize")
|
||||
.appendQueryParameter("response_type", "code")
|
||||
.appendQueryParameter("client_id", result.clientId)
|
||||
.appendQueryParameter("redirect_uri", "mastodon-android-auth://callback")
|
||||
.appendQueryParameter("redirect_uri", "megalodon-android-auth://callback")
|
||||
.appendQueryParameter("scope", SCOPE)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.joinmastodon.android.events;
|
||||
|
||||
public class RemoveAccountPostsEvent{
|
||||
public final String accountID;
|
||||
public final String postsByAccountID;
|
||||
public final boolean isUnfollow;
|
||||
|
||||
public RemoveAccountPostsEvent(String accountID, String postsByAccountID, boolean isUnfollow){
|
||||
this.accountID=accountID;
|
||||
this.postsByAccountID=postsByAccountID;
|
||||
this.isUnfollow=isUnfollow;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.joinmastodon.android.model.Status;
|
||||
public class StatusCountersUpdatedEvent{
|
||||
public String id;
|
||||
public long favorites, reblogs, replies;
|
||||
public boolean favorited, reblogged, pinned;
|
||||
public boolean favorited, reblogged, bookmarked, pinned;
|
||||
|
||||
public StatusCountersUpdatedEvent(Status s){
|
||||
id=s.id;
|
||||
@@ -14,6 +14,7 @@ public class StatusCountersUpdatedEvent{
|
||||
replies=s.repliesCount;
|
||||
favorited=s.favourited;
|
||||
reblogged=s.reblogged;
|
||||
bookmarked=s.bookmarked;
|
||||
pinned=s.pinned;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ package org.joinmastodon.android.events;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
public class StatusCreatedEvent{
|
||||
public Status status;
|
||||
public final Status status;
|
||||
public final String accountID;
|
||||
|
||||
public StatusCreatedEvent(Status status){
|
||||
public StatusCreatedEvent(Status status, String accountID){
|
||||
this.status=status;
|
||||
this.accountID=accountID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.view.View;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.events.StatusCreatedEvent;
|
||||
import org.joinmastodon.android.events.StatusUnpinnedEvent;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
@@ -109,4 +110,9 @@ public class AccountTimelineFragment extends StatusListFragment{
|
||||
displayItems.subList(index, lastIndex).clear();
|
||||
adapter.notifyItemRangeRemoved(index, lastIndex-index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
})
|
||||
.wrapProgress(getActivity(), R.string.loading, false)
|
||||
.wrapProgress(getActivity(), R.string.loading, true)
|
||||
.exec(accountID);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.statuses.GetBookmarkedStatuses;
|
||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
|
||||
public class BookmarkedStatusListFragment extends StatusListFragment{
|
||||
private String nextMaxID;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity){
|
||||
super.onAttach(activity);
|
||||
setTitle(R.string.bookmarks);
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetBookmarkedStatuses(offset==0 ? null : nextMaxID, count)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(HeaderPaginationList<Status> result){
|
||||
if(result.nextPageUri!=null)
|
||||
nextMaxID=result.nextPageUri.getQueryParameter("max_id");
|
||||
else
|
||||
nextMaxID=null;
|
||||
onDataLoaded(result, nextMaxID!=null);
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetBookmarks;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
|
||||
public class BookmarksListFragment extends StatusListFragment{
|
||||
|
||||
private String accountID;
|
||||
private Account self;
|
||||
private String lastMaxId=null;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
accountID=getArguments().getString("account");
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
self=session.self;
|
||||
setTitle(R.string.bookmarks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShown(){
|
||||
super.onShown();
|
||||
if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading)
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count) {
|
||||
GetBookmarks b=new GetBookmarks(offset>0 ? lastMaxId : null, null, count);
|
||||
currentRequest=b.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(List<Status> result){
|
||||
onDataLoaded(result, b.getMaxId()!=null);
|
||||
lastMaxId=b.getMaxId();
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import android.text.Layout;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -52,7 +51,6 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.twitter.twittertext.Regex;
|
||||
import com.twitter.twittertext.TwitterTextEmojiRegex;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
@@ -102,7 +100,6 @@ import org.parceler.Parcels;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -133,21 +130,6 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
private static final Pattern AUTO_COMPLETE_PATTERN=Pattern.compile("(?<!\\w)(?:@([a-zA-Z0-9_]+)(@[a-zA-Z0-9_.-]+)?|#([^\\s.]+)|:([a-zA-Z0-9_]+))");
|
||||
private static final Pattern HIGHLIGHT_PATTERN=Pattern.compile("(?<!\\w)(?:@([a-zA-Z0-9_]+)(@[a-zA-Z0-9_.-]+)?|#([^\\s.]+))");
|
||||
|
||||
private static final String VALID_URL_PATTERN_STRING =
|
||||
"(" + // $1 total match
|
||||
"(" + Regex.URL_VALID_PRECEDING_CHARS + ")" + // $2 Preceding character
|
||||
"(" + // $3 URL
|
||||
"(https?://)" + // $4 Protocol (optional)
|
||||
"(" + Regex.URL_VALID_DOMAIN + ")" + // $5 Domain(s)
|
||||
"(?::(" + Regex.URL_VALID_PORT_NUMBER + "))?" + // $6 Port number (optional)
|
||||
"(/" +
|
||||
Regex.URL_VALID_PATH + "*+" +
|
||||
")?" + // $7 URL Path and anchor
|
||||
"(\\?" + Regex.URL_VALID_URL_QUERY_CHARS + "*" + // $8 Query String
|
||||
Regex.URL_VALID_URL_QUERY_ENDING_CHARS + ")?" +
|
||||
")" +
|
||||
")";
|
||||
private static final Pattern URL_PATTERN=Pattern.compile(VALID_URL_PATTERN_STRING, Pattern.CASE_INSENSITIVE);
|
||||
@SuppressLint("NewApi") // this class actually exists on 6.0
|
||||
private final BreakIterator breakIterator=BreakIterator.getCharacterInstance();
|
||||
|
||||
@@ -505,7 +487,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
replyText.setText(getString(R.string.in_reply_to, replyTo.account.displayName));
|
||||
int visibilityNameRes = switch (statusVisibility) {
|
||||
case PUBLIC -> R.string.visibility_public;
|
||||
case UNLISTED -> R.string.visibility_unlisted;
|
||||
case UNLISTED -> R.string.sk_visibility_unlisted;
|
||||
case PRIVATE -> R.string.visibility_followers_only;
|
||||
case DIRECT -> R.string.visibility_private;
|
||||
};
|
||||
@@ -521,6 +503,13 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
replyArrow.setBounds(0, 0, V.dp(20), V.dp(20));
|
||||
replyText.setCompoundDrawables(replyArrow, null, visibilityIcon, null);
|
||||
|
||||
replyText.setOnClickListener(v->{
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelable("status", Parcels.wrap(replyTo));
|
||||
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
Nav.go(getActivity(), ThreadFragment.class, args);
|
||||
});
|
||||
ArrayList<String> mentions=new ArrayList<>();
|
||||
String ownID=AccountSessionManager.getInstance().getAccount(accountID).self.id;
|
||||
if(!replyTo.account.id.equals(ownID))
|
||||
@@ -644,7 +633,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
|
||||
String countableText=TwitterTextEmojiRegex.VALID_EMOJI_PATTERN.matcher(
|
||||
MENTION_PATTERN.matcher(
|
||||
URL_PATTERN.matcher(text).replaceAll("$2xxxxxxxxxxxxxxxxxxxxxxx")
|
||||
HtmlParser.URL_PATTERN.matcher(text).replaceAll("$2xxxxxxxxxxxxxxxxxxxxxxx")
|
||||
).replaceAll("$1@$3")
|
||||
).replaceAll("x");
|
||||
charCount=0;
|
||||
@@ -738,7 +727,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
wm.removeView(sendingOverlay);
|
||||
sendingOverlay=null;
|
||||
if(editingStatus==null){
|
||||
E.post(new StatusCreatedEvent(result));
|
||||
E.post(new StatusCreatedEvent(result, accountID));
|
||||
if(replyTo!=null){
|
||||
replyTo.repliesCount++;
|
||||
E.post(new StatusCountersUpdatedEvent(replyTo));
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.statuses.GetFavoritedStatuses;
|
||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
|
||||
public class FavoritedStatusListFragment extends StatusListFragment{
|
||||
private String nextMaxID;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity){
|
||||
super.onAttach(activity);
|
||||
setTitle(R.string.your_favorites);
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetFavoritedStatuses(offset==0 ? null : nextMaxID, count)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(HeaderPaginationList<Status> result){
|
||||
if(result.nextPageUri!=null)
|
||||
nextMaxID=result.nextPageUri.getQueryParameter("max_id");
|
||||
else
|
||||
nextMaxID=null;
|
||||
onDataLoaded(result, nextMaxID!=null);
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetFavourites;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
|
||||
public class FavoritesListFragment extends StatusListFragment{
|
||||
|
||||
private String accountID;
|
||||
private String lastMaxId=null;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
accountID=getArguments().getString("account");
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
setTitle(R.string.favorited_posts);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShown(){
|
||||
super.onShown();
|
||||
if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading)
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count) {
|
||||
GetFavourites b=new GetFavourites(offset>0 ? lastMaxId : null, null, count);
|
||||
currentRequest=b.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(List<Status> result){
|
||||
onDataLoaded(result, b.getMaxId()!=null);
|
||||
lastMaxId=b.getMaxId();
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetFollowRequests;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
@@ -50,7 +51,7 @@ public class FollowRequestsListFragment extends BaseRecyclerFragment<FollowReque
|
||||
private String accountID;
|
||||
private Map<String, Relationship> relationships=Collections.emptyMap();
|
||||
private GetAccountRelationships relationshipsRequest;
|
||||
private String lastMaxId=null;
|
||||
private String nextMaxID;
|
||||
|
||||
public FollowRequestsListFragment(){
|
||||
super(20);
|
||||
@@ -66,7 +67,7 @@ public class FollowRequestsListFragment extends BaseRecyclerFragment<FollowReque
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
setTitle(R.string.follow_requests);
|
||||
setTitle(R.string.sk_follow_requests);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,10 +76,14 @@ public class FollowRequestsListFragment extends BaseRecyclerFragment<FollowReque
|
||||
relationshipsRequest.cancel();
|
||||
relationshipsRequest=null;
|
||||
}
|
||||
currentRequest=new GetFollowRequests(offset>0 ? lastMaxId : null, null, count)
|
||||
currentRequest=new GetFollowRequests(offset==0 ? null : nextMaxID, count)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(List<Account> result){
|
||||
public void onSuccess(HeaderPaginationList<Account> result){
|
||||
if(result.nextPageUri!=null)
|
||||
nextMaxID=result.nextPageUri.getQueryParameter("max_id");
|
||||
else
|
||||
nextMaxID=null;
|
||||
onDataLoaded(result.stream().map(AccountWrapper::new).collect(Collectors.toList()), false);
|
||||
loadRelationships();
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
accountID=getArguments().getString("account");
|
||||
setTitle(R.string.app_name);
|
||||
setTitle(R.string.sk_app_name);
|
||||
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
|
||||
setRetainInstance(true);
|
||||
|
||||
@@ -316,7 +316,7 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
|
||||
private void updateToolbarLogo(){
|
||||
toolbarLogo =new TextView(getActivity());
|
||||
toolbarLogo.setText(getString(R.string.app_name).toLowerCase(Locale.getDefault()));
|
||||
toolbarLogo.setText(getString(R.string.sk_app_name).toLowerCase(Locale.getDefault()));
|
||||
toolbarLogo.setTextAppearance(R.style.app_title);
|
||||
|
||||
toolbarShowNewPostsBtn=new Button(getActivity());
|
||||
@@ -432,4 +432,9 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
public void onSelfUpdateStateChanged(SelfUpdateStateChangedEvent ev){
|
||||
updateUpdateState(ev.state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldRemoveAccountPostsWhenUnfollowing(){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
||||
if(args.containsKey("profileAccount")){
|
||||
profileAccountId=args.getString("profileAccount");
|
||||
profileDisplayUsername=args.getString("profileDisplayUsername");
|
||||
setTitle(getString(R.string.lists_with_user, profileDisplayUsername));
|
||||
setTitle(getString(R.string.sk_lists_with_user, profileDisplayUsername));
|
||||
// setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetFollowRequests;
|
||||
import org.joinmastodon.android.events.FollowRequestHandledEvent;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.ui.SimpleViewHolder;
|
||||
import org.joinmastodon.android.ui.tabs.TabLayout;
|
||||
import org.joinmastodon.android.ui.tabs.TabLayoutMediator;
|
||||
@@ -29,8 +30,6 @@ import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
@@ -167,9 +166,9 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
|
||||
}
|
||||
|
||||
public void refreshFollowRequestsBadge() {
|
||||
new GetFollowRequests(null, null, 1).setCallback(new Callback<>() {
|
||||
new GetFollowRequests(null, 1).setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(List<Account> accounts) {
|
||||
public void onSuccess(HeaderPaginationList<Account> accounts) {
|
||||
getToolbar().getMenu().findItem(R.id.follow_requests).setVisible(!accounts.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.NotificationDeletedEvent;
|
||||
import org.joinmastodon.android.events.PollUpdatedEvent;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.PaginatedResponse;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
@@ -27,6 +29,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.Nav;
|
||||
@@ -122,6 +125,10 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
.collect(Collectors.toSet());
|
||||
loadRelationships(needRelationships);
|
||||
maxID=result.maxID;
|
||||
|
||||
if(offset==0 && !result.items.isEmpty()){
|
||||
new SaveMarkers(null, result.items.get(0).id).exec(accountID);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -192,14 +199,23 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNotificationDeleted(NotificationDeletedEvent ev) {
|
||||
Notification notification = getNotificationByID(ev.id);
|
||||
if(notification==null)
|
||||
public void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
|
||||
if(!ev.accountID.equals(accountID) || ev.isUnfollow)
|
||||
return;
|
||||
data.remove(notification);
|
||||
List<Notification> toRemove=Stream.concat(data.stream(), preloadedData.stream())
|
||||
.filter(n->n.account!=null && n.account.id.equals(ev.postsByAccountID))
|
||||
.collect(Collectors.toList());
|
||||
for(Notification n:toRemove){
|
||||
removeNotification(n);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNotification(Notification n){
|
||||
data.remove(n);
|
||||
preloadedData.remove(n);
|
||||
int index=-1;
|
||||
for(int i=0;i<displayItems.size();i++){
|
||||
if(ev.id.equals(displayItems.get(i).parentID)){
|
||||
if(n.id.equals(displayItems.get(i).parentID)){
|
||||
index=i;
|
||||
break;
|
||||
}
|
||||
@@ -208,11 +224,10 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
||||
return;
|
||||
int lastIndex;
|
||||
for(lastIndex=index;lastIndex<displayItems.size();lastIndex++){
|
||||
if(!displayItems.get(lastIndex).parentID.equals(ev.id))
|
||||
if(!displayItems.get(lastIndex).parentID.equals(n.id))
|
||||
break;
|
||||
}
|
||||
displayItems.subList(index, lastIndex).clear();
|
||||
adapter.notifyItemRangeRemoved(index, lastIndex-index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
|
||||
}
|
||||
|
||||
private abstract class BaseViewHolder extends BindableViewHolder<AccountField>{
|
||||
private ShapeDrawable background=new ShapeDrawable();
|
||||
protected ShapeDrawable background=new ShapeDrawable();
|
||||
|
||||
public BaseViewHolder(int layout){
|
||||
super(getActivity(), layout, list);
|
||||
@@ -220,6 +220,20 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
|
||||
super.onBind(item);
|
||||
title.setText(item.parsedName);
|
||||
value.setText(item.parsedValue);
|
||||
if(item.verifiedAt!=null){
|
||||
background.getPaint().setColor(UiUtils.isDarkTheme() ? 0xFF49595a : 0xFFd7e3da);
|
||||
int textColor=UiUtils.isDarkTheme() ? 0xFF89bb9c : 0xFF5b8e63;
|
||||
value.setTextColor(textColor);
|
||||
value.setLinkTextColor(textColor);
|
||||
Drawable check=getResources().getDrawable(R.drawable.ic_fluent_checkmark_24_regular, getActivity().getTheme()).mutate();
|
||||
check.setTint(textColor);
|
||||
value.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, check, null);
|
||||
}else{
|
||||
background.getPaint().setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
|
||||
value.setTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
|
||||
value.setLinkTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.colorAccent));
|
||||
value.setCompoundDrawables(null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,6 @@ import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Outline;
|
||||
@@ -19,8 +18,6 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ImageSpan;
|
||||
@@ -252,7 +249,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
tab.setText(switch(position){
|
||||
case 0 -> R.string.posts;
|
||||
case 1 -> R.string.posts_and_replies;
|
||||
case 2 -> R.string.pinned_posts;
|
||||
case 2 -> R.string.sk_pinned_posts;
|
||||
case 3 -> R.string.media;
|
||||
case 4 -> R.string.profile_about;
|
||||
default -> throw new IllegalStateException();
|
||||
@@ -286,6 +283,18 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
followersBtn.setOnClickListener(this::onFollowersOrFollowingClick);
|
||||
followingBtn.setOnClickListener(this::onFollowersOrFollowingClick);
|
||||
|
||||
username.setOnLongClickListener(v->{
|
||||
String username=account.acct;
|
||||
if(!username.contains("@")){
|
||||
username+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
|
||||
}
|
||||
getActivity().getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText(null, "@"+username));
|
||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.TIRAMISU){ // Android 13+ SystemUI shows its own thing when you put things into the clipboard
|
||||
Toast.makeText(getActivity(), R.string.text_copied, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return sizeWrapper;
|
||||
}
|
||||
|
||||
@@ -453,16 +462,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
// noinspection SetTextI18n
|
||||
username.setText('@'+account.acct+(isSelf ? ('@'+AccountSessionManager.getInstance().getAccount(accountID).domain) : ""));
|
||||
}
|
||||
username.setOnLongClickListener(l->{
|
||||
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE);
|
||||
Vibrator v = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("Username", '@'+account.acct+'@'+AccountSessionManager.getInstance().getAccount(accountID).domain);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
Toast.makeText(getActivity(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) v.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||
else v.vibrate(50);
|
||||
return true;
|
||||
});
|
||||
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
|
||||
if(TextUtils.isEmpty(parsedBio)){
|
||||
bio.setVisibility(View.GONE);
|
||||
@@ -548,17 +547,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
}
|
||||
if(relationship==null && !isOwnProfile)
|
||||
return;
|
||||
inflater.inflate(R.menu.profile, menu);
|
||||
inflater.inflate(isOwnProfile ? R.menu.profile_own : R.menu.profile, menu);
|
||||
menu.findItem(R.id.share).setTitle(getString(R.string.share_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.manage_user_lists).setTitle(getString(R.string.lists_with_user, account.getDisplayUsername()));
|
||||
if(isOwnProfile){
|
||||
for(int i=0;i<menu.size();i++){
|
||||
MenuItem item=menu.getItem(i);
|
||||
item.setVisible(item.getItemId()==R.id.share || item.getItemId()==R.id.bookmarks || item.getItemId()==R.id.manage_user_lists);
|
||||
}
|
||||
menu.findItem(R.id.favorites_list).setVisible(true);
|
||||
if(isOwnProfile)
|
||||
return;
|
||||
}
|
||||
|
||||
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
||||
@@ -582,16 +575,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
intent.setType("text/plain");
|
||||
intent.putExtra(Intent.EXTRA_TEXT, account.url);
|
||||
startActivity(Intent.createChooser(intent, item.getTitle()));
|
||||
}else if(id==R.id.bookmarks) {
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelable("profileAccount", Parcels.wrap(account));
|
||||
Nav.go(getActivity(), BookmarksListFragment.class, args);
|
||||
}else if(id==R.id.favorites_list) {
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelable("profileAccount", Parcels.wrap(account));
|
||||
Nav.go(getActivity(), FavoritesListFragment.class, args);
|
||||
}else if(id==R.id.mute){
|
||||
confirmToggleMuted();
|
||||
}else if(id==R.id.block){
|
||||
@@ -623,6 +606,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
})
|
||||
.wrapProgress(getActivity(), R.string.loading, false)
|
||||
.exec(accountID);
|
||||
}else if(id==R.id.bookmarks){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), BookmarkedStatusListFragment.class, args);
|
||||
}else if(id==R.id.favorites){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), FavoritedStatusListFragment.class, args);
|
||||
}else if(id==R.id.manage_user_lists){
|
||||
final Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
@@ -667,7 +658,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
notifyProgress.setIndeterminateTintList(notifyButton.getTextColors());
|
||||
followsYouView.setVisibility(relationship.followedBy ? View.VISIBLE : View.GONE);
|
||||
notifyButton.setSelected(relationship.notifying);
|
||||
if (getActivity() != null) notifyButton.setContentDescription(getString(relationship.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username));
|
||||
if (getActivity() != null) notifyButton.setContentDescription(getString(relationship.notifying ? R.string.sk_user_post_notifications_on : R.string.sk_user_post_notifications_off, '@'+account.username));
|
||||
}
|
||||
|
||||
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
|
||||
|
||||
@@ -15,7 +15,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
@@ -36,6 +35,7 @@ import org.joinmastodon.android.MainActivity;
|
||||
import org.joinmastodon.android.MastodonApp;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIController;
|
||||
import org.joinmastodon.android.api.PushSubscriptionManager;
|
||||
import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
@@ -69,6 +69,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
private NotificationPolicyItem notificationPolicyItem;
|
||||
private String accountID;
|
||||
private boolean needUpdateNotificationSettings;
|
||||
private boolean needAppRestart;
|
||||
private PushSubscription pushSubscription;
|
||||
|
||||
private ImageView themeTransitionWindowView;
|
||||
@@ -94,7 +95,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
items.add(new HeaderItem(R.string.settings_theme));
|
||||
items.add(themeItem=new ThemeItem());
|
||||
items.add(new SwitchItem(R.string.theme_true_black, R.drawable.ic_fluent_dark_theme_24_regular, GlobalUserPreferences.trueBlackTheme, this::onTrueBlackThemeChanged));
|
||||
items.add(new SwitchItem(R.string.disable_marquee, R.drawable.ic_fluent_text_more_24_regular, GlobalUserPreferences.disableMarquee, i->{
|
||||
items.add(new SwitchItem(R.string.sk_disable_marquee, R.drawable.ic_fluent_text_more_24_regular, GlobalUserPreferences.disableMarquee, i->{
|
||||
GlobalUserPreferences.disableMarquee=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
@@ -108,28 +109,33 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
GlobalUserPreferences.useCustomTabs=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_show_interaction_counts, R.drawable.ic_fluent_number_row_24_regular, GlobalUserPreferences.showInteractionCounts, i->{
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_interaction_counts, R.drawable.ic_fluent_number_row_24_regular, GlobalUserPreferences.showInteractionCounts, i->{
|
||||
GlobalUserPreferences.showInteractionCounts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{
|
||||
items.add(new SwitchItem(R.string.sk_settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{
|
||||
GlobalUserPreferences.alwaysExpandContentWarnings=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.home_timeline));
|
||||
items.add(new SwitchItem(R.string.settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
||||
GlobalUserPreferences.showReplies=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_show_boosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, GlobalUserPreferences.showBoosts, i->{
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_boosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, GlobalUserPreferences.showBoosts, i->{
|
||||
GlobalUserPreferences.showBoosts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.settings_load_new_posts, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
||||
items.add(new SwitchItem(R.string.sk_settings_load_new_posts, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
||||
GlobalUserPreferences.loadNewPosts=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
}));
|
||||
items.add(new SwitchItem(R.string.sk_settings_show_federated_timeline, R.drawable.ic_fluent_earth_24_regular, GlobalUserPreferences.showFederatedTimeline, i->{
|
||||
GlobalUserPreferences.showFederatedTimeline=i.checked;
|
||||
GlobalUserPreferences.save();
|
||||
needAppRestart=true;
|
||||
}));
|
||||
|
||||
items.add(new HeaderItem(R.string.settings_notifications));
|
||||
items.add(notificationPolicyItem=new NotificationPolicyItem());
|
||||
@@ -146,14 +152,14 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
|
||||
items.add(new RedHeaderItem(R.string.settings_spicy));
|
||||
if (GithubSelfUpdater.needSelfUpdating()) {
|
||||
checkForUpdateItem = new TextItem(R.string.check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
|
||||
checkForUpdateItem = new TextItem(R.string.sk_check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
|
||||
items.add(checkForUpdateItem);
|
||||
}
|
||||
items.add(new TextItem(R.string.settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/mastodon/mastodon-android")));
|
||||
items.add(new TextItem(R.string.sk_settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/sk22/megalodon")));
|
||||
items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
|
||||
items.add(new TextItem(R.string.log_out, this::confirmLogOut));
|
||||
|
||||
items.add(new FooterItem(getString(R.string.settings_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)));
|
||||
items.add(new FooterItem(getString(R.string.sk_settings_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,9 +204,14 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
@Override
|
||||
public void onDestroy(){
|
||||
super.onDestroy();
|
||||
if(needUpdateNotificationSettings){
|
||||
if(needUpdateNotificationSettings && PushSubscriptionManager.arePushNotificationsAvailable()){
|
||||
AccountSessionManager.getInstance().getAccount(accountID).getPushSubscriptionManager().updatePushSettings(pushSubscription);
|
||||
}
|
||||
if(needAppRestart){
|
||||
Intent intent = Intent.makeRestartActivityTask(MastodonApp.context.getPackageManager().getLaunchIntentForPackage(MastodonApp.context.getPackageName()).getComponent());
|
||||
MastodonApp.context.startActivity(intent);
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -376,7 +387,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
}
|
||||
|
||||
if (ev.state == GithubSelfUpdater.UpdateState.NO_UPDATE) {
|
||||
Toast.makeText(getActivity(), R.string.no_update_available, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(getActivity(), R.string.sk_no_update_available, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,10 +763,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
if (state == GithubSelfUpdater.UpdateState.CHECKING) return;
|
||||
GithubSelfUpdater.UpdateInfo info=updater.getUpdateInfo();
|
||||
if(state!=GithubSelfUpdater.UpdateState.DOWNLOADED){
|
||||
text.setText(getString(R.string.update_available, info.version));
|
||||
text.setText(getString(R.string.sk_update_available, info.version));
|
||||
button.setText(getString(R.string.download_update, UiUtils.formatFileSize(getActivity(), info.size, false)));
|
||||
}else{
|
||||
text.setText(getString(R.string.update_ready, info.version));
|
||||
text.setText(getString(R.string.sk_update_ready, info.version));
|
||||
button.setText(R.string.install_update);
|
||||
}
|
||||
if(state==GithubSelfUpdater.UpdateState.DOWNLOADING){
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.events.PollUpdatedEvent;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.events.StatusCreatedEvent;
|
||||
import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
@@ -18,6 +19,8 @@ import org.parceler.Parcels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.Nav;
|
||||
@@ -134,6 +137,40 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean shouldRemoveAccountPostsWhenUnfollowing(){
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
|
||||
List<Status> toRemove=Stream.concat(data.stream(), preloadedData.stream())
|
||||
.filter(s->s.account.id.equals(ev.postsByAccountID) || (s.reblog!=null && s.reblog.account.id.equals(ev.postsByAccountID)))
|
||||
.collect(Collectors.toList());
|
||||
for(Status s:toRemove){
|
||||
removeStatus(s);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeStatus(Status status){
|
||||
data.remove(status);
|
||||
preloadedData.remove(status);
|
||||
int index=-1;
|
||||
for(int i=0;i<displayItems.size();i++){
|
||||
if(status.id.equals(displayItems.get(i).parentID)){
|
||||
index=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index==-1)
|
||||
return;
|
||||
int lastIndex;
|
||||
for(lastIndex=index;lastIndex<displayItems.size();lastIndex++){
|
||||
if(!displayItems.get(lastIndex).parentID.equals(status.id))
|
||||
break;
|
||||
}
|
||||
displayItems.subList(index, lastIndex).clear();
|
||||
adapter.notifyItemRangeRemoved(index, lastIndex-index);
|
||||
}
|
||||
|
||||
public class EventListener{
|
||||
|
||||
@Subscribe
|
||||
@@ -165,28 +202,13 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
Status status=getStatusByID(ev.id);
|
||||
if(status==null)
|
||||
return;
|
||||
data.remove(status);
|
||||
preloadedData.remove(status);
|
||||
int index=-1;
|
||||
for(int i=0;i<displayItems.size();i++){
|
||||
if(ev.id.equals(displayItems.get(i).parentID)){
|
||||
index=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index==-1)
|
||||
return;
|
||||
int lastIndex;
|
||||
for(lastIndex=index;lastIndex<displayItems.size();lastIndex++){
|
||||
if(!displayItems.get(lastIndex).parentID.equals(ev.id))
|
||||
break;
|
||||
}
|
||||
displayItems.subList(index, lastIndex).clear();
|
||||
adapter.notifyItemRangeRemoved(index, lastIndex-index);
|
||||
removeStatus(status);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusCreated(StatusCreatedEvent ev){
|
||||
if(!ev.accountID.equals(accountID))
|
||||
return;
|
||||
StatusListFragment.this.onStatusCreated(ev);
|
||||
}
|
||||
|
||||
@@ -206,5 +228,14 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
|
||||
if(!ev.accountID.equals(accountID))
|
||||
return;
|
||||
if(ev.isUnfollow && !shouldRemoveAccountPostsWhenUnfollowing())
|
||||
return;
|
||||
StatusListFragment.this.onRemoveAccountPostsEvent(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ public abstract class BaseAccountListFragment extends BaseRecyclerFragment<BaseA
|
||||
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.manage_user_lists).setTitle(getString(R.string.lists_with_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.manage_user_lists).setTitle(getString(R.string.sk_lists_with_user, account.getDisplayUsername()));
|
||||
MenuItem hideBoosts=menu.findItem(R.id.hide_boosts);
|
||||
if(relationship.following){
|
||||
hideBoosts.setTitle(getString(relationship.showingReblogs ? R.string.hide_boosts_from_user : R.string.show_boosts_from_user, account.getDisplayUsername()));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.joinmastodon.android.fragments.discover;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
@@ -17,6 +18,8 @@ import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.BuildConfig;
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||
import org.joinmastodon.android.fragments.ListTimelinesFragment;
|
||||
@@ -29,6 +32,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import me.grishka.appkit.fragments.AppKitFragment;
|
||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||
import me.grishka.appkit.fragments.OnBackPressedListener;
|
||||
@@ -58,6 +62,8 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
private String accountID;
|
||||
private Runnable searchDebouncer=this::onSearchChangedDebounced;
|
||||
|
||||
private final boolean noFederated = !GlobalUserPreferences.showFederatedTimeline;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -75,10 +81,11 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
tabLayout=view.findViewById(R.id.tabbar);
|
||||
pager=view.findViewById(R.id.pager);
|
||||
|
||||
tabViews=new FrameLayout[7];
|
||||
tabViews=new FrameLayout[noFederated ? 6 : 7];
|
||||
for(int i=0;i<tabViews.length;i++){
|
||||
FrameLayout tabView=new FrameLayout(getActivity());
|
||||
tabView.setId(switch(i){
|
||||
int switchIndex = noFederated && i > 0 ? i + 1 : i;
|
||||
tabView.setId(switch(switchIndex){
|
||||
case 0 -> R.id.discover_local_timeline;
|
||||
case 1 -> R.id.discover_federated_timeline;
|
||||
case 2 -> R.id.discover_hashtags;
|
||||
@@ -86,7 +93,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
case 4 -> R.id.discover_news;
|
||||
case 5 -> R.id.discover_users;
|
||||
case 6 -> R.id.discover_lists;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+i);
|
||||
default -> throw new IllegalStateException("Unexpected value: "+switchIndex);
|
||||
});
|
||||
tabView.setVisibility(View.GONE);
|
||||
view.addView(tabView); // needed so the fragment manager will have somewhere to restore the tab fragment
|
||||
@@ -131,34 +138,38 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
localTimelineFragment=new LocalTimelineFragment();
|
||||
localTimelineFragment.setArguments(args);
|
||||
|
||||
federatedTimelineFragment=new FederatedTimelineFragment();
|
||||
federatedTimelineFragment.setArguments(args);
|
||||
|
||||
listTimelinesFragment=new ListTimelinesFragment();
|
||||
listTimelinesFragment.setArguments(args);
|
||||
|
||||
getChildFragmentManager().beginTransaction()
|
||||
FragmentTransaction transaction = getChildFragmentManager().beginTransaction()
|
||||
.add(R.id.discover_posts, postsFragment)
|
||||
.add(R.id.discover_local_timeline, localTimelineFragment)
|
||||
.add(R.id.discover_federated_timeline, federatedTimelineFragment)
|
||||
.add(R.id.discover_hashtags, hashtagsFragment)
|
||||
.add(R.id.discover_news, newsFragment)
|
||||
.add(R.id.discover_users, accountsFragment)
|
||||
.add(R.id.discover_lists, listTimelinesFragment)
|
||||
.commit();
|
||||
.add(R.id.discover_lists, listTimelinesFragment);
|
||||
|
||||
if (!noFederated) {
|
||||
federatedTimelineFragment=new FederatedTimelineFragment();
|
||||
federatedTimelineFragment.setArguments(args);
|
||||
transaction.add(R.id.discover_federated_timeline, federatedTimelineFragment);
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
tabLayoutMediator=new TabLayoutMediator(tabLayout, pager, new TabLayoutMediator.TabConfigurationStrategy(){
|
||||
@Override
|
||||
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position){
|
||||
if (noFederated && position > 0) position++;
|
||||
tab.setText(switch(position){
|
||||
case 0 -> R.string.local_timeline;
|
||||
case 1 -> R.string.federated_timeline;
|
||||
case 1 -> R.string.sk_federated_timeline;
|
||||
case 2 -> R.string.hashtags;
|
||||
case 3 -> R.string.posts;
|
||||
case 4 -> R.string.news;
|
||||
case 5 -> R.string.for_you;
|
||||
case 6 -> R.string.list_timelines;
|
||||
case 6 -> R.string.sk_list_timelines;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+position);
|
||||
});
|
||||
tab.view.textView.setAllCaps(true);
|
||||
@@ -280,6 +291,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
}
|
||||
|
||||
private Fragment getFragmentForPage(int page){
|
||||
if (noFederated && page > 0) page++;
|
||||
return switch(page){
|
||||
case 0 -> localTimelineFragment;
|
||||
case 1 -> federatedTimelineFragment;
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.widget.TextView;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.ui.DividerItemDecoration;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
@@ -131,7 +132,10 @@ public class InstanceRulesFragment extends AppKitFragment{
|
||||
|
||||
@Override
|
||||
public void onBind(Instance.Rule item){
|
||||
title.setText(item.text);
|
||||
if(item.parsedText==null){
|
||||
item.parsedText=HtmlParser.parseLinks(item.text);
|
||||
}
|
||||
title.setText(item.parsedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.fragments.MastodonToolbarFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
@@ -130,6 +132,7 @@ public class ReportDoneFragment extends MastodonToolbarFragment{
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
Nav.finish(ReportDoneFragment.this);
|
||||
E.post(new RemoveAccountPostsEvent(accountID, reportAccount.id, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -134,6 +134,8 @@ public class Instance extends BaseModel{
|
||||
public static class Rule{
|
||||
public String id;
|
||||
public String text;
|
||||
|
||||
public transient CharSequence parsedText;
|
||||
}
|
||||
|
||||
@Parcel
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@AllFieldsAreRequired
|
||||
public class Marker extends BaseModel{
|
||||
public String lastReadId;
|
||||
public long version;
|
||||
public Instant updatedAt;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Marker{"+
|
||||
"lastReadId='"+lastReadId+'\''+
|
||||
", version="+version+
|
||||
", updatedAt="+updatedAt+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class Poll extends BaseModel{
|
||||
@RequiredField
|
||||
public String id;
|
||||
public Instant expiresAt;
|
||||
public boolean expired;
|
||||
private boolean expired;
|
||||
public boolean multiple;
|
||||
public int votersCount;
|
||||
public boolean voted;
|
||||
@@ -48,6 +48,10 @@ public class Poll extends BaseModel{
|
||||
'}';
|
||||
}
|
||||
|
||||
public boolean isExpired(){
|
||||
return expired || (expiresAt!=null && expiresAt.isBefore(Instant.now()));
|
||||
}
|
||||
|
||||
@Parcel
|
||||
public static class Option{
|
||||
public String title;
|
||||
|
||||
@@ -130,6 +130,7 @@ public class Status extends BaseModel implements DisplayItemsParent{
|
||||
repliesCount=ev.replies;
|
||||
favourited=ev.favorited;
|
||||
reblogged=ev.reblogged;
|
||||
bookmarked=ev.bookmarked;
|
||||
pinned=ev.pinned;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ImageDescriptionSheet extends BottomSheet{
|
||||
}
|
||||
|
||||
TextView heading=new TextView(activity);
|
||||
heading.setText(R.string.image_description);
|
||||
heading.setText(R.string.sk_image_description);
|
||||
heading.setAllCaps(true);
|
||||
heading.setTypeface(null, Typeface.BOLD);
|
||||
heading.setPadding(0, V.dp(24), 0, V.dp(8));
|
||||
|
||||
@@ -100,7 +100,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
private void bindButton(TextView btn, long count){
|
||||
if(GlobalUserPreferences.showInteractionCounts && count>0 && !item.hideCounts){
|
||||
btn.setText(DecimalFormat.getIntegerInstance().format(count));
|
||||
btn.setText(UiUtils.abbreviateNumber(count));
|
||||
btn.setCompoundDrawablePadding(V.dp(8));
|
||||
}else{
|
||||
btn.setText("");
|
||||
@@ -147,7 +147,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||
if(id==R.id.favorite_btn)
|
||||
return R.string.button_favorite;
|
||||
if(id==R.id.bookmark_btn)
|
||||
return R.string.button_bookmark;
|
||||
return R.string.add_bookmark;
|
||||
if(id==R.id.share_btn)
|
||||
return R.string.button_share;
|
||||
return 0;
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.app.ProgressDialog;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
@@ -209,6 +210,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
});
|
||||
}else if(id==R.id.block_domain){
|
||||
UiUtils.confirmToggleBlockDomain(activity, item.parentFragment.getAccountID(), account.getDomain(), relationship!=null && relationship.domainBlocking, ()->{});
|
||||
}else if(id==R.id.bookmark){
|
||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(item.status, !item.status.bookmarked);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@@ -226,6 +229,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
if(item.hasVisibilityToggle){
|
||||
visibility.setImageResource(item.status.spoilerRevealed ? R.drawable.ic_visibility_off : R.drawable.ic_visibility);
|
||||
visibility.setContentDescription(item.parentFragment.getString(item.status.spoilerRevealed ? R.string.hide_content : R.string.reveal_content));
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
|
||||
visibility.setTooltipText(visibility.getContentDescription());
|
||||
}
|
||||
}
|
||||
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
|
||||
if(TextUtils.isEmpty(item.extraText)){
|
||||
@@ -306,6 +312,16 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
MenuItem block=menu.findItem(R.id.block);
|
||||
MenuItem report=menu.findItem(R.id.report);
|
||||
MenuItem follow=menu.findItem(R.id.follow);
|
||||
MenuItem bookmark=menu.findItem(R.id.bookmark);
|
||||
bookmark.setVisible(false);
|
||||
/* disabled in megalodon: add/remove bookmark is already available through status footer
|
||||
if(item.status!=null){
|
||||
bookmark.setVisible(true);
|
||||
bookmark.setTitle(item.status.bookmarked ? R.string.remove_bookmark : R.string.add_bookmark);
|
||||
}else{
|
||||
bookmark.setVisible(false);
|
||||
}
|
||||
*/
|
||||
if(isOwnPost){
|
||||
mute.setVisible(false);
|
||||
block.setVisible(false);
|
||||
|
||||
@@ -38,13 +38,13 @@ public class PollFooterStatusDisplayItem extends StatusDisplayItem{
|
||||
@Override
|
||||
public void onBind(PollFooterStatusDisplayItem item){
|
||||
String text=item.parentFragment.getResources().getQuantityString(R.plurals.x_voters, item.poll.votersCount, item.poll.votersCount);
|
||||
if(item.poll.expiresAt!=null && !item.poll.expired){
|
||||
if(item.poll.expiresAt!=null && !item.poll.isExpired()){
|
||||
text+=" · "+UiUtils.formatTimeLeft(itemView.getContext(), item.poll.expiresAt);
|
||||
}else if(item.poll.expired){
|
||||
}else if(item.poll.isExpired()){
|
||||
text+=" · "+item.parentFragment.getString(R.string.poll_closed);
|
||||
}
|
||||
this.text.setText(text);
|
||||
button.setVisibility(item.poll.expired || item.poll.voted || !item.poll.multiple ? View.GONE : View.VISIBLE);
|
||||
button.setVisibility(item.poll.isExpired() || item.poll.voted || !item.poll.multiple ? View.GONE : View.VISIBLE);
|
||||
button.setEnabled(item.poll.selectedOptions!=null && !item.poll.selectedOptions.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||
this.poll=poll;
|
||||
text=HtmlParser.parseCustomEmoji(option.title, poll.emojis);
|
||||
emojiHelper.setText(text);
|
||||
showResults=poll.expired || poll.voted;
|
||||
showResults=poll.isExpired() || poll.voted;
|
||||
if(showResults && option.votesCount!=null && poll.votersCount>0){
|
||||
votesFraction=(float)option.votesCount/(float)poll.votersCount;
|
||||
int mostVotedCount=0;
|
||||
|
||||
@@ -178,7 +178,7 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
toolbar=uiOverlay.findViewById(R.id.toolbar);
|
||||
toolbar.setNavigationOnClickListener(v->onStartSwipeToDismissTransition(0));
|
||||
imageDescriptionButton = toolbar.getMenu()
|
||||
.add(R.string.image_description)
|
||||
.add(R.string.sk_image_description)
|
||||
.setIcon(R.drawable.ic_fluent_image_alt_text_24_regular)
|
||||
.setVisible(attachments.get(pager.getCurrentItem()).description != null
|
||||
&& !attachments.get(pager.getCurrentItem()).description.isEmpty())
|
||||
|
||||
@@ -1,9 +1,29 @@
|
||||
package org.joinmastodon.android.ui.text;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.fonts.FontFamily;
|
||||
import android.graphics.fonts.FontStyle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.BulletSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.LeadingMarginSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StrikethroughSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.text.style.SubscriptSpan;
|
||||
import android.text.style.SuperscriptSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.twitter.twittertext.Regex;
|
||||
|
||||
import org.joinmastodon.android.MastodonApp;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.model.Mention;
|
||||
@@ -12,11 +32,11 @@ import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.nodes.Node;
|
||||
import org.jsoup.nodes.TextNode;
|
||||
import org.jsoup.safety.Cleaner;
|
||||
import org.jsoup.safety.Safelist;
|
||||
import org.jsoup.select.NodeVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
@@ -26,8 +46,25 @@ import java.util.stream.Collectors;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class HtmlParser{
|
||||
private static final String TAG="HtmlParser";
|
||||
private static final String VALID_URL_PATTERN_STRING =
|
||||
"(" + // $1 total match
|
||||
"(" + Regex.URL_VALID_PRECEDING_CHARS + ")" + // $2 Preceding character
|
||||
"(" + // $3 URL
|
||||
"(https?://)" + // $4 Protocol (optional)
|
||||
"(" + Regex.URL_VALID_DOMAIN + ")" + // $5 Domain(s)
|
||||
"(?::(" + Regex.URL_VALID_PORT_NUMBER + "))?" + // $6 Port number (optional)
|
||||
"(/" +
|
||||
Regex.URL_VALID_PATH + "*+" +
|
||||
")?" + // $7 URL Path and anchor
|
||||
"(\\?" + Regex.URL_VALID_URL_QUERY_CHARS + "*" + // $8 Query String
|
||||
Regex.URL_VALID_URL_QUERY_ENDING_CHARS + ")?" +
|
||||
")" +
|
||||
")";
|
||||
public static final Pattern URL_PATTERN=Pattern.compile(VALID_URL_PATTERN_STRING, Pattern.CASE_INSENSITIVE);
|
||||
private static Pattern EMOJI_CODE_PATTERN=Pattern.compile(":([\\w]+):");
|
||||
|
||||
private HtmlParser(){}
|
||||
@@ -49,11 +86,17 @@ public class HtmlParser{
|
||||
public Object span;
|
||||
public int start;
|
||||
public Element element;
|
||||
public boolean more;
|
||||
|
||||
public SpanInfo(Object span, int start, Element element){
|
||||
this(span, start, element, false);
|
||||
}
|
||||
|
||||
public SpanInfo(Object span, int start, Element element, boolean more){
|
||||
this.span=span;
|
||||
this.start=start;
|
||||
this.element=element;
|
||||
this.more=more;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,24 +144,59 @@ public class HtmlParser{
|
||||
openSpans.add(new SpanInfo(new InvisibleSpan(), ssb.length(), el));
|
||||
}
|
||||
}
|
||||
case "li" -> openSpans.add(new SpanInfo(new BulletSpan(V.dp(8)), ssb.length(), el));
|
||||
case "em", "i" -> openSpans.add(new SpanInfo(new StyleSpan(Typeface.ITALIC), ssb.length(), el));
|
||||
case "h1", "h2", "h3", "h4", "h5", "h6" -> {
|
||||
// increase line height above heading (multiplying the margin)
|
||||
if (node.previousSibling()!=null) ssb.setSpan(new RelativeSizeSpan(2), ssb.length() - 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (!node.nodeName().equals("h1")) {
|
||||
openSpans.add(new SpanInfo(new StyleSpan(Typeface.BOLD), ssb.length(), el));
|
||||
}
|
||||
openSpans.add(new SpanInfo(new RelativeSizeSpan(switch(node.nodeName()) {
|
||||
case "h1" -> 1.5f;
|
||||
case "h2" -> 1.25f;
|
||||
case "h3" -> 1.125f;
|
||||
default -> 1;
|
||||
}), ssb.length(), el, !node.nodeName().equals("h1")));
|
||||
}
|
||||
case "strong", "b" -> openSpans.add(new SpanInfo(new StyleSpan(Typeface.BOLD), ssb.length(), el));
|
||||
case "u" -> openSpans.add(new SpanInfo(new UnderlineSpan(), ssb.length(), el));
|
||||
case "s", "del" -> openSpans.add(new SpanInfo(new StrikethroughSpan(), ssb.length(), el));
|
||||
case "sub", "sup" -> {
|
||||
openSpans.add(new SpanInfo(node.nodeName().equals("sub") ? new SubscriptSpan() : new SuperscriptSpan(), ssb.length(), el));
|
||||
openSpans.add(new SpanInfo(new RelativeSizeSpan(0.8f), ssb.length(), el, true));
|
||||
}
|
||||
case "code", "pre" -> openSpans.add(new SpanInfo(new TypefaceSpan("monospace"), ssb.length(), el));
|
||||
case "blockquote" -> openSpans.add(new SpanInfo(new LeadingMarginSpan.Standard(V.dp(10)), ssb.length(), el));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final static List<String> blockElements = Arrays.asList("p", "ul", "ol", "blockquote", "h1", "h2", "h3", "h4", "h5", "h6");
|
||||
|
||||
@Override
|
||||
public void tail(@NonNull Node node, int depth){
|
||||
if(node instanceof Element el){
|
||||
processOpenSpan(el);
|
||||
if("span".equals(el.nodeName()) && el.hasClass("ellipsis")){
|
||||
ssb.append("…", new DeleteWhenCopiedSpan(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}else if("p".equals(el.nodeName())){
|
||||
if(node.nextSibling()!=null)
|
||||
ssb.append("\n\n");
|
||||
}else if(!openSpans.isEmpty()){
|
||||
SpanInfo si=openSpans.get(openSpans.size()-1);
|
||||
if(si.element==el){
|
||||
ssb.setSpan(si.span, si.start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
openSpans.remove(openSpans.size()-1);
|
||||
}
|
||||
}else if(blockElements.contains(el.nodeName()) && node.nextSibling()!=null){
|
||||
ssb.append("\n"); // line end
|
||||
ssb.append("\n", new RelativeSizeSpan(0.75f), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // margin after block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processOpenSpan(Element el) {
|
||||
if(!openSpans.isEmpty()){
|
||||
SpanInfo si=openSpans.get(openSpans.size()-1);
|
||||
if(si.element==el){
|
||||
ssb.setSpan(si.span, si.start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
openSpans.remove(openSpans.size()-1);
|
||||
if(si.more) processOpenSpan(el);
|
||||
}
|
||||
if("li".equals(el.nodeName()) && el.nextSibling()!=null) {
|
||||
ssb.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,4 +250,18 @@ public class HtmlParser{
|
||||
public static String strip(String html){
|
||||
return Jsoup.clean(html, Safelist.none());
|
||||
}
|
||||
|
||||
public static CharSequence parseLinks(String text){
|
||||
Matcher matcher=URL_PATTERN.matcher(text);
|
||||
if(!matcher.find()) // Return the original string if there are no URLs
|
||||
return text;
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
|
||||
do{
|
||||
String url=matcher.group(3);
|
||||
if(TextUtils.isEmpty(matcher.group(4)))
|
||||
url="http://"+url;
|
||||
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null), matcher.start(3), matcher.end(3), 0);
|
||||
}while(matcher.find()); // Find more URLs
|
||||
return ssb;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class DiscoverInfoBannerHelper{
|
||||
case TRENDING_HASHTAGS -> R.string.trending_hashtags_info_banner;
|
||||
case TRENDING_LINKS -> R.string.trending_links_info_banner;
|
||||
case LOCAL_TIMELINE -> R.string.local_timeline_info_banner;
|
||||
case FEDERATED_TIMELINE -> R.string.federated_timeline_info_banner;
|
||||
case FEDERATED_TIMELINE -> R.string.sk_federated_timeline_info_banner;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.events.FollowRequestHandledEvent;
|
||||
import org.joinmastodon.android.events.NotificationDeletedEvent;
|
||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||
import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
import org.joinmastodon.android.events.StatusUnpinnedEvent;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
@@ -345,6 +346,9 @@ public class UiUtils{
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
resultCallback.accept(result);
|
||||
if(!currentlyBlocked){
|
||||
E.post(new RemoveAccountPostsEvent(accountID, account.id, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -387,6 +391,9 @@ public class UiUtils{
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
resultCallback.accept(result);
|
||||
if(!currentlyMuted){
|
||||
E.post(new RemoveAccountPostsEvent(accountID, account.id, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -403,7 +410,7 @@ public class UiUtils{
|
||||
}
|
||||
|
||||
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback, boolean forRedraft){
|
||||
showConfirmationAlert(activity, forRedraft ? R.string.confirm_delete_and_redraft_title : R.string.confirm_delete_title, forRedraft ? R.string.confirm_delete_and_redraft : R.string.confirm_delete, forRedraft ? R.string.delete_and_redraft : R.string.delete, ()->{
|
||||
showConfirmationAlert(activity, forRedraft ? R.string.sk_confirm_delete_and_redraft_title : R.string.confirm_delete_title, forRedraft ? R.string.sk_confirm_delete_and_redraft : R.string.confirm_delete, forRedraft ? R.string.sk_delete_and_redraft : R.string.delete, ()->{
|
||||
new DeleteStatus(status.id)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
@@ -425,9 +432,9 @@ public class UiUtils{
|
||||
|
||||
public static void confirmPinPost(Activity activity, String accountID, Status status, boolean pinned, Consumer<Status> resultCallback){
|
||||
showConfirmationAlert(activity,
|
||||
pinned ? R.string.confirm_pin_post_title : R.string.confirm_unpin_post_title,
|
||||
pinned ? R.string.confirm_pin_post : R.string.confirm_unpin_post,
|
||||
pinned ? R.string.pin_post : R.string.unpin_post,
|
||||
pinned ? R.string.sk_confirm_pin_post_title : R.string.sk_confirm_unpin_post_title,
|
||||
pinned ? R.string.sk_confirm_pin_post : R.string.sk_confirm_unpin_post,
|
||||
pinned ? R.string.sk_pin_post : R.string.sk_unpin_post,
|
||||
()->{
|
||||
new SetStatusPinned(status.id, pinned)
|
||||
.setCallback(new Callback<>() {
|
||||
@@ -444,7 +451,7 @@ public class UiUtils{
|
||||
error.showToast(activity);
|
||||
}
|
||||
})
|
||||
.wrapProgress(activity, pinned ? R.string.pinning : R.string.unpinning, false)
|
||||
.wrapProgress(activity, pinned ? R.string.sk_pinning : R.string.sk_unpinning, false)
|
||||
.exec(accountID);
|
||||
}
|
||||
);
|
||||
@@ -500,7 +507,7 @@ public class UiUtils{
|
||||
public void onSuccess(Relationship result) {
|
||||
resultCallback.accept(result);
|
||||
progressCallback.accept(false);
|
||||
Toast.makeText(activity, activity.getString(result.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(activity, activity.getString(result.notifying ? R.string.sk_user_post_notifications_on : R.string.sk_user_post_notifications_off, '@'+account.username), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -524,6 +531,9 @@ public class UiUtils{
|
||||
public void onSuccess(Relationship result){
|
||||
resultCallback.accept(result);
|
||||
progressCallback.accept(false);
|
||||
if(!result.following){
|
||||
E.post(new RemoveAccountPostsEvent(accountID, account.id, true));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -660,8 +670,7 @@ public class UiUtils{
|
||||
|
||||
public static void openURL(Context context, @Nullable String accountID, String url){
|
||||
Uri uri=Uri.parse(url);
|
||||
String accountDomain=accountID != null ? AccountSessionManager.getInstance().getAccount(accountID).domain : null;
|
||||
if(accountDomain!=null && "https".equals(uri.getScheme()) && accountDomain.equalsIgnoreCase(uri.getAuthority())){
|
||||
if(accountID!=null && "https".equals(uri.getScheme()) && AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority())){
|
||||
List<String> path=uri.getPathSegments();
|
||||
// Match URLs like https://mastodon.social/@Gargron/108132679274083591
|
||||
if(path.size()==2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$")){
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.DragEvent;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
@@ -22,7 +21,6 @@ import androidx.annotation.RequiresApi;
|
||||
|
||||
public class ComposeEditText extends EditText{
|
||||
private SelectionListener selectionListener;
|
||||
private MediaAcceptingInputConnection inputConnectionWrapper=new MediaAcceptingInputConnection();
|
||||
|
||||
public ComposeEditText(Context context){
|
||||
super(context);
|
||||
@@ -54,11 +52,10 @@ public class ComposeEditText extends EditText{
|
||||
// Support receiving images from keyboards
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs){
|
||||
final var ic = super.onCreateInputConnection(outAttrs);
|
||||
final InputConnection ic=super.onCreateInputConnection(outAttrs);
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N_MR1){
|
||||
outAttrs.contentMimeTypes=selectionListener.onGetAllowedMediaMimeTypes();
|
||||
inputConnectionWrapper.setTarget(ic);
|
||||
return inputConnectionWrapper;
|
||||
return new MediaAcceptingInputConnection(ic);
|
||||
}
|
||||
return ic;
|
||||
}
|
||||
@@ -106,8 +103,8 @@ public class ComposeEditText extends EditText{
|
||||
}
|
||||
|
||||
private class MediaAcceptingInputConnection extends InputConnectionWrapper{
|
||||
public MediaAcceptingInputConnection(){
|
||||
super(null, true);
|
||||
public MediaAcceptingInputConnection(InputConnection conn){
|
||||
super(conn, false);
|
||||
}
|
||||
|
||||
@RequiresApi(api=Build.VERSION_CODES.N_MR1)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class SplashLogoView extends ImageView{
|
||||
private Bitmap shadow;
|
||||
private Paint paint=new Paint();
|
||||
|
||||
public SplashLogoView(Context context){
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SplashLogoView(Context context, AttributeSet attrs){
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SplashLogoView(Context context, AttributeSet attrs, int defStyle){
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas){
|
||||
if(shadow!=null){
|
||||
paint.setColor(0xBF000000);
|
||||
canvas.drawBitmap(shadow, 0, 0, paint);
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh){
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if(w!=oldw || h!=oldh)
|
||||
updateShadow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageDrawable(@Nullable Drawable drawable){
|
||||
super.setImageDrawable(drawable);
|
||||
updateShadow();
|
||||
}
|
||||
|
||||
private void updateShadow(){
|
||||
int w=getWidth();
|
||||
int h=getHeight();
|
||||
Drawable drawable=getDrawable();
|
||||
if(w==0 || h==0 || drawable==null)
|
||||
return;
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
Bitmap temp=Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
|
||||
shadow=Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
|
||||
Canvas c=new Canvas(temp);
|
||||
c.translate(getWidth()/2f-drawable.getIntrinsicWidth()/2f, getHeight()/2f-drawable.getIntrinsicHeight()/2f);
|
||||
drawable.draw(c);
|
||||
c=new Canvas(shadow);
|
||||
Paint paint=new Paint();
|
||||
paint.setShadowLayer(V.dp(2), 0, 0, 0xff000000);
|
||||
c.drawBitmap(temp, 0, 0, paint);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 43 KiB |
@@ -1,3 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:pathData="M4 6.748c0-1.243 1.007-2.25 2.25-2.25h9c1.243 0 2.25 1.007 2.25 2.25V21.25c0 0.268-0.143 0.517-0.376 0.65-0.233 0.134-0.52 0.133-0.751-0.002l-5.623-3.28-5.622 3.28c-0.232 0.135-0.519 0.136-0.752 0.002C4.144 21.767 4 21.52 4 21.25V6.748zM15.25 2C17.873 2 20 4.127 20 6.75v11.873c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75V6.751c0-1.796-1.455-3.25-3.25-3.25H6.637S6.75 2.942 7.434 2.42C8 2 8.602 2 8.602 2h6.648z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
<path android:pathData="M4 6.748c0-1.243 1.007-2.25 2.25-2.25h9c1.243 0 2.25 1.007 2.25 2.25V21.25c0 0.268-0.143 0.517-0.376 0.65-0.233 0.134-0.52 0.133-0.751-0.002l-5.623-3.28-5.622 3.28c-0.232 0.135-0.519 0.136-0.752 0.002C4.144 21.767 4 21.52 4 21.25V6.748zm2.25-0.75c-0.414 0-0.75 0.336-0.75 0.75v13.196l4.873-2.842c0.233-0.137 0.522-0.137 0.755 0l4.873 2.842V6.748c0-0.414-0.336-0.75-0.75-0.75h-9zm9-3.998C17.873 2 20 4.127 20 6.75v11.873c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75V6.751c0-1.796-1.455-3.25-3.25-3.25H6.637S6.75 2.942 7.434 2.42C8 2 8.602 2 8.602 2h6.648z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:pathData="M4.53 12.97c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06l4.5 4.5c0.293 0.293 0.767 0.293 1.06 0l11-11c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.767-0.293-1.06 0L8.5 16.94l-3.97-3.97z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
||||
27
mastodon/src/main/res/drawable/splash_logo.xml
Normal file
27
mastodon/src/main/res/drawable/splash_logo.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="257dp"
|
||||
android:height="67dp"
|
||||
android:viewportWidth="313"
|
||||
android:viewportHeight="81">
|
||||
<path
|
||||
android:pathData="M72.95,18.45C71.82,9.95 64.5,3.24 55.85,1.95C54.38,1.73 48.85,0.93 36.02,0.93H35.92C23.09,0.93 20.34,1.73 18.87,1.95C10.44,3.22 2.76,9.23 0.88,17.84C-0,22.08 -0.1,26.78 0.07,31.09C0.31,37.27 0.36,43.43 0.91,49.6C1.29,53.69 1.95,57.74 2.9,61.73C4.68,69.11 11.86,75.25 18.9,77.75C26.43,80.35 34.53,80.79 42.29,79C43.14,78.79 43.98,78.56 44.82,78.29C46.71,77.68 48.92,77 50.55,75.81C50.57,75.8 50.59,75.77 50.6,75.75C50.61,75.72 50.62,75.7 50.62,75.66V69.7C50.62,69.7 50.62,69.65 50.6,69.62C50.6,69.6 50.57,69.58 50.55,69.56C50.53,69.55 50.5,69.54 50.48,69.53C50.45,69.53 50.43,69.53 50.41,69.53C45.43,70.73 40.33,71.34 35.23,71.33C26.43,71.33 24.06,67.09 23.39,65.34C22.85,63.82 22.5,62.22 22.36,60.61C22.36,60.59 22.36,60.57 22.37,60.54C22.37,60.52 22.39,60.49 22.42,60.48C22.44,60.47 22.46,60.46 22.49,60.44H22.57C27.46,61.64 32.48,62.25 37.51,62.25C38.72,62.25 39.92,62.25 41.14,62.21C46.19,62.06 51.52,61.81 56.51,60.82C56.63,60.8 56.76,60.77 56.87,60.75C64.72,59.21 72.19,54.42 72.95,42.27C72.97,41.79 73.04,37.25 73.04,36.76C73.04,35.07 73.58,24.79 72.96,18.48L72.95,18.45Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="36.62"
|
||||
android:startY="0.93"
|
||||
android:endX="36.62"
|
||||
android:endY="80.07"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF6364FF"/>
|
||||
<item android:offset="1" android:color="#FF563ACC"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M14.81,23.2C14.81,20.72 16.77,18.72 19.2,18.72C21.62,18.72 23.58,20.73 23.58,23.2C23.58,25.67 21.62,27.68 19.2,27.68C16.77,27.68 14.81,25.67 14.81,23.2Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M80.02,27.06V47.66H72.03V27.67C72.03,23.45 70.3,21.32 66.83,21.32C63,21.32 61.07,23.87 61.07,28.87V39.82H53.14V28.87C53.14,23.84 51.24,21.32 47.38,21.32C43.92,21.32 42.18,23.45 42.18,27.67V47.65H34.21V27.06C34.21,22.86 35.25,19.51 37.35,17.03C39.53,14.54 42.37,13.29 45.89,13.29C49.97,13.29 53.07,14.9 55.11,18.11L57.11,21.52L59.1,18.11C61.14,14.91 64.23,13.29 68.32,13.29C71.84,13.29 74.69,14.55 76.86,17.03C78.96,19.51 80.01,22.83 80.01,27.06H80.02ZM107.49,37.3C109.15,35.51 109.93,33.29 109.93,30.59C109.93,27.89 109.14,25.65 107.49,23.94C105.91,22.15 103.89,21.3 101.45,21.3C99.02,21.3 97.01,22.15 95.41,23.94C93.83,25.65 93.04,27.89 93.04,30.59C93.04,33.29 93.83,35.53 95.41,37.3C97,39 99.02,39.87 101.45,39.87C103.89,39.87 105.9,39.02 107.49,37.3ZM109.93,14.12H117.8V47.06H109.93V43.18C107.55,46.41 104.26,48 99.99,48C95.71,48 92.42,46.36 89.5,43C86.64,39.64 85.18,35.48 85.18,30.61C85.18,25.74 86.65,21.65 89.5,18.29C92.43,14.93 95.92,13.23 99.99,13.23C104.06,13.23 107.55,14.81 109.93,18.02V14.14V14.12ZM144.26,29.97C146.58,31.76 147.73,34.25 147.67,37.41C147.67,40.77 146.52,43.41 144.14,45.24C141.76,47.03 138.89,47.94 135.41,47.94C129.13,47.94 124.87,45.3 122.61,40.11L129.43,35.96C130.34,38.78 132.35,40.25 135.41,40.25C138.22,40.25 139.62,39.33 139.62,37.42C139.62,36.03 137.79,34.78 134.07,33.8C132.66,33.41 131.5,33.01 130.6,32.68C129.31,32.16 128.22,31.56 127.31,30.83C125.05,29.04 123.9,26.68 123.9,23.65C123.9,20.42 124.99,17.85 127.19,16C129.45,14.09 132.19,13.18 135.48,13.18C140.73,13.18 144.56,15.48 147.07,20.16L140.37,24.1C139.4,21.86 137.74,20.74 135.48,20.74C133.11,20.74 131.95,21.65 131.95,23.44C131.95,24.83 133.78,26.08 137.5,27.06C140.37,27.72 142.63,28.7 144.26,29.97H144.27H144.26ZM169.26,22.27H162.37V35.98C162.37,37.63 162.98,38.63 164.15,39.08C165,39.4 166.71,39.47 169.27,39.34V47.05C163.98,47.71 160.14,47.17 157.88,45.41C155.62,43.7 154.53,40.53 154.53,36V22.27H149.23V14.1H154.53V7.46L162.39,4.89V14.12H169.29V22.29H169.27L169.26,22.27ZM194.34,37.1C195.92,35.4 196.71,33.22 196.71,30.58C196.71,27.94 195.92,25.78 194.34,24.05C192.74,22.35 190.79,21.48 188.42,21.48C186.04,21.48 184.09,22.33 182.49,24.05C180.97,25.84 180.18,28 180.18,30.58C180.18,33.16 180.97,35.31 182.49,37.1C184.08,38.81 186.04,39.67 188.42,39.67C190.79,39.67 192.74,38.82 194.34,37.1ZM176.96,42.96C173.85,39.6 172.32,35.52 172.32,30.58C172.32,25.63 173.85,21.62 176.96,18.26C180.07,14.9 183.91,13.19 188.42,13.19C192.92,13.19 196.77,14.9 199.87,18.26C202.97,21.62 204.57,25.77 204.57,30.58C204.57,35.39 202.97,39.6 199.87,42.96C196.76,46.32 192.98,47.96 188.42,47.96C183.85,47.96 180.06,46.32 176.96,42.96ZM230.86,37.29C232.45,35.5 233.24,33.28 233.24,30.58C233.24,27.87 232.45,25.63 230.86,23.93C229.28,22.14 227.26,21.29 224.82,21.29C222.39,21.29 220.37,22.14 218.73,23.93C217.14,25.63 216.35,27.87 216.35,30.58C216.35,33.28 217.14,35.52 218.73,37.29C220.38,38.99 222.45,39.86 224.82,39.86C227.2,39.86 229.27,39 230.86,37.29ZM233.24,0.92H241.11V47.05H233.24V43.17C230.93,46.39 227.63,47.99 223.36,47.99C219.09,47.99 215.75,46.35 212.8,42.98C209.93,39.62 208.48,35.47 208.48,30.6C208.48,25.73 209.95,21.64 212.8,18.28C215.72,14.92 219.26,13.22 223.36,13.22C227.45,13.22 230.93,14.8 233.24,18.01V0.93V0.92ZM268.74,37.07C270.32,35.36 271.12,33.18 271.12,30.54C271.12,27.9 270.32,25.74 268.74,24.01C267.15,22.31 265.21,21.45 262.82,21.45C260.43,21.45 258.5,22.3 256.9,24.01C255.37,25.8 254.58,27.96 254.58,30.54C254.58,33.12 255.37,35.28 256.9,37.07C258.48,38.77 260.44,39.64 262.82,39.64C265.2,39.64 267.14,38.78 268.74,37.07ZM251.36,42.92C248.26,39.56 246.73,35.48 246.73,30.54C246.73,25.6 248.25,21.58 251.36,18.22C254.47,14.86 258.32,13.15 262.82,13.15C267.32,13.15 271.18,14.86 274.27,18.22C277.38,21.58 278.97,25.73 278.97,30.54C278.97,35.35 277.38,39.56 274.27,42.92C271.16,46.28 267.38,47.93 262.82,47.93C258.26,47.93 254.46,46.28 251.36,42.92ZM313,26.78V47.01H305.14V27.84C305.14,25.66 304.59,24.01 303.48,22.77C302.45,21.65 300.98,21.07 299.09,21.07C294.65,21.07 292.39,23.77 292.39,29.24V47.03H284.53V14.1H292.39V17.81C294.28,14.71 297.28,13.19 301.47,13.19C304.82,13.19 307.57,14.37 309.71,16.81C311.91,19.24 313,22.54 313,26.82"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
@@ -35,16 +35,18 @@
|
||||
android:id="@+id/reply_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="-12dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
android:drawableStart="@drawable/ic_fluent_arrow_reply_20_filled"
|
||||
tools:drawableEnd="@drawable/ic_fluent_earth_20_regular"
|
||||
android:drawableTint="?android:textColorSecondary"
|
||||
android:drawablePadding="6dp"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"/>
|
||||
android:ellipsize="end"
|
||||
android:background="?android:selectableItemBackground"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -185,7 +187,7 @@
|
||||
android:layout_weight="1"
|
||||
android:textSize="16sp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/mark_media_as_sensitive" />
|
||||
android:text="@string/sk_mark_media_as_sensitive" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
@@ -212,6 +214,7 @@
|
||||
android:tint="@color/compose_button"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@string/add_media"
|
||||
android:tooltipText="@string/add_media"
|
||||
android:src="@drawable/ic_fluent_image_24_regular"/>
|
||||
|
||||
<ImageButton
|
||||
@@ -224,6 +227,7 @@
|
||||
android:tint="@color/compose_button"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@string/add_poll"
|
||||
android:tooltipText="@string/add_poll"
|
||||
android:src="@drawable/ic_fluent_poll_24_selector"/>
|
||||
|
||||
<ImageButton
|
||||
@@ -236,6 +240,7 @@
|
||||
android:tint="@color/compose_button"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@string/emoji"
|
||||
android:tooltipText="@string/emoji"
|
||||
android:src="@drawable/ic_fluent_emoji_24_selector"/>
|
||||
|
||||
<ImageButton
|
||||
@@ -248,6 +253,7 @@
|
||||
android:tint="@color/compose_button"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@string/content_warning"
|
||||
android:tooltipText="@string/content_warning"
|
||||
android:src="@drawable/ic_fluent_chat_warning_24_selector"/>
|
||||
|
||||
<ImageButton
|
||||
@@ -260,6 +266,7 @@
|
||||
android:tint="@color/compose_button"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@string/post_visibility"
|
||||
android:tooltipText="@string/post_visibility"
|
||||
android:src="@drawable/ic_fluent_earth_24_regular"/>
|
||||
|
||||
<Space
|
||||
|
||||
@@ -73,11 +73,13 @@
|
||||
android:transformPivotY="1px"
|
||||
android:background="#478E6A"/>
|
||||
|
||||
<ImageView
|
||||
<org.joinmastodon.android.ui.views.SplashLogoView
|
||||
android:layout_width="261dp"
|
||||
android:layout_height="67dp"
|
||||
android:layout_height="71dp"
|
||||
android:layout_gravity="center_horizontal|top"
|
||||
android:layout_marginTop="24dp"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/splash_logo"/>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
style="?secondaryButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/reject_follow_request"
|
||||
android:contentDescription="@string/sk_reject_follow_request"
|
||||
android:drawableStart="@drawable/ic_fluent_dismiss_24_filled"
|
||||
android:singleLine="true" />
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
android:id="@+id/accept_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/accept_follow_request"
|
||||
android:contentDescription="@string/sk_accept_follow_request"
|
||||
android:drawableStart="@drawable/ic_fluent_checkmark_24_filled"
|
||||
android:singleLine="true" />
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:src="@drawable/ic_round_checkbox"/>
|
||||
|
||||
<TextView
|
||||
<org.joinmastodon.android.ui.views.LinkedTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textAppearance="@style/m3_body_medium"
|
||||
tools:text="@string/update_available"/>
|
||||
tools:text="@string/sk_update_available"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:title="@string/visibility_public"/>
|
||||
<item android:id="@+id/vis_unlisted"
|
||||
android:icon="@drawable/ic_fluent_people_community_24_regular"
|
||||
android:title="@string/visibility_unlisted"/>
|
||||
android:title="@string/sk_visibility_unlisted"/>
|
||||
<item android:id="@+id/vis_followers"
|
||||
android:icon="@drawable/ic_fluent_people_checkmark_24_regular"
|
||||
android:title="@string/visibility_followers_only"/>
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
android:id="@+id/follow_requests"
|
||||
android:icon="@drawable/ic_follow_requests_24_badged"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/follow_requests" />
|
||||
android:title="@string/sk_follow_requests" />
|
||||
</menu>
|
||||
@@ -2,13 +2,14 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/edit" android:title="@string/edit"/>
|
||||
<item android:id="@+id/delete" android:title="@string/delete"/>
|
||||
<item android:id="@+id/delete_and_redraft" android:title="@string/delete_and_redraft"/>
|
||||
<item android:id="@+id/pin" android:title="@string/pin_post"/>
|
||||
<item android:id="@+id/unpin" android:title="@string/unpin_post"/>
|
||||
<item android:id="@+id/delete_and_redraft" android:title="@string/sk_delete_and_redraft"/>
|
||||
<item android:id="@+id/pin" android:title="@string/sk_pin_post"/>
|
||||
<item android:id="@+id/unpin" android:title="@string/sk_unpin_post"/>
|
||||
<item android:id="@+id/mute" android:title="@string/mute_user"/>
|
||||
<item android:id="@+id/block" android:title="@string/block_user"/>
|
||||
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
||||
<item android:id="@+id/follow" android:title="@string/follow_user"/>
|
||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||
<item android:id="@+id/bookmark" android:title="@string/add_bookmark"/>
|
||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||
</menu>
|
||||
@@ -6,13 +6,6 @@
|
||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
||||
<item android:id="@+id/hide_boosts" android:title="@string/hide_boosts_from_user"/>
|
||||
<item android:id="@+id/manage_user_lists" android:title="@string/lists_with_user"/>
|
||||
<item android:id="@+id/manage_user_lists" android:title="@string/sk_lists_with_user"/>
|
||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||
<item android:id="@+id/favorites_list" android:title="@string/favorited_posts" android:visible="false"/>
|
||||
<item
|
||||
android:id="@+id/bookmarks"
|
||||
android:showAsAction="always"
|
||||
android:visible="false"
|
||||
android:icon="@drawable/ic_fluent_bookmark_multiple_24_filled"
|
||||
android:title="@string/bookmarks"/>
|
||||
</menu>
|
||||
6
mastodon/src/main/res/menu/profile_own.xml
Normal file
6
mastodon/src/main/res/menu/profile_own.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/bookmarks" android:title="@string/bookmarks" android:icon="@drawable/ic_fluent_bookmark_multiple_24_regular" android:showAsAction="always"/>
|
||||
<item android:id="@+id/favorites" android:title="@string/your_favorites" android:icon="@drawable/ic_fluent_star_24_regular"/>
|
||||
<item android:id="@+id/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular"/>
|
||||
</menu>
|
||||
3
mastodon/src/main/res/values-ar-rSA/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-ar-rSA/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -1,5 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="get_started">Пачаць</string>
|
||||
<string name="log_in">Увайсці</string>
|
||||
<string name="next">Далей</string>
|
||||
<string name="error">Памылка</string>
|
||||
<string name="ok">Добра</string>
|
||||
<string name="notifications">Апавяшчэнні</string>
|
||||
<string name="share_toot_title">Абагуліць</string>
|
||||
<string name="settings">Налады</string>
|
||||
<string name="cancel">Скасаваць</string>
|
||||
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
|
||||
3
mastodon/src/main/res/values-be-rBY/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-be-rBY/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-bn-rBD/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-bn-rBD/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-bs-rBA/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-bs-rBA/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -5,15 +5,15 @@
|
||||
<string name="next">Següent</string>
|
||||
<string name="loading_instance">Obtenint informació sobre la instància…</string>
|
||||
<string name="error">Error</string>
|
||||
<string name="not_a_mastodon_instance">Sembla que %s no és una instància Mastodon.</string>
|
||||
<string name="not_a_mastodon_instance">Sembla que %s no és una instància de Mastodon.</string>
|
||||
<string name="ok">D\'acord</string>
|
||||
<string name="preparing_auth">Preparant a l\'autenticació…</string>
|
||||
<string name="finishing_auth">Finalitzant autentificació…</string>
|
||||
<string name="preparing_auth">Preparant l\'autenticació…</string>
|
||||
<string name="finishing_auth">Finalitzant l\'autenticació…</string>
|
||||
<string name="user_boosted">%s ha impulsat</string>
|
||||
<string name="in_reply_to">En resposta a %s</string>
|
||||
<string name="notifications">Notificacions</string>
|
||||
<string name="user_followed_you">t\'ha seguit</string>
|
||||
<string name="user_sent_follow_request">t\'ha enviat una sol·licitud de seguiment</string>
|
||||
<string name="user_sent_follow_request">ha sol·licitat seguir-te</string>
|
||||
<string name="user_favorited">ha afavorit la teva publicació</string>
|
||||
<string name="notification_boosted">ha impulsat la teva publicació</string>
|
||||
<string name="poll_ended">l\'enquesta ha finalitzat</string>
|
||||
@@ -24,7 +24,7 @@
|
||||
<string name="share_toot_title">Comparteix</string>
|
||||
<string name="settings">Configuració</string>
|
||||
<string name="publish">Publica</string>
|
||||
<string name="discard_draft">Voleu descartar l\'esborrany?</string>
|
||||
<string name="discard_draft">Vols descartar l\'esborrany?</string>
|
||||
<string name="discard">Descarta</string>
|
||||
<string name="cancel">Cancel·la</string>
|
||||
<plurals name="followers">
|
||||
@@ -49,14 +49,14 @@
|
||||
<string name="mention_user">Menciona %s</string>
|
||||
<string name="share_user">Comparteix %s</string>
|
||||
<string name="mute_user">Silencia %s</string>
|
||||
<string name="unmute_user">Deixar de silenciar %s</string>
|
||||
<string name="unmute_user">Deixa de silenciar %s</string>
|
||||
<string name="block_user">Bloca %s</string>
|
||||
<string name="unblock_user">Desbloca %s</string>
|
||||
<string name="report_user">Denuncia %s</string>
|
||||
<string name="block_domain">Bloca %s</string>
|
||||
<string name="unblock_domain">Desbloca %s</string>
|
||||
<plurals name="x_posts">
|
||||
<item quantity="one">%,d entrada</item>
|
||||
<item quantity="one">%,d publicació</item>
|
||||
<item quantity="other">%,d publicacions</item>
|
||||
</plurals>
|
||||
<string name="profile_joined">S\'ha unit</string>
|
||||
@@ -101,12 +101,12 @@
|
||||
<item quantity="other">%,d votants</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">Finalitzada</string>
|
||||
<string name="confirm_mute_title">Silenciar el compte</string>
|
||||
<string name="confirm_mute">Confirma per silenciar %s</string>
|
||||
<string name="do_mute">Silenciar</string>
|
||||
<string name="confirm_mute_title">Silencia el compte</string>
|
||||
<string name="confirm_mute">Confirma per a silenciar %s</string>
|
||||
<string name="do_mute">Silencia</string>
|
||||
<string name="confirm_unmute_title">Deixar de silenciar el compte</string>
|
||||
<string name="confirm_unmute">Confirma per deixar de silenciar %s</string>
|
||||
<string name="do_unmute">Deixar de silenciar</string>
|
||||
<string name="do_unmute">Deixa de silenciar</string>
|
||||
<string name="confirm_block_title">Bloca el compte</string>
|
||||
<string name="confirm_block_domain_title">Bloca el domini</string>
|
||||
<string name="confirm_block">Confirma per blocar %s</string>
|
||||
@@ -135,12 +135,12 @@
|
||||
<string name="all_notifications">Totes</string>
|
||||
<string name="mentions">Mencions</string>
|
||||
<plurals name="x_people_talking">
|
||||
<item quantity="one">%d persona parla</item>
|
||||
<item quantity="other">%d persones estan parlant</item>
|
||||
<item quantity="one">%d persona està parlant-ne</item>
|
||||
<item quantity="other">%d persones estan parlant-ne</item>
|
||||
</plurals>
|
||||
<plurals name="discussed_x_times">
|
||||
<item quantity="one">S\'ha comentat %d cop</item>
|
||||
<item quantity="other">S\'ha comentat %d cops</item>
|
||||
<item quantity="one">S\'ha comentat %d vegada</item>
|
||||
<item quantity="other">S\'ha comentat %d vegades</item>
|
||||
</plurals>
|
||||
<string name="report_title">Denuncia %s</string>
|
||||
<string name="report_choose_reason">Quin és el problema amb aquesta publicació?</string>
|
||||
@@ -160,7 +160,7 @@
|
||||
<string name="report_choose_posts_subtitle">Selecciona tots els aplicables</string>
|
||||
<string name="report_comment_title">Hi ha res més que hauríem de saber?</string>
|
||||
<string name="report_comment_hint">Comentaris addicionals</string>
|
||||
<string name="sending_report">Enviant informe…</string>
|
||||
<string name="sending_report">S\'està enviant l\'informe…</string>
|
||||
<string name="report_sent_title">Gràcies per informar, ho investigarem.</string>
|
||||
<string name="report_sent_subtitle">Mentre ho revisem, pots prendre mesures contra %s.</string>
|
||||
<string name="unfollow_user">Deixar de seguir %s</string>
|
||||
@@ -176,7 +176,7 @@
|
||||
<string name="instance_rules_title">Algunes normes bàsiques</string>
|
||||
<string name="instance_rules_subtitle">Pren un minut per revisar les normes establertes i aplicades pels administradors de %s.</string>
|
||||
<string name="signup_title">Deixa que et posem en marxa a %s</string>
|
||||
<string name="edit_photo">editar</string>
|
||||
<string name="edit_photo">edita</string>
|
||||
<string name="display_name">nom visible</string>
|
||||
<string name="username">nom d\'usuari</string>
|
||||
<string name="email">correu electrònic</string>
|
||||
@@ -223,9 +223,9 @@
|
||||
<string name="notification_type_mention">Mencions</string>
|
||||
<string name="notification_type_poll">Enquestes</string>
|
||||
<string name="choose_account">Selecciona un compte</string>
|
||||
<string name="err_not_logged_in">Si us plau, inicia sessió primer a Mastodon</string>
|
||||
<string name="err_not_logged_in">Primer inicia sessió a Mastodon</string>
|
||||
<plurals name="cant_add_more_than_x_attachments">
|
||||
<item quantity="one">No pots afegir més de %d fitxer multimèdia</item>
|
||||
<item quantity="one">No pots afegir més d\'%d fitxer multimèdia</item>
|
||||
<item quantity="other">No pots afegir més de %d fitxers multimèdia</item>
|
||||
</plurals>
|
||||
<string name="media_attachment_unsupported_type">El tipus de fitxer %s no és compatible</string>
|
||||
@@ -236,8 +236,8 @@
|
||||
<string name="theme_dark">Fosc</string>
|
||||
<string name="theme_true_black">Mode negre pur</string>
|
||||
<string name="settings_behavior">Comportament</string>
|
||||
<string name="settings_gif">Reproduir emojis i avatar animats</string>
|
||||
<string name="settings_custom_tabs">Utilitzar el navegador intern</string>
|
||||
<string name="settings_gif">Reprodueix emojis i avatar animats</string>
|
||||
<string name="settings_custom_tabs">Utilitza el navegador intern</string>
|
||||
<string name="settings_notifications">Notificacions</string>
|
||||
<string name="notify_me_when">Notifica\'m quan</string>
|
||||
<string name="notify_anyone">qualsevol</string>
|
||||
@@ -259,7 +259,7 @@
|
||||
<string name="media_cache_cleared">S\'ha esborrat la memòria cau multimèdia</string>
|
||||
<string name="confirm_log_out">Segur que vols tancar la sessió?</string>
|
||||
<string name="sensitive_content">Contingut sensible</string>
|
||||
<string name="sensitive_content_explain">L\'autor va marcar aquest mitjà com a sensible. Toca per a mostrar-lo.</string>
|
||||
<string name="sensitive_content_explain">L\'autor ha marcat aquest mitjà com a sensible. Toca per a mostrar-lo.</string>
|
||||
<string name="media_hidden">Toca per a mostrar</string>
|
||||
<string name="avatar_description">Vés al perfil de: %s</string>
|
||||
<string name="more_options">Més opcions</string>
|
||||
@@ -368,7 +368,7 @@
|
||||
<string name="file_size_gb">%.2f GB</string>
|
||||
<string name="file_upload_progress">%1$s de %2$s</string>
|
||||
<string name="file_upload_time_remaining">%s restants</string>
|
||||
<string name="upload_error_connection_lost">El teu dispositiu ha perdut la connexió a internet</string>
|
||||
<string name="upload_error_connection_lost">El dispositiu ha perdut la connexió a Internet</string>
|
||||
<string name="upload_processing">S\'està processant…</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_available">Mastodon per a Android %s està preparat per a baixar-se.</string>
|
||||
@@ -380,9 +380,7 @@
|
||||
<string name="privacy_policy_title">Mastodon i la teva privacitat</string>
|
||||
<string name="privacy_policy_subtitle">Tot i que l\'aplicació Mastodon no recull cap dada, el servidor mitjançant el qual et registres pot tenir una política diferent. Pren un minut per revisar i acceptar la política de privadesa de l\'aplicació Mastodon i la política de privadesa del teu servidor.</string>
|
||||
<string name="i_agree">D’acord</string>
|
||||
<!-- Missing strings -->
|
||||
<string name="bookmarks">Marcadors</string>
|
||||
<string name="pinned_posts">Fixat</string>
|
||||
<string name="empty_list">Aquesta llista està buida</string>
|
||||
<string name="instance_signup_closed">Aquest servidor no accepta nous registres.</string>
|
||||
<string name="bookmarks">Marcadors</string>
|
||||
</resources>
|
||||
|
||||
4
mastodon/src/main/res/values-ca-rES/strings_sk.xml
Normal file
4
mastodon/src/main/res/values-ca-rES/strings_sk.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="sk_pinned_posts">Fixat</string>
|
||||
</resources>
|
||||
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="get_started">Začít</string>
|
||||
<string name="get_started">Začínáme</string>
|
||||
<string name="log_in">Přihlásit se</string>
|
||||
<string name="next">Další</string>
|
||||
<string name="loading_instance">Získávání informací o instanci…</string>
|
||||
<string name="error">Chyba</string>
|
||||
<string name="not_a_mastodon_instance">Zdá se, že %s není instancí Mastodonu.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="preparing_auth">Příprava na ověřování…</string>
|
||||
<string name="finishing_auth">Dokončení ověřování…</string>
|
||||
<string name="preparing_auth">Příprava na autentizaci…</string>
|
||||
<string name="finishing_auth">Dokončení autentizace…</string>
|
||||
<string name="user_boosted">Uživatel %s boostnul</string>
|
||||
<string name="in_reply_to">V odpovědi na %s</string>
|
||||
<string name="notifications">Upozornění</string>
|
||||
<string name="user_followed_you">vás sleduje</string>
|
||||
<string name="user_followed_you">vás začal(a) sledovat</string>
|
||||
<string name="user_sent_follow_request">vám poslal(a) žádost o sledování</string>
|
||||
<string name="user_favorited">si oblíbil(a) váš příspěvek</string>
|
||||
<string name="notification_boosted">boostnul(a) váš příspěvek</string>
|
||||
@@ -34,9 +34,9 @@
|
||||
<item quantity="other">sledujících</item>
|
||||
</plurals>
|
||||
<plurals name="following">
|
||||
<item quantity="one">sledovaní</item>
|
||||
<item quantity="few">sledování</item>
|
||||
<item quantity="many">sledování</item>
|
||||
<item quantity="one">sledovaný</item>
|
||||
<item quantity="few">sledovaní</item>
|
||||
<item quantity="many">sledovaných</item>
|
||||
<item quantity="other">sledovaných</item>
|
||||
</plurals>
|
||||
<plurals name="posts">
|
||||
@@ -52,10 +52,10 @@
|
||||
<string name="button_follow">Sledovat</string>
|
||||
<string name="button_following">Sleduji</string>
|
||||
<string name="edit_profile">Upravit profil</string>
|
||||
<string name="mention_user">Zmínit @%s</string>
|
||||
<string name="mention_user">Zmínit %s</string>
|
||||
<string name="share_user">Sdílet %s</string>
|
||||
<string name="mute_user">Skrýt %s</string>
|
||||
<string name="unmute_user">Odkrýt @%s</string>
|
||||
<string name="unmute_user">Zrušit skrytí @%s</string>
|
||||
<string name="block_user">Blokovat %s</string>
|
||||
<string name="unblock_user">Odblokovat %s</string>
|
||||
<string name="report_user">Nahlásit %s</string>
|
||||
@@ -67,14 +67,14 @@
|
||||
<item quantity="many">%,d příspěvků</item>
|
||||
<item quantity="other">%,d příspěvků</item>
|
||||
</plurals>
|
||||
<string name="profile_joined">Účet vytvořen</string>
|
||||
<string name="profile_joined">Připojen/a</string>
|
||||
<string name="done">Hotovo</string>
|
||||
<string name="loading">Načítání…</string>
|
||||
<string name="field_label">Označení</string>
|
||||
<string name="field_content">Obsah</string>
|
||||
<string name="saving">Ukládání…</string>
|
||||
<string name="post_from_user">Příspěvek od %s</string>
|
||||
<string name="poll_option_hint">Možnost %d</string>
|
||||
<string name="poll_option_hint">Volba %d</string>
|
||||
<plurals name="x_minutes">
|
||||
<item quantity="one">%d minuta</item>
|
||||
<item quantity="few">%d minuty</item>
|
||||
@@ -108,7 +108,7 @@
|
||||
</plurals>
|
||||
<plurals name="x_hours_left">
|
||||
<item quantity="one">Zbývá %d hodina</item>
|
||||
<item quantity="few">Zbývá %d hodiny</item>
|
||||
<item quantity="few">Zbývají %d hodiny</item>
|
||||
<item quantity="many">Zbývá %d hodin</item>
|
||||
<item quantity="other">Zbývá %d hodin</item>
|
||||
</plurals>
|
||||
@@ -129,20 +129,20 @@
|
||||
<string name="confirm_mute">Potvrdit skrytí %s</string>
|
||||
<string name="do_mute">Skrýt</string>
|
||||
<string name="confirm_unmute_title">Zrušit skrytí účtu</string>
|
||||
<string name="confirm_unmute">Potvrďte zrušení skrytí %s</string>
|
||||
<string name="do_unmute">Odkrýt</string>
|
||||
<string name="confirm_unmute">Potvrdit zrušení skrytí %s</string>
|
||||
<string name="do_unmute">Zrušit skrytí</string>
|
||||
<string name="confirm_block_title">Blokovat účet</string>
|
||||
<string name="confirm_block_domain_title">Blokovat doménu</string>
|
||||
<string name="confirm_block">Potvrďte blokování %s</string>
|
||||
<string name="confirm_block">Potvrdit blokování %s</string>
|
||||
<string name="do_block">Blokovat</string>
|
||||
<string name="confirm_unblock_title">Odblokovat účet</string>
|
||||
<string name="confirm_unblock_domain_title">Odblokovat doménu</string>
|
||||
<string name="confirm_unblock">Potvrďte odblokování %s</string>
|
||||
<string name="confirm_unblock">Potvrdit odblokování %s</string>
|
||||
<string name="do_unblock">Odblokovat</string>
|
||||
<string name="button_muted">Skrytý</string>
|
||||
<string name="button_blocked">Blokovaný</string>
|
||||
<string name="action_vote">Hlasovat</string>
|
||||
<string name="tap_to_reveal">Klepnutím zobraz</string>
|
||||
<string name="tap_to_reveal">Klepněte pro zobrazení</string>
|
||||
<string name="delete">Smazat</string>
|
||||
<string name="confirm_delete_title">Smazat příspěvek</string>
|
||||
<string name="confirm_delete">Opravdu chcete smazat tento příspěvek?</string>
|
||||
@@ -165,42 +165,42 @@
|
||||
<item quantity="other">%d lidí mluví</item>
|
||||
</plurals>
|
||||
<plurals name="discussed_x_times">
|
||||
<item quantity="one">Diskutováno %d krát</item>
|
||||
<item quantity="few">Diskutováno %d krát</item>
|
||||
<item quantity="many">Diskutováno %d krát</item>
|
||||
<item quantity="other">Diskutováno %d krát</item>
|
||||
<item quantity="one">Diskutováno %dkrát</item>
|
||||
<item quantity="few">Diskutováno %dkrát</item>
|
||||
<item quantity="many">Diskutováno %dkrát</item>
|
||||
<item quantity="other">Diskutováno %dkrát</item>
|
||||
</plurals>
|
||||
<string name="report_title">Nahlásit %s</string>
|
||||
<string name="report_choose_reason">Co je na tomto příspěvku špatně?</string>
|
||||
<string name="report_choose_reason_account">Co je špatně na %s?</string>
|
||||
<string name="report_choose_reason_subtitle">Vyberte nejbližší možnost</string>
|
||||
<string name="report_reason_personal">Nelíbí se mi</string>
|
||||
<string name="report_reason_personal">Nelíbí se mi to</string>
|
||||
<string name="report_reason_personal_subtitle">Není to něco, co chcete vidět</string>
|
||||
<string name="report_reason_spam">Je to spam</string>
|
||||
<string name="report_reason_spam_subtitle">Škodlivé odkazy, falešné interakce nebo opakované odpovědi</string>
|
||||
<string name="report_reason_violation">Porušuje pravidla serveru</string>
|
||||
<string name="report_reason_violation_subtitle">Máte za to, že porušuje konkrétní pravidla</string>
|
||||
<string name="report_reason_other">Jde o něco jiného</string>
|
||||
<string name="report_reason_violation">Porušuje to pravidla serveru</string>
|
||||
<string name="report_reason_violation_subtitle">Máte za to, že to porušuje konkrétní pravidla</string>
|
||||
<string name="report_reason_other">It\'s something else</string>
|
||||
<string name="report_reason_other_subtitle">Problém neodpovídá ostatním kategoriím</string>
|
||||
<string name="report_choose_rule">Která pravidla porušuje?</string>
|
||||
<string name="report_choose_rule">Která pravidla to porušuje?</string>
|
||||
<string name="report_choose_rule_subtitle">Vyberte všechna relevantní</string>
|
||||
<string name="report_choose_posts">Existují příspěvky dokládající toto hlášení?</string>
|
||||
<string name="report_choose_posts_subtitle">Vyberte všechna relevantní</string>
|
||||
<string name="report_choose_posts_subtitle">Vyberte všechny relevantní</string>
|
||||
<string name="report_comment_title">Je ještě něco jiného, co bychom měli vědět?</string>
|
||||
<string name="report_comment_hint">Dodatečné komentáře</string>
|
||||
<string name="report_comment_hint">Další komentáře</string>
|
||||
<string name="sending_report">Odesílání hlášení…</string>
|
||||
<string name="report_sent_title">Děkujeme za nahlášení, podíváme se na to.</string>
|
||||
<string name="report_sent_subtitle">Zatímco to posuzujeme, můžete podniknout kroky proti %s.</string>
|
||||
<string name="report_sent_subtitle">Zatímco to posuzujeme, můžete podniknout akce proti %s.</string>
|
||||
<string name="unfollow_user">Přestat sledovat %s</string>
|
||||
<string name="unfollow">Přestat sledovat</string>
|
||||
<string name="mute_user_explain">Neuvidíte jejich příspěvky nebo boostnutí v domovském kanálu. Nebudou vědět, že jsou skrytí.</string>
|
||||
<string name="block_user_explain">Už nebudou moci sledovat nebo vidět vaše příspěvky, ale mohou vidět, že byli blokováni.</string>
|
||||
<string name="mute_user_explain">Neuvidíte příspěvky nebo boosty tohoto uživatele ve svém domovském kanálu. Nebude vědět, že je skryt.</string>
|
||||
<string name="block_user_explain">Tento uživatel vás již nebude moci sledovat ani vidět vaše příspěvky, ale může zjistit, že je blokován.</string>
|
||||
<string name="report_personal_title">Nechcete tohle vidět?</string>
|
||||
<string name="report_personal_subtitle">Když uvidíte něco, co se vám nelíbí na Mastodonu, můžete odstranit tuto osobu ze svého zážitku.</string>
|
||||
<string name="back">Zpět</string>
|
||||
<string name="instance_catalog_title">Mastodon tvoří uživatelé z různých serverů.</string>
|
||||
<string name="instance_catalog_subtitle">Vyberte si server podle na svých zájmů, regionu nebo obecného účelu. Stále se můžete spojit se všemi bez ohledu na server.</string>
|
||||
<string name="search_communities">Hledat nebo zadat URL</string>
|
||||
<string name="search_communities">Hledat server nebo zadat URL</string>
|
||||
<string name="instance_rules_title">Některá základní pravidla</string>
|
||||
<string name="instance_rules_subtitle">Udělejte si chvíli čas a zkontrolujte pravidla, která admini %s nastavili a vynucují.</string>
|
||||
<string name="signup_title">Pojďme si nastavit %s</string>
|
||||
@@ -227,19 +227,19 @@
|
||||
<string name="confirm_email_subtitle">Klepněte na odkaz, který jsme vám poslali e-mailem, abyste účet ověřili.</string>
|
||||
<string name="resend">Poslat znovu</string>
|
||||
<string name="open_email_app">Otevřít e-mailovou aplikaci</string>
|
||||
<string name="resent_email">Potvrzující e-mail odeslán</string>
|
||||
<string name="resent_email">Potvrzující e-mail byl odeslán</string>
|
||||
<string name="compose_hint">Napište nebo vložte, co máte na mysli</string>
|
||||
<string name="content_warning">Varování o obsahu</string>
|
||||
<string name="add_image_description">Přidat popis obrázku…</string>
|
||||
<string name="retry_upload">Opakovat nahrání</string>
|
||||
<string name="edit_image">Upravit obrázek</string>
|
||||
<string name="save">Uložit</string>
|
||||
<string name="add_alt_text">Přidat alt text</string>
|
||||
<string name="alt_text_subtitle">Alt text popisuje obrázky pro lidi se špatným nebo žádným zrakem. Pokuste se zahrnout jen tolik obsahu, kolik je potřeba pro pochopení kontextu.</string>
|
||||
<string name="alt_text_hint">Např. podezřívavě rozhlížející se pes se zúženýma očima namířenýma na kameru.</string>
|
||||
<string name="visibility_public">Veřejný</string>
|
||||
<string name="add_alt_text">Přidat alternativní text</string>
|
||||
<string name="alt_text_subtitle">Alternativní text popisuje obrázky pro lidi se špatným zrakem nebo bez zraku. Pokuste se zahrnout jen tolik obsahu, kolik je potřeba pro pochopení kontextu.</string>
|
||||
<string name="alt_text_hint">např. Podezřívavě rozhlížející se pes se zúženýma očima namířenýma na kameru.</string>
|
||||
<string name="visibility_public">Veřejné</string>
|
||||
<string name="visibility_followers_only">Pouze sledující</string>
|
||||
<string name="visibility_private">Pouze lidé, které zmíním</string>
|
||||
<string name="visibility_private">Pouze zmínění lidé</string>
|
||||
<string name="search_all">Vše</string>
|
||||
<string name="search_people">Lidé</string>
|
||||
<string name="recent_searches">Nedávná hledání</string>
|
||||
@@ -247,53 +247,53 @@
|
||||
<string name="skip">Přeskočit</string>
|
||||
<string name="notification_type_follow">Noví sledující</string>
|
||||
<string name="notification_type_favorite">Oblíbené</string>
|
||||
<string name="notification_type_reblog">Boostnutí</string>
|
||||
<string name="notification_type_reblog">Boosty</string>
|
||||
<string name="notification_type_mention">Zmínky</string>
|
||||
<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ích příloh</item>
|
||||
<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">Vizuální podoba</string>
|
||||
<string name="settings_theme">Vizuální vzhled</string>
|
||||
<string name="theme_auto">Automatická</string>
|
||||
<string name="theme_light">Světlá</string>
|
||||
<string name="theme_dark">Tmavá</string>
|
||||
<string name="theme_light">Světlý</string>
|
||||
<string name="theme_dark">Tmavý</string>
|
||||
<string name="theme_true_black">Režim skutečně černé</string>
|
||||
<string name="settings_behavior">Chování</string>
|
||||
<string name="settings_gif">Přehrávat animované avatary a emoji</string>
|
||||
<string name="settings_custom_tabs">Používat interní prohlížeč</string>
|
||||
<string name="settings_notifications">Upozornění</string>
|
||||
<string name="settings_custom_tabs">Používat prohlížeč v aplikaci</string>
|
||||
<string name="settings_notifications">Oznámení</string>
|
||||
<string name="notify_me_when">Upozornit mě, když</string>
|
||||
<string name="notify_anyone">kdokoliv</string>
|
||||
<string name="notify_follower">sledující</string>
|
||||
<string name="notify_followed">někdo, koho sleduji</string>
|
||||
<string name="notify_none">nikoho</string>
|
||||
<string name="notify_favorites">Oblíbil si můj příspěvek</string>
|
||||
<string name="notify_follow">Sleduje mě</string>
|
||||
<string name="notify_reblog">Boostnul můj příspěvek</string>
|
||||
<string name="notify_mention">Zmiňuje mě</string>
|
||||
<string name="notify_favorites">Oblíbí si můj příspěvek</string>
|
||||
<string name="notify_follow">Začne mě sledovat</string>
|
||||
<string name="notify_reblog">Boostne můj příspěvek</string>
|
||||
<string name="notify_mention">Zmíní mě</string>
|
||||
<string name="settings_boring">Nudná část</string>
|
||||
<string name="settings_account">Nastavení účtu</string>
|
||||
<string name="settings_contribute">Přispějte do Mastodonu</string>
|
||||
<string name="settings_tos">Podmínky používání</string>
|
||||
<string name="settings_tos">Podmínky užití</string>
|
||||
<string name="settings_privacy_policy">Zásady ochrany osobních údajů</string>
|
||||
<string name="settings_spicy">Ostrá část</string>
|
||||
<string name="settings_clear_cache">Vymazat mezipaměť médií</string>
|
||||
<string name="settings_app_version">Mastodon pro Android v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Mezipaměť médií vymazána</string>
|
||||
<string name="settings_app_version">Mastodon for Android v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Mezipaměť médií byla vymazána</string>
|
||||
<string name="confirm_log_out">Opravdu se chcete odhlásit?</string>
|
||||
<string name="sensitive_content">Citlivý obsah</string>
|
||||
<string name="sensitive_content_explain">Autor označil toto médium za citlivé. Klepnutím zobrazíte.</string>
|
||||
<string name="media_hidden">Klepnutím zobrazit</string>
|
||||
<string name="avatar_description">Jít na profil %s</string>
|
||||
<string name="sensitive_content_explain">Autor označil toto médium jako citlivé. Klepnutím ho zobrazíte.</string>
|
||||
<string name="media_hidden">Klepněte pro zobrazení</string>
|
||||
<string name="avatar_description">Přejít na profil uživatele %s</string>
|
||||
<string name="more_options">Více možností</string>
|
||||
<string name="reveal_content">Zobrazit obsah</string>
|
||||
<string name="reveal_content">Odhalit obsah</string>
|
||||
<string name="hide_content">Skrýt obsah</string>
|
||||
<string name="new_post">Nový příspěvek</string>
|
||||
<string name="button_reply">Odpovědět</string>
|
||||
@@ -309,34 +309,34 @@
|
||||
<string name="my_profile">Můj profil</string>
|
||||
<string name="media_viewer">Prohlížeč médií</string>
|
||||
<string name="follow_user">Sledovat %s</string>
|
||||
<string name="unfollowed_user">Sledování %s ukončeno</string>
|
||||
<string name="unfollowed_user">Sledování %s bylo zrušeno</string>
|
||||
<string name="followed_user">Nyní sledujete %s</string>
|
||||
<string name="open_in_browser">Otevřít v prohlížeči</string>
|
||||
<string name="hide_boosts_from_user">Skrýt boosty od %s</string>
|
||||
<string name="show_boosts_from_user">Zobrazit boosty od %s</string>
|
||||
<string name="signup_reason">proč se chcete připojit?</string>
|
||||
<string name="signup_reason">proč se chcete zaregistrovat?</string>
|
||||
<string name="signup_reason_note">Toto nám pomůže posoudit vaši žádost.</string>
|
||||
<string name="clear">Vyčistit</string>
|
||||
<string name="profile_header">Obrázek v záhlaví</string>
|
||||
<string name="profile_picture">Profilová fotografie</string>
|
||||
<string name="profile_picture">Profilový obrázek</string>
|
||||
<string name="reorder">Změnit pořadí</string>
|
||||
<string name="download">Stáhnout</string>
|
||||
<string name="permission_required">Vyžadováno oprávnění</string>
|
||||
<string name="permission_required">Je vyžadováno oprávnění</string>
|
||||
<string name="storage_permission_to_download">Aplikace potřebuje přístup k vašemu úložišti, aby mohla uložit tento soubor.</string>
|
||||
<string name="open_settings">Otevřít nastavení</string>
|
||||
<string name="error_saving_file">Chyba při ukládání souboru</string>
|
||||
<string name="file_saved">Soubor uložen</string>
|
||||
<string name="error_saving_file">Nastala chyba při ukládání souboru</string>
|
||||
<string name="file_saved">Soubor byl uložen</string>
|
||||
<string name="downloading">Stahování…</string>
|
||||
<string name="no_app_to_handle_action">Nebyly nalezeny žádné aplikace pro tuto úlohu</string>
|
||||
<string name="local_timeline">Komunita</string>
|
||||
<string name="trending_posts_info_banner">Toto jsou příspěvky, které získávají pozornost ve vašem koutu Mastodonu.</string>
|
||||
<string name="trending_hashtags_info_banner">Toto jsou hashtagy, které získávají pozornost ve vašem koutu Mastodonu.</string>
|
||||
<string name="trending_links_info_banner">Toto jsou zprávy, které jsou nejvíce sdíleny ve vašem koutu Mastodonu.</string>
|
||||
<string name="trending_posts_info_banner">Tyto příspěvky získávají na popularitě ve vašem koutu Mastodonu.</string>
|
||||
<string name="trending_hashtags_info_banner">Tyto hashtagy získávají na popularitě ve vašem koutu Mastodonu.</string>
|
||||
<string name="trending_links_info_banner">Tyto zprávy jsou nejvíce sdíleny ve vašem koutu Mastodonu.</string>
|
||||
<string name="local_timeline_info_banner">Toto jsou nejnovější příspěvky od lidí, kteří používají stejný server Mastodonu jako vy.</string>
|
||||
<string name="dismiss">Zavřít</string>
|
||||
<string name="see_new_posts">Zobrazit nové příspěvky</string>
|
||||
<string name="load_missing_posts">Načíst chybějící příspěvky</string>
|
||||
<string name="follow_back">Sledovat zpátky</string>
|
||||
<string name="follow_back">Sledovat nazpět</string>
|
||||
<string name="button_follow_pending">Čekající</string>
|
||||
<string name="follows_you">Sleduje vás</string>
|
||||
<string name="manually_approves_followers">Ručně schvaluje sledující</string>
|
||||
@@ -351,34 +351,34 @@
|
||||
</plurals>
|
||||
<plurals name="x_following">
|
||||
<item quantity="one">%,d sledující</item>
|
||||
<item quantity="few">%,d sledování</item>
|
||||
<item quantity="many">%,d sledování</item>
|
||||
<item quantity="other">%,d sledování</item>
|
||||
<item quantity="few">%,d sledovaní</item>
|
||||
<item quantity="many">%,d sledovaných</item>
|
||||
<item quantity="other">%,d sledovaných</item>
|
||||
</plurals>
|
||||
<plurals name="x_favorites">
|
||||
<item quantity="one">%,d oblíbený</item>
|
||||
<item quantity="few">%,d oblíbené</item>
|
||||
<item quantity="many">%,d oblíbených</item>
|
||||
<item quantity="other">%,d oblíbených</item>
|
||||
<item quantity="one">%,d oblíbení</item>
|
||||
<item quantity="few">%,d oblíbení</item>
|
||||
<item quantity="many">%,d oblíbení</item>
|
||||
<item quantity="other">%,d oblíbení</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="one">%,d boostnul</item>
|
||||
<item quantity="few">%,d boostnuli</item>
|
||||
<item quantity="many">%,d boostnulo</item>
|
||||
<item quantity="other">%,d boostnulo</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="post_info_reblogs">Reblogy</string>
|
||||
<string name="post_info_favorites">Oblíbené</string>
|
||||
<string name="edit_history">Historie změn</string>
|
||||
<string name="post_info_reblogs">Boosty</string>
|
||||
<string name="post_info_favorites">Oblíbení</string>
|
||||
<string name="edit_history">Historie úprav</string>
|
||||
<string name="last_edit_at_x">Poslední úprava %s</string>
|
||||
<string name="time_just_now">právě teď</string>
|
||||
<plurals name="x_seconds_ago">
|
||||
<item quantity="one">Před 1 vteřinou</item>
|
||||
<item quantity="few">Před %d vteřinami</item>
|
||||
<item quantity="many">Před %d vteřinami</item>
|
||||
<item quantity="other">Před %d vteřinami</item>
|
||||
<item quantity="one">před %d sekundou</item>
|
||||
<item quantity="few">před %d sekundami</item>
|
||||
<item quantity="many">před %d sekundami</item>
|
||||
<item quantity="other">před %d sekundami</item>
|
||||
</plurals>
|
||||
<plurals name="x_minutes_ago">
|
||||
<item quantity="one">před %d minutou</item>
|
||||
@@ -388,21 +388,21 @@
|
||||
</plurals>
|
||||
<string name="edited_timestamp">upraveno %s</string>
|
||||
<string name="edit_original_post">Původní příspěvek</string>
|
||||
<string name="edit_text_edited">Text upraven</string>
|
||||
<string name="edit_spoiler_added">Upozornění na obsah bylo přidáno</string>
|
||||
<string name="edit_spoiler_edited">Upozornění na obsah upraveno</string>
|
||||
<string name="edit_spoiler_removed">Upozornění na obsah odstraněno</string>
|
||||
<string name="edit_poll_added">Anketa přidána</string>
|
||||
<string name="edit_poll_edited">Anketa upravena</string>
|
||||
<string name="edit_poll_removed">Anketa odstraněna</string>
|
||||
<string name="edit_text_edited">Text byl upraven</string>
|
||||
<string name="edit_spoiler_added">Varování o obsahu bylo přidáno</string>
|
||||
<string name="edit_spoiler_edited">Varování o obsahu bylo upraveno</string>
|
||||
<string name="edit_spoiler_removed">Varování o obsahu bylo odebráno</string>
|
||||
<string name="edit_poll_added">Anketa byla přidána</string>
|
||||
<string name="edit_poll_edited">Anketa byla upravena</string>
|
||||
<string name="edit_poll_removed">Anketa byla odebrána</string>
|
||||
<string name="edit_media_added">Média přidána</string>
|
||||
<string name="edit_media_removed">Média odstraněna</string>
|
||||
<string name="edit_media_reordered">Média přeřazena</string>
|
||||
<string name="edit_media_reordered">Pořadí médií bylo změněno</string>
|
||||
<string name="edit_marked_sensitive">Označeno jako citlivé</string>
|
||||
<string name="edit_marked_not_sensitive">Označeno, že není citlivé</string>
|
||||
<string name="edit_multiple_changed">Příspěvek upraven</string>
|
||||
<string name="edit_multiple_changed">Příspěvek byl upraven</string>
|
||||
<string name="edit">Upravit</string>
|
||||
<string name="discard_changes">Zrušit změny?</string>
|
||||
<string name="discard_changes">Zahodit změny?</string>
|
||||
<string name="upload_failed">Nahrávání se nezdařilo</string>
|
||||
<string name="file_size_bytes">%d bajtů</string>
|
||||
<string name="file_size_kb">%.2f KB</string>
|
||||
@@ -413,7 +413,7 @@
|
||||
<string name="upload_error_connection_lost">Vaše zařízení ztratilo připojení k internetu</string>
|
||||
<string name="upload_processing">Zpracovávání…</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_available">Mastodon pro Android %s je připravený ke stažení.</string>
|
||||
<string name="update_available">Mastodon pro Android %s je připraven ke stažení.</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_ready">Mastodon pro Android %s je stažený a připravený k instalaci.</string>
|
||||
<!-- %s is file size -->
|
||||
@@ -423,4 +423,10 @@
|
||||
<string name="privacy_policy_subtitle">Ačkoliv aplikace Mastodon neshromažďuje žádná data, server, na kterém se registrujete, může mít jiné zásady. Věnujte minutu kontrole a odsouhlasení zásad soukromí aplikace Mastodon a vašeho serveru.</string>
|
||||
<string name="i_agree">Souhlasím</string>
|
||||
<string name="empty_list">Tento seznam je prázdný</string>
|
||||
<string name="instance_signup_closed">Tento server nepřijímá nové registrace.</string>
|
||||
<string name="text_copied">Zkopírováno do schránky</string>
|
||||
<string name="add_bookmark">Přidat do záložek</string>
|
||||
<string name="remove_bookmark">Odstranit ze záložek</string>
|
||||
<string name="bookmarks">Záložky</string>
|
||||
<string name="your_favorites">Vaše oblíbení</string>
|
||||
</resources>
|
||||
|
||||
3
mastodon/src/main/res/values-cs-rCZ/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-cs-rCZ/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -3,12 +3,12 @@
|
||||
<string name="get_started">Loslegen</string>
|
||||
<string name="log_in">Anmelden</string>
|
||||
<string name="next">Weiter</string>
|
||||
<string name="loading_instance">Instanzinformationen werden geladen…</string>
|
||||
<string name="loading_instance">Instanzinformationen werden geladen …</string>
|
||||
<string name="error">Fehler</string>
|
||||
<string name="not_a_mastodon_instance">%s scheint keine Mastodon-Instanz 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="preparing_auth">Authentifizierung wird vorbereitet …</string>
|
||||
<string name="finishing_auth">Authentifizierung wird abgeschlossen …</string>
|
||||
<string name="user_boosted">%s hat diesen Beitrag geteilt</string>
|
||||
<string name="in_reply_to">Als Antwort auf %s</string>
|
||||
<string name="notifications">Benachrichtigungen</string>
|
||||
@@ -40,7 +40,6 @@
|
||||
<item quantity="other">Beiträge</item>
|
||||
</plurals>
|
||||
<string name="posts">Beiträge</string>
|
||||
<string name="pinned_posts">Angeheftet</string>
|
||||
<string name="posts_and_replies">Beiträge und Antworten</string>
|
||||
<string name="media">Medien</string>
|
||||
<string name="profile_about">Über</string>
|
||||
@@ -62,10 +61,10 @@
|
||||
</plurals>
|
||||
<string name="profile_joined">Beigetreten</string>
|
||||
<string name="done">Fertig</string>
|
||||
<string name="loading">Wird geladen…</string>
|
||||
<string name="loading">wird geladen …</string>
|
||||
<string name="field_label">Beschriftung</string>
|
||||
<string name="field_content">Inhalt</string>
|
||||
<string name="saving">Speichern…</string>
|
||||
<string name="saving">Speichern …</string>
|
||||
<string name="post_from_user">Beitrag von %s</string>
|
||||
<string name="poll_option_hint">%d. Auswahl</string>
|
||||
<plurals name="x_minutes">
|
||||
@@ -121,20 +120,9 @@
|
||||
<string name="action_vote">Abstimmen</string>
|
||||
<string name="tap_to_reveal">Tippen zum Anzeigen</string>
|
||||
<string name="delete">Löschen</string>
|
||||
<string name="delete_and_redraft">Löschen und neu erstellen</string>
|
||||
<string name="confirm_delete_title">Beitrag löschen</string>
|
||||
<string name="confirm_delete_and_redraft_title">Beitrag löschen und neu erstellen</string>
|
||||
<string name="confirm_delete">Bist du dir sicher, dass du diesen Beitrag löschen möchtest?</string>
|
||||
<string name="confirm_delete_and_redraft">Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest?</string>
|
||||
<string name="deleting">Wird gelöscht…</string>
|
||||
<string name="pin_post">An Profil anheften</string>
|
||||
<string name="confirm_pin_post_title">Beitrag an Profil anheften</string>
|
||||
<string name="confirm_pin_post">Möchtest du den Beitrag an dein Profil anheften?</string>
|
||||
<string name="pinning">Wird angeheftet…</string>
|
||||
<string name="unpin_post">Von Profil lösen</string>
|
||||
<string name="confirm_unpin_post_title">Angehefteten Beitrag von Profil lösen</string>
|
||||
<string name="confirm_unpin_post">Bist du dir sicher, dass du den angehefteten Beitrag von deinem Profil lösen möchtest?</string>
|
||||
<string name="unpinning">Wird vom Profil gelöst…</string>
|
||||
<string name="notification_channel_audio_player">Audiowiedergabe</string>
|
||||
<string name="play">Abspielen</string>
|
||||
<string name="pause">Pausieren</string>
|
||||
@@ -214,18 +202,14 @@
|
||||
<string name="resent_email">Bestätigungs-E-Mail gesendet</string>
|
||||
<string name="compose_hint">Eintippen oder einfügen, was dir am Herzen liegt</string>
|
||||
<string name="content_warning">Inhaltwarnung</string>
|
||||
<string name="add_image_description">Bildbeschreibung hinzufügen…</string>
|
||||
<string name="add_image_description">Bildbeschreibung hinzufügen …</string>
|
||||
<string name="retry_upload">Hochladen erneut versuchen</string>
|
||||
<string name="image_description">Bildbeschreibung</string>
|
||||
<string name="image_upload_failed">Fehler beim Hochladen des Bildes</string>
|
||||
<string name="video_upload_failed">Fehler beim Hochladen des Videos</string>
|
||||
<string name="edit_image">Bild bearbeiten</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="add_alt_text">Bildbeschreibung hinzufügen</string>
|
||||
<string name="alt_text_subtitle">Die Bildbeschreibung („Alt-Text“) ist eine wichtige Unterstützung für blinde und sehbehinderte Menschen. Beschränke dich bei der Formulierung auf das nötigste, interpretiere nicht und beschreibe nur, was zu sehen ist, damit der Kontext verständlich ist und alle Menschen daran teilhaben können.</string>
|
||||
<string name="alt_text_hint">z. B. „Eine Giraffe auf einem Dreirad, während sie eine Banane isst.“</string>
|
||||
<string name="visibility_public">Öffentlich</string>
|
||||
<string name="visibility_unlisted">Nicht gelistet</string>
|
||||
<string name="visibility_followers_only">Nur Follower</string>
|
||||
<string name="visibility_private">Nur erwähnte Profile</string>
|
||||
<string name="search_all">Alle</string>
|
||||
@@ -253,11 +237,7 @@
|
||||
<string name="theme_true_black">Echter Schwarzmodus</string>
|
||||
<string name="settings_behavior">Verhalten</string>
|
||||
<string name="settings_gif">Animierte GIFs, Avatare und Emojis abspielen</string>
|
||||
<string name="settings_show_replies">Antworten anzeigen</string>
|
||||
<string name="settings_show_boosts">Geteilte Beiträge anzeigen</string>
|
||||
<string name="settings_load_new_posts">Automatisch neue Beiträge laden</string>
|
||||
<string name="settings_custom_tabs">In-App-Browser verwenden</string>
|
||||
<string name="settings_show_interaction_counts">Interaktions-Anzahlen anzeigen</string>
|
||||
<string name="settings_notifications">Benachrichtigungen</string>
|
||||
<string name="notify_me_when">Benachrichtige mich, wenn</string>
|
||||
<string name="notify_anyone">irgendjemand</string>
|
||||
@@ -275,7 +255,7 @@
|
||||
<string name="settings_privacy_policy">Datenschutzbestimmungen</string>
|
||||
<string name="settings_spicy">Gefährliches</string>
|
||||
<string name="settings_clear_cache">Medienpuffer leeren</string>
|
||||
<string name="settings_app_version">Megalodon v%1$s (%2$d)</string>
|
||||
<string name="settings_app_version">Mastodon für Android v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Medienpuffer geleert</string>
|
||||
<string name="confirm_log_out">Bist du dir sicher, dass du dich abmelden möchtest?</string>
|
||||
<string name="sensitive_content">Inhaltswarnung</string>
|
||||
@@ -292,7 +272,6 @@
|
||||
<string name="button_share">Teilen</string>
|
||||
<string name="media_no_description">Medien ohne Beschreibung</string>
|
||||
<string name="add_media">Medien hinzufügen</string>
|
||||
<string name="mark_media_as_sensitive">Medien als NSFW markieren</string>
|
||||
<string name="add_poll">Umfrage hinzufügen</string>
|
||||
<string name="emoji">Emoji</string>
|
||||
<string name="post_visibility">Sichtbarkeit des Beitrages</string>
|
||||
@@ -303,10 +282,8 @@
|
||||
<string name="unfollowed_user">%s entfolgt</string>
|
||||
<string name="followed_user">Du folgst nun %s</string>
|
||||
<string name="open_in_browser">Im Browser öffnen</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="user_post_notifications_on">Benachrichtigungen über Beiträge von %s aktiviert</string>
|
||||
<string name="user_post_notifications_off">Benachrichtigungen über Beiträge von %s deaktiviert</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">Weshalb möchtest du beitreten?</string>
|
||||
<string name="signup_reason_note">Das erleichtert uns die Prüfung deiner Anmeldung.</string>
|
||||
<string name="clear">Leeren</string>
|
||||
@@ -319,15 +296,13 @@
|
||||
<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>
|
||||
<string name="downloading">Wird heruntergeladen…</string>
|
||||
<string name="downloading">wird heruntergeladen …</string>
|
||||
<string name="no_app_to_handle_action">Es gibt keine App, um diese Aktion auszuführen</string>
|
||||
<string name="local_timeline">Lokal</string>
|
||||
<string name="federated_timeline">Föderation</string>
|
||||
<string name="trending_posts_info_banner">Dies sind Beiträge, die auf deinem Mastodon-Server gerade angesagt sind.</string>
|
||||
<string name="trending_hashtags_info_banner">Diese Hashtags sind auf deinem Mastodon-Server gerade angesagt.</string>
|
||||
<string name="trending_links_info_banner">Diese journalistischen Nachrichten werden auf deinem Mastodon-Server gerade am häufigsten geteilt.</string>
|
||||
<string name="local_timeline_info_banner">Das sind die neuesten Beiträge von Personen, die denselben Mastodon-Server benutzen.</string>
|
||||
<string name="federated_timeline_info_banner">Das sind die neuesten Beiträge von Personen, die in der Föderation deines Servers sind.</string>
|
||||
<string name="dismiss">Verwerfen</string>
|
||||
<string name="see_new_posts">Neue Beiträge anzeigen</string>
|
||||
<string name="load_missing_posts">Weitere Beiträge laden</string>
|
||||
@@ -394,28 +369,18 @@
|
||||
<string name="file_upload_progress">%1$s von %2$s</string>
|
||||
<string name="file_upload_time_remaining">%s verbleibend</string>
|
||||
<string name="upload_error_connection_lost">Dein Gerät hat gerade keinen Zugang zum Internet</string>
|
||||
<string name="upload_processing">Wird verarbeitet…</string>
|
||||
<string name="upload_processing">wird verarbeitet …</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_available">Megalodon %s ist zum Herunterladen bereit.</string>
|
||||
<string name="update_available">Mastodon für Android %s ist zum Herunterladen bereit.</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_ready">Megalodon %s wurde heruntergeladen und kann jetzt installiert werden.</string>
|
||||
<string name="update_ready">Mastodon für Android %s wurde heruntergeladen und kann jetzt installiert werden.</string>
|
||||
<!-- %s is file size -->
|
||||
<string name="download_update">(%s) herunterladen</string>
|
||||
<string name="install_update">Installieren</string>
|
||||
<string name="check_for_update">Auf Update prüfen</string>
|
||||
<string name="no_update_available">Kein Update verfügbar</string>
|
||||
<string name="list_timelines">Listen</string>
|
||||
<string name="favorited_posts">Favorisierte Beiträge</string>
|
||||
<string name="follow_requests">Folgeanfragen</string>
|
||||
<string name="accept_follow_request">Folgeanfrage akzeptieren</string>
|
||||
<string name="reject_follow_request">Folgeanfrage ablehnen</string>
|
||||
<string name="lists_with_user">Listen mit %s</string>
|
||||
<string name="privacy_policy_title">Mastodon und Ihre Privatsphäre</string>
|
||||
<string name="privacy_policy_subtitle">Obwohl die Megalodon-App keine Daten sammelt, kann der Server, über den Sie sich anmelden, eine andere Richtlinie haben. Nehmen Sie sich eine Minute Zeit, um die Mastodon-Datenschutzrichtlinien und die Datenschutzrichtlinien Ihres Servers zu lesen und zu akzeptieren.</string>
|
||||
<string name="privacy_policy_subtitle">Obwohl die Mastodon-App keine Daten sammelt, kann der Server, über den Sie sich anmelden, eine andere Richtlinie haben. Nehmen Sie sich eine Minute Zeit, um die Mastodon-Datenschutzrichtlinien und die Datenschutzrichtlinien Ihres Servers zu lesen und zu akzeptieren.</string>
|
||||
<string name="i_agree">Ich stimme zu</string>
|
||||
<string name="settings_always_reveal_content_warnings">Inhaltswarnungen immer ausklappen</string>
|
||||
<string name="disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
|
||||
<string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
|
||||
<string name="empty_list">Diese Liste ist leer</string>
|
||||
<string name="instance_signup_closed">Dieser Server akzeptiert keine neuen Registrierungen.</string>
|
||||
<string name="your_favorites">Deine Favoriten</string>
|
||||
</resources>
|
||||
|
||||
41
mastodon/src/main/res/values-de-rDE/strings_sk.xml
Normal file
41
mastodon/src/main/res/values-de-rDE/strings_sk.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="sk_app_name">Megalodon</string>
|
||||
<string name="sk_pinned_posts">Angeheftet</string>
|
||||
<string name="sk_delete_and_redraft">Löschen und neu erstellen</string>
|
||||
<string name="sk_confirm_delete_and_redraft_title">Beitrag löschen und neu erstellen</string>
|
||||
<string name="sk_confirm_delete_and_redraft">Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest?</string>
|
||||
<string name="sk_pin_post">An Profil anheften</string>
|
||||
<string name="sk_confirm_pin_post_title">Beitrag an Profil anheften</string>
|
||||
<string name="sk_confirm_pin_post">Möchtest du den Beitrag an dein Profil anheften?</string>
|
||||
<string name="sk_pinning">Wird angeheftet…</string>
|
||||
<string name="sk_unpin_post">Von Profil lösen</string>
|
||||
<string name="sk_confirm_unpin_post_title">Angehefteten Beitrag von Profil lösen</string>
|
||||
<string name="sk_confirm_unpin_post">Bist du dir sicher, dass du den angehefteten Beitrag von deinem Profil lösen möchtest?</string>
|
||||
<string name="sk_unpinning">Wird vom Profil gelöst…</string>
|
||||
<string name="sk_image_description">Bildbeschreibung</string>
|
||||
<string name="sk_visibility_unlisted">Nicht gelistet</string>
|
||||
<string name="sk_settings_show_replies">Antworten anzeigen</string>
|
||||
<string name="sk_settings_show_boosts">Geteilte Beiträge anzeigen</string>
|
||||
<string name="sk_settings_load_new_posts">Automatisch neue Beiträge laden</string>
|
||||
<string name="sk_settings_show_interaction_counts">Interaktions-Anzahlen anzeigen</string>
|
||||
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
|
||||
<string name="sk_mark_media_as_sensitive">Medien als sensibel markieren</string>
|
||||
<string name="sk_user_post_notifications_on">Benachrichtigungen über Beiträge von %s aktiviert</string>
|
||||
<string name="sk_user_post_notifications_off">Benachrichtigungen über Beiträge von %s deaktiviert</string>
|
||||
<string name="sk_federated_timeline">Föderation</string>
|
||||
<string name="sk_federated_timeline_info_banner">Das sind die neuesten Beiträge von Personen, die in der Föderation deines Servers sind.</string>
|
||||
<string name="sk_update_available">Megalodon %s ist zum Herunterladen bereit.</string>
|
||||
<string name="sk_update_ready">Megalodon %s wurde heruntergeladen und kann jetzt installiert werden.</string>
|
||||
<string name="sk_check_for_update">Auf Update prüfen</string>
|
||||
<string name="sk_no_update_available">Kein Update verfügbar</string>
|
||||
<string name="sk_list_timelines">Listen</string>
|
||||
<string name="sk_follow_requests">Folgeanfragen</string>
|
||||
<string name="sk_accept_follow_request">Folgeanfrage akzeptieren</string>
|
||||
<string name="sk_reject_follow_request">Folgeanfrage ablehnen</string>
|
||||
<string name="sk_lists_with_user">Listen mit %s</string>
|
||||
<string name="sk_settings_always_reveal_content_warnings">Inhaltswarnungen immer ausklappen</string>
|
||||
<string name="sk_disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
|
||||
<string name="sk_settings_contribute">Zu Megalodon beitragen</string>
|
||||
<string name="sk_settings_show_federated_timeline">Föderierte Timeline anzeigen</string>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-el-rGR/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-el-rGR/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
41
mastodon/src/main/res/values-es-rES/strings_sk.xml
Normal file
41
mastodon/src/main/res/values-es-rES/strings_sk.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="sk_pinned_posts">Anclado</string>
|
||||
<string name="sk_delete_and_redraft">Eliminar y editar</string>
|
||||
<string name="sk_confirm_delete_and_redraft_title">Eliminar y editar post</string>
|
||||
<string name="sk_confirm_delete_and_redraft">Seguro que quiere eliminar y volver a editar este post\?</string>
|
||||
<string name="sk_pin_post">Fijar en perfil</string>
|
||||
<string name="sk_confirm_pin_post_title">Fijar post en perfil</string>
|
||||
<string name="sk_confirm_pin_post">Desea fijar el post en su perfil\?</string>
|
||||
<string name="sk_pinning">Fijando post…</string>
|
||||
<string name="sk_unpin_post">Quitar del perfil</string>
|
||||
<string name="sk_confirm_unpin_post_title">Quitar post del perfil</string>
|
||||
<string name="sk_confirm_unpin_post">Está seguro que quiere quitar el post\?</string>
|
||||
<string name="sk_app_name">Megalodon</string>
|
||||
<string name="sk_unpinning">Quitando post…</string>
|
||||
<string name="sk_image_description">Descripción de la imagen</string>
|
||||
<string name="sk_visibility_unlisted">Sin listar</string>
|
||||
<string name="sk_settings_show_replies">Mostrar respuestas</string>
|
||||
<string name="sk_settings_show_boosts">Mostrar boosts</string>
|
||||
<string name="sk_settings_load_new_posts">Cargar nuevos posts automáticamente</string>
|
||||
<string name="sk_settings_show_interaction_counts">Mostrar contadores de interacciones</string>
|
||||
<string name="sk_mark_media_as_sensitive">Marcar medio como sensible</string>
|
||||
<string name="sk_user_post_notifications_on">Activadas las notificaciones de posts para %s</string>
|
||||
<string name="sk_user_post_notifications_off">Desactivadas las notificaciones de posts para %s</string>
|
||||
<string name="sk_federated_timeline">Federación</string>
|
||||
<string name="sk_federated_timeline_info_banner">Estos son los posts más recientes de las personas de tu federación.</string>
|
||||
<string name="sk_update_available">Megalodon %s está listo para descargar.</string>
|
||||
<string name="sk_update_ready">Megalodon %s se ha descargado y está listo para instalarse.</string>
|
||||
<string name="sk_check_for_update">Buscar actualizaciones</string>
|
||||
<string name="sk_no_update_available">No hay actualizaciones disponibles</string>
|
||||
<string name="sk_list_timelines">Listas</string>
|
||||
<string name="sk_follow_requests">Solicitudes de seguimiento</string>
|
||||
<string name="sk_accept_follow_request">Aceptar solicitud de seguimiento</string>
|
||||
<string name="sk_reject_follow_request">Rechazar solicitud de seguimiento</string>
|
||||
<string name="sk_lists_with_user">Listas con %s</string>
|
||||
<string name="sk_settings_always_reveal_content_warnings">Mostrar siempre advertencias de contenido</string>
|
||||
<string name="sk_disable_marquee">Desactivar desplazamiento de texto en barras del título</string>
|
||||
<string name="sk_settings_contribute">Contribuir a Megalodon</string>
|
||||
<string name="sk_settings_show_federated_timeline">Mostrar el timeline federado</string>
|
||||
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-eu-rES/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-eu-rES/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-fi-rFI/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-fi-rFI/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -382,4 +382,9 @@
|
||||
<string name="i_agree">J’accepte</string>
|
||||
<string name="empty_list">Cette liste est vide</string>
|
||||
<string name="instance_signup_closed">Ce serveur n\'accepte pas les nouvelles inscriptions.</string>
|
||||
<string name="text_copied">Copié dans le presse-papier</string>
|
||||
<string name="add_bookmark">Favoris</string>
|
||||
<string name="remove_bookmark">Retirer des favoris</string>
|
||||
<string name="bookmarks">Favoris</string>
|
||||
<string name="your_favorites">Vos favoris</string>
|
||||
</resources>
|
||||
|
||||
41
mastodon/src/main/res/values-fr-rFR/strings_sk.xml
Normal file
41
mastodon/src/main/res/values-fr-rFR/strings_sk.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="sk_pinned_posts">Épinglé</string>
|
||||
<string name="sk_confirm_delete_and_redraft_title">Supprimer et reformuler le message</string>
|
||||
<string name="sk_confirm_delete_and_redraft">Voulez-vous vraiment supprimer et reformuler ce message \?</string>
|
||||
<string name="sk_confirm_pin_post">Voulez-vous épingler ce message à votre profil \?</string>
|
||||
<string name="sk_pinning">Épinglage de la publication…</string>
|
||||
<string name="sk_unpin_post">Détacher du profil</string>
|
||||
<string name="sk_confirm_unpin_post_title">Détacher la publication du profil</string>
|
||||
<string name="sk_unpinning">Détachement de la publication…</string>
|
||||
<string name="sk_image_description">Description de l\'image</string>
|
||||
<string name="sk_visibility_unlisted">Non répertorié</string>
|
||||
<string name="sk_settings_show_replies">Afficher les réponses</string>
|
||||
<string name="sk_settings_show_boosts">Afficher les boosts</string>
|
||||
<string name="sk_settings_load_new_posts">Charger automatiquement les nouvelles publications</string>
|
||||
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
|
||||
<string name="sk_mark_media_as_sensitive">Marquer le média comme sensible</string>
|
||||
<string name="sk_user_post_notifications_on">Notifications de publication activées pour %s</string>
|
||||
<string name="sk_user_post_notifications_off">Désactivation des notifications de publication pour %s</string>
|
||||
<string name="sk_update_available">Megalodon %s est prêt à être téléchargé.</string>
|
||||
<string name="sk_update_ready">Megalodon %s est téléchargé et prêt à être installé.</string>
|
||||
<string name="sk_check_for_update">Vérifier les mises à jour</string>
|
||||
<string name="sk_no_update_available">Pas de mise a jour disponible</string>
|
||||
<string name="sk_list_timelines">Listes</string>
|
||||
<string name="sk_follow_requests">Suivre les demandes</string>
|
||||
<string name="sk_accept_follow_request">Accepter la demande de suivi</string>
|
||||
<string name="sk_reject_follow_request">Refuser la demande de suivi</string>
|
||||
<string name="sk_lists_with_user">Listes avec %s</string>
|
||||
<string name="sk_settings_always_reveal_content_warnings">Toujours afficher les avertissements de contenu</string>
|
||||
<string name="sk_disable_marquee">Désactiver le défilement du texte dans les barres de titre</string>
|
||||
<string name="sk_settings_contribute">Contribuez à Megalodon</string>
|
||||
<string name="sk_settings_show_federated_timeline">Afficher la timeline fédérée</string>
|
||||
<string name="sk_app_name">Megalodon</string>
|
||||
<string name="sk_delete_and_redraft">Supprimer et reformuler</string>
|
||||
<string name="sk_pin_post">Épingler au profil</string>
|
||||
<string name="sk_confirm_pin_post_title">Épingler la publication au profil</string>
|
||||
<string name="sk_confirm_unpin_post">Êtes-vous sûr de vouloir détacher cette publication \?</string>
|
||||
<string name="sk_settings_show_interaction_counts">Afficher le nombre d\'interactions</string>
|
||||
<string name="sk_federated_timeline">Fédération</string>
|
||||
<string name="sk_federated_timeline_info_banner">Ce sont les publications les plus récentes des membres de votre fédération.</string>
|
||||
</resources>
|
||||
3
mastodon/src/main/res/values-ga-rIE/strings_sk.xml
Normal file
3
mastodon/src/main/res/values-ga-rIE/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user