Started ringtone picker

This commit is contained in:
Sylvain Berfini 2023-09-29 12:03:45 +02:00
parent bdca32be49
commit 2a1b2bf7ac
6 changed files with 101 additions and 22 deletions

View file

@ -121,7 +121,7 @@ class CorePreferences @UiThread constructor(private val context: Context) {
get() = context.filesDir.absolutePath + "/assistant_third_party_default_values"
@get:AnyThread
private val ringtonesPath: String
val ringtonesPath: String
get() = context.filesDir.absolutePath + "/share/sounds/linphone/rings/"
@get:AnyThread

View file

@ -4,21 +4,40 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.annotation.UiThread
import androidx.navigation.navGraphViewModels
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.SettingsFragmentBinding
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.settings.viewmodel.SettingsViewModel
@UiThread
class SettingsFragment : GenericFragment() {
companion object {
private const val TAG = "[Settings Fragment]"
}
private lateinit var binding: SettingsFragmentBinding
private val viewModel: SettingsViewModel by navGraphViewModels(
R.id.main_nav_graph
)
private val ringtoneListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val path = viewModel.availableRingtonesPaths[position]
val label = viewModel.availableRingtonesNames[position]
Log.i("$TAG Selected ringtone is now [$label] ($path)")
viewModel.setRingtone(path)
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -36,5 +55,24 @@ class SettingsFragment : GenericFragment() {
binding.setBackClickListener {
goBack()
}
// Ringtone related
val ringtonesAdapter = ArrayAdapter(
requireContext(),
R.layout.drop_down_item,
viewModel.availableRingtonesNames
)
ringtonesAdapter.setDropDownViewResource(R.layout.assistant_transport_dropdown_cell)
binding.deviceRingtoneSpinner.adapter = ringtonesAdapter
viewModel.selectedRingtone.observe(viewLifecycleOwner) { ringtone ->
binding.deviceRingtoneSpinner.setSelection(
viewModel.availableRingtonesPaths.indexOf(
ringtone
)
)
}
binding.deviceRingtoneSpinner.onItemSelectedListener = ringtoneListener
}
}

View file

@ -23,9 +23,13 @@ import android.os.Vibrator
import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import java.io.File
import java.util.Locale
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils
class SettingsViewModel @UiThread constructor() : ViewModel() {
companion object {
@ -42,7 +46,9 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
val videoEnabled = MutableLiveData<Boolean>()
val autoInitiateVideoCalls = MutableLiveData<Boolean>()
val autoAcceptVideoRequests = MutableLiveData<Boolean>()
val useDeviceRingtone = MutableLiveData<Boolean>()
val availableRingtonesPaths = arrayListOf<String>()
val availableRingtonesNames = arrayListOf<String>()
val selectedRingtone = MutableLiveData<String>()
val vibrateDuringIncomingCall = MutableLiveData<Boolean>()
val autoRecordCalls = MutableLiveData<Boolean>()
@ -64,17 +70,19 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
Log.w("$TAG Device doesn't seem to have a vibrator, hiding related setting")
}
computeAvailableRingtones()
coreContext.postOnCoreThread { core ->
echoCancellerEnabled.postValue(core.isEchoCancellationEnabled)
routeAudioToBluetooth.postValue(corePreferences.routeAudioToBluetoothIfAvailable)
videoEnabled.postValue(core.isVideoEnabled)
autoInitiateVideoCalls.postValue(core.videoActivationPolicy.automaticallyInitiate)
autoAcceptVideoRequests.postValue(core.videoActivationPolicy.automaticallyAccept)
useDeviceRingtone.postValue(core.ring == null)
vibrateDuringIncomingCall.postValue(core.isVibrationOnIncomingCallEnabled)
autoRecordCalls.postValue(corePreferences.automaticallyStartCallRecording)
useWifiOnly.postValue(core.isWifiOnlyEnabled)
selectedRingtone.postValue(core.ring.orEmpty())
}
}
@ -129,11 +137,9 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
}
@UiThread
fun toggleDeviceRingtone() {
val newValue = useDeviceRingtone.value == false
fun setRingtone(ringtone: String) {
coreContext.postOnCoreThread { core ->
core.ring = if (newValue) null else corePreferences.defaultRingtonePath
useDeviceRingtone.postValue(newValue)
core.ring = ringtone
}
}
@ -178,4 +184,25 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
fun toggleUserInterfaceExpand() {
expandUserInterface.value = expandUserInterface.value == false
}
@UiThread
private fun computeAvailableRingtones() {
availableRingtonesNames.add(
AppUtils.getString(R.string.settings_calls_use_device_ringtone_label)
)
availableRingtonesPaths.add("")
val directory = File(corePreferences.ringtonesPath)
val files = directory.listFiles()
for (ringtone in files.orEmpty()) {
if (ringtone.absolutePath.endsWith(".mkv")) {
val name = ringtone.name
.substringBefore(".")
.replace("_", " ")
.capitalize(Locale.getDefault())
availableRingtonesNames.add(name)
availableRingtonesPaths.add(ringtone.absolutePath)
}
}
}
}

View file

@ -279,6 +279,9 @@
android:layout_marginEnd="16dp"
android:layout_marginTop="24dp"
android:text="@string/help_troubleshooting_title"
android:drawableEnd="@drawable/caret_right"
android:drawablePadding="8dp"
app:drawableTint="@color/gray_main2_500"
app:layout_constraintTop_toBottomOf="@id/advanced_title"
app:layout_constraintStart_toEndOf="@id/debug_icon"
app:layout_constraintEnd_toEndOf="parent"/>

View file

@ -285,32 +285,42 @@
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
android:id="@+id/device_ringtone_title"
android:onClick="@{() -> viewModel.toggleDeviceRingtone()}"
android:visibility="@{viewModel.expandCalls ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/settings_calls_use_device_ringtone_title"
android:text="@string/settings_calls_ringtones_title"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/device_ringtone_switch"
app:layout_constraintBottom_toBottomOf="@id/device_ringtone_switch"
app:layout_constraintTop_toBottomOf="@id/auto_accept_video_switch"
app:layout_constraintStart_toStartOf="@id/calls_background"
app:layout_constraintEnd_toStartOf="@id/device_ringtone_switch"/>
app:layout_constraintEnd_toEndOf="@id/calls_background"/>
<com.google.android.material.materialswitch.MaterialSwitch
<androidx.appcompat.widget.AppCompatSpinner
style="@style/material_switch_style"
android:id="@+id/device_ringtone_switch"
android:onClick="@{() -> viewModel.toggleDeviceRingtone()}"
android:id="@+id/device_ringtone_spinner"
android:visibility="@{viewModel.expandCalls ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@drawable/edit_text_background"
android:paddingStart="20dp"
android:paddingEnd="20dp"
app:layout_constraintTop_toBottomOf="@id/device_ringtone_title"
app:layout_constraintStart_toStartOf="@id/device_ringtone_title"
app:layout_constraintEnd_toEndOf="@id/device_ringtone_title" />
<ImageView
android:id="@+id/device_ringtone_spinner_caret"
android:visibility="@{viewModel.expandCalls ? View.VISIBLE : View.GONE}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.useDeviceRingtone}"
app:layout_constraintEnd_toEndOf="@id/calls_background"
app:layout_constraintTop_toBottomOf="@id/auto_accept_video_switch" />
android:layout_marginEnd="20dp"
android:src="@drawable/caret_down"
app:layout_constraintTop_toTopOf="@id/device_ringtone_spinner"
app:layout_constraintBottom_toBottomOf="@id/device_ringtone_spinner"
app:layout_constraintEnd_toEndOf="@id/device_ringtone_spinner"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
@ -340,7 +350,7 @@
android:layout_marginEnd="16dp"
android:checked="@{viewModel.vibrateDuringIncomingCall}"
app:layout_constraintEnd_toEndOf="@id/calls_background"
app:layout_constraintTop_toBottomOf="@id/device_ringtone_switch" />
app:layout_constraintTop_toBottomOf="@id/device_ringtone_spinner" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"

View file

@ -185,7 +185,8 @@
<string name="settings_calls_auto_initiate_video_subtitle">Always initiate calls as video</string>
<string name="settings_calls_auto_accept_video_title">Accept video calls</string>
<string name="settings_calls_auto_accept_video_subtitle">Always accept video calls</string>
<string name="settings_calls_use_device_ringtone_title">Use this device\'s ringtone</string>
<string name="settings_calls_ringtones_title">Choose your ringtone:</string>
<string name="settings_calls_use_device_ringtone_label">Use this device\'s ringtone</string>
<string name="settings_calls_vibrate_while_ringing_title">Vibrate while incoming call is ringing</string>
<string name="settings_calls_auto_record_title">Automatically start recording calls</string>
<string name="settings_network_title">Network</string>