Collection member listing.

pull/131/head
Tom Hacohen 4 years ago
parent 251e610fe8
commit df9f2f4ed4

@ -0,0 +1,63 @@
package com.etesync.syncadapter.ui.etebase
import android.graphics.Color.parseColor
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.etesync.syncadapter.CachedCollection
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.R
import com.etesync.syncadapter.resource.LocalCalendar
import com.etesync.syncadapter.ui.BaseActivity
class CollectionMembersFragment : Fragment() {
private val collectionModel: CollectionViewModel by activityViewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val ret = inflater.inflate(R.layout.etebase_view_collection_members, container, false)
if (savedInstanceState == null) {
collectionModel.observe(this) {
(activity as? BaseActivity?)?.supportActionBar?.setTitle(R.string.collection_members_title)
if (container != null) {
initUi(inflater, ret, it)
}
}
}
return ret
}
private fun initUi(inflater: LayoutInflater, v: View, cachedCollection: CachedCollection) {
v.findViewById<View>(R.id.add_member).setOnClickListener {
}
val meta = cachedCollection.meta
val colorSquare = v.findViewById<View>(R.id.color)
val color = if (!meta.color.isNullOrBlank()) parseColor(meta.color) else LocalCalendar.defaultColor
when (meta.collectionType) {
Constants.ETEBASE_TYPE_CALENDAR -> {
colorSquare.setBackgroundColor(color)
}
Constants.ETEBASE_TYPE_TASKS -> {
colorSquare.setBackgroundColor(color)
}
Constants.ETEBASE_TYPE_ADDRESS_BOOK -> {
colorSquare.visibility = View.GONE
}
}
val title = v.findViewById<View>(R.id.display_name) as TextView
title.text = meta.name
val desc = v.findViewById<View>(R.id.description) as TextView
desc.text = meta.description
v.findViewById<View>(R.id.progressBar).visibility = View.GONE
}
}

@ -0,0 +1,145 @@
package com.etesync.syncadapter.ui.etebase
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.fragment.app.ListFragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.observe
import com.etebase.client.CollectionMember
import com.etebase.client.FetchOptions
import com.etesync.syncadapter.CachedCollection
import com.etesync.syncadapter.R
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import java.util.*
import java.util.concurrent.Future
class CollectionMembersListFragment : ListFragment(), AdapterView.OnItemClickListener {
private val model: AccountViewModel by activityViewModels()
private val collectionModel: CollectionViewModel by activityViewModels()
private val membersModel: LoadMembersViewModel by viewModels()
private var emptyTextView: TextView? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.collection_members_list, container, false)
//This is instead of setEmptyText() function because of Google bug
//See: https://code.google.com/p/android/issues/detail?id=21742
emptyTextView = view.findViewById<TextView>(android.R.id.empty)
return view
}
private fun setListAdapterMembers(members: List<CollectionMember>) {
val context = context
if (context != null) {
val listAdapter = MembersListAdapter(context)
setListAdapter(listAdapter)
listAdapter.addAll(members)
emptyTextView!!.setText(R.string.collection_members_list_empty)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.observe(this) {
collectionModel.observe(this) { cachedCollection ->
membersModel.loadMembers(it, cachedCollection)
}
}
membersModel.observe(this) {
setListAdapterMembers(it)
}
listView.onItemClickListener = this
}
override fun onDestroyView() {
super.onDestroyView()
membersModel.cancelLoad()
}
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
val member = listAdapter?.getItem(position) as CollectionMember
/*
AlertDialog.Builder(requireActivity())
.setIcon(R.drawable.ic_info_dark)
.setTitle(R.string.collection_members_remove_title)
.setMessage(getString(R.string.collection_members_remove, member.user))
.setPositiveButton(android.R.string.yes) { dialog, which ->
val frag = RemoveMemberFragment.newInstance(account, info, member.user!!)
frag.show(requireFragmentManager(), null)
}
.setNegativeButton(android.R.string.no) { dialog, which -> }.show()
*/
}
internal inner class MembersListAdapter(context: Context) : ArrayAdapter<CollectionMember>(context, R.layout.collection_members_list_item) {
override fun getView(position: Int, _v: View?, parent: ViewGroup): View {
var v = _v
if (v == null)
v = LayoutInflater.from(context).inflate(R.layout.collection_members_list_item, parent, false)
val member = getItem(position)
val tv = v!!.findViewById<View>(R.id.title) as TextView
tv.text = member!!.username
// FIXME: Also mark admins
val readOnly = v.findViewById<View>(R.id.read_only)
readOnly.visibility = if (member.accessLevel == "ro") View.VISIBLE else View.GONE
return v
}
}
}
class LoadMembersViewModel : ViewModel() {
private val members = MutableLiveData<List<CollectionMember>>()
private var asyncTask: Future<Unit>? = null
fun loadMembers(accountCollectionHolder: AccountHolder, cachedCollection: CachedCollection) {
asyncTask = doAsync {
val ret = LinkedList<CollectionMember>()
val col = cachedCollection.col
val memberManager = accountCollectionHolder.colMgr.getMemberManager(col)
var iterator: String? = null
var done = false
while (!done) {
val chunk = memberManager.list(FetchOptions().iterator(iterator).limit(30))
iterator = chunk.stoken
done = chunk.isDone
ret.addAll(chunk.data)
}
uiThread {
members.value = ret
}
}
}
fun cancelLoad() {
asyncTask?.cancel(true)
}
fun observe(owner: LifecycleOwner, observer: (List<CollectionMember>) -> Unit) =
members.observe(owner, observer)
}

@ -129,8 +129,19 @@ class ViewCollectionFragment : Fragment() {
}
}
R.id.on_manage_members -> {
Toast.makeText(context, "Manage", Toast.LENGTH_LONG).show()
}
if (cachedCollection.col.accessLevel == "adm") {
parentFragmentManager.commit {
replace(R.id.fragment_container, CollectionMembersFragment())
addToBackStack(null)
}
} else {
val dialog = AlertDialog.Builder(requireContext())
.setIcon(R.drawable.ic_info_dark)
.setTitle(R.string.not_allowed_title)
.setMessage(R.string.edit_owner_only_anon)
.setPositiveButton(android.R.string.yes) { _, _ -> }.create()
dialog.show()
} }
R.id.on_import -> {
Toast.makeText(context, "Import", Toast.LENGTH_LONG).show()
}

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/collection_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_margin" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/activity_margin">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right" />
</LinearLayout>
<LinearLayout
android:id="@+id/add_member"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_margin"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="@string/collection_members_add"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"
android:src="@drawable/ic_account_add_dark" />
</LinearLayout>
<fragment android:name="com.etesync.syncadapter.ui.etebase.CollectionMembersListFragment"
android:id="@+id/list_entries_container"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
Loading…
Cancel
Save