Răsfoiți Sursa

Merge pull request #6116 from nextcloud/feature/ui-revamp/account-dialog

New design (UI) - Choose account dialog
Tobias Kaminsky 5 ani în urmă
părinte
comite
196956193d

+ 1 - 1
scripts/analysis/findbugs-results.txt

@@ -1 +1 @@
-78
+370

+ 162 - 0
src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt

@@ -0,0 +1,162 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Infomaniak Network SA
+ * Copyright (C) 2020 Infomaniak Network SA
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.ui
+
+import android.annotation.SuppressLint
+import android.app.Dialog
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.DialogFragment
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.nextcloud.client.account.User
+import com.nextcloud.client.account.UserAccountManager
+import com.owncloud.android.R
+import com.owncloud.android.ui.activity.BaseActivity
+import com.owncloud.android.ui.activity.DrawerActivity
+import com.owncloud.android.ui.adapter.UserListAdapter
+import com.owncloud.android.ui.adapter.UserListItem
+import com.owncloud.android.utils.DisplayUtils
+import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener
+import com.owncloud.android.utils.ThemeUtils
+import kotlinx.android.synthetic.main.account_item.*
+import kotlinx.android.synthetic.main.dialog_choose_account.*
+import java.util.ArrayList
+
+private const val ARG_CURRENT_USER_PARAM = "currentUser"
+
+class ChooseAccountDialogFragment : DialogFragment(), AvatarGenerationListener, UserListAdapter.ClickListener {
+    private lateinit var dialogView: View
+    private var currentUser: User? = null
+    private lateinit var accountManager: UserAccountManager
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        arguments?.let {
+            currentUser = it.getParcelable(ARG_CURRENT_USER_PARAM)
+        }
+    }
+
+    @SuppressLint("InflateParams")
+    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+        dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_choose_account, null)
+        return MaterialAlertDialogBuilder(requireContext())
+            .setView(dialogView)
+            .create()
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        accountManager = (activity as BaseActivity).userAccountManager
+        currentUser?.let { user ->
+
+            // Defining user picture
+            user_icon.tag = user.accountName
+            DisplayUtils.setAvatar(
+                user,
+                this,
+                resources.getDimension(R.dimen.list_item_avatar_icon_radius),
+                resources,
+                user_icon,
+                context)
+
+            // Defining user texts, accounts, etc.
+            user_name.text = user.toOwnCloudAccount().displayName
+            ticker.visibility = View.GONE
+            account.text = user.accountName
+
+            // Defining user right indicator
+            val icon = ThemeUtils.tintDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_check_circle),
+                ThemeUtils.primaryColor(requireContext(), true))
+            account_menu.setImageDrawable(icon)
+
+            // Creating adapter for accounts list
+            val adapter = UserListAdapter(activity as BaseActivity,
+                accountManager,
+                getAccountListItems(),
+                null,
+                this,
+                false,
+                false)
+            accounts_list.adapter = adapter
+
+            // Creating listeners for quick-actions
+            current_account.setOnClickListener {
+                dismiss()
+            }
+            add_account.setOnClickListener {
+                (activity as DrawerActivity).openAddAccount()
+            }
+            manage_accounts.setOnClickListener {
+                (activity as DrawerActivity).openManageAccounts()
+            }
+        }
+    }
+
+    private fun getAccountListItems(): List<UserListItem>? {
+        val users = accountManager.allUsers
+        val adapterUserList: MutableList<UserListItem> = ArrayList(users.size)
+        // Remove the current account from the adapter to display only other accounts
+        for (user in users) {
+            if (user != currentUser) {
+                adapterUserList.add(UserListItem(user))
+            }
+        }
+        return adapterUserList
+    }
+
+    /**
+     * Fragment creator
+     */
+    companion object {
+        @JvmStatic
+        fun newInstance(user: User) =
+            ChooseAccountDialogFragment().apply {
+                arguments = Bundle().apply {
+                    putParcelable(ARG_CURRENT_USER_PARAM, user)
+                }
+            }
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+        return dialogView
+    }
+
+    override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean {
+        return (callContext as ImageView).tag.toString() == tag
+    }
+
+    override fun avatarGenerated(avatarDrawable: Drawable?, callContext: Any?) {
+        user_icon.setImageDrawable(avatarDrawable)
+    }
+
+    override fun onAccountClicked(user: User?) {
+        (activity as DrawerActivity).accountClicked(user.hashCode())
+    }
+
+    override fun onOptionItemClicked(user: User?, view: View?) {
+        // Un-needed for this context
+    }
+}

+ 22 - 11
src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -9,6 +9,7 @@
  * Copyright (C) 2016 Nextcloud
  * Copyright (C) 2016 Nextcloud
  * Copyright (C) 2016 ownCloud Inc.
  * Copyright (C) 2016 ownCloud Inc.
  * Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
  * Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
+ * Copyright (C) 2020 Infomaniak Network SA
  *
  *
  * This program is free software; you can redistribute it and/or
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -62,6 +63,7 @@ import com.nextcloud.client.onboarding.FirstRunActivity;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.DarkMode;
 import com.nextcloud.client.preferences.DarkMode;
 import com.nextcloud.java.util.Optional;
 import com.nextcloud.java.util.Optional;
+import com.nextcloud.ui.ChooseAccountDialogFragment;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.PassCodeManager;
 import com.owncloud.android.authentication.PassCodeManager;
@@ -495,16 +497,7 @@ public abstract class DrawerActivity extends ToolbarActivity
     private void handleAccountItemClick(MenuItem menuItem) {
     private void handleAccountItemClick(MenuItem menuItem) {
         switch (menuItem.getItemId()) {
         switch (menuItem.getItemId()) {
             case R.id.drawer_menu_account_add:
             case R.id.drawer_menu_account_add:
-                boolean isProviderOrOwnInstallationVisible = getResources()
-                    .getBoolean(R.bool.show_provider_or_own_installation);
-
-                if (isProviderOrOwnInstallationVisible) {
-                    Intent firstRunIntent = new Intent(getApplicationContext(), FirstRunActivity.class);
-                    firstRunIntent.putExtra(FirstRunActivity.EXTRA_ALLOW_CLOSE, true);
-                    startActivity(firstRunIntent);
-                } else {
-                    startAccountCreation();
-                }
+                openAddAccount();
                 break;
                 break;
 
 
             case R.id.drawer_menu_account_manage:
             case R.id.drawer_menu_account_manage:
@@ -517,11 +510,29 @@ public abstract class DrawerActivity extends ToolbarActivity
         }
         }
     }
     }
 
 
+    public void showManageAccountsDialog() {
+        ChooseAccountDialogFragment choseAccountDialog = ChooseAccountDialogFragment.newInstance(accountManager.getUser());
+        choseAccountDialog.show(getSupportFragmentManager(), "fragment_chose_account");
+    }
+
     public void openManageAccounts() {
     public void openManageAccounts() {
         Intent manageAccountsIntent = new Intent(getApplicationContext(), ManageAccountsActivity.class);
         Intent manageAccountsIntent = new Intent(getApplicationContext(), ManageAccountsActivity.class);
         startActivityForResult(manageAccountsIntent, ACTION_MANAGE_ACCOUNTS);
         startActivityForResult(manageAccountsIntent, ACTION_MANAGE_ACCOUNTS);
     }
     }
 
 
+    public void openAddAccount() {
+        boolean isProviderOrOwnInstallationVisible = getResources()
+            .getBoolean(R.bool.show_provider_or_own_installation);
+
+        if (isProviderOrOwnInstallationVisible) {
+            Intent firstRunIntent = new Intent(getApplicationContext(), FirstRunActivity.class);
+            firstRunIntent.putExtra(FirstRunActivity.EXTRA_ALLOW_CLOSE, true);
+            startActivity(firstRunIntent);
+        } else {
+            startAccountCreation();
+        }
+    }
+
     private void startPhotoSearch(MenuItem menuItem) {
     private void startPhotoSearch(MenuItem menuItem) {
         SearchEvent searchEvent = new SearchEvent("image/%", SearchRemoteOperation.SearchType.PHOTO_SEARCH);
         SearchEvent searchEvent = new SearchEvent("image/%", SearchRemoteOperation.SearchType.PHOTO_SEARCH);
 
 
@@ -569,7 +580,7 @@ public abstract class DrawerActivity extends ToolbarActivity
      *
      *
      * @param hashCode HashCode of account to be set
      * @param hashCode HashCode of account to be set
      */
      */
-    private void accountClicked(int hashCode) {
+    public void accountClicked(int hashCode) {
         final User currentUser = accountManager.getUser();
         final User currentUser = accountManager.getUser();
         if (currentUser.hashCode() != hashCode && accountManager.setCurrentOwnCloudAccount(hashCode)) {
         if (currentUser.hashCode() != hashCode && accountManager.setCurrentOwnCloudAccount(hashCode)) {
             fetchExternalLinks(true);
             fetchExternalLinks(true);

+ 1 - 1
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -265,7 +265,7 @@ public class FileDisplayActivity extends FileActivity
         });
         });
 
 
         mSwitchAccountButton.setOnClickListener(v -> {
         mSwitchAccountButton.setOnClickListener(v -> {
-            openManageAccounts();
+            showManageAccountsDialog();
         });
         });
 
 
         mDualPane = getResources().getBoolean(R.bool.large_land_layout);
         mDualPane = getResources().getBoolean(R.bool.large_land_layout);

+ 3 - 5
src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -161,7 +161,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
                                               getUserListItems(),
                                               getUserListItems(),
                                               tintedCheck,
                                               tintedCheck,
                                               this,
                                               this,
-                                              multipleAccountsSupported);
+                                              multipleAccountsSupported, true);
 
 
         recyclerView.setAdapter(userListAdapter);
         recyclerView.setAdapter(userListAdapter);
         recyclerView.setLayoutManager(new LinearLayoutManager(this));
         recyclerView.setLayoutManager(new LinearLayoutManager(this));
@@ -309,8 +309,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
                                       getUserListItems(),
                                       getUserListItems(),
                                       tintedCheck,
                                       tintedCheck,
                                       this,
                                       this,
-                                      multipleAccountsSupported
-                                  );
+                                      multipleAccountsSupported, false);
                                   recyclerView.setAdapter(userListAdapter);
                                   recyclerView.setAdapter(userListAdapter);
                                   runOnUiThread(() -> userListAdapter.notifyDataSetChanged());
                                   runOnUiThread(() -> userListAdapter.notifyDataSetChanged());
                               } catch (OperationCanceledException e) {
                               } catch (OperationCanceledException e) {
@@ -362,8 +361,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
                                                       userListItemArray,
                                                       userListItemArray,
                                                       tintedCheck,
                                                       tintedCheck,
                                                       this,
                                                       this,
-                                                      multipleAccountsSupported
-                );
+                                                      multipleAccountsSupported, false);
                 recyclerView.setAdapter(userListAdapter);
                 recyclerView.setAdapter(userListAdapter);
             } else {
             } else {
                 onBackPressed();
                 onBackPressed();

+ 8 - 4
src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java

@@ -40,7 +40,6 @@ import com.owncloud.android.R;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.BaseActivity;
 import com.owncloud.android.ui.activity.BaseActivity;
-import com.owncloud.android.ui.activity.ReceiveExternalFilesActivity;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ThemeUtils;
 import com.owncloud.android.utils.ThemeUtils;
 
 
@@ -68,13 +67,15 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
     public static final int KEY_USER_INFO_REQUEST_CODE = 13;
     public static final int KEY_USER_INFO_REQUEST_CODE = 13;
     private ClickListener clickListener;
     private ClickListener clickListener;
     private boolean showAddAccount;
     private boolean showAddAccount;
+    private boolean showDotsMenu;
 
 
     public UserListAdapter(BaseActivity context,
     public UserListAdapter(BaseActivity context,
                            UserAccountManager accountManager,
                            UserAccountManager accountManager,
                            List<UserListItem> values,
                            List<UserListItem> values,
                            Drawable tintedCheck,
                            Drawable tintedCheck,
                            ClickListener clickListener,
                            ClickListener clickListener,
-                           boolean showAddAccount) {
+                           boolean showAddAccount,
+                           boolean showDotsMenu) {
         this.context = context;
         this.context = context;
         this.accountManager = accountManager;
         this.accountManager = accountManager;
         this.values = values;
         this.values = values;
@@ -85,6 +86,7 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
         this.tintedCheck = tintedCheck;
         this.tintedCheck = tintedCheck;
         this.clickListener = clickListener;
         this.clickListener = clickListener;
         this.showAddAccount = showAddAccount;
         this.showAddAccount = showAddAccount;
+        this.showDotsMenu = showDotsMenu;
     }
     }
 
 
     @Override
     @Override
@@ -306,10 +308,12 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
             ImageView accountMenu = view.findViewById(R.id.account_menu);
             ImageView accountMenu = view.findViewById(R.id.account_menu);
 
 
             view.setOnClickListener(this);
             view.setOnClickListener(this);
-            if(context instanceof ReceiveExternalFilesActivity) {
+            if (showDotsMenu) {
+                accountMenu.setVisibility(View.VISIBLE);
+                accountMenu.setOnClickListener(this);
+            } else {
                 accountMenu.setVisibility(View.GONE);
                 accountMenu.setVisibility(View.GONE);
             }
             }
-            accountMenu.setOnClickListener(this);
         }
         }
 
 
         public void setData(User user) {
         public void setData(User user) {

+ 1 - 0
src/main/java/com/owncloud/android/ui/dialog/MultipleAccountsDialog.java

@@ -95,6 +95,7 @@ public class MultipleAccountsDialog extends DialogFragment implements Injectable
                                                       getAccountListItems(),
                                                       getAccountListItems(),
                                                       tintedCheck,
                                                       tintedCheck,
                                                       this,
                                                       this,
+                                                      false,
                                                       false);
                                                       false);
 
 
         listView.setHasFixedSize(true);
         listView.setHasFixedSize(true);

+ 19 - 2
src/main/res/drawable/ic_check_circle.xml

@@ -1,8 +1,25 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2020 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:width="24dp"
     android:height="24dp"
     android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:tint="#4995FB"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
     <path
     <path
         android:fillColor="#FF000000"
         android:fillColor="#FF000000"
         android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z" />
         android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z" />

+ 55 - 45
src/main/res/layout/account_item.xml

@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   Nextcloud Android client application
   Nextcloud Android client application
 
 
   Copyright (C) 2016 Andy Scherzinger
   Copyright (C) 2016 Andy Scherzinger
   Copyright (C) 2016 Nextcloud
   Copyright (C) 2016 Nextcloud
   Copyright (C) 2016 ownCloud
   Copyright (C) 2016 ownCloud
+  Copyright (C) 2020 Infomaniak Network SA
 
 
   This program is free software; you can redistribute it and/or
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
   modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -19,78 +19,87 @@
   You should have received a copy of the GNU Affero General Public
   You should have received a copy of the GNU Affero General Public
   License along with this program. If not, see <http://www.gnu.org/licenses/>.
   License along with this program. If not, see <http://www.gnu.org/licenses/>.
 -->
 -->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<com.google.android.material.card.MaterialCardView 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:layout_width="match_parent"
     android:layout_width="match_parent"
     android:layout_height="@dimen/account_item_layout_height"
     android:layout_height="@dimen/account_item_layout_height"
+    android:layout_margin="@dimen/standard_quarter_margin"
     android:orientation="horizontal"
     android:orientation="horizontal"
-    android:weightSum="1">
+    app:cardBackgroundColor="@color/transparent"
+    app:cardElevation="0dp">
 
 
-    <FrameLayout
-        android:id="@+id/avatar_container"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_alignParentStart="true">
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        tools:ignore="UnusedAttribute">
 
 
-        <ImageView
-            android:id="@+id/user_icon"
-            android:layout_width="@dimen/user_icon_size"
-            android:layout_height="@dimen/user_icon_size"
-            android:layout_gravity="top|start"
-            android:layout_marginBottom="@dimen/account_item_layout_user_image_margin"
-            android:layout_marginStart="@dimen/account_item_layout_user_image_left_start_margin"
-            android:layout_marginEnd="@dimen/account_item_layout_user_image_margin"
-            android:layout_marginTop="@dimen/account_item_layout_user_image_margin"
-            android:src="@drawable/folder"
-            android:contentDescription="@string/avatar"/>
+        <FrameLayout
+            android:id="@+id/avatar_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true">
 
 
-        <ImageView
-            android:id="@+id/ticker"
-            android:layout_width="18dp"
-            android:layout_height="18dp"
-            android:layout_gravity="bottom|end"
-            android:background="@drawable/round_bgnd"
-            android:src="@drawable/account_circle_white"
-            android:contentDescription="@string/active_user"/>
-    </FrameLayout>
+            <ImageView
+                android:id="@+id/user_icon"
+                android:layout_width="@dimen/user_icon_size"
+                android:layout_height="@dimen/user_icon_size"
+                android:layout_gravity="top|start"
+                android:layout_marginStart="@dimen/account_item_layout_user_image_left_start_margin"
+                android:layout_marginTop="@dimen/account_item_layout_user_image_margin"
+                android:layout_marginEnd="@dimen/account_item_layout_user_image_margin"
+                android:layout_marginBottom="@dimen/account_item_layout_user_image_margin"
+                android:contentDescription="@string/avatar"
+                android:src="@drawable/folder" />
+
+            <ImageView
+                android:id="@+id/ticker"
+                android:layout_width="18dp"
+                android:layout_height="18dp"
+                android:layout_gravity="bottom|end"
+                android:background="@drawable/round_bgnd"
+                android:contentDescription="@string/active_user"
+                android:src="@drawable/account_circle_white" />
+        </FrameLayout>
 
 
 
 
         <LinearLayout
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true"
             android:layout_centerInParent="true"
+            android:layout_marginEnd="25dp"
             android:layout_toEndOf="@id/avatar_container"
             android:layout_toEndOf="@id/avatar_container"
             android:orientation="vertical"
             android:orientation="vertical"
-            android:paddingEnd="@dimen/zero"
-            android:layout_marginEnd="25dp"
-            android:paddingStart="3dp">
+            android:paddingStart="3dp"
+            android:paddingEnd="@dimen/zero">
 
 
             <TextView
             <TextView
                 android:id="@+id/user_name"
                 android:id="@+id/user_name"
                 android:layout_width="match_parent"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginEnd="@dimen/standard_half_margin"
-                android:layout_marginStart="@dimen/standard_margin"
+                android:layout_marginStart="@dimen/standard_half_margin"
                 android:layout_marginTop="@dimen/standard_quarter_margin"
                 android:layout_marginTop="@dimen/standard_quarter_margin"
+                android:layout_marginEnd="@dimen/standard_double_margin"
                 android:ellipsize="end"
                 android:ellipsize="end"
                 android:gravity="bottom"
                 android:gravity="bottom"
                 android:maxLines="1"
                 android:maxLines="1"
                 android:text="@string/placeholder_filename"
                 android:text="@string/placeholder_filename"
-                android:textAppearance="?android:attr/textAppearanceListItem"/>
+                android:textAppearance="?android:attr/textAppearanceListItem" />
 
 
             <TextView
             <TextView
                 android:id="@+id/account"
                 android:id="@+id/account"
                 android:layout_width="match_parent"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_marginStart="@dimen/standard_half_margin"
+                android:layout_marginEnd="@dimen/standard_double_margin"
                 android:layout_marginBottom="@dimen/standard_quarter_margin"
                 android:layout_marginBottom="@dimen/standard_quarter_margin"
-                android:layout_marginEnd="@dimen/standard_half_margin"
-                android:layout_marginStart="@dimen/standard_margin"
                 android:ellipsize="end"
                 android:ellipsize="end"
                 android:gravity="top"
                 android:gravity="top"
-                android:maxLines="2"
+                android:maxLines="1"
                 android:text="@string/placeholder_sentence"
                 android:text="@string/placeholder_sentence"
-                android:textColor="?android:attr/textColorSecondary"/>
+                android:textColor="?android:attr/textColorSecondary" />
 
 
         </LinearLayout>
         </LinearLayout>
 
 
@@ -98,13 +107,14 @@
             android:id="@+id/account_menu"
             android:id="@+id/account_menu"
             android:layout_width="wrap_content"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_height="match_parent"
-            android:layout_centerVertical="true"
             android:layout_alignParentEnd="true"
             android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
             android:clickable="true"
             android:clickable="true"
             android:contentDescription="@string/overflow_menu"
             android:contentDescription="@string/overflow_menu"
             android:focusable="true"
             android:focusable="true"
-            android:paddingEnd="@dimen/alternate_padding"
             android:paddingStart="@dimen/standard_half_padding"
             android:paddingStart="@dimen/standard_half_padding"
-            android:src="@drawable/ic_dots_vertical"/>
+            android:paddingEnd="@dimen/alternate_padding"
+            android:src="@drawable/ic_dots_vertical" />
 
 
-</RelativeLayout>
+    </RelativeLayout>
+</com.google.android.material.card.MaterialCardView>

+ 101 - 0
src/main/res/layout/dialog_choose_account.xml

@@ -0,0 +1,101 @@
+<!--
+  Nextcloud Android client application
+
+  Copyright (C) 2020 Infomaniak Network SA
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context="com.nextcloud.ui.ChooseAccountDialogFragment">
+
+    <include
+        android:id="@+id/current_account"
+        layout="@layout/account_item"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/account_item_layout_height"
+        android:layout_margin="@dimen/standard_quarter_margin"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/separator_line"
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:layout_marginTop="@dimen/standard_quarter_margin"
+        android:background="@color/list_divider_background"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/current_account" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/accounts_list"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/account_action_button_vertical_margin"
+        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+        app:layout_constrainedHeight="true"
+        app:layout_constraintBottom_toTopOf="@+id/add_account"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/separator_line" />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/add_account"
+        style="@style/Widget.MaterialComponents.Button.TextButton.Icon"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/account_action_button_height"
+        android:layout_marginStart="@dimen/account_action_button_margin"
+        android:layout_marginEnd="@dimen/account_action_button_margin"
+        android:paddingStart="10dp"
+        android:paddingEnd="0dp"
+        android:text="@string/prefs_add_account"
+        android:textAlignment="textStart"
+        android:textAllCaps="false"
+        android:textColor="@color/fontAppbar"
+        app:icon="@drawable/ic_account_plus"
+        app:iconGravity="start"
+        app:iconPadding="22dp"
+        app:iconTint="@color/fontAppbar"
+        app:layout_constraintBottom_toTopOf="@+id/manage_accounts"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/manage_accounts"
+        style="@style/Widget.MaterialComponents.Button.TextButton.Icon"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/account_action_button_height"
+        android:layout_marginStart="@dimen/account_action_button_margin"
+        android:layout_marginEnd="@dimen/account_action_button_margin"
+        android:layout_marginBottom="@dimen/account_action_button_margin"
+        android:paddingStart="12dp"
+        android:paddingEnd="0dp"
+        android:text="@string/prefs_manage_accounts"
+        android:textAlignment="textStart"
+        android:textAllCaps="false"
+        android:textColor="@color/fontAppbar"
+        app:icon="@drawable/ic_settings"
+        app:iconGravity="start"
+        app:iconPadding="20dp"
+        app:iconTint="@color/fontAppbar"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 4 - 2
src/main/res/values/dims.xml

@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   ownCloud Android client application
   ownCloud Android client application
 
 
   Copyright (C) 2014 ownCloud Inc.
   Copyright (C) 2014 ownCloud Inc.
@@ -144,4 +143,7 @@
     <dimen name="button_corner_radius">24dp</dimen>
     <dimen name="button_corner_radius">24dp</dimen>
     <integer name="media_grid_width">4</integer>
     <integer name="media_grid_width">4</integer>
     <dimen name="copy_internal_link_padding">10dp</dimen>
     <dimen name="copy_internal_link_padding">10dp</dimen>
+    <dimen name="account_action_button_margin">12dp</dimen>
+    <dimen name="account_action_button_height">50dp</dimen>
+    <dimen name="account_action_button_vertical_margin">10dp</dimen>
 </resources>
 </resources>