mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2025-07-23 12:00:31 +03:00
Compare commits
108 commits
Author | SHA1 | Date | |
---|---|---|---|
|
cf022002c5 | ||
|
4b4b6c49b2 | ||
|
49cc9a187e | ||
|
b954708e3a | ||
|
0fcd1c6d4b | ||
|
1c2c6f404a | ||
|
2e33cd58f5 | ||
|
c5e096728e | ||
|
b0c11f5c2c | ||
|
c0b6bbd4ea | ||
|
442e27760a | ||
|
d514c7b8d6 | ||
|
5b843291a7 | ||
|
8a9b0d897f | ||
|
e051bec7a0 | ||
|
6a74a35efe | ||
|
723771e464 | ||
|
b1b3c5230c | ||
|
764e3a1762 | ||
|
a71fa29f72 | ||
|
cb2c811970 | ||
|
bc81e32720 | ||
|
a79121a8dd | ||
|
293a811392 | ||
|
1df2cba3d0 | ||
|
5e2e91df3d | ||
|
b06a5731bd | ||
|
dfe30f9bfb | ||
|
477b2bfc3b | ||
|
e6a8a45e03 | ||
|
e93d6660f1 | ||
|
65383b8787 | ||
|
5d78347d3f | ||
|
02a066a253 | ||
|
749aefe858 | ||
|
15e10958b8 | ||
|
a12e2910c5 | ||
|
7e6d0a5c6e | ||
|
e9ce3bd664 | ||
|
7dc61b8aaf | ||
|
ebdaa79c81 | ||
|
d8abb4213e | ||
|
b77d87ccb1 | ||
|
c611438172 | ||
|
7aa02a8b15 | ||
|
e1da85235d | ||
|
cca71af7c2 | ||
|
c83acd6b17 | ||
|
df50f40843 | ||
|
d6e78e78ba | ||
|
cbea08af24 | ||
|
db984a485f | ||
|
a09d08b826 | ||
|
200488fa6a | ||
|
18ae76c6f7 | ||
|
7e2b3d0c8f | ||
|
e889b19673 | ||
|
e1cb74911a | ||
|
1f4503cd96 | ||
|
5a51c48302 | ||
|
c821c96396 | ||
|
1374bfdca9 | ||
|
5f83abff97 | ||
|
e69c46661d | ||
|
66f2bd4639 | ||
|
96fa8abbfa | ||
|
9216c86658 | ||
|
786a4bc846 | ||
|
b06fc3e952 | ||
|
4ea7e592a2 | ||
|
36d4c6dc11 | ||
|
caba5201f9 | ||
|
4ea99e4385 | ||
|
cb0bac8ff6 | ||
|
1d77fd9106 | ||
|
6e932b6fd8 | ||
|
d044d1d36f | ||
|
bbd9c909b7 | ||
|
ea6cb35b73 | ||
|
fd00042f4d | ||
|
dd2a4dcf28 | ||
|
78a4b51e4e | ||
|
c465858eaa | ||
|
7747a99585 | ||
|
75283ef507 | ||
|
e60d5e9882 | ||
|
a9386d6927 | ||
|
cc234a6aee | ||
|
a5c6a60a20 | ||
|
d8a417983a | ||
|
df27c45434 | ||
|
6d5dbb2585 | ||
|
578c9b3d66 | ||
|
fb932b293f | ||
|
3bde1ae578 | ||
|
78fccc9578 | ||
|
1be12f1fe1 | ||
|
4fefda1f68 | ||
|
59952c8203 | ||
|
fdc2cb07c8 | ||
|
a8b16b1956 | ||
|
edbe7689bf | ||
|
c4cf8f58a1 | ||
|
d1e8a6ce43 | ||
|
7547d4e681 | ||
|
b99d55e5ff | ||
|
b57de8254c | ||
|
0d9f46c66c |
158 changed files with 4439 additions and 1373 deletions
|
@ -13,8 +13,8 @@ android {
|
|||
defaultConfig {
|
||||
minSdk 21
|
||||
targetSdk 34
|
||||
versionCode 529
|
||||
versionName "3.32.0"
|
||||
versionCode 534
|
||||
versionName "3.33.1"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
flavorDimensions "default"
|
||||
|
@ -100,7 +100,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')
|
||||
|
||||
|
@ -141,7 +141,7 @@ dependencies {
|
|||
implementation("com.vanniktech:android-image-cropper:4.3.3")
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:4.12.0"
|
||||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||
implementation 'com.github.penfeizhou.android.animation:glide-plugin:3.0.4'
|
||||
implementation 'com.github.penfeizhou.android.animation:glide-plugin:3.0.5'
|
||||
implementation 'androidx.media3:media3-exoplayer-hls:1.2.1'
|
||||
implementation "androidx.media3:media3-exoplayer:1.2.1"
|
||||
implementation "androidx.media3:media3-exoplayer-dash:1.2.1"
|
||||
|
|
|
@ -72,6 +72,10 @@
|
|||
android:host="*"
|
||||
android:pathPrefix="/@"
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:pathPrefix="/notes"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
@ -230,7 +234,7 @@
|
|||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".mastodon.activities.MediaActivity"
|
||||
android:hardwareAccelerated="false"
|
||||
android:hardwareAccelerated="true"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/Transparent" />
|
||||
|
||||
|
@ -753,4 +757,4 @@
|
|||
android:resource="@xml/compose_shortcuts" />
|
||||
</activity-alias>
|
||||
</application>
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
|
|
@ -1,4 +1,24 @@
|
|||
[
|
||||
{
|
||||
"version": "3.33.1",
|
||||
"code": "534",
|
||||
"note": "Added:\n- Highlight bottom hashtags\n- Support Trending Links\n- Featured tags displayed in profiles\n- Add/Remove featured tags from the profile editor\n\nChanged:\n- Add confirmation dialog when long pressing the boost button\n- Open messages by tapping on Scheduled Boost\n- Improve language picker when filtered with some languages\n\nFixed:\n- Limits number of fetch for filters\n- Pleroma instances cannot select media\n- Wrong messages deleted for scheduled (messages and boosts)\n- Fix a crash with long threads\n- Fix a potential memory issue for not cropped media\n- Fix embedded quotes not displayed\n- Some crashes"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
|
|
|
@ -212,6 +212,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
public static List<Filter> mainFilters;
|
||||
public static List<app.fedilab.android.mastodon.client.entities.api.Account> filteredAccounts;
|
||||
public static boolean filterFetched;
|
||||
public static int filterFetchedRetry = 0;
|
||||
public static boolean show_boosts, show_replies, show_dms, show_art_nsfw, show_self_boosts, show_self_replies, show_my_messages;
|
||||
public static String regex_home, regex_local, regex_public;
|
||||
public static iconLauncher mLauncher = iconLauncher.BUBBLES;
|
||||
|
@ -1358,6 +1359,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
filteredAccounts = new ArrayList<>();
|
||||
|
||||
filterFetched = false;
|
||||
filterFetchedRetry = 0;
|
||||
networkStateReceiver = new NetworkStateReceiver();
|
||||
networkStateReceiver.addListener(this);
|
||||
registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
|
@ -1473,6 +1475,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
});
|
||||
|
||||
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);
|
||||
|
|
|
@ -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<Attachment>) b.getSerializable(Helper.ARG_MEDIA_ATTACHMENTS);
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.text.Html;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -37,6 +38,7 @@ import com.bumptech.glide.Glide;
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -45,10 +47,13 @@ import java.util.Objects;
|
|||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.BuildConfig;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.AccountFeaturedHashtagItemBinding;
|
||||
import app.fedilab.android.databinding.AccountFieldItemBinding;
|
||||
import app.fedilab.android.databinding.ActivityEditProfileBinding;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Account;
|
||||
import app.fedilab.android.mastodon.client.entities.api.FeaturedTag;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Field;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Tag;
|
||||
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
|
||||
import app.fedilab.android.mastodon.exception.DBException;
|
||||
import app.fedilab.android.mastodon.helper.Helper;
|
||||
|
@ -62,6 +67,8 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
public static final int PICK_MEDIA_HEADER = 5706;
|
||||
private ActivityEditProfileBinding binding;
|
||||
private AccountsVM accountsVM;
|
||||
private static final int MAX_FIELDS = 4;
|
||||
private static final int MAX_FEATURED_HASHTAGS = 10;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
|
@ -87,8 +94,9 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
|
||||
return false;
|
||||
});
|
||||
accountsVM = new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class);
|
||||
|
||||
new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class).getConnectedAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken)
|
||||
accountsVM.getConnectedAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken)
|
||||
.observe(EditProfileActivity.this, account -> {
|
||||
if (account != null) {
|
||||
Helper.setCurrentAccountMastodonAccount(EditProfileActivity.this, account);
|
||||
|
@ -97,9 +105,10 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
Helper.sendToastMessage(getApplication(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void initializeView() {
|
||||
//Hydrate values
|
||||
|
@ -113,6 +122,68 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
else
|
||||
bio = Html.fromHtml(Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.note).toString();
|
||||
binding.bio.setText(bio);
|
||||
|
||||
accountsVM.getFeaturedTagsSuggestions(BaseMainActivity.currentInstance, BaseMainActivity.currentToken).observe(this, featuredTags -> {
|
||||
StringBuilder text = new StringBuilder(getString(R.string.no_feature_hashtag_suggestion));
|
||||
if(featuredTags != null && !featuredTags.isEmpty()) {
|
||||
text = new StringBuilder();
|
||||
for (Tag tag : featuredTags) {
|
||||
text.append(String.format("#%s ", tag.name));
|
||||
}
|
||||
}
|
||||
binding.featuredHashtagsSuggestions.setText(text);
|
||||
});
|
||||
accountsVM.getAccountFeaturedTags(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.id).observe(this, featuredTags -> {
|
||||
if(featuredTags != null && !featuredTags.isEmpty()) {
|
||||
for (FeaturedTag featuredTag : featuredTags) {
|
||||
AccountFeaturedHashtagItemBinding featuredHashtagItemBinding = AccountFeaturedHashtagItemBinding.inflate(getLayoutInflater());
|
||||
featuredHashtagItemBinding.name.setText(featuredTag.name);
|
||||
featuredHashtagItemBinding.remove.setOnClickListener(v -> {
|
||||
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this);
|
||||
deleteConfirm.setTitle(getString(R.string.delete_featured_hashtag));
|
||||
deleteConfirm.setMessage(getString(R.string.delete_featured_hashtag_confirm));
|
||||
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||
((ViewGroup)featuredHashtagItemBinding.getRoot().getParent()).removeView(featuredHashtagItemBinding.getRoot());
|
||||
if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) {
|
||||
binding.addFeaturedHashtags.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.addFeaturedHashtags.setVisibility(View.VISIBLE);
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
deleteConfirm.create().show();
|
||||
});
|
||||
binding.featuredHashtagsContainer.addView(featuredHashtagItemBinding.getRoot());
|
||||
}
|
||||
}
|
||||
binding.addFeaturedHashtags.setOnClickListener(view -> {
|
||||
AccountFeaturedHashtagItemBinding featuredHashtagItemBinding = AccountFeaturedHashtagItemBinding.inflate(getLayoutInflater());
|
||||
featuredHashtagItemBinding.remove.setOnClickListener(v -> {
|
||||
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this);
|
||||
deleteConfirm.setTitle(getString(R.string.delete_featured_hashtag));
|
||||
deleteConfirm.setMessage(getString(R.string.delete_featured_hashtag_confirm));
|
||||
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||
((ViewGroup)featuredHashtagItemBinding.getRoot().getParent()).removeView(featuredHashtagItemBinding.getRoot());
|
||||
if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) {
|
||||
binding.addFeaturedHashtags.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.addFeaturedHashtags.setVisibility(View.VISIBLE);
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
deleteConfirm.create().show();
|
||||
});
|
||||
binding.featuredHashtagsContainer.addView(featuredHashtagItemBinding.getRoot());
|
||||
|
||||
if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) {
|
||||
binding.addFeaturedHashtags.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.addFeaturedHashtags.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source != null) {
|
||||
binding.sensitive.setChecked(Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source.sensitive);
|
||||
switch (Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source.privacy) {
|
||||
|
@ -135,7 +206,7 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
binding.unlocked.setChecked(true);
|
||||
}
|
||||
List<Field> fields = Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.fields;
|
||||
if (fields != null && fields.size() > 0) {
|
||||
if (fields != null && !fields.isEmpty()) {
|
||||
for (Field field : fields) {
|
||||
AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater());
|
||||
fieldItemBinding.name.setText(field.name);
|
||||
|
@ -151,11 +222,11 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
deleteConfirm.setMessage(getString(R.string.delete_field_confirm));
|
||||
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||
binding.fieldsContainer.removeView(fieldItemBinding.getRoot());
|
||||
if (binding.fieldsContainer.getChildCount() < 4) {
|
||||
binding.fieldsContainer.setVisibility(View.VISIBLE);
|
||||
((ViewGroup)fieldItemBinding.getRoot().getParent()).removeView(fieldItemBinding.getRoot());
|
||||
if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) {
|
||||
binding.addField.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.fieldsContainer.setVisibility(View.GONE);
|
||||
binding.addField.setVisibility(View.VISIBLE);
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
@ -163,7 +234,11 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
});
|
||||
binding.fieldsContainer.addView(fieldItemBinding.getRoot());
|
||||
}
|
||||
|
||||
if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) {
|
||||
binding.addField.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.addField.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
binding.addField.setOnClickListener(view -> {
|
||||
AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater());
|
||||
|
@ -173,25 +248,24 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
deleteConfirm.setMessage(getString(R.string.delete_field_confirm));
|
||||
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||
binding.fieldsContainer.removeView(fieldItemBinding.getRoot());
|
||||
if (binding.fieldsContainer.getChildCount() < 4) {
|
||||
binding.fieldsContainer.setVisibility(View.VISIBLE);
|
||||
((ViewGroup)fieldItemBinding.getRoot().getParent()).removeView(fieldItemBinding.getRoot());
|
||||
if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) {
|
||||
binding.addField.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.fieldsContainer.setVisibility(View.GONE);
|
||||
binding.addField.setVisibility(View.VISIBLE);
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
deleteConfirm.create().show();
|
||||
});
|
||||
binding.fieldsContainer.addView(fieldItemBinding.getRoot());
|
||||
if (binding.fieldsContainer.getChildCount() >= 4) {
|
||||
|
||||
if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) {
|
||||
binding.addField.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.addField.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Actions with the activity
|
||||
accountsVM = new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class);
|
||||
binding.headerSelect.setOnClickListener(view -> startActivityForResult(prepareIntent(), EditProfileActivity.PICK_MEDIA_HEADER));
|
||||
|
||||
binding.avatarSelect.setOnClickListener(view -> startActivityForResult(prepareIntent(), EditProfileActivity.PICK_MEDIA_AVATAR));
|
||||
|
@ -280,7 +354,7 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
intent.setType("*/*");
|
||||
String[] mimetypes;
|
||||
long max_size = -1;
|
||||
if (instanceInfo.getMimeTypeImage().size() > 0) {
|
||||
if (!instanceInfo.getMimeTypeImage().isEmpty()) {
|
||||
mimetypes = instanceInfo.getMimeTypeImage().toArray(new String[0]);
|
||||
max_size = instanceInfo.configuration.media_attachments.image_size_limit;
|
||||
} else {
|
||||
|
@ -323,6 +397,16 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
return fields;
|
||||
}
|
||||
|
||||
|
||||
List<String> getFeaturedHashtags() {
|
||||
List<String> featuredHashtags = new ArrayList<>();
|
||||
for (int i = 0; i < binding.featuredHashtagsContainer.getChildCount(); i++) {
|
||||
String name = Objects.requireNonNull(((TextInputEditText) binding.featuredHashtagsContainer.getChildAt(i).findViewById(R.id.name)).getText()).toString().trim();
|
||||
featuredHashtags.add(name);
|
||||
}
|
||||
return featuredHashtags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
|
@ -338,7 +422,8 @@ public class EditProfileActivity extends BaseBarActivity {
|
|||
getPrivacy(),
|
||||
binding.sensitive.isChecked(),
|
||||
null,
|
||||
getFields()
|
||||
getFields(),
|
||||
getFeaturedHashtags()
|
||||
)
|
||||
.observe(EditProfileActivity.this, account -> {
|
||||
if (account != null) {
|
||||
|
|
|
@ -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<Attachment>) 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);
|
||||
|
|
|
@ -40,6 +40,7 @@ import android.text.method.LinkMovementMethod;
|
|||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
@ -69,6 +70,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
|
@ -96,6 +98,7 @@ import app.fedilab.android.databinding.TabProfileCustomViewBinding;
|
|||
import app.fedilab.android.mastodon.client.entities.api.Account;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Attachment;
|
||||
import app.fedilab.android.mastodon.client.entities.api.FamiliarFollowers;
|
||||
import app.fedilab.android.mastodon.client.entities.api.FeaturedTag;
|
||||
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;
|
||||
|
@ -116,6 +119,7 @@ import app.fedilab.android.mastodon.helper.SpannableHelper;
|
|||
import app.fedilab.android.mastodon.helper.ThemeHelper;
|
||||
import app.fedilab.android.mastodon.ui.drawer.FieldAdapter;
|
||||
import app.fedilab.android.mastodon.ui.drawer.IdentityProofsAdapter;
|
||||
import app.fedilab.android.mastodon.ui.drawer.StatusAdapter;
|
||||
import app.fedilab.android.mastodon.ui.pageadapter.FedilabProfileTLPageAdapter;
|
||||
import app.fedilab.android.mastodon.viewmodel.mastodon.AccountsVM;
|
||||
import app.fedilab.android.mastodon.viewmodel.mastodon.NodeInfoVM;
|
||||
|
@ -229,7 +233,46 @@ public class ProfileActivity extends BaseActivity {
|
|||
//Check if account is homeMuted
|
||||
accountsVM.isMuted(Helper.getCurrentAccount(ProfileActivity.this), account).observe(this, result -> homeMuted = result != null && result);
|
||||
ContextCompat.registerReceiver(ProfileActivity.this, broadcast_data, new IntentFilter(Helper.BROADCAST_DATA), ContextCompat.RECEIVER_NOT_EXPORTED);
|
||||
//Search for featured tags
|
||||
|
||||
accountsVM.getAccountFeaturedTags(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account!=null?account.id:account_id).observe(this, featuredTags -> {
|
||||
if(featuredTags != null && !featuredTags.isEmpty()) {
|
||||
binding.featuredHashtagsContainer.setVisibility(View.VISIBLE);
|
||||
binding.featuredHashtags.removeAllViews();
|
||||
for(FeaturedTag featuredTag: featuredTags) {
|
||||
if(featuredTag.statuses_count > 0 ) {
|
||||
Chip chip = new Chip(ProfileActivity.this);
|
||||
chip.setClickable(true);
|
||||
chip.setEnsureMinTouchTargetSize(false);
|
||||
chip.setText(String.format("#%s", featuredTag.name));
|
||||
chip.setTextColor(ThemeHelper.getAttColor(ProfileActivity.this, R.attr.colorPrimary));
|
||||
chip.setOnClickListener(v -> {
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.ACCOUNT_TIMELINE);
|
||||
if (account != null) {
|
||||
args.putSerializable(Helper.ARG_CACHED_ACCOUNT_ID, account.id);
|
||||
}
|
||||
args.putString(Helper.ARG_TAGGED, featuredTag.name);
|
||||
args.putBoolean(Helper.ARG_SHOW_PINNED, false);
|
||||
args.putBoolean(Helper.ARG_SHOW_REPLIES, false);
|
||||
args.putBoolean(Helper.ARG_SHOW_REBLOGS, false);
|
||||
args.putBoolean(Helper.ARG_CHECK_REMOTELY, checkRemotely);
|
||||
Intent intent = new Intent(ProfileActivity.this, TimelineActivity.class);
|
||||
new CachedBundle(ProfileActivity.this).insertBundle(args, Helper.getCurrentAccount(ProfileActivity.this), bundleId -> {
|
||||
Bundle _bundle = new Bundle();
|
||||
_bundle.putLong(Helper.ARG_INTENT_ID, bundleId);
|
||||
intent.putExtras(_bundle);
|
||||
startActivity(intent);
|
||||
});
|
||||
});
|
||||
binding.featuredHashtags.addView(chip);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
binding.featuredHashtagsContainer.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -57,21 +57,30 @@ public class TimelineActivity extends BaseBarActivity {
|
|||
Timeline.TimeLineEnum timelineType = null;
|
||||
String lemmy_post_id = null;
|
||||
PinnedTimeline pinnedTimeline = null;
|
||||
String tagged = null;
|
||||
String timelineAccountId = null;
|
||||
Status status = null;
|
||||
if (bundle != null) {
|
||||
timelineType = (Timeline.TimeLineEnum) bundle.get(Helper.ARG_TIMELINE_TYPE);
|
||||
lemmy_post_id = bundle.getString(Helper.ARG_LEMMY_POST_ID, null);
|
||||
pinnedTimeline = (PinnedTimeline) bundle.getSerializable(Helper.ARG_REMOTE_INSTANCE);
|
||||
status = (Status) bundle.getSerializable(Helper.ARG_STATUS);
|
||||
tagged = bundle.getString(Helper.ARG_TAGGED, null);
|
||||
timelineAccountId = bundle.getString(Helper.ARG_CACHED_ACCOUNT_ID, null);
|
||||
}
|
||||
if (pinnedTimeline != null && pinnedTimeline.remoteInstance != null) {
|
||||
setTitle(pinnedTimeline.remoteInstance.host);
|
||||
}
|
||||
if(tagged != null) {
|
||||
setTitle(String.format("#%s",tagged));
|
||||
}
|
||||
FragmentMastodonTimeline fragmentMastodonTimeline = new FragmentMastodonTimeline();
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(Helper.ARG_TIMELINE_TYPE, timelineType);
|
||||
args.putSerializable(Helper.ARG_REMOTE_INSTANCE, pinnedTimeline);
|
||||
args.putSerializable(Helper.ARG_LEMMY_POST_ID, lemmy_post_id);
|
||||
args.putSerializable(Helper.ARG_TAGGED, tagged);
|
||||
args.putSerializable(Helper.ARG_CACHED_ACCOUNT_ID, timelineAccountId);
|
||||
if (status != null) {
|
||||
args.putSerializable(Helper.ARG_STATUS, status);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import app.fedilab.android.R;
|
|||
import app.fedilab.android.databinding.ActivityTrendsBinding;
|
||||
import app.fedilab.android.mastodon.client.entities.app.Timeline;
|
||||
import app.fedilab.android.mastodon.helper.Helper;
|
||||
import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentMastodonLink;
|
||||
import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentMastodonTag;
|
||||
import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentMastodonTimeline;
|
||||
|
||||
|
@ -56,6 +57,7 @@ public class TrendsActivity extends BaseBarActivity {
|
|||
|
||||
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.tags)));
|
||||
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.toots)));
|
||||
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.links)));
|
||||
binding.searchTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
|
@ -75,6 +77,8 @@ public class TrendsActivity extends BaseBarActivity {
|
|||
fragmentMastodonTimeline.scrollToTop();
|
||||
} else if (fragment instanceof FragmentMastodonTag fragmentMastodonTag) {
|
||||
fragmentMastodonTag.scrollToTop();
|
||||
}else if (fragment instanceof FragmentMastodonLink fragmentMastodonLink) {
|
||||
fragmentMastodonLink.scrollToTop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +133,17 @@ public class TrendsActivity extends BaseBarActivity {
|
|||
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TREND_TAG);
|
||||
fragmentMastodonTag.setArguments(bundle);
|
||||
return fragmentMastodonTag;
|
||||
} else if(position == 1) {
|
||||
FragmentMastodonTimeline fragmentMastodonTimeline = new FragmentMastodonTimeline();
|
||||
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TREND_MESSAGE);
|
||||
fragmentMastodonTimeline.setArguments(bundle);
|
||||
return fragmentMastodonTimeline;
|
||||
} else {
|
||||
FragmentMastodonLink fragmentMastodonLink = new FragmentMastodonLink();
|
||||
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TREND_LINK);
|
||||
fragmentMastodonLink.setArguments(bundle);
|
||||
return fragmentMastodonLink;
|
||||
}
|
||||
FragmentMastodonTimeline fragmentMastodonTimeline = new FragmentMastodonTimeline();
|
||||
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TREND_MESSAGE);
|
||||
fragmentMastodonTimeline.setArguments(bundle);
|
||||
return fragmentMastodonTimeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,7 +152,7 @@ public class TrendsActivity extends BaseBarActivity {
|
|||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 2;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ public interface MastodonAccountsService {
|
|||
@Query("exclude_reblogs") Boolean exclude_reblogs,
|
||||
@Query("only_media") Boolean only_media,
|
||||
@Query("pinned") Boolean pinned,
|
||||
@Query("tagged") String tagged,
|
||||
@Query("limit") int limit
|
||||
);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.List;
|
|||
|
||||
import app.fedilab.android.mastodon.client.entities.api.Account;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Conversation;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Link;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Marker;
|
||||
import app.fedilab.android.mastodon.client.entities.api.MastodonList;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Status;
|
||||
|
@ -80,6 +81,11 @@ public interface MastodonTimelinesService {
|
|||
@Query("offset") Integer offset,
|
||||
@Query("limit") Integer limit);
|
||||
|
||||
@GET("trends/links")
|
||||
Call<List<Link>> getLinkTrends(@Header("Authorization") String token,
|
||||
@Query("offset") Integer offset,
|
||||
@Query("limit") Integer limit);
|
||||
|
||||
//Public Tags timelines
|
||||
@GET("timelines/tag/{hashtag}")
|
||||
Call<List<Status>> getHashTag(
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package app.fedilab.android.mastodon.client.entities.api;
|
||||
/* Copyright 2025 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 <http://www.gnu.org/licenses>. */
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class Link implements Serializable {
|
||||
@SerializedName("url")
|
||||
public String url;
|
||||
@SerializedName("title")
|
||||
public String title;
|
||||
@SerializedName("description")
|
||||
public String description;
|
||||
@SerializedName("type")
|
||||
public String type;
|
||||
@SerializedName("author_name")
|
||||
public String author_name;
|
||||
@SerializedName("author_url")
|
||||
public String author_url;
|
||||
@SerializedName("provider_name")
|
||||
public String provider_name;
|
||||
@SerializedName("provider_url")
|
||||
public String provider_url;
|
||||
@SerializedName("html")
|
||||
public String html;
|
||||
@SerializedName("width")
|
||||
public int width;
|
||||
@SerializedName("height")
|
||||
public int height;
|
||||
@SerializedName("image")
|
||||
public String image;
|
||||
@SerializedName("embed_url")
|
||||
public String embed_url;
|
||||
@SerializedName("blurhash")
|
||||
public String blurhash;
|
||||
@SerializedName("history")
|
||||
public List<History> history;
|
||||
}
|
|
@ -16,6 +16,7 @@ package app.fedilab.android.mastodon.client.entities.api;
|
|||
|
||||
import android.content.Context;
|
||||
import android.text.Spannable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -28,6 +29,7 @@ import java.lang.ref.WeakReference;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.mastodon.helper.Helper;
|
||||
import app.fedilab.android.mastodon.helper.SpannableHelper;
|
||||
import de.timfreiheit.mathjax.android.MathJaxView;
|
||||
|
||||
|
@ -113,6 +115,7 @@ public class Status implements Serializable, Cloneable {
|
|||
public List<Reaction> reactions;
|
||||
|
||||
public String attachedNotification = null;
|
||||
public int gifPosition = 0;
|
||||
|
||||
public transient boolean isFetchMore = false;
|
||||
public transient boolean isFetching = false;
|
||||
|
@ -139,6 +142,8 @@ public class Status implements Serializable, Cloneable {
|
|||
public boolean spoilerChecked = false;
|
||||
public Filter filteredByApp;
|
||||
public transient Spannable contentSpan;
|
||||
|
||||
public transient String[] bottomTags;
|
||||
public transient Spannable contentSpoilerSpan;
|
||||
public transient Spannable contentTranslateSpan;
|
||||
public transient MathJaxView mathJaxView;
|
||||
|
@ -162,6 +167,13 @@ public class Status implements Serializable, Cloneable {
|
|||
return contentSpan;
|
||||
}
|
||||
|
||||
public synchronized String[] getBottomTags() {
|
||||
if(bottomTags == null) {
|
||||
bottomTags = SpannableHelper.hasBottomTags(content);
|
||||
}
|
||||
return bottomTags;
|
||||
}
|
||||
|
||||
public synchronized Spannable getSpanSpoiler(Context context, WeakReference<View> viewWeakReference, Callback callback) {
|
||||
if (contentSpoilerSpan == null) {
|
||||
contentSpoilerSpan = SpannableHelper.convert(context, spoiler_text, this, null, null, viewWeakReference, callback, true, false);
|
||||
|
|
|
@ -378,6 +378,8 @@ public class Timeline {
|
|||
REMOTE("REMOTE"),
|
||||
@SerializedName("TREND_TAG")
|
||||
TREND_TAG("TREND_TAG"),
|
||||
@SerializedName("TREND_LINK")
|
||||
TREND_LINK("TREND_LINK"),
|
||||
@SerializedName("TREND_MESSAGE")
|
||||
TREND_MESSAGE("TREND_MESSAGE"),
|
||||
@SerializedName("ACCOUNT_SUGGESTION")
|
||||
|
|
|
@ -73,10 +73,30 @@ public class CrossActionHelper {
|
|||
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
boolean confirmFav = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION_FAV), false);
|
||||
boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true);
|
||||
List<BaseAccount> accounts = new Account(context).getCrossAccounts();
|
||||
if (accounts.size() == 1) {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> fetchRemote(context, actionType, accounts.get(0), targetedAccount, targetedStatus);
|
||||
Runnable myRunnable = () -> {
|
||||
if ((actionType == TypeOfCrossAction.REBLOG_ACTION && confirmBoost) || (actionType == TypeOfCrossAction.FAVOURITE_ACTION && confirmFav)) {
|
||||
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
|
||||
if (actionType == TypeOfCrossAction.REBLOG_ACTION) {
|
||||
alt_bld.setMessage(context.getString(R.string.reblog_add));
|
||||
} else {
|
||||
alt_bld.setMessage(context.getString(R.string.favourite_add));
|
||||
}
|
||||
alt_bld.setPositiveButton(R.string.yes, (dia, id) -> {
|
||||
fetchRemote(context, actionType, accounts.get(0), targetedAccount, targetedStatus);
|
||||
dia.dismiss();
|
||||
});
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dia, id) -> dia.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
} else {
|
||||
fetchRemote(context, actionType, accounts.get(0), targetedAccount, targetedStatus);
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
} else {
|
||||
List<app.fedilab.android.mastodon.client.entities.api.Account> accountList = new ArrayList<>();
|
||||
|
@ -97,8 +117,7 @@ public class CrossActionHelper {
|
|||
}
|
||||
builderSingle.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
builderSingle.setAdapter(accountsSearchAdapter, (dialog, which) -> {
|
||||
boolean confirmFav = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION_FAV), false);
|
||||
boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true);
|
||||
|
||||
BaseAccount selectedAccount = accountArray[which];
|
||||
if ((actionType == TypeOfCrossAction.REBLOG_ACTION && confirmBoost) || (actionType == TypeOfCrossAction.FAVOURITE_ACTION && confirmFav)) {
|
||||
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
|
||||
|
@ -109,9 +128,9 @@ public class CrossActionHelper {
|
|||
}
|
||||
alt_bld.setPositiveButton(R.string.yes, (dia, id) -> {
|
||||
fetchRemote(context, actionType, selectedAccount, targetedAccount, targetedStatus);
|
||||
dialog.dismiss();
|
||||
dia.dismiss();
|
||||
});
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dia, id) -> dialog.dismiss());
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dia, id) -> dia.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
} else {
|
||||
|
|
|
@ -47,7 +47,7 @@ public class CustomEmoji extends ReplacementSpan {
|
|||
}
|
||||
|
||||
public SpannableStringBuilder makeEmoji(SpannableStringBuilder content, List<Emoji> emojiList, boolean animate, Status.Callback callback) {
|
||||
if (emojiList != null && emojiList.size() > 0) {
|
||||
if (emojiList != null && !emojiList.isEmpty()) {
|
||||
int count = 1;
|
||||
for (Emoji emoji : emojiList) {
|
||||
Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
|
||||
|
@ -68,13 +68,6 @@ public class CustomEmoji extends ReplacementSpan {
|
|||
|
||||
@Override
|
||||
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
|
||||
if (fontMetricsInt != null) {
|
||||
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
|
||||
fontMetricsInt.top = (int) fontMetrics.top;
|
||||
fontMetricsInt.ascent = (int) fontMetrics.ascent;
|
||||
fontMetricsInt.descent = (int) fontMetrics.descent;
|
||||
fontMetricsInt.bottom = (int) fontMetrics.bottom;
|
||||
}
|
||||
return (int) (paint.getTextSize() * scale);
|
||||
}
|
||||
|
||||
|
@ -85,7 +78,7 @@ public class CustomEmoji extends ReplacementSpan {
|
|||
int emojiSize = (int) (paint.getTextSize() * scale);
|
||||
imageDrawable.setBounds(0, 0, emojiSize, emojiSize);
|
||||
int transY = bottom - imageDrawable.getBounds().bottom;
|
||||
transY -= paint.getFontMetrics().descent / 2;
|
||||
transY -= (int) (paint.getFontMetrics().descent / 2);
|
||||
canvas.translate(x, (float) transY);
|
||||
imageDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
@ -93,19 +86,31 @@ public class CustomEmoji extends ReplacementSpan {
|
|||
}
|
||||
|
||||
public Target<Drawable> getTarget(boolean animate, Status.Callback callback) {
|
||||
return new CustomTarget<Drawable>() {
|
||||
return new CustomTarget<>() {
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (imageDrawable instanceof Animatable) {
|
||||
((Animatable) imageDrawable).start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (imageDrawable instanceof Animatable) {
|
||||
((Animatable) imageDrawable).stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
|
||||
View view = viewWeakReference.get();
|
||||
|
||||
if (animate && resource instanceof Animatable) {
|
||||
Drawable.Callback drawableCallBack = resource.getCallback();
|
||||
|
||||
resource.setCallback(new Drawable.Callback() {
|
||||
@Override
|
||||
public void invalidateDrawable(@NonNull Drawable drawable) {
|
||||
if (drawableCallBack != null) {
|
||||
drawableCallBack.invalidateDrawable(drawable);
|
||||
}
|
||||
if(view != null) {
|
||||
view.invalidate();
|
||||
}
|
||||
|
@ -113,22 +118,18 @@ public class CustomEmoji extends ReplacementSpan {
|
|||
|
||||
@Override
|
||||
public void scheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable, long l) {
|
||||
if (drawableCallBack != null) {
|
||||
drawableCallBack.scheduleDrawable(drawable, runnable, l);
|
||||
}
|
||||
view.postDelayed(runnable, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unscheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable) {
|
||||
if (drawableCallBack != null) {
|
||||
drawableCallBack.unscheduleDrawable(drawable, runnable);
|
||||
}
|
||||
view.removeCallbacks(runnable);
|
||||
}
|
||||
});
|
||||
((Animatable) resource).start();
|
||||
}
|
||||
imageDrawable = resource;
|
||||
if (view != null) {
|
||||
if(view != null) {
|
||||
view.invalidate();
|
||||
}
|
||||
if (callback != null && !callbackCalled) {
|
||||
|
@ -139,6 +140,17 @@ public class CustomEmoji extends ReplacementSpan {
|
|||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
View view = viewWeakReference.get();
|
||||
if (imageDrawable != null) {
|
||||
if (imageDrawable instanceof Animatable) {
|
||||
((Animatable) imageDrawable).stop();
|
||||
imageDrawable.setCallback(null);
|
||||
}
|
||||
}
|
||||
imageDrawable = null;
|
||||
if(view != null) {
|
||||
view.invalidate();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -118,12 +118,7 @@ public class DividerDecoration extends RecyclerView.ItemDecoration {
|
|||
|
||||
c.drawLine(startPx, view.getTop() - margin, startPx, bottomPx, paint);
|
||||
}
|
||||
int color;
|
||||
if (indentation - 1 >= colorList.size()) {
|
||||
color = colorList.get(indentation - 1 - colorList.size());
|
||||
} else {
|
||||
color = colorList.get(indentation - 1);
|
||||
}
|
||||
int color = colorList.get(indentation%colorList.size()-1);
|
||||
paint.setColor(ResourcesCompat.getColor(_mContext.getResources(), color, _mContext.getTheme()));
|
||||
|
||||
float startDp = 6 * fontScale * (indentation - 1) + 6 * fontScale;
|
||||
|
|
|
@ -127,12 +127,7 @@ public class DividerDecorationSimple extends RecyclerView.ItemDecoration {
|
|||
|
||||
c.drawLine(startPx, view.getTop() - margin, startPx, bottomPx, paint);
|
||||
}
|
||||
int color;
|
||||
if (indentation - 1 >= colorList.size()) {
|
||||
color = colorList.get(indentation - 1 - colorList.size());
|
||||
} else {
|
||||
color = colorList.get(indentation - 1);
|
||||
}
|
||||
int color = colorList.get(indentation%colorList.size()-1);
|
||||
paint.setColor(ResourcesCompat.getColor(_mContext.getResources(), color, _mContext.getTheme()));
|
||||
|
||||
float startDp = 6 * fontScale * (indentation - 1) + 6 * fontScale;
|
||||
|
|
|
@ -288,6 +288,7 @@ public class Helper {
|
|||
public static final String ARG_SHOW_REBLOGS = "ARG_SHOW_REBLOGS";
|
||||
public static final String ARG_INITIALIZE_VIEW = "ARG_INITIALIZE_VIEW";
|
||||
public static final String ARG_SHOW_PINNED = "ARG_SHOW_PINNED";
|
||||
public static final String ARG_TAGGED = "ARG_TAGGED";
|
||||
public static final String ARG_SHOW_MEDIA_ONY = "ARG_SHOW_MEDIA_ONY";
|
||||
public static final String ARG_MENTION = "ARG_MENTION";
|
||||
public static final String ARG_CHECK_REMOTELY = "ARG_CHECK_REMOTELY";
|
||||
|
@ -1848,7 +1849,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=");
|
||||
|
@ -1858,7 +1858,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
|
||||
|
|
|
@ -559,7 +559,7 @@ public class MastodonHelper {
|
|||
return val;
|
||||
} else {
|
||||
if (instanceInfo != null) {
|
||||
max_car = instanceInfo.max_toot_chars != null ? Integer.parseInt(instanceInfo.max_toot_chars) : instanceInfo.configuration.statusesConf.max_characters;
|
||||
max_car = instanceInfo.max_toot_chars != null && instanceInfo.max_toot_chars.matches("\\d+") ? Integer.parseInt(instanceInfo.max_toot_chars) : instanceInfo.configuration.statusesConf.max_characters;
|
||||
} else {
|
||||
max_car = 500;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -107,6 +107,28 @@ public class SpannableHelper {
|
|||
private static int linkColor;
|
||||
private static boolean underlineLinks;
|
||||
|
||||
private static final String patternBottomTags = "\\n{2,}((#[\\w_À-ú-]+)(\\s*| *))+$";
|
||||
|
||||
public static String[] hasBottomTags(String text) {
|
||||
if (text == null) {
|
||||
return new String[]{};
|
||||
}
|
||||
SpannableString initialContent;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
initialContent = new SpannableString(Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY));
|
||||
} else {
|
||||
initialContent = new SpannableString(Html.fromHtml(text));
|
||||
}
|
||||
final Pattern bottomTagsPattern = Pattern.compile(patternBottomTags, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcherBottomTags = bottomTagsPattern.matcher(initialContent);
|
||||
String[] tags = new String[]{};
|
||||
while (matcherBottomTags.find()) {
|
||||
String stringTags = Objects.requireNonNull(matcherBottomTags.group()).trim();
|
||||
tags = stringTags.split("\\s");
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
public static Spannable convert(Context context, String text,
|
||||
Status status, Account account, Announcement announcement,
|
||||
WeakReference<View> viewWeakReference, Status.Callback callback, boolean convertHtml, boolean convertMarkdown) {
|
||||
|
@ -148,7 +170,8 @@ public class SpannableHelper {
|
|||
if (status != null && status.mentions != null) {
|
||||
mentions.addAll(status.mentions);
|
||||
}
|
||||
if(!convertMarkdown) {
|
||||
boolean markdownSupport = sharedpreferences.getBoolean(context.getString(R.string.SET_MARKDOWN_SUPPORT), false);
|
||||
if(!markdownSupport) {
|
||||
text = text.replaceAll("((<\\s?p\\s?>|<\\s?br\\s?/?>)>(((?!(<\\s?br\\s?/?>|<\\s?/s?p\\s?>)).)*))", "$2<blockquote>$3</blockquote>");
|
||||
}
|
||||
text = text.trim().replaceAll("\\s{3}", " ");
|
||||
|
@ -162,7 +185,8 @@ public class SpannableHelper {
|
|||
} else {
|
||||
initialContent = new SpannableString(text);
|
||||
}
|
||||
boolean markdownSupport = sharedpreferences.getBoolean(context.getString(R.string.SET_MARKDOWN_SUPPORT), false);
|
||||
|
||||
|
||||
//Get all links
|
||||
SpannableStringBuilder content;
|
||||
if (markdownSupport && convertMarkdown) {
|
||||
|
@ -350,9 +374,9 @@ public class SpannableHelper {
|
|||
} else {
|
||||
makeLinks(context, status, content, url, start, end, sameContent);
|
||||
}
|
||||
replaceQuoteSpans(context, content);
|
||||
emails(context, content, status);
|
||||
}
|
||||
replaceQuoteSpans(context, content);
|
||||
emails(context, content, status);
|
||||
|
||||
Pattern imgPattern = Pattern.compile("<img [^>]*src=\"([^\"]+)\"[^>]*>");
|
||||
Matcher matcherImg = imgPattern.matcher(text);
|
||||
|
@ -393,6 +417,20 @@ public class SpannableHelper {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean underlineBottomHashTags = sharedpreferences.getBoolean(context.getString(R.string.SET_UNDERLINE_BOTTOM_HASHTAGS), true);
|
||||
if(underlineBottomHashTags) {
|
||||
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
|
||||
final Pattern bottomTagsPattern = Pattern.compile(patternBottomTags, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcherBottomTags = bottomTagsPattern.matcher(content);
|
||||
int length = 0;
|
||||
while (matcherBottomTags.find()) {
|
||||
length = Objects.requireNonNull(matcherBottomTags.group()).length();
|
||||
}
|
||||
spannableStringBuilder.append(content,0, content.length()-length);
|
||||
return trimSpannable(spannableStringBuilder);
|
||||
|
||||
}
|
||||
return trimSpannable(new SpannableStringBuilder(content));
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public class TimelineHelper {
|
|||
*/
|
||||
public static List<Status> filterStatus(Context context, List<Status> statuses, Timeline.TimeLineEnum filterTimeLineType) {
|
||||
//A security to make sure filters have been fetched before displaying messages
|
||||
if (!BaseMainActivity.filterFetched) {
|
||||
if (!BaseMainActivity.filterFetched && BaseMainActivity.filterFetchedRetry < 3) {
|
||||
MastodonFiltersService mastodonFiltersService = initv2(context);
|
||||
List<Filter> filterList;
|
||||
Call<List<Filter>> getFiltersCall = mastodonFiltersService.getFilters(BaseMainActivity.currentToken);
|
||||
|
@ -92,6 +92,7 @@ public class TimelineHelper {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
BaseMainActivity.filterFetchedRetry++;
|
||||
}
|
||||
|
||||
//If there are filters:
|
||||
|
@ -222,7 +223,7 @@ public class TimelineHelper {
|
|||
public static List<Notification> filterNotification(Context context, List<Notification> notifications) {
|
||||
//A security to make sure filters have been fetched before displaying messages
|
||||
List<Notification> notificationToRemove = new ArrayList<>();
|
||||
if (!BaseMainActivity.filterFetched) {
|
||||
if (!BaseMainActivity.filterFetched && BaseMainActivity.filterFetchedRetry < 3) {
|
||||
try {
|
||||
FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class);
|
||||
filtersVM.getFilters(BaseMainActivity.currentInstance, BaseMainActivity.currentToken).observe((LifecycleOwner) context, filters -> {
|
||||
|
@ -232,6 +233,7 @@ public class TimelineHelper {
|
|||
} catch (Exception e) {
|
||||
return notifications;
|
||||
}
|
||||
BaseMainActivity.filterFetchedRetry++;
|
||||
}
|
||||
//If there are filters:
|
||||
if (BaseMainActivity.mainFilters != null && !BaseMainActivity.mainFilters.isEmpty() && notifications != null && !notifications.isEmpty()) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.Manifest;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
|
@ -315,7 +316,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
*/
|
||||
private void manageMentions(Context context, Status statusDraft, ComposeViewHolder holder) {
|
||||
|
||||
if (statusDraft.mentions != null && (statusDraft.text == null || statusDraft.text.length() == 0) && statusDraft.mentions.size() > 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 +427,25 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
||||
String[] mimetypes = new String[0];
|
||||
if (type == ComposeActivity.mediaType.PHOTO) {
|
||||
if (instanceInfo != null && instanceInfo.getMimeTypeImage() != null && instanceInfo.getMimeTypeImage().size() > 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 +510,9 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
*/
|
||||
private boolean canBeRemoved(Status draft) {
|
||||
return draft.poll == null
|
||||
&& (draft.media_attachments == null || draft.media_attachments.size() == 0)
|
||||
&& (draft.text == null || draft.text.trim().length() == 0)
|
||||
&& (draft.spoiler_text == null || draft.spoiler_text.trim().length() == 0);
|
||||
&& (draft.media_attachments == null || draft.media_attachments.isEmpty())
|
||||
&& (draft.text == null || draft.text.trim().isEmpty())
|
||||
&& (draft.spoiler_text == null || draft.spoiler_text.trim().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -717,7 +718,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
|
||||
InputStream is;
|
||||
newContent[0] = "";
|
||||
if (mentions.size() > 0) {
|
||||
if (!mentions.isEmpty()) {
|
||||
for (String mention : mentions) {
|
||||
newContent[0] += mention + " ";
|
||||
}
|
||||
|
@ -734,7 +735,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
Gson gson = new Gson();
|
||||
List<Quotes.Quote> quotes = gson.fromJson(json, new TypeToken<List<Quotes.Quote>>() {
|
||||
}.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;
|
||||
|
@ -762,7 +763,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
|
||||
if (holder.binding.content.getSelectionStart() != 0)
|
||||
currentCursorPosition[0] = holder.binding.content.getSelectionStart();
|
||||
if (contentString.length() == 0)
|
||||
if (contentString.isEmpty())
|
||||
currentCursorPosition[0] = 0;
|
||||
//Only check last 15 characters before cursor position to avoid lags
|
||||
//Less than 15 characters are written before the cursor position
|
||||
|
@ -858,7 +859,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
if (currentCursorPosition >= 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;
|
||||
|
@ -886,10 +887,10 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
"hashtags", false, true, false, 0,
|
||||
null, null, 10).observe((LifecycleOwner) context,
|
||||
results -> {
|
||||
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;
|
||||
|
@ -931,7 +932,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
deltaSearch = oldContent.substring(currentCursorPosition - searchLength);
|
||||
}
|
||||
|
||||
if (!search.equals(""))
|
||||
if (!search.isEmpty())
|
||||
deltaSearch = deltaSearch.replace("#" + search, "");
|
||||
String newContent = oldContent.substring(0, currentCursorPosition - searchLength);
|
||||
newContent += deltaSearch;
|
||||
|
@ -954,7 +955,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
new Thread(() -> {
|
||||
List<Emoji> 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) {
|
||||
|
@ -997,7 +998,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
deltaSearch = oldContent.substring(currentCursorPosition - searchLength);
|
||||
}
|
||||
|
||||
if (!search.equals(""))
|
||||
if (!search.isEmpty())
|
||||
deltaSearch = deltaSearch.replace(":" + search, "");
|
||||
String newContent = oldContent.substring(0, currentCursorPosition - searchLength);
|
||||
newContent += deltaSearch;
|
||||
|
@ -1049,9 +1050,9 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
|
||||
if (title != null && title.trim().length() > 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);
|
||||
}
|
||||
|
||||
|
@ -1059,12 +1060,12 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
contentBuilder.append("\n\n");
|
||||
}
|
||||
|
||||
if (description != null && description.trim().length() > 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");
|
||||
}
|
||||
|
@ -1311,7 +1312,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
}
|
||||
for (Status status : statusList) {
|
||||
if (getItemViewType(position) == TYPE_COMPOSE) {
|
||||
if (status != null && status.media_attachments != null && status.media_attachments.size() > 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()) {
|
||||
|
@ -1355,7 +1356,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
holder.binding.buttonAttachManual.setEnabled(false);
|
||||
holder.binding.buttonPoll.setEnabled(true);
|
||||
}
|
||||
holder.binding.buttonPoll.setEnabled(statusDraft.media_attachments == null || statusDraft.media_attachments.size() == 0);
|
||||
holder.binding.buttonPoll.setEnabled(statusDraft.media_attachments == null || statusDraft.media_attachments.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1380,7 +1381,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
Status status = statusList.get(position);
|
||||
StatusSimpleViewHolder holder = (StatusSimpleViewHolder) viewHolder;
|
||||
|
||||
if (status.media_attachments != null && status.media_attachments.size() > 0) {
|
||||
if (status.media_attachments != null && !status.media_attachments.isEmpty()) {
|
||||
holder.binding.simpleMedia.removeAllViews();
|
||||
List<Attachment> attachmentList = statusList.get(position).media_attachments;
|
||||
for (Attachment attachment : attachmentList) {
|
||||
|
@ -1449,7 +1450,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
statusFromUser.pronouns = null;
|
||||
boolean pronounsSupport = sharedpreferences.getBoolean(context.getString(R.string.SET_PRONOUNS_SUPPORT), true);
|
||||
if(pronounsSupport) {
|
||||
if (accountFromUser.fields != null && accountFromUser.fields.size() > 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);
|
||||
|
@ -1571,17 +1572,17 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
holder.binding.contentSpoiler.setInputType(newInputTypeSpoiler);
|
||||
holder.binding.buttonAttach.setOnClickListener(v -> {
|
||||
|
||||
if (instanceInfo.configuration.media_attachments.supported_mime_types != null) {
|
||||
if (instanceInfo.getMimeTypeAudio().size() == 0) {
|
||||
if (instanceInfo.configuration.media_attachments.supported_mime_types != null && instanceInfo.configuration.media_attachments.supported_mime_types.size() > 1) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1689,7 +1690,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
unlisted_changed = true;
|
||||
});
|
||||
|
||||
if (statusDraft.spoilerChecked || statusDraft.spoiler_text != null && statusDraft.spoiler_text.trim().length() > 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);
|
||||
|
@ -1709,7 +1710,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
//Last compose drawer
|
||||
buttonVisibility(holder);
|
||||
|
||||
if (emojis != null && emojis.size() > 0) {
|
||||
if (emojis != null && !emojis.isEmpty()) {
|
||||
holder.binding.buttonEmoji.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.buttonEmoji.setVisibility(View.GONE);
|
||||
|
@ -1785,7 +1786,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
camelCaseTags.add(tag);
|
||||
}
|
||||
}
|
||||
if (camelCaseTags.size() > 0) {
|
||||
if (!camelCaseTags.isEmpty()) {
|
||||
statusDraft.text += "\n\n";
|
||||
int lenght = 0;
|
||||
for (String tag : camelCaseTags) {
|
||||
|
@ -1819,7 +1820,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
camelCaseTags.add(tag);
|
||||
}
|
||||
}
|
||||
if (camelCaseTags.size() > 0) {
|
||||
if (!camelCaseTags.isEmpty()) {
|
||||
statusList.get(position).tagAdded = true;
|
||||
int lenght = 0;
|
||||
for (String tag : camelCaseTags) {
|
||||
|
@ -1902,7 +1903,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
String[] languagesArr = new String[0];
|
||||
|
||||
int selection = 0;
|
||||
if (storedLanguages != null && storedLanguages.size() > 0) {
|
||||
if (storedLanguages != null && !storedLanguages.isEmpty()) {
|
||||
int i = 0;
|
||||
codesArr = new String[storedLanguages.size()];
|
||||
languagesArr = new String[storedLanguages.size()];
|
||||
|
@ -1915,7 +1916,6 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
i++;
|
||||
}
|
||||
} else {
|
||||
|
||||
List<Languages.Language> languages = Languages.get(context);
|
||||
if (languages != null) {
|
||||
codesArr = new String[languages.size()];
|
||||
|
@ -1936,23 +1936,34 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
|
||||
builder.setTitle(context.getString(R.string.message_language));
|
||||
|
||||
builder.setSingleChoiceItems(languagesArr, selection, null);
|
||||
String[] finalCodesArr = codesArr;
|
||||
builder.setPositiveButton(R.string.validate, (dialog, which) -> {
|
||||
int selectedPosition = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
|
||||
editor.putString(context.getString(R.string.SET_COMPOSE_LANGUAGE) + account.user_id + account.instance, finalCodesArr[selectedPosition]);
|
||||
editor.apply();
|
||||
statusDraft.language = finalCodesArr[selectedPosition];
|
||||
notifyItemChanged(holder.getLayoutPosition());
|
||||
dialog.dismiss();
|
||||
});
|
||||
builder.setNegativeButton(R.string.reset, (dialog, which) -> {
|
||||
editor.putString(context.getString(R.string.SET_COMPOSE_LANGUAGE) + account.user_id + account.instance, null);
|
||||
editor.apply();
|
||||
statusDraft.language = null;
|
||||
notifyItemChanged(holder.getLayoutPosition());
|
||||
dialog.dismiss();
|
||||
});
|
||||
if (storedLanguages == null || storedLanguages.isEmpty()) {
|
||||
builder.setSingleChoiceItems(languagesArr, selection, null);
|
||||
builder.setPositiveButton(R.string.validate, (dialog, which) -> {
|
||||
int selectedPosition = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
|
||||
editor.putString(context.getString(R.string.SET_COMPOSE_LANGUAGE) + account.user_id + account.instance, finalCodesArr[selectedPosition]);
|
||||
editor.apply();
|
||||
statusDraft.language = finalCodesArr[selectedPosition];
|
||||
notifyItemChanged(holder.getLayoutPosition());
|
||||
dialog.dismiss();
|
||||
});
|
||||
builder.setNegativeButton(R.string.reset, (dialog, which) -> {
|
||||
editor.putString(context.getString(R.string.SET_COMPOSE_LANGUAGE) + account.user_id + account.instance, null);
|
||||
editor.apply();
|
||||
statusDraft.language = null;
|
||||
notifyItemChanged(holder.getLayoutPosition());
|
||||
dialog.dismiss();
|
||||
});
|
||||
} else {
|
||||
builder.setSingleChoiceItems(languagesArr, selection, (dialog, which) -> {
|
||||
int selectedPosition = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
|
||||
editor.putString(context.getString(R.string.SET_COMPOSE_LANGUAGE) + account.user_id + account.instance, finalCodesArr[selectedPosition]);
|
||||
editor.apply();
|
||||
statusDraft.language = finalCodesArr[selectedPosition];
|
||||
notifyItemChanged(holder.getLayoutPosition());
|
||||
dialog.dismiss();
|
||||
});
|
||||
}
|
||||
builder.create().show();
|
||||
});
|
||||
}
|
||||
|
@ -1988,6 +1999,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
composePollBinding.option1.textLayout.setHint(context.getString(R.string.poll_choice_s, 1));
|
||||
composePollBinding.option2.text.setFilters(fArray);
|
||||
composePollBinding.option2.textLayout.setHint(context.getString(R.string.poll_choice_s, 2));
|
||||
composePollBinding.option2.textLayout.setHint(context.getString(R.string.poll_choice_s, 2));
|
||||
composePollBinding.option1.buttonRemove.setVisibility(View.GONE);
|
||||
composePollBinding.option2.buttonRemove.setVisibility(View.GONE);
|
||||
int finalMax_entry = max_entry;
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
package app.fedilab.android.mastodon.ui.drawer;
|
||||
/* Copyright 2025 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 <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterInside;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.github.mikephil.charting.components.Description;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.DrawerLinkBinding;
|
||||
import app.fedilab.android.mastodon.activities.MediaActivity;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Attachment;
|
||||
import app.fedilab.android.mastodon.client.entities.api.History;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Link;
|
||||
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
|
||||
import app.fedilab.android.mastodon.helper.Helper;
|
||||
|
||||
public class LinkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private final List<Link> linkList;
|
||||
private Context context;
|
||||
|
||||
public LinkAdapter(List<Link> linkList) {
|
||||
this.linkList = linkList;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return linkList.size();
|
||||
}
|
||||
|
||||
public Link getItem(int position) {
|
||||
return linkList.get(position);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
context = parent.getContext();
|
||||
DrawerLinkBinding itemBinding = DrawerLinkBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new LinkViewHolder(itemBinding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||
Link link = linkList.get(position);
|
||||
LinkViewHolder linkViewHolder = (LinkViewHolder) viewHolder;
|
||||
linkViewHolder.binding.linkTitle.setText(link.title);
|
||||
linkViewHolder.binding.linkDescription.setText(link.description);
|
||||
linkViewHolder.binding.linkAuthor.setText(link.provider_name);
|
||||
|
||||
if(link.author_url != null && link.author_url.startsWith("http")) {
|
||||
linkViewHolder.binding.linkAuthor.setText(link.provider_name + " (" +link.author_name + ")");
|
||||
linkViewHolder.binding.linkAuthor.setOnClickListener(v->{
|
||||
Helper.openBrowser(context, link.author_url);
|
||||
});
|
||||
}
|
||||
|
||||
if(link.image != null) {
|
||||
Glide.with(context).load(link.image) .apply(new RequestOptions().transform(new CenterInside(), new RoundedCorners(10))).into(linkViewHolder.binding.linkImage);
|
||||
linkViewHolder.binding.linkImage.setVisibility(View.VISIBLE);
|
||||
linkViewHolder.binding.linkImage.setOnClickListener(v->{
|
||||
Intent intent = new Intent(context, MediaActivity.class);
|
||||
Bundle args = new Bundle();
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.preview_url = link.image;
|
||||
attachment.url = link.image;
|
||||
attachment.remote_url = link.image;
|
||||
attachment.type = "image";
|
||||
ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
attachments.add(attachment);
|
||||
args.putSerializable(Helper.ARG_MEDIA_ARRAY, attachments);
|
||||
args.putInt(Helper.ARG_MEDIA_POSITION, 1);
|
||||
new CachedBundle(context).insertBundle(args, Helper.getCurrentAccount(context), bundleId -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putLong(Helper.ARG_INTENT_ID, bundleId);
|
||||
intent.putExtras(bundle);
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat
|
||||
.makeSceneTransitionAnimation(((Activity)context), linkViewHolder.binding.linkImage, attachment.url);
|
||||
// start the new activity
|
||||
context.startActivity(intent, options.toBundle());
|
||||
});
|
||||
});
|
||||
} else {
|
||||
linkViewHolder.binding.linkImage.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
|
||||
linkViewHolder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
|
||||
linkViewHolder.binding.dividerCard.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
List<Entry> trendsEntry = new ArrayList<>();
|
||||
|
||||
List<History> historyList = link.history;
|
||||
|
||||
|
||||
|
||||
if (historyList != null) {
|
||||
for (History history : historyList) {
|
||||
trendsEntry.add(0, new Entry(Float.parseFloat(history.day), Float.parseFloat(history.uses)));
|
||||
}
|
||||
}
|
||||
|
||||
LineDataSet dataTrending = new LineDataSet(trendsEntry, context.getString(R.string.trending));
|
||||
dataTrending.setDrawValues(false);
|
||||
dataTrending.setDrawFilled(true);
|
||||
dataTrending.setDrawCircles(false);
|
||||
dataTrending.setDrawCircleHole(false);
|
||||
linkViewHolder.binding.chart.getAxis(YAxis.AxisDependency.LEFT).setEnabled(false);
|
||||
linkViewHolder.binding.chart.getAxis(YAxis.AxisDependency.RIGHT).setEnabled(false);
|
||||
linkViewHolder.binding.chart.getXAxis().setEnabled(false);
|
||||
linkViewHolder.binding.chart.getLegend().setEnabled(false);
|
||||
linkViewHolder.binding.chart.setTouchEnabled(false);
|
||||
dataTrending.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
Description description = linkViewHolder.binding.chart.getDescription();
|
||||
description.setEnabled(false);
|
||||
List<ILineDataSet> dataSets = new ArrayList<>();
|
||||
|
||||
|
||||
dataSets.add(dataTrending);
|
||||
|
||||
LineData data = new LineData(dataSets);
|
||||
linkViewHolder.binding.chart.setData(data);
|
||||
linkViewHolder.binding.chart.invalidate();
|
||||
|
||||
linkViewHolder.binding.getRoot().setOnClickListener(v -> Helper.openBrowser(context, link.url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return linkList.size();
|
||||
}
|
||||
|
||||
|
||||
public static class LinkViewHolder extends RecyclerView.ViewHolder {
|
||||
DrawerLinkBinding binding;
|
||||
|
||||
LinkViewHolder(DrawerLinkBinding itemView) {
|
||||
super(itemView.getRoot());
|
||||
binding = itemView;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,6 +108,7 @@ import com.bumptech.glide.ListPreloader;
|
|||
import com.bumptech.glide.RequestBuilder;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.github.stom79.mytransl.MyTransL;
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.smarteist.autoimageslider.SliderAnimations;
|
||||
import com.smarteist.autoimageslider.SliderView;
|
||||
|
@ -143,6 +144,7 @@ import app.fedilab.android.databinding.LayoutPollItemBinding;
|
|||
import app.fedilab.android.mastodon.activities.ComposeActivity;
|
||||
import app.fedilab.android.mastodon.activities.ContextActivity;
|
||||
import app.fedilab.android.mastodon.activities.CustomSharingActivity;
|
||||
import app.fedilab.android.mastodon.activities.HashTagActivity;
|
||||
import app.fedilab.android.mastodon.activities.MediaActivity;
|
||||
import app.fedilab.android.mastodon.activities.ProfileActivity;
|
||||
import app.fedilab.android.mastodon.activities.ReportActivity;
|
||||
|
@ -508,6 +510,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
LinearLayoutCompat.MarginLayoutParams psc = (LinearLayoutCompat.MarginLayoutParams) holder.binding.statusContent.getLayoutParams();
|
||||
psc.setMarginStart((int) Helper.convertDpToPixel(6, context));
|
||||
holder.binding.statusContent.setLayoutParams(psc);
|
||||
LinearLayoutCompat.MarginLayoutParams pst = (LinearLayoutCompat.MarginLayoutParams) holder.binding.statusHashtags.getLayoutParams();
|
||||
pst.setMarginStart((int) Helper.convertDpToPixel(6, context));
|
||||
holder.binding.statusHashtags.setLayoutParams(pst);
|
||||
LinearLayoutCompat.MarginLayoutParams psq = (LinearLayoutCompat.MarginLayoutParams) holder.binding.quotedMessage.cardviewContainer.getLayoutParams();
|
||||
psq.setMarginStart((int) Helper.convertDpToPixel(6, context));
|
||||
holder.binding.quotedMessage.cardviewContainer.setLayoutParams(psq);
|
||||
|
@ -547,7 +552,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
String loadMediaType = sharedpreferences.getString(context.getString(R.string.SET_LOAD_MEDIA_TYPE), "ALWAYS");
|
||||
boolean pronounsSupport = sharedpreferences.getBoolean(context.getString(R.string.SET_PRONOUNS_SUPPORT), true);
|
||||
if(pronounsSupport) {
|
||||
if (statusToDeal.pronouns == null && statusToDeal.account.fields != null && statusToDeal.account.fields.size() > 0) {
|
||||
if (statusToDeal.pronouns == null && statusToDeal.account != null && statusToDeal.account.fields != null && statusToDeal.account.fields.size() > 0) {
|
||||
for (Field field : statusToDeal.account.fields) {
|
||||
if (PronounsHelper.pronouns.contains(field.name.toLowerCase().trim())) {
|
||||
statusToDeal.pronouns = Helper.parseHtml(field.value);
|
||||
|
@ -1510,6 +1515,37 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()));
|
||||
}),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
boolean underlineBottomHashTags = sharedpreferences.getBoolean(context.getString(R.string.SET_UNDERLINE_BOTTOM_HASHTAGS), true);
|
||||
if(underlineBottomHashTags) {
|
||||
if (statusToDeal.getBottomTags().length > 0) {
|
||||
holder.binding.statusHashtags.setVisibility(View.VISIBLE);
|
||||
holder.binding.statusHashtags.removeAllViews();
|
||||
for (String tag : statusToDeal.getBottomTags()) {
|
||||
Chip chip = new Chip(context);
|
||||
chip.setClickable(true);
|
||||
chip.setEnsureMinTouchTargetSize(false);
|
||||
chip.setText(tag);
|
||||
chip.setTextColor(ThemeHelper.getAttColor(context, R.attr.colorPrimary));
|
||||
chip.setOnClickListener(v -> {
|
||||
Intent intentTag = new Intent(context, HashTagActivity.class);
|
||||
Bundle args = new Bundle();
|
||||
args.putString(Helper.ARG_SEARCH_KEYWORD, tag.replace("#", ""));
|
||||
new CachedBundle(context).insertBundle(args, Helper.getCurrentAccount(context), bundleId -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putLong(Helper.ARG_INTENT_ID, bundleId);
|
||||
intentTag.putExtras(bundle);
|
||||
intentTag.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intentTag);
|
||||
});
|
||||
});
|
||||
holder.binding.statusHashtags.addView(chip);
|
||||
}
|
||||
} else {
|
||||
holder.binding.statusHashtags.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
holder.binding.statusHashtags.setVisibility(View.GONE);
|
||||
}
|
||||
if (truncate_toots_size > 0) {
|
||||
holder.binding.statusContent.setMaxLines(truncate_toots_size);
|
||||
holder.binding.statusContent.setEllipsize(TextUtils.TruncateAt.END);
|
||||
|
@ -1576,6 +1612,15 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
});
|
||||
}
|
||||
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
|
||||
//Release players if they already exist
|
||||
if(holder.binding.mediaContainer.getChildCount() > 0 ) {
|
||||
for(int i = 0 ; i < holder.binding.mediaContainer.getChildCount() ; i++ ) {
|
||||
PlayerView video = holder.binding.mediaContainer.getChildAt(i).findViewById(R.id.media_video);
|
||||
if (video != null && video.getPlayer() != null) {
|
||||
video.getPlayer().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.binding.mediaContainer.removeAllViews();
|
||||
PlayerView video = holder.binding.media.media1Container.findViewById(R.id.media_video);
|
||||
if (video != null && video.getPlayer() != null) {
|
||||
|
@ -1615,7 +1660,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
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;
|
||||
|
@ -2107,7 +2152,11 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
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));
|
||||
|
@ -3580,10 +3629,23 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
public void onViewRecycled(@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
super.onViewRecycled(viewHolder);
|
||||
if (viewHolder instanceof StatusViewHolder holder) {
|
||||
if (holder.binding != null) {
|
||||
PlayerView doubleTapPlayerView = holder.binding.media.getRoot().findViewById(R.id.media_video);
|
||||
if (doubleTapPlayerView != null && doubleTapPlayerView.getPlayer() != null) {
|
||||
doubleTapPlayerView.getPlayer().release();
|
||||
//Release players
|
||||
if (holder.binding != null) { //Cropped views
|
||||
if(holder.binding.media.getRoot().getChildCount() > 0) {
|
||||
for(int i = 0 ; i < holder.binding.media.getRoot().getChildCount() ; i++ ) {
|
||||
PlayerView doubleTapPlayerView = holder.binding.media.getRoot().getChildAt(i).findViewById(R.id.media_video);
|
||||
if (doubleTapPlayerView != null && doubleTapPlayerView.getPlayer() != null) {
|
||||
doubleTapPlayerView.getPlayer().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (holder.binding.mediaContainer.getChildCount() > 0) { //Not cropped views
|
||||
for(int i = 0 ; i < holder.binding.mediaContainer.getChildCount() ; i++ ) {
|
||||
PlayerView doubleTapPlayerView = holder.binding.mediaContainer.getChildAt(i).findViewById(R.id.media_video);
|
||||
if (doubleTapPlayerView != null && doubleTapPlayerView.getPlayer() != null) {
|
||||
doubleTapPlayerView.getPlayer().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -605,7 +605,7 @@ public class StatusDirectMessageAdapter extends RecyclerView.Adapter<RecyclerVie
|
|||
video.getPlayer().release();
|
||||
}
|
||||
holder.binding.media.media4Container.removeAllViews();
|
||||
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);
|
||||
for (Attachment attachment : status.media_attachments) {
|
||||
LayoutMediaBinding layoutMediaBinding = LayoutMediaBinding.inflate(LayoutInflater.from(context));
|
||||
layoutMediaBinding.mediaRoot.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
|
||||
|
|
|
@ -45,6 +45,7 @@ import app.fedilab.android.BaseMainActivity;
|
|||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.DrawerStatusScheduledBinding;
|
||||
import app.fedilab.android.mastodon.activities.ComposeActivity;
|
||||
import app.fedilab.android.mastodon.activities.ContextActivity;
|
||||
import app.fedilab.android.mastodon.client.entities.api.ScheduledStatus;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Tag;
|
||||
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
|
||||
|
@ -61,9 +62,6 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
|
|||
private final List<ScheduledBoost> scheduledBoosts;
|
||||
public ScheduledActions scheduledActions;
|
||||
private Context context;
|
||||
private ScheduledStatus scheduledStatus;
|
||||
private StatusDraft statusDraft;
|
||||
private ScheduledBoost scheduledBoost;
|
||||
|
||||
public StatusScheduledAdapter(List<ScheduledStatus> scheduledStatuses, List<StatusDraft> statusDraftList, List<ScheduledBoost> scheduledBoosts) {
|
||||
this.scheduledStatuses = scheduledStatuses;
|
||||
|
@ -82,32 +80,27 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
|
|||
@Override
|
||||
public void onBindViewHolder(@NonNull StatusScheduledHolder holder, int position) {
|
||||
|
||||
scheduledStatus = null;
|
||||
statusDraft = null;
|
||||
String scheduledDate = null;
|
||||
String statusContent = null;
|
||||
if (scheduledStatuses != null) {
|
||||
scheduledStatus = scheduledStatuses.get(position);
|
||||
scheduledDate = Helper.dateToString(scheduledStatus.scheduled_at);
|
||||
statusContent = scheduledStatus.params.text;
|
||||
if (scheduledStatus.params.in_reply_to_id != null) {
|
||||
if (scheduledStatuses != null && scheduledStatuses.size() > position) {
|
||||
scheduledDate = Helper.dateToString(scheduledStatuses.get(position).scheduled_at);
|
||||
statusContent = scheduledStatuses.get(position).params.text;
|
||||
if (scheduledStatuses.get(position).params.in_reply_to_id != null) {
|
||||
holder.binding.reply.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.reply.setVisibility(View.GONE);
|
||||
}
|
||||
} else if (statusDraftList != null) {
|
||||
statusDraft = statusDraftList.get(position);
|
||||
scheduledDate = Helper.dateToString(statusDraft.scheduled_at);
|
||||
statusContent = statusDraft.statusDraftList.get(0).text;
|
||||
if (statusDraft.statusDraftList.get(0).in_reply_to_id != null) {
|
||||
} else if (statusDraftList != null && statusDraftList.size() > position) {
|
||||
scheduledDate = Helper.dateToString(statusDraftList.get(position).scheduled_at);
|
||||
statusContent = statusDraftList.get(position).statusDraftList.get(0).text;
|
||||
if (statusDraftList.get(position).statusDraftList.get(0).in_reply_to_id != null) {
|
||||
holder.binding.reply.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.reply.setVisibility(View.GONE);
|
||||
}
|
||||
} else if (scheduledBoosts != null) {
|
||||
scheduledBoost = scheduledBoosts.get(position);
|
||||
scheduledDate = Helper.dateToString(scheduledBoost.scheduledAt);
|
||||
if (scheduledBoost.status.in_reply_to_id != null) {
|
||||
} else if (scheduledBoosts != null && scheduledBoosts.size() > position) {
|
||||
scheduledDate = Helper.dateToString(scheduledBoosts.get(position).scheduledAt);
|
||||
if (scheduledBoosts.get(position).status.in_reply_to_id != null) {
|
||||
holder.binding.reply.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.reply.setVisibility(View.GONE);
|
||||
|
@ -116,10 +109,10 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
|
|||
|
||||
holder.binding.date.setText(scheduledDate);
|
||||
|
||||
if (scheduledBoost != null) {
|
||||
if (scheduledBoosts != null && scheduledBoosts.size() > position) {
|
||||
SpannableString statusContentSpan;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
statusContentSpan = new SpannableString(Html.fromHtml(scheduledBoost.status.content, FROM_HTML_MODE_LEGACY));
|
||||
statusContentSpan = new SpannableString(Html.fromHtml(scheduledBoosts.get(position).status.content, FROM_HTML_MODE_LEGACY));
|
||||
else
|
||||
statusContentSpan = new SpannableString(Html.fromHtml(statusContent));
|
||||
holder.binding.statusContent.setText(statusContentSpan, TextView.BufferType.SPANNABLE);
|
||||
|
@ -142,6 +135,17 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
|
|||
intent.putExtras(bundle);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
} else if(scheduledBoosts != null) {
|
||||
Intent intentContext = new Intent(context, ContextActivity.class);
|
||||
Bundle args2 = new Bundle();
|
||||
args2.putSerializable(Helper.ARG_STATUS, scheduledBoosts.get(position).status);
|
||||
new CachedBundle(context).insertBundle(args2, Helper.getCurrentAccount(context), bundleId2 -> {
|
||||
Bundle bundleCached = new Bundle();
|
||||
bundleCached.putLong(Helper.ARG_INTENT_ID, bundleId2);
|
||||
intentContext.putExtras(bundleCached);
|
||||
intentContext.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intentContext);
|
||||
});
|
||||
}
|
||||
});
|
||||
holder.binding.delete.setOnClickListener(v -> {
|
||||
|
@ -149,43 +153,37 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
|
|||
unfollowConfirm.setMessage(context.getString(R.string.remove_scheduled));
|
||||
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
unfollowConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||
if (scheduledStatus != null) {
|
||||
if (scheduledStatuses != null && scheduledStatuses.size() > position) {
|
||||
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
|
||||
statusesVM.deleteScheduledStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, scheduledStatus.id)
|
||||
statusesVM.deleteScheduledStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, scheduledStatuses.get(position).id)
|
||||
.observe((LifecycleOwner) context, unused -> {
|
||||
if (scheduledStatuses != null) {
|
||||
scheduledStatuses.remove(scheduledStatus);
|
||||
if (scheduledStatuses.isEmpty()) {
|
||||
scheduledActions.onAllDeleted();
|
||||
}
|
||||
notifyItemRemoved(position);
|
||||
scheduledStatuses.remove(scheduledStatuses.get(position));
|
||||
if (scheduledStatuses.isEmpty()) {
|
||||
scheduledActions.onAllDeleted();
|
||||
}
|
||||
notifyItemRemoved(position);
|
||||
});
|
||||
} else if (statusDraft != null) {
|
||||
} else if (statusDraftList != null && statusDraftList.size() > position) {
|
||||
try {
|
||||
new StatusDraft(context).removeScheduled(statusDraft);
|
||||
WorkManager.getInstance(context).cancelWorkById(statusDraft.workerUuid);
|
||||
if (statusDraftList != null) {
|
||||
statusDraftList.remove(statusDraft);
|
||||
if (statusDraftList.isEmpty()) {
|
||||
scheduledActions.onAllDeleted();
|
||||
}
|
||||
notifyItemRemoved(position);
|
||||
new StatusDraft(context).removeScheduled(statusDraftList.get(position));
|
||||
WorkManager.getInstance(context).cancelWorkById(statusDraftList.get(position).workerUuid);
|
||||
statusDraftList.remove(statusDraftList.get(position));
|
||||
if (statusDraftList.isEmpty()) {
|
||||
scheduledActions.onAllDeleted();
|
||||
}
|
||||
notifyItemRemoved(position);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (scheduledBoost != null) {
|
||||
} else if (scheduledBoosts != null && position < scheduledBoosts.size()) {
|
||||
try {
|
||||
new ScheduledBoost(context).removeScheduled(scheduledBoost);
|
||||
WorkManager.getInstance(context).cancelWorkById(scheduledBoost.workerUuid);
|
||||
if (scheduledBoosts != null) {
|
||||
scheduledBoosts.remove(scheduledBoost);
|
||||
if (scheduledBoosts.isEmpty()) {
|
||||
scheduledActions.onAllDeleted();
|
||||
}
|
||||
notifyItemRemoved(position);
|
||||
new ScheduledBoost(context).removeScheduled(scheduledBoosts.get(position));
|
||||
WorkManager.getInstance(context).cancelWorkById(scheduledBoosts.get(position).workerUuid);
|
||||
scheduledBoosts.remove(scheduledBoosts.get(position));
|
||||
if (scheduledBoosts.isEmpty()) {
|
||||
scheduledActions.onAllDeleted();
|
||||
}
|
||||
notifyItemRemoved(position);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package app.fedilab.android.mastodon.ui.fragment.media;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ public class FragmentMediaProfile extends Fragment {
|
|||
public void federatedAccount(Account account) {
|
||||
if (account != null && isAdded() && !requireActivity().isFinishing()) {
|
||||
accountId = account.id;
|
||||
accountsVM.getAccountStatuses(tempInstance, null, accountId, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(tempInstance, null, accountId, null, null, null, null, null, true, false, null, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), statuses -> initializeStatusesCommonView(statuses));
|
||||
} else {
|
||||
if (isAdded() && !requireActivity().isFinishing()) {
|
||||
|
@ -141,7 +141,7 @@ public class FragmentMediaProfile extends Fragment {
|
|||
tempToken = BaseMainActivity.currentToken;
|
||||
tempInstance = BaseMainActivity.currentInstance;
|
||||
accountId = accountTimeline.id;
|
||||
accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, null, null, true, false, null, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ public class FragmentMediaProfile extends Fragment {
|
|||
if (!flagLoading) {
|
||||
flagLoading = true;
|
||||
binding.loadingNextElements.setVisibility(View.VISIBLE);
|
||||
accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, max_id, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, max_id, null, null, null, null, true, false, null, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), newStatuses -> dealWithPagination(newStatuses));
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -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<String> 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
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
package app.fedilab.android.mastodon.ui.fragment.timeline;
|
||||
/* Copyright 2025 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 <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.FragmentPaginationBinding;
|
||||
import app.fedilab.android.mastodon.activities.SearchResultTabActivity;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Link;
|
||||
import app.fedilab.android.mastodon.helper.MastodonHelper;
|
||||
import app.fedilab.android.mastodon.ui.drawer.LinkAdapter;
|
||||
import app.fedilab.android.mastodon.viewmodel.mastodon.TimelinesVM;
|
||||
|
||||
|
||||
public class FragmentMastodonLink extends Fragment {
|
||||
|
||||
|
||||
private FragmentPaginationBinding binding;
|
||||
private LinkAdapter linkAdapter;
|
||||
private Integer offset;
|
||||
private boolean flagLoading;
|
||||
private List<Link> linkList;
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
binding = FragmentPaginationBinding.inflate(inflater, container, false);
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
|
||||
boolean displayScrollBar = sharedpreferences.getBoolean(getString(R.string.SET_TIMELINE_SCROLLBAR), false);
|
||||
binding.recyclerView.setVerticalScrollBarEnabled(displayScrollBar);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
binding.loader.setVisibility(View.VISIBLE);
|
||||
binding.recyclerView.setVisibility(View.GONE);
|
||||
offset = 0;
|
||||
flagLoading = false;
|
||||
binding.swipeContainer.setRefreshing(false);
|
||||
binding.swipeContainer.setEnabled(false);
|
||||
router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Router for timelines
|
||||
*/
|
||||
private void router() {
|
||||
TimelinesVM timelinesVM = new ViewModelProvider(FragmentMastodonLink.this).get(TimelinesVM.class);
|
||||
timelinesVM.getLinksTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, offset, MastodonHelper.SEARCH_PER_CALL)
|
||||
.observe(getViewLifecycleOwner(), links -> {
|
||||
if (links != null && offset == 0) {
|
||||
initializeLinkCommonView(links);
|
||||
} else if (links != null) {
|
||||
dealWithPaginationTag(links);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void scrollToTop() {
|
||||
binding.recyclerView.setAdapter(linkAdapter);
|
||||
}
|
||||
|
||||
private void dealWithPaginationTag(final List<Link> links) {
|
||||
if (binding == null || !isAdded() || getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
if (links == null || links.isEmpty()) {
|
||||
flagLoading = true;
|
||||
binding.loadingNextElements.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
offset += MastodonHelper.SEARCH_PER_CALL;
|
||||
binding.swipeContainer.setRefreshing(false);
|
||||
binding.loadingNextElements.setVisibility(View.GONE);
|
||||
flagLoading = false;
|
||||
int start = linkList.size();
|
||||
linkList.addAll(links);
|
||||
linkAdapter.notifyItemRangeInserted(start, links.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the view for links
|
||||
*
|
||||
* @param links List of {@link Link}
|
||||
*/
|
||||
private void initializeLinkCommonView(final List<Link> links) {
|
||||
if (binding == null || !isAdded() || getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
linkList = new ArrayList<>();
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
binding.noAction.setVisibility(View.GONE);
|
||||
binding.swipeContainer.setRefreshing(false);
|
||||
binding.swipeContainer.setOnRefreshListener(() -> {
|
||||
binding.swipeContainer.setRefreshing(true);
|
||||
router();
|
||||
});
|
||||
if (links == null || links.isEmpty()) {
|
||||
if (requireActivity() instanceof SearchResultTabActivity) {
|
||||
((SearchResultTabActivity) requireActivity()).tagEmpty = true;
|
||||
if (((SearchResultTabActivity) requireActivity()).accountEmpty != null) {
|
||||
if (((SearchResultTabActivity) requireActivity()).accountEmpty) {
|
||||
((SearchResultTabActivity) requireActivity()).moveToMessage();
|
||||
} else {
|
||||
((SearchResultTabActivity) requireActivity()).moveToAccount();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
binding.recyclerView.setVisibility(View.GONE);
|
||||
binding.noAction.setVisibility(View.VISIBLE);
|
||||
binding.noActionText.setText(R.string.no_tags);
|
||||
return;
|
||||
}
|
||||
offset += MastodonHelper.SEARCH_PER_CALL;
|
||||
binding.recyclerView.setVisibility(View.VISIBLE);
|
||||
binding.noAction.setVisibility(View.GONE);
|
||||
linkList.addAll(links);
|
||||
linkAdapter = new LinkAdapter(linkList);
|
||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(requireActivity());
|
||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||
binding.recyclerView.setAdapter(linkAdapter);
|
||||
binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if (dy > 0) {
|
||||
int visibleItemCount = mLayoutManager.getChildCount();
|
||||
int totalItemCount = mLayoutManager.getItemCount();
|
||||
|
||||
if (firstVisibleItem + visibleItemCount == totalItemCount) {
|
||||
if (!flagLoading) {
|
||||
flagLoading = true;
|
||||
binding.loadingNextElements.setVisibility(View.VISIBLE);
|
||||
router();
|
||||
}
|
||||
} else {
|
||||
binding.loadingNextElements.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
@ -89,6 +91,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
private Integer offset;
|
||||
private StatusAdapter statusAdapter;
|
||||
private Timeline.TimeLineEnum timelineType;
|
||||
private String tagged;
|
||||
private List<Status> timelineStatuses;
|
||||
//Handle actions that can be done in other fragments
|
||||
private final BroadcastReceiver receive_action = new BroadcastReceiver() {
|
||||
|
@ -416,6 +419,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
lemmy_post_id = bundle.getString(Helper.ARG_LEMMY_POST_ID, null);
|
||||
list_id = bundle.getString(Helper.ARG_LIST_ID, null);
|
||||
search = bundle.getString(Helper.ARG_SEARCH_KEYWORD, null);
|
||||
tagged = bundle.getString(Helper.ARG_TAGGED, null);
|
||||
searchCache = bundle.getString(Helper.ARG_SEARCH_KEYWORD_CACHE, null);
|
||||
pinnedTimeline = (PinnedTimeline) bundle.getSerializable(Helper.ARG_REMOTE_INSTANCE);
|
||||
canBeFederated = true;
|
||||
|
@ -571,9 +575,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 +639,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 +730,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 +767,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 +1140,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);
|
||||
|
@ -1164,8 +1173,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
public void federatedAccount(Account account) {
|
||||
if (account != null && isAdded() && !requireActivity().isFinishing()) {
|
||||
accountIDInRemoteInstance = account.id;
|
||||
accountsVM.getAccountStatuses(tempInstance[0], null, accountIDInRemoteInstance, null, null, null, null, null, false, true, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(tempInstance[0], null, accountIDInRemoteInstance, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(tempInstance[0], null, accountIDInRemoteInstance, null, null, null, null, null, false, true, tagged, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(tempInstance[0], null, accountIDInRemoteInstance, null, null, null, exclude_replies, exclude_reblogs, media_only, false, tagged, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), otherStatuses -> {
|
||||
if (otherStatuses != null && otherStatuses.statuses != null) {
|
||||
if (pinnedStatuses != null && pinnedStatuses.statuses != null) {
|
||||
|
@ -1197,9 +1206,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 +1234,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 +1248,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 +1259,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 +1270,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);
|
||||
|
@ -1294,8 +1317,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
if (direction == null && !checkRemotely) {
|
||||
if (show_pinned) {
|
||||
//Fetch pinned statuses to display them at the top
|
||||
accountsVM.getAccountStatuses(currentInstance, MainActivity.currentToken, accountId, null, null, null, null, null, false, true, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountId, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(currentInstance, MainActivity.currentToken, accountId, null, null, null, null, null, false, true, tagged, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountId, null, null, null, exclude_replies, exclude_reblogs, media_only, false, tagged, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), otherStatuses -> {
|
||||
if (otherStatuses != null && otherStatuses.statuses != null && pinnedStatuses != null && pinnedStatuses.statuses != null) {
|
||||
for (Status status : pinnedStatuses.statuses) {
|
||||
|
@ -1306,11 +1329,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
}
|
||||
}));
|
||||
} else {
|
||||
accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, null, null, null, exclude_replies, exclude_reblogs, media_only, false, tagged, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
||||
}
|
||||
} else if (direction == DIRECTION.BOTTOM) {
|
||||
accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, max_id, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, max_id, null, null, exclude_replies, exclude_reblogs, media_only, false, tagged, MastodonHelper.statusesPerCall(requireActivity()))
|
||||
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false, true, fetchStatus));
|
||||
} else {
|
||||
flagLoading = false;
|
||||
|
|
|
@ -20,12 +20,14 @@ import android.net.Uri;
|
|||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.net.IDN;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -251,6 +253,7 @@ public class AccountsVM extends AndroidViewModel {
|
|||
* @param sensitive Whether to mark authored statuses as sensitive by default.
|
||||
* @param language Default language to use for authored statuses. (ISO 6391)
|
||||
* @param fields Profile metadata name (By default, max 4 fields and 255 characters per property/value)
|
||||
* @param featuredHashtags Featured hashtags that will be displayed on the profile
|
||||
* @return {@link LiveData} containing an {@link Account}
|
||||
*/
|
||||
public LiveData<Account> updateCredentials(@NonNull String instance, String token,
|
||||
|
@ -262,10 +265,15 @@ public class AccountsVM extends AndroidViewModel {
|
|||
String privacy,
|
||||
Boolean sensitive,
|
||||
String language,
|
||||
LinkedHashMap<Integer, Field.FieldParams> fields
|
||||
LinkedHashMap<Integer, Field.FieldParams> fields,
|
||||
List<String> featuredHashtags
|
||||
) {
|
||||
MastodonAccountsService mastodonAccountsService = init(instance);
|
||||
accountMutableLiveData = new MutableLiveData<>();
|
||||
if(featuredHashtags == null) {
|
||||
featuredHashtags = new ArrayList<>();
|
||||
}
|
||||
List<String> finalFeaturedHashtags = featuredHashtags;
|
||||
new Thread(() -> {
|
||||
Account account = null;
|
||||
Account.AccountParams accountParams = new Account.AccountParams();
|
||||
|
@ -291,6 +299,46 @@ public class AccountsVM extends AndroidViewModel {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Call<List<FeaturedTag>> featuredTagsCall = mastodonAccountsService.getFeaturedTags(token);
|
||||
try {
|
||||
Response<List<FeaturedTag>> featuredTagsResponse = featuredTagsCall.execute();
|
||||
if (featuredTagsResponse.isSuccessful()) {
|
||||
List<FeaturedTag> currentFeaturedTags = featuredTagsResponse.body();
|
||||
if(currentFeaturedTags == null) {
|
||||
currentFeaturedTags = new ArrayList<>();
|
||||
}
|
||||
List<String> currentTags = new ArrayList<>();
|
||||
for(FeaturedTag featuredTag: currentFeaturedTags) {
|
||||
currentTags.add(featuredTag.name);
|
||||
}
|
||||
List<String> toRemove = new ArrayList<>();
|
||||
List<String> toAdd = new ArrayList<>();
|
||||
for(String value: currentTags) {
|
||||
if(!finalFeaturedHashtags.contains(value)){
|
||||
toRemove.add(value);
|
||||
}
|
||||
}
|
||||
for(String value: finalFeaturedHashtags) {
|
||||
if(!currentTags.contains(value)){
|
||||
toAdd.add(value);
|
||||
}
|
||||
}
|
||||
for(String remove: toRemove) {
|
||||
for(FeaturedTag featuredTag: currentFeaturedTags) {
|
||||
if(featuredTag.name.trim().equalsIgnoreCase(remove.trim())) {
|
||||
mastodonAccountsService.removeFeaturedTag(token, featuredTag.id).execute();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(String add: toAdd) {
|
||||
mastodonAccountsService.addFeaturedTag(token, add).execute();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Account finalAccount = account;
|
||||
Runnable myRunnable = () -> accountMutableLiveData.setValue(finalAccount);
|
||||
|
@ -372,6 +420,7 @@ public class AccountsVM extends AndroidViewModel {
|
|||
Boolean excludeReblogs,
|
||||
Boolean only_media,
|
||||
Boolean pinned,
|
||||
String tagged,
|
||||
int count) {
|
||||
statusesMutableLiveData = new MutableLiveData<>();
|
||||
MastodonAccountsService mastodonAccountsService = init(instance);
|
||||
|
@ -379,7 +428,7 @@ public class AccountsVM extends AndroidViewModel {
|
|||
List<Status> statusList = null;
|
||||
Pagination pagination = null;
|
||||
Call<List<Status>> accountStatusesCall = mastodonAccountsService.getAccountStatuses(
|
||||
token, id, maxId, sinceId, minId, excludeReplies, excludeReblogs, only_media, pinned, count);
|
||||
token, id, maxId, sinceId, minId, excludeReplies, excludeReblogs, only_media, pinned, tagged, count);
|
||||
if (accountStatusesCall != null) {
|
||||
try {
|
||||
Response<List<Status>> accountStatusesResponse = accountStatusesCall.execute();
|
||||
|
|
|
@ -49,6 +49,7 @@ import app.fedilab.android.mastodon.client.endpoints.MastodonTimelinesService;
|
|||
import app.fedilab.android.mastodon.client.entities.api.Account;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Conversation;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Conversations;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Link;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Marker;
|
||||
import app.fedilab.android.mastodon.client.entities.api.MastodonList;
|
||||
import app.fedilab.android.mastodon.client.entities.api.Pagination;
|
||||
|
@ -95,6 +96,7 @@ public class TimelinesVM extends AndroidViewModel {
|
|||
private MutableLiveData<Marker> markerMutableLiveData;
|
||||
private MutableLiveData<List<Status>> statusListMutableLiveData;
|
||||
private MutableLiveData<List<Tag>> tagListMutableLiveData;
|
||||
private MutableLiveData<List<Link>> linkListMutableLiveData;
|
||||
|
||||
public TimelinesVM(@NonNull Application application) {
|
||||
super(application);
|
||||
|
@ -244,6 +246,30 @@ public class TimelinesVM extends AndroidViewModel {
|
|||
return tagListMutableLiveData;
|
||||
}
|
||||
|
||||
public LiveData<List<Link>> getLinksTrends(String token, @NonNull String instance, Integer offset, Integer limit) {
|
||||
MastodonTimelinesService mastodonTimelinesService = init(instance);
|
||||
linkListMutableLiveData = new MutableLiveData<>();
|
||||
new Thread(() -> {
|
||||
Call<List<Link>> publicTlCall = mastodonTimelinesService.getLinkTrends(token, offset, limit);
|
||||
List<Link> linkList = null;
|
||||
if (publicTlCall != null) {
|
||||
try {
|
||||
Response<List<Link>> publicTlResponse = publicTlCall.execute();
|
||||
if (publicTlResponse.isSuccessful()) {
|
||||
linkList = publicTlResponse.body();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
List<Link> finalLinkList = linkList;
|
||||
Runnable myRunnable = () -> linkListMutableLiveData.setValue(finalLinkList);
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
return linkListMutableLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public timeline for Nitter
|
||||
*
|
||||
|
|
|
@ -22,13 +22,12 @@ import android.content.Context;
|
|||
import android.os.Build;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import com.google.android.material.chip.Chip;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
@ -39,7 +38,6 @@ import java.util.List;
|
|||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.DrawerInstancePeertubeBinding;
|
||||
import app.fedilab.android.peertube.client.data.InstanceData.Instance;
|
||||
import app.fedilab.android.peertube.helper.RoundedBackgroundSpan;
|
||||
|
||||
|
||||
public class InstanceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
@ -95,28 +93,22 @@ public class InstanceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
holder.binding.name.setText(instance.getName());
|
||||
holder.binding.host.setText(instance.getHost());
|
||||
|
||||
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
|
||||
String between = "";
|
||||
holder.binding.chips.removeAllViews();
|
||||
if (peertubeInformation != null && peertubeInformation.getCategories() != null) {
|
||||
LinkedHashMap<Integer, String> info_cat = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
if (instance.getCategories() != null && instance.getCategories().size() > 0 && instance.getSpannableStringBuilder() == null) {
|
||||
for (int category : instance.getCategories()) {
|
||||
String cat = info_cat.get(category);
|
||||
stringBuilder.append(between);
|
||||
if (cat != null && cat.trim().toLowerCase().compareTo("null") != 0) {
|
||||
if (between.length() == 0) between = " ";
|
||||
String tag = " " + cat + " ";
|
||||
stringBuilder.append(tag);
|
||||
stringBuilder.setSpan(new RoundedBackgroundSpan(context), stringBuilder.length() - tag.length(), stringBuilder.length() - tag.length() + tag.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
Chip chip = new Chip(context);
|
||||
chip.setClickable(false);
|
||||
chip.setEnsureMinTouchTargetSize(false);
|
||||
chip.setText(cat);
|
||||
holder.binding.chips.addView(chip);
|
||||
}
|
||||
}
|
||||
instance.setSpannableStringBuilder(stringBuilder);
|
||||
}
|
||||
}
|
||||
if (instance.getSpannableStringBuilder() != null) {
|
||||
holder.binding.tags.setText(instance.getSpannableStringBuilder());
|
||||
}
|
||||
|
||||
if (peertubeInformation != null && peertubeInformation.getLanguages() != null) {
|
||||
LinkedHashMap<String, String> info_lang = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2025 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 <http://www.gnu.org/licenses>
|
||||
-->
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_marginTop="6dp"
|
||||
app:cardElevation="0dp"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
tools:text="@tools:sample/first_names" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/remove"
|
||||
android:layout_marginStart="5dp"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:contentDescription="@string/delete_field"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:padding="0dp"
|
||||
android:textColor="?colorError"
|
||||
app:icon="@drawable/ic_compose_attachment_remove"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconTint="?colorError"
|
||||
app:layout_constraintStart_toStartOf="@id/banner_pp"
|
||||
app:layout_constraintTop_toTopOf="@id/banner_pp"
|
||||
app:strokeColor="?colorError" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -55,6 +55,7 @@
|
|||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:layout_marginStart="5dp"
|
||||
android:id="@+id/remove"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:layout_width="36dp"
|
||||
|
|
|
@ -161,32 +161,160 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/acct"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/fields"
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/fields_main_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/bio">
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/bio"
|
||||
>
|
||||
<View
|
||||
android:id="@+id/fields_border_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:background="@drawable/translation_border"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/fields_border_top" />
|
||||
|
||||
<androidx.constraintlayout.widget.Placeholder
|
||||
android:id="@+id/fields_border_top"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/fields_label"
|
||||
app:layout_constraintEnd_toEndOf="@id/fields_label"
|
||||
app:layout_constraintTop_toTopOf="@id/fields_label" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/fields_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:background="?colorSurface"
|
||||
android:elevation="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/fields_title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/fields_container"
|
||||
android:id="@+id/fields"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:padding="5dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/fields_label">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/add_field"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/fields_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/add_field"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:text="@string/add_field"
|
||||
app:icon="@drawable/ic_baseline_add_24" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/featured_hashtags_main_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/fields_main_container"
|
||||
>
|
||||
<View
|
||||
android:id="@+id/featured_hashtags_border_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:background="@drawable/translation_border"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/featured_hashtags_border_top" />
|
||||
|
||||
<androidx.constraintlayout.widget.Placeholder
|
||||
android:id="@+id/featured_hashtags_border_top"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/featured_hashtags_label"
|
||||
app:layout_constraintEnd_toEndOf="@id/featured_hashtags_label"
|
||||
app:layout_constraintTop_toTopOf="@id/featured_hashtags_label" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/featured_hashtags_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:text="@string/add_field"
|
||||
app:icon="@drawable/ic_baseline_add_24" />
|
||||
android:background="?colorSurface"
|
||||
android:elevation="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/featured_hashtags_title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/featured_hashtags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:padding="5dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/featured_hashtags_label">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/Suggestions"/>
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/featured_hashtags_suggestions"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/Suggestions"/>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_marginTop="5dp"
|
||||
android:id="@+id/featured_hashtags_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/add_featured_hashtags"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:text="@string/add_featured_hashtag"
|
||||
app:icon="@drawable/ic_baseline_add_24" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/visibility_label"
|
||||
|
@ -196,7 +324,7 @@
|
|||
android:layout_marginTop="12dp"
|
||||
android:text="@string/toots_visibility_title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintTop_toBottomOf="@id/fields" />
|
||||
app:layout_constraintTop_toBottomOf="@id/featured_hashtags_main_container" />
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/visibility_group"
|
||||
|
|
|
@ -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 @@
|
|||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/description_container"
|
||||
android:fitsSystemWindows="true"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:background="#AA000000"
|
||||
|
|
|
@ -375,6 +375,27 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/info" />
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/featured_hashtags_container"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/fields_container">
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/featured_hashtags"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:chipSpacingHorizontal="6dp"
|
||||
app:chipSpacingVertical="6dp"
|
||||
/>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
|
@ -388,7 +409,7 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/fields_container"
|
||||
app:layout_constraintTop_toBottomOf="@+id/featured_hashtags_container"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:gravity="end|center_vertical"
|
||||
android:minHeight="20dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:padding="5dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp" />
|
||||
|
@ -20,17 +21,19 @@
|
|||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/valueBG"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/value"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingTop="10dp"
|
||||
android:drawablePadding="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textIsSelectable="true" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
|
88
app/src/main/res/layouts/mastodon/layout/drawer_link.xml
Normal file
88
app/src/main/res/layouts/mastodon/layout/drawer_link.xml
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2025 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 <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/cardview_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/card_margin"
|
||||
android:layout_marginTop="@dimen/card_margin"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:cardElevation="0dp"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/divider_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="?colorOutline" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/fab_margin"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingEnd="@dimen/fab_margin">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/link_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/link_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/count"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textSize="25sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/link_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/link_image" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/link_author"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical" />
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/chart"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="50dp" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -281,6 +281,18 @@
|
|||
tools:maxLines="10"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/status_hashtags"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
app:chipSpacingHorizontal="6dp"
|
||||
app:chipSpacingVertical="6dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/description"/>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/status_content_maths"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -725,6 +737,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@string/action_quote"
|
||||
android:visibility="gone"
|
||||
app:icon="@drawable/ic_baseline_format_quote_24"
|
||||
app:iconGravity="textStart"
|
||||
app:iconSize="28dp"
|
||||
|
@ -851,6 +864,7 @@
|
|||
app:layout_constraintWidth_max="48dp" />
|
||||
|
||||
<androidx.constraintlayout.helper.widget.Flow
|
||||
android:id="@+id/action_buttons_flow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:constraint_referenced_ids="action_button_reply_container,action_button_boost_container,action_button_quote,action_button_favorite_container,action_button_bookmark,action_button_translate,action_button_maths,status_add_custom_emoji,status_emoji,action_button_more"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/media"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -16,6 +16,9 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Fedilab.DrawerMedia"
|
||||
app:strokeColor="?colorOutline"
|
||||
app:strokeWidth="1dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
|
|
|
@ -14,91 +14,108 @@
|
|||
You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main_container"
|
||||
style="@style/Widget.Material3.CardView.Outlined"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:divider="?android:dividerHorizontal"
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="end">
|
||||
android:layout_marginVertical="6dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="12dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
app:layout_constraintBottom_toTopOf="@id/host"
|
||||
app:layout_constraintEnd_toStartOf="@id/pickup"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/cities" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/host"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
app:layout_constraintStart_toEndOf="@+id/name"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toTopOf="@id/barrier_1"
|
||||
app:layout_constraintEnd_toStartOf="@id/pickup"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/name" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/followers_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:drawablePadding="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_group_24"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tags" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/languages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:drawablePadding="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_forum_24"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/followers_instance" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/sensitive_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/languages" />
|
||||
app:layout_constraintTop_toBottomOf="@id/name"
|
||||
tools:text="@tools:sample/cities" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/pickup"
|
||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:text="@string/pickup_instance"
|
||||
app:icon="@drawable/ic_navigate_next"
|
||||
app:iconGravity="end"
|
||||
app:layout_constraintBottom_toTopOf="@id/barrier_1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sensitive_content" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier_1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="host,pickup" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintTop_toBottomOf="@id/barrier_1"
|
||||
tools:maxLines="4"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chips"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
app:chipSpacingHorizontal="6dp"
|
||||
app:chipSpacingVertical="6dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/description">
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/followers_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:drawablePadding="12dp"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_group_24"
|
||||
app:layout_constraintTop_toBottomOf="@id/chips" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/languages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:drawablePadding="12dp"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_forum_24"
|
||||
app:layout_constraintTop_toBottomOf="@id/followers_instance" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/sensitive_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/languages" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -68,7 +68,7 @@
|
|||
<string name="favourite_remove">هل تود إزالة هذه الرسالة من مفضلاتك؟</string>
|
||||
<string name="reblog_add">هل تود إعادة مشاركة هذه الرسالة؟</string>
|
||||
<string name="reblog_remove">هل تود إلغاء إعادة مشاركة هذه الرسالة؟</string>
|
||||
<string name="more_action_1">كتم</string>
|
||||
<string name="more_action_1">الكتم</string>
|
||||
<string name="more_action_2">حظر</string>
|
||||
<string name="more_action_3">الإبلاغ عنه</string>
|
||||
<string name="more_action_4">حذف</string>
|
||||
|
@ -179,7 +179,7 @@
|
|||
<string name="notif_status">أنشأ رسالة جديدة</string>
|
||||
<string name="notif_reblog">رقى تبويقك</string>
|
||||
<string name="notif_favourite">أُعجِب بتبويقك</string>
|
||||
<string name="notif_follow">يتابعك</string>
|
||||
<string name="notif_follow">يُتابعك</string>
|
||||
<string name="notif_follow_request">طلب متابَعتك</string>
|
||||
<string name="delete_notification_ask_all">هل تود حذف كافة الإشعارات؟</string>
|
||||
<string name="delete_notification_all">تم حذف جميع الإشعارات بنجاح!</string>
|
||||
|
@ -241,7 +241,7 @@
|
|||
</string-array>
|
||||
<string name="action_follow">متابعة</string>
|
||||
<string name="action_unblock">إلغاء الحظر</string>
|
||||
<string name="action_mute">كتم</string>
|
||||
<string name="action_mute">كتم الصوت</string>
|
||||
<string name="action_unmute">إلغاء الكتم</string>
|
||||
<string name="request_sent">تم إرسال الطلب</string>
|
||||
<string name="followed_by">يتابعك</string>
|
||||
|
@ -605,7 +605,7 @@
|
|||
<string name="replace_instagram">انستغرام</string>
|
||||
<string name="replace_twitter_description">استخدام واجهة أمامية بديلة لتويتر</string>
|
||||
<string name="replace_instagram_description">استخدام واجهة أمامية بديلة لـ Instagram</string>
|
||||
<string name="hide_content">إخفاء المحتوى <</string>
|
||||
<string name="hide_content"><![CDATA[إخفاء المحتوى <]]></string>
|
||||
<string name="set_accounts_page">عدد الحسابات لكل تحميل</string>
|
||||
<string name="replace_youtube_host">نطاق الواجهة الأمامية لـ YouTube</string>
|
||||
<string name="replace_reddit">ريديت</string>
|
||||
|
@ -619,7 +619,7 @@
|
|||
<string name="data_export_settings_success">تم تصدير الإعدادات بنجاح</string>
|
||||
<string name="data_import_settings_success">تم استيراد الإعدادات بنجاح</string>
|
||||
<string name="followers_only">المتابِعون فقط</string>
|
||||
<string name="show_content">إظهار المحتوى></string>
|
||||
<string name="show_content">إظهار المحتوى ></string>
|
||||
<string name="stop_recording">إيقاف التسجيل</string>
|
||||
<string name="replace_instagram_host">نطاق الواجهة الأمامية لـ Instagram</string>
|
||||
<string name="toots_visibility_title">مدى رؤية الرسائل بشكل افتراضي:</string>
|
||||
|
@ -680,7 +680,7 @@
|
|||
<string name="account_unsuspended">الحساب غير معلّق</string>
|
||||
<string name="account_suspended">تم تعليق الحساب</string>
|
||||
<string name="account_disabled">تم تعطيل الحساب</string>
|
||||
<string name="state">الحالة</string>
|
||||
<string name="state">الحَالة</string>
|
||||
<string name="restart_the_app">إعادة تشغيل التطبيق؟</string>
|
||||
<string name="restart_the_app_theme">تحتاج إلى إعادة تشغيل التطبيق لتفعيل التغييرات.</string>
|
||||
<string name="set_language_picker_title">اللغات في المُنتَقي</string>
|
||||
|
@ -860,7 +860,7 @@
|
|||
<string name="set_autoplay_gif">تشغيل الوسائط المتحركة آليا</string>
|
||||
<string name="thumbnail">الصورة المصغرة</string>
|
||||
<string name="set_alt_text_mandatory_warn">تنبيه فقط</string>
|
||||
<string name="permission_missing">لم يتم منح الإذن</string>
|
||||
<string name="permission_missing">لم يتم منح الإذن!</string>
|
||||
<string name="about_mastodon">\"ماستدون ليس موقعا شبكيا واحدا مثل تويتر أو فيسبوك، بل هو شبكة من آلاف المجتمعات المحلية التي تديرها مختلف المنظمات والأفراد الذين يقدمون تجربة إعلامية اجتماعية مميزة.\"</string>
|
||||
<string name="push_distributors">موزع الإشعارات</string>
|
||||
<string name="report_indication_title_status">أخبرنا ما الخَطب مع هذا المنشور</string>
|
||||
|
@ -913,4 +913,208 @@
|
|||
<string name="display_remote_conversation">إظهار المحادثة البُعدية</string>
|
||||
<string name="add_keyword">إضافة كلمة مفتاحية</string>
|
||||
<string name="silenced">تم كتمه</string>
|
||||
<string name="twitter_tags">وسوم تويتر (عبر Nitter)</string>
|
||||
<string name="report_1_block">لن ترى منشوراتهم. لن يتمكنوا من رؤية منشوراتك أو متابعتك. سيتمكنون من معرفة أنهم محظورون.</string>
|
||||
<string name="delete_cache_message">هل أنت متأكد أنك تريد حذف الذاكرة المؤقتة؟ إذا كانت لديك مسودات تحتوي على وسائط، فستفقد الوسائط المرفقة.</string>
|
||||
<string name="messages_stored_in_drafts">الرسائل المخزنة في المسودات</string>
|
||||
<string name="set_single_topbar">عند التمكين، سيكون للتطبيق شريط واحد فقط للخطوط الزمنية</string>
|
||||
<string name="set_display_relative_date">عرض التاريخ النسبي للرسائل</string>
|
||||
<string name="set_use_cache_indication">سيتم تخزين الخطوط الزمنية مؤقتًا حتى يكون التطبيق أسرع.</string>
|
||||
<string name="set_display_counters_description">سيعرض عداد فقاعات في علامات تبويب الخطوط الزمنية للرسائل الجديدة</string>
|
||||
<string name="unblock_domain_confirm">هل أنت متأكد من إلغاء حظر %1$s؟</string>
|
||||
<string name="action_pinned_delete">حذف الخطوط الزمنية المثبتة؟</string>
|
||||
<string name="thread_long_message_message">سيتم تقسيم الرسالة إلى عدة ردود لتتوافق مع الحد الأقصى لعدد الأحرف في خادمك.</string>
|
||||
<string name="set_cardview">بطاقات مرتفعة</string>
|
||||
<string name="toast_on_your_instance">بدأت المحادثة على خادمك!</string>
|
||||
<string name="set_remove_left_margin">إزالة الهامش الأيسر في الخطوط الزمنية لجعل الرسائل أكثر إحكامًا</string>
|
||||
<string name="exclude_visibility">استبعاد مستوى الرؤية</string>
|
||||
<string name="self">ذاتي</string>
|
||||
<string name="hide_single_media_with_card">إخفاء الوسائط المفردة عند وجود معاينة رابط</string>
|
||||
<string name="set_mention_at_top">الإشارات في الأعلى</string>
|
||||
<string name="number_of_replies">عدد الردود</string>
|
||||
<string name="update_date">تاريخ التحديث</string>
|
||||
<string name="tags_renamed">تم تغيير الوسم!</string>
|
||||
<string name="tags_deleted">تمت إزالة الوسم!</string>
|
||||
<string name="underline_links">تسطير العناصر القابلة للنقر</string>
|
||||
<string name="chart_home_cache_logs">سجلات الذاكرة المؤقتة للرئيسية</string>
|
||||
<string name="local_only">محلي فقط</string>
|
||||
<string name="instance_health_indication">الإصدار: %s \n %s مستخدم - %s حالة</string>
|
||||
<string name="qr_code_generator">مولد رمز الاستجابة السريعة</string>
|
||||
<string name="approved">موافق عليه</string>
|
||||
<string name="icons_extra_features_visibility_summary">إذا كان خادمك لا يقبل بعض الميزات الإضافية، يمكنك إخفاء هذه الأيقونات</string>
|
||||
<string name="account_silenced">تم إسكات الحساب</string>
|
||||
<string name="report">إبلاغ</string>
|
||||
<string name="notif_signed_up">تم التسجيل</string>
|
||||
<string name="set_customize_dark_indication">يسمح بتخصيص بعض العناصر في الرسائل للسمة الداكنة.</string>
|
||||
<string name="auto_fetch_missing">جلب الرسائل المفقودة تلقائيًا</string>
|
||||
<string name="more_options">خيارات إضافية</string>
|
||||
<string name="action_favourite">إضافة للمفضلة</string>
|
||||
<string name="warn_boost_no_media_description">تحذير إذا لم يكن للرسالة وصف وسائط قبل إعادة النشر</string>
|
||||
<string name="add_content_warning">إضافة تحذير محتوى</string>
|
||||
<string name="set_language">تعيين اللغة</string>
|
||||
<string name="attach_files">إرفاق ملفات</string>
|
||||
<string name="add_poll">إضافة استطلاع</string>
|
||||
<string name="toast_error_internet">لا يوجد اتصال بالإنترنت!</string>
|
||||
<string name="toast_error_token_empty">لا يمكن أن يكون الرمز فارغًا!</string>
|
||||
<string name="favourited_by">أُعجب به بواسطة</string>
|
||||
<string name="otp_message">رمز مصادقة ثنائية</string>
|
||||
<string name="add_all_users_home_muted">إضافة جميع المستخدمين إلى قائمة الكتم في الرئيسية</string>
|
||||
<string name="filter_action_explanations">اختر الإجراء الذي سيتم تنفيذه عندما يتطابق منشور مع المُرشح</string>
|
||||
<string name="messages_in_cache_for_other_timelines">الرسائل المخزنة مؤقتًا للخطوط الزمنية الأخرى</string>
|
||||
<string name="mute_tag">هل أنت متأكد من كتم الوسم %1$s؟</string>
|
||||
<string name="toast_error_fetch_message">لم يتمكن التطبيق من العثور على الرسالة عن بعد.</string>
|
||||
<string name="set_fetch_home">جلب رسائل الرئيسية تلقائيًا</string>
|
||||
<string name="set_custom_accent_value_light_description">اللون الذي سيتم تطبيقه على السمة الفاتحة</string>
|
||||
<string name="instance_information">معلومات الخادم</string>
|
||||
<string name="network">الشبكة</string>
|
||||
<string name="delete_notification_all_warning">هل أنت متأكد أنك تريد حذف جميع الإشعارات؟ لا يمكن التراجع عن هذا الإجراء.</string>
|
||||
<string name="toast_fetch_error">لا يمكن للتطبيق العثور على البيانات عن بعد!</string>
|
||||
<string name="translate_in">ترجمة إلى</string>
|
||||
<string name="chart_home_cache">سجلات الذاكرة المؤقتة للرئيسية لكل ساعة</string>
|
||||
<string name="set_notif_update">إشعار للتحديثات</string>
|
||||
<string name="create_domain_block">إنشاء حظر نطاق</string>
|
||||
<string name="type_default_theme_light">سمة فاتحة افتراضية</string>
|
||||
<string name="translator_domain">نطاق المترجم</string>
|
||||
<string name="card_picture">صورة البطاقة</string>
|
||||
<string name="set_disable_topbar_scrolling_title">تعطيل تمرير الشريط العلوي</string>
|
||||
<string name="set_audo_hide_compose_summary">إخفاء زر الإنشاء تلقائيًا عند التمرير لأعلى في الخط الزمني</string>
|
||||
<string name="fail_count">%d فشل</string>
|
||||
<string name="inserted_count">%d رسائل جديدة</string>
|
||||
<string name="set_disable_release_notes_indication">عند نشر إصدار جديد، لن يتم تنبيهك داخل التطبيق.</string>
|
||||
<string name="fetch_home_every">جلب الرئيسية كل</string>
|
||||
<string name="reply_visibility">مستوى رؤية الرد</string>
|
||||
<string name="hide_with_warning">إخفاء مع تحذير</string>
|
||||
<string name="set_audo_hide_compose_title">إخفاء زر الإنشاء تلقائيًا</string>
|
||||
<string name="remember_position">تذكر الموضع في الخطوط الزمنية</string>
|
||||
<string name="set_live_translate">فرض الترجمة إلى لغة معينة. اختر القيمة الأولى لإعادة التعيين إلى إعدادات الجهاز</string>
|
||||
<string name="icons_extra_features">أيقونات للميزات الإضافية</string>
|
||||
<string name="set_display_local_only">عرض زر محلي فقط</string>
|
||||
<string name="also_followed_by">متابع أيضًا بواسطة:</string>
|
||||
<string name="action_change_subscribed_language">تغيير اللغات المشترك بها</string>
|
||||
<string name="type_of_home_delay_title">وقت جلب الرئيسية</string>
|
||||
<string name="set_mention_booster">الإشارة إلى مُعيد النشر</string>
|
||||
<string name="set_mention_booster_indication">عند الرد على إعادة نشر، سيتم الإشارة إلى الشخص الذي أعاد النشر في الرد</string>
|
||||
<string name="set_alt_text_mandatory_description_warn">إذا كانت هناك وسائط مفقودة، فسيتم عرض مربع حوار مع إمكانية إرسال الرسالة بدون وصف وسائط</string>
|
||||
<string name="fails">فشل</string>
|
||||
<string name="frequency_minutes">التكرار (بالدقائق)</string>
|
||||
<string name="fetched_count">%d رسائل مجلوبة</string>
|
||||
<string name="frequency_count_minutes">%d تكرار (بالدقائق)</string>
|
||||
<string name="set_custom_accent">لون تمييز مخصص</string>
|
||||
<string name="toast_try_later">من فضلك، حاول مرة أخرى لاحقًا.</string>
|
||||
<string name="formula">صيغة</string>
|
||||
<string name="maths_format">تنسيق الرياضيات</string>
|
||||
<string name="no_cached_messages">لا توجد رسائل مخزنة مؤقتًا في الرئيسية!</string>
|
||||
<string name="check_home_cache">التحقق من الذاكرة المؤقتة للرئيسية</string>
|
||||
<string name="set_custom_accent_dark_value">لون تمييز داكن</string>
|
||||
<string name="set_custom_accent_value_dark_description">اللون الذي سيتم تطبيقه على السمة الداكنة</string>
|
||||
<string name="clipboard_version">تم نسخ المعلومات إلى الحافظة</string>
|
||||
<string name="tag_already_followed">أنت تتابع هذا الوسم بالفعل!</string>
|
||||
<string name="show_self_boosts">عرض معيدات النشر الخاصة بي</string>
|
||||
<string name="show_self_replies">عرض ردودي الخاصة</string>
|
||||
<string name="set_push_notifications_delay">تعيين التأخير بين كل عملية جلب جديدة</string>
|
||||
<string name="notif_reported">أرسل تقريرًا</string>
|
||||
<string name="set_pixelfed_full_media">وسائط بملء الشاشة</string>
|
||||
<string name="set_pixelfed_full_media_indication">ستأخذ الوسائط عرض الشاشة بالكامل وسيتم احترام نسبة العرض إلى الارتفاع.</string>
|
||||
<string name="copy_version">نسخ المعلومات</string>
|
||||
<string name="is_up">يعمل!</string>
|
||||
<string name="use_token">استخدام رمز</string>
|
||||
<string name="toast_fail_authenticate">فشل التطبيق في مصادقة الحساب!</string>
|
||||
<string name="set_unlisted_replies_indication">يتعلق هذا فقط بالردود العامة. عند التمكين، ستكون ردودك تلقائيًا ذات مستوى رؤية غير مدرج بدلاً من عام</string>
|
||||
<string name="mark_unresolved">تمييز كغير محلول</string>
|
||||
<string name="mark_resolved">تمييز كمحلول</string>
|
||||
<string name="account_undisabled">تم إلغاء تعطيل الحساب</string>
|
||||
<string name="not_interested">غير مهتم</string>
|
||||
<string name="pref_custom_theme_new_summary">السماح بإنشاء سمتك المخصصة</string>
|
||||
<string name="instance_token">الرمز الخاص بك</string>
|
||||
<string name="action_reblog">إعادة نشر</string>
|
||||
<string name="action_quote">اقتباس</string>
|
||||
<string name="remove_content_warning">إزالة تحذير المحتوى</string>
|
||||
<string name="change_visibility">تغيير مستوى الرؤية</string>
|
||||
<string name="action_publish">نشر</string>
|
||||
<string name="open_new_attachment_panel">فتح لوحة مرفقات جديدة</string>
|
||||
<string name="close_new_attachment_panel">إغلاق لوحة المرفقات الجديدة</string>
|
||||
<string name="attach_images">إرفاق صور</string>
|
||||
<string name="attach_audio">إرفاق صوت</string>
|
||||
<string name="attach_videos">إرفاق فيديوهات</string>
|
||||
<string name="pronouns_support">دعم الضمائر</string>
|
||||
<string name="is_down">متوقف!</string>
|
||||
<string name="instance_health_uptime">وقت التشغيل: %,.2f %%</string>
|
||||
<string name="report_1_mute">لن ترى منشوراتهم. لا يزال بإمكانهم متابعتك ورؤية منشوراتك ولن يعرفوا أنهم مكتومون.</string>
|
||||
<string name="report_2_title">هل هناك أي منشورات تدعم هذا التقرير؟</string>
|
||||
<string name="aggregate_notifications_summary">عند التشغيل، سيقوم التطبيق بدمج الإشعارات ذات الصلة</string>
|
||||
<string name="display_media_notification_summary">سيتم عرض الوسائط في إشعارات معيدات النشر والمفضلة</string>
|
||||
<string name="write_the_tag_to_follow">اكتب الوسم للمتابعة</string>
|
||||
<string name="not_valid_tag_name">اسم الوسم غير صالح!</string>
|
||||
<string name="max_indentation_thread">أقصى مسافة بادئة في السلاسل</string>
|
||||
<string name="account_unsilenced">تم إلغاء إسكات الحساب</string>
|
||||
<string name="set_language_picker">السماح بتقليل قائمة اللغات في المنتقي عند إنشاء رسالة.</string>
|
||||
<string name="hide_completely">إخفاء بالكامل</string>
|
||||
<string name="hide_with_warning_description">إخفاء المحتوى المُرشح خلف تحذير يذكر عنوان المُرشح</string>
|
||||
<string name="hide_completely_description">إخفاء المحتوى المُرشح بالكامل، كما لو لم يكن موجودًا</string>
|
||||
<string name="context_home_list">الرئيسية والقوائم</string>
|
||||
<string name="keyword_or_phrase">كلمة مفتاحية أو عبارة</string>
|
||||
<string name="display_remote_profile">عرض الملف الشخصي عن بعد</string>
|
||||
<string name="notif_submitted_report">تم إرسال تقرير</string>
|
||||
<string name="unpin_timeline">إزالة الخط الزمني المثبت؟</string>
|
||||
<string name="unpin_timeline_description">هل أنت متأكد من إلغاء تثبيت هذا الخط الزمني؟</string>
|
||||
<string name="order_lists">ترتيب القوائم</string>
|
||||
<string name="admin_domainblock_domain">لن يمنع حظر النطاق إنشاء إدخالات حساب في قاعدة البيانات، ولكنه سيطبق تلقائيًا وبأثر رجعي طرق إشراف محددة على تلك الحسابات.</string>
|
||||
<string name="admin_domainblock_reject_media">تجاهل جميع التقارير الواردة من هذا النطاق. غير ذي صلة بالتعليقات</string>
|
||||
<string name="set_customize_light">تخصيص السمة الفاتحة</string>
|
||||
<string name="set_customize_light_indication">يسمح بتخصيص بعض العناصر في الرسائل للسمة الفاتحة.</string>
|
||||
<string name="set_customize_dark">تخصيص السمة الداكنة</string>
|
||||
<string name="set_extand_extra_features">بتمكين هذا الخيار، سيعرض التطبيق ميزات إضافية. هذه الميزة مخصصة لبرامج التواصل الاجتماعي مثل Pleroma أو Akkoma أو Glitch Social</string>
|
||||
<string name="icons_visibility">رؤية الأيقونات</string>
|
||||
<string name="set_remote_profile">سيعرض التطبيق الملفات الشخصية بشكل عام للحصول على جميع الرسائل. ستحتاج التفاعلات إلى خطوة إضافية لتوحيد الرسائل.</string>
|
||||
<string name="set_remote_conversation">سيعرض التطبيق المحادثات بشكل عام للحصول على جميع الرسائل. ستحتاج التفاعلات إلى خطوة إضافية لتوحيد الرسائل.</string>
|
||||
<string name="set_display_compact_buttons">أزرار إجراءات مدمجة</string>
|
||||
<string name="boost_original_date">عرض التاريخ الأصلي لمعيدات النشر</string>
|
||||
<string name="set_disable_release_notes">تعطيل ملاحظات الإصدار</string>
|
||||
<string name="home_cache">الذاكرة المؤقتة للرئيسية</string>
|
||||
<string name="number_of_media">عدد الوسائط</string>
|
||||
<string name="total_fetched">إجمالي الرسائل المجلبة</string>
|
||||
<string name="set_custom_accent_indication">تحديد لون سمة لكل حساب</string>
|
||||
<string name="admin_domainblock_reject_obfuscate">إخفاء اسم النطاق جزئيًا في القائمة إذا تم تمكين الإعلان عن قائمة قيود النطاق</string>
|
||||
<string name="admin_domainblock_private_comment">تعليق حول هذا القيد على النطاق للاستخدام الداخلي من قبل المشرفين.</string>
|
||||
<string name="admin_domainblock_public_comment">تعليق حول هذا القيد على النطاق للجمهور العام، إذا تم تمكين الإعلان عن قائمة قيود النطاق.</string>
|
||||
<string name="saved_changes">تم حفظ التغييرات!</string>
|
||||
<string name="type_of_theme">اختر وضعًا للسمة</string>
|
||||
<string name="pref_customize_summary">السماح بتعيين ألوانك المخصصة للسمات.</string>
|
||||
<string name="set_cardview_indication">عند التمكين، سيكون للعناصر في الخطوط الزمنية ظل وارتفاع.</string>
|
||||
<string name="about_peertube">PeerTube هو أداة لمشاركة مقاطع الفيديو عبر الإنترنت طورته Framasoft، وهي منظمة فرنسية غير ربحية.… يسمح PeerTube بربط المنصات ببعضها البعض، مما يخلق شبكة كبيرة من المنصات المستقلة والمترابطة في نفس الوقت</string>
|
||||
<string name="messages_in_cache_for_home">الرسائل المخزنة مؤقتًا للرئيسية</string>
|
||||
<string name="set_your_max_char_count">تعيين الحد الأقصى لعدد الأحرف الخاص بك</string>
|
||||
<string name="set_timelines_in_a_list">عند التمكين، سيتم عرض جميع الخطوط الزمنية المثبتة في قائمة منسدلة</string>
|
||||
<string name="toast_feature_not_supported">لا يبدو أن خادمك يدعم هذه الميزة!</string>
|
||||
<string name="watch_trends_for_instance">مشاهدة الاتجاهات لهذا الخادم</string>
|
||||
<string name="admin_domainblock_severity">الإسكات سيجعل منشورات الحساب غير مرئية لأي شخص لا يتابعهم. التعليق سيزيل جميع محتويات الحساب والوسائط وبيانات الملف الشخصي. استخدم لا شيء إذا كنت ترغب فقط في رفض ملفات الوسائط.</string>
|
||||
<string name="admin_domainblock_reject_reports">تجاهل جميع التقارير الواردة من هذا النطاق. غير ذي صلة بالتعليقات</string>
|
||||
<string name="set_dynamic_color_indication">محاذاة لونية مع نظام ألوان خلفية شاشتك الشخصية.</string>
|
||||
<string name="set_custom_colors">تعيين ألوان مخصصة</string>
|
||||
<string name="light_custom_colors">فاتح - ألوان مخصصة</string>
|
||||
<string name="cark_custom_colors">داكن - ألوان مخصصة</string>
|
||||
<string name="group_reblogs">تجميع معيدات النشر في الخط الزمني الرئيسي</string>
|
||||
<string name="icons_visibility_summary">يمكنك إخفاء هذه الأيقونات السفلية بأمان للحصول على مساحة أكبر. توجد أيضًا في القائمة الفرعية.</string>
|
||||
<string name="set_display_reaction_indication">عرض أزرار ردود الفعل</string>
|
||||
<string name="set_remote_profile_title">الملفات الشخصية عن بعد</string>
|
||||
<string name="set_remote_conversation_title">المحادثات عن بعد</string>
|
||||
<string name="set_pixelfed_presentation">عرض وسائط Pixelfed</string>
|
||||
<string name="set_display_compact_buttons_description">لن تأخذ الأزرار في أسفل الرسائل العرض الكامل</string>
|
||||
<string name="timeline_scrollbar">عرض شريط تمرير للخطوط الزمنية</string>
|
||||
<string name="set_display_quote_indication">عرض زر اقتباس</string>
|
||||
<string name="markdown_support">دعم ماركداون</string>
|
||||
<string name="set_maths_support">كتابة صيغة</string>
|
||||
<string name="filter_languages">تصفية اللغات</string>
|
||||
<string name="toast_error_peertube_not_supported">خادم Peertube الخاص بك قديم جدًا ولا يمكن للتطبيق دعمه.</string>
|
||||
<string name="fetch_home_messages">جلب رسائل الرئيسية</string>
|
||||
<string name="set_mention_at_top_indication">عند الرد، ستتم إضافة جميع الإشارات إلى بداية الرسالة</string>
|
||||
<string name="tags_stored">تم تخزين الوسم!</string>
|
||||
<string name="more_media">%1$s وسائط إضافية</string>
|
||||
<string name="set_alt_text_mandatory_description">لن يتم إرسال الرسالة إذا كان هناك وصف مفقود مع الوسائط</string>
|
||||
<string name="truncate_links">قص الروابط</string>
|
||||
<string name="truncate_links_max">الحد الأقصى للأحرف في الروابط</string>
|
||||
<string name="messages">%1$d رسائل مخزنة مؤقتًا</string>
|
||||
<string name="updated_count">%d رسائل محدثة</string>
|
||||
<string name="track_selection_title">اختيار المسارات</string>
|
||||
<string name="set_custom_accent_light_value">لون تمييز فاتح</string>
|
||||
</resources>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1096,4 +1096,24 @@
|
|||
<string name="set_pixelfed_full_media">Média přes celý displej</string>
|
||||
<string name="set_pixelfed_full_media_indication">Média se budou zobrazovat přes celou šířku displeje a u výšky se bude respektovat poměr stran.</string>
|
||||
<string name="twitter_tags">Tagy Twitteru (přes Nitter)</string>
|
||||
<string name="more_options">Více voleb</string>
|
||||
<string name="action_favourite">Oblíbené</string>
|
||||
<string name="action_reblog">Boostnout</string>
|
||||
<string name="action_quote">Citovat</string>
|
||||
<string name="add_content_warning">Přidat varování o obsahu</string>
|
||||
<string name="remove_content_warning">Odstranit varování o obsahu</string>
|
||||
<string name="change_visibility">Změnit viditelnost</string>
|
||||
<string name="set_language">Nastavit jazyk</string>
|
||||
<string name="action_publish">Publikovat</string>
|
||||
<string name="open_new_attachment_panel">Otevřít panel pro novou přílohu</string>
|
||||
<string name="close_new_attachment_panel">Zavřít panel pro novou přílohu</string>
|
||||
<string name="attach_images">Připojit obrázky</string>
|
||||
<string name="attach_audio">Připojit zvuk</string>
|
||||
<string name="attach_videos">Připojit videa</string>
|
||||
<string name="attach_files">Připojit soubory</string>
|
||||
<string name="add_poll">Přidat anketu</string>
|
||||
<string name="instance_information">Informace o instanci</string>
|
||||
<string name="network">Síť</string>
|
||||
<string name="set_audo_hide_compose_title">Automaticky skrývat tlačítko pro vytvoření</string>
|
||||
<string name="set_audo_hide_compose_summary">Automaticky skrývat tlačítko pro vytvoření během posouvání nahoru po časové ose</string>
|
||||
</resources>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<string name="disclaimer_full">Gall y wybodaeth isod roi adlewyrchiad anghyflawn o broffil y defnyddiwr.</string>
|
||||
<string name="insert_emoji">Mewnosod emoji</string>
|
||||
<string name="no_emoji">Ni gasglwyd emoji dethol gan yr ap am y tro.</string>
|
||||
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
|
||||
<string name="logout_account_confirmation">Dych chi\'n siwr i chi eisiau allgofnodi @%1$s@%2$s?</string>
|
||||
<!-- Status -->
|
||||
<string name="no_status">Dim neges i\'w dangos</string>
|
||||
<string name="favourite_add">Ychwanegu\'r neges hon at eich ffefrynnau\?</string>
|
||||
|
@ -76,7 +76,7 @@
|
|||
<string name="more_action_6">Rhannu</string>
|
||||
<string name="more_action_7">Crybwyll</string>
|
||||
<string name="more_action_8">Tawelu am gyfnod</string>
|
||||
<string name="more_action_9">Delete & re-draft</string>
|
||||
<string name="more_action_9">Dileu & ailwampio</string>
|
||||
<string-array name="more_action_confirm">
|
||||
<item>Tawelu\'r cyfrif hwn?</item>
|
||||
<item>Blocio\'r cyfrif hwn?</item>
|
||||
|
@ -105,11 +105,11 @@
|
|||
<string name="date_day">%d d</string>
|
||||
<plurals name="date_seconds_polls">
|
||||
<item quantity="zero">%d seconds</item>
|
||||
<item quantity="one">%d second</item>
|
||||
<item quantity="two">%d seconds</item>
|
||||
<item quantity="few">%d seconds</item>
|
||||
<item quantity="many">%d seconds</item>
|
||||
<item quantity="other">%d seconds</item>
|
||||
<item quantity="one">%d eiliad</item>
|
||||
<item quantity="two">eiliad</item>
|
||||
<item quantity="few">%d eiliadau</item>
|
||||
<item quantity="many">%d eiliadau</item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="date_minutes_polls">
|
||||
<item quantity="zero">%d minutes</item>
|
||||
|
@ -120,20 +120,20 @@
|
|||
<item quantity="other">%d minutes</item>
|
||||
</plurals>
|
||||
<plurals name="date_hours_polls">
|
||||
<item quantity="zero">%d hours</item>
|
||||
<item quantity="one">%d hour</item>
|
||||
<item quantity="two">%d hours</item>
|
||||
<item quantity="few">%d hours</item>
|
||||
<item quantity="many">%d hours</item>
|
||||
<item quantity="other">%d hours</item>
|
||||
<item quantity="zero">%d awr</item>
|
||||
<item quantity="one">%d awr</item>
|
||||
<item quantity="two">%d awr</item>
|
||||
<item quantity="few">%d oriau</item>
|
||||
<item quantity="many">%d oriau</item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="date_day_polls">
|
||||
<item quantity="zero">%d days</item>
|
||||
<item quantity="one">%d day</item>
|
||||
<item quantity="two">%d days</item>
|
||||
<item quantity="few">%d days</item>
|
||||
<item quantity="many">%d days</item>
|
||||
<item quantity="other">%d days</item>
|
||||
<item quantity="one">%d dydd</item>
|
||||
<item quantity="two">%d dydd</item>
|
||||
<item quantity="few">%d dyddiau</item>
|
||||
<item quantity="many">%d dyddiau</item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<!-- TOOT -->
|
||||
<string name="toot_select_image_error">Roedd gwall!</string>
|
||||
|
@ -176,11 +176,11 @@
|
|||
<!-- Notifications -->
|
||||
<string name="no_notifications">Dim hysbysiad i\'w arddangos</string>
|
||||
<string name="notif_mention">wedi\'ch crybwyll</string>
|
||||
<string name="notif_status">wrote a new message</string>
|
||||
<string name="notif_status">wedi ysgrifennu neges newydd</string>
|
||||
<string name="notif_reblog">wedi hybu\'ch tŵt</string>
|
||||
<string name="notif_favourite">wedi nodi\'ch tŵt yn ffefryn</string>
|
||||
<string name="notif_follow">wedi\'ch dilyn chi</string>
|
||||
<string name="notif_follow_request">asked to follow you</string>
|
||||
<string name="notif_follow_request">ymofyn i ganlyn chi</string>
|
||||
<string name="delete_notification_ask_all">Dileu pob hysbysiad?</string>
|
||||
<string name="delete_notification_all">Mae pob hysbysiad wedi ei ddileu!</string>
|
||||
<!-- HEADER -->
|
||||
|
@ -318,10 +318,10 @@
|
|||
<string name="channel_notif_follow">New follow</string>
|
||||
<string name="channel_notif_boost">Hybiad newydd</string>
|
||||
<string name="channel_notif_fav">Ffefryn newydd</string>
|
||||
<string name="channel_notif_mention">New Mention</string>
|
||||
<string name="channel_notif_mention">Crybwylliad newydd</string>
|
||||
<string name="channel_notif_poll">Poll Ended</string>
|
||||
<string name="channel_notif_backup">Negeseuon wrth gefn</string>
|
||||
<string name="channel_notif_status">New posts</string>
|
||||
<string name="channel_notif_status">Postiau newydd</string>
|
||||
<string name="channel_notif_media">Lawrlwytho Cyfryngau</string>
|
||||
<string name="select_sound">Dewis tôn</string>
|
||||
<string name="set_enable_time_slot">Caniatau slot amser</string>
|
||||
|
@ -398,34 +398,34 @@
|
|||
<string name="no_tags">Dim tagiau</string>
|
||||
<string name="set_retrieve_metadata_share_from_extras">Attach an image when sharing a URL</string>
|
||||
<!-- end languages -->
|
||||
<string name="create_poll">Create a poll</string>
|
||||
<string name="poll_choice_s">Choice %d</string>
|
||||
<string name="create_poll">Creu pôl</string>
|
||||
<string name="poll_choice_s">Dewis %d</string>
|
||||
<string name="poll_invalid_choices">You need two choices at least for the poll!</string>
|
||||
<string name="done">Done</string>
|
||||
<string name="done">Wedi gorffen</string>
|
||||
<string name="poll_finish_at">end at %s</string>
|
||||
<string name="vote">Vote</string>
|
||||
<string name="notif_poll">A poll you have voted in has ended</string>
|
||||
<string name="notif_poll_self">Mae arolwg barn a gyhoeddwyd gennych wedi dod i ben</string>
|
||||
<string name="settings_category_notif_categories">Categories</string>
|
||||
<string name="settings_category_notif_categories">Categorïau</string>
|
||||
<string name="move_timeline">Move timeline</string>
|
||||
<string name="hide_timeline">Hide timeline</string>
|
||||
<string name="reorder_timelines">Rheoli ffrydiau</string>
|
||||
<string name="reorder_list_deleted">List permanently deleted</string>
|
||||
<string name="reorder_list_deleted">Rhestr wedi dileu\'n barhaol</string>
|
||||
<string name="reorder_instance_removed">Followed instance removed</string>
|
||||
<string name="reorder_tag_removed">Pinned tag removed</string>
|
||||
<string name="undo">Undo</string>
|
||||
<string name="undo">Dadwneud</string>
|
||||
<string name="warning_main_timeline">Main timelines can only be hidden!</string>
|
||||
<string name="set_sensitive_content">Always mark media as sensitive</string>
|
||||
<string name="gnu_instance">GNU instance</string>
|
||||
<string name="gnu_instance">Enghraifft GNU</string>
|
||||
<string name="set_forward_tags">Forward tags in replies</string>
|
||||
<string name="set_long_press_media">Long press to store media</string>
|
||||
<string name="add_tags">Manage tags</string>
|
||||
<string name="add_tags">Rheoli tagiau</string>
|
||||
<string name="display_name">Display name</string>
|
||||
<string name="label_emoji">Emoji</string>
|
||||
<string name="label_text">Text</string>
|
||||
<string name="label_filter">Filter</string>
|
||||
<string name="label_brush">Brush</string>
|
||||
<string name="discard">Discard</string>
|
||||
<string name="label_brush">Brws</string>
|
||||
<string name="discard">Gwaredu</string>
|
||||
<string name="saving">Saving…</string>
|
||||
<string name="image_saved">Image Saved Successfully!</string>
|
||||
<string name="save_image_failed">Failed to save Image</string>
|
||||
|
@ -435,30 +435,30 @@
|
|||
<string name="toast_unmute_conversation">The conversation is no longer muted!</string>
|
||||
<string name="toast_mute_conversation">The conversation is muted</string>
|
||||
<string name="category_general">General</string>
|
||||
<string name="category_regional">Regional</string>
|
||||
<string name="category_art">Art</string>
|
||||
<string name="category_regional">Rhanbarthol</string>
|
||||
<string name="category_art">Celf</string>
|
||||
<string name="category_activism">Activism</string>
|
||||
<string name="category_games">Gaming</string>
|
||||
<string name="category_games">Gêmau</string>
|
||||
<string name="category_tech">Technology</string>
|
||||
<string name="category_furry">Furry</string>
|
||||
<string name="category_food">Food</string>
|
||||
<string name="instance_logo">Logo of the instance</string>
|
||||
<string name="join_mastodon">Join Mastodon</string>
|
||||
<string name="category_furry">Blewog</string>
|
||||
<string name="category_food">Bwyd</string>
|
||||
<string name="instance_logo">Logo enghraifft</string>
|
||||
<string name="join_mastodon">Ymuno â Mastodon</string>
|
||||
<string name="pickup_instance_category">Choose an instance by picking up a category, then tap on a check button.</string>
|
||||
<string name="users">%1$s users</string>
|
||||
<string name="users">%1$s defnyddwyr</string>
|
||||
<string name="password_confirm">Confirm password</string>
|
||||
<string name="agreement_check">I agree to %1$s and %2$s</string>
|
||||
<string name="server_rules">server rules</string>
|
||||
<string name="agreement_check">Dw i\'n cytuno â %1$s a %2$s</string>
|
||||
<string name="server_rules">rheolau gweinydd</string>
|
||||
<string name="tos">terms of service</string>
|
||||
<string name="sign_up">Cofrestru</string>
|
||||
<string name="validation_needed">This instance works with invitations. Your account will need to be manually approved by an administrator before being usable.</string>
|
||||
<string name="password_error">Passwords don\'t match!</string>
|
||||
<string name="password_error">Dydy\'r cyfrinair ddim yn cyd-fynd!</string>
|
||||
<string name="email_error">The email doesn\'t seem to be valid!</string>
|
||||
<string name="email_indicator">You will be sent a confirmation e-mail</string>
|
||||
<string name="password_indicator">Use at least 8 characters</string>
|
||||
<string name="password_too_short">Password should contain at least 8 characters</string>
|
||||
<string name="username_error">Username should only contain letters, numbers and underscores</string>
|
||||
<string name="account_created">Account created!</string>
|
||||
<string name="account_created">Cyfrif wedi creu!</string>
|
||||
<string name="account_created_message"> 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 <b>%1$s</b> in the first field and tap on <b>Connect</b>.\n\n
|
||||
|
@ -467,43 +467,43 @@
|
|||
<string name="save_draft">Save the message in drafts?</string>
|
||||
<string name="administration">Administration</string>
|
||||
<string name="reports">Reports</string>
|
||||
<string name="unresolved">Unresolved</string>
|
||||
<string name="remote">Remote</string>
|
||||
<string name="unresolved">Ddim wedi penderfynu</string>
|
||||
<string name="remote">Bell</string>
|
||||
<string name="active">Active</string>
|
||||
<string name="pending">Pending</string>
|
||||
<string name="disabled">Disabled</string>
|
||||
<string name="suspended">Suspended</string>
|
||||
<string name="permissions">Permissions</string>
|
||||
<string name="disable">Disable</string>
|
||||
<string name="silence">Silence</string>
|
||||
<string name="pending">Hyd</string>
|
||||
<string name="disabled">Anabl</string>
|
||||
<string name="suspended">Ar grog</string>
|
||||
<string name="permissions">Caniatâd</string>
|
||||
<string name="disable">Anablu</string>
|
||||
<string name="silence">Distawrwydd</string>
|
||||
<string name="account">Account</string>
|
||||
<string name="unsilence">Undo silence</string>
|
||||
<string name="undisable">Undo disable</string>
|
||||
<string name="suspend">Suspend</string>
|
||||
<string name="unsuspend">Undo suspend</string>
|
||||
<string name="unsilence">Dadwneud distawrwydd</string>
|
||||
<string name="undisable">Dadwneud anablu</string>
|
||||
<string name="suspend">Gwahardd</string>
|
||||
<string name="unsuspend">Dadwneud gwahardd</string>
|
||||
<string name="audio">The application needs to access audio recording</string>
|
||||
<string name="voice_message">Voice message</string>
|
||||
<string name="voice_message">Neges llais</string>
|
||||
<string name="set_enable_time_slot_indication">During the time slot, the app will send notifications. You can reverse (ie: silent) this time slot with the right spinner.</string>
|
||||
<string name="set_fit_preview_indication">Previews will not be cropped in timelines</string>
|
||||
<string name="set_capitalize_indication">Automatically insert a line break after the mention to capitalize the first letter</string>
|
||||
<string name="settings_title_custom_sharing_indication">Allow content creators to share statuses to their RSS feeds</string>
|
||||
<string name="compose">Compose</string>
|
||||
<string name="select">Select</string>
|
||||
<string name="add_instances">Add an instance</string>
|
||||
<string name="compose">Cyfansoddi</string>
|
||||
<string name="select">Dewis</string>
|
||||
<string name="add_instances">Adio enghraifft</string>
|
||||
<string name="set_enable_crash_report">Enable crash reports</string>
|
||||
<string name="set_enable_crash_report_indication">If enabled, a crash report will be created locally and then you will be able to share it.</string>
|
||||
<string name="crash_title">Mae Fedilab wedi stopio :(</string>
|
||||
<string name="crash_message">Mae modd i chi anfon adroddiad crash ata\'i drwy ebost. Bydd yn help i\'w ddatrys. :)\n\nMae modd i chi ychwanegu cynnwys ychwanegol! Diolch!</string>
|
||||
<string name="visibility">Visibility</string>
|
||||
<string name="visibility">Gwelededd</string>
|
||||
<string name="set_disable_animated_emoji">Disable custom animated emojis</string>
|
||||
<string name="report_account">Report account</string>
|
||||
<plurals name="number_of_voters">
|
||||
<item quantity="zero">%d voters</item>
|
||||
<item quantity="one">%d voter</item>
|
||||
<item quantity="two">%d voters</item>
|
||||
<item quantity="few">%d voters</item>
|
||||
<item quantity="many">%d voters</item>
|
||||
<item quantity="other">%d voters</item>
|
||||
<item quantity="zero">%d pleidleisiwr</item>
|
||||
<item quantity="one">%d pleidleisiwr</item>
|
||||
<item quantity="two">%d pleidleisiwr</item>
|
||||
<item quantity="few">%d pleidleisiwyr</item>
|
||||
<item quantity="many">%d pleidleisiwyr</item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string-array name="poll_choice_type">
|
||||
<item>Single choice</item>
|
||||
|
@ -531,7 +531,7 @@
|
|||
<string name="note_for_account">Notes for the account</string>
|
||||
<string name="set_resize_picture_indication">Allow to compress large photos into smaller sized photos with very less or negligible loss in quality of the image.</string>
|
||||
<string name="set_resize_video_indication">Allow compressing videos while maintaining their quality.</string>
|
||||
<string name="order_by">Order by</string>
|
||||
<string name="order_by">Trefnu erbyn</string>
|
||||
<string name="link_color_title">Links</string>
|
||||
<string name="link_color">Change the color of links (URLs, mentions, tags, etc.) in messages</string>
|
||||
<string name="boost_header_color_title">Reblogs header</string>
|
||||
|
@ -540,19 +540,19 @@
|
|||
<string name="boost_header_color">Change the color of the header for reblogs</string>
|
||||
<string name="background_status_title">Posts</string>
|
||||
<string name="background_status">Background color of posts in timelines</string>
|
||||
<string name="reset_color">Reset colors</string>
|
||||
<string name="reset_color">Ailosod lliwiau</string>
|
||||
<string name="clik_reset">Tap here to reset all your custom colors</string>
|
||||
<string name="reset">Reset</string>
|
||||
<string name="icons_color_title">Icons</string>
|
||||
<string name="icons_color">Color of bottom icons in timelines</string>
|
||||
<string name="logo_of_the_instance">Logo of the instance</string>
|
||||
<string name="edit_profile">Edit profile</string>
|
||||
<string name="make_an_action">Make an action</string>
|
||||
<string name="translation">Translation</string>
|
||||
<string name="logo_of_the_instance">Logo enghraifft</string>
|
||||
<string name="edit_profile">Golygu proffeil</string>
|
||||
<string name="make_an_action">Gwneud gweithred</string>
|
||||
<string name="translation">Cyfieithiad</string>
|
||||
<string name="text_color_title">Text color</string>
|
||||
<string name="text_color">Change the text color in messages</string>
|
||||
<string name="pref_custom_theme">Use a custom theme</string>
|
||||
<string name="theming">Theming</string>
|
||||
<string name="theming">Themâu</string>
|
||||
<string name="data_export_theme">The theme was exported</string>
|
||||
<string name="data_export_theme_success">The theme has been successfully exported in CSV</string>
|
||||
<string name="import_theme">Import a theme</string>
|
||||
|
@ -560,33 +560,33 @@
|
|||
<string name="export_theme">Export the theme</string>
|
||||
<string name="export_theme_title">Tap here to export the current theme</string>
|
||||
<string name="theme_file_error">An error occurred when selecting the theme file</string>
|
||||
<string name="user_count">User count</string>
|
||||
<string name="status_count">Status count</string>
|
||||
<string name="instance_count">Instance count</string>
|
||||
<string name="user_count">Cyfrifiad defnyddwyr</string>
|
||||
<string name="status_count">Cyfrifiad safleoedd</string>
|
||||
<string name="instance_count">Cyfrifiad enghraifft</string>
|
||||
<string name="poll_finish_in">End in %s</string>
|
||||
<string name="no_instance_reccord">This instance is not available on https://instances.social</string>
|
||||
<string name="no_instance_reccord">Dydy\'r enghraifft\'na ddim ar gael yn https://instances.social</string>
|
||||
<string name="display_full_link">Display full link</string>
|
||||
<string name="share_link">Share link</string>
|
||||
<string name="open_other_app">Open with another app</string>
|
||||
<string name="check_redirect">Check redirect</string>
|
||||
<string name="no_redirect">This URL does not redirect</string>
|
||||
<string name="redirect_detected">%1$s \n\nredirects to\n\n %2$s</string>
|
||||
<string name="redirect_detected">%1$s \n\nyn ailgyfeirio i\n\n %2$s</string>
|
||||
<string name="set_utm_parameters">Remove UTM parameters</string>
|
||||
<string name="set_utm_parameters_indication">The app will automatically remove UTM parameters from URLs before visiting a link.</string>
|
||||
<string name="talking_about">%d people talking</string>
|
||||
<string name="twitter_accounts">Twitter accounts (via Nitter)</string>
|
||||
<string name="talking_about">%d pobl yn sôn</string>
|
||||
<string name="twitter_accounts">Cyfrifon Twitter (trwy Nitter)</string>
|
||||
<string name="list_of_twitter_accounts">Twitter usernames space separated</string>
|
||||
<string name="identity_proofs">Identity proofs</string>
|
||||
<string name="verified_user">Verified identity</string>
|
||||
<string name="verified_by">Verified by %1$s (%2$s)</string>
|
||||
<string name="verified_by">Wedi gwirio erbyn %1$s (%2$s)</string>
|
||||
<string name="action_disabled">Action disabled</string>
|
||||
<string name="action_unfollow">Unfollow</string>
|
||||
<string name="error_destination_path">Something went wrong, please check your download directory in settings.</string>
|
||||
<string name="action_announcements">Announcements</string>
|
||||
<string name="action_announcements">Cyhoeddiadau</string>
|
||||
<string name="no_announcements">No announcements!</string>
|
||||
<string name="add_reaction">Add a reaction</string>
|
||||
<string name="set_video_cache">Video cache in MB, zero means no cache.</string>
|
||||
<string name="set_watermark">Watermarks</string>
|
||||
<string name="set_watermark">Dyfrnodau</string>
|
||||
<string name="set_watermark_indication">Automatically add a watermark at the bottom of pictures. The text can be customized for each account.</string>
|
||||
<string name="no_distributors_found">No distributors found!</string>
|
||||
<string name="no_distributors_explanation">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.</string>
|
||||
|
@ -625,4 +625,4 @@
|
|||
<string name="set_accounts_page">Nifer y cyfrifon fesul llwyth</string>
|
||||
<string name="proxy_protocol_http">HTTP</string>
|
||||
<string name="proxy_protocol_socks">SOCKS</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -584,13 +584,13 @@
|
|||
<string name="keepon">Fortfahren</string>
|
||||
<string name="instance_not_valid">Diese Instanz scheint nicht gültig zu sein!</string>
|
||||
<string name="boosted_by">Geteilt von</string>
|
||||
<string name="favourited_by">Favoritisiert von</string>
|
||||
<string name="favourited_by">Favorisiert von</string>
|
||||
<string name="followers_only">Nur Follower</string>
|
||||
<string name="eg_sensitive_content">Z. B.: Sensibler Inhalt</string>
|
||||
<string name="add_status">Status hinzufügen</string>
|
||||
<string name="remove_status">Status entfernen</string>
|
||||
<string name="instance_health_checkedat">Überprüft am: %s</string>
|
||||
<string name="show_content">Inhalt anzeigen ></string>
|
||||
<string name="show_content"><![CDATA[Inhalt anzeigen >]]></string>
|
||||
<string name="stop_recording">Aufnahme anhalten</string>
|
||||
<string name="report_val1">Ich mag es nicht</string>
|
||||
<string name="report_val2">Es ist Spam</string>
|
||||
|
@ -660,7 +660,7 @@
|
|||
<string name="bottom_menu">Unteres Menü</string>
|
||||
<string name="top_menu">Oberes Menü</string>
|
||||
<string name="report_1_title_more">Einstellungen zur Kontrolle dessen, was Du auf Mastodon siehst:</string>
|
||||
<string name="hide_content">Inhalt verbergen <</string>
|
||||
<string name="hide_content"><![CDATA[Inhalt verbergen <]]></string>
|
||||
<string name="category_custom">Benutzerdefiniert</string>
|
||||
<string name="post_message_text">Sende Nachricht %d/%d</string>
|
||||
<string name="is_up">Ist erreichbar!</string>
|
||||
|
@ -894,8 +894,8 @@
|
|||
<string name="admin_domainblock_domain">Das Blockieren der Domäne verhindert nicht die Erstellung von Konto-Einträgen in der Datenbank, sondern wendet rückwirkend und automatisch bestimmte Moderations-Methoden auf diese Konten an.</string>
|
||||
<string name="admin_domainblock_reject_reports">Ignoriere alle Meldungen die von dieser Domäne kommen. Für Suspendierungen irrelevant</string>
|
||||
<string name="admin_domainblock_severity">Stummschaltung macht die Beiträge des Kontos für alle unsichtbar, die ihm nicht folgen. Suspendierung entfernt alle Inhalte, Medien und Profildaten des Kontos. Verwende Keine, wenn Du nur die Mediendateien ablehnen möchtest.</string>
|
||||
<string name="admin_domainblock_reject_obfuscate">Verschleiere teilweise den Domänennamen in der Liste, wenn die Verteilung der Liste der Domänen-Beschränkunden aktiviert ist</string>
|
||||
<string name="admin_domainblock_public_comment">Kommentiere die Domainbeschränkung für die Öffentlichkeit, wenn die Verteilung der Liste der Domainbeschränkunden aktiviert ist.</string>
|
||||
<string name="admin_domainblock_reject_obfuscate">Verschleiere teilweise den Domänennamen in der Liste, wenn die Verteilung der Liste der Domänen-Beschränkungen aktiviert ist</string>
|
||||
<string name="admin_domainblock_public_comment">Kommentiere die Domainbeschränkung für die Öffentlichkeit, wenn die Verteilung der Liste der Domainbeschränkungen aktiviert ist.</string>
|
||||
<string name="order_lists">Listen sortieren</string>
|
||||
<string name="notif_reported">Bericht senden</string>
|
||||
<string name="mute_tag">Den Hashtag %1$s wirklich stummschalten\?</string>
|
||||
|
@ -1078,4 +1078,25 @@
|
|||
<string name="Pronouns">Pronomen</string>
|
||||
<string name="pronouns_support">Unterstützung von Pronomen</string>
|
||||
<string name="qr_code_generator">QR Code Generator</string>
|
||||
<string name="instance_token">Dein Token</string>
|
||||
<string name="more_options">Mehr Optionen</string>
|
||||
<string name="action_favourite">Favorisieren</string>
|
||||
<string name="action_quote">Zitieren</string>
|
||||
<string name="add_content_warning">Content Warnung (CW) hinzufügen</string>
|
||||
<string name="remove_content_warning">Content Warnung (CW) entfernen</string>
|
||||
<string name="action_publish">Veröffentlichen</string>
|
||||
<string name="change_visibility">Sichtbarkeit anpassen</string>
|
||||
<string name="set_language">Sprache ändern</string>
|
||||
<string name="network">Netzwerk</string>
|
||||
<string name="set_audo_hide_compose_title">Verstecke Verfassen-Knopf automatisch</string>
|
||||
<string name="set_audo_hide_compose_summary">Versteckt den Verfassen-Knopf automatisch beim Scrollen durch eine Timeline</string>
|
||||
<string name="attach_images">Bilder anhängen</string>
|
||||
<string name="attach_audio">Audio angehängen</string>
|
||||
<string name="attach_videos">Videos anhängen</string>
|
||||
<string name="open_new_attachment_panel">Anhangsbereich öffnen</string>
|
||||
<string name="close_new_attachment_panel">Neuen Anhangsbereich schließen</string>
|
||||
<string name="attach_files">Dateien anhängen</string>
|
||||
<string name="add_poll">Umfrage anhängen</string>
|
||||
<string name="links">Links</string>
|
||||
<string name="toast_error_internet">Es gibt keine Verbindung zum Internet!</string>
|
||||
</resources>
|
||||
|
|
|
@ -448,13 +448,7 @@
|
|||
<string name="password_too_short">La contraseña debe tener al menos 8 caracteres</string>
|
||||
<string name="username_error">Los nombres de usuario solo pueden contener letras, números y guiones bajos</string>
|
||||
<string name="account_created">¡Cuenta creada!</string>
|
||||
<string name="account_created_message"> ¡Tu cuenta ha sido creada!
|
||||
\n
|
||||
\n \u0020Valida tu correo electrónico dentro de las próximas 48 horas.
|
||||
\n
|
||||
\n \u0020Ahora puedes conectar tu cuenta escribiendo <b>%1$s</b> en el primer campo y pulsando en <b>Conectar</b>.
|
||||
\n
|
||||
\n \u0020<b>Importante</b>: Si tu instancia requiere validación, recibirás un correo electrónico cuando se haya completado. \u0020</string>
|
||||
<string name="account_created_message">¡Tu cuenta ha sido creada! \n \n \u0020Valida tu correo electrónico dentro de las próximas 48 horas. \n \n \u0020Ahora puedes conectar tu cuenta escribiendo <b>%1$s</b> en el primer campo y pulsando en <b>Conectar</b>. \n \n \u0020<b>Importante</b>: Si tu instancia requiere validación, recibirás un correo electrónico cuando se haya completado.</string>
|
||||
<string name="save_draft">¿Guardar el mensaje en borradores?</string>
|
||||
<string name="administration">Administración</string>
|
||||
<string name="reports">Informes</string>
|
||||
|
@ -1064,7 +1058,7 @@
|
|||
<string name="data_import_settings_success">Los ajustes se importaron con éxito</string>
|
||||
<string name="messages_stored_in_drafts">Mensajes guardados en borradores</string>
|
||||
<string name="watch_trends_for_instance">Mira los temas relevantes en esta instancia</string>
|
||||
<string name="hide_content">Ocultar contenido <</string>
|
||||
<string name="hide_content"><![CDATA[Ocultar contenido <]]></string>
|
||||
<string name="set_fetch_home">Obtener automáticamente los mensajes de inicio</string>
|
||||
<string name="home_cache">Caché de Inicio</string>
|
||||
<string name="type_of_home_delay_title">Intervalo de actualización de la página de inicio</string>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -956,7 +956,7 @@
|
|||
<string name="set_remove_left_margin">Suppression de la marge de gauche dans les lignes de temps pour rendre les messages plus compacts</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="post_format">Format de publication</string>
|
||||
<string name="set_pixelfed_presentation">Présentation façon Pixelfed pour les médias</string>
|
||||
<string name="set_pixelfed_presentation">Présentation de Pixelfed pour les médias</string>
|
||||
<string name="set_display_quote_indication">Afficher le bouton « Citer »</string>
|
||||
<string name="set_display_reaction_indication">Afficher les boutons \"Réactions\"</string>
|
||||
<string name="set_post_format">Format du message</string>
|
||||
|
@ -1075,7 +1075,7 @@
|
|||
<string name="copy_version">Copier l\'information</string>
|
||||
<string name="qr_code_generator">Générateur de QR Code</string>
|
||||
<string name="set_disable_topbar_scrolling_title">Désactiver le défilement de la barre supérieure</string>
|
||||
<string name="thread_long_message_message">Le message sera divisé en plusieurs réponses en respectant la limite des caractères max de votre instance.</string>
|
||||
<string name="thread_long_message_message">Le message sera divisé en plusieurs réponses afin de respecter le nombre maximum de caractères de votre instance.</string>
|
||||
<string name="card_picture">Image de la carte</string>
|
||||
<string name="set_display_relative_date">Afficher la date relative des messages</string>
|
||||
<string name="pronouns_support">Prise en charge des pronoms</string>
|
||||
|
@ -1086,4 +1086,22 @@
|
|||
<string name="toast_fail_authenticate">L\'application n\'a réussi à authentifier le compte !</string>
|
||||
<string name="toast_error_internet">Pas de connexion internet !</string>
|
||||
<string name="set_pixelfed_full_media">Médias en plein écran</string>
|
||||
<string name="more_options">Plus d\'options</string>
|
||||
<string name="action_favourite">Favorit</string>
|
||||
<string name="action_quote">Citer</string>
|
||||
<string name="add_content_warning">Ajouter avertissement de contenu</string>
|
||||
<string name="action_publish">Publier</string>
|
||||
<string name="open_new_attachment_panel">Ouvrir nouveau panneau de pièces jointes</string>
|
||||
<string name="close_new_attachment_panel">Fermer nouveau panneau de pièces jointes</string>
|
||||
<string name="attach_videos">Joindre vidéos</string>
|
||||
<string name="attach_files">Joindre fichiers</string>
|
||||
<string name="network">Réseau</string>
|
||||
<string name="instance_information">Information de l\'instance</string>
|
||||
<string name="add_poll">Ajouter un sondage</string>
|
||||
<string name="remove_content_warning">Supprimer avertissement de contenu</string>
|
||||
<string name="change_visibility">Changer la visibilité</string>
|
||||
<string name="set_language">Définir la langue</string>
|
||||
<string name="attach_audio">Joindre audio</string>
|
||||
<string name="attach_images">Joindre images</string>
|
||||
<string name="set_pixelfed_full_media_indication">Les fichiers multimédia ocuperont toute la largeur de l\'écran et le format de la hauteur de l\'image sera respecté.</string>
|
||||
</resources>
|
||||
|
|
|
@ -1090,4 +1090,13 @@
|
|||
<string name="more_options">Máis opcións</string>
|
||||
<string name="action_quote">Citar</string>
|
||||
<string name="remove_content_warning">Retirar aviso sobre o contido</string>
|
||||
<string name="instance_information">Información da instancia</string>
|
||||
<string name="set_audo_hide_compose_title">Oculta o botón para redactar</string>
|
||||
<string name="network">Rede</string>
|
||||
<string name="set_audo_hide_compose_summary">Oculta automáticamente o botón para redactar cando te desprazas nunha cronoloxía</string>
|
||||
<string name="set_mention_booster">Mencionar a quen promoveu</string>
|
||||
<string name="set_mention_booster_indication">Ao responder a unha promoción, a persoa que promoveu será mencionada na resposta</string>
|
||||
<string name="links">Ligazóns</string>
|
||||
<string name="link_image">Imaxe anexa á ligazón</string>
|
||||
<string name="underline_bottom_hashtags">Destacar cancelos da parte inferior</string>
|
||||
</resources>
|
||||
|
|
|
@ -602,7 +602,7 @@
|
|||
<string name="channel_notif_signup">Nuova iscrizione</string>
|
||||
<string name="channel_notif_report">Nuova segnalazione</string>
|
||||
<string name="notif_update_push">Un messaggio che hai condiviso è stato modificato</string>
|
||||
<string name="show_content">Mostra contenuto ></string>
|
||||
<string name="show_content"><![CDATA[Mostra contenuto >]]></string>
|
||||
<string name="stop_recording">Ferma registrazione</string>
|
||||
<string name="report_val4">Si tratta di altro</string>
|
||||
<string name="report_1_unfollow">Stai seguendo questo account. Per non vedere più i suoi post sul tuo home feed, smetti di seguirlo.</string>
|
||||
|
@ -660,7 +660,7 @@
|
|||
<string name="post_message_text">Inviando messaggio %d/%d</string>
|
||||
<string name="is_up">É online!</string>
|
||||
<string name="notif_display_favourites">Preferiti</string>
|
||||
<string name="hide_content">Nascondi contenuto<</string>
|
||||
<string name="hide_content"><![CDATA[Nascondi contenuto >]]></string>
|
||||
<string name="report_1_mute_title">Muta %1$s</string>
|
||||
<string name="report_more_additional">Commenti aggiuntivi</string>
|
||||
<string name="dont_have_an_account">Non hai un account\?</string>
|
||||
|
@ -1069,4 +1069,38 @@
|
|||
<string name="fail_count">%d fallimenti</string>
|
||||
<string name="group_reblogs">Raggruppa i riblog nella linea temporale iniziale</string>
|
||||
<string name="fails">Fallisce</string>
|
||||
<string name="Pronouns">Pronomi</string>
|
||||
<string name="underline_links">Sottolinea gli elementi cliccabili</string>
|
||||
<string name="instance_token">Il tuo token</string>
|
||||
<string name="more_options">Altre opzioni</string>
|
||||
<string name="action_quote">Cita</string>
|
||||
<string name="action_favourite">Preferito</string>
|
||||
<string name="remove_content_warning">Rimuovi l\'avviso sul contenuto</string>
|
||||
<string name="add_content_warning">Aggiungi un avviso sul contenuto</string>
|
||||
<string name="change_visibility">Cambia la visibilità</string>
|
||||
<string name="set_language">Seleziona la lingua</string>
|
||||
<string name="action_publish">Pubblica</string>
|
||||
<string name="open_new_attachment_panel">Apri un pannello per nuovi allegati</string>
|
||||
<string name="close_new_attachment_panel">Chiudi il pannello per nuovi allegati</string>
|
||||
<string name="attach_images">Allega immagini</string>
|
||||
<string name="attach_audio">Allega audio</string>
|
||||
<string name="attach_videos">Allega video</string>
|
||||
<string name="attach_files">Allega file</string>
|
||||
<string name="add_poll">Aggiungi sondaggio</string>
|
||||
<string name="toast_error_token_empty">Il token non può essere vuoto!</string>
|
||||
<string name="instance_information">Informazioni sull\'istanza</string>
|
||||
<string name="copy_version">Copia informazioni</string>
|
||||
<string name="qr_code_generator">Generatore di QR</string>
|
||||
<string name="twitter_tags">Tag Twitter (via Nitter)</string>
|
||||
<string name="pronouns_support">Supporto dei pronomi</string>
|
||||
<string name="toast_fail_authenticate">L\'app non è riuscita ad autenticare l\'account!</string>
|
||||
<string name="tag_already_followed">Già segui questo tag!</string>
|
||||
<string name="toast_error_internet">Non c\'è connessione internet!</string>
|
||||
<string name="clipboard_version">Le informazioni sono state copiate negli appunti</string>
|
||||
<string name="network">Rete</string>
|
||||
<string name="set_mention_booster_indication">Quando si risponde ad un boost, la persone che è stata boostata sarà citata nella replica</string>
|
||||
<string name="set_pixelfed_full_media">Media a schermo intero</string>
|
||||
<string name="use_token">Usa un token</string>
|
||||
<string name="set_display_relative_date">Mostra la data relativa per i messaggi</string>
|
||||
<string name="timeline_scrollbar">Mostra la barra di scorrimento per le linee temporali</string>
|
||||
</resources>
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<string name="mention">Ibdaren</string>
|
||||
<string name="reblog">Izuzar</string>
|
||||
<string name="show_boosts">Sken-d izuzar</string>
|
||||
<string name="show_replies">Ssekned tiririt</string>
|
||||
<string name="show_replies">Sken-d tiririyin</string>
|
||||
<string name="action_open_in_web">Ldi deg iminig</string>
|
||||
<string name="translate">Suqel</string>
|
||||
<!--- Menu -->
|
||||
|
@ -63,12 +63,12 @@
|
|||
<string name="no_emoji">The app did not collect custom emojis for the moment.</string>
|
||||
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
|
||||
<!-- Status -->
|
||||
<string name="no_status">Ulac ituten ara d-nesken</string>
|
||||
<string name="no_status">Ulac iznan ara d-nesken</string>
|
||||
<string name="favourite_add">Add this toot to your favourites?</string>
|
||||
<string name="favourite_remove">Remove this toot from your favourites?</string>
|
||||
<string name="reblog_add">Boost this toot?</string>
|
||||
<string name="reblog_remove">Unboost this toot?</string>
|
||||
<string name="more_action_1">Susem</string>
|
||||
<string name="more_action_1">Sgugem</string>
|
||||
<string name="more_action_2">Seḥbes</string>
|
||||
<string name="more_action_3">Cetki</string>
|
||||
<string name="more_action_4">Kkes</string>
|
||||
|
@ -225,7 +225,7 @@
|
|||
</string-array>
|
||||
<string name="action_follow">Ḍfeṛ</string>
|
||||
<string name="action_unblock">Serreḥ</string>
|
||||
<string name="action_mute">Susem</string>
|
||||
<string name="action_mute">Sgugem</string>
|
||||
<string name="action_unmute">Unmute</string>
|
||||
<string name="request_sent">Request sent</string>
|
||||
<string name="followed_by">Yeṭafar-ik id</string>
|
||||
|
@ -243,9 +243,9 @@
|
|||
<string name="keywords_hint_custom_sharing">Awalen n tsaruţ…</string>
|
||||
<!-- ACTIVITY CACHE -->
|
||||
<string name="v_public">Azayez</string>
|
||||
<string name="v_unlisted">Unlisted</string>
|
||||
<string name="v_unlisted">War abdar</string>
|
||||
<string name="v_private">Uslig</string>
|
||||
<string name="v_direct">Direct</string>
|
||||
<string name="v_direct">Srid</string>
|
||||
<!-- PRIVACY -->
|
||||
<string name="filter_regex">Filter out by regular expressions</string>
|
||||
<string name="search">Nadi</string>
|
||||
|
@ -324,7 +324,7 @@
|
|||
<string name="display_toot_truncate">Sken ddeqs</string>
|
||||
<string name="hide_toot_truncate">Sken kra kan</string>
|
||||
<string name="tags_already_stored">The tag already exists!</string>
|
||||
<string name="schedule_boost">Schedule boost</string>
|
||||
<string name="schedule_boost">Sɣiwes azuzer</string>
|
||||
<string name="boost_scheduled">The boost is scheduled!</string>
|
||||
<string name="no_scheduled_boosts">No scheduled boost to display!</string>
|
||||
<string name="open_menu">Ldi umuɣ</string>
|
||||
|
@ -466,7 +466,7 @@
|
|||
<string name="suspend">Suspend</string>
|
||||
<string name="unsuspend">Undo suspend</string>
|
||||
<string name="audio">The application needs to access audio recording</string>
|
||||
<string name="voice_message">Voice message</string>
|
||||
<string name="voice_message">Izen s taɣect</string>
|
||||
<string name="set_enable_time_slot_indication">During the time slot, the app will send notifications. You can reverse (ie: silent) this time slot with the right spinner.</string>
|
||||
<string name="set_fit_preview_indication">Previews will not be cropped in timelines</string>
|
||||
<string name="set_capitalize_indication">Automatically insert a line break after the mention to capitalize the first letter</string>
|
||||
|
@ -643,4 +643,9 @@
|
|||
<string name="import_settings">Iɣewwaṛen n uketer</string>
|
||||
<string name="load_settings">Ɛebbi iɣewwaṛen yettwasifḍen</string>
|
||||
<string name="import_data">Kter isefka</string>
|
||||
<string name="instance_information">Talɣut ɣef uqeddac</string>
|
||||
<string name="interactions">Timyigawin</string>
|
||||
<string name="Directory">Akaram</string>
|
||||
<string name="my_instance">Aqeddac-iw</string>
|
||||
<string name="followers_only">Imeḍfaṛen kan</string>
|
||||
</resources>
|
||||
|
|
|
@ -97,4 +97,77 @@
|
|||
<string name="set_custom_accent_light_value">Šviesi akcento spalva</string>
|
||||
<string name="thumbnail">Miniatiūra</string>
|
||||
<string name="set_custom_accent_dark_value">Tamsi akcento spalva</string>
|
||||
<string name="favourite">Mėgstami</string>
|
||||
<string name="follow">Nauji sekėjai</string>
|
||||
<string name="mention">Paminėjimai</string>
|
||||
<string name="reblog">Pasidalinimai</string>
|
||||
<string name="show_boosts">Rodyti pasidalinimus</string>
|
||||
<string name="show_replies">Rodyti atsakymus</string>
|
||||
<string name="show_self_boosts">Rodyti savo pasidalinimus</string>
|
||||
<string name="show_self_replies">Rodyti savo atsakymus</string>
|
||||
<string name="show_my_messages">Rodyti mano įrašus</string>
|
||||
<string name="show_privates">Rodyti tiesiogines žinutes</string>
|
||||
<string name="action_open_in_web">Atverti naršyklėje</string>
|
||||
<string name="translate">Versti</string>
|
||||
<string name="home_menu">Pagrindinis</string>
|
||||
<string name="context_home">Pagrindinė laiko juosta</string>
|
||||
<string name="settings_category_label_interface">Sąsaja</string>
|
||||
<string name="done">Atlikta</string>
|
||||
<string name="display_name">Rodomas vardas</string>
|
||||
<string name="label_emoji">Jaustukai</string>
|
||||
<string name="more_options">Daugiau parinkčių</string>
|
||||
<string name="muted_menu">Nutildyti naudotojai</string>
|
||||
<string name="muted_menu_home">Pagrindinio nutildyti naudotojai</string>
|
||||
<string name="send_email">Siųsti el. laišką</string>
|
||||
<string name="disclaimer_full">Žemiau esanti informacija gali nevisiškai atitikti naudotojo profilį.</string>
|
||||
<string name="insert_emoji">Įterpti jaustuką</string>
|
||||
<string name="no_emoji">Šiuo metu programėlė nerinko pasirinktinių jaustukų.</string>
|
||||
<string name="action_favourite">Pamėgti</string>
|
||||
<string name="action_reblog">Pasidalinti</string>
|
||||
<string name="action_quote">Cituoti</string>
|
||||
<string name="poll_choice_s">%d pasirinkimas</string>
|
||||
<string name="poll_invalid_choices">Reikia bent dviejų pasirinkimų apklausai.</string>
|
||||
<string name="gnu_instance">GNU serveris</string>
|
||||
<string name="label_text">Tekstas</string>
|
||||
<string name="label_filter">Filtras</string>
|
||||
<string name="profile_picture">Profilio nuotrauka</string>
|
||||
<string name="blocked_menu">Užblokuoti naudotojai</string>
|
||||
<string name="report_1_unfollow">Sekate šią paskyrą. Kad nebematytumėte jų įrašų savo pagrindiniame sraute, nebesekite jų.</string>
|
||||
<string name="context_home_list">Pagrindinė ir sąrašai</string>
|
||||
<string name="logout_account_confirmation">Ar tikrai norite atsijungti @%1$s@%2$s?</string>
|
||||
<string name="messages_in_cache_for_home">Įrašai podėlyje skalei Pagrindinė</string>
|
||||
<string name="mute_home">Nutildyti skalei pagrindinė</string>
|
||||
<string name="check_home_cache">Tikrinti pagrindinio podėlį</string>
|
||||
<string name="chart_home_cache_logs">Pagrindinio podėlio žurnalai</string>
|
||||
<string name="chart_home_cache">Pagrindinio podėlio įrašai per valandą</string>
|
||||
<string name="follows_you">Seka jus</string>
|
||||
<string name="fails">Failai</string>
|
||||
<string name="set_custom_accent_value_dark_description">Spalva, kuri bus taikoma tamsiai temai</string>
|
||||
<string name="set_custom_accent_value_light_description">Spalva, kuri bus taikoma šviesiai temai</string>
|
||||
<string name="fetch_home_every">Gauti pagrindinę kas</string>
|
||||
<string name="type_of_home_delay_title">Pagrindinės gavimo laikas</string>
|
||||
<string name="set_fetch_home">Automatiškai gauti pagrindinius įrašus</string>
|
||||
<string name="set_live_translate">Priverstinai išverskite į konkrečią kalbą. Pasirinkite pirmąją reikšmę, kad atkurtumėte įrenginio nustatymus.</string>
|
||||
<string name="home_cache">Pagrindinio podėlis</string>
|
||||
<string name="fetch_home_messages">Gauti pagrindinius įrašus</string>
|
||||
<string name="clipboard">Įrašo turinys nukopijuotas į iškarpinę</string>
|
||||
<string name="clipboard_url">Įrašo URL nukopijuotas į iškarpinę</string>
|
||||
<string name="clipboard_version">Informacija nukopijuota į iškarpinę</string>
|
||||
<string name="media">Medija</string>
|
||||
<string name="validate">Patikrinti</string>
|
||||
<string name="share_with">Bendrinti su</string>
|
||||
<string name="shared_via">Bendrinta per „Fedilab“</string>
|
||||
<string name="replies">Atsakymai</string>
|
||||
<string name="username">Naudotojo vardas</string>
|
||||
<string name="drafts">Juodraščiai</string>
|
||||
<string name="notifications">Pranešimai</string>
|
||||
<string name="follow_request">Sekimo prašymai</string>
|
||||
<string name="favourite_add">Pridėti šį įrašą prie savo mėgstamų?</string>
|
||||
<string name="favourite_remove">Pašalinti šį įrašą iš savo mėgstamų?</string>
|
||||
<string name="reblog_add">Pasidalinti šiuo įrašu?</string>
|
||||
<string name="warn_boost_no_media_description">Įspėti, jei prieš pasidalinat įrašą nėra medijos aprašo</string>
|
||||
<string name="no_status">Nėra įrašo parodyti.</string>
|
||||
<string name="languages">Kalbos</string>
|
||||
<string name="administration">Administravimas</string>
|
||||
<string name="reports">Ataskaitos</string>
|
||||
</resources>
|
||||
|
|
|
@ -276,7 +276,7 @@
|
|||
<string name="poxy_port">Порт</string>
|
||||
<string name="poxy_login">Имя пользователя</string>
|
||||
<string name="poxy_password">Пароль</string>
|
||||
<string name="set_share_details">Добавлять детали сообщения при перепосте</string>
|
||||
<string name="set_share_details">Добавлять детали сообщения при перепубликации</string>
|
||||
<string name="support_the_app_on_liberapay">Поддержать приложение на Liberapay</string>
|
||||
<string name="alert_regex">В регулярном выражении есть ошибка!</string>
|
||||
<string name="toast_instance_unavailable">На этом инстансе лент не найдено!</string>
|
||||
|
@ -682,7 +682,7 @@
|
|||
<string name="followed_tags">Отслеживаемые теги</string>
|
||||
<string name="follow_tag">Подписаться на тег</string>
|
||||
<string name="report_val4">Другое</string>
|
||||
<string name="show_content">Показать содержимое ></string>
|
||||
<string name="show_content"><![CDATA[Показать содержимое>]]></string>
|
||||
<string name="join_the_fediverse">Присоединяйтесь к fediverse</string>
|
||||
<string name="invite_join_the_fediverse">Привет! Приглашаем Вас присоединиться к Fediverse.</string>
|
||||
<string name="report_val_more4">Проблема не подпадает под другие категории</string>
|
||||
|
@ -1030,4 +1030,13 @@
|
|||
<string name="unmute_home">Не игнорировать для домашней</string>
|
||||
<string name="mute_them_all">Игнорировать их все</string>
|
||||
<string name="manage_accounts">Управление профилями</string>
|
||||
<string name="toast_fetch_error">Приложение не может найти удаленные данные!</string>
|
||||
<string name="set_notif_admin_report">Новый отчёт (модераторы)</string>
|
||||
<string name="open_with_account">Открыть из другой учётной записи</string>
|
||||
<string name="set_audo_hide_compose_title">Припрятывать кнопку Составить</string>
|
||||
<string name="create_domain_block">Добавить блокировку домена</string>
|
||||
<string name="admin_reject_obfuscate">Обфусцировать доменное имя</string>
|
||||
<string name="admin_domainblock_reject_media">Игнорироать все жалобы, поступающие от этого домена. Не имеет значения для приостановок</string>
|
||||
<string name="admin_reject_reports">Отклонять жалобы</string>
|
||||
<string name="admin_domainblock_reject_reports">Игнорироать все жалобы, поступающие от этого домена. Не имеет значения для приостановок</string>
|
||||
</resources>
|
||||
|
|
|
@ -372,32 +372,32 @@
|
|||
<string name="change_tag_column">Змінити назву стовпця</string>
|
||||
<string name="misskey_instance">Екземпляр Misskey</string>
|
||||
<string name="trending">В тренді</string>
|
||||
<string name="local">Local</string>
|
||||
<string name="local">Місцевий</string>
|
||||
<string name="category">Категорія</string>
|
||||
<string name="description">Description</string>
|
||||
<string name="description">Опис</string>
|
||||
<string name="share">Поділіться</string>
|
||||
<string name="toots_server">Повідомлення (сервер)</string>
|
||||
<string name="toots_client">Повідомлення (пристрій)</string>
|
||||
<string name="settings_category_label_timelines">Часові рамки</string>
|
||||
<string name="settings_category_label_interface">Interface</string>
|
||||
<string name="contact">Contacts</string>
|
||||
<string name="settings_category_label_interface">Інтерфейс</string>
|
||||
<string name="contact">Контакти</string>
|
||||
<string name="toot_select_file_error">Під час вибору файлу резервної копії сталася помилка!</string>
|
||||
<string name="action_logout_account">Вийти з облікового запису</string>
|
||||
<string name="all">Все</string>
|
||||
<string name="copy_link">Копіювати посилання</string>
|
||||
<string name="calls_blocked">http-дзвінки, заблоковані програмою</string>
|
||||
<string name="list_of_blocked_domains">Список заблокованих дзвінків</string>
|
||||
<string name="submit">Submit</string>
|
||||
<string name="submit">Надіслати</string>
|
||||
<string name="filter_timeline_with_a_tag">Фільтрувати шкалу часу з тегами</string>
|
||||
<string name="no_tags">No tags</string>
|
||||
<string name="no_tags">Без тегів</string>
|
||||
<string name="set_retrieve_metadata_share_from_extras">Додайте зображення, коли надсилаєте URL-адресу</string>
|
||||
<!-- end languages -->
|
||||
<string name="create_poll">Створіть опитування</string>
|
||||
<string name="poll_choice_s">Вибір %d</string>
|
||||
<string name="poll_invalid_choices">Вам потрібно принаймні два варіанти для опитування!</string>
|
||||
<string name="done">Готово</string>
|
||||
<string name="poll_finish_at">end at %s</string>
|
||||
<string name="vote">Vote</string>
|
||||
<string name="poll_finish_at">кінець о %s</string>
|
||||
<string name="vote">Голосувати</string>
|
||||
<string name="notif_poll">Опитування, у якому ви проголосували, завершено</string>
|
||||
<string name="notif_poll_self">Опубліковане вами опитування закінчилося</string>
|
||||
<string name="settings_category_notif_categories">Категорії</string>
|
||||
|
@ -415,9 +415,9 @@
|
|||
<string name="set_long_press_media">Натисніть і утримуйте, щоб зберегти медіа</string>
|
||||
<string name="add_tags">Керуйте тегами</string>
|
||||
<string name="display_name">Відображуване ім\'я</string>
|
||||
<string name="label_emoji">Emoji</string>
|
||||
<string name="label_text">Text</string>
|
||||
<string name="label_filter">Filter</string>
|
||||
<string name="label_emoji">Е-пошта</string>
|
||||
<string name="label_text">Текст</string>
|
||||
<string name="label_filter">Фільтр</string>
|
||||
<string name="label_brush">Кисть</string>
|
||||
<string name="discard">Відкинути</string>
|
||||
<string name="saving">Збереження…</string>
|
||||
|
@ -428,12 +428,12 @@
|
|||
<string name="unmute_conversation">Увімкнути бесіду</string>
|
||||
<string name="toast_unmute_conversation">Розмова більше не ігнорується!</string>
|
||||
<string name="toast_mute_conversation">Розмова вимкнено</string>
|
||||
<string name="category_general">General</string>
|
||||
<string name="category_general">Загальне</string>
|
||||
<string name="category_regional">Регіональний</string>
|
||||
<string name="category_art">Арт</string>
|
||||
<string name="category_activism">Активізм</string>
|
||||
<string name="category_games">Геймінг</string>
|
||||
<string name="category_tech">Technology</string>
|
||||
<string name="category_tech">Технології</string>
|
||||
<string name="category_furry">Пухнастий</string>
|
||||
<string name="category_food">Їжа</string>
|
||||
<string name="instance_logo">Логотип інстанції</string>
|
||||
|
@ -453,24 +453,20 @@
|
|||
<string name="password_too_short">Пароль має містити не менше 8 символів</string>
|
||||
<string name="username_error">Ім\'я користувача має містити лише літери, цифри та підкреслення</string>
|
||||
<string name="account_created">Обліковий запис створено!</string>
|
||||
<string name="account_created_message"> 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 <b>%1$s</b> in the first field and click on <b>Connect</b>.\n\n
|
||||
<b>Important</b>: If your instance required validation, you will receive an email once it is validated!
|
||||
</string>
|
||||
<string name="account_created_message">Ваш обліковий запис створено!\n\nПодумайте про підтвердження вашої електронної пошти протягом наступних 48 годин.\n\n Тепер ви можете підключити свій обліковий запис, ввівши <b>%1$s</b> у перше поле та натиснувши <b>Підключитися</b>.\n\n<b>Важливо</b>: Якщо ваш екземпляр потребував перевірки, ви отримаєте електронний лист після її завершення!</string>
|
||||
<string name="save_draft">Зберегти повідомлення в чернетках?</string>
|
||||
<string name="administration">Administration</string>
|
||||
<string name="administration">Адміністрація</string>
|
||||
<string name="reports">Reports</string>
|
||||
<string name="unresolved">Невирішено</string>
|
||||
<string name="remote">Дистанційний</string>
|
||||
<string name="active">Active</string>
|
||||
<string name="active">Активний</string>
|
||||
<string name="pending">В очікуванні</string>
|
||||
<string name="disabled">Вимкнено</string>
|
||||
<string name="suspended">Підвішено</string>
|
||||
<string name="permissions">Дозволи</string>
|
||||
<string name="disable">Вимкнути</string>
|
||||
<string name="silence">Тиша</string>
|
||||
<string name="account">Account</string>
|
||||
<string name="account">Обліковий запис</string>
|
||||
<string name="unsilence">Відмінити тишу</string>
|
||||
<string name="undisable">Відмінити вимкнення</string>
|
||||
<string name="suspend">Призупинити</string>
|
||||
|
@ -517,10 +513,10 @@
|
|||
<string name="set_unfollow_validation">Показати діалогове вікно підтвердження, перш ніж скасувати підписку</string>
|
||||
<string name="replace_medium">Replace Medium links</string>
|
||||
<string name="replace_medium_description">Використовуйте альтернативний фронтенд для Medium</string>
|
||||
<string name="replace_medium_host">Default: scribe.rip</string>
|
||||
<string name="replace_medium_host">Середній фронтенд-домен</string>
|
||||
<string name="set_push_notifications">Використовуйте систему push-повідомлень для отримання сповіщень у режимі реального часу.</string>
|
||||
<string name="action_add_notes">Add notes</string>
|
||||
<string name="note_for_account">Notes for the account</string>
|
||||
<string name="action_add_notes">Додати нотатки</string>
|
||||
<string name="note_for_account">Примітки до облікового запису</string>
|
||||
<string name="set_resize_picture_indication">Дозволяє стискати великі фотографії у фотографії меншого розміру з дуже незначною втратою якості зображення.</string>
|
||||
<string name="set_resize_video_indication">Дозволяє стискати відео, зберігаючи їх якість.</string>
|
||||
<string name="order_by">Замовити за</string>
|
||||
|
@ -530,32 +526,32 @@
|
|||
<string name="displayname_title">Змініть колір відображуваного імені у верхній частині повідомлень</string>
|
||||
<string name="username_title">Змініть колір імені користувача у верхній частині повідомлень</string>
|
||||
<string name="boost_header_color">Змініть колір заголовка для реблогів</string>
|
||||
<string name="background_status_title">Posts</string>
|
||||
<string name="background_status_title">Дописи</string>
|
||||
<string name="background_status">Колір фону публікацій у часових шкалах</string>
|
||||
<string name="reset_color">Скинути кольори</string>
|
||||
<string name="clik_reset">Торкніться тут, щоб скинути всі власні кольори</string>
|
||||
<string name="reset">Скинути</string>
|
||||
<string name="icons_color_title">Icons</string>
|
||||
<string name="icons_color_title">Іконки</string>
|
||||
<string name="icons_color">Колір нижніх значків на шкалі часу</string>
|
||||
<string name="logo_of_the_instance">Логотип інстанції</string>
|
||||
<string name="edit_profile">Редагувати профіль</string>
|
||||
<string name="make_an_action">Зробіть дію</string>
|
||||
<string name="translation">Переклад</string>
|
||||
<string name="text_color_title">Text color</string>
|
||||
<string name="text_color_title">Колір тексту</string>
|
||||
<string name="text_color">Змінити колір тексту в повідомленнях</string>
|
||||
<string name="pref_custom_theme">Використовуйте спеціальну тему</string>
|
||||
<string name="theming">Тематизація</string>
|
||||
<string name="data_export_theme">Тему було експортовано</string>
|
||||
<string name="data_export_theme_success">Тему успішно експортовано у CSV</string>
|
||||
<string name="import_theme">Import a theme</string>
|
||||
<string name="import_theme">Імпорт теми</string>
|
||||
<string name="import_theme_title">Торкніться тут, щоб імпортувати тему з попереднього експорту</string>
|
||||
<string name="export_theme">Export the theme</string>
|
||||
<string name="export_theme">Експорт теми</string>
|
||||
<string name="export_theme_title">Торкніться тут, щоб експортувати поточну тему</string>
|
||||
<string name="theme_file_error">Під час вибору файлу теми сталася помилка</string>
|
||||
<string name="user_count">Кількість користувачів</string>
|
||||
<string name="status_count">Кількість статусів</string>
|
||||
<string name="instance_count">Кількість примірників</string>
|
||||
<string name="poll_finish_in">End in %s</string>
|
||||
<string name="poll_finish_in">Закінчиться через %s</string>
|
||||
<string name="no_instance_reccord">Цей екземпляр недоступний на https://instances.social</string>
|
||||
<string name="display_full_link">Показати повне посилання</string>
|
||||
<string name="share_link">Поділитися посиланням</string>
|
||||
|
@ -652,7 +648,7 @@
|
|||
<string name="hide_content"><![CDATA[Hide content <]]></string>
|
||||
<string name="report_val1">Мені це не подобається</string>
|
||||
<string name="report_val4">Це щось інше</string>
|
||||
<string name="stop_recording">ЗУпинити запис</string>
|
||||
<string name="stop_recording">Зупинити запис</string>
|
||||
<string name="report_1_title">Не хочеш це бачити?</string>
|
||||
<string name="report_1_unfollow_title">Відписатись від %1$s</string>
|
||||
<string name="instance_health_uptime">Час роботи: %,.2f %%</string>
|
||||
|
@ -1106,4 +1102,11 @@
|
|||
<string name="action_favourite">Улюблений</string>
|
||||
<string name="network">Мережа</string>
|
||||
<string name="instance_information">Інформація про примірник</string>
|
||||
<string name="set_audo_hide_compose_title">Автоматично приховати кнопку створення</string>
|
||||
<string name="set_audo_hide_compose_summary">Автоматично приховувати кнопку створення під час прокручування вгору на часовій шкалі</string>
|
||||
<string name="set_mention_booster_indication">Під час відповіді на посилення особа, яка здійснила посилення, буде згадана у відповіді</string>
|
||||
<string name="set_mention_booster">Згадайте бустер</string>
|
||||
<string name="underline_bottom_hashtags">Виділіть нижні хештеги</string>
|
||||
<string name="links">Посилання</string>
|
||||
<string name="link_image">Зображення додано до посилання</string>
|
||||
</resources>
|
||||
|
|
|
@ -1094,4 +1094,11 @@
|
|||
<string name="instance_information">实例信息</string>
|
||||
<string name="attach_files">附加文件</string>
|
||||
<string name="network">网络</string>
|
||||
<string name="set_audo_hide_compose_summary">向上滚动时间轴时自动隐藏编辑按钮</string>
|
||||
<string name="set_audo_hide_compose_title">自动隐藏编辑按钮</string>
|
||||
<string name="set_mention_booster_indication">回复转嘟时,会在回复中提及转发嘟文的人</string>
|
||||
<string name="set_mention_booster">提及转发嘟文者</string>
|
||||
<string name="links">链接</string>
|
||||
<string name="underline_bottom_hashtags">突出显示底部话题标签</string>
|
||||
<string name="link_image">附加到链接的图像</string>
|
||||
</resources>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<string name="email">Email</string>
|
||||
<string name="accounts">Accounts</string>
|
||||
<string name="toots">Messages</string>
|
||||
<string name="links">Links</string>
|
||||
<string name="tags">Tags</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="instance">Instance</string>
|
||||
|
@ -731,13 +732,19 @@
|
|||
<string name="interactions">Interactions</string>
|
||||
<string name="add_filter">Add filter</string>
|
||||
<string name="add_field">Add Field</string>
|
||||
<string name="add_featured_hashtag">Add Featured Hashtag</string>
|
||||
<string name="no_feature_hashtag_suggestion">No suggestions for featured hashtags!</string>
|
||||
<string name="unlocked">Unlocked</string>
|
||||
<string name="locked">Locked</string>
|
||||
<string name="save_changes">Save changes</string>
|
||||
<string name="set_bot_content">Bot account</string>
|
||||
<string name="fields_title">Add or remove fields</string>
|
||||
<string name="featured_hashtags_title">Add or remove featured hashtags</string>
|
||||
<string name="set_discoverable_content">Account discoverable</string>
|
||||
<string name="delete_field">Delete field</string>
|
||||
<string name="delete_featured_hashtag">Delete featured hashtag</string>
|
||||
<string name="delete_field_confirm">Are you sure you want to delete that field?</string>
|
||||
<string name="delete_featured_hashtag_confirm">Are you sure you want to delete that featured hashtag?</string>
|
||||
<string name="profiled_updated">Profile has been updated!</string>
|
||||
<string name="not_valid_list_name">List name is not valid!</string>
|
||||
<string name="no_account_in_list">No accounts found for this list!</string>
|
||||
|
@ -1148,7 +1155,7 @@
|
|||
<string name="SET_DISABLE_ANIMATED_EMOJI" translatable="false">SET_DISABLE_ANIMATED_EMOJI</string>
|
||||
<string name="SET_CAPITALIZE" translatable="false">SET_CAPITALIZE</string>
|
||||
<string name="SET_MENTIONS_AT_TOP" translatable="false">SET_MENTIONS_AT_TOP</string>
|
||||
|
||||
<string name="SET_MENTION_BOOSTER" translatable="false">SET_MENTION_BOOSTER</string>
|
||||
<string name="SET_THREAD_MESSAGE" translatable="false">SET_THREAD_MESSAGE</string>
|
||||
<string name="SET_THEME_BASE" translatable="false">SET_THEME_BASE</string>
|
||||
<string name="SET_DYNAMICCOLOR" translatable="false">SET_DYNAMICCOLOR</string>
|
||||
|
@ -1265,6 +1272,7 @@
|
|||
<string name="SET_TIMELINE_SCROLLBAR" translatable="false">SET_TIMELINE_SCROLLBAR</string>
|
||||
<string name="SET_MARKDOWN_SUPPORT" translatable="false">SET_MARKDOWN_SUPPORT</string>
|
||||
<string name="SET_TRUNCATE_LINKS" translatable="false">SET_TRUNCATE_LINKS</string>
|
||||
<string name="SET_UNDERLINE_BOTTOM_HASHTAGS" translatable="false">SET_UNDERLINE_BOTTOM_HASHTAGS</string>
|
||||
<string name="SET_UNDERLINE_CLICKABLE" translatable="false">SET_UNDERLINE_CLICKABLE</string>
|
||||
<string name="SET_PRONOUNS_SUPPORT" translatable="false">SET_PRONOUNS_SUPPORT</string>
|
||||
<string name="SET_TRUNCATE_LINKS_MAX" translatable="false">SET_TRUNCATE_LINKS_MAX</string>
|
||||
|
@ -1382,6 +1390,7 @@
|
|||
<string name="set_push_notifications_delay">Set the delay between each new fetch</string>
|
||||
<string name="refresh_every">Fetch notifications every:</string>
|
||||
<string name="type_of_notifications_delay_title">Notifications fetch time</string>
|
||||
<string name="link_image">Image attached to the link</string>
|
||||
<string-array name="photo_editor_emoji" translatable="false">
|
||||
<!-- Smiles -->
|
||||
<item>u+1f604</item>
|
||||
|
@ -2060,6 +2069,8 @@
|
|||
<string name="set_mention_at_top">Mentions at the top</string>
|
||||
<string name="set_mention_at_top_indication">When replying mentions will all be added to the beginning of the message</string>
|
||||
|
||||
<string name="set_mention_booster">Mention the booster</string>
|
||||
<string name="set_mention_booster_indication">When replying to a boost, the person who boosted will be mentioned in the reply</string>
|
||||
|
||||
<string name="number_of_media">Number of media</string>
|
||||
<string name="number_of_replies">Number of replies</string>
|
||||
|
@ -2079,6 +2090,7 @@
|
|||
<string name="toot_error_no_media_description">There are missing media descriptions</string>
|
||||
|
||||
<string name="truncate_links">Truncate links</string>
|
||||
<string name="underline_bottom_hashtags">Highlight bottom hashtags</string>
|
||||
<string name="underline_links">Underline clickable elements</string>
|
||||
<string name="truncate_links_max">Max chars in links</string>
|
||||
|
||||
|
|
|
@ -273,5 +273,8 @@
|
|||
<item name="android:insetBottom">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.Fedilab.DrawerMedia" parent="">
|
||||
<item name="cornerSize">6dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -32,6 +32,15 @@
|
|||
app:singleLineTitle="false"
|
||||
app:summary="@string/set_mention_at_top_indication"
|
||||
app:title="@string/set_mention_at_top" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:defaultValue="false"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/SET_MENTION_BOOSTER"
|
||||
app:singleLineTitle="false"
|
||||
app:summary="@string/set_mention_booster_indication"
|
||||
app:title="@string/set_mention_booster" />
|
||||
|
||||
<!--
|
||||
<SwitchPreferenceCompat
|
||||
app:defaultValue="false"
|
||||
|
|
|
@ -72,6 +72,14 @@
|
|||
app:singleLineTitle="false"
|
||||
app:title="@string/truncate_links" />
|
||||
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/SET_UNDERLINE_BOTTOM_HASHTAGS"
|
||||
app:singleLineTitle="false"
|
||||
app:title="@string/underline_bottom_hashtags" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
app:iconSpaceReserved="false"
|
||||
|
@ -256,7 +264,7 @@
|
|||
app:title="@string/set_fit_preview" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:defaultValue="false"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/SET_AUTO_PLAY_GIG_MEDIA"
|
||||
app:singleLineTitle="false"
|
||||
|
|
|
@ -373,8 +373,11 @@ public class Translate {
|
|||
//Retrieves the translated content
|
||||
String content;
|
||||
try {
|
||||
content = URLDecoder.decode(translationJson.getString("translation"), "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
String data = translationJson.getString("translation");
|
||||
data = data.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
|
||||
data = data.replaceAll("\\+", "%2B");
|
||||
content = URLDecoder.decode(data, "utf-8");
|
||||
} catch (Exception e) {
|
||||
content = translationJson.getString("translation");
|
||||
}
|
||||
translate.setTranslatedContent(content);
|
||||
|
|
14
src/fdroid/fastlane/metadata/android/ar/changelogs/500.txt
Normal file
14
src/fdroid/fastlane/metadata/android/ar/changelogs/500.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
تم إضافة:
|
||||
- ثلاثة أيقونات تطبيق جديدة (برايد، وردي، وقرصان)
|
||||
- الحفاظ على الموضع في المحادثات عن بعد
|
||||
|
||||
تم إصلاح:
|
||||
- ماركداون: إيقاف تحليل الوسوم ودعم النص المشطوب
|
||||
- جعل المؤشر أكثر وضوحاً عند الكتابة
|
||||
- عدم عمل الحد الأقصى لطول الأحرف في النسخ المخصصة
|
||||
- مشكلة علامات التبويب في الملفات الشخصية
|
||||
- عدم إمكانية النقر على الوسوم في بعض اللغات
|
||||
- خطأ يتعلق بالحسابات التي لديها عدد كبير جداً من المتابعين
|
||||
- مشكلة الانهيار عند وجود عدة صور متحركة (GIF) في نفس الرسالة
|
||||
- - الحد الأقصى لأحرف الاستطلاع
|
||||
- بعض الأعطال
|
|
@ -0,0 +1,8 @@
|
|||
تمت إضافة:
|
||||
- دعم أندرويد 14
|
||||
- تقسيم الرسائل الطويلة تلقائيًا في سلاسل المحادثات (الافتراضي: اسأل)
|
||||
- الروابط والوسائط قابلة للنقر عند الإنشاء
|
||||
|
||||
تم إصلاح:
|
||||
- تجنب الخطأ 429 مع NTFY
|
||||
- تم إصلاح العديد من الأعطال
|
|
@ -0,0 +1,8 @@
|
|||
تمت إضافة:
|
||||
- دعم أندرويد 14
|
||||
- تقسيم الرسائل الطويلة تلقائيًا في سلاسل المحادثات (الافتراضي: اسأل)
|
||||
- الروابط والوسائط قابلة للنقر عند الإنشاء
|
||||
|
||||
تم إصلاح:
|
||||
- تجنب الخطأ 429 مع NTFY
|
||||
- تم إصلاح العديد من الأعطال
|
14
src/fdroid/fastlane/metadata/android/ar/changelogs/503.txt
Normal file
14
src/fdroid/fastlane/metadata/android/ar/changelogs/503.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
تمت الإضافة:
|
||||
- السماح بوضع خط تحت العناصر القابلة للنقر (الإعدادات > الجداول الزمنية - الافتراضي: معطل)
|
||||
- السماح بتعطيل التاريخ النسبي في الرسائل
|
||||
|
||||
تم التغيير:
|
||||
- العدادات قريبة من أزرار الإجراءات
|
||||
- إخفاء منتقي الرموز التعبيرية إذا لم يكن لدى المثيل رموز تعبيرية
|
||||
- ترتيب الوسوم التي تتابعها
|
||||
- منتقي الحساب عند الفتح بحساب آخر
|
||||
|
||||
تم الإصلاح:
|
||||
- إصلاح عطل عند الإنشاء
|
||||
- إصلاح مشكلة زر الرجوع
|
||||
- إصلاح مشكلة عرض الوسوم التي تتابعها
|
|
@ -0,0 +1,9 @@
|
|||
**تمت الإضافة:**
|
||||
- إضافة شريط تمرير للمخططات الزمنية (معطل افتراضيًا)
|
||||
- إضافة شريط بحث للرموز التعبيرية المخصصة
|
||||
|
||||
**تم الإصلاح:**
|
||||
- إصلاح ظهور المطالبة بالتقسيم عدة مرات عند الرفض
|
||||
- إصلاح الأعطال المتعلقة بالملفات الشخصية
|
||||
- إصلاح مشكلة تتعلق بالاستطلاعات وPleroma
|
||||
- إصلاح عدم ظهور الرموز التعبيرية في أداة الاختيار
|
25
src/fdroid/fastlane/metadata/android/ar/changelogs/505.txt
Normal file
25
src/fdroid/fastlane/metadata/android/ar/changelogs/505.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
تمت إضافة:
|
||||
- دعم أندرويد 14
|
||||
- تقسيم الرسائل الطويلة تلقائيًا في سلاسل المحادثات (الافتراضي: اسأل)
|
||||
- الروابط والوسائط قابلة للنقر عند الإنشاء
|
||||
- السماح بوضع خط تحت العناصر القابلة للنقر (الإعدادات > الجداول الزمنية - الافتراضي: معطل)
|
||||
- السماح بتعطيل التاريخ النسبي في الرسائل
|
||||
- إضافة شريط تمرير للجداول الزمنية (الافتراضي: معطل)
|
||||
- إضافة شريط بحث للرموز التعبيرية المخصصة
|
||||
- الروابط قابلة للنقر في أوصاف الوسائط
|
||||
|
||||
تم تغيير:
|
||||
- العدادات قريبة من أزرار الإجراءات
|
||||
- إخفاء منتقي الرموز التعبيرية إذا لم يكن لدى المثيل أي رموز تعبيرية
|
||||
- ترتيب الوسوم المتابعة
|
||||
- منتقي الحساب عند الفتح بحساب آخر
|
||||
|
||||
تم إصلاح:
|
||||
- تجنب الخطأ 429 مع NTFY
|
||||
- إصلاح الألوان المخصصة (أندرويد 14)
|
||||
- إصلاح عطل عند الإنشاء
|
||||
- مشكلة عرض مع الوسوم المتابعة
|
||||
- أعطال مع الملفات الشخصية
|
||||
- إصلاح مشكلة مع الاستطلاع و Pleroma
|
||||
- الرموز التعبيرية لا تظهر في المنتقي
|
||||
- تم إصلاح العديد من الأعطال
|
|
@ -0,0 +1 @@
|
|||
يُفترض أن يُصلح هذا الإصدار الأعطال (TransactionTooLargeException). إذا واجهت أعطالاً، تراجع عن الإصدار عبر FDdroid.
|
|
@ -0,0 +1,2 @@
|
|||
- مشكلة في الإنشاء
|
||||
- من المفترض أن يصلح هذا الإصدار الأعطال (TransactionTooLargeException). إذا واجهت أعطالاً، فعد إلى الإصدارات السابقة عبر FDdroid.
|
|
@ -0,0 +1 @@
|
|||
- إصلاح موضع التذكر
|
|
@ -0,0 +1,6 @@
|
|||
تمت إضافة:
|
||||
- شريط علوي ثابت (افتراضي: معطل)
|
||||
- تكرار استخدام الوسوم عند التأليف
|
||||
|
||||
تم إصلاح:
|
||||
- بعض الأعطال
|
11
src/fdroid/fastlane/metadata/android/ar/changelogs/510.txt
Normal file
11
src/fdroid/fastlane/metadata/android/ar/changelogs/510.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
تمت إضافة:
|
||||
- شريط علوي ثابت (معطل افتراضياً)
|
||||
- تكرار استخدام الوسوم عند كتابة منشور
|
||||
|
||||
تم تغيير:
|
||||
- تعطيل دعم Markdown افتراضياً
|
||||
|
||||
تم إصلاح:
|
||||
- إصلاح الأعطال التي تحدث أثناء التفاعلات أو عند فتح شاشة جديدة
|
||||
- إصلاح لون مربعات الحوار في الإعدادات
|
||||
- إصلاح بعض الأعطال الطفيفة
|
|
@ -0,0 +1,9 @@
|
|||
تمت إضافة:
|
||||
- النقر على لافتات الحسابات لعرضها كوسائط
|
||||
|
||||
تم إصلاح:
|
||||
- فقدان الموضع عند التبديل بين الحسابات
|
||||
- ظهور ملفات شخصية خاطئة عند تمكين المحادثات عن بعد
|
||||
- الجدول الزمني المحلي لـ Peertube
|
||||
- البحث عن مثيلات Peertube
|
||||
- أعطال الإصدار السابق
|
|
@ -0,0 +1,8 @@
|
|||
تم إضافة:
|
||||
- دعم الضمائر (الجدول الزمني / الإنشاء / الإكمال التلقائي)
|
||||
|
||||
تم تغيير:
|
||||
- استخدام مكتبة Media3
|
||||
|
||||
تم إصلاح:
|
||||
- مشاكل التعطل من الإصدار السابق
|
10
src/fdroid/fastlane/metadata/android/ar/changelogs/513.txt
Normal file
10
src/fdroid/fastlane/metadata/android/ar/changelogs/513.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
**أضيف:**
|
||||
* دعم الضمائر (الجدول الزمني/الإنشاء/الإكمال التلقائي)
|
||||
|
||||
**تم تغيير:**
|
||||
* استخدام مكتبة Media3
|
||||
|
||||
**تم إصلاح:**
|
||||
* مدة كتم الصوت المؤقت طويلة جداً
|
||||
* مشاركة مقاطع الفيديو تقوم بتنزيلها فقط
|
||||
* أعطال من الإصدار السابق
|
|
@ -0,0 +1,9 @@
|
|||
تمت إضافة:
|
||||
- السماح بتعطيل دعم الضمائر (افتراضي: ممكّن)
|
||||
- إضافة المزيد من الدعم للضمائر (الترجمة إلى لغات مختلفة)
|
||||
|
||||
تم إصلاح:
|
||||
- إصلاح انهيار عند الإبلاغ عن الرسائل
|
||||
- إصلاح انهيار عند متابعة الوسوم
|
||||
- إصلاح بعض مشاكل العرض
|
||||
- عدة إصلاحات من الإصدار الأخير (3.28.0)
|
|
@ -10,3 +10,16 @@
|
|||
- إجراءات ما بين الحسابات بواسطة الضغط المطوّل
|
||||
- ميزة الترجمة
|
||||
- خطوط زمنية فنية
|
||||
- خيارات متعددة للتحديثات التلقائية
|
||||
- إشعارات الدفع عبر UnifiedPush (بما في ذلك ntfy على FDroid)
|
||||
- البقاء متصلاً لتلقي الإشعارات المباشرة
|
||||
- إشعارات مؤجلة (الاتصال كل 30 ثانية)
|
||||
- استبدال روابط يوتيوب وتويتر بروابط إلى نسخ invidious و nitter
|
||||
- سمات مخصصة، استيراد وتصدير، وتحديد
|
||||
- استيراد وتصدير قاعدة بيانات التطبيق
|
||||
- منتقي رموز تعبيرية (إيموجي) مع رموز مخصصة
|
||||
- أيقونات تشغيل متعددة
|
||||
- تصفية متقدمة للمنشورات (toots)
|
||||
- جدول زمني فني خاص لوسم mastoart
|
||||
- تصدير المنشورات (toots)
|
||||
- تخصيص مشاركة الروابط لمشاركة الروابط مباشرة إلى خدمات أخرى
|
||||
|
|
14
src/fdroid/fastlane/metadata/android/ca/changelogs/500.txt
Normal file
14
src/fdroid/fastlane/metadata/android/ca/changelogs/500.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
S'ha afegit:
|
||||
- Tres noves icones d'app (Orgull, Rosa i Pirata)
|
||||
- Mantenir la posició amb converses remotes
|
||||
|
||||
Reparacions:
|
||||
- Markdown: atura l'anàlisi d'etiquetes i admet text tatxat
|
||||
- Cursor més visible en redactar
|
||||
- Corregeix la longitud màxima del caràcter personalitzat d'instància que no funciona
|
||||
- Pestanyes als perfils
|
||||
- Reparació d'etiquetes no clicables per a alguns idiomes
|
||||
- Error amb comptes amb una gran quantitat de seguidores
|
||||
- Fallides quan un bran tenia diversos gifs
|
||||
- Màxim de carpacters en enquesta
|
||||
- Algunes fallides
|
|
@ -0,0 +1,8 @@
|
|||
S'ha afegit:
|
||||
- Suport per a Android 14
|
||||
- Divideix automàticament els missatges llargs en els fils (per defecte: ASK)
|
||||
- Els enllaços i els mèdia són clicables mentre es redacta
|
||||
|
||||
Reparacions:
|
||||
- Evita l'error 429 amb NTFY
|
||||
- S'han corregit diverses fallides
|
|
@ -0,0 +1,8 @@
|
|||
S'ha afegit:
|
||||
- Suport per a Android 14
|
||||
- Divideix automàticament els missatges llargs en els fils (per defecte: ASK)
|
||||
- Els enllaços i els mèdia són clicables mentre es redacta
|
||||
|
||||
Reparacions:
|
||||
- Evita l'error 429 amb NTFY
|
||||
- S'han corregit diverses fallides
|
14
src/fdroid/fastlane/metadata/android/ca/changelogs/503.txt
Normal file
14
src/fdroid/fastlane/metadata/android/ca/changelogs/503.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
S'ha afegit:
|
||||
- Permet subratllar els elements clicables (Configuració > Pissarres - per defecte: deshabilitat)
|
||||
- Permet deshabilitar la data relativa en els brams
|
||||
|
||||
Canvis:
|
||||
- Comptadors a tocar dels botons d'acció
|
||||
- Oculta el selector d'emoticones si la instància no té emoticones
|
||||
- S'ordenen les etiquetes en seguiment
|
||||
- Selector de comptes en obrir amb un altre compte
|
||||
|
||||
Reparacions:
|
||||
- Correcció d'una fallida en redactar
|
||||
- Correcció d'un problema amb el botó d'enrere
|
||||
- Problema de visualització amb les etiquetes en seguiment
|
|
@ -0,0 +1,9 @@
|
|||
S'ha afegit:
|
||||
- Una barra rodoladora per a pissarres (per defecte: desactivada)
|
||||
- Una barra de cerca per a les emoticones a mida
|
||||
|
||||
Reparacions:
|
||||
- Reparat que l'indicador preguntés diverses vegades quan es rebutjava la divisió
|
||||
- Fallides amb perfils
|
||||
- Reparat un problema entre l'enquesta i Pleroma
|
||||
- Emoticona que no sortia al selector
|
25
src/fdroid/fastlane/metadata/android/ca/changelogs/505.txt
Normal file
25
src/fdroid/fastlane/metadata/android/ca/changelogs/505.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
S'ha afegit:
|
||||
- Suport per a Android 14
|
||||
- Divisió automàtica dels brams llargs en els fils (per defecte: ASK)
|
||||
- Enllaços i mèdia clicables en redactar
|
||||
- Permetre de subratllar els elements clicables (Configuració > Pissarres - per defecte: deshabilitat)
|
||||
- Permetre deshabilitar la data relativa en els brams
|
||||
- Una barra de ròdol per a les pissarres (per defecte: deshabilitat)
|
||||
- Una barra de cerca per emoticones a mida
|
||||
- Enllaços clicables en les descripcions de mèdia
|
||||
|
||||
Canvis:
|
||||
- Comptadors a tocar dels botons d'acció
|
||||
- Ocultar el selector d'emoticones si la instància no té emoticones
|
||||
- Ordenació de les etiquetes en seguiment
|
||||
- Selector de comptes en obrir amb un altre compte
|
||||
|
||||
Reparacions:
|
||||
- Evitar error 429 amb NTFY
|
||||
- Correcció de colors a mida (Android 14)
|
||||
- Correcció d'una fallida en redactar
|
||||
- Problema de visualització d'etiquetes en seguiment
|
||||
- Fallides amb perfils
|
||||
- Correcció d'un problema entre l'enquesta i Pleroma
|
||||
- Emoticona que no es mostra al selector
|
||||
- Correcció de fallides diverses
|
|
@ -0,0 +1 @@
|
|||
Aquest llançament hauria de corregir les fallides (TransactionTooLargeException). Si teniu fallides, torneu a la versió anterior amb l'ajut d'FDdroid.
|
|
@ -0,0 +1,2 @@
|
|||
- Problema de redacció
|
||||
- Aquesta versió hauria de corregir les fallides (TransactionTooLargeException). Si teniu fallides, torneu a la versió anterior amb l'ajut d'FDdroid.
|
|
@ -0,0 +1 @@
|
|||
- Reparat el record de posició
|
|
@ -0,0 +1,6 @@
|
|||
S'ha afegit:
|
||||
- Reparació de barra superior (per defecte: deshabilitada)
|
||||
- Freqüència d'ús d'etiquetes en redactar
|
||||
|
||||
Reparacions:
|
||||
- Algunes fallides
|
11
src/fdroid/fastlane/metadata/android/ca/changelogs/510.txt
Normal file
11
src/fdroid/fastlane/metadata/android/ca/changelogs/510.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
S'ha afegit:
|
||||
- Reparació de barra superior (per defecte: deshabilitada)
|
||||
- Freqüència d'ús d'etiquetes en redactar
|
||||
|
||||
Canvis:
|
||||
- El suport de Markdown està deshabilitat per defecte
|
||||
|
||||
Reparacions:
|
||||
- Reparació de fallides en interaccions o en obrir una pantalla nova
|
||||
- Reparat el color dels diàlegs a Configuració
|
||||
- Algunes fallides menors
|
|
@ -0,0 +1,9 @@
|
|||
S'ha afegit:
|
||||
- Tocar els bàners de comptes per mostrar-los com a mèdia
|
||||
|
||||
Reparacions:
|
||||
- Pèrdua de posició en canviar entre comptes
|
||||
- Perfils erronis en habilitar converses remotes
|
||||
- Pissarra local de Peertube
|
||||
- Cerca d'instàncies de Peertube
|
||||
- Fallides de la versió anterior
|
|
@ -0,0 +1,8 @@
|
|||
S'ha afegit:
|
||||
- Implementació de pronoms (Pissarra/Redactar/Autocompletar)
|
||||
|
||||
Canvis:
|
||||
- Us de la biblioteca Media3
|
||||
|
||||
Reparacions:
|
||||
- Fallides de la versió anterior
|
10
src/fdroid/fastlane/metadata/android/ca/changelogs/513.txt
Normal file
10
src/fdroid/fastlane/metadata/android/ca/changelogs/513.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
S'ha afegit:
|
||||
- Implementació de pronoms (Pissarra/Redactar/Autocompletar)
|
||||
|
||||
Canvis:
|
||||
- Us de la biblioteca Media3
|
||||
|
||||
Reparacions:
|
||||
- Durada excessiva del silenciat temporal
|
||||
- Compartició de vídeos només els descarregava
|
||||
- Fallides de la versió anterior
|
|
@ -0,0 +1,9 @@
|
|||
S'ha afegit:
|
||||
- Permet deshabilitar la compatibilitat amb els pronoms (per defecte: habilitat)
|
||||
- Més suport per als pronoms (localització en diferents idiomes)
|
||||
|
||||
Reparacions:
|
||||
- Reparada una fallida en denunciar brams
|
||||
- Reparada una fallida en seguir etiquetes
|
||||
- Reparats alguns problemes de visualització
|
||||
- Diverses correccions de l'última versió (3.28.0)
|
|
@ -0,0 +1,6 @@
|
|||
S'ha afegit:
|
||||
- Mostrar un codi QR als perfils
|
||||
|
||||
Reparacions:
|
||||
- Reparació del toc de brams en les converses
|
||||
- Els pronoms que ocupaven massa lloc
|
11
src/fdroid/fastlane/metadata/android/ca/changelogs/516.txt
Normal file
11
src/fdroid/fastlane/metadata/android/ca/changelogs/516.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
S'ha afegit:
|
||||
- Permetre editar brams programats de la banda del servidor
|
||||
|
||||
Canvis:
|
||||
- Ordenar alfabèticament el nom de la llista en els perfils
|
||||
|
||||
Reparacions:
|
||||
- Notificacions fugaces
|
||||
- Selector d'instàncies del Peertube
|
||||
- Edició de fils programats (local)
|
||||
- Cerca instantània de resultats repetits de Hashtag
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue