[UI] Add teacher list action buttons. (#105)

* Update code

TODO: Change icons color

* Change "More" icon, update teachers list

* Update code

* Update code

* Reformat code

* Apply suggestions from code review

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>

* Update code

* Update app/src/main/java/pl/szczodrzynski/edziennik/ui/teachers/TeachersListFragment.kt

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>

* Update code

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
This commit is contained in:
Antoni Czaplicki 2021-10-24 18:29:04 +02:00 committed by GitHub
parent e629e03b33
commit e02246f97d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 95 additions and 28 deletions

View File

@ -197,7 +197,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
.isInDrawer(true)
list += NavTarget(DRAWER_ITEM_MORE, R.string.menu_more, null)
.withIcon(CommunityMaterial.Icon.cmd_dots_horizontal_circle_outline)
.withIcon(CommunityMaterial.Icon.cmd_dots_horizontal)
.isInDrawer(true)
.isStatic(true)
.withSubItems(*moreList.toTypedArray())

View File

@ -442,7 +442,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
fun getTeacherByLastFirst(nameLastFirst: String, loginId: String? = null): Teacher {
// comparing full name is safer than splitting and swapping
val teacher = teacherList.singleOrNull { it.fullNameLastFirst == nameLastFirst }
val nameParts = nameLastFirst.split(" ")
val nameParts = nameLastFirst.split(" ", limit = 2)
return if (nameParts.size == 1)
validateTeacher(teacher, nameParts[0], "", loginId)
else
@ -450,11 +450,13 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
}
fun getTeacherByFirstLast(nameFirstLast: String, loginId: String? = null): Teacher {
val nameParts = nameFirstLast.split(" ")
// comparing full name is safer than splitting and swapping
val teacher = teacherList.singleOrNull { it.fullName == nameFirstLast }
val nameParts = nameFirstLast.split(" ", limit = 2)
return if (nameParts.size == 1)
getTeacher(nameParts[0], "", loginId)
validateTeacher(teacher, nameParts[0], "", loginId)
else
getTeacher(nameParts[0], nameParts[1], loginId)
validateTeacher(teacher, nameParts[0], nameParts[1], loginId)
}
fun getTeacherByFDotLast(nameFDotLast: String, loginId: String? = null): Teacher {

View File

@ -12,6 +12,7 @@ import androidx.room.Ignore
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.ext.fixName
import pl.szczodrzynski.edziennik.ext.getNameInitials
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.ext.join
import java.util.*
@ -117,15 +118,23 @@ open class Teacher {
type = type and (1 shl i).inv()
}
fun getTypeText(c: Context): String {
val list = mutableListOf<String>()
fun getTypeText(c: Context, subjectList: List<Subject>? = null): String {
val roles = mutableListOf<String>()
types.forEach {
if (isType(it))
list += typeName(c, it, typeDescription)
roles += typeName(c, it, typeDescription)
}
return list.join(", ")
}
if (subjectList != null && subjects.isNotEmpty()) {
return subjects.joinToString(
prefix = if (roles.isNotEmpty()) roles.joinToString(postfix = ": ") else "",
transform = { subjectId ->
subjectList.firstOrNull { it.id == subjectId }?.longName ?: ""
},
)
}
return roles.joinToString()
}
@Ignore
var image: Bitmap? = null

View File

@ -4,19 +4,23 @@
package pl.szczodrzynski.edziennik.ui.teachers
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Subject
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
import pl.szczodrzynski.edziennik.databinding.TeacherItemBinding
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.ui.messages.MessagesUtils.getProfileImage
import pl.szczodrzynski.edziennik.utils.BetterLink
import pl.szczodrzynski.edziennik.ext.*
import kotlin.coroutines.CoroutineContext
class TeachersAdapter(
@ -36,6 +40,8 @@ class TeachersAdapter(
var items = listOf<Teacher>()
var subjectList = listOf<Subject>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(activity)
val view = TeacherItemBinding.inflate(inflater, parent, false)
@ -47,19 +53,28 @@ class TeachersAdapter(
val b = holder.b
b.name.text = item.fullName
b.image.setImageBitmap(item.image?: getProfileImage(48, 24, 16, 12, 1, item.fullName))
var role = item.getTypeText(activity)
if (item.subjects.isNotNullNorEmpty()) {
val subjects = item.subjects.map { App.db.subjectDao().getByIdNow(App.profileId, it).longName }
role = role.plus(": ").plus(subjects.joinToString())
b.image.setImageBitmap(item.image)
b.type.text = item.getTypeText(activity, subjectList)
b.copy.isVisible = true
b.copy.onClick {
item.fullName.copyToClipboard(activity)
Toast.makeText(activity, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
}
b.type.text = role
b.copy.attachToastHint(R.string.copy_to_clipboard)
if (item.loginId.isNotNullNorBlank()) {
b.sendMessage.isVisible = true
item.fullName.let { name ->
BetterLink.attach(
b.name,
teachers = mapOf(item.id to name)
)
b.sendMessage.onClick {
val intent = Intent(
Intent.ACTION_MAIN,
"fragmentId" to MainActivity.TARGET_MESSAGES_COMPOSE,
"messageRecipientId" to item.id
)
activity.sendBroadcast(intent)
}
b.sendMessage.attachToastHint(R.string.send_message)
} else {
b.sendMessage.isVisible = false
}
}

View File

@ -15,10 +15,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.databinding.TeachersListFragmentBinding
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
import pl.szczodrzynski.edziennik.ui.messages.MessagesUtils
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
import kotlin.coroutines.CoroutineContext
@ -48,11 +50,21 @@ class TeachersListFragment : Fragment(), CoroutineScope {
val adapter = TeachersAdapter(activity)
adapter.subjectList = withContext(Dispatchers.IO) {
App.db.subjectDao().getAllNow(App.profileId)
}
app.db.teacherDao().getAllTeachers(App.profileId).observe(viewLifecycleOwner, Observer { items ->
if (!isAdded) return@Observer
// load & configure the adapter
adapter.items = items
adapter.items = items.sortedWith(compareBy(
{ it.subjects.isEmpty() },
{ it.type == 0 },
))
adapter.items.forEach {
it.image = it.image ?: MessagesUtils.getProfileImage(48, 24, 16, 12, 1, it.fullName)
}
if (items.isNotNullNorEmpty() && b.list.adapter == null) {
b.list.adapter = adapter
b.list.apply {

View File

@ -8,12 +8,12 @@
<ImageView
android:id="@+id/image"
android:layout_marginLeft="8dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
tools:srcCompat="@drawable/bg_circle"
android:layout_marginStart="8dp" />
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
tools:srcCompat="@drawable/bg_circle" />
<LinearLayout
android:layout_width="0dp"
@ -43,4 +43,31 @@
tools:text="Jan Kowalski" />
</LinearLayout>
<com.mikepenz.iconics.view.IconicsImageButton
android:id="@+id/sendMessage"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="?selectableItemBackground"
android:visibility="gone"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-email-plus-outline"
app:iiv_size="24dp"
tools:visibility="visible" />
<com.mikepenz.iconics.view.IconicsImageButton
android:id="@+id/copy"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="?selectableItemBackground"
android:visibility="gone"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-clipboard-text-multiple-outline"
app:iiv_size="24dp"
tools:visibility="visible" />
</LinearLayout>

View File

@ -1376,4 +1376,5 @@
<string name="login_summary_account_parent">(Parent)</string>
<string name="menu_teachers">Teachers</string>
<string name="edziennik_progress_endpoint_addressbook">Syncing addressbook…</string>
<string name="send_message">Send message</string>
</resources>

View File

@ -1496,5 +1496,6 @@
<string name="login_mobidziennik_server_prefix">https://</string>
<string name="login_mobidziennik_server_suffix">.mobidziennik.pl/</string>
<string name="styled_text_dialog_title">Edytuj tekst</string>
<string name="send_message">Wyślij wiadomość</string>
<string name="login_qr_decoding_error">Kod QR nie wygląda na prawidłowy</string>
</resources>