Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 94585ffd authored by Vincent Breitmoser's avatar Vincent Breitmoser Committed by GitHub
Browse files

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

Add accounts header to the drawer
parents 7736d361 e9d3c14f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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}"
+13 −17
Original line number Diff line number Diff line
@@ -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) {
+112 −24
Original line number Diff line number Diff line
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,25 +84,78 @@ public class K9Drawer {
                .withOnDrawerItemClickListener(createItemClickListener())
                .withOnDrawerListener(parent.createOnDrawerListener())
                .withSavedInstance(savedInstanceState)
                .withAccountHeader(buildAccountHeader())
                .build();

        addHeaderItems();
        addFooterItems();

        initializeFolderIcons();
    }

    private void addHeaderItems() {
    private AccountHeader buildAccountHeader() {
        AccountHeaderBuilder headerBuilder = new AccountHeaderBuilder()
                .withActivity(parent)
                .withHeaderBackground(R.drawable.drawer_header_background)
                .withTranslucentStatusBar(false);

        if (!K9.isHideSpecialAccounts()) {
            drawer.addItems(new PrimaryDrawerItem()
            headerBuilder.addProfiles(new ProfileDrawerItem()
                    .withNameShown(true)
                    .withName(R.string.integrated_inbox_title)
                            .withIcon(getResId(R.attr.iconUnifiedInbox))
                            .withIdentifier(DRAWER_ID_UNIFIED_INBOX),
                    new DividerDrawerItem());
                    .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;

            headerItemCount += 2;
            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() {
        drawer.addItems(new DividerDrawerItem(),
@@ -130,23 +203,38 @@ 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;
                }
            }
        };
    }

@@ -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() {
+3 −1
Original line number Diff line number Diff line
@@ -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)
        }

+11 −0
Original line number Diff line number Diff line
<?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>
 No newline at end of file
Loading