217 lines
7.7 KiB
Kotlin
217 lines
7.7 KiB
Kotlin
/*
|
|
* Copyright (c) 2022 Proton AG
|
|
*
|
|
* This file is part of Proton Mail.
|
|
*
|
|
* Proton Mail 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, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Proton Mail 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 Proton Mail. If not, see https://www.gnu.org/licenses/.
|
|
*/
|
|
package ch.protonmail.android.activities.settings
|
|
|
|
import android.app.Activity
|
|
import android.content.Intent
|
|
import android.media.RingtoneManager
|
|
import android.net.Uri
|
|
import android.os.Bundle
|
|
import android.view.MenuItem
|
|
import android.view.View
|
|
import android.widget.RadioButton
|
|
import androidx.annotation.LayoutRes
|
|
import androidx.core.view.isVisible
|
|
import androidx.lifecycle.ViewModelProviders
|
|
import ch.protonmail.android.R
|
|
import ch.protonmail.android.activities.BaseActivity
|
|
import ch.protonmail.android.core.ProtonMailApplication
|
|
import ch.protonmail.android.utils.extensions.showToast
|
|
import dagger.hilt.android.AndroidEntryPoint
|
|
import kotlinx.android.synthetic.main.activity_notification_settings.*
|
|
import studio.forface.viewstatestore.ViewStateActivity
|
|
import javax.inject.Inject
|
|
|
|
// region constants
|
|
private const val EXTRA_CURRENT_ACTION = "extra.current.action"
|
|
private const val REQUEST_CODE_PICK_RINGTONE = 5
|
|
// endregion
|
|
|
|
/**
|
|
* An `Activity` for set Notification related Settings.
|
|
* Inherit from [BaseActivity]
|
|
* Implements [ViewStateActivity] for bind `ViewStateStore`s implicitly to the Lifecycle
|
|
*/
|
|
@AndroidEntryPoint
|
|
internal class NotificationSettingsActivity : BaseActivity(), ViewStateActivity {
|
|
|
|
/** @return an instance of [getApplicationContext] casted as [ProtonMailApplication] */
|
|
private val app get() = applicationContext as ProtonMailApplication
|
|
|
|
/** TODO: doc */
|
|
private var currentAction = 0
|
|
|
|
/** An [Array] of [String] for the available options for notifications */
|
|
private val notificationOptions by lazy {
|
|
resources.getStringArray(R.array.notification_options)
|
|
}
|
|
|
|
/** [NotificationSettingsViewModel.Factory] for [NotificationSettingsViewModel] */
|
|
@Inject
|
|
lateinit var viewModelFactory: NotificationSettingsViewModel.Factory
|
|
|
|
/** A Lazy instance of [NotificationSettingsViewModel] */
|
|
private val viewModel by lazy {
|
|
ViewModelProviders.of(this, viewModelFactory)
|
|
.get(NotificationSettingsViewModel::class.java)
|
|
}
|
|
|
|
/** @return [LayoutRes] for the content View */
|
|
override fun getLayoutId() = R.layout.activity_notification_settings
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
val actionBar = supportActionBar
|
|
actionBar?.setDisplayHomeAsUpEnabled(true)
|
|
|
|
currentAction = intent.getIntExtra(EXTRA_CURRENT_ACTION, 0)
|
|
createOptions()
|
|
|
|
ringtone_settings.setOnClickListener { onRingtoneChooserClicked() }
|
|
|
|
viewModel.ringtoneSettings.observe {
|
|
doOnData(::onRingtoneSettings)
|
|
doOnError { showToast(it) }
|
|
doOnLoadingChange { /* TODO: show progress */ }
|
|
}
|
|
}
|
|
|
|
/** Register to EventBus */
|
|
override fun onStart() {
|
|
super.onStart()
|
|
app.bus.register(this)
|
|
}
|
|
|
|
/** Unregister from EventBus */
|
|
override fun onStop() {
|
|
app.bus.unregister(this)
|
|
super.onStop()
|
|
}
|
|
|
|
/** Handle OptionsMenu selection */
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
// Override of back soft button for save current progress
|
|
if (item.itemId == android.R.id.home) {
|
|
saveAndFinish()
|
|
return true
|
|
}
|
|
return super.onOptionsItemSelected(item)
|
|
}
|
|
|
|
/** Override of [onBackPressed] for save current progress */
|
|
override fun onBackPressed() {
|
|
saveAndFinish()
|
|
}
|
|
|
|
/** Handle ringtone picking event */
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
if (requestCode == REQUEST_CODE_PICK_RINGTONE) {
|
|
val uri = data!!.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)!!
|
|
viewModel.setRingtone(uri)
|
|
}
|
|
} else super.onActivityResult(requestCode, resultCode, data)
|
|
}
|
|
|
|
private fun createOptions() {
|
|
// Create a map associating a generated view Id to notificationOptions
|
|
val idOptionsMap = notificationOptions.associateBy { View.generateViewId() }
|
|
|
|
// Create a list on RadioButton's with dividers
|
|
idOptionsMap.map { (id, option) ->
|
|
|
|
// Create a RadioButton
|
|
val button = layoutInflater.inflate(
|
|
R.layout.radio_button_list_item,
|
|
notification_radio_group,
|
|
false
|
|
) as RadioButton
|
|
|
|
// Create a divider
|
|
val divider = layoutInflater.inflate(
|
|
R.layout.horizontal_divider, notification_radio_group, false
|
|
)
|
|
|
|
// Setup the RadioButton
|
|
button.apply {
|
|
this.id = id
|
|
text = option
|
|
isChecked = option == notificationOptions[currentAction]
|
|
}
|
|
|
|
// Return button and divider
|
|
return@map button to divider
|
|
|
|
}.forEach { (button, divider) ->
|
|
|
|
// Add button and divider to the RadioGroup
|
|
notification_radio_group.apply {
|
|
addView(button)
|
|
addView(divider)
|
|
}
|
|
}
|
|
|
|
notification_radio_group.setOnCheckedChangeListener { _, checkedId ->
|
|
currentAction = notificationOptions.indexOf(idOptionsMap[checkedId])
|
|
toggleRingtoneContainerVisibility()
|
|
|
|
val user = mUserManager.requireCurrentLegacyUser()
|
|
val notificationSettingsChanged = currentAction != user.notificationSetting
|
|
if (notificationSettingsChanged) {
|
|
user.notificationSetting = currentAction
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Called when user requests to select a new ringtone for the Notification */
|
|
private fun onRingtoneChooserClicked() {
|
|
val currentRingtone = viewModel.currentRingtoneUri
|
|
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
|
|
.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
|
|
.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.select_tone))
|
|
.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentRingtone)
|
|
|
|
// Open ringtone picker or show Toast
|
|
intent.resolveActivity(packageManager)?.let {
|
|
startActivityForResult(intent, REQUEST_CODE_PICK_RINGTONE)
|
|
} ?: showToast(R.string.no_application_found)
|
|
}
|
|
|
|
/** When [RingtoneSettingsUiModel] is received from [NotificationSettingsViewModel] */
|
|
private fun onRingtoneSettings(settings: RingtoneSettingsUiModel) {
|
|
toggleRingtoneContainerVisibility(settings.userOption)
|
|
ringtone_title.text = settings.name
|
|
}
|
|
|
|
private fun saveAndFinish() {
|
|
setResult(Activity.RESULT_OK)
|
|
finish()
|
|
}
|
|
|
|
/**
|
|
* Toggle the visibility of [ringtone_container] whether the passed [Int]
|
|
* @param someUnknownInt [Int] which entity is not clearly declared/
|
|
* Default is [currentAction]
|
|
*/
|
|
private fun toggleRingtoneContainerVisibility(someUnknownInt: Int = currentAction) {
|
|
ringtone_container.isVisible = someUnknownInt == 1 || someUnknownInt == 3
|
|
}
|
|
}
|