Browse Source

First bits of user info code

Mario Danic 8 years ago
parent
commit
38f1cc0e28

+ 3 - 1
build.gradle

@@ -28,7 +28,7 @@ configurations.all {
 }
 
 ext {
-    supportLibraryVersion = '25.0.0'
+    supportLibraryVersion = '25.1.0'
 
     travisBuild = System.getenv("TRAVIS") == "true"
 
@@ -45,6 +45,8 @@ repositories {
     }
 }
 
+}
+
 android {
     lintOptions {
         abortOnError true

+ 35 - 0
res/layout/user_info_layout.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout 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="match_parent">
+
+
+    <include
+        layout="@layout/toolbar_standard"></include>
+
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/generic_rv"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+    </android.support.v7.widget.RecyclerView>
+
+    <RelativeLayout
+        android:id="@+id/multi_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <include layout="@layout/empty_list"/>
+
+        </ScrollView>
+    </RelativeLayout>
+
+
+</android.support.design.widget.CoordinatorLayout>

+ 29 - 0
res/layout/user_info_list_item.xml

@@ -0,0 +1,29 @@
+<?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"/>
+
+    <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"/>
+
+</RelativeLayout>

+ 14 - 0
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>

+ 38 - 0
src/com/owncloud/android/datamodel/StringPair.java

@@ -0,0 +1,38 @@
+/**
+ * Nextcloud Android client application
+ *
+ * @author Mario Danic
+ * 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.datamodel;
+
+/**
+ * Created by mdjanic on 25/01/2017.
+ */
+
+public class StringPair {
+    public String first;
+    public String second;
+
+    public StringPair() {
+    }
+
+    public StringPair(String first, String second) {
+        this.first = first;
+        this.second = second;
+    }
+}

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

@@ -0,0 +1,192 @@
+package com.owncloud.android.ui.activity;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.support.v7.widget.DividerItemDecoration;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+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.RelativeLayout;
+import android.widget.TextView;
+
+import com.owncloud.android.R;
+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.ui.adapter.UserInfoAdapter;
+
+import org.parceler.Parcels;
+
+import butterknife.BindString;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
+/**
+ * Created by mdjanic on 25/01/2017.
+ */
+
+public class UserInfoActivity extends FileActivity {
+    private static final String TAG = UserInfoActivity.class.getSimpleName();
+
+    protected static final String KEY_USER_DATA = "USER_DATA";
+    protected static final String KEY_NEXTCLOUD_ACCOUNT = "NEXTCLOUD_ACCOUNT";
+
+
+    @BindView(R.id.generic_rv)
+    RecyclerView genericRecyclerView;
+
+    @BindView(R.id.multi_view)
+    RelativeLayout multiView;
+    @BindView(R.id.empty_list_view)
+    LinearLayout multiListContainer;
+    @BindView(R.id.empty_list_view_text)
+    TextView multiListMessage;
+    @BindView(R.id.empty_list_view_headline)
+    TextView multiListHeadline;
+    @BindView(R.id.empty_list_icon)
+    ImageView multiListIcon;
+    @BindView(R.id.empty_list_progress)
+    ProgressBar multiListProgressBar;
+
+    @BindString(R.string.preview_sorry)
+    String sorryMessage;
+
+    RecyclerView.LayoutManager layoutManager;
+
+    RecyclerView.Adapter adapter;
+
+    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();
+
+        if (bundle.containsKey(KEY_NEXTCLOUD_ACCOUNT)) {
+            account = Parcels.unwrap(bundle.getParcelable(KEY_NEXTCLOUD_ACCOUNT));
+        }
+
+        setContentView(R.layout.user_info_layout);
+        unbinder = ButterKnife.bind(this);
+
+        setupToolbar();
+        updateActionBarTitleAndHomeButtonByString(getResources().getString(R.string.user_information_description));
+
+        layoutManager = new LinearLayoutManager(this);
+        genericRecyclerView.setLayoutManager(layoutManager);
+
+        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(genericRecyclerView.getContext(),
+                ((LinearLayoutManager)layoutManager).getOrientation());
+        genericRecyclerView.addItemDecoration(dividerItemDecoration);
+
+        if (savedInstanceState != null && savedInstanceState.containsKey(KEY_USER_DATA)) {
+            userInfo = Parcels.unwrap(savedInstanceState.getParcelable(KEY_USER_DATA));
+            adapter = new UserInfoAdapter(userInfo, UserInfoActivity.this);
+            multiView.setVisibility(View.VISIBLE);
+            genericRecyclerView.setVisibility(View.GONE);
+        } 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;
+            default:
+                retval = super.onOptionsItemSelected(item);
+        }
+        return retval;
+    }
+
+    public void onDestroy() {
+        super.onDestroy();
+        unbinder.unbind();
+    }
+
+
+    private void setMultiListLoadingMessage() {
+        if (multiView != null) {
+            multiListHeadline.setText(R.string.file_list_loading);
+            multiListMessage.setText("");
+
+            multiListIcon.setVisibility(View.GONE);
+            multiListProgressBar.setVisibility(View.VISIBLE);
+        }
+    }
+
+    public void setMessageForMultiList(String headline, String message) {
+        if (multiView != null && multiListMessage != null) {
+            multiListHeadline.setText(headline);
+            multiListMessage.setText(message);
+
+            multiListProgressBar.setVisibility(View.GONE);
+        }
+    }
+
+
+    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);
+                    adapter = new UserInfoAdapter(userInfo, UserInfoActivity.this);
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            genericRecyclerView.setAdapter(adapter);
+                            multiView.setVisibility(View.GONE);
+                            genericRecyclerView.setVisibility(View.VISIBLE);
+                        }
+                    });
+                } else {
+                    // show error
+                    RemoteOperationResult remoteOperationResult = (RemoteOperationResult) result.getData().get(0);
+                    setMessageForMultiList(remoteOperationResult.getLogMessage(), sorryMessage);
+                }
+            }
+        });
+
+        t.start();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        if (userInfo != null) {
+            outState.putParcelable(KEY_USER_DATA, Parcels.wrap(userInfo));
+        }
+    }
+
+}

+ 156 - 0
src/com/owncloud/android/ui/adapter/UserInfoAdapter.java

@@ -0,0 +1,156 @@
+/**
+ * Nextcloud Android client application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017 Nextcloud GmbH.
+ * <p>
+ * 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.
+ * <p>
+ * 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.
+ * <p>
+ * 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.adapter;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.StringPair;
+import com.owncloud.android.lib.common.UserInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+/**
+ * Created by mdjanic on 24/01/2017.
+ */
+
+
+public class UserInfoAdapter extends RecyclerView.Adapter<UserInfoAdapter.ViewHolder> {
+
+    private UserInfo userInfo;
+    private Context context;
+
+    private List<StringPair> stringPairs;
+
+    public UserInfoAdapter(UserInfo userInfo, Context context) {
+        this.userInfo = userInfo;
+        this.context = context;
+
+        stringPairs = new ArrayList<>();
+        getRelevantInformation();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        // Just as an example, return 0 or 2 depending on position
+        // Note that unlike in ListView adapters, types don't have to be contiguous
+        if (position % 2 == 0) {
+            return 0;
+        } else {
+            return 1;
+        }
+
+    }
+
+    @Override
+    public UserInfoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+        View itemView = inflater.inflate(R.layout.user_info_list_item, parent, false);
+
+        if (context != null) {
+            if (viewType == 0) {
+                itemView.setBackgroundColor(context.getResources().getColor(R.color.white));
+            } else {
+                itemView.setBackgroundColor(context.getResources().getColor(R.color.white2));
+            }
+        }
+        return new ViewHolder(itemView);
+    }
+
+    @Override
+    public void onBindViewHolder(UserInfoAdapter.ViewHolder holder, int position) {
+        StringPair currentPair = stringPairs.get(position);
+        holder.attributeHeadlineTextView.setText(currentPair.first);
+        holder.attributeValueTextView.setText(currentPair.second);
+    }
+
+    @Override
+    public int getItemCount() {
+        return stringPairs.size();
+    }
+
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+        @BindView(R.id.attribute_headline_tv)
+        TextView attributeHeadlineTextView;
+        @BindView(R.id.attribute_value_tv)
+        TextView attributeValueTextView;
+
+        public ViewHolder(View itemView) {
+            super(itemView);
+            ButterKnife.bind(this, itemView);
+        }
+    }
+
+    private void getRelevantInformation() {
+        if (!TextUtils.isEmpty(userInfo.getDisplayName())) {
+            if (context != null) {
+                stringPairs.add(new StringPair(context.getResources().getString(R.string.user_info_full_name),
+                        userInfo.getDisplayName()));
+            }
+        }
+
+        if (!TextUtils.isEmpty((userInfo.getEmail()))) {
+            if (context != null) {
+                stringPairs.add(new StringPair(context.getResources().getString(R.string.user_info_email),
+                        userInfo.getEmail()));
+            }
+        }
+
+        if (!TextUtils.isEmpty(userInfo.getPhone())) {
+            if (context != null) {
+                stringPairs.add(new StringPair(context.getResources().getString(R.string.user_info_phone),
+                        userInfo.getPhone()));
+            }
+        }
+
+        if (!TextUtils.isEmpty(userInfo.getAddress())) {
+            if (context != null) {
+                stringPairs.add(new StringPair(context.getResources().getString(R.string.user_info_address),
+                        userInfo.getAddress()));
+            }
+        }
+
+        if (!TextUtils.isEmpty(userInfo.getWebpage())) {
+            if (context != null) {
+                stringPairs.add(new StringPair(context.getResources().getString(R.string.user_info_website),
+                        userInfo.getWebpage()));
+            }
+        }
+
+        if (!TextUtils.isEmpty(userInfo.getTwitter())) {
+            if (context != null) {
+                stringPairs.add(new StringPair(context.getResources().getString(R.string.user_info_twitter),
+                        userInfo.getTwitter()));
+            }
+        }
+    }
+
+}

+ 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" />

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

@@ -59,9 +59,13 @@ 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;
 
+import butterknife.OnItemClick;
+
 /**
  * An Activity that allows the user to manage accounts.
  */
@@ -108,10 +112,14 @@ 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("NEXTCLOUD_ACCOUNT", Parcels.wrap(account));
+                startActivity(intent);
             }
         });
 

+ 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));
+        }
     }
 
     /**

+ 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>