mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2025-01-07 00:20:08 +02:00
Merge branch 'develop'
This commit is contained in:
commit
12981deafb
72 changed files with 1697 additions and 704 deletions
|
@ -13,8 +13,8 @@ android {
|
|||
defaultConfig {
|
||||
minSdk 21
|
||||
targetSdk 32
|
||||
versionCode 443
|
||||
versionName "3.10.0"
|
||||
versionCode 446
|
||||
versionName "3.11.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
flavorDimensions "default"
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
[
|
||||
{
|
||||
"version": "3.11.0",
|
||||
"code": "446",
|
||||
"note": "Added:\n- Display all messages in threads from remote instances (when possible)\n- Allow to unmute/unfollow/unpin a tag from tag timelines\n- Display most used accounts in header menu for an easy switch\n- Automatically add the tag when composing from a tag timeline\n- Add a translate button at the bottom of messages (default: disabled)\n- Add account role in profiles\n- Translate morse\n\nChanged:\n- Disable animations after a refresh\n\nFixed:\n- Contact not working when composing\n- Status bar for black theme\n- Message duplicated in conversations when edited\n- Color issue on Android 5\n- Several crashes"
|
||||
},
|
||||
{
|
||||
"version": "3.10.2",
|
||||
"code": "445",
|
||||
"note": "Added:\n- Allow to unmute/unfollow/unpin a tag from tag timelines\n- Automatically add the tag when composing from a tag timeline\n- Add a translate button at the bottom of messages (default: disabled)\n- Add account role in profiles\n\nFixed:\n- Contact not working when composing\n- Status bar for black theme\n- Message duplicated in conversations when edited\n- Color issue on Android 5"
|
||||
},
|
||||
{
|
||||
"version": "3.10.1",
|
||||
"code": "444",
|
||||
"note": "Added:\n- Display all messages in threads from remote instances (when possible)\n* Only public messages for instances using the Mastodon API\n* A dedicated button is displayed at the top right when conditions are filled."
|
||||
},
|
||||
{
|
||||
"version": "3.10.0",
|
||||
"code": "443",
|
||||
|
|
|
@ -697,7 +697,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken)
|
||||
.observe(BaseMainActivity.this, mastodonAccount -> {
|
||||
//Initialize static var
|
||||
if (mastodonAccount != null) {
|
||||
if (mastodonAccount != null && currentAccount != null) {
|
||||
currentAccount.mastodon_account = mastodonAccount;
|
||||
displayReleaseNotesIfNeeded(BaseMainActivity.this, false);
|
||||
new Thread(() -> {
|
||||
|
@ -758,6 +758,57 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
}
|
||||
}).start();
|
||||
}
|
||||
//Fetch recent used accounts
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<BaseAccount> accounts = new Account(BaseMainActivity.this).getLastUsedAccounts();
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
if (accounts != null && accounts.size() > 0) {
|
||||
Helper.loadPP(this, headerMainBinding.otherAccount1, accounts.get(0));
|
||||
headerMainBinding.otherAccount1.setVisibility(View.VISIBLE);
|
||||
headerMainBinding.otherAccount1.setOnClickListener(v -> {
|
||||
headerMenuOpen = false;
|
||||
Toasty.info(BaseMainActivity.this, getString(R.string.toast_account_changed, "@" + accounts.get(0).mastodon_account.acct + "@" + accounts.get(0).instance), Toasty.LENGTH_LONG).show();
|
||||
BaseMainActivity.currentToken = accounts.get(0).token;
|
||||
BaseMainActivity.currentUserID = accounts.get(0).user_id;
|
||||
api = accounts.get(0).api;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(PREF_USER_TOKEN, accounts.get(0).token);
|
||||
editor.commit();
|
||||
//The user is now aut
|
||||
//The user is now authenticated, it will be redirected to MainActivity
|
||||
Intent mainActivity = new Intent(this, MainActivity.class);
|
||||
startActivity(mainActivity);
|
||||
finish();
|
||||
});
|
||||
if (accounts.size() > 1) {
|
||||
Helper.loadPP(this, headerMainBinding.otherAccount2, accounts.get(1));
|
||||
headerMainBinding.otherAccount2.setVisibility(View.VISIBLE);
|
||||
headerMainBinding.otherAccount2.setOnClickListener(v -> {
|
||||
headerMenuOpen = false;
|
||||
Toasty.info(BaseMainActivity.this, getString(R.string.toast_account_changed, "@" + accounts.get(1).mastodon_account.acct + "@" + accounts.get(1).instance), Toasty.LENGTH_LONG).show();
|
||||
BaseMainActivity.currentToken = accounts.get(1).token;
|
||||
BaseMainActivity.currentUserID = accounts.get(1).user_id;
|
||||
api = accounts.get(1).api;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(PREF_USER_TOKEN, accounts.get(1).token);
|
||||
editor.commit();
|
||||
//The user is now aut
|
||||
//The user is now authenticated, it will be redirected to MainActivity
|
||||
Intent mainActivity = new Intent(this, MainActivity.class);
|
||||
startActivity(mainActivity);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
protected abstract void rateThisApp();
|
||||
|
|
|
@ -19,8 +19,11 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
@ -81,6 +84,9 @@ public class BaseActivity extends AppCompatActivity {
|
|||
break;
|
||||
case "BLACK":
|
||||
setTheme(R.style.BlackAppTheme);
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
currentThemeId = R.style.BlackAppTheme;
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
@ -115,6 +121,9 @@ public class BaseActivity extends AppCompatActivity {
|
|||
case "BLACK":
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
setTheme(R.style.BlackAppTheme);
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
currentThemeId = R.style.BlackAppTheme;
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
|
|
@ -19,8 +19,11 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
@ -74,6 +77,9 @@ public class BaseAlertDialogActivity extends AppCompatActivity {
|
|||
setTheme(R.style.SolarizedAlertDialog);
|
||||
break;
|
||||
case "BLACK":
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
setTheme(R.style.BlackAlertDialog);
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
@ -102,6 +108,9 @@ public class BaseAlertDialogActivity extends AppCompatActivity {
|
|||
break;
|
||||
case "BLACK":
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
setTheme(R.style.BlackAlertDialog);
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
|
|
@ -19,8 +19,11 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
@ -73,6 +76,9 @@ public class BaseBarActivity extends AppCompatActivity {
|
|||
setTheme(R.style.SolarizedAppThemeBar);
|
||||
break;
|
||||
case "BLACK":
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
setTheme(R.style.BlackAppThemeBar);
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
@ -102,6 +108,9 @@ public class BaseBarActivity extends AppCompatActivity {
|
|||
break;
|
||||
case "BLACK":
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
setTheme(R.style.BlackAppThemeBar);
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
|
|
@ -19,8 +19,11 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
@ -73,6 +76,9 @@ public class BaseTransparentActivity extends AppCompatActivity {
|
|||
setTheme(R.style.TransparentSolarized);
|
||||
break;
|
||||
case "BLACK":
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
setTheme(R.style.TransparentBlack);
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
@ -102,6 +108,9 @@ public class BaseTransparentActivity extends AppCompatActivity {
|
|||
break;
|
||||
case "BLACK":
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.BLACK);
|
||||
setTheme(R.style.TransparentBlack);
|
||||
break;
|
||||
case "DRACULA":
|
||||
|
|
|
@ -402,8 +402,8 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
|||
return true;
|
||||
}
|
||||
|
||||
private void onRetrieveContact(PopupContactBinding binding, List<app.fedilab.android.client.entities.api.Account> accounts) {
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
private void onRetrieveContact(PopupContactBinding popupContactBinding, List<app.fedilab.android.client.entities.api.Account> accounts) {
|
||||
popupContactBinding.loader.setVisibility(View.GONE);
|
||||
if (accounts == null) {
|
||||
accounts = new ArrayList<>();
|
||||
}
|
||||
|
@ -413,8 +413,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
|||
checkedValues.add(composeAdapter.getLastComposeContent().contains("@" + account.acct));
|
||||
}
|
||||
AccountsReplyAdapter contactAdapter = new AccountsReplyAdapter(contacts, checkedValues);
|
||||
binding.lvAccountsSearch.setAdapter(contactAdapter);
|
||||
binding.lvAccountsSearch.setLayoutManager(new LinearLayoutManager(ComposeActivity.this));
|
||||
contactAdapter.actionDone = ComposeActivity.this;
|
||||
popupContactBinding.lvAccountsSearch.setAdapter(contactAdapter);
|
||||
popupContactBinding.lvAccountsSearch.setLayoutManager(new LinearLayoutManager(ComposeActivity.this));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -869,10 +870,14 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
|||
|
||||
|
||||
private boolean canBeSent(StatusDraft statusDraft) {
|
||||
if (statusDraft == null || statusDraft.statusDraftList == null || statusDraft.statusDraftList.isEmpty()) {
|
||||
if (statusDraft == null) {
|
||||
return false;
|
||||
}
|
||||
Status statusCheck = statusDraft.statusDraftList.get(0);
|
||||
List<Status> statuses = statusDraft.statusDraftList;
|
||||
if (statuses == null || statuses.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
Status statusCheck = statuses.get(0);
|
||||
if (statusCheck == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package app.fedilab.android.activities;
|
|||
import static app.fedilab.android.BaseMainActivity.currentAccount;
|
||||
import static app.fedilab.android.ui.drawer.StatusAdapter.sendAction;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
|
@ -33,6 +34,9 @@ import androidx.fragment.app.Fragment;
|
|||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.client.entities.api.Status;
|
||||
|
@ -43,19 +47,22 @@ import app.fedilab.android.helper.Helper;
|
|||
import app.fedilab.android.helper.MastodonHelper;
|
||||
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonContext;
|
||||
import app.fedilab.android.viewmodel.mastodon.StatusesVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
public class ContextActivity extends BaseActivity {
|
||||
public class ContextActivity extends BaseActivity implements FragmentMastodonContext.FirstMessage {
|
||||
|
||||
public static boolean expand;
|
||||
public static boolean displayCW;
|
||||
public static Resources.Theme theme;
|
||||
Fragment currentFragment;
|
||||
private Status firstMessage;
|
||||
private String remote_instance;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
app.fedilab.android.databinding.ActivityConversationBinding binding = ActivityConversationBinding.inflate(getLayoutInflater());
|
||||
ActivityConversationBinding binding = ActivityConversationBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
|
@ -75,8 +82,10 @@ public class ContextActivity extends BaseActivity {
|
|||
Bundle b = getIntent().getExtras();
|
||||
displayCW = sharedpreferences.getBoolean(getString(R.string.SET_EXPAND_CW), false);
|
||||
Status focusedStatus = null; // or other values
|
||||
if (b != null)
|
||||
if (b != null) {
|
||||
focusedStatus = (Status) b.getSerializable(Helper.ARG_STATUS);
|
||||
remote_instance = b.getString(Helper.ARG_REMOTE_INSTANCE, null);
|
||||
}
|
||||
if (focusedStatus == null || currentAccount == null || currentAccount.mastodon_account == null) {
|
||||
finish();
|
||||
return;
|
||||
|
@ -84,29 +93,34 @@ public class ContextActivity extends BaseActivity {
|
|||
MastodonHelper.loadPPMastodon(binding.profilePicture, currentAccount.mastodon_account);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(Helper.ARG_STATUS, focusedStatus);
|
||||
currentFragment = Helper.addFragment(getSupportFragmentManager(), R.id.nav_host_fragment_content_main, new FragmentMastodonContext(), bundle, null, null);
|
||||
StatusesVM timelinesVM = new ViewModelProvider(ContextActivity.this).get(StatusesVM.class);
|
||||
timelinesVM.getStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, focusedStatus.id).observe(ContextActivity.this, status -> {
|
||||
if (status != null) {
|
||||
StatusCache statusCache = new StatusCache();
|
||||
statusCache.instance = BaseMainActivity.currentInstance;
|
||||
statusCache.user_id = BaseMainActivity.currentUserID;
|
||||
statusCache.status = status;
|
||||
statusCache.status_id = status.id;
|
||||
//Update cache
|
||||
new Thread(() -> {
|
||||
try {
|
||||
new StatusCache(getApplication()).updateIfExists(statusCache);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
//Update UI
|
||||
Runnable myRunnable = () -> sendAction(ContextActivity.this, Helper.ARG_STATUS_ACTION, status, null);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
bundle.putString(Helper.ARG_REMOTE_INSTANCE, remote_instance);
|
||||
FragmentMastodonContext fragmentMastodonContext = new FragmentMastodonContext();
|
||||
fragmentMastodonContext.firstMessage = this;
|
||||
currentFragment = Helper.addFragment(getSupportFragmentManager(), R.id.nav_host_fragment_content_main, fragmentMastodonContext, bundle, null, null);
|
||||
if (remote_instance == null) {
|
||||
StatusesVM timelinesVM = new ViewModelProvider(ContextActivity.this).get(StatusesVM.class);
|
||||
timelinesVM.getStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, focusedStatus.id).observe(ContextActivity.this, status -> {
|
||||
if (status != null) {
|
||||
StatusCache statusCache = new StatusCache();
|
||||
statusCache.instance = BaseMainActivity.currentInstance;
|
||||
statusCache.user_id = BaseMainActivity.currentUserID;
|
||||
statusCache.status = status;
|
||||
statusCache.status_id = status.id;
|
||||
//Update cache
|
||||
new Thread(() -> {
|
||||
try {
|
||||
new StatusCache(getApplication()).updateIfExists(statusCache);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
//Update UI
|
||||
Runnable myRunnable = () -> sendAction(ContextActivity.this, Helper.ARG_STATUS_ACTION, status, null);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,6 +140,18 @@ public class ContextActivity extends BaseActivity {
|
|||
} else {
|
||||
itemDisplayCW.setIcon(R.drawable.ic_outline_remove_red_eye_24);
|
||||
}
|
||||
MenuItem action_remote = menu.findItem(R.id.action_remote);
|
||||
if (remote_instance != null) {
|
||||
action_remote.setVisible(false);
|
||||
} else {
|
||||
if (firstMessage != null && !firstMessage.visibility.equalsIgnoreCase("direct") && !firstMessage.visibility.equalsIgnoreCase("private")) {
|
||||
Pattern pattern = Helper.statusIdInUrl;
|
||||
Matcher matcher = pattern.matcher(firstMessage.uri);
|
||||
action_remote.setVisible(matcher.find());
|
||||
} else {
|
||||
action_remote.setVisible(false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -151,8 +177,53 @@ public class ContextActivity extends BaseActivity {
|
|||
((FragmentMastodonContext) currentFragment).refresh();
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
} else if (item.getItemId() == R.id.action_remote) {
|
||||
|
||||
if (firstMessage == null) {
|
||||
Toasty.warning(ContextActivity.this, getString(R.string.toast_try_later), Toasty.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
if (firstMessage.account.acct != null) {
|
||||
String[] splitAcct = firstMessage.account.acct.split("@");
|
||||
String instance;
|
||||
if (splitAcct.length > 1) {
|
||||
instance = splitAcct[1];
|
||||
} else {
|
||||
Toasty.info(ContextActivity.this, getString(R.string.toast_on_your_instance), Toasty.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
Pattern pattern = Helper.statusIdInUrl;
|
||||
Matcher matcher = pattern.matcher(firstMessage.uri);
|
||||
String remoteId = null;
|
||||
if (matcher.find()) {
|
||||
remoteId = matcher.group(1);
|
||||
}
|
||||
if (remoteId != null) {
|
||||
StatusesVM statusesVM = new ViewModelProvider(ContextActivity.this).get(StatusesVM.class);
|
||||
statusesVM.getStatus(instance, null, remoteId).observe(ContextActivity.this, status -> {
|
||||
if (status != null) {
|
||||
Intent intentContext = new Intent(ContextActivity.this, ContextActivity.class);
|
||||
intentContext.putExtra(Helper.ARG_STATUS, status);
|
||||
intentContext.putExtra(Helper.ARG_REMOTE_INSTANCE, instance);
|
||||
intentContext.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intentContext);
|
||||
} else {
|
||||
Toasty.warning(ContextActivity.this, getString(R.string.toast_error_fetch_message), Toasty.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toasty.warning(ContextActivity.this, getString(R.string.toast_error_fetch_message), Toasty.LENGTH_SHORT).show();
|
||||
}
|
||||
} else {
|
||||
Toasty.warning(ContextActivity.this, getString(R.string.toast_error_fetch_message), Toasty.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(Status status) {
|
||||
firstMessage = status;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ import android.view.MenuItem;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
|
@ -56,11 +57,15 @@ public class HashTagActivity extends BaseActivity {
|
|||
|
||||
public static int position;
|
||||
private String tag;
|
||||
private boolean pinnedTag;
|
||||
private boolean followedTag;
|
||||
private boolean mutedTag;
|
||||
private String stripTag;
|
||||
private Boolean pinnedTag;
|
||||
private Boolean followedTag;
|
||||
private Boolean mutedTag;
|
||||
private TagVM tagVM;
|
||||
private Filter fedilabFilter;
|
||||
private Filter.KeywordsAttributes keyword;
|
||||
private PinnedTimeline pinnedTimeline;
|
||||
private Pinned pinned;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -75,9 +80,10 @@ public class HashTagActivity extends BaseActivity {
|
|||
}
|
||||
if (tag == null)
|
||||
finish();
|
||||
pinnedTag = false;
|
||||
followedTag = false;
|
||||
mutedTag = false;
|
||||
pinnedTag = null;
|
||||
followedTag = null;
|
||||
mutedTag = null;
|
||||
stripTag = tag.replaceAll("#", "");
|
||||
setSupportActionBar(binding.toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
//Remove title
|
||||
|
@ -91,7 +97,7 @@ public class HashTagActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
tagVM = new ViewModelProvider(HashTagActivity.this).get(TagVM.class);
|
||||
tagVM.getTag(MainActivity.currentInstance, MainActivity.currentToken, tag).observe(this, returnedTag -> {
|
||||
tagVM.getTag(MainActivity.currentInstance, MainActivity.currentToken, stripTag).observe(this, returnedTag -> {
|
||||
if (returnedTag != null) {
|
||||
followedTag = returnedTag.following;
|
||||
invalidateOptionsMenu();
|
||||
|
@ -100,19 +106,24 @@ public class HashTagActivity extends BaseActivity {
|
|||
ReorderVM reorderVM = new ViewModelProvider(HashTagActivity.this).get(ReorderVM.class);
|
||||
reorderVM.getAllPinned().observe(HashTagActivity.this, pinned -> {
|
||||
if (pinned != null) {
|
||||
this.pinned = pinned;
|
||||
pinnedTag = false;
|
||||
if (pinned.pinnedTimelines != null) {
|
||||
for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
|
||||
if (pinnedTimeline.tagTimeline != null) {
|
||||
if (pinnedTimeline.tagTimeline.name.equalsIgnoreCase(tag)) {
|
||||
if (pinnedTimeline.tagTimeline.name.equalsIgnoreCase(stripTag)) {
|
||||
this.pinnedTimeline = pinnedTimeline;
|
||||
pinnedTag = true;
|
||||
invalidateOptionsMenu();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (MainActivity.filterFetched && MainActivity.mainFilters != null) {
|
||||
mutedTag = false;
|
||||
for (Filter filter : MainActivity.mainFilters) {
|
||||
if (filter.title.equalsIgnoreCase(Helper.FEDILAB_MUTED_HASHTAGS)) {
|
||||
fedilabFilter = filter;
|
||||
|
@ -120,17 +131,14 @@ public class HashTagActivity extends BaseActivity {
|
|||
for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) {
|
||||
if (fetch.equalsIgnoreCase(keywordsAttributes.keyword)) {
|
||||
mutedTag = true;
|
||||
keyword = keywordsAttributes;
|
||||
invalidateOptionsMenu();
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutedTag = false;
|
||||
invalidateOptionsMenu();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mutedTag = true;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
|
@ -141,12 +149,12 @@ public class HashTagActivity extends BaseActivity {
|
|||
Intent intentToot = new Intent(HashTagActivity.this, ComposeActivity.class);
|
||||
StatusDraft statusDraft = new StatusDraft();
|
||||
Status status = new Status();
|
||||
status.text = "#" + tag;
|
||||
status.text = "#" + stripTag;
|
||||
List<Status> statuses = new ArrayList<>();
|
||||
statuses.add(status);
|
||||
statusDraft.statusDraftList = statuses;
|
||||
Bundle _b = new Bundle();
|
||||
_b.putSerializable(Helper.ARG_TAG_TIMELINE, statusDraft);
|
||||
_b.putSerializable(Helper.ARG_STATUS_DRAFT, statusDraft);
|
||||
intentToot.putExtras(_b);
|
||||
startActivity(intentToot);
|
||||
});
|
||||
|
@ -158,89 +166,125 @@ public class HashTagActivity extends BaseActivity {
|
|||
finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_add_timeline) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Pinned pinned = new Pinned(HashTagActivity.this).getPinned(currentAccount);
|
||||
boolean canBeAdded = true;
|
||||
boolean update = true;
|
||||
if (pinned == null) {
|
||||
pinned = new Pinned();
|
||||
pinned.pinnedTimelines = new ArrayList<>();
|
||||
update = false;
|
||||
} else {
|
||||
for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
|
||||
if (pinnedTimeline.type == Timeline.TimeLineEnum.TAG) {
|
||||
if (pinnedTimeline.tagTimeline.name.compareTo(tag.trim()) == 0) {
|
||||
canBeAdded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!canBeAdded) {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> Toasty.warning(HashTagActivity.this, getString(R.string.tags_already_stored), Toasty.LENGTH_SHORT).show();
|
||||
mainHandler.post(myRunnable);
|
||||
return;
|
||||
}
|
||||
PinnedTimeline pinnedTimeline = new PinnedTimeline();
|
||||
pinnedTimeline.type = Timeline.TimeLineEnum.TAG;
|
||||
pinnedTimeline.position = pinned.pinnedTimelines.size();
|
||||
pinnedTimeline.displayed = true;
|
||||
TagTimeline tagTimeline = new TagTimeline();
|
||||
tagTimeline.name = tag.trim();
|
||||
tagTimeline.isNSFW = false;
|
||||
tagTimeline.isART = false;
|
||||
pinnedTimeline.tagTimeline = tagTimeline;
|
||||
pinned.pinnedTimelines.add(pinnedTimeline);
|
||||
if (update) {
|
||||
|
||||
if (pinnedTag) {
|
||||
AlertDialog.Builder unpinConfirm = new AlertDialog.Builder(HashTagActivity.this, Helper.dialogStyle());
|
||||
unpinConfirm.setMessage(getString(R.string.unpin_timeline_description));
|
||||
unpinConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
unpinConfirm.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||
pinned.pinnedTimelines.remove(pinnedTimeline);
|
||||
try {
|
||||
new Pinned(HashTagActivity.this).updatePinned(pinned);
|
||||
} else {
|
||||
new Pinned(HashTagActivity.this).insertPinned(pinned);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
pinnedTag = false;
|
||||
invalidateOptionsMenu();
|
||||
Bundle b = new Bundle();
|
||||
b.putBoolean(Helper.RECEIVE_REDRAW_TOPBAR, true);
|
||||
Intent intentBD = new Intent(Helper.BROADCAST_DATA);
|
||||
intentBD.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(HashTagActivity.this).sendBroadcast(intentBD);
|
||||
pinnedTag = true;
|
||||
invalidateOptionsMenu();
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
dialog.dismiss();
|
||||
});
|
||||
unpinConfirm.show();
|
||||
} else {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Pinned pinned = new Pinned(HashTagActivity.this).getPinned(currentAccount);
|
||||
boolean canBeAdded = true;
|
||||
boolean update = true;
|
||||
if (pinned == null) {
|
||||
pinned = new Pinned();
|
||||
pinned.pinnedTimelines = new ArrayList<>();
|
||||
update = false;
|
||||
} else {
|
||||
for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
|
||||
if (pinnedTimeline.type == Timeline.TimeLineEnum.TAG) {
|
||||
if (pinnedTimeline.tagTimeline.name.compareTo(stripTag.trim()) == 0) {
|
||||
canBeAdded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!canBeAdded) {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> Toasty.warning(HashTagActivity.this, getString(R.string.tags_already_stored), Toasty.LENGTH_SHORT).show();
|
||||
mainHandler.post(myRunnable);
|
||||
return;
|
||||
}
|
||||
pinnedTimeline = new PinnedTimeline();
|
||||
pinnedTimeline.type = Timeline.TimeLineEnum.TAG;
|
||||
pinnedTimeline.position = pinned.pinnedTimelines.size();
|
||||
pinnedTimeline.displayed = true;
|
||||
TagTimeline tagTimeline = new TagTimeline();
|
||||
tagTimeline.name = stripTag.trim();
|
||||
tagTimeline.isNSFW = false;
|
||||
tagTimeline.isART = false;
|
||||
pinnedTimeline.tagTimeline = tagTimeline;
|
||||
pinned.pinnedTimelines.add(pinnedTimeline);
|
||||
if (update) {
|
||||
new Pinned(HashTagActivity.this).updatePinned(pinned);
|
||||
} else {
|
||||
new Pinned(HashTagActivity.this).insertPinned(pinned);
|
||||
}
|
||||
Bundle b = new Bundle();
|
||||
b.putBoolean(Helper.RECEIVE_REDRAW_TOPBAR, true);
|
||||
Intent intentBD = new Intent(Helper.BROADCAST_DATA);
|
||||
intentBD.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(HashTagActivity.this).sendBroadcast(intentBD);
|
||||
pinnedTag = true;
|
||||
invalidateOptionsMenu();
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
} else if (item.getItemId() == R.id.action_follow_tag) {
|
||||
tagVM.follow(MainActivity.currentInstance, MainActivity.currentToken, tag).observe(this, returnedTag -> {
|
||||
if (returnedTag != null) {
|
||||
followedTag = returnedTag.following;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
if (!followedTag) {
|
||||
tagVM.follow(MainActivity.currentInstance, MainActivity.currentToken, stripTag).observe(this, returnedTag -> {
|
||||
if (returnedTag != null) {
|
||||
followedTag = returnedTag.following;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
tagVM.unfollow(MainActivity.currentInstance, MainActivity.currentToken, stripTag).observe(this, returnedTag -> {
|
||||
if (returnedTag != null) {
|
||||
followedTag = returnedTag.following;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item.getItemId() == R.id.action_mute) {
|
||||
|
||||
if (MainActivity.mainFilters == null || fedilabFilter == null) {
|
||||
MainActivity.mainFilters = new ArrayList<>();
|
||||
Filter.FilterParams filterParams = new Filter.FilterParams();
|
||||
filterParams.title = Helper.FEDILAB_MUTED_HASHTAGS;
|
||||
filterParams.filter_action = "hide";
|
||||
filterParams.context = new ArrayList<>();
|
||||
filterParams.context.add("home");
|
||||
filterParams.context.add("public");
|
||||
filterParams.context.add("thread");
|
||||
filterParams.context.add("account");
|
||||
String finalTag = tag;
|
||||
FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class);
|
||||
filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
|
||||
.observe(HashTagActivity.this, filter -> {
|
||||
if (filter != null) {
|
||||
MainActivity.mainFilters.add(filter);
|
||||
mutedTag = false;
|
||||
fedilabFilter = filter;
|
||||
muteTags();
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
if (!mutedTag) {
|
||||
if (MainActivity.mainFilters == null || fedilabFilter == null) {
|
||||
MainActivity.mainFilters = new ArrayList<>();
|
||||
Filter.FilterParams filterParams = new Filter.FilterParams();
|
||||
filterParams.title = Helper.FEDILAB_MUTED_HASHTAGS;
|
||||
filterParams.filter_action = "hide";
|
||||
filterParams.context = new ArrayList<>();
|
||||
filterParams.context.add("home");
|
||||
filterParams.context.add("public");
|
||||
filterParams.context.add("thread");
|
||||
filterParams.context.add("account");
|
||||
FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class);
|
||||
filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
|
||||
.observe(HashTagActivity.this, filter -> {
|
||||
if (filter != null) {
|
||||
MainActivity.mainFilters.add(filter);
|
||||
mutedTag = false;
|
||||
fedilabFilter = filter;
|
||||
muteTags();
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
muteTags();
|
||||
}
|
||||
} else {
|
||||
muteTags();
|
||||
unmuteTags();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -249,6 +293,24 @@ public class HashTagActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
|
||||
private void unmuteTags() {
|
||||
String search = tag.startsWith("#") ? tag : "#" + tag;
|
||||
for (Filter.KeywordsAttributes keywordsAttributes : fedilabFilter.keywords) {
|
||||
if (search.equalsIgnoreCase(keywordsAttributes.keyword)) {
|
||||
keyword = keywordsAttributes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keyword != null && keyword.id != null) {
|
||||
FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class);
|
||||
filtersVM.removeKeyword(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, keyword.id);
|
||||
fedilabFilter.keywords.remove(keyword);
|
||||
mutedTag = false;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void muteTags() {
|
||||
Filter.FilterParams filterParams = new Filter.FilterParams();
|
||||
filterParams.id = fedilabFilter.id;
|
||||
|
@ -261,6 +323,7 @@ public class HashTagActivity extends BaseActivity {
|
|||
FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class);
|
||||
filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
|
||||
.observe(HashTagActivity.this, filter -> {
|
||||
fedilabFilter = filter;
|
||||
mutedTag = true;
|
||||
invalidateOptionsMenu();
|
||||
});
|
||||
|
@ -272,13 +335,42 @@ public class HashTagActivity extends BaseActivity {
|
|||
MenuItem pin = menu.findItem(R.id.action_add_timeline);
|
||||
MenuItem follow = menu.findItem(R.id.action_follow_tag);
|
||||
MenuItem mute = menu.findItem(R.id.action_mute);
|
||||
if (pinnedTag && pin != null) {
|
||||
if (pinnedTag != null) {
|
||||
pin.setVisible(true);
|
||||
if (pinnedTag) {
|
||||
pin.setIcon(R.drawable.tag_pin_off);
|
||||
pin.setTitle(getString(R.string.unpin_tag));
|
||||
} else {
|
||||
pin.setTitle(getString(R.string.unpin_tag));
|
||||
pin.setIcon(R.drawable.tag_pin);
|
||||
}
|
||||
} else {
|
||||
pin.setVisible(false);
|
||||
}
|
||||
if (followedTag && follow != null) {
|
||||
if (followedTag != null) {
|
||||
follow.setVisible(true);
|
||||
if (followedTag) {
|
||||
follow.setTitle(getString(R.string.unfollow_tag));
|
||||
follow.setIcon(R.drawable.tag_unfollow);
|
||||
} else {
|
||||
follow.setTitle(getString(R.string.follow_tag));
|
||||
follow.setIcon(R.drawable.tag_follow);
|
||||
}
|
||||
} else {
|
||||
follow.setVisible(false);
|
||||
}
|
||||
mute.setVisible(!mutedTag);
|
||||
if (mutedTag != null) {
|
||||
mute.setVisible(true);
|
||||
if (mutedTag) {
|
||||
mute.setTitle(getString(R.string.unmute_tag_action));
|
||||
mute.setIcon(R.drawable.tag_unmuted);
|
||||
} else {
|
||||
mute.setTitle(getString(R.string.mute_tag_action));
|
||||
mute.setIcon(R.drawable.tag_muted);
|
||||
}
|
||||
} else {
|
||||
mute.setVisible(false);
|
||||
}
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class LoginActivity extends BaseActivity {
|
|||
public static boolean requestedAdmin;
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
public static void proceedLogin(Activity activity, Account account) {
|
||||
public void proceedLogin(Activity activity, Account account) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
//update the database
|
||||
|
@ -74,8 +74,8 @@ public class LoginActivity extends BaseActivity {
|
|||
//The user is now authenticated, it will be redirected to MainActivity
|
||||
Runnable myRunnable = () -> {
|
||||
Intent mainActivity = new Intent(activity, MainActivity.class);
|
||||
activity.startActivity(mainActivity);
|
||||
activity.finish();
|
||||
startActivity(mainActivity);
|
||||
finish();
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (DBException e) {
|
||||
|
@ -111,18 +111,23 @@ public class LoginActivity extends BaseActivity {
|
|||
//API call to retrieve account information for the new token
|
||||
AccountsVM accountsVM = new ViewModelProvider(LoginActivity.this).get(AccountsVM.class);
|
||||
accountsVM.getConnectedAccount(currentInstanceLogin, account.token).observe(LoginActivity.this, mastodonAccount -> {
|
||||
account.mastodon_account = mastodonAccount;
|
||||
account.user_id = mastodonAccount.id;
|
||||
//We check if user have really moderator rights
|
||||
if (requestedAdmin) {
|
||||
AdminVM adminVM = new ViewModelProvider(LoginActivity.this).get(AdminVM.class);
|
||||
adminVM.getAccount(account.instance, account.token, account.user_id).observe(LoginActivity.this, adminAccount -> {
|
||||
account.admin = adminAccount != null;
|
||||
if (mastodonAccount != null) {
|
||||
account.mastodon_account = mastodonAccount;
|
||||
account.user_id = mastodonAccount.id;
|
||||
//We check if user have really moderator rights
|
||||
if (requestedAdmin) {
|
||||
AdminVM adminVM = new ViewModelProvider(LoginActivity.this).get(AdminVM.class);
|
||||
adminVM.getAccount(account.instance, account.token, account.user_id).observe(LoginActivity.this, adminAccount -> {
|
||||
account.admin = adminAccount != null;
|
||||
proceedLogin(LoginActivity.this, account);
|
||||
});
|
||||
} else {
|
||||
proceedLogin(LoginActivity.this, account);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
proceedLogin(LoginActivity.this, account);
|
||||
Toasty.error(LoginActivity.this, getString(R.string.toast_token), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
Toasty.error(LoginActivity.this, getString(R.string.toast_token), Toast.LENGTH_LONG).show();
|
||||
|
|
|
@ -188,6 +188,30 @@ public class ProfileActivity extends BaseActivity {
|
|||
LocalBroadcastManager.getInstance(ProfileActivity.this).registerReceiver(broadcast_data, new IntentFilter(Helper.BROADCAST_DATA));
|
||||
}
|
||||
|
||||
|
||||
private void updateViewWithNewData(Account account) {
|
||||
if (account != null) {
|
||||
if (account.role != null && account.role.highlighted) {
|
||||
binding.accountRole.setText(account.role.name);
|
||||
binding.accountRole.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (binding.accountTabLayout.getTabCount() > 2) {
|
||||
TabLayout.Tab statusTab = binding.accountTabLayout.getTabAt(0);
|
||||
TabLayout.Tab followingTab = binding.accountTabLayout.getTabAt(1);
|
||||
TabLayout.Tab followerTab = binding.accountTabLayout.getTabAt(2);
|
||||
if (statusTab != null) {
|
||||
statusTab.setText(getString(R.string.status_cnt, Helper.withSuffix(account.statuses_count)));
|
||||
}
|
||||
if (followingTab != null) {
|
||||
followingTab.setText(getString(R.string.following_cnt, Helper.withSuffix(account.following_count)));
|
||||
}
|
||||
if (followerTab != null) {
|
||||
followerTab.setText(getString(R.string.followers_cnt, Helper.withSuffix(account.followers_count)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeView(Account account) {
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(ProfileActivity.this);
|
||||
if (account == null) {
|
||||
|
@ -497,7 +521,11 @@ public class ProfileActivity extends BaseActivity {
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (accountInstance != null && !accountInstance.equalsIgnoreCase(MainActivity.currentInstance)) {
|
||||
accountsVM.lookUpAccount(accountInstance, account.username).observe(ProfileActivity.this, this::updateViewWithNewData);
|
||||
} else if (accountInstance != null && accountInstance.equalsIgnoreCase(MainActivity.currentInstance)) {
|
||||
updateViewWithNewData(account);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -875,16 +903,20 @@ public class ProfileActivity extends BaseActivity {
|
|||
if (relationship == null || !relationship.following) {
|
||||
accountsVM.follow(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account.id, true, false)
|
||||
.observe(ProfileActivity.this, newRelationShip -> {
|
||||
relationship = newRelationShip;
|
||||
updateAccount();
|
||||
if (isChecked) {
|
||||
timelinesVM.addAccountsList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, listsId[which], userIds).observe(ProfileActivity.this, success -> {
|
||||
if (success == null || !success) {
|
||||
Toasty.error(ProfileActivity.this, getString(R.string.toast_error_add_to_list), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
if (newRelationShip != null) {
|
||||
relationship = newRelationShip;
|
||||
updateAccount();
|
||||
if (isChecked) {
|
||||
timelinesVM.addAccountsList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, listsId[which], userIds).observe(ProfileActivity.this, success -> {
|
||||
if (success == null || !success) {
|
||||
Toasty.error(ProfileActivity.this, getString(R.string.toast_error_add_to_list), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
timelinesVM.deleteAccountsList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, listsId[which], userIds);
|
||||
}
|
||||
} else {
|
||||
timelinesVM.deleteAccountsList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, listsId[which], userIds);
|
||||
Toasty.error(ProfileActivity.this, getString(R.string.toast_error_add_to_list), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package app.fedilab.android.activities;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import static androidx.navigation.ui.NavigationUI.setupActionBarWithNavController;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.ActivitySettingsBinding;
|
||||
|
||||
public class SettingsActivity extends BaseBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app.fedilab.android.databinding.ActivitySettingsBinding binding = ActivitySettingsBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
NavController navController = Navigation.findNavController(this, R.id.fragment_container);
|
||||
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder().build();
|
||||
setupActionBarWithNavController(this, navController, appBarConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
NavController navController = Navigation.findNavController(this, R.id.fragment_container);
|
||||
return navController.navigateUp() || super.onSupportNavigateUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
NavController navController = Navigation.findNavController(this, R.id.fragment_container);
|
||||
if (item.getItemId() == android.R.id.home && navController.getCurrentDestination() != null && navController.getCurrentDestination().getId() == R.id.FragmentSettingsCategories) {
|
||||
finish();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package app.fedilab.android.activities
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.navigateUp
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import app.fedilab.android.R
|
||||
import app.fedilab.android.databinding.ActivitySettingsBinding
|
||||
|
||||
class SettingsActivity : BaseBarActivity() {
|
||||
private lateinit var binding: ActivitySettingsBinding
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
binding = ActivitySettingsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
val navController = findNavController(R.id.fragment_container)
|
||||
appBarConfiguration = AppBarConfiguration.Builder().build()
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
val navController = findNavController(R.id.fragment_container)
|
||||
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val navController = findNavController(R.id.fragment_container)
|
||||
if (item.itemId == android.R.id.home && navController.currentDestination?.id == R.id.FragmentSettingsCategories) {
|
||||
finish()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
}
|
|
@ -105,6 +105,12 @@ public interface MastodonAccountsService {
|
|||
@Path("id") String id
|
||||
);
|
||||
|
||||
//Get Account
|
||||
@GET("accounts/lookup")
|
||||
Call<Account> lookUpAccount(
|
||||
@Query("acct") String acct
|
||||
);
|
||||
|
||||
//Get Account statuses
|
||||
@GET("accounts/{id}/statuses")
|
||||
Call<List<Status>> getAccountStatuses(
|
||||
|
|
|
@ -96,7 +96,7 @@ public interface MastodonFiltersService {
|
|||
);
|
||||
|
||||
//Remove a keyword for a filter
|
||||
@DELETE("filter_keywords/{id}")
|
||||
@DELETE("filters/keywords/{id}")
|
||||
Call<Void> removeKeywordFilter(
|
||||
@Header("Authorization") String token,
|
||||
@Path("id") String id
|
||||
|
|
|
@ -73,12 +73,40 @@ public class Account implements Serializable {
|
|||
public List<Field> fields;
|
||||
@SerializedName("suspended")
|
||||
public boolean suspended;
|
||||
@SerializedName("limited")
|
||||
public boolean limited;
|
||||
@SerializedName("discoverable")
|
||||
public boolean discoverable;
|
||||
@SerializedName("group")
|
||||
public boolean group;
|
||||
@SerializedName("mute_expires_at")
|
||||
public Date mute_expires_at;
|
||||
@SerializedName("moved")
|
||||
public Account moved;
|
||||
@SerializedName("role")
|
||||
public Role role;
|
||||
|
||||
|
||||
public static class Role implements Serializable {
|
||||
@SerializedName("id")
|
||||
public String id;
|
||||
@SerializedName("name")
|
||||
public String name;
|
||||
@SerializedName("color")
|
||||
public String color;
|
||||
@SerializedName("position")
|
||||
public int position;
|
||||
@SerializedName("permissions")
|
||||
public int permissions;
|
||||
@SerializedName("highlighted")
|
||||
public boolean highlighted;
|
||||
@SerializedName("created_at")
|
||||
public Date created_at;
|
||||
@SerializedName("updated_at")
|
||||
public Date updated_at;
|
||||
}
|
||||
|
||||
|
||||
public transient RelationShip relationShip;
|
||||
|
||||
public synchronized Spannable getSpanDisplayName(Context context, WeakReference<View> viewWeakReference) {
|
||||
|
|
|
@ -318,6 +318,23 @@ public class Account extends BaseAccount implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last used account
|
||||
*
|
||||
* @return BaseAccount {@link BaseAccount}
|
||||
*/
|
||||
public List<BaseAccount> getLastUsedAccounts() throws DBException {
|
||||
if (db == null) {
|
||||
throw new DBException("db is null. Wrong initialization.");
|
||||
}
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_USER_ACCOUNT, null, null, null, null, null, Sqlite.COL_UPDATED_AT + " DESC", null);
|
||||
return cursorToListUser(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an account from db
|
||||
*
|
||||
|
|
|
@ -439,6 +439,44 @@ public class CrossActionHelper {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch and federate the remote status
|
||||
*/
|
||||
public static void fetchStatusInRemoteInstance(@NonNull Context context, String url, String instance, Callback callback) {
|
||||
|
||||
MastodonSearchService mastodonSearchService = init(context, instance);
|
||||
new Thread(() -> {
|
||||
Call<Results> resultsCall = mastodonSearchService.search(null, url, null, "statuses", null, null, null, null, null, null, null);
|
||||
Results results = null;
|
||||
if (resultsCall != null) {
|
||||
try {
|
||||
Response<Results> resultsResponse = resultsCall.execute();
|
||||
if (resultsResponse.isSuccessful()) {
|
||||
|
||||
results = resultsResponse.body();
|
||||
if (results != null) {
|
||||
if (results.statuses == null) {
|
||||
results.statuses = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Results finalResults = results;
|
||||
Runnable myRunnable = () -> {
|
||||
if (finalResults != null && finalResults.statuses != null && finalResults.statuses.size() > 0) {
|
||||
callback.federatedStatus(finalResults.statuses.get(0));
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch and federate the remote status
|
||||
*/
|
||||
|
|
|
@ -343,6 +343,8 @@ public class Helper {
|
|||
public static final Pattern codePattern = Pattern.compile("code=([\\w-]+)");
|
||||
public static final Pattern nitterIDPattern = Pattern.compile("/status/(\\d+)");
|
||||
public static final Pattern emailPattern = Pattern.compile("(\\s+[\\w_.-]+@[a-zA-Z0-9][a-zA-Z0-9.-]{1,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+)");
|
||||
public static final Pattern statusIdInUrl = Pattern.compile("statuses/(\\w+)");
|
||||
|
||||
/*public static final Pattern urlPattern = Pattern.compile(
|
||||
"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,10}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))",
|
||||
|
||||
|
|
|
@ -53,6 +53,11 @@ import androidx.preference.PreferenceManager;
|
|||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.MalformedURLException;
|
||||
|
@ -127,6 +132,19 @@ public class SpannableHelper {
|
|||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
Document htmlContent = Jsoup.parse(text);
|
||||
Elements mentionElements = htmlContent.select("a.mention");
|
||||
//We keep a reference to mentions
|
||||
HashMap<String, String> mentionsMap = new HashMap<>();
|
||||
if (mentionElements.size() > 0) {
|
||||
for (int i = 0; i < mentionElements.size(); i++) {
|
||||
Element mentionElement = mentionElements.get(i);
|
||||
String href = mentionElement.attr("href");
|
||||
String mention = mentionElement.text();
|
||||
mentionsMap.put(mention, href);
|
||||
}
|
||||
}
|
||||
|
||||
text = text.replaceAll("((<\\s?p\\s?>|<\\s?br\\s?\\/?>)>(((?!([<])).)*))", "$2<blockquote>$3</blockquote>");
|
||||
Pattern imgPattern = Pattern.compile("<img [^>]*src=\"([^\"]+)\"[^>]*>");
|
||||
Matcher matcherImg = imgPattern.matcher(text);
|
||||
|
@ -178,7 +196,7 @@ public class SpannableHelper {
|
|||
content.removeSpan(span);
|
||||
}
|
||||
//Make tags, mentions, groups
|
||||
interaction(context, content, status, mentionList, forceMentions);
|
||||
interaction(context, content, status, mentionList, forceMentions, mentionsMap);
|
||||
//Make all links
|
||||
linkify(context, content, urlDetails);
|
||||
linkifyURL(context, content, urlDetails);
|
||||
|
@ -759,7 +777,7 @@ public class SpannableHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private static void interaction(Context context, Spannable content, Status status, List<Mention> mentions, boolean forceMentions) {
|
||||
private static void interaction(Context context, Spannable content, Status status, List<Mention> mentions, boolean forceMentions, HashMap<String, String> mentionsMap) {
|
||||
// --- For all patterns defined in Helper class ---
|
||||
for (Map.Entry<Helper.PatternType, Pattern> entry : Helper.patternHashMap.entrySet()) {
|
||||
Helper.PatternType patternType = entry.getKey();
|
||||
|
@ -837,8 +855,9 @@ public class SpannableHelper {
|
|||
intent = new Intent(context, ProfileActivity.class);
|
||||
b = new Bundle();
|
||||
Mention targetedMention = null;
|
||||
String acct = null;
|
||||
HashMap<String, Integer> countUsername = new HashMap<>();
|
||||
|
||||
//Mentions is retrieved with associated Mentions array
|
||||
if (mentions != null) {
|
||||
for (Mention mention : mentions) {
|
||||
Integer count = countUsername.get(mention.username);
|
||||
|
@ -861,11 +880,19 @@ public class SpannableHelper {
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else if (mentionsMap.containsKey(word.trim())) {//Mentions will be find through its URL
|
||||
URL url;
|
||||
try {
|
||||
url = new URL(mentionsMap.get(word.trim()));
|
||||
acct = word.trim() + "@" + url.getHost();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (targetedMention != null) {
|
||||
b.putString(Helper.ARG_USER_ID, targetedMention.id);
|
||||
} else {
|
||||
b.putString(Helper.ARG_MENTION, word.trim());
|
||||
b.putString(Helper.ARG_MENTION, acct != null ? acct : word.trim());
|
||||
}
|
||||
|
||||
intent.putExtras(b);
|
||||
|
|
|
@ -231,7 +231,9 @@ public class ComposeWorker extends Worker {
|
|||
if (statusResponse.isSuccessful()) {
|
||||
Status statusReply = statusResponse.body();
|
||||
if (statusReply != null) {
|
||||
StatusAdapter.sendAction(context, Helper.ARG_STATUS_POSTED, statusReply, null);
|
||||
if (dataPost.statusEditId == null) {
|
||||
StatusAdapter.sendAction(context, Helper.ARG_STATUS_POSTED, statusReply, null);
|
||||
}
|
||||
}
|
||||
if (firstSendMessage == null && statusReply != null) {
|
||||
firstSendMessage = statusReply;
|
||||
|
|
|
@ -34,7 +34,6 @@ public class AccountsReplyAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
private final boolean[] checked;
|
||||
public ActionDone actionDone;
|
||||
|
||||
|
||||
public AccountsReplyAdapter(List<Account> accounts, List<Boolean> checked) {
|
||||
this.accounts = accounts;
|
||||
this.checked = new boolean[checked.size()];
|
||||
|
|
|
@ -80,8 +80,9 @@ import java.lang.ref.WeakReference;
|
|||
import java.text.Normalizer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
@ -124,11 +125,52 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
public static boolean autocomplete = false;
|
||||
public static String[] ALPHA = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
|
||||
"s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "!", ",", "?",
|
||||
".", "'"};
|
||||
".", "'", "!", "/", "(", ")", "&", ":", ";", "=", "+", "-", "_",
|
||||
"\"", "$", "@", "¿", "¡"
|
||||
};
|
||||
public static String[] MORSE = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..",
|
||||
"--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
|
||||
"..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----", "-.-.--", "--..--",
|
||||
"..--..", ".-.-.-", ".----.",};
|
||||
"..--..", ".-.-.-", ".----.", "-.-.--", "-..-.", "-.--.", "-.--.-", ".-...", "---...", "-.-.-.", "-...-", ".-.-.", "-....-", "..--.-",
|
||||
".-..-.", "...-..-", ".--.-.", "..-.-", "--...-"
|
||||
};
|
||||
|
||||
public static String[] MORSE2 = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..",
|
||||
"--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
|
||||
"..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----", "-.-.--", "--..--",
|
||||
"..--..", ".-.-.-", ".----.", "-.-.--", "-..-.", "-.--.", "-.--.-", ".-...", "---...", "-.-.-.", "-...-", ".-.-.", "-....-", "..--.-",
|
||||
".-..-.", "...-..-", ".--.-.", "..-.-", "--...-"
|
||||
};
|
||||
|
||||
public static int countMorseChar(String content) {
|
||||
int count_char = 0;
|
||||
for (String morseCode : MORSE2) {
|
||||
if (content.contains(morseCode) && !morseCode.equals(".") && !morseCode.equals("..") && !morseCode.equals("...") && !morseCode.equals("-") && !morseCode.equals("--")) {
|
||||
count_char++;
|
||||
}
|
||||
}
|
||||
return count_char;
|
||||
}
|
||||
|
||||
public static String morseToText(String morseContent) {
|
||||
LinkedHashMap<String, String> ALPHA_TO_MORSE = new LinkedHashMap<>();
|
||||
for (int i = 0; i < ALPHA.length && i < MORSE.length; i++) {
|
||||
ALPHA_TO_MORSE.put(MORSE[i], ALPHA[i]);
|
||||
}
|
||||
List<String> MORSELIST = Arrays.asList(MORSE2);
|
||||
MORSELIST.sort((s1, s2) -> s2.length() - s1.length());
|
||||
LinkedHashMap<String, String> MORSE_TO_ALPHA = new LinkedHashMap<>();
|
||||
for (String s : MORSELIST) {
|
||||
MORSE_TO_ALPHA.put(s, ALPHA_TO_MORSE.get(s));
|
||||
}
|
||||
for (String morseCode : MORSELIST) {
|
||||
if (MORSE_TO_ALPHA.containsKey(morseCode)) {
|
||||
morseContent = morseContent.replaceAll(Pattern.quote(morseCode), MORSE_TO_ALPHA.get(morseCode));
|
||||
}
|
||||
}
|
||||
return morseContent;
|
||||
}
|
||||
|
||||
private final List<Status> statusList;
|
||||
private final int TYPE_NORMAL = 0;
|
||||
private final BaseAccount account;
|
||||
|
@ -142,6 +184,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
private List<Emoji> emojisList = new ArrayList<>();
|
||||
public promptDraftListener promptDraftListener;
|
||||
private boolean unlisted_changed = false;
|
||||
public static int currentCursorPosition;
|
||||
|
||||
public ComposeAdapter(List<Status> statusList, int statusCount, BaseAccount account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility, String editMessageId) {
|
||||
this.statusList = statusList;
|
||||
|
@ -298,6 +341,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
} else {
|
||||
holder.binding.content.requestFocus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setStatusCount(int count) {
|
||||
|
@ -538,7 +582,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
newContent[0] = Normalizer.normalize(newContent[0], Normalizer.Form.NFD);
|
||||
newContent[0] = newContent[0].replaceAll("[^\\p{ASCII}]", "");
|
||||
|
||||
HashMap<String, String> ALPHA_TO_MORSE = new HashMap<>();
|
||||
LinkedHashMap<String, String> ALPHA_TO_MORSE = new LinkedHashMap<>();
|
||||
for (int i = 0; i < ALPHA.length && i < MORSE.length; i++) {
|
||||
ALPHA_TO_MORSE.put(ALPHA[i], MORSE[i]);
|
||||
}
|
||||
|
@ -550,7 +594,6 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
String morse = ALPHA_TO_MORSE.get(word.substring(i, i + 1).toLowerCase());
|
||||
builder.append(morse).append(" ");
|
||||
}
|
||||
|
||||
builder.append(" ");
|
||||
}
|
||||
newContent[0] = "";
|
||||
|
@ -558,7 +601,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
newContent[0] += mention + " ";
|
||||
}
|
||||
newContent[0] += builder.toString();
|
||||
|
||||
newContent[0] = newContent[0].replaceAll("null", "");
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
Runnable myRunnable = () -> {
|
||||
|
@ -590,7 +633,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
return;
|
||||
}
|
||||
|
||||
String patternh = "^(.|\\s)*(:fedilab_hugs:)$";
|
||||
String patternh = "^(.|\\s)*(:fedilab_hugs:)";
|
||||
final Pattern hPattern = Pattern.compile(patternh);
|
||||
Matcher mh = hPattern.matcher((s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0])));
|
||||
|
||||
|
@ -599,7 +642,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
return;
|
||||
}
|
||||
|
||||
String patternM = "^(.|\\s)*(:fedilab_morse:)$";
|
||||
String patternM = "^(.|\\s)*(:fedilab_morse:)";
|
||||
final Pattern mPattern = Pattern.compile(patternM);
|
||||
Matcher mm = mPattern.matcher((s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0])));
|
||||
if (mm.matches()) {
|
||||
|
@ -852,19 +895,27 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
//It only targets last message in a thread
|
||||
//Return content of last compose message
|
||||
public String getLastComposeContent() {
|
||||
return statusList.get(statusList.size() - 1).text != null ? statusList.get(statusList.size() - 1).text : "";
|
||||
if (currentCursorPosition < statusList.size()) {
|
||||
return statusList.get(currentCursorPosition).text != null ? statusList.get(currentCursorPosition).text : "";
|
||||
} else return "";
|
||||
}
|
||||
//------- end contact ----->
|
||||
|
||||
//Used to write contact when composing
|
||||
public void updateContent(boolean checked, String acct) {
|
||||
if (checked) {
|
||||
if (!statusList.get(statusList.size() - 1).text.contains(acct))
|
||||
statusList.get(statusList.size() - 1).text = String.format("%s %s", acct, statusList.get(statusList.size() - 1).text);
|
||||
} else {
|
||||
statusList.get(statusList.size() - 1).text = statusList.get(statusList.size() - 1).text.replaceAll("\\s*" + acct, "");
|
||||
if (currentCursorPosition < statusList.size()) {
|
||||
if (checked) {
|
||||
if (statusList.get(currentCursorPosition).text == null) {
|
||||
statusList.get(currentCursorPosition).text = "";
|
||||
}
|
||||
if (!statusList.get(currentCursorPosition).text.contains(acct)) {
|
||||
statusList.get(currentCursorPosition).text = String.format("@%s %s", acct, statusList.get(currentCursorPosition).text);
|
||||
}
|
||||
} else {
|
||||
statusList.get(currentCursorPosition).text = statusList.get(currentCursorPosition).text.replaceAll("@" + acct, "");
|
||||
}
|
||||
notifyItemChanged(currentCursorPosition);
|
||||
}
|
||||
notifyItemChanged(statusList.size() - 1);
|
||||
}
|
||||
|
||||
//Put cursor to the end after changing contacts
|
||||
|
@ -1038,16 +1089,14 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
composeAttachmentItemBinding.preview.setOnClickListener(v -> displayAttachments(holder, position, finalMediaPosition));
|
||||
if (attachment.description == null || attachment.description.trim().isEmpty()) {
|
||||
composeAttachmentItemBinding.buttonDescription.setIconResource(R.drawable.ic_baseline_warning_24);
|
||||
composeAttachmentItemBinding.buttonDescription.setStrokeColor(ThemeHelper.getNoDescriptionColorStateList(context));
|
||||
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.no_description));
|
||||
Helper.changeDrawableColor(context, R.drawable.ic_baseline_warning_24, ContextCompat.getColor(context, R.color.no_description));
|
||||
composeAttachmentItemBinding.buttonDescription.setIconTint(ThemeHelper.getNoDescriptionColorStateList(context));
|
||||
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.black));
|
||||
composeAttachmentItemBinding.buttonDescription.setIconTintResource(R.color.black);
|
||||
composeAttachmentItemBinding.buttonDescription.setBackgroundTintList(ThemeHelper.getNoDescriptionColorStateList(context));
|
||||
} else {
|
||||
composeAttachmentItemBinding.buttonDescription.setIconTint(ThemeHelper.getHavingDescriptionColorStateList(context));
|
||||
composeAttachmentItemBinding.buttonDescription.setIconResource(R.drawable.ic_baseline_check_circle_24);
|
||||
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.having_description));
|
||||
composeAttachmentItemBinding.buttonDescription.setStrokeColor(ThemeHelper.getHavingDescriptionColorStateList(context));
|
||||
Helper.changeDrawableColor(context, R.drawable.ic_baseline_check_circle_24, ContextCompat.getColor(context, R.color.having_description));
|
||||
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
composeAttachmentItemBinding.buttonDescription.setIconTintResource(R.color.white);
|
||||
composeAttachmentItemBinding.buttonDescription.setBackgroundTintList(ThemeHelper.getHavingDescriptionColorStateList(context));
|
||||
}
|
||||
holder.binding.attachmentsList.addView(composeAttachmentItemBinding.getRoot());
|
||||
mediaPosition++;
|
||||
|
@ -1318,6 +1367,11 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
addAttachment(position, uris);
|
||||
}
|
||||
});
|
||||
holder.binding.content.setOnFocusChangeListener((view, focused) -> {
|
||||
if (focused) {
|
||||
currentCursorPosition = holder.getLayoutPosition();
|
||||
}
|
||||
});
|
||||
if (statusDraft.cursorPosition <= holder.binding.content.length()) {
|
||||
holder.binding.content.setSelection(statusDraft.cursorPosition);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
public FetchMoreCallBack fetchMoreCallBack;
|
||||
private Context context;
|
||||
private boolean isExpended = false;
|
||||
private RecyclerView mRecyclerView;
|
||||
|
||||
public ConversationAdapter(List<Conversation> conversations) {
|
||||
if (conversations == null) {
|
||||
|
@ -194,7 +195,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
holder.binding.spoiler.setVisibility(View.VISIBLE);
|
||||
holder.binding.spoiler.setText(
|
||||
conversation.last_status.getSpanSpoiler(context,
|
||||
new WeakReference<>(holder.binding.spoiler), () -> notifyItemChanged(holder.getBindingAdapterPosition())),
|
||||
new WeakReference<>(holder.binding.spoiler), () -> mRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
} else {
|
||||
holder.binding.spoiler.setVisibility(View.GONE);
|
||||
|
@ -204,7 +205,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
//--- MAIN CONTENT ---
|
||||
holder.binding.statusContent.setText(
|
||||
conversation.last_status.getSpanContent(context,
|
||||
new WeakReference<>(holder.binding.statusContent), () -> notifyItemChanged(holder.getBindingAdapterPosition())),
|
||||
new WeakReference<>(holder.binding.statusContent), () -> mRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
//--- DATE ---
|
||||
holder.binding.lastMessageDate.setText(Helper.dateDiff(context, conversation.last_status.created_at));
|
||||
|
@ -224,6 +225,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
return false;
|
||||
});
|
||||
|
||||
|
||||
displayAttachments(holder, position);
|
||||
if (holder.timer != null) {
|
||||
holder.timer.cancel();
|
||||
|
@ -245,6 +247,13 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
applyColorConversation(context, holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
||||
super.onAttachedToRecyclerView(recyclerView);
|
||||
|
||||
mRecyclerView = recyclerView;
|
||||
}
|
||||
|
||||
private void displayAttachments(ConversationAdapter.ConversationHolder holder, int position) {
|
||||
if (conversationList.get(position).last_status != null) {
|
||||
Status status = conversationList.get(position).last_status;
|
||||
|
|
|
@ -367,11 +367,9 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
|
||||
} else {
|
||||
holderStatus.bindingNotification.status.mainContainer.setAlpha(.7f);
|
||||
holderStatus.bindingNotification.status.mainContainer.setVisibility(View.VISIBLE);
|
||||
boolean displayMedia = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_MEDIA_NOTIFICATION), true);
|
||||
if (displayMedia && notification.status != null && notification.status.media_attachments != null && notification.status.media_attachments.size() > 0) {
|
||||
holderStatus.bindingNotification.status.mediaContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
if (!displayMedia) {
|
||||
holderStatus.bindingNotification.status.attachmentsListContainer.setVisibility(View.GONE);
|
||||
holderStatus.bindingNotification.status.mediaContainer.setVisibility(View.GONE);
|
||||
}
|
||||
String title = "";
|
||||
|
|
|
@ -395,6 +395,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true);
|
||||
boolean fullAttachement = sharedpreferences.getBoolean(context.getString(R.string.SET_FULL_PREVIEW), false);
|
||||
boolean displayBookmark = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_BOOKMARK), true);
|
||||
boolean displayTranslate = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_TRANSLATE), false);
|
||||
boolean displayCounters = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_COUNTER_FAV_BOOST), false);
|
||||
String loadMediaType = sharedpreferences.getString(context.getString(R.string.SET_LOAD_MEDIA_TYPE), "ALWAYS");
|
||||
|
||||
|
@ -628,6 +629,11 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
} else {
|
||||
holder.binding.actionButtonBookmark.setVisibility(View.GONE);
|
||||
}
|
||||
if (displayTranslate) {
|
||||
holder.binding.actionButtonTranslate.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.actionButtonTranslate.setVisibility(View.GONE);
|
||||
}
|
||||
//--- ACTIONS ---
|
||||
holder.binding.actionButtonBookmark.setChecked(statusToDeal.bookmarked);
|
||||
//---> BOOKMARK/UNBOOKMARK
|
||||
|
@ -635,6 +641,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
CrossActionHelper.doCrossAction(context, CrossActionHelper.TypeOfCrossAction.BOOKMARK_ACTION, null, statusToDeal);
|
||||
return true;
|
||||
});
|
||||
holder.binding.actionButtonTranslate.setOnClickListener(v -> {
|
||||
translate(context, statusToDeal, holder, adapter);
|
||||
});
|
||||
holder.binding.actionButtonBookmark.setOnClickListener(v -> {
|
||||
if (remote) {
|
||||
Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show();
|
||||
|
@ -887,6 +896,11 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
holder.binding.actionButtonReply.getLayoutParams().width = (int) (normalSize * scaleIcon);
|
||||
holder.binding.actionButtonReply.getLayoutParams().height = (int) (normalSize * scaleIcon);
|
||||
holder.binding.actionButtonReply.requestLayout();
|
||||
|
||||
holder.binding.actionButtonTranslate.getLayoutParams().width = (int) (normalSize * scaleIcon);
|
||||
holder.binding.actionButtonTranslate.getLayoutParams().height = (int) (normalSize * scaleIcon);
|
||||
holder.binding.actionButtonTranslate.requestLayout();
|
||||
|
||||
holder.binding.actionButtonBoost.setImageSize((int) (normalSize * scaleIcon));
|
||||
holder.binding.actionButtonFavorite.setImageSize((int) (normalSize * scaleIcon));
|
||||
holder.binding.actionButtonBookmark.setImageSize((int) (normalSize * scaleIcon));
|
||||
|
@ -1453,25 +1467,27 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (context instanceof ContextActivity) {
|
||||
if (context instanceof ContextActivity && !remote) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(Helper.ARG_STATUS, statusToDeal);
|
||||
Fragment fragment = Helper.addFragment(((AppCompatActivity) context).getSupportFragmentManager(), R.id.nav_host_fragment_content_main, new FragmentMastodonContext(), bundle, null, FragmentMastodonContext.class.getName());
|
||||
((ContextActivity) context).setCurrentFragment((FragmentMastodonContext) fragment);
|
||||
} else {
|
||||
if (remote) {
|
||||
Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show();
|
||||
searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1)
|
||||
.observe((LifecycleOwner) context, results -> {
|
||||
if (results != null && results.statuses != null && results.statuses.size() > 0) {
|
||||
Status fetchedStatus = results.statuses.get(0);
|
||||
Intent intent = new Intent(context, ContextActivity.class);
|
||||
intent.putExtra(Helper.ARG_STATUS, fetchedStatus);
|
||||
context.startActivity(intent);
|
||||
} else {
|
||||
Toasty.info(context, context.getString(R.string.toast_error_search), Toasty.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
if (!(context instanceof ContextActivity)) { //We are not already checking a remote conversation
|
||||
Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show();
|
||||
searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1)
|
||||
.observe((LifecycleOwner) context, results -> {
|
||||
if (results != null && results.statuses != null && results.statuses.size() > 0) {
|
||||
Status fetchedStatus = results.statuses.get(0);
|
||||
Intent intent = new Intent(context, ContextActivity.class);
|
||||
intent.putExtra(Helper.ARG_STATUS, fetchedStatus);
|
||||
context.startActivity(intent);
|
||||
} else {
|
||||
Toasty.info(context, context.getString(R.string.toast_error_search), Toasty.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Intent intent = new Intent(context, ContextActivity.class);
|
||||
intent.putExtra(Helper.ARG_STATUS, statusToDeal);
|
||||
|
@ -1674,41 +1690,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
}));
|
||||
builderInner.show();
|
||||
} else if (itemId == R.id.action_translate) {
|
||||
MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE;
|
||||
final MyTransL myTransL = MyTransL.getInstance(et);
|
||||
myTransL.setObfuscation(true);
|
||||
Params params = new Params();
|
||||
params.setSplit_sentences(false);
|
||||
params.setFormat(Params.fType.TEXT);
|
||||
params.setSource_lang("auto");
|
||||
myTransL.setLibretranslateDomain("translate.fedilab.app");
|
||||
String statusToTranslate;
|
||||
String translate = sharedpreferences.getString(context.getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale());
|
||||
if (translate != null && translate.equalsIgnoreCase("default")) {
|
||||
translate = MyTransL.getLocale();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
statusToTranslate = Html.fromHtml(statusToDeal.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
statusToTranslate = Html.fromHtml(statusToDeal.content).toString();
|
||||
myTransL.translate(statusToTranslate, translate, params, new Results() {
|
||||
@Override
|
||||
public void onSuccess(Translate translate) {
|
||||
if (translate.getTranslatedContent() != null) {
|
||||
statusToDeal.translationShown = true;
|
||||
statusToDeal.translationContent = translate.getTranslatedContent();
|
||||
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
|
||||
} else {
|
||||
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(HttpsConnectionException httpsConnectionException) {
|
||||
|
||||
}
|
||||
});
|
||||
translate(context, statusToDeal, holder, adapter);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_report) {
|
||||
Intent intent = new Intent(context, ReportActivity.class);
|
||||
|
@ -1916,6 +1898,56 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
|
||||
}
|
||||
|
||||
private static void translate(Context context, Status statusToDeal,
|
||||
StatusViewHolder holder,
|
||||
RecyclerView.Adapter<RecyclerView.ViewHolder> adapter) {
|
||||
String statusToTranslate;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
statusToTranslate = Html.fromHtml(statusToDeal.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
statusToTranslate = Html.fromHtml(statusToDeal.content).toString();
|
||||
|
||||
int countMorseChar = ComposeAdapter.countMorseChar(statusToTranslate);
|
||||
if (countMorseChar < 4) {
|
||||
MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE;
|
||||
final MyTransL myTransL = MyTransL.getInstance(et);
|
||||
myTransL.setObfuscation(true);
|
||||
Params params = new Params();
|
||||
params.setSplit_sentences(false);
|
||||
params.setFormat(Params.fType.TEXT);
|
||||
params.setSource_lang("auto");
|
||||
myTransL.setLibretranslateDomain("translate.fedilab.app");
|
||||
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String translate = sharedpreferences.getString(context.getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale());
|
||||
if (translate != null && translate.equalsIgnoreCase("default")) {
|
||||
translate = MyTransL.getLocale();
|
||||
}
|
||||
|
||||
|
||||
myTransL.translate(statusToTranslate, translate, params, new Results() {
|
||||
@Override
|
||||
public void onSuccess(Translate translate) {
|
||||
if (translate.getTranslatedContent() != null) {
|
||||
statusToDeal.translationShown = true;
|
||||
statusToDeal.translationContent = translate.getTranslatedContent();
|
||||
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
|
||||
} else {
|
||||
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(HttpsConnectionException httpsConnectionException) {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
statusToDeal.translationShown = true;
|
||||
statusToDeal.translationContent = ComposeAdapter.morseToText(statusToTranslate);
|
||||
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadAndAddAttachment(Context context, LayoutMediaBinding layoutMediaBinding,
|
||||
StatusViewHolder holder,
|
||||
|
@ -2205,6 +2237,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
Helper.changeDrawableColor(context, R.drawable.ic_person, theme_icons_color);
|
||||
Helper.changeDrawableColor(context, R.drawable.ic_bot, theme_icons_color);
|
||||
Helper.changeDrawableColor(context, R.drawable.ic_round_reply_24, theme_icons_color);
|
||||
Helper.changeDrawableColor(context, holder.binding.actionButtonTranslate, theme_icons_color);
|
||||
holder.binding.actionButtonFavorite.setInActiveImageTintColor(theme_icons_color);
|
||||
holder.binding.actionButtonBookmark.setInActiveImageTintColor(theme_icons_color);
|
||||
holder.binding.actionButtonBoost.setInActiveImageTintColor(theme_icons_color);
|
||||
|
@ -2265,8 +2298,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
StatusViewHolder holder = (StatusViewHolder) viewHolder;
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (sharedpreferences.getBoolean(context.getString(R.string.SET_CARDVIEW), false)) {
|
||||
holder.binding.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
|
||||
holder.binding.dividerCard.setVisibility(View.GONE);
|
||||
holder.bindingFilteredHide.cardviewContainer.setCardElevation(Helper.convertDpToPixel(5, context));
|
||||
holder.bindingFilteredHide.dividerCard.setVisibility(View.GONE);
|
||||
}
|
||||
if (status.isFetchMore && fetchMoreCallBack != null) {
|
||||
holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
package app.fedilab.android.ui.fragment.settings;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.helper.SettingsStorage;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
public class FragmentSettingsCategories extends PreferenceFragmentCompat {
|
||||
|
||||
private static final int REQUEST_CODE = 5412;
|
||||
private static final int PICKUP_FILE = 452;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_categories);
|
||||
|
||||
|
||||
Preference pref_category_key_account = findPreference(getString(R.string.pref_category_key_account));
|
||||
if (pref_category_key_account != null) {
|
||||
pref_category_key_account.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToAccount());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_timeline = findPreference(getString(R.string.pref_category_key_timeline));
|
||||
if (pref_category_key_timeline != null) {
|
||||
pref_category_key_timeline.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToTimelines());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_notifications = findPreference(getString(R.string.pref_category_key_notifications));
|
||||
if (pref_category_key_notifications != null) {
|
||||
pref_category_key_notifications.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToNotifications());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_interface = findPreference(getString(R.string.pref_category_key_interface));
|
||||
if (pref_category_key_interface != null) {
|
||||
pref_category_key_interface.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToInterface());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_compose = findPreference(getString(R.string.pref_category_key_compose));
|
||||
if (pref_category_key_compose != null) {
|
||||
pref_category_key_compose.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToCompose());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_languages = findPreference(getString(R.string.pref_category_key_languages));
|
||||
if (pref_category_key_languages != null) {
|
||||
pref_category_key_languages.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToLanguage());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_privacy = findPreference(getString(R.string.pref_category_key_privacy));
|
||||
if (pref_category_key_privacy != null) {
|
||||
pref_category_key_privacy.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToPrivacy());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_category_key_theming = findPreference(getString(R.string.pref_category_key_theming));
|
||||
if (pref_category_key_theming != null) {
|
||||
pref_category_key_theming.setOnPreferenceClickListener(preference -> {
|
||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
|
||||
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToTheming());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
ActivityResultLauncher<String> permissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
||||
if (isGranted) {
|
||||
SettingsStorage.saveSharedPreferencesToFile(requireActivity());
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
|
||||
}
|
||||
});
|
||||
|
||||
Preference pref_export_settings = findPreference(getString(R.string.pref_export_settings));
|
||||
if (pref_export_settings != null) {
|
||||
pref_export_settings.setOnPreferenceClickListener(preference -> {
|
||||
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Preference pref_import_settings = findPreference(getString(R.string.pref_import_settings));
|
||||
if (pref_import_settings != null) {
|
||||
pref_import_settings.setOnPreferenceClickListener(preference -> {
|
||||
Intent openFileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
openFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
openFileIntent.setType("text/plain");
|
||||
String[] mimeTypes = new String[]{"text/plain"};
|
||||
openFileIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
|
||||
startActivityForResult(
|
||||
Intent.createChooser(
|
||||
openFileIntent,
|
||||
getString(R.string.load_settings)), PICKUP_FILE);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == PICKUP_FILE) {
|
||||
boolean result = data != null && SettingsStorage.loadSharedPreferencesFromFile(requireActivity(), data.getData());
|
||||
if (result) {
|
||||
Toasty.success(requireActivity(), getString(R.string.data_import_settings_success), Toasty.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toasty.error(requireActivity(), getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (requestCode == REQUEST_CODE) {
|
||||
if (grantResults.length > 0
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
SettingsStorage.saveSharedPreferencesToFile(requireActivity());
|
||||
} else {
|
||||
Toasty.error(requireActivity(), getString(R.string.permission_missing), Toasty.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
package app.fedilab.android.ui.fragment.settings
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import app.fedilab.android.BaseMainActivity.currentAccount
|
||||
import app.fedilab.android.R
|
||||
import app.fedilab.android.helper.SettingsStorage
|
||||
import es.dmoral.toasty.Toasty
|
||||
|
||||
|
||||
class FragmentSettingsCategories : PreferenceFragmentCompat() {
|
||||
|
||||
private val REQUEST_CODE = 5412
|
||||
private val PICKUP_FILE = 452
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.pref_categories, rootKey)
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_account))?.setOnPreferenceClickListener {
|
||||
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToAccount())
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_timeline))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToTimelines())
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_notifications))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToNotifications())
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_interface))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToInterface())
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_compose))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToCompose())
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_privacy))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToPrivacy())
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_theming))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToTheming())
|
||||
false
|
||||
}
|
||||
@Suppress("DEPRECATION") val permissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { isGranted ->
|
||||
if (isGranted) {
|
||||
SettingsStorage.saveSharedPreferencesToFile(context)
|
||||
} else {
|
||||
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
findPreference<Preference>(getString(R.string.pref_export_settings))?.setOnPreferenceClickListener {
|
||||
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
false
|
||||
}
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_import_settings))?.setOnPreferenceClickListener {
|
||||
val openFileIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
openFileIntent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
openFileIntent.type = "text/plain"
|
||||
val mimeTypes = arrayOf("text/plain")
|
||||
openFileIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
|
||||
|
||||
startActivityForResult(
|
||||
Intent.createChooser(
|
||||
openFileIntent,
|
||||
getString(R.string.load_settings)), PICKUP_FILE)
|
||||
false
|
||||
}
|
||||
|
||||
val adminPreference = findPreference<Preference>(getString(R.string.pref_category_key_administration))
|
||||
adminPreference?.isVisible = currentAccount != null && currentAccount.admin
|
||||
adminPreference?.setOnPreferenceClickListener { false }
|
||||
|
||||
findPreference<Preference>(getString(R.string.pref_category_key_languages))?.setOnPreferenceClickListener {
|
||||
findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToLanguage())
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == PICKUP_FILE) {
|
||||
val result = SettingsStorage.loadSharedPreferencesFromFile(context, data?.data)
|
||||
if (result) {
|
||||
activity?.let { Toasty.success(it, getString(R.string.data_import_settings_success), Toasty.LENGTH_LONG).show() }
|
||||
} else {
|
||||
activity?.let { Toasty.error(it, getString(R.string.toast_error), Toasty.LENGTH_LONG).show() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
when (requestCode) {
|
||||
REQUEST_CODE -> if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
SettingsStorage.saveSharedPreferencesToFile(context)
|
||||
} else {
|
||||
Toast.makeText(context, getString(R.string.permission_missing), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,9 +34,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.ContextActivity;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.client.entities.api.Context;
|
||||
import app.fedilab.android.client.entities.api.Status;
|
||||
import app.fedilab.android.client.entities.app.Timeline;
|
||||
|
@ -54,6 +54,8 @@ public class FragmentMastodonContext extends Fragment {
|
|||
private StatusesVM statusesVM;
|
||||
private List<Status> statuses;
|
||||
private StatusAdapter statusAdapter;
|
||||
public FirstMessage firstMessage;
|
||||
|
||||
//Handle actions that can be done in other fragments
|
||||
private final BroadcastReceiver receive_action = new BroadcastReceiver() {
|
||||
@Override
|
||||
|
@ -64,6 +66,7 @@ public class FragmentMastodonContext extends Fragment {
|
|||
String delete_statuses_for_user = b.getString(Helper.ARG_STATUS_ACCOUNT_ID_DELETED);
|
||||
Status status_to_delete = (Status) b.getSerializable(Helper.ARG_STATUS_DELETED);
|
||||
Status statusPosted = (Status) b.getSerializable(Helper.ARG_STATUS_POSTED);
|
||||
Status status_to_update = (Status) b.getSerializable(Helper.ARG_STATUS_UPDATED);
|
||||
if (receivedStatus != null && statusAdapter != null) {
|
||||
int position = getPosition(receivedStatus);
|
||||
if (position >= 0) {
|
||||
|
@ -95,6 +98,12 @@ public class FragmentMastodonContext extends Fragment {
|
|||
statuses.remove(position);
|
||||
statusAdapter.notifyItemRemoved(position);
|
||||
}
|
||||
} else if (status_to_update != null && statusAdapter != null) {
|
||||
int position = getPosition(status_to_update);
|
||||
if (position >= 0) {
|
||||
statuses.set(position, status_to_update);
|
||||
statusAdapter.notifyItemChanged(position);
|
||||
}
|
||||
} else if (statusPosted != null && statusAdapter != null) {
|
||||
if (requireActivity() instanceof ContextActivity) {
|
||||
int i = 0;
|
||||
|
@ -116,8 +125,10 @@ public class FragmentMastodonContext extends Fragment {
|
|||
}
|
||||
};
|
||||
private Status focusedStatus;
|
||||
private String remote_instance;
|
||||
private Status firstStatus;
|
||||
private boolean pullToRefresh;
|
||||
private String user_token, user_instance;
|
||||
|
||||
/**
|
||||
* Return the position of the status in the ArrayList
|
||||
|
@ -145,17 +156,26 @@ public class FragmentMastodonContext extends Fragment {
|
|||
pullToRefresh = false;
|
||||
if (getArguments() != null) {
|
||||
focusedStatus = (Status) getArguments().getSerializable(Helper.ARG_STATUS);
|
||||
remote_instance = getArguments().getString(Helper.ARG_REMOTE_INSTANCE, null);
|
||||
}
|
||||
if (remote_instance != null) {
|
||||
user_instance = remote_instance;
|
||||
user_token = null;
|
||||
} else {
|
||||
user_instance = MainActivity.currentInstance;
|
||||
user_token = MainActivity.currentToken;
|
||||
}
|
||||
if (focusedStatus == null) {
|
||||
getChildFragmentManager().beginTransaction().remove(this).commit();
|
||||
}
|
||||
|
||||
binding = FragmentPaginationBinding.inflate(inflater, container, false);
|
||||
statusesVM = new ViewModelProvider(FragmentMastodonContext.this).get(StatusesVM.class);
|
||||
binding.recyclerView.setNestedScrollingEnabled(true);
|
||||
this.statuses = new ArrayList<>();
|
||||
focusedStatus.isFocused = true;
|
||||
this.statuses.add(focusedStatus);
|
||||
statusAdapter = new StatusAdapter(this.statuses, Timeline.TimeLineEnum.UNKNOWN, false, true, false);
|
||||
statusAdapter = new StatusAdapter(this.statuses, Timeline.TimeLineEnum.UNKNOWN, false, true, remote_instance != null);
|
||||
binding.swipeContainer.setRefreshing(false);
|
||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(requireActivity());
|
||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||
|
@ -164,12 +184,12 @@ public class FragmentMastodonContext extends Fragment {
|
|||
if (this.statuses.size() > 0) {
|
||||
binding.swipeContainer.setRefreshing(true);
|
||||
pullToRefresh = true;
|
||||
statusesVM.getContext(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, focusedStatus.id)
|
||||
statusesVM.getContext(user_instance, user_token, focusedStatus.id)
|
||||
.observe(getViewLifecycleOwner(), this::initializeContextView);
|
||||
}
|
||||
});
|
||||
if (focusedStatus != null) {
|
||||
statusesVM.getContext(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, focusedStatus.id)
|
||||
statusesVM.getContext(user_instance, user_token, focusedStatus.id)
|
||||
.observe(getViewLifecycleOwner(), this::initializeContextView);
|
||||
}
|
||||
LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_STATUS_ACTION));
|
||||
|
@ -196,7 +216,7 @@ public class FragmentMastodonContext extends Fragment {
|
|||
} else {
|
||||
id = focusedStatus.id;
|
||||
}
|
||||
statusesVM.getContext(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, id)
|
||||
statusesVM.getContext(user_instance, user_token, id)
|
||||
.observe(FragmentMastodonContext.this, this::initializeContextView);
|
||||
}
|
||||
}
|
||||
|
@ -228,6 +248,10 @@ public class FragmentMastodonContext extends Fragment {
|
|||
} else {
|
||||
firstStatus = statuses.get(0);
|
||||
}
|
||||
if (firstMessage != null) {
|
||||
firstMessage.get(firstStatus);
|
||||
}
|
||||
|
||||
int statusPosition = context.ancestors.size();
|
||||
//Build the array of statuses
|
||||
statuses.addAll(0, context.ancestors);
|
||||
|
@ -250,4 +274,8 @@ public class FragmentMastodonContext extends Fragment {
|
|||
super.onDestroyView();
|
||||
}
|
||||
|
||||
|
||||
public interface FirstMessage {
|
||||
void get(Status status);
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ import androidx.lifecycle.ViewModelProvider;
|
|||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -262,6 +263,11 @@ public class FragmentMastodonConversation extends Fragment implements Conversati
|
|||
if (binding == null || !isAdded() || getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RecyclerView.ItemAnimator animator = binding.recyclerView.getItemAnimator();
|
||||
if (animator instanceof SimpleItemAnimator) {
|
||||
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
|
||||
}
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
binding.noAction.setVisibility(View.GONE);
|
||||
binding.swipeContainer.setRefreshing(false);
|
||||
|
|
|
@ -32,6 +32,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
@ -253,6 +254,10 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
|
|||
if (binding == null || !isAdded() || getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
RecyclerView.ItemAnimator animator = binding.recyclerView.getItemAnimator();
|
||||
if (animator instanceof SimpleItemAnimator) {
|
||||
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
|
||||
}
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
binding.noAction.setVisibility(View.GONE);
|
||||
binding.swipeContainer.setRefreshing(false);
|
||||
|
@ -345,6 +350,9 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
|
|||
route(null, false);
|
||||
}
|
||||
}
|
||||
if (notificationList != null && notificationList.size() > 0) {
|
||||
route(FragmentMastodonTimeline.DIRECTION.FETCH_NEW, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -361,7 +362,6 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
if (timelineType != null) {
|
||||
slug = timelineType != Timeline.TimeLineEnum.ART ? timelineType.getValue() + (ident != null ? "|" + ident : "") : Timeline.TimeLineEnum.TAG.getValue() + (ident != null ? "|" + ident : "");
|
||||
}
|
||||
|
||||
LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_STATUS_ACTION));
|
||||
binding = FragmentPaginationBinding.inflate(inflater, container, false);
|
||||
return binding.getRoot();
|
||||
|
@ -539,6 +539,10 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
if (statusReport != null) {
|
||||
scrollToTop();
|
||||
}
|
||||
RecyclerView.ItemAnimator animator = binding.recyclerView.getItemAnimator();
|
||||
if (animator instanceof SimpleItemAnimator) {
|
||||
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
|
||||
}
|
||||
mLayoutManager = new LinearLayoutManager(requireActivity());
|
||||
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||
|
|
|
@ -212,9 +212,7 @@ public class FragmentNotificationContainer extends Fragment {
|
|||
}
|
||||
});
|
||||
dialogBuilder.setOnDismissListener(dialogInterface -> doAction(changes.get(), excludedCategoriesList));
|
||||
dialogBuilder.setPositiveButton(R.string.close, (dialog, id) -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
dialogBuilder.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
|
||||
AlertDialog alertDialog = dialogBuilder.create();
|
||||
alertDialog.show();
|
||||
});
|
||||
|
|
|
@ -296,6 +296,36 @@ public class AccountsVM extends AndroidViewModel {
|
|||
return accountMutableLiveData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param acct The acct of the account
|
||||
* @return {@link LiveData} containing an {@link Account}
|
||||
*/
|
||||
public LiveData<Account> lookUpAccount(@NonNull String instance, @NonNull String acct) {
|
||||
accountMutableLiveData = new MutableLiveData<>();
|
||||
MastodonAccountsService mastodonAccountsService = init(instance);
|
||||
new Thread(() -> {
|
||||
Account account = null;
|
||||
Call<Account> accountCall = mastodonAccountsService.lookUpAccount(acct);
|
||||
if (accountCall != null) {
|
||||
|
||||
try {
|
||||
Response<Account> accountResponse = accountCall.execute();
|
||||
if (accountResponse.isSuccessful()) {
|
||||
account = accountResponse.body();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Account finalAccount = account;
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> accountMutableLiveData.setValue(finalAccount);
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
return accountMutableLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id The id of the account
|
||||
* @return {@link LiveData} containing an {@link Account}
|
||||
|
|
|
@ -212,4 +212,24 @@ public class FiltersVM extends AndroidViewModel {
|
|||
}).start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a filter
|
||||
*
|
||||
* @param id ID of the filter
|
||||
*/
|
||||
public void removeKeyword(@NonNull String instance, String token, @NonNull String id) {
|
||||
MastodonFiltersService mastodonAccountsService = initV2(instance);
|
||||
new Thread(() -> {
|
||||
Call<Void> removeFilterCall = mastodonAccountsService.removeKeywordFilter(token, id);
|
||||
if (removeFilterCall != null) {
|
||||
try {
|
||||
removeFilterCall.execute();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="@color/having_description"
|
||||
android:tint="?colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94V1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11H1v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94V23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94H23v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z" />
|
||||
</vector>
|
|
@ -1,10 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="@color/no_description"
|
||||
android:tint="@color/black"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:fillColor="@color/black"
|
||||
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z" />
|
||||
</vector>
|
||||
|
|
9
app/src/main/res/drawable/tag_follow.xml
Normal file
9
app/src/main/res/drawable/tag_follow.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorControlNormal"
|
||||
android:pathData="M21.41,11.58L12.41,2.58C12.04,2.21 11.53,2 11,2H4A2,2 0,0 0,2 4V11C2,11.53 2.21,12.04 2.59,12.41L3,12.81C3.9,12.27 4.94,12 6,12A6,6 0,0 1,12 18C12,19.06 11.72,20.09 11.18,21L11.58,21.4C11.95,21.78 12.47,22 13,22C13.53,22 14.04,21.79 14.41,21.41L21.41,14.41C21.79,14.04 22,13.53 22,13C22,12.47 21.79,11.96 21.41,11.58M5.5,7A1.5,1.5 0,0 1,4 5.5A1.5,1.5 0,0 1,5.5 4A1.5,1.5 0,0 1,7 5.5A1.5,1.5 0,0 1,5.5 7M10,19H7V22H5V19H2V17H5V14H7V17H10V19Z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/tag_muted.xml
Normal file
9
app/src/main/res/drawable/tag_muted.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorControlNormal"
|
||||
android:pathData="M5.64,3.64L21.36,19.36L19.95,20.78L16,16.83V20L11,15H7V9H8.17L4.22,5.05L5.64,3.64M16,4V11.17L12.41,7.58L16,4Z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/tag_pin.xml
Normal file
9
app/src/main/res/drawable/tag_pin.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorControlNormal"
|
||||
android:pathData="M16,12V4H17V2H7V4H8V12L6,14V16H11.2V22H12.8V16H18V14L16,12Z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/tag_pin_off.xml
Normal file
9
app/src/main/res/drawable/tag_pin_off.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorControlNormal"
|
||||
android:pathData="M2,5.27L3.28,4L20,20.72L18.73,22L12.8,16.07V22H11.2V16H6V14L8,12V11.27L2,5.27M16,12L18,14V16H17.82L8,6.18V4H7V2H17V4H16V12Z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/tag_unfollow.xml
Normal file
9
app/src/main/res/drawable/tag_unfollow.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorControlNormal"
|
||||
android:pathData="M21.41,11.58L12.41,2.58C12.04,2.21 11.53,2 11,2H4A2,2 0,0 0,2 4V11C2,11.53 2.21,12.04 2.59,12.41L3,12.81C3.9,12.27 4.94,12 6,12A6,6 0,0 1,12 18C12,19.06 11.72,20.09 11.18,21L11.58,21.4C11.95,21.78 12.47,22 13,22C13.53,22 14.04,21.79 14.41,21.41L21.41,14.41C21.79,14.04 22,13.53 22,13C22,12.47 21.79,11.96 21.41,11.58M5.5,7A1.5,1.5 0,0 1,4 5.5A1.5,1.5 0,0 1,5.5 4A1.5,1.5 0,0 1,7 5.5A1.5,1.5 0,0 1,5.5 7M8.12,21.54L6,19.41L3.88,21.54L2.46,20.12L4.59,18L2.46,15.88L3.87,14.47L6,16.59L8.12,14.47L9.53,15.88L7.41,18L9.53,20.12L8.12,21.54Z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/tag_unmuted.xml
Normal file
9
app/src/main/res/drawable/tag_unmuted.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorControlNormal"
|
||||
android:pathData="M4,9V15H8L13,20V4L8,9H4M16.55,2.47L15.5,3.53L17.93,6L15,9L17.93,12L15,15L17.93,18L15.5,20.47L16.55,21.53L20,18L17.07,15L20,12L17.07,9L20,6L16.55,2.47Z" />
|
||||
</vector>
|
|
@ -50,6 +50,8 @@
|
|||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.AppCompat.Title"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
|
|
@ -142,17 +142,38 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/avatar_container"
|
||||
tools:text="@tools:sample/first_names" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/account_un"
|
||||
style="@style/TextAppearance.AppCompat.Caption"
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/account_un_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:singleLine="true"
|
||||
android:gravity="center"
|
||||
app:layout_constraintEnd_toEndOf="@id/banner_container"
|
||||
app:layout_constraintStart_toStartOf="@id/banner_container"
|
||||
app:layout_constraintTop_toBottomOf="@id/account_dn"
|
||||
tools:text="\@username\@instance.test" />
|
||||
app:layout_constraintTop_toBottomOf="@id/account_dn">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/account_un"
|
||||
style="@style/TextAppearance.AppCompat.Caption"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
tools:text="\@username\@instance.test" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/account_role"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
||||
android:layout_marginStart="5dp"
|
||||
android:background="@drawable/blue_border"
|
||||
android:textColor="?colorPrimary"
|
||||
android:visibility="gone"
|
||||
tools:text="Owner"
|
||||
tools:visibility="visible" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/names_container"
|
||||
|
@ -163,7 +184,7 @@
|
|||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/account_un">
|
||||
app:layout_constraintTop_toBottomOf="@+id/account_un_container">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -80,21 +80,21 @@
|
|||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_description"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:text="@string/description"
|
||||
android:textColor="@color/black"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="@color/no_description"
|
||||
app:backgroundTint="@color/no_description"
|
||||
app:icon="@drawable/ic_baseline_warning_24"
|
||||
app:iconTint="@color/no_description"
|
||||
app:iconGravity="end"
|
||||
app:iconTint="@color/black"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_order_down"
|
||||
app:layout_constraintStart_toEndOf="@id/button_order_up"
|
||||
app:layout_constraintTop_toBottomOf="@id/preview"
|
||||
app:strokeColor="@color/no_description" />
|
||||
app:layout_constraintTop_toBottomOf="@id/preview" />
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
|
|
|
@ -598,7 +598,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/action_button_reply"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:background="@color/transparent"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
|
@ -659,7 +659,7 @@
|
|||
<com.varunest.sparkbutton.SparkButton
|
||||
android:id="@+id/action_button_bookmark"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/status_add_custom_emoji"
|
||||
app:layout_constraintEnd_toStartOf="@+id/action_button_translate"
|
||||
app:layout_constraintStart_toEndOf="@+id/action_button_favorite"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="48dp"
|
||||
|
@ -675,12 +675,30 @@
|
|||
app:sparkbutton_secondaryColor="@color/marked_icon" />
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/action_button_translate"
|
||||
android:layout_gravity="center"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="@color/transparent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@string/translate"
|
||||
android:src="@drawable/ic_baseline_translate_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/status_add_custom_emoji"
|
||||
app:layout_constraintStart_toEndOf="@+id/action_button_bookmark"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/status_add_custom_emoji"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:background="@color/transparent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/status_emoji"
|
||||
app:layout_constraintStart_toEndOf="@+id/action_button_bookmark"
|
||||
app:layout_constraintStart_toEndOf="@+id/action_button_translate"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
|
@ -695,7 +713,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/status_emoji"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:background="@color/transparent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/action_button_more"
|
||||
app:layout_constraintStart_toEndOf="@+id/status_add_custom_emoji"
|
||||
|
@ -713,7 +731,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/action_button_more"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:background="@color/transparent"
|
||||
android:layout_gravity="center|end"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
@ -37,15 +37,48 @@
|
|||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingBottom="5dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/account_profile_picture"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/profile_picture"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/account_profile_picture"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/profile_picture"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/other_account1"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="gone"
|
||||
tools:src="@tools:sample/avatars"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/other_account2"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="20dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="gone"
|
||||
tools:src="@tools:sample/avatars"
|
||||
tools:visibility="visible" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/change_account"
|
||||
|
@ -55,7 +88,7 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
style="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:id="@+id/account_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -6,9 +6,15 @@
|
|||
android:icon="@drawable/ic_baseline_expand_more_24"
|
||||
android:title="@string/expand_conversation"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_remote"
|
||||
android:icon="@drawable/ic_baseline_location_searching_24"
|
||||
android:title="@string/display_remote_conversation"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_show_cw"
|
||||
android:icon="@drawable/ic_outline_remove_red_eye_24"
|
||||
android:title="@string/expand_cw"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
</menu>
|
|
@ -3,17 +3,17 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_follow_tag"
|
||||
android:icon="@drawable/ic_baseline_post_add_24"
|
||||
android:icon="@drawable/tag_follow"
|
||||
android:title="@string/follow_tag"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_add_timeline"
|
||||
android:icon="@drawable/ic_baseline_add_24"
|
||||
android:title="@string/add_instances"
|
||||
android:icon="@drawable/tag_pin"
|
||||
android:title="@string/pin_tag"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_mute"
|
||||
android:icon="@drawable/ic_baseline_volume_mute_24"
|
||||
android:title="@string/mute_tag"
|
||||
android:icon="@drawable/tag_muted"
|
||||
android:title="@string/mute_tag_action"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
|
@ -15,10 +15,10 @@
|
|||
<string name="save_over">Média uložena</string>
|
||||
<string name="download_from" formatted="false">Soubor: %1$s</string>
|
||||
<string name="password">Heslo</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="accounts">Účty</string>
|
||||
<string name="toots">Zprávy</string>
|
||||
<string name="tags">Štítky</string>
|
||||
<string name="tags">Tagy</string>
|
||||
<string name="save">Uložit</string>
|
||||
<string name="instance">Instance</string>
|
||||
<string name="instance_example">Instance: mastodon.social</string>
|
||||
|
@ -53,21 +53,21 @@
|
|||
<string name="local_menu">Místní časová osa</string>
|
||||
<string name="muted_menu">Ztlumení uživatelé</string>
|
||||
<string name="blocked_menu">Blokovaní uživatelé</string>
|
||||
<string name="notifications">Oznámení</string>
|
||||
<string name="follow_request">Žádost o sledování</string>
|
||||
<string name="notifications">Upozornění</string>
|
||||
<string name="follow_request">Žádosti o sledování</string>
|
||||
<string name="settings">Nastavení</string>
|
||||
<string name="send_email">Poslat e-mail</string>
|
||||
<string name="scheduled_toots">Naplánované zprávy</string>
|
||||
<string name="disclaimer_full">Níže uvedené informace mohou popisovat uživatelský profil neúplně.</string>
|
||||
<string name="insert_emoji">Vložit smajlík</string>
|
||||
<string name="no_emoji">Aplikace prozatím nenačetla uživatelské smajlíky.</string>
|
||||
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
|
||||
<string name="logout_account_confirmation">Opravdu se chcete odhlásit od @%1$s@%2$s\?</string>
|
||||
<!-- Status -->
|
||||
<string name="no_status">Žádné zprávy k zobrazení</string>
|
||||
<string name="favourite_add">Přidat tuto zprávu k oblíbeným\?</string>
|
||||
<string name="favourite_remove">Odstranit tuto zprávu z oblíbených\?</string>
|
||||
<string name="reblog_add">Boostnout tuto zprávu\?</string>
|
||||
<string name="reblog_remove">Zrušit boost\?</string>
|
||||
<string name="reblog_remove">Zrušit boost této zprávy\?</string>
|
||||
<string name="more_action_1">Ztlumit</string>
|
||||
<string name="more_action_2">Blokovat</string>
|
||||
<string name="more_action_3">Nahlásit</string>
|
||||
|
@ -96,65 +96,62 @@
|
|||
<string name="bookmarks">Záložky</string>
|
||||
<string name="bookmark_add">Přidat do záložek</string>
|
||||
<string name="bookmark_remove">Odstranit záložku</string>
|
||||
<string name="status_bookmarked">Toot byl přidán do záložek!</string>
|
||||
<string name="status_unbookmarked">Toot byl odstraněn ze záložek!</string>
|
||||
<string name="status_bookmarked">Status byl přidán do záložek!</string>
|
||||
<string name="status_unbookmarked">Status byl odstraněn ze záložek!</string>
|
||||
<!-- Date -->
|
||||
<string name="date_seconds">%d s</string>
|
||||
<string name="date_minutes">%d m</string>
|
||||
<string name="date_hours">%d h</string>
|
||||
<string name="date_day">%d d</string>
|
||||
<plurals name="date_seconds_polls">
|
||||
<item quantity="one">%d second</item>
|
||||
<item quantity="few">%d seconds</item>
|
||||
<item quantity="many">%d seconds</item>
|
||||
<item quantity="other">%d seconds</item>
|
||||
<item quantity="one">%d sekunda</item>
|
||||
<item quantity="few">%d sekundy</item>
|
||||
<item quantity="other">%d sekund</item>
|
||||
</plurals>
|
||||
<plurals name="date_minutes_polls">
|
||||
<item quantity="one">%d minute</item>
|
||||
<item quantity="few">%d minutes</item>
|
||||
<item quantity="many">%d minutes</item>
|
||||
<item quantity="other">%d minutes</item>
|
||||
<item quantity="one">%d minuta</item>
|
||||
<item quantity="few">%d minuty</item>
|
||||
<item quantity="other">%d minut</item>
|
||||
</plurals>
|
||||
<plurals name="date_hours_polls">
|
||||
<item quantity="one">%d hour</item>
|
||||
<item quantity="few">%d hours</item>
|
||||
<item quantity="many">%d hours</item>
|
||||
<item quantity="other">%d hours</item>
|
||||
<item quantity="one">%d hodina</item>
|
||||
<item quantity="few">%d hodiny</item>
|
||||
<item quantity="other">%d hodin</item>
|
||||
</plurals>
|
||||
<plurals name="date_day_polls">
|
||||
<item quantity="one">%d day</item>
|
||||
<item quantity="few">%d days</item>
|
||||
<item quantity="many">%d days</item>
|
||||
<item quantity="other">%d days</item>
|
||||
<item quantity="one">%d den</item>
|
||||
<item quantity="few">%d dny</item>
|
||||
<item quantity="other">%d dní</item>
|
||||
</plurals>
|
||||
<!-- TOOT -->
|
||||
<string name="toot_select_image_error">Nastala chyba při výběru média!</string>
|
||||
<string name="toot_delete_media">Smazat médium?</string>
|
||||
<string name="toot_delete_media">Smazat médium\?</string>
|
||||
<string name="toot_error_no_content">Vaše zpráva je prázdná!</string>
|
||||
<string name="toot_sent">Zpráva byla odeslána!</string>
|
||||
<string name="toot_sensitive">Citlivý obsah?</string>
|
||||
<string name="toot_sensitive">Citlivý obsah\?</string>
|
||||
<string name="no_draft">Žádné koncepty!</string>
|
||||
<string name="choose_accounts">Vyberte účet</string>
|
||||
<string name="select_accounts">Vyberte účty</string>
|
||||
<string name="remove_draft">Odstranit koncept?</string>
|
||||
<string name="remove_draft">Odstranit koncept\?</string>
|
||||
<string name="upload_form_description">Popsat pro zrakově postižené</string>
|
||||
<!-- Instance -->
|
||||
<string name="instance_no_description">Popis není dostupný!</string>
|
||||
<!-- About -->
|
||||
<string name="about_vesrion">Release %1$s</string>
|
||||
<string name="about_developer">Vývojář:</string>
|
||||
<string name="about_license">Licence: </string>
|
||||
<string name="about_license">Licence:</string>
|
||||
<string name="about_license_action">GNU GPL V3</string>
|
||||
<string name="about_code">Zdrojový kód: </string>
|
||||
<string name="about_code">Zdrojový kód:</string>
|
||||
<string name="about_thekinrar">Prohledat instance:</string>
|
||||
<!-- Conversation -->
|
||||
<!-- Accounts -->
|
||||
<string name="no_accounts">Žádný účet k zobrazení</string>
|
||||
<string name="no_follow_request">Není požadavek ke sledování</string>
|
||||
<string name="no_follow_request">Žádný požadavek ke sledování</string>
|
||||
<string name="status_cnt">Zprávy
|
||||
\n %1$s</string>
|
||||
<string name="following_cnt">Sleduji \n %1$s</string>
|
||||
<string name="followers_cnt">Sledující \n %1$s</string>
|
||||
<string name="followers_cnt">Sledující
|
||||
\n %1$s</string>
|
||||
<string name="reject">Odmítnout</string>
|
||||
<!-- Scheduled toots -->
|
||||
<string name="no_scheduled_toots">Žádné naplánované zprávy k zobrazení!</string>
|
||||
|
@ -167,14 +164,14 @@
|
|||
<string name="timed_mute_profile">%1$s je ztlumen do %2$s. \n Klikněte zde pro zrušení ztišení.</string>
|
||||
<!-- Notifications -->
|
||||
<string name="no_notifications">Žádné upozornění k zobrazení</string>
|
||||
<string name="notif_mention">vás zmínil/a</string>
|
||||
<string name="notif_status">wrote a new message</string>
|
||||
<string name="notif_reblog">boostnul/a váš toot</string>
|
||||
<string name="notif_favourite">si oblíbil/a váš toot</string>
|
||||
<string name="notif_mention">vás zmínil(a)</string>
|
||||
<string name="notif_status">napsal(a) novou zprávu</string>
|
||||
<string name="notif_reblog">boostnul(a) váš status</string>
|
||||
<string name="notif_favourite">si oblíbil(a) váš status</string>
|
||||
<string name="notif_follow">vás sleduje</string>
|
||||
<string name="notif_follow_request">asked to follow you</string>
|
||||
<string name="delete_notification_ask_all">Smazat všechna oznámení?</string>
|
||||
<string name="delete_notification_all">Všechna oznámení byla smazána!</string>
|
||||
<string name="notif_follow_request">vás chce sledovat</string>
|
||||
<string name="delete_notification_ask_all">Smazat všechna upozornění\?</string>
|
||||
<string name="delete_notification_all">Všechna upozornění byla smazána!</string>
|
||||
<!-- HEADER -->
|
||||
<string name="followers">Sledující</string>
|
||||
<!-- TOAST -->
|
||||
|
@ -191,7 +188,7 @@
|
|||
<string name="toast_unfavourite">Zpráva byla odstraněna z oblíbených!</string>
|
||||
<string name="toast_error">Oops! Došlo k chybě!</string>
|
||||
<string name="toast_code_error">Došlo k chybě! Instance nevrátila autorizační kód!</string>
|
||||
<string name="toast_error_instance">Tato doména není platná!</string>
|
||||
<string name="toast_error_instance">Doména instance se zdá být neplatná!</string>
|
||||
<string name="toast_error_loading_account">Došlo k chybě při přepínání mezi účty!</string>
|
||||
<string name="toast_error_search">Při vyhledávání došlo k chybě!</string>
|
||||
<string name="nothing_to_do">Nelze vykonat akci</string>
|
||||
|
@ -199,18 +196,18 @@
|
|||
<!-- Settings -->
|
||||
<string name="set_toots_page">Počet zpráv pro jedno nahrání</string>
|
||||
<string name="set_disable_gif">Zakázat GIF avatary</string>
|
||||
<string name="set_notif_follow">Oznámení v případě sledování</string>
|
||||
<string name="set_notif_follow_share">Oznámení v případě boostnutí vašeho tootu</string>
|
||||
<string name="set_notif_follow_add">Oznámení v případě oblíbení vašeho tootu</string>
|
||||
<string name="set_notif_follow_mention">Oznámení v případě, že vás někdo zmíní</string>
|
||||
<string name="set_notif_follow_poll">Oznámení po skončení ankety</string>
|
||||
<string name="set_notif_status">Notify for new posts</string>
|
||||
<string name="set_share_validation">Zobrazit potvrzení před boostnutí</string>
|
||||
<string name="set_notif_follow">Upozornit, když vás někdo začne sledovat</string>
|
||||
<string name="set_notif_follow_share">Upozornit, když někdo boostne váš status</string>
|
||||
<string name="set_notif_follow_add">Upozornit, když si někdo oblíbí váš status</string>
|
||||
<string name="set_notif_follow_mention">Upozornit, když vás někdo zmíní</string>
|
||||
<string name="set_notif_follow_poll">Upozornit, když skončí anketa</string>
|
||||
<string name="set_notif_status">Upozornit na nové příspěvky</string>
|
||||
<string name="set_share_validation">Zobrazit potvrzení před boostnutím</string>
|
||||
<string name="set_share_validation_fav">Zobrazit potvrzení před oblíbením</string>
|
||||
<string name="set_notify">Oznámení?</string>
|
||||
<string name="set_notif_silent">Tichá oznámení</string>
|
||||
<string name="set_nsfw_timeout">NSFW prodleva (vteřiny, 0 znamená vypnuto)</string>
|
||||
<string name="set_med_desc_timeout">Media Description timeout (seconds, 0 means off)</string>
|
||||
<string name="set_notify">Upozornit\?</string>
|
||||
<string name="set_notif_silent">Tichá upozornění</string>
|
||||
<string name="set_nsfw_timeout">Prodleva NSFW (v sekundách, 0 znamená vypnuto)</string>
|
||||
<string name="set_med_desc_timeout">Timeout pro popis médií (v sekundách, 0 znamená vypnuto)</string>
|
||||
<string name="settings_title_custom_sharing">Vlastní sdílení</string>
|
||||
<string name="settings_custom_sharing_url">Vaše vlastní sdílecí URL…</string>
|
||||
<string name="set_lock_account">Zamknout účet</string>
|
||||
|
@ -231,7 +228,7 @@
|
|||
<item>Žlutá</item>
|
||||
<item>Bílá</item>
|
||||
</string-array>
|
||||
<string name="action_follow">Následovat</string>
|
||||
<string name="action_follow">Sledovat</string>
|
||||
<string name="action_unblock">Odblokovat</string>
|
||||
<string name="action_mute">Ztlumit</string>
|
||||
<string name="action_unmute">Zrušit ztlumení</string>
|
||||
|
@ -239,7 +236,7 @@
|
|||
<string name="followed_by">Sleduje vás</string>
|
||||
<string name="set_capitalize">První písmeno velké v odpovědích</string>
|
||||
<string name="set_resize_picture">Změnit velikost obrázků</string>
|
||||
<string name="set_resize_video">Resize videos</string>
|
||||
<string name="set_resize_video">Změnit velikost videa</string>
|
||||
<!-- Quick settings for notifications -->
|
||||
<!-- CACHE -->
|
||||
<string name="cache_units">Mb</string>
|
||||
|
@ -260,26 +257,26 @@
|
|||
<string name="delete">Odstranit</string>
|
||||
<!-- About lists -->
|
||||
<string name="action_lists">Seznamy</string>
|
||||
<string name="action_lists_confirm_delete">Jsi si jist/a, že chceš trvale odstranit tento seznam?</string>
|
||||
<string name="action_lists_confirm_delete">Opravdu chcete trvale smazat tento seznam\?</string>
|
||||
<string name="action_lists_add_to">Přidat do seznamu</string>
|
||||
<string name="action_lists_delete">Odstranit seznam</string>
|
||||
<string name="action_lists_delete">Smazat seznam</string>
|
||||
<string name="action_lists_title_placeholder">Nový název seznamu</string>
|
||||
<string name="action_lists_add_user">The account was added to the list!</string>
|
||||
<string name="action_lists_empty">You don\'t have any lists yet!</string>
|
||||
<string name="action_lists_add_user">Účet byl přidán do seznamu!</string>
|
||||
<string name="action_lists_empty">Ještě nemáte žádný seznam!</string>
|
||||
<!-- Migration -->
|
||||
<string name="account_moved_to">%1$s se přesunul do %2$s</string>
|
||||
<string name="media_ready">Média byla nahrána. Klikněte pro zobrazení.</string>
|
||||
<!-- Proxy -->
|
||||
<string name="proxy_set">Proxy</string>
|
||||
<string name="proxy_enable">Povolit proxy?</string>
|
||||
<string name="proxy_enable">Povolit proxy\?</string>
|
||||
<string name="poxy_host">Host</string>
|
||||
<string name="poxy_port">Port</string>
|
||||
<string name="poxy_login">Přihlašovací jméno</string>
|
||||
<string name="poxy_password">Heslo</string>
|
||||
<string name="set_share_details">Přidat podrobnosti zprávy při sdílení</string>
|
||||
<string name="support_the_app_on_liberapay">Podpořit aplikaci na Liberapay</string>
|
||||
<string name="alert_regex">Chyba v regulárním výrazu!</string>
|
||||
<string name="toast_instance_unavailable">Časová osa nenalezena na této instanci!</string>
|
||||
<string name="alert_regex">V regulárním výrazu je chyba!</string>
|
||||
<string name="toast_instance_unavailable">Na této instanci nebyly nalezeny žádné časové osy!</string>
|
||||
<string name="follow_instance">Sledovat instanci</string>
|
||||
<string name="toast_instance_already_added">Tuto instanci již sledujete!</string>
|
||||
<string name="action_partnership">Partnerství</string>
|
||||
|
@ -292,13 +289,13 @@
|
|||
<string name="action_filters_empty_content">Žádné filtry k zobrazení. Můžete vytvořit nový filtr klepnutím na tlačítko \"+\".</string>
|
||||
<string name="filter_keyword">Klíčové slovo nebo fráze</string>
|
||||
<string name="context_home">Domovská časová osa</string>
|
||||
<string name="context_public">Veřejná časová osa</string>
|
||||
<string name="context_notification">Oznámení</string>
|
||||
<string name="context_public">Veřejné časové osy</string>
|
||||
<string name="context_notification">Upozornění</string>
|
||||
<string name="context_conversation">Konverzace</string>
|
||||
<string name="filter_keyword_explanations">Velikost písmen ani varování o obsahu nebudou brána v potaz</string>
|
||||
<string name="context_drop">Zahodit místo skrytí</string>
|
||||
<string name="context_drop_explanations">Filtrované zprávy zmizí nezvratně i v případě, že je filtr později odstraněn</string>
|
||||
<string name="context_whole_word_explanations">V případě, že klíčové slovo nebo fráze je pouze alfanumerické, filtr se uplatní pouze pokud odpovídá celému slovu</string>
|
||||
<string name="context_whole_word_explanations">V případě, že klíčové slovo nebo fráze je pouze alfanumerické, filtr se uplatní, pouze pokud odpovídá celému slovu</string>
|
||||
<string name="context_whole_word">Celé slovo</string>
|
||||
<string name="filter_context">Kontext filtru</string>
|
||||
<string name="filter_context_explanations">Jeden nebo několik kontextů pro aplikaci filtru</string>
|
||||
|
@ -313,15 +310,15 @@
|
|||
<string name="channel_notif_mention">Nová zmínka</string>
|
||||
<string name="channel_notif_poll">Anketa skončila</string>
|
||||
<string name="channel_notif_backup">Záloha zpráv</string>
|
||||
<string name="channel_notif_status">New posts</string>
|
||||
<string name="channel_notif_status">Nové příspěvky</string>
|
||||
<string name="channel_notif_media">Stahování médií</string>
|
||||
<string name="select_sound">Vybrat tón</string>
|
||||
<string name="set_enable_time_slot">Zapnout rozvrh oznámení</string>
|
||||
<string name="block_domain_confirm_message">Určitě chcete zablokovat %s?\n\nJiž z této domény neuvidíte ve všech veřejných časových osách ani v oznámeních žádný obsah. Vaši sledující z této domény budou odstraněni.</string>
|
||||
<string name="block_domain">Zablokovat doménu</string>
|
||||
<string name="toast_block_domain">Doména je blokována</string>
|
||||
<string name="retrieve_remote_status">Načítám vzdálený toot</string>
|
||||
<string name="peertube_instance">Peertube instance</string>
|
||||
<string name="retrieve_remote_status">Načítám vzdálený status</string>
|
||||
<string name="peertube_instance">Instance Peertube</string>
|
||||
<string name="set_display_emoji">Použít Emoji One</string>
|
||||
<string name="information">Informace</string>
|
||||
<string name="set_display_card">Zobrazit náhled ve všech zprávách</string>
|
||||
|
@ -331,20 +328,20 @@
|
|||
<string name="set_truncate_toot">Ořezat zprávy delší než \'x\' řádků. 0 znamená vypnuto.</string>
|
||||
<string name="display_toot_truncate">Zobrazit více</string>
|
||||
<string name="hide_toot_truncate">Zobrazit méně</string>
|
||||
<string name="tags_already_stored">Štítek již existuje!</string>
|
||||
<string name="tags_already_stored">Tag již existuje!</string>
|
||||
<string name="schedule_boost">Naplánovat boost</string>
|
||||
<string name="boost_scheduled">Boost je naplánováo!</string>
|
||||
<string name="no_scheduled_boosts">Žádný naplánovaý boost k zobrazení!</string>
|
||||
<string name="boost_scheduled">Boost je naplánován!</string>
|
||||
<string name="no_scheduled_boosts">Žádný naplánovaný boost k zobrazení!</string>
|
||||
<string name="open_menu">Otevřete nabídku</string>
|
||||
<string name="profile_picture">Profilový obrázek</string>
|
||||
<string name="profile_banner">Profilová hlavička</string>
|
||||
<string name="contact_instance_admin">Kontaktovat administrátora instance</string>
|
||||
<string name="mastohost_logo">MastoHost logo</string>
|
||||
<string name="mastohost_logo">Logo MastoHost</string>
|
||||
<string name="emoji_picker">Výběr emotikonů</string>
|
||||
<string name="expand_conversation">Ukázat celou konverzaci</string>
|
||||
<string name="custom_emoji_picker">Uživatelský výběr emoji</string>
|
||||
<string name="favicon">Favicon</string>
|
||||
<string name="media_description">Médium pro přidání popisu</string>
|
||||
<string name="media_description">Přidat k médiu popis (pro zrakově postižené)</string>
|
||||
<string-array name="filter_expire">
|
||||
<item>Nikdy</item>
|
||||
<item>30 minut</item>
|
||||
|
@ -359,7 +356,7 @@
|
|||
<string name="show_media_only">Pouze média</string>
|
||||
<string name="show_media_nsfw">Zobrazit NSFW</string>
|
||||
<string name="bot">Bot</string>
|
||||
<string name="pixelfed_instance">Pixelfed instance</string>
|
||||
<string name="pixelfed_instance">Instance Pixelfed</string>
|
||||
<string name="mastodon_instance">Instance Mastodon</string>
|
||||
<string name="any_tags">Kterýkoliv</string>
|
||||
<string name="all_tags">Všechny</string>
|
||||
|
@ -368,7 +365,7 @@
|
|||
<string name="some_words_all">Všechna slova (oddělená mezerami)</string>
|
||||
<string name="some_tags">Add some words to filter (space-separated)</string>
|
||||
<string name="change_tag_column">Změnit název sloupce</string>
|
||||
<string name="misskey_instance">Misskey instance</string>
|
||||
<string name="misskey_instance">Instance Misskey</string>
|
||||
<string name="trending">Populární</string>
|
||||
<string name="local">Místní</string>
|
||||
<string name="category">Kategorie</string>
|
||||
|
@ -376,19 +373,19 @@
|
|||
<string name="share">Sdílet</string>
|
||||
<string name="toots_server">Zprávy (Server)</string>
|
||||
<string name="toots_client">Zprávy (Zařízení)</string>
|
||||
<string name="settings_category_label_timelines">Časové osi</string>
|
||||
<string name="settings_category_label_timelines">Časové osy</string>
|
||||
<string name="settings_category_label_interface">Rozhraní</string>
|
||||
<string name="contact">Kontakty</string>
|
||||
<string name="toot_select_file_error">Při výběru zálohového souboru nastala chyba!</string>
|
||||
<string name="action_logout_account">Odhlásit účet</string>
|
||||
<string name="all">Vše</string>
|
||||
<string name="copy_link">Kopírovat odkaz</string>
|
||||
<string name="calls_blocked">volání http je blokováné aplikací</string>
|
||||
<string name="list_of_blocked_domains">Seznam blokovaných domén</string>
|
||||
<string name="calls_blocked">volání http je blokováno aplikací</string>
|
||||
<string name="list_of_blocked_domains">Seznam blokovaných volání</string>
|
||||
<string name="submit">Odeslat</string>
|
||||
<string name="filter_timeline_with_a_tag">Filtrovat časovou osu s hashtagy</string>
|
||||
<string name="no_tags">Žádné hashtagy</string>
|
||||
<string name="set_retrieve_metadata_share_from_extras">Připojit při sdílení URL obrázek</string>
|
||||
<string name="set_retrieve_metadata_share_from_extras">Při sdílení URL připojit obrázek</string>
|
||||
<!-- end languages -->
|
||||
<string name="create_poll">Vytvořit anketu</string>
|
||||
<string name="poll_choice_s">Volba %d</string>
|
||||
|
@ -396,7 +393,7 @@
|
|||
<string name="done">Hotovo</string>
|
||||
<string name="poll_finish_at">skončit po %s</string>
|
||||
<string name="vote">Hlasovat</string>
|
||||
<string name="notif_poll">Anketa, ve které jste hlasoval/a, skončila</string>
|
||||
<string name="notif_poll">Anketa, ve které jste hlasoval(a), skončila</string>
|
||||
<string name="notif_poll_self">Vaše anketa skončila</string>
|
||||
<string name="settings_category_notif_categories">Kategorie</string>
|
||||
<string name="move_timeline">Přesunout časovou osu</string>
|
||||
|
@ -404,14 +401,14 @@
|
|||
<string name="reorder_timelines">Spravovat časové osy</string>
|
||||
<string name="reorder_list_deleted">Seznam trvale smazán</string>
|
||||
<string name="reorder_instance_removed">Sledovaná instance odstraněna</string>
|
||||
<string name="reorder_tag_removed">Připnuté značky odstraněny</string>
|
||||
<string name="reorder_tag_removed">Připnutý tag odstraněn</string>
|
||||
<string name="undo">Vrátit zpět</string>
|
||||
<string name="warning_main_timeline">Hlavní časové linie mohou být pouze skryty!</string>
|
||||
<string name="warning_main_timeline">Hlavní časové osy mohou být pouze skryty!</string>
|
||||
<string name="set_sensitive_content">Vždy označovat média jako citlivá</string>
|
||||
<string name="gnu_instance">GNU instance</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">Spravovat štítky</string>
|
||||
<string name="gnu_instance">Instance GNU</string>
|
||||
<string name="set_forward_tags">V odpovědích přeposílat tagy</string>
|
||||
<string name="set_long_press_media">K uložení média dlouze stlačte</string>
|
||||
<string name="add_tags">Spravovat tagy</string>
|
||||
<string name="display_name">Zobrazované jméno</string>
|
||||
<string name="label_emoji">Emoji</string>
|
||||
<string name="label_text">Text</string>
|
||||
|
@ -419,81 +416,84 @@
|
|||
<string name="label_brush">Štětec</string>
|
||||
<string name="discard">Zahodit</string>
|
||||
<string name="saving">Ukladáno…</string>
|
||||
<string name="image_saved">Image Saved Successfully!</string>
|
||||
<string name="image_saved">Obrázek byl úspěšně uložen!</string>
|
||||
<string name="save_image_failed">Nepodařilo se uložit obrázek</string>
|
||||
<string name="add_poll_item">Přidat položku ankety</string>
|
||||
<string name="mute_conversation">Ztišit konverzaci</string>
|
||||
<string name="unmute_conversation">Unmute conversation</string>
|
||||
<string name="toast_unmute_conversation">The conversation is no longer muted!</string>
|
||||
<string name="toast_mute_conversation">The conversation is muted</string>
|
||||
<string name="unmute_conversation">Zrušit umlčení konverzace</string>
|
||||
<string name="toast_unmute_conversation">Konverzace už není umlčená!</string>
|
||||
<string name="toast_mute_conversation">Konverzace je umlčená</string>
|
||||
<string name="category_general">Základní</string>
|
||||
<string name="category_regional">Regionální</string>
|
||||
<string name="category_art">Umění</string>
|
||||
<string name="category_activism">Aktivismus</string>
|
||||
<string name="category_games">Hrání</string>
|
||||
<string name="category_games">Hraní</string>
|
||||
<string name="category_tech">Technologie</string>
|
||||
<string name="category_furry">Furry</string>
|
||||
<string name="category_food">Jídlo</string>
|
||||
<string name="instance_logo">Logo of the instance</string>
|
||||
<string name="instance_logo">Logo instance</string>
|
||||
<string name="join_mastodon">Připojte se k Mastodonu</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="password_confirm">Confirm password</string>
|
||||
<string name="agreement_check">I agree to %1$s and %2$s</string>
|
||||
<string name="users">%1$s uživatelů</string>
|
||||
<string name="password_confirm">Potvrdit heslo</string>
|
||||
<string name="agreement_check">Souhlasím s %1$s a %2$s</string>
|
||||
<string name="server_rules">pravidla serveru</string>
|
||||
<string name="tos">podmínky užití</string>
|
||||
<string name="sign_up">Registrovat se</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="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="validation_needed">Tato instance funguje na pozvánky. Aby se dal váš účet používat, musí ho ručně schválit administrátor.</string>
|
||||
<string name="password_error">Hesla nesouhlasí!</string>
|
||||
<string name="email_error">E-mail se zdá být neplatný!</string>
|
||||
<string name="email_indicator">Poslali jsme vám potvrzovací e-mail</string>
|
||||
<string name="password_indicator">Použijte minimálně 8 znaků</string>
|
||||
<string name="password_too_short">Heslo musí mít minimálně 8 znaků</string>
|
||||
<string name="username_error">Username should only contain letters, numbers and underscores</string>
|
||||
<string name="username_error">Uživatelské jméno smí obsahovat jen písmena, číslice a podtržítka</string>
|
||||
<string name="account_created">Účet vytvořen!</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="save_draft">Save the message in drafts?</string>
|
||||
<string name="account_created_message"> Váš účet byl vytvořen!
|
||||
\n
|
||||
\n Nezapomeňte ověřit e-mail během příštích 48 hodin.
|
||||
\n
|
||||
\n Nyní se můžete připojit ke svému účtu napsáním <b>%1$s</b> do prvního pole a kliknutím na <b>Připojit</b>.
|
||||
\n
|
||||
\n <b>Důležité</b>: Pokud vaše instance vyžaduje ověření, po jeho provedení dostanete e-mailovou zprávu! </string>
|
||||
<string name="save_draft">Uložit zprávu do konceptů\?</string>
|
||||
<string name="administration">Administrace</string>
|
||||
<string name="reports">Reports</string>
|
||||
<string name="unresolved">Unresolved</string>
|
||||
<string name="reports">Hlášení</string>
|
||||
<string name="unresolved">Nevyřešeno</string>
|
||||
<string name="remote">Remote</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="active">Aktivní</string>
|
||||
<string name="pending">Čekající</string>
|
||||
<string name="disabled">Vypnuto</string>
|
||||
<string name="suspended">Pozastaveno</string>
|
||||
<string name="permissions">Oprávnění</string>
|
||||
<string name="disable">Vypnout</string>
|
||||
<string name="silence">Silence</string>
|
||||
<string name="account">Account</string>
|
||||
<string name="account">Účet</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="audio">The application needs to access audio recording</string>
|
||||
<string name="voice_message">Voice message</string>
|
||||
<string name="undisable">Zrušit vypnutí</string>
|
||||
<string name="suspend">Pozastavit</string>
|
||||
<string name="unsuspend">Zrušit pozastavení</string>
|
||||
<string name="audio">Zvuk</string>
|
||||
<string name="voice_message">Hlasová zpráva</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_fit_preview_indication">Náhledy nebudou v časových osách oříznuty</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="settings_title_custom_sharing_indication">Umožňuje tvůrcům obsahu sdílet statusy do jejich kanálů RSS</string>
|
||||
<string name="compose">Vytváření</string>
|
||||
<string name="select">Select</string>
|
||||
<string name="add_instances">Add an instance</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="add_instances">Přidat instanci</string>
|
||||
<string name="set_enable_crash_report">Zapnout hlášení o pádech aplikace</string>
|
||||
<string name="set_enable_crash_report_indication">Pokud je zapnuto, místně se vytvoří hlášení o pádu a pak ho budete moci sdílet.</string>
|
||||
<string name="crash_title">Fedilab přestal fungovat :(</string>
|
||||
<string name="crash_message">Pošlete mi mailem údaje o chybě. Pomůžete tak při opravě :)\n\nMůžete přidat dodatečný obsah. Děkuji!</string>
|
||||
<string name="visibility">Visibility</string>
|
||||
<string name="crash_message">Pošlete mi mailem údaje o chybě. Pomůžete tak při opravě :)
|
||||
\n
|
||||
\nMůžete přidat dodatečný obsah. Děkuji!</string>
|
||||
<string name="visibility">Viditelnost</string>
|
||||
<string name="set_disable_animated_emoji">Disable custom animated emojis</string>
|
||||
<string name="report_account">Report account</string>
|
||||
<string name="report_account">Nahlásit účet</string>
|
||||
<plurals name="number_of_voters">
|
||||
<item quantity="one">%d voter</item>
|
||||
<item quantity="few">%d voters</item>
|
||||
<item quantity="many">%d voters</item>
|
||||
<item quantity="other">%d voters</item>
|
||||
<item quantity="one">%d hlasující</item>
|
||||
<item quantity="few">%d hlasující</item>
|
||||
<item quantity="other">%d hlasujících</item>
|
||||
</plurals>
|
||||
<string-array name="poll_choice_type">
|
||||
<item>Jediná volba</item>
|
||||
|
@ -508,82 +508,89 @@
|
|||
<item>3 dny</item>
|
||||
<item>7 dní</item>
|
||||
</string-array>
|
||||
<string name="poll_duplicated_entry">Your poll can\'t have duplicated options!</string>
|
||||
<string name="set_clear_cache_exit">Clear cache when leaving</string>
|
||||
<string name="set_clear_cache_exit_indication">The cache (media, cached messages, data from the built-in browser) will be automatically cleared when leaving the application.</string>
|
||||
<string name="unfollow_confirm">Do you want to unfollow this account?</string>
|
||||
<string name="set_unfollow_validation">Show confirmation dialog before unfollowing</string>
|
||||
<string name="replace_medium">Replace Medium links</string>
|
||||
<string name="replace_medium_description">Replace medium.com links with an open source alternative front-end focused on privacy.</string>
|
||||
<string name="replace_medium_host">Default: scribe.rip</string>
|
||||
<string name="set_push_notifications">Use a push notifications system for getting notifications in real time.</string>
|
||||
<string name="action_add_notes">Add notes</string>
|
||||
<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="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>
|
||||
<string name="poll_duplicated_entry">Vaše anketa má duplicitní volby!</string>
|
||||
<string name="set_clear_cache_exit">Při opuštění vymazat cache</string>
|
||||
<string name="set_clear_cache_exit_indication">Cache (média, cachované zprávy, data z vestavěného prohlížeče) se při opuštění aplikace automaticky vymaže.</string>
|
||||
<string name="unfollow_confirm">Chcete přestat sledovat tento účet\?</string>
|
||||
<string name="set_unfollow_validation">Před ukončením sledování zobrazit potvrzovací dialog</string>
|
||||
<string name="replace_medium">Medium</string>
|
||||
<string name="replace_medium_description">Použít alternativní frontend pro Medium</string>
|
||||
<string name="replace_medium_host">Doména frontendu pro Medium</string>
|
||||
<string name="set_push_notifications">Používat systém push notifikací pro získávání upozornění v reálném čase.</string>
|
||||
<string name="action_add_notes">Přidat poznámky</string>
|
||||
<string name="note_for_account">Poznámky k účtu</string>
|
||||
<string name="set_resize_picture_indication">Umožnit kompresi velkých fotografií na menší velikost s velmi malou až zanedbatelnou ztrátou kvality.</string>
|
||||
<string name="set_resize_video_indication">Umožnit kompresi videa při udržení kvality.</string>
|
||||
<string name="order_by">Řadit podle</string>
|
||||
<string name="link_color_title">Odkazy</string>
|
||||
<string name="link_color">Změnit ve zprávách barvu odkazů (URL, zmínek, tagů apod.)</string>
|
||||
<string name="boost_header_color_title">Hlavička reblogů</string>
|
||||
<string name="displayname_title">Change the color of display name at the top of messages</string>
|
||||
<string name="username_title">Change the color of the user name at the top of messages</string>
|
||||
<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="boost_header_color">Změnit barvu hlavičky pro reblogy</string>
|
||||
<string name="background_status_title">Příspěvky</string>
|
||||
<string name="background_status">Barva pozadí příspěvků v časových osách</string>
|
||||
<string name="reset_color">Resetovat barvy</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="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="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>
|
||||
<string name="icons_color_title">Ikony</string>
|
||||
<string name="icons_color">Barva dolních ikon v časových osách</string>
|
||||
<string name="logo_of_the_instance">Logo instance</string>
|
||||
<string name="edit_profile">Upravit profil</string>
|
||||
<string name="make_an_action">Provést akci</string>
|
||||
<string name="translation">Překlad</string>
|
||||
<string name="text_color_title">Barva textu</string>
|
||||
<string name="text_color">Změnit barvu textu ve zprávách</string>
|
||||
<string name="pref_custom_theme">Použít vlastní téma</string>
|
||||
<string name="theming">Témata</string>
|
||||
<string name="data_export_theme">Téma bylo exportováno</string>
|
||||
<string name="data_export_theme_success">Téma bylo úspěšně exportováno do CSV</string>
|
||||
<string name="import_theme">Importovat téma</string>
|
||||
<string name="import_theme_title">Tap here to import a theme from a previous export</string>
|
||||
<string name="export_theme">Export the theme</string>
|
||||
<string name="export_theme">Exportovat téma</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="theme_file_error">Při výběru souboru s tématem došlo k chybě</string>
|
||||
<string name="user_count">Počet uživatelů</string>
|
||||
<string name="status_count">Počet statusů</string>
|
||||
<string name="instance_count">Počet instancí</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="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="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="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="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="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_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>
|
||||
<string name="select_distributors">Select a distributor</string>
|
||||
<string name="no_instance_reccord">Tato instance není k dispozici na https://instances.social</string>
|
||||
<string name="display_full_link">Zobrazit úplný odkaz</string>
|
||||
<string name="share_link">Sdílet odkaz</string>
|
||||
<string name="open_other_app">Otevřít jinou aplikací</string>
|
||||
<string name="check_redirect">Zkontrolovat přesměrování</string>
|
||||
<string name="no_redirect">Tento URL není přesměrování</string>
|
||||
<string name="redirect_detected">%1$s
|
||||
\n
|
||||
\npřesměrovává na
|
||||
\n
|
||||
\n %2$s</string>
|
||||
<string name="set_utm_parameters">Odstranit parametry UTM</string>
|
||||
<string name="set_utm_parameters_indication">Aplikace bude před otevřením odkazu automaticky odstraňovat parametry UTM.</string>
|
||||
<string name="talking_about">Hovoří %d lidí</string>
|
||||
<string name="twitter_accounts">Účty Twitteru (přes Nitter)</string>
|
||||
<string name="list_of_twitter_accounts">Uživatelská jména Twitteru oddělená mezerou</string>
|
||||
<string name="identity_proofs">Ověření identity</string>
|
||||
<string name="verified_user">Ověřená identita</string>
|
||||
<string name="verified_by">Ověřil(a) %1$s (%2$s)</string>
|
||||
<string name="action_disabled">Akce vypnuta</string>
|
||||
<string name="action_unfollow">Zrušit sledování</string>
|
||||
<string name="error_destination_path">Došlo k nějaké chybě, zkontrolujte prosím nastavení adresáře pro stahování.</string>
|
||||
<string name="action_announcements">Oznámení</string>
|
||||
<string name="no_announcements">Žádná oznámení!</string>
|
||||
<string name="add_reaction">Přidat reakci</string>
|
||||
<string name="set_video_cache">Video cache v MB, nula znamená žádnou cache.</string>
|
||||
<string name="set_watermark">Vodoznaky</string>
|
||||
<string name="set_watermark_indication">Automaticky přidávat vodoznak do dolní části obrázků. Text lze pro každý účet samostatně nastavit.</string>
|
||||
<string name="no_distributors_found">Nenalezeni žádní distributoři!</string>
|
||||
<string name="no_distributors_explanation">Pro příjem push notifikací potřebujete distributora.
|
||||
\nDalší podrobnosti najdete na %1$s.
|
||||
\n
|
||||
\nMůžete také ignorovat tuto zprávu tak, že push notifikace v nastavení vypnete.</string>
|
||||
<string name="select_distributors">Vybrat distributora</string>
|
||||
<string name="delete_cache">Vymazat cache</string>
|
||||
<string name="report_val_more3">Víte, že to porušuje určitá pravidla</string>
|
||||
<string name="types_of_notifications_to_display">Typy oznámení k zobrazení</string>
|
||||
<string name="types_of_notifications_to_display">Typy upozornění k zobrazení</string>
|
||||
<string name="also_boosted_by">Boostuje také:</string>
|
||||
<string name="admin_scope">Jsem moderátor</string>
|
||||
<string name="last_active">Naposledy aktivní</string>
|
||||
|
@ -592,13 +599,13 @@
|
|||
<string name="approved">Schváleno</string>
|
||||
<string name="set_single_topbar_title">Jediný panel akcí</string>
|
||||
<string name="message_has_been_sent">Zpráva byla odeslána!</string>
|
||||
<string name="poll_type">Typ hlasování:</string>
|
||||
<string name="poll_duration">Doba trvání hlasování:</string>
|
||||
<string name="poll_type">Typ ankety:</string>
|
||||
<string name="poll_duration">Doba trvání ankety:</string>
|
||||
<string name="most_recent">Nejnovější</string>
|
||||
<string name="filter">Filtr</string>
|
||||
<string name="icon_size">Velikosti ikon</string>
|
||||
<string name="toots_visibility_title">Výchozí viditelnost zpráv:</string>
|
||||
<string name="set_notifications_page">Počet oznámení na jedno nahrání</string>
|
||||
<string name="set_notifications_page">Počet upozornění na jedno nahrání</string>
|
||||
<string name="replace_reddit_host">Doména frontendu Redditu</string>
|
||||
<string name="hide_content">Skrýt obsah <</string>
|
||||
<string name="report_val2">Je to spam</string>
|
||||
|
@ -609,10 +616,10 @@
|
|||
<string name="about_mastodon">„Mastodon není jediný web jako Twitter nebo Facebook, je to síť tisíců komunit provozovaných různými organizacemi a jednotlivci, kteří poskytují bezproblémové zážitky se sociálními médii.“</string>
|
||||
<string name="notif_display_favourites">Oblíbené</string>
|
||||
<string name="notif_display_updates_from_people">Aktualizace od lidí</string>
|
||||
<string name="clear_all_notif">Vymazat všechna oznámení</string>
|
||||
<string name="mark_all_as_read">Označit všechna oznámení jako přečtená</string>
|
||||
<string name="clear_all_notif">Vymazat všechna upozornění</string>
|
||||
<string name="mark_all_as_read">Označit všechna upozornění jako přečtená</string>
|
||||
<string name="display_all_categories">Zobrazit všechny kategorie</string>
|
||||
<string name="delete_notification_all_warning">Opravdu chcete smazat všechna oznámení\? Nelze to vzít zpět.</string>
|
||||
<string name="delete_notification_all_warning">Opravdu chcete smazat všechna upozornění\? Nelze to vzít zpět.</string>
|
||||
<string name="delete_field_confirm">Opravdu chcete smazat toto pole\?</string>
|
||||
<string name="report_val4">Je to něco jiného</string>
|
||||
<string name="report_3_title">Která pravidla jsou porušována\?</string>
|
||||
|
@ -652,7 +659,7 @@
|
|||
<string name="my_account">Můj účet</string>
|
||||
<string name="clear_cache">Vymazat cache</string>
|
||||
<string name="release_notes">Poznámky k vydání</string>
|
||||
<string name="disable_notifications">Vypnout oznámení</string>
|
||||
<string name="disable_notifications">Vypnout upozornění</string>
|
||||
<string name="notifications_are">Během tohoto časového úseku</string>
|
||||
<string name="pref_theme_base">Základ tématu</string>
|
||||
<string name="origin_report">Původ nahlášeného účtu</string>
|
||||
|
@ -664,19 +671,19 @@
|
|||
<string name="data_export_settings_success">Nastavení byla úspěšně exportována</string>
|
||||
<string name="category_custom">Vlastní</string>
|
||||
<string name="report_val1">Nemám to rád(a)</string>
|
||||
<string name="boosted_by">Boostováno</string>
|
||||
<string name="favourited_by">Oblíbeno u</string>
|
||||
<string name="boosted_by">Boostoval(a)</string>
|
||||
<string name="favourited_by">Oblíbil(a) si</string>
|
||||
<string name="followers_only">Jen sledující</string>
|
||||
<string name="report_val3">Porušuje to pravidla serveru</string>
|
||||
<string name="report_more_additional">Doplňující komentáře</string>
|
||||
<string name="report_more_forward">Přeposlat na %1$s</string>
|
||||
<string name="notif_display_poll_results">Výsledky hlasování</string>
|
||||
<string name="report_sent">Report byl odeslán!</string>
|
||||
<string name="report_sent">Hlášení bylo odesláno!</string>
|
||||
<string name="interactions">Interakce</string>
|
||||
<string name="set_discoverable_content">Účet je objevitelný</string>
|
||||
<string name="type_of_notifications">Typ oznámení</string>
|
||||
<string name="type_of_notifications">Typ upozornění</string>
|
||||
<string name="pref_contributor">Témata od přispěvatelů</string>
|
||||
<string name="notification_sounds">Zvuky oznámení</string>
|
||||
<string name="notification_sounds">Zvuky upozornění</string>
|
||||
<string name="staff">Personál</string>
|
||||
<string name="my_app">Moje aplikace</string>
|
||||
<string name="msg_save_image">Opravdu chcete odejít bez uložení obrázku\?</string>
|
||||
|
@ -709,7 +716,7 @@
|
|||
<string name="profiled_updated">Profil byl aktualizován!</string>
|
||||
<string name="not_valid_list_name">Název seznamu není platný!</string>
|
||||
<string name="report_val_more1">To není něco, co chcete vidět</string>
|
||||
<string name="report_more_remote">Tento účet je z jiného serveru. Poslat mu také anonymizovanou kopii reportu\?</string>
|
||||
<string name="report_more_remote">Tento účet je z jiného serveru. Poslat mu také anonymizovanou kopii hlášení\?</string>
|
||||
<string name="dont_have_an_account">Nemáte účet\?</string>
|
||||
<string name="invite_join_the_fediverse">Ahoj! Zveme vás k připojení do Fediverse.</string>
|
||||
<string name="notif_display_mentions">Zmínky</string>
|
||||
|
@ -733,7 +740,7 @@
|
|||
<string name="instance_health_indication">verze: %s
|
||||
\n %s uživatelů - %s statusů</string>
|
||||
<string name="remove_status">Odebrat status</string>
|
||||
<string name="report_indication_title_status_more">Vybrat nejlepší shodu</string>
|
||||
<string name="report_indication_title_status_more">Vyberte nejlepší shodu</string>
|
||||
<string name="instance_health_checkedat">Zkontrolováno: %s</string>
|
||||
<string name="add_status">Přidat status</string>
|
||||
<string name="channel_notif_report">Nové hlášení</string>
|
||||
|
@ -752,9 +759,9 @@
|
|||
<string name="cached_messages">Cachované zprávy</string>
|
||||
<string name="select_a_theme">Vybrat téma</string>
|
||||
<string name="display_timelines">Zobrazit časové osy</string>
|
||||
<string name="type_of_notifications_title">Vybrat typy oznámení</string>
|
||||
<string name="type_of_notifications_title">Vybrat typy upozornění</string>
|
||||
<string name="notif_update_push">Sdílená zpráva byla upravena</string>
|
||||
<string name="messages_in_cache_for_other_timelines">Zprávy v cache o ostatní časové osy</string>
|
||||
<string name="messages_in_cache_for_other_timelines">Zprávy v cache pro ostatní časové osy</string>
|
||||
<string name="set_live_translate">Vynutit překlad do určitého jazyka. K resetu do výchozího nastavení vyberte první hodnotu</string>
|
||||
<string name="recent_ip">Poslední IP</string>
|
||||
<string name="allow">Povolit</string>
|
||||
|
@ -832,4 +839,87 @@
|
|||
<string name="delete_keyword">Smazat klíčové slovo</string>
|
||||
<string name="add_keyword">Přidat klíčové slovo</string>
|
||||
<string name="filtered_by">Filtrováno: %1$s</string>
|
||||
<string name="set_push_notifications_delay">Nastavit prodlevu před dalším načtením</string>
|
||||
<string name="aggregate_notifications_summary">Pokud je zapnuto, aplikace sbalí související upozornění</string>
|
||||
<string name="display_media_notification">V upozorněních zobrazovat média</string>
|
||||
<string name="display_media_notification_summary">Budou se zobrazovat média v upozorněních na reblogy a oblíbení</string>
|
||||
<string name="assign_to_me">Přiřazeno mně</string>
|
||||
<string name="unassign">Zrušit přiřazení</string>
|
||||
<string name="admin_domainblock_reject_media">Ignorovat všechna hlášení z této domény. Nerelevantní pro pozastavení</string>
|
||||
<string name="admin_domainblock_reject_reports">Ignorovat všechna hlášení přicházející z této domény. Nerelevantní pro pozastavení</string>
|
||||
<string name="admin_reject_obfuscate">Obfuskovat název domény</string>
|
||||
<string name="set_cardview">Vyvýšené karty</string>
|
||||
<string name="set_cardview_indication">Pokud je zapnuto, položky v časových osách budou mít stín a vyvýšení.</string>
|
||||
<string name="set_customize_light">Přizpůsobit světlé téma</string>
|
||||
<string name="set_custom_colors">Nastavit vlastní barvy</string>
|
||||
<string name="light_custom_colors">Světlé – vlastní barvy</string>
|
||||
<string name="set_customize_dark_indication">Umožňuje přizpůsobit tmavému barevnému tématu některé elementy ve zprávách.</string>
|
||||
<string name="notif_display_reblogs">Reblogy</string>
|
||||
<string name="pref_theme_base_summary">Zvolte, zda má být základ tématu tmavý nebo světlý</string>
|
||||
<string name="report_2_title">Existují nějaké příspěvky dokládající toto hlášení\?</string>
|
||||
<string name="action_announcement_from_to">Oznámení · %1$s - %2$s</string>
|
||||
<string name="set_timelines_in_a_list">Pokud je zapnuto, všechny připnuté časové osy se budou zobrazovat v rozbalovací nabídce</string>
|
||||
<string name="fetch_notifications">Načíst upozornění</string>
|
||||
<string name="pickup_logo">Vybrat logo</string>
|
||||
<string name="set_unlisted_replies_indication">Týká se jen „veřejných“ odpovědí. Pokud je zapnuto, vaše odpovědi budou mít automaticky „neuvedenou“ viditelnost namísto „veřejné“</string>
|
||||
<string name="notification_remove_from_cache">Upozornění byla odstraněna z cache.</string>
|
||||
<string name="custom_warning">Vlastní varování</string>
|
||||
<string name="list_reported_statuses">Hlášené statusy</string>
|
||||
<string name="account_unsuspended">Pozastavení účtu zrušeno</string>
|
||||
<string name="account_suspended">Účet pozastaven</string>
|
||||
<string name="action_lists_edit">Upravit seznam</string>
|
||||
<string name="filter_action">Akce filtru</string>
|
||||
<string name="notif_submitted_report">Poslal(a) hlášení</string>
|
||||
<string name="notif_reported">odeslal(a) hlášení</string>
|
||||
<string name="refresh_every">Načítat upozornění každých:</string>
|
||||
<string name="cark_custom_colors">Tmavé – vlastní barvy</string>
|
||||
<string name="aggregate_notifications">Agregovat upozornění</string>
|
||||
<string name="account_undisabled">Deaktivace účtu zrušena</string>
|
||||
<string name="keep_notifications">Zachovat upozornění</string>
|
||||
<string name="admin_domainblock_domain">Blokace domény nezabrání vytváření položek účtů v databázi, ale retroaktivně a automaticky na tyto účty aplikuje určité moderační metody.</string>
|
||||
<string name="set_customize_dark">Přizpůsobit tmavé téma</string>
|
||||
<string name="set_display_counters_description">Bude zobrazovat bublinové počitadlo pro nové zprávy u časových os</string>
|
||||
<string name="hide_with_warning_description">Skrýt filtrovaný obsah za varování zmiňující titulek filtru</string>
|
||||
<string name="hide_completely_description">Úplně skrýt filtrovaný obsah, jako kdyby neexistoval</string>
|
||||
<string name="pref_customize_summary">Umožňuje nastavit vaše vlastní barvy pro témata.</string>
|
||||
<string name="set_customize_light_indication">Umožňuje přizpůsobit světlému barevnému tématu některé elementy ve zprávách.</string>
|
||||
<string name="order_lists">Řadit seznamy</string>
|
||||
<string name="admin_reject_reports">Odmítat hlášení</string>
|
||||
<string name="admin_domainblock_reject_obfuscate">Částečně obfuskovat název domény v seznamu, pokud je zapnuto zveřejňování seznamu doménových omezení</string>
|
||||
<string name="type_of_notifications_delay_title">Čas načítání upozornění</string>
|
||||
<string name="set_single_topbar">Pokud je zapnuto, aplikace bude mít jen jeden panel pro časové osy</string>
|
||||
<string name="full_date_edited">%1$s upravil(a) %2$s</string>
|
||||
<string name="account_disabled">Účet deaktivován</string>
|
||||
<string name="report">Hlášení</string>
|
||||
<string name="notif_display_updates">Aktualizace</string>
|
||||
<string name="context_home_list">Domov a seznamy</string>
|
||||
<string name="toast_error_add_to_list">Aplikaci se nepovedlo přidat účet do seznamu!</string>
|
||||
<string name="notif_signed_up">Registroval(a) se</string>
|
||||
<string name="not_interested">Bez zájmu</string>
|
||||
<string name="set_notif_update">Upozornit na aktualizace</string>
|
||||
<string name="set_notif_user_sign_up">Nová registrace (moderátoři)</string>
|
||||
<string name="set_notif_admin_report">Nové hlášení (moderátoři)</string>
|
||||
<string name="reject_reports">Odmítat hlášení</string>
|
||||
<string name="admin_domainblock_public_comment">Komentář ohledně omezení této domény pro obecnou veřejnost, pokud je zapnuto zveřejňování seznamu doménových omezení.</string>
|
||||
<string name="admin_domainblock_private_comment">Komentář ohledně omezení této domény pro interní použití moderátory.</string>
|
||||
<string name="type_of_theme">Výběr režimu pro téma</string>
|
||||
<string name="set_language_picker">Umožňuje omezit seznam jazyků ve výběru při vytváření zprávy.</string>
|
||||
<string name="change_logo_description">Změnit logo aplikace na vašem zařízení</string>
|
||||
<string name="set_dynamic_color_indication">Přizpůsobuje tonalitu barevného schématu podle vaší osobní tapety.</string>
|
||||
<string name="messages_in_cache_for_home">Zprávy v cache pro domovskou časovou osu</string>
|
||||
<string name="push_distributors">Distributor pro push</string>
|
||||
<string name="notif_update">Upravil(a) zprávu</string>
|
||||
<string name="filter_action_explanations">Vyberte, kterou akci provést, pokud bude příspěvek vyhovovat filtru</string>
|
||||
<string name="pref_custom_theme_new_summary">Umožňuje vytvořit vaše vlastní téma</string>
|
||||
<string name="set_unlisted_replies">Odpovědi s neuvedenou viditelností</string>
|
||||
<string name="display_remote_conversation">Zobrazit vzdálenou konverzaci</string>
|
||||
<string name="toast_on_your_instance">Konverzace začala na vaší instanci!</string>
|
||||
<string name="toast_error_fetch_message">Aplikace nenašla vzdálenou zprávu.</string>
|
||||
<string name="pref_contributor_summary">Výběr z témat vytvořených přispěvateli</string>
|
||||
<string name="toast_try_later">Zkuste to prosím později znovu.</string>
|
||||
<string name="set_your_max_char_count">Nastavte svůj max. počet znaků</string>
|
||||
<string name="set_display_translate_indication">Vždy zobrazovat tlačítko překladu</string>
|
||||
<string name="pin_tag">Připnout tag</string>
|
||||
<string name="unfollow_tag">Nesledovat tag</string>
|
||||
<string name="unpin_tag">Odepnout tag</string>
|
||||
</resources>
|
|
@ -21,7 +21,6 @@
|
|||
<string name="poxy_password">Facal-faire</string>
|
||||
<string name="context_notification">Brathan</string>
|
||||
<string name="share">Co-roinn</string>
|
||||
<string name="account_created_message">" "</string>
|
||||
<string name="notif_display_mentions">Iomraidhean</string>
|
||||
<string name="notif_display_favourites">Annsachdan</string>
|
||||
<string name="yes">Tha</string>
|
||||
|
|
|
@ -903,4 +903,17 @@
|
|||
<string name="set_dynamic_color_indication">Segue a tonalidade do fondo de pantalla para axustar o esquema de cores.</string>
|
||||
<string name="type_default_theme_light">Decorado claro por defecto</string>
|
||||
<string name="type_default_theme_dark">Decorado escuro por defecto</string>
|
||||
<string name="set_customize_light">Personalizar Decorado Claro</string>
|
||||
<string name="set_customize_light_indication">Permite personalizar algúns elementos nas mensaxes para o decorado claro.</string>
|
||||
<string name="set_customize_dark_indication">Permite personalizar algúns elementos da mensaxe no decorado escuro.</string>
|
||||
<string name="set_custom_colors">Establecer cores</string>
|
||||
<string name="light_custom_colors">Claro - Cores personais</string>
|
||||
<string name="display_remote_conversation">Mostrar conversa remota</string>
|
||||
<string name="toast_try_later">Inténtao outra vez máis tarde.</string>
|
||||
<string name="toast_error_fetch_message">A app non atopa a mensaxe remota.</string>
|
||||
<string name="set_cardview_indication">Se o activas, os elementos nas cronoloxías terán unha sombra e elevación.</string>
|
||||
<string name="set_customize_dark">Personalizar Decorado Escuro</string>
|
||||
<string name="toast_on_your_instance">A conversa comezou na túa instancia!</string>
|
||||
<string name="cark_custom_colors">Escuro - Cores personais</string>
|
||||
<string name="set_cardview">Tarxetas elevadas</string>
|
||||
</resources>
|
|
@ -32,10 +32,10 @@
|
|||
<string name="text_size">Szöveg és ikon méret</string>
|
||||
<string name="next">Következő</string>
|
||||
<string name="previous">Előző</string>
|
||||
<string name="open_with">Megnyitás a következővel:</string>
|
||||
<string name="open_with">Megnyitás a következővel</string>
|
||||
<string name="validate">Jóváhagyás</string>
|
||||
<string name="media">Média</string>
|
||||
<string name="share_with">Megosztás a következővel:</string>
|
||||
<string name="share_with">Megosztás a következővel</string>
|
||||
<string name="shared_via">Megosztva a Fedilabon keresztül</string>
|
||||
<string name="replies">Válaszok</string>
|
||||
<string name="username">Felhasználónév</string>
|
||||
|
@ -207,8 +207,8 @@
|
|||
<string name="set_lock_account">Fiók zárolása</string>
|
||||
<string name="set_save_changes">Változások mentése</string>
|
||||
<string name="set_fit_preview">Előnézeti képek méretre szabása</string>
|
||||
<string name="settings_time_from">Kezdet:</string>
|
||||
<string name="settings_time_to">Befejezés:</string>
|
||||
<string name="settings_time_from">Kezdet</string>
|
||||
<string name="settings_time_to">Befejezés</string>
|
||||
<string name="embedded_browser">Beépített böngésző használata</string>
|
||||
<string name="custom_tabs">Egyéni lapok</string>
|
||||
<string name="expand_cw">cw automatikus kibontása</string>
|
||||
|
|
|
@ -208,7 +208,7 @@
|
|||
<string name="embedded_browser">내장 브라우저 사용</string>
|
||||
<string name="custom_tabs">커스텀 탭</string>
|
||||
<string name="expand_cw">CW를 자동으로 펼침</string>
|
||||
<string name="set_led_colour">LED 색 설정</string>
|
||||
<string name="set_led_colour">LED 색 설정:</string>
|
||||
<string-array name="led_colours">
|
||||
<item>파란색</item>
|
||||
<item>청록색</item>
|
||||
|
|
|
@ -582,19 +582,19 @@
|
|||
<string name="stop_recording">Stopp opptak</string>
|
||||
<string name="set_accounts_page">Antall kontoer per innlasting</string>
|
||||
<string name="category_music">Musikk</string>
|
||||
<string name="cannot_be_empty">Dette feltet må fylles ut.</string>
|
||||
<string name="cannot_be_empty">Dette feltet må fylles ut!</string>
|
||||
<string name="replace_twitter">Twitter</string>
|
||||
<string name="replace_youtube">YouTube</string>
|
||||
<string name="replace_twitter_host">Domene for Twitter-grenseflate</string>
|
||||
<string name="replace_instagram_description">Bruk en alternativ grenseflate for Instagram</string>
|
||||
<string name="other">Annet</string>
|
||||
<string name="add_status">Legg til status</string>
|
||||
<string name="is_up">Er oppe.</string>
|
||||
<string name="is_up">Er oppe!</string>
|
||||
<string name="instance_health_uptime">Oppetid: %,.2f %%</string>
|
||||
<string name="keepon">Fortsett</string>
|
||||
<string name="category_custom">Tilpasset</string>
|
||||
<string name="followers_only">Kun følgere</string>
|
||||
<string name="is_down">Er nede.</string>
|
||||
<string name="is_down">Er nede!</string>
|
||||
<string name="instance_health_checkedat">Sjekket: %s</string>
|
||||
<string name="report_1_mute_title">Forstum %1$s</string>
|
||||
<string name="report_1_block_title">Blokker %1$s</string>
|
||||
|
@ -604,7 +604,7 @@
|
|||
\n %s brukere - %s statuser</string>
|
||||
<string name="replace_youtube_description">Bruk en alternativ grenseflate for YouTube</string>
|
||||
<string name="replace_youtube_host">Domene for YouTube-grenseflate</string>
|
||||
<string name="instance_not_valid">Instansen ser ikke ut til å være gyldig.</string>
|
||||
<string name="instance_not_valid">Instansen ser ikke ut til å være gyldig!</string>
|
||||
<string name="boosted_by">Framhevet av</string>
|
||||
<string name="favourited_by">Favorittmerket av</string>
|
||||
<string name="eg_sensitive_content">F.eks: Sensitivt innhold</string>
|
||||
|
|
|
@ -313,10 +313,12 @@
|
|||
<string name="channel_notif_media">Baixar mídia</string>
|
||||
<string name="select_sound">Selecionar toque</string>
|
||||
<string name="set_enable_time_slot">Ativar definição de momento</string>
|
||||
<string name="block_domain_confirm_message">Tem certeza de que quer bloquear %s?\n\nSeus seguidores desta instância serão removidos, e você não verá nenhum conteúdo ou notificação desta instância.</string>
|
||||
<string name="block_domain_confirm_message">Tem certeza que deseja bloquear %s\?
|
||||
\n
|
||||
\nVocê não verá nenhum conteúdo dessa instância em nenhuma linha do tempo pública ou em suas notificações. Seus seguidores dessa instância serão removidos.</string>
|
||||
<string name="block_domain">Bloquear instância</string>
|
||||
<string name="toast_block_domain">Instância bloqueada!</string>
|
||||
<string name="retrieve_remote_status">Carregando toot remoto!</string>
|
||||
<string name="toast_block_domain">Instância bloqueada</string>
|
||||
<string name="retrieve_remote_status">Obtendo status remoto</string>
|
||||
<string name="peertube_instance">Instância Peertube</string>
|
||||
<string name="set_display_emoji">Usar Emoji One</string>
|
||||
<string name="information">Informação</string>
|
||||
|
@ -635,4 +637,5 @@
|
|||
<string name="report_indication_title_status">Diga-nos o que está havendo com este post</string>
|
||||
<string name="add_status">Adicionar status</string>
|
||||
<string name="post_message_text">Enviando mensagem %d/%d</string>
|
||||
<string name="channel_notif_update">Nova atualização</string>
|
||||
</resources>
|
|
@ -572,7 +572,7 @@
|
|||
<string name="action_unfollow">Отписаться</string>
|
||||
<string name="error_destination_path">Что-то пошло не так, пожалуйста, проверьте папку загрузок в настройках.</string>
|
||||
<string name="action_announcements">Объявления</string>
|
||||
<string name="no_announcements">Объявлений пока нет.</string>
|
||||
<string name="no_announcements">Объявлений пока нет!</string>
|
||||
<string name="add_reaction">Добавить реакцию</string>
|
||||
<string name="set_video_cache">Кэш видео в MB, ноль означает, нет кэша.</string>
|
||||
<string name="set_watermark">Водяные знаки</string>
|
||||
|
|
|
@ -532,7 +532,7 @@
|
|||
<string name="make_an_action">Faghe un\'atzione</string>
|
||||
<string name="translation">Tradutzione</string>
|
||||
<string name="text_color_title">Colore de su testu</string>
|
||||
<string name="text_color">Càmbia su colore de su testu in is ricuadros</string>
|
||||
<string name="text_color">Càmbia su colore de su testu in is messàgios</string>
|
||||
<string name="pref_custom_theme">Imprea unu tema personalizadu</string>
|
||||
<string name="theming">Temas</string>
|
||||
<string name="data_export_theme">As esportadu su tema</string>
|
||||
|
@ -901,4 +901,17 @@
|
|||
<string name="set_dynamic_color_indication">Allìnia tonalmente cun s\'ischema de colores de s\'isfundu personale tuo.</string>
|
||||
<string name="pref_customize_summary">Ti permitit de cunfigurare is colores personalizados tuos pro is temas.</string>
|
||||
<string name="type_default_theme_dark">Tema iscuru predefinidu</string>
|
||||
<string name="set_customize_dark">Personaliza su tema iscuru</string>
|
||||
<string name="set_custom_colors">Cunfigura colores personalizados</string>
|
||||
<string name="light_custom_colors">Craru - Colores personalizados</string>
|
||||
<string name="cark_custom_colors">Iscuru - Colores personalizados</string>
|
||||
<string name="toast_on_your_instance">S\'arresonada est incumintzada in s\'istàntzia tua!</string>
|
||||
<string name="set_customize_light">Personaliza su tema craru</string>
|
||||
<string name="set_cardview">Cartas elevadas</string>
|
||||
<string name="set_cardview_indication">Cando est abilitadu is elementos in is lìnias de tempus ant a tènnere un\'umbra e un\'artària.</string>
|
||||
<string name="set_customize_dark_indication">Permitit de personalizare unos cantos elementos in is messàgios pro su tema iscuru.</string>
|
||||
<string name="display_remote_conversation">Ammustra s\'arresonada remota</string>
|
||||
<string name="set_customize_light_indication">Permitit de personalizare unos cantos elementos in is messàgios pro su tema craru.</string>
|
||||
<string name="toast_try_later">Torra a proare prus a tardu.</string>
|
||||
<string name="toast_error_fetch_message">S\'aplicatzione no at agatadu su messàgiu remotu.</string>
|
||||
</resources>
|
|
@ -297,7 +297,7 @@
|
|||
<string name="filter_keyword_explanations">Srogość liter we tekście ani we upozorniyniu ô zawartości niy majōm znaczynio</string>
|
||||
<string name="context_drop">Ôdciep zamiast kryć</string>
|
||||
<string name="context_drop_explanations">Filtrowane tuty zniknōm doimyntnie, nawet jak filter bydzie wymazany</string>
|
||||
<string name="context_whole_word_explanations">Jak słowo kluczowe abo fraza sōm ino alfanumeryczne, to to bydzie użyte, jak bydzie pasować cołke słowo</string>
|
||||
<string name="context_whole_word_explanations">Jak słowo kluczowe abo fraza sōm ino alfanumeryczne, to bydzie użyte, jak bydzie pasować cołke słowo</string>
|
||||
<string name="context_whole_word">Cołke słowo</string>
|
||||
<string name="filter_context">Kōnteksty filtra</string>
|
||||
<string name="filter_context_explanations">Jedyn abo wiyncyj kōntekstōw, kaj filter winiyn być użyty</string>
|
||||
|
|
|
@ -534,7 +534,7 @@
|
|||
<string name="make_an_action">Bir eylem yap</string>
|
||||
<string name="translation">Çeviri</string>
|
||||
<string name="text_color_title">Metin rengi</string>
|
||||
<string name="text_color">İçeriklerdeki metin rengini değiştir</string>
|
||||
<string name="text_color">Mesajlardaki metin rengini değiştir</string>
|
||||
<string name="pref_custom_theme">Kişisel tema kullan</string>
|
||||
<string name="theming">Tema</string>
|
||||
<string name="data_export_theme">Tema dışa aktarıldı</string>
|
||||
|
@ -907,4 +907,23 @@
|
|||
<string name="type_default_theme_dark">Öntanımlı koyu tema</string>
|
||||
<string name="type_of_theme">Tema için bir mod seçin</string>
|
||||
<string name="set_dynamic_color_indication">Kişisel duvar kağıdınızın renk düzeniyle ton olarak uyum sağlayın.</string>
|
||||
<string name="set_cardview">Yükseltilmiş kartlar</string>
|
||||
<string name="set_custom_colors">Özel renkler ayarla</string>
|
||||
<string name="cark_custom_colors">Koyu - Özel renkler</string>
|
||||
<string name="set_cardview_indication">Etkinleştirildiğinde, zaman çizelgelerindeki ögelerin bir gölgesi ve bir yüksekliği olacaktır.</string>
|
||||
<string name="set_customize_dark_indication">Koyu tema için mesajlardaki bazı ögeleri özelleştirmeye izin verir.</string>
|
||||
<string name="set_customize_light">Açık Temayı Özelleştir</string>
|
||||
<string name="set_customize_light_indication">Açık tema için mesajlardaki bazı ögeleri özelleştirmeye izin verir.</string>
|
||||
<string name="set_customize_dark">Koyu Temayı Özelleştir</string>
|
||||
<string name="light_custom_colors">Açık - Özel renkler</string>
|
||||
<string name="display_remote_conversation">Uzak görüşmeyi göster</string>
|
||||
<string name="toast_on_your_instance">Görüşme sizin sunucunuzda başladı!</string>
|
||||
<string name="toast_try_later">Lütfen daha sonra tekrar deneyin.</string>
|
||||
<string name="toast_error_fetch_message">Uygulama uzak mesajı bulamadı.</string>
|
||||
<string name="mute_tag_action">Etiketi sessize al</string>
|
||||
<string name="unpin_tag">Etiketin sabitlemesini kaldır</string>
|
||||
<string name="set_display_translate_indication">Her zaman çevir düğmesini göster</string>
|
||||
<string name="unmute_tag_action">Etiketin sesini aç</string>
|
||||
<string name="pin_tag">Etiketi sabitle</string>
|
||||
<string name="unfollow_tag">Etiketi takibi bırak</string>
|
||||
</resources>
|
|
@ -527,7 +527,7 @@
|
|||
<string name="make_an_action">添加操作</string>
|
||||
<string name="translation">翻译</string>
|
||||
<string name="text_color_title">文本颜色</string>
|
||||
<string name="text_color">更改点的文本颜色</string>
|
||||
<string name="text_color">更改消息中文本的颜色</string>
|
||||
<string name="pref_custom_theme">使用自定义主题</string>
|
||||
<string name="theming">主题</string>
|
||||
<string name="data_export_theme">主题已导出</string>
|
||||
|
|
|
@ -1356,6 +1356,7 @@
|
|||
<string name="SET_FILTER_REGEX_PUBLIC" translatable="false">SET_FILTER_REGEX_PUBLIC</string>
|
||||
<string name="SET_NOTIF_VALIDATION" translatable="false">SET_NOTIF_VALIDATION</string>
|
||||
<string name="SET_DISPLAY_BOOKMARK" translatable="false">SET_DISPLAY_BOOKMARK</string>
|
||||
<string name="SET_DISPLAY_TRANSLATE" translatable="false">SET_DISPLAY_TRANSLATE</string>
|
||||
<string name="SET_NOTIF_VALIDATION_FAV" translatable="false">SET_NOTIF_VALIDATION_FAV</string>
|
||||
<string name="SET_DISPLAY_COUNTER_FAV_BOOST" translatable="false">SET_DISPLAY_COUNTER_FAV_BOOST</string>
|
||||
<string name="SET_INNER_MARKER" translatable="false">SET_INNER_MARKER</string>
|
||||
|
@ -1423,6 +1424,7 @@
|
|||
<string name="poll_type">Poll type:</string>
|
||||
<string name="poll_duration">Poll duration:</string>
|
||||
<string name="set_display_bookmark_indication">Always display bookmark button</string>
|
||||
<string name="set_display_translate_indication">Always display translate button</string>
|
||||
<string name="display">Display</string>
|
||||
<string name="bottom_menu">Bottom menu</string>
|
||||
<string name="top_menu">Top bar menu</string>
|
||||
|
@ -2048,4 +2050,13 @@
|
|||
<string name="set_custom_colors">Set custom colors</string>
|
||||
<string name="light_custom_colors">Light - Custom colors</string>
|
||||
<string name="cark_custom_colors">Dark - Custom colors</string>
|
||||
<string name="display_remote_conversation">Display remote conversation</string>
|
||||
<string name="toast_try_later">Please, try again later.</string>
|
||||
<string name="toast_on_your_instance">The conversation started on your instance!</string>
|
||||
<string name="toast_error_fetch_message">The app didn\'t find the remote message.</string>
|
||||
<string name="mute_tag_action">Mute tag</string>
|
||||
<string name="unmute_tag_action">Unmute tag</string>
|
||||
<string name="pin_tag">Pin tag</string>
|
||||
<string name="unpin_tag">Unpin tag</string>
|
||||
<string name="unfollow_tag">Unfollow tag</string>
|
||||
</resources>
|
|
@ -53,12 +53,14 @@
|
|||
app:icon="@drawable/ic_theming"
|
||||
app:key="@string/pref_category_key_theming" />
|
||||
|
||||
<!--
|
||||
<Preference
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:title="@string/administration"
|
||||
app:icon="@drawable/ic_admin"
|
||||
app:key="@string/pref_category_key_administration" />
|
||||
-->
|
||||
|
||||
<Preference
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -42,6 +42,13 @@
|
|||
app:singleLineTitle="false"
|
||||
app:title="@string/set_display_bookmark_indication" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/SET_DISPLAY_TRANSLATE"
|
||||
app:singleLineTitle="false"
|
||||
app:title="@string/set_display_translate_indication" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:defaultValue="true"
|
||||
app:iconSpaceReserved="false"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Added:
|
||||
- Display all messages in threads from remote instances (when possible)
|
||||
* Only public messages for instances using the Mastodon API
|
||||
* A dedicated button is displayed at the top right when conditions are filled.
|
11
src/fdroid/fastlane/metadata/android/en/changelogs/445.txt
Normal file
11
src/fdroid/fastlane/metadata/android/en/changelogs/445.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
Added:
|
||||
- Allow to unmute/unfollow/unpin a tag from tag timelines
|
||||
- Automatically add the tag when composing from a tag timeline
|
||||
- Add a translate button at the bottom of messages (default: disabled)
|
||||
- Add account role in profiles
|
||||
|
||||
Fixed:
|
||||
- Contact not working when composing
|
||||
- Status bar for black theme
|
||||
- Message duplicated in conversations when edited
|
||||
- Color issue on Android 5
|
18
src/fdroid/fastlane/metadata/android/en/changelogs/446.txt
Normal file
18
src/fdroid/fastlane/metadata/android/en/changelogs/446.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
Added:
|
||||
- Display all messages in threads from remote instances (when possible)
|
||||
- Allow to unmute/unfollow/unpin a tag from tag timelines
|
||||
- Display most used accounts in header menu for an easy switch
|
||||
- Automatically add the tag when composing from a tag timeline
|
||||
- Add a translate button at the bottom of messages (default: disabled)
|
||||
- Add account role in profiles
|
||||
- Translate morse
|
||||
|
||||
Changed:
|
||||
- Disable animations after a refresh
|
||||
|
||||
Fixed:
|
||||
- Contact not working when composing
|
||||
- Status bar for black theme
|
||||
- Message duplicated in conversations when edited
|
||||
- Color issue on Android 5
|
||||
- Several crashes
|
|
@ -0,0 +1,5 @@
|
|||
Nova versión de Fedilab con novas funcións.
|
||||
- Agora podes escribir fíos
|
||||
- Ver o fío completo ao responder
|
||||
- Soporte para caché
|
||||
- Novo deseño
|
1
src/fdroid/fastlane/metadata/android/gl/title.txt
Normal file
1
src/fdroid/fastlane/metadata/android/gl/title.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Fedilab
|
Loading…
Reference in a new issue