1
0
Fork 0
fenix/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsComponent.kt

171 lines
6.8 KiB
Kotlin

/* This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings.quicksettings
import android.content.Context
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.reactivex.Observable
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.support.ktx.kotlin.toUri
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.mvi.Action
import org.mozilla.fenix.mvi.ActionBusFactory
import org.mozilla.fenix.mvi.Change
import org.mozilla.fenix.mvi.UIComponent
import org.mozilla.fenix.mvi.UIComponentViewModel
import org.mozilla.fenix.mvi.UIView
import org.mozilla.fenix.mvi.ViewState
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.toStatus
import org.mozilla.fenix.settings.toggle
import org.mozilla.fenix.utils.Settings
class QuickSettingsComponent(
private val container: ViewGroup,
owner: Fragment,
bus: ActionBusFactory,
override var initialState: QuickSettingsState
) : UIComponent<QuickSettingsState, QuickSettingsAction, QuickSettingsChange>(
owner,
bus.getManagedEmitter(QuickSettingsAction::class.java),
bus.getSafeManagedObservable(QuickSettingsChange::class.java)
) {
override fun initView(): UIView<QuickSettingsState, QuickSettingsAction, QuickSettingsChange> {
return QuickSettingsUIView(container, actionEmitter, changesObservable, container)
}
override fun render(): Observable<QuickSettingsState> =
ViewModelProvider(owner, QuickSettingsViewModel.Factory(initialState, changesObservable)).get(
QuickSettingsViewModel::class.java
).render(uiView)
init {
render()
}
fun toggleSitePermission(
context: Context,
featurePhone: PhoneFeature,
url: String,
sitePermissions: SitePermissions?
): SitePermissions {
return if (sitePermissions == null) {
val settings = Settings.getInstance(context)
val origin = requireNotNull(url.toUri().host)
var location = settings.getSitePermissionsPhoneFeatureLocation().toStatus()
var camera = settings.getSitePermissionsPhoneFeatureCameraAction().toStatus()
var microphone = settings.getSitePermissionsPhoneFeatureMicrophoneAction().toStatus()
var notification = settings.getSitePermissionsPhoneFeatureNotificationAction().toStatus()
when (featurePhone) {
PhoneFeature.CAMERA -> camera = camera.toggle()
PhoneFeature.LOCATION -> location = location.toggle()
PhoneFeature.MICROPHONE -> microphone = microphone.toggle()
PhoneFeature.NOTIFICATION -> notification = notification.toggle()
}
context.components.storage.addSitePermissionException(origin, location, notification, microphone, camera)
} else {
val updatedSitePermissions = sitePermissions.toggle(featurePhone)
context.components.storage.updateSitePermissions(updatedSitePermissions)
updatedSitePermissions
}
}
}
data class QuickSettingsState(val mode: Mode) : ViewState {
sealed class Mode {
data class Normal(
val url: String,
val isSecured: Boolean,
val isTrackingProtectionOn: Boolean,
val sitePermissions: SitePermissions?
) : Mode()
data class ActionLabelUpdated(
val phoneFeature: PhoneFeature,
val sitePermissions: SitePermissions?
) :
Mode()
data class CheckPendingFeatureBlockedByAndroid(val sitePermissions: SitePermissions?) :
Mode()
}
}
sealed class QuickSettingsAction : Action {
data class SelectReportProblem(val url: String) : QuickSettingsAction()
data class ToggleTrackingProtection(val trackingProtection: Boolean) : QuickSettingsAction()
data class SelectBlockedByAndroid(val permissions: Array<String>) : QuickSettingsAction()
data class TogglePermission(val featurePhone: PhoneFeature) : QuickSettingsAction()
}
sealed class QuickSettingsChange : Change {
data class Change(
val url: String,
val isSecured: Boolean,
val isTrackingProtectionOn: Boolean,
val sitePermissions: SitePermissions?
) : QuickSettingsChange()
data class PermissionGranted(val phoneFeature: PhoneFeature, val sitePermissions: SitePermissions?) :
QuickSettingsChange()
data class PromptRestarted(val sitePermissions: SitePermissions?) : QuickSettingsChange()
data class Stored(val phoneFeature: PhoneFeature, val sitePermissions: SitePermissions?) : QuickSettingsChange()
}
class QuickSettingsViewModel(initialState: QuickSettingsState, changesObservable: Observable<QuickSettingsChange>) :
UIComponentViewModel<QuickSettingsState, QuickSettingsAction, QuickSettingsChange>(
initialState,
changesObservable,
reducer
) {
class Factory(
private val initialState: QuickSettingsState,
private val changesObservable: Observable<QuickSettingsChange>
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T =
QuickSettingsViewModel(initialState, changesObservable) as T
}
companion object {
val reducer: (QuickSettingsState, QuickSettingsChange) -> QuickSettingsState = { state, change ->
when (change) {
is QuickSettingsChange.Change -> {
state.copy(
mode = QuickSettingsState.Mode.Normal(
change.url,
change.isSecured,
change.isTrackingProtectionOn,
change.sitePermissions
)
)
}
is QuickSettingsChange.PermissionGranted -> {
state.copy(
mode = QuickSettingsState.Mode.ActionLabelUpdated(change.phoneFeature, change.sitePermissions)
)
}
is QuickSettingsChange.PromptRestarted -> {
state.copy(
mode = QuickSettingsState.Mode.CheckPendingFeatureBlockedByAndroid(change.sitePermissions)
)
}
is QuickSettingsChange.Stored -> {
state.copy(
mode = QuickSettingsState.Mode.ActionLabelUpdated(change.phoneFeature, change.sitePermissions)
)
}
}
}
}
}