Merge pull request #4489 from k9mail/localized_folder_name_formatter

Respect configured language when formatting folder names
This commit is contained in:
cketti 2020-01-29 14:28:54 +01:00 committed by GitHub
commit fb327a4dd7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 67 additions and 102 deletions

View file

@ -4,6 +4,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferActivity
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferPresenter
import com.fsck.k9.ui.folders.FolderNameFormatter
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.mock
import org.junit.Test
@ -15,6 +16,7 @@ import org.koin.test.AutoCloseKoinTest
import org.koin.test.check.checkModules
import org.openintents.openpgp.OpenPgpApiManager
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@ -32,6 +34,7 @@ class DependencyInjectionTest : AutoCloseKoinTest() {
getKoin().checkModules {
create<OpenPgpApiManager> { parametersOf(lifecycleOwner) }
create<AutocryptKeyTransferPresenter> { parametersOf(lifecycleOwner, autocryptTransferView) }
create<FolderNameFormatter> { parametersOf(RuntimeEnvironment.application) }
}
}
}

View file

@ -4,6 +4,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferActivity
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferPresenter
import com.fsck.k9.ui.folders.FolderNameFormatter
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.mock
import org.junit.Test
@ -15,6 +16,7 @@ import org.koin.test.AutoCloseKoinTest
import org.koin.test.check.checkModules
import org.openintents.openpgp.OpenPgpApiManager
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@ -32,6 +34,7 @@ class DependencyInjectionTest : AutoCloseKoinTest() {
getKoin().checkModules {
create<OpenPgpApiManager> { parametersOf(lifecycleOwner) }
create<AutocryptKeyTransferPresenter> { parametersOf(lifecycleOwner, autocryptTransferView) }
create<FolderNameFormatter> { parametersOf(RuntimeEnvironment.application) }
}
}
}

View file

@ -2,83 +2,26 @@ package com.fsck.k9.activity;
import com.fsck.k9.Account;
import com.fsck.k9.DI;
import com.fsck.k9.mailstore.Folder;
import com.fsck.k9.mailstore.FolderType;
import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.ui.folders.FolderNameFormatter;
public class FolderInfoHolder implements Comparable<FolderInfoHolder> {
private final FolderNameFormatter folderNameFormatter = DI.get(FolderNameFormatter.class);
public class FolderInfoHolder {
private final FolderNameFormatter folderNameFormatter;
public String serverId;
public String displayName;
public long lastChecked;
public int unreadMessageCount = -1;
public int flaggedMessageCount = -1;
public final String serverId;
public final String displayName;
public final long lastChecked;
public boolean loading;
public String status;
public boolean lastCheckFailed;
public LocalFolder folder;
public boolean pushActive;
public boolean moreMessages;
@Override
public boolean equals(Object o) {
return o instanceof FolderInfoHolder && serverId.equals(((FolderInfoHolder) o).serverId);
}
@Override
public int hashCode() {
return serverId.hashCode();
}
public int compareTo(FolderInfoHolder o) {
String s1 = this.serverId;
String s2 = o.serverId;
int ret = s1.compareToIgnoreCase(s2);
if (ret != 0) {
return ret;
} else {
return s1.compareTo(s2);
}
}
private String truncateStatus(String mess) {
if (mess != null && mess.length() > 27) {
mess = mess.substring(0, 27);
}
return mess;
}
// constructor for an empty object for comparisons
public FolderInfoHolder() {
}
public FolderInfoHolder(LocalFolder folder, Account account) {
populate(folder, account);
}
public FolderInfoHolder(LocalFolder folder, Account account, int unreadCount) {
populate(folder, account, unreadCount);
}
public void populate(LocalFolder folder, Account account, int unreadCount) {
populate(folder, account);
this.unreadMessageCount = unreadCount;
folder.close();
}
public void populate(LocalFolder localFolder, Account account) {
this.folder = localFolder;
public FolderInfoHolder(FolderNameFormatter folderNameFormatter, LocalFolder localFolder, Account account) {
this.folderNameFormatter = folderNameFormatter;
this.serverId = localFolder.getServerId();
this.lastChecked = localFolder.getLastUpdate();
this.status = truncateStatus(localFolder.getStatus());
this.displayName = getDisplayName(account, localFolder);
setMoreMessagesFromFolder(localFolder);
}
@ -94,7 +37,11 @@ public class FolderInfoHolder implements Comparable<FolderInfoHolder> {
return folderNameFormatter.displayName(folder);
}
private static FolderType getFolderType(Account account, String serverId) {
public void setMoreMessagesFromFolder(LocalFolder folder) {
moreMessages = folder.hasMoreMessages();
}
public static FolderType getFolderType(Account account, String serverId) {
if (serverId.equals(account.getInboxFolder())) {
return FolderType.INBOX;
} else if (serverId.equals(account.getOutboxFolder())) {
@ -113,22 +60,4 @@ public class FolderInfoHolder implements Comparable<FolderInfoHolder> {
return FolderType.REGULAR;
}
}
/**
* Returns the display name for a folder.
*
* Deprecated. Use {@link FolderNameFormatter} instead.
*/
@Deprecated
public static String getDisplayName(Account account, String serverId, String name) {
FolderNameFormatter folderNameFormatter = DI.get(FolderNameFormatter.class);
FolderType folderType = getFolderType(account, serverId);
Folder folder = new Folder(-1, serverId, name, folderType);
return folderNameFormatter.displayName(folder);
}
public void setMoreMessagesFromFolder(LocalFolder folder) {
moreMessages = folder.hasMoreMessages();
}
}

View file

@ -12,6 +12,8 @@ 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;
@ -22,6 +24,8 @@ 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;
@ -40,6 +44,9 @@ public class FolderSettings extends K9PreferenceActivity {
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;
@ -61,6 +68,8 @@ public class FolderSettings extends K9PreferenceActivity {
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);
@ -79,7 +88,7 @@ public class FolderSettings extends K9PreferenceActivity {
addPreferencesFromResource(R.xml.folder_settings_preferences);
String folderName = mFolder.getName();
String displayName = FolderInfoHolder.getDisplayName(mAccount, folderServerId, folderName);
String displayName = getDisplayName(mAccount, folderServerId, folderName);
Preference category = findPreference(PREFERENCE_TOP_CATERGORY);
category.setTitle(displayName);
@ -179,4 +188,11 @@ public class FolderSettings extends K9PreferenceActivity {
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);
}
}

View file

@ -62,6 +62,8 @@ import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.preferences.StorageEditor;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.ui.R;
import com.fsck.k9.ui.folders.FolderNameFormatter;
import com.fsck.k9.ui.folders.FolderNameFormatterFactory;
import com.fsck.k9.ui.messagelist.MessageListAppearance;
import com.fsck.k9.ui.messagelist.MessageListConfig;
import com.fsck.k9.ui.messagelist.MessageListFragmentDiContainer;
@ -105,6 +107,8 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
private final SortTypeToastProvider sortTypeToastProvider = DI.get(SortTypeToastProvider.class);
private final MessageListFragmentDiContainer diContainer = new MessageListFragmentDiContainer(this);
private final FolderNameFormatterFactory folderNameFormatterFactory = DI.get(FolderNameFormatterFactory.class);
private FolderNameFormatter folderNameFormatter;
ListView listView;
private SwipeRefreshLayout swipeRefreshLayout;
@ -309,6 +313,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
folderNameFormatter = folderNameFormatterFactory.create(requireActivity());
Context appContext = getActivity().getApplicationContext();
preferences = Preferences.getPreferences(appContext);
@ -523,7 +528,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
private FolderInfoHolder getFolderInfoHolder(String folderServerId, Account account) {
try {
LocalFolder localFolder = MlfUtils.getOpenFolder(folderServerId, account);
return new FolderInfoHolder(localFolder, account);
return new FolderInfoHolder(folderNameFormatter, localFolder, account);
} catch (MessagingException e) {
throw new RuntimeException(e);
}
@ -1276,15 +1281,11 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
updateFooter(null);
} else {
String message;
if (!currentFolder.lastCheckFailed) {
if (account.getDisplayCount() == 0) {
message = context.getString(R.string.message_list_load_more_messages_action);
} else {
message = String.format(context.getString(R.string.load_more_messages_fmt),
account.getDisplayCount());
}
if (account.getDisplayCount() == 0) {
message = context.getString(R.string.message_list_load_more_messages_action);
} else {
message = context.getString(R.string.status_loading_more_failed);
message = String.format(context.getString(R.string.load_more_messages_fmt),
account.getDisplayCount());
}
updateFooter(message);
}
@ -1548,7 +1549,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
if (isThreadDisplay) {
folderServerId = messages.get(0).getFolderServerId();
} else if (singleFolderMode) {
folderServerId = currentFolder.folder.getServerId();
folderServerId = currentFolder.serverId;
} else {
folderServerId = null;
}
@ -1578,7 +1579,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
if (isThreadDisplay) {
folderServerId = messages.get(0).getFolderServerId();
} else if (singleFolderMode) {
folderServerId = currentFolder.folder.getServerId();
folderServerId = currentFolder.serverId;
} else {
folderServerId = null;
}

View file

@ -38,10 +38,11 @@ import java.util.HashSet
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.koin.core.parameter.parametersOf
class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : KoinComponent {
private val viewModel: FoldersViewModel by parent.viewModel()
private val folderNameFormatter: FolderNameFormatter by inject()
private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(parent) }
private val preferences: Preferences by inject()
private val themeManager: ThemeManager by inject()
private val resources: Resources by inject()

View file

@ -25,12 +25,13 @@ 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 ChooseFolderActivity : K9Activity() {
private val viewModel: ChooseFolderViewModel by viewModel()
private val preferences: Preferences by inject()
private val messagingController: MessagingController by inject()
private val folderNameFormatter: FolderNameFormatter by inject()
private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(this) }
private val folderIconProvider by lazy { FolderIconProvider(theme) }
private lateinit var recyclerView: RecyclerView

View file

@ -0,0 +1,9 @@
package com.fsck.k9.ui.folders
import android.content.Context
class FolderNameFormatterFactory {
fun create(context: Context): FolderNameFormatter {
return FolderNameFormatter(context.resources)
}
}

View file

@ -1,10 +1,12 @@
package com.fsck.k9.ui.folders
import android.content.Context
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
val foldersUiModule = module {
single { FolderNameFormatter(get()) }
single { FolderNameFormatterFactory() }
factory { (context: Context) -> FolderNameFormatter(context.resources) }
single { FoldersLiveDataFactory(get(), get(), get()) }
viewModel { FoldersViewModel(get()) }
}

View file

@ -29,10 +29,11 @@ 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 ManageFoldersActivity : K9Activity() {
private val viewModel: ManageFoldersViewModel by viewModel()
private val folderNameFormatter: FolderNameFormatter by inject()
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) }

View file

@ -13,6 +13,7 @@ import com.fsck.k9.ui.R
import com.fsck.k9.ui.folders.FolderNameFormatter
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.koin.core.parameter.parametersOf
/**
* A [ListPreference] that allows selecting one of an account's folders.
@ -27,7 +28,7 @@ constructor(
android.R.attr.dialogPreferenceStyle),
defStyleRes: Int = 0
) : ListPreference(context, attrs, defStyleAttr, defStyleRes), KoinComponent {
private val folderNameFormatter: FolderNameFormatter by inject()
private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(context) }
private val noFolderSelectedName = context.getString(R.string.account_settings_no_folder_selected).italicize()
private lateinit var automaticFolderOption: CharSequence

View file

@ -168,8 +168,6 @@ Please submit bug reports, contribute new features and ask questions at
<string name="status_invalid_id_error">Message not found</string>
<string name="status_loading_error">Message loading error</string>
<string name="status_loading_more_failed">Retry loading more messages</string>
<string name="load_more_messages_fmt">Load up
to <xliff:g id="messages_to_load">%d</xliff:g> more</string>