Added shortcuts to chat rooms if contacts shortcuts are disabled

This commit is contained in:
Sylvain Berfini 2020-04-06 12:41:36 +02:00
parent 339e30a75e
commit 0710256695
12 changed files with 173 additions and 16 deletions

View file

@ -57,9 +57,11 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
private val listener = object : ContactsUpdatedListenerStub() {
override fun onContactsUpdated() {
Log.i("[Main Activity] Contact(s) updated, update shortcuts")
if (corePreferences.contactsShortcuts) {
Log.i("[Main Activity] Contact(s) updated, update shortcuts")
Compatibility.createShortcutsToContacts(this@MainActivity)
} else if (corePreferences.chatRoomShortcuts) {
Compatibility.createShortcutsToChatRooms(this@MainActivity)
}
}
}
@ -89,8 +91,6 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
startActivity(intent)
}
if (intent != null) handleIntentParams(intent)
if (coreContext.core.proxyConfigList.isEmpty()) {
if (corePreferences.firstStart) {
corePreferences.firstStart = false
@ -122,6 +122,8 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
findNavController(R.id.nav_host_fragment).addOnDestinationChangedListener(this)
if (intent != null) handleIntentParams(intent)
}
override fun onDestroy() {
@ -194,8 +196,16 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
findNavController(R.id.nav_host_fragment).navigate(Uri.parse(deepLink))
}
intent.hasExtra("Chat") -> {
Log.i("[Main Activity] Found chat intent extra, go to chat rooms list")
findNavController(R.id.nav_host_fragment).navigate(R.id.action_global_masterChatRoomsFragment)
val deepLink = if (intent.hasExtra("RemoteSipUri") && intent.hasExtra("LocalSipUri")) {
val peerAddress = intent.getStringExtra("RemoteSipUri")
val localAddress = intent.getStringExtra("LocalSipUri")
Log.i("[Main Activity] Found chat room intent extra: local SIP URI=[$localAddress], peer SIP URI=[$peerAddress]")
"linphone-android://chat-room/$localAddress/$peerAddress"
} else {
Log.i("[Main Activity] Found chat intent extra, go to chat rooms list")
"linphone-android://chat/"
}
findNavController(R.id.nav_host_fragment).navigate(Uri.parse(deepLink))
}
intent.hasExtra("Dialer") -> {
Log.i("[Main Activity] Found dialer intent extra, go to dialer")

View file

@ -196,7 +196,7 @@ class MasterChatRoomsFragment : MasterFragment() {
val localSipUri = arguments?.getString("LocalSipUri")
val remoteSipUri = arguments?.getString("RemoteSipUri")
if (localSipUri != null && remoteSipUri != null) {
Log.i("[Chat] Found local ($localSipUri) & remote addresses ($remoteSipUri) in arguments")
Log.i("[Chat] Found local [$localSipUri] & remote [$remoteSipUri] addresses in arguments")
arguments?.clear()
val localAddress = Factory.instance().createAddress(localSipUri)
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)

View file

@ -24,10 +24,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.settings.viewmodels.ChatSettingsViewModel
import org.linphone.compatibility.Compatibility
import org.linphone.databinding.SettingsChatFragmentBinding
class ChatSettingsFragment : Fragment() {
@ -53,5 +55,15 @@ class ChatSettingsFragment : Fragment() {
binding.setBackClickListener { findNavController().popBackStack() }
binding.back.visibility = if (resources.getBoolean(R.bool.isTablet)) View.INVISIBLE else View.VISIBLE
viewModel.launcherShortcutsEvent.observe(viewLifecycleOwner, Observer {
it.consume { newValue ->
if (newValue) {
Compatibility.createShortcutsToChatRooms(requireContext())
} else {
Compatibility.removeShortcuts(requireContext())
}
}
})
}
}

View file

@ -27,6 +27,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.activities.main.settings.viewmodels.ContactsSettingsViewModel
import org.linphone.compatibility.Compatibility
@ -61,7 +62,10 @@ class ContactsSettingsFragment : Fragment() {
if (newValue) {
Compatibility.createShortcutsToContacts(requireContext())
} else {
Compatibility.removeShortcutsToContacts(requireContext())
Compatibility.removeShortcuts(requireContext())
if (corePreferences.chatRoomShortcuts) {
Compatibility.createShortcutsToChatRooms(requireContext())
}
}
}
})

View file

@ -21,6 +21,7 @@ package org.linphone.activities.main.settings.viewmodels
import androidx.lifecycle.MutableLiveData
import org.linphone.activities.main.settings.SettingListenerStub
import org.linphone.utils.Event
class ChatSettingsViewModel : GenericSettingsViewModel() {
val fileSharingUrlListener = object : SettingListenerStub() {
@ -37,6 +38,15 @@ class ChatSettingsViewModel : GenericSettingsViewModel() {
}
val downloadedImagesPublic = MutableLiveData<Boolean>()
val launcherShortcutsListener = object : SettingListenerStub() {
override fun onBoolValueChanged(newValue: Boolean) {
prefs.chatRoomShortcuts = newValue
launcherShortcutsEvent.value = Event(newValue)
}
}
val launcherShortcuts = MutableLiveData<Boolean>()
val launcherShortcutsEvent = MutableLiveData<Event<Boolean>>()
val hideEmptyRoomsListener = object : SettingListenerStub() {
override fun onBoolValueChanged(newValue: Boolean) {
prefs.hideEmptyRooms = newValue
@ -53,6 +63,7 @@ class ChatSettingsViewModel : GenericSettingsViewModel() {
init {
downloadedImagesPublic.value = prefs.makePublicDownloadedImages
launcherShortcuts.value = prefs.chatRoomShortcuts
hideEmptyRooms.value = prefs.hideEmptyRooms
hideRoomsRemovedProxies.value = prefs.hideRoomsFromRemovedProxies
fileSharingUrl.value = core.fileTransferServer

View file

@ -24,7 +24,7 @@ import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.os.Build
import android.provider.Settings
import org.linphone.contact.ShortcutsHelper
import org.linphone.utils.ShortcutsHelper
@TargetApi(25)
class Api25Compatibility {
@ -52,7 +52,11 @@ class Api25Compatibility {
ShortcutsHelper.createShortcutsToContacts(context)
}
fun removeShortcutsToContacts(context: Context) {
fun createShortcutsToChatRooms(context: Context) {
ShortcutsHelper.createShortcutsToChatRooms(context)
}
fun removeShortcuts(context: Context) {
ShortcutsHelper.removeShortcuts(context)
}
}

View file

@ -95,14 +95,20 @@ class Compatibility {
}
}
fun removeShortcutsToContacts(context: Context) {
fun removeShortcuts(context: Context) {
if (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
Api25Compatibility.removeShortcutsToContacts(context)
Api25Compatibility.removeShortcuts(context)
}
}
/* Chat */
fun createShortcutsToChatRooms(context: Context) {
if (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
Api25Compatibility.createShortcutsToChatRooms(context)
}
}
fun addImageToMediaStore(context: Context, content: Content): Boolean {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return Api29Compatibility.addImageToMediaStore(context, content)

View file

@ -108,6 +108,12 @@ class CorePreferences constructor(private val context: Context) {
get() = config.getString("app", "device_name", Compatibility.getDeviceName(context))
set(value) = config.setString("app", "device_name", value)
var chatRoomShortcuts: Boolean
get() = config.getBool("app", "chat_room_shortcuts", true)
set(value) {
config.setBool("app", "chat_room_shortcuts", value)
}
/* Contacts */
// TODO: use it
@ -124,9 +130,9 @@ class CorePreferences constructor(private val context: Context) {
}
var contactsShortcuts: Boolean
get() = config.getBool("app", "shortcuts", true)
get() = config.getBool("app", "contact_shortcuts", false)
set(value) {
config.setBool("app", "shortcuts", value)
config.setBool("app", "contact_shortcuts", value)
}
/* Call */

View file

@ -17,18 +17,25 @@
* 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.contact
package org.linphone.utils
import android.annotation.TargetApi
import android.content.Context
import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.os.Bundle
import androidx.collection.ArraySet
import androidx.core.app.Person
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.graphics.drawable.IconCompat
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.contact.Contact
import org.linphone.contact.NativeContact
import org.linphone.core.Address
import org.linphone.core.ChatRoom
import org.linphone.core.ChatRoomCapabilities
import org.linphone.core.tools.Log
@ -114,6 +121,90 @@ class ShortcutsHelper(val context: Context) {
return null
}
fun createShortcutsToChatRooms(context: Context) {
val shortcuts = ArrayList<ShortcutInfo>()
val shortcutManager = context.getSystemService(ShortcutManager::class.java)
if (shortcutManager.isRateLimitingActive) {
Log.e("[Shortcut Helper] Rate limiting is active, aborting")
return
}
val maxShortcuts = shortcutManager.maxShortcutCountPerActivity
var count = 0
for (room in coreContext.core.chatRooms) {
// Android can usually only have around 4-5 shortcuts at a time
if (count >= maxShortcuts) {
Log.w("[Shortcut Helper] Max amount of shortcuts reached ($count)")
break
}
val shortcut: ShortcutInfo? = createChatRoomShortcut(context, room)
if (shortcut != null) {
Log.i("[Shortcut Helper] Creating launcher shortcut for ${shortcut.shortLabel}")
shortcuts.add(shortcut)
count += 1
}
}
shortcutManager.dynamicShortcuts = shortcuts
}
private fun createChatRoomShortcut(context: Context, chatRoom: ChatRoom): ShortcutInfo? {
try {
val categories: ArraySet<String> = ArraySet()
categories.add(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION)
val peerAddress = chatRoom.peerAddress.asStringUriOnly()
val localAddress = chatRoom.localAddress.asStringUriOnly()
val personsList = arrayListOf<Person>()
var subject = ""
var icon: IconCompat
if (chatRoom.hasCapability(ChatRoomCapabilities.Basic.toInt())) {
val contact =
coreContext.contactsManager.findContactByAddress(chatRoom.peerAddress)
if (contact != null) {
personsList.add(contact.getPerson())
}
subject = contact?.fullName ?: LinphoneUtils.getDisplayName(chatRoom.peerAddress)
icon = contact?.getPerson()?.icon ?: IconCompat.createWithResource(context, R.drawable.avatar)
} else {
for (participant in chatRoom.participants) {
val contact =
coreContext.contactsManager.findContactByAddress(participant.address)
if (contact != null) {
personsList.add(contact.getPerson())
}
}
subject = chatRoom.subject
icon = IconCompat.createWithResource(context, R.drawable.chat_group_avatar)
}
val persons = arrayOfNulls<Person>(personsList.size)
personsList.toArray(persons)
val args = Bundle()
args.putString("RemoteSipUri", peerAddress)
args.putString("LocalSipUri", localAddress)
val intent = Intent(Intent.ACTION_MAIN)
intent.setClass(context, MainActivity::class.java)
intent.putExtra("Chat", true)
intent.putExtra("RemoteSipUri", peerAddress)
intent.putExtra("LocalSipUri", localAddress)
return ShortcutInfoCompat.Builder(context, "$localAddress#$peerAddress")
.setShortLabel(subject)
.setIcon(icon)
.setPersons(persons)
.setCategories(categories)
.setIntent(intent)
.build().toShortcutInfo()
} catch (e: Exception) {
Log.e("[Shortcuts Helper] ShortcutInfo.Builder exception: $e")
}
return null
}
fun removeShortcuts(context: Context) {
Log.w("[Shortcut Helper] Removing all contacts shortcuts")
val shortcutManager = context.getSystemService(ShortcutManager::class.java)

View file

@ -80,6 +80,13 @@
linphone:listener="@{viewModel.downloadedImagesPublicListener}"
linphone:checked="@={viewModel.downloadedImagesPublic}"/>
<include
layout="@layout/settings_widget_switch"
linphone:title="@{@string/chat_settings_launcher_shortcuts_title}"
linphone:subtitle="@{@string/chat_settings_launcher_shortcuts_summary}"
linphone:listener="@{viewModel.launcherShortcutsListener}"
linphone:checked="@={viewModel.launcherShortcuts}"/>
<include
layout="@layout/settings_widget_switch"
linphone:title="@{@string/chat_settings_hide_empty_rooms_title}"

View file

@ -44,6 +44,10 @@
android:id="@+id/chatsDeepLink"
app:uri="linphone-android://chat/"
android:autoVerify="true" />
<deepLink
android:id="@+id/chatRoomDeepLink"
app:uri="linphone-android://chat-room/{LocalSipUri}/{RemoteSipUri}"
android:autoVerify="true" />
</fragment>
<fragment
android:id="@+id/masterContactsFragment"

View file

@ -347,6 +347,8 @@
<string name="chat_settings_file_sharing_url_summary">Do not edit unless you know what you are doing!</string>
<string name="chat_settings_downloaded_images_public_title">Make downloaded images visible in native gallery</string>
<string name="chat_settings_downloaded_images_public_summary">Images in ephemeral messages won\'t be</string>
<string name="chat_settings_launcher_shortcuts_title">Create shortcuts to chat rooms in launcher</string>
<string name="chat_settings_launcher_shortcuts_summary">Will be replaced by contacts shortcuts if enabled</string>
<string name="chat_settings_hide_empty_rooms_title">Hide empty chat rooms</string>
<string name="chat_settings_hide_empty_rooms_summary"></string>
<string name="chat_settings_hide_rooms_removed_proxies_title">Hide chat rooms from removed proxy configs</string>
@ -371,8 +373,8 @@
<string name="contacts_settings_native_presence_summary">Inserting information shortcuts from the &appName; contact into native Android contacts</string>
<string name="contacts_settings_show_organization_title">Display contact organization</string>
<string name="contacts_settings_show_organization_summary"></string>
<string name="contacts_settings_launcher_shortcuts_title">Create shortcuts in launcher</string>
<string name="contacts_settings_launcher_shortcuts_summary"></string>
<string name="contacts_settings_launcher_shortcuts_title">Create shortcuts to contacts in launcher</string>
<string name="contacts_settings_launcher_shortcuts_summary">Will replace chat room shortcuts if any</string>
<!-- Advanced settings -->
<string name="advanced_settings_debug_mode_title">Debug logs</string>