diff --git a/CHANGELOG.md b/CHANGELOG.md index 54e3e139c..7127a8aa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,13 @@ Group changes to describe their impact on the project, as follows: ### Added - Conference creation with scheduling, video, different layouts, showing who is speaking and who is muted, etc... +- Chat rooms can be individually muted (no notification when receiving a chat message) ### Changed - In-call views have been re-designed - Improved how call logs are handled to improve performances - Improved how contact avatars are generated +- 3-dots menu even for basic chat rooms ### Fixed - Multiple file download attempt from the same chat bubble at the same time needed app restart to properly download each file @@ -27,6 +29,25 @@ Group changes to describe their impact on the project, as follows: - Show service notification sooner to prevent crash if Core creation takes too long - Trying to keep the preferred driver (OpenSLES / AAudio) when switching device +## [4.6.9] - 2022-05-30 + +### Fixed +- ANR when screen turns OFF/ON while app is in foreground +- Crash due to missing CoreContext instance in TelecomManager service +- One-to-One encrypted chat room creation if it already exists +- Crash if ConnectionService feature isn't supported by the device + +### Changed +- Updated translations from Weblate +- Improved audio devices logs + +## [4.6.8] - 2022-05-23 + +### Fixed +- Crash due to missing CoreContext in CoreService +- Crash in BootReceiver if auto start is disabled +- Other crashes + ## [4.6.7] - 2022-05-04 ### Changed diff --git a/app/build.gradle b/app/build.gradle index a9b27ae9a..4a0a56fff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -216,7 +216,7 @@ dependencies { implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0" implementation "androidx.window:window:1.0.0" - implementation 'androidx.constraintlayout:constraintlayout:2.1.3' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation "androidx.gridlayout:gridlayout:1.0.0" implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1' diff --git a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt index cb340badc..d0d658ec9 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt @@ -561,10 +561,6 @@ class DetailChatRoomFragment : MasterFragment() + val basicChatRoom: Boolean = chatRoom.hasCapability(ChatRoomCapabilities.Basic.toInt()) + val oneToOneChatRoom: Boolean = chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) val encryptedChatRoom: Boolean = chatRoom.hasCapability(ChatRoomCapabilities.Encrypted.toInt()) @@ -99,6 +101,8 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf val groupCallAvailable: Boolean get() = LinphoneUtils.isRemoteConferencingAvailable() + val notificationsMuted = MutableLiveData() + private var addressToCall: Address? = null private val bounceAnimator: ValueAnimator by lazy { @@ -235,6 +239,8 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf callInProgress.value = chatRoom.core.callsNb > 0 updateRemotesComposing() + notificationsMuted.value = areNotificationsMuted() + if (corePreferences.enableAnimations) bounceAnimator.start() } @@ -250,10 +256,6 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf if (corePreferences.enableAnimations) bounceAnimator.end() } - fun hideMenu(): Boolean { - return chatRoom.hasCapability(ChatRoomCapabilities.Basic.toInt()) || (oneToOneChatRoom && !encryptedChatRoom) - } - fun contactLookup() { displayName.value = when { chatRoom.hasCapability(ChatRoomCapabilities.Basic.toInt()) -> LinphoneUtils.getDisplayName( @@ -307,6 +309,17 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf formatLastMessage(chatRoom.lastMessageInHistory) } + fun areNotificationsMuted(): Boolean { + val id = LinphoneUtils.getChatRoomId(chatRoom.localAddress, chatRoom.peerAddress) + return corePreferences.chatRoomMuted(id) + } + + fun muteNotifications(mute: Boolean) { + val id = LinphoneUtils.getChatRoomId(chatRoom.localAddress, chatRoom.peerAddress) + corePreferences.muteChatRoom(id, mute) + notificationsMuted.value = mute + } + private fun formatLastMessage(msg: ChatMessage?) { val builder = SpannableStringBuilder() if (msg == null) { diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index cfdf8bcdc..cdf1b6e8d 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -84,6 +84,18 @@ class CorePreferences constructor(private val context: Context) { // logcatLogsOutput = false } + fun chatRoomMuted(id: String): Boolean { + val sharedPreferences: SharedPreferences = coreContext.context.getSharedPreferences("notifications", Context.MODE_PRIVATE) + return sharedPreferences.getBoolean(id, false) + } + + fun muteChatRoom(id: String, mute: Boolean) { + val sharedPreferences: SharedPreferences = coreContext.context.getSharedPreferences("notifications", Context.MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.putBoolean(id, mute) + editor.apply() + } + /* App settings */ var debugLogs: Boolean diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 67fd007f2..f60740622 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -167,7 +167,14 @@ class NotificationsManager(private val context: Context) { ShortcutsHelper.createShortcutsToChatRooms(context) } } - displayIncomingChatNotification(room, message) + + val id = LinphoneUtils.getChatRoomId(room.localAddress, room.peerAddress) + val mute = corePreferences.chatRoomMuted(id) + if (mute) { + Log.i("[Notifications Manager] Chat room $id has been muted") + } else { + displayIncomingChatNotification(room, message) + } } override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) { diff --git a/app/src/main/res/drawable-xhdpi/menu_notifications_off.png b/app/src/main/res/drawable-xhdpi/menu_notifications_off.png new file mode 100644 index 000000000..e014eced1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/menu_notifications_off.png differ diff --git a/app/src/main/res/drawable-xhdpi/menu_notifications_on.png b/app/src/main/res/drawable-xhdpi/menu_notifications_on.png new file mode 100644 index 000000000..f48062e06 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/menu_notifications_on.png differ diff --git a/app/src/main/res/drawable-xhdpi/voip_call_list_menu.png b/app/src/main/res/drawable-xhdpi/voip_call_list_menu.png index fdd82bea6..b4e2ff3bf 100644 Binary files a/app/src/main/res/drawable-xhdpi/voip_call_list_menu.png and b/app/src/main/res/drawable-xhdpi/voip_call_list_menu.png differ diff --git a/app/src/main/res/drawable-xhdpi/voip_menu_more.png b/app/src/main/res/drawable-xhdpi/voip_menu_more.png index 7f7f7d8fd..64abbbba8 100644 Binary files a/app/src/main/res/drawable-xhdpi/voip_menu_more.png and b/app/src/main/res/drawable-xhdpi/voip_menu_more.png differ diff --git a/app/src/main/res/layout/chat_room_detail_fragment.xml b/app/src/main/res/layout/chat_room_detail_fragment.xml index c22659ad2..f69bb7e5c 100644 --- a/app/src/main/res/layout/chat_room_detail_fragment.xml +++ b/app/src/main/res/layout/chat_room_detail_fragment.xml @@ -11,9 +11,6 @@ - @@ -131,7 +128,6 @@ - - @@ -131,24 +130,42 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/title" - android:layout_toLeftOf="@id/ephemeral" + android:layout_toLeftOf="@id/icons" android:ellipsize="end" android:maxLines="2" - android:text="@{viewModel.lastMessageText}" /> + android:text="@{viewModel.lastMessageText, default=`Lorem ipsum dolor sit amet`}" /> - + android:gravity="right"> + + + + + + diff --git a/app/src/main/res/layout/chat_room_menu.xml b/app/src/main/res/layout/chat_room_menu.xml index a5d1d778d..6c7550a2a 100644 --- a/app/src/main/res/layout/chat_room_menu.xml +++ b/app/src/main/res/layout/chat_room_menu.xml @@ -16,6 +16,12 @@ + + @@ -25,6 +31,12 @@ + + + + + + Appel de groupe Voulez-vous démarrer un appel de groupe ?\nToutes les personnes dans cette conversation vont recevoir un appel. Démarrer + Désactiver les notifications + Activer les notifications + Les notifications sont désactivées pour cette conversation \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8fea766ed..34da62b26 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -190,6 +190,8 @@ Conversation\'s devices Ephemeral messages Delete messages + Disable notifications + Enable notifications Ephemeral messages This message will be deleted on both ends once it has been read and after the selected timeout. Disabled @@ -773,6 +775,7 @@ Contact is an admin in this conversation Contact isn\'t an admin in this conversation Messages are ephemeral in this conversation + Notifications are disabled for this conversation Contact can be invited in encrypted conversations Go into conversation Go into encrypted conversation diff --git a/build.gradle b/build.gradle index bf3a0c8ea..83d1f7501 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } // for com.github.chrisbanes:PhotoView } dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' + classpath 'com.android.tools.build:gradle:7.2.1' classpath 'com.google.gms:google-services:4.3.10' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21" classpath "org.jlleitschuh.gradle:ktlint-gradle:10.1.0"