mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 09:49:25 +02:00
Use CategoryAppsAndRulesFragment for CategoryTimeLimitRulesFragment
This commit is contained in:
parent
2c30b648e6
commit
2e97eaec5e
5 changed files with 113 additions and 161 deletions
|
@ -39,6 +39,7 @@ class AppAndRuleAdapter: RecyclerView.Adapter<AppAndRuleAdapter.Holder>() {
|
|||
private const val RULE_ENTRY = 4
|
||||
private const val EXPAND_RULES_ITEM = 5
|
||||
private const val RULES_INTRO = 6
|
||||
private const val ADD_RULE_ITEM = 7
|
||||
}
|
||||
|
||||
var items: List<AppAndRuleItem> by Delegates.observable(emptyList()) { _, _, _ -> notifyDataSetChanged() }
|
||||
|
@ -67,6 +68,7 @@ class AppAndRuleAdapter: RecyclerView.Adapter<AppAndRuleAdapter.Holder>() {
|
|||
is AppAndRuleItem.RuleEntry -> RULE_ENTRY
|
||||
AppAndRuleItem.ExpandRulesItem -> EXPAND_RULES_ITEM
|
||||
AppAndRuleItem.RulesIntro -> RULES_INTRO
|
||||
AppAndRuleItem.AddRuleItem -> ADD_RULE_ITEM
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder = Holder(
|
||||
|
@ -106,6 +108,16 @@ class AppAndRuleAdapter: RecyclerView.Adapter<AppAndRuleAdapter.Holder>() {
|
|||
parent,
|
||||
false
|
||||
).root
|
||||
ADD_RULE_ITEM -> AddItemViewBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
).apply {
|
||||
label = parent.context.getString(R.string.category_time_limit_rule_dialog_new)
|
||||
wide = true
|
||||
|
||||
root.setOnClickListener { handlers?.onAddTimeLimitRuleClicked() }
|
||||
}.root
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
)
|
||||
|
@ -173,6 +185,7 @@ class AppAndRuleAdapter: RecyclerView.Adapter<AppAndRuleAdapter.Holder>() {
|
|||
}
|
||||
AppAndRuleItem.ExpandRulesItem -> {/* nothing to do */}
|
||||
AppAndRuleItem.RulesIntro -> {/* nothing to do */}
|
||||
AppAndRuleItem.AddRuleItem -> {/* nothing to do */}
|
||||
}.let { }
|
||||
}
|
||||
|
||||
|
|
|
@ -25,4 +25,5 @@ sealed class AppAndRuleItem {
|
|||
data class RuleEntry(val rule: TimeLimitRule): AppAndRuleItem()
|
||||
object ExpandRulesItem: AppAndRuleItem()
|
||||
object RulesIntro: AppAndRuleItem()
|
||||
object AddRuleItem: AppAndRuleItem()
|
||||
}
|
|
@ -21,24 +21,34 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.timelimit.android.R
|
||||
import io.timelimit.android.async.Threads
|
||||
import io.timelimit.android.data.Database
|
||||
import io.timelimit.android.data.extensions.getDateLive
|
||||
import io.timelimit.android.data.model.HintsToShow
|
||||
import io.timelimit.android.data.model.TimeLimitRule
|
||||
import io.timelimit.android.livedata.map
|
||||
import io.timelimit.android.livedata.switchMap
|
||||
import io.timelimit.android.logic.DefaultAppLogic
|
||||
import io.timelimit.android.sync.actions.AddCategoryAppsAction
|
||||
import io.timelimit.android.sync.actions.CreateTimeLimitRuleAction
|
||||
import io.timelimit.android.sync.actions.RemoveCategoryAppsAction
|
||||
import io.timelimit.android.sync.actions.UpdateTimeLimitRuleAction
|
||||
import io.timelimit.android.ui.main.ActivityViewModel
|
||||
import io.timelimit.android.ui.main.getActivityViewModel
|
||||
import io.timelimit.android.ui.manage.category.apps.add.AddCategoryAppsFragment
|
||||
import io.timelimit.android.ui.manage.category.timelimit_rules.edit.EditTimeLimitRuleDialogFragment
|
||||
import io.timelimit.android.ui.manage.category.timelimit_rules.edit.EditTimeLimitRuleDialogFragmentListener
|
||||
import kotlinx.android.synthetic.main.fragment_category_apps_and_rules.*
|
||||
|
||||
abstract class CategoryAppsAndRulesFragment: Fragment(), Handlers {
|
||||
abstract class CategoryAppsAndRulesFragment: Fragment(), Handlers, EditTimeLimitRuleDialogFragmentListener {
|
||||
private val adapter = AppAndRuleAdapter().also { it.handlers = this }
|
||||
private val database: Database by lazy { DefaultAppLogic.with(requireContext()).database }
|
||||
private val auth: ActivityViewModel by lazy { getActivityViewModel(requireActivity()) }
|
||||
val auth: ActivityViewModel by lazy { getActivityViewModel(requireActivity()) }
|
||||
val database: Database by lazy { DefaultAppLogic.with(requireContext()).database }
|
||||
abstract val childId: String
|
||||
abstract val categoryId: String
|
||||
|
||||
|
@ -51,10 +61,86 @@ abstract class CategoryAppsAndRulesFragment: Fragment(), Handlers {
|
|||
|
||||
recycler.layoutManager = LinearLayoutManager(requireContext())
|
||||
recycler.adapter = adapter
|
||||
|
||||
ItemTouchHelper(object: ItemTouchHelper.Callback() {
|
||||
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
|
||||
val index = viewHolder.adapterPosition
|
||||
val item = if (index == RecyclerView.NO_POSITION) null else adapter.items[index]
|
||||
|
||||
if (item == AppAndRuleItem.RulesIntro) {
|
||||
return makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.END or ItemTouchHelper.START) or
|
||||
makeFlag(ItemTouchHelper.ACTION_STATE_IDLE, ItemTouchHelper.END or ItemTouchHelper.START)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder) = throw IllegalStateException()
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
val database = database
|
||||
|
||||
Threads.database.submit {
|
||||
database.config().setHintsShownSync(HintsToShow.TIME_LIMIT_RULE_INTRODUCTION)
|
||||
}
|
||||
}
|
||||
}).attachToRecyclerView(recycler)
|
||||
|
||||
val userDate = database.user().getUserByIdLive(childId).getDateLive(auth.logic.realTimeLogic)
|
||||
|
||||
userDate.switchMap { date ->
|
||||
val firstDayOfWeekAsEpochDay = date.dayOfEpoch - date.dayOfWeek
|
||||
|
||||
database.usedTimes().getUsedTimesOfWeek(
|
||||
categoryId = categoryId,
|
||||
firstDayOfWeekAsEpochDay = firstDayOfWeekAsEpochDay
|
||||
).map { res ->
|
||||
firstDayOfWeekAsEpochDay to res
|
||||
}
|
||||
}.observe(viewLifecycleOwner) {
|
||||
adapter.epochDayOfStartOfWeek = it.first
|
||||
adapter.usedTimes = it.second
|
||||
}
|
||||
}
|
||||
|
||||
fun setListContent(items: List<AppAndRuleItem>) { adapter.items = items }
|
||||
|
||||
override fun notifyRuleCreated() {
|
||||
Snackbar.make(requireView(), R.string.category_time_limit_rules_snackbar_created, Snackbar.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun notifyRuleDeleted(oldRule: TimeLimitRule) {
|
||||
Snackbar.make(requireView(), R.string.category_time_limit_rules_snackbar_deleted, Snackbar.LENGTH_SHORT)
|
||||
.setAction(R.string.generic_undo) {
|
||||
auth.tryDispatchParentAction(
|
||||
CreateTimeLimitRuleAction(
|
||||
rule = oldRule
|
||||
)
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun notifyRuleUpdated(oldRule: TimeLimitRule, newRule: TimeLimitRule) {
|
||||
Snackbar.make(requireView(), R.string.category_time_limit_rules_snackbar_updated, Snackbar.LENGTH_SHORT)
|
||||
.setAction(R.string.generic_undo) {
|
||||
auth.tryDispatchParentAction(
|
||||
UpdateTimeLimitRuleAction(
|
||||
ruleId = oldRule.id,
|
||||
applyToExtraTimeUsage = oldRule.applyToExtraTimeUsage,
|
||||
maximumTimeInMillis = oldRule.maximumTimeInMillis,
|
||||
dayMask = oldRule.dayMask,
|
||||
start = oldRule.startMinuteOfDay,
|
||||
end = oldRule.endMinuteOfDay,
|
||||
sessionDurationMilliseconds = oldRule.sessionDurationMilliseconds,
|
||||
sessionPauseMilliseconds = oldRule.sessionPauseMilliseconds
|
||||
)
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onAppClicked(app: AppAndRuleItem.AppEntry) {
|
||||
if (auth.tryDispatchParentAction(
|
||||
RemoveCategoryAppsAction(
|
||||
|
|
|
@ -16,36 +16,17 @@
|
|||
package io.timelimit.android.ui.manage.category.timelimit_rules
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.timelimit.android.R
|
||||
import io.timelimit.android.async.Threads
|
||||
import io.timelimit.android.data.Database
|
||||
import io.timelimit.android.data.extensions.getDateLive
|
||||
import io.timelimit.android.data.model.HintsToShow
|
||||
import io.timelimit.android.data.model.TimeLimitRule
|
||||
import io.timelimit.android.livedata.map
|
||||
import io.timelimit.android.livedata.switchMap
|
||||
import io.timelimit.android.logic.AppLogic
|
||||
import io.timelimit.android.logic.DefaultAppLogic
|
||||
import io.timelimit.android.sync.actions.CreateTimeLimitRuleAction
|
||||
import io.timelimit.android.sync.actions.UpdateTimeLimitRuleAction
|
||||
import io.timelimit.android.ui.main.ActivityViewModel
|
||||
import io.timelimit.android.ui.main.getActivityViewModel
|
||||
import io.timelimit.android.ui.manage.category.ManageCategoryFragmentArgs
|
||||
import io.timelimit.android.ui.manage.category.timelimit_rules.edit.EditTimeLimitRuleDialogFragment
|
||||
import io.timelimit.android.ui.manage.category.timelimit_rules.edit.EditTimeLimitRuleDialogFragmentListener
|
||||
import kotlinx.android.synthetic.main.fragment_category_time_limit_rules.*
|
||||
import io.timelimit.android.ui.manage.category.appsandrules.AppAndRuleItem
|
||||
import io.timelimit.android.ui.manage.category.appsandrules.CategoryAppsAndRulesFragment
|
||||
|
||||
class CategoryTimeLimitRulesFragment : Fragment(), EditTimeLimitRuleDialogFragmentListener {
|
||||
class CategoryTimeLimitRulesFragment: CategoryAppsAndRulesFragment() {
|
||||
companion object {
|
||||
fun newInstance(params: ManageCategoryFragmentArgs): CategoryTimeLimitRulesFragment {
|
||||
val result = CategoryTimeLimitRulesFragment()
|
||||
|
@ -54,130 +35,28 @@ class CategoryTimeLimitRulesFragment : Fragment(), EditTimeLimitRuleDialogFragme
|
|||
}
|
||||
}
|
||||
|
||||
private val logic: AppLogic by lazy { DefaultAppLogic.with(context!!) }
|
||||
private val params: ManageCategoryFragmentArgs by lazy { ManageCategoryFragmentArgs.fromBundle(arguments!!) }
|
||||
private val database: Database by lazy { logic.database }
|
||||
private val params: ManageCategoryFragmentArgs by lazy { ManageCategoryFragmentArgs.fromBundle(requireArguments()) }
|
||||
private val rules: LiveData<List<TimeLimitRule>> by lazy { database.timeLimitRules().getTimeLimitRulesByCategory(params.categoryId) }
|
||||
private val auth: ActivityViewModel by lazy { getActivityViewModel(activity!!) }
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_category_time_limit_rules, container, false)
|
||||
}
|
||||
override val childId: String get() = params.childId
|
||||
override val categoryId: String get() = params.categoryId
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val adapter = Adapter()
|
||||
|
||||
recycler.layoutManager = LinearLayoutManager(context!!)
|
||||
recycler.adapter = adapter
|
||||
|
||||
val userDate = database.user().getUserByIdLive(params.childId).getDateLive(logic.realTimeLogic)
|
||||
|
||||
userDate.switchMap { date ->
|
||||
val firstDayOfWeekAsEpochDay = date.dayOfEpoch - date.dayOfWeek
|
||||
|
||||
database.usedTimes().getUsedTimesOfWeek(
|
||||
categoryId = params.categoryId,
|
||||
firstDayOfWeekAsEpochDay = firstDayOfWeekAsEpochDay
|
||||
).map { res ->
|
||||
firstDayOfWeekAsEpochDay to res
|
||||
}
|
||||
}.observe(viewLifecycleOwner, Observer {
|
||||
adapter.epochDayOfStartOfWeek = it.first
|
||||
adapter.usedTimes = it.second
|
||||
})
|
||||
|
||||
val hasHiddenIntro = database.config().wereHintsShown(HintsToShow.TIME_LIMIT_RULE_INTRODUCTION)
|
||||
|
||||
rules.map { rules ->
|
||||
rules.sortedBy { it.dayMask }.map { TimeLimitRuleRuleItem(it) }
|
||||
rules.sortedBy { it.dayMask }.map { AppAndRuleItem.RuleEntry(it) }
|
||||
}.switchMap {
|
||||
val baseList = it + listOf(AddTimeLimitRuleItem)
|
||||
val baseList = it + listOf(AppAndRuleItem.AddRuleItem)
|
||||
|
||||
hasHiddenIntro.map { hasHiddenIntro ->
|
||||
if (hasHiddenIntro) {
|
||||
baseList
|
||||
} else {
|
||||
listOf(TimeLimitRuleIntroductionItem) + baseList
|
||||
listOf(AppAndRuleItem.RulesIntro) + baseList
|
||||
}
|
||||
}
|
||||
}.observe(viewLifecycleOwner, Observer {
|
||||
adapter.data = it
|
||||
})
|
||||
|
||||
adapter.handlers = object: TimeLimitRulesHandlers {
|
||||
override fun onTimeLimitRuleClicked(rule: TimeLimitRule) {
|
||||
if (auth.requestAuthenticationOrReturnTrue()) {
|
||||
EditTimeLimitRuleDialogFragment.newInstance(rule, this@CategoryTimeLimitRulesFragment).show(fragmentManager!!)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAddTimeLimitRuleClicked() {
|
||||
if (auth.requestAuthenticationOrReturnTrueAllowChild(childId = params.childId)) {
|
||||
EditTimeLimitRuleDialogFragment.newInstance(params.categoryId, this@CategoryTimeLimitRulesFragment).show(fragmentManager!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemTouchHelper(object: ItemTouchHelper.Callback() {
|
||||
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
|
||||
val index = viewHolder.adapterPosition
|
||||
val item = if (index == RecyclerView.NO_POSITION) null else adapter.data[index]
|
||||
|
||||
if (item == TimeLimitRuleIntroductionItem) {
|
||||
return makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.END or ItemTouchHelper.START) or
|
||||
makeFlag(ItemTouchHelper.ACTION_STATE_IDLE, ItemTouchHelper.END or ItemTouchHelper.START)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder) = throw IllegalStateException()
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
val database = logic.database
|
||||
|
||||
Threads.database.submit {
|
||||
database.config().setHintsShownSync(HintsToShow.TIME_LIMIT_RULE_INTRODUCTION)
|
||||
}
|
||||
}
|
||||
}).attachToRecyclerView(recycler)
|
||||
}
|
||||
|
||||
override fun notifyRuleCreated() {
|
||||
Snackbar.make(view!!, R.string.category_time_limit_rules_snackbar_created, Snackbar.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun notifyRuleDeleted(oldRule: TimeLimitRule) {
|
||||
Snackbar.make(view!!, R.string.category_time_limit_rules_snackbar_deleted, Snackbar.LENGTH_SHORT)
|
||||
.setAction(R.string.generic_undo) {
|
||||
auth.tryDispatchParentAction(
|
||||
CreateTimeLimitRuleAction(
|
||||
rule = oldRule
|
||||
)
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun notifyRuleUpdated(oldRule: TimeLimitRule, newRule: TimeLimitRule) {
|
||||
Snackbar.make(view!!, R.string.category_time_limit_rules_snackbar_updated, Snackbar.LENGTH_SHORT)
|
||||
.setAction(R.string.generic_undo) {
|
||||
auth.tryDispatchParentAction(
|
||||
UpdateTimeLimitRuleAction(
|
||||
ruleId = oldRule.id,
|
||||
applyToExtraTimeUsage = oldRule.applyToExtraTimeUsage,
|
||||
maximumTimeInMillis = oldRule.maximumTimeInMillis,
|
||||
dayMask = oldRule.dayMask,
|
||||
start = oldRule.startMinuteOfDay,
|
||||
end = oldRule.endMinuteOfDay,
|
||||
sessionDurationMilliseconds = oldRule.sessionDurationMilliseconds,
|
||||
sessionPauseMilliseconds = oldRule.sessionPauseMilliseconds
|
||||
)
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}.observe(viewLifecycleOwner) { setListContent(it) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
<!--
|
||||
TimeLimit Copyright <C> 2019 Jonas Lochmann
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="io.timelimit.android.ui.manage.category.timelimit_rules.CategoryTimeLimitRulesFragment">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</RelativeLayout>
|
Loading…
Add table
Add a link
Reference in a new issue