Merge pull request #228 from vector-im/feature/settings_v2

Split settings into sub sections
This commit is contained in:
Benoit Marty 2019-06-27 11:54:03 +02:00 committed by GitHub
commit f092c40999
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 3634 additions and 3465 deletions

View File

@ -24,6 +24,7 @@ import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.R
import im.vector.riotredesign.features.home.AvatarRenderer

open class UserAvatarPreference : Preference {

@ -52,11 +53,15 @@ open class UserAvatarPreference : Preference {
}

open fun refreshAvatar() {
if (null != mAvatarView && null != mSession) {
// TODO
// val myUser = session!!.myUser
// VectorUtils.loadUserAvatar(context, session, mAvatarView, myUser.avatarUrl, myUser.user_id, myUser.displayname)
val session = mSession ?: return
val view = mAvatarView ?: return

session.getUser(session.sessionParams.credentials.userId)?.let {
AvatarRenderer.render(it, view)
} ?: run {
AvatarRenderer.render(null, session.sessionParams.credentials.userId, null, view)
}

}

fun setSession(session: Session) {

View File

@ -51,8 +51,6 @@ public class PreferencesManager {
public static final String SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY = "SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY";
public static final String SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY = "SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY";

//TODO delete
public static final String SETTINGS_NOTIFICATION_PRIVACY_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_PRIVACY_PREFERENCE_KEY";
public static final String SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY";
public static final String SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY";
public static final String SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY";

View File

@ -48,20 +48,15 @@ class VectorSettingsActivity : VectorBaseActivity(),
override fun initUiAndData() {
configureToolbar(settingsToolbar)

var vectorSettingsPreferencesFragment: Fragment? = null
if (isFirstCreation()) {
vectorSettingsPreferencesFragment = VectorSettingsPreferencesFragmentV2.newInstance()
val vectorSettingsPreferencesFragment = VectorSettingsRoot.newInstance()
// display the fragment
supportFragmentManager.beginTransaction()
.replace(R.id.vector_settings_page, vectorSettingsPreferencesFragment, FRAGMENT_TAG)
.commit()
} else {
vectorSettingsPreferencesFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG)
}


supportFragmentManager.addOnBackStackChangedListener(this)

}

override fun onDestroy() {
@ -78,9 +73,7 @@ class VectorSettingsActivity : VectorBaseActivity(),
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference?): Boolean {
var oFragment: Fragment? = null

if ("Legacy" == pref?.title) {
oFragment = VectorSettingsPreferencesFragment.newInstance(session.sessionParams.credentials.userId)
} else if (PreferencesManager.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref?.key) {
if (PreferencesManager.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref?.key) {
oFragment = VectorSettingsNotificationsTroubleshootFragment.newInstance(session.sessionParams.credentials.userId)
} else if (PreferencesManager.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref?.key) {
oFragment = VectorSettingsAdvancedNotificationPreferenceFragment.newInstance(session.sessionParams.credentials.userId)

View File

@ -0,0 +1,112 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.os.Bundle
import android.text.TextUtils
import android.view.View
import androidx.annotation.CallSuper
import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.R
import im.vector.riotredesign.core.platform.VectorPreferenceFragment
import im.vector.riotredesign.core.utils.toast
import org.koin.android.ext.android.inject

abstract class VectorSettingsBaseFragment : VectorPreferenceFragment() {

private var mLoadingView: View? = null


// members
protected val mSession by inject<Session>()

abstract val preferenceXmlRes: Int

@CallSuper
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(preferenceXmlRes)

bindPref()
}

override fun onResume() {
super.onResume()

// find the view from parent activity
mLoadingView = activity?.findViewById(R.id.vector_settings_spinner_views)
}

abstract fun bindPref()


/**
* Display the loading view.
*/
protected fun displayLoadingView() {
// search the loading view from the upper view
if (null == mLoadingView) {
var parent = view

while (parent != null && mLoadingView == null) {
mLoadingView = parent.findViewById(R.id.vector_settings_spinner_views)
parent = parent.parent as View
}
} else {
mLoadingView?.visibility = View.VISIBLE
}
}

/**
* Hide the loading view.
*/
protected fun hideLoadingView() {
mLoadingView?.visibility = View.GONE
}

/**
* Hide the loading view and refresh the preferences.
*
* @param refresh true to refresh the display
*/
protected fun hideLoadingView(refresh: Boolean) {
mLoadingView?.visibility = View.GONE

if (refresh) {
// TODO refreshDisplay()
}
}

/**
* A request has been processed.
* Display a toast if there is a an error message
*
* @param errorMessage the error message
*/
protected fun onCommonDone(errorMessage: String?) {
if (!isAdded) {
return
}
activity?.runOnUiThread {
if (!TextUtils.isEmpty(errorMessage) && errorMessage != null) {
activity?.toast(errorMessage!!)
}
hideLoadingView()
}
}


}

View File

@ -0,0 +1,171 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import androidx.preference.PreferenceCategory
import im.vector.riotredesign.R
import im.vector.riotredesign.core.preference.ProgressBarPreference

class VectorSettingsFlair : VectorSettingsBaseFragment() {

override var titleRes = R.string.settings_flair
override val preferenceXmlRes = R.xml.vector_settings_flair

// current publicised group list
private var mPublicisedGroups: MutableSet<String>? = null

// Group Flairs
private val mGroupsFlairCategory by lazy {
findPreference(PreferencesManager.SETTINGS_GROUPS_FLAIR_KEY) as PreferenceCategory
}

override fun bindPref() {
// Flair
refreshGroupFlairsList()
}

//==============================================================================================================
// Group flairs management
//==============================================================================================================

/**
* Force the refresh of the devices list.<br></br>
* The devices list is the list of the devices where the user as looged in.
* It can be any mobile device, as any browser.
*/
private fun refreshGroupFlairsList() {
// display a spinner while refreshing
if (0 == mGroupsFlairCategory.preferenceCount) {
activity?.let {
val preference = ProgressBarPreference(it)
mGroupsFlairCategory.addPreference(preference)
}
}

/*
TODO
session.groupsManager.getUserPublicisedGroups(session.myUserId, true, object : MatrixCallback<Set<String>> {
override fun onSuccess(publicisedGroups: Set<String>) {
// clear everything
mGroupsFlairCategory.removeAll()

if (publicisedGroups.isEmpty()) {
val vectorGroupPreference = Preference(activity)
vectorGroupPreference.title = resources.getString(R.string.settings_without_flair)
mGroupsFlairCategory.addPreference(vectorGroupPreference)
} else {
buildGroupsList(publicisedGroups)
}
}

override fun onNetworkError(e: Exception) {
// NOP
}

override fun onMatrixError(e: MatrixError) {
// NOP
}

override fun onUnexpectedError(e: Exception) {
// NOP
}
})
*/
}

/**
* Build the groups list.
*
* @param publicisedGroups the publicised groups list.
*/
private fun buildGroupsList(publicisedGroups: Set<String>) {
var isNewList = true

mPublicisedGroups?.let {
if (it.size == publicisedGroups.size) {
isNewList = !it.containsAll(publicisedGroups)
}
}

if (isNewList) {
/*
TODO
val joinedGroups = ArrayList(session.groupsManager.joinedGroups)
Collections.sort(joinedGroups, Group.mGroupsComparator)

mPublicisedGroups = publicisedGroups.toMutableSet()

for ((prefIndex, group) in joinedGroups.withIndex()) {
val vectorGroupPreference = VectorGroupPreference(activity!!)
vectorGroupPreference.key = DEVICES_PREFERENCE_KEY_BASE + prefIndex

vectorGroupPreference.setGroup(group, session)
vectorGroupPreference.title = group.displayName
vectorGroupPreference.summary = group.groupId

vectorGroupPreference.isChecked = publicisedGroups.contains(group.groupId)
mGroupsFlairCategory.addPreference(vectorGroupPreference)

vectorGroupPreference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
if (newValue is Boolean) {
/*
* if mPublicisedGroup is null somehow, then
* we cant check it contains groupId or not
* so set isFlaired to false
*/
val isFlaired = mPublicisedGroups?.contains(group.groupId) ?: false

if (newValue != isFlaired) {
displayLoadingView()
session.groupsManager.updateGroupPublicity(group.groupId, newValue, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
hideLoadingView()
if (newValue) {
mPublicisedGroups?.add(group.groupId)
} else {
mPublicisedGroups?.remove(group.groupId)
}
}

private fun onError() {
hideLoadingView()
// restore default value
vectorGroupPreference.isChecked = publicisedGroups.contains(group.groupId)
}

override fun onNetworkError(e: Exception) {
onError()
}

override fun onMatrixError(e: MatrixError) {
onError()
}

override fun onUnexpectedError(e: Exception) {
onError()
}
})
}
}
true
}
}
*/
}
}

}

View File

@ -0,0 +1,893 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.AsyncTask
import android.text.Editable
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.showPassword
import im.vector.riotredesign.core.platform.SimpleTextWatcher
import im.vector.riotredesign.core.preference.UserAvatarPreference
import im.vector.riotredesign.core.preference.VectorPreference
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
import im.vector.riotredesign.core.utils.allGranted
import im.vector.riotredesign.core.utils.copyToClipboard
import im.vector.riotredesign.core.utils.toast
import im.vector.riotredesign.features.MainActivity
import im.vector.riotredesign.features.themes.ThemeUtils
import java.lang.ref.WeakReference
import java.util.*

class VectorSettingsGeneral : VectorSettingsBaseFragment() {

override var titleRes = R.string.settings_general_title
override val preferenceXmlRes = R.xml.vector_settings_general

private var mDisplayedEmails = ArrayList<String>()
private var mDisplayedPhoneNumber = ArrayList<String>()

private val mUserSettingsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_USER_SETTINGS_PREFERENCE_KEY) as PreferenceCategory
}
private val mUserAvatarPreference by lazy {
findPreference(PreferencesManager.SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY) as UserAvatarPreference
}
private val mDisplayNamePreference by lazy {
findPreference(PreferencesManager.SETTINGS_DISPLAY_NAME_PREFERENCE_KEY) as EditTextPreference
}
private val mPasswordPreference by lazy {
findPreference(PreferencesManager.SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY)
}

// Local contacts
private val mContactSettingsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_CONTACT_PREFERENCE_KEYS) as PreferenceCategory
}

private val mContactPhonebookCountryPreference by lazy {
findPreference(PreferencesManager.SETTINGS_CONTACTS_PHONEBOOK_COUNTRY_PREFERENCE_KEY)
}


override fun bindPref() {
// Avatar
mUserAvatarPreference.let {
it.setSession(mSession)
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
onUpdateAvatarClick()
false
}
}

// Display name
mDisplayNamePreference.let {
it.summary = mSession.getUser(mSession.sessionParams.credentials.userId)?.displayName ?: ""
it.text = it.summary.toString()
it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
onDisplayNameClick(newValue?.let { (it as String).trim() })
false
}
}

// Password
mPasswordPreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
notImplemented()
// onPasswordUpdateClick()
false
}

// Add Email
(findPreference(ADD_EMAIL_PREFERENCE_KEY) as EditTextPreference).let {
// It does not work on XML, do it here
it.icon = activity?.let {
ThemeUtils.tintDrawable(it,
ContextCompat.getDrawable(it, R.drawable.ic_add_black)!!, R.attr.vctr_settings_icon_tint_color)
}

// Unfortunately, this is not supported in lib v7
// it.editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS

it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
notImplemented()
//addEmail((newValue as String).trim())
false
}
}

// Add phone number
findPreference(ADD_PHONE_NUMBER_PREFERENCE_KEY).let {
// It does not work on XML, do it here
it.icon = activity?.let {
ThemeUtils.tintDrawable(it,
ContextCompat.getDrawable(it, R.drawable.ic_add_black)!!, R.attr.vctr_settings_icon_tint_color)
}

it.setOnPreferenceClickListener {
notImplemented()
// TODO val intent = PhoneNumberAdditionActivity.getIntent(activity, session.credentials.userId)
// startActivityForResult(intent, REQUEST_NEW_PHONE_NUMBER)
true
}
}

// Advanced settings

// user account
findPreference(PreferencesManager.SETTINGS_LOGGED_IN_PREFERENCE_KEY)
.summary = mSession.sessionParams.credentials.userId

// home server
findPreference(PreferencesManager.SETTINGS_HOME_SERVER_PREFERENCE_KEY)
.summary = mSession.sessionParams.homeServerConnectionConfig.homeServerUri.toString()

// identity server
findPreference(PreferencesManager.SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY)
.summary = mSession.sessionParams.homeServerConnectionConfig.identityServerUri.toString()


refreshEmailsList()
refreshPhoneNumbersList()
// Contacts
setContactsPreferences()

// clear cache
findPreference(PreferencesManager.SETTINGS_CLEAR_CACHE_PREFERENCE_KEY).let {
/*
TODO
MXSession.getApplicationSizeCaches(activity, object : SimpleApiCallback<Long>() {
override fun onSuccess(size: Long) {
if (null != activity) {
it.summary = android.text.format.Formatter.formatFileSize(activity, size)
}
}
})
*/

it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
displayLoadingView()
MainActivity.restartApp(activity!!, clearCache = true, clearCredentials = false)
false
}
}

// clear medias cache
findPreference(PreferencesManager.SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY).let {
/*
TODO
MXMediaCache.getCachesSize(activity, object : SimpleApiCallback<Long>() {
override fun onSuccess(size: Long) {
if (null != activity) {
it.summary = android.text.format.Formatter.formatFileSize(activity, size)
}
}
})
*/

it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
notImplemented()
/* TODO
displayLoadingView()

val task = ClearMediaCacheAsyncTask(
backgroundTask = {
session.mediaCache.clear()
activity?.let { it -> Glide.get(it).clearDiskCache() }
},
onCompleteTask = {
hideLoadingView()

MXMediaCache.getCachesSize(activity, object : SimpleApiCallback<Long>() {
override fun onSuccess(size: Long) {
it.summary = Formatter.formatFileSize(activity, size)
}
})
}
)

try {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
} catch (e: Exception) {
Timber.e(e, "## session.getMediaCache().clear() failed " + e.message)
task.cancel(true)
hideLoadingView()
}
*/

false
}
}

// Deactivate account section

// deactivate account
findPreference(PreferencesManager.SETTINGS_DEACTIVATE_ACCOUNT_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.let {
notImplemented()
// TODO startActivity(DeactivateAccountActivity.getIntent(it))
}

false
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (allGranted(grantResults)) {
if (requestCode == PERMISSION_REQUEST_CODE_LAUNCH_CAMERA) {
changeAvatar()
}
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_NEW_PHONE_NUMBER -> refreshPhoneNumbersList()
REQUEST_PHONEBOOK_COUNTRY -> onPhonebookCountryUpdate(data)
/* TODO
VectorUtils.TAKE_IMAGE -> {
val thumbnailUri = VectorUtils.getThumbnailUriFromIntent(activity, data, session.mediaCache)

if (null != thumbnailUri) {
displayLoadingView()

val resource = ResourceUtils.openResource(activity, thumbnailUri, null)

if (null != resource) {
session.mediaCache.uploadContent(resource.mContentStream, null, resource.mMimeType, null, object : MXMediaUploadListener() {

override fun onUploadError(uploadId: String?, serverResponseCode: Int, serverErrorMessage: String?) {
activity?.runOnUiThread { onCommonDone(serverResponseCode.toString() + " : " + serverErrorMessage) }
}

override fun onUploadComplete(uploadId: String?, contentUri: String?) {
activity?.runOnUiThread {
session.myUser.updateAvatarUrl(contentUri, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
onCommonDone(null)
refreshDisplay()
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
if (MatrixError.M_CONSENT_NOT_GIVEN == e.errcode) {
activity?.runOnUiThread {
hideLoadingView()
(activity as VectorAppCompatActivity).consentNotGivenHelper.displayDialog(e)
}
} else {
onCommonDone(e.localizedMessage)
}
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
}
}
})
}
}
}
*/
}
}
}

/**
* Update the avatar.
*/
private fun onUpdateAvatarClick() {
notImplemented()

/* TODO
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this, PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
changeAvatar()
}
*/
}

private fun changeAvatar() {
/* TODO
val intent = Intent(activity, VectorMediaPickerActivity::class.java)
intent.putExtra(VectorMediaPickerActivity.EXTRA_AVATAR_MODE, true)
startActivityForResult(intent, VectorUtils.TAKE_IMAGE)
*/
}


//==============================================================================================================
// contacts management
//==============================================================================================================

private fun setContactsPreferences() {
/* TODO
// Permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// on Android >= 23, use the system one
mContactSettingsCategory.removePreference(findPreference(ContactsManager.CONTACTS_BOOK_ACCESS_KEY))
}
// Phonebook country
mContactPhonebookCountryPreference.summary = PhoneNumberUtils.getHumanCountryCode(PhoneNumberUtils.getCountryCode(activity))

mContactPhonebookCountryPreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val intent = CountryPickerActivity.getIntent(activity, true)
startActivityForResult(intent, REQUEST_PHONEBOOK_COUNTRY)
true
}
*/
}

private fun onPhonebookCountryUpdate(data: Intent?) {
/* TODO
if (data != null && data.hasExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_NAME)
&& data.hasExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_CODE)) {
val countryCode = data.getStringExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_CODE)
if (!TextUtils.equals(countryCode, PhoneNumberUtils.getCountryCode(activity))) {
PhoneNumberUtils.setCountryCode(activity, countryCode)
mContactPhonebookCountryPreference.summary = data.getStringExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_NAME)
}
}
*/
}

//==============================================================================================================
// Phone number management
//==============================================================================================================

/**
* Refresh phone number list
*/
private fun refreshPhoneNumbersList() {
/* TODO
val currentPhoneNumber3PID = ArrayList(session.myUser.getlinkedPhoneNumbers())

val phoneNumberList = ArrayList<String>()
for (identifier in currentPhoneNumber3PID) {
phoneNumberList.add(identifier.address)
}

// check first if there is an update
var isNewList = true
if (phoneNumberList.size == mDisplayedPhoneNumber.size) {
isNewList = !mDisplayedPhoneNumber.containsAll(phoneNumberList)
}

if (isNewList) {
// remove the displayed one
run {
var index = 0
while (true) {
val preference = mUserSettingsCategory.findPreference(PHONE_NUMBER_PREFERENCE_KEY_BASE + index)

if (null != preference) {
mUserSettingsCategory.removePreference(preference)
} else {
break
}
index++
}
}

// add new phone number list
mDisplayedPhoneNumber = phoneNumberList

val addPhoneBtn = mUserSettingsCategory.findPreference(ADD_PHONE_NUMBER_PREFERENCE_KEY)
?: return

var order = addPhoneBtn.order

for ((index, phoneNumber3PID) in currentPhoneNumber3PID.withIndex()) {
val preference = VectorPreference(activity!!)

preference.title = getString(R.string.settings_phone_number)
var phoneNumberFormatted = phoneNumber3PID.address
try {
// Attempt to format phone number
val phoneNumber = PhoneNumberUtil.getInstance().parse("+$phoneNumberFormatted", null)
phoneNumberFormatted = PhoneNumberUtil.getInstance().format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL)
} catch (e: NumberParseException) {
// Do nothing, we will display raw version
}

preference.summary = phoneNumberFormatted
preference.key = PHONE_NUMBER_PREFERENCE_KEY_BASE + index
preference.order = order

preference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
displayDelete3PIDConfirmationDialog(phoneNumber3PID, preference.summary)
true
}

preference.onPreferenceLongClickListener = object : VectorPreference.OnPreferenceLongClickListener {
override fun onPreferenceLongClick(preference: Preference): Boolean {
activity?.let { copyToClipboard(it, phoneNumber3PID.address) }
return true
}
}

order++
mUserSettingsCategory.addPreference(preference)
}

addPhoneBtn.order = order
} */
}

//==============================================================================================================
// Email management
//==============================================================================================================

/**
* Refresh the emails list
*/
private fun refreshEmailsList() {
val currentEmail3PID = emptyList<String>() // TODO ArrayList(session.myUser.getlinkedEmails())

val newEmailsList = ArrayList<String>()
for (identifier in currentEmail3PID) {
// TODO newEmailsList.add(identifier.address)
}

// check first if there is an update
var isNewList = true
if (newEmailsList.size == mDisplayedEmails.size) {
isNewList = !mDisplayedEmails.containsAll(newEmailsList)
}

if (isNewList) {
// remove the displayed one
run {
var index = 0
while (true) {
val preference = mUserSettingsCategory.findPreference(EMAIL_PREFERENCE_KEY_BASE + index)

if (null != preference) {
mUserSettingsCategory.removePreference(preference)
} else {
break
}
index++
}
}

// add new emails list
mDisplayedEmails = newEmailsList

val addEmailBtn = mUserSettingsCategory.findPreference(ADD_EMAIL_PREFERENCE_KEY)
?: return

var order = addEmailBtn.order

for ((index, email3PID) in currentEmail3PID.withIndex()) {
val preference = VectorPreference(activity!!)

preference.title = getString(R.string.settings_email_address)
preference.summary = "TODO" // email3PID.address
preference.key = EMAIL_PREFERENCE_KEY_BASE + index
preference.order = order

preference.onPreferenceClickListener = Preference.OnPreferenceClickListener { pref ->
displayDelete3PIDConfirmationDialog(/* TODO email3PID, */ pref.summary)
true
}

preference.onPreferenceLongClickListener = object : VectorPreference.OnPreferenceLongClickListener {
override fun onPreferenceLongClick(preference: Preference): Boolean {
activity?.let { copyToClipboard(it, "TODO") } //email3PID.address) }
return true
}
}

mUserSettingsCategory.addPreference(preference)

order++
}

addEmailBtn.order = order
}
}

/**
* Attempt to add a new email to the account
*
* @param email the email to add.
*/
private fun addEmail(email: String) {
// check first if the email syntax is valid
// if email is null , then also its invalid email
if (TextUtils.isEmpty(email) || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
activity?.toast(R.string.auth_invalid_email)
return
}

// check first if the email syntax is valid
if (mDisplayedEmails.indexOf(email) >= 0) {
activity?.toast(R.string.auth_email_already_defined)
return
}

notImplemented()
/* TODO
val pid = ThreePid(email, ThreePid.MEDIUM_EMAIL)

displayLoadingView()

session.myUser.requestEmailValidationToken(pid, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
activity?.runOnUiThread { showEmailValidationDialog(pid) }
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
if (TextUtils.equals(MatrixError.THREEPID_IN_USE, e.errcode)) {
onCommonDone(getString(R.string.account_email_already_used_error))
} else {
onCommonDone(e.localizedMessage)
}
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
*/
}

/**
* Show an email validation dialog to warn the user tho valid his email link.
*
* @param pid the used pid.
*/
/* TODO
private fun showEmailValidationDialog(pid: ThreePid) {
activity?.let {
AlertDialog.Builder(it)
.setTitle(R.string.account_email_validation_title)
.setMessage(R.string.account_email_validation_message)
.setPositiveButton(R.string._continue) { _, _ ->
session.myUser.add3Pid(pid, true, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
it.runOnUiThread {
hideLoadingView()
refreshEmailsList()
}
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
if (TextUtils.equals(e.errcode, MatrixError.THREEPID_AUTH_FAILED)) {
it.runOnUiThread {
hideLoadingView()
it.toast(R.string.account_email_validation_error)
}
} else {
onCommonDone(e.localizedMessage)
}
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
}
.setNegativeButton(R.string.cancel) { _, _ ->
hideLoadingView()
}
.show()
}
} */


/**
* Display a dialog which asks confirmation for the deletion of a 3pid
*
* @param pid the 3pid to delete
* @param preferenceSummary the displayed 3pid
*/
private fun displayDelete3PIDConfirmationDialog(/* TODO pid: ThirdPartyIdentifier,*/ preferenceSummary: CharSequence) {
val mediumFriendlyName = "TODO" // ThreePid.getMediumFriendlyName(pid.medium, activity).toLowerCase(VectorLocale.applicationLocale)
val dialogMessage = getString(R.string.settings_delete_threepid_confirmation, mediumFriendlyName, preferenceSummary)

activity?.let {
AlertDialog.Builder(it)
.setTitle(R.string.dialog_title_confirmation)
.setMessage(dialogMessage)
.setPositiveButton(R.string.remove) { _, _ ->
notImplemented()
/* TODO
displayLoadingView()

session.myUser.delete3Pid(pid, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
when (pid.medium) {
ThreePid.MEDIUM_EMAIL -> refreshEmailsList()
ThreePid.MEDIUM_MSISDN -> refreshPhoneNumbersList()
}
onCommonDone(null)
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
onCommonDone(e.localizedMessage)
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
*/
}
.setNegativeButton(R.string.cancel, null)
.show()
}
}


/**
* Update the password.
*/
private fun onPasswordUpdateClick() {
activity?.let { activity ->
val view: ViewGroup = activity.layoutInflater.inflate(R.layout.dialog_change_password, null) as ViewGroup

val showPassword: ImageView = view.findViewById(R.id.change_password_show_passwords)
val oldPasswordTil: TextInputLayout = view.findViewById(R.id.change_password_old_pwd_til)
val oldPasswordText: TextInputEditText = view.findViewById(R.id.change_password_old_pwd_text)
val newPasswordText: TextInputEditText = view.findViewById(R.id.change_password_new_pwd_text)
val confirmNewPasswordTil: TextInputLayout = view.findViewById(R.id.change_password_confirm_new_pwd_til)
val confirmNewPasswordText: TextInputEditText = view.findViewById(R.id.change_password_confirm_new_pwd_text)
val changePasswordLoader: View = view.findViewById(R.id.change_password_loader)

var passwordShown = false

showPassword.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
passwordShown = !passwordShown

oldPasswordText.showPassword(passwordShown)
newPasswordText.showPassword(passwordShown)
confirmNewPasswordText.showPassword(passwordShown)

showPassword.setImageResource(if (passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
}
})

val dialog = AlertDialog.Builder(activity)
.setView(view)
.setPositiveButton(R.string.settings_change_password_submit, null)
.setNegativeButton(R.string.cancel, null)
.setOnDismissListener {
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.applicationWindowToken, 0)
}
.create()

dialog.setOnShowListener {
val updateButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
updateButton.isEnabled = false

fun updateUi() {
val oldPwd = oldPasswordText.text.toString().trim()
val newPwd = newPasswordText.text.toString().trim()
val newConfirmPwd = confirmNewPasswordText.text.toString().trim()

updateButton.isEnabled = oldPwd.isNotEmpty() && newPwd.isNotEmpty() && TextUtils.equals(newPwd, newConfirmPwd)

if (newPwd.isNotEmpty() && newConfirmPwd.isNotEmpty() && !TextUtils.equals(newPwd, newConfirmPwd)) {
confirmNewPasswordTil.error = getString(R.string.passwords_do_not_match)
}
}

oldPasswordText.addTextChangedListener(object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) {
oldPasswordTil.error = null
updateUi()
}
})

newPasswordText.addTextChangedListener(object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) {
confirmNewPasswordTil.error = null
updateUi()
}
})

confirmNewPasswordText.addTextChangedListener(object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) {
confirmNewPasswordTil.error = null
updateUi()
}
})

fun showPasswordLoadingView(toShow: Boolean) {
if (toShow) {
showPassword.isEnabled = false
oldPasswordText.isEnabled = false
newPasswordText.isEnabled = false
confirmNewPasswordText.isEnabled = false
changePasswordLoader.isVisible = true
updateButton.isEnabled = false
} else {
showPassword.isEnabled = true
oldPasswordText.isEnabled = true
newPasswordText.isEnabled = true
confirmNewPasswordText.isEnabled = true
changePasswordLoader.isVisible = false
updateButton.isEnabled = true
}
}

updateButton.setOnClickListener {
if (passwordShown) {
// Hide passwords during processing
showPassword.performClick()
}

val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.applicationWindowToken, 0)

val oldPwd = oldPasswordText.text.toString().trim()
val newPwd = newPasswordText.text.toString().trim()

notImplemented()
/* TODO
showPasswordLoadingView(true)

session.updatePassword(oldPwd, newPwd, object : MatrixCallback<Unit> {
private fun onDone(@StringRes textResId: Int) {
showPasswordLoadingView(false)

if (textResId == R.string.settings_fail_to_update_password_invalid_current_password) {
oldPasswordTil.error = getString(textResId)
} else {
dialog.dismiss()
activity.toast(textResId, Toast.LENGTH_LONG)
}
}

override fun onSuccess(info: Void?) {
onDone(R.string.settings_password_updated)
}

override fun onNetworkError(e: Exception) {
onDone(R.string.settings_fail_to_update_password)
}

override fun onMatrixError(e: MatrixError) {
if (e.error == "Invalid password") {
onDone(R.string.settings_fail_to_update_password_invalid_current_password)
} else {
dialog.dismiss()
onDone(R.string.settings_fail_to_update_password)
}
}

override fun onUnexpectedError(e: Exception) {
onDone(R.string.settings_fail_to_update_password)
}
})
*/
}
}
dialog.show()
}
}

/**
* Update the displayname.
*/
private fun onDisplayNameClick(value: String?) {
notImplemented()
/* TODO
if (!TextUtils.equals(session.myUser.displayname, value)) {
displayLoadingView()

session.myUser.updateDisplayName(value, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
// refresh the settings value
PreferenceManager.getDefaultSharedPreferences(activity).edit {
putString(PreferencesManager.SETTINGS_DISPLAY_NAME_PREFERENCE_KEY, value)
}

onCommonDone(null)

refreshDisplay()
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
if (MatrixError.M_CONSENT_NOT_GIVEN == e.errcode) {
activity?.runOnUiThread {
hideLoadingView()
(activity as VectorAppCompatActivity).consentNotGivenHelper.displayDialog(e)
}
} else {
onCommonDone(e.localizedMessage)
}
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
}
*/
}

private class ClearMediaCacheAsyncTask internal constructor(
backgroundTask: () -> Unit,
onCompleteTask: () -> Unit
) : AsyncTask<Unit, Unit, Unit>() {

private val backgroundTaskReference = WeakReference(backgroundTask)
private val onCompleteTaskReference = WeakReference(onCompleteTask)
override fun doInBackground(vararg params: Unit?) {
backgroundTaskReference.get()?.invoke()
}

override fun onPostExecute(result: Unit?) {
super.onPostExecute(result)
onCompleteTaskReference.get()?.invoke()
}
}

companion object {
private const val ADD_EMAIL_PREFERENCE_KEY = "ADD_EMAIL_PREFERENCE_KEY"
private const val ADD_PHONE_NUMBER_PREFERENCE_KEY = "ADD_PHONE_NUMBER_PREFERENCE_KEY"

private const val EMAIL_PREFERENCE_KEY_BASE = "EMAIL_PREFERENCE_KEY_BASE"
private const val PHONE_NUMBER_PREFERENCE_KEY_BASE = "PHONE_NUMBER_PREFERENCE_KEY_BASE"

private const val REQUEST_NEW_PHONE_NUMBER = 456
private const val REQUEST_PHONEBOOK_COUNTRY = 789
}
}

View File

@ -0,0 +1,118 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.preference.Preference
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import im.vector.matrix.android.api.Matrix
import im.vector.riotredesign.R
import im.vector.riotredesign.core.utils.copyToClipboard
import im.vector.riotredesign.core.utils.displayInWebView
import im.vector.riotredesign.features.version.getVersion

class VectorSettingsHelpAbout : VectorSettingsBaseFragment() {

override var titleRes = R.string.preference_root_help_about
override val preferenceXmlRes = R.xml.vector_settings_help_about

override fun bindPref() {
// preference to start the App info screen, to facilitate App permissions access
findPreference(APP_INFO_LINK_PREFERENCE_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {

activity?.let {
val intent = Intent().apply {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

val uri = Uri.fromParts("package", requireContext().packageName, null)

data = uri
}
it.applicationContext.startActivity(intent)
}

true
}

// application version
(findPreference(PreferencesManager.SETTINGS_VERSION_PREFERENCE_KEY)).let {
it.summary = getVersion(longFormat = false, useBuildNumber = true)

it.setOnPreferenceClickListener { pref ->
copyToClipboard(requireContext(), pref.summary)
true
}
}

// SDK version
(findPreference(PreferencesManager.SETTINGS_SDK_VERSION_PREFERENCE_KEY)).let {
it.summary = Matrix.getSdkVersion()

it.setOnPreferenceClickListener { pref ->
copyToClipboard(requireContext(), pref.summary)
true
}
}

// olm version
findPreference(PreferencesManager.SETTINGS_OLM_VERSION_PREFERENCE_KEY)
.summary = mSession.getCryptoVersion(requireContext(), false)

// copyright
findPreference(PreferencesManager.SETTINGS_COPYRIGHT_PREFERENCE_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.displayInWebView(VectorSettingsUrls.COPYRIGHT)
false
}

// terms & conditions
findPreference(PreferencesManager.SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.displayInWebView(VectorSettingsUrls.TAC)
false
}

// privacy policy
findPreference(PreferencesManager.SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.displayInWebView(VectorSettingsUrls.PRIVACY_POLICY)
false
}

// third party notice
findPreference(PreferencesManager.SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.displayInWebView(VectorSettingsUrls.THIRD_PARTY_LICENSES)
false
}

findPreference(PreferencesManager.SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY)
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
// See https://developers.google.com/android/guides/opensource
startActivity(Intent(requireActivity(), OssLicensesMenuActivity::class.java))
false
}
}

companion object {
private const val APP_INFO_LINK_PREFERENCE_KEY = "APP_INFO_LINK_PREFERENCE_KEY"
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import androidx.appcompat.app.AlertDialog
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import im.vector.riotredesign.R
import java.util.ArrayList
import kotlin.Comparator
import kotlin.String
import kotlin.getValue
import kotlin.lazy
import kotlin.let

class VectorSettingsIgnoredUsers : VectorSettingsBaseFragment() {

override var titleRes = R.string.settings_ignored_users
override val preferenceXmlRes = R.xml.vector_settings_ignored_users

// displayed the ignored users list
private val mIgnoredUserSettingsCategoryDivider by lazy {
findPreference(PreferencesManager.SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY)
}
private val mIgnoredUserSettingsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_IGNORED_USERS_PREFERENCE_KEY) as PreferenceCategory
}

override fun bindPref() {
// Ignore users
refreshIgnoredUsersList()
}

//==============================================================================================================
// ignored users list management
//==============================================================================================================

/**
* Refresh the ignored users list
*/
private fun refreshIgnoredUsersList() {
val ignoredUsersList = mutableListOf<String>() // TODO session.dataHandler.ignoredUserIds

ignoredUsersList.sortWith(Comparator { u1, u2 ->
u1.toLowerCase(VectorLocale.applicationLocale).compareTo(u2.toLowerCase(VectorLocale.applicationLocale))
})

val preferenceScreen = preferenceScreen

preferenceScreen.removePreference(mIgnoredUserSettingsCategory)
preferenceScreen.removePreference(mIgnoredUserSettingsCategoryDivider)
mIgnoredUserSettingsCategory.removeAll()

if (ignoredUsersList.size > 0) {
preferenceScreen.addPreference(mIgnoredUserSettingsCategoryDivider)
preferenceScreen.addPreference(mIgnoredUserSettingsCategory)

for (userId in ignoredUsersList) {
val preference = Preference(activity)

preference.title = userId
preference.key = IGNORED_USER_KEY_BASE + userId

preference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.let {
AlertDialog.Builder(it)
.setMessage(getString(R.string.settings_unignore_user, userId))
.setPositiveButton(R.string.yes) { _, _ ->
displayLoadingView()

val idsList = ArrayList<String>()
idsList.add(userId)

notImplemented()
/* TODO
session.unIgnoreUsers(idsList, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
onCommonDone(null)
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
onCommonDone(e.localizedMessage)
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
*/
}
.setNegativeButton(R.string.no, null)
.show()
}

false
}

mIgnoredUserSettingsCategory.addPreference(preference)
}
}
}

companion object {
private const val IGNORED_USER_KEY_BASE = "IGNORED_USER_KEY_BASE"
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.text.TextUtils
import androidx.appcompat.app.AlertDialog
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.SwitchPreference
import im.vector.riotredesign.R

class VectorSettingsLabs : VectorSettingsBaseFragment() {

override var titleRes = R.string.room_settings_labs_pref_title
override val preferenceXmlRes = R.xml.vector_settings_labs

private val mLabsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_LABS_PREFERENCE_KEY) as PreferenceCategory
}

override fun bindPref() {
// Lab
val useCryptoPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY) as SwitchPreference
val cryptoIsEnabledPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY)


if (mSession.isCryptoEnabled()) {
mLabsCategory.removePreference(useCryptoPref)

cryptoIsEnabledPref.isEnabled = false
} else {
mLabsCategory.removePreference(cryptoIsEnabledPref)

useCryptoPref.isChecked = false

useCryptoPref.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValueAsVoid ->
if (TextUtils.isEmpty(mSession.sessionParams.credentials.deviceId)) {
activity?.let { activity ->
AlertDialog.Builder(activity)
.setMessage(R.string.room_settings_labs_end_to_end_warnings)
.setPositiveButton(R.string.logout) { _, _ ->
notImplemented()
// TODO CommonActivityUtils.logout(activity)
}
.setNegativeButton(R.string.cancel) { _, _ ->
useCryptoPref.isChecked = false
}
.setOnCancelListener {
useCryptoPref.isChecked = false
}
.show()
}
} else {
val newValue = newValueAsVoid as Boolean

if (mSession.isCryptoEnabled() != newValue) {
notImplemented()
/* TODO
displayLoadingView()

session.enableCrypto(newValue, object : MatrixCallback<Unit> {
private fun refresh() {
activity?.runOnUiThread {
hideLoadingView()
useCryptoPref.isChecked = session.isCryptoEnabled

if (session.isCryptoEnabled) {
mLabsCategory.removePreference(useCryptoPref)
mLabsCategory.addPreference(cryptoIsEnabledPref)
}
}
}

override fun onSuccess(info: Void?) {
useCryptoPref.isEnabled = false
refresh()
}

override fun onNetworkError(e: Exception) {
useCryptoPref.isChecked = false
}

override fun onMatrixError(e: MatrixError) {
useCryptoPref.isChecked = false
}

override fun onUnexpectedError(e: Exception) {
useCryptoPref.isChecked = false
}
})
*/
}
}

true
}
}

// SaveMode Management
findPreference(PreferencesManager.SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY)
.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
notImplemented()
/* TODO
val sessions = Matrix.getMXSessions(activity)
for (session in sessions) {
session.setUseDataSaveMode(newValue as Boolean)
}
*/

true
}
}

}

View File

@ -16,28 +16,68 @@

package im.vector.riotredesign.features.settings

import android.os.Bundle
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.SwitchPreference
import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.MatrixCallback
import im.vector.riotredesign.R
import im.vector.riotredesign.core.platform.VectorPreferenceFragment
import im.vector.riotredesign.core.preference.BingRule
import im.vector.riotredesign.core.pushers.PushersManager
import im.vector.riotredesign.push.fcm.FcmHelper
import org.koin.android.ext.android.inject

// Referenced in vector_settings_preferences_root.xml
class VectorSettingsNotificationPreferenceFragment : VectorPreferenceFragment() {
class VectorSettingsNotificationPreferenceFragment : VectorSettingsBaseFragment() {

override var titleRes: Int = R.string.settings_notifications
override val preferenceXmlRes = R.xml.vector_settings_notifications

val pushManager: PushersManager by inject()


override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.vector_settings_notifications)
// background sync category
private val mSyncRequestTimeoutPreference by lazy {
// ? Cause it can be removed
findPreference(PreferencesManager.SETTINGS_SET_SYNC_TIMEOUT_PREFERENCE_KEY) as EditTextPreference?
}
private val mSyncRequestDelayPreference by lazy {
// ? Cause it can be removed
findPreference(PreferencesManager.SETTINGS_SET_SYNC_DELAY_PREFERENCE_KEY) as EditTextPreference?
}

private val backgroundSyncCategory by lazy {
findPreference(PreferencesManager.SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY)
}
private val backgroundSyncDivider by lazy {
findPreference(PreferencesManager.SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY)
}
private val backgroundSyncPreference by lazy {
findPreference(PreferencesManager.SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY) as SwitchPreference
}

private val notificationsSettingsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_NOTIFICATIONS_KEY) as PreferenceCategory
}

override fun bindPref() {
for (preferenceKey in mPrefKeyToBingRuleId.keys) {
val preference = findPreference(preferenceKey)

if (null != preference) {
if (preference is SwitchPreference) {
preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValueAsVoid ->
// on some old android APIs,
// the callback is called even if there is no user interaction
// so the value will be checked to ensure there is really no update.
// TODO onPushRuleClick(preference.key, newValueAsVoid as Boolean)
true
}
}
}
}
}


override fun onResume() {
super.onResume()
@ -69,4 +109,203 @@ class VectorSettingsNotificationPreferenceFragment : VectorPreferenceFragment()
}
return super.onPreferenceTreeClick(preference)
}

/**
* Update a push rule.
*/
private fun onPushRuleClick(preferenceKey: String, newValue: Boolean) {
notImplemented()
/* TODO
val matrixInstance = Matrix.getInstance(context)
val pushManager = matrixInstance.pushManager

Timber.v("onPushRuleClick $preferenceKey : set to $newValue")

when (preferenceKey) {

PreferencesManager.SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY -> {
if (pushManager.isScreenTurnedOn != newValue) {
pushManager.isScreenTurnedOn = newValue
}
}

PreferencesManager.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY -> {
val isConnected = matrixInstance.isConnected
val isAllowed = pushManager.areDeviceNotificationsAllowed()

// avoid useless update
if (isAllowed == newValue) {
return
}

pushManager.setDeviceNotificationsAllowed(!isAllowed)

// when using FCM
// need to register on servers
if (isConnected && pushManager.useFcm() && (pushManager.isServerRegistered || pushManager.isServerUnRegistered)) {
val listener = object : MatrixCallback<Unit> {

private fun onDone() {
activity?.runOnUiThread {
hideLoadingView(true)
refreshPushersList()
}
}

override fun onSuccess(info: Void?) {
onDone()
}

override fun onMatrixError(e: MatrixError?) {
// Set again the previous state
pushManager.setDeviceNotificationsAllowed(isAllowed)
onDone()
}

override fun onNetworkError(e: java.lang.Exception?) {
// Set again the previous state
pushManager.setDeviceNotificationsAllowed(isAllowed)
onDone()
}

override fun onUnexpectedError(e: java.lang.Exception?) {
// Set again the previous state
pushManager.setDeviceNotificationsAllowed(isAllowed)
onDone()
}
}

displayLoadingView()
if (pushManager.isServerRegistered) {
pushManager.unregister(listener)
} else {
pushManager.register(listener)
}
}
}

// check if there is an update

// on some old android APIs,
// the callback is called even if there is no user interaction
// so the value will be checked to ensure there is really no update.
else -> {

val ruleId = mPrefKeyToBingRuleId[preferenceKey]
val rule = session.dataHandler.pushRules()?.findDefaultRule(ruleId)

// check if there is an update
var curValue = null != rule && rule.isEnabled

if (TextUtils.equals(ruleId, BingRule.RULE_ID_DISABLE_ALL) || TextUtils.equals(ruleId, BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS)) {
curValue = !curValue
}

// on some old android APIs,
// the callback is called even if there is no user interaction
// so the value will be checked to ensure there is really no update.
if (newValue == curValue) {
return
}

if (null != rule) {
displayLoadingView()
session.dataHandler.bingRulesManager.updateEnableRuleStatus(rule, !rule.isEnabled, object : BingRulesManager.onBingRuleUpdateListener {
private fun onDone() {
refreshDisplay()
hideLoadingView()
}

override fun onBingRuleUpdateSuccess() {
onDone()
}

override fun onBingRuleUpdateFailure(errorMessage: String) {
activity?.toast(errorMessage)
onDone()
}
})
}
}
}
*/
}

/**
* Refresh the background sync preference
*/
private fun refreshBackgroundSyncPrefs() {
/* TODO
activity?.let { activity ->
val pushManager = Matrix.getInstance(activity).pushManager

val timeout = pushManager.backgroundSyncTimeOut / 1000
val delay = pushManager.backgroundSyncDelay / 1000

// update the settings
PreferenceManager.getDefaultSharedPreferences(activity).edit {
putString(PreferencesManager.SETTINGS_SET_SYNC_TIMEOUT_PREFERENCE_KEY, timeout.toString() + "")
putString(PreferencesManager.SETTINGS_SET_SYNC_DELAY_PREFERENCE_KEY, delay.toString() + "")
}

mSyncRequestTimeoutPreference?.let {
it.summary = secondsToText(timeout)
it.text = timeout.toString() + ""

it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
var newTimeOut = timeout

try {
newTimeOut = Integer.parseInt(newValue as String)
} catch (e: Exception) {
Timber.e(e, "## refreshBackgroundSyncPrefs : parseInt failed " + e.message)
}

if (newTimeOut != timeout) {
pushManager.backgroundSyncTimeOut = newTimeOut * 1000

activity.runOnUiThread { refreshBackgroundSyncPrefs() }
}

false
}
}

mSyncRequestDelayPreference?.let {
it.summary = secondsToText(delay)
it.text = delay.toString() + ""

it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
var newDelay = delay

try {
newDelay = Integer.parseInt(newValue as String)
} catch (e: Exception) {
Timber.e(e, "## refreshBackgroundSyncPrefs : parseInt failed " + e.message)
}

if (newDelay != delay) {
pushManager.backgroundSyncDelay = newDelay * 1000

activity.runOnUiThread { refreshBackgroundSyncPrefs() }
}

false
}
}
}
*/
}

companion object {
private const val DUMMY_RULE = "DUMMY_RULE"

// preference name <-> rule Id
private var mPrefKeyToBingRuleId = mapOf(
PreferencesManager.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY to BingRule.RULE_ID_DISABLE_ALL,
PreferencesManager.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY to DUMMY_RULE,
PreferencesManager.SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY to DUMMY_RULE
)
}

}

View File

@ -0,0 +1,206 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import android.widget.CheckedTextView
import android.widget.LinearLayout
import androidx.appcompat.app.AlertDialog
import androidx.preference.Preference
import androidx.preference.SwitchPreference
import im.vector.riotredesign.R
import im.vector.riotredesign.features.configuration.VectorConfiguration
import im.vector.riotredesign.features.themes.ThemeUtils
import org.koin.android.ext.android.inject

class VectorSettingsPreferences : VectorSettingsBaseFragment() {

override var titleRes = R.string.settings_preferences
override val preferenceXmlRes = R.xml.vector_settings_preferences

private val selectedLanguagePreference by lazy {
findPreference(PreferencesManager.SETTINGS_INTERFACE_LANGUAGE_PREFERENCE_KEY)
}
private val textSizePreference by lazy {
findPreference(PreferencesManager.SETTINGS_INTERFACE_TEXT_SIZE_KEY)
}

private val vectorConfiguration by inject<VectorConfiguration>()

override fun bindPref() {
// user interface preferences
setUserInterfacePreferences()

// Themes
findPreference(ThemeUtils.APPLICATION_THEME_KEY)
.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
if (newValue is String) {
vectorConfiguration.updateApplicationTheme(newValue)
// Restart the Activity
activity?.let {
// Note: recreate does not apply the color correctly
it.startActivity(it.intent)
it.finish()
}
true
} else {
false
}
}

// Url preview
(findPreference(PreferencesManager.SETTINGS_SHOW_URL_PREVIEW_KEY) as SwitchPreference).let {
/*
TODO
it.isChecked = session.isURLPreviewEnabled

it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
if (null != newValue && newValue as Boolean != session.isURLPreviewEnabled) {
displayLoadingView()
session.setURLPreviewStatus(newValue, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
it.isChecked = session.isURLPreviewEnabled
hideLoadingView()
}

private fun onError(errorMessage: String) {
activity?.toast(errorMessage)

onSuccess(null)
}

override fun onNetworkError(e: Exception) {
onError(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
onError(e.localizedMessage)
}

override fun onUnexpectedError(e: Exception) {
onError(e.localizedMessage)
}
})
}

false
}
*/
}

// update keep medias period
findPreference(PreferencesManager.SETTINGS_MEDIA_SAVING_PERIOD_KEY).let {
it.summary = PreferencesManager.getSelectedMediasSavingPeriodString(activity)

it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
context?.let { context: Context ->
AlertDialog.Builder(context)
.setSingleChoiceItems(R.array.media_saving_choice,
PreferencesManager.getSelectedMediasSavingPeriod(activity)) { d, n ->
PreferencesManager.setSelectedMediasSavingPeriod(activity, n)
d.cancel()

it.summary = PreferencesManager.getSelectedMediasSavingPeriodString(activity)
}
.show()
}

false
}
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_LOCALE -> {
activity?.let {
startActivity(it.intent)
it.finish()
}
}
}
}
}


//==============================================================================================================
// user interface management
//==============================================================================================================

private fun setUserInterfacePreferences() {
// Selected language
selectedLanguagePreference.summary = VectorLocale.localeToLocalisedString(VectorLocale.applicationLocale)

selectedLanguagePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
notImplemented()
// TODO startActivityForResult(LanguagePickerActivity.getIntent(activity), REQUEST_LOCALE)
true
}

// Text size
textSizePreference.summary = FontScale.getFontScaleDescription(activity!!)

textSizePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.let { displayTextSizeSelection(it) }
true
}
}

private fun displayTextSizeSelection(activity: Activity) {
val inflater = activity.layoutInflater
val layout = inflater.inflate(R.layout.dialog_select_text_size, null)

val dialog = AlertDialog.Builder(activity)
.setTitle(R.string.font_size)
.setView(layout)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.show()

val linearLayout = layout.findViewById<LinearLayout>(R.id.text_selection_group_view)

val childCount = linearLayout.childCount

val scaleText = FontScale.getFontScaleDescription(activity)

for (i in 0 until childCount) {
val v = linearLayout.getChildAt(i)

if (v is CheckedTextView) {
v.isChecked = TextUtils.equals(v.text, scaleText)

v.setOnClickListener {
dialog.dismiss()
FontScale.updateFontScale(activity, v.text.toString())
activity.startActivity(activity.intent)
activity.finish()
}
}
}
}

companion object {
private const val REQUEST_LOCALE = 777
}

}

View File

@ -16,22 +16,20 @@

package im.vector.riotredesign.features.settings

import android.os.Bundle
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.withArgs
import im.vector.riotredesign.core.platform.VectorPreferenceFragment

class VectorSettingsPreferencesFragmentV2 : VectorPreferenceFragment() {
class VectorSettingsRoot : VectorSettingsBaseFragment() {

override var titleRes: Int = R.string.title_activity_settings
override val preferenceXmlRes = R.xml.vector_settings_root

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.vector_settings_preferences_root)
override fun bindPref() {
// Nothing to do
}


companion object {
fun newInstance() = VectorSettingsPreferencesFragmentV2()
fun newInstance() = VectorSettingsRoot()
.withArgs {
//putString(ARG_MATRIX_ID, matrixId)
}

View File

@ -0,0 +1,868 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.annotation.SuppressLint
import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Typeface
import android.text.TextUtils
import android.view.KeyEvent
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.SwitchPreference
import com.google.android.material.textfield.TextInputEditText
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.extensions.getFingerprintHumanReadable
import im.vector.matrix.android.api.extensions.sortByLastSeen
import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
import im.vector.riotredesign.R
import im.vector.riotredesign.core.dialogs.ExportKeysDialog
import im.vector.riotredesign.core.intent.ExternalIntentData
import im.vector.riotredesign.core.intent.analyseIntent
import im.vector.riotredesign.core.intent.getFilenameFromUri
import im.vector.riotredesign.core.platform.SimpleTextWatcher
import im.vector.riotredesign.core.preference.ProgressBarPreference
import im.vector.riotredesign.core.preference.VectorPreference
import im.vector.riotredesign.core.utils.*
import im.vector.riotredesign.features.crypto.keys.KeysExporter
import im.vector.riotredesign.features.crypto.keys.KeysImporter
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupManageActivity
import timber.log.Timber
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*

class VectorSettingsSecurityPrivacy : VectorSettingsBaseFragment() {

override var titleRes = R.string.settings_security_and_privacy
override val preferenceXmlRes = R.xml.vector_settings_security_privacy

// used to avoid requesting to enter the password for each deletion
private var mAccountPassword: String = ""

// devices: device IDs and device names
private var mDevicesNameList: List<DeviceInfo> = ArrayList()

private var mMyDeviceInfo: DeviceInfo? = null


// cryptography
private val mCryptographyCategory by lazy {
findPreference(PreferencesManager.SETTINGS_CRYPTOGRAPHY_PREFERENCE_KEY) as PreferenceCategory
}
private val mCryptographyCategoryDivider by lazy {
findPreference(PreferencesManager.SETTINGS_CRYPTOGRAPHY_DIVIDER_PREFERENCE_KEY)
}
// cryptography manage
private val mCryptographyManageCategory by lazy {
findPreference(PreferencesManager.SETTINGS_CRYPTOGRAPHY_MANAGE_PREFERENCE_KEY) as PreferenceCategory
}
private val mCryptographyManageCategoryDivider by lazy {
findPreference(PreferencesManager.SETTINGS_CRYPTOGRAPHY_MANAGE_DIVIDER_PREFERENCE_KEY)
}
// displayed pushers
private val mPushersSettingsDivider by lazy {
findPreference(PreferencesManager.SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY)
}
private val mPushersSettingsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY) as PreferenceCategory
}
private val mDevicesListSettingsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_DEVICES_LIST_PREFERENCE_KEY) as PreferenceCategory
}
private val mDevicesListSettingsCategoryDivider by lazy {
findPreference(PreferencesManager.SETTINGS_DEVICES_DIVIDER_PREFERENCE_KEY)
}
private val cryptoInfoDeviceNamePreference by lazy {
findPreference(PreferencesManager.SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY) as VectorPreference
}

private val cryptoInfoDeviceIdPreference by lazy {
findPreference(PreferencesManager.SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY)
}

private val manageBackupPref by lazy {
findPreference(PreferencesManager.SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY)
}

private val exportPref by lazy {
findPreference(PreferencesManager.SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY)
}

private val importPref by lazy {
findPreference(PreferencesManager.SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY)
}

private val cryptoInfoTextPreference by lazy {
findPreference(PreferencesManager.SETTINGS_ENCRYPTION_INFORMATION_DEVICE_KEY_PREFERENCE_KEY)
}
// encrypt to unverified devices
private val sendToUnverifiedDevicesPref by lazy {
findPreference(PreferencesManager.SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY) as SwitchPreference
}

override fun bindPref() {
// Push target
refreshPushersList()

// Device list
refreshDevicesList()

//Refresh Key Management section
refreshKeysManagementSection()

// Analytics

// Analytics tracking management
(findPreference(PreferencesManager.SETTINGS_USE_ANALYTICS_KEY) as SwitchPreference).let {
// On if the analytics tracking is activated
it.isChecked = PreferencesManager.useAnalytics(requireContext())

it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
PreferencesManager.setUseAnalytics(requireContext(), newValue as Boolean)
true
}
}

// Rageshake Management
(findPreference(PreferencesManager.SETTINGS_USE_RAGE_SHAKE_KEY) as SwitchPreference).let {
it.isChecked = PreferencesManager.useRageshake(requireContext())

it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
PreferencesManager.setUseRageshake(requireContext(), newValue as Boolean)
true
}
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (allGranted(grantResults)) {
if (requestCode == PERMISSION_REQUEST_CODE_EXPORT_KEYS) {
exportKeys()
}
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_E2E_FILE_REQUEST_CODE -> importKeys(data)
}
}
}


private fun refreshKeysManagementSection() {
//If crypto is not enabled parent section will be removed
//TODO notice that this will not work when no network
manageBackupPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
context?.let {
startActivity(KeysBackupManageActivity.intent(it))
}
false
}

exportPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
exportKeys()
true
}

importPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
importKeys()
true
}
}

/**
* Manage the e2e keys export.
*/
private fun exportKeys() {
// We need WRITE_EXTERNAL permission
if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS)) {
activity?.let { activity ->
ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener {
override fun onPassphrase(passphrase: String) {
displayLoadingView()

KeysExporter(mSession)
.export(requireContext(),
passphrase,
object : MatrixCallback<String> {
override fun onSuccess(data: String) {
if (isAdded) {
hideLoadingView()

AlertDialog.Builder(activity)
.setMessage(getString(R.string.encryption_export_saved_as, data))
.setCancelable(false)
.setPositiveButton(R.string.ok, null)
.show()
}
}

override fun onFailure(failure: Throwable) {
onCommonDone(failure.localizedMessage)
}

})
}
})
}
}
}

/**
* Manage the e2e keys import.
*/
@SuppressLint("NewApi")
private fun importKeys() {
activity?.let { openFileSelection(it, this, false, REQUEST_E2E_FILE_REQUEST_CODE) }
}

/**
* Manage the e2e keys import.
*
* @param intent the intent result
*/
private fun importKeys(intent: Intent?) {
// sanity check
if (null == intent) {
return
}

val sharedDataItems = analyseIntent(intent)
val thisActivity = activity

if (sharedDataItems.isNotEmpty() && thisActivity != null) {
val sharedDataItem = sharedDataItems[0]

val uri = when (sharedDataItem) {
is ExternalIntentData.IntentDataUri -> sharedDataItem.uri
is ExternalIntentData.IntentDataClipData -> sharedDataItem.clipDataItem.uri
else -> null
}

val mimetype = when (sharedDataItem) {
is ExternalIntentData.IntentDataClipData -> sharedDataItem.mimeType
else -> null
}

if (uri == null) {
return
}

val appContext = thisActivity.applicationContext

val filename = getFilenameFromUri(appContext, uri)

val dialogLayout = thisActivity.layoutInflater.inflate(R.layout.dialog_import_e2e_keys, null)

val textView = dialogLayout.findViewById<TextView>(R.id.dialog_e2e_keys_passphrase_filename)

if (filename.isNullOrBlank()) {
textView.isVisible = false
} else {
textView.isVisible = true
textView.text = getString(R.string.import_e2e_keys_from_file, filename)
}

val builder = AlertDialog.Builder(thisActivity)
.setTitle(R.string.encryption_import_room_keys)
.setView(dialogLayout)

val passPhraseEditText = dialogLayout.findViewById<TextInputEditText>(R.id.dialog_e2e_keys_passphrase_edit_text)
val importButton = dialogLayout.findViewById<Button>(R.id.dialog_e2e_keys_import_button)

passPhraseEditText.addTextChangedListener(object : SimpleTextWatcher() {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
importButton.isEnabled = !TextUtils.isEmpty(passPhraseEditText.text)
}
})

val importDialog = builder.show()

importButton.setOnClickListener(View.OnClickListener {
val password = passPhraseEditText.text.toString()

displayLoadingView()

KeysImporter(mSession)
.import(requireContext(),
uri,
mimetype,
password,
object : MatrixCallback<ImportRoomKeysResult> {
override fun onSuccess(data: ImportRoomKeysResult) {
if (!isAdded) {
return
}

hideLoadingView()

AlertDialog.Builder(thisActivity)
.setMessage(getString(R.string.encryption_import_room_keys_success,
data.successfullyNumberOfImportedKeys,
data.totalNumberOfKeys))
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
.show()
}

override fun onFailure(failure: Throwable) {
appContext.toast(failure.localizedMessage)
hideLoadingView()
}
})

importDialog.dismiss()
})
}
}

//==============================================================================================================
// Cryptography
//==============================================================================================================

private fun removeCryptographyPreference() {
preferenceScreen.let {
it.removePreference(mCryptographyCategory)
it.removePreference(mCryptographyCategoryDivider)

// Also remove keys management section
it.removePreference(mCryptographyManageCategory)
it.removePreference(mCryptographyManageCategoryDivider)
}
}

/**
* Build the cryptography preference section.
*
* @param aMyDeviceInfo the device info
*/
private fun refreshCryptographyPreference(aMyDeviceInfo: DeviceInfo?) {
val userId = mSession.sessionParams.credentials.userId
val deviceId = mSession.sessionParams.credentials.deviceId

// device name
if (null != aMyDeviceInfo) {
cryptoInfoDeviceNamePreference.summary = aMyDeviceInfo.displayName

cryptoInfoDeviceNamePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
displayDeviceRenameDialog(aMyDeviceInfo)
true
}

cryptoInfoDeviceNamePreference.onPreferenceLongClickListener = object : VectorPreference.OnPreferenceLongClickListener {
override fun onPreferenceLongClick(preference: Preference): Boolean {
activity?.let { copyToClipboard(it, aMyDeviceInfo.displayName!!) }
return true
}
}
}

// crypto section: device ID
if (!TextUtils.isEmpty(deviceId)) {
cryptoInfoDeviceIdPreference.summary = deviceId

cryptoInfoDeviceIdPreference.setOnPreferenceClickListener {
activity?.let { copyToClipboard(it, deviceId!!) }
true
}
}

// crypto section: device key (fingerprint)
if (!TextUtils.isEmpty(deviceId) && !TextUtils.isEmpty(userId)) {
val deviceInfo = mSession.getDeviceInfo(userId, deviceId)

if (null != deviceInfo && !TextUtils.isEmpty(deviceInfo.fingerprint())) {
cryptoInfoTextPreference.summary = deviceInfo.getFingerprintHumanReadable()

cryptoInfoTextPreference.setOnPreferenceClickListener {
deviceInfo.fingerprint()?.let {
copyToClipboard(requireActivity(), it)
}
true
}
}
}

sendToUnverifiedDevicesPref.isChecked = false

sendToUnverifiedDevicesPref.isChecked = mSession.getGlobalBlacklistUnverifiedDevices()

sendToUnverifiedDevicesPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
mSession.setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked)

true
}
}


//==============================================================================================================
// devices list
//==============================================================================================================

private fun removeDevicesPreference() {
preferenceScreen.let {
it.removePreference(mDevicesListSettingsCategory)
it.removePreference(mDevicesListSettingsCategoryDivider)
}
}

/**
* Force the refresh of the devices list.<br></br>
* The devices list is the list of the devices where the user as looged in.
* It can be any mobile device, as any browser.
*/
private fun refreshDevicesList() {
if (mSession.isCryptoEnabled() && !TextUtils.isEmpty(mSession.sessionParams.credentials.deviceId)) {
// display a spinner while loading the devices list
if (0 == mDevicesListSettingsCategory.preferenceCount) {
activity?.let {
val preference = ProgressBarPreference(it)
mDevicesListSettingsCategory.addPreference(preference)
}
}

mSession.getDevicesList(object : MatrixCallback<DevicesListResponse> {
override fun onSuccess(data: DevicesListResponse) {
if (!isAdded) {
return
}

if (data.devices?.isEmpty() == true) {
removeDevicesPreference()
} else {
buildDevicesSettings(data.devices!!)
}
}

override fun onFailure(failure: Throwable) {
if (!isAdded) {
return
}

removeDevicesPreference()
onCommonDone(failure.message)
}
})
} else {
removeDevicesPreference()
removeCryptographyPreference()
}
}

/**
* Build the devices portion of the settings.<br></br>
* Each row correspond to a device ID and its corresponding device name. Clicking on the row
* display a dialog containing: the device ID, the device name and the "last seen" information.
*
* @param aDeviceInfoList the list of the devices
*/
private fun buildDevicesSettings(aDeviceInfoList: List<DeviceInfo>) {
var preference: VectorPreference
var typeFaceHighlight: Int
var isNewList = true
val myDeviceId = mSession.sessionParams.credentials.deviceId

if (aDeviceInfoList.size == mDevicesNameList.size) {
isNewList = !mDevicesNameList.containsAll(aDeviceInfoList)
}

if (isNewList) {
var prefIndex = 0
mDevicesNameList = aDeviceInfoList

// sort before display: most recent first
mDevicesNameList.sortByLastSeen()

// start from scratch: remove the displayed ones
mDevicesListSettingsCategory.removeAll()

for (deviceInfo in mDevicesNameList) {
// set bold to distinguish current device ID
if (null != myDeviceId && myDeviceId == deviceInfo.deviceId) {
mMyDeviceInfo = deviceInfo
typeFaceHighlight = Typeface.BOLD
} else {
typeFaceHighlight = Typeface.NORMAL
}

// add the edit text preference
preference = VectorPreference(requireActivity()).apply {
mTypeface = typeFaceHighlight
}

if (null == deviceInfo.deviceId && null == deviceInfo.displayName) {
continue
} else {
if (null != deviceInfo.deviceId) {
preference.title = deviceInfo.deviceId
}

// display name parameter can be null (new JSON API)
if (null != deviceInfo.displayName) {
preference.summary = deviceInfo.displayName
}
}

preference.key = DEVICES_PREFERENCE_KEY_BASE + prefIndex
prefIndex++

// onClick handler: display device details dialog
preference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
displayDeviceDetailsDialog(deviceInfo)
true
}

mDevicesListSettingsCategory.addPreference(preference)
}

refreshCryptographyPreference(mMyDeviceInfo)
}
}

/**
* Display a dialog containing the device ID, the device name and the "last seen" information.<>
* This dialog allow to delete the corresponding device (see [.displayDeviceDeletionDialog])
*
* @param aDeviceInfo the device information
*/
private fun displayDeviceDetailsDialog(aDeviceInfo: DeviceInfo) {

activity?.let {

val builder = AlertDialog.Builder(it)
val inflater = it.layoutInflater
val layout = inflater.inflate(R.layout.dialog_device_details, null)
var textView = layout.findViewById<TextView>(R.id.device_id)

textView.text = aDeviceInfo.deviceId

// device name
textView = layout.findViewById(R.id.device_name)
val displayName = if (TextUtils.isEmpty(aDeviceInfo.displayName)) LABEL_UNAVAILABLE_DATA else aDeviceInfo.displayName
textView.text = displayName

// last seen info
textView = layout.findViewById(R.id.device_last_seen)

val lastSeenIp = aDeviceInfo.lastSeenIp?.takeIf { ip -> ip.isNotBlank() } ?: "-"

val lastSeenTime = aDeviceInfo.lastSeenTs?.let { ts ->
val dateFormatTime = SimpleDateFormat("HH:mm:ss")
val date = Date(ts)

val time = dateFormatTime.format(date)
val dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault())

dateFormat.format(date) + ", " + time
} ?: "-"

val lastSeenInfo = getString(R.string.devices_details_last_seen_format, lastSeenIp, lastSeenTime)
textView.text = lastSeenInfo

// title & icon
builder.setTitle(R.string.devices_details_dialog_title)
.setIcon(android.R.drawable.ic_dialog_info)
.setView(layout)
.setPositiveButton(R.string.rename) { _, _ -> displayDeviceRenameDialog(aDeviceInfo) }

// disable the deletion for our own device
if (!TextUtils.equals(mSession.getMyDevice()?.deviceId, aDeviceInfo.deviceId)) {
builder.setNegativeButton(R.string.delete) { _, _ -> deleteDevice(aDeviceInfo) }
}

builder.setNeutralButton(R.string.cancel, null)
.setOnKeyListener(DialogInterface.OnKeyListener { dialog, keyCode, event ->
if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
dialog.cancel()
return@OnKeyListener true
}
false
})
.show()
}
}

/**
* Display an alert dialog to rename a device
*
* @param aDeviceInfoToRename device info
*/
private fun displayDeviceRenameDialog(aDeviceInfoToRename: DeviceInfo) {
activity?.let {
val inflater = it.layoutInflater
val layout = inflater.inflate(R.layout.dialog_base_edit_text, null)

val input = layout.findViewById<EditText>(R.id.edit_text)
input.setText(aDeviceInfoToRename.displayName)

AlertDialog.Builder(it)
.setTitle(R.string.devices_details_device_name)
.setView(layout)
.setPositiveButton(R.string.ok) { _, _ ->
displayLoadingView()

val newName = input.text.toString()

mSession.setDeviceName(aDeviceInfoToRename.deviceId!!, newName, object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
hideLoadingView()

// search which preference is updated
val count = mDevicesListSettingsCategory.preferenceCount

for (i in 0 until count) {
val pref = mDevicesListSettingsCategory.getPreference(i)

if (TextUtils.equals(aDeviceInfoToRename.deviceId, pref.title)) {
pref.summary = newName
}
}

// detect if the updated device is the current account one
if (TextUtils.equals(cryptoInfoDeviceIdPreference.summary, aDeviceInfoToRename.deviceId)) {
cryptoInfoDeviceNamePreference.summary = newName
}

// Also change the display name in aDeviceInfoToRename, in case of multiple renaming
aDeviceInfoToRename.displayName = newName
}

override fun onFailure(failure: Throwable) {
onCommonDone(failure.localizedMessage)
}
})
}
.setNegativeButton(R.string.cancel, null)
.show()
}
}

/**
* Try to delete a device.
*
* @param deviceInfo the device to delete
*/
private fun deleteDevice(deviceInfo: DeviceInfo) {
val deviceId = deviceInfo.deviceId
if (deviceId == null) {
Timber.e("## displayDeviceDeletionDialog(): sanity check failure")
return
}

displayLoadingView()
mSession.deleteDevice(deviceId, object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
hideLoadingView()
// force settings update
refreshDevicesList()
}

override fun onFailure(failure: Throwable) {
var isPasswordRequestFound = false

if (failure is Failure.RegistrationFlowError) {
// We only support LoginFlowTypes.PASSWORD
// Check if we can provide the user password
failure.registrationFlowResponse.flows?.forEach { interactiveAuthenticationFlow ->
isPasswordRequestFound = isPasswordRequestFound || interactiveAuthenticationFlow.stages?.any { it == LoginFlowTypes.PASSWORD } == true
}

if (isPasswordRequestFound) {
maybeShowDeleteDeviceWithPasswordDialog(deviceId, failure.registrationFlowResponse.session)
}

}

if (!isPasswordRequestFound) {
// LoginFlowTypes.PASSWORD not supported, and this is the only one RiotX supports so far...
onCommonDone(failure.localizedMessage)
}
}
})
}

/**
* Show a dialog to ask for user password, or use a previously entered password.
*/
private fun maybeShowDeleteDeviceWithPasswordDialog(deviceId: String, authSession: String?) {
if (!TextUtils.isEmpty(mAccountPassword)) {
deleteDeviceWithPassword(deviceId, authSession, mAccountPassword)
} else {
activity?.let {
val inflater = it.layoutInflater
val layout = inflater.inflate(R.layout.dialog_device_delete, null)
val passwordEditText = layout.findViewById<EditText>(R.id.delete_password)

AlertDialog.Builder(it)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.devices_delete_dialog_title)
.setView(layout)
.setPositiveButton(R.string.devices_delete_submit_button_label, DialogInterface.OnClickListener { _, _ ->
if (TextUtils.isEmpty(passwordEditText.toString())) {
it.toast(R.string.error_empty_field_your_password)
return@OnClickListener
}
mAccountPassword = passwordEditText.text.toString()
deleteDeviceWithPassword(deviceId, authSession, mAccountPassword)
})
.setNegativeButton(R.string.cancel) { _, _ ->
hideLoadingView()
}
.setOnKeyListener(DialogInterface.OnKeyListener { dialog, keyCode, event ->
if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
dialog.cancel()
hideLoadingView()
return@OnKeyListener true
}
false
})
.show()
}
}
}

private fun deleteDeviceWithPassword(deviceId: String, authSession: String?, accountPassword: String) {
mSession.deleteDeviceWithUserPassword(deviceId, authSession, accountPassword, object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
hideLoadingView()
// force settings update
refreshDevicesList()
}

override fun onFailure(failure: Throwable) {
// Password is maybe not good
onCommonDone(failure.localizedMessage)
mAccountPassword = ""
}
})
}

//==============================================================================================================
// pushers list management
//==============================================================================================================

/**
* Refresh the pushers list
*/
private fun refreshPushersList() {
activity?.let { activity ->
/* TODO
val pushManager = Matrix.getInstance(activity).pushManager
val pushersList = ArrayList(pushManager.mPushersList)

if (pushersList.isEmpty()) {
preferenceScreen.removePreference(mPushersSettingsCategory)
preferenceScreen.removePreference(mPushersSettingsDivider)
return
}

// check first if there is an update
var isNewList = true
if (pushersList.size == mDisplayedPushers.size) {
isNewList = !mDisplayedPushers.containsAll(pushersList)
}

if (isNewList) {
// remove the displayed one
mPushersSettingsCategory.removeAll()

// add new emails list
mDisplayedPushers = pushersList

var index = 0

for (pushRule in mDisplayedPushers) {
if (null != pushRule.lang) {
val isThisDeviceTarget = TextUtils.equals(pushManager.currentRegistrationToken, pushRule.pushkey)

val preference = VectorPreference(activity).apply {
mTypeface = if (isThisDeviceTarget) Typeface.BOLD else Typeface.NORMAL
}
preference.title = pushRule.deviceDisplayName
preference.summary = pushRule.appDisplayName
preference.key = PUSHER_PREFERENCE_KEY_BASE + index
index++
mPushersSettingsCategory.addPreference(preference)

// the user cannot remove the self device target
if (!isThisDeviceTarget) {
preference.onPreferenceLongClickListener = object : VectorPreference.OnPreferenceLongClickListener {
override fun onPreferenceLongClick(preference: Preference): Boolean {
AlertDialog.Builder(activity)
.setTitle(R.string.dialog_title_confirmation)
.setMessage(R.string.settings_delete_notification_targets_confirmation)
.setPositiveButton(R.string.remove)
{ _, _ ->
displayLoadingView()
pushManager.unregister(session, pushRule, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
refreshPushersList()
onCommonDone(null)
}

override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}

override fun onMatrixError(e: MatrixError) {
onCommonDone(e.localizedMessage)
}

override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
}
.setNegativeButton(R.string.cancel, null)
.show()
return true
}
}
}
}
}
}
*/
}
}

companion object {
private const val REQUEST_E2E_FILE_REQUEST_CODE = 123

private const val PUSHER_PREFERENCE_KEY_BASE = "PUSHER_PREFERENCE_KEY_BASE"
private const val DEVICES_PREFERENCE_KEY_BASE = "DEVICES_PREFERENCE_KEY_BASE"

// TODO i18n
private const val LABEL_UNAVAILABLE_DATA = "none"
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotredesign.features.settings

import android.app.Activity
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import androidx.preference.Preference
import androidx.preference.SwitchPreference
import im.vector.riotredesign.R
import im.vector.riotredesign.core.utils.getCallRingtoneName
import im.vector.riotredesign.core.utils.getCallRingtoneUri
import im.vector.riotredesign.core.utils.setCallRingtoneUri
import im.vector.riotredesign.core.utils.setUseRiotDefaultRingtone

class VectorSettingsVoiceVideo : VectorSettingsBaseFragment() {

override var titleRes = R.string.preference_voice_and_video
override val preferenceXmlRes = R.xml.vector_settings_voice_video

private val mUseRiotCallRingtonePreference by lazy {
findPreference(PreferencesManager.SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY) as SwitchPreference
}
private val mCallRingtonePreference by lazy {
findPreference(PreferencesManager.SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY)
}

override fun bindPref() {
// Incoming call sounds
mUseRiotCallRingtonePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
activity?.let { setUseRiotDefaultRingtone(it, mUseRiotCallRingtonePreference.isChecked) }
false
}

mCallRingtonePreference.let {
activity?.let { activity -> it.summary = getCallRingtoneName(activity) }
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
displayRingtonePicker()
false
}
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_CALL_RINGTONE -> {
val callRingtoneUri: Uri? = data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
val thisActivity = activity
if (callRingtoneUri != null && thisActivity != null) {
setCallRingtoneUri(thisActivity, callRingtoneUri)
mCallRingtonePreference.summary = getCallRingtoneName(thisActivity)
}
}
}
}
}


private fun displayRingtonePicker() {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.settings_call_ringtone_dialog_title))
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true)
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE)
activity?.let { putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, getCallRingtoneUri(it)) }
}
startActivityForResult(intent, REQUEST_CALL_RINGTONE)
}

companion object {
private const val REQUEST_CALL_RINGTONE = 999
}

}

View File

@ -1,22 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:strokeWidth="1"
android:pathData="M7,7m-1.636,0a1.636,1.636 0,1 1,3.272 0a1.636,1.636 0,1 1,-3.272 0"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#454545"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M11.036,8.636a0.9,0.9 0,0 0,0.18 0.993l0.033,0.033a1.09,1.09 0,1 1,-1.544 1.543l-0.032,-0.032a0.9,0.9 0,0 0,-0.993 -0.18,0.9 0.9,0 0,0 -0.545,0.823v0.093a1.09,1.09 0,1 1,-2.182 0v-0.049a0.9,0.9 0,0 0,-0.59 -0.824,0.9 0.9,0 0,0 -0.992,0.18l-0.033,0.033a1.09,1.09 0,1 1,-1.543 -1.544l0.032,-0.032a0.9,0.9 0,0 0,0.18 -0.993,0.9 0.9,0 0,0 -0.823,-0.545L2.09,8.135a1.09,1.09 0,1 1,0 -2.182h0.049a0.9,0.9 0,0 0,0.824 -0.59,0.9 0.9,0 0,0 -0.18,-0.992l-0.033,-0.033a1.09,1.09 0,1 1,1.544 -1.543l0.032,0.032a0.9,0.9 0,0 0,0.993 0.18h0.044a0.9,0.9 0,0 0,0.545 -0.823L5.908,2.09a1.09,1.09 0,0 1,2.182 0v0.049a0.9,0.9 0,0 0,0.545 0.824,0.9 0.9,0 0,0 0.993,-0.18l0.033,-0.033a1.09,1.09 0,1 1,1.543 1.544l-0.032,0.032a0.9,0.9 0,0 0,-0.18 0.993v0.044a0.9,0.9 0,0 0,0.823 0.545h0.093a1.09,1.09 0,1 1,0 2.182h-0.049a0.9,0.9 0,0 0,-0.824 0.545z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#454545"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="11dp"
android:height="14dp"
android:viewportWidth="11"
android:viewportHeight="14">
<path
android:strokeWidth="1"
android:pathData="M0.588,8.8s0.588,-0.6 2.353,-0.6c1.765,0 2.941,1.2 4.706,1.2C9.412,9.4 10,8.8 10,8.8V1.6s-0.588,0.6 -2.353,0.6C5.882,2.2 4.706,1 2.941,1c-1.765,0 -2.353,0.6 -2.353,0.6v7.2zM0.588,13V8.8"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#454545"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:pathData="M21,15.92v3a2,2 0,0 1,-2.18 2,19.79 19.79,0 0,1 -8.63,-3.07 19.5,19.5 0,0 1,-6 -6,19.79 19.79,0 0,1 -3.07,-8.67A2,2 0,0 1,3.11 1h3a2,2 0,0 1,2 1.72c0.127,0.96 0.361,1.903 0.7,2.81a2,2 0,0 1,-0.45 2.11L7.09,8.91a16,16 0,0 0,6 6l1.27,-1.27a2,2 0,0 1,2.11 -0.45c0.907,0.339 1.85,0.573 2.81,0.7A2,2 0,0 1,21 15.92z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,22 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="24">
<path
android:pathData="M8,8m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
<path
android:pathData="M4.21,13.89L3,23l5,-3 5,3 -1.21,-9.12"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,22 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,12m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
<path
android:pathData="M19.4,15a1.65,1.65 0,0 0,0.33 1.82l0.06,0.06a2,2 0,1 1,-2.83 2.83l-0.06,-0.06a1.65,1.65 0,0 0,-1.82 -0.33,1.65 1.65,0 0,0 -1,1.51L14.08,21a2,2 0,1 1,-4 0v-0.09A1.65,1.65 0,0 0,9 19.4a1.65,1.65 0,0 0,-1.82 0.33l-0.06,0.06a2,2 0,1 1,-2.83 -2.83l0.06,-0.06a1.65,1.65 0,0 0,0.33 -1.82,1.65 1.65,0 0,0 -1.51,-1L3,14.08a2,2 0,1 1,0 -4h0.09A1.65,1.65 0,0 0,4.6 9a1.65,1.65 0,0 0,-0.33 -1.82l-0.06,-0.06a2,2 0,1 1,2.83 -2.83l0.06,0.06a1.65,1.65 0,0 0,1.82 0.33L9,4.68a1.65,1.65 0,0 0,1 -1.51L10,3a2,2 0,1 1,4 0v0.09a1.65,1.65 0,0 0,1 1.51,1.65 1.65,0 0,0 1.82,-0.33l0.06,-0.06a2,2 0,1 1,2.83 2.83l-0.06,0.06a1.65,1.65 0,0 0,-0.33 1.82L19.32,9c0.26,0.604 0.852,0.997 1.51,1L21,10a2,2 0,1 1,0 4h-0.09a1.65,1.65 0,0 0,-1.51 1z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:pathData="M11,11m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#7E899C"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M8.09,8C8.5754,6.62 9.9854,5.7914 11.4272,6.0387C12.869,6.286 13.9222,7.5372 13.92,9C13.92,11 10.92,12 10.92,12"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#7E899C"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M11.0002,15.9913L11,15.9913"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#7E899C"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="20dp"
android:viewportWidth="17"
android:viewportHeight="20">
<path
android:pathData="M16,19v-2a4,4 0,0 0,-4 -4H5a4,4 0,0 0,-4 4v2"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
<path
android:pathData="M8.5,5m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
<path
android:pathData="M5.672,2.172l5.656,5.656"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="22dp"
android:viewportWidth="18"
android:viewportHeight="22">
<path
android:pathData="M1,14s1,-1 4,-1 5,2 8,2 4,-1 4,-1V2s-1,1 -4,1 -5,-2 -8,-2 -4,1 -4,1v12zM1,21v-7"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="20">
<path
android:pathData="M21,6v13H3V6M1,1h22v5H1zM10,10h4"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="22dp"
android:viewportWidth="20"
android:viewportHeight="22">
<path
android:pathData="M16,7A6,6 0,1 0,4 7c0,7 -3,9 -3,9h18s-3,-2 -3,-9M11.73,20a2,2 0,0 1,-3.46 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="20">
<path
android:pathData="M4,19v-7M4,8V1M12,19v-9M12,6V1M20,19v-5M20,10V1M1,12h6M9,6h6M17,14h6"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,22 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="22dp"
android:viewportWidth="20"
android:viewportHeight="22">
<path
android:pathData="M3,10L17,10A2,2 0,0 1,19 12L19,19A2,2 0,0 1,17 21L3,21A2,2 0,0 1,1 19L1,12A2,2 0,0 1,3 10z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
<path
android:pathData="M5,10L5,6a5,5 0,1 1,10 0v4"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#7E899C"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<!-- Created to detect what has to be implemented (especially in the settings) -->
<bool name="false_not_implemented">false</bool>

</resources>

View File

@ -28,6 +28,7 @@
<string name="push_gateway_item_url">Url:</string>
<string name="push_gateway_item_format">Format:</string>

<string name="preference_root_legacy">Legacy</string>
<string name="preference_voice_and_video">Voice &amp; Video</string>
<string name="preference_root_help_about">Help &amp; About</string>

</resources>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_GROUPS_FLAIR_KEY"
android:title="@string/settings_flair" />

</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen 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">


<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_USER_SETTINGS_PREFERENCE_KEY"
android:title="@string/settings_user_settings">

<im.vector.riotredesign.core.preference.UserAvatarPreference
android:key="SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY"
android:title="@string/settings_profile_picture" />

<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:key="SETTINGS_DISPLAY_NAME_PREFERENCE_KEY"
android:summary="@string/settings_display_name"
android:title="@string/settings_display_name" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY"
android:summary="@string/password_hint"
android:title="@string/settings_password" />

<!-- Email will be added here -->

<!-- Note: inputType does not work, it is set also in code, as well as iconTint -->
<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:icon="@drawable/ic_add_black"
android:inputType="textEmailAddress"
android:key="ADD_EMAIL_PREFERENCE_KEY"
android:order="100"
android:title="@string/settings_add_email_address"
app:iconTint="?attr/vctr_settings_icon_tint_color" />

<!-- Phone will be added here -->

<!-- Note: iconTint does not work, it is also done in code -->
<im.vector.riotredesign.core.preference.VectorPreference
android:icon="@drawable/ic_add_black"
android:key="ADD_PHONE_NUMBER_PREFERENCE_KEY"
android:order="200"
android:title="@string/settings_add_phone_number"
app:iconTint="?attr/vctr_settings_icon_tint_color" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CONTACT_PREFERENCE_KEYS"
android:title="@string/settings_contact">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="CONTACT_BOOK_ACCESS_KEY"
android:title="@string/settings_contacts_app_permission" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dialogTitle="@string/settings_select_country"
android:key="SETTINGS_CONTACTS_PHONEBOOK_COUNTRY_PREFERENCE_KEY"
android:title="@string/settings_contacts_phonebook_country" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory android:title="@string/settings_advanced">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_LOGGED_IN_PREFERENCE_KEY"
android:title="@string/settings_logged_in"
tools:summary="\@user:matrix.org" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_HOME_SERVER_PREFERENCE_KEY"
android:title="@string/settings_home_server"
tools:summary="@string/default_hs_server_url" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY"
android:title="@string/settings_identity_server"
tools:summary="@string/default_identity_server_url" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY"
android:title="@string/settings_clear_media_cache" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_CLEAR_CACHE_PREFERENCE_KEY"
android:title="@string/settings_clear_cache" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_DEACTIVATE_ACCOUNT_CATEGORY_KEY"
android:title="@string/settings_deactivate_account_section">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_DEACTIVATE_ACCOUNT_KEY"
android:title="@string/settings_deactivate_my_account" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_OTHERS_PREFERENCE_KEY"
android:title="@string/settings_other">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="APP_INFO_LINK_PREFERENCE_KEY"
android:summary="@string/settings_app_info_link_summary"
android:title="@string/settings_app_info_link_title" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_VERSION_PREFERENCE_KEY"
android:title="@string/settings_version"
tools:summary="1.2.3" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_SDK_VERSION_PREFERENCE_KEY"
android:title="@string/settings_sdk_version"
tools:summary="4.5.6" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_OLM_VERSION_PREFERENCE_KEY"
android:title="@string/settings_olm_version"
tools:summary="7.8.9" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_COPYRIGHT_PREFERENCE_KEY"
android:title="@string/settings_copyright" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY"
android:title="@string/settings_app_term_conditions" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY"
android:title="@string/settings_privacy_policy" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
android:title="@string/settings_third_party_notices" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
android:title="@string/settings_other_third_party_notices" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen 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">

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_IGNORED_USERS_PREFERENCE_KEY"
android:title="@string/settings_ignored_users" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY" />


</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen 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">

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_LABS_PREFERENCE_KEY"
android:title="@string/room_settings_labs_pref_title">

<im.vector.riotredesign.core.preference.VectorPreference
android:focusable="false"
android:key="labs_warning"
android:title="@string/room_settings_labs_warning_message" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY"
android:title="@string/room_settings_labs_end_to_end" />

<im.vector.riotredesign.core.preference.VectorPreference
android:focusable="false"
android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY"
android:title="@string/room_settings_labs_end_to_end_is_active" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY"
android:summary="@string/settings_data_save_mode_summary"
android:title="@string/settings_data_save_mode" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_USE_JITSI_CONF_PREFERENCE_KEY"
android:title="@string/settings_labs_create_conference_with_jitsi" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY"
android:summary="@string/settings_labs_enable_send_voice_summary"
android:title="@string/settings_labs_enable_send_voice" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

</androidx.preference.PreferenceScreen>

View File

@ -2,34 +2,34 @@
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<!--<im.vector.riotredesign.core.preference.VectorSwitchPreference-->
<!--android:key="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"-->
<!--android:title="@string/settings_enable_all_notif" />-->
<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_NOTIFICATIONS_KEY"
android:title="@string/settings_notifications">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
android:defaultValue="true"
android:key="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
android:title="@string/settings_enable_all_notif" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
android:key="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
android:title="@string/settings_enable_this_device" />
<!--android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"-->

<!--<im.vector.riotredesign.core.preference.VectorSwitchPreference-->
<!--android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"-->
<!--android:key="SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY"-->
<!--android:title="@string/settings_turn_screen_on" />-->

<!--<im.vector.riotredesign.core.preference.VectorPreference-->
<!--android:dialogTitle="@string/settings_notification_privacy"-->
<!--android:key="SETTINGS_NOTIFICATION_PRIVACY_PREFERENCE_KEY"-->
<!--android:title="@string/settings_notification_privacy" />-->
<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
android:key="SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY"
android:title="@string/settings_turn_screen_on" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
android:enabled="false"
android:key="SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY"
android:persistent="false"
android:visibility="gone"
android:summary="@string/settings_notification_advanced_summary"
android:title="@string/settings_notification_advanced"
android:enabled="false"
android:visibility="gone"
app:fragment="im.vector.fragments.VectorSettingsNotificationsAdvancedFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
@ -37,19 +37,58 @@
android:title="@string/settings_notification_troubleshoot"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsNotificationsTroubleshootFragment" />

<PreferenceCategory android:title="@string/settings_expert">
</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<!--im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY"
android:title="@string/settings_background_sync">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_START_ON_BOOT_PREFERENCE_KEY"
android:title="@string/settings_start_on_boot" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY"
android:title="@string/settings_enable_background_sync" />

<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:dependency="SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY"
android:key="SETTINGS_SET_SYNC_TIMEOUT_PREFERENCE_KEY"
android:numeric="integer"
android:title="@string/settings_set_sync_timeout" />

<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:dependency="SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY"
android:key="SETTINGS_SET_SYNC_DELAY_PREFERENCE_KEY"
android:numeric="integer"
android:title="@string/settings_set_sync_delay" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY"
android:title="@string/settings_notifications_targets" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY" /-->

<im.vector.riotredesign.core.preference.VectorPreferenceCategory android:title="@string/settings_expert">

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:title="@string/settings_notifications_targets"
android:persistent="false"
android:title="@string/settings_notifications_targets"
app:fragment="im.vector.riotredesign.features.settings.push.PushGatewaysFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:title="@string/settings_push_rules"
android:persistent="false"
android:title="@string/settings_push_rules"
app:fragment="im.vector.riotredesign.features.settings.push.PushRulesFragment" />

</PreferenceCategory>
</im.vector.riotredesign.core.preference.VectorPreferenceCategory>
</androidx.preference.PreferenceScreen>

373
vector/src/main/res/xml/vector_settings_preferences.xml Executable file → Normal file
View File

@ -1,67 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen 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">
xmlns:app="http://schemas.android.com/apk/res-auto">

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_USER_SETTINGS_PREFERENCE_KEY"
android:title="@string/settings_user_settings">

<im.vector.riotredesign.core.preference.UserAvatarPreference
android:key="SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY"
android:title="@string/settings_profile_picture" />

<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:key="SETTINGS_DISPLAY_NAME_PREFERENCE_KEY"
android:summary="@string/settings_display_name"
android:title="@string/settings_display_name" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY"
android:summary="@string/password_hint"
android:title="@string/settings_password" />

<!-- Email will be added here -->

<!-- Note: inputType does not work, it is set also in code, as well as iconTint -->
<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:icon="@drawable/ic_add_black"
android:inputType="textEmailAddress"
android:key="ADD_EMAIL_PREFERENCE_KEY"
android:order="100"
android:title="@string/settings_add_email_address"
app:iconTint="?attr/vctr_settings_icon_tint_color" />

<!-- Phone will be added here -->

<!-- Note: iconTint does not work, it is also done in code -->
<im.vector.riotredesign.core.preference.VectorPreference
android:icon="@drawable/ic_add_black"
android:key="ADD_PHONE_NUMBER_PREFERENCE_KEY"
android:order="200"
android:title="@string/settings_add_phone_number"
app:iconTint="?attr/vctr_settings_icon_tint_color" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CONTACT_PREFERENCE_KEYS"
android:title="@string/settings_contact">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="CONTACT_BOOK_ACCESS_KEY"
android:title="@string/settings_contacts_app_permission" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dialogTitle="@string/settings_select_country"
android:key="SETTINGS_CONTACTS_PHONEBOOK_COUNTRY_PREFERENCE_KEY"
android:title="@string/settings_contacts_phonebook_country" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_USER_INTERFACE_KEY"
@ -168,89 +108,12 @@

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_GROUPS_FLAIR_KEY"
android:title="@string/settings_flair" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_NOTIFICATIONS_KEY"
android:title="@string/settings_notifications">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
android:title="@string/settings_enable_all_notif" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
android:key="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
android:title="@string/settings_enable_this_device" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
android:key="SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY"
android:title="@string/settings_turn_screen_on" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dialogTitle="@string/settings_notification_privacy"
android:key="SETTINGS_NOTIFICATION_PRIVACY_PREFERENCE_KEY"
android:title="@string/settings_notification_privacy" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
android:key="SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_notification_advanced_summary"
android:title="@string/settings_notification_advanced"
app:fragment="im.vector.fragments.VectorSettingsNotificationsAdvancedFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY"
android:title="@string/settings_notification_troubleshoot"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsNotificationsTroubleshootFragment" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY"
android:title="@string/settings_background_sync">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_START_ON_BOOT_PREFERENCE_KEY"
android:title="@string/settings_start_on_boot" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY"
android:title="@string/settings_enable_background_sync" />

<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:dependency="SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY"
android:key="SETTINGS_SET_SYNC_TIMEOUT_PREFERENCE_KEY"
android:numeric="integer"
android:title="@string/settings_set_sync_timeout" />

<im.vector.riotredesign.core.preference.VectorEditTextPreference
android:dependency="SETTINGS_ENABLE_BACKGROUND_SYNC_PREFERENCE_KEY"
android:key="SETTINGS_SET_SYNC_DELAY_PREFERENCE_KEY"
android:numeric="integer"
android:title="@string/settings_set_sync_delay" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY"
android:title="@string/settings_notifications_targets" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory android:title="@string/settings_media">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_MEDIA_SAVING_PERIOD_KEY"
android:title="@string/settings_keep_media" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY"
android:summary="@string/settings_labs_native_camera_summary"
@ -284,230 +147,4 @@

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory android:title="@string/settings_call_category">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:disableDependentsState="true"
android:key="SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY"
android:title="@string/settings_call_ringtone_use_riot_ringtone" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dependency="SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY"
android:key="SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY"
android:title="@string/settings_call_ringtone_title" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_IGNORED_USERS_PREFERENCE_KEY"
android:title="@string/settings_ignored_users" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_LABS_PREFERENCE_KEY"
android:title="@string/room_settings_labs_pref_title">

<im.vector.riotredesign.core.preference.VectorPreference
android:focusable="false"
android:key="labs_warning"
android:title="@string/room_settings_labs_warning_message" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY"
android:title="@string/room_settings_labs_end_to_end" />

<im.vector.riotredesign.core.preference.VectorPreference
android:focusable="false"
android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY"
android:title="@string/room_settings_labs_end_to_end_is_active" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY"
android:summary="@string/settings_data_save_mode_summary"
android:title="@string/settings_data_save_mode" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:key="SETTINGS_USE_JITSI_CONF_PREFERENCE_KEY"
android:title="@string/settings_labs_create_conference_with_jitsi" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY"
android:summary="@string/settings_labs_enable_send_voice_summary"
android:title="@string/settings_labs_enable_send_voice" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<!-- ************ Cryptography section ************ -->
<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CRYPTOGRAPHY_PREFERENCE_KEY"
android:title="@string/settings_cryptography">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY"
android:title="@string/encryption_information_device_name" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY"
android:title="@string/encryption_information_device_id" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_KEY_PREFERENCE_KEY"
android:title="@string/encryption_information_device_key" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY"
android:summary="@string/encryption_never_send_to_unverified_devices_summary"
android:title="@string/encryption_never_send_to_unverified_devices_title" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_CRYPTOGRAPHY_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CRYPTOGRAPHY_MANAGE_PREFERENCE_KEY"
android:title="@string/settings_cryptography_manage_keys">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/encryption_settings_manage_message_recovery_summary"
android:title="@string/encryption_message_recovery" />
<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
android:summary="@string/encryption_export_room_keys_summary"
android:title="@string/encryption_export_e2e_room_keys" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
android:summary="@string/encryption_import_room_keys_summary"
android:title="@string/encryption_import_e2e_room_keys" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_CRYPTOGRAPHY_MANAGE_DIVIDER_PREFERENCE_KEY" />

<!-- devices list: device ids + device names -->
<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_DEVICES_LIST_PREFERENCE_KEY"
android:title="@string/settings_devices_list" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_DEVICES_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory android:title="@string/settings_advanced">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_LOGGED_IN_PREFERENCE_KEY"
android:title="@string/settings_logged_in"
tools:summary="\@user:matrix.org" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_HOME_SERVER_PREFERENCE_KEY"
android:title="@string/settings_home_server"
tools:summary="@string/default_hs_server_url" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY"
android:title="@string/settings_identity_server"
tools:summary="@string/default_identity_server_url" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_ANALYTICS_PREFERENCE_KEY"
android:title="@string/settings_analytics">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:key="SETTINGS_USE_ANALYTICS_KEY"
android:summary="@string/settings_opt_in_of_analytics_summary"
android:title="@string/settings_opt_in_of_analytics" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_USE_RAGE_SHAKE_KEY"
android:title="@string/send_bug_report_rage_shake" />
</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_OTHERS_PREFERENCE_KEY"
android:title="@string/settings_other">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="APP_INFO_LINK_PREFERENCE_KEY"
android:summary="@string/settings_app_info_link_summary"
android:title="@string/settings_app_info_link_title" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_VERSION_PREFERENCE_KEY"
android:title="@string/settings_version"
tools:summary="1.2.3" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_SDK_VERSION_PREFERENCE_KEY"
android:title="@string/settings_sdk_version"
tools:summary="4.5.6" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_OLM_VERSION_PREFERENCE_KEY"
android:title="@string/settings_olm_version"
tools:summary="7.8.9" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_COPYRIGHT_PREFERENCE_KEY"
android:title="@string/settings_copyright" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY"
android:title="@string/settings_app_term_conditions" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY"
android:title="@string/settings_privacy_policy" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
android:title="@string/settings_third_party_notices" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
android:title="@string/settings_other_third_party_notices" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_MEDIA_SAVING_PERIOD_KEY"
android:title="@string/settings_keep_media" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY"
android:title="@string/settings_clear_media_cache" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_CLEAR_CACHE_PREFERENCE_KEY"
android:title="@string/settings_clear_cache" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_DEACTIVATE_ACCOUNT_CATEGORY_KEY"
android:title="@string/settings_deactivate_account_section">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_DEACTIVATE_ACCOUNT_KEY"
android:title="@string/settings_deactivate_my_account" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

</androidx.preference.PreferenceScreen>

View File

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_general"
android:title="@string/settings_general_title"
app:fragment="com.example.SyncFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_flair"
android:title="@string/settings_flair"
app:fragment="com.example.SyncFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_bell"
android:key="SETTINGS_NOTIFICATIONS_KEY"
android:title="@string/settings_notifications"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsNotificationPreferenceFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_sliders"
android:title="@string/settings_preferences"
app:fragment="com.example.SyncFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_lock"
android:title="@string/settings_security_and_privacy"
app:fragment="com.example.SyncFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_lab"
android:title="@string/room_settings_labs_pref_title"
app:fragment="com.example.SyncFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_devices_info"
android:title="@string/preference_root_legacy"
app:fragment="com.example.SyncFragment" />

</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_root_general"
android:title="@string/settings_general_title"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsGeneral" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:enabled="@bool/false_not_implemented"
android:icon="@drawable/ic_settings_root_flair"
android:title="@string/settings_flair"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsFlair" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_root_notification"
android:key="SETTINGS_NOTIFICATIONS_KEY"
android:title="@string/settings_notifications"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsNotificationPreferenceFragment" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_root_preferences"
android:title="@string/settings_preferences"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsPreferences" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:enabled="@bool/false_not_implemented"
android:icon="@drawable/ic_settings_root_call"
android:title="@string/preference_voice_and_video"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsVoiceVideo" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:enabled="@bool/false_not_implemented"
android:icon="@drawable/ic_settings_root_ignored_users"
android:title="@string/settings_ignored_users"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsIgnoredUsers" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_root_security_privacy"
android:title="@string/settings_security_and_privacy"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsSecurityPrivacy" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_root_labs"
android:title="@string/room_settings_labs_pref_title"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsLabs" />

<im.vector.riotredesign.core.preference.VectorPreference
android:layout_width="match_parent"
android:icon="@drawable/ic_settings_root_help_about"
android:title="@string/preference_root_help_about"
app:fragment="im.vector.riotredesign.features.settings.VectorSettingsHelpAbout" />

</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<!-- ************ Cryptography section ************ -->
<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CRYPTOGRAPHY_PREFERENCE_KEY"
android:title="@string/settings_cryptography">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY"
android:title="@string/encryption_information_device_name" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY"
android:title="@string/encryption_information_device_id" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_KEY_PREFERENCE_KEY"
android:title="@string/encryption_information_device_key" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY"
android:summary="@string/encryption_never_send_to_unverified_devices_summary"
android:title="@string/encryption_never_send_to_unverified_devices_title" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_CRYPTOGRAPHY_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CRYPTOGRAPHY_MANAGE_PREFERENCE_KEY"
android:title="@string/settings_cryptography_manage_keys">

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/encryption_settings_manage_message_recovery_summary"
android:title="@string/encryption_message_recovery" />
<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
android:summary="@string/encryption_export_room_keys_summary"
android:title="@string/encryption_export_e2e_room_keys" />

<im.vector.riotredesign.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
android:summary="@string/encryption_import_room_keys_summary"
android:title="@string/encryption_import_e2e_room_keys" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_CRYPTOGRAPHY_MANAGE_DIVIDER_PREFERENCE_KEY" />

<!-- devices list: device ids + device names -->
<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_DEVICES_LIST_PREFERENCE_KEY"
android:title="@string/settings_devices_list" />

<im.vector.riotredesign.core.preference.VectorPreferenceDivider android:key="SETTINGS_DEVICES_DIVIDER_PREFERENCE_KEY" />

<im.vector.riotredesign.core.preference.VectorPreferenceCategory
android:key="SETTINGS_ANALYTICS_PREFERENCE_KEY"
android:title="@string/settings_analytics">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:key="SETTINGS_USE_ANALYTICS_KEY"
android:summary="@string/settings_opt_in_of_analytics_summary"
android:title="@string/settings_opt_in_of_analytics" />

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_USE_RAGE_SHAKE_KEY"
android:title="@string/send_bug_report_rage_shake" />
</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen 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">

<im.vector.riotredesign.core.preference.VectorPreferenceCategory android:title="@string/settings_call_category">

<im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true"
android:disableDependentsState="true"
android:key="SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY"
android:title="@string/settings_call_ringtone_use_riot_ringtone" />

<im.vector.riotredesign.core.preference.VectorPreference
android:dependency="SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY"
android:key="SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY"
android:title="@string/settings_call_ringtone_title" />

</im.vector.riotredesign.core.preference.VectorPreferenceCategory>

</androidx.preference.PreferenceScreen>