1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-11-23 12:06:13 -06:00

Add account headers in student picker (#871)

This commit is contained in:
Dominik Korsa 2020-06-12 21:35:51 +02:00 committed by GitHub
parent 30af77614e
commit a05da2656a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 185 additions and 59 deletions

View File

@ -14,7 +14,7 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
private fun mapStudents(students: List<SdkStudent>, email: String, password: String): List<Student> { private fun mapStudents(students: List<SdkStudent>, email: String, password: String): List<Student> {
return students.map { student -> return students.map { student ->
Student( Student(
email = email, email = email.ifBlank { student.email },
password = password, password = password,
isParent = student.isParent, isParent = student.isParent,
symbol = student.symbol, symbol = student.symbol,

View File

@ -0,0 +1,3 @@
package io.github.wulkanowy.ui.modules.account
data class Account(val email: String, val isParent: Boolean)

View File

@ -3,33 +3,72 @@ package io.github.wulkanowy.ui.modules.account
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.HeaderAccountBinding
import io.github.wulkanowy.databinding.ItemAccountBinding import io.github.wulkanowy.databinding.ItemAccountBinding
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import javax.inject.Inject import javax.inject.Inject
class AccountAdapter @Inject constructor() : RecyclerView.Adapter<AccountAdapter.ItemViewHolder>() { class AccountAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var items = emptyList<Student>() var items = emptyList<AccountItem<*>>()
var onClickListener: (Student) -> Unit = {} var onClickListener: (Student) -> Unit = {}
override fun getItemCount() = items.size override fun getItemCount() = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( override fun getItemViewType(position: Int) = items[position].viewType.id
ItemAccountBinding.inflate(LayoutInflater.from(parent.context), parent, false)
) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
AccountItem.ViewType.HEADER.id -> HeaderViewHolder(HeaderAccountBinding.inflate(inflater, parent, false))
AccountItem.ViewType.ITEM.id -> ItemViewHolder(ItemAccountBinding.inflate(inflater, parent, false))
else -> throw IllegalStateException()
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is HeaderViewHolder -> bindHeaderViewHolder(holder.binding, items[position].value as Account)
is ItemViewHolder -> bindItemViewHolder(holder.binding, items[position].value as Student)
}
}
private fun bindHeaderViewHolder(binding: HeaderAccountBinding, account: Account) {
with(binding) {
accountHeaderEmail.text = account.email
accountHeaderType.setText(if (account.isParent) R.string.account_type_parent else R.string.account_type_student)
}
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { private fun bindItemViewHolder(binding: ItemAccountBinding, student: Student) {
val student = items[position] with(binding) {
with(holder.binding) {
accountItemName.text = "${student.studentName} ${student.className}" accountItemName.text = "${student.studentName} ${student.className}"
accountItemSchool.text = student.schoolName accountItemSchool.text = student.schoolName
with(accountItemLoginMode) {
visibility = when (Sdk.Mode.valueOf(student.loginMode)) {
Sdk.Mode.API -> {
setText(R.string.account_login_mobile_api)
VISIBLE
}
Sdk.Mode.HYBRID -> {
setText(R.string.account_login_hybrid)
VISIBLE
}
Sdk.Mode.SCRAPPER -> {
GONE
}
}
}
with(accountItemImage) { with(accountItemImage) {
val colorImage = if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary) val colorImage = if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
@ -42,5 +81,8 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter<AccountAdapter
} }
} }
class HeaderViewHolder(val binding: HeaderAccountBinding) :
RecyclerView.ViewHolder(binding.root)
class ItemViewHolder(val binding: ItemAccountBinding) : RecyclerView.ViewHolder(binding.root) class ItemViewHolder(val binding: ItemAccountBinding) : RecyclerView.ViewHolder(binding.root)
} }

View File

@ -9,7 +9,6 @@ import android.widget.Toast.LENGTH_LONG
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.DialogAccountBinding import io.github.wulkanowy.databinding.DialogAccountBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.login.LoginActivity
@ -54,7 +53,7 @@ class AccountDialog : BaseDialogFragment<DialogAccountBinding>(), AccountView {
} }
} }
override fun updateData(data: List<Student>) { override fun updateData(data: List<AccountItem<*>>) {
with(accountAdapter) { with(accountAdapter) {
items = data items = data
notifyDataSetChanged() notifyDataSetChanged()

View File

@ -0,0 +1,9 @@
package io.github.wulkanowy.ui.modules.account
data class AccountItem<out T>(val value: T, val viewType: ViewType) {
enum class ViewType(val id: Int) {
HEADER(1),
ITEM(2)
}
}

View File

@ -83,11 +83,20 @@ class AccountPresenter @Inject constructor(
} }
} }
private fun createAccountItems(items: List<Student>): List<AccountItem<*>> {
return items.groupBy { Account(it.email, it.isParent) }.map { (account, students) ->
listOf(AccountItem(account, AccountItem.ViewType.HEADER)) + students.map { student ->
AccountItem(student, AccountItem.ViewType.ITEM)
}
}.flatten()
}
private fun loadData() { private fun loadData() {
Timber.i("Loading account data started") Timber.i("Loading account data started")
disposable.add(studentRepository.getSavedStudents(false) disposable.add(studentRepository.getSavedStudents(false)
.subscribeOn(schedulers.backgroundThread) .subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread) .observeOn(schedulers.mainThread)
.map { createAccountItems(it) }
.subscribe({ .subscribe({
Timber.i("Loading account result: Success") Timber.i("Loading account result: Success")
view?.updateData(it) view?.updateData(it)

View File

@ -1,13 +1,12 @@
package io.github.wulkanowy.ui.modules.account package io.github.wulkanowy.ui.modules.account
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.ui.base.BaseView import io.github.wulkanowy.ui.base.BaseView
interface AccountView : BaseView { interface AccountView : BaseView {
fun initView() fun initView()
fun updateData(data: List<Student>) fun updateData(data: List<AccountItem<*>>)
fun dismissView() fun dismissView()

View File

@ -5,45 +5,60 @@
android:layout_width="300dp" android:layout_width="300dp"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView <LinearLayout
android:id="@+id/accountDialogTitle"
android:layout_width="match_parent"
android:layout_height="64dp"
android:paddingStart="24dp"
android:paddingLeft="24dp"
android:paddingEnd="24dp"
android:paddingRight="24dp"
android:text="@string/account_title"
android:textSize="20sp"
android:textStyle="bold"
app:firstBaselineToTopHeight="40dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/accountDialogRecycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/accountDialogTitle" android:orientation="vertical">
android:overScrollMode="never"
tools:itemCount="3"
tools:listitem="@layout/item_account" />
<com.google.android.material.button.MaterialButton <TextView
android:id="@+id/accountDialogAdd" android:id="@+id/accountDialogTitle"
style="@style/Widget.MaterialComponents.Button.TextButton" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:paddingStart="24dp"
android:layout_below="@id/accountDialogRecycler" android:paddingLeft="24dp"
android:layout_margin="8dp" android:paddingEnd="24dp"
android:text="@string/account_add_new" android:paddingRight="24dp"
android:textColor="?android:textColorPrimary" /> android:text="@string/account_title"
android:textSize="20sp"
android:textStyle="bold"
app:firstBaselineToTopHeight="40dp" />
<com.google.android.material.button.MaterialButton <androidx.recyclerview.widget.RecyclerView
android:id="@+id/accountDialogRemove" android:id="@+id/accountDialogRecycler"
style="@style/Widget.MaterialComponents.Button.TextButton" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="0dp"
android:layout_height="wrap_content" android:layout_marginTop="8dp"
android:layout_below="@id/accountDialogRecycler" android:layout_weight="1"
android:layout_alignParentEnd="true" android:overScrollMode="never"
android:layout_margin="8dp" tools:itemCount="3"
android:text="@string/account_logout" /> tools:listitem="@layout/item_account" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/accountDialogAdd"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/account_add_new"
android:textColor="?android:textColorPrimary" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<com.google.android.material.button.MaterialButton
android:id="@+id/accountDialogRemove"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/account_logout" />
</LinearLayout>
</LinearLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="24dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
tools:context=".ui.modules.account.AccountAdapter">
<TextView
android:id="@+id/accountHeaderEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorPrimary"
android:textSize="14sp"
tools:text="jan@fakelog.cf" />
<TextView
android:id="@+id/accountHeaderType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
tools:text="Konto ucznia" />
</LinearLayout>

View File

@ -3,20 +3,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="wrap_content"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="24dp" android:paddingVertical="8dp"
android:paddingLeft="24dp" android:paddingHorizontal="16dp"
android:paddingEnd="24dp"
android:paddingRight="24dp"
tools:context=".ui.modules.account.AccountAdapter"> tools:context=".ui.modules.account.AccountAdapter">
<ImageView <ImageView
android:id="@+id/accountItemImage" android:id="@+id/accountItemImage"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_all_account" app:srcCompat="@drawable/ic_all_account"
@ -27,7 +24,7 @@
android:id="@+id/accountItemName" android:id="@+id/accountItemName"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp" android:layout_marginStart="16dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textSize="16sp" android:textSize="16sp"
@ -40,7 +37,7 @@
android:id="@+id/accountItemSchool" android:id="@+id/accountItemSchool"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp" android:layout_marginStart="16dp"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
@ -50,4 +47,21 @@
app:layout_constraintStart_toEndOf="@id/accountItemImage" app:layout_constraintStart_toEndOf="@id/accountItemImage"
app:layout_constraintTop_toBottomOf="@id/accountItemName" app:layout_constraintTop_toBottomOf="@id/accountItemName"
tools:text="@tools:sample/lorem/random" /> tools:text="@tools:sample/lorem/random" />
<TextView
android:id="@+id/accountItemLoginMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/accountItemImage"
app:layout_constraintTop_toBottomOf="@id/accountItemSchool"
tools:text="Tryb API mobilne"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -265,6 +265,10 @@
<string name="account_logout">Wyloguj</string> <string name="account_logout">Wyloguj</string>
<string name="account_confirm">Czy chcesz wylogować aktualnego ucznia?</string> <string name="account_confirm">Czy chcesz wylogować aktualnego ucznia?</string>
<string name="account_logout_student">Wylogowanie ucznia</string> <string name="account_logout_student">Wylogowanie ucznia</string>
<string name="account_type_student">Konto ucznia</string>
<string name="account_type_parent">Konto rodzica</string>
<string name="account_login_mobile_api">Tryb API mobilne</string>
<string name="account_login_hybrid">Tryb hybrydowy</string>
<!--About--> <!--About-->
<string name="about_version">Wersja aplikacji</string> <string name="about_version">Wersja aplikacji</string>
<string name="about_contributor">Twórcy</string> <string name="about_contributor">Twórcy</string>

View File

@ -282,6 +282,10 @@
<string name="account_logout">Logout</string> <string name="account_logout">Logout</string>
<string name="account_confirm">Do you want to log out of an active student?</string> <string name="account_confirm">Do you want to log out of an active student?</string>
<string name="account_logout_student">Student logout</string> <string name="account_logout_student">Student logout</string>
<string name="account_type_student">Student account</string>
<string name="account_type_parent">Parent account</string>
<string name="account_login_mobile_api">Mobile API mode</string>
<string name="account_login_hybrid">Hybrid mode</string>
<!--About--> <!--About-->