Migrate away from the kotlin-android-extensions

This commit is contained in:
Jonas Lochmann 2021-05-24 02:00:00 +02:00
parent e7687fd511
commit 9fa2104cf1
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
21 changed files with 135 additions and 152 deletions

View file

@ -16,14 +16,10 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-parcelize'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'kotlin-kapt'
androidExtensions {
experimental = true
}
android {
compileSdkVersion 30
defaultConfig {
@ -49,6 +45,9 @@ android {
// set to empty string to disable this check
buildConfigField 'String', 'updateServerBuildsCertificate', '"2170068198547F15129DE8CC46E2A8BF1485A6E5030916E26DDE41AE0E81DAC2"'
}
buildFeatures {
viewBinding true
}
flavorDimensions 'api', 'channel', 'server'
productFlavors {

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -18,7 +18,7 @@ package io.timelimit.android.data.customtypes
import android.os.Parcelable
import android.text.TextUtils
import androidx.room.TypeConverter
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import java.util.*
import kotlin.collections.ArrayList

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -29,7 +29,7 @@ import io.timelimit.android.data.customtypes.ImmutableBitmaskAdapter
import io.timelimit.android.extensions.MinuteOfDay
import io.timelimit.android.livedata.ignoreUnchanged
import io.timelimit.android.livedata.map
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@Entity(tableName = "time_limit_rule")
@TypeConverters(ImmutableBitmaskAdapter::class)

View file

@ -21,7 +21,7 @@ import androidx.lifecycle.LiveData
import androidx.room.TypeConverter
import io.timelimit.android.data.model.App
import io.timelimit.android.data.model.AppActivity
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
abstract class PlatformIntegration(
val maximumProtectionLevel: ProtectionLevel

View file

@ -23,41 +23,40 @@ import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.Navigation
import io.timelimit.android.R
import io.timelimit.android.databinding.SingleFragmentWrapperBinding
import io.timelimit.android.livedata.liveDataFromNonNullValue
import io.timelimit.android.ui.main.ActivityViewModelHolder
import io.timelimit.android.ui.main.AuthenticationFab
import kotlinx.android.synthetic.main.single_fragment_wrapper.*
abstract class SingleFragmentWrapper: Fragment() {
val activity: ActivityViewModelHolder by lazy { getActivity() as ActivityViewModelHolder }
private lateinit var navController: NavController
protected lateinit var binding: SingleFragmentWrapperBinding
protected val navigation get() = navController
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
navController = Navigation.findNavController(container!!)
return inflater.inflate(R.layout.single_fragment_wrapper, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = SingleFragmentWrapperBinding.inflate(inflater, container, false)
AuthenticationFab.manageAuthenticationFab(
fab = fab,
fab = binding.fab,
fragment = this,
shouldHighlight = activity.getActivityViewModel().shouldHighlightAuthenticationButton,
authenticatedUser = activity.getActivityViewModel().authenticatedUser,
doesSupportAuth = liveDataFromNonNullValue(showAuthButton)
)
fab.setOnClickListener { activity.showAuthenticationScreen() }
binding.fab.setOnClickListener { activity.showAuthenticationScreen() }
if (savedInstanceState == null) {
childFragmentManager.beginTransaction()
.replace(R.id.container, createChildFragment())
.commit()
}
return binding.root
}
abstract fun createChildFragment(): Fragment

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -26,8 +26,8 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import io.timelimit.android.R
import io.timelimit.android.databinding.ActivityHomescreenBinding
import io.timelimit.android.databinding.ActivityHomescreenItemBinding
import kotlinx.android.synthetic.main.activity_homescreen.*
class HomescreenActivity: AppCompatActivity() {
companion object {
@ -35,11 +35,13 @@ class HomescreenActivity: AppCompatActivity() {
}
private val model: HomescreenModel by lazy { ViewModelProvider(this).get(HomescreenModel::class.java) }
private lateinit var binding: ActivityHomescreenBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_homescreen)
binding = ActivityHomescreenBinding.inflate(layoutInflater)
setContentView(binding.root)
model.handleLaunchIfNotYetExecuted(intent.getBooleanExtra(FORCE_SELECTION, false))
@ -80,14 +82,14 @@ class HomescreenActivity: AppCompatActivity() {
}
private fun initOptionList() {
maincard.visibility = View.VISIBLE
binding.maincard.visibility = View.VISIBLE
val options = HomescreenUtil.launcherOptions(this)
launcher_options.removeAllViews()
binding.launcherOptions.removeAllViews()
options.forEach { option ->
val view = ActivityHomescreenItemBinding.inflate(LayoutInflater.from(this), launcher_options, true)
val view = ActivityHomescreenItemBinding.inflate(LayoutInflater.from(this), binding.launcherOptions, true)
view.label = try {
packageManager.getApplicationLabel(
@ -119,18 +121,18 @@ class HomescreenActivity: AppCompatActivity() {
}
private fun hideOptionList() {
maincard.visibility = View.GONE
binding.maincard.visibility = View.GONE
launcher_options.removeAllViews()
binding.launcherOptions.removeAllViews()
}
private fun showProgress(progresss: Int) {
progress_card.visibility = View.VISIBLE
progress_bar.progress = progresss
binding.progressCard.visibility = View.VISIBLE
binding.progressBar.progress = progresss
}
private fun hideProgress() {
progress_card.visibility = View.GONE
binding.progressCard.visibility = View.GONE
}
override fun onResume() {

View file

@ -25,6 +25,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.MutableLiveData
import androidx.viewpager.widget.ViewPager
import io.timelimit.android.R
import io.timelimit.android.databinding.LockActivityBinding
import io.timelimit.android.extensions.showSafe
import io.timelimit.android.logic.BlockingReason
import io.timelimit.android.logic.DefaultAppLogic
@ -36,7 +37,6 @@ import io.timelimit.android.ui.main.ActivityViewModelHolder
import io.timelimit.android.ui.main.AuthenticationFab
import io.timelimit.android.ui.manage.child.primarydevice.UpdatePrimaryDeviceDialogFragment
import io.timelimit.android.ui.util.SyncStatusModel
import kotlinx.android.synthetic.main.lock_activity.*
class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
companion object {
@ -88,7 +88,8 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
val adapter = LockActivityAdapter(supportFragmentManager, this)
setContentView(R.layout.lock_activity)
val binding = LockActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
syncModel.statusText.observe(this) { supportActionBar?.subtitle = it }
@ -96,7 +97,7 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
model.init(blockedPackageName, blockedActivityName)
pager.adapter = adapter
binding.pager.adapter = adapter
model.content.observe(this) {
if (isResumed && it is LockscreenContent.Blocked.BlockedCategory && it.reason == BlockingReason.RequiresCurrentDevice && !model.didOpenSetCurrentDeviceScreen) {
@ -109,16 +110,16 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
}
AuthenticationFab.manageAuthenticationFab(
fab = fab,
fab = binding.fab,
shouldHighlight = activityModel.shouldHighlightAuthenticationButton,
authenticatedUser = activityModel.authenticatedUser,
activity = this,
doesSupportAuth = showAuth
)
fab.setOnClickListener { showAuthenticationScreen() }
binding.fab.setOnClickListener { showAuthenticationScreen() }
pager.addOnPageChangeListener(object: ViewPager.SimpleOnPageChangeListener() {
binding.pager.addOnPageChangeListener(object: ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
@ -126,7 +127,7 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
}
})
tabs.setupWithViewPager(pager)
binding.tabs.setupWithViewPager(binding.pager)
model.content.observe(this) {
val isTimeOver = it is LockscreenContent.Blocked.BlockedCategory && it.blockingHandling.activityBlockingReason == BlockingReason.TimeOver

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -23,25 +23,19 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import io.timelimit.android.R
import io.timelimit.android.data.model.ChildTask
import io.timelimit.android.databinding.RecyclerFragmentBinding
import io.timelimit.android.ui.manage.child.tasks.ConfirmTaskDialogFragment
import kotlinx.android.synthetic.main.recycler_fragment.*
class LockTaskFragment: Fragment() {
private val model: LockModel by activityViewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.recycler_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = RecyclerFragmentBinding.inflate(inflater, container, false)
val adapter = LockTaskAdapter()
recycler.layoutManager = LinearLayoutManager(requireContext())
recycler.adapter = adapter
binding.recycler.layoutManager = LinearLayoutManager(requireContext())
binding.recycler.adapter = adapter
model.blockedCategoryTasks.observe(viewLifecycleOwner) { tasks ->
adapter.content = listOf(LockTaskItem.Introduction) + tasks.map { LockTaskItem.Task(it) }
@ -55,5 +49,7 @@ class LockTaskFragment: Fragment() {
ConfirmTaskDialogFragment.newInstance(taskId = task.taskId, taskTitle = task.taskTitle, fromManageScreen = false).show(parentFragmentManager)
}
}
return binding.root
}
}

View file

@ -31,6 +31,7 @@ import io.timelimit.android.async.Threads
import io.timelimit.android.data.Database
import io.timelimit.android.data.model.HintsToShow
import io.timelimit.android.data.model.TimeLimitRule
import io.timelimit.android.databinding.FragmentCategoryAppsAndRulesBinding
import io.timelimit.android.logic.DefaultAppLogic
import io.timelimit.android.sync.actions.AddCategoryAppsAction
import io.timelimit.android.sync.actions.CreateTimeLimitRuleAction
@ -42,7 +43,6 @@ 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 io.timelimit.android.ui.manage.child.apps.assign.AssignAppCategoryDialogFragment
import kotlinx.android.synthetic.main.fragment_category_apps_and_rules.*
abstract class CategoryAppsAndRulesFragment: Fragment(), Handlers, EditTimeLimitRuleDialogFragmentListener {
private val adapter = AppAndRuleAdapter().also { it.handlers = this }
@ -53,16 +53,12 @@ abstract class CategoryAppsAndRulesFragment: Fragment(), Handlers, EditTimeLimit
abstract val categoryId: String
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_category_apps_and_rules, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentCategoryAppsAndRulesBinding.inflate(inflater, container, false)
model.init(userId = childId, categoryId = categoryId)
recycler.layoutManager = LinearLayoutManager(requireContext())
recycler.adapter = adapter
binding.recycler.layoutManager = LinearLayoutManager(requireContext())
binding.recycler.adapter = adapter
model.dateAndUsedTimes.observe(viewLifecycleOwner) { (date, usedTimes) ->
adapter.date = date
@ -91,7 +87,9 @@ abstract class CategoryAppsAndRulesFragment: Fragment(), Handlers, EditTimeLimit
database.config().setHintsShownSync(HintsToShow.TIME_LIMIT_RULE_INTRODUCTION)
}
}
}).attachToRecyclerView(recycler)
}).attachToRecyclerView(binding.recycler)
return binding.root
}
fun setListContent(items: List<AppAndRuleItem>) { adapter.items = items }

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -31,6 +31,7 @@ import io.timelimit.android.data.customtypes.ImmutableBitmask
import io.timelimit.android.data.model.Category
import io.timelimit.android.data.model.HintsToShow
import io.timelimit.android.data.model.withConfigCopiedToOtherDates
import io.timelimit.android.databinding.FragmentBlockedTimeAreasBinding
import io.timelimit.android.livedata.map
import io.timelimit.android.livedata.waitForNonNullValue
import io.timelimit.android.logic.DefaultAppLogic
@ -38,7 +39,6 @@ import io.timelimit.android.sync.actions.UpdateCategoryBlockedTimesAction
import io.timelimit.android.ui.main.ActivityViewModel
import io.timelimit.android.ui.main.getActivityViewModel
import io.timelimit.android.ui.mustread.MustReadFragment
import kotlinx.android.synthetic.main.fragment_blocked_time_areas.*
class BlockedTimeAreasFragment : Fragment(), CopyBlockedTimeAreasDialogFragmentListener {
companion object {
@ -59,6 +59,7 @@ class BlockedTimeAreasFragment : Fragment(), CopyBlockedTimeAreasDialogFragmentL
private val items = MutableLiveData<BlockedTimeItems>()
private val childId: String get() = requireArguments().getString(CHILD_ID)!!
private val categoryId: String get() = requireArguments().getString(CATEGORY_ID)!!
private lateinit var binding: FragmentBlockedTimeAreasBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -82,10 +83,6 @@ class BlockedTimeAreasFragment : Fragment(), CopyBlockedTimeAreasDialogFragmentL
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_blocked_time_areas, container, false)
}
fun updateBlockedTimes(oldMask: ImmutableBitmask, newMask: ImmutableBitmask) {
if (
auth.tryDispatchParentAction(
@ -96,7 +93,7 @@ class BlockedTimeAreasFragment : Fragment(), CopyBlockedTimeAreasDialogFragmentL
allowAsChild = true
)
) {
Snackbar.make(coordinator.parent as View, R.string.blocked_time_areas_snackbar_modified, Snackbar.LENGTH_SHORT)
Snackbar.make(binding.coordinator.parent as View, R.string.blocked_time_areas_snackbar_modified, Snackbar.LENGTH_SHORT)
.also {
if (auth.isParentAuthenticated()) {
it.setAction(R.string.generic_undo) {
@ -119,29 +116,29 @@ class BlockedTimeAreasFragment : Fragment(), CopyBlockedTimeAreasDialogFragmentL
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FragmentBlockedTimeAreasBinding.inflate(inflater, container, false)
btn_help.setOnClickListener {
binding.btnHelp.setOnClickListener {
BlockedTimeAreasHelpDialog().show(parentFragmentManager)
}
btn_copy_to_other_days.setOnClickListener {
binding.btnCopyToOtherDays.setOnClickListener {
if (auth.requestAuthenticationOrReturnTrue()) {
CopyBlockedTimeAreasDialogFragment.newInstance(this@BlockedTimeAreasFragment).show(parentFragmentManager)
}
}
BlockedTimeAreasLogic.init(
recycler = recycler,
daySpinner = spinner_day,
detailedModeCheckbox = detailed_mode,
recycler = binding.recycler,
daySpinner = binding.spinnerDay,
detailedModeCheckbox = binding.detailedMode,
checkAuthentication = {
if (auth.isParentAuthenticated()) {
BlockedTimeAreasLogic.Authentication.FullyAvailable
} else if (auth.isParentOrChildAuthenticated(childId = childId)) {
BlockedTimeAreasLogic.Authentication.OnlyAllowAddingLimits(
showHintHook = { Snackbar.make(coordinator.parent as View, R.string.blocked_time_areas_snackbar_child_hint, Snackbar.LENGTH_LONG).show() },
showHintHook = { Snackbar.make(binding.coordinator.parent as View, R.string.blocked_time_areas_snackbar_child_hint, Snackbar.LENGTH_LONG).show() },
showErrorHook = { auth.requestAuthentication() }
)
} else {
@ -154,5 +151,7 @@ class BlockedTimeAreasFragment : Fragment(), CopyBlockedTimeAreasDialogFragmentL
currentData = category.map { it?.blockedMinutesInWeek },
lifecycleOwner = this
)
return binding.root
}
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -28,7 +28,6 @@ import io.timelimit.android.livedata.map
import io.timelimit.android.ui.fragment.ChildFragmentWrapper
import io.timelimit.android.ui.main.FragmentWithCustomTitle
import io.timelimit.android.ui.manage.child.category.ManageChildCategoriesFragment
import kotlinx.android.synthetic.main.single_fragment_wrapper.*
class ManageChildFragment : ChildFragmentWrapper(), FragmentWithCustomTitle {
private val params: ManageChildFragmentArgs by lazy { ManageChildFragmentArgs.fromBundle(arguments!!) }
@ -46,7 +45,7 @@ class ManageChildFragment : ChildFragmentWrapper(), FragmentWithCustomTitle {
super.onViewCreated(view, savedInstanceState)
if (savedInstanceState == null && params.fromRedirect) {
Snackbar.make(coordinator, R.string.manage_child_redirected_toast, Snackbar.LENGTH_LONG).show()
Snackbar.make(binding.coordinator, R.string.manage_child_redirected_toast, Snackbar.LENGTH_LONG).show()
}
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -30,6 +30,7 @@ import io.timelimit.android.R
import io.timelimit.android.async.Threads
import io.timelimit.android.data.model.Category
import io.timelimit.android.data.model.HintsToShow
import io.timelimit.android.databinding.RecyclerFragmentBinding
import io.timelimit.android.extensions.safeNavigate
import io.timelimit.android.logic.AppLogic
import io.timelimit.android.logic.DefaultAppLogic
@ -42,7 +43,6 @@ import io.timelimit.android.ui.manage.child.ManageChildFragmentArgs
import io.timelimit.android.ui.manage.child.ManageChildFragmentDirections
import io.timelimit.android.ui.manage.child.category.create.CreateCategoryDialogFragment
import io.timelimit.android.ui.manage.child.category.specialmode.SetCategorySpecialModeFragment
import kotlinx.android.synthetic.main.recycler_fragment.*
class ManageChildCategoriesFragment : Fragment() {
companion object {
@ -55,9 +55,12 @@ class ManageChildCategoriesFragment : Fragment() {
private val auth: ActivityViewModel by lazy { getActivityViewModel(requireActivity()) }
private val logic: AppLogic by lazy { DefaultAppLogic.with(requireContext()) }
private val model: ManageChildCategoriesModel by viewModels()
private lateinit var binding: RecyclerFragmentBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.recycler_fragment, container, false)
binding = RecyclerFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -134,8 +137,8 @@ class ManageChildCategoriesFragment : Fragment() {
}
}
recycler.adapter = adapter
recycler.layoutManager = LinearLayoutManager(context)
binding.recycler.adapter = adapter
binding.recycler.layoutManager = LinearLayoutManager(context)
model.init(params.childId)
model.listContent.observe(viewLifecycleOwner, Observer { adapter.categories = it })
@ -199,6 +202,6 @@ class ManageChildCategoriesFragment : Fragment() {
database.config().setHintsShownSync(HintsToShow.CATEGORIES_INTRODUCTION)
}
}
}).attachToRecyclerView(recycler)
}).attachToRecyclerView(binding.recycler)
}
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -28,9 +28,9 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import io.timelimit.android.R
import io.timelimit.android.data.model.ChildTask
import io.timelimit.android.databinding.RecyclerFragmentBinding
import io.timelimit.android.sync.actions.UpdateChildTaskAction
import io.timelimit.android.ui.main.getActivityViewModel
import kotlinx.android.synthetic.main.recycler_fragment.*
class ManageChildTasksFragment: Fragment(), EditTaskDialogFragment.Listener {
companion object {
@ -54,16 +54,11 @@ class ManageChildTasksFragment: Fragment(), EditTaskDialogFragment.Listener {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.recycler_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = RecyclerFragmentBinding.inflate(inflater, container, false)
val adapter = ChildTaskAdapter()
recycler.layoutManager = LinearLayoutManager(requireContext())
recycler.adapter = adapter
binding.recycler.layoutManager = LinearLayoutManager(requireContext())
binding.recycler.adapter = adapter
model.listContent.observe(viewLifecycleOwner) { adapter.data = it }
model.isChildTheCurrentDeviceUser.observe(viewLifecycleOwner) {/* keep the value fresh */}
@ -100,7 +95,9 @@ class ManageChildTasksFragment: Fragment(), EditTaskDialogFragment.Listener {
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { model.hideIntro() }
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean = throw IllegalStateException()
}).attachToRecyclerView(recycler)
}).attachToRecyclerView(binding.recycler)
return binding.root
}
override fun onTaskRemoved(task: ChildTask) {

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -24,12 +24,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import io.timelimit.android.R
import io.timelimit.android.databinding.AnnoyActivityBinding
import io.timelimit.android.livedata.map
import io.timelimit.android.logic.DefaultAppLogic
import io.timelimit.android.ui.manage.device.manage.ManipulationWarningTypeLabel
import io.timelimit.android.ui.manage.device.manage.ManipulationWarnings
import io.timelimit.android.util.TimeTextUtil
import kotlinx.android.synthetic.main.annoy_activity.*
class AnnoyActivity : AppCompatActivity() {
companion object {
@ -53,7 +53,8 @@ class AnnoyActivity : AppCompatActivity() {
val model = ViewModelProviders.of(this).get(AnnoyModel::class.java)
val logic = DefaultAppLogic.with(this)
setContentView(R.layout.annoy_activity)
val binding = AnnoyActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (logic.platformIntegration.setLockTaskPackages(listOf(packageName))) {
@ -67,7 +68,7 @@ class AnnoyActivity : AppCompatActivity() {
shutdown()
}
annoy_timer.setText(
binding.annoyTimer.setText(
getString(R.string.annoy_timer, TimeTextUtil.seconds(it.toInt(), this@AnnoyActivity))
)
})
@ -86,10 +87,10 @@ class AnnoyActivity : AppCompatActivity() {
}
}.observe(this, Observer {
if (it.isNullOrEmpty()) {
annoy_reason.visibility = View.GONE
binding.annoyReason.visibility = View.GONE
} else {
annoy_reason.visibility = View.VISIBLE
annoy_reason.setText(it)
binding.annoyReason.visibility = View.VISIBLE
binding.annoyReason.setText(it)
}
})
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -21,16 +21,15 @@ import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import io.timelimit.android.R
import io.timelimit.android.async.Threads
import io.timelimit.android.data.model.UserType
import io.timelimit.android.databinding.ActivityUnlockAfterManipulationBinding
import io.timelimit.android.extensions.showSafe
import io.timelimit.android.logic.DefaultAppLogic
import io.timelimit.android.ui.backdoor.BackdoorDialogFragment
import io.timelimit.android.ui.login.NewLoginFragment
import io.timelimit.android.ui.main.ActivityViewModel
import io.timelimit.android.ui.main.ActivityViewModelHolder
import kotlinx.android.synthetic.main.activity_unlock_after_manipulation.*
class UnlockAfterManipulationActivity : AppCompatActivity(), ActivityViewModelHolder {
private val model: ActivityViewModel by lazy {
@ -42,7 +41,9 @@ class UnlockAfterManipulationActivity : AppCompatActivity(), ActivityViewModelHo
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_unlock_after_manipulation)
val binding = ActivityUnlockAfterManipulationBinding.inflate(layoutInflater)
setContentView(binding.root)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
startLockTask()
@ -74,8 +75,8 @@ class UnlockAfterManipulationActivity : AppCompatActivity(), ActivityViewModelHo
}
})
auth_btn.setOnClickListener { showAuthenticationScreen() }
use_backdoor.setOnClickListener { BackdoorDialogFragment().show(supportFragmentManager) }
binding.authBtn.setOnClickListener { showAuthenticationScreen() }
binding.useBackdoor.setOnClickListener { BackdoorDialogFragment().show(supportFragmentManager) }
}
override fun showAuthenticationScreen() {

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -23,10 +23,10 @@ import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.timelimit.android.R
import io.timelimit.android.async.Threads
import io.timelimit.android.coroutines.CoroutineFragment
import io.timelimit.android.data.model.*
import io.timelimit.android.databinding.FragmentOverviewBinding
import io.timelimit.android.livedata.waitForNonNullValue
import io.timelimit.android.logic.AppLogic
import io.timelimit.android.logic.DefaultAppLogic
@ -34,7 +34,6 @@ import io.timelimit.android.sync.actions.ReviewChildTaskAction
import io.timelimit.android.ui.main.ActivityViewModel
import io.timelimit.android.ui.main.getActivityViewModel
import io.timelimit.android.ui.payment.RequiresPurchaseDialogFragment
import kotlinx.android.synthetic.main.fragment_overview.*
import kotlinx.coroutines.launch
class OverviewFragment : CoroutineFragment() {
@ -44,16 +43,11 @@ class OverviewFragment : CoroutineFragment() {
private val model: OverviewFragmentModel by viewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_overview, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentOverviewBinding.inflate(inflater, container, false)
val adapter = OverviewFragmentAdapter()
recycler.adapter = adapter
recycler.layoutManager = LinearLayoutManager(requireContext())
binding.recycler.adapter = adapter
binding.recycler.layoutManager = LinearLayoutManager(requireContext())
adapter.handlers = object: OverviewFragmentHandlers {
override fun onAddUserClicked() {
@ -155,7 +149,9 @@ class OverviewFragment : CoroutineFragment() {
}
}
}
).attachToRecyclerView(recycler)
).attachToRecyclerView(binding.recycler)
return binding.root
}
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -16,7 +16,7 @@
package io.timelimit.android.ui.overview.overview
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@Parcelize
data class OverviewItemVisibility(

View file

@ -34,7 +34,6 @@ import io.timelimit.android.ui.main.ActivityViewModel
import io.timelimit.android.ui.main.ActivityViewModelHolder
import io.timelimit.android.ui.main.AuthenticationFab
import io.timelimit.android.ui.main.FragmentWithCustomTitle
import kotlinx.android.synthetic.main.single_fragment_wrapper.*
class UninstallFragment : Fragment(), FragmentWithCustomTitle {
companion object {
@ -79,21 +78,17 @@ class UninstallFragment : Fragment(), FragmentWithCustomTitle {
if (it == null) { navigation.popBackStack() }
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
AuthenticationFab.manageAuthenticationFab(
fab = fab,
fab = binding.fab,
fragment = this,
shouldHighlight = activity.getActivityViewModel().shouldHighlightAuthenticationButton,
authenticatedUser = activity.getActivityViewModel().authenticatedUser,
doesSupportAuth = liveDataFromNonNullValue(!BuildConfig.storeCompilant)
)
fab.setOnClickListener { activity.showAuthenticationScreen() }
binding.fab.setOnClickListener { activity.showAuthenticationScreen() }
return binding.root
}
override fun onSaveInstanceState(outState: Bundle) {

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -22,16 +22,12 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import io.timelimit.android.R
import io.timelimit.android.databinding.ParentModeFragmentBinding
import io.timelimit.android.ui.overview.about.AboutFragment
import kotlinx.android.synthetic.main.parent_mode_fragment.*
class ParentModeFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.parent_mode_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding = ParentModeFragmentBinding.inflate(inflater, container, false)
if (savedInstanceState == null) {
childFragmentManager.beginTransaction()
@ -39,7 +35,7 @@ class ParentModeFragment : Fragment() {
.commitNow()
}
bottom_navigation_view.setOnNavigationItemSelectedListener { menuItem ->
binding.bottomNavigationView.setOnNavigationItemSelectedListener { menuItem ->
if (childFragmentManager.isStateSaved) {
false
} else {
@ -56,5 +52,7 @@ class ParentModeFragment : Fragment() {
true
}
}
return binding.root
}
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -38,7 +38,6 @@ import io.timelimit.android.logic.DefaultAppLogic
import io.timelimit.android.ui.mustread.MustReadFragment
import io.timelimit.android.ui.update.UpdateConsentCard
import io.timelimit.android.update.UpdateUtil
import kotlinx.android.synthetic.main.fragment_setup_local_mode.*
class SetupLocalModeFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -69,7 +68,7 @@ class SetupLocalModeFragment : Fragment() {
binding.nextBtn.setOnClickListener {
model.trySetupWithPassword(
set_password_view.readPassword(),
binding.setPasswordView.readPassword(),
SetupNetworkTimeVerification.readSelection(binding.networkTimeVerification),
enableUpdateChecks = binding.update.enableSwitch.isChecked
)

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2021 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
@ -34,7 +34,6 @@ import io.timelimit.android.extensions.safeNavigate
import io.timelimit.android.logic.DefaultAppLogic
import io.timelimit.android.ui.setup.parentmode.SetupParentmodeDialogFragment
import io.timelimit.android.ui.setup.privacy.PrivacyInfoDialogFragment
import kotlinx.android.synthetic.main.fragment_setup_select_mode.*
class SetupSelectModeFragment : Fragment() {
companion object {
@ -44,9 +43,10 @@ class SetupSelectModeFragment : Fragment() {
}
private lateinit var navigation: NavController
private lateinit var binding: FragmentSetupSelectModeBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = FragmentSetupSelectModeBinding.inflate(inflater, container, false)
binding = FragmentSetupSelectModeBinding.inflate(inflater, container, false)
return binding.root
}
@ -56,43 +56,43 @@ class SetupSelectModeFragment : Fragment() {
navigation = Navigation.findNavController(view)
btn_local_mode.setOnClickListener {
binding.btnLocalMode.setOnClickListener {
navigation.safeNavigate(
SetupSelectModeFragmentDirections.actionSetupSelectModeFragmentToSetupDevicePermissionsFragment(),
R.id.setupSelectModeFragment
)
}
btn_parent_mode.setOnClickListener {
binding.btnParentMode.setOnClickListener {
PrivacyInfoDialogFragment().apply {
setTargetFragment(this@SetupSelectModeFragment, REQ_SETUP_CONNECTED_PARENT)
}.show(fragmentManager!!)
}.show(parentFragmentManager)
}
btn_network_child_mode.setOnClickListener {
binding.btnNetworkChildMode.setOnClickListener {
PrivacyInfoDialogFragment().apply {
setTargetFragment(this@SetupSelectModeFragment, REQ_SETUP_CONNECTED_CHILD)
}.show(fragmentManager!!)
}.show(parentFragmentManager)
}
btn_parent_key_mode.setOnClickListener {
binding.btnParentKeyMode.setOnClickListener {
SetupParentmodeDialogFragment().apply {
setTargetFragment(this@SetupSelectModeFragment, REQUEST_SETUP_PARENT_MODE)
}.show(parentFragmentManager)
}
btn_uninstall.setOnClickListener {
DefaultAppLogic.with(context!!).platformIntegration.disableDeviceAdmin()
binding.btnUninstall.setOnClickListener {
DefaultAppLogic.with(requireContext()).platformIntegration.disableDeviceAdmin()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
startActivity(
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${context!!.packageName}"))
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${requireContext().packageName}"))
.addCategory(Intent.CATEGORY_DEFAULT)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
} else {
startActivity(
Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.parse("package:${context!!.packageName}"))
Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.parse("package:${requireContext().packageName}"))
)
}
}