mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 01:39:22 +02:00
Move lock screen fragment within pager
This commit is contained in:
parent
73f1a22ab4
commit
7f207d0c08
6 changed files with 151 additions and 134 deletions
|
@ -23,15 +23,18 @@ import android.os.Bundle
|
|||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import io.timelimit.android.R
|
||||
import io.timelimit.android.extensions.showSafe
|
||||
import io.timelimit.android.logic.BlockingReason
|
||||
import io.timelimit.android.logic.DefaultAppLogic
|
||||
import io.timelimit.android.sync.network.UpdatePrimaryDeviceRequestType
|
||||
import io.timelimit.android.ui.IsAppInForeground
|
||||
import io.timelimit.android.ui.login.NewLoginFragment
|
||||
import io.timelimit.android.ui.main.ActivityViewModel
|
||||
import io.timelimit.android.ui.main.ActivityViewModelHolder
|
||||
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 {
|
||||
|
@ -58,6 +61,9 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
|
|||
}
|
||||
|
||||
private val model: LockModel by viewModels()
|
||||
private val syncModel: SyncStatusModel by viewModels()
|
||||
private val activityModel: ActivityViewModel by viewModels()
|
||||
private var isResumed = false
|
||||
|
||||
override var ignoreStop: Boolean = false
|
||||
|
||||
|
@ -74,27 +80,30 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.lock_activity)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, LockFragment.newInstance(blockedPackageName, blockedActivityName))
|
||||
.commitNow()
|
||||
}
|
||||
setContentView(R.layout.lock_activity)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
stopMediaPlayback()
|
||||
}
|
||||
|
||||
val syncModel = ViewModelProviders.of(this).get(SyncStatusModel::class.java)
|
||||
|
||||
syncModel.statusText.observe(this, Observer {
|
||||
supportActionBar?.subtitle = it
|
||||
})
|
||||
syncModel.statusText.observe(this) { supportActionBar?.subtitle = it }
|
||||
|
||||
currentInstances.add(this)
|
||||
|
||||
model.init(blockedPackageName, blockedActivityName)
|
||||
|
||||
pager.adapter = LockActivityAdapter(supportFragmentManager)
|
||||
|
||||
model.content.observe(this) {
|
||||
if (isResumed && it is LockscreenContent.Blocked.BlockedCategory && it.reason == BlockingReason.RequiresCurrentDevice && !model.didOpenSetCurrentDeviceScreen) {
|
||||
model.didOpenSetCurrentDeviceScreen = true
|
||||
|
||||
UpdatePrimaryDeviceDialogFragment
|
||||
.newInstance(UpdatePrimaryDeviceRequestType.SetThisDevice)
|
||||
.show(supportFragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -103,9 +112,7 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
|
|||
currentInstances.remove(this)
|
||||
}
|
||||
|
||||
override fun getActivityViewModel(): ActivityViewModel {
|
||||
return ViewModelProviders.of(this).get(ActivityViewModel::class.java)
|
||||
}
|
||||
override fun getActivityViewModel(): ActivityViewModel = activityModel
|
||||
|
||||
override fun showAuthenticationScreen() {
|
||||
NewLoginFragment().showSafe(supportFragmentManager, LOGIN_DIALOG_TAG)
|
||||
|
@ -115,12 +122,14 @@ class LockActivity : AppCompatActivity(), ActivityViewModelHolder {
|
|||
super.onResume()
|
||||
|
||||
lockTaskModeWorkaround()
|
||||
isResumed = true
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
lockTaskModeWorkaround()
|
||||
isResumed = false
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2020 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/>.
|
||||
*/
|
||||
|
||||
package io.timelimit.android.ui.lock
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentPagerAdapter
|
||||
|
||||
class LockActivityAdapter(fragmentManager: FragmentManager): FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||
override fun getCount(): Int = 1
|
||||
|
||||
override fun getItem(position: Int): Fragment = when (position) {
|
||||
0 -> LockReasonFragment()
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
}
|
|
@ -54,6 +54,8 @@ class LockModel(application: Application): AndroidViewModel(application) {
|
|||
|
||||
val title: String? get() = logic.platformIntegration.getLocalAppTitle(packageAndActivityNameLiveInternal.value!!.first)
|
||||
val icon: Drawable? get() = logic.platformIntegration.getAppIcon(packageAndActivityNameLiveInternal.value!!.first)
|
||||
val packageAndActivityNameLive: LiveData<Pair<String, String?>> = packageAndActivityNameLiveInternal
|
||||
var didOpenSetCurrentDeviceScreen = false
|
||||
|
||||
fun init(packageName: String, activityName: String?) {
|
||||
if (didInit) return
|
||||
|
@ -119,18 +121,21 @@ class LockModel(application: Application): AndroidViewModel(application) {
|
|||
val categoryHandlings = appBaseHandling.categoryIds.map { handlingCache.get(it) }
|
||||
val blockingHandling = categoryHandlings.find { it.shouldBlockActivities }
|
||||
|
||||
value = if (blockingHandling == null) LockscreenContent.Close else LockscreenContent.BlockedCategory(
|
||||
value = if (blockingHandling == null) LockscreenContent.Close else LockscreenContent.Blocked.BlockedCategory(
|
||||
deviceAndUserRelatedData = deviceAndUserRelatedData,
|
||||
blockingHandling = blockingHandling,
|
||||
level = appBaseHandling.level,
|
||||
userRelatedData = deviceAndUserRelatedData.userRelatedData,
|
||||
appBaseHandling = appBaseHandling
|
||||
appPackageName = packageName,
|
||||
appActivityName = activityName
|
||||
).also { scheduleUpdate((blockingHandling.dependsOnMaxTime - realTime.timeInMillis)) }
|
||||
} else if (appBaseHandling is AppBaseHandling.BlockDueToNoCategory) {
|
||||
value = LockscreenContent.BlockDueToNoCategory(
|
||||
value = LockscreenContent.Blocked.BlockDueToNoCategory(
|
||||
userRelatedData = deviceAndUserRelatedData.userRelatedData,
|
||||
deviceId = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.id,
|
||||
enableActivityLevelBlocking = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.enableActivityLevelBlocking
|
||||
enableActivityLevelBlocking = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.enableActivityLevelBlocking,
|
||||
appPackageName = packageName,
|
||||
appActivityName = activityName
|
||||
)
|
||||
} else {
|
||||
value = LockscreenContent.Close; return
|
||||
|
@ -201,27 +206,37 @@ class LockModel(application: Application): AndroidViewModel(application) {
|
|||
sealed class LockscreenContent {
|
||||
object Close: LockscreenContent()
|
||||
|
||||
data class BlockedCategory(
|
||||
val deviceAndUserRelatedData: DeviceAndUserRelatedData,
|
||||
val blockingHandling: CategoryItselfHandling,
|
||||
val appBaseHandling: AppBaseHandling,
|
||||
val level: BlockingLevel,
|
||||
val userRelatedData: UserRelatedData
|
||||
): LockscreenContent() {
|
||||
val appCategoryTitle = blockingHandling.createdWithCategoryRelatedData.category.title
|
||||
val reason = blockingHandling.activityBlockingReason
|
||||
val deviceId = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.id
|
||||
val userId = userRelatedData.user.id
|
||||
val timeZone = userRelatedData.user.timeZone
|
||||
val blockedCategoryId = blockingHandling.createdWithCategoryRelatedData.category.id
|
||||
val deviceRelatedData = deviceAndUserRelatedData.deviceRelatedData
|
||||
val hasFullVersion = deviceRelatedData.isConnectedAndHasPremium || deviceRelatedData.isLocalMode
|
||||
val enableActivityLevelBlocking = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.enableActivityLevelBlocking
|
||||
}
|
||||
sealed class Blocked: LockscreenContent() {
|
||||
abstract val userRelatedData: UserRelatedData
|
||||
abstract val appPackageName: String
|
||||
abstract val appActivityName: String?
|
||||
abstract val enableActivityLevelBlocking: Boolean
|
||||
|
||||
data class BlockDueToNoCategory(
|
||||
val userRelatedData: UserRelatedData,
|
||||
val deviceId: String,
|
||||
val enableActivityLevelBlocking: Boolean
|
||||
): LockscreenContent()
|
||||
class BlockedCategory(
|
||||
val deviceAndUserRelatedData: DeviceAndUserRelatedData,
|
||||
val blockingHandling: CategoryItselfHandling,
|
||||
val level: BlockingLevel,
|
||||
override val userRelatedData: UserRelatedData,
|
||||
override val appPackageName: String,
|
||||
override val appActivityName: String?
|
||||
): Blocked() {
|
||||
val appCategoryTitle = blockingHandling.createdWithCategoryRelatedData.category.title
|
||||
val reason = blockingHandling.activityBlockingReason
|
||||
val deviceId = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.id
|
||||
val userId = userRelatedData.user.id
|
||||
val timeZone = userRelatedData.user.timeZone
|
||||
val blockedCategoryId = blockingHandling.createdWithCategoryRelatedData.category.id
|
||||
val deviceRelatedData = deviceAndUserRelatedData.deviceRelatedData
|
||||
val hasFullVersion = deviceRelatedData.isConnectedAndHasPremium || deviceRelatedData.isLocalMode
|
||||
override val enableActivityLevelBlocking = deviceAndUserRelatedData.deviceRelatedData.deviceEntry.enableActivityLevelBlocking
|
||||
}
|
||||
|
||||
class BlockDueToNoCategory(
|
||||
override val userRelatedData: UserRelatedData,
|
||||
val deviceId: String,
|
||||
override val enableActivityLevelBlocking: Boolean,
|
||||
override val appPackageName: String,
|
||||
override val appActivityName: String?
|
||||
): Blocked()
|
||||
}
|
||||
}
|
|
@ -30,8 +30,8 @@ import io.timelimit.android.data.extensions.sortedCategories
|
|||
import io.timelimit.android.data.model.*
|
||||
import io.timelimit.android.data.model.derived.DeviceRelatedData
|
||||
import io.timelimit.android.data.model.derived.UserRelatedData
|
||||
import io.timelimit.android.databinding.LockFragmentBinding
|
||||
import io.timelimit.android.databinding.LockFragmentCategoryButtonBinding
|
||||
import io.timelimit.android.databinding.LockReasonFragmentBinding
|
||||
import io.timelimit.android.date.DateInTimezone
|
||||
import io.timelimit.android.livedata.*
|
||||
import io.timelimit.android.logic.*
|
||||
|
@ -53,38 +53,13 @@ import io.timelimit.android.ui.payment.RequiresPurchaseDialogFragment
|
|||
import io.timelimit.android.ui.view.SelectTimeSpanViewListener
|
||||
import java.util.*
|
||||
|
||||
class LockFragment : Fragment() {
|
||||
class LockReasonFragment : Fragment() {
|
||||
companion object {
|
||||
private const val EXTRA_PACKAGE_NAME = "pkg"
|
||||
private const val EXTRA_ACTIVITY = "activitiy"
|
||||
private const val STATUS_DID_OPEN_SET_CURRENT_DEVICE_SCREEN = "didOpenSetCurrentDeviceScreen"
|
||||
private const val LOCATION_REQUEST_CODE = 1
|
||||
|
||||
fun newInstance(packageName: String, activity: String?): LockFragment {
|
||||
val result = LockFragment()
|
||||
val arguments = Bundle()
|
||||
|
||||
arguments.putString(EXTRA_PACKAGE_NAME, packageName)
|
||||
|
||||
if (activity != null) {
|
||||
arguments.putString(EXTRA_ACTIVITY, activity)
|
||||
}
|
||||
|
||||
result.arguments = arguments
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private var didOpenSetCurrentDeviceScreen = false
|
||||
private val packageName: String by lazy { requireArguments().getString(EXTRA_PACKAGE_NAME)!! }
|
||||
private val activityName: String? by lazy {
|
||||
if (requireArguments().containsKey(EXTRA_ACTIVITY))
|
||||
requireArguments().getString(EXTRA_ACTIVITY)
|
||||
else
|
||||
null
|
||||
}
|
||||
private val auth: ActivityViewModel by lazy { getActivityViewModel(requireActivity()) }
|
||||
private lateinit var binding: LockFragmentBinding
|
||||
private lateinit var binding: LockReasonFragmentBinding
|
||||
private val model: LockModel by activityViewModels()
|
||||
|
||||
private fun setupHandlers(deviceId: String, userRelatedData: UserRelatedData, blockedCategoryId: String?) {
|
||||
|
@ -140,23 +115,23 @@ class LockFragment : Fragment() {
|
|||
(activity as LockActivity).showAuthenticationScreen()
|
||||
}
|
||||
|
||||
override fun setThisDeviceAsCurrentDevice() = this@LockFragment.setThisDeviceAsCurrentDevice()
|
||||
override fun setThisDeviceAsCurrentDevice() = this@LockReasonFragment.setThisDeviceAsCurrentDevice()
|
||||
|
||||
override fun requestLocationPermission() {
|
||||
RequestWifiPermission.doRequest(this@LockFragment, LOCATION_REQUEST_CODE)
|
||||
RequestWifiPermission.doRequest(this@LockReasonFragment, LOCATION_REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setThisDeviceAsCurrentDevice() {
|
||||
didOpenSetCurrentDeviceScreen = true
|
||||
model.didOpenSetCurrentDeviceScreen = true
|
||||
|
||||
UpdatePrimaryDeviceDialogFragment
|
||||
.newInstance(UpdatePrimaryDeviceRequestType.SetThisDevice)
|
||||
.show(parentFragmentManager)
|
||||
}
|
||||
|
||||
private fun bindAddToCategoryOptions(userRelatedData: UserRelatedData) {
|
||||
private fun bindAddToCategoryOptions(userRelatedData: UserRelatedData, blockedPackageName: String) {
|
||||
binding.addToCategoryOptions.removeAllViews()
|
||||
|
||||
userRelatedData.sortedCategories().forEach { (_, category) ->
|
||||
|
@ -166,7 +141,7 @@ class LockFragment : Fragment() {
|
|||
auth.tryDispatchParentAction(
|
||||
AddCategoryAppsAction(
|
||||
categoryId = category.category.id,
|
||||
packageNames = listOf(packageName)
|
||||
packageNames = listOf(blockedPackageName)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -238,22 +213,8 @@ class LockFragment : Fragment() {
|
|||
model.missingNetworkIdPermission.observe(viewLifecycleOwner) { binding.missingNetworkIdPermission = it }
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
didOpenSetCurrentDeviceScreen = savedInstanceState.getBoolean(STATUS_DID_OPEN_SET_CURRENT_DEVICE_SCREEN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
outState.putBoolean(STATUS_DID_OPEN_SET_CURRENT_DEVICE_SCREEN, didOpenSetCurrentDeviceScreen)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
binding = LockFragmentBinding.inflate(layoutInflater, container, false)
|
||||
binding = LockReasonFragmentBinding.inflate(layoutInflater, container, false)
|
||||
|
||||
AuthenticationFab.manageAuthenticationFab(
|
||||
fab = binding.fab,
|
||||
|
@ -272,7 +233,7 @@ class LockFragment : Fragment() {
|
|||
)
|
||||
}
|
||||
|
||||
binding.packageName = packageName
|
||||
model.packageAndActivityNameLive.observe(viewLifecycleOwner) { binding.packageName = it.first }
|
||||
|
||||
binding.appTitle = model.title ?: "???"
|
||||
binding.appIcon.setImageDrawable(model.icon)
|
||||
|
@ -288,50 +249,51 @@ class LockFragment : Fragment() {
|
|||
|
||||
requireActivity().finish()
|
||||
}
|
||||
is LockscreenContent.BlockedCategory -> {
|
||||
binding.activityName = if (content.enableActivityLevelBlocking) activityName?.removePrefix(packageName) else null
|
||||
is LockscreenContent.Blocked -> {
|
||||
binding.activityName = if (content.enableActivityLevelBlocking) content.appActivityName?.removePrefix(content.appPackageName) else null
|
||||
|
||||
binding.appCategoryTitle = content.appCategoryTitle
|
||||
binding.reason = content.reason
|
||||
binding.blockedKindLabel = when (content.level) {
|
||||
BlockingLevel.Activity -> "Activity"
|
||||
BlockingLevel.App -> "App"
|
||||
}
|
||||
setupHandlers(
|
||||
deviceId = content.deviceId,
|
||||
blockedCategoryId = content.blockedCategoryId,
|
||||
userRelatedData = content.userRelatedData
|
||||
)
|
||||
bindExtraTimeView(
|
||||
deviceRelatedData = content.deviceRelatedData,
|
||||
categoryId = content.blockedCategoryId,
|
||||
timeZone = content.userRelatedData.timeZone
|
||||
)
|
||||
binding.manageDisableTimeLimits.handlers = ManageDisableTimelimitsViewHelper.createHandlers(
|
||||
childId = content.userId,
|
||||
childTimezone = content.timeZone,
|
||||
activity = requireActivity(),
|
||||
hasFullVersion = content.hasFullVersion
|
||||
)
|
||||
when (content) {
|
||||
is LockscreenContent.Blocked.BlockedCategory -> {
|
||||
binding.appCategoryTitle = content.appCategoryTitle
|
||||
binding.reason = content.reason
|
||||
binding.blockedKindLabel = when (content.level) {
|
||||
BlockingLevel.Activity -> "Activity"
|
||||
BlockingLevel.App -> "App"
|
||||
}
|
||||
setupHandlers(
|
||||
deviceId = content.deviceId,
|
||||
blockedCategoryId = content.blockedCategoryId,
|
||||
userRelatedData = content.userRelatedData
|
||||
)
|
||||
bindExtraTimeView(
|
||||
deviceRelatedData = content.deviceRelatedData,
|
||||
categoryId = content.blockedCategoryId,
|
||||
timeZone = content.userRelatedData.timeZone
|
||||
)
|
||||
binding.manageDisableTimeLimits.handlers = ManageDisableTimelimitsViewHelper.createHandlers(
|
||||
childId = content.userId,
|
||||
childTimezone = content.timeZone,
|
||||
activity = requireActivity(),
|
||||
hasFullVersion = content.hasFullVersion
|
||||
)
|
||||
}
|
||||
is LockscreenContent.Blocked.BlockDueToNoCategory -> {
|
||||
binding.appCategoryTitle = null
|
||||
binding.reason = BlockingReason.NotPartOfAnCategory
|
||||
binding.blockedKindLabel = "App"
|
||||
|
||||
if (content.reason == BlockingReason.RequiresCurrentDevice && !didOpenSetCurrentDeviceScreen && isResumed) {
|
||||
setThisDeviceAsCurrentDevice()
|
||||
} else null
|
||||
}
|
||||
is LockscreenContent.BlockDueToNoCategory -> {
|
||||
binding.activityName = if (content.enableActivityLevelBlocking) activityName?.removePrefix(packageName) else null
|
||||
setupHandlers(
|
||||
deviceId = content.deviceId,
|
||||
blockedCategoryId = null,
|
||||
userRelatedData = content.userRelatedData
|
||||
)
|
||||
|
||||
binding.appCategoryTitle = null
|
||||
binding.reason = BlockingReason.NotPartOfAnCategory
|
||||
binding.blockedKindLabel = "App"
|
||||
|
||||
setupHandlers(
|
||||
deviceId = content.deviceId,
|
||||
blockedCategoryId = null,
|
||||
userRelatedData = content.userRelatedData
|
||||
)
|
||||
|
||||
bindAddToCategoryOptions(content.userRelatedData)
|
||||
bindAddToCategoryOptions(
|
||||
userRelatedData = content.userRelatedData,
|
||||
blockedPackageName = content.appPackageName
|
||||
)
|
||||
}
|
||||
}.let {/* require handling all paths */}
|
||||
}
|
||||
}.let {/* require handling all paths */}
|
||||
}
|
|
@ -13,9 +13,10 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
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:id="@+id/container"
|
||||
android:id="@+id/pager"
|
||||
tools:context=".ui.lock.LockActivity" />
|
|
@ -16,7 +16,7 @@
|
|||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".ui.lock.LockFragment">
|
||||
tools:context=".ui.lock.LockReasonFragment">
|
||||
|
||||
<data>
|
||||
<variable
|
Loading…
Add table
Add a link
Reference in a new issue