Prechádzať zdrojové kódy

Redesigned user profile screen

Vadik Sirekanyan 7 rokov pred
rodič
commit
1baa4980eb

+ 6 - 0
app/src/main/AndroidManifest.xml

@@ -42,8 +42,14 @@
             android:name=".user.UserActivity"
             android:parentActivityName=".MainActivity"/>
 
+        <activity
+            android:name=".profile.ProfileActivity"
+            android:theme="@style/ProfileTheme" />
+
         <activity
             android:name="ru.ulogin.sdk.UloginAuthActivity"
             android:configChanges="orientation|screenSize"/>
+
     </application>
+
 </manifest>

+ 2 - 35
app/src/main/java/me/vadik/knigopis/MainActivity.kt

@@ -11,7 +11,6 @@ import android.support.v7.app.AppCompatActivity
 import android.support.v7.widget.LinearLayoutManager
 import android.support.v7.widget.RecyclerView
 import android.support.v7.widget.Toolbar
-import android.text.format.DateUtils
 import android.view.MenuItem
 import android.view.View
 import android.widget.TextView
@@ -38,6 +37,7 @@ import me.vadik.knigopis.model.PlannedBook
 import me.vadik.knigopis.model.note.Identity
 import me.vadik.knigopis.model.note.Note
 import me.vadik.knigopis.model.subscription.Subscription
+import me.vadik.knigopis.profile.createProfileIntent
 import me.vadik.knigopis.user.createUserIntent
 import org.koin.android.ext.android.inject
 import retrofit2.HttpException
@@ -170,18 +170,6 @@ class MainActivity : AppCompatActivity(), Router {
         }
     }
 
-    override fun shareProfile(url: String) {
-        val sharingIntent = Intent(Intent.ACTION_SEND)
-            .setType("text/plain")
-            .putExtra(Intent.EXTRA_TEXT, url)
-        startActivity(
-            Intent.createChooser(
-                sharingIntent,
-                getString(R.string.option_share_title)
-            )
-        )
-    }
-
     private fun initNavigationView() {
         if (auth.isAuthorized()) {
             bottomNavigation.show()
@@ -209,28 +197,7 @@ class MainActivity : AppCompatActivity(), Router {
                     true
                 }
                 R.id.option_profile -> {
-                    api.getProfile(auth.getAccessToken())
-                        .io2main()
-                        .subscribe({ user ->
-                            AlertDialog.Builder(this)
-                                .setTitle("Мой профиль")
-                                .setMessage(
-                                    """
-                                        Имя: ${user.nickname ?: "(не задано)"}
-                                        Книг: ${user.booksCount}
-                                        Подписок: ${user.subscriptions?.size ?: 0}
-                                        Создан: ${DateUtils.getRelativeTimeSpanString(user.fixedCreatedAt.time)}
-                                        Обновлен: ${DateUtils.getRelativeTimeSpanString(user.fixedUpdatedAt.time)}
-                                    """.trimIndent()
-                                )
-                                .setPositiveButton("Поделиться") { _, _ ->
-                                    shareProfile(user.fixedProfile)
-                                }
-                                .setNegativeButton("Закрыть", null)
-                                .show()
-                        }, {
-                            logError("Cannot get profile", it)
-                        })
+                    startActivity(createProfileIntent())
                     true
                 }
                 R.id.option_about -> {

+ 0 - 1
app/src/main/java/me/vadik/knigopis/Router.kt

@@ -10,5 +10,4 @@ interface Router {
     fun openUserScreen(user: Subscription)
     fun openUserScreen(user: Identity)
     fun openBrowser(uri: Uri)
-    fun shareProfile(url: String)
 }

+ 12 - 0
app/src/main/java/me/vadik/knigopis/common/Context.kt

@@ -0,0 +1,12 @@
+package me.vadik.knigopis.common
+
+import android.content.Intent
+
+private const val TEXT_MIME_TYPE = "text/plain"
+
+fun createTextShareIntent(text: String, title: String): Intent {
+    val sharingIntent = Intent(Intent.ACTION_SEND)
+        .setType(TEXT_MIME_TYPE)
+        .putExtra(Intent.EXTRA_TEXT, text)
+    return Intent.createChooser(sharingIntent, title)
+}

+ 100 - 0
app/src/main/java/me/vadik/knigopis/profile/ProfileActivity.kt

@@ -0,0 +1,100 @@
+package me.vadik.knigopis.profile
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.Toolbar
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
+import com.bumptech.glide.request.RequestOptions
+import kotlinx.android.synthetic.main.profile_activity.*
+import kotlinx.android.synthetic.main.profile_contact_item.*
+import me.vadik.knigopis.R
+import me.vadik.knigopis.api.Endpoint
+import me.vadik.knigopis.auth.KAuth
+import me.vadik.knigopis.common.createTextShareIntent
+import me.vadik.knigopis.io2main
+import me.vadik.knigopis.logError
+import org.koin.android.ext.android.inject
+
+fun Context.createProfileIntent() = Intent(this, ProfileActivity::class.java)
+
+class ProfileActivity : AppCompatActivity() {
+
+    private val api by inject<Endpoint>()
+    private val auth by inject<KAuth>()
+    private var profileUrl: String? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.profile_activity)
+        initToolbar(profileToolbar)
+        profileBooksCount.text = getString(R.string.profile_caption_books, 0)
+        profileWishesCount.text = getString(R.string.profile_caption_wishes, 0)
+        profileReviewsCount.text = getString(R.string.profile_caption_reviews, 0)
+    }
+
+    override fun onStart() {
+        super.onStart()
+        api.getProfile(auth.getAccessToken())
+            .io2main()
+            .subscribe({ user ->
+                profileUrl = user.fixedProfile
+                profileNickname.text = user.nickname ?: "(не указано имя)"
+                profileContactTitle.text = user.identity
+                Glide.with(this)
+                    .load(user.photo)
+                    .apply(
+                        RequestOptions.circleCropTransform()
+                            .placeholder(R.drawable.oval_placeholder_background)
+                    )
+                    .transition(DrawableTransitionOptions.withCrossFade())
+                    .into(profileAvatar)
+                updateCounters(user.booksCount)
+            }, {
+                logError("cannot get profile", it)
+            })
+    }
+
+    private fun updateCounters(totalBooksCount: Int) {
+        api.getFinishedBooks(auth.getAccessToken())
+            .io2main()
+            .subscribe({ finishedBooks ->
+                profileBooksCount.text = getString(
+                    R.string.profile_caption_books,
+                    finishedBooks.size
+                )
+                profileWishesCount.text = getString(
+                    R.string.profile_caption_wishes,
+                    totalBooksCount - finishedBooks.size
+                )
+                profileReviewsCount.text = getString(
+                    R.string.profile_caption_reviews,
+                    finishedBooks.count { it.notes.isNotEmpty() }
+                )
+            }, {
+                logError("cannot check books count", it)
+            })
+    }
+
+    private fun initToolbar(toolbar: Toolbar) {
+        toolbar.setNavigationIcon(R.drawable.ic_close)
+        toolbar.setNavigationOnClickListener { finish() }
+        toolbar.inflateMenu(R.menu.profile_menu)
+        toolbar.setOnMenuItemClickListener {
+            when (it.itemId) {
+                R.id.option_share_profile -> {
+                    profileUrl?.let {
+                        startActivity(
+                            createTextShareIntent(it, getString(R.string.option_share_title))
+                        )
+                    }
+                    true
+                }
+                else -> false
+            }
+        }
+    }
+
+}

+ 9 - 0
app/src/main/res/drawable/ic_close.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>

+ 88 - 0
app/src/main/res/layout/profile_activity.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout 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:background="@color/colorPrimaryDark"
+    tools:ignore="ContentDescription">
+
+    <android.support.v7.widget.Toolbar
+        android:id="@+id/profileToolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="5" />
+
+    <ImageView
+        android:id="@+id/profileAvatar"
+        android:layout_width="128dp"
+        android:layout_height="128dp"
+        android:layout_gravity="center_horizontal"
+        tools:src="@drawable/oval_placeholder_background" />
+
+    <TextView
+        android:id="@+id/profileNickname"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:gravity="center"
+        android:padding="16dp"
+        android:textColor="@color/white"
+        android:textSize="28sp"
+        tools:text="Павел Дуров" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+
+    <!-- TODO: visible -->
+    <include
+        layout="@layout/profile_contact_item"
+        android:visibility="invisible" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="5" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#BBFFFFFF" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:id="@+id/profileBooksCount"
+            style="@style/ProfileCaptionItem" />
+
+        <TextView
+            android:id="@+id/profileWishesCount"
+            style="@style/ProfileCaptionItem" />
+
+        <TextView
+            android:id="@+id/profileReviewsCount"
+            style="@style/ProfileCaptionItem" />
+
+    </LinearLayout>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#BBFFFFFF" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="56dp" />
+
+</LinearLayout>

+ 32 - 0
app/src/main/res/layout/profile_contact_item.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout 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="wrap_content"
+    android:layout_height="48dp"
+    android:layout_gravity="center_horizontal"
+    android:paddingEnd="16dp"
+    android:paddingStart="16dp">
+
+    <ImageView
+        android:id="@+id/profileContactIcon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_gravity="center_vertical"
+        android:tint="@color/white"
+        app:srcCompat="@drawable/ic_public"
+        tools:ignore="ContentDescription" />
+
+    <TextView
+        android:id="@+id/profileContactTitle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_marginStart="40dp"
+        android:ellipsize="end"
+        android:maxLines="1"
+        android:textColor="@color/white"
+        android:textSize="16sp"
+        tools:text="Вконтакте" />
+
+</FrameLayout>

+ 18 - 0
app/src/main/res/menu/profile_menu.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <!-- TODO -->
+    <!--<item-->
+    <!--android:id="@+id/option_edit_profile"-->
+    <!--android:icon="@drawable/ic_edit"-->
+    <!--android:title="@string/profile_option_edit"-->
+    <!--app:iconTint="@color/white"-->
+    <!--app:showAsAction="ifRoom" />-->
+
+    <item
+        android:id="@+id/option_share_profile"
+        android:title="@string/profile_option_share"
+        app:showAsAction="never" />
+
+</menu>

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

@@ -2,6 +2,7 @@
 <resources>
     <color name="colorPrimary">#673AB7</color>
     <color name="colorPrimaryDark">#512DA8</color>
+    <color name="colorPrimaryDark_97">#F7512DA8</color>
     <color name="colorPrimaryLight">#9575CD</color>
     <color name="colorPrimaryLightest">#B39DDB</color>
     <color name="colorPrimary100">#D1C4E9</color>

+ 9 - 0
app/src/main/res/values/strings.xml

@@ -16,6 +16,15 @@
     <string name="option_share_title">Share your profile</string>
     <string name="option_about">About</string>
 
+    <!-- profile -->
+    <string name="profile_caption_books">%d\nbooks</string>
+    <string name="profile_caption_wishes">%d\nwishes</string>
+    <string name="profile_caption_reviews">%d\nreviews</string>
+
+    <!-- profile menu -->
+    <string name="profile_option_edit">Edit</string>
+    <string name="profile_option_share">Share</string>
+
     <!-- books -->
     <string name="book_header_todo">Todo</string>
     <string name="book_header_done_first">Done in %s</string>

+ 21 - 0
app/src/main/res/values/styles.xml

@@ -8,6 +8,11 @@
         <item name="android:listDivider">@drawable/recycler_view_divider</item>
     </style>
 
+    <style name="ProfileTheme" parent="AppTheme">
+        <item name="android:windowBackground">@color/colorPrimaryDark_97</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+
     <style name="DevTheme" parent="AppTheme">
         <!--<item name="colorPrimary">#9C27B0</item>-->
         <!--<item name="colorPrimaryDark">#7B1FA2</item>-->
@@ -30,6 +35,22 @@
         <item name="android:drawablePadding">8dp</item>
     </style>
 
+    <style name="ProfileCaptionItem">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:background">?android:attr/selectableItemBackground</item>
+        <item name="android:clickable">true</item>
+        <item name="android:ellipsize">end</item>
+        <item name="android:focusable">true</item>
+        <item name="android:gravity">center</item>
+        <item name="android:lineSpacingExtra">8sp</item>
+        <item name="android:maxLines">2</item>
+        <item name="android:padding">16dp</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textColor">@color/white</item>
+    </style>
+
     <style name="TextInputLayoutStyle">
         <item name="android:layout_marginLeft">16dp</item>
         <item name="android:layout_marginRight">16dp</item>