New settings (#891)
* change drawer items * rename SettingsActivity * introduce AccountSettings activity * improve account settings, move notification settings * sync settings with server * rename settings back to preferences * add functionality for settings * move mediaPreviewEnabled preference to AccountPreferences * replace shared prefs with accountmanager * move PreferencesFragment to support library * split preferences fragment into smaller fragments, merge AccountPreferencesActivity into PreferencesFragment * adjust icon size, add icons to general preferences * change mediaPreviewEnabled and alwaysShowSensitiveMedia pref position * add database migration * remove pullNotificationCheckInterval option * fix preference in TimelineFragment * Update Chinese translations. (#915) * Update zh-CN translations. * Update zh-SG translations. * Update zh-TW translations. * Update zh-MO translations. * Update zh-HK translations. * Fix errors in zh-CN translations. * Fix errors in zh-SG translations. * Fix errors in zh-TW translations. * Fix errors in zh-MO translations. * Fix errors in zh-HK translations.
This commit is contained in:
parent
5c88edf276
commit
70ca42c8b7
@ -74,6 +74,7 @@ dependencies {
|
||||
implementation "com.android.support:design:$supportLibraryVersion"
|
||||
implementation "com.android.support:exifinterface:$supportLibraryVersion"
|
||||
implementation "com.android.support:cardview-v7:$supportLibraryVersion"
|
||||
implementation "com.android.support:preference-v7:$supportLibraryVersion"
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
|
||||
implementation 'com.squareup.picasso:picasso:2.5.2'
|
||||
|
@ -52,7 +52,7 @@ public final class AccountListActivity extends BaseActivity implements HasSuppor
|
||||
return intent;
|
||||
}
|
||||
|
||||
enum Type {
|
||||
public enum Type {
|
||||
BLOCKS,
|
||||
MUTES,
|
||||
FOLLOW_REQUESTS,
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
package com.keylesspalace.tusky;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
@ -32,8 +31,6 @@ import android.util.TypedValue;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
@ -122,10 +119,6 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
|
||||
super.finish();
|
||||
}
|
||||
|
||||
protected SharedPreferences getPrivatePreferences() {
|
||||
return getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
protected void redirectIfNotLoggedIn() {
|
||||
AccountEntity account = accountManager.getActiveAccount();
|
||||
if (account == null) {
|
||||
@ -154,34 +147,6 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
protected void enablePushNotifications() {
|
||||
// schedule job to pull notifications
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
String minutesString = preferences.getString("pullNotificationCheckInterval", "15");
|
||||
long minutes = Long.valueOf(minutesString);
|
||||
if (minutes < 15) {
|
||||
preferences.edit().putString("pullNotificationCheckInterval", "15").apply();
|
||||
minutes = 15;
|
||||
}
|
||||
setPullNotificationCheckInterval(minutes);
|
||||
}
|
||||
|
||||
protected void disablePushNotifications() {
|
||||
// Cancel the repeating call for "pull" notifications.
|
||||
JobManager.instance().cancelAllForTag(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG);
|
||||
}
|
||||
|
||||
protected void setPullNotificationCheckInterval(long minutes) {
|
||||
long checkInterval = 1000 * 60 * minutes;
|
||||
|
||||
new JobRequest.Builder(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG)
|
||||
.setPeriodic(checkInterval)
|
||||
.setUpdateCurrent(true)
|
||||
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
|
||||
.build()
|
||||
.scheduleAsync();
|
||||
}
|
||||
|
||||
protected void showErrorDialog(View anyView, @StringRes int descriptionId, @StringRes int actionId, View.OnClickListener listener) {
|
||||
if (anyView != null) {
|
||||
Snackbar bar = Snackbar.make(anyView, getString(descriptionId), Snackbar.LENGTH_SHORT);
|
||||
|
@ -390,7 +390,7 @@ public final class ComposeActivity
|
||||
}
|
||||
photoUploadUri = savedInstanceState.getParcelable("photoUploadUri");
|
||||
} else {
|
||||
statusMarkSensitive = false;
|
||||
statusMarkSensitive = activeAccount.getDefaultMediaSensitivity();
|
||||
startingHideText = false;
|
||||
photoUploadUri = null;
|
||||
}
|
||||
@ -406,9 +406,7 @@ public final class ComposeActivity
|
||||
if (intent != null) {
|
||||
|
||||
if (startingVisibility == Status.Visibility.UNKNOWN) {
|
||||
Status.Visibility preferredVisibility = Status.Visibility.byString(
|
||||
preferences.getString("defaultPostPrivacy",
|
||||
Status.Visibility.PUBLIC.serverString()));
|
||||
Status.Visibility preferredVisibility = activeAccount.getDefaultPostPrivacy();
|
||||
Status.Visibility replyVisibility = Status.Visibility.byNum(
|
||||
intent.getIntExtra(REPLY_VISIBILITY_EXTRA, Status.Visibility.UNKNOWN.getNum()));
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
package com.keylesspalace.tusky;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.preference.DialogPreference;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
@ -25,9 +27,8 @@ import java.util.ArrayList;
|
||||
/**
|
||||
* This Preference lets the user select their preferred emoji font
|
||||
*/
|
||||
public class EmojiPreference extends DialogPreference {
|
||||
public class EmojiPreference extends Preference {
|
||||
private static final String TAG = "EmojiPreference";
|
||||
private final Context context;
|
||||
private EmojiCompatFont selected, original;
|
||||
static final String FONT_PREFERENCE = "selected_emoji_font";
|
||||
private static final EmojiCompatFont[] FONTS = EmojiCompatFont.FONTS;
|
||||
@ -42,13 +43,6 @@ public class EmojiPreference extends DialogPreference {
|
||||
|
||||
public EmojiPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.context = context;
|
||||
|
||||
setDialogLayoutResource(R.layout.dialog_emojicompat);
|
||||
|
||||
setPositiveButtonText(android.R.string.ok);
|
||||
setNegativeButtonText(android.R.string.cancel);
|
||||
setDialogIcon(null);
|
||||
|
||||
// Find out which font is currently active
|
||||
this.selected = EmojiCompatFont.byId(PreferenceManager
|
||||
@ -60,27 +54,31 @@ public class EmojiPreference extends DialogPreference {
|
||||
setSummary(selected.getDisplay(context));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
protected void onClick() {
|
||||
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_emojicompat, null);
|
||||
|
||||
for(int i = 0; i < viewIds.length; i++) {
|
||||
setupItem(view.findViewById(viewIds[i]), FONTS[i]);
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setView(view)
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> onDialogOk())
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void setupItem(View container, EmojiCompatFont font) {
|
||||
Context context = container.getContext();
|
||||
|
||||
TextView title = container.findViewById(R.id.emojicompat_name);
|
||||
TextView caption = container.findViewById(R.id.emojicompat_caption);
|
||||
ImageView thumb = container.findViewById(R.id.emojicompat_thumb);
|
||||
ImageButton download = container.findViewById(R.id.emojicompat_download);
|
||||
|
||||
ImageButton cancel = container.findViewById(R.id.emojicompat_download_cancel);
|
||||
|
||||
RadioButton radio = container.findViewById(R.id.emojicompat_radio);
|
||||
TextView title = container.findViewById(R.id.emojicompat_name);
|
||||
TextView caption = container.findViewById(R.id.emojicompat_caption);
|
||||
ImageView thumb = container.findViewById(R.id.emojicompat_thumb);
|
||||
ImageButton download = container.findViewById(R.id.emojicompat_download);
|
||||
ImageButton cancel = container.findViewById(R.id.emojicompat_download_cancel);
|
||||
RadioButton radio = container.findViewById(R.id.emojicompat_radio);
|
||||
|
||||
// Initialize all the views
|
||||
title.setText(font.getDisplay(context));
|
||||
@ -122,7 +120,7 @@ public class EmojiPreference extends DialogPreference {
|
||||
cancel.setVisibility(View.VISIBLE);
|
||||
|
||||
|
||||
font.downloadFont(context, new EmojiCompatFont.Downloader.EmojiDownloadListener() {
|
||||
font.downloadFont(getContext(), new EmojiCompatFont.Downloader.EmojiDownloadListener() {
|
||||
@Override
|
||||
public void onDownloaded(EmojiCompatFont font) {
|
||||
finishDownload(font, container);
|
||||
@ -194,7 +192,7 @@ public class EmojiPreference extends DialogPreference {
|
||||
cancel.setVisibility(View.GONE);
|
||||
caption.setVisibility(View.VISIBLE);
|
||||
|
||||
if(font.isDownloaded(context)) {
|
||||
if(font.isDownloaded(getContext())) {
|
||||
// Make it selectable
|
||||
download.setVisibility(View.GONE);
|
||||
radio.setVisibility(View.VISIBLE);
|
||||
@ -225,7 +223,7 @@ public class EmojiPreference extends DialogPreference {
|
||||
Log.i(TAG, "saveSelectedFont: Font ID: " + index);
|
||||
// It's saved using the key FONT_PREFERENCE
|
||||
PreferenceManager
|
||||
.getDefaultSharedPreferences(context)
|
||||
.getDefaultSharedPreferences(getContext())
|
||||
.edit()
|
||||
.putInt(FONT_PREFERENCE, index)
|
||||
.apply();
|
||||
@ -235,29 +233,26 @@ public class EmojiPreference extends DialogPreference {
|
||||
/**
|
||||
* That's it. The user doesn't want to switch between these amazing radio buttons anymore!
|
||||
* That means, the selected font can be saved (if the user hit OK)
|
||||
* @param positiveResult if OK has been selected.
|
||||
*/
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
if(positiveResult) {
|
||||
private void onDialogOk() {
|
||||
saveSelectedFont();
|
||||
if(selected != original) {
|
||||
new AlertDialog.Builder(context)
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.restart_required)
|
||||
.setMessage(R.string.restart_emoji)
|
||||
.setNegativeButton(R.string.later, null)
|
||||
.setPositiveButton(R.string.restart, ((dialog, which) -> {
|
||||
// Restart the app
|
||||
// From https://stackoverflow.com/a/17166729/5070653
|
||||
Intent launchIntent = new Intent(context, MainActivity.class);
|
||||
Intent launchIntent = new Intent(getContext(), SplashActivity.class);
|
||||
PendingIntent mPendingIntent = PendingIntent.getActivity(
|
||||
context,
|
||||
getContext(),
|
||||
// This is the codepoint of the party face emoji :D
|
||||
0x1f973,
|
||||
launchIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
AlarmManager mgr =
|
||||
(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
(AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
|
||||
if (mgr != null) {
|
||||
mgr.set(
|
||||
AlarmManager.RTC,
|
||||
@ -267,11 +262,7 @@ public class EmojiPreference extends DialogPreference {
|
||||
System.exit(0);
|
||||
})).show();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This line is needed in order to reset the radio buttons later
|
||||
selected = original;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.text.emoji.EmojiCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
@ -85,15 +84,14 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
|
||||
private static final long DRAWER_ITEM_ADD_ACCOUNT = -13;
|
||||
private static final long DRAWER_ITEM_EDIT_PROFILE = 0;
|
||||
private static final long DRAWER_ITEM_FAVOURITES = 1;
|
||||
private static final long DRAWER_ITEM_MUTED_USERS = 2;
|
||||
private static final long DRAWER_ITEM_BLOCKED_USERS = 3;
|
||||
private static final long DRAWER_ITEM_SEARCH = 4;
|
||||
private static final long DRAWER_ITEM_PREFERENCES = 5;
|
||||
private static final long DRAWER_ITEM_ABOUT = 6;
|
||||
private static final long DRAWER_ITEM_LOG_OUT = 7;
|
||||
private static final long DRAWER_ITEM_FOLLOW_REQUESTS = 8;
|
||||
private static final long DRAWER_ITEM_SAVED_TOOT = 9;
|
||||
private static final long DRAWER_ITEM_LISTS = 10;
|
||||
private static final long DRAWER_ITEM_LISTS = 2;
|
||||
private static final long DRAWER_ITEM_SEARCH = 3;
|
||||
private static final long DRAWER_ITEM_SAVED_TOOT = 4;
|
||||
private static final long DRAWER_ITEM_ACCOUNT_SETTINGS = 5;
|
||||
private static final long DRAWER_ITEM_SETTINGS = 6;
|
||||
private static final long DRAWER_ITEM_ABOUT = 7;
|
||||
private static final long DRAWER_ITEM_LOG_OUT = 8;
|
||||
private static final long DRAWER_ITEM_FOLLOW_REQUESTS = 9;
|
||||
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> fragmentInjector;
|
||||
@ -215,9 +213,9 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
|
||||
|
||||
// Setup push notifications
|
||||
if (NotificationHelper.areNotificationsEnabled(this, accountManager)) {
|
||||
enablePushNotifications();
|
||||
NotificationHelper.enablePullNotifications();
|
||||
} else {
|
||||
disablePushNotifications();
|
||||
NotificationHelper.disablePullNotifications();
|
||||
}
|
||||
|
||||
eventHub.getEvents()
|
||||
@ -311,22 +309,17 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
|
||||
}
|
||||
});
|
||||
|
||||
VectorDrawableCompat muteDrawable = VectorDrawableCompat.create(getResources(),
|
||||
R.drawable.ic_mute_24dp, getTheme());
|
||||
ThemeUtils.setDrawableTint(this, muteDrawable, R.attr.toolbar_icon_tint);
|
||||
|
||||
List<IDrawerItem> listItems = new ArrayList<>(11);
|
||||
List<IDrawerItem> listItems = new ArrayList<>(10);
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_EDIT_PROFILE).withName(R.string.action_edit_profile).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_person));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_FAVOURITES).withName(R.string.action_view_favourites).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_star));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_LISTS).withName(R.string.action_lists).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_list));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_MUTED_USERS).withName(R.string.action_view_mutes).withSelectable(false).withIcon(muteDrawable));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_BLOCKED_USERS).withName(R.string.action_view_blocks).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_block));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_SEARCH).withName(R.string.action_search).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_search));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_SAVED_TOOT).withName(R.string.action_access_saved_toot).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_save));
|
||||
listItems.add(new PrimaryDrawerItem().withIdentifier(DRAWER_ITEM_SAVED_TOOT).withName(R.string.action_access_saved_toot).withSelectable(false).withIcon(R.drawable.ic_notebook).withIconTintingEnabled(true));
|
||||
listItems.add(new DividerDrawerItem());
|
||||
listItems.add(new SecondaryDrawerItem().withIdentifier(DRAWER_ITEM_PREFERENCES).withName(R.string.action_view_preferences).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_settings));
|
||||
listItems.add(new SecondaryDrawerItem().withIdentifier(DRAWER_ITEM_ACCOUNT_SETTINGS).withName(R.string.action_view_account_preferences).withSelectable(false).withIcon(R.drawable.ic_account_settings).withIconTintingEnabled(true));
|
||||
listItems.add(new SecondaryDrawerItem().withIdentifier(DRAWER_ITEM_SETTINGS).withName(R.string.action_view_preferences).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_settings));
|
||||
listItems.add(new SecondaryDrawerItem().withIdentifier(DRAWER_ITEM_ABOUT).withName(R.string.about_title_activity).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_info));
|
||||
listItems.add(new SecondaryDrawerItem().withIdentifier(DRAWER_ITEM_LOG_OUT).withName(R.string.action_logout).withSelectable(false).withIcon(GoogleMaterial.Icon.gmd_exit_to_app));
|
||||
listItems.add(new SecondaryDrawerItem().withIdentifier(DRAWER_ITEM_LOG_OUT).withName(R.string.action_logout).withSelectable(false).withIcon(R.drawable.ic_logout).withIconTintingEnabled(true));
|
||||
|
||||
drawer = new DrawerBuilder()
|
||||
.withActivity(this)
|
||||
@ -344,19 +337,14 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_FAVOURITES) {
|
||||
Intent intent = new Intent(MainActivity.this, FavouritesActivity.class);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_MUTED_USERS) {
|
||||
Intent intent = new Intent(MainActivity.this, AccountListActivity.class);
|
||||
intent.putExtra("type", AccountListActivity.Type.MUTES);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_BLOCKED_USERS) {
|
||||
Intent intent = new Intent(MainActivity.this, AccountListActivity.class);
|
||||
intent.putExtra("type", AccountListActivity.Type.BLOCKS);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_SEARCH) {
|
||||
Intent intent = new Intent(MainActivity.this, SearchActivity.class);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_PREFERENCES) {
|
||||
Intent intent = new Intent(MainActivity.this, PreferencesActivity.class);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_ACCOUNT_SETTINGS) {
|
||||
Intent intent = PreferencesActivity.newIntent(MainActivity.this, PreferencesActivity.ACCOUNT_PREFERENCES);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_SETTINGS) {
|
||||
Intent intent = PreferencesActivity.newIntent(MainActivity.this, PreferencesActivity.GENERAL_PREFERENCES);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else if (drawerItemIdentifier == DRAWER_ITEM_ABOUT) {
|
||||
Intent intent = new Intent(MainActivity.this, AboutActivity.class);
|
||||
@ -444,8 +432,9 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
|
||||
|
||||
AccountEntity newAccount = accountManager.logActiveAccountOut();
|
||||
|
||||
if (!NotificationHelper.areNotificationsEnabled(MainActivity.this, accountManager))
|
||||
disablePushNotifications();
|
||||
if (!NotificationHelper.areNotificationsEnabled(MainActivity.this, accountManager)) {
|
||||
NotificationHelper.disablePullNotifications();
|
||||
}
|
||||
|
||||
Intent intent;
|
||||
if (newAccount == null) {
|
||||
|
@ -1,180 +0,0 @@
|
||||
/* Copyright 2017 Andrew Dawson
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.annotation.XmlRes;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.keylesspalace.tusky.fragment.PreferencesFragment;
|
||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||
|
||||
public class PreferencesActivity extends BaseActivity
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private boolean restartActivitiesOnExit;
|
||||
private @XmlRes int currentPreferences;
|
||||
private @StringRes int currentTitle;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState != null) {
|
||||
restartActivitiesOnExit = savedInstanceState.getBoolean("restart");
|
||||
} else {
|
||||
Bundle extras = getIntent().getExtras();
|
||||
restartActivitiesOnExit = extras != null && extras.getBoolean("restart");
|
||||
}
|
||||
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
setContentView(R.layout.activity_preferences);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
currentPreferences = R.xml.preferences;
|
||||
currentTitle = R.string.action_view_preferences;
|
||||
} else {
|
||||
currentPreferences = savedInstanceState.getInt("preferences");
|
||||
currentTitle = savedInstanceState.getInt("title");
|
||||
}
|
||||
showFragment(currentPreferences, currentTitle);
|
||||
|
||||
}
|
||||
|
||||
public void showFragment(@XmlRes int preferenceId, @StringRes int title) {
|
||||
|
||||
//TODO: cache the Fragments so they can be reused
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.fragment_container, PreferencesFragment.newInstance(preferenceId))
|
||||
.commit();
|
||||
|
||||
getFragmentManager().executePendingTransactions();
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setTitle(title);
|
||||
}
|
||||
|
||||
currentPreferences = preferenceId;
|
||||
currentTitle = title;
|
||||
}
|
||||
|
||||
private void saveInstanceState(Bundle outState) {
|
||||
outState.putBoolean("restart", restartActivitiesOnExit);
|
||||
outState.putInt("preferences", currentPreferences);
|
||||
outState.putInt("title", currentTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
saveInstanceState(outState);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
switch (key) {
|
||||
case "appTheme": {
|
||||
String theme = sharedPreferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT);
|
||||
Log.d("activeTheme", theme);
|
||||
ThemeUtils.setAppNightMode(theme, this);
|
||||
restartActivitiesOnExit = true;
|
||||
|
||||
// recreate() could be used instead, but it doesn't have an animation B).
|
||||
Intent intent = getIntent();
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
Bundle savedInstanceState = new Bundle();
|
||||
saveInstanceState(savedInstanceState);
|
||||
intent.putExtras(savedInstanceState);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
finish();
|
||||
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
|
||||
}
|
||||
case "statusTextSize": {
|
||||
restartActivitiesOnExit = true;
|
||||
break;
|
||||
}
|
||||
case "absoluteTimeView": {
|
||||
restartActivitiesOnExit = true;
|
||||
break;
|
||||
}
|
||||
case "notificationsEnabled": {
|
||||
boolean enabled = sharedPreferences.getBoolean("notificationsEnabled", true);
|
||||
if (enabled) {
|
||||
enablePushNotifications();
|
||||
} else {
|
||||
disablePushNotifications();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "pullNotificationCheckInterval": {
|
||||
String s = sharedPreferences.getString("pullNotificationCheckInterval", "15");
|
||||
long minutes = Long.valueOf(s);
|
||||
setPullNotificationCheckInterval(minutes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
//if we are not on the top level, show the top level. Else exit the activity
|
||||
if (currentPreferences != R.xml.preferences) {
|
||||
showFragment(R.xml.preferences, R.string.action_view_preferences);
|
||||
|
||||
} else {
|
||||
/* Switching themes won't actually change the theme of activities on the back stack.
|
||||
* Either the back stack activities need to all be recreated, or do the easier thing, which
|
||||
* is hijack the back button press and use it to launch a new MainActivity and clear the
|
||||
* back stack. */
|
||||
if (restartActivitiesOnExit) {
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivityWithSlideInAnimation(intent);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home: {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
186
app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt
Normal file
186
app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt
Normal file
@ -0,0 +1,186 @@
|
||||
/* Copyright 2018 Conny Duck
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.support.v4.app.Fragment
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
|
||||
import com.keylesspalace.tusky.fragment.preference.*
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.keylesspalace.tusky.util.getNonNullString
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.DispatchingAndroidInjector
|
||||
import dagger.android.support.HasSupportFragmentInjector
|
||||
import kotlinx.android.synthetic.main.toolbar_basic.*
|
||||
import java.lang.IllegalArgumentException
|
||||
import javax.inject.Inject
|
||||
|
||||
class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreferenceChangeListener, HasSupportFragmentInjector {
|
||||
|
||||
@Inject
|
||||
lateinit var eventHub: EventHub
|
||||
|
||||
@Inject
|
||||
lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>
|
||||
|
||||
private var restartActivitiesOnExit: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.activity_preferences)
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.run {
|
||||
setDisplayHomeAsUpEnabled(true)
|
||||
setDisplayShowHomeEnabled(true)
|
||||
}
|
||||
|
||||
val fragment: Fragment = when(intent.getIntExtra(EXTRA_PREFERENCE_TYPE, 0)) {
|
||||
GENERAL_PREFERENCES -> {
|
||||
setTitle(R.string.action_view_preferences)
|
||||
PreferencesFragment.newInstance()
|
||||
}
|
||||
ACCOUNT_PREFERENCES -> {
|
||||
setTitle(R.string.action_view_account_preferences)
|
||||
AccountPreferencesFragment.newInstance()
|
||||
}
|
||||
NOTIFICATION_PREFERENCES -> {
|
||||
setTitle(R.string.pref_title_edit_notification_settings)
|
||||
NotificationPreferencesFragment.newInstance()
|
||||
}
|
||||
TAB_FILTER_PREFERENCES -> {
|
||||
setTitle(R.string.pref_title_status_tabs)
|
||||
TabFilterPreferencesFragment.newInstance()
|
||||
}
|
||||
PROXY_PREFERENCES -> {
|
||||
setTitle(R.string.pref_title_http_proxy_settings)
|
||||
ProxyPreferencesFragment.newInstance()
|
||||
}
|
||||
else -> throw IllegalArgumentException("preferenceType not known")
|
||||
}
|
||||
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, fragment)
|
||||
.commit()
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun saveInstanceState(outState: Bundle) {
|
||||
outState.putBoolean("restart", restartActivitiesOnExit)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
outState.putBoolean("restart", restartActivitiesOnExit)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
when (key) {
|
||||
"appTheme" -> {
|
||||
val theme = sharedPreferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT)
|
||||
Log.d("activeTheme", theme)
|
||||
ThemeUtils.setAppNightMode(theme!!, this)
|
||||
restartActivitiesOnExit = true
|
||||
|
||||
// recreate() could be used instead, but it doesn't have an animation B).
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val savedInstanceState = Bundle()
|
||||
saveInstanceState(savedInstanceState)
|
||||
intent.putExtras(savedInstanceState)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
finish()
|
||||
overridePendingTransition(R.anim.fade_in, R.anim.fade_out)
|
||||
|
||||
restartActivitiesOnExit = true
|
||||
|
||||
}
|
||||
"statusTextSize" -> {
|
||||
restartActivitiesOnExit = true
|
||||
}
|
||||
"absoluteTimeView" -> {
|
||||
restartActivitiesOnExit = true
|
||||
}
|
||||
}
|
||||
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
}
|
||||
|
||||
|
||||
override fun onBackPressed() {
|
||||
/* Switching themes won't actually change the theme of activities on the back stack.
|
||||
* Either the back stack activities need to all be recreated, or do the easier thing, which
|
||||
* is hijack the back button press and use it to launch a new MainActivity and clear the
|
||||
* back stack. */
|
||||
if (restartActivitiesOnExit) {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
|
||||
return fragmentInjector
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val GENERAL_PREFERENCES = 0
|
||||
const val ACCOUNT_PREFERENCES = 1
|
||||
const val NOTIFICATION_PREFERENCES = 2
|
||||
const val TAB_FILTER_PREFERENCES = 3
|
||||
const val PROXY_PREFERENCES = 4
|
||||
private const val EXTRA_PREFERENCE_TYPE = "EXTRA_PREFERENCE_TYPE"
|
||||
|
||||
@JvmStatic
|
||||
fun newIntent(context: Context, preferenceType: Int): Intent {
|
||||
val intent = Intent(context, PreferencesActivity::class.java)
|
||||
intent.putExtra(EXTRA_PREFERENCE_TYPE, preferenceType)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -20,9 +20,7 @@ import android.app.Application;
|
||||
import android.app.Service;
|
||||
import android.arch.persistence.room.Room;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.text.emoji.EmojiCompat;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
@ -31,6 +29,7 @@ import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.db.AppDatabase;
|
||||
import com.keylesspalace.tusky.di.AppInjector;
|
||||
import com.keylesspalace.tusky.util.EmojiCompatFont;
|
||||
import com.keylesspalace.tusky.util.NotificationPullJobCreator;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -59,10 +58,6 @@ public class TuskyApplication extends Application implements HasActivityInjector
|
||||
|
||||
private ServiceLocator serviceLocator;
|
||||
|
||||
public static TuskyApplication getInstance(@NonNull Context context) {
|
||||
return (TuskyApplication) context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
@ -70,7 +65,8 @@ public class TuskyApplication extends Application implements HasActivityInjector
|
||||
appDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "tuskyDB")
|
||||
.allowMainThreadQueries()
|
||||
.addMigrations(AppDatabase.MIGRATION_2_3, AppDatabase.MIGRATION_3_4, AppDatabase.MIGRATION_4_5,
|
||||
AppDatabase.MIGRATION_5_6, AppDatabase.MIGRATION_6_7, AppDatabase.MIGRATION_7_8, AppDatabase.MIGRATION_8_9)
|
||||
AppDatabase.MIGRATION_5_6, AppDatabase.MIGRATION_6_7, AppDatabase.MIGRATION_7_8,
|
||||
AppDatabase.MIGRATION_8_9, AppDatabase.MIGRATION_9_10)
|
||||
.build();
|
||||
accountManager = new AccountManager(appDatabase);
|
||||
serviceLocator = new ServiceLocator() {
|
||||
|
@ -10,4 +10,5 @@ data class BlockEvent(val accountId: String) : Dispatchable
|
||||
data class MuteEvent(val accountId: String) : Dispatchable
|
||||
data class StatusDeletedEvent(val statusId: String) : Dispatchable
|
||||
data class StatusComposedEvent(val status: Status) : Dispatchable
|
||||
data class ProfileEditedEvent(val newProfileData: Account) : Dispatchable
|
||||
data class ProfileEditedEvent(val newProfileData: Account) : Dispatchable
|
||||
data class PreferenceChangedEvent(val preferenceKey: String) : Dispatchable
|
@ -21,6 +21,7 @@ import android.arch.persistence.room.PrimaryKey
|
||||
import android.arch.persistence.room.TypeConverters
|
||||
|
||||
import com.keylesspalace.tusky.entity.Emoji
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
|
||||
@Entity(indices = [Index(value = ["domain", "accountId"],
|
||||
unique = true)])
|
||||
@ -41,6 +42,10 @@ data class AccountEntity(@field:PrimaryKey(autoGenerate = true) var id: Long,
|
||||
var notificationSound: Boolean = true,
|
||||
var notificationVibration: Boolean = true,
|
||||
var notificationLight: Boolean = true,
|
||||
var defaultPostPrivacy: Status.Visibility = Status.Visibility.PUBLIC,
|
||||
var defaultMediaSensitivity: Boolean = false,
|
||||
var alwaysShowSensitiveMedia: Boolean = false,
|
||||
var mediaPreviewEnabled: Boolean = true,
|
||||
var lastNotificationId: String = "0",
|
||||
var activeNotifications: String = "[]",
|
||||
var emojis: List<Emoji> = emptyList()) {
|
||||
|
@ -17,6 +17,7 @@ package com.keylesspalace.tusky.db
|
||||
|
||||
import android.util.Log
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
|
||||
/**
|
||||
* This class caches the account database and handles all account related operations
|
||||
@ -111,6 +112,8 @@ class AccountManager(db: AppDatabase) {
|
||||
it.username = account.username
|
||||
it.displayName = account.name
|
||||
it.profilePictureUrl = account.avatar
|
||||
it.defaultPostPrivacy = account.source?.privacy ?: Status.Visibility.PUBLIC
|
||||
it.defaultMediaSensitivity = account.source?.sensitive ?: false
|
||||
it.emojis = account.emojis ?: emptyList()
|
||||
|
||||
Log.d(TAG, "updateActiveAccount: saving account with id " + it.id)
|
||||
|
@ -25,7 +25,7 @@ import android.support.annotation.NonNull;
|
||||
* DB version & declare DAO
|
||||
*/
|
||||
|
||||
@Database(entities = {TootEntity.class, AccountEntity.class, InstanceEntity.class}, version = 9, exportSchema = false)
|
||||
@Database(entities = {TootEntity.class, AccountEntity.class, InstanceEntity.class}, version = 10, exportSchema = false)
|
||||
public abstract class AppDatabase extends RoomDatabase {
|
||||
|
||||
public abstract TootDao tootDao();
|
||||
@ -105,4 +105,15 @@ public abstract class AppDatabase extends RoomDatabase {
|
||||
database.execSQL("ALTER TABLE `TootEntity` ADD COLUMN `descriptions` TEXT DEFAULT '[]'");
|
||||
}
|
||||
};
|
||||
|
||||
public static final Migration MIGRATION_9_10 = new Migration(9, 10) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `defaultPostPrivacy` INTEGER NOT NULL DEFAULT 1");
|
||||
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `defaultMediaSensitivity` INTEGER NOT NULL DEFAULT 0");
|
||||
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `alwaysShowSensitiveMedia` INTEGER NOT NULL DEFAULT 0");
|
||||
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `mediaPreviewEnabled` INTEGER NOT NULL DEFAULT '1'");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ import android.arch.persistence.room.TypeConverter
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.keylesspalace.tusky.entity.Emoji
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
|
||||
class Converters {
|
||||
|
||||
@ -33,4 +34,14 @@ class Converters {
|
||||
fun emojiListToJson(emojiList: List<Emoji>?): String {
|
||||
return gson.toJson(emojiList)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun visibilityToInt(visibility: Status.Visibility): Int {
|
||||
return visibility.num
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun intToVisibility(visibility: Int): Status.Visibility {
|
||||
return Status.Visibility.byNum(visibility)
|
||||
}
|
||||
}
|
@ -77,8 +77,8 @@ abstract class ActivitiesModule {
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesSavedTootActivity(): SavedTootActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesSPreferencesActivity(): PreferencesActivity
|
||||
@ContributesAndroidInjector(modules = [FragmentBuildersModule::class])
|
||||
abstract fun contributesPreferencesActivity(): PreferencesActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesViewMediaActivity(): ViewMediaActivity
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.keylesspalace.tusky.di
|
||||
|
||||
import com.keylesspalace.tusky.fragment.*
|
||||
import com.keylesspalace.tusky.fragment.preference.*
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
|
||||
@ -43,4 +44,11 @@ abstract class FragmentBuildersModule {
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun searchFragment(): SearchFragment
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun notificationPreferencesFragment(): NotificationPreferencesFragment
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun accountPreferencesFragment(): AccountPreferencesFragment
|
||||
|
||||
}
|
@ -47,6 +47,7 @@ import com.keylesspalace.tusky.adapter.NotificationsAdapter;
|
||||
import com.keylesspalace.tusky.appstore.BlockEvent;
|
||||
import com.keylesspalace.tusky.appstore.EventHub;
|
||||
import com.keylesspalace.tusky.appstore.FavoriteEvent;
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent;
|
||||
import com.keylesspalace.tusky.appstore.ReblogEvent;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
@ -87,7 +88,6 @@ public class NotificationsFragment extends SFragment implements
|
||||
SwipeRefreshLayout.OnRefreshListener,
|
||||
StatusActionListener,
|
||||
NotificationsAdapter.NotificationActionListener,
|
||||
SharedPreferences.OnSharedPreferenceChangeListener,
|
||||
Injectable {
|
||||
private static final String TAG = "NotificationF"; // logging tag
|
||||
|
||||
@ -194,10 +194,9 @@ public class NotificationsFragment extends SFragment implements
|
||||
recyclerView.addItemDecoration(divider);
|
||||
|
||||
adapter = new NotificationsAdapter(this, this);
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(
|
||||
getActivity());
|
||||
alwaysShowSensitiveMedia = preferences.getBoolean("alwaysShowSensitiveMedia", false);
|
||||
boolean mediaPreviewEnabled = preferences.getBoolean("mediaPreviewEnabled", true);
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
|
||||
boolean mediaPreviewEnabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
|
||||
adapter.setMediaPreviewEnabled(mediaPreviewEnabled);
|
||||
boolean useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false);
|
||||
adapter.setUseAbsoluteTime(useAbsoluteTime);
|
||||
@ -273,7 +272,6 @@ public class NotificationsFragment extends SFragment implements
|
||||
* Use a modified scroll listener that both loads more notificationsEnabled as it goes, and hides
|
||||
* the compose button on down-scroll. */
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
hideFab = preferences.getBoolean("fabHide", false);
|
||||
scrollListener = new EndlessOnScrollListener(layoutManager) {
|
||||
@Override
|
||||
@ -314,6 +312,8 @@ public class NotificationsFragment extends SFragment implements
|
||||
handleReblogEvent((ReblogEvent) event);
|
||||
} else if (event instanceof BlockEvent) {
|
||||
removeAllByAccountId(((BlockEvent) event).getAccountId());
|
||||
} else if (event instanceof PreferenceChangedEvent) {
|
||||
onPreferenceChanged(((PreferenceChangedEvent) event).getPreferenceKey());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -564,15 +564,14 @@ public class NotificationsFragment extends SFragment implements
|
||||
Log.w(TAG, "Didn't find a notification for ID: " + notificationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
public void onPreferenceChanged(String key) {
|
||||
switch (key) {
|
||||
case "fabHide": {
|
||||
hideFab = sharedPreferences.getBoolean("fabHide", false);
|
||||
hideFab = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("fabHide", false);
|
||||
break;
|
||||
}
|
||||
case "mediaPreviewEnabled": {
|
||||
boolean enabled = sharedPreferences.getBoolean("mediaPreviewEnabled", true);
|
||||
boolean enabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
|
||||
if (enabled != adapter.isMediaPreviewEnabled()) {
|
||||
adapter.setMediaPreviewEnabled(enabled);
|
||||
fullyRefresh();
|
||||
|
@ -1,303 +0,0 @@
|
||||
/* Copyright 2017 Andrew Dawson
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.fragment;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.support.annotation.XmlRes;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
|
||||
import com.keylesspalace.tusky.BuildConfig;
|
||||
import com.keylesspalace.tusky.PreferencesActivity;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.TuskyApplication;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PreferencesFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
SharedPreferences sharedPreferences;
|
||||
static boolean httpProxyChanged = false;
|
||||
static boolean pendingRestart = false;
|
||||
|
||||
public static PreferencesFragment newInstance(@XmlRes int preference) {
|
||||
PreferencesFragment fragment = new PreferencesFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("preference", preference);
|
||||
|
||||
fragment.setArguments(args);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private AccountManager accountManager;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
accountManager = TuskyApplication.getInstance(getActivity()).getServiceLocator()
|
||||
.get(AccountManager.class);
|
||||
|
||||
|
||||
int preference = getArguments().getInt("preference");
|
||||
|
||||
addPreferencesFromResource(preference);
|
||||
|
||||
Preference regexPref = findPreference("tabFilterRegex");
|
||||
if (regexPref != null) regexPref.setOnPreferenceClickListener(pref -> {
|
||||
// Reset the error dialog when shown; if the dialog was closed with the cancel button
|
||||
// while an invalid regex was present, this would otherwise cause buggy behaviour.
|
||||
((EditTextPreference) regexPref).getEditText().setError(null);
|
||||
|
||||
// Test the regex as the user inputs text, ensuring immediate feedback and preventing
|
||||
// setting of an invalid regex, which would cause a crash loop.
|
||||
((EditTextPreference) regexPref).getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
try {
|
||||
Pattern.compile(s.toString());
|
||||
((EditTextPreference) regexPref).getEditText().setError(null);
|
||||
AlertDialog dialog = (AlertDialog) ((EditTextPreference) pref).getDialog();
|
||||
if (dialog != null) dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
|
||||
} catch (IllegalArgumentException e) {
|
||||
((AlertDialog) ((EditTextPreference) pref).getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||
((EditTextPreference) regexPref).getEditText().setError(getString(R.string.error_invalid_regex));
|
||||
}
|
||||
}
|
||||
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
Preference notificationPreferences = findPreference("notificationPreferences");
|
||||
|
||||
if (notificationPreferences != null) {
|
||||
|
||||
AccountEntity activeAccount = accountManager.getActiveAccount();
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O && activeAccount != null) {
|
||||
notificationPreferences.setSummary(getString(R.string.pref_summary_notifications, activeAccount.getFullName()));
|
||||
}
|
||||
|
||||
|
||||
//on Android O and newer, launch the system notification settings instead of the app settings
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
|
||||
notificationPreferences.setOnPreferenceClickListener(pref -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
|
||||
|
||||
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID);
|
||||
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
} else {
|
||||
notificationPreferences.setOnPreferenceClickListener(pref -> {
|
||||
PreferencesActivity activity = (PreferencesActivity) getActivity();
|
||||
if (activity != null) {
|
||||
activity.showFragment(R.xml.notification_preferences, R.string.pref_title_edit_notification_settings);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Preference timelineFilterPreferences = findPreference("timelineFilterPreferences");
|
||||
if (timelineFilterPreferences != null) {
|
||||
timelineFilterPreferences.setOnPreferenceClickListener(pref -> {
|
||||
PreferencesActivity activity = (PreferencesActivity) getActivity();
|
||||
if (activity != null) {
|
||||
activity.showFragment(R.xml.timeline_filter_preferences, R.string.pref_title_status_tabs);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
Preference httpProxyPreferences = findPreference("httpProxyPreferences");
|
||||
if (httpProxyPreferences != null) {
|
||||
httpProxyPreferences.setOnPreferenceClickListener(pref -> {
|
||||
PreferencesActivity activity = (PreferencesActivity) getActivity();
|
||||
if (activity != null) {
|
||||
pendingRestart = false;
|
||||
activity.showFragment(R.xml.http_proxy_preferences, R.string.pref_title_http_proxy_settings);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (preference == R.xml.notification_preferences) {
|
||||
|
||||
AccountEntity activeAccount = accountManager.getActiveAccount();
|
||||
|
||||
if (activeAccount != null) {
|
||||
|
||||
CheckBoxPreference notificationPref = (CheckBoxPreference) findPreference("notificationsEnabled");
|
||||
notificationPref.setChecked(activeAccount.getNotificationsEnabled());
|
||||
|
||||
CheckBoxPreference mentionedPref = (CheckBoxPreference) findPreference("notificationFilterMentions");
|
||||
mentionedPref.setChecked(activeAccount.getNotificationsMentioned());
|
||||
|
||||
CheckBoxPreference followedPref = (CheckBoxPreference) findPreference("notificationFilterFollows");
|
||||
followedPref.setChecked(activeAccount.getNotificationsFollowed());
|
||||
|
||||
CheckBoxPreference boostedPref = (CheckBoxPreference) findPreference("notificationFilterReblogs");
|
||||
boostedPref.setChecked(activeAccount.getNotificationsReblogged());
|
||||
|
||||
CheckBoxPreference favoritedPref = (CheckBoxPreference) findPreference("notificationFilterFavourites");
|
||||
favoritedPref.setChecked(activeAccount.getNotificationsFavorited());
|
||||
|
||||
CheckBoxPreference soundPref = (CheckBoxPreference) findPreference("notificationAlertSound");
|
||||
soundPref.setChecked(activeAccount.getNotificationSound());
|
||||
|
||||
CheckBoxPreference vibrationPref = (CheckBoxPreference) findPreference("notificationAlertVibrate");
|
||||
vibrationPref.setChecked(activeAccount.getNotificationVibration());
|
||||
|
||||
CheckBoxPreference lightPref = (CheckBoxPreference) findPreference("notificationAlertLight");
|
||||
lightPref.setChecked(activeAccount.getNotificationLight());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
sharedPreferences = getPreferenceManager().getSharedPreferences();
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
updateSummary("httpProxyServer");
|
||||
updateSummary("httpProxyPort");
|
||||
updateHttpProxySummary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onPause();
|
||||
if (pendingRestart) {
|
||||
pendingRestart = false;
|
||||
httpProxyChanged = false;
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
||||
String key) {
|
||||
|
||||
switch (key) {
|
||||
case "httpProxyServer":
|
||||
case "httpProxyPort":
|
||||
updateSummary(key);
|
||||
case "httpProxyEnabled":
|
||||
httpProxyChanged = true;
|
||||
return;
|
||||
default:
|
||||
}
|
||||
|
||||
AccountEntity activeAccount = accountManager.getActiveAccount();
|
||||
|
||||
if (activeAccount != null) {
|
||||
switch (key) {
|
||||
case "notificationsEnabled":
|
||||
activeAccount.setNotificationsEnabled(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationFilterMentions":
|
||||
activeAccount.setNotificationsMentioned(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationFilterFollows":
|
||||
activeAccount.setNotificationsFollowed(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationFilterReblogs":
|
||||
activeAccount.setNotificationsReblogged(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationFilterFavourites":
|
||||
activeAccount.setNotificationsFavorited(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationAlertSound":
|
||||
activeAccount.setNotificationSound(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationAlertVibrate":
|
||||
activeAccount.setNotificationVibration(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
case "notificationAlertLight":
|
||||
activeAccount.setNotificationLight(sharedPreferences.getBoolean(key, true));
|
||||
break;
|
||||
}
|
||||
accountManager.saveAccount(activeAccount);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateSummary(String key) {
|
||||
switch (key) {
|
||||
case "httpProxyServer":
|
||||
case "httpProxyPort":
|
||||
EditTextPreference editTextPreference = (EditTextPreference) findPreference(key);
|
||||
if (editTextPreference != null) {
|
||||
editTextPreference.setSummary(editTextPreference.getText());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHttpProxySummary() {
|
||||
Preference httpProxyPref = findPreference("httpProxyPreferences");
|
||||
if (httpProxyPref != null) {
|
||||
if (httpProxyChanged) {
|
||||
pendingRestart = true;
|
||||
}
|
||||
|
||||
Boolean httpProxyEnabled = sharedPreferences.getBoolean("httpProxyEnabled", false);
|
||||
|
||||
String httpServer = sharedPreferences.getString("httpProxyServer", "");
|
||||
|
||||
try {
|
||||
int httpPort = Integer.parseInt(sharedPreferences.getString("httpProxyPort", "-1"));
|
||||
|
||||
if (httpProxyEnabled && !httpServer.isEmpty() && (httpPort > 0 && httpPort < 65535)) {
|
||||
httpProxyPref.setSummary(httpServer + ":" + httpPort);
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// user has entered wrong port, fall back to empty summary
|
||||
}
|
||||
|
||||
httpProxyPref.setSummary("");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -50,10 +50,12 @@ import com.keylesspalace.tusky.appstore.BlockEvent;
|
||||
import com.keylesspalace.tusky.appstore.EventHub;
|
||||
import com.keylesspalace.tusky.appstore.FavoriteEvent;
|
||||
import com.keylesspalace.tusky.appstore.MuteEvent;
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent;
|
||||
import com.keylesspalace.tusky.appstore.ReblogEvent;
|
||||
import com.keylesspalace.tusky.appstore.StatusComposedEvent;
|
||||
import com.keylesspalace.tusky.appstore.StatusDeletedEvent;
|
||||
import com.keylesspalace.tusky.appstore.UnfollowEvent;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.interfaces.ActionButtonActivity;
|
||||
@ -90,7 +92,6 @@ import static com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvid
|
||||
public class TimelineFragment extends SFragment implements
|
||||
SwipeRefreshLayout.OnRefreshListener,
|
||||
StatusActionListener,
|
||||
SharedPreferences.OnSharedPreferenceChangeListener,
|
||||
Injectable {
|
||||
private static final String TAG = "TimelineF"; // logging tag
|
||||
private static final String KIND_ARG = "kind";
|
||||
@ -119,6 +120,9 @@ public class TimelineFragment extends SFragment implements
|
||||
public TimelineCases timelineCases;
|
||||
@Inject
|
||||
public EventHub eventHub;
|
||||
@Inject
|
||||
public AccountManager accountManager;
|
||||
|
||||
private boolean eventRegistered = false;
|
||||
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
@ -244,9 +248,8 @@ public class TimelineFragment extends SFragment implements
|
||||
|
||||
private void setupTimelinePreferences() {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
alwaysShowSensitiveMedia = preferences.getBoolean("alwaysShowSensitiveMedia", false);
|
||||
boolean mediaPreviewEnabled = preferences.getBoolean("mediaPreviewEnabled", true);
|
||||
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
|
||||
boolean mediaPreviewEnabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
|
||||
adapter.setMediaPreviewEnabled(mediaPreviewEnabled);
|
||||
boolean useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false);
|
||||
adapter.setUseAbsoluteTime(useAbsoluteTime);
|
||||
@ -413,6 +416,8 @@ public class TimelineFragment extends SFragment implements
|
||||
} else if (event instanceof StatusComposedEvent) {
|
||||
Status status = ((StatusComposedEvent) event).getStatus();
|
||||
handleStatusComposeEvent(status);
|
||||
} else if (event instanceof PreferenceChangedEvent) {
|
||||
onPreferenceChanged(((PreferenceChangedEvent) event).getPreferenceKey());
|
||||
}
|
||||
});
|
||||
eventRegistered = true;
|
||||
@ -630,15 +635,15 @@ public class TimelineFragment extends SFragment implements
|
||||
super.viewAccount(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
private void onPreferenceChanged(String key) {
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
switch (key) {
|
||||
case "fabHide": {
|
||||
hideFab = sharedPreferences.getBoolean("fabHide", false);
|
||||
break;
|
||||
}
|
||||
case "mediaPreviewEnabled": {
|
||||
boolean enabled = sharedPreferences.getBoolean("mediaPreviewEnabled", true);
|
||||
boolean enabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
|
||||
boolean oldMediaPreviewEnabled = adapter.getMediaPreviewEnabled();
|
||||
if (enabled != oldMediaPreviewEnabled) {
|
||||
adapter.setMediaPreviewEnabled(enabled);
|
||||
@ -682,7 +687,7 @@ public class TimelineFragment extends SFragment implements
|
||||
}
|
||||
case "alwaysShowSensitiveMedia": {
|
||||
//it is ok if only newly loaded statuses are affected, no need to fully refresh
|
||||
alwaysShowSensitiveMedia = sharedPreferences.getBoolean("alwaysShowSensitiveMedia", false);
|
||||
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -157,8 +157,8 @@ public final class ViewThreadFragment extends SFragment implements
|
||||
threadLineDrawable));
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(
|
||||
getActivity());
|
||||
alwaysShowSensitiveMedia = preferences.getBoolean("alwaysShowSensitiveMedia", false);
|
||||
boolean mediaPreviewEnabled = preferences.getBoolean("mediaPreviewEnabled", true);
|
||||
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
|
||||
boolean mediaPreviewEnabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
|
||||
adapter.setMediaPreviewEnabled(mediaPreviewEnabled);
|
||||
boolean useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false);
|
||||
adapter.setUseAbsoluteTime(useAbsoluteTime);
|
||||
|
@ -0,0 +1,252 @@
|
||||
/* Copyright 2018 Conny Duck
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.design.widget.Snackbar
|
||||
import android.support.v14.preference.SwitchPreference
|
||||
import android.support.v7.preference.ListPreference
|
||||
import android.support.v7.preference.Preference
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.keylesspalace.tusky.AccountListActivity
|
||||
import com.keylesspalace.tusky.BuildConfig
|
||||
import com.keylesspalace.tusky.PreferencesActivity
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class AccountPreferencesFragment : PreferenceFragmentCompat(),
|
||||
Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
|
||||
Injectable {
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
@Inject
|
||||
lateinit var mastodonApi: MastodonApi
|
||||
|
||||
@Inject
|
||||
lateinit var eventHub: EventHub
|
||||
|
||||
private lateinit var notificationPreference: Preference
|
||||
private lateinit var mutedUsersPreference: Preference
|
||||
private lateinit var blockedUsersPreference: Preference
|
||||
|
||||
private lateinit var defaultPostPrivacyPreference: ListPreference
|
||||
private lateinit var defaultMediaSensitivityPreference: SwitchPreference
|
||||
private lateinit var alwaysShowSensitiveMediaPreference: SwitchPreference
|
||||
private lateinit var mediaPreviewEnabledPreference: SwitchPreference
|
||||
|
||||
private val iconSize by lazy {resources.getDimensionPixelSize(R.dimen.preference_icon_size)}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.account_preferences)
|
||||
|
||||
notificationPreference = findPreference("notificationPreference")
|
||||
mutedUsersPreference = findPreference("mutedUsersPreference")
|
||||
blockedUsersPreference = findPreference("blockedUsersPreference")
|
||||
defaultPostPrivacyPreference = findPreference("defaultPostPrivacy") as ListPreference
|
||||
defaultMediaSensitivityPreference = findPreference("defaultMediaSensitivity") as SwitchPreference
|
||||
mediaPreviewEnabledPreference = findPreference("mediaPreviewEnabled") as SwitchPreference
|
||||
alwaysShowSensitiveMediaPreference = findPreference("alwaysShowSensitiveMedia") as SwitchPreference
|
||||
|
||||
notificationPreference.icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_notifications).sizePx(iconSize).color(ThemeUtils.getColor(context, R.attr.toolbar_icon_tint))
|
||||
mutedUsersPreference.icon = getTintedIcon(R.drawable.ic_mute_24dp)
|
||||
blockedUsersPreference.icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_block).sizePx(iconSize).color(ThemeUtils.getColor(context, R.attr.toolbar_icon_tint))
|
||||
|
||||
notificationPreference.onPreferenceClickListener = this
|
||||
mutedUsersPreference.onPreferenceClickListener = this
|
||||
blockedUsersPreference.onPreferenceClickListener = this
|
||||
|
||||
defaultPostPrivacyPreference.onPreferenceChangeListener = this
|
||||
defaultMediaSensitivityPreference.onPreferenceChangeListener = this
|
||||
mediaPreviewEnabledPreference.onPreferenceChangeListener = this
|
||||
alwaysShowSensitiveMediaPreference.onPreferenceChangeListener = this
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
accountManager.activeAccount?.let {
|
||||
|
||||
defaultPostPrivacyPreference.value = it.defaultPostPrivacy.serverString()
|
||||
defaultPostPrivacyPreference.icon = getIconForVisibility(it.defaultPostPrivacy)
|
||||
|
||||
defaultMediaSensitivityPreference.isChecked = it.defaultMediaSensitivity
|
||||
defaultMediaSensitivityPreference.icon = getIconForSensitivity(it.defaultMediaSensitivity)
|
||||
|
||||
mediaPreviewEnabledPreference.isChecked = it.mediaPreviewEnabled
|
||||
alwaysShowSensitiveMediaPreference.isChecked = it.alwaysShowSensitiveMedia
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
when(preference) {
|
||||
defaultPostPrivacyPreference -> {
|
||||
preference.icon = getIconForVisibility(Status.Visibility.byString(newValue as String))
|
||||
syncWithServer(visibility = newValue)
|
||||
}
|
||||
defaultMediaSensitivityPreference -> {
|
||||
preference.icon = getIconForSensitivity(newValue as Boolean)
|
||||
syncWithServer(sensitive = newValue)
|
||||
}
|
||||
mediaPreviewEnabledPreference -> {
|
||||
accountManager.activeAccount?.let {
|
||||
it.mediaPreviewEnabled = newValue as Boolean
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
}
|
||||
alwaysShowSensitiveMediaPreference -> {
|
||||
accountManager.activeAccount?.let {
|
||||
it.alwaysShowSensitiveMedia = newValue as Boolean
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventHub.dispatch(PreferenceChangedEvent(preference.key))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPreferenceClick(preference: Preference): Boolean {
|
||||
|
||||
when(preference) {
|
||||
notificationPreference -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val intent = Intent()
|
||||
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
|
||||
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
activity?.let {
|
||||
val intent = PreferencesActivity.newIntent(it, PreferencesActivity.NOTIFICATION_PREFERENCES)
|
||||
it.startActivity(intent)
|
||||
it.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
mutedUsersPreference -> {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.MUTES)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
return true
|
||||
}
|
||||
blockedUsersPreference -> {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.BLOCKS)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
return true
|
||||
}
|
||||
|
||||
else -> return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun syncWithServer(visibility: String? = null, sensitive: Boolean? = null) {
|
||||
mastodonApi.accountUpdateSource(visibility, sensitive)
|
||||
.enqueue(object: Callback<Account>{
|
||||
override fun onResponse(call: Call<Account>, response: Response<Account>) {
|
||||
val account = response.body()
|
||||
if(response.isSuccessful && account != null) {
|
||||
|
||||
accountManager.activeAccount?.let {
|
||||
it.defaultPostPrivacy = account.source?.privacy ?: Status.Visibility.PUBLIC
|
||||
it.defaultMediaSensitivity = account.source?.sensitive ?: false
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
} else {
|
||||
Log.e("AccountPreferences", "failed updating settings on server")
|
||||
showErrorSnackbar(visibility, sensitive)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<Account>, t: Throwable) {
|
||||
Log.e("AccountPreferences", "failed updating settings on server", t)
|
||||
showErrorSnackbar(visibility, sensitive)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
private fun showErrorSnackbar(visibility: String?, sensitive: Boolean?) {
|
||||
view?.let {view ->
|
||||
Snackbar.make(view, R.string.pref_failed_to_sync, Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.action_retry) { syncWithServer( visibility, sensitive)}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIconForVisibility(visibility: Status.Visibility): Drawable? {
|
||||
val drawableId = when (visibility) {
|
||||
Status.Visibility.PRIVATE -> R.drawable.ic_lock_outline_24dp
|
||||
|
||||
Status.Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp
|
||||
|
||||
else -> R.drawable.ic_public_24dp
|
||||
}
|
||||
|
||||
return getTintedIcon(drawableId)
|
||||
}
|
||||
|
||||
private fun getIconForSensitivity(sensitive: Boolean): Drawable? {
|
||||
val drawableId = if (sensitive) {
|
||||
R.drawable.ic_hide_media_24dp
|
||||
} else {
|
||||
R.drawable.ic_eye_24dp
|
||||
}
|
||||
|
||||
return getTintedIcon(drawableId)
|
||||
}
|
||||
|
||||
private fun getTintedIcon(iconId: Int): Drawable? {
|
||||
val drawable = context?.getDrawable(iconId)
|
||||
ThemeUtils.setDrawableTint(context, drawable, R.attr.toolbar_icon_tint)
|
||||
return drawable
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(): AccountPreferencesFragment {
|
||||
return AccountPreferencesFragment()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/* Copyright 2018 Conny Duck
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v14.preference.SwitchPreference
|
||||
import android.support.v7.preference.Preference
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
import android.view.View
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class NotificationPreferencesFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener, Injectable {
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.notification_preferences)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val activeAccount = accountManager.activeAccount
|
||||
|
||||
if (activeAccount != null) {
|
||||
|
||||
val notificationPref = findPreference("notificationsEnabled") as SwitchPreference
|
||||
notificationPref.isChecked = activeAccount.notificationsEnabled
|
||||
notificationPref.onPreferenceChangeListener = this
|
||||
|
||||
val mentionedPref = findPreference("notificationFilterMentions") as SwitchPreference
|
||||
mentionedPref.isChecked = activeAccount.notificationsMentioned
|
||||
mentionedPref.onPreferenceChangeListener = this
|
||||
|
||||
val followedPref = findPreference("notificationFilterFollows") as SwitchPreference
|
||||
followedPref.isChecked = activeAccount.notificationsFollowed
|
||||
followedPref.onPreferenceChangeListener = this
|
||||
|
||||
val boostedPref = findPreference("notificationFilterReblogs") as SwitchPreference
|
||||
boostedPref.isChecked = activeAccount.notificationsReblogged
|
||||
boostedPref.onPreferenceChangeListener = this
|
||||
|
||||
val favoritedPref = findPreference("notificationFilterFavourites") as SwitchPreference
|
||||
favoritedPref.isChecked = activeAccount.notificationsFavorited
|
||||
favoritedPref.onPreferenceChangeListener = this
|
||||
|
||||
val soundPref = findPreference("notificationAlertSound") as SwitchPreference
|
||||
soundPref.isChecked = activeAccount.notificationSound
|
||||
soundPref.onPreferenceChangeListener = this
|
||||
|
||||
val vibrationPref = findPreference("notificationAlertVibrate") as SwitchPreference
|
||||
vibrationPref.isChecked = activeAccount.notificationVibration
|
||||
vibrationPref.onPreferenceChangeListener = this
|
||||
|
||||
val lightPref = findPreference("notificationAlertLight") as SwitchPreference
|
||||
lightPref.isChecked = activeAccount.notificationLight
|
||||
lightPref.onPreferenceChangeListener = this
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
|
||||
val activeAccount = accountManager.activeAccount
|
||||
|
||||
if (activeAccount != null) {
|
||||
when (preference.key) {
|
||||
"notificationsEnabled" -> {
|
||||
activeAccount.notificationsEnabled = newValue as Boolean
|
||||
if(NotificationHelper.areNotificationsEnabled(preference.context, accountManager)) {
|
||||
NotificationHelper.enablePullNotifications()
|
||||
} else {
|
||||
NotificationHelper.disablePullNotifications()
|
||||
}
|
||||
}
|
||||
"notificationFilterMentions" -> activeAccount.notificationsMentioned = newValue as Boolean
|
||||
"notificationFilterFollows" -> activeAccount.notificationsFollowed = newValue as Boolean
|
||||
"notificationFilterReblogs" -> activeAccount.notificationsReblogged = newValue as Boolean
|
||||
"notificationFilterFavourites" -> activeAccount.notificationsFavorited = newValue as Boolean
|
||||
"notificationAlertSound" -> activeAccount.notificationSound = newValue as Boolean
|
||||
"notificationAlertVibrate" -> activeAccount.notificationVibration = newValue as Boolean
|
||||
"notificationAlertLight" -> activeAccount.notificationLight = newValue as Boolean
|
||||
}
|
||||
accountManager.saveAccount(activeAccount)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(): NotificationPreferencesFragment {
|
||||
return NotificationPreferencesFragment()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/* Copyright 2018 Conny Duck
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
import com.keylesspalace.tusky.PreferencesActivity
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.keylesspalace.tusky.util.getNonNullString
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
|
||||
class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private val iconSize by lazy {resources.getDimensionPixelSize(R.dimen.preference_icon_size)}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
|
||||
addPreferencesFromResource(R.xml.preferences)
|
||||
|
||||
val themePreference = findPreference("appTheme")
|
||||
themePreference.icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_palette).sizePx(iconSize).color(ThemeUtils.getColor(context, R.attr.toolbar_icon_tint))
|
||||
|
||||
val emojiPreference = findPreference("emojiCompat")
|
||||
emojiPreference.icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_sentiment_satisfied).sizePx(iconSize).color(ThemeUtils.getColor(context, R.attr.toolbar_icon_tint))
|
||||
|
||||
val textSizePreference = findPreference("statusTextSize")
|
||||
textSizePreference.icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_format_size).sizePx(iconSize).color(ThemeUtils.getColor(context, R.attr.toolbar_icon_tint))
|
||||
|
||||
val timelineFilterPreferences = findPreference("timelineFilterPreferences")
|
||||
timelineFilterPreferences.setOnPreferenceClickListener { _ ->
|
||||
activity?.let {
|
||||
val intent = PreferencesActivity.newIntent(it, PreferencesActivity.TAB_FILTER_PREFERENCES)
|
||||
it.startActivity(intent)
|
||||
it.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val httpProxyPreferences = findPreference("httpProxyPreferences")
|
||||
httpProxyPreferences.setOnPreferenceClickListener { _ ->
|
||||
activity?.let {
|
||||
val intent = PreferencesActivity.newIntent(it, PreferencesActivity.PROXY_PREFERENCES)
|
||||
it.startActivity(intent)
|
||||
it.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateHttpProxySummary()
|
||||
}
|
||||
|
||||
private fun updateHttpProxySummary() {
|
||||
|
||||
val httpProxyPref = findPreference("httpProxyPreferences")
|
||||
|
||||
val sharedPreferences = preferenceManager.sharedPreferences
|
||||
|
||||
val httpProxyEnabled = sharedPreferences.getBoolean("httpProxyEnabled", false)
|
||||
|
||||
val httpServer = sharedPreferences.getNonNullString("httpProxyServer", "")
|
||||
|
||||
try {
|
||||
val httpPort = sharedPreferences.getNonNullString("httpProxyPort", "-1").toInt()
|
||||
|
||||
if (httpProxyEnabled && httpServer.isNotBlank() && httpPort > 0 && httpPort < 65535) {
|
||||
httpProxyPref.summary = "$httpServer:$httpPort"
|
||||
return
|
||||
}
|
||||
} catch (e: NumberFormatException) {
|
||||
// user has entered wrong port, fall back to empty summary
|
||||
}
|
||||
|
||||
httpProxyPref.summary = ""
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(): PreferencesFragment {
|
||||
return PreferencesFragment()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/* Copyright 2018 Conny Duck
|
||||
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.support.v7.preference.EditTextPreference
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
import com.keylesspalace.tusky.R
|
||||
|
||||
class ProxyPreferencesFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private var pendingRestart = false
|
||||
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.http_proxy_preferences)
|
||||
|
||||
sharedPreferences = preferenceManager.sharedPreferences
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
updateSummary("httpProxyServer")
|
||||
updateSummary("httpProxyPort")
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
|
||||
|
||||
if (pendingRestart) {
|
||||
pendingRestart = false
|
||||
System.exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
updateSummary (key)
|
||||
}
|
||||
|
||||
private fun updateSummary(key: String) {
|
||||
when (key) {
|
||||
"httpProxyServer", "httpProxyPort" -> {
|
||||
val editTextPreference = findPreference(key) as EditTextPreference
|
||||
editTextPreference.summary = editTextPreference.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): ProxyPreferencesFragment {
|
||||
return ProxyPreferencesFragment()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/* Copyright 2018 Conny Duck
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.widget.EditText
|
||||
import com.keylesspalace.tusky.R
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class TabFilterPreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.timeline_filter_preferences)
|
||||
|
||||
sharedPreferences = preferenceManager.sharedPreferences
|
||||
|
||||
val regexPref = findPreference("tabFilterRegex")
|
||||
if (regexPref != null) {
|
||||
|
||||
regexPref.summary = sharedPreferences.getString("tabFilterRegex", "")
|
||||
regexPref.setOnPreferenceClickListener {
|
||||
|
||||
val editText = EditText(requireContext())
|
||||
editText.setText(sharedPreferences.getString("tabFilterRegex", ""))
|
||||
|
||||
val dialog = AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.pref_title_filter_regex)
|
||||
.setView(editText)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
sharedPreferences
|
||||
.edit()
|
||||
.putString("tabFilterRegex", editText.text.toString())
|
||||
.apply()
|
||||
regexPref.summary = editText.text.toString()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create()
|
||||
|
||||
editText.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(newRegex: Editable) {
|
||||
try {
|
||||
Pattern.compile(newRegex.toString())
|
||||
editText.error = null
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
|
||||
} catch (e: IllegalArgumentException) {
|
||||
editText.error = getString(R.string.error_invalid_regex)
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s1: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
||||
override fun onTextChanged(s1: CharSequence, start: Int, before: Int, count: Int) {}
|
||||
})
|
||||
dialog.show()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): TabFilterPreferencesFragment {
|
||||
return TabFilterPreferencesFragment()
|
||||
}
|
||||
}
|
||||
}
|
@ -166,6 +166,11 @@ public interface MastodonApi {
|
||||
@GET("api/v1/accounts/verify_credentials")
|
||||
Call<Account> accountVerifyCredentials();
|
||||
|
||||
@FormUrlEncoded
|
||||
@PATCH("api/v1/accounts/update_credentials")
|
||||
Call<Account> accountUpdateSource(@Nullable @Field("source[privacy]") String privacy,
|
||||
@Nullable @Field("source[sensitive]") Boolean sensitive);
|
||||
|
||||
@Multipart
|
||||
@PATCH("api/v1/accounts/update_credentials")
|
||||
Call<Account> accountUpdateCredentials(
|
||||
|
@ -37,6 +37,8 @@ import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.text.BidiFormatter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
import com.keylesspalace.tusky.BuildConfig;
|
||||
import com.keylesspalace.tusky.MainActivity;
|
||||
import com.keylesspalace.tusky.R;
|
||||
@ -103,6 +105,13 @@ public class NotificationHelper {
|
||||
public static final String CHANNEL_BOOST = "CHANNEL_BOOST";
|
||||
public static final String CHANNEL_FAVOURITE = "CHANNEL_FAVOURITE";
|
||||
|
||||
/**
|
||||
* time in minutes between notification checks
|
||||
* note that this cannot be less than 15 minutes due to Android battery saving constraints
|
||||
*/
|
||||
private static final int NOTIFICATION_CHECK_INTERVAL_MINUTES = 15;
|
||||
|
||||
|
||||
/**
|
||||
* Takes a given Mastodon notification and either creates a new Android notification or updates
|
||||
* the state of the existing notification to reflect the new interaction.
|
||||
@ -424,6 +433,25 @@ public class NotificationHelper {
|
||||
|
||||
}
|
||||
|
||||
public static void enablePullNotifications() {
|
||||
long checkInterval = 1000 * 60 * NOTIFICATION_CHECK_INTERVAL_MINUTES;
|
||||
|
||||
new JobRequest.Builder(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG)
|
||||
.setPeriodic(checkInterval)
|
||||
.setUpdateCurrent(true)
|
||||
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
|
||||
.build()
|
||||
.scheduleAsync();
|
||||
|
||||
Log.d(TAG, "enabled notification checks with "+ NOTIFICATION_CHECK_INTERVAL_MINUTES + "min interval");
|
||||
}
|
||||
|
||||
public static void disablePullNotifications() {
|
||||
JobManager.instance().cancelAllForTag(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG);
|
||||
Log.d(TAG, "disabled notification checks");
|
||||
|
||||
}
|
||||
|
||||
public static void clearNotificationsForActiveAccount(@NonNull Context context, @NonNull AccountManager accountManager) {
|
||||
AccountEntity account = accountManager.getActiveAccount();
|
||||
if (account != null) {
|
||||
|
@ -13,7 +13,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public License along with Tusky. If
|
||||
* not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
package com.keylesspalace.tusky;
|
||||
package com.keylesspalace.tusky.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
@ -26,7 +26,6 @@ import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.entity.Notification;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.util.NotificationHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
@ -98,10 +97,10 @@ public final class NotificationPullJobCreator implements JobCreator {
|
||||
if (notifications.isSuccessful()) {
|
||||
onNotificationsReceived(account, notifications.body());
|
||||
} else {
|
||||
Log.w(TAG, "error receiving notificationsEnabled");
|
||||
Log.w(TAG, "error receiving notifications");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "error receiving notificationsEnabled", e);
|
||||
Log.w(TAG, "error receiving notifications", e);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.keylesspalace.tusky.util
|
||||
|
||||
import android.content.SharedPreferences
|
||||
|
||||
fun SharedPreferences.getNonNullString(key: String, defValue: String): String {
|
||||
return this.getString(key, defValue) ?: defValue
|
||||
}
|
13
app/src/main/res/drawable/ic_account_settings.xml
Normal file
13
app/src/main/res/drawable/ic_account_settings.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M8.9987,3.9987C6.7925,3.9987 5,5.7913 5,7.9975C5,10.21 6.7925,12.0025 8.9987,12.0025C11.2113,12.0025 12.9975,10.21 12.9975,7.9975C12.9975,5.7913 11.2113,3.9987 8.9987,3.9987ZM8.9987,13.9987C6.3288,13.9987 1.0013,15.3325 1.0013,17.9975L1.0013,20L12.08,20C12.0262,19.6675 12.0025,19.3362 12.0025,18.9988C12.0025,17.485 12.495,16.0113 13.4087,14.8C11.88,14.2775 10.1813,13.9987 8.9987,13.9987ZM17.9887,13.9987C17.8712,13.9987 17.7588,14.0912 17.7388,14.2087L17.5487,15.5275C17.2512,15.6588 16.9575,15.82 16.6988,16.02L15.4587,15.5175C15.3512,15.4787 15.22,15.5225 15.1512,15.63L14.15,17.3587C14.0913,17.4713 14.1112,17.5975 14.2087,17.6812L15.2688,18.5113C15.2487,18.6712 15.2388,18.8275 15.2388,18.9988C15.2388,19.17 15.2487,19.3312 15.2688,19.4925L14.2087,20.3225C14.1212,20.4 14.0913,20.5325 14.15,20.64L15.1512,22.3687C15.21,22.48 15.3413,22.52 15.4587,22.48L16.6988,21.9825C16.9575,22.1825 17.2412,22.3488 17.5487,22.4713L17.7388,23.7888C17.7588,23.9113 17.8612,23.9988 17.9887,23.9988L19.99,23.9988C20.1123,23.9988 20.22,23.9113 20.2393,23.7888L20.4297,22.4713C20.7275,22.3387 21.0205,22.1825 21.27,21.9825L22.52,22.48C22.6312,22.52 22.7588,22.48 22.8325,22.3687L23.8288,20.64C23.8913,20.5325 23.8575,20.4 23.77,20.3225L22.7002,19.4925C22.72,19.3312 22.7393,19.17 22.7393,18.9988C22.7393,18.8275 22.7295,18.6712 22.7002,18.5113L23.76,17.6812C23.8475,17.5975 23.8812,17.4713 23.8188,17.3587L22.8225,15.63C22.7588,15.5225 22.6312,15.4787 22.51,15.5175L21.27,16.02C21.0107,15.82 20.7275,15.65 20.42,15.5275L20.2295,14.2087C20.22,14.0912 20.1123,13.9987 19.99,13.9987M18.9888,17.5C19.8188,17.5 20.4888,18.1687 20.4888,18.9988C20.4888,19.8288 19.8188,20.4975 18.9888,20.4975C18.1588,20.4975 17.49,19.8288 17.49,18.9988C17.49,18.1687 18.1588,17.5 18.9888,17.5Z"
|
||||
android:strokeWidth="0.2"
|
||||
android:strokeLineJoin="round" />
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_logout.xml
Normal file
10
app/src/main/res/drawable/ic_logout.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="#000"
|
||||
android:pathData="M14.08,15.59L16.67,13H7V11H16.67L14.08,8.41L15.5,7L20.5,12L15.5,17L14.08,15.59M19,3A2,2 0 0,1 21,5V9.67L19,7.67V5H5V19H19V16.33L21,14.33V19A2,2 0 0,1 19,21H5C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H19Z" />
|
||||
</vector>
|
8
app/src/main/res/drawable/ic_notebook.xml
Normal file
8
app/src/main/res/drawable/ic_notebook.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M3,7V5H5V4C5,2.89 5.9,2 7,2H13V9L15.5,7.5L18,9V2H19C20.05,2 21,2.95 21,4V20C21,21.05 20.05,22 19,22H7C5.95,22 5,21.05 5,20V19H3V17H5V13H3V11H5V7H3M7,11H5V13H7V11M7,7V5H5V7H7M7,19V17H5V19H7Z" />
|
||||
</vector>
|
@ -158,7 +158,6 @@
|
||||
<string name="pref_title_edit_notification_settings">تعديل الاشعارات</string>
|
||||
<string name="pref_title_notifications_enabled">الإخطارات</string>
|
||||
<string name="pref_summary_notifications">للحساب %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">مدة تحديث التحميل</string>
|
||||
<string name="pref_title_notification_alerts">التنبيهات</string>
|
||||
<string name="pref_title_notification_alert_sound">إعلام بالصوت</string>
|
||||
<string name="pref_title_notification_alert_vibrate">إعلام بالاهتزار</string>
|
||||
|
@ -139,7 +139,6 @@
|
||||
<string name="pref_title_notification_settings">Notificacions</string>
|
||||
<string name="pref_title_edit_notification_settings">Edita les notificacions</string>
|
||||
<string name="pref_title_notifications_enabled">Notificacions</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Comprova l\'interval</string>
|
||||
<string name="pref_title_notification_alerts">Alertes</string>
|
||||
<string name="pref_title_notification_alert_sound">Notifica amb un so</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Notifica amb una vibració</string>
|
||||
@ -159,16 +158,6 @@
|
||||
<string name="pref_title_show_replies">Mostra les respostes</string>
|
||||
<string name="pref_title_show_media_preview">Mostra les previsualitzacions</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minuts</item>
|
||||
<item>20 minuts</item>
|
||||
<item>25 minuts</item>
|
||||
<item>30 minuts</item>
|
||||
<item>45 minuts</item>
|
||||
<item>1 hora</item>
|
||||
<item>2 hores</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Privacitat predeterminada dels toots</string>
|
||||
<string name="pref_publishing">Publicació</string>
|
||||
|
||||
|
@ -165,7 +165,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Golygu Hysbysiadau </string>
|
||||
<string name="pref_title_notifications_enabled">Hysbysiadau</string>
|
||||
<string name="pref_summary_notifications">i gyfrif %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Cadarnhau Amser</string>
|
||||
<string name="pref_title_notification_alerts">Negeseuon pwysig</string>
|
||||
<string name="pref_title_notification_alert_sound">Cael hysbysiad sŵn </string>
|
||||
<string name="pref_title_notification_alert_vibrate">Cael hysbysiad crynu </string>
|
||||
@ -200,16 +199,6 @@
|
||||
<string name="pref_title_http_proxy_server">Gweinydd procsi HTTP </string>
|
||||
<string name="pref_title_http_proxy_port">Porthol procsiHTTP </string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 munud</item>
|
||||
<item>20 munud</item>
|
||||
<item>25 munud</item>
|
||||
<item>30 munud</item>
|
||||
<item>45 munud</item>
|
||||
<item>1 awr</item>
|
||||
<item>2 awr</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Preifatrwydd postiadau rhagosodedig</string>
|
||||
<string name="pref_publishing">Cyhoeddi </string>
|
||||
|
||||
|
@ -134,16 +134,6 @@
|
||||
<string name="pref_title_custom_tabs">Öffne Links in der App</string>
|
||||
<string name="pref_title_hide_follow_button">Verstecke Button bei Bildlauf </string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 Minuten</item>
|
||||
<item>20 Minuten</item>
|
||||
<item>25 Minuten</item>
|
||||
<item>30 Minuten</item>
|
||||
<item>45 Minuten</item>
|
||||
<item>1 Stunde</item>
|
||||
<item>2 Stunden</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>Öffentlich</item>
|
||||
<item>Nicht gelistet</item>
|
||||
@ -214,7 +204,6 @@
|
||||
<string name="pref_title_show_replies">Zeige Antworten</string>
|
||||
<string name="pref_title_show_media_preview">Zeige Medienvorschauen</string>
|
||||
<string name="pref_title_show_boosts">Zeige Boosts</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Überprüfungsintervall</string>
|
||||
<string name="no_content">leer</string>
|
||||
<string name="action_hide_media">Verstecke Medien</string>
|
||||
<string name="pref_title_status_filter">Timeline-Filter</string>
|
||||
|
@ -160,7 +160,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Editar notificaciones</string>
|
||||
<string name="pref_title_notifications_enabled">Notificaciones</string>
|
||||
<string name="pref_summary_notifications">para la cuenta %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Intervalo</string>
|
||||
<string name="pref_title_notification_alerts">Alertas</string>
|
||||
<string name="pref_title_notification_alert_sound">Notificar con sonido</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Notificar con vibración</string>
|
||||
@ -195,16 +194,6 @@
|
||||
<string name="pref_title_http_proxy_server">Servidor del proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Puerto del proxy HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minutos</item>
|
||||
<item>20 minutos</item>
|
||||
<item>25 minutos</item>
|
||||
<item>30 minutos</item>
|
||||
<item>45 minutos</item>
|
||||
<item>1 hora</item>
|
||||
<item>2 hora</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Visibilidad por defecto</string>
|
||||
<string name="pref_publishing">Publicaciones</string>
|
||||
|
||||
|
@ -165,7 +165,6 @@
|
||||
<string name="pref_title_edit_notification_settings" >ویرایش اعلانها</string>
|
||||
<string name="pref_title_notifications_enabled" >اعلان ها</string>
|
||||
<string name="pref_summary_notifications" >برای حساب %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval" >فاصله را بررسی کن</string>
|
||||
<string name="pref_title_notification_alerts" >هشدارها</string>
|
||||
<string name="pref_title_notification_alert_sound" >اعلان با صدا</string>
|
||||
<string name="pref_title_notification_alert_vibrate" >اعلان با لرزش</string>
|
||||
@ -199,16 +198,6 @@
|
||||
<string name="pref_title_http_proxy_enable" >فعالسازی پراکسی HTTP</string>
|
||||
<string name="pref_title_http_proxy_server" >سرور پراکسی HTTP</string>
|
||||
<string name="pref_title_http_proxy_port" >پورت پراکسی HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>۱۵ دقیقه</item>
|
||||
<item>۲۰ دقیقه</item>
|
||||
<item>۲۵ دقیقه</item>
|
||||
<item>۳۰ دقیقه</item>
|
||||
<item>۴۵ دقیقه</item>
|
||||
<item>۱ ساعت</item>
|
||||
<item>۲ ساعت</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">حریم خصوصی پیشفرض پست</string>
|
||||
<string name="pref_publishing" >انتشار</string>
|
||||
|
@ -177,7 +177,6 @@
|
||||
<string name="search_no_results">Aucun résultat</string>
|
||||
<string name="dialog_unfollow_warning">Désirez-vous cesser de suivre ce compte \?</string>
|
||||
<string name="pref_summary_notifications">pour le compte %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Interval de vérifications</string>
|
||||
<string name="pref_title_app_theme">Theme de l\'application</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
@ -193,16 +192,6 @@
|
||||
<string name="pref_title_http_proxy_server">Adresse du serveur proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Port du serveur proxy HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minutes</item>
|
||||
<item>20 minutes</item>
|
||||
<item>25 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>45 minutes</item>
|
||||
<item>1 heure</item>
|
||||
<item>2 heures</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Confidentialité par defaut</string>
|
||||
<string name="pref_publishing">Publier</string>
|
||||
|
||||
|
@ -140,7 +140,6 @@
|
||||
<string name="pref_title_notification_settings">Értesítések</string>
|
||||
<string name="pref_title_edit_notification_settings">Értesítések szerkesztése</string>
|
||||
<string name="pref_title_notifications_enabled">Értesítések</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Ellenőrzési időköz</string>
|
||||
<string name="pref_title_notification_alerts">Figyelmeztetések</string>
|
||||
<string name="pref_title_notification_alert_sound">Értesítés hanggal</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Értesítés rezgéssel</string>
|
||||
|
@ -165,7 +165,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Modifica Notifiche</string>
|
||||
<string name="pref_title_notifications_enabled">Notifiche</string>
|
||||
<string name="pref_summary_notifications">per l\'account %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Intervallo di controllo</string>
|
||||
<string name="pref_title_notification_alerts">Allarmi</string>
|
||||
<string name="pref_title_notification_alert_sound">Notifica con suoneria</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Notifica con vibrazione</string>
|
||||
@ -200,16 +199,6 @@
|
||||
<string name="pref_title_http_proxy_server">Server proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Porta proxy HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minuti</item>
|
||||
<item>20 minuti</item>
|
||||
<item>25 minuti</item>
|
||||
<item>30 minuti</item>
|
||||
<item>45 minuti</item>
|
||||
<item>1 ora</item>
|
||||
<item>2 ore</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Privacy di default dei post</string>
|
||||
<string name="pref_publishing">Pubblicando</string>
|
||||
|
||||
|
@ -159,7 +159,6 @@
|
||||
<string name="pref_title_edit_notification_settings">通知を設定</string>
|
||||
<string name="pref_title_notifications_enabled">プッシュ通知</string>
|
||||
<string name="pref_summary_notifications">対象: %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">通知の取得間隔</string>
|
||||
<string name="pref_title_notification_alerts">通知時の動作</string>
|
||||
<string name="pref_title_notification_alert_sound">着信音を鳴らす</string>
|
||||
<string name="pref_title_notification_alert_vibrate">バイブレーションする</string>
|
||||
@ -194,16 +193,6 @@
|
||||
<string name="pref_title_http_proxy_server">HTTPプロキシーサーバー</string>
|
||||
<string name="pref_title_http_proxy_port">HTTPプロキシーポート</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15分</item>
|
||||
<item>20分</item>
|
||||
<item>25分</item>
|
||||
<item>30分</item>
|
||||
<item>45分</item>
|
||||
<item>1時間</item>
|
||||
<item>2時間</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">デフォルトの投稿プライバシー</string>
|
||||
<string name="pref_publishing">投稿</string>
|
||||
|
||||
|
@ -158,7 +158,6 @@
|
||||
<string name="pref_title_edit_notification_settings">알림 설정 편집</string>
|
||||
<string name="pref_title_notifications_enabled">알림</string>
|
||||
<string name="pref_summary_notifications">%1$s 계정의 알림</string>
|
||||
<string name="pref_title_pull_notification_check_interval">확인 간격</string>
|
||||
<string name="pref_title_notification_alerts">알림</string>
|
||||
<string name="pref_title_notification_alert_sound">소리로 알림</string>
|
||||
<string name="pref_title_notification_alert_vibrate">진동으로 알림</string>
|
||||
|
@ -68,6 +68,8 @@
|
||||
|
||||
<item name="compound_button_color">@color/compound_button_color_dark</item>
|
||||
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.ImageButton.Dark" parent="@style/Widget.AppCompat.Button.Borderless.Colored">
|
||||
|
@ -158,7 +158,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Meldingen bewerken</string>
|
||||
<string name="pref_title_notifications_enabled">Meldingen</string>
|
||||
<string name="pref_summary_notifications">voor account %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Controlefrequentie</string>
|
||||
<string name="pref_title_notification_alerts">Waarschuwen met</string>
|
||||
<string name="pref_title_notification_alert_sound">geluid</string>
|
||||
<string name="pref_title_notification_alert_vibrate">trillen</string>
|
||||
@ -193,16 +192,6 @@
|
||||
<string name="pref_title_http_proxy_server">Serveradres van HTTP-proxy</string>
|
||||
<string name="pref_title_http_proxy_port">Poort van HTTP-proxy</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minuten</item>
|
||||
<item>20 minuten</item>
|
||||
<item>25 minuten</item>
|
||||
<item>30 minuten</item>
|
||||
<item>45 minuten</item>
|
||||
<item>1 uur</item>
|
||||
<item>2 uur</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Standaardzichtbaarheid van jouw toots</string>
|
||||
<string name="pref_publishing">Publiceren</string>
|
||||
|
||||
|
@ -158,7 +158,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Modificar las notificacions</string>
|
||||
<string name="pref_title_notifications_enabled">Notificacions</string>
|
||||
<string name="pref_summary_notifications">pel compte %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Comprovar l\'interval</string>
|
||||
<string name="pref_title_notification_alerts">Alèrtas</string>
|
||||
<string name="pref_title_notification_alert_sound">Notificar amb un son</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Notificra amb una vibracion</string>
|
||||
@ -194,16 +193,6 @@
|
||||
<string name="pref_title_http_proxy_server">Servidor proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Pòrt del servidor proxy HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minutas</item>
|
||||
<item>20 minutas</item>
|
||||
<item>25 minutas</item>
|
||||
<item>30 minutas</item>
|
||||
<item>45 minutas</item>
|
||||
<item>1 ora</item>
|
||||
<item>2 oras</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Privacitat predeterminada dels tuts</string>
|
||||
<string name="pref_publishing">Publicacion</string>
|
||||
|
||||
|
@ -160,7 +160,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Edytuj powiadomienia</string>
|
||||
<string name="pref_title_notifications_enabled">Powiadomienia</string>
|
||||
<string name="pref_summary_notifications">dla konta %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Częstotliwość sprawdzania</string>
|
||||
<string name="pref_title_notification_alerts">Alerty</string>
|
||||
<string name="pref_title_notification_alert_sound">Powiadamiaj dźwiękiem</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Powiadamiaj wibracją</string>
|
||||
@ -195,16 +194,6 @@
|
||||
<string name="pref_title_http_proxy_server">Serwer proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Port proxy HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minut</item>
|
||||
<item>20 minut</item>
|
||||
<item>25 minut</item>
|
||||
<item>30 minut</item>
|
||||
<item>45 minut</item>
|
||||
<item>1 godzinę</item>
|
||||
<item>2 godziny</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Domyślne ustawienia prywatności wpisów</string>
|
||||
<string name="pref_publishing">Publikowanie</string>
|
||||
|
||||
|
@ -158,7 +158,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Editar Notificações</string>
|
||||
<string name="pref_title_notifications_enabled">Notificações</string>
|
||||
<string name="pref_summary_notifications">para a conta %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Intervalo de checagem</string>
|
||||
<string name="pref_title_notification_alerts">Alertas</string>
|
||||
<string name="pref_title_notification_alert_sound">Notificar com som</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Notificar com vibração</string>
|
||||
@ -194,17 +193,6 @@
|
||||
<string name="pref_title_http_proxy_server">Servidor do proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Porta do proxy HTTP</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minutos</item>
|
||||
<item>20 minutos</item>
|
||||
<item>25 minutos</item>
|
||||
<item>30 minutos</item>
|
||||
<item>45 minutos</item>
|
||||
<item>1 hora</item>
|
||||
<item>2 horas</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<string name="pref_default_post_privacy">Privacidade padrão dos posts</string>
|
||||
<string name="pref_publishing">Publicação</string>
|
||||
|
||||
|
@ -156,7 +156,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Настройки уведомлений</string>
|
||||
<string name="pref_title_notifications_enabled">Push-уведомления</string>
|
||||
<string name="pref_summary_notifications">для аккаунта %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Интервал проверки</string>
|
||||
<string name="pref_title_notification_alerts">Предупреждения</string>
|
||||
<string name="pref_title_notification_alert_sound">Звуковые уведомления</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Использовать вибрацию</string>
|
||||
@ -191,16 +190,6 @@
|
||||
<string name="pref_title_http_proxy_server">Адрес сервера</string>
|
||||
<string name="pref_title_http_proxy_port">Порт</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 минут</item>
|
||||
<item>20 минут</item>
|
||||
<item>25 минут</item>
|
||||
<item>30 минут</item>
|
||||
<item>45 минут</item>
|
||||
<item>1 час</item>
|
||||
<item>2 часа</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Приватность статусов по умолчанию</string>
|
||||
<string name="pref_publishing">Публикация</string>
|
||||
|
||||
|
@ -164,7 +164,6 @@
|
||||
<string name="pref_title_edit_notification_settings">Redigera notifieringar</string>
|
||||
<string name="pref_title_notifications_enabled">Notifieringar</string>
|
||||
<string name="pref_summary_notifications">för konto %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Uppdateringsintervall</string>
|
||||
<string name="pref_title_notification_alerts">Alarm</string>
|
||||
<string name="pref_title_notification_alert_sound">Meddela med ljud</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Meddela med vibration</string>
|
||||
@ -198,16 +197,6 @@
|
||||
<string name="pref_title_http_proxy_enable">Aktivera HTTP-proxy</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP proxy server</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP proxy port</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minuter</item>
|
||||
<item>20 minuter</item>
|
||||
<item>25 minuter</item>
|
||||
<item>30 minuter</item>
|
||||
<item>45 minuter</item>
|
||||
<item>1 timme</item>
|
||||
<item>2 timmar</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Standardinställning för inlägg</string>
|
||||
<string name="pref_publishing">Publicering</string>
|
||||
|
@ -156,7 +156,6 @@
|
||||
<string name="pref_title_edit_notification_settings">அறிவிப்புகளை திருத்த</string>
|
||||
<string name="pref_title_notifications_enabled">அறிவிப்புகள்</string>
|
||||
<string name="pref_summary_notifications">%1$s கணக்குக்கு</string>
|
||||
<string name="pref_title_pull_notification_check_interval">சரிபார்க்கவேண்டிய இடைவேளை</string>
|
||||
<string name="pref_title_notification_alerts">எச்சரிக்கைகள்</string>
|
||||
<string name="pref_title_notification_alert_sound">ஒலி மூலம் தெரிவிக்கவும்</string>
|
||||
<string name="pref_title_notification_alert_vibrate">அதிர்வுடன் தெரிவிக்கவும்</string>
|
||||
@ -192,16 +191,6 @@
|
||||
<string name="pref_title_http_proxy_server">HTTP ப்ராக்ஸி சேவையகம்</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP ப்ராக்ஸி போர்ட்</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 நிமிடங்கள்</item>
|
||||
<item>20 நிமிடங்கள்</item>
|
||||
<item>25 நிமிடங்கள்</item>
|
||||
<item>30 நிமிடங்கள்</item>
|
||||
<item>45 நிமிடங்கள்</item>
|
||||
<item>1 மணி நேரம்</item>
|
||||
<item>2 மணி நேரம்</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">தனியுரிமையில் பதிவிடுவதை முன்னிருப்பாக்கு</string>
|
||||
<string name="pref_publishing">வெளியீடு</string>
|
||||
|
||||
|
@ -3,13 +3,14 @@
|
||||
<string name="error_generic">应用程序出现异常。</string>
|
||||
<string name="error_empty">内容不能为空。</string>
|
||||
<string name="error_invalid_domain">该域名无效</string>
|
||||
<string name="error_failed_app_registration">无法连接到该实例。</string>
|
||||
<string name="error_failed_app_registration">无法连接此服务器。</string>
|
||||
<string name="error_no_web_browser_found">没有可用的浏览器。</string>
|
||||
<string name="error_authorization_unknown">认证过程出现未知错误。</string>
|
||||
<string name="error_authorization_denied">授权被拒绝。</string>
|
||||
<string name="error_retrieving_oauth_token">无法获取登录信息。</string>
|
||||
<string name="error_compose_character_limit">嘟文太长了!</string>
|
||||
<string name="error_image_upload_size">文件大小限制 8MB。</string>
|
||||
<string name="error_video_upload_size">视频文件大小限制 40MB。</string>
|
||||
<string name="error_media_upload_type">无法上传此类型的文件。</string>
|
||||
<string name="error_media_upload_opening">此文件无法打开。</string>
|
||||
<string name="error_media_upload_permission">需要授予 Tusky 读取媒体文件的权限。</string>
|
||||
@ -18,15 +19,17 @@
|
||||
<string name="error_media_upload_sending">媒体文件上传失败。</string>
|
||||
<string name="error_report_too_few_statuses">至少要报告 1 则嘟文。</string>
|
||||
<string name="error_invalid_regex">正则表达式无效</string>
|
||||
<string name="error_sender_account_gone">嘟文发送时出错。</string>
|
||||
|
||||
<string name="title_home">主页</string>
|
||||
<string name="title_advanced">高级</string>
|
||||
<string name="title_notifications">通知</string>
|
||||
<string name="title_public_local">本站时间轴</string>
|
||||
<string name="title_public_federated">跨站公共时间轴</string>
|
||||
<string name="title_public_federated">跨站公共时间线</string>
|
||||
<string name="title_view_thread">嘟文</string>
|
||||
<string name="title_tag">#%s</string>
|
||||
<string name="title_statuses">嘟文</string>
|
||||
<string name="title_statuses_with_replies">嘟文和回复</string>
|
||||
<string name="title_follows">正在关注</string>
|
||||
<string name="title_followers">关注者</string>
|
||||
<string name="title_favourites">我的收藏</string>
|
||||
@ -35,6 +38,7 @@
|
||||
<string name="title_follow_requests">关注请求</string>
|
||||
<string name="title_edit_profile">编辑个人资料</string>
|
||||
<string name="title_saved_toot">草稿</string>
|
||||
<string name="title_licenses">开源协议</string>
|
||||
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="status_boosted_format">%s 转嘟了</string>
|
||||
@ -43,6 +47,8 @@
|
||||
<string name="status_sensitive_media_directions">点击显示</string>
|
||||
<string name="status_content_warning_show_more">显示更多</string>
|
||||
<string name="status_content_warning_show_less">折叠内容</string>
|
||||
<string name="status_content_show_more">展开</string>
|
||||
<string name="status_content_show_less">折叠</string>
|
||||
|
||||
<string name="footer_empty">还没有内容,向下滑动即可刷新。</string>
|
||||
|
||||
@ -53,18 +59,21 @@
|
||||
<string name="report_username_format">报告用户 @%s 的滥用行为</string>
|
||||
<string name="report_comment_hint">报告更多信息</string>
|
||||
|
||||
<string name="action_quick_reply">快捷回复</string>
|
||||
<string name="action_reply">回复</string>
|
||||
<string name="action_reblog">转嘟</string>
|
||||
<string name="action_favourite">收藏</string>
|
||||
<string name="action_more">更多</string>
|
||||
<string name="action_compose">发表新嘟文</string>
|
||||
<string name="action_login">登录 Mastodon 帐号</string>
|
||||
<string name="action_logout">登出</string>
|
||||
<string name="action_logout_confirm">确定要登出帐号 %1$s 吗?</string>
|
||||
<string name="action_logout">退出登录</string>
|
||||
<string name="action_logout_confirm">确定要退出帐号 %1$s 吗?</string>
|
||||
<string name="action_follow">关注</string>
|
||||
<string name="action_unfollow">取消关注</string>
|
||||
<string name="action_block">屏蔽</string>
|
||||
<string name="action_unblock">取消屏蔽</string>
|
||||
<string name="action_hide_reblogs">隐藏转嘟</string>
|
||||
<string name="action_show_reblogs">显示转嘟</string>
|
||||
<string name="action_report">报告</string>
|
||||
<string name="action_delete">删除</string>
|
||||
<string name="action_send">发嘟</string>
|
||||
@ -73,6 +82,7 @@
|
||||
<string name="action_close">关闭</string>
|
||||
<string name="action_view_profile">个人资料</string>
|
||||
<string name="action_view_preferences">设置</string>
|
||||
<string name="action_view_account_preferences">帐户设置</string>
|
||||
<string name="action_view_favourites">我的收藏</string>
|
||||
<string name="action_view_mutes">被隐藏的用户</string>
|
||||
<string name="action_view_blocks">被屏蔽的用户</string>
|
||||
@ -89,6 +99,7 @@
|
||||
<string name="action_open_drawer">打开应用抽屉</string>
|
||||
<string name="action_save">保存</string>
|
||||
<string name="action_edit_profile">编辑个人资料</string>
|
||||
<string name="action_edit_own_profile">编辑</string>
|
||||
<string name="action_undo">撤销</string>
|
||||
<string name="action_accept">接受</string>
|
||||
<string name="action_reject">拒绝</string>
|
||||
@ -104,10 +115,14 @@
|
||||
|
||||
<string name="send_status_link_to">分享链接到…</string>
|
||||
<string name="send_status_content_to">分享嘟文到…</string>
|
||||
<string name="send_media_to">分享媒体到…</string>
|
||||
|
||||
<string name="confirmation_reported">报告已发送!</string>
|
||||
<string name="confirmation_unblocked">用户已被屏蔽</string>
|
||||
<string name="confirmation_unmuted">用户已被隐藏</string>
|
||||
<string name="confirmation_unblocked">已解除屏蔽</string>
|
||||
<string name="confirmation_unmuted">已取消隐藏</string>
|
||||
|
||||
<string name="status_sent">已发送!</string>
|
||||
<string name="status_sent_long">成功发布回复。</string>
|
||||
|
||||
<string name="hint_domain">域名</string>
|
||||
<string name="hint_compose">有什么新鲜事?</string>
|
||||
@ -118,6 +133,7 @@
|
||||
|
||||
<string name="search_no_results">没找到结果</string>
|
||||
|
||||
<string name="label_quick_reply">回复…</string>
|
||||
<string name="label_avatar">头像</string>
|
||||
<string name="label_header">标题</string>
|
||||
|
||||
@ -125,15 +141,16 @@
|
||||
|
||||
<string name="login_connection">正在连接…</string>
|
||||
|
||||
<string name="dialog_whats_an_instance">请输入你帐号所在的 Mastodon 站点的域名,比如 mastodon.social,pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n还没有 Mastodon 帐号?你也可以输入想注册的实例的域名,然后在该实例创建新的帐号并授权 Tusky 登入。
|
||||
\n\n你帐号所在的 Mastodon 站点被称为 Mastodon 的一个「实例」(instance)。但是在 Mastodon 里,跨实例互动和站内互动一样简单。
|
||||
\n\n可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 了解更多信息。
|
||||
<string name="dialog_whats_an_instance">请输入你帐号所在的 Mastodon 站点的域名,比如 pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n还没有 Mastodon 帐号?你也可以输入想注册的 Mastodon 站点的域名,然后在该服务器创建新的帐号并授权 Tusky 登入。
|
||||
\n\n在 Mastodon 里,跨站互动和站内互动一样简单。可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 了解更多信息。
|
||||
</string>
|
||||
<string name="dialog_title_finishing_media_upload">正在结束上传…</string>
|
||||
<string name="dialog_message_uploading_media">正在上传…</string>
|
||||
<string name="dialog_download_image">下载</string>
|
||||
<string name="dialog_message_cancel_follow_request">移除关注请求?</string>
|
||||
<string name="dialog_unfollow_warning">不再关注此用户?</string>
|
||||
<string name="dialog_delete_toot_warning">删除这条嘟文?</string>
|
||||
|
||||
<string name="visibility_public">公开:所有人可见,并会出现在公共时间轴上</string>
|
||||
<string name="visibility_unlisted">不公开:所有人可见,但不会出现在公共时间轴上</string>
|
||||
@ -144,7 +161,6 @@
|
||||
<string name="pref_title_edit_notification_settings">通知设置</string>
|
||||
<string name="pref_title_notifications_enabled">通知</string>
|
||||
<string name="pref_summary_notifications">帐号 %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">检查间隔时间</string>
|
||||
<string name="pref_title_notification_alerts">提醒</string>
|
||||
<string name="pref_title_notification_alert_sound">通知铃声</string>
|
||||
<string name="pref_title_notification_alert_vibrate">振动</string>
|
||||
@ -156,6 +172,7 @@
|
||||
<string name="pref_title_notification_filter_favourites">嘟文被收藏</string>
|
||||
<string name="pref_title_appearance_settings">外观</string>
|
||||
<string name="pref_title_app_theme">应用主题</string>
|
||||
<string name="pref_title_timelines">时间线</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
<item>黑夜</item>
|
||||
@ -167,7 +184,7 @@
|
||||
<string name="pref_title_browser_settings">浏览器</string>
|
||||
<string name="pref_title_custom_tabs">使用 Chrome Custom Tabs</string>
|
||||
<string name="pref_title_hide_follow_button">浏览时自动隐藏发嘟按钮</string>
|
||||
<string name="pref_title_status_filter">时间轴过滤</string>
|
||||
<string name="pref_title_status_filter">时间线过滤</string>
|
||||
<string name="pref_title_status_tabs">选项卡</string>
|
||||
<string name="pref_title_show_boosts">显示转嘟</string>
|
||||
<string name="pref_title_show_replies">显示回复</string>
|
||||
@ -179,18 +196,9 @@
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理服务器</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP 代理端口</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 分钟</item>
|
||||
<item>20 分钟</item>
|
||||
<item>25 分钟</item>
|
||||
<item>30 分钟</item>
|
||||
<item>45 分钟</item>
|
||||
<item>1 小时</item>
|
||||
<item>2 小时</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">嘟文默认可见范围</string>
|
||||
<string name="pref_publishing">发布</string>
|
||||
<string name="pref_failed_to_sync">同步失败设置</string>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>公开</item>
|
||||
@ -200,11 +208,21 @@
|
||||
|
||||
<string name="pref_status_text_size">字体大小</string>
|
||||
|
||||
<!--<string-array name="status_text_size_names">-->
|
||||
<!--<item>小</item>-->
|
||||
<!--<item>中</item>-->
|
||||
<!--<item>大</item>-->
|
||||
<!--</string-array>-->
|
||||
<string-array name="status_text_size_names">
|
||||
<item>最小</item>
|
||||
<item>小</item>
|
||||
<item>标准</item>
|
||||
<item>大</item>
|
||||
<item>最大</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_media_display">媒体显示</string>
|
||||
|
||||
<string-array name="media_display_names">
|
||||
<item>自动隐藏敏感媒体</item>
|
||||
<item>总是显示敏感媒体</item>
|
||||
<item>总是隐藏所有媒体</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_channel_mention_name">被提及</string>
|
||||
<string name="notification_channel_mention_descriptions">当有用户在嘟文中提及我时</string>
|
||||
@ -270,7 +288,7 @@
|
||||
|
||||
<string name="action_lists">列表</string>
|
||||
<string name="title_lists">列表</string>
|
||||
<string name="title_list_timeline">列表公共时间轴</string>
|
||||
<string name="title_list_timeline">列表公共时间线</string>
|
||||
|
||||
<string name="compose_active_account_description">使用帐号 %1$s 发布嘟文</string>
|
||||
|
||||
@ -280,10 +298,52 @@
|
||||
<string name="lock_account_label">保护你的帐户(锁嘟)</string>
|
||||
<string name="lock_account_label_description">你需要手动审核所有关注请求</string>
|
||||
<string name="compose_save_draft">保存为草稿?</string>
|
||||
<string name="send_toot_notification_title">正在发送...</string>
|
||||
<string name="send_toot_notification_title">正在发送…</string>
|
||||
<string name="send_toot_notification_error_title">发送失败</string>
|
||||
<string name="send_toot_notification_channel_name">嘟文发送中</string>
|
||||
<string name="send_toot_notification_cancel_title">发送已被取消</string>
|
||||
<string name="send_toot_notification_saved_content">嘟文已保存到草稿</string>
|
||||
<string name="action_compose_shortcut">发表嘟文</string>
|
||||
|
||||
<string name="error_no_custom_emojis">当前服务器没有自定义的 Emoji 表情</string>
|
||||
<string name="copy_to_clipboard_success">已复制到剪贴板</string>
|
||||
<string name="emoji_style">Emoji 表情</string>
|
||||
<string name="system_default">系统默认</string>
|
||||
<string name="download_fonts">需要下载 Emoji 数据</string>
|
||||
<string name="performing_lookup_title">正在查找…</string>
|
||||
<string name="expand_collapse_all_statuses">展开/折叠所有嘟文</string>
|
||||
<string name="action_open_toot">打开嘟文</string>
|
||||
<string name="restart_required">需要重启应用</string>
|
||||
<string name="restart_emoji">你需要重启 Tusky 才能生效</string>
|
||||
<string name="later">以后</string>
|
||||
<string name="restart">立即重启</string>
|
||||
<string name="caption_systememoji">系统默认 Emoji 表情</string>
|
||||
<string name="caption_blobmoji">Android 4.4–7.1 的黄馒头 Emoji 表情</string>
|
||||
<string name="caption_twemoji">Mastodon 使用的 Emoji 表情</string>
|
||||
|
||||
<string name="download_failed">下载失败</string>
|
||||
|
||||
<string name="profile_badge_bot_text">Bot</string>
|
||||
<string name="account_moved_description">%1$s 已迁移到:</string>
|
||||
|
||||
<string name="reblog_private">转嘟(可见者不变)</string>
|
||||
<string name="unreblog_private">取消转嘟</string>
|
||||
|
||||
<string name="license_description">Tusky 使用了以下开源项目的源码:</string>
|
||||
<string name="license_apache_2">以 Apache License 授权(复制如下)</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
|
||||
<string name="profile_metadata_label">个人资料附加信息</string>
|
||||
<string name="profile_metadata_add">添加信息</string>
|
||||
<string name="profile_metadata_label_label">标签</string>
|
||||
<string name="profile_metadata_content_label">内容</string>
|
||||
|
||||
<string name="pref_title_absolute_time">嘟文显示精确时间</string>
|
||||
|
||||
<string name="label_remote_account">以下信息可能并不完整,要查看完整资料请使用浏览器打开。</string>
|
||||
|
||||
<string name="unpin_action">取消置顶</string>
|
||||
<string name="pin_action">置顶</string>
|
||||
|
||||
</resources>
|
||||
|
@ -3,13 +3,14 @@
|
||||
<string name="error_generic">應用程式出現異常。</string>
|
||||
<string name="error_empty">內容不能為空。</string>
|
||||
<string name="error_invalid_domain">該域名無效</string>
|
||||
<string name="error_failed_app_registration">無法連接到該實例。</string>
|
||||
<string name="error_failed_app_registration">無法連接此伺服器。</string>
|
||||
<string name="error_no_web_browser_found">沒有可用的瀏覽器。</string>
|
||||
<string name="error_authorization_unknown">認證過程出現未知錯誤。</string>
|
||||
<string name="error_authorization_denied">授權被拒絕。</string>
|
||||
<string name="error_retrieving_oauth_token">無法獲取登錄信息。</string>
|
||||
<string name="error_compose_character_limit">嘟文太長了!</string>
|
||||
<string name="error_image_upload_size">文件大小限制 8MB。</string>
|
||||
<string name="error_video_upload_size">視頻文件大小限制 40MB。</string>
|
||||
<string name="error_media_upload_type">無法上傳此類型的文件。</string>
|
||||
<string name="error_media_upload_opening">此文件無法打開。</string>
|
||||
<string name="error_media_upload_permission">需要授予 Tusky 讀取媒體文件的權限。</string>
|
||||
@ -17,24 +18,27 @@
|
||||
<string name="error_media_upload_image_or_video">無法在嘟文中同時插入視頻和圖片。</string>
|
||||
<string name="error_media_upload_sending">媒體文件上傳失敗。</string>
|
||||
<string name="error_report_too_few_statuses">至少要報告 1 則嘟文。</string>
|
||||
<string name="error_invalid_regex">正則表達式無效</string>
|
||||
<string name="error_invalid_regex">正規表示式無效</string>
|
||||
<string name="error_sender_account_gone">嘟文發送時出錯。</string>
|
||||
|
||||
<string name="title_home">主頁</string>
|
||||
<string name="title_advanced">高級</string>
|
||||
<string name="title_notifications">通知</string>
|
||||
<string name="title_public_local">本站時間軸</string>
|
||||
<string name="title_public_federated">跨站公共時間軸</string>
|
||||
<string name="title_public_federated">跨站公共時間缐</string>
|
||||
<string name="title_view_thread">嘟文</string>
|
||||
<string name="title_tag">#%s</string>
|
||||
<string name="title_statuses">嘟文</string>
|
||||
<string name="title_statuses_with_replies">嘟文和回覆</string>
|
||||
<string name="title_follows">正在關注</string>
|
||||
<string name="title_followers">關注者</string>
|
||||
<string name="title_favourites">我的收藏</string>
|
||||
<string name="title_mutes">被隱藏的用户</string>
|
||||
<string name="title_blocks">被屏蔽的用户</string>
|
||||
<string name="title_mutes">被隱藏的用戶</string>
|
||||
<string name="title_blocks">被屏蔽的用戶</string>
|
||||
<string name="title_follow_requests">關注請求</string>
|
||||
<string name="title_edit_profile">編輯個人資料</string>
|
||||
<string name="title_saved_toot">草稿</string>
|
||||
<string name="title_licenses">開源授權</string>
|
||||
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="status_boosted_format">%s 轉嘟了</string>
|
||||
@ -43,6 +47,8 @@
|
||||
<string name="status_sensitive_media_directions">點擊顯示</string>
|
||||
<string name="status_content_warning_show_more">顯示更多</string>
|
||||
<string name="status_content_warning_show_less">摺疊內容</string>
|
||||
<string name="status_content_show_less">摺疊</string>
|
||||
<string name="status_content_show_more">展開</string>
|
||||
|
||||
<string name="footer_empty">還沒有內容,向下滑動即可刷新。</string>
|
||||
|
||||
@ -50,21 +56,24 @@
|
||||
<string name="notification_favourite_format">%s 收藏了你的嘟文</string>
|
||||
<string name="notification_follow_format">%s 關注了你</string>
|
||||
|
||||
<string name="report_username_format">報告用户 @%s 的濫用行為</string>
|
||||
<string name="report_username_format">報告用戶 @%s 的濫用行為</string>
|
||||
<string name="report_comment_hint">報告更多信息</string>
|
||||
|
||||
<string name="action_quick_reply">快捷回覆</string>
|
||||
<string name="action_reply">回覆</string>
|
||||
<string name="action_reblog">轉嘟</string>
|
||||
<string name="action_favourite">收藏</string>
|
||||
<string name="action_more">更多</string>
|
||||
<string name="action_compose">發表新嘟文</string>
|
||||
<string name="action_login">登錄 Mastodon 帳號</string>
|
||||
<string name="action_logout">登出</string>
|
||||
<string name="action_logout_confirm">確定要登出帳號 %1$s 嗎?</string>
|
||||
<string name="action_logout">退出登錄</string>
|
||||
<string name="action_logout_confirm">確定要退出帳號 %1$s 嗎?</string>
|
||||
<string name="action_follow">關注</string>
|
||||
<string name="action_unfollow">取消關注</string>
|
||||
<string name="action_block">屏蔽</string>
|
||||
<string name="action_unblock">取消屏蔽</string>
|
||||
<string name="action_hide_reblogs">隱藏轉嘟</string>
|
||||
<string name="action_show_reblogs">顯示轉嘟</string>
|
||||
<string name="action_report">報告</string>
|
||||
<string name="action_delete">刪除</string>
|
||||
<string name="action_send">發嘟</string>
|
||||
@ -73,9 +82,10 @@
|
||||
<string name="action_close">關閉</string>
|
||||
<string name="action_view_profile">個人資料</string>
|
||||
<string name="action_view_preferences">設置</string>
|
||||
<string name="action_view_account_preferences">帳戶設置</string>
|
||||
<string name="action_view_favourites">我的收藏</string>
|
||||
<string name="action_view_mutes">被隱藏的用户</string>
|
||||
<string name="action_view_blocks">被屏蔽的用户</string>
|
||||
<string name="action_view_mutes">被隱藏的用戶</string>
|
||||
<string name="action_view_blocks">被屏蔽的用戶</string>
|
||||
<string name="action_view_follow_requests">關注請求</string>
|
||||
<string name="action_view_media">媒體</string>
|
||||
<string name="action_open_in_web">在瀏覽器中打開</string>
|
||||
@ -89,10 +99,11 @@
|
||||
<string name="action_open_drawer">打開應用抽屜</string>
|
||||
<string name="action_save">保存</string>
|
||||
<string name="action_edit_profile">編輯個人資料</string>
|
||||
<string name="action_edit_own_profile">編輯</string>
|
||||
<string name="action_undo">撤銷</string>
|
||||
<string name="action_accept">接受</string>
|
||||
<string name="action_reject">拒絕</string>
|
||||
<string name="action_search">搜索</string>
|
||||
<string name="action_search">搜尋</string>
|
||||
<string name="action_access_saved_toot">草稿</string>
|
||||
<string name="action_toggle_visibility">設置嘟文可見範圍</string>
|
||||
<string name="action_content_warning">設置內容提醒信息</string>
|
||||
@ -104,10 +115,14 @@
|
||||
|
||||
<string name="send_status_link_to">分享鏈接到…</string>
|
||||
<string name="send_status_content_to">分享嘟文到…</string>
|
||||
<string name="send_media_to">分享媒體到…</string>
|
||||
|
||||
<string name="confirmation_reported">報告已發送!</string>
|
||||
<string name="confirmation_unblocked">用户已被屏蔽</string>
|
||||
<string name="confirmation_unmuted">用户已被隱藏</string>
|
||||
<string name="confirmation_unblocked">已解除屏蔽</string>
|
||||
<string name="confirmation_unmuted">已取消隱藏</string>
|
||||
|
||||
<string name="status_sent">已發送!</string>
|
||||
<string name="status_sent_long">成功發佈回覆。</string>
|
||||
|
||||
<string name="hint_domain">域名</string>
|
||||
<string name="hint_compose">有什麼新鮮事?</string>
|
||||
@ -118,6 +133,7 @@
|
||||
|
||||
<string name="search_no_results">沒找到結果</string>
|
||||
|
||||
<string name="label_quick_reply">回覆…</string>
|
||||
<string name="label_avatar">頭像</string>
|
||||
<string name="label_header">標題</string>
|
||||
|
||||
@ -125,26 +141,26 @@
|
||||
|
||||
<string name="login_connection">正在連接…</string>
|
||||
|
||||
<string name="dialog_whats_an_instance">請輸入你帳號所在的 Mastodon 站點的域名,比如 mastodon.social,pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n還沒有 Mastodon 帳號?你也可以輸入想註冊的實例的域名,然後在該實例創建新的帳號並授權 Tusky 登入。
|
||||
\n\n你帳號所在的 Mastodon 站點被稱為 Mastodon 的一個「實例」(instance)。但是在 Mastodon 裏,跨實例互動和站內互動一樣簡單。
|
||||
\n\n可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 瞭解更多信息。
|
||||
<string name="dialog_whats_an_instance">請輸入你帳號所在的 Mastodon 站點的域名,比如 pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n還沒有 Mastodon 帳號?你也可以輸入想註冊的 Mastodon 站點的域名,然後在該伺服器創建新的帳號並授權 Tusky 登入。
|
||||
\n\n在 Mastodon 裡,跨站互動和站內互動一樣簡單。可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 瞭解更多信息。
|
||||
</string>
|
||||
<string name="dialog_title_finishing_media_upload">正在結束上傳…</string>
|
||||
<string name="dialog_message_uploading_media">正在上傳…</string>
|
||||
<string name="dialog_download_image">下載</string>
|
||||
<string name="dialog_unfollow_warning">不再關注此用户?</string>
|
||||
<string name="dialog_message_cancel_follow_request">移除關注請求?</string>
|
||||
<string name="dialog_unfollow_warning">不再關注此用戶?</string>
|
||||
<string name="dialog_delete_toot_warning">刪除這條嘟文?</string>
|
||||
|
||||
<string name="visibility_public">公開:所有人可見,並會出現在公共時間軸上</string>
|
||||
<string name="visibility_unlisted">不公開:所有人可見,但不會出現在公共時間軸上</string>
|
||||
<string name="visibility_private">僅關注者:只有經過你確認後關注你的用户可見</string>
|
||||
<string name="visibility_direct">私信:只有被提及的用户可見</string>
|
||||
<string name="visibility_private">僅關注者:只有經過你確認後關注你的用戶可見</string>
|
||||
<string name="visibility_direct">私信:只有被提及的用戶可見</string>
|
||||
|
||||
<string name="pref_title_notification_settings">通知</string>
|
||||
<string name="pref_title_edit_notification_settings">通知設置</string>
|
||||
<string name="pref_title_notifications_enabled">通知</string>
|
||||
<string name="pref_summary_notifications">帳號 %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">檢查間隔時間</string>
|
||||
<string name="pref_title_notification_alerts">提醒</string>
|
||||
<string name="pref_title_notification_alert_sound">通知鈴聲</string>
|
||||
<string name="pref_title_notification_alert_vibrate">振動</string>
|
||||
@ -156,6 +172,7 @@
|
||||
<string name="pref_title_notification_filter_favourites">嘟文被收藏</string>
|
||||
<string name="pref_title_appearance_settings">外觀</string>
|
||||
<string name="pref_title_app_theme">應用主題</string>
|
||||
<string name="pref_title_timelines">時間線</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
<item>黑夜</item>
|
||||
@ -167,30 +184,21 @@
|
||||
<string name="pref_title_browser_settings">瀏覽器</string>
|
||||
<string name="pref_title_custom_tabs">使用 Chrome Custom Tabs</string>
|
||||
<string name="pref_title_hide_follow_button">瀏覽時自動隱藏發嘟按鈕</string>
|
||||
<string name="pref_title_status_filter">時間軸過濾</string>
|
||||
<string name="pref_title_status_filter">時間線過濾</string>
|
||||
<string name="pref_title_status_tabs">選項卡</string>
|
||||
<string name="pref_title_show_boosts">顯示轉嘟</string>
|
||||
<string name="pref_title_show_replies">顯示回覆</string>
|
||||
<string name="pref_title_filter_regex">使用正則表達式過濾</string>
|
||||
<string name="pref_title_filter_regex">使用正規表示式過濾</string>
|
||||
<string name="pref_title_show_media_preview">顯示預覽圖</string>
|
||||
<string name="pref_title_proxy_settings">代理</string>
|
||||
<string name="pref_title_http_proxy_settings">HTTP 代理</string>
|
||||
<string name="pref_title_http_proxy_enable">啟用 HTTP 代理</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理服務器</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理伺服器</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP 代理端口</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 分鐘</item>
|
||||
<item>20 分鐘</item>
|
||||
<item>25 分鐘</item>
|
||||
<item>30 分鐘</item>
|
||||
<item>45 分鐘</item>
|
||||
<item>1 小時</item>
|
||||
<item>2 小時</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">嘟文默認可見範圍</string>
|
||||
<string name="pref_publishing">發佈</string>
|
||||
<string name="pref_failed_to_sync">同步失敗設置</string>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>公開</item>
|
||||
@ -200,20 +208,30 @@
|
||||
|
||||
<string name="pref_status_text_size">字體大小</string>
|
||||
|
||||
<!--<string-array name="status_text_size_names">-->
|
||||
<!--<item>小</item>-->
|
||||
<!--<item>中</item>-->
|
||||
<!--<item>大</item>-->
|
||||
<!--</string-array>-->
|
||||
<string-array name="status_text_size_names">
|
||||
<item>最小</item>
|
||||
<item>小</item>
|
||||
<item>標準</item>
|
||||
<item>大</item>
|
||||
<item>最大</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_media_display">媒體顯示</string>
|
||||
|
||||
<string-array name="media_display_names">
|
||||
<item>自動隱藏敏感媒體</item>
|
||||
<item>總是顯示敏感媒體</item>
|
||||
<item>總是隱藏所有媒體</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_channel_mention_name">被提及</string>
|
||||
<string name="notification_channel_mention_descriptions">當有用户在嘟文中提及我時</string>
|
||||
<string name="notification_channel_mention_descriptions">當有用戶在嘟文中提及我時</string>
|
||||
<string name="notification_channel_follow_name">關注者</string>
|
||||
<string name="notification_channel_follow_description">當有用户關注我時</string>
|
||||
<string name="notification_channel_follow_description">當有用戶關注我時</string>
|
||||
<string name="notification_channel_boost_name">轉嘟</string>
|
||||
<string name="notification_channel_boost_description">當有用户轉嘟了我的嘟文時</string>
|
||||
<string name="notification_channel_boost_description">當有用戶轉嘟了我的嘟文時</string>
|
||||
<string name="notification_channel_favourite_name">被收藏</string>
|
||||
<string name="notification_channel_favourite_description">當有用户收藏了我的嘟文時</string>
|
||||
<string name="notification_channel_favourite_description">當有用戶收藏了我的嘟文時</string>
|
||||
|
||||
|
||||
<string name="notification_mention_format">%s 提及了你</string>
|
||||
@ -270,20 +288,62 @@
|
||||
|
||||
<string name="action_lists">列表</string>
|
||||
<string name="title_lists">列表</string>
|
||||
<string name="title_list_timeline">列表公共時間軸</string>
|
||||
<string name="title_list_timeline">列表公共時間缐</string>
|
||||
|
||||
<string name="compose_active_account_description">使用帳號 %1$s 發佈嘟文</string>
|
||||
|
||||
<string name="error_failed_set_caption">設置圖片標題失敗。</string>
|
||||
<string name="action_set_caption">設置圖片標題</string>
|
||||
<string name="action_remove_media">移除</string>
|
||||
<string name="lock_account_label">保護你的帳户(鎖嘟)</string>
|
||||
<string name="lock_account_label">保護你的帳戶(鎖嘟)</string>
|
||||
<string name="lock_account_label_description">你需要手動審核所有關注請求</string>
|
||||
<string name="compose_save_draft">保存為草稿?</string>
|
||||
<string name="send_toot_notification_title">正在發送...</string>
|
||||
<string name="send_toot_notification_title">正在發送…</string>
|
||||
<string name="send_toot_notification_error_title">發送失敗</string>
|
||||
<string name="send_toot_notification_channel_name">嘟文發送中</string>
|
||||
<string name="send_toot_notification_cancel_title">發送已被取消</string>
|
||||
<string name="send_toot_notification_saved_content">嘟文已保存到草稿</string>
|
||||
<string name="action_compose_shortcut">發表嘟文</string>
|
||||
|
||||
<string name="error_no_custom_emojis">當前服務器沒有自定義的 Emoji 表情</string>
|
||||
<string name="copy_to_clipboard_success">已複製到剪貼板</string>
|
||||
<string name="emoji_style">Emoji 表情</string>
|
||||
<string name="system_default">系統默認</string>
|
||||
<string name="download_fonts">需要下載 Emoji 數據</string>
|
||||
<string name="performing_lookup_title">正在查找…</string>
|
||||
<string name="expand_collapse_all_statuses">展開/摺疊所有嘟文</string>
|
||||
<string name="action_open_toot">打開嘟文</string>
|
||||
<string name="restart_required">需要重啟應用</string>
|
||||
<string name="restart_emoji">你需要重啟 Tusky 才能生效</string>
|
||||
<string name="later">以後</string>
|
||||
<string name="restart">立即重啟</string>
|
||||
<string name="caption_systememoji">系統默認 Emoji 表情</string>
|
||||
<string name="caption_blobmoji">Android 4.4–7.1 的黃饅頭 Emoji 表情</string>
|
||||
<string name="caption_twemoji">Mastodon 使用的 Emoji 表情</string>
|
||||
|
||||
<string name="download_failed">下載失敗</string>
|
||||
|
||||
<string name="profile_badge_bot_text">Bot</string>
|
||||
<string name="account_moved_description">%1$s 已遷移到:</string>
|
||||
|
||||
<string name="reblog_private">轉嘟(可見者不變)</string>
|
||||
<string name="unreblog_private">取消轉嘟</string>
|
||||
|
||||
<string name="license_description">Tusky 使用了以下開源項目的源碼:</string>
|
||||
<string name="license_apache_2">以 Apache License 授權(複製如下)</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
|
||||
<string name="profile_metadata_label">个人资料附加信息</string>
|
||||
<string name="profile_metadata_add">添加信息</string>
|
||||
<string name="profile_metadata_label_label">標籤</string>
|
||||
<string name="profile_metadata_content_label">內容</string>
|
||||
|
||||
<string name="pref_title_absolute_time">嘟文顯示精確時間</string>
|
||||
|
||||
<string name="label_remote_account">以下信息可能並不完整,要查看完整資料請使用瀏覽器打開。</string>
|
||||
|
||||
<string name="unpin_action">取消置頂</string>
|
||||
<string name="pin_action">置頂</string>
|
||||
|
||||
</resources>
|
||||
|
@ -3,13 +3,14 @@
|
||||
<string name="error_generic">應用程式出現異常。</string>
|
||||
<string name="error_empty">內容不能為空。</string>
|
||||
<string name="error_invalid_domain">該域名無效</string>
|
||||
<string name="error_failed_app_registration">無法連接到該實例。</string>
|
||||
<string name="error_failed_app_registration">無法連接此伺服器。</string>
|
||||
<string name="error_no_web_browser_found">沒有可用的瀏覽器。</string>
|
||||
<string name="error_authorization_unknown">認證過程出現未知錯誤。</string>
|
||||
<string name="error_authorization_denied">授權被拒絕。</string>
|
||||
<string name="error_retrieving_oauth_token">無法獲取登錄信息。</string>
|
||||
<string name="error_compose_character_limit">嘟文太長了!</string>
|
||||
<string name="error_image_upload_size">文件大小限制 8MB。</string>
|
||||
<string name="error_video_upload_size">視頻文件大小限制 40MB。</string>
|
||||
<string name="error_media_upload_type">無法上傳此類型的文件。</string>
|
||||
<string name="error_media_upload_opening">此文件無法打開。</string>
|
||||
<string name="error_media_upload_permission">需要授予 Tusky 讀取媒體文件的權限。</string>
|
||||
@ -17,24 +18,27 @@
|
||||
<string name="error_media_upload_image_or_video">無法在嘟文中同時插入視頻和圖片。</string>
|
||||
<string name="error_media_upload_sending">媒體文件上傳失敗。</string>
|
||||
<string name="error_report_too_few_statuses">至少要報告 1 則嘟文。</string>
|
||||
<string name="error_invalid_regex">正則表達式無效</string>
|
||||
<string name="error_invalid_regex">正規表示式無效</string>
|
||||
<string name="error_sender_account_gone">嘟文發送時出錯。</string>
|
||||
|
||||
<string name="title_home">主頁</string>
|
||||
<string name="title_advanced">高級</string>
|
||||
<string name="title_notifications">通知</string>
|
||||
<string name="title_public_local">本站時間軸</string>
|
||||
<string name="title_public_federated">跨站公共時間軸</string>
|
||||
<string name="title_public_federated">跨站公共時間缐</string>
|
||||
<string name="title_view_thread">嘟文</string>
|
||||
<string name="title_tag">#%s</string>
|
||||
<string name="title_statuses">嘟文</string>
|
||||
<string name="title_statuses_with_replies">嘟文和回覆</string>
|
||||
<string name="title_follows">正在關注</string>
|
||||
<string name="title_followers">關注者</string>
|
||||
<string name="title_favourites">我的收藏</string>
|
||||
<string name="title_mutes">被隱藏的用户</string>
|
||||
<string name="title_blocks">被屏蔽的用户</string>
|
||||
<string name="title_mutes">被隱藏的用戶</string>
|
||||
<string name="title_blocks">被屏蔽的用戶</string>
|
||||
<string name="title_follow_requests">關注請求</string>
|
||||
<string name="title_edit_profile">編輯個人資料</string>
|
||||
<string name="title_saved_toot">草稿</string>
|
||||
<string name="title_licenses">開源授權</string>
|
||||
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="status_boosted_format">%s 轉嘟了</string>
|
||||
@ -43,6 +47,8 @@
|
||||
<string name="status_sensitive_media_directions">點擊顯示</string>
|
||||
<string name="status_content_warning_show_more">顯示更多</string>
|
||||
<string name="status_content_warning_show_less">摺疊內容</string>
|
||||
<string name="status_content_show_less">摺疊</string>
|
||||
<string name="status_content_show_more">展開</string>
|
||||
|
||||
<string name="footer_empty">還沒有內容,向下滑動即可刷新。</string>
|
||||
|
||||
@ -50,21 +56,24 @@
|
||||
<string name="notification_favourite_format">%s 收藏了你的嘟文</string>
|
||||
<string name="notification_follow_format">%s 關注了你</string>
|
||||
|
||||
<string name="report_username_format">報告用户 @%s 的濫用行為</string>
|
||||
<string name="report_username_format">報告用戶 @%s 的濫用行為</string>
|
||||
<string name="report_comment_hint">報告更多信息</string>
|
||||
|
||||
<string name="action_quick_reply">快捷回覆</string>
|
||||
<string name="action_reply">回覆</string>
|
||||
<string name="action_reblog">轉嘟</string>
|
||||
<string name="action_favourite">收藏</string>
|
||||
<string name="action_more">更多</string>
|
||||
<string name="action_compose">發表新嘟文</string>
|
||||
<string name="action_login">登錄 Mastodon 帳號</string>
|
||||
<string name="action_logout">登出</string>
|
||||
<string name="action_logout_confirm">確定要登出帳號 %1$s 嗎?</string>
|
||||
<string name="action_logout">退出登錄</string>
|
||||
<string name="action_logout_confirm">確定要退出帳號 %1$s 嗎?</string>
|
||||
<string name="action_follow">關注</string>
|
||||
<string name="action_unfollow">取消關注</string>
|
||||
<string name="action_block">屏蔽</string>
|
||||
<string name="action_unblock">取消屏蔽</string>
|
||||
<string name="action_hide_reblogs">隱藏轉嘟</string>
|
||||
<string name="action_show_reblogs">顯示轉嘟</string>
|
||||
<string name="action_report">報告</string>
|
||||
<string name="action_delete">刪除</string>
|
||||
<string name="action_send">發嘟</string>
|
||||
@ -73,9 +82,10 @@
|
||||
<string name="action_close">關閉</string>
|
||||
<string name="action_view_profile">個人資料</string>
|
||||
<string name="action_view_preferences">設置</string>
|
||||
<string name="action_view_account_preferences">帳戶設置</string>
|
||||
<string name="action_view_favourites">我的收藏</string>
|
||||
<string name="action_view_mutes">被隱藏的用户</string>
|
||||
<string name="action_view_blocks">被屏蔽的用户</string>
|
||||
<string name="action_view_mutes">被隱藏的用戶</string>
|
||||
<string name="action_view_blocks">被屏蔽的用戶</string>
|
||||
<string name="action_view_follow_requests">關注請求</string>
|
||||
<string name="action_view_media">媒體</string>
|
||||
<string name="action_open_in_web">在瀏覽器中打開</string>
|
||||
@ -89,10 +99,11 @@
|
||||
<string name="action_open_drawer">打開應用抽屜</string>
|
||||
<string name="action_save">保存</string>
|
||||
<string name="action_edit_profile">編輯個人資料</string>
|
||||
<string name="action_edit_own_profile">編輯</string>
|
||||
<string name="action_undo">撤銷</string>
|
||||
<string name="action_accept">接受</string>
|
||||
<string name="action_reject">拒絕</string>
|
||||
<string name="action_search">搜索</string>
|
||||
<string name="action_search">搜尋</string>
|
||||
<string name="action_access_saved_toot">草稿</string>
|
||||
<string name="action_toggle_visibility">設置嘟文可見範圍</string>
|
||||
<string name="action_content_warning">設置內容提醒信息</string>
|
||||
@ -104,10 +115,14 @@
|
||||
|
||||
<string name="send_status_link_to">分享鏈接到…</string>
|
||||
<string name="send_status_content_to">分享嘟文到…</string>
|
||||
<string name="send_media_to">分享媒體到…</string>
|
||||
|
||||
<string name="confirmation_reported">報告已發送!</string>
|
||||
<string name="confirmation_unblocked">用户已被屏蔽</string>
|
||||
<string name="confirmation_unmuted">用户已被隱藏</string>
|
||||
<string name="confirmation_unblocked">已解除屏蔽</string>
|
||||
<string name="confirmation_unmuted">已取消隱藏</string>
|
||||
|
||||
<string name="status_sent">已發送!</string>
|
||||
<string name="status_sent_long">成功發佈回覆。</string>
|
||||
|
||||
<string name="hint_domain">域名</string>
|
||||
<string name="hint_compose">有什麼新鮮事?</string>
|
||||
@ -118,6 +133,7 @@
|
||||
|
||||
<string name="search_no_results">沒找到結果</string>
|
||||
|
||||
<string name="label_quick_reply">回覆…</string>
|
||||
<string name="label_avatar">頭像</string>
|
||||
<string name="label_header">標題</string>
|
||||
|
||||
@ -125,26 +141,26 @@
|
||||
|
||||
<string name="login_connection">正在連接…</string>
|
||||
|
||||
<string name="dialog_whats_an_instance">請輸入你帳號所在的 Mastodon 站點的域名,比如 mastodon.social,pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n還沒有 Mastodon 帳號?你也可以輸入想註冊的實例的域名,然後在該實例創建新的帳號並授權 Tusky 登入。
|
||||
\n\n你帳號所在的 Mastodon 站點被稱為 Mastodon 的一個「實例」(instance)。但是在 Mastodon 裏,跨實例互動和站內互動一樣簡單。
|
||||
\n\n可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 瞭解更多信息。
|
||||
<string name="dialog_whats_an_instance">請輸入你帳號所在的 Mastodon 站點的域名,比如 pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n還沒有 Mastodon 帳號?你也可以輸入想註冊的 Mastodon 站點的域名,然後在該伺服器創建新的帳號並授權 Tusky 登入。
|
||||
\n\n在 Mastodon 裡,跨站互動和站內互動一樣簡單。可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 瞭解更多信息。
|
||||
</string>
|
||||
<string name="dialog_title_finishing_media_upload">正在結束上傳…</string>
|
||||
<string name="dialog_message_uploading_media">正在上傳…</string>
|
||||
<string name="dialog_download_image">下載</string>
|
||||
<string name="dialog_unfollow_warning">不再關注此用户?</string>
|
||||
<string name="dialog_message_cancel_follow_request">移除關注請求?</string>
|
||||
<string name="dialog_unfollow_warning">不再關注此用戶?</string>
|
||||
<string name="dialog_delete_toot_warning">刪除這條嘟文?</string>
|
||||
|
||||
<string name="visibility_public">公開:所有人可見,並會出現在公共時間軸上</string>
|
||||
<string name="visibility_unlisted">不公開:所有人可見,但不會出現在公共時間軸上</string>
|
||||
<string name="visibility_private">僅關注者:只有經過你確認後關注你的用户可見</string>
|
||||
<string name="visibility_direct">私信:只有被提及的用户可見</string>
|
||||
<string name="visibility_private">僅關注者:只有經過你確認後關注你的用戶可見</string>
|
||||
<string name="visibility_direct">私信:只有被提及的用戶可見</string>
|
||||
|
||||
<string name="pref_title_notification_settings">通知</string>
|
||||
<string name="pref_title_edit_notification_settings">通知設置</string>
|
||||
<string name="pref_title_notifications_enabled">通知</string>
|
||||
<string name="pref_summary_notifications">帳號 %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">檢查間隔時間</string>
|
||||
<string name="pref_title_notification_alerts">提醒</string>
|
||||
<string name="pref_title_notification_alert_sound">通知鈴聲</string>
|
||||
<string name="pref_title_notification_alert_vibrate">振動</string>
|
||||
@ -156,6 +172,7 @@
|
||||
<string name="pref_title_notification_filter_favourites">嘟文被收藏</string>
|
||||
<string name="pref_title_appearance_settings">外觀</string>
|
||||
<string name="pref_title_app_theme">應用主題</string>
|
||||
<string name="pref_title_timelines">時間線</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
<item>黑夜</item>
|
||||
@ -167,30 +184,21 @@
|
||||
<string name="pref_title_browser_settings">瀏覽器</string>
|
||||
<string name="pref_title_custom_tabs">使用 Chrome Custom Tabs</string>
|
||||
<string name="pref_title_hide_follow_button">瀏覽時自動隱藏發嘟按鈕</string>
|
||||
<string name="pref_title_status_filter">時間軸過濾</string>
|
||||
<string name="pref_title_status_filter">時間線過濾</string>
|
||||
<string name="pref_title_status_tabs">選項卡</string>
|
||||
<string name="pref_title_show_boosts">顯示轉嘟</string>
|
||||
<string name="pref_title_show_replies">顯示回覆</string>
|
||||
<string name="pref_title_filter_regex">使用正則表達式過濾</string>
|
||||
<string name="pref_title_filter_regex">使用正規表示式過濾</string>
|
||||
<string name="pref_title_show_media_preview">顯示預覽圖</string>
|
||||
<string name="pref_title_proxy_settings">代理</string>
|
||||
<string name="pref_title_http_proxy_settings">HTTP 代理</string>
|
||||
<string name="pref_title_http_proxy_enable">啟用 HTTP 代理</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理服務器</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理伺服器</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP 代理端口</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 分鐘</item>
|
||||
<item>20 分鐘</item>
|
||||
<item>25 分鐘</item>
|
||||
<item>30 分鐘</item>
|
||||
<item>45 分鐘</item>
|
||||
<item>1 小時</item>
|
||||
<item>2 小時</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">嘟文默認可見範圍</string>
|
||||
<string name="pref_publishing">發佈</string>
|
||||
<string name="pref_failed_to_sync">同步失敗設置</string>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>公開</item>
|
||||
@ -200,20 +208,30 @@
|
||||
|
||||
<string name="pref_status_text_size">字體大小</string>
|
||||
|
||||
<!--<string-array name="status_text_size_names">-->
|
||||
<!--<item>小</item>-->
|
||||
<!--<item>中</item>-->
|
||||
<!--<item>大</item>-->
|
||||
<!--</string-array>-->
|
||||
<string-array name="status_text_size_names">
|
||||
<item>最小</item>
|
||||
<item>小</item>
|
||||
<item>標準</item>
|
||||
<item>大</item>
|
||||
<item>最大</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_media_display">媒體顯示</string>
|
||||
|
||||
<string-array name="media_display_names">
|
||||
<item>自動隱藏敏感媒體</item>
|
||||
<item>總是顯示敏感媒體</item>
|
||||
<item>總是隱藏所有媒體</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_channel_mention_name">被提及</string>
|
||||
<string name="notification_channel_mention_descriptions">當有用户在嘟文中提及我時</string>
|
||||
<string name="notification_channel_mention_descriptions">當有用戶在嘟文中提及我時</string>
|
||||
<string name="notification_channel_follow_name">關注者</string>
|
||||
<string name="notification_channel_follow_description">當有用户關注我時</string>
|
||||
<string name="notification_channel_follow_description">當有用戶關注我時</string>
|
||||
<string name="notification_channel_boost_name">轉嘟</string>
|
||||
<string name="notification_channel_boost_description">當有用户轉嘟了我的嘟文時</string>
|
||||
<string name="notification_channel_boost_description">當有用戶轉嘟了我的嘟文時</string>
|
||||
<string name="notification_channel_favourite_name">被收藏</string>
|
||||
<string name="notification_channel_favourite_description">當有用户收藏了我的嘟文時</string>
|
||||
<string name="notification_channel_favourite_description">當有用戶收藏了我的嘟文時</string>
|
||||
|
||||
|
||||
<string name="notification_mention_format">%s 提及了你</string>
|
||||
@ -270,20 +288,62 @@
|
||||
|
||||
<string name="action_lists">列表</string>
|
||||
<string name="title_lists">列表</string>
|
||||
<string name="title_list_timeline">列表公共時間軸</string>
|
||||
<string name="title_list_timeline">列表公共時間缐</string>
|
||||
|
||||
<string name="compose_active_account_description">使用帳號 %1$s 發佈嘟文</string>
|
||||
|
||||
<string name="error_failed_set_caption">設置圖片標題失敗。</string>
|
||||
<string name="action_set_caption">設置圖片標題</string>
|
||||
<string name="action_remove_media">移除</string>
|
||||
<string name="lock_account_label">保護你的帳户(鎖嘟)</string>
|
||||
<string name="lock_account_label">保護你的帳戶(鎖嘟)</string>
|
||||
<string name="lock_account_label_description">你需要手動審核所有關注請求</string>
|
||||
<string name="compose_save_draft">保存為草稿?</string>
|
||||
<string name="send_toot_notification_title">正在發送...</string>
|
||||
<string name="send_toot_notification_title">正在發送…</string>
|
||||
<string name="send_toot_notification_error_title">發送失敗</string>
|
||||
<string name="send_toot_notification_channel_name">嘟文發送中</string>
|
||||
<string name="send_toot_notification_cancel_title">發送已被取消</string>
|
||||
<string name="send_toot_notification_saved_content">嘟文已保存到草稿</string>
|
||||
<string name="action_compose_shortcut">發表嘟文</string>
|
||||
|
||||
<string name="error_no_custom_emojis">當前服務器沒有自定義的 Emoji 表情</string>
|
||||
<string name="copy_to_clipboard_success">已複製到剪貼板</string>
|
||||
<string name="emoji_style">Emoji 表情</string>
|
||||
<string name="system_default">系統默認</string>
|
||||
<string name="download_fonts">需要下載 Emoji 數據</string>
|
||||
<string name="performing_lookup_title">正在查找…</string>
|
||||
<string name="expand_collapse_all_statuses">展開/摺疊所有嘟文</string>
|
||||
<string name="action_open_toot">打開嘟文</string>
|
||||
<string name="restart_required">需要重啟應用</string>
|
||||
<string name="restart_emoji">你需要重啟 Tusky 才能生效</string>
|
||||
<string name="later">以後</string>
|
||||
<string name="restart">立即重啟</string>
|
||||
<string name="caption_systememoji">系統默認 Emoji 表情</string>
|
||||
<string name="caption_blobmoji">Android 4.4–7.1 的黃饅頭 Emoji 表情</string>
|
||||
<string name="caption_twemoji">Mastodon 使用的 Emoji 表情</string>
|
||||
|
||||
<string name="download_failed">下載失敗</string>
|
||||
|
||||
<string name="profile_badge_bot_text">Bot</string>
|
||||
<string name="account_moved_description">%1$s 已遷移到:</string>
|
||||
|
||||
<string name="reblog_private">轉嘟(可見者不變)</string>
|
||||
<string name="unreblog_private">取消轉嘟</string>
|
||||
|
||||
<string name="license_description">Tusky 使用了以下開源項目的源碼:</string>
|
||||
<string name="license_apache_2">以 Apache License 授權(複製如下)</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
|
||||
<string name="profile_metadata_label">个人资料附加信息</string>
|
||||
<string name="profile_metadata_add">添加信息</string>
|
||||
<string name="profile_metadata_label_label">標籤</string>
|
||||
<string name="profile_metadata_content_label">內容</string>
|
||||
|
||||
<string name="pref_title_absolute_time">嘟文顯示精確時間</string>
|
||||
|
||||
<string name="label_remote_account">以下信息可能並不完整,要查看完整資料請使用瀏覽器打開。</string>
|
||||
|
||||
<string name="unpin_action">取消置頂</string>
|
||||
<string name="pin_action">置頂</string>
|
||||
|
||||
</resources>
|
||||
|
@ -3,13 +3,14 @@
|
||||
<string name="error_generic">应用程序出现异常。</string>
|
||||
<string name="error_empty">内容不能为空。</string>
|
||||
<string name="error_invalid_domain">该域名无效</string>
|
||||
<string name="error_failed_app_registration">无法连接到该实例。</string>
|
||||
<string name="error_failed_app_registration">无法连接此服务器。</string>
|
||||
<string name="error_no_web_browser_found">没有可用的浏览器。</string>
|
||||
<string name="error_authorization_unknown">认证过程出现未知错误。</string>
|
||||
<string name="error_authorization_denied">授权被拒绝。</string>
|
||||
<string name="error_retrieving_oauth_token">无法获取登录信息。</string>
|
||||
<string name="error_compose_character_limit">嘟文太长了!</string>
|
||||
<string name="error_image_upload_size">文件大小限制 8MB。</string>
|
||||
<string name="error_video_upload_size">视频文件大小限制 40MB。</string>
|
||||
<string name="error_media_upload_type">无法上传此类型的文件。</string>
|
||||
<string name="error_media_upload_opening">此文件无法打开。</string>
|
||||
<string name="error_media_upload_permission">需要授予 Tusky 读取媒体文件的权限。</string>
|
||||
@ -18,15 +19,17 @@
|
||||
<string name="error_media_upload_sending">媒体文件上传失败。</string>
|
||||
<string name="error_report_too_few_statuses">至少要报告 1 则嘟文。</string>
|
||||
<string name="error_invalid_regex">正则表达式无效</string>
|
||||
<string name="error_sender_account_gone">嘟文发送时出错。</string>
|
||||
|
||||
<string name="title_home">主页</string>
|
||||
<string name="title_advanced">高级</string>
|
||||
<string name="title_notifications">通知</string>
|
||||
<string name="title_public_local">本站时间轴</string>
|
||||
<string name="title_public_federated">跨站公共时间轴</string>
|
||||
<string name="title_public_federated">跨站公共时间线</string>
|
||||
<string name="title_view_thread">嘟文</string>
|
||||
<string name="title_tag">#%s</string>
|
||||
<string name="title_statuses">嘟文</string>
|
||||
<string name="title_statuses_with_replies">嘟文和回复</string>
|
||||
<string name="title_follows">正在关注</string>
|
||||
<string name="title_followers">关注者</string>
|
||||
<string name="title_favourites">我的收藏</string>
|
||||
@ -35,6 +38,7 @@
|
||||
<string name="title_follow_requests">关注请求</string>
|
||||
<string name="title_edit_profile">编辑个人资料</string>
|
||||
<string name="title_saved_toot">草稿</string>
|
||||
<string name="title_licenses">开源协议</string>
|
||||
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="status_boosted_format">%s 转嘟了</string>
|
||||
@ -43,6 +47,8 @@
|
||||
<string name="status_sensitive_media_directions">点击显示</string>
|
||||
<string name="status_content_warning_show_more">显示更多</string>
|
||||
<string name="status_content_warning_show_less">折叠内容</string>
|
||||
<string name="status_content_show_more">展开</string>
|
||||
<string name="status_content_show_less">折叠</string>
|
||||
|
||||
<string name="footer_empty">还没有内容,向下滑动即可刷新。</string>
|
||||
|
||||
@ -53,18 +59,21 @@
|
||||
<string name="report_username_format">报告用户 @%s 的滥用行为</string>
|
||||
<string name="report_comment_hint">报告更多信息</string>
|
||||
|
||||
<string name="action_quick_reply">快捷回复</string>
|
||||
<string name="action_reply">回复</string>
|
||||
<string name="action_reblog">转嘟</string>
|
||||
<string name="action_favourite">收藏</string>
|
||||
<string name="action_more">更多</string>
|
||||
<string name="action_compose">发表新嘟文</string>
|
||||
<string name="action_login">登录 Mastodon 帐号</string>
|
||||
<string name="action_logout">登出</string>
|
||||
<string name="action_logout_confirm">确定要登出帐号 %1$s 吗?</string>
|
||||
<string name="action_logout">退出登录</string>
|
||||
<string name="action_logout_confirm">确定要退出帐号 %1$s 吗?</string>
|
||||
<string name="action_follow">关注</string>
|
||||
<string name="action_unfollow">取消关注</string>
|
||||
<string name="action_block">屏蔽</string>
|
||||
<string name="action_unblock">取消屏蔽</string>
|
||||
<string name="action_hide_reblogs">隐藏转嘟</string>
|
||||
<string name="action_show_reblogs">显示转嘟</string>
|
||||
<string name="action_report">报告</string>
|
||||
<string name="action_delete">删除</string>
|
||||
<string name="action_send">发嘟</string>
|
||||
@ -73,6 +82,7 @@
|
||||
<string name="action_close">关闭</string>
|
||||
<string name="action_view_profile">个人资料</string>
|
||||
<string name="action_view_preferences">设置</string>
|
||||
<string name="action_view_account_preferences">帐户设置</string>
|
||||
<string name="action_view_favourites">我的收藏</string>
|
||||
<string name="action_view_mutes">被隐藏的用户</string>
|
||||
<string name="action_view_blocks">被屏蔽的用户</string>
|
||||
@ -89,6 +99,7 @@
|
||||
<string name="action_open_drawer">打开应用抽屉</string>
|
||||
<string name="action_save">保存</string>
|
||||
<string name="action_edit_profile">编辑个人资料</string>
|
||||
<string name="action_edit_own_profile">编辑</string>
|
||||
<string name="action_undo">撤销</string>
|
||||
<string name="action_accept">接受</string>
|
||||
<string name="action_reject">拒绝</string>
|
||||
@ -104,10 +115,14 @@
|
||||
|
||||
<string name="send_status_link_to">分享链接到…</string>
|
||||
<string name="send_status_content_to">分享嘟文到…</string>
|
||||
<string name="send_media_to">分享媒体到…</string>
|
||||
|
||||
<string name="confirmation_reported">报告已发送!</string>
|
||||
<string name="confirmation_unblocked">用户已被屏蔽</string>
|
||||
<string name="confirmation_unmuted">用户已被隐藏</string>
|
||||
<string name="confirmation_unblocked">已解除屏蔽</string>
|
||||
<string name="confirmation_unmuted">已取消隐藏</string>
|
||||
|
||||
<string name="status_sent">已发送!</string>
|
||||
<string name="status_sent_long">成功发布回复。</string>
|
||||
|
||||
<string name="hint_domain">域名</string>
|
||||
<string name="hint_compose">有什么新鲜事?</string>
|
||||
@ -118,6 +133,7 @@
|
||||
|
||||
<string name="search_no_results">没找到结果</string>
|
||||
|
||||
<string name="label_quick_reply">回复…</string>
|
||||
<string name="label_avatar">头像</string>
|
||||
<string name="label_header">标题</string>
|
||||
|
||||
@ -125,15 +141,16 @@
|
||||
|
||||
<string name="login_connection">正在连接…</string>
|
||||
|
||||
<string name="dialog_whats_an_instance">请输入你帐号所在的 Mastodon 站点的域名,比如 mastodon.social,pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n还没有 Mastodon 帐号?你也可以输入想注册的实例的域名,然后在该实例创建新的帐号并授权 Tusky 登入。
|
||||
\n\n你帐号所在的 Mastodon 站点被称为 Mastodon 的一个「实例」(instance)。但是在 Mastodon 里,跨实例互动和站内互动一样简单。
|
||||
\n\n可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 了解更多信息。
|
||||
<string name="dialog_whats_an_instance">请输入你帐号所在的 Mastodon 站点的域名,比如 pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n还没有 Mastodon 帐号?你也可以输入想注册的 Mastodon 站点的域名,然后在该服务器创建新的帐号并授权 Tusky 登入。
|
||||
\n\n在 Mastodon 里,跨站互动和站内互动一样简单。可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 了解更多信息。
|
||||
</string>
|
||||
<string name="dialog_title_finishing_media_upload">正在结束上传…</string>
|
||||
<string name="dialog_message_uploading_media">正在上传…</string>
|
||||
<string name="dialog_download_image">下载</string>
|
||||
<string name="dialog_message_cancel_follow_request">移除关注请求?</string>
|
||||
<string name="dialog_unfollow_warning">不再关注此用户?</string>
|
||||
<string name="dialog_delete_toot_warning">删除这条嘟文?</string>
|
||||
|
||||
<string name="visibility_public">公开:所有人可见,并会出现在公共时间轴上</string>
|
||||
<string name="visibility_unlisted">不公开:所有人可见,但不会出现在公共时间轴上</string>
|
||||
@ -144,7 +161,6 @@
|
||||
<string name="pref_title_edit_notification_settings">通知设置</string>
|
||||
<string name="pref_title_notifications_enabled">通知</string>
|
||||
<string name="pref_summary_notifications">帐号 %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">检查间隔时间</string>
|
||||
<string name="pref_title_notification_alerts">提醒</string>
|
||||
<string name="pref_title_notification_alert_sound">通知铃声</string>
|
||||
<string name="pref_title_notification_alert_vibrate">振动</string>
|
||||
@ -156,6 +172,7 @@
|
||||
<string name="pref_title_notification_filter_favourites">嘟文被收藏</string>
|
||||
<string name="pref_title_appearance_settings">外观</string>
|
||||
<string name="pref_title_app_theme">应用主题</string>
|
||||
<string name="pref_title_timelines">时间线</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
<item>黑夜</item>
|
||||
@ -167,7 +184,7 @@
|
||||
<string name="pref_title_browser_settings">浏览器</string>
|
||||
<string name="pref_title_custom_tabs">使用 Chrome Custom Tabs</string>
|
||||
<string name="pref_title_hide_follow_button">浏览时自动隐藏发嘟按钮</string>
|
||||
<string name="pref_title_status_filter">时间轴过滤</string>
|
||||
<string name="pref_title_status_filter">时间线过滤</string>
|
||||
<string name="pref_title_status_tabs">选项卡</string>
|
||||
<string name="pref_title_show_boosts">显示转嘟</string>
|
||||
<string name="pref_title_show_replies">显示回复</string>
|
||||
@ -179,18 +196,9 @@
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理服务器</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP 代理端口</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 分钟</item>
|
||||
<item>20 分钟</item>
|
||||
<item>25 分钟</item>
|
||||
<item>30 分钟</item>
|
||||
<item>45 分钟</item>
|
||||
<item>1 小时</item>
|
||||
<item>2 小时</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">嘟文默认可见范围</string>
|
||||
<string name="pref_publishing">发布</string>
|
||||
<string name="pref_failed_to_sync">同步失败设置</string>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>公开</item>
|
||||
@ -200,11 +208,21 @@
|
||||
|
||||
<string name="pref_status_text_size">字体大小</string>
|
||||
|
||||
<!--<string-array name="status_text_size_names">-->
|
||||
<!--<item>小</item>-->
|
||||
<!--<item>中</item>-->
|
||||
<!--<item>大</item>-->
|
||||
<!--</string-array>-->
|
||||
<string-array name="status_text_size_names">
|
||||
<item>最小</item>
|
||||
<item>小</item>
|
||||
<item>标准</item>
|
||||
<item>大</item>
|
||||
<item>最大</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_media_display">媒体显示</string>
|
||||
|
||||
<string-array name="media_display_names">
|
||||
<item>自动隐藏敏感媒体</item>
|
||||
<item>总是显示敏感媒体</item>
|
||||
<item>总是隐藏所有媒体</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_channel_mention_name">被提及</string>
|
||||
<string name="notification_channel_mention_descriptions">当有用户在嘟文中提及我时</string>
|
||||
@ -270,7 +288,7 @@
|
||||
|
||||
<string name="action_lists">列表</string>
|
||||
<string name="title_lists">列表</string>
|
||||
<string name="title_list_timeline">列表公共时间轴</string>
|
||||
<string name="title_list_timeline">列表公共时间线</string>
|
||||
|
||||
<string name="compose_active_account_description">使用帐号 %1$s 发布嘟文</string>
|
||||
|
||||
@ -280,10 +298,52 @@
|
||||
<string name="lock_account_label">保护你的帐户(锁嘟)</string>
|
||||
<string name="lock_account_label_description">你需要手动审核所有关注请求</string>
|
||||
<string name="compose_save_draft">保存为草稿?</string>
|
||||
<string name="send_toot_notification_title">正在发送...</string>
|
||||
<string name="send_toot_notification_title">正在发送…</string>
|
||||
<string name="send_toot_notification_error_title">发送失败</string>
|
||||
<string name="send_toot_notification_channel_name">嘟文发送中</string>
|
||||
<string name="send_toot_notification_cancel_title">发送已被取消</string>
|
||||
<string name="send_toot_notification_saved_content">嘟文已保存到草稿</string>
|
||||
<string name="action_compose_shortcut">发表嘟文</string>
|
||||
|
||||
<string name="error_no_custom_emojis">当前服务器没有自定义的 Emoji 表情</string>
|
||||
<string name="copy_to_clipboard_success">已复制到剪贴板</string>
|
||||
<string name="emoji_style">Emoji 表情</string>
|
||||
<string name="system_default">系统默认</string>
|
||||
<string name="download_fonts">需要下载 Emoji 数据</string>
|
||||
<string name="performing_lookup_title">正在查找…</string>
|
||||
<string name="expand_collapse_all_statuses">展开/折叠所有嘟文</string>
|
||||
<string name="action_open_toot">打开嘟文</string>
|
||||
<string name="restart_required">需要重启应用</string>
|
||||
<string name="restart_emoji">你需要重启 Tusky 才能生效</string>
|
||||
<string name="later">以后</string>
|
||||
<string name="restart">立即重启</string>
|
||||
<string name="caption_systememoji">系统默认 Emoji 表情</string>
|
||||
<string name="caption_blobmoji">Android 4.4–7.1 的黄馒头 Emoji 表情</string>
|
||||
<string name="caption_twemoji">Mastodon 使用的 Emoji 表情</string>
|
||||
|
||||
<string name="download_failed">下载失败</string>
|
||||
|
||||
<string name="profile_badge_bot_text">Bot</string>
|
||||
<string name="account_moved_description">%1$s 已迁移到:</string>
|
||||
|
||||
<string name="reblog_private">转嘟(可见者不变)</string>
|
||||
<string name="unreblog_private">取消转嘟</string>
|
||||
|
||||
<string name="license_description">Tusky 使用了以下开源项目的源码:</string>
|
||||
<string name="license_apache_2">以 Apache License 授权(复制如下)</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
|
||||
<string name="profile_metadata_label">个人资料附加信息</string>
|
||||
<string name="profile_metadata_add">添加信息</string>
|
||||
<string name="profile_metadata_label_label">标签</string>
|
||||
<string name="profile_metadata_content_label">内容</string>
|
||||
|
||||
<string name="pref_title_absolute_time">嘟文显示精确时间</string>
|
||||
|
||||
<string name="label_remote_account">以下信息可能并不完整,要查看完整资料请使用浏览器打开。</string>
|
||||
|
||||
<string name="unpin_action">取消置顶</string>
|
||||
<string name="pin_action">置顶</string>
|
||||
|
||||
</resources>
|
||||
|
@ -3,13 +3,14 @@
|
||||
<string name="error_generic">應用程式出現異常。</string>
|
||||
<string name="error_empty">內容不能為空。</string>
|
||||
<string name="error_invalid_domain">該域名無效</string>
|
||||
<string name="error_failed_app_registration">無法連接到該實例。</string>
|
||||
<string name="error_failed_app_registration">無法連接此伺服器。</string>
|
||||
<string name="error_no_web_browser_found">沒有可用的瀏覽器。</string>
|
||||
<string name="error_authorization_unknown">認證過程出現未知錯誤。</string>
|
||||
<string name="error_authorization_denied">授權被拒絕。</string>
|
||||
<string name="error_retrieving_oauth_token">無法獲取登錄信息。</string>
|
||||
<string name="error_compose_character_limit">嘟文太長了!</string>
|
||||
<string name="error_image_upload_size">文件大小限制 8MB。</string>
|
||||
<string name="error_video_upload_size">視頻文件大小限制 40MB。</string>
|
||||
<string name="error_media_upload_type">無法上傳此類型的文件。</string>
|
||||
<string name="error_media_upload_opening">此文件無法打開。</string>
|
||||
<string name="error_media_upload_permission">需要授予 Tusky 讀取媒體文件的權限。</string>
|
||||
@ -18,15 +19,17 @@
|
||||
<string name="error_media_upload_sending">媒體文件上傳失敗。</string>
|
||||
<string name="error_report_too_few_statuses">至少要報告 1 則嘟文。</string>
|
||||
<string name="error_invalid_regex">正規表示式無效</string>
|
||||
<string name="error_sender_account_gone">嘟文發送時出錯。</string>
|
||||
|
||||
<string name="title_home">主頁</string>
|
||||
<string name="title_advanced">高級</string>
|
||||
<string name="title_notifications">通知</string>
|
||||
<string name="title_public_local">本站時間軸</string>
|
||||
<string name="title_public_federated">跨站公共時間軸</string>
|
||||
<string name="title_public_federated">跨站公共時間缐</string>
|
||||
<string name="title_view_thread">嘟文</string>
|
||||
<string name="title_tag">#%s</string>
|
||||
<string name="title_statuses">嘟文</string>
|
||||
<string name="title_statuses_with_replies">嘟文和回覆</string>
|
||||
<string name="title_follows">正在關注</string>
|
||||
<string name="title_followers">關注者</string>
|
||||
<string name="title_favourites">我的收藏</string>
|
||||
@ -35,6 +38,7 @@
|
||||
<string name="title_follow_requests">關注請求</string>
|
||||
<string name="title_edit_profile">編輯個人資料</string>
|
||||
<string name="title_saved_toot">草稿</string>
|
||||
<string name="title_licenses">開源授權</string>
|
||||
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="status_boosted_format">%s 轉嘟了</string>
|
||||
@ -43,6 +47,8 @@
|
||||
<string name="status_sensitive_media_directions">點擊顯示</string>
|
||||
<string name="status_content_warning_show_more">顯示更多</string>
|
||||
<string name="status_content_warning_show_less">摺疊內容</string>
|
||||
<string name="status_content_show_less">摺疊</string>
|
||||
<string name="status_content_show_more">展開</string>
|
||||
|
||||
<string name="footer_empty">還沒有內容,向下滑動即可刷新。</string>
|
||||
|
||||
@ -53,18 +59,21 @@
|
||||
<string name="report_username_format">報告用戶 @%s 的濫用行為</string>
|
||||
<string name="report_comment_hint">報告更多信息</string>
|
||||
|
||||
<string name="action_quick_reply">快捷回覆</string>
|
||||
<string name="action_reply">回覆</string>
|
||||
<string name="action_reblog">轉嘟</string>
|
||||
<string name="action_favourite">收藏</string>
|
||||
<string name="action_more">更多</string>
|
||||
<string name="action_compose">發表新嘟文</string>
|
||||
<string name="action_login">登錄 Mastodon 帳號</string>
|
||||
<string name="action_logout">登出</string>
|
||||
<string name="action_logout_confirm">確定要登出帳號 %1$s 嗎?</string>
|
||||
<string name="action_logout">退出登錄</string>
|
||||
<string name="action_logout_confirm">確定要退出帳號 %1$s 嗎?</string>
|
||||
<string name="action_follow">關注</string>
|
||||
<string name="action_unfollow">取消關注</string>
|
||||
<string name="action_block">屏蔽</string>
|
||||
<string name="action_unblock">取消屏蔽</string>
|
||||
<string name="action_hide_reblogs">隱藏轉嘟</string>
|
||||
<string name="action_show_reblogs">顯示轉嘟</string>
|
||||
<string name="action_report">報告</string>
|
||||
<string name="action_delete">刪除</string>
|
||||
<string name="action_send">發嘟</string>
|
||||
@ -73,6 +82,7 @@
|
||||
<string name="action_close">關閉</string>
|
||||
<string name="action_view_profile">個人資料</string>
|
||||
<string name="action_view_preferences">設置</string>
|
||||
<string name="action_view_account_preferences">帳戶設置</string>
|
||||
<string name="action_view_favourites">我的收藏</string>
|
||||
<string name="action_view_mutes">被隱藏的用戶</string>
|
||||
<string name="action_view_blocks">被屏蔽的用戶</string>
|
||||
@ -89,10 +99,11 @@
|
||||
<string name="action_open_drawer">打開應用抽屜</string>
|
||||
<string name="action_save">保存</string>
|
||||
<string name="action_edit_profile">編輯個人資料</string>
|
||||
<string name="action_edit_own_profile">編輯</string>
|
||||
<string name="action_undo">撤銷</string>
|
||||
<string name="action_accept">接受</string>
|
||||
<string name="action_reject">拒絕</string>
|
||||
<string name="action_search">搜索</string>
|
||||
<string name="action_search">搜尋</string>
|
||||
<string name="action_access_saved_toot">草稿</string>
|
||||
<string name="action_toggle_visibility">設置嘟文可見範圍</string>
|
||||
<string name="action_content_warning">設置內容提醒信息</string>
|
||||
@ -104,10 +115,14 @@
|
||||
|
||||
<string name="send_status_link_to">分享鏈接到…</string>
|
||||
<string name="send_status_content_to">分享嘟文到…</string>
|
||||
<string name="send_media_to">分享媒體到…</string>
|
||||
|
||||
<string name="confirmation_reported">報告已發送!</string>
|
||||
<string name="confirmation_unblocked">用戶已被屏蔽</string>
|
||||
<string name="confirmation_unmuted">用戶已被隱藏</string>
|
||||
<string name="confirmation_unblocked">已解除屏蔽</string>
|
||||
<string name="confirmation_unmuted">已取消隱藏</string>
|
||||
|
||||
<string name="status_sent">已發送!</string>
|
||||
<string name="status_sent_long">成功發佈回覆。</string>
|
||||
|
||||
<string name="hint_domain">域名</string>
|
||||
<string name="hint_compose">有什麼新鮮事?</string>
|
||||
@ -118,6 +133,7 @@
|
||||
|
||||
<string name="search_no_results">沒找到結果</string>
|
||||
|
||||
<string name="label_quick_reply">回覆…</string>
|
||||
<string name="label_avatar">頭像</string>
|
||||
<string name="label_header">標題</string>
|
||||
|
||||
@ -125,15 +141,16 @@
|
||||
|
||||
<string name="login_connection">正在連接…</string>
|
||||
|
||||
<string name="dialog_whats_an_instance">請輸入你帳號所在的 Mastodon 站點的域名,比如 mastodon.social,pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n還沒有 Mastodon 帳號?你也可以輸入想註冊的實例的域名,然後在該實例創建新的帳號並授權 Tusky 登入。
|
||||
\n\n你帳號所在的 Mastodon 站點被稱為 Mastodon 的一個「實例」(instance)。但是在 Mastodon 裡,跨實例互動和站內互動一樣簡單。
|
||||
\n\n可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 瞭解更多信息。
|
||||
<string name="dialog_whats_an_instance">請輸入你帳號所在的 Mastodon 站點的域名,比如 pawoo.net,mstdn.jp,mao.daizhige.org,<a href="https://instances.social">等等</a> 。
|
||||
\n\n還沒有 Mastodon 帳號?你也可以輸入想註冊的 Mastodon 站點的域名,然後在該伺服器創建新的帳號並授權 Tusky 登入。
|
||||
\n\n在 Mastodon 裡,跨站互動和站內互動一樣簡單。可以前往 <a href="https://joinmastodon.org">https://joinmastodon.org</a> 瞭解更多信息。
|
||||
</string>
|
||||
<string name="dialog_title_finishing_media_upload">正在結束上傳…</string>
|
||||
<string name="dialog_message_uploading_media">正在上傳…</string>
|
||||
<string name="dialog_download_image">下載</string>
|
||||
<string name="dialog_message_cancel_follow_request">移除關注請求?</string>
|
||||
<string name="dialog_unfollow_warning">不再關注此用戶?</string>
|
||||
<string name="dialog_delete_toot_warning">刪除這條嘟文?</string>
|
||||
|
||||
<string name="visibility_public">公開:所有人可見,並會出現在公共時間軸上</string>
|
||||
<string name="visibility_unlisted">不公開:所有人可見,但不會出現在公共時間軸上</string>
|
||||
@ -144,7 +161,6 @@
|
||||
<string name="pref_title_edit_notification_settings">通知設置</string>
|
||||
<string name="pref_title_notifications_enabled">通知</string>
|
||||
<string name="pref_summary_notifications">帳號 %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">檢查間隔時間</string>
|
||||
<string name="pref_title_notification_alerts">提醒</string>
|
||||
<string name="pref_title_notification_alert_sound">通知鈴聲</string>
|
||||
<string name="pref_title_notification_alert_vibrate">振動</string>
|
||||
@ -156,6 +172,7 @@
|
||||
<string name="pref_title_notification_filter_favourites">嘟文被收藏</string>
|
||||
<string name="pref_title_appearance_settings">外觀</string>
|
||||
<string name="pref_title_app_theme">應用主題</string>
|
||||
<string name="pref_title_timelines">時間線</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
<item>黑夜</item>
|
||||
@ -167,7 +184,7 @@
|
||||
<string name="pref_title_browser_settings">瀏覽器</string>
|
||||
<string name="pref_title_custom_tabs">使用 Chrome Custom Tabs</string>
|
||||
<string name="pref_title_hide_follow_button">瀏覽時自動隱藏發嘟按鈕</string>
|
||||
<string name="pref_title_status_filter">時間軸過濾</string>
|
||||
<string name="pref_title_status_filter">時間線過濾</string>
|
||||
<string name="pref_title_status_tabs">選項卡</string>
|
||||
<string name="pref_title_show_boosts">顯示轉嘟</string>
|
||||
<string name="pref_title_show_replies">顯示回覆</string>
|
||||
@ -176,21 +193,12 @@
|
||||
<string name="pref_title_proxy_settings">代理</string>
|
||||
<string name="pref_title_http_proxy_settings">HTTP 代理</string>
|
||||
<string name="pref_title_http_proxy_enable">啟用 HTTP 代理</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理服務器</string>
|
||||
<string name="pref_title_http_proxy_server">HTTP 代理伺服器</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP 代理端口</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 分鐘</item>
|
||||
<item>20 分鐘</item>
|
||||
<item>25 分鐘</item>
|
||||
<item>30 分鐘</item>
|
||||
<item>45 分鐘</item>
|
||||
<item>1 小時</item>
|
||||
<item>2 小時</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">嘟文默認可見範圍</string>
|
||||
<string name="pref_publishing">發佈</string>
|
||||
<string name="pref_failed_to_sync">同步失敗設置</string>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>公開</item>
|
||||
@ -200,11 +208,21 @@
|
||||
|
||||
<string name="pref_status_text_size">字體大小</string>
|
||||
|
||||
<!--<string-array name="status_text_size_names">-->
|
||||
<!--<item>小</item>-->
|
||||
<!--<item>中</item>-->
|
||||
<!--<item>大</item>-->
|
||||
<!--</string-array>-->
|
||||
<string-array name="status_text_size_names">
|
||||
<item>最小</item>
|
||||
<item>小</item>
|
||||
<item>標準</item>
|
||||
<item>大</item>
|
||||
<item>最大</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_media_display">媒體顯示</string>
|
||||
|
||||
<string-array name="media_display_names">
|
||||
<item>自動隱藏敏感媒體</item>
|
||||
<item>總是顯示敏感媒體</item>
|
||||
<item>總是隱藏所有媒體</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_channel_mention_name">被提及</string>
|
||||
<string name="notification_channel_mention_descriptions">當有用戶在嘟文中提及我時</string>
|
||||
@ -270,7 +288,7 @@
|
||||
|
||||
<string name="action_lists">列表</string>
|
||||
<string name="title_lists">列表</string>
|
||||
<string name="title_list_timeline">列表公共時間軸</string>
|
||||
<string name="title_list_timeline">列表公共時間缐</string>
|
||||
|
||||
<string name="compose_active_account_description">使用帳號 %1$s 發佈嘟文</string>
|
||||
|
||||
@ -280,10 +298,52 @@
|
||||
<string name="lock_account_label">保護你的帳戶(鎖嘟)</string>
|
||||
<string name="lock_account_label_description">你需要手動審核所有關注請求</string>
|
||||
<string name="compose_save_draft">保存為草稿?</string>
|
||||
<string name="send_toot_notification_title">正在發送...</string>
|
||||
<string name="send_toot_notification_title">正在發送…</string>
|
||||
<string name="send_toot_notification_error_title">發送失敗</string>
|
||||
<string name="send_toot_notification_channel_name">嘟文發送中</string>
|
||||
<string name="send_toot_notification_cancel_title">發送已被取消</string>
|
||||
<string name="send_toot_notification_saved_content">嘟文已保存到草稿</string>
|
||||
<string name="action_compose_shortcut">發表嘟文</string>
|
||||
|
||||
<string name="error_no_custom_emojis">當前服務器沒有自定義的 Emoji 表情</string>
|
||||
<string name="copy_to_clipboard_success">已複製到剪貼板</string>
|
||||
<string name="emoji_style">Emoji 表情</string>
|
||||
<string name="system_default">系統默認</string>
|
||||
<string name="download_fonts">需要下載 Emoji 數據</string>
|
||||
<string name="performing_lookup_title">正在查找…</string>
|
||||
<string name="expand_collapse_all_statuses">展開/摺疊所有嘟文</string>
|
||||
<string name="action_open_toot">打開嘟文</string>
|
||||
<string name="restart_required">需要重啟應用</string>
|
||||
<string name="restart_emoji">你需要重啟 Tusky 才能生效</string>
|
||||
<string name="later">以後</string>
|
||||
<string name="restart">立即重啟</string>
|
||||
<string name="caption_systememoji">系統默認 Emoji 表情</string>
|
||||
<string name="caption_blobmoji">Android 4.4–7.1 的黃饅頭 Emoji 表情</string>
|
||||
<string name="caption_twemoji">Mastodon 使用的 Emoji 表情</string>
|
||||
|
||||
<string name="download_failed">下載失敗</string>
|
||||
|
||||
<string name="profile_badge_bot_text">Bot</string>
|
||||
<string name="account_moved_description">%1$s 已遷移到:</string>
|
||||
|
||||
<string name="reblog_private">轉嘟(可見者不變)</string>
|
||||
<string name="unreblog_private">取消轉嘟</string>
|
||||
|
||||
<string name="license_description">Tusky 使用了以下開源項目的源碼:</string>
|
||||
<string name="license_apache_2">以 Apache License 授權(複製如下)</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
|
||||
<string name="profile_metadata_label">个人资料附加信息</string>
|
||||
<string name="profile_metadata_add">添加信息</string>
|
||||
<string name="profile_metadata_label_label">標籤</string>
|
||||
<string name="profile_metadata_content_label">內容</string>
|
||||
|
||||
<string name="pref_title_absolute_time">嘟文顯示精確時間</string>
|
||||
|
||||
<string name="label_remote_account">以下信息可能並不完整,要查看完整資料請使用瀏覽器打開。</string>
|
||||
|
||||
<string name="unpin_action">取消置頂</string>
|
||||
<string name="pin_action">置頂</string>
|
||||
|
||||
</resources>
|
||||
|
@ -30,4 +30,5 @@
|
||||
|
||||
<item name="wrap_content" format="integer" type="dimen">-2</item>
|
||||
|
||||
<dimen name="preference_icon_size">20dp</dimen>
|
||||
</resources>
|
||||
|
@ -8,16 +8,6 @@
|
||||
|
||||
<string name="status_sensitive_media_template" translatable="false"><b>%1$s</b><br>%2$s</string>
|
||||
|
||||
<string-array name="pull_notification_check_intervals" inputType="integer">
|
||||
<item>15</item>
|
||||
<item>20</item>
|
||||
<item>25</item>
|
||||
<item>30</item>
|
||||
<item>45</item>
|
||||
<item>60</item>
|
||||
<item>120</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="post_privacy_values">
|
||||
<item>public</item>
|
||||
<item>unlisted</item>
|
||||
|
@ -82,6 +82,7 @@
|
||||
<string name="action_close">Close</string>
|
||||
<string name="action_view_profile">Profile</string>
|
||||
<string name="action_view_preferences">Preferences</string>
|
||||
<string name="action_view_account_preferences">Account Preferences</string>
|
||||
<string name="action_view_favourites">Favourites</string>
|
||||
<string name="action_view_mutes">Muted users</string>
|
||||
<string name="action_view_blocks">Blocked users</string>
|
||||
@ -162,10 +163,9 @@
|
||||
<string name="visibility_direct">Direct: Post to mentioned users only</string>
|
||||
|
||||
<string name="pref_title_notification_settings">Notifications</string>
|
||||
<string name="pref_title_edit_notification_settings">Edit Notifications</string>
|
||||
<string name="pref_title_edit_notification_settings">Notifications</string>
|
||||
<string name="pref_title_notifications_enabled">Notifications</string>
|
||||
<string name="pref_summary_notifications">for account %1$s</string>
|
||||
<string name="pref_title_pull_notification_check_interval">Check Interval</string>
|
||||
<string name="pref_title_notification_alerts">Alerts</string>
|
||||
<string name="pref_title_notification_alert_sound">Notify with a sound</string>
|
||||
<string name="pref_title_notification_alert_vibrate">Notify with vibration</string>
|
||||
@ -177,6 +177,7 @@
|
||||
<string name="pref_title_notification_filter_favourites">my posts are favourited</string>
|
||||
<string name="pref_title_appearance_settings">Appearance</string>
|
||||
<string name="pref_title_app_theme">App Theme</string>
|
||||
<string name="pref_title_timelines">Timelines</string>
|
||||
|
||||
<string-array name="app_theme_names">
|
||||
<item>Dark</item>
|
||||
@ -200,18 +201,9 @@
|
||||
<string name="pref_title_http_proxy_server">HTTP proxy server</string>
|
||||
<string name="pref_title_http_proxy_port">HTTP proxy port</string>
|
||||
|
||||
<string-array name="pull_notification_check_interval_names">
|
||||
<item>15 minutes</item>
|
||||
<item>20 minutes</item>
|
||||
<item>25 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>45 minutes</item>
|
||||
<item>1 hour</item>
|
||||
<item>2 hours</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_default_post_privacy">Default post privacy</string>
|
||||
<string name="pref_publishing">Publishing</string>
|
||||
<string name="pref_publishing">Publishing (synced with server)</string>
|
||||
<string name="pref_failed_to_sync">Failed to sync settings</string>
|
||||
|
||||
<string-array name="post_privacy_names">
|
||||
<item>Public</item>
|
||||
@ -229,6 +221,14 @@
|
||||
<item>Largest</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_media_display">Media display</string>
|
||||
|
||||
<string-array name="media_display_names">
|
||||
<item>Hide media marked as sensitive</item>
|
||||
<item>Always show media marked as sensitive</item>
|
||||
<item>Always hide all media</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_channel_mention_name">New Mentions</string>
|
||||
<string name="notification_channel_mention_descriptions">Notifications about new mentions</string>
|
||||
<string name="notification_channel_follow_name">New Followers</string>
|
||||
|
@ -127,6 +127,8 @@
|
||||
|
||||
<item name="compound_button_color">@color/compound_button_color_light</item>
|
||||
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.ImageButton.Light" parent="Widget.AppCompat.Button.Borderless.Colored">
|
||||
|
47
app/src/main/res/xml/account_preferences.xml
Normal file
47
app/src/main/res/xml/account_preferences.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="@string/preferences_file_key">
|
||||
|
||||
<Preference
|
||||
android:key="notificationPreference"
|
||||
android:title="@string/pref_title_edit_notification_settings" />
|
||||
|
||||
<Preference
|
||||
android:key="mutedUsersPreference"
|
||||
android:title="@string/action_view_mutes" />
|
||||
|
||||
<Preference
|
||||
android:key="blockedUsersPreference"
|
||||
android:title="@string/action_view_blocks" />
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_publishing">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="public"
|
||||
android:entries="@array/post_privacy_names"
|
||||
android:entryValues="@array/post_privacy_values"
|
||||
android:key="defaultPostPrivacy"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_default_post_privacy" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_eye_24dp"
|
||||
android:key="defaultMediaSensitivity"
|
||||
android:title="Always mark media as sensitive" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_timelines">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="mediaPreviewEnabled"
|
||||
android:title="@string/pref_title_show_media_preview" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="alwaysShowSensitiveMedia"
|
||||
android:title="@string/pref_title_alway_show_sensitive_media" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
@ -1,18 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen android:title="@string/pref_title_http_proxy_settings"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/pref_title_http_proxy_settings">
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="httpProxyEnabled"
|
||||
android:title="@string/pref_title_http_proxy_enable" />
|
||||
android:title="@string/pref_title_http_proxy_enable"
|
||||
app:iconSpaceReserved="false" />
|
||||
<EditTextPreference
|
||||
android:key="httpProxyServer"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_http_proxy_server"
|
||||
android:summary="%s" />
|
||||
app:iconSpaceReserved="false" />
|
||||
<EditTextPreference
|
||||
android:key="httpProxyPort"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_http_proxy_port"
|
||||
android:summary="%s" />
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceScreen>
|
@ -1,57 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen android:key="notificationSettings"
|
||||
android:title="@string/pref_title_edit_notification_settings"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="notificationSettings"
|
||||
android:title="@string/pref_title_edit_notification_settings">
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationsEnabled"
|
||||
android:title="@string/pref_title_notifications_enabled" />
|
||||
android:title="@string/pref_title_notifications_enabled"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:dependency="notificationsEnabled"
|
||||
android:title="@string/pref_title_notification_filters">
|
||||
android:title="@string/pref_title_notification_filters"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterMentions"
|
||||
android:title="@string/pref_title_notification_filter_mentions" />
|
||||
android:title="@string/pref_title_notification_filter_mentions"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterFollows"
|
||||
android:title="@string/pref_title_notification_filter_follows" />
|
||||
android:title="@string/pref_title_notification_filter_follows"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterReblogs"
|
||||
android:title="@string/pref_title_notification_filter_reblogs" />
|
||||
android:title="@string/pref_title_notification_filter_reblogs"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterFavourites"
|
||||
android:title="@string/pref_title_notification_filter_favourites" />
|
||||
android:title="@string/pref_title_notification_filter_favourites"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:dependency="notificationsEnabled"
|
||||
android:title="@string/pref_title_notification_alerts">
|
||||
android:title="@string/pref_title_notification_alerts"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationAlertSound"
|
||||
android:title="@string/pref_title_notification_alert_sound" />
|
||||
android:title="@string/pref_title_notification_alert_sound"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationAlertVibrate"
|
||||
android:title="@string/pref_title_notification_alert_vibrate" />
|
||||
android:title="@string/pref_title_notification_alert_vibrate"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notificationAlertLight"
|
||||
android:title="@string/pref_title_notification_alert_light" />
|
||||
android:title="@string/pref_title_notification_alert_light"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="@string/preferences_file_key">
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_appearance_settings">
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_appearance_settings">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="night"
|
||||
@ -16,7 +18,8 @@
|
||||
android:defaultValue="@string/system_default"
|
||||
android:key="emojiCompat"
|
||||
android:summary="@string/system_default"
|
||||
android:title="@string/emoji_style"/>
|
||||
android:icon="@drawable/ic_emoji_24dp"
|
||||
android:title="@string/emoji_style" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="medium"
|
||||
@ -31,64 +34,31 @@
|
||||
android:key="fabHide"
|
||||
android:title="@string/pref_title_hide_follow_button" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="mediaPreviewEnabled"
|
||||
android:title="@string/pref_title_show_media_preview" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:dependency="mediaPreviewEnabled"
|
||||
android:key="alwaysShowSensitiveMedia"
|
||||
android:title="@string/pref_title_alway_show_sensitive_media" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="absoluteTimeView"
|
||||
android:title="@string/pref_title_absolute_time" />
|
||||
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_publishing">
|
||||
<ListPreference
|
||||
android:defaultValue="public"
|
||||
android:entries="@array/post_privacy_names"
|
||||
android:entryValues="@array/post_privacy_values"
|
||||
android:key="defaultPostPrivacy"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_default_post_privacy" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_browser_settings">
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_browser_settings">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="customTabs"
|
||||
android:title="@string/pref_title_custom_tabs" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_status_filter">
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_status_filter">
|
||||
<Preference
|
||||
android:key="timelineFilterPreferences"
|
||||
android:title="@string/pref_title_status_tabs" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_notification_settings">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="15"
|
||||
android:entries="@array/pull_notification_check_interval_names"
|
||||
android:entryValues="@array/pull_notification_check_intervals"
|
||||
android:key="pullNotificationCheckInterval"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_pull_notification_check_interval" />
|
||||
|
||||
<Preference
|
||||
android:key="notificationPreferences"
|
||||
android:title="@string/pref_title_edit_notification_settings" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_proxy_settings">
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_proxy_settings">
|
||||
<Preference
|
||||
android:key="httpProxyPreferences"
|
||||
android:summary="%s"
|
||||
|
@ -1,23 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen android:title="@string/pref_title_status_tabs"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/pref_title_status_tabs">
|
||||
|
||||
<PreferenceCategory android:title="@string/title_home">
|
||||
<PreferenceCategory
|
||||
android:title="@string/title_home"
|
||||
app:iconSpaceReserved="false">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="tabFilterHomeBoosts"
|
||||
android:title="@string/pref_title_show_boosts" />
|
||||
android:title="@string/pref_title_show_boosts"
|
||||
app:iconSpaceReserved="false" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="tabFilterHomeReplies"
|
||||
android:title="@string/pref_title_show_replies" />
|
||||
android:title="@string/pref_title_show_replies"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/title_advanced">
|
||||
<EditTextPreference
|
||||
android:key="tabFilterRegex"
|
||||
<PreferenceCategory
|
||||
android:title="@string/title_advanced"
|
||||
app:iconSpaceReserved="false">
|
||||
<Preference
|
||||
android:inputType="textNoSuggestions"
|
||||
android:title="@string/pref_title_filter_regex" />
|
||||
android:key="tabFilterRegex"
|
||||
android:title="@string/pref_title_filter_regex"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user