diff --git a/app/build.gradle b/app/build.gradle
index 13b1fa375c383c0357aeb01c434793f4c305754d..c9abf69c4f744fbe79c3af5ca1546fd43fd28956 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,8 +13,8 @@ android {
defaultConfig {
minSdk 21
targetSdk 34
- versionCode 528
- versionName "3.31.3"
+ versionCode 532
+ versionName "3.32.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
flavorDimensions "default"
@@ -109,7 +109,7 @@ allprojects {
}
}
dependencies {
- implementation 'org.unifiedpush.android:connector:3.0.7'
+ implementation 'org.unifiedpush.android:connector:3.0.9'
playstoreImplementation('org.unifiedpush.android:embedded-fcm-distributor:3.0.0')
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 94a24f1b5e85b727b5e61e62fc450f3b02d40018..28b4e7fb587e87c238de4aec573ab63e528eaae2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,6 +11,8 @@
tools:ignore="ScopedStorage" />
+
+
+
@@ -228,6 +234,7 @@
android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -750,4 +757,4 @@
android:resource="@xml/compose_shortcuts" />
-
\ No newline at end of file
+
diff --git a/app/src/main/assets/release_notes/notes.json b/app/src/main/assets/release_notes/notes.json
index dbb5859157a847e9de9bb014a71dd44b9e0662f2..8f9710a1479f4a08072672a30e1c4c43b25ad696 100644
--- a/app/src/main/assets/release_notes/notes.json
+++ b/app/src/main/assets/release_notes/notes.json
@@ -1,4 +1,24 @@
[
+ {
+ "version": "3.32.3",
+ "code": "532",
+ "note": "Fixed:\n- Polls not displayed\n- Pagination with trends\n- Push notifications not working on some devices"
+ },
+ {
+ "version": "3.32.2",
+ "code": "531",
+ "note": "Added:\n- An outline around media\n\nChanged:\n- Make username, display name in nav drawer clickable\n- Gif media not animated by default\n- Disable by default the mention to the booster when replying. Can be enabled in Settings > Compose (per account)\n\nFixed:\n- Wrong preview picture on share from another app\n- Crash when translating with MinT\n- Refresh and pagination broken for the Trending timeline\n- Fix lags / Crashes"
+ },
+ {
+ "version": "3.32.1",
+ "code": "530",
+ "note": "Fixed:\n- Fix a crash on some devices\n- Hide quote button\n- Fix a layout issue with pictures in landscape\n- Fix a crash when opening the original message from a picture"
+},
+ {
+ "version": "3.32.0",
+ "code": "529",
+ "note": "Added:\n- Add option to disable auto hiding compose button\n\nChanged:\n- Add more content descriptions for buttons\n- Update some buttons\n- Update navigation drawer header\n- Squeeze action buttons when needed to prevent overlapping\n\nFixed:\n- Fix crash when media are too heavy\n- Some custom emojis in bio do not render\n- Posting messages does not work on some Friendica instances\n- Fix a crash with auto-split messages\n- Fix a crash when opening conversations\n- Fix a background color issue when displaying media"
+ },
{
"version": "3.31.3",
"code": "528",
diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java
index 41ff2a0a7284e65b19f6a2da13484e606f4e0a9c..f99cea43451a96433f1c49a2310f3b467805d447 100644
--- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java
+++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java
@@ -72,6 +72,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
+import androidx.appcompat.widget.TooltipCompat;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
@@ -354,6 +355,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
};
private NetworkStateReceiver networkStateReceiver;
+ SharedPreferences sharedpreferences;
+
public static void fetchRecentAccounts(Activity activity, NavHeaderMainBinding headerMainBinding) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
//Fetch some db values to initialize data
@@ -461,7 +464,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
public static void manageDrawerMenu(Activity activity, NavigationView navigationView, NavHeaderMainBinding headerMainBinding) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
if (headerMenuOpen) {
- headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24);
+ headerMainBinding.ownerAccounts.setIconResource(R.drawable.ic_baseline_arrow_drop_up_24);
new Thread(() -> {
try {
List accounts = new Account(activity).getOtherAccounts();
@@ -592,7 +595,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
Intent mainActivity = new Intent(activity, MainActivity.class);
activity.startActivity(mainActivity);
activity.finish();
- headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24);
+ headerMainBinding.ownerAccounts.setIconResource(R.drawable.ic_accounts);
return true;
}
return false;
@@ -624,47 +627,32 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
} else if (Helper.getCurrentAccount(activity).peertube_account != null) {
navigationView.inflateMenu(R.menu.activity_main_drawer_peertube);
}
- headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24);
+ headerMainBinding.ownerAccounts.setIconResource(R.drawable.ic_accounts);
headerMenuOpen = false;
}
}
- public static void headerOptionInfoClick(Activity activity, NavHeaderMainBinding headerMainBinding, FragmentManager fragmentManager) {
- PopupMenu popup = new PopupMenu(activity, headerMainBinding.headerOptionInfo);
- popup.getMenuInflater()
- .inflate(R.menu.main, popup.getMenu());
-
- popup.setOnMenuItemClickListener(item -> {
- int itemId = item.getItemId();
- if (itemId == R.id.action_logout_account) {
- AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity);
- alt_bld.setTitle(R.string.action_logout);
- if (Helper.getCurrentAccount(activity).mastodon_account != null && Helper.getCurrentAccount(activity).instance != null) {
- alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, Helper.getCurrentAccount(activity).mastodon_account.username, Helper.getCurrentAccount(activity).instance));
- } else if (Helper.getCurrentAccount(activity).peertube_account != null && Helper.getCurrentAccount(activity).instance != null) {
- alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, Helper.getCurrentAccount(activity).peertube_account.getUsername(), Helper.getCurrentAccount(activity).instance));
- } else {
- alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, "", ""));
- }
- alt_bld.setPositiveButton(R.string.action_logout, (dialog, id) -> {
- dialog.dismiss();
- try {
- Helper.removeAccount(activity);
- } catch (DBException e) {
- e.printStackTrace();
- }
- });
- alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
- AlertDialog alert = alt_bld.create();
- alert.show();
- return true;
- } else if (itemId == R.id.action_proxy) {
- (new ProxyActivity()).show(fragmentManager, null);
- return true;
+ public static void headerLogoutClick(Activity activity, NavHeaderMainBinding headerMainBinding, FragmentManager fragmentManager) {
+ AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity);
+ alt_bld.setTitle(R.string.action_logout);
+ if (Helper.getCurrentAccount(activity).mastodon_account != null && Helper.getCurrentAccount(activity).instance != null) {
+ alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, Helper.getCurrentAccount(activity).mastodon_account.username, Helper.getCurrentAccount(activity).instance));
+ } else if (Helper.getCurrentAccount(activity).peertube_account != null && Helper.getCurrentAccount(activity).instance != null) {
+ alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, Helper.getCurrentAccount(activity).peertube_account.getUsername(), Helper.getCurrentAccount(activity).instance));
+ } else {
+ alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, "", ""));
+ }
+ alt_bld.setPositiveButton(R.string.action_logout, (dialog, id) -> {
+ dialog.dismiss();
+ try {
+ Helper.removeAccount(activity);
+ } catch (DBException e) {
+ e.printStackTrace();
}
- return true;
});
- popup.show();
+ alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
+ AlertDialog alert = alt_bld.create();
+ alert.show();
}
/**
@@ -1125,7 +1113,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this);
+ sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this);
if (!Helper.isLoggedIn(BaseMainActivity.this)) {
//It is not, the user is redirected to the login page
Intent myIntent = new Intent(BaseMainActivity.this, LoginActivity.class);
@@ -1464,12 +1452,13 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
startActivity(intent);
} else if (id == R.id.nav_about_instance) {
(new InstanceActivity()).show(getSupportFragmentManager(), null);
+ } else if (id == R.id.nav_instance_info) {
+ (new InstanceHealthActivity()).show(getSupportFragmentManager(), null);
}
binding.drawerLayout.close();
return false;
});
- headerMainBinding.instanceInfo.setOnClickListener(v -> (new InstanceHealthActivity()).show(getSupportFragmentManager(), null));
headerMainBinding.accountProfilePicture.setOnClickListener(v -> {
Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class);
Bundle args = new Bundle();
@@ -1483,13 +1472,16 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
});
- headerMainBinding.accountAcc.setOnClickListener(v -> headerMainBinding.changeAccount.callOnClick());
- headerMainBinding.changeAccount.setOnClickListener(v -> {
+ TooltipCompat.setTooltipText(headerMainBinding.ownerAccounts, getString(R.string.manage_accounts));
+ headerMainBinding.accountName.setOnClickListener(v -> headerMainBinding.ownerAccounts.performClick());
+ headerMainBinding.accountAcc.setOnClickListener(v -> headerMainBinding.ownerAccounts.performClick());
+ headerMainBinding.ownerAccounts.setOnClickListener(v -> {
headerMenuOpen = !headerMenuOpen;
manageDrawerMenu(BaseMainActivity.this, binding.navView, headerMainBinding);
});
- headerMainBinding.headerOptionInfo.setOnClickListener(v -> headerOptionInfoClick(BaseMainActivity.this, headerMainBinding, getSupportFragmentManager()));
+ TooltipCompat.setTooltipText(headerMainBinding.headerLogout,getString(R.string.action_logout));
+ headerMainBinding.headerLogout.setOnClickListener(v -> headerLogoutClick(BaseMainActivity.this, headerMainBinding, getSupportFragmentManager()));
//Toolbar search
binding.toolbarSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@@ -1605,8 +1597,14 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
fetchRecentAccounts(BaseMainActivity.this, headerMainBinding);
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (!sharedpreferences.getBoolean(getString(R.string.SET_AUTO_HIDE_COMPOSE), true) && !getFloatingVisibility())
+ manageFloatingButton(true);
+ }
+
private void manageTopBarScrolling(Toolbar toolbar) {
- final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
final boolean topBarScrolling = !sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_TOPBAR_SCROLLING), false);
final AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
@@ -2029,10 +2027,12 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
}
public void manageFloatingButton(boolean display) {
- if (display) {
- binding.compose.show();
- } else {
- binding.compose.hide();
+ if (sharedpreferences.getBoolean(getString(R.string.SET_AUTO_HIDE_COMPOSE), true)) {
+ if (display) {
+ binding.compose.show();
+ } else {
+ binding.compose.hide();
+ }
}
}
diff --git a/app/src/main/java/app/fedilab/android/mastodon/activities/ComposeActivity.java b/app/src/main/java/app/fedilab/android/mastodon/activities/ComposeActivity.java
index d0e53c863517c72dbd954e6022be322705bf1f65..bfd204e75279335baeb0a39e2a4606b386594fa4 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/activities/ComposeActivity.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/activities/ComposeActivity.java
@@ -502,6 +502,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
private void initializeAfterBundle(Bundle b) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
new Thread(() -> {
if (b != null) {
statusReply = (Status) b.getSerializable(Helper.ARG_STATUS_REPLY);
@@ -514,6 +515,8 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
if (account == null) {
account = Helper.getCurrentAccount(ComposeActivity.this);
}
+ boolean setMentionBooster = sharedpreferences.getBoolean(getString(R.string.SET_MENTION_BOOSTER) + account.user_id + account.instance, false);
+
editMessageId = b.getString(Helper.ARG_EDIT_STATUS_ID, null);
instance = b.getString(Helper.ARG_INSTANCE, null);
token = b.getString(Helper.ARG_TOKEN, null);
@@ -523,7 +526,11 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
} else if (visibility == null && Helper.getCurrentAccount(ComposeActivity.this) != null && Helper.getCurrentAccount(ComposeActivity.this).mastodon_account != null && Helper.getCurrentAccount(ComposeActivity.this).mastodon_account.source != null) {
visibility = Helper.getCurrentAccount(ComposeActivity.this).mastodon_account.source.privacy;
}
- mentionBooster = (Account) b.getSerializable(Helper.ARG_MENTION_BOOSTER);
+ if(setMentionBooster) {
+ mentionBooster = (Account) b.getSerializable(Helper.ARG_MENTION_BOOSTER);
+ } else {
+ mentionBooster = null;
+ }
accountMention = (Account) b.getSerializable(Helper.ARG_ACCOUNT_MENTION);
//Shared elements
sharedAttachments = (ArrayList) b.getSerializable(Helper.ARG_MEDIA_ATTACHMENTS);
diff --git a/app/src/main/java/app/fedilab/android/mastodon/activities/MediaActivity.java b/app/src/main/java/app/fedilab/android/mastodon/activities/MediaActivity.java
index aca57088ca11427f1d3be653d6829e07bfb9a299..a705dbf5de4c602785b2d9021728b0335aaed7d8 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/activities/MediaActivity.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/activities/MediaActivity.java
@@ -141,6 +141,9 @@ public class MediaActivity extends BaseBarActivity implements OnDownloadInterfac
if (bundle != null) {
mediaPosition = bundle.getInt(Helper.ARG_MEDIA_POSITION, 1);
+ if(mediaPosition < 1 ) {
+ mediaPosition = 1;
+ }
attachments = (ArrayList) bundle.getSerializable(Helper.ARG_MEDIA_ARRAY);
mediaFromProfile = bundle.getBoolean(Helper.ARG_MEDIA_ARRAY_PROFILE, false);
status = (Status) bundle.getSerializable(Helper.ARG_STATUS);
@@ -230,6 +233,9 @@ public class MediaActivity extends BaseBarActivity implements OnDownloadInterfac
public void onPageSelected(int position) {
mediaPosition = position;
+ if(mediaPosition < 1 ) {
+ mediaPosition = 1;
+ }
String description = attachments.get(position).description;
if (handler != null) {
handler.removeCallbacksAndMessages(null);
diff --git a/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java
index 30af13d8db79992a1f27ca90d507d2e3af60c775..1588c20ce7a96b7e3a50f45189dad982d7e3a483 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java
@@ -82,9 +82,6 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
import androidmads.library.qrgenearator.QRGContents;
import androidmads.library.qrgenearator.QRGEncoder;
@@ -103,6 +100,7 @@ import app.fedilab.android.mastodon.client.entities.api.Field;
import app.fedilab.android.mastodon.client.entities.api.IdentityProof;
import app.fedilab.android.mastodon.client.entities.api.MastodonList;
import app.fedilab.android.mastodon.client.entities.api.RelationShip;
+import app.fedilab.android.mastodon.client.entities.api.Status;
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
import app.fedilab.android.mastodon.client.entities.app.Languages;
import app.fedilab.android.mastodon.client.entities.app.Pinned;
@@ -132,7 +130,6 @@ public class ProfileActivity extends BaseActivity {
private RelationShip relationship;
private FamiliarFollowers familiarFollowers;
private Account account;
- private ScheduledExecutorService scheduledExecutorService;
private action doAction;
private AccountsVM accountsVM;
private RecyclerView identityProofsRecycler;
@@ -357,14 +354,7 @@ public class ProfileActivity extends BaseActivity {
this.identityProofList = identityProofs;
updateAccount();
});
- //Animate emojis
- if (account.emojis != null && !account.emojis.isEmpty()) {
- boolean disableAnimatedEmoji = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
- if (!disableAnimatedEmoji) {
- scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
- scheduledExecutorService.scheduleAtFixedRate(() -> binding.accountDn.invalidate(), 0, 130, TimeUnit.MILLISECONDS);
- }
- }
+
binding.accountTabLayout.clearOnTabSelectedListeners();
binding.accountTabLayout.removeAllTabs();
//Tablayout for timelines/following/followers
@@ -550,8 +540,15 @@ public class ProfileActivity extends BaseActivity {
});
binding.accountNote.setText(
account.getSpanNote(ProfileActivity.this,
- new WeakReference<>(binding.accountNote)),
+ new WeakReference<>(binding.accountNote), () -> {
+ //TODO: replace this hack
+ binding.accountNote.setText(
+ account.getSpanNote(ProfileActivity.this,
+ new WeakReference<>(binding.accountNote)), TextView.BufferType.SPANNABLE);
+
+ }),
TextView.BufferType.SPANNABLE);
+
binding.accountNote.setMovementMethod(LinkMovementMethod.getInstance());
@@ -1370,10 +1367,6 @@ public class ProfileActivity extends BaseActivity {
@Override
public void onDestroy() {
- if (scheduledExecutorService != null) {
- scheduledExecutorService.shutdownNow();
- scheduledExecutorService = null;
- }
try {
unregisterReceiver(broadcast_data);
} catch (IllegalArgumentException e) {
diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java
index 8d4cad2906df1cc9ff6857259a162747e6f03887..2408db28e0224bbc68cf2784fefd1b4665747f1e 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java
@@ -112,6 +112,9 @@ public class Account implements Serializable {
public synchronized Spannable getSpanNote(Context context, WeakReference viewWeakReference) {
return SpannableHelper.convert(context, note, null, this, null, viewWeakReference, null, true, false);
}
+ public synchronized Spannable getSpanNote(Context context, WeakReference viewWeakReference, Status.Callback callback) {
+ return SpannableHelper.convert(context, note, null, this, null, viewWeakReference, callback, true, false);
+ }
@Override
public boolean equals(@Nullable Object obj) {
diff --git a/app/src/main/java/app/fedilab/android/mastodon/helper/Helper.java b/app/src/main/java/app/fedilab/android/mastodon/helper/Helper.java
index 257820ba879504dfac5ba806b305eb727f3e2080..6beaa52c502913b0e12fa0121e76502370e40f53 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/helper/Helper.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/helper/Helper.java
@@ -34,6 +34,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
@@ -99,6 +100,7 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestOptions;
+import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -916,7 +918,7 @@ public class Helper {
ft.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);
Fragment _fragment = fragmentManager.findFragmentByTag(tag);
if (_fragment != null && _fragment.isAdded()) {
- ft.show(_fragment).commit();
+ ft.show(_fragment).commitAllowingStateLoss();
fragment = _fragment;
} else {
if (args != null) fragment.setArguments(args);
@@ -928,7 +930,7 @@ public class Helper {
}catch (Exception ignored){}
}
if (!fragmentManager.isDestroyed()) {
- ft.commit();
+ ft.commitAllowingStateLoss();
}
}
fragmentManager.executePendingTransactions();
@@ -1461,6 +1463,24 @@ public class Helper {
imageView.setColorFilter(color);
}
+ /**
+ * change color of a drawable
+ *
+ * @param materialButton {@link MaterialButton}
+ * @param hexaColor example 0xffff00
+ */
+ public static void changeDrawableColor(Context context, MaterialButton materialButton, int hexaColor) {
+ if (materialButton == null)
+ return;
+ int color;
+ try {
+ color = context.getResources().getColor(hexaColor);
+ } catch (Resources.NotFoundException e) {
+ color = hexaColor;
+ }
+ materialButton.setIconTint(ColorStateList.valueOf(color));
+ }
+
/**
* change color of a drawable
*
@@ -1828,7 +1848,6 @@ public class Helper {
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpURLConnection.getHeaderField("Content-Disposition");
-
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
@@ -1838,7 +1857,12 @@ public class Helper {
}
} else {
// extracts file name from URL
- fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
+ try {
+ URL downLoadUrlTmp = new URL(downloadUrl);
+ fileName = downLoadUrlTmp.getPath().replace("/","_");
+ }catch (Exception exception) {
+ fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
+ }
}
fileName = FileNameCleaner.cleanFileName(fileName);
// opens input stream from the HTTP connection
@@ -2139,6 +2163,22 @@ public class Helper {
.build();
}
+ public static OkHttpClient myPostOkHttpClient(Context context) {
+ return new OkHttpClient.Builder()
+ .addInterceptor(chain -> {
+ Request originalRequest = chain.request();
+ Request requestWithUserAgent = originalRequest.newBuilder()
+ .header("User-Agent", context.getString(R.string.app_name) + "/" + BuildConfig.VERSION_NAME + "/" + BuildConfig.VERSION_CODE)
+ .build();
+ return chain.proceed(requestWithUserAgent);
+ })
+ .readTimeout(120, TimeUnit.SECONDS)
+ .connectTimeout(120, TimeUnit.SECONDS)
+ .callTimeout(120, TimeUnit.SECONDS)
+ .proxy(Helper.getProxy(context))
+ .build();
+ }
+
public static String parseHtml(String html) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY).toString();
diff --git a/app/src/main/java/app/fedilab/android/mastodon/helper/MediaHelper.java b/app/src/main/java/app/fedilab/android/mastodon/helper/MediaHelper.java
index 6e90fac39b04c2fab7685ef2e86eef2c49cf141d..ca01bb2802ad1ada0a1edf79cbd924dfcf5321f3 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/helper/MediaHelper.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/helper/MediaHelper.java
@@ -25,6 +25,7 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
@@ -266,6 +267,32 @@ public class MediaHelper {
);
}
+
+ public static Drawable rescaleImageIfNeeded(Activity activity, Drawable image) {
+ if (!(image instanceof BitmapDrawable)) {
+ return image;
+ }
+ int maxSize = 2000;
+ int width = image.getIntrinsicWidth();
+ int height = image.getIntrinsicHeight();
+ float scaleFactor;
+ if(width > maxSize || height > maxSize) {
+ if(width >= height) {
+ scaleFactor = (float) maxSize / width;
+ } else {
+ scaleFactor = (float) maxSize / height;
+ }
+ } else {
+ return image;
+ }
+ Bitmap b = ((BitmapDrawable)image).getBitmap();
+ int sizeX = Math.round(image.getIntrinsicWidth() * scaleFactor);
+ int sizeY = Math.round(image.getIntrinsicHeight() * scaleFactor);
+ Bitmap bitmapResized = Bitmap.createScaledBitmap(b, sizeX, sizeY, false);
+ image = new BitmapDrawable(activity.getResources(), bitmapResized);
+ return image;
+ }
+
/**
* Record media
*
diff --git a/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java b/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java
index 42e1d8e0d70692677f16980e16a58cf415af2695..ebcb2416f860c0ba889e4fa2fa48e2b69579afe1 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java
@@ -47,9 +47,7 @@ import com.google.gson.Gson;
import java.io.IOException;
import java.net.IDN;
import java.util.ArrayList;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import app.fedilab.android.BaseMainActivity;
@@ -72,7 +70,6 @@ import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.ui.drawer.StatusAdapter;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
-import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Response;
@@ -94,19 +91,11 @@ public class ComposeWorker extends Worker {
context.getSystemService(NOTIFICATION_SERVICE);
}
- private static OkHttpClient getOkHttpClient(Context context) {
- return new OkHttpClient.Builder()
- .readTimeout(120, TimeUnit.SECONDS)
- .connectTimeout(120, TimeUnit.SECONDS)
- .proxy(Helper.getProxy(context.getApplicationContext()))
- .build();
- }
-
private static MastodonStatusesService init(Context context, String instance) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://" + (instance != null ? IDN.toASCII(instance, IDN.ALLOW_UNASSIGNED) : null) + "/api/v1/")
.addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
- .client(getOkHttpClient(context))
+ .client(Helper.myPostOkHttpClient(context))
.build();
return retrofit.create(MastodonStatusesService.class);
}
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java
index 93f301ecd11a0c6ac0bc0a479b130be6219c8bb8..53b019467bcc0fd230e7f6c0b5efb74339ed8be0 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java
@@ -315,7 +315,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (statusDraft.mentions != null && (statusDraft.text == null || statusDraft.text.isEmpty()) && !statusDraft.mentions.isEmpty()) {
//Retrieves mentioned accounts + OP and adds them at the beginin of the toot
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
Mention inReplyToUser;
@@ -426,25 +426,25 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (instanceInfo != null && instanceInfo.getMimeTypeImage() != null && !instanceInfo.getMimeTypeImage().isEmpty()) {
mimetypes = instanceInfo.getMimeTypeImage().toArray(new String[0]);
} else {
mimetypes = new String[]{"image/*"};
}
} else if (type == ComposeActivity.mediaType.VIDEO) {
- if (instanceInfo != null && instanceInfo.getMimeTypeVideo() != null && instanceInfo.getMimeTypeVideo().size() > 0) {
+ if (instanceInfo != null && instanceInfo.getMimeTypeVideo() != null && !instanceInfo.getMimeTypeVideo().isEmpty()) {
mimetypes = instanceInfo.getMimeTypeVideo().toArray(new String[0]);
} else {
mimetypes = new String[]{"video/*"};
}
} else if (type == ComposeActivity.mediaType.AUDIO) {
- if (instanceInfo != null && instanceInfo.getMimeTypeAudio() != null && instanceInfo.getMimeTypeAudio().size() > 0) {
+ if (instanceInfo != null && instanceInfo.getMimeTypeAudio() != null && !instanceInfo.getMimeTypeAudio().isEmpty()) {
mimetypes = instanceInfo.getMimeTypeAudio().toArray(new String[0]);
} else {
mimetypes = new String[]{"audio/*"};
}
} else if (type == ComposeActivity.mediaType.ALL) {
- if (instanceInfo != null && instanceInfo.getMimeTypeOther() != null && instanceInfo.getMimeTypeOther().size() > 0) {
+ if (instanceInfo != null && instanceInfo.getMimeTypeOther() != null && !instanceInfo.getMimeTypeOther().isEmpty()) {
mimetypes = instanceInfo.getMimeTypeOther().toArray(new String[0]);
} else {
mimetypes = new String[]{"*/*"};
@@ -509,9 +509,9 @@ public class ComposeAdapter extends RecyclerView.Adapter splitText = ComposeHelper.splitToots(contentString, max_car);
- contentString = splitText.get(0);
+ if(!splitText.isEmpty()) {
+ contentString = splitText.get(0);
+ }
}
int currentLength = MastodonHelper.countLength(holder);
if (promptDraftListener != null) {
@@ -715,7 +717,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (!mentions.isEmpty()) {
for (String mention : mentions) {
newContent[0] += mention + " ";
}
@@ -732,7 +734,7 @@ public class ComposeAdapter extends RecyclerView.Adapter quotes = gson.fromJson(json, new TypeToken>() {
}.getType());
- if (quotes != null && quotes.size() > 0) {
+ if (quotes != null && !quotes.isEmpty()) {
final int random = new Random().nextInt(quotes.size());
Quotes.Quote quote = quotes.get(random);
newContent[0] += quote.content + "\n- " + quote.author;
@@ -760,7 +762,7 @@ public class ComposeAdapter extends RecyclerView.Adapter= oldContent.length())
deltaSearch = oldContent.substring(currentCursorPosition - searchLength);
}
- if (!search.equals(""))
+ if (!search.isEmpty())
deltaSearch = deltaSearch.replace("@" + search, "");
String newContent = oldContent.substring(0, currentCursorPosition - searchLength);
newContent += deltaSearch;
@@ -884,10 +886,10 @@ public class ComposeAdapter extends RecyclerView.Adapter {
- if (results == null || results.hashtags == null || results.hashtags.size() == 0) {
+ if (results == null || results.hashtags == null || results.hashtags.isEmpty()) {
return;
}
- if (camelTags != null && camelTags.size() > 0) {
+ if (camelTags != null && !camelTags.isEmpty()) {
for (String camelTag : camelTags) {
Tag tag = new Tag();
tag.name = camelTag;
@@ -929,7 +931,7 @@ public class ComposeAdapter extends RecyclerView.Adapter {
List emojisToDisplay = new ArrayList<>();
try {
- if (emojisList == null || emojisList.size() == 0) {
+ if (emojisList == null || emojisList.isEmpty()) {
emojisList = new EmojiInstance(context).getEmojiList(BaseMainActivity.currentInstance);
}
if (emojis == null) {
@@ -995,7 +997,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (title != null && !title.trim().isEmpty()) {
contentBuilder.append(title);
- } else if (subject != null && subject.trim().length() > 0) {
+ } else if (subject != null && !subject.trim().isEmpty()) {
contentBuilder.append(subject);
}
@@ -1057,12 +1059,12 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (description != null && !description.trim().isEmpty()) {
if (url != null && !description.contains(url)) {
contentBuilder.append(url).append("\n\n");
}
contentBuilder.append("> ").append(description);
- } else if (content != null && content.trim().length() > 0) {
+ } else if (content != null && !content.trim().isEmpty()) {
if (!content.contains(url)) {
contentBuilder.append(url).append("\n\n");
}
@@ -1309,7 +1311,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (status != null && status.media_attachments != null && !status.media_attachments.isEmpty()) {
int mediaPosition = 0;
for (Attachment attachment : status.media_attachments) {
if (attachment.description == null || attachment.description.trim().isEmpty()) {
@@ -1353,7 +1355,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (status.media_attachments != null && !status.media_attachments.isEmpty()) {
holder.binding.simpleMedia.removeAllViews();
List attachmentList = statusList.get(position).media_attachments;
for (Attachment attachment : attachmentList) {
@@ -1447,7 +1449,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (accountFromUser.fields != null && !accountFromUser.fields.isEmpty()) {
for (Field field : accountFromUser.fields) {
if (PronounsHelper.pronouns.contains(field.name.toLowerCase().trim())) {
statusList.get(position).pronouns = Helper.parseHtml(field.value);
@@ -1570,16 +1572,16 @@ public class ComposeAdapter extends RecyclerView.Adapter {
if (instanceInfo.configuration.media_attachments.supported_mime_types != null) {
- if (instanceInfo.getMimeTypeAudio().size() == 0) {
+ if (instanceInfo.getMimeTypeAudio().isEmpty()) {
holder.binding.buttonAttachAudio.setEnabled(false);
}
- if (instanceInfo.getMimeTypeImage().size() == 0) {
+ if (instanceInfo.getMimeTypeImage().isEmpty()) {
holder.binding.buttonAttachImage.setEnabled(false);
}
- if (instanceInfo.getMimeTypeVideo().size() == 0) {
+ if (instanceInfo.getMimeTypeVideo().isEmpty()) {
holder.binding.buttonAttachVideo.setEnabled(false);
}
- if (instanceInfo.getMimeTypeOther().size() == 0) {
+ if (instanceInfo.getMimeTypeOther().isEmpty()) {
holder.binding.buttonAttachManual.setEnabled(false);
}
}
@@ -1687,7 +1689,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (statusDraft.spoilerChecked || statusDraft.spoiler_text != null && !statusDraft.spoiler_text.trim().isEmpty()) {
holder.binding.contentSpoiler.setVisibility(View.VISIBLE);
} else {
holder.binding.contentSpoiler.setVisibility(View.GONE);
@@ -1697,15 +1699,17 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (emojis != null && !emojis.isEmpty()) {
holder.binding.buttonEmoji.setVisibility(View.VISIBLE);
} else {
holder.binding.buttonEmoji.setVisibility(View.GONE);
@@ -1781,7 +1785,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (!camelCaseTags.isEmpty()) {
statusDraft.text += "\n\n";
int lenght = 0;
for (String tag : camelCaseTags) {
@@ -1815,7 +1819,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (!camelCaseTags.isEmpty()) {
statusList.get(position).tagAdded = true;
int lenght = 0;
for (String tag : camelCaseTags) {
@@ -1898,7 +1902,7 @@ public class ComposeAdapter extends RecyclerView.Adapter 0) {
+ if (storedLanguages != null && !storedLanguages.isEmpty()) {
int i = 0;
codesArr = new String[storedLanguages.size()];
languagesArr = new String[storedLanguages.size()];
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java
index 694e600edfbc4a381550b8ef6f62453cc90a40a7..eab59d9bb7e246f5f3c8e2d9143f8fe0605a8d34 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java
@@ -59,7 +59,6 @@ import android.os.Looper;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextUtils;
-import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -1279,27 +1278,23 @@ public class StatusAdapter extends RecyclerView.Adapter
holder.binding.actionButtonReply.getLayoutParams().height = (int) (normalSize * scaleIcon);
holder.binding.actionButtonReply.requestLayout();
- holder.binding.actionButtonTranslate.getLayoutParams().width = (int) (normalSize * scaleIcon);
- holder.binding.actionButtonTranslate.getLayoutParams().height = (int) (normalSize * scaleIcon);
+ holder.binding.actionButtonTranslate.setIconSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonTranslate.requestLayout();
holder.binding.actionButtonBoost.setImageSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonFavorite.setImageSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonBookmark.setImageSize((int) (normalSize * scaleIcon));
-
- holder.binding.statusAddCustomEmoji.getLayoutParams().width = (int) (normalSize * scaleIcon);
- holder.binding.statusAddCustomEmoji.getLayoutParams().height = (int) (normalSize * scaleIcon);
+ holder.binding.statusAddCustomEmoji.setIconSize((int) (normalSize * scaleIcon));
holder.binding.statusAddCustomEmoji.requestLayout();
- holder.binding.actionButtonQuote.getLayoutParams().width = (int) (normalSize * scaleIcon);
- holder.binding.actionButtonQuote.getLayoutParams().height = (int) (normalSize * scaleIcon);
+ holder.binding.actionButtonQuote.setIconSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonQuote.requestLayout();
- holder.binding.statusEmoji.getLayoutParams().width = (int) (normalSize * scaleIcon);
- holder.binding.statusEmoji.getLayoutParams().height = (int) (normalSize * scaleIcon);
- holder.binding.actionButtonMore.getLayoutParams().width = (int) (normalSize * scaleIcon);
- holder.binding.actionButtonMore.getLayoutParams().height = (int) (normalSize * scaleIcon);
+ holder.binding.statusEmoji.setIconSize((int) (normalSize * scaleIcon));
+ holder.binding.statusEmoji.requestLayout();
+
+ holder.binding.actionButtonMore.setIconSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonMore.requestLayout();
holder.binding.actionShare.getLayoutParams().width = (int) (normalSize * scaleIcon);
holder.binding.actionShare.getLayoutParams().height = (int) (normalSize * scaleIcon);
@@ -1620,7 +1615,7 @@ public class StatusAdapter extends RecyclerView.Adapter
holder.binding.displayMedia.setVisibility(View.GONE);
holder.binding.media.mediaContainer.setVisibility(View.VISIBLE);
int mediaPosition = 1;
- boolean autoplaygif = sharedpreferences.getBoolean(context.getString(R.string.SET_AUTO_PLAY_GIG_MEDIA), true);
+ boolean autoplaygif = sharedpreferences.getBoolean(context.getString(R.string.SET_AUTO_PLAY_GIG_MEDIA), false);
if (!fullAttachement || statusToDeal.sensitive) {
int defaultHeight = (int) Helper.convertDpToPixel(300, context);
int orientation = context.getResources().getConfiguration().orientation;
@@ -2112,7 +2107,11 @@ public class StatusAdapter extends RecyclerView.Adapter
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
}));
- holder.binding.poll.pollContainer.setVisibility(View.VISIBLE);
+ if (statusToDeal.spoiler_text == null || statusToDeal.spoiler_text.trim().isEmpty() || statusToDeal.isExpended) {
+ holder.binding.poll.pollContainer.setVisibility(View.VISIBLE);
+ } else {
+ holder.binding.poll.pollContainer.setVisibility(View.GONE);
+ }
String pollInfo = context.getResources().getQuantityString(R.plurals.number_of_voters, normalize, normalize);
if (statusToDeal.poll.expired) {
pollInfo += " - " + context.getString(R.string.poll_finish_at, MastodonHelper.dateToStringPoll(statusToDeal.poll.expires_at));
@@ -2224,11 +2223,11 @@ public class StatusAdapter extends RecyclerView.Adapter
// Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> holder.binding.statusContent.invalidate(), 0, 100, TimeUnit.MILLISECONDS);
if (remote) {
- holder.binding.actionButtonMoreContainer.setVisibility(View.GONE);
+ holder.binding.actionButtonMore.setVisibility(View.GONE);
} else {
- holder.binding.actionButtonMoreContainer.setVisibility(View.VISIBLE);
+ holder.binding.actionButtonMore.setVisibility(View.VISIBLE);
}
- holder.binding.actionButtonMoreContainer.setOnClickListener(v -> {
+ holder.binding.actionButtonMore.setOnClickListener(v -> {
boolean isOwner = statusToDeal.account.id.compareTo(BaseMainActivity.currentUserID) == 0;
PopupMenu popup = new PopupMenu(context, holder.binding.actionButtonMore);
popup.getMenuInflater()
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java
index eab60c443358f98f4f335c1e023fd75ccceddfce..9485ee7258c61280f402ced0289b6e657c0e451b 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java
@@ -605,7 +605,7 @@ public class StatusDirectMessageAdapter extends RecyclerView.Adapter. */
+
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
@@ -58,6 +59,7 @@ import app.fedilab.android.mastodon.activities.MediaActivity;
import app.fedilab.android.mastodon.client.entities.api.Attachment;
import app.fedilab.android.mastodon.helper.CacheDataSourceFactory;
import app.fedilab.android.mastodon.helper.Helper;
+import app.fedilab.android.mastodon.helper.MediaHelper;
import app.fedilab.android.mastodon.viewmodel.mastodon.TimelinesVM;
import es.dmoral.toasty.Toasty;
@@ -167,7 +169,9 @@ public class FragmentMedia extends Fragment {
return;
}
binding.mediaPicture.setZoomable(true);
- binding.mediaPicture.setImageDrawable(resource);
+
+ Drawable scaledRessource = MediaHelper.rescaleImageIfNeeded(requireActivity(), resource);
+ binding.mediaPicture.setImageDrawable(scaledRessource);
if (attachment.type.equalsIgnoreCase("image") && !attachment.url.toLowerCase().endsWith(".gif")) {
binding.mediaPicture.setVisibility(View.VISIBLE);
@@ -185,7 +189,8 @@ public class FragmentMedia extends Fragment {
return;
}
binding.loader.setVisibility(View.GONE);
- binding.mediaPicture.setImageDrawable(resource);
+ Drawable scaledRessource = MediaHelper.rescaleImageIfNeeded(requireActivity(), resource);
+ binding.mediaPicture.setImageDrawable(scaledRessource);
binding.mediaPicture.setZoomable(true);
}
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentComposeSettings.java b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentComposeSettings.java
index 2b27992e41e6562a71618a391b01df25e5e6a3cf..232d731c699837e0c544057bd0729266831616a4 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentComposeSettings.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentComposeSettings.java
@@ -23,6 +23,7 @@ import androidx.preference.ListPreference;
import androidx.preference.MultiSelectListPreference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
+import androidx.preference.SwitchPreferenceCompat;
import java.util.List;
import java.util.Objects;
@@ -59,6 +60,12 @@ public class FragmentComposeSettings extends PreferenceFragmentCompat implements
SET_WATERMARK_TEXT.setText(val);
}
+ SwitchPreferenceCompat SET_MENTION_BOOSTER = findPreference(getString(R.string.SET_MENTION_BOOSTER));
+ if (SET_MENTION_BOOSTER != null) {
+ boolean val = sharedPreferences.getBoolean(getString(R.string.SET_MENTION_BOOSTER) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, sharedPreferences.getBoolean(getString(R.string.SET_MENTION_BOOSTER), false));
+ SET_MENTION_BOOSTER.setChecked(val);
+ }
+
MultiSelectListPreference SET_SELECTED_LANGUAGE = findPreference(getString(R.string.SET_SELECTED_LANGUAGE));
if (SET_SELECTED_LANGUAGE != null) {
@@ -66,7 +73,7 @@ public class FragmentComposeSettings extends PreferenceFragmentCompat implements
Set storedLanguages = sharedPreferences.getStringSet(getString(R.string.SET_SELECTED_LANGUAGE), null);
String[] selectedValue = new String[0];
- if (storedLanguages != null && storedLanguages.size() > 0) {
+ if (storedLanguages != null && !storedLanguages.isEmpty()) {
if (storedLanguages.size() == 1 && storedLanguages.toArray()[0] == null) {
sharedPreferences.edit().remove(getString(R.string.SET_SELECTED_LANGUAGE)).commit();
} else {
@@ -102,6 +109,11 @@ public class FragmentComposeSettings extends PreferenceFragmentCompat implements
editor.putString(getString(R.string.SET_WATERMARK_TEXT) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, sharedPreferences.getString(getString(R.string.SET_WATERMARK_TEXT), null));
editor.apply();
}
+ if (Objects.requireNonNull(key).equalsIgnoreCase(getString(R.string.SET_MENTION_BOOSTER))) {
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putBoolean(getString(R.string.SET_MENTION_BOOSTER) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, sharedPreferences.getBoolean(getString(R.string.SET_MENTION_BOOSTER), false));
+ editor.apply();
+ }
}
@Override
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentNetworkSettings.java b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentNetworkSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c3bcb844ecce838805ed15a98241e26e7f1bed8
--- /dev/null
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentNetworkSettings.java
@@ -0,0 +1,60 @@
+package app.fedilab.android.mastodon.ui.fragment.settings;
+/* Copyright 2022 Thomas Schneider
+ *
+ * This file is a part of Fedilab
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Fedilab; if not,
+ * see . */
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+
+import java.io.IOException;
+
+import app.fedilab.android.R;
+import app.fedilab.android.mastodon.activities.ProxyActivity;
+import app.fedilab.android.mastodon.helper.Helper;
+import app.fedilab.android.mastodon.helper.ZipHelper;
+import es.dmoral.toasty.Toasty;
+
+public class FragmentNetworkSettings extends PreferenceFragmentCompat {
+
+ @Override
+ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
+ addPreferencesFromResource(R.xml.pref_network);
+
+
+ Preference pref_proxy = findPreference(getString(R.string.pref_key_proxy));
+ if (pref_proxy != null) {
+ pref_proxy.setOnPreferenceClickListener(preference -> {
+ (new ProxyActivity()).show(getParentFragmentManager(), null);
+ return false;
+ });
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentSettingsCategories.java b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentSettingsCategories.java
index b628431b4b32e9dcb6c561eac239927d3e2fb182..b1d1d6566f5be7ddf3dd3639c6725c2474711127 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentSettingsCategories.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentSettingsCategories.java
@@ -138,6 +138,15 @@ public class FragmentSettingsCategories extends PreferenceFragmentCompat {
});
}
+ Preference pref_category_key_network = findPreference(getString(R.string.pref_category_key_network));
+ if (pref_category_key_network != null) {
+ pref_category_key_network.setOnPreferenceClickListener(preference -> {
+ NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
+ navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToNetwork());
+ return false;
+ });
+ }
+
Preference pref_category_key_extra_features = findPreference(getString(R.string.pref_category_key_extra_features));
if (pref_category_key_extra_features != null) {
pref_category_key_extra_features.setOnPreferenceClickListener(preference -> {
diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonTimeline.java
index 8f15fa9b2978732ce6923e49b55c2879a43327e7..d2127dd4c1d82b1a0298cb7fe19c260f603d2a8f 100644
--- a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonTimeline.java
+++ b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonTimeline.java
@@ -17,6 +17,7 @@ package app.fedilab.android.mastodon.ui.fragment.timeline;
import static app.fedilab.android.BaseMainActivity.currentInstance;
import static app.fedilab.android.BaseMainActivity.networkAvailable;
+import static app.fedilab.android.mastodon.helper.Helper.TAG;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -26,6 +27,7 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -571,9 +573,13 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
insertedStatus = updateStatusListWith(fetched_statuses.statuses);
} else { //Trends cannot be ordered by id
insertedStatus = fetched_statuses.statuses.size();
- int fromPosition = timelineStatuses.size();
- timelineStatuses.addAll(fetched_statuses.statuses);
- statusAdapter.notifyItemRangeInserted(fromPosition, insertedStatus);
+ for(Status statusReceived: fetched_statuses.statuses) {
+ if (!timelineStatuses.contains(statusReceived)) {
+ timelineStatuses.add(statusReceived);
+ statusAdapter.notifyItemInserted(timelineStatuses.size() - 1);
+ insertedStatus++;
+ }
+ }
}
//For these directions, the app will display counters for new messages
if (insertedStatus >= 0 && update != null && direction != DIRECTION.FETCH_NEW && !fetchingMissing) {
@@ -631,7 +637,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
binding.loader.setVisibility(View.GONE);
binding.noAction.setVisibility(View.GONE);
binding.swipeContainer.setRefreshing(false);
- if (searchCache == null && timelineType != Timeline.TimeLineEnum.TREND_MESSAGE) {
+ if (searchCache == null ) {
binding.swipeContainer.setOnRefreshListener(() -> {
binding.swipeContainer.setRefreshing(true);
flagLoading = false;
@@ -722,7 +728,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
binding.recyclerView.addOnScrollListener(preloader);
binding.recyclerView.setItemViewCacheSize(0);
- if (timelineType != Timeline.TimeLineEnum.TREND_MESSAGE) {
+
binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
@@ -759,7 +765,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
if (slug != null /*&& slug.compareTo(Helper.getSlugOfFirstFragment(requireActivity(), currentUserID, currentInstance)) == 0*/ && rememberPosition) {
route(DIRECTION.FETCH_NEW, true);
}
- }
+
}
@@ -1132,7 +1138,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
}
});
}
- } else if (pinnedTimeline != null && pinnedTimeline.remoteInstance.type == RemoteInstance.InstanceType.PIXELFED) {
+ }
+ else if (pinnedTimeline != null && pinnedTimeline.remoteInstance.type == RemoteInstance.InstanceType.PIXELFED) {
if (direction == null) {
timelinesVM.getPixelfedDiscoverTrending(remoteInstance)
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
@@ -1197,9 +1204,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
accountId[0] = accountTimeline.id;
}
displayStatuses(direction, accountId[0], tempInstance[0], tempToken[0], fetchStatus);
- } else if (search != null) {
+ }
+ else if (search != null) {
SearchVM searchVM = new ViewModelProvider(FragmentMastodonTimeline.this).get(viewModelKey, SearchVM.class);
-
if (direction == null) {
searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, search.trim(), null, null, false, true, false, 0, null, null, MastodonHelper.SEARCH_PER_CALL)
.observe(getViewLifecycleOwner(), results -> {
@@ -1225,7 +1232,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
} else {
flagLoading = false;
}
- } else if (searchCache != null) {
+ }
+ else if (searchCache != null) {
SearchVM searchVM = new ViewModelProvider(FragmentMastodonTimeline.this).get(viewModelKey, SearchVM.class);
searchVM.searchCache(BaseMainActivity.currentInstance, BaseMainActivity.currentUserID, searchCache.trim())
.observe(getViewLifecycleOwner(), results -> {
@@ -1238,7 +1246,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
Toasty.error(requireActivity(), getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
}
});
- } else if (timelineType == Timeline.TimeLineEnum.FAVOURITE_TIMELINE) {
+ }
+ else if (timelineType == Timeline.TimeLineEnum.FAVOURITE_TIMELINE) {
if (direction == null) {
accountsVM.getFavourites(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, String.valueOf(MastodonHelper.statusesPerCall(requireActivity())), null, null)
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
@@ -1248,7 +1257,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
} else {
flagLoading = false;
}
- } else if (timelineType == Timeline.TimeLineEnum.BOOKMARK_TIMELINE) {
+ }
+ else if (timelineType == Timeline.TimeLineEnum.BOOKMARK_TIMELINE) {
if (direction == null) {
accountsVM.getBookmarks(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, String.valueOf(MastodonHelper.statusesPerCall(requireActivity())), null, null, null)
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
@@ -1258,17 +1268,28 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
} else {
flagLoading = false;
}
- } else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE) {
+ }
+ else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE) {
if (direction == null) {
timelinesVM.getStatusTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
timelinesVM.getStatusTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, max_id, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false, true, fetchStatus));
- } else {
+ }else if (direction == DIRECTION.TOP) {
flagLoading = false;
+ } else if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP || direction == DIRECTION.FETCH_NEW) {
+ timelinesVM.getStatusTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, null, MastodonHelper.statusesPerCall(requireActivity()))
+ .observe(getViewLifecycleOwner(), statusesRefresh -> {
+ if (statusAdapter != null) {
+ dealWithPagination(statusesRefresh, direction, true, true, fetchStatus);
+ } else {
+ initializeStatusesCommonView(statusesRefresh);
+ }
+ });
}
- } else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC) {
+ }
+ else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC) {
if (direction == null) {
timelinesVM.getStatusTrends(null, publicTrendsDomain, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
diff --git a/app/src/main/java/app/fedilab/android/peertube/activities/PeertubeMainActivity.java b/app/src/main/java/app/fedilab/android/peertube/activities/PeertubeMainActivity.java
index 3e0fdf634aa7e3e00c8d83d120f0af88df80cd26..70eb61dc0b2767cfc1aeb21c2aeacbc5f9099a10 100644
--- a/app/src/main/java/app/fedilab/android/peertube/activities/PeertubeMainActivity.java
+++ b/app/src/main/java/app/fedilab/android/peertube/activities/PeertubeMainActivity.java
@@ -20,7 +20,7 @@ import static app.fedilab.android.BaseMainActivity.currentToken;
import static app.fedilab.android.BaseMainActivity.currentUserID;
import static app.fedilab.android.BaseMainActivity.fetchRecentAccounts;
import static app.fedilab.android.BaseMainActivity.headerMenuOpen;
-import static app.fedilab.android.BaseMainActivity.headerOptionInfoClick;
+import static app.fedilab.android.BaseMainActivity.headerLogoutClick;
import static app.fedilab.android.BaseMainActivity.mamageNewIntent;
import static app.fedilab.android.BaseMainActivity.manageDrawerMenu;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_ID;
@@ -328,8 +328,8 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
headerMainBinding.accountAcc.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18 * 1.1f / scale);
app.fedilab.android.mastodon.helper.Helper.loadPP(PeertubeMainActivity.this, headerMainBinding.accountProfilePicture, app.fedilab.android.mastodon.helper.Helper.getCurrentAccount(PeertubeMainActivity.this), false);
headerMainBinding.backgroundImage.setAlpha(0.5f);
- headerMainBinding.accountAcc.setOnClickListener(v -> headerMainBinding.changeAccount.callOnClick());
- headerMainBinding.changeAccount.setOnClickListener(v -> {
+ TooltipCompat.setTooltipText(headerMainBinding.ownerAccounts, getString(R.string.manage_accounts));
+ headerMainBinding.ownerAccounts.setOnClickListener(v -> {
headerMenuOpen = !headerMenuOpen;
manageDrawerMenu(PeertubeMainActivity.this, binding.drawerNavView, headerMainBinding);
@@ -345,9 +345,7 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
headerMainBinding.accountAcc.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18 * 1.1f / scale);
app.fedilab.android.mastodon.helper.Helper.loadPP(PeertubeMainActivity.this, headerMainBinding.accountProfilePicture, app.fedilab.android.mastodon.helper.Helper.getCurrentAccount(PeertubeMainActivity.this), false);
headerMainBinding.backgroundImage.setAlpha(0.5f);
- headerMainBinding.accountAcc.setOnClickListener(v -> headerMainBinding.changeAccount.callOnClick());
- headerMainBinding.changeAccount.setOnClickListener(v -> {
-
+ headerMainBinding.ownerAccounts.setOnClickListener(v -> {
headerMenuOpen = !headerMenuOpen;
manageDrawerMenu(PeertubeMainActivity.this, binding.drawerNavView, headerMainBinding);
});
@@ -358,7 +356,8 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
};
mainHandler.post(myRunnable);
}).start();
- headerMainBinding.instanceInfo.setVisibility(View.GONE);
+ View navInstanceInfo = binding.drawerNavView.findViewById(R.id.nav_instance_info);
+ binding.drawerNavView.removeView(navInstanceInfo);
binding.drawerNavView.addHeaderView(headerMainBinding.getRoot());
binding.drawerNavView.setNavigationItemSelectedListener(item -> {
if (item.getItemId() == R.id.action_settings) {
@@ -414,7 +413,8 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
binding.drawerLayout.close();
return false;
});
- headerMainBinding.headerOptionInfo.setOnClickListener(v -> headerOptionInfoClick(PeertubeMainActivity.this, headerMainBinding, getSupportFragmentManager()));
+ TooltipCompat.setTooltipText(headerMainBinding.headerLogout, getString(R.string.action_logout));
+ headerMainBinding.headerLogout.setOnClickListener(v -> headerLogoutClick(PeertubeMainActivity.this, headerMainBinding, getSupportFragmentManager()));
fetchRecentAccounts(PeertubeMainActivity.this, headerMainBinding);
} else {
new Thread(() -> {
@@ -512,9 +512,9 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
}
private void startInForeground() {
- Intent retrieveInfoServiceIntent = new Intent(this, RetrieveInfoService.class);
+ Intent notificationIntent = new Intent(this, RetrieveInfoService.class);
try {
- startService(retrieveInfoServiceIntent);
+ startService(notificationIntent);
} catch (Exception ignored) {
}
}
diff --git a/app/src/main/java/app/fedilab/android/peertube/services/RetrieveInfoService.java b/app/src/main/java/app/fedilab/android/peertube/services/RetrieveInfoService.java
index a49837624654dc6025aa1a55f1407b54c6ded899..d4274e0c838435baeef7109991d60c5550e3e79f 100644
--- a/app/src/main/java/app/fedilab/android/peertube/services/RetrieveInfoService.java
+++ b/app/src/main/java/app/fedilab/android/peertube/services/RetrieveInfoService.java
@@ -16,19 +16,28 @@ package app.fedilab.android.peertube.services;
import static app.fedilab.android.peertube.helper.Helper.peertubeInformation;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.Service;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
import android.net.ConnectivityManager;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import androidx.annotation.Nullable;
+import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import java.util.LinkedHashMap;
+import java.util.Objects;
+import app.fedilab.android.R;
import app.fedilab.android.peertube.client.RetrofitPeertubeAPI;
import app.fedilab.android.peertube.client.entities.PeertubeInformation;
import app.fedilab.android.peertube.helper.EmojiHelper;
@@ -37,6 +46,7 @@ import app.fedilab.android.peertube.helper.NetworkStateReceiver;
public class RetrieveInfoService extends Service implements NetworkStateReceiver.NetworkStateReceiverListener {
+ static String NOTIFICATION_CHANNEL_ID = "update_info_peertube";
private NetworkStateReceiver networkStateReceiver;
@@ -45,6 +55,36 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
networkStateReceiver = new NetworkStateReceiver();
networkStateReceiver.addListener(this);
ContextCompat.registerReceiver(RetrieveInfoService.this, networkStateReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION), ContextCompat.RECEIVER_NOT_EXPORTED);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+ getString(R.string.notification_channel_name),
+ NotificationManager.IMPORTANCE_DEFAULT);
+ channel.setSound(null, null);
+
+ ((NotificationManager) Objects.requireNonNull(getSystemService(Context.NOTIFICATION_SERVICE))).createNotificationChannel(channel);
+ Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(R.drawable.ic_notification)
+ .setContentTitle(getString(R.string.app_name))
+ .setContentText(getString(R.string.notification_channel_name))
+ .setAutoCancel(true).build();
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
+ } else {
+ startForeground(1, notification);
+ }
+
+ } else {
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
+ .setContentTitle(getString(R.string.app_name))
+ .setDefaults(Notification.DEFAULT_ALL)
+ .setContentText(getString(R.string.notification_channel_name))
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setAutoCancel(true);
+
+ Notification notification = builder.build();
+ startForeground(1, notification);
+ }
}
@@ -100,7 +140,7 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
@Override
public void run() {
EmojiHelper.fillMapEmoji(getApplicationContext());
- if (peertubeInformation == null || peertubeInformation.getCategories() == null || peertubeInformation.getCategories().isEmpty()) {
+ if (peertubeInformation == null || peertubeInformation.getCategories() == null || peertubeInformation.getCategories().size() == 0) {
peertubeInformation = new PeertubeInformation();
peertubeInformation.setCategories(new LinkedHashMap<>());
peertubeInformation.setLanguages(new LinkedHashMap<>());
@@ -110,6 +150,7 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
peertubeInformation.setTranslations(new LinkedHashMap<>());
peertubeInformation = new RetrofitPeertubeAPI(RetrieveInfoService.this).getPeertubeInformation();
}
+ stopForeground(true);
}
};
thread.start();
diff --git a/app/src/main/res/layouts/mastodon/drawable/ic_accounts.xml b/app/src/main/res/layouts/mastodon/drawable/ic_accounts.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2d0f8f6ee1a062ad69a535a3b6961e0278e402a
--- /dev/null
+++ b/app/src/main/res/layouts/mastodon/drawable/ic_accounts.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layouts/mastodon/drawable/ic_logout.xml b/app/src/main/res/layouts/mastodon/drawable/ic_logout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5dc221b49843cba0678c3c0ccff038a4ac16ff91
--- /dev/null
+++ b/app/src/main/res/layouts/mastodon/drawable/ic_logout.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/app/src/main/res/layouts/mastodon/drawable/ic_network_prefs.xml b/app/src/main/res/layouts/mastodon/drawable/ic_network_prefs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c167dfb64abdc3b967381e5b09546f6ec9dc34c7
--- /dev/null
+++ b/app/src/main/res/layouts/mastodon/drawable/ic_network_prefs.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layouts/mastodon/drawable/ic_proxy.xml b/app/src/main/res/layouts/mastodon/drawable/ic_proxy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc93ade865cdc1e905960a2e1d88e3c7ca2a81db
--- /dev/null
+++ b/app/src/main/res/layouts/mastodon/drawable/ic_proxy.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layouts/mastodon/layout/activity_media_pager.xml b/app/src/main/res/layouts/mastodon/layout/activity_media_pager.xml
index 2b541a9d93e58ae9ee7f0d562eab84f22a736eba..2cf7620ed614aabdf50849b96cda59057177c17b 100644
--- a/app/src/main/res/layouts/mastodon/layout/activity_media_pager.xml
+++ b/app/src/main/res/layouts/mastodon/layout/activity_media_pager.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
- android:fitsSystemWindows="true"
+ android:fitsSystemWindows="false"
android:background="@android:color/transparent">
@@ -35,6 +35,7 @@
+ app:layout_constraintWidth_max="48dp">
-
+
-
+ app:layout_constraintWidth_max="48dp">
-
+
-
+ app:icon="@drawable/ic_baseline_format_quote_24"
+ app:iconGravity="textStart"
+ app:iconSize="28dp"
+ app:iconTint="?colorControlNormal"
+ app:layout_constraintWidth_max="48dp" />
-
+ app:layout_constraintWidth_max="48dp">
+
+
-
+
+
-
-
-
-
-
-
-
+ android:contentDescription="@string/more_options"
+ app:icon="@drawable/ic_round_more_horiz_24"
+ app:iconGravity="textStart"
+ app:iconSize="28dp"
+ app:iconTint="?colorControlNormal"
+ app:layout_constraintWidth_max="48dp" />
-
+
diff --git a/app/src/main/res/layouts/mastodon/layout/drawer_status_compose.xml b/app/src/main/res/layouts/mastodon/layout/drawer_status_compose.xml
index 506fb0a9928710796210ba7a0dd76053486662ac..7ccb3799ba5c509860f46e06696748c9448551d0 100644
--- a/app/src/main/res/layouts/mastodon/layout/drawer_status_compose.xml
+++ b/app/src/main/res/layouts/mastodon/layout/drawer_status_compose.xml
@@ -179,6 +179,7 @@
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
android:layout_marginStart="6dp"
+ android:contentDescription="@string/open_new_attachment_panel"
app:icon="@drawable/ic_compose_attach"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintStart_toStartOf="parent"
@@ -191,6 +192,7 @@
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
android:checkable="true"
+ android:contentDescription="@string/add_content_warning"
app:icon="@drawable/ic_compose_sensitive"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintStart_toEndOf="@id/button_attach"
@@ -203,6 +205,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
+ android:contentDescription="@string/change_visibility"
app:icon="@drawable/ic_compose_visibility_public"
app:iconGravity="textStart"
app:iconPadding="0dp"
@@ -216,6 +219,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
+ android:contentDescription="@string/set_language"
android:fontFamily="monospace"
android:minWidth="72dp"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
@@ -253,6 +257,7 @@
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
android:layout_marginEnd="6dp"
+ android:contentDescription="@string/action_publish"
app:icon="@drawable/ic_compose_post"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintEnd_toEndOf="parent"
@@ -276,6 +281,7 @@
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:contentDescription="@string/attach_images"
app:icon="@drawable/ic_compose_attach_image" />
diff --git a/app/src/main/res/layouts/mastodon/layout/fragment_notification_container.xml b/app/src/main/res/layouts/mastodon/layout/fragment_notification_container.xml
index 742303a182c83396cc04f2aabc895f4a77e21710..cf25f709008cbcd1940c1f7a87a7f4b7afd7d91b 100644
--- a/app/src/main/res/layouts/mastodon/layout/fragment_notification_container.xml
+++ b/app/src/main/res/layouts/mastodon/layout/fragment_notification_container.xml
@@ -36,11 +36,11 @@
diff --git a/app/src/main/res/layouts/mastodon/layout/fragment_slide_media.xml b/app/src/main/res/layouts/mastodon/layout/fragment_slide_media.xml
index e82be301dd37d726486ee85063d252044c0772bb..f59694b1040a6cde54eefec0ee330424d8bfbad3 100644
--- a/app/src/main/res/layouts/mastodon/layout/fragment_slide_media.xml
+++ b/app/src/main/res/layouts/mastodon/layout/fragment_slide_media.xml
@@ -9,8 +9,7 @@
+ android:layout_height="match_parent">
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
+
diff --git a/app/src/main/res/menus/mastodon/menu/activity_main_drawer.xml b/app/src/main/res/menus/mastodon/menu/activity_main_drawer.xml
index 12cbc5418e9bcd498cd65a909b5fd91e793ecc5a..eeb6be63f7e3b5602397d33b7381cc221e6db40f 100644
--- a/app/src/main/res/menus/mastodon/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menus/mastodon/menu/activity_main_drawer.xml
@@ -73,6 +73,11 @@
android:icon="@drawable/ic_info_outline_white_24dp"
android:title="@string/action_about_instance"
android:visible="true" />
+
diff --git a/app/src/main/res/menus/mastodon/menu/bottom_nav_menu.xml b/app/src/main/res/menus/mastodon/menu/bottom_nav_menu.xml
index 3fda0121cd7d9e2e62f5309316de65d4b2ac99a9..0c328b2e6f3402591d30a66ccde2ca01d953344e 100644
--- a/app/src/main/res/menus/mastodon/menu/bottom_nav_menu.xml
+++ b/app/src/main/res/menus/mastodon/menu/bottom_nav_menu.xml
@@ -24,6 +24,6 @@
+ android:title="@string/v_direct" />
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_graph_settings.xml b/app/src/main/res/navigation/nav_graph_settings.xml
index bc89c544b4e55957589f2a7aee212e4472204b01..4e364c76efccde06acc840053f2bebc9350a9d50 100644
--- a/app/src/main/res/navigation/nav_graph_settings.xml
+++ b/app/src/main/res/navigation/nav_graph_settings.xml
@@ -76,6 +76,14 @@
app:popEnterAnim="@anim/pop_enter"
app:popExitAnim="@anim/pop_exit" />
+
+
+
+
Média přes celý displej
Média se budou zobrazovat přes celou šířku displeje a u výšky se bude respektovat poměr stran.
Tagy Twitteru (přes Nitter)
+ Více voleb
+ Oblíbené
+ Boostnout
+ Citovat
+ Přidat varování o obsahu
+ Odstranit varování o obsahu
+ Změnit viditelnost
+ Nastavit jazyk
+ Publikovat
+ Otevřít panel pro novou přílohu
+ Zavřít panel pro novou přílohu
+ Připojit obrázky
+ Připojit zvuk
+ Připojit videa
+ Připojit soubory
+ Přidat anketu
+ Informace o instanci
+ Síť
+ Automaticky skrývat tlačítko pro vytvoření
+ Automaticky skrývat tlačítko pro vytvoření během posouvání nahoru po časové ose
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 64c140a5e2b63f4f30415fb3f310bf43a4809edd..0f64e39bab8a332f0f9ae0eb8b458786e3434dba 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -1078,4 +1078,13 @@
Pronomen
Unterstützung von Pronomen
QR Code Generator
+ Dein Token
+ Mehr Optionen
+ Favorisieren
+ Zitieren
+ Content Warnung (CW) hinzufügen
+ Content Warnung (CW) entfernen
+ Veröffentlichen
+ Sichtbarkeit anpassen
+ Sprache ändern
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index 0da33f6d0a865e43d47e413f1f58c2eeaf2d332f..5a593f90090b5aa12f6422a7bf58bffc823b375d 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -2,20 +2,20 @@
درباره
درباره این نمونه
- حریم شخصی
+ حریم خصوصی
حافظه نهان
خروج از حساب
بستن
- بله
- خیر
- لغو
+ آری
+ نه
+ رد کردن
بارگیری
بارگیری %1$s
- رسانه، ذخیره شد
+ رسانه ذخیره شد
پرونده: %1$s
گذرواژه
- ایمیل
+ رایانامه
حسابها
بوقها
برچسبها
@@ -24,59 +24,59 @@
نمونه: mastodon.social
اکنون با این حساب کار میکند: %1$s
افزودن حساب کاربری
- از محتوای بوق در حافظه رونوشت گرفته شد
- از نشانی بوق در حافظه رونوشت گرفته شد
+ محتوای بوق در بریدهدان رونویسی شد
+ نشانی بوق در بریدهدان رونویسی شد
دوربین
- حذف همه
+ پاککردن همه
زمانبندی
- اندازه متن
+ اندازه نوشته
بعدی
- قبلی
- باز کردن با
- تایید
+ پیشین
+ گشودن با
+ پذیرش
رسانه
همرسانی با
- همرسانی با Fedilab
+ همرسانیشده با فدیلب
پاسخها
نام کاربری
پیشنویسها
- پسندها
- دنبالکنندههای جدید
+ برگزیدهها
+ دنبالکنندگان جدید
اشارهها
تقویتها
نمایش تقویتها
نمایش پاسخها
- باز کردن در مرورگر
+ گشودن در مرورگر
ترجمه
خانه
خط زمانی محلی
- کاربران بی صدا شده
- کاربران مسدود شده
- اعلانها
- درخواست پیگیری
+ کاربران بیصدا
+ کاربران بستهشده
+ آگاهسازیها
+ درخواست دنبال کردن
تنظیمات
- فرستادن یک رایانامه
- بوقهای زمانبندی شده
- اطلاعات زیر ممکن است نمایه کاربر را کامل منعکس نکند.
+ فرستادن رایانامه
+ بوقهای زمانبندیشده
+ دادههای زیر ممکن است نمایه کاربر را بهطور کامل نشان ندهند.
درج شکلک
- The app did not collect custom emojis for the moment.
- Are you sure you want to logout @%1$s@%2$s?
+ برنامه هنوز شکلکهای سفارشی را جمعآوری نکرده است.
+ آیا مطمئنید که میخواهید از @%1$s@%2$s خارج شوید؟
بوقی برای نمایش نیست
- این بوق به علاقهمندیها اضافه شود؟
- این بوق از علاقهمندیها حذف شود؟
+ این بوق به برگزیدهها افزوده شود؟
+ این بوق از برگزیدهها پاک شود؟
این بوق تقویت شود؟
- تقویت این بوق حذف شود؟
- بیصدا
+ تقویت این بوق پاک شود؟
+ بیصدا کردن
مسدود کردن
گزارش
- حذف
- رونوشت
- بهاشتراکگذاری
+ پاککردن
+ رونوشت
+ همرسانی
اشاره
بیصدا کردن زماندار
- حذف و بازنویسی
+ پاککردن و بازنویسی
- این حساب بیصدا شود؟
- این حساب مسدود شود؟
@@ -93,127 +93,126 @@
- این بوق پاک شود؟
- این بوق پاک و بازنویسی شود؟
- نشانکها
- افزودن به نشانکها
- حذف نشانک
- Status has been added to bookmarks!
- مطلب از نشانکها حذف شد!
+ نشانهها
+ افزودن به نشانهها
+ پاککردن نشانه
+ بوق به نشانهها افزوده شد!
+ بوق از نشانهها پاک شد!
- %d ث
- %d د
- %d س
- %d ر
+ %d ثانیه
+ %d دقیقه
+ %d ساعت
+ %d روز
- - %d second
+ - %d ثانیه
- %d ثانیه
- - %d minute
+ - %d دقیقه
- %d دقیقه
- - %d hour
+ - %d ساعت
- %d ساعت
- - %d day
+ - %d روز
- %d روز
- An error occurred while selecting the media!
- Remove this media?
- Your toot is empty!
- The toot has been sent!
- Sensitive content?
- No drafts!
- Choose an account
- Select some accounts
- Delete draft?
- Describe for the visually impaired
+ خطایی هنگام انتخاب رسانه رخ داد!
+ این رسانه پاک شود؟
+ بوق شما خالی است!
+ بوق فرستاده شد!
+ محتوای حساس؟
+ پیشنویسی وجود ندارد!
+ انتخاب حساب
+ چند حساب انتخاب کنید
+ پیشنویس پاک شود؟
+ توصیف برای افراد با مشکل بینایی
- No description available!
+ توصیفی در دسترس نیست!
- Release %1$s
- Developer:
- License:
+ نسخه %1$s
+ توسعهدهنده:
+ پروانه:
GNU GPL V3
- Source code:
- Search instances:
+ کد منبع:
+ کاوش نمونهها:
- No account to display
- No follow request
- بوقها
-\n %1$s
- Following \n %1$s
- Followers \n %1$s
- Reject
+ حسابی برای نمایش نیست
+ درخواستی برای دنبال کردن نیست
+ بوقها\n %1$s
+ دنبالشوندگان \n %1$s
+ دنبالکنندگان\n %1$s
+ رد کردن
- No scheduled toots to display!
- Delete scheduled toot?
- The toot has been scheduled!
- The scheduled date must be greater than the current hour!
+ بوق زمانبندیشدهای برای نمایش نیست!
+ بوق زمانبندیشده پاک شود؟
+ بوق زمانبندی شد!
+ تاریخ زمانبندی باید از ساعت کنونی بیشتر باشد!
- The time for muting should be greater than one minute.
- %1$s has been muted until %2$s.\n You can unmute this account from their profile page.
- %1$s is muted until %2$s.\n Tap here to unmute the account.
+ زمان بیصدا کردن باید بیشتر از یک دقیقه باشد.
+ %1$s تا %2$s بیصدا شد.\n میتوانید این حساب را از صفحه نمایهاش از حالت بیصدا خارج کنید.
+ %1$s تا %2$s بیصدا است.\n برای خروج از حالت بیصدا اینجا بزنید.
- No notification to display
- mentioned you
- wrote a new message
- boosted your status
- favourited your status
- followed you
- asked to follow you
- Delete all notifications?
- All notifications have been deleted!
+ آگاهسازی برای نمایش نیست
+ از شما یاد کرد
+ پیام جدیدی نوشت
+ بوق شما را تقویت کرد
+ بوق شما را برگزید
+ شما را دنبال کرد
+ درخواست دنبال کردن شما را داد
+ همه آگاهسازها پاک شوند؟
+ همه آگاهسازها پاک شدند!
- Followers
+ دنبالکنندگان
- Unable to get client id!
- The account was blocked!
- The account is no longer blocked!
- The account was muted!
- The account is no longer muted!
- The account was followed!
- The account is no longer followed!
- The toot was boosted!
- The toot is no longer boosted!
- The toot was added to your favourites!
- The toot was removed from your favourites!
- Oops ! An error occurred!
- An error occurred! The instance did not return an authorisation code!
- The instance domain does not seem to be valid!
- An error occurred while switching between accounts!
- An error occurred while searching!
- No action can be taken
- An error occurred while translating!
+ ناتوان در دریافت شناسه کارخواه(کلاینت)!
+ حساب بسته شد!
+ حساب دیگر بسته نیست!
+ حساب بیصدا شد!
+ حساب دیگر بیصدا نیست!
+ حساب دنبال شد!
+ حساب دیگر دنبال نمیشود!
+ بوق تقویت شد!
+ بوق دیگر تقویتشده نیست!
+ بوق به برگزیدههای شما افزوده شد!
+ بوق از برگزیدههای شما پاک شد!
+ اوه! خطایی رخ داد!
+ خطایی رخ داد! نمونه کد تأیید را برنگرداند!
+ دامنه نمونه درست به نظر نمیرسد!
+ خطایی هنگام جابهجایی بین حسابها رخ داد!
+ خطایی هنگام جستجو رخ داد!
+ هیچ اقدامی نمیتوان انجام داد
+ خطایی هنگام ترجمه رخ داد!
- Number of toots per load
- Disable GIF avatars
- Notify when someone follows you
- Notify when someone boosts your status
- Notify when someone favourites your status
- Notify when someone mentions you
- Notify when a poll ended
- Notify for new posts
- Show confirmation dialog before boosting
- Show confirmation dialog before adding to favourites
- Notify?
- Silent Notifications
- NSFW view timeout (seconds, 0 means off)
- Media Description timeout (seconds, 0 means off)
- Custom sharing
- Your custom sharing URL…
- Lock account
- Save changes
- Fit preview images
- Between
- and
- Use the built-in browser
- Custom tabs
- Automatically expand cw
- Set LED colour:
+ شمار بوقها در هر بارگذاری
+ نمایش تصاویر متحرک در آواتارها غیرفعال شود
+ آگاهسازی هنگام دنبال شدن بهدست کسی
+ آگاهسازی هنگام تقویت بوق شما
+ آگاهسازی هنگام برگزیدن بوق شما
+ آگاهسازی هنگام اشاره به شما
+ آگاهسازی هنگام پایان نظرسنجی
+ آگاهسازی برای بوقهای جدید
+ نمایش پیام پذیرش پیش از تقویت
+ نمایش پیام پذیرش پیش از افزودن به برگزیدهها
+ آگاهسازی شود؟
+ آگاهسازیهای بیصدا
+ مهلت نمایش محتوای حساس (ثانیه، 0 یعنی خاموش)
+ مهلت توصیف رسانه (ثانیه، 0 یعنی خاموش)
+ همرسانی سفارشی
+ نشانی همرسانی سفارشی شما…
+ قفل کردن حساب
+ ذخیره تغییرات
+ تناسب پیشنمایش تصاویر
+ از
+ تا
+ بهکارگیری مرورگر داخلی
+ زبانههای سفارشی
+ گسترش خودکار هشدار محتوا
+ تنظیم رنگ LED:
- Blue
- Cyan
@@ -223,120 +222,120 @@
- Yellow
- White
- Follow
- Unblock
- Mute
- Unmute
- Request sent
- Follows you
- First letter in capital for replies
- Resize pictures
- Resize videos
+ دنبال کردن
+ باز کردن
+ بیصدا کردن
+ خروج از بیصدا
+ درخواست فرستاده شد
+ شما را دنبال میکند
+ حرف نخست بزرگ برای پاسخها
+ تغییر اندازه تصاویر
+ تغییر اندازه ویدیوها
- Mb
+ مگابایت
- Title
- Title…
- Description
- Keywords
- Keywords…
+ عنوان
+ عنوان…
+ توصیف
+ کلیدواژهها
+ کلیدواژهها…
- Public
- Unlisted
- Private
- Direct
+ عمومی
+ فهرستنشده
+ خصوصی
+ مستقیم
- Filter out by regular expressions
- Search
- Delete
+ پالایش با عبارات منظم
+ جستجو
+ پاککردن
- Lists
- Are you sure you want to permanently delete this list?
- Add to list
- Delete list
- New list title
- The account was added to the list!
- You don\'t have any lists yet!
+ فهرستها
+ آیا مطمئنید که میخواهید این فهرست را برای همیشه پاک کنید؟
+ افزودن به فهرست
+ پاککردن فهرست
+ عنوان فهرست جدید
+ حساب به فهرست افزوده شد!
+ هنوز هیچ فهرستی ندارید!
- %1$s has moved to %2$s
- Media has been loaded. Tap here to display it.
+ %1$s به %2$s منتقل شده است
+ رسانه بارگذاری شد. برای نمایش اینجا بزنید.
- Proxy
- Enable proxy?
- Host
- Port
- Login
- Password
- Add toot details when sharing
- Support the app on Liberapay
- There is an error in the regular expression!
- No timelines was found on this instance!
- Follow instance
- You already follow this instance!
- Partnerships
- Hide boosts from %s
- Feature on profile
- Show boosts from %s
- Don\'t feature on profile
- Direct message
- Filters
- No filters to display. You can create one by tapping on the \"+\" button.
- Keyword or phrase
- Home timeline
- Public timelines
- Notifications
- Conversations
- Will be matched regardless of casing in text or content warning of a toot
- Drop instead of hide
- Filtered toots will disappear irreversibly, even if filter is later removed
- When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word
- Whole word
- Filter contexts
- One or multiple contexts where the filter should apply
- Expire after
- Delete filter?
- Update filter
- You have not created a list yet. Tap on the \"+\" button to add a new one.
- Automatically expand hidden media
- New follow
- New Boost
- New Favourite
- New Mention
- Poll Ended
- Toots Backup
- New posts
- Media Download
- Select Tone
- Enable time slot
- Are you sure to block %s?\n\nYou will not see any content from that domain in any public timeline or in your notifications. Your followers from that domain will be removed.
- Block domain
- The domain is blocked
- Fetching remote status
- Peertube instance
- Use Emoji One
- Information
- Display previews in all toots
- The account id has been copied in the clipboard!
- Change the language
- Truncate long toots
- Truncate toots over \'x\' lines. Zero means disabled.
- Display more
- Display less
- The tag already exists!
- Schedule boost
- The boost is scheduled!
- No scheduled boost to display!
- Open menu
- Profile picture
- Profile banner
- Contact admin of the instance
- MastoHost logo
- Emoji picker
- Expand the conversation
- Custom emoji picker
- Favicon
- Add description for media (for the visually impaired)
+ پروکسی
+ فعالسازی پروکسی؟
+ میزبان
+ درگاه
+ ورود
+ گذرواژه
+ افزودن جزئیات بوق هنگام همرسانی
+ پشتیبانی از برنامه در Liberapay
+ خطایی در عبارت منظم وجود دارد!
+ هیچ خط زمانیای در این نمونه یافت نشد!
+ دنبال کردن نمونه
+ شما این نمونه را از قبل دنبال میکنید!
+ همکاریها
+ پنهان کردن تقویتها از %s
+ نمایش در نمایه
+ نمایش تقویتها از %s
+ عدم نمایش در نمایه
+ پیام مستقیم
+ پالایشها
+ پالایشی برای نمایش نیست. با زدن دکمه «+» میتوانید یکی بسازید.
+ کلیدواژه یا عبارت
+ خط زمانی خانه
+ خطهای زمانی عمومی
+ آگاهسازها
+ گفتوگوها
+ صرفنظر از بزرگ یا کوچک بودن حروف، در متن یا هشدار محتوای بوق تطبیق داده میشود
+ پاککردن به جای پنهان کردن
+ بوقهای پالایششده بهطور غیرقابل بازگشت ناپدید میشوند، حتی اگر پالایش پس از آن پاک شود
+ اگر کلیدواژه یا عبارت فقط شامل حروف و اعداد باشد، تنها در صورت تطبیق با کل واژه اعمال میشود
+ کل واژه
+ زمینههای پالایش
+ یک یا چند زمینه که پالایش باید در آنها اعمال شود
+ انقضا پس از
+ پالایش پاک شود؟
+ بهروزرسانی پالایش
+ هنوز فهرستی نساختهاید. برای افزودن فهرست جدید روی دکمه «+» بزنید.
+ گسترش خودکار رسانههای پنهان
+ دنبالکننده جدید
+ تقویت جدید
+ برگزیدن جدید
+ اشاره جدید
+ پایان نظرسنجی
+ پشتیبان بوقها
+ بوقهای جدید
+ بارگیری رسانه
+ انتخاب صدا
+ فعالسازی بازه زمانی
+ آیا مطمئنید که میخواهید %s را ببندید؟\n\nشما هیچ محتوایی از آن دامنه را در خطهای زمانی عمومی یا آگاهسازیهایتان نخواهید دید. دنبالکنندگان شما از آن دامنه پاک خواهند شد.
+ بستن دامنه
+ دامنه بسته شد
+ بازیابی وضعیت از راه دور
+ نمونه پیرتیوب
+ بهکارگیری Emoji One
+ دادهها
+ نمایش پیشنمایش در همه بوقها
+ شناسه حساب در بریدهدان رونویسی شد!
+ تغییر زبان
+ کوتاه کردن بوقهای بلند
+ کوتاه کردن بوقهای بیش از «x» خط. صفر یعنی غیرفعال.
+ نمایش بیشتر
+ نمایش کمتر
+ برچسب از قبل وجود دارد!
+ زمانبندی تقویت
+ تقویت زمانبندی شد!
+ تقویت زمانبندیشدهای برای نمایش نیست!
+ گشودن فهرست
+ تصویر نمایه
+ بنر نمایه
+ تماس با مدیر نمونه
+ نماد MastoHost
+ انتخابکننده شکلک
+ گسترش گفتوگو
+ انتخابکننده شکلک سفارشی
+ نمادک
+ افزودن توصیف برای رسانه (برای افراد با مشکل بینایی)
- Never
- 30 minutes
@@ -347,143 +346,139 @@
- 1 week
- Languages
- Media only
- Show NSFW
- Bot
- Pixelfed instance
- Mastodon instance
- Any of these
- All of these
- None of these
- Any of these words (space-separated)
- All these words (space-separated)
- Add some words to filter (space-separated)
- Change column name
- Misskey instance
- Trending
- Local
- Category
- Description
- Share
- Toots (Server)
- Toots (Device)
- Timelines
- Interface
- Contacts
- An error occurred when selecting the backup file!
- Logout account
- All
- Copy link
- http calls blocked by the application
- List of blocked calls
- Submit
- Filter timeline with tags
- No tags
- Attach an image when sharing a URL
+ زبانها
+ فقط رسانه
+ نمایش محتوای حساس
+ ربات
+ نمونه پیکسلفد
+ نمونه ماستادون
+ هر یک از اینها
+ همه اینها
+ هیچیک از اینها
+ هر یک از این واژهها (با فاصله جدا شده)
+ همه این واژهها (با فاصله جدا شده)
+ افزودن چند واژه برای پالایش (با فاصله جدا شده)
+ تغییر نام ستون برچسب
+ نمونه Misskey
+ روندها
+ محلی
+ دسته
+ توصیف
+ همرسانی
+ بوقها (کارساز)
+ بوقها (دستگاه)
+ خطهای زمانی
+ رابط کاربری
+ تماسها
+ خطایی هنگام انتخاب پرونده پشتیبان رخ داد!
+ خروج از حساب
+ همه
+ رونوشت پیوند
+ فراخوانهای HTTP توسط برنامه بسته شدهاند
+ فهرست فراخوانهای بستهشده
+ ارسال
+ پالایش خط زمانی با برچسبها
+ بدون برچسب
+ پیوست تصویر هنگام همرسانی پیوند
- Create a poll
- Choice %d
- You need two choices at least for the poll!
- Done
- end at %s
- Vote
- A poll you have voted in has ended
- A poll you tooted has ended
- Categories
- Move timeline
- Hide timeline
- Reorder timelines
- List permanently deleted
- Followed instance removed
- Pinned tag removed
- Undo
- Main timelines can only be hidden!
- Always mark media as sensitive
- GNU instance
- Forward tags in replies
- Long press to store media
- Manage tags
- Display name
- Emoji
- Text
- Filter
- Brush
- Discard
- Saving…
- Image Saved Successfully!
- Failed to save Image
- Add a poll item
- Mute conversation
- Unmute conversation
- The conversation is no longer muted!
- The conversation is muted
- General
- Regional
- Art
- Activism
- Gaming
- Technology
- Furry
- Food
- Logo of the instance
- Join Mastodon
- Choose an instance by picking up a category, then tap on a check button.
- %1$s users
- Confirm password
- I agree to %1$s and %2$s
- server rules
- terms of service
- Sign up
- This instance works with invitations. Your account will need to be manually approved by an administrator before being usable.
- Passwords don\'t match!
- The email doesn\'t seem to be valid!
- You will be sent a confirmation e-mail
- Use at least 8 characters
- Password should contain at least 8 characters
- Username should only contain letters, numbers and underscores
- Account created!
- Your account has been created!\n\n
- Think to validate your email within the 48 next hours.\n\n
- You can now connect your account by writing %1$s in the first field and click on Connect.\n\n
- Important: If your instance required validation, you will receive an email once it is validated!
-
- Save the message in drafts?
- Administration
- Reports
- Unresolved
- Remote
- Active
- Pending
- Disabled
- Suspended
- Permissions
- Disable
- Silence
- Account
- Undo silence
- Undo disable
- Suspend
- Undo suspend
- The application needs to access audio recording
- Voice message
- During the time slot, the app will send notifications. You can reverse (ie: silent) this time slot with the right spinner.
- Previews will not be cropped in timelines
- Automatically insert a line break after the mention to capitalize the first letter
- Allow content creators to share statuses to their RSS feeds
- Compose
- Select
- Add an instance
- Enable crash reports
- If enabled, a crash report will be created locally and then you will be able to share it.
- Fedilab has stopped :(
- You can send me by email the crash report. It will help to fix it :)\n\nYou can add additional content. Thank you!
- Visibility
- Disable custom animated emojis
- Report account
+ ساخت نظرسنجی
+ گزینه %d
+ برای نظرسنجی حداقل به دو گزینه نیاز است!
+ انجام شد
+ پایان در %s
+ رأی
+ نظرسنجیای که در آن رأی دادهاید پایان یافت
+ نظرسنجیای که منتشر کردهاید پایان یافت
+ دستهها
+ جابهجایی خط زمانی
+ پنهان کردن خط زمانی
+ بازچینش خطهای زمانی
+ فهرست برای همیشه پاک شد
+ نمونه دنبالشده پاک شد
+ برچسب سنجاقشده پاک شد
+ بازگرداندن
+ خطهای زمانی اصلی فقط میتوانند پنهان شوند!
+ همیشه علامتگذاری رسانه بهعنوان حساس
+ نمونه گنو
+ ارسال برچسبها در پاسخها
+ فشار طولانی برای ذخیره رسانه
+ مدیریت برچسبها
+ نام نمایشی
+ شکلک
+ نوشته
+ پالایش
+ قلممو
+ دور انداختن
+ در حال ذخیره…
+ تصویر با موفقیت ذخیره شد!
+ ذخیره تصویر ناموفق بود
+ افزودن گزینه نظرسنجی
+ بیصدا کردن گفتوگو
+ خروج گفتوگو از بیصدا
+ گفتوگو دیگر بیصدا نیست!
+ گفتوگو بیصدا شد
+ عمومی
+ منطقهای
+ هنر
+ کنشگری
+ بازی
+ فناوری
+ فری
+ غذا
+ نماد نمونه
+ پیوستن به ماستادون
+ یک نمونه را با انتخاب دسته و سپس زدن دکمه پذیرش انتخاب کنید.
+ %1$s کاربر
+ تکرار گذرواژه
+ من با %1$s و %2$s موافقم
+ قوانین کارساز
+ شرایط خدمات
+ نامنویسی
+ این نمونه با دعوتنامه کار میکند. حساب شما باید پیش از بهکارگیری بهدست مدیر بهصورت دستی پذیرفته شود.
+ گذرواژهها همخوانی ندارند!
+ رایانامه درست به نظر نمیرسد!
+ رایانامه پذیرش برای شما فرستاده خواهد شد
+ حداقل از ۸ نویسه استفاده کنید
+ گذرواژه باید دستکم ۸ نویسه داشته باشد
+ نام کاربری فقط باید شامل حروف، اعداد و زیرخط باشد
+ حساب ساخته شد!
+ حساب شما ساخته شد!\n\n فراموش نکنید رایانامه خود را ظرف ۴۸ ساعت آینده بپذیرید.\n\n اکنون میتوانید با نوشتن %1$s در کادر نخست و کلیک روی اتصال به حساب خود متصل شوید.\n\n مهم: اگر نمونه شما نیاز به پذیرش دارد، پس از پذیرش، رایانامهای دریافت خواهید کرد!
+ پیام در پیشنویسها ذخیره شود؟
+ مدیریت
+ گزارشها
+ حلنشده
+ دور
+ فعال
+ در انتظار
+ غیرفعال
+ تعلیقشده
+ اجازهها
+ غیرفعال کردن
+ بیصدا کردن
+ حساب
+ لغو بیصدا
+ لغو غیرفعال
+ تعلیق
+ لغو تعلیق
+ برنامه نیاز به دسترسی به ضبط صدا دارد
+ پیام صوتی
+ در بازه زمانی، برنامه آگاهسازیها را ارسال میکند. میتوانید این بازه را با چرخاننده سمت راست معکوس کنید (یعنی بیصدا).
+ پیشنمایشها در خطهای زمانی برش نمیخورند
+ بهطور خودکار پس از اشاره، یک خط جدید درج میشود تا حرف نخست بزرگ شود
+ اجازه به سازندگان محتوا برای همرسانی وضعیتها به خوراکهای RSS آنها
+ نگارش
+ انتخاب
+ افزودن نمونه
+ فعالسازی گزارشهای خرابی
+ اگر فعال شود، گزارش خرابی بهصورت محلی ساخته میشود و سپس میتوانید آن را همرسانی کنید.
+ فدیلب متوقف شد :(\"
+ میتوانید گزارش خرابی را از طریق رایانامه برای من بفرستید. این کمک میکند تا مشکل برطرف شود :)\n\nمیتوانید محتوای اضافی اضافه کنید. سپاسگزارم!
+ دیدپذیری
+ غیرفعالسازی شکلکهای متحرک سفارشی
+ گزارش حساب
- - %d voter
- - %d voters
+ - %d رأیدهنده
+ - %d رأیدهنده
- Single choice
@@ -498,80 +493,601 @@
- 3 days
- 7 days
- Your poll can\'t have duplicated options!
- Clear cache when leaving
- The cache (media, cached messages, data from the built-in browser) will be automatically cleared when leaving the application.
- Do you want to unfollow this account?
- Show confirmation dialog before unfollowing
- Replace Medium links
- Replace medium.com links with an open source alternative front-end focused on privacy.
- Default: scribe.rip
- Use a push notifications system for getting notifications in real time.
- Add notes
- Notes for the account
- Allow to compress large photos into smaller sized photos with very less or negligible loss in quality of the image.
- Allow compressing videos while maintaining their quality.
- Order by
- Links
- Change the color of links (URLs, mentions, tags, etc.) in messages
- Reblogs header
- Change the color of display name at the top of messages
- Change the color of the user name at the top of messages
- Change the color of the header for reblogs
- Posts
- Background color of posts in timelines
- Reset colors
- Tap here to reset all your custom colors
- Reset
- Icons
- Color of bottom icons in timelines
- Logo of the instance
- Edit profile
- Make an action
- Translation
- Text color
- Change the text color in messages
- Use a custom theme
- Theming
- The theme was exported
- The theme has been successfully exported in CSV
- Import a theme
- Tap here to import a theme from a previous export
- Export the theme
- Tap here to export the current theme
- An error occurred when selecting the theme file
- User count
- Status count
- Instance count
- End in %s
- This instance is not available on https://instances.social
- Display full link
- Share link
- Open with another app
- Check redirect
- This URL does not redirect
- %1$s \n\nredirects to\n\n %2$s
- Remove UTM parameters
- The app will automatically remove UTM parameters from URLs before visiting a link.
- %d people talking
- Twitter accounts (via Nitter)
- Twitter usernames space separated
- Identity proofs
- هویت تایید شده
- تایید شده توسط %1$s (%2$s)
- Action disabled
- Unfollow
- Something went wrong, please check your download directory in settings.
- Announcements
- No announcements!
- Add a reaction
- Video cache in MB, zero means no cache.
- Watermarks
- Automatically add a watermark at the bottom of pictures. The text can be customized for each account.
- No distributors found!
- You need a distributor for receiving push notifications.\nYou will find more details at %1$s.\n\nYou can also disable push notifications in settings for ignoring that message.
- Select a distributor
+ نظرسنجی شما نمیتواند گزینههای تکراری داشته باشد!
+ پاککردن حافظه نهان هنگام خروج
+ حافظه نهان (رسانه، پیامهای ذخیرهشده، دادههای مرورگر داخلی) هنگام خروج از برنامه بهطور خودکار پاک میشود.
+ آیا میخواهید این حساب را دنبال نکنید؟
+ نمایش گفتوگوی پذیرش پیش از لغو دنبال کردن
+ جایگزینی پیوندهای مدیوم
+ جایگزینی پیوندهای medium.com با یک نما متنباز با تمرکز بر حریم خصوصی
+ پیشفرض: scribe.rip
+ استفاده از سامانه آگاهسازی فشاری برای دریافت آگاهسازیها در زمان واقعی.
+ افزودن یادداشتها
+ یادداشتها برای حساب
+ امکان فشردهسازی تصاویر بزرگ به تصاویر کوچکتر با کمترین یا بدون افت کیفیت.
+ امکان فشردهسازی ویدیوها با حفظ کیفیت آنها.
+ مرتبسازی بر اساس
+ پیوندها
+ تغییر رنگ پیوندها (نشانیها، اشارهها، برچسبها و...) در پیامها
+ سربرگ تقویتها
+ تغییر رنگ نام نمایشی در بالای پیامها
+ تغییر رنگ نام کاربری در بالای پیامها
+ تغییر رنگ سربرگ برای تقویتها
+ بوقها
+ رنگ پسزمینه بوقها در خطهای زمانی
+ بازنشانی رنگها
+ برای بازنشانی همه رنگهای سفارشی اینجا بزنید
+ بازنشانی
+ نمادها
+ رنگ نمادهای پایین در خطهای زمانی
+ نماد نمونه
+ ویرایش نمایه
+ انجام یک کنش
+ ترجمه
+ رنگ نوشته
+ تغییر رنگ نوشته در پیامها
+ استفاده از پوسته سفارشی
+ پوستهسازی
+ پوسته صادر شد
+ پوسته با موفقیت در قالب CSV صادر شد
+ وارد کردن پوسته
+ برای وارد کردن پوسته از صادرات قبلی اینجا بزنید
+ صدور پوسته
+ برای صدور پوسته کنونی اینجا بزنید
+ خطایی هنگام انتخاب پرونده پوسته رخ داد
+ شمار کاربران
+ شمار وضعیتها
+ شمار نمونهها
+ پایان در %s
+ این نمونه در https://instances.social در دسترس نیست
+ نمایش پیوند کامل
+ همرسانی پیوند
+ گشودن با برنامه دیگر
+ بررسی تغییر مسیر
+ این نشانی تغییر مسیر نمیدهد
+ %1$s \n\nبه\n\n %2$s تغییر مسیر میدهد
+ پاککردن پارامترهای UTM
+ برنامه بهطور خودکار پارامترهای UTM را از نشانیها پیش از بازدید پیوند پاک میکند.
+ %d نفر در حال گفتگو
+ حسابهای توییتر (از طریق Nitter)
+ نامهای کاربری توییتر با فاصله جدا شده
+ اثبات هویت
+ هویت تاییدشده
+ تاییدشده بهدست %1$s (%2$s)
+ کنش غیرفعال
+ لغو دنبال کردن
+ مشکلی پیش آمد، لطفاً پوشه بارگیری را در تنظیمات بررسی کنید.
+ اطلاعیه
+ اطلاعیهای وجود ندارد!
+ افزودن واکنش
+ حافظه نهان ویدیو به مگابایت، صفر یعنی بدون حافظه نهان.
+ واترمارک
+ افزودن خودکار واترمارک در پایین تصاویر. متن میتواند برای هر حساب سفارشی شود.
+ توزیعکنندهای یافت نشد!
+ برای دریافت آگاهسازیهای فشاری به توزیعکننده نیاز دارید.\nجزئیات بیشتر را در %1$s خواهید یافت.\n\nهمچنین میتوانید آگاهسازیهای فشاری را در تنظیمات غیرفعال کنید تا این پیام نادیده گرفته شود.
+ انتخاب توزیعکننده
اندازه نماد
نمایش بوقهای مستقیم
- کاربران بیصدا شده خانه
-
\ No newline at end of file
+ کاربران بیصدای خانه
+ گزارش
+ برچسبهای توییتر (با Nitter)
+ برگزیدهشده توسط
+ مثال: محتوای حساس
+ هرزنامه است
+ به فدیورس بپیوندید
+ نوع نظرسنجی:
+ بهکارگیری توکن
+ تازهترین
+ دامنه
+ آیا میخواهید بدون ذخیره تصویر خارج شوید؟
+ اینجا بزنید تا نظرسنجی تازه شود
+ پاسخ
+ مدیریت حسابها
+ نوشتن
+ اگر توصیفی برای رسانه وجود نداشته باشد، بوق فرستاده نمیشود
+ آخرین ۲۴ ساعت
+ رنگ برجسته تیره
+ دامنههای بستهشده
+ بهروزرسانی جدید
+ توکن شما
+ کاربری گزارشی فرستاد
+ نمایه بهروزرسانی شد!
+ زمانبندیشده
+ پالایه
+ گزینههای نمایش
+ دریافت آگاهسازیها
+ گزارشی فرستاد
+ مترجم
+ بهکاربردن نما جایگزین برای اینستاگرام
+ تغییر دیدپذیری
+ تنظیم زبان
+ پیوست تصاویر
+ پیوست پروندهها
+ افزودن نظرسنجی
+ حساب غیرفعال شد
+ حساب از بیصدا خارج شد
+ لغو دنبال کردن برچسب
+ برچسب موردنظر برای دنبال کردن را بنویسید
+ ویرایش فهرست
+ افزودن کلیدواژه
+ نمایش نمایه از نمونه میزبان
+ پاک کردن خط زمانی
+ باز کردن دامنه
+ مرتبسازی فهرستها
+ شدت
+ بیصدا کردن پستهای حساب را برای کسانی که آن را دنبال نمیکنند نامرئی میکند. تعلیق همه محتوای حساب، رسانهها و دادههای نمایه را حذف میکند. اگر فقط میخواهید پروندههای رسانهای را رد کنید، هیچکدام را انتخاب کنید.
+ آیا مطمئنید که میخواهید برچسب %1$s را بیصدا کنید؟
+ انتخاب یک حالت برای پوسته
+ امکان سفارشیسازی برخی عناصر در بوقها برای پوسته تیره.
+ لطفاً بعداً دوباره تلاش کنید.
+ لغو بیصدا کردن برچسب
+ گروهبندی تقویتها در خط زمانی خانه
+ دیدپذیری نمادها
+ دیدپذیری پاسخ
+ برنامه گفتوگوهای عمومی را برای دریافت همه بوقها نمایش میدهد. کنشها نیاز به گام اضافی برای فدراسیون بوقها دارند.
+ هنگام انتشار نسخه جدید، در برنامه آگاهسازی نمیشوید.
+ پالایش زبانها
+ ترجمه به
+ اشارهها در بالا
+ شمار پاسخها
+ تاریخ بهروزرسانی
+ توصیفهای رسانهای وجود ندارند
+ کوتاه کردن پیوندها
+ فقط هشدار
+ هیچ بوق نهانشدهای در خانه نیست!
+ %1$d بوق نهانشده
+ دریافت بوقها
+ افزودن توصیف
+ انتخاب مسیرها
+ رنگ برجسته سفارشی
+ درخواست دنبال کردن شما را داده است
+ توییتر
+ اینستاگرام
+ دامنه نمای اینستاگرام
+ فقط دنبالکنندگان
+ ارسال بوق %d/%d
+ فعال است!
+ غیرفعال است!
+ بررسیشده در: %s
+ توقف ضبط
+ گزارش %1$s
+ بگویید مشکل این بوق چیست
+ اینجا گزینههای شما برای کنترل آنچه در Mastodon میبینید:
+ لغو دنبال کردن %1$s
+ آیا بوقهایی برای پشتیبانی از این گزارش وجود دارند؟
+ همه موارد مرتبط را انتخاب کنید
+ حساب از سرور دیگری است. آیا نسخهای ناشناس از گزارش را آنجا هم بفرستیم؟
+ سلام! شما را به پیوستن به فدیورس دعوت میکنیم.
+ «Mastodon یک وبسایت واحد مثل Twitter یا Facebook نیست، شبکهای از هزاران جامعه است که توسط سازمانها و افراد مختلف اداره میشوند و تجربهای یکپارچه از رسانههای اجتماعی ارائه میدهند.»
+ نامبردنها
+ پسندها
+ تقویتها
+ نتایج نظرسنجی
+ دنبال کردنها
+ علامتگذاری همه آگاهسازیها بهعنوان خواندهشده
+ نمایش همه دستهها
+ بازشده
+ قفلشده
+ ذخیره تغییرات
+ حساب ربات
+ حساب قابلکشف
+ آیا مطمئنید که میخواهید این بخش را پاک کنید؟
+ نمایش
+ منوی پایین
+ بهکارگیری زبان پیشفرض سیستم
+ زبان بوقها
+ برنامه نتوانست حساب را تصدیق کند!
+ گشودن پیشنویس
+ غیرفعال کردن پیمایش نوار بالا
+ پنهانسازی خودکار دکمه نوشتن
+ خطهای زمانی در فهرست
+ نمایش تاریخ نسبی برای بوقها
+ نمایش رسانه
+ نمایش خطهای زمانی
+ بوق نهانشده
+ هنگام فعال بودن، برنامه آگاهسازیهای مرتبط را جمع میکند
+ وضعیت ورود
+ هشدار
+ بهکاربردن نما جایگزین برای توییتر
+ بهکاربردن نما جایگزین برای ردیت
+ رسانه در آگاهسازیها برای تقویتها و پسندها نمایش داده میشود
+ لغو اختصاص
+ آیا مطمئنید که میخواهید %1$s را باز کنید؟
+ سیاست حریم خصوصی
+ برنامه من
+ توزیعکننده فشار
+ گزینههای بیشتر
+ برگزیدن
+ تقویت
+ نقل
+ هشدار در صورت نبود توصیف رسانه پیش از تقویت
+ این بوق توصیف رسانه ندارد. آیا مطمئنید که میخواهید آن را تقویت کنید؟
+ افزودن هشدار محتوا
+ پاککردن هشدار محتوا
+ انتشار
+ گشودن بخش پیوست جدید
+ بستن بخش پیوست جدید
+ پیوست صدا
+ پیوست ویدیوها
+ توکن نمیتواند خالی باشد!
+ نامنویسی جدید
+ گزارش جدید
+ افزودن وضعیت
+ همچنین تقویتشده توسط:
+ لغو دنبال کردن برچسب
+ بوق از نشانکهای شما پاک شد!
+ انتخاب پوستهای که توسط مشارکتکنندگان ساخته شده است
+ پذیرفتهشده
+ منشأ حساب گزارششده
+ مستطیل
+ بوقهای نهانشده برای دیگر خطهای زمانی
+ آیا مطمئنید که میخواهید حافظه نهان را پاک کنید؟ اگر پیشنویسهایی با رسانه دارید، رسانههای پیوست از دست میروند.
+ تغییر لوگوی برنامه در دستگاه شما
+ سنجاق بوق
+ پاسخهای فهرستنشده
+ آگاهسازیها از حافظه نهان پاک شدند.
+ بوقهای گزارششده
+ بیصدا
+ حساب رد شد
+ بوقی را ویرایش کرد
+ عنوان
+ آیا مطمئنید که میخواهید آن خط زمانی را از سنجاق بردارید؟
+ خطهای زمانی سنجاقشده پاک شوند؟
+ دیدگاه درباره این محدودیت دامنه برای عموم، اگر نمایش فهرست محدودیتهای دامنه فعال باشد.
+ این بوق به پاسخها تقسیم شود؟
+ تقسیم نشود
+ تقسیم بوق
+ بوق به چندین پاسخ تقسیم میشود تا با بیشینه نویسههای نمونه شما سازگار باشد.
+ پوسته روشن پیشفرض
+ سفارشیسازی پوسته روشن
+ روشن - رنگهای سفارشی
+ گفتوگو در نمونهی شما آغاز شد!
+ لغو سنجاق برچسب
+ همه را بیصدا کن
+ وارد کردن دادهها
+ مترجم
+ کلید رابط مترجم
+ نسخه
+ نسخه مترجم
+ با فعال کردن این گزینه، برنامه ویژگیهای اضافی را نمایش میدهد. این ویژگی برای نرمافزارهای اجتماعی مانند پلروما، آکوما یا گلیچ سوشال طراحی شده است
+ میتوانید این نمادها را در پایین پنهان کنید تا فضای بیشتری داشته باشید. آنها در زیرمنو نیز هستند.
+ گفتوگوهای نمونه میزبان
+ دکمههای پایین بوقها کل عرض را اشغال نمیکنند
+ پیرتیوب شما بیش از حد قدیمی است و برنامه از آن پشتیبانی نمیکند.
+ توکن ورود دو مرحلهای
+ دریافت خودکار بوقهای خانه
+ دریافت خودکار بوقهای گمشده
+ برچسب تغییر کرد!
+ برچسب پاک شد!
+ مدیریت برچسبها
+ خط زمانی گفتوگو برای بوقهای مستقیم
+ بیشینه نویسهها در پیوندها
+ بازیابی حساب دور!
+ رنگ برجسته روشن
+ ردیت
+ دادههای نمونه
+ نمونه لمی
+ رونویسی دادهها
+ کاربری نامنویسی کرد
+ نامنویسیها
+ دامنه نمای توییتر
+ تولیدکننده کد QR
+ شبکه
+ ضمیر
+ پشتیبانی ضمیر
+ پاککردن وضعیت
+ تقویتشده توسط
+ دیگر
+ در حال ارسال بوق…
+ زمان فعال: %,.2f %%
+
+ ]]>
+ بهترین گزینه را انتخاب کنید
+ خوشم نمیآید
+ چیزی نیست که بخواهید ببینید
+ آیا چیز دیگری هست که باید بدانیم؟
+ دیدگاههای اضافی
+ گزارش فرستاده شد!
+ حساب ندارید؟
+ تعاملات
+ افزودن پالایه
+ افزودن بخش
+ کارکنان
+ حالت پاککن
+ اعلان · %1$s - %2$s
+ پاک کردن حافظه نهان
+ اندازه حافظه نهان پرونده
+ تأخیر بین هر دریافت جدید را تنظیم کنید
+ دریافت آگاهسازیها هر:
+ حذف حاشیه چپ
+ قالب بوق
+ دریافت خانه هر
+ تعریف رنگ پوسته برای هر حساب
+ بندانگشتی
+ اجازه دادن
+ هشدار سفارشی
+ نامنویسی کرد
+ نادیده گرفتن همه گزارشها از این دامنه. برای تعلیقها بیربط است
+ بهکارگیری حافظه نهان
+ خطهای زمانی نهان میشوند تا برنامه سریعتر باشد.
+ بارگیری بندانگشتیها برای رسانه
+ پاک کردن کلیدواژه
+ بیصدا برای خانه
+ بارگیری تنظیمات صادرشده
+ رد گزارشها
+ دامنه مترجم
+ پوستههای مشارکتکنندگان
+ پنهان کردن محتوای پالایششده پشت هشداری با ذکر عنوان پالایه
+ خانه و فهرستها
+ برنامه نتوانست دادههای نمونه میزبان را پیدا کند!
+ خط زیر موارد قابل کلیک
+ بوقی که همرسانی کردید ویرایش شده است
+ نوع آگاهسازیها را انتخاب کنید
+ من مدیر هستم
+ شکل
+ حساب فعال شد
+ پنهانسازی خودکار دکمه نوشتن هنگام پیمایش به بالا در خط زمانی
+ نمایش رسانه در آگاهسازیها
+ فقط پاسخهای «عمومی» را شامل میشود. هنگام فعال بودن، پاسخهای شما خودکار «فهرستنشده» میشوند بهجای «عمومی»
+ آگاهسازی کاربر از طریق رایانامه
+ گزارشهای حافظه نهان خانه
+ ناکامیها
+ تکرار (دقیقه)
+ خروج
+ هنگام فعال بودن، همه خطهای زمانی سنجاقشده در منوی کشویی نمایش داده میشوند
+ نمایش شمارشگر برای بوقها
+ کاربر
+ پاکسازی حافظه نهان
+ لغو سنجاق بوق
+ لغو دنبال کردن
+ سفارشیسازی پوسته تیره
+ نوشتن فرمول
+ قالب ریاضی
+ پنهان کردن رسانه تکی هنگام وجود پیشنمایش پیوند
+ تغییر زبانهای اشتراکشده
+ امکان ایجاد پوسته سفارشی
+ "همچنین برگزیدهشده توسط: "
+ پیشینه بوق
+ خود
+ بررسی حافظه نهان خانه
+ آخرین فعالیت
+ مکان
+ خط
+ نمایش دکمههای «واکنشها»
+ وضعیت رایانامه
+ شمارشگر حبابی برای بوقهای جدید در زبانههای خط زمانی نمایش میدهد
+ تنظیمات صادر شدند
+ تنظیمات با موفقیت صادر شدند
+ تنظیمات با موفقیت وارد شدند
+ پاک کردن بخش
+ پذیرفتن
+ نمایش تقویتهای خود
+ بوق به نشانکهای شما افزوده شد!
+ شمار حسابها در هر بارگذاری
+ بهکاربردن نما جایگزین برای یوتیوب
+ آیا مطمئنید که میخواهید همه آگاهسازیها را پاک کنید؟ این کار قابل بازگشت نیست.
+ دنبال کردن برچسب
+ گزارشی فرستاد
+ دیدگاه خصوصی
+ دیدگاه درباره این محدودیت دامنه برای استفاده داخلی مدیران.
+ بوقهای ذخیرهشده در پیشنویسها
+ کنشهای بیشتر
+ وضعیت
+ بوقهای نهانشده برای خانه
+ بهروزرسانیها
+ همیشه دکمه نشانهگذاری را نمایش بده
+ دریافت بوقهای بیشتر…
+ بیضی
+ انتخاب لوگو
+ بازآغاز
+ سوابق حافظه نهان خانه در هر ساعت
+ خودکار
+ دادهها در بریدهدان رونویسی شدند
+ نمایش پاسخهای خود
+ نمایش بوقهای من
+ چندگزینهای
+ شما هماکنون این برچسب را دنبال میکنید!
+ دیدپذیری پیشفرض بوقها:
+ ارتباط اینترنتی وجود ندارد!
+ شمار آگاهسازیها در هر بارگذاری
+ پروتکل
+ موسیقی
+ این بخش نمیتواند خالی باشد!
+ جدید
+ دامنه نمای ردیت
+ ادامه
+ نسخه: %s\n%s کاربر - %s بوق
+ مشکل در دستههای دیگر جای نمیگیرد
+ شما این حساب را دنبال میکنید. برای ندیدن بوقهایشان در خوراک خانه، آنها را لغو دنبال کنید.
+ بیصدا کردن %1$s
+ بوقهایشان را نخواهید دید. آنها نمیتوانند بوقهایتان را ببینند یا شما را دنبال کنند. متوجه خواهند شد که بسته شدهاند.
+ کدام قوانین نقض شدهاند؟
+ ارسال به %1$s
+ بهروزرسانیهای افراد
+ حلشده
+ نمایش شمارشگرها
+ اختصاص به من
+ خط زمانی سنجاقشده پاک شود؟
+ دامنهها
+ به هر حال بفرست
+ %d بوق دریافتشده
+ یوتیوب
+ رسانه تمامصفحه
+ رسانهها کل عرض صفحه را میگیرند و نسبت ابعاد برای ارتفاع رعایت میشود.
+ HTTP
+ SOCKS
+ دامنه نما یوتیوب
+ سفارشی
+ نمونه به نظر درست نمیآید!
+ پیوندهای مخرب، تعامل جعلی، یا پاسخهای تکراری
+ قوانین کارساز را نقض میکند
+ میدانید که قوانین خاصی را نقض میکند
+ چیز دیگری است
+ نمیخواهید این را ببینید؟
+ بوقهایشان را نخواهید دید. آنها همچنان میتوانند شما را دنبال کنند و بوقهایتان را ببینند و نمیدانند که بیصدا شدهاند.
+ بستن %1$s
+ «PeerTube ابزاری برای همرسانی ویدیوهای آنلاین است که توسط Framasoft، یک سازمان غیرانتفاعی فرانسوی، توسعه یافته است... PeerTube به سکوها اجازه میدهد به یکدیگر متصل شوند و شبکهای بزرگ از سکوهای خودمختار و بههمپیوسته ایجاد کنند.»
+ پاک کردن همه آگاهسازیها
+ نام فهرست درست نیست!
+ هیچ حسابی برای این فهرست یافت نشد!
+ انواع آگاهسازیهای قابلنمایش
+ تأیید لغو دنبال کردنها
+ بوق فرستاده شد!
+ تکگزینهای
+ مدت نظرسنجی:
+ همیشه دکمه ترجمه را نمایش بده
+ تغییر لوگو
+ بوق دیگر سنجاق نیست!
+ نگهداری آگاهسازیها
+ آگاهسازی برای بهروزرسانیها
+ نوع آگاهسازیها
+ نمونه من
+ حساب من
+ ویرایش بوق
+ %1$s ویرایش کرد %2$s
+ ویرایششده در %1$s
+ ایجادشده در %1$s
+ پیوسته
+ آیپی اخیر
+ مدیر
+ مدیر
+ پذیرفتهشده
+ حساب بیصدا شد
+ وضعیت
+ زبانهای انتخابگر
+ آیا مطمئنید که میخواهید این برچسب را لغو دنبال کنید؟
+ نام برچسب درست نیست!
+ برچسبهای دنبالشده
+ دنبال کردن برچسب
+ نمایهها
+ پنهان کردن کامل محتوای پالایششده، مانند اینکه وجود نداشته باشد
+ کلیدواژه یا عبارت
+ علاقهمند نیستم
+ شما هیچ دامنهای را نبستهاید
+ امکان تنظیم رنگهای سفارشی برای پوستهها.
+ هنگام فعال بودن، موارد در خطهای زمانی سایه و برجستگی خواهند داشت.
+ امکان سفارشیسازی برخی عناصر در بوقها برای پوسته روشن.
+ تنظیم رنگهای سفارشی
+ تیره - رنگهای سفارشی
+ نمایش گفتوگو از نمونه میزبان
+ برنامه بوق را در نمونه میزبان پیدا نکرد.
+ بیصدا کردن برچسب
+ قالب بوق
+ نمادهای ویژگیهای اضافی
+ فقط محلی
+ دنبالشده توسط:
+ دریافت بوقهای خانه
+ برچسب ذخیره شد!
+ رنگی که برای پوسته روشن اعمال میشود
+ صداهای آگاهسازی
+ غیرفعال کردن آگاهسازیها
+ در این بازه زمانی
+ پایه پوسته
+ انتخاب کنید که پایه پوسته تیره باشد یا روشن
+ سفارشیسازی خطهای زمانی
+ انتخاب پوسته
+ منوی نوار بالا
+ حداکثر تعداد نویسهها را تنظیم کنید
+ یادداشتهای انتشار
+ برنامه نتوانست توکن دریافت کند
+ رسانه بارگذاری نشد!
+ زمان دریافت آگاهسازیها
+ صدور تنظیمات
+ وارد کردن تنظیمات
+ اجازه داده نشد!
+ نوار کنش تکی
+ هنگام فعال بودن، برنامه فقط یک نوار برای خطهای زمانی خواهد داشت
+ گشودن بوق اصلی
+ پذیرفتهنشده
+ بهخاطر سپردن جایگاه در خطهای زمانی
+ تجمیع آگاهسازیها
+ ترجمه بوقها
+ بوق سنجاق شد
+ سنجاقشده
+ تصویر کارت
+ اجبار ترجمه به زبانی خاص. اولین مقدار را انتخاب کنید تا به تنظیمات دستگاه بازگردد
+ حداکثر تورفتگی در نخها
+ علامتگذاری بهعنوان حلنشده
+ علامتگذاری بهعنوان حلشده
+ حساب پذیرفته شد
+ حساب هشدار گرفت
+ حساب از تعلیق خارج شد
+ حساب معلق شد
+ برنامه بازآغاز شود؟
+ برای اعمال تغییرات باید برنامه را بازآغاز کنید.
+ امکان کاهش فهرست زبانها در انتخابگر هنگام نوشتن بوق.
+ شما هیچ برچسبی را دنبال نمیکنید!
+ نمونهی شما از این ویژگی پشتیبانی نمیکند!
+ پیگیری روندها برای این نمونه
+ کارکرد پالایه
+ انتخاب کنید چه کارکردی هنگام تطبیق بوق با پالایه انجام شود
+ پنهان با هشدار
+ پنهان کامل
+ نمایش به هر حال
+ پالایششده: %1$s
+ برنامه نتوانست حساب را به فهرست بیفزاید!
+ پیشنهادها
+ نامنویسی جدید (مدیران)
+ گزارش جدید (مدیران)
+ گشودن با حساب دیگر
+ رد رسانه
+ بستن دامنه مانع ایجاد ورودیهای حساب در پایگاه داده نمیشود، اما روشهای نظارتی خاصی را بهصورت خودکار و گذشتهنگر بر آن حسابها اعمال میکند.
+ رد پروندههای رسانهای
+ رد گزارشها
+ نادیده گرفتن همه گزارشها از این دامنه. برای تعلیقها بیربط است
+ پنهانسازی نام دامنه
+ پنهانسازی جزئی نام دامنه در فهرست، اگر نمایش فهرست محدودیتهای دامنه فعال باشد
+ دیدگاه عمومی
+ تغییرات ذخیره شدند!
+ ایجاد بستن دامنه
+ تقسیم بوقهای طولانی به پاسخها
+ سفارشیسازی رنگها
+ رنگ پویا
+ هماهنگی رنگی با طرح رنگ کاغذدیواری شخصی شما.
+ پوسته تیره پیشفرض
+ کارتهای برجسته
+ سنجاق برچسب
+ لغو بیصدا برای خانه
+ افزودن همه کاربران به خانه بیصدا
+ همه حسابها برای خط زمانی خانه بیصدا خواهند شد.
+ حذف حاشیه چپ در خطهای زمانی برای فشردهتر کردن بوقها
+ ویژگیهای اضافی
+ اگر نمونهی شما برخی ویژگیهای اضافی را نمیپذیرد، میتوانید این نمادها را پنهان کنید
+ نمایش دکمهی «نقل»
+ حباب
+ حذف دیدپذیری
+ فهرست
+ دنبالشوندگان
+ نمایههای نمونه میزبان
+ برنامه نمایههای عمومی را برای دریافت همه بوقها نمایش میدهد. کنشها نیاز به گام اضافی برای فدراسیون بوقها دارند.
+ نمایش دکمهی «فقط محلی»
+ نمایش پیکسلفد برای رسانه
+ دکمههای کنش فشرده
+ راهنما
+ نمایش تاریخ اصلی برای تقویتها
+ نمایش نوار پیمایش برای خطهای زمانی
+ پشتیبانی از مارکداون
+ غیرفعال کردن یادداشتهای انتشار
+ فرمول
+ زمان دریافت خانه
+ حافظه نهان خانه
+ هنگام پاسخ، همه اشارهها به ابتدای بوق افزوده میشوند
+ شمار رسانهها
+ %1$s رسانه دیگر
+ توصیفهای اجباری رسانه
+ اگر رسانهای بدون توصیف باشد، گفتوگویی نمایش داده میشود با امکان فرستادن بوق بدون توصیف رسانه
+ نادیده گرفتن بهینهسازی باتری
+ پخش خودکار رسانههای متحرک
+ بوقهای جدید
+ بوقهای بهروزرسانیشده
+ مجموع بوقهای دریافتشده
+ %d ناکامی
+ %d بوق جدید
+ %d بوق بهروزرسانیشده
+ %d تکرار (دقیقه)
+ شما را دنبال میکند
+ بارگیری رسانه از نمونه میزبان
+ رسانه بارگیری نشد!
+ دریافت خودکار رسانههای نمونه میزبان هنگام در دسترس نبودن
+ رنگی که برای پوسته تیره اعمال میشود
+
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index b0e0f87d65fd08c0faa161067b6e8d3144b56d40..93340f4d1bcd1fcae1fbe289523db4eb79c7b7e6 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -1074,4 +1074,26 @@
Etiquetas de Twitter (con Nitter)
Multimedia a pantalla completa
O multimedia ocupará todo o ancho da pantalla e vanse respetar as proporcións de aspecto.
+ Promover
+ Engadir aviso sobre o contido
+ Cambiar a visibilidade
+ Establecer idioma
+ Publicar
+ Abrir o panel de novo anexo
+ Pechar o panel de novo anexo
+ Anexar audio
+ Anexar vídeos
+ Anexar ficheiros
+ Anexar unha enquisa
+ Favorecer
+ Anexar imaxes
+ Máis opcións
+ Citar
+ Retirar aviso sobre o contido
+ Información da instancia
+ Oculta o botón para redactar
+ Rede
+ Oculta automáticamente o botón para redactar cando te desprazas nunha cronoloxía
+ Mencionar a quen promoveu
+ Ao responder a unha promoción, a persoa que promoveu será mencionada na resposta
diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml
index a8dcdb39cb4fe8a3fd4b5e7010fb9dbc02f97643..3cf53ba0f3d2733125f25ee065a948f6bd1bbe80 100644
--- a/app/src/main/res/values-kab/strings.xml
+++ b/app/src/main/res/values-kab/strings.xml
@@ -45,7 +45,7 @@
Ibdaren
Izuzar
Sken-d izuzar
- Ssekned tiririt
+ Sken-d tiririyin
Ldi deg iminig
Suqel
@@ -63,12 +63,12 @@
The app did not collect custom emojis for the moment.
Are you sure you want to logout @%1$s@%2$s?
- Ulac ituten ara d-nesken
+ Ulac iznan ara d-nesken
Add this toot to your favourites?
Remove this toot from your favourites?
Boost this toot?
Unboost this toot?
- Susem
+ Sgugem
Seḥbes
Cetki
Kkes
@@ -225,7 +225,7 @@
Ḍfeṛ
Serreḥ
- Susem
+ Sgugem
Unmute
Request sent
Yeṭafar-ik id
@@ -243,9 +243,9 @@
Awalen n tsaruţ…
Azayez
- Unlisted
+ War abdar
Uslig
- Direct
+ Srid
Filter out by regular expressions
Nadi
@@ -324,7 +324,7 @@
Sken ddeqs
Sken kra kan
The tag already exists!
- Schedule boost
+ Sɣiwes azuzer
The boost is scheduled!
No scheduled boost to display!
Ldi umuɣ
@@ -466,7 +466,7 @@
Suspend
Undo suspend
The application needs to access audio recording
- Voice message
+ Izen s taɣect
During the time slot, the app will send notifications. You can reverse (ie: silent) this time slot with the right spinner.
Previews will not be cropped in timelines
Automatically insert a line break after the mention to capitalize the first letter
@@ -643,4 +643,9 @@
Iɣewwaṛen n uketer
Ɛebbi iɣewwaṛen yettwasifḍen
Kter isefka
+ Talɣut ɣef uqeddac
+ Timyigawin
+ Akaram
+ Aqeddac-iw
+ Imeḍfaṛen kan
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 93f00f9a2cff0b6425f5e25057072c93e71a6557..53f242153c76467b9934c5d5b41949e281e92b62 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -276,7 +276,7 @@
Порт
Имя пользователя
Пароль
- Добавлять детали сообщения при перепосте
+ Добавлять детали сообщения при перепубликации
Поддержать приложение на Liberapay
В регулярном выражении есть ошибка!
На этом инстансе лент не найдено!
@@ -682,7 +682,7 @@
Отслеживаемые теги
Подписаться на тег
Другое
- Показать содержимое >
+ ]]>
Присоединяйтесь к fediverse
Привет! Приглашаем Вас присоединиться к Fediverse.
Проблема не подпадает под другие категории
@@ -693,13 +693,13 @@
Запоминать позицию на ленте
Будут отображаться медиа в уведомлениях для репостов и избранного
Версия
- Скрыть содержимое <
+
Пожаловаться на %1$s
Это НЕ то что вы бы хотели видеть
Использовать кэш
Это спам
Вредоносные ссылки, повторяющиеся ответы
- «Mastodon — это не один веб-сайт, такой как Twitter или Facebook, это сеть из тысяч сообществ, управляемых различными организациями и частными лицами, которые обеспечивают бесперебойную работу в социальных сетях».
+ «Mastodon — это не один вебсайт как Twitter или Facebook, это сеть из тысяч сообществ, управляемых различными организациями и частными лицами, которые вместе обеспечивают безбарьерную социальную сеть».
Измените логотип приложения на вашем устройстве
Перезапустить приложение\?
Вы должны перезапустить приложение, чтобы применить изменения.
@@ -906,4 +906,132 @@
Миниатюра
Определите цвет темы для каждой учетной записи
Выберите действие, которое нужно выполнить, когда сообщение соответствует фильтру
+ Состояние
+ Языки на выбор
+ Редактировать список
+ Главная и ленты
+ Добавить ключевое слово
+ Отобразить удалённый профиль
+ Домены
+ Личный комментарий
+ Вы уверены что хотите игнорировать тег %1$s?
+ Раздробить длинные сообщения в ответах?
+ Позволяет установить свои собственные цвета для тем оформления.
+ Динамические цвета
+ Частично запутать доменное имя в списке, если включён список ограничений домена
+ Теги Твиттера (через Nitter)
+ Ваш токен
+ Токен не может быть пустым!
+ Удалить хронологическую ленту
+ Выравнивать тонально с цветовой гаммой ваших личных обоев.
+ Настроить свои цвета
+ Заблокированные домены
+ Позволяет сократить список языков при составлении сообщения.
+ Больше настроек
+ Повысить
+ Добавить предупреждение о содержимом
+ Закрыть новую панель вложения
+ Открыть новую панель вложения
+ Прикрепить аудио
+ Прикрепить видео
+ Прикрепить файлы
+ Добавить опрос
+ Используйте токен
+ Приложение не смогло аутентифицировать профиль!
+ Ключевое слово или фраза
+ У вас нет заблокированных доменов
+ Разблокировать домен
+ Удалить прикреплённую хронологическую ленту?
+ Не разделять
+ Разделять сообщение
+ Игнорировать для домашней ленты
+ Начался разговор на вашем сервере!
+ Подчеркните кликабельные элементы
+ %d полученных сообщений
+ %d новых сообщений
+ %d обновленных сообщений
+ Название
+ Информация о сервере
+ Не интересует
+ Вы уверены что хотите разблокировать %1$s?
+ Публичный комментарий
+ Изменения были сохранены!
+ Светлая тема - Свои цвета
+ Пожалуйста, попробуйте ещё раз позже.
+ Кеш домашней ленты
+ Сообщение не будет отправлено если отсутствует описание для медиа
+ Отсутствуют описания медиа
+ Обрезать ссылки
+ Новая регистрация (модераторы)
+ Разделять длинные сообщения в ответах
+ Если включено, то элементы в ленте будут иметь тень и приподняты.
+ Настроить светлую тему оформления
+ Не игнорировать тег
+ Формат сообщения
+ Отключить примечания к выпуску
+ Получать домашнюю ленту каждые
+ Получение сообщений
+ %d частота (минуты)
+ Медиафайлы не могут быть загружены!
+ Зарегистрировался
+ Сеть
+ Прокомментируйте почему этот домен ограничен для публичного использования, если список одобренных доменов включён.
+ отправил жалобу
+ Приподнятые карточки
+ Приложение не обнаружило удалённое сообщение.
+ Цитировать
+ Убрать предупреждение о содержимом
+ Опубликовать
+ Медиа будут принимать всю ширину экрана, и соотношение сторон для высоты будет соблюдаться.
+ Установить язык
+ Прикрепить изображения
+ Избранное
+ Изменить видимость
+ Речь идет только о «публичных» ответах. Если включено, то ваши ответы будут автоматически иметь видимость «не в ленте» вместо «публичные»
+ Политика конфиденциальности
+ Настроить цвета
+ Тёмная тема - Свои цвета
+ Отображать удалённый разговор
+ Составить
+ Автоматически получать сообщения из домашней ленты
+ Выберите режим для темы
+ Изменил сообщение
+ Действие фильтра
+ Вы уверены что хотите открепить хронологическую ленту?
+ Формула
+ Фильтр языков
+ Математический формат
+ Переводить на
+ Написать формулу
+ Удалить ключевое слово
+ Всё равно показать
+ Следить за обсуждаемым на этом сервере
+ Жалоба отправлена
+ Только предупреждать
+ Читает вас
+ Загрузить медиа удалённо
+ Прикрепить тег
+ Подключение к Интернету отсутствует!
+ Отфильтровано: %1$s
+ Полноэкранное медиа
+ В читаемых у:
+ Позволяет настраивать некоторые элементы в сообщениях для тёмной темы.
+ Настроить тёмную тему оформления
+ Позволяет настраивать некоторые элементы в сообщениях для светлой темы.
+ Установить формат сообщения
+ Значки для дополнительных возможностей
+ Токен двухэтапной аутентификации
+ Удалить прикреплённые хронологические ленты?
+ Оставить уведомления
+ Прокомментируйте почему этот домен ограничен для внутреннего использования модераторами.
+ Игнорировать тег
+ Открепить тег
+ Не следить за тегом
+ Не игнорировать для домашней
+ Игнорировать их все
+ Управление профилями
+ Приложение не может найти удаленные данные!
+ Новый отчёт (модераторы)
+ Открыть из другой учётной записи
+ Припрятывать кнопку Составить
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 3f0365b9ec3ec6b4b37aef75e05042297b968f10..e979ca433f4ea5d9822d9ef1b6d15ec935f26d2e 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -1088,4 +1088,26 @@
Теги Twitter (через Ritter)
Повноекранний медіафайл
Медіафайли займатимуть всю ширину екрана, а співвідношення сторін по висоті буде дотримано.
+ Підвищення
+ Вилучити попередження про вміст
+ Встановити мову
+ Відкрити нову панель вкладень
+ Додайте зображення
+ Прикріпіть аудіо
+ Прикріпіть відео
+ Змінити видимість
+ Опублікувати
+ Цитата
+ Закрийте нову панель вкладень
+ Прикріпити файли
+ Додайте попередження про вміст
+ Додайте опитування
+ Більше варіантів
+ Улюблений
+ Мережа
+ Інформація про примірник
+ Автоматично приховати кнопку створення
+ Автоматично приховувати кнопку створення під час прокручування вгору на часовій шкалі
+ Під час відповіді на посилення особа, яка здійснила посилення, буде згадана у відповіді
+ Згадайте бустер
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 85512e9e0f4b4b0936944412fdb9febdff5c2a32..ce664e62e8da7f6f95c7f4be388bfb41f61dda4f 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -1076,4 +1076,26 @@
Twitter 标签(通过 Nitter)
全屏媒体
媒体文件会占据整个屏幕宽度,会保持高度的长宽比。
+ 更多选项
+ 喜欢
+ 转发
+ 引用
+ 移除内容警告
+ 设置语言
+ 发布
+ 打开新附件面板
+ 附加图像
+ 附加音频
+ 附加视频
+ 发起投票
+ 添加内容警告
+ 关闭新附件面板
+ 修改可见性
+ 实例信息
+ 附加文件
+ 网络
+ 向上滚动时间轴时自动隐藏编辑按钮
+ 自动隐藏编辑按钮
+ 回复转嘟时,会在回复中提及转发嘟文的人
+ 提及转发嘟文者
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 36f21d294b70166071b925456a356e4ccceeb5a4..2766016da7b4948e3137d19c4868e445246c4a31 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -57,6 +57,7 @@
Show direct messages
Open in browser
Translate
+ More options
Home
Local timeline
@@ -77,6 +78,9 @@
Add this message to your favourites?
Remove this message from your favourites?
Boost this message?
+ Favorite
+ Boost
+ Quote
Warn if message has no media description before boosting
This message has missing media description. Are you sure to boost it?
Unboost this message?
@@ -110,6 +114,21 @@
Remove bookmark
Status has been added to bookmarks!
Status was removed from bookmarks!
+
+
+ Add content warning
+ Remove content warning
+ Change visibility
+ Set language
+ Publish
+ Open new attachment panel
+ Close new attachment panel
+ Attach images
+ Attach audio
+ Attach videos
+ Attach files
+ Add a poll
+
%d s
%d m
@@ -350,6 +369,7 @@
Peertube instance
Use Emoji One
Information
+ Instance information
Display previews in all messages
The account id has been copied in the clipboard!
Change the language
@@ -608,6 +628,7 @@
Export the theme
Tap here to export the current theme
An error occurred when selecting the theme file
+ Network
User count
Status count
Instance count
@@ -1111,6 +1132,7 @@
SET_UNFOLLOW_VALIDATION
SET_USE_SINGLE_TOPBAR
SET_DISABLE_TOPBAR_SCROLLING
+ SET_AUTO_HIDE_COMPOSE
SET_DISPLAY_COUNTERS
SET_DISPLAY_COMPACT_ACTION_BUTTON
@@ -1126,7 +1148,7 @@
SET_DISABLE_ANIMATED_EMOJI
SET_CAPITALIZE
SET_MENTIONS_AT_TOP
-
+ SET_MENTION_BOOSTER
SET_THREAD_MESSAGE
SET_THEME_BASE
SET_DYNAMICCOLOR
@@ -1773,10 +1795,13 @@
pref_category_key_pixelfed
pref_category_key_home_cache
pref_category_theming
+ pref_category_network
pref_category_administration
pref_category_languages
pref_category_key_extra_features
+ pref_key_proxy
+
pref_export_settings
pref_import_settings
Export settings
@@ -1786,6 +1811,8 @@
Push distributor
Single action bar
Disable top bar scrolling
+ Auto hide compose button
+ Automatically hide compose button when scrolling up on a timeline
When enabled, the app will only have a single bar for timelines
Timelines in a list
When enabled, all pinned timelines will be displayed in a drop-down menu
@@ -2033,6 +2060,8 @@
Mentions at the top
When replying mentions will all be added to the beginning of the message
+ Mention the booster
+ When replying to a boost, the person who boosted will be mentioned in the reply
Number of media
Number of replies
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index e69af45c371f7332ec9e06e29ad0a172669c63cb..889e6d3ef8dd1aedbf28b224c22e47cac8d370ab 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -273,5 +273,8 @@
- 0dp
+
diff --git a/app/src/main/res/xml/pref_categories.xml b/app/src/main/res/xml/pref_categories.xml
index cd88e770e45294d5ce695564a0aa1d9d8423f480..70dc57807f4e278052cdc37289af1a5fd2771b30 100644
--- a/app/src/main/res/xml/pref_categories.xml
+++ b/app/src/main/res/xml/pref_categories.xml
@@ -67,6 +67,13 @@
app:icon="@drawable/ic_theming"
app:key="@string/pref_category_key_theming" />
+
+