Эх сурвалжийг харах

Merge pull request #585 from nextcloud/feature-user-information

Show user information
Andy Scherzinger 8 жил өмнө
parent
commit
a11dab8a13

+ 3 - 0
build.gradle

@@ -173,11 +173,14 @@ dependencies {
     compile "com.android.support:design:${supportLibraryVersion}"
     compile 'com.jakewharton:disklrucache:2.0.2'
     compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
+    compile "com.android.support:cardview-v7:${supportLibraryVersion}"
     compile 'com.getbase:floatingactionbutton:1.10.1'
     compile 'com.google.code.findbugs:annotations:2.0.1'
     compile group: 'commons-io', name: 'commons-io', version: '2.4'
     compile 'com.google.android.gms:play-services:10.2.0'
     compile 'com.github.evernote:android-job:v1.1.8'
+    compile 'com.jakewharton:butterknife:8.4.0'
+    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
 
     /// dependencies for local unit tests
     testCompile 'junit:junit:4.12'

+ 1 - 0
src/main/AndroidManifest.xml

@@ -75,6 +75,7 @@
             </intent-filter>
         </activity>
         <activity android:name=".ui.activity.ManageAccountsActivity" />
+        <activity android:name=".ui.activity.UserInfoActivity" />
         <activity android:name=".ui.activity.ParticipateActivity" />
         <activity android:name=".ui.activity.FolderSyncActivity" />
         <activity android:name=".ui.activity.UploadFilesActivity" />

+ 52 - 84
src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -24,20 +24,14 @@ import android.accounts.AccountManager;
 import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
 import android.accounts.OperationCanceledException;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.view.MenuItem;
@@ -48,10 +42,10 @@ import android.widget.ListView;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
-import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.ui.adapter.AccountListAdapter;
@@ -59,6 +53,8 @@ import com.owncloud.android.ui.adapter.AccountListItem;
 import com.owncloud.android.ui.helpers.FileOperationsHelper;
 import com.owncloud.android.utils.DisplayUtils;
 
+import org.parceler.Parcels;
+
 import java.util.ArrayList;
 import java.util.Set;
 
@@ -71,6 +67,12 @@ public class ManageAccountsActivity extends FileActivity
     public static final String KEY_ACCOUNT_LIST_CHANGED = "ACCOUNT_LIST_CHANGED";
     public static final String KEY_CURRENT_ACCOUNT_CHANGED = "CURRENT_ACCOUNT_CHANGED";
 
+    private static final String KEY_ACCOUNT = "ACCOUNT";
+    private static final String KEY_DISPLAY_NAME = "DISPLAY_NAME";
+
+    private static final int KEY_USER_INFO_REQUEST_CODE = 13;
+    private static final int KEY_DELETE_CODE = 101;
+
     private ListView mListView;
     private final Handler mHandler = new Handler();
     private String mAccountName;
@@ -108,16 +110,46 @@ public class ManageAccountsActivity extends FileActivity
 
         mListView.setAdapter(mAccountListAdapter);
 
+        final Intent intent = new Intent(this, UserInfoActivity.class);
+
         mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                switchAccount(mAccountListAdapter.getItem(position).getAccount());
+                Account account = mAccountListAdapter.getItem(position).getAccount();
+                intent.putExtra(KEY_ACCOUNT, Parcels.wrap(account));
+                try {
+                    OwnCloudAccount oca = new OwnCloudAccount(account, MainApp.getAppContext());
+                    intent.putExtra(KEY_DISPLAY_NAME, oca.getDisplayName());
+                } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
+                    Log_OC.d(TAG, "Failed to find NC account");
+                }
+
+                startActivityForResult(intent, KEY_USER_INFO_REQUEST_CODE);
             }
         });
 
         initializeComponentGetters();
     }
 
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (resultCode) {
+            case KEY_DELETE_CODE:
+                if (data != null) {
+                    Bundle bundle = data.getExtras();
+                    if (bundle.containsKey(KEY_ACCOUNT)) {
+                        Account account = Parcels.unwrap(bundle.getParcelable(KEY_ACCOUNT));
+                        mAccountName = account.name;
+                        performAccountRemoval(account);
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
     @Override
     public void onBackPressed() {
         Intent resultIntent = new Intent();
@@ -202,22 +234,6 @@ public class ManageAccountsActivity extends FileActivity
         return retval;
     }
 
-    @Override
-    public void performAccountRemoval(Account account) {
-        AccountRemovalConfirmationDialog dialog = AccountRemovalConfirmationDialog.newInstance(account);
-        mAccountName = account.name;
-        dialog.show(getFragmentManager(), "dialog");
-    }
-
-    @Override
-    public void changePasswordOfAccount(Account account) {
-        Intent updateAccountCredentials = new Intent(ManageAccountsActivity.this, AuthenticatorActivity.class);
-        updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, account);
-        updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
-                AuthenticatorActivity.ACTION_UPDATE_TOKEN);
-        startActivity(updateAccountCredentials);
-    }
-
     @Override
     public void createAccount() {
         AccountManager am = AccountManager.get(getApplicationContext());
@@ -256,20 +272,6 @@ public class ManageAccountsActivity extends FileActivity
                 }, mHandler);
     }
 
-    public void switchAccount(Account account) {
-        if (getAccount().name.equals(account.name)) {
-            // current account selected, just go back
-            finish();
-        } else {
-            // restart list of files with new account
-            AccountUtils.setCurrentOwnCloudAccount(ManageAccountsActivity.this, account.name);
-            Intent i = new Intent(ManageAccountsActivity.this, FileDisplayActivity.class);
-            i.putExtra(FileActivity.EXTRA_ACCOUNT, account);
-            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            startActivity(i);
-        }
-    }
-
     @Override
     public void run(AccountManagerFuture<Boolean> future) {
         if (future.isDone()) {
@@ -294,8 +296,13 @@ public class ManageAccountsActivity extends FileActivity
                 AccountUtils.setCurrentOwnCloudAccount(this, accountName);
             }
 
-            mAccountListAdapter = new AccountListAdapter(this, getAccountListItems(), mTintedCheck);
-            mListView.setAdapter(mAccountListAdapter);
+            ArrayList<AccountListItem> accountListItemArray = getAccountListItems();
+            if (accountListItemArray.size() > 1) {
+                mAccountListAdapter = new AccountListAdapter(this, accountListItemArray, mTintedCheck);
+                mListView.setAdapter(mAccountListAdapter);
+            } else {
+                onBackPressed();
+            }
         }
     }
 
@@ -339,6 +346,11 @@ public class ManageAccountsActivity extends FileActivity
         return new ManageAccountsServiceConnection();
     }
 
+    private void performAccountRemoval(Account account) {
+        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+        am.removeAccount(account, this, this.getHandler());
+    }
+
     /**
      * Defines callbacks for service binding, passed to bindService()
      */
@@ -368,48 +380,4 @@ public class ManageAccountsActivity extends FileActivity
         }
     }
 
-    public static class AccountRemovalConfirmationDialog extends DialogFragment {
-
-        private static final String ARG__ACCOUNT = "account";
-
-        private Account mAccount;
-
-        public static AccountRemovalConfirmationDialog newInstance(Account account) {
-            Bundle bundle = new Bundle();
-            bundle.putParcelable(ARG__ACCOUNT, account);
-
-            AccountRemovalConfirmationDialog dialog = new AccountRemovalConfirmationDialog();
-            dialog.setArguments(bundle);
-
-            return dialog;
-        }
-
-        @Override
-        public void onCreate(@Nullable Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            mAccount = getArguments().getParcelable(ARG__ACCOUNT);
-        }
-
-        @NonNull
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            return new AlertDialog.Builder(getActivity(), R.style.Theme_ownCloud_Dialog)
-                    .setTitle(R.string.delete_account)
-                    .setMessage(getResources().getString(R.string.delete_account_warning, mAccount.name))
-                    .setIcon(R.drawable.ic_warning)
-                    .setPositiveButton(R.string.common_ok,
-                            new DialogInterface.OnClickListener() {
-                                @Override
-                                public void onClick(DialogInterface dialogInterface, int i) {
-                                    AccountManager am = (AccountManager) getActivity().getSystemService(ACCOUNT_SERVICE);
-                                    am.removeAccount(
-                                            mAccount,
-                                            (ManageAccountsActivity)getActivity(),
-                                            ((ManageAccountsActivity)getActivity()).getHandler());
-                                }
-                            })
-                    .setNegativeButton(R.string.common_cancel, null)
-                    .create();
-        }
-    }
 }

+ 4 - 2
src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java

@@ -54,8 +54,10 @@ public abstract class ToolbarActivity extends BaseActivity {
         setSupportActionBar(toolbar);
 
         mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
-        mProgressBar.setIndeterminateDrawable(
-                ContextCompat.getDrawable(this, R.drawable.actionbar_progress_indeterminate_horizontal));
+        if (mProgressBar != null) {
+            mProgressBar.setIndeterminateDrawable(
+                    ContextCompat.getDrawable(this, R.drawable.actionbar_progress_indeterminate_horizontal));
+        }
     }
 
     /**

+ 378 - 0
src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java

@@ -0,0 +1,378 @@
+/**
+ * Nextcloud Android client application
+ *
+ * @author Mario Danic
+ * @author Andy Scherzinger
+ * Copyright (C) 2017 Mario Danic
+ * Copyright (C) 2017 Andy Scherzinger
+ * Copyright (C) 2017 Nextcloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) 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.owncloud.android.ui.activity;
+
+import android.accounts.Account;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.authentication.AuthenticatorActivity;
+import com.owncloud.android.lib.common.UserInfo;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
+import com.owncloud.android.utils.DisplayUtils;
+
+import org.parceler.Parcels;
+
+import butterknife.BindString;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
+/**
+ * This Activity presents the user information.
+ */
+public class UserInfoActivity extends FileActivity {
+    private static final String TAG = UserInfoActivity.class.getSimpleName();
+
+    private static final String KEY_USER_DATA = "USER_DATA";
+    private static final String KEY_ACCOUNT = "ACCOUNT";
+
+    private static final int KEY_DELETE_CODE = 101;
+
+    @BindView(R.id.empty_list_view)
+    public LinearLayout emptyContentContainer;
+
+    @BindView(R.id.empty_list_view_text)
+    public TextView emptyContentMessage;
+
+    @BindView(R.id.empty_list_view_headline)
+    public TextView emptyContentHeadline;
+
+    @BindView(R.id.empty_list_icon)
+    public ImageView emptyContentIcon;
+
+    @BindView(R.id.user_info_view)
+    public LinearLayout userInfoView;
+
+    @BindView(R.id.user_icon)
+    public ImageView avatar;
+
+    @BindView(R.id.drawer_username)
+    public TextView userName;
+
+    @BindView(R.id.drawer_username_full)
+    public TextView fullName;
+
+    @BindView(R.id.phone_container)
+    public View mPhoneNumberContainer;
+
+    @BindView(R.id.phone_number)
+    public TextView mPhoneNumberTextView;
+
+    @BindView(R.id.phone_icon)
+    public ImageView mPhoneNumberIcon;
+
+    @BindView(R.id.email_container)
+    public View mEmailContainer;
+
+    @BindView(R.id.email_address)
+    public TextView mEmailAddressTextView;
+
+    @BindView(R.id.email_icon)
+    public ImageView mEmailIcon;
+
+    @BindView(R.id.address_container)
+    public View mAddressContainer;
+
+    @BindView(R.id.address)
+    public TextView mAddressTextView;
+
+    @BindView(R.id.address_icon)
+    public ImageView mAddressIcon;
+
+    @BindView(R.id.website_container)
+    public View mWebsiteContainer;
+
+    @BindView(R.id.website_address)
+    public TextView mWebsiteTextView;
+
+    @BindView(R.id.twitter_container)
+    public View mTwitterContainer;
+
+    @BindView(R.id.twitter_handle)
+    public TextView mTwitterHandleTextView;
+
+    @BindView(R.id.empty_list_progress)
+    public ProgressBar multiListProgressBar;
+
+    @BindString(R.string.preview_sorry)
+    public String sorryMessage;
+
+    private float mCurrentAccountAvatarRadiusDimension;
+
+    private Unbinder unbinder;
+
+    private UserInfo userInfo;
+    private Account account;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log_OC.v(TAG, "onCreate() start");
+        super.onCreate(savedInstanceState);
+
+        Bundle bundle = getIntent().getExtras();
+
+        account = Parcels.unwrap(bundle.getParcelable(KEY_ACCOUNT));
+
+        if (savedInstanceState != null && savedInstanceState.containsKey(KEY_USER_DATA)) {
+            userInfo = Parcels.unwrap(savedInstanceState.getParcelable(KEY_USER_DATA));
+        }
+
+        mCurrentAccountAvatarRadiusDimension = getResources().getDimension(R.dimen.nav_drawer_header_avatar_radius);
+
+        setContentView(R.layout.user_info_layout);
+        unbinder = ButterKnife.bind(this);
+
+        setupToolbar();
+        updateActionBarTitleAndHomeButtonByString("");
+
+        setAccount(AccountUtils.getCurrentOwnCloudAccount(this));
+        onAccountSet(false);
+
+        if (userInfo != null) {
+            populateUserInfoUi(userInfo);
+            emptyContentContainer.setVisibility(View.GONE);
+            userInfoView.setVisibility(View.VISIBLE);
+        } else {
+            setMultiListLoadingMessage();
+            fetchAndSetData();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.user_info_menu, menu);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        boolean retval = true;
+        switch (item.getItemId()) {
+            case android.R.id.home:
+                onBackPressed();
+                break;
+            case R.id.change_password:
+                changeAccountPassword(account);
+                break;
+            case R.id.delete_account:
+                openAccountRemovalConfirmationDialog(account);
+                break;
+            default:
+                retval = super.onOptionsItemSelected(item);
+                break;
+        }
+        return retval;
+    }
+
+    public void onDestroy() {
+        super.onDestroy();
+        unbinder.unbind();
+    }
+
+    private void setMultiListLoadingMessage() {
+        if (emptyContentContainer != null) {
+            emptyContentHeadline.setText(R.string.file_list_loading);
+            emptyContentMessage.setText("");
+
+            emptyContentIcon.setVisibility(View.GONE);
+            multiListProgressBar.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private void setMessageForMultiList(String headline, String message) {
+        if (emptyContentContainer != null && emptyContentMessage != null) {
+            emptyContentHeadline.setText(headline);
+            emptyContentMessage.setText(message);
+
+            multiListProgressBar.setVisibility(View.GONE);
+        }
+    }
+
+    private void populateUserInfoUi(UserInfo userInfo) {
+        userName.setText(account.name);
+        DisplayUtils.setAvatar(account, UserInfoActivity.this,
+                mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager(),avatar);
+
+        int tint = ContextCompat.getColor(this, R.color.primary);
+
+        if (userInfo != null) {
+            if (!TextUtils.isEmpty(userInfo.getDisplayName())) {
+                fullName.setText(userInfo.getDisplayName());
+            }
+
+            populateUserInfoElement(mPhoneNumberContainer, mPhoneNumberTextView, userInfo.getPhone(),
+                    mPhoneNumberIcon, tint);
+            populateUserInfoElement(mEmailContainer, mEmailAddressTextView, userInfo.getEmail(), mEmailIcon, tint);
+            populateUserInfoElement(mAddressContainer, mAddressTextView, userInfo.getAddress(), mAddressIcon, tint);
+
+            populateUserInfoElement(mWebsiteContainer, mWebsiteTextView, userInfo.getWebpage());
+            populateUserInfoElement(mTwitterContainer, mTwitterHandleTextView, userInfo.getTwitter());
+        }
+    }
+
+    private void populateUserInfoElement(View container, TextView textView, String text) {
+        if (!TextUtils.isEmpty(text)) {
+            textView.setText(text);
+        } else {
+            container.setVisibility(View.GONE);
+        }
+    }
+
+    private void populateUserInfoElement(View container, TextView textView, String text, ImageView icon, @ColorInt int
+            tint) {
+        if (!TextUtils.isEmpty(text)) {
+            textView.setText(text);
+            DrawableCompat.setTint(icon.getDrawable(), tint);
+        } else {
+            container.setVisibility(View.GONE);
+        }
+    }
+
+
+    private void changeAccountPassword(Account account) {
+        Intent updateAccountCredentials = new Intent(UserInfoActivity.this, AuthenticatorActivity.class);
+        updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, account);
+        updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
+                AuthenticatorActivity.ACTION_UPDATE_TOKEN);
+        startActivity(updateAccountCredentials);
+    }
+
+    private void openAccountRemovalConfirmationDialog(Account account) {
+        UserInfoActivity.AccountRemovalConfirmationDialog dialog =
+                UserInfoActivity.AccountRemovalConfirmationDialog.newInstance(account);
+        dialog.show(getFragmentManager(), "dialog");
+    }
+
+    public static class AccountRemovalConfirmationDialog extends DialogFragment {
+
+        private Account account;
+
+        public static UserInfoActivity.AccountRemovalConfirmationDialog newInstance(Account account) {
+            Bundle bundle = new Bundle();
+            bundle.putParcelable(KEY_ACCOUNT, account);
+
+            UserInfoActivity.AccountRemovalConfirmationDialog dialog = new
+                    UserInfoActivity.AccountRemovalConfirmationDialog();
+            dialog.setArguments(bundle);
+
+            return dialog;
+        }
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            account = getArguments().getParcelable(KEY_ACCOUNT);
+        }
+
+        @NonNull
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            return new AlertDialog.Builder(getActivity(), R.style.Theme_ownCloud_Dialog)
+                    .setTitle(R.string.delete_account)
+                    .setMessage(getResources().getString(R.string.delete_account_warning, account.name))
+                    .setIcon(R.drawable.ic_warning)
+                    .setPositiveButton(R.string.common_ok,
+                            new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialogInterface, int i) {
+                                    Bundle bundle = new Bundle();
+                                    bundle.putParcelable(KEY_ACCOUNT, Parcels.wrap(account));
+                                    Intent intent = new Intent();
+                                    intent.putExtras(bundle);
+                                    if (getActivity() != null) {
+                                        getActivity().setResult(KEY_DELETE_CODE, intent);
+                                        getActivity().finish();
+                                    }
+
+                                }
+                            })
+                    .setNegativeButton(R.string.common_cancel, null)
+                    .create();
+        }
+    }
+
+    private void fetchAndSetData() {
+        Thread t = new Thread(new Runnable() {
+            public void run() {
+
+                RemoteOperation getRemoteUserInfoOperation = new GetRemoteUserInfoOperation();
+                RemoteOperationResult result = getRemoteUserInfoOperation.execute(account, UserInfoActivity.this);
+
+                if (result.isSuccess() && result.getData() != null) {
+                    userInfo = (UserInfo) result.getData().get(0);
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            populateUserInfoUi(userInfo);
+
+                            emptyContentContainer.setVisibility(View.GONE);
+                            userInfoView.setVisibility(View.VISIBLE);
+                        }
+                    });
+                } else {
+                    // show error
+                    setMessageForMultiList(result.getLogMessage(), sorryMessage);
+                    Log_OC.d(TAG, result.getLogMessage());
+                }
+            }
+        });
+
+        t.start();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        if (userInfo != null) {
+            outState.putParcelable(KEY_USER_DATA, Parcels.wrap(userInfo));
+        }
+    }
+}

+ 0 - 34
src/main/java/com/owncloud/android/ui/adapter/AccountListAdapter.java

@@ -74,13 +74,6 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
             viewHolder.checkViewItem.setImageDrawable(mTintedCheck);
             viewHolder.usernameViewItem = (TextView) convertView.findViewById(R.id.user_name);
             viewHolder.accountViewItem = (TextView) convertView.findViewById(R.id.account);
-            viewHolder.passwordButtonItem = (ImageView) convertView.findViewById(R.id.passwordButton);
-            viewHolder.removeButtonItem = (ImageView) convertView.findViewById(R.id.removeButton);
-
-            if(mListener == null) {
-                viewHolder.passwordButtonItem.setVisibility(View.GONE);
-                viewHolder.removeButtonItem.setVisibility(View.GONE);
-            }
 
             convertView.setTag(viewHolder);
         } else {
@@ -98,7 +91,6 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
                 setUsername(viewHolder, account);
                 setAvatar(viewHolder, account);
                 setCurrentlyActiveState(viewHolder, account);
-                setupListeners(position, viewHolder);
 
             } // create add account action item
             else if (AccountListItem.TYPE_ACTION_ADD == accountListItem.getType() && mListener != null) {
@@ -131,26 +123,6 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
         viewHolder.accountViewItem.setTag(account.name);
     }
 
-    private void setupListeners(final int position, AccountViewHolderItem viewHolder) {
-        if (mListener != null) {
-            /// bind listener to change password
-            viewHolder.passwordButtonItem.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mListener.changePasswordOfAccount(mValues.get(position).getAccount());
-                }
-            });
-
-            /// bind listener to remove account
-            viewHolder.removeButtonItem.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mListener.performAccountRemoval(mValues.get(position).getAccount());
-                }
-            });
-        }
-    }
-
     private void setCurrentlyActiveState(AccountViewHolderItem viewHolder, Account account) {
         if (AccountUtils.getCurrentOwnCloudAccount(getContext()).name.equals(account.name)) {
             viewHolder.checkViewItem.setVisibility(View.VISIBLE);
@@ -195,9 +167,6 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
      * Listener interface for Activities using the {@link AccountListAdapter}
      */
     public interface AccountListAdapterListener {
-        void performAccountRemoval(Account account);
-
-        void changePasswordOfAccount(Account account);
 
         void createAccount();
     }
@@ -211,8 +180,5 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
 
         TextView usernameViewItem;
         TextView accountViewItem;
-
-        ImageView passwordButtonItem;
-        ImageView removeButtonItem;
     }
 }

BIN
src/main/res/drawable-hdpi/ic_map_marker.png


BIN
src/main/res/drawable-hdpi/ic_phone.png


BIN
src/main/res/drawable-mdpi/ic_map_marker.png


BIN
src/main/res/drawable-mdpi/ic_phone.png


BIN
src/main/res/drawable-xhdpi/ic_map_marker.png


BIN
src/main/res/drawable-xhdpi/ic_phone.png


BIN
src/main/res/drawable-xxhdpi/ic_map_marker.png


BIN
src/main/res/drawable-xxhdpi/ic_phone.png


BIN
src/main/res/drawable-xxxhdpi/ic_map_marker.png


BIN
src/main/res/drawable-xxxhdpi/ic_phone.png


+ 1 - 31
src/main/res/layout/account_item.xml

@@ -21,7 +21,7 @@
 -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
+    android:layout_width="match_parent"
     android:layout_height="@dimen/account_item_layout_height"
     android:orientation="horizontal"
     android:weightSum="1">
@@ -60,9 +60,7 @@
         android:layout_height="wrap_content"
         android:layout_centerInParent="true"
         android:layout_toEndOf="@id/avatar_container"
-        android:layout_toLeftOf="@+id/passwordButton"
         android:layout_toRightOf="@id/avatar_container"
-        android:layout_toStartOf="@id/passwordButton"
         android:orientation="vertical">
 
         <TextView
@@ -96,32 +94,4 @@
             android:textColor="?android:attr/textColorSecondary"/>
     </LinearLayout>
 
-    <ImageView
-        android:id="@+id/passwordButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true"
-        android:layout_gravity="center_vertical"
-        android:layout_toLeftOf="@+id/removeButton"
-        android:layout_toStartOf="@id/removeButton"
-        android:paddingBottom="@dimen/standard_padding"
-        android:paddingLeft="@dimen/standard_half_padding"
-        android:paddingRight="@dimen/standard_half_padding"
-        android:paddingTop="@dimen/standard_padding"
-        android:src="@drawable/ic_key"/>
-
-    <ImageView
-        android:id="@+id/removeButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentRight="true"
-        android:layout_centerInParent="true"
-        android:layout_gravity="center_vertical"
-        android:paddingBottom="@dimen/standard_padding"
-        android:paddingLeft="@dimen/standard_half_padding"
-        android:paddingRight="@dimen/standard_padding"
-        android:paddingTop="@dimen/standard_padding"
-        android:src="@drawable/ic_action_delete_grey"/>
-
 </RelativeLayout>

+ 109 - 0
src/main/res/layout/toolbar_user_information.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Nextcloud Android client application
+
+  Copyright (C) 2017 Andy Scherzinger
+  Copyright (C) 2017 Nextcloud
+
+  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/>.
+-->
+<android.support.design.widget.AppBarLayout
+    android:id="@+id/appbar"
+    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="@dimen/nav_drawer_header_height"
+    android:background="@drawable/background"
+    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
+
+    <android.support.v7.widget.Toolbar
+        android:id="@id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="?attr/actionBarSize"
+        app:layout_scrollFlags="scroll|enterAlways|snap"
+        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:gravity="bottom">
+
+        <RelativeLayout
+            xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="12dp"
+            android:layout_marginLeft="12dp"
+            android:layout_marginRight="@dimen/standard_half_margin"
+            android:gravity="bottom"
+            android:orientation="horizontal"
+            android:weightSum="1">
+
+            <FrameLayout
+                android:id="@+id/avatar_container"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+
+                <ImageView
+                    android:id="@+id/user_icon"
+                    android:layout_width="@dimen/nav_drawer_header_avatar"
+                    android:layout_height="@dimen/nav_drawer_header_avatar"
+                    android:src="@drawable/ic_account_circle"/>
+            </FrameLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerInParent="true"
+                android:layout_marginLeft="@dimen/standard_half_margin"
+                android:layout_marginRight="@dimen/standard_half_margin"
+                android:layout_toEndOf="@id/avatar_container"
+                android:layout_toRightOf="@id/avatar_container"
+                android:orientation="vertical">
+
+                <TextView
+                    android:id="@+id/drawer_username_full"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:ellipsize="end"
+                    android:maxLines="1"
+                    android:shadowColor="@color/black"
+                    android:shadowDx="0.5"
+                    android:shadowDy="0"
+                    android:shadowRadius="2"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/drawer_header_text"
+                    android:textStyle="bold"/>
+
+                <TextView
+                    android:id="@+id/drawer_username"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:ellipsize="end"
+                    android:lines="1"
+                    android:maxLines="1"
+                    android:shadowColor="@color/black"
+                    android:shadowDx="0.5"
+                    android:shadowDy="0"
+                    android:shadowRadius="2"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/drawer_header_subtext"/>
+            </LinearLayout>
+
+        </RelativeLayout>
+
+    </LinearLayout>
+
+</android.support.design.widget.AppBarLayout>

+ 246 - 0
src/main/res/layout/user_info_layout.xml

@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Nextcloud Android client application
+
+  Copyright (C) 2017 Andy Scherzinger
+  Copyright (C) 2017 Nextcloud
+
+  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/>.
+-->
+<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                                                 xmlns:card_view="http://schemas.android.com/apk/res-auto"
+                                                 android:layout_width="match_parent"
+                                                 android:layout_height="match_parent">
+
+    <include
+        layout="@layout/toolbar_user_information"/>
+
+    <include layout="@layout/empty_list"/>
+
+    <RelativeLayout
+        android:id="@+id/multi_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingTop="@dimen/nav_drawer_header_height">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true">
+
+            <LinearLayout
+                android:id="@+id/user_info_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone">
+
+                <android.support.v7.widget.CardView
+                    android:id="@+id/primary_user_info_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_margin="@dimen/standard_half_margin"
+                    card_view:cardCornerRadius="3dp"
+                    card_view:cardUseCompatPadding="true">
+
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical">
+
+                        <RelativeLayout
+                            android:id="@+id/phone_container"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+
+                            <ImageView
+                                android:id="@+id/phone_icon"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:layout_margin="@dimen/standard_margin"
+                                android:src="@drawable/ic_phone"/>
+
+                            <TextView
+                                android:id="@+id/phone_number"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_centerInParent="true"
+                                android:layout_marginRight="@dimen/standard_padding"
+                                android:layout_marginBottom="@dimen/standard_margin"
+                                android:layout_marginTop="@dimen/standard_margin"
+                                android:layout_toEndOf="@id/phone_icon"
+                                android:layout_toRightOf="@id/phone_icon"
+                                android:maxLines="3"
+                                android:text="@string/placeholder_filename"
+                                android:textAppearance="?android:attr/textAppearanceListItem"/>
+
+                        </RelativeLayout>
+
+                        <RelativeLayout
+                            android:id="@+id/email_container"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+
+                            <View
+                                android:layout_width="match_parent"
+                                android:layout_height="1dp"
+                                android:background="@color/list_divider_background"/>
+
+                            <ImageView
+                                android:id="@+id/email_icon"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:layout_margin="@dimen/standard_margin"
+                                android:src="@drawable/ic_email"/>
+
+                            <TextView
+                                android:id="@+id/email_address"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_centerInParent="true"
+                                android:layout_marginRight="@dimen/standard_padding"
+                                android:layout_marginBottom="@dimen/standard_margin"
+                                android:layout_marginTop="@dimen/standard_margin"
+                                android:layout_toEndOf="@id/email_icon"
+                                android:layout_toRightOf="@id/email_icon"
+                                android:maxLines="3"
+                                android:text="@string/placeholder_filename"
+                                android:textAppearance="?android:attr/textAppearanceListItem"/>
+
+                        </RelativeLayout>
+
+                        <RelativeLayout
+                            android:id="@+id/address_container"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+
+                            <View
+                                android:layout_width="match_parent"
+                                android:layout_height="1dp"
+                                android:background="@color/list_divider_background"/>
+
+                            <ImageView
+                                android:id="@+id/address_icon"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:layout_margin="@dimen/standard_margin"
+                                android:src="@drawable/ic_map_marker"/>
+
+                            <TextView
+                                android:id="@+id/address"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_centerInParent="true"
+                                android:layout_marginRight="@dimen/standard_padding"
+                                android:layout_marginBottom="@dimen/standard_margin"
+                                android:layout_marginTop="@dimen/standard_margin"
+                                android:layout_toEndOf="@id/address_icon"
+                                android:layout_toRightOf="@id/address_icon"
+                                android:maxLines="3"
+                                android:text="@string/placeholder_filename"
+                                android:textAppearance="?android:attr/textAppearanceListItem"/>
+
+                        </RelativeLayout>
+
+                    </LinearLayout>
+
+                </android.support.v7.widget.CardView>
+
+                <android.support.v7.widget.CardView
+                    android:id="@+id/secondary_user_info_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_margin="@dimen/standard_half_margin"
+                    card_view:cardCornerRadius="3dp"
+                    card_view:cardUseCompatPadding="true">
+
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical">
+
+                        <LinearLayout
+                            android:id="@+id/website_container"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_margin="@dimen/standard_margin"
+                            android:orientation="vertical">
+
+                            <TextView
+                                android:id="@+id/website_headline"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:text="@string/user_info_website"
+                                android:textAppearance="?android:attr/textAppearanceListItem"/>
+
+                            <TextView
+                                android:id="@+id/website_address"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:maxLines="3"
+                                android:text="@string/user_info_twitter"
+                                android:textColor="?android:attr/textColorSecondary"/>
+
+                        </LinearLayout>
+
+                        <LinearLayout
+                            android:id="@+id/twitter_container"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginBottom="@dimen/standard_margin"
+                            android:orientation="vertical">
+
+                            <View
+                                android:layout_width="match_parent"
+                                android:layout_height="1dp"
+                                android:layout_marginBottom="@dimen/standard_margin"
+                                android:background="@color/list_divider_background"/>
+
+                            <TextView
+                                android:id="@+id/twitter_headline"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_marginRight="@dimen/standard_margin"
+                                android:layout_marginLeft="@dimen/standard_margin"
+                                android:text="Twitter"
+                                android:textAppearance="?android:attr/textAppearanceListItem"/>
+
+                            <TextView
+                                android:id="@+id/twitter_handle"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_marginRight="@dimen/standard_margin"
+                                android:layout_marginLeft="@dimen/standard_margin"
+                                android:maxLines="1"
+                                android:text="@string/placeholder_filename"
+                                android:textColor="?android:attr/textColorSecondary"/>
+
+                        </LinearLayout>
+
+                    </LinearLayout>
+
+                </android.support.v7.widget.CardView>
+
+            </LinearLayout>
+
+        </ScrollView>
+
+    </RelativeLayout>
+
+
+</android.support.design.widget.CoordinatorLayout>

+ 31 - 0
src/main/res/layout/user_info_list_item.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/user_info_item_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/attribute_headline_tv"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginBottom="4dp"
+        android:textSize="20sp"
+        android:textStyle="bold"
+        android:text="@string/placeholder_filename"/>
+
+    <TextView
+        android:id="@+id/attribute_value_tv"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/attribute_headline_tv"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_marginBottom="8dp"
+        android:textSize="16sp"
+        android:text="@string/placeholder_filename"/>
+
+</RelativeLayout>

+ 14 - 0
src/main/res/menu/user_info_menu.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/change_password"
+        android:title="@string/change_password">
+    </item>
+
+    <item
+        android:id="@+id/delete_account"
+        android:title="@string/delete_account">
+    </item>
+
+</menu>

+ 1 - 0
src/main/res/values/colors.xml

@@ -26,6 +26,7 @@
     <color name="list_item_lastmod_and_filesize_text">@color/secondaryTextColor</color>
     <color name="black">#000000</color>
     <color name="white">#FFFFFF</color>
+    <color name="white2">#F7F7F7</color>
     <color name="fab_white">#fafafa</color>
     <color name="white_pressed">#f1f1f1</color>
     <color name="half_black">#808080</color>

+ 13 - 1
src/main/res/values/strings.xml

@@ -314,7 +314,8 @@
     <string name="conflict_keep_both">Keep both</string>
     <string name="conflict_use_local_version">local version</string>
     <string name="conflict_use_server_version">server version</string>
-    
+
+    <string name="preview_sorry">Sorry about that!</string>
     <string name="preview_image_description">Image preview</string>
     <string name="preview_image_error_unknown_format">This image cannot be shown</string>
 
@@ -565,4 +566,15 @@
     <string name="welcome_feature_3_text">Keep your photos safe</string>
 
     <string name="whats_new_skip">Skip</string>
+
+    <!-- User information -->
+    <string name="user_info_full_name">Full name</string>
+    <string name="user_info_email">Email</string>
+    <string name="user_info_phone">Phone number</string>
+    <string name="user_info_address">Address</string>
+    <string name="user_info_website">Website</string>
+    <string name="user_info_twitter">Twitter</string>
+
+    <string name="user_information_description">User information</string>
+
 </resources>