mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 02:58:07 +00:00
Add Message Waiting Indication
This commit is contained in:
parent
c7ddf2d8d0
commit
f16a0f42ae
10 changed files with 204 additions and 31 deletions
21
Linphone/Assets.xcassets/voicemail.imageset/Contents.json
vendored
Normal file
21
Linphone/Assets.xcassets/voicemail.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "voicemail.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Linphone/Assets.xcassets/voicemail.imageset/voicemail.svg
vendored
Normal file
1
Linphone/Assets.xcassets/voicemail.imageset/voicemail.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M200,72a56,56,0,0,0-39.14,96H95.14A56,56,0,1,0,56,184H200a56,56,0,0,0,0-112ZM16,128a40,40,0,1,1,40,40A40,40,0,0,1,16,128Zm184,40a40,40,0,1,1,40-40A40,40,0,0,1,200,168Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 291 B |
|
|
@ -437,6 +437,31 @@ class CoreContext: ObservableObject {
|
|||
DispatchQueue.main.async {
|
||||
self.accounts = accountModels
|
||||
}
|
||||
}, onMessageWaitingIndicationChanged: { (core: Core, event: Event, mwi: MessageWaitingIndication) in
|
||||
if (mwi.hasMessageWaiting()) {
|
||||
let summaries = mwi.summaries
|
||||
Log.info(
|
||||
"[CoreContext][onMessageWaitingIndicationChanged] MWI NOTIFY received, messages are waiting (\(summaries.count) summaries)"
|
||||
)
|
||||
|
||||
if let defaultAccount = core.defaultAccount?.params?.identityAddress, let mwiAccount = mwi.accountAddress, defaultAccount.weakEqual(address2: mwiAccount){
|
||||
if !summaries.isEmpty {
|
||||
let summary = summaries.first
|
||||
DispatchQueue.main.async {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.waitingMessageCount = Int(summary?.nbNew ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.info("[CoreContext][onMessageWaitingIndicationChanged] MWI NOTIFY received, no message is waiting")
|
||||
DispatchQueue.main.async {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.waitingMessageCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.mCore.addDelegate(delegate: self.mCoreDelegate)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import Foundation
|
||||
|
||||
public enum AppGitInfo {
|
||||
public static let branch = "master"
|
||||
public static let commit = "33b379285"
|
||||
public static let branch = "feature/mwi"
|
||||
public static let commit = "623d2e067"
|
||||
public static let tag = "6.1.0-alpha"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -419,6 +419,8 @@
|
|||
"message_meeting_invitation_updated_notification" = "Meeting has been updated";
|
||||
"message_reaction_click_to_remove_label" = "Click to remove";
|
||||
"message_reactions_info_all_title" = "Reactions";
|
||||
"mwi_messages_are_waiting_single" = "1 new voice message";
|
||||
"mwi_messages_are_waiting_multiple" = "%@ new voice messages";
|
||||
"network_not_reachable" = "You aren't connected to internet";
|
||||
"network_reachable_again" = "Network is now reachable again";
|
||||
"new_conversation_create_group" = "Create a group conversation";
|
||||
|
|
|
|||
|
|
@ -419,6 +419,8 @@
|
|||
"message_meeting_invitation_updated_notification" = "Réunion mise à jour";
|
||||
"message_reaction_click_to_remove_label" = "Cliquez pour supprimer";
|
||||
"message_reactions_info_all_title" = "Réactions";
|
||||
"mwi_messages_are_waiting_single" = "1 message vocal en attente";
|
||||
"mwi_messages_are_waiting_multiple" = "%@ messages vocaux en attente";
|
||||
"network_not_reachable" = "Vous n’êtes pas connecté à internet";
|
||||
"network_reachable_again" = "Vous êtes à nouveau connecté à internet";
|
||||
"new_conversation_create_group" = "Créer une conversation de groupe";
|
||||
|
|
|
|||
|
|
@ -140,6 +140,54 @@ struct ContentView: View {
|
|||
.background(Color.redDanger500)
|
||||
}
|
||||
|
||||
if sharedMainViewModel.waitingMessageCount > 0 && (!telecomManager.callInProgress || (telecomManager.callInProgress && !telecomManager.callDisplayed)) {
|
||||
HStack {
|
||||
Image("voicemail")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 26, height: 26)
|
||||
.padding(.leading, 10)
|
||||
|
||||
if sharedMainViewModel.waitingMessageCount > 1 {
|
||||
Text(String(format: String(localized: "mwi_messages_are_waiting_multiple"), sharedMainViewModel.waitingMessageCount.description))
|
||||
.default_text_style_white(styleSize: 16)
|
||||
} else {
|
||||
Text(String(localized: "mwi_messages_are_waiting_single"))
|
||||
.default_text_style_white(styleSize: 16)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(
|
||||
action: {
|
||||
withAnimation {
|
||||
sharedMainViewModel.waitingMessageCount = 0
|
||||
}
|
||||
}, label: {
|
||||
Image("x")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 26, height: 26)
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 40)
|
||||
.padding(.horizontal, 10)
|
||||
.background(Color.gray)
|
||||
.onTapGesture {
|
||||
if let index = accountProfileViewModel.defaultAccountModelIndex,
|
||||
index < coreContext.accounts.count {
|
||||
sharedMainViewModel.waitingMessageCount = 0
|
||||
coreContext.accounts[index].callVoicemailUri()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !sharedMainViewModel.fileUrlsToShare.isEmpty && (!telecomManager.callInProgress || (telecomManager.callInProgress && !telecomManager.callDisplayed)) {
|
||||
HStack {
|
||||
Image("share-network")
|
||||
|
|
|
|||
|
|
@ -90,15 +90,51 @@ struct SideMenuAccountRow: View {
|
|||
Spacer()
|
||||
|
||||
HStack {
|
||||
if model.voicemailCount > 0 {
|
||||
Button {
|
||||
model.callVoicemailUri()
|
||||
} label: {
|
||||
ZStack(alignment: .top) {
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
Image("voicemail")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c500)
|
||||
.frame(width: 22, height: 22)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Text(String(model.voicemailCount))
|
||||
.foregroundStyle(Color.redDanger500)
|
||||
.default_text_style_600(styleSize: 12)
|
||||
.lineLimit(1)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.padding(.top, 1)
|
||||
}
|
||||
.frame(width: 30, height: 30)
|
||||
}
|
||||
.highPriorityGesture(
|
||||
TapGesture().onEnded {
|
||||
model.callVoicemailUri()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if model.notificationsCount > 0 && !CorePreferences.disableChatFeature {
|
||||
Text(String(model.notificationsCount))
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 12)
|
||||
.lineLimit(1)
|
||||
.frame(width: 20, height: 20)
|
||||
.background(Color.redDanger500)
|
||||
.cornerRadius(50)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
VStack {
|
||||
Text(String(model.notificationsCount))
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 12)
|
||||
.lineLimit(1)
|
||||
.frame(width: 20, height: 20)
|
||||
.background(Color.redDanger500)
|
||||
.cornerRadius(50)
|
||||
}
|
||||
.frame(width: 30, height: 30)
|
||||
.padding(.trailing, -8)
|
||||
}
|
||||
|
||||
Menu {
|
||||
|
|
@ -112,15 +148,18 @@ struct SideMenuAccountRow: View {
|
|||
Label("drawer_menu_manage_account", systemImage: "arrow.right.circle")
|
||||
}
|
||||
} label: {
|
||||
Image("dots-three-vertical")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundColor(Color.gray)
|
||||
.scaledToFit()
|
||||
.frame(height: 30)
|
||||
VStack {
|
||||
Image("dots-three-vertical")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundColor(Color.grayMain2c500)
|
||||
.scaledToFit()
|
||||
.frame(height: 25)
|
||||
}
|
||||
.frame(width: 30, height: 30)
|
||||
}
|
||||
}
|
||||
.frame(width: 64, alignment: .trailing)
|
||||
.frame(alignment: .trailing)
|
||||
.padding(.top, 12)
|
||||
.padding(.bottom, 12)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ class AccountModel: ObservableObject {
|
|||
@Published var registrationStateAssociatedUIColor: Color = .clear
|
||||
@Published var isRegistrered: Bool = false
|
||||
@Published var notificationsCount: Int = 0
|
||||
@Published var showMwi: Bool = false
|
||||
@Published var voicemailCount: Int = 0
|
||||
@Published var isDefaultAccount: Bool = false
|
||||
@Published var displayName: String = ""
|
||||
@Published var address: String = ""
|
||||
|
|
@ -51,23 +53,46 @@ class AccountModel: ObservableObject {
|
|||
|
||||
init(account: Account, core: Core) {
|
||||
self.account = account
|
||||
|
||||
self.computeNotificationsCount()
|
||||
|
||||
accountDelegate = AccountDelegateStub(onRegistrationStateChanged: { (_: Account, _: RegistrationState, _: String) in
|
||||
self.update()
|
||||
})
|
||||
self.computeNotificationsCount()
|
||||
|
||||
accountDelegate = AccountDelegateStub(
|
||||
onRegistrationStateChanged: { (_: Account, _: RegistrationState, _: String) in
|
||||
self.update()
|
||||
}, onMessageWaitingIndicationChanged: { (account: Account, mwi: MessageWaitingIndication) in
|
||||
Log.info("\(AccountModel.TAG) Account \(account.params?.identityAddress?.asStringUriOnly() ?? "Error") has received a MWI NOTIFY. \(mwi.hasMessageWaiting() ? "Message(s) are waiting." : "No message is waiting.")")
|
||||
let showMwiTmp = mwi.hasMessageWaiting()
|
||||
var voicemailCountTmp = 0
|
||||
for summary in mwi.summaries {
|
||||
let contextClass = summary.contextClass
|
||||
let nbNew = summary.nbNew
|
||||
let nbNewUrgent = summary.nbNewUrgent
|
||||
let nbOld = summary.nbOld
|
||||
let nbOldUrgent = summary.nbOldUrgent
|
||||
Log.info("\(AccountModel.TAG) [MWI] \(contextClass): new \(nbNew) urgent \(nbNewUrgent), old \(nbOld) urgent \(nbOldUrgent)")
|
||||
|
||||
voicemailCountTmp = Int(nbNew)
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.showMwi = showMwiTmp
|
||||
self.voicemailCount = voicemailCountTmp
|
||||
}
|
||||
}
|
||||
)
|
||||
account.addDelegate(delegate: accountDelegate!)
|
||||
|
||||
coreDelegate = CoreDelegateStub(onCallStateChanged: { (_: Core, _: Call, _: Call.State, _: String) in
|
||||
self.computeNotificationsCount()
|
||||
}, onMessagesReceived: { (_: Core, _: ChatRoom, _: [ChatMessage]) in
|
||||
self.computeNotificationsCount()
|
||||
}, onChatRoomRead: { (_: Core, _: ChatRoom) in
|
||||
self.computeNotificationsCount()
|
||||
}, onMessageRetracted: { (_: Core, _: ChatRoom, _: ChatMessage) in
|
||||
self.computeNotificationsCount()
|
||||
})
|
||||
coreDelegate = CoreDelegateStub(
|
||||
onCallStateChanged: { (_: Core, _: Call, _: Call.State, _: String) in
|
||||
self.computeNotificationsCount()
|
||||
}, onMessagesReceived: { (_: Core, _: ChatRoom, _: [ChatMessage]) in
|
||||
self.computeNotificationsCount()
|
||||
}, onChatRoomRead: { (_: Core, _: ChatRoom) in
|
||||
self.computeNotificationsCount()
|
||||
}, onMessageRetracted: { (_: Core, _: ChatRoom, _: ChatMessage) in
|
||||
self.computeNotificationsCount()
|
||||
}
|
||||
)
|
||||
core.addDelegate(delegate: coreDelegate!)
|
||||
|
||||
CoreContext.shared.doOnCoreQueue { _ in
|
||||
|
|
@ -311,6 +336,15 @@ class AccountModel: ObservableObject {
|
|||
|
||||
self.isDefaultAccount = true
|
||||
}
|
||||
|
||||
func callVoicemailUri() {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if let voicemail = self.account.params?.voicemailAddress {
|
||||
Log.info("\(AccountModel.TAG) Calling voicemail address \(voicemail.asStringUriOnly())")
|
||||
TelecomManager.shared.doCallOrJoinConf(address: voicemail)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AccountDeviceModel: ObservableObject {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class SharedMainViewModel: ObservableObject {
|
|||
@Published var dialPlansShortLabelList: [String] = []
|
||||
|
||||
@Published var fileUrlsToShare: [String] = []
|
||||
@Published var waitingMessageCount: Int = 0
|
||||
|
||||
@Published var operationInProgress = false
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue