Added country picker for assistant's account register

This commit is contained in:
Sylvain Berfini 2023-09-08 11:05:47 +02:00
parent f4b6deb06a
commit 16a467b7d1
6 changed files with 312 additions and 3 deletions

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.assistant.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Filter
import android.widget.Filterable
import android.widget.TextView
import kotlin.collections.ArrayList
import org.linphone.R
import org.linphone.core.DialPlan
import org.linphone.core.Factory
class CountryPickerAdapter : BaseAdapter(), Filterable {
private var countries: ArrayList<DialPlan>
init {
val dialPlans = Factory.instance().dialPlans
countries = arrayListOf()
countries.addAll(dialPlans)
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: View = convertView ?: LayoutInflater.from(parent.context).inflate(
R.layout.assistant_country_picker_cell,
parent,
false
)
val dialPlan: DialPlan = countries[position]
val name = view.findViewById<TextView>(R.id.country_name)
name.text = dialPlan.country
val dialCode = view.findViewById<TextView>(R.id.country_prefix)
dialCode.text = String.format("(%s)", dialPlan.countryCallingCode)
view.tag = dialPlan
return view
}
override fun getItem(position: Int): DialPlan {
return countries[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return countries.size
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence): FilterResults {
val filteredCountries = arrayListOf<DialPlan>()
for (dialPlan in Factory.instance().dialPlans) {
if (dialPlan.country.contains(constraint, ignoreCase = true) ||
dialPlan.countryCallingCode.contains(constraint)
) {
filteredCountries.add(dialPlan)
}
}
val filterResults = FilterResults()
filterResults.values = filteredCountries
return filterResults
}
@Suppress("UNCHECKED_CAST")
override fun publishResults(
constraint: CharSequence,
results: FilterResults
) {
countries = results.values as ArrayList<DialPlan>
notifyDataSetChanged()
}
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.assistant.fragment
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.*
import androidx.annotation.UiThread
import androidx.fragment.app.DialogFragment
import org.linphone.R
import org.linphone.core.DialPlan
import org.linphone.databinding.AssistantCountryPickerFragmentBinding
import org.linphone.ui.assistant.adapter.CountryPickerAdapter
@UiThread
class CountryPickerFragment : DialogFragment() {
private var _binding: AssistantCountryPickerFragmentBinding? = null
private val binding get() = _binding!!
private lateinit var adapter: CountryPickerAdapter
var listener: CountryPickedListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.Theme_LinphoneDialog)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = AssistantCountryPickerFragmentBinding.inflate(inflater, container, false)
adapter = CountryPickerAdapter()
binding.countryList.adapter = adapter
binding.countryList.setOnItemClickListener { _, _, position, _ ->
if (position >= 0 && position < adapter.count) {
val dialPlan = adapter.getItem(position)
listener?.onCountryClicked(dialPlan)
}
dismiss()
}
binding.searchCountry.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
adapter.filter.filter(s)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
})
binding.setCancelClickListener {
dismiss()
}
return binding.root
}
interface CountryPickedListener {
fun onCountryClicked(dialPlan: DialPlan)
}
}

View file

@ -79,7 +79,9 @@ class RegisterFragment : Fragment() {
}
binding.setShowCountryPickerClickListener {
// TODO FIXME
val countryPickerFragment = CountryPickerFragment()
countryPickerFragment.listener = viewModel
countryPickerFragment.show(childFragmentManager, "CountryPicker")
}
binding.setOpenSubscribeWebPageClickListener {

View file

@ -33,14 +33,17 @@ import kotlinx.coroutines.withContext
import org.json.JSONException
import org.json.JSONObject
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.core.AccountCreator
import org.linphone.core.AccountCreatorListenerStub
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub
import org.linphone.core.DialPlan
import org.linphone.core.tools.Log
import org.linphone.ui.assistant.fragment.CountryPickerFragment
import org.linphone.utils.Event
class AccountCreationViewModel @UiThread constructor() : ViewModel() {
class AccountCreationViewModel @UiThread constructor() : ViewModel(), CountryPickerFragment.CountryPickedListener {
companion object {
private const val TAG = "[Account Creation ViewModel]"
}
@ -238,6 +241,11 @@ class AccountCreationViewModel @UiThread constructor() : ViewModel() {
}
}
@UiThread
override fun onCountryClicked(dialPlan: DialPlan) {
internationalPrefix.value = "+${dialPlan.countryCallingCode}"
}
@UiThread
override fun onCleared() {
coreContext.postOnCoreThread { core ->
@ -318,10 +326,11 @@ class AccountCreationViewModel @UiThread constructor() : ViewModel() {
private fun checkUsername() {
usernameError.postValue("")
accountCreator.username = username.value.orEmpty().trim()
accountCreator.domain = corePreferences.defaultDomain
operationInProgress.postValue(true)
val status = accountCreator.isAccountExist
Log.i("$TAG isAccountExist returned $status")
Log.i("$TAG isAccountExist for username [${accountCreator.username}] returned $status")
if (status != AccountCreator.Status.RequestOk) {
Log.e("$TAG Can't check if account already exists [$status]")
operationInProgress.postValue(false)

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:orientation="horizontal"
android:padding="5dp">
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/country_name"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/country_prefix"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="5dp" />
</LinearLayout>

View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View"/>
<variable
name="cancelClickListener"
type="android.view.View.OnClickListener"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center"
android:singleLine="true"
android:text="Choose your country"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<com.google.android.material.textfield.TextInputLayout
android:layout_toLeftOf="@id/clear_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Country name">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/search_country"
android:imeOptions="actionDone"
android:singleLine="true"
android:inputType="textPersonName"
android:background="@color/transparent_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="@+id/clear_field"
android:onClick="@{() -> searchCountry.setText(``)}"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:src="@drawable/x" />
</RelativeLayout>
<ListView
android:id="@+id/countryList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:cacheColorHint="@color/transparent_color"
android:divider="@color/blue_outgoing_message"
android:dividerHeight="1dp" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:onClick="@{cancelClickListener}"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cancel"
android:gravity="right" />
</LinearLayout>
</layout>