[Home] Implement dismissing, adding and removing cards. Remove debug card.

This commit is contained in:
Kuba Szczodrzyński 2020-03-11 18:25:28 +01:00
parent 1e494ebb70
commit 35f4a31a76
5 changed files with 172 additions and 17 deletions

View File

@ -7,6 +7,7 @@ package pl.szczodrzynski.edziennik.ui.modules.home
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment.Companion.removeCard
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment.Companion.swapCards import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment.Companion.swapCards
import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
@ -14,7 +15,7 @@ class CardItemTouchHelperCallback(private val cardAdapter: HomeCardAdapter, priv
companion object { companion object {
private const val TAG = "CardItemTouchHelperCallback" private const val TAG = "CardItemTouchHelperCallback"
private const val DRAG_FLAGS = ItemTouchHelper.UP or ItemTouchHelper.DOWN private const val DRAG_FLAGS = ItemTouchHelper.UP or ItemTouchHelper.DOWN
private const val SWIPE_FLAGS = 0 private const val SWIPE_FLAGS = ItemTouchHelper.RIGHT
} }
private var dragCardView: MaterialCardView? = null private var dragCardView: MaterialCardView? = null
@ -27,11 +28,14 @@ class CardItemTouchHelperCallback(private val cardAdapter: HomeCardAdapter, priv
val fromPosition = viewHolder.adapterPosition val fromPosition = viewHolder.adapterPosition
val toPosition = target.adapterPosition val toPosition = target.adapterPosition
swapCards(fromPosition, toPosition, cardAdapter) return swapCards(fromPosition, toPosition, cardAdapter)
return true
} }
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
removeCard(viewHolder.adapterPosition)
cardAdapter.items.removeAt(viewHolder.adapterPosition)
cardAdapter.notifyItemRemoved(viewHolder.adapterPosition)
}
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
super.onSelectedChanged(viewHolder, actionState) super.onSelectedChanged(viewHolder, actionState)

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-3-11.
*/
package pl.szczodrzynski.edziennik.ui.modules.home
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard.Companion.CARD_EVENTS
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard.Companion.CARD_GRADES
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard.Companion.CARD_LUCKY_NUMBER
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard.Companion.CARD_TIMETABLE
import kotlin.collections.set
class HomeConfigDialog(
val activity: AppCompatActivity,
private val reloadOnDismiss: Boolean = true,
val onShowListener: ((tag: String) -> Unit)? = null,
val onDismissListener: ((tag: String) -> Unit)? = null
) {
companion object {
const val TAG = "HomeConfigDialog"
}
private val app by lazy { activity.application as App }
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
private lateinit var dialog: AlertDialog
init { run {
if (activity.isFinishing)
return@run
onShowListener?.invoke(TAG)
val ids = listOf(
CARD_LUCKY_NUMBER,
CARD_TIMETABLE,
CARD_GRADES,
CARD_EVENTS
)
val items = listOf(
app.getString(R.string.card_type_lucky_number),
app.getString(R.string.card_type_timetable),
app.getString(R.string.card_type_grades),
app.getString(R.string.card_type_events)
)
val checkedItems = ids.map { it to false }.toMap().toMutableMap()
val profileId = App.profileId
val homeCards = profileConfig.homeCards
.filter { it.profileId == profileId }
.toMutableList()
homeCards.forEach {
checkedItems[it.cardId] = true
}
dialog = MaterialAlertDialogBuilder(activity)
.setTitle(R.string.home_configure_add_remove)
.setMultiChoiceItems(items.toTypedArray(), checkedItems.values.toBooleanArray()) { _, which, isChecked ->
if (isChecked) {
homeCards += HomeCardModel(profileId, ids[which])
}
else {
homeCards.removeAll { it.profileId == profileId && it.cardId == ids[which] }
}
}
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
.setOnDismissListener {
profileConfig.homeCards = homeCards
onDismissListener?.invoke(TAG)
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
}
.show()
}}
}

View File

@ -25,8 +25,12 @@ import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding
import pl.szczodrzynski.edziennik.onClick
import pl.szczodrzynski.edziennik.ui.dialogs.home.StudentNumberDialog import pl.szczodrzynski.edziennik.ui.dialogs.home.StudentNumberDialog
import pl.szczodrzynski.edziennik.ui.modules.home.cards.* import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeEventsCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeGradesCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeLuckyNumberCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeTimetableCard
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
@ -36,12 +40,12 @@ class HomeFragment : Fragment(), CoroutineScope {
companion object { companion object {
private const val TAG = "HomeFragment" private const val TAG = "HomeFragment"
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter) { fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter): Boolean {
val fromCard = cardAdapter.items[fromPosition] val fromCard = cardAdapter.items[fromPosition]
val toCard = cardAdapter.items[toPosition] val toCard = cardAdapter.items[toPosition]
if (fromCard.id == 100 || toCard.id == 100) { if (fromCard.id == 100 || toCard.id == 100) {
// debug card is not swappable // debug card is not swappable
return return false
} }
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition] cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
cardAdapter.items[toPosition] = fromCard cardAdapter.items[toPosition] = fromCard
@ -52,6 +56,15 @@ class HomeFragment : Fragment(), CoroutineScope {
homeCards[fromPosition] = homeCards[toPosition] homeCards[fromPosition] = homeCards[toPosition]
homeCards[toPosition] = fromPair homeCards[toPosition] = fromPair
App.config.forProfile().ui.homeCards = homeCards App.config.forProfile().ui.homeCards = homeCards
return true
}
fun removeCard(position: Int) {
val homeCards = App.config.forProfile().ui.homeCards.toMutableList()
if (position >= homeCards.size)
return
homeCards.removeAt(position)
App.config.forProfile().ui.homeCards = homeCards
} }
} }
@ -76,7 +89,7 @@ class HomeFragment : Fragment(), CoroutineScope {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// TODO check if app, activity, b can be null // TODO check if app, activity, b can be null
if (app.profile == null || !isAdded) if (!isAdded)
return return
activity.bottomSheet.prependItems( activity.bottomSheet.prependItems(
@ -106,6 +119,9 @@ class HomeFragment : Fragment(), CoroutineScope {
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show() Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
}) })
) )
b.configureCards.onClick {
HomeConfigDialog(activity, reloadOnDismiss = true)
}
val showUnified = false val showUnified = false
@ -130,8 +146,8 @@ class HomeFragment : Fragment(), CoroutineScope {
else -> null else -> null
} }
} }
if (App.devMode) //if (App.devMode)
items += HomeDebugCard(100, app, activity, this, app.profile) // items += HomeDebugCard(100, app, activity, this, app.profile)
val adapter = HomeCardAdapter(items) val adapter = HomeCardAdapter(items)
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout)) val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout))

View File

@ -3,18 +3,67 @@
~ Copyright (c) Kuba Szczodrzyński 2019-11-23. ~ Copyright (c) Kuba Szczodrzyński 2019-11-23.
--> -->
<layout xmlns:tools="http://schemas.android.com/tools" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:tools="http://schemas.android.com/tools">
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator <pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
android:id="@+id/refreshLayout" android:id="@+id/refreshLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/list" android:id="@+id/list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
tools:listitem="@layout/card_home" /> tools:itemCount="1"
tools:listitem="@layout/card_home_timetable" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="8dp"
android:background="@drawable/divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginBottom="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
android:text="@string/home_configure_notice"
android:textAppearance="@style/NavView.TextView.Helper"
android:textSize="12sp"
android:textStyle="italic" />
<Button
android:id="@+id/configureCards"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:minHeight="0dp"
android:text="@string/home_configure_add_remove" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator> </pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
</layout> </layout>

View File

@ -1261,4 +1261,10 @@
<string name="grades_config_dont_count_grades">Wyklucz wybrane oceny ze średniej</string> <string name="grades_config_dont_count_grades">Wyklucz wybrane oceny ze średniej</string>
<string name="grades_config_dont_count_hint">Oceny oddziel przecinkiem</string> <string name="grades_config_dont_count_hint">Oceny oddziel przecinkiem</string>
<string name="grades_config_dont_count_placeholder">Podaj oceny...</string> <string name="grades_config_dont_count_placeholder">Podaj oceny...</string>
<string name="home_configure_notice">Możesz usunąć karty przesuwając w prawo lub zmienić ich kolejność, przytrzymując na kartę.</string>
<string name="home_configure_add_remove">Dodaj/usuń karty</string>
<string name="card_type_lucky_number">Szczęśliwy numerek</string>
<string name="card_type_timetable">Plan lekcji</string>
<string name="card_type_grades">Ostatnie oceny</string>
<string name="card_type_events">Najbliższe wydarzenia</string>
</resources> </resources>