Merge pull request #3745 from morckx/add-accounts-header-to-drawer

Add accounts header to the drawer
This commit is contained in:
Vincent Breitmoser 2018-11-28 10:51:45 +01:00 committed by GitHub
commit 94585ffd93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 142 additions and 44 deletions

View file

@ -33,6 +33,7 @@ dependencies {
implementation "com.xwray:groupie:2.1.0"
implementation "com.xwray:groupie-kotlin-android-extensions:2.1.0"
implementation 'com.mikepenz:materialdrawer:6.0.7'
implementation 'com.mikepenz:fontawesome-typeface:5.3.1.1@aar'
implementation 'com.github.ByteHamster:SearchPreference:v1.1.4'
implementation "commons-io:commons-io:${versions.commonsIo}"

View file

@ -3,9 +3,6 @@ package com.fsck.k9.activity;
import android.annotation.SuppressLint;
import android.app.SearchManager;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@ -15,7 +12,6 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentManager.OnBackStackChangedListener;
import android.support.v4.app.FragmentTransaction;
@ -47,7 +43,6 @@ import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.ParcelableUtil;
import com.fsck.k9.mailstore.Folder;
import com.fsck.k9.mailstore.SearchStatusManager;
import com.fsck.k9.mailstore.StorageManager;
import com.fsck.k9.notification.NotificationChannelManager;
@ -60,8 +55,6 @@ import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.SearchField;
import com.fsck.k9.ui.K9Drawer;
import com.fsck.k9.ui.R;
import com.fsck.k9.ui.messagelist.MessageListViewModel;
import com.fsck.k9.ui.messagelist.MessageListViewModelFactory;
import com.fsck.k9.ui.messageview.MessageViewFragment;
import com.fsck.k9.ui.messageview.MessageViewFragment.MessageViewFragmentListener;
import com.fsck.k9.ui.settings.SettingsActivity;
@ -245,16 +238,8 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
return;
}
ViewModelProvider viewModelProvider = ViewModelProviders.of(this, new MessageListViewModelFactory());
MessageListViewModel viewModel = viewModelProvider.get(MessageListViewModel.class);
if (isDrawerEnabled()) {
viewModel.getFolders(account).observe(this, new Observer<List<Folder>>() {
@Override
public void onChanged(@Nullable List<Folder> folders) {
drawer.setUserFolders(folders);
}
});
drawer.updateUserAccountsAndFolders(account);
}
findFragments();
@ -619,7 +604,18 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
public void openUnifiedInbox() {
drawer.selectUnifiedInbox();
performSearch(SearchAccount.createUnifiedInboxAccount().getRelatedSearch());
actionDisplaySearch(this, SearchAccount.createUnifiedInboxAccount().getRelatedSearch(), false, false);
}
public void openRealAccount(Account realAccount) {
if (realAccount.getAutoExpandFolder() == null) {
FolderList.actionHandleAccount(this, realAccount);
} else {
LocalSearch search = new LocalSearch(realAccount.getAutoExpandFolder());
search.addAllowedFolder(realAccount.getAutoExpandFolder());
search.addAccountUuid(realAccount.getUuid());
actionDisplaySearch(this, search, false, false);
}
}
private void performSearch(LocalSearch search) {

View file

@ -1,32 +1,50 @@
package com.fsck.k9.ui;
import java.util.ArrayList;
import java.util.List;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.DrawerLayout;
import android.util.TypedValue;
import android.view.View;
import com.fsck.k9.Account;
import com.fsck.k9.DI;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.activity.MessageList;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.mailstore.Folder;
import com.fsck.k9.ui.folders.FolderNameFormatter;
import com.fsck.k9.ui.messagelist.MessageListViewModel;
import com.fsck.k9.ui.messagelist.MessageListViewModelFactory;
import com.fsck.k9.ui.settings.SettingsActivity;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.Drawer.OnDrawerItemClickListener;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class K9Drawer {
// Bit shift for identifiers of user folders items, to leave space for other items
private static final short DRAWER_FOLDER_SHIFT = 2;
private static final short DRAWER_ACCOUNT_SHIFT = 16;
private static final long DRAWER_ID_UNIFIED_INBOX = 0;
private static final long DRAWER_ID_PREFERENCES = 1;
@ -35,8 +53,9 @@ public class K9Drawer {
private final FolderNameFormatter folderNameFormatter = DI.get(FolderNameFormatter.class);
private final Drawer drawer;
private AccountHeader accountHeader;
private final MessageList parent;
private int headerItemCount = 0;
private int headerItemCount = 1;
private int iconFolderInboxResId;
private int iconFolderOutboxResId;
@ -51,6 +70,7 @@ public class K9Drawer {
private boolean unifiedInboxSelected;
private String openedFolderServerId;
private final Preferences preferences = DI.get(Preferences.class);
public K9Drawer(MessageList parent, Bundle savedInstanceState) {
this.parent = parent;
@ -64,24 +84,77 @@ public class K9Drawer {
.withOnDrawerItemClickListener(createItemClickListener())
.withOnDrawerListener(parent.createOnDrawerListener())
.withSavedInstance(savedInstanceState)
.withAccountHeader(buildAccountHeader())
.build();
addHeaderItems();
addFooterItems();
initializeFolderIcons();
}
private void addHeaderItems() {
if (!K9.isHideSpecialAccounts()) {
drawer.addItems(new PrimaryDrawerItem()
.withName(R.string.integrated_inbox_title)
.withIcon(getResId(R.attr.iconUnifiedInbox))
.withIdentifier(DRAWER_ID_UNIFIED_INBOX),
new DividerDrawerItem());
private AccountHeader buildAccountHeader() {
AccountHeaderBuilder headerBuilder = new AccountHeaderBuilder()
.withActivity(parent)
.withHeaderBackground(R.drawable.drawer_header_background)
.withTranslucentStatusBar(false);
headerItemCount += 2;
if (!K9.isHideSpecialAccounts()) {
headerBuilder.addProfiles(new ProfileDrawerItem()
.withNameShown(true)
.withName(R.string.integrated_inbox_title)
.withEmail(parent.getString(R.string.integrated_inbox_detail))
.withIcon(new IconicsDrawable(parent, FontAwesome.Icon.faw_users)
.colorRes(R.color.material_drawer_background).backgroundColor(Color.GRAY)
.sizeDp(56).paddingDp(8))
.withSetSelected(unifiedInboxSelected)
.withIdentifier(DRAWER_ID_UNIFIED_INBOX)
);
}
HashSet <Uri> photoUris = new HashSet<Uri>();
List <Account> accounts = preferences.getAccounts();
for (int i = 0; i < preferences.getAccounts().size(); i++) {
Account account = accounts.get(i);
long drawerId = (account.getAccountNumber()+1) << DRAWER_ACCOUNT_SHIFT;
ProfileDrawerItem pdi = new ProfileDrawerItem()
.withNameShown(true)
.withName(account.getDescription())
.withEmail(account.getEmail())
.withIdentifier(drawerId)
.withSetSelected(false)
.withTag(account);
Uri photoUri = Contacts.getInstance(parent).getPhotoUri(account.getEmail());
if (photoUri != null && !photoUris.contains(photoUri)) {
photoUris.add(photoUri);
pdi.withIcon(photoUri);
} else {
pdi.withIcon(new IconicsDrawable(parent, FontAwesome.Icon.faw_user_alt)
.colorRes(R.color.material_drawer_background).backgroundColor(account.getChipColor())
.sizeDp(56).paddingDp(14));
}
headerBuilder.addProfiles(pdi);
}
accountHeader = headerBuilder
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean currentProfile) {
if (profile.getIdentifier() == DRAWER_ID_UNIFIED_INBOX) {
parent.openUnifiedInbox();
return false;
} else {
Account account = (Account) ((ProfileDrawerItem) profile).getTag();
parent.openRealAccount(account);
updateUserAccountsAndFolders(account);
return false;
}
}
})
.build();
return accountHeader;
}
private void addFooterItems() {
@ -130,22 +203,37 @@ public class K9Drawer {
return folderNameFormatter.displayName(folder);
}
public void updateUserAccountsAndFolders(Account account) {
if (account == null) {
selectUnifiedInbox();
} else {
unifiedInboxSelected = false;
accountHeader.setActiveProfile((account.getAccountNumber()+1) << DRAWER_ACCOUNT_SHIFT);
accountHeader.getHeaderBackgroundView().setColorFilter(account.getChipColor(), PorterDuff.Mode.OVERLAY);
ViewModelProvider viewModelProvider = ViewModelProviders.of(parent, new MessageListViewModelFactory());
MessageListViewModel viewModel = viewModelProvider.get(MessageListViewModel.class);
viewModel.getFolders(account).observe(parent, new Observer<List<Folder>>() {
@Override
public void onChanged(@Nullable List<Folder> folders) {
setUserFolders(folders);
}
});
}
}
private OnDrawerItemClickListener createItemClickListener() {
return new OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
long id = drawerItem.getIdentifier();
if (id == DRAWER_ID_UNIFIED_INBOX) {
parent.openUnifiedInbox();
return false;
} else if (id == DRAWER_ID_PREFERENCES) {
if (id == DRAWER_ID_PREFERENCES) {
SettingsActivity.launch(parent);
return false;
} else {
Folder folder = (Folder) drawerItem.getTag();
parent.openFolder(folder.getServerId());
return false;
}
Folder folder = (Folder) drawerItem.getTag();
parent.openFolder(folder.getServerId());
return false;
}
};
}
@ -177,8 +265,6 @@ public class K9Drawer {
if (openedFolderDrawerId != -1) {
drawer.setSelection(openedFolderDrawerId, false);
} else if (unifiedInboxSelected) {
selectUnifiedInbox();
}
}
@ -204,7 +290,9 @@ public class K9Drawer {
public void selectUnifiedInbox() {
unifiedInboxSelected = true;
openedFolderServerId = null;
drawer.setSelection(DRAWER_ID_UNIFIED_INBOX, false);
accountHeader.setActiveProfile(DRAWER_ID_UNIFIED_INBOX);
accountHeader.getHeaderBackgroundView().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
clearUserFolders();
}
public DrawerLayout getLayout() {

View file

@ -12,10 +12,12 @@ import org.jetbrains.anko.coroutines.experimental.bg
class MessageListViewModel(private val folderRepositoryManager: FolderRepositoryManager) : ViewModel() {
private val foldersLiveData = MutableLiveData<List<Folder>>()
private var account: Account? = null
fun getFolders(account: Account): LiveData<List<Folder>> {
if (foldersLiveData.value == null) {
if (foldersLiveData.value == null || this.account != account) {
this.account = account
loadFolders(account)
}

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:angle="45"
android:centerColor="#777"
android:endColor="#444"
android:startColor="#555"
android:type="linear" />
<corners
android:radius="0dp"/>
</shape>

View file

@ -116,7 +116,7 @@
<item name="material_drawer_divider">@color/material_drawer_dark_divider</item>
<item name="material_drawer_selected">@color/material_drawer_dark_selected</item>
<item name="material_drawer_selected_text">@color/material_drawer_dark_selected_text</item>
<item name="material_drawer_header_selection_text">@color/material_drawer_header_selection_text</item>
<item name="material_drawer_header_selection_text">@color/material_drawer_dark_header_selection_text</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="iconUnifiedInbox">@drawable/ic_inbox_multiple_dark</item>