Merge pull request #4589 from k9mail/refactor_manage_folders
Refactor 'manage folders' and 'folder settings' screens
This commit is contained in:
commit
231f54955d
17 changed files with 424 additions and 434 deletions
|
@ -145,11 +145,6 @@
|
|||
android:configChanges="keyboardHidden|orientation|locale"
|
||||
android:label="@string/account_setup_check_settings_title"/>
|
||||
|
||||
<activity
|
||||
android:name="com.fsck.k9.activity.setup.FolderSettings"
|
||||
android:configChanges="locale"
|
||||
android:label="@string/folder_settings_title"/>
|
||||
|
||||
<activity
|
||||
android:name="com.fsck.k9.ui.endtoend.AutocryptKeyTransferActivity"
|
||||
android:configChanges="locale"
|
||||
|
|
|
@ -171,11 +171,6 @@
|
|||
android:configChanges="keyboardHidden|orientation|locale"
|
||||
android:label="@string/account_setup_check_settings_title"/>
|
||||
|
||||
<activity
|
||||
android:name=".activity.setup.FolderSettings"
|
||||
android:configChanges="locale"
|
||||
android:label="@string/folder_settings_title"/>
|
||||
|
||||
<activity
|
||||
android:name=".ui.endtoend.AutocryptKeyTransferActivity"
|
||||
android:configChanges="locale"
|
||||
|
|
|
@ -23,6 +23,7 @@ dependencies {
|
|||
implementation "com.takisoft.preferencex:preferencex-ringtone:${versions.preferencesFix}"
|
||||
implementation "androidx.recyclerview:recyclerview:${versions.androidxRecyclerView}"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidxLifecycle}"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.androidxLifecycle}"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:${versions.androidxNavigation}"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:${versions.androidxNavigation}"
|
||||
implementation "androidx.constraintlayout:constraintlayout:${versions.androidxConstraintLayout}"
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
|
||||
package com.fsck.k9.activity.setup;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mailstore.Folder;
|
||||
import com.fsck.k9.mailstore.FolderType;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.activity.FolderInfoHolder;
|
||||
import com.fsck.k9.activity.K9PreferenceActivity;
|
||||
import com.fsck.k9.controller.MessagingController;
|
||||
import com.fsck.k9.job.K9JobManager;
|
||||
import com.fsck.k9.mail.FolderClass;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.ui.folders.FolderNameFormatter;
|
||||
import com.fsck.k9.ui.folders.FolderNameFormatterFactory;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class FolderSettings extends K9PreferenceActivity {
|
||||
|
||||
private static final String EXTRA_FOLDER_NAME = "com.fsck.k9.folderName";
|
||||
private static final String EXTRA_ACCOUNT = "com.fsck.k9.account";
|
||||
|
||||
private static final String PREFERENCE_TOP_CATERGORY = "folder_settings";
|
||||
private static final String PREFERENCE_DISPLAY_CLASS = "folder_settings_folder_display_mode";
|
||||
private static final String PREFERENCE_SYNC_CLASS = "folder_settings_folder_sync_mode";
|
||||
private static final String PREFERENCE_PUSH_CLASS = "folder_settings_folder_push_mode";
|
||||
private static final String PREFERENCE_NOTIFY_CLASS = "folder_settings_folder_notify_mode";
|
||||
private static final String PREFERENCE_IN_TOP_GROUP = "folder_settings_in_top_group";
|
||||
private static final String PREFERENCE_INTEGRATE = "folder_settings_include_in_integrated_inbox";
|
||||
|
||||
private final MessagingController messagingController = DI.get(MessagingController.class);
|
||||
private final K9JobManager jobManager = DI.get(K9JobManager.class);
|
||||
private final FolderNameFormatterFactory folderNameFormatterFactory = DI.get(FolderNameFormatterFactory.class);
|
||||
|
||||
private FolderNameFormatter folderNameFormatter;
|
||||
|
||||
private LocalFolder mFolder;
|
||||
|
||||
private CheckBoxPreference mInTopGroup;
|
||||
private CheckBoxPreference mIntegrate;
|
||||
private ListPreference mDisplayClass;
|
||||
private ListPreference mSyncClass;
|
||||
private ListPreference mPushClass;
|
||||
private ListPreference mNotifyClass;
|
||||
|
||||
public static void actionSettings(Context context, Account account, String folderServerId) {
|
||||
Intent i = new Intent(context, FolderSettings.class);
|
||||
i.putExtra(EXTRA_FOLDER_NAME, folderServerId);
|
||||
i.putExtra(EXTRA_ACCOUNT, account.getUuid());
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
folderNameFormatter = folderNameFormatterFactory.create(this);
|
||||
|
||||
String folderServerId = (String)getIntent().getSerializableExtra(EXTRA_FOLDER_NAME);
|
||||
String accountUuid = getIntent().getStringExtra(EXTRA_ACCOUNT);
|
||||
Account mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
||||
|
||||
try {
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(mAccount);
|
||||
mFolder = localStore.getFolder(folderServerId);
|
||||
mFolder.open();
|
||||
} catch (MessagingException me) {
|
||||
Timber.e(me, "Unable to edit folder %s preferences", folderServerId);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isPushCapable = messagingController.isPushCapable(mAccount);
|
||||
|
||||
addPreferencesFromResource(R.xml.folder_settings_preferences);
|
||||
|
||||
String folderName = mFolder.getName();
|
||||
String displayName = getDisplayName(mAccount, folderServerId, folderName);
|
||||
Preference category = findPreference(PREFERENCE_TOP_CATERGORY);
|
||||
category.setTitle(displayName);
|
||||
|
||||
|
||||
mInTopGroup = (CheckBoxPreference)findPreference(PREFERENCE_IN_TOP_GROUP);
|
||||
mInTopGroup.setChecked(mFolder.isInTopGroup());
|
||||
mIntegrate = (CheckBoxPreference)findPreference(PREFERENCE_INTEGRATE);
|
||||
mIntegrate.setChecked(mFolder.isIntegrate());
|
||||
|
||||
mDisplayClass = (ListPreference) findPreference(PREFERENCE_DISPLAY_CLASS);
|
||||
mDisplayClass.setValue(mFolder.getDisplayClass().name());
|
||||
mDisplayClass.setSummary(mDisplayClass.getEntry());
|
||||
mDisplayClass.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final String summary = newValue.toString();
|
||||
int index = mDisplayClass.findIndexOfValue(summary);
|
||||
mDisplayClass.setSummary(mDisplayClass.getEntries()[index]);
|
||||
mDisplayClass.setValue(summary);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mSyncClass = (ListPreference) findPreference(PREFERENCE_SYNC_CLASS);
|
||||
mSyncClass.setValue(mFolder.getRawSyncClass().name());
|
||||
mSyncClass.setSummary(mSyncClass.getEntry());
|
||||
mSyncClass.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final String summary = newValue.toString();
|
||||
int index = mSyncClass.findIndexOfValue(summary);
|
||||
mSyncClass.setSummary(mSyncClass.getEntries()[index]);
|
||||
mSyncClass.setValue(summary);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/* Temporarily disabled. See GH-4253
|
||||
mPushClass = (ListPreference) findPreference(PREFERENCE_PUSH_CLASS);
|
||||
mPushClass.setEnabled(isPushCapable);
|
||||
mPushClass.setValue(mFolder.getRawPushClass().name());
|
||||
mPushClass.setSummary(mPushClass.getEntry());
|
||||
mPushClass.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final String summary = newValue.toString();
|
||||
int index = mPushClass.findIndexOfValue(summary);
|
||||
mPushClass.setSummary(mPushClass.getEntries()[index]);
|
||||
mPushClass.setValue(summary);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
mNotifyClass = (ListPreference) findPreference(PREFERENCE_NOTIFY_CLASS);
|
||||
mNotifyClass.setValue(mFolder.getRawNotifyClass().name());
|
||||
mNotifyClass.setSummary(mNotifyClass.getEntry());
|
||||
mNotifyClass.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final String summary = newValue.toString();
|
||||
int index = mNotifyClass.findIndexOfValue(summary);
|
||||
mNotifyClass.setSummary(mNotifyClass.getEntries()[index]);
|
||||
mNotifyClass.setValue(summary);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveSettings() throws MessagingException {
|
||||
mFolder.setInTopGroup(mInTopGroup.isChecked());
|
||||
mFolder.setIntegrate(mIntegrate.isChecked());
|
||||
// We call getPushClass() because display class changes can affect push class when push class is set to inherit
|
||||
FolderClass oldPushClass = mFolder.getPushClass();
|
||||
FolderClass oldDisplayClass = mFolder.getDisplayClass();
|
||||
mFolder.setDisplayClass(FolderClass.valueOf(mDisplayClass.getValue()));
|
||||
mFolder.setSyncClass(FolderClass.valueOf(mSyncClass.getValue()));
|
||||
/* Temporarily disabled. See GH-4253
|
||||
mFolder.setPushClass(FolderClass.valueOf(mPushClass.getValue()));
|
||||
*/
|
||||
mFolder.setNotifyClass(FolderClass.valueOf(mNotifyClass.getValue()));
|
||||
|
||||
mFolder.save();
|
||||
|
||||
FolderClass newPushClass = mFolder.getPushClass();
|
||||
FolderClass newDisplayClass = mFolder.getDisplayClass();
|
||||
|
||||
if (oldPushClass != newPushClass
|
||||
|| (newPushClass != FolderClass.NO_CLASS && oldDisplayClass != newDisplayClass)) {
|
||||
jobManager.schedulePusherRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
try {
|
||||
saveSettings();
|
||||
} catch (MessagingException e) {
|
||||
Timber.e(e, "Saving folder settings failed");
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
public String getDisplayName(Account account, String serverId, String name) {
|
||||
FolderType folderType = FolderInfoHolder.getFolderType(account, serverId);
|
||||
Folder folder = new Folder(-1, serverId, name, folderType);
|
||||
|
||||
return folderNameFormatter.displayName(folder);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.fsck.k9.ui.managefolders
|
||||
|
||||
import androidx.preference.PreferenceDataStore
|
||||
import com.fsck.k9.mail.FolderClass
|
||||
import com.fsck.k9.mailstore.LocalFolder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class FolderSettingsDataStore(private val folder: LocalFolder) : PreferenceDataStore() {
|
||||
private val saveScope = CoroutineScope(GlobalScope.coroutineContext + Dispatchers.IO)
|
||||
|
||||
override fun getBoolean(key: String?, defValue: Boolean): Boolean {
|
||||
return when (key) {
|
||||
"folder_settings_in_top_group" -> folder.isInTopGroup
|
||||
"folder_settings_include_in_integrated_inbox" -> folder.isIntegrate
|
||||
else -> error("Unknown key: $key")
|
||||
}
|
||||
}
|
||||
|
||||
override fun putBoolean(key: String?, value: Boolean) {
|
||||
return when (key) {
|
||||
"folder_settings_in_top_group" -> updateFolder { isInTopGroup = value }
|
||||
"folder_settings_include_in_integrated_inbox" -> updateFolder { isIntegrate = value }
|
||||
else -> error("Unknown key: $key")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getString(key: String?, defValue: String?): String? {
|
||||
return when (key) {
|
||||
"folder_settings_folder_display_mode" -> folder.displayClass.name
|
||||
"folder_settings_folder_sync_mode" -> folder.rawSyncClass.name
|
||||
"folder_settings_folder_notify_mode" -> folder.rawNotifyClass.name
|
||||
else -> error("Unknown key: $key")
|
||||
}
|
||||
}
|
||||
|
||||
override fun putString(key: String?, value: String?) {
|
||||
val newValue = requireNotNull(value) { "'value' can't be null" }
|
||||
|
||||
when (key) {
|
||||
"folder_settings_folder_display_mode" -> updateFolder { displayClass = FolderClass.valueOf(newValue) }
|
||||
"folder_settings_folder_sync_mode" -> updateFolder { syncClass = FolderClass.valueOf(newValue) }
|
||||
"folder_settings_folder_notify_mode" -> updateFolder { notifyClass = FolderClass.valueOf(newValue) }
|
||||
else -> error("Unknown key: $key")
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateFolder(block: LocalFolder.() -> Unit) {
|
||||
saveScope.launch {
|
||||
block(folder)
|
||||
folder.save()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.fsck.k9.ui.managefolders
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.preference.Preference
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.ui.folders.FolderNameFormatter
|
||||
import com.fsck.k9.ui.observeNotNull
|
||||
import com.takisoft.preferencex.PreferenceFragmentCompat
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
|
||||
class FolderSettingsFragment : PreferenceFragmentCompat() {
|
||||
private val viewModel: FolderSettingsViewModel by viewModel()
|
||||
private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(requireActivity()) }
|
||||
|
||||
override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
// Set empty preferences resource while data is being loaded
|
||||
setPreferencesFromResource(R.xml.empty_preferences, null)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val arguments = arguments ?: error("Arguments missing")
|
||||
val accountUuid = arguments.getString(EXTRA_ACCOUNT) ?: error("Missing argument '$EXTRA_ACCOUNT'")
|
||||
val folderServerId = arguments.getString(EXTRA_FOLDER_SERVER_ID)
|
||||
?: error("Missing argument '$EXTRA_FOLDER_SERVER_ID'")
|
||||
|
||||
viewModel.getFolderSettingsLiveData(accountUuid, folderServerId)
|
||||
.observeNotNull(viewLifecycleOwner) { folderSettings ->
|
||||
preferenceManager.preferenceDataStore = folderSettings.dataStore
|
||||
setPreferencesFromResource(R.xml.folder_settings_preferences, null)
|
||||
|
||||
setCategoryTitle(folderSettings)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setCategoryTitle(folderSettings: FolderSettingsData) {
|
||||
val folderDisplayName = folderNameFormatter.displayName(folderSettings.folder)
|
||||
findPreference<Preference>(PREFERENCE_TOP_CATEGORY)!!.title = folderDisplayName
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_ACCOUNT = "account"
|
||||
const val EXTRA_FOLDER_SERVER_ID = "folderServerId"
|
||||
|
||||
private const val PREFERENCE_TOP_CATEGORY = "folder_settings"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.fsck.k9.ui.managefolders
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.activity.FolderInfoHolder
|
||||
import com.fsck.k9.mailstore.Folder
|
||||
import com.fsck.k9.mailstore.LocalFolder
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class FolderSettingsViewModel(
|
||||
private val preferences: Preferences,
|
||||
private val localStoreProvider: LocalStoreProvider
|
||||
) : ViewModel() {
|
||||
private var folderSettingsLiveData: LiveData<FolderSettingsData>? = null
|
||||
|
||||
fun getFolderSettingsLiveData(accountUuid: String, folderServerId: String): LiveData<FolderSettingsData> {
|
||||
return folderSettingsLiveData ?: createFolderSettingsLiveData(accountUuid, folderServerId).also {
|
||||
folderSettingsLiveData = it
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFolderSettingsLiveData(
|
||||
accountUuid: String,
|
||||
folderServerId: String
|
||||
): LiveData<FolderSettingsData> {
|
||||
return liveData(context = viewModelScope.coroutineContext) {
|
||||
val account = loadAccount(accountUuid)
|
||||
val localFolder = loadLocalFolder(account, folderServerId)
|
||||
|
||||
val folderSettingsData = FolderSettingsData(
|
||||
folder = createFolderObject(account, folderServerId, localFolder),
|
||||
dataStore = FolderSettingsDataStore(localFolder)
|
||||
)
|
||||
emit(folderSettingsData)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadAccount(accountUuid: String): Account {
|
||||
return withContext(Dispatchers.IO) {
|
||||
preferences.getAccount(accountUuid) ?: error("Missing account: $accountUuid")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadLocalFolder(account: Account, folderServerId: String): LocalFolder {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val localStore = localStoreProvider.getInstance(account)
|
||||
val folder = localStore.getFolder(folderServerId)
|
||||
folder.open()
|
||||
folder
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFolderObject(account: Account, folderServerId: String, localFolder: LocalFolder): Folder {
|
||||
val folderType = FolderInfoHolder.getFolderType(account, folderServerId)
|
||||
return Folder(id = -1, serverId = folderServerId, name = localFolder.name, type = folderType)
|
||||
}
|
||||
}
|
||||
|
||||
data class FolderSettingsData(val folder: Folder, val dataStore: FolderSettingsDataStore)
|
|
@ -4,5 +4,6 @@ import org.koin.androidx.viewmodel.dsl.viewModel
|
|||
import org.koin.dsl.module
|
||||
|
||||
val manageFoldersUiModule = module {
|
||||
viewModel { ManageFoldersViewModel(get()) }
|
||||
viewModel { ManageFoldersViewModel(foldersLiveDataFactory = get()) }
|
||||
viewModel { FolderSettingsViewModel(preferences = get(), localStoreProvider = get()) }
|
||||
}
|
||||
|
|
|
@ -1,230 +1,59 @@
|
|||
package com.fsck.k9.ui.managefolders
|
||||
|
||||
import android.content.Context
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.ActionBar
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.SearchView.OnQueryTextListener
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Account.FolderMode
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.activity.K9Activity
|
||||
import com.fsck.k9.activity.setup.FolderSettings
|
||||
import com.fsck.k9.controller.MessagingController
|
||||
import com.fsck.k9.controller.SimpleMessagingListener
|
||||
import com.fsck.k9.mailstore.DisplayFolder
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.ui.folders.FolderIconProvider
|
||||
import com.fsck.k9.ui.folders.FolderNameFormatter
|
||||
import com.fsck.k9.ui.helper.SizeFormatter
|
||||
import com.fsck.k9.ui.observeNotNull
|
||||
import com.mikepenz.fastadapter.FastAdapter
|
||||
import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||
import java.util.Locale
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import com.fsck.k9.ui.findNavController
|
||||
|
||||
class ManageFoldersActivity : K9Activity() {
|
||||
private val viewModel: ManageFoldersViewModel by viewModel()
|
||||
private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(this) }
|
||||
private val messagingController: MessagingController by inject()
|
||||
private val preferences: Preferences by inject()
|
||||
private val folderIconProvider by lazy { FolderIconProvider(theme) }
|
||||
private val sizeFormatter: SizeFormatter by inject { parametersOf(this) }
|
||||
|
||||
private lateinit var account: Account
|
||||
private lateinit var actionBar: ActionBar
|
||||
private lateinit var itemAdapter: ItemAdapter<FolderListItem>
|
||||
|
||||
private val messagingListener = object : SimpleMessagingListener() {
|
||||
override fun accountSizeChanged(account: Account, oldSize: Long, newSize: Long) {
|
||||
if (account == this@ManageFoldersActivity.account) {
|
||||
runOnUiThread {
|
||||
val toastText = getString(
|
||||
R.string.account_size_changed,
|
||||
account.description,
|
||||
sizeFormatter.formatSize(oldSize),
|
||||
sizeFormatter.formatSize(newSize)
|
||||
)
|
||||
val toast = Toast.makeText(application, toastText, Toast.LENGTH_LONG)
|
||||
toast.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private lateinit var navController: NavController
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setLayout(R.layout.folder_list)
|
||||
setLayout(R.layout.activity_manage_folders)
|
||||
|
||||
if (!decodeArguments()) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val accountUuid = intent.getStringExtra(EXTRA_ACCOUNT) ?: error("Missing Intent extra '$EXTRA_ACCOUNT'")
|
||||
|
||||
initializeActionBar()
|
||||
initializeFolderList()
|
||||
|
||||
viewModel.getFolders(account).observeNotNull(this) { folders ->
|
||||
updateFolderList(folders)
|
||||
}
|
||||
initializeNavController(accountUuid)
|
||||
}
|
||||
|
||||
private fun decodeArguments(): Boolean {
|
||||
val accountUuid = intent.getStringExtra(EXTRA_ACCOUNT) ?: return false
|
||||
account = preferences.getAccount(accountUuid) ?: return false
|
||||
private fun initializeNavController(accountUuid: String) {
|
||||
navController = findNavController(R.id.nav_host_fragment)
|
||||
|
||||
val fragmentArguments = bundleOf(
|
||||
ManageFoldersFragment.EXTRA_ACCOUNT to accountUuid
|
||||
)
|
||||
navController.setGraph(R.navigation.navigation_manage_folders, fragmentArguments)
|
||||
|
||||
val appBarConfiguration = AppBarConfiguration(topLevelDestinationIds = emptySet())
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return navController.navigateUp() || super.onSupportNavigateUp() || navigateUpBySimulatedBackButtonPress()
|
||||
}
|
||||
|
||||
private fun navigateUpBySimulatedBackButtonPress(): Boolean {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
|
||||
private fun initializeActionBar() {
|
||||
actionBar = supportActionBar!!
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
}
|
||||
|
||||
private fun initializeFolderList() {
|
||||
itemAdapter = ItemAdapter()
|
||||
itemAdapter.itemFilter.filterPredicate = ::folderListFilter
|
||||
|
||||
val folderListAdapter = FastAdapter.with(itemAdapter).apply {
|
||||
setHasStableIds(true)
|
||||
onClickListener = { _, _, item: FolderListItem, _ ->
|
||||
openFolderSettings(item.serverId)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
val recyclerView = findViewById<RecyclerView>(R.id.folderList)
|
||||
recyclerView.adapter = folderListAdapter
|
||||
}
|
||||
|
||||
private fun updateFolderList(displayFolders: List<DisplayFolder>) {
|
||||
val folderListItems = displayFolders.map { displayFolder ->
|
||||
val databaseId = displayFolder.folder.id
|
||||
val folderIconResource = folderIconProvider.getFolderIcon(displayFolder.folder.type)
|
||||
val displayName = folderNameFormatter.displayName(displayFolder.folder)
|
||||
val serverId = displayFolder.folder.serverId
|
||||
|
||||
FolderListItem(databaseId, folderIconResource, displayName, serverId)
|
||||
}
|
||||
|
||||
itemAdapter.set(folderListItems)
|
||||
}
|
||||
|
||||
private fun openFolderSettings(folderServerId: String) {
|
||||
FolderSettings.actionSettings(this, account, folderServerId)
|
||||
}
|
||||
|
||||
public override fun onPause() {
|
||||
messagingController.removeListener(messagingListener)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
public override fun onResume() {
|
||||
super.onResume()
|
||||
messagingController.addListener(messagingListener)
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_H -> displayHelpText()
|
||||
KeyEvent.KEYCODE_1 -> setDisplayMode(FolderMode.FIRST_CLASS)
|
||||
KeyEvent.KEYCODE_2 -> setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS)
|
||||
KeyEvent.KEYCODE_3 -> setDisplayMode(FolderMode.NOT_SECOND_CLASS)
|
||||
KeyEvent.KEYCODE_4 -> setDisplayMode(FolderMode.ALL)
|
||||
else -> return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun displayHelpText() {
|
||||
val toast = Toast.makeText(this, R.string.folder_list_help_key, Toast.LENGTH_LONG)
|
||||
toast.show()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
super.onCreateOptionsMenu(menu)
|
||||
menuInflater.inflate(R.menu.folder_list_option, menu)
|
||||
configureFolderSearchView(menu)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun configureFolderSearchView(menu: Menu) {
|
||||
val folderMenuItem = menu.findItem(R.id.filter_folders)
|
||||
val folderSearchView = folderMenuItem.actionView as SearchView
|
||||
folderSearchView.queryHint = getString(R.string.folder_list_filter_hint)
|
||||
folderSearchView.setOnQueryTextListener(object : OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
itemAdapter.filter(query)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
itemAdapter.filter(newText)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> onBackPressed()
|
||||
R.id.list_folders -> refreshFolderList()
|
||||
R.id.compact -> compactAccount()
|
||||
R.id.display_1st_class -> setDisplayMode(FolderMode.FIRST_CLASS)
|
||||
R.id.display_1st_and_2nd_class -> setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS)
|
||||
R.id.display_not_second_class -> setDisplayMode(FolderMode.NOT_SECOND_CLASS)
|
||||
R.id.display_all -> setDisplayMode(FolderMode.ALL)
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun refreshFolderList() {
|
||||
messagingController.refreshFolderList(account)
|
||||
}
|
||||
|
||||
private fun compactAccount() {
|
||||
val toastText = getString(R.string.compacting_account, account.description)
|
||||
val toast = Toast.makeText(application, toastText, Toast.LENGTH_SHORT)
|
||||
toast.show()
|
||||
|
||||
messagingController.compact(account, null)
|
||||
}
|
||||
|
||||
private fun setDisplayMode(newMode: FolderMode) {
|
||||
account.folderDisplayMode = newMode
|
||||
preferences.saveAccount(account)
|
||||
|
||||
itemAdapter.filter(null)
|
||||
}
|
||||
|
||||
private fun folderListFilter(item: FolderListItem, constraint: CharSequence?): Boolean {
|
||||
if (constraint.isNullOrEmpty()) return true
|
||||
|
||||
val locale = Locale.getDefault()
|
||||
val displayName = item.displayName.toLowerCase(locale)
|
||||
return constraint.splitToSequence(" ")
|
||||
.map { it.toLowerCase(locale) }
|
||||
.any { it in displayName }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_ACCOUNT = "account"
|
||||
|
||||
@JvmStatic
|
||||
fun launch(context: Context, account: Account) {
|
||||
val intent = Intent(context, ManageFoldersActivity::class.java)
|
||||
intent.putExtra(EXTRA_ACCOUNT, account.uuid)
|
||||
context.startActivity(intent)
|
||||
fun launch(activity: Activity, account: Account) {
|
||||
val intent = Intent(activity, ManageFoldersActivity::class.java).apply {
|
||||
putExtra(EXTRA_ACCOUNT, account.uuid)
|
||||
}
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
package com.fsck.k9.ui.managefolders
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.controller.MessagingController
|
||||
import com.fsck.k9.mailstore.DisplayFolder
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.ui.folders.FolderIconProvider
|
||||
import com.fsck.k9.ui.folders.FolderNameFormatter
|
||||
import com.fsck.k9.ui.observeNotNull
|
||||
import com.mikepenz.fastadapter.FastAdapter
|
||||
import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||
import java.util.Locale
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
|
||||
class ManageFoldersFragment : Fragment() {
|
||||
private val viewModel: ManageFoldersViewModel by viewModel()
|
||||
private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(requireActivity()) }
|
||||
private val messagingController: MessagingController by inject()
|
||||
private val preferences: Preferences by inject()
|
||||
private val folderIconProvider by lazy { FolderIconProvider(requireActivity().theme) }
|
||||
|
||||
private lateinit var account: Account
|
||||
private lateinit var itemAdapter: ItemAdapter<FolderListItem>
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
val arguments = arguments ?: error("Missing arguments")
|
||||
val accountUuid = arguments.getString(EXTRA_ACCOUNT) ?: error("Missing argument '$EXTRA_ACCOUNT'")
|
||||
account = preferences.getAccount(accountUuid) ?: error("Missing account: $accountUuid")
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_manage_folders, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
initializeFolderList()
|
||||
|
||||
viewModel.getFolders(account).observeNotNull(this) { folders ->
|
||||
updateFolderList(folders)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeFolderList() {
|
||||
itemAdapter = ItemAdapter()
|
||||
itemAdapter.itemFilter.filterPredicate = ::folderListFilter
|
||||
|
||||
val folderListAdapter = FastAdapter.with(itemAdapter).apply {
|
||||
setHasStableIds(true)
|
||||
onClickListener = { _, _, item: FolderListItem, _ ->
|
||||
openFolderSettings(item.serverId)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
val recyclerView = requireView().findViewById<RecyclerView>(R.id.folderList)
|
||||
recyclerView.adapter = folderListAdapter
|
||||
}
|
||||
|
||||
private fun updateFolderList(displayFolders: List<DisplayFolder>) {
|
||||
val folderListItems = displayFolders.map { displayFolder ->
|
||||
val databaseId = displayFolder.folder.id
|
||||
val folderIconResource = folderIconProvider.getFolderIcon(displayFolder.folder.type)
|
||||
val displayName = folderNameFormatter.displayName(displayFolder.folder)
|
||||
val serverId = displayFolder.folder.serverId
|
||||
|
||||
FolderListItem(databaseId, folderIconResource, displayName, serverId)
|
||||
}
|
||||
|
||||
itemAdapter.set(folderListItems)
|
||||
}
|
||||
|
||||
private fun openFolderSettings(folderServerId: String) {
|
||||
val folderSettingsArguments = bundleOf(
|
||||
FolderSettingsFragment.EXTRA_ACCOUNT to account.uuid,
|
||||
FolderSettingsFragment.EXTRA_FOLDER_SERVER_ID to folderServerId
|
||||
)
|
||||
findNavController().navigate(R.id.action_manageFoldersScreen_to_folderSettingsScreen, folderSettingsArguments)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.folder_list_option, menu)
|
||||
configureFolderSearchView(menu)
|
||||
}
|
||||
|
||||
private fun configureFolderSearchView(menu: Menu) {
|
||||
val folderMenuItem = menu.findItem(R.id.filter_folders)
|
||||
val folderSearchView = folderMenuItem.actionView as SearchView
|
||||
folderSearchView.queryHint = getString(R.string.folder_list_filter_hint)
|
||||
folderSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
itemAdapter.filter(query)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
itemAdapter.filter(newText)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.list_folders -> refreshFolderList()
|
||||
R.id.display_1st_class -> setDisplayMode(Account.FolderMode.FIRST_CLASS)
|
||||
R.id.display_1st_and_2nd_class -> setDisplayMode(Account.FolderMode.FIRST_AND_SECOND_CLASS)
|
||||
R.id.display_not_second_class -> setDisplayMode(Account.FolderMode.NOT_SECOND_CLASS)
|
||||
R.id.display_all -> setDisplayMode(Account.FolderMode.ALL)
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun refreshFolderList() {
|
||||
messagingController.refreshFolderList(account)
|
||||
}
|
||||
|
||||
private fun setDisplayMode(newMode: Account.FolderMode) {
|
||||
account.folderDisplayMode = newMode
|
||||
preferences.saveAccount(account)
|
||||
|
||||
itemAdapter.filter(null)
|
||||
}
|
||||
|
||||
private fun folderListFilter(item: FolderListItem, constraint: CharSequence?): Boolean {
|
||||
if (constraint.isNullOrEmpty()) return true
|
||||
|
||||
val locale = Locale.getDefault()
|
||||
val displayName = item.displayName.toLowerCase(locale)
|
||||
return constraint.splitToSequence(" ")
|
||||
.map { it.toLowerCase(locale) }
|
||||
.any { it in displayName }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_ACCOUNT = "account"
|
||||
}
|
||||
}
|
19
app/ui/src/main/res/layout/activity_manage_folders.xml
Normal file
19
app/ui/src/main/res/layout/activity_manage_folders.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/toolbar" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
app:defaultNavHost="true" />
|
||||
|
||||
</LinearLayout>
|
9
app/ui/src/main/res/layout/fragment_manage_folders.xml
Normal file
9
app/ui/src/main/res/layout/fragment_manage_folders.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/folderList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/folder_list_item" />
|
|
@ -25,10 +25,6 @@
|
|||
android:title="@string/folder_list_display_mode_not_second_class"/>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/compact"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/compact_action"/>
|
||||
<item
|
||||
android:id="@+id/list_folders"
|
||||
android:icon="?attr/iconActionRefresh"
|
||||
|
|
25
app/ui/src/main/res/navigation/navigation_manage_folders.xml
Normal file
25
app/ui/src/main/res/navigation/navigation_manage_folders.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/navigation_onboarding"
|
||||
app:startDestination="@id/manageFoldersScreen">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/manageFoldersScreen"
|
||||
android:name="com.fsck.k9.ui.managefolders.ManageFoldersFragment"
|
||||
android:label="@string/folders_action"
|
||||
tools:layout="@layout/fragment_manage_folders">
|
||||
|
||||
<action
|
||||
android:id="@+id/action_manageFoldersScreen_to_folderSettingsScreen"
|
||||
app:destination="@id/folderSettingsScreen" />
|
||||
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/folderSettingsScreen"
|
||||
android:name="com.fsck.k9.ui.managefolders.FolderSettingsFragment"
|
||||
android:label="@string/folder_settings_title"/>
|
||||
|
||||
</navigation>
|
|
@ -756,8 +756,6 @@ Please submit bug reports, contribute new features and ask questions at
|
|||
<string name="message_view_help_key">Del (or D) - Delete\nR - Reply\nA - Reply All\nC - Compose\nF - Forward\nM - Move\nV - Archive\nY - Copy\nZ - Mark (Un)read\nG - Star\nO - Sort type\nI - Sort order\nQ - Return to Folders\nS - Select/deselect\nJ or P - Previous Message\nK or N - Next Message</string>
|
||||
<string name="message_list_help_key">Del (or D) - Delete\nC - Compose\nM - Move\nV - Archive\nY - Copy\nZ - Mark (Un)read\nG - Star\nO - Sort type\nI - Sort order\nQ - Return to Folders\nS - Select/deselect</string>
|
||||
|
||||
<string name="folder_list_help_key">1 - Display only 1st Class folders\n2 - Display 1st and 2nd Class folders\n3 - Display all except 2nd Class folders\n4 - Display all folders\nQ - Return to Accounts\nS - Edit Account Settings</string>
|
||||
|
||||
<string name="folder_list_filter_hint">Folder name contains</string>
|
||||
|
||||
<string name="folder_list_display_mode_label">Show folders…</string>
|
||||
|
|
2
app/ui/src/main/res/xml/empty_preferences.xml
Normal file
2
app/ui/src/main/res/xml/empty_preferences.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen />
|
|
@ -14,62 +14,51 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Make sure to add android:persistent="false" to all preferences to disable saving
|
||||
the preference values to SharedPreferences. We use our own storage mechanism for
|
||||
the preferences. See com.fsck.k9.preferences.Storage.
|
||||
|
||||
Also note that every sub-PreferenceScreen needs an "android:key" parameter so the correct screen
|
||||
can be displayed after the device has been rotated.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="folder_settings">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_in_top_group"
|
||||
android:title="@string/folder_settings_in_top_group_label"
|
||||
android:summary="@string/folder_settings_in_top_group_summary" />
|
||||
|
||||
<ListPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_folder_display_mode"
|
||||
android:title="@string/folder_settings_folder_display_mode_label"
|
||||
android:summary="%s"
|
||||
android:entries="@array/folder_settings_folder_display_mode_entries"
|
||||
android:entryValues="@array/folder_settings_folder_display_mode_values"
|
||||
android:dialogTitle="@string/folder_settings_folder_display_mode_label" />
|
||||
|
||||
<ListPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_folder_sync_mode"
|
||||
android:title="@string/folder_settings_folder_sync_mode_label"
|
||||
android:summary="%s"
|
||||
android:entries="@array/folder_settings_folder_sync_mode_entries"
|
||||
android:entryValues="@array/folder_settings_folder_sync_mode_values"
|
||||
android:dialogTitle="@string/folder_settings_folder_sync_mode_label" />
|
||||
|
||||
<!-- Temporarily disabled. See GH-4253
|
||||
<ListPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_folder_push_mode"
|
||||
android:title="@string/folder_settings_folder_push_mode_label"
|
||||
android:summary="%s"
|
||||
android:entries="@array/folder_settings_folder_push_mode_entries"
|
||||
android:entryValues="@array/folder_settings_folder_push_mode_values"
|
||||
android:dialogTitle="@string/folder_settings_folder_push_mode_label" />
|
||||
-->
|
||||
|
||||
<ListPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_folder_notify_mode"
|
||||
android:title="@string/folder_settings_folder_notify_mode_label"
|
||||
android:summary="%s"
|
||||
android:entries="@array/folder_settings_folder_notify_mode_entries"
|
||||
android:entryValues="@array/folder_settings_folder_notify_mode_values"
|
||||
android:dialogTitle="@string/folder_settings_folder_notify_mode_label" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_include_in_integrated_inbox"
|
||||
android:title="@string/folder_settings_include_in_integrated_inbox_label"
|
||||
android:summary="@string/folder_settings_include_in_integrated_inbox_summary" />
|
||||
|
|
Loading…
Reference in a new issue