Compare commits

..

6 commits

Author SHA1 Message Date
benoit.martins
eb41590ed0 Add Localizable file for msgNotificationService 2025-04-13 23:38:24 +02:00
benoit.martins
05fc902790 Remove toast notification for validated QR code 2025-04-13 23:20:34 +02:00
benoit.martins
7219731c0e Fix vCard contact list 2025-04-13 23:16:46 +02:00
Benoit Martins
5989887723 Add core delegate in contactsManager to get and remove friends from the list 2025-04-04 17:35:26 +02:00
Benoit Martins
b83ae7fde6 Add new localizable files 2025-04-04 15:13:19 +02:00
Benoit Martins
21b8f02e65 Remove older localizable file 2025-04-04 15:07:15 +02:00
32 changed files with 1354 additions and 8044 deletions

View file

@ -7,7 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
4ED1F0A881A9ACB5977A8987 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
4ED1F0A881A9ACB5977A8987 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
660AAF7F2B839272004C0FA6 /* msgNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 660D8A702B517D260092694D /* GoogleService-Info.plist */; };
6613A0AE2BAEB7DF008923A4 /* MeetingFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */; };
@ -21,7 +21,6 @@
667E5D7F2B8E430C00EBCFC4 /* linphonerc-factory in Resources */ = {isa = PBXBuildFile; fileRef = D732A90B2B0376F500DB42BA /* linphonerc-factory */; };
667E5D812B8E444E00EBCFC4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 667E5D802B8E444D00EBCFC4 /* GoogleService-Info.plist */; };
6691CA7E2B839C2D00B2A7B8 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6691CA7D2B839C2D00B2A7B8 /* NotificationService.swift */; };
66A3E5B72CAE8E5C00FCB7FA /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */; };
66C468FB2D2BE54800A836F7 /* PIPViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C468FA2D2BE54300A836F7 /* PIPViewModel.swift */; };
66C491F92B24D25B00CEA16D /* ConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */; };
66C491FB2B24D32600CEA16D /* CoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FA2B24D32600CEA16D /* CoreExtension.swift */; };
@ -43,8 +42,6 @@
66FBFC4B2B83BD7B00BC6AB1 /* CoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FA2B24D32600CEA16D /* CoreExtension.swift */; };
66FDB7812C7C689A00561566 /* EventEditViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FDB7802C7C689A00561566 /* EventEditViewController.swift */; };
C60E8F192C0F649200A06DB8 /* UIApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60E8F182C0F649200A06DB8 /* UIApplicationExtension.swift */; };
C618BF562D75CA03005A00E0 /* linphonesw in Frameworks */ = {isa = PBXBuildFile; productRef = C618BF552D75CA03005A00E0 /* linphonesw */; };
C618BF582D75CA0D005A00E0 /* linphonesw in Frameworks */ = {isa = PBXBuildFile; productRef = C618BF572D75CA0D005A00E0 /* linphonesw */; };
C62817282C1B389700DBA646 /* SideMenuAccountRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C62817272C1B389700DBA646 /* SideMenuAccountRow.swift */; };
C628172E2C1C3A3600DBA646 /* AccountExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C628172D2C1C3A3600DBA646 /* AccountExtension.swift */; };
C62817302C1C3DCC00DBA646 /* AccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C628172F2C1C3DCC00DBA646 /* AccountModel.swift */; };
@ -66,7 +63,6 @@
D70A26F22B7F5D95006CC8FC /* ConversationFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A26F12B7F5D95006CC8FC /* ConversationFragment.swift */; };
D70C82A52C85EDCA0087F43F /* ConversationForwardMessageFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70C82A42C85EDC90087F43F /* ConversationForwardMessageFragment.swift */; };
D70C82A72C85F5910087F43F /* ConversationForwardMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70C82A62C85F5910087F43F /* ConversationForwardMessageViewModel.swift */; };
D70C93DE2AC2D0F60063CA3B /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */; };
D714035B2BE11E00004BD8CA /* CallMediaEncryptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714035A2BE11E00004BD8CA /* CallMediaEncryptionModel.swift */; };
D714DE602C1B3B34006C1F1D /* RegisterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714DE5F2C1B3B34006C1F1D /* RegisterViewModel.swift */; };
D714DE622C1C4636006C1F1D /* RegisterCodeConfirmationFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714DE612C1C4636006C1F1D /* RegisterCodeConfirmationFragment.swift */; };
@ -112,6 +108,7 @@
D7343FEF2D3FE16C0059D784 /* HelpViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7343FEE2D3FE16B0059D784 /* HelpViewModel.swift */; };
D73449992BC6932A00778C56 /* MeetingWaitingRoomFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */; };
D734499B2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */; };
D737AEEF2DA011F2005C1280 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D737AEED2DA011F2005C1280 /* Localizable.strings */; };
D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */; };
D748BF2E2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D748BF2D2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift */; };
D74C9CF82ACACECE0021626A /* WelcomePage1Fragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74C9CF72ACACECE0021626A /* WelcomePage1Fragment.swift */; };
@ -181,6 +178,7 @@
D7DC096F2CFA1D7600A6D47C /* AccountProfileFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */; };
D7DC09712CFDBF9A00A6D47C /* AccountProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DC09702CFDBF8300A6D47C /* AccountProfileViewModel.swift */; };
D7E2E69F2CE356C90080DA0D /* PopupViewWithTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E2E69E2CE356C90080DA0D /* PopupViewWithTextField.swift */; };
D7E394C52DAC6561005FA0DD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D737AEED2DA011F2005C1280 /* Localizable.strings */; };
D7E6ADF32B9875C20009A2BC /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E6ADF22B9875C20009A2BC /* Message.swift */; };
D7E6ADF52B9876ED0009A2BC /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E6ADF42B9876ED0009A2BC /* Attachment.swift */; };
D7E6D0492AE933AD00A57AAF /* FavoriteContactsListFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E6D0482AE933AD00A57AAF /* FavoriteContactsListFragment.swift */; };
@ -271,7 +269,6 @@
D70A26F12B7F5D95006CC8FC /* ConversationFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationFragment.swift; sourceTree = "<group>"; };
D70C82A42C85EDC90087F43F /* ConversationForwardMessageFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationForwardMessageFragment.swift; sourceTree = "<group>"; };
D70C82A62C85F5910087F43F /* ConversationForwardMessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationForwardMessageViewModel.swift; sourceTree = "<group>"; };
D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
D714035A2BE11E00004BD8CA /* CallMediaEncryptionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallMediaEncryptionModel.swift; sourceTree = "<group>"; };
D714DE5F2C1B3B34006C1F1D /* RegisterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterViewModel.swift; sourceTree = "<group>"; };
D714DE612C1C4636006C1F1D /* RegisterCodeConfirmationFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterCodeConfirmationFragment.swift; sourceTree = "<group>"; };
@ -319,6 +316,8 @@
D7343FEE2D3FE16B0059D784 /* HelpViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpViewModel.swift; sourceTree = "<group>"; };
D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomFragment.swift; sourceTree = "<group>"; };
D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomViewModel.swift; sourceTree = "<group>"; };
D737AEEE2DA011F2005C1280 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
D737AEF02DA01203005C1280 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountLoginFragment.swift; sourceTree = "<group>"; };
D748BF2D2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountWarningFragment.swift; sourceTree = "<group>"; };
D74C9CF72ACACECE0021626A /* WelcomePage1Fragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomePage1Fragment.swift; sourceTree = "<group>"; };
@ -407,7 +406,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C618BF582D75CA0D005A00E0 /* linphonesw in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -415,8 +413,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C618BF562D75CA03005A00E0 /* linphonesw in Frameworks */,
4ED1F0A881A9ACB5977A8987 /* BuildFile in Frameworks */,
4ED1F0A881A9ACB5977A8987 /* (null) in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -597,7 +594,7 @@
D719ABBA2ABC67BF00B41C10 /* Assets.xcassets */,
D719ABBC2ABC67BF00B41C10 /* Linphone.entitlements */,
D7A2EDDA2AC19EEC005D90FC /* Info.plist */,
D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */,
D737AEED2DA011F2005C1280 /* Localizable.strings */,
D719ABBD2ABC67BF00B41C10 /* Preview Content */,
D7D24D0C2AC1B4C700C6F35B /* Fonts */,
D7ADF6012AFE5C7C00212231 /* Ressources */,
@ -1070,18 +1067,16 @@
};
};
};
buildConfigurationList = D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "linphone" */;
buildConfigurationList = D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "Linphone" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
fr,
);
mainGroup = D719ABAA2ABC67BF00B41C10;
packageReferences = (
C618BF542D75CA03005A00E0 /* XCRemoteSwiftPackageReference "linphone-sdk-swift-ios" */,
);
productRefGroup = D719ABB42ABC67BF00B41C10 /* Products */;
projectDirPath = "";
projectRoot = "";
@ -1098,8 +1093,8 @@
buildActionMask = 2147483647;
files = (
667E5D7F2B8E430C00EBCFC4 /* linphonerc-factory in Resources */,
D7E394C52DAC6561005FA0DD /* Localizable.strings in Resources */,
667E5D812B8E444E00EBCFC4 /* GoogleService-Info.plist in Resources */,
66A3E5B72CAE8E5C00FCB7FA /* Localizable.xcstrings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1110,6 +1105,7 @@
D7D24D142AC1B4E800C6F35B /* NotoSans-Regular.ttf in Resources */,
D7D24D182AC1B4E800C6F35B /* NotoSans-ExtraBold.ttf in Resources */,
D7D24D152AC1B4E800C6F35B /* NotoSans-Light.ttf in Resources */,
D737AEEF2DA011F2005C1280 /* Localizable.strings in Resources */,
D783C77D2B1089B200622CC2 /* assistant_third_party_default_values in Resources */,
D7D24D162AC1B4E800C6F35B /* NotoSans-SemiBold.ttf in Resources */,
D7D24D172AC1B4E800C6F35B /* NotoSans-Bold.ttf in Resources */,
@ -1119,7 +1115,6 @@
D732A90C2B0376F500DB42BA /* linphonerc-default in Resources */,
D732A90D2B0376F500DB42BA /* linphonerc-factory in Resources */,
D783C77C2B1089B200622CC2 /* assistant_linphone_default_values in Resources */,
D70C93DE2AC2D0F60063CA3B /* Localizable.xcstrings in Resources */,
660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1386,6 +1381,18 @@
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
D737AEED2DA011F2005C1280 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
D737AEEE2DA011F2005C1280 /* en */,
D737AEF02DA01203005C1280 /* fr */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
660AAF812B839272004C0FA6 /* Debug */ = {
isa = XCBuildConfiguration;
@ -1716,7 +1723,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "linphone" */ = {
D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "Linphone" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D719ABC02ABC67BF00B41C10 /* Debug */,
@ -1735,30 +1742,6 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
C618BF542D75CA03005A00E0 /* XCRemoteSwiftPackageReference "linphone-sdk-swift-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://gitlab.linphone.org/BC/public/linphone-sdk-swift-ios.git";
requirement = {
branch = stable;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
C618BF552D75CA03005A00E0 /* linphonesw */ = {
isa = XCSwiftPackageProductDependency;
package = C618BF542D75CA03005A00E0 /* XCRemoteSwiftPackageReference "linphone-sdk-swift-ios" */;
productName = linphonesw;
};
C618BF572D75CA0D005A00E0 /* linphonesw */ = {
isa = XCSwiftPackageProductDependency;
package = C618BF542D75CA03005A00E0 /* XCRemoteSwiftPackageReference "linphone-sdk-swift-ios" */;
productName = linphonesw;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = D719ABAB2ABC67BF00B41C10 /* Project object */;
}

View file

@ -17,7 +17,7 @@
BlueprintIdentifier = "D719ABB22ABC67BF00B41C10"
BuildableName = "Linphone.app"
BlueprintName = "Linphone"
ReferencedContainer = "container:linphone.xcodeproj">
ReferencedContainer = "container:Linphone.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@ -46,7 +46,7 @@
BlueprintIdentifier = "D719ABB22ABC67BF00B41C10"
BuildableName = "Linphone.app"
BlueprintName = "Linphone"
ReferencedContainer = "container:linphone.xcodeproj">
ReferencedContainer = "container:Linphone.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
@ -63,7 +63,7 @@
BlueprintIdentifier = "D719ABB22ABC67BF00B41C10"
BuildableName = "Linphone.app"
BlueprintName = "Linphone"
ReferencedContainer = "container:linphone.xcodeproj">
ReferencedContainer = "container:Linphone.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>

View file

@ -28,6 +28,8 @@ import Combine
final class ContactsManager: ObservableObject {
static let TAG = "[ContactsManager]"
static let shared = ContactsManager()
private var coreContext = CoreContext.shared
@ -42,12 +44,14 @@ final class ContactsManager: ObservableObject {
@Published var lastSearchSuggestions: [SearchResult] = []
@Published var avatarListModel: [ContactAvatarModel] = []
private var coreDelegate: CoreDelegate?
private var friendListDelegate: FriendListDelegate?
private var magicSearchDelegate: MagicSearchDelegate?
private init() {}
func fetchContacts() {
coreContext.doOnCoreQueue { core in
self.coreContext.doOnCoreQueue { core in
if core.globalState == GlobalState.Shutdown || core.globalState == GlobalState.Off {
print("\(#function) - Core is being stopped or already destroyed, abort")
} else {
@ -88,12 +92,12 @@ final class ContactsManager: ObservableObject {
}
}
MagicSearchSingleton.shared.searchForContactsWithoutCoreThread(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
let store = CNContactStore()
store.requestAccess(for: .contacts) { (granted, error) in
if let error = error {
print("\(#function) - failed to request access", error)
self.addFriendListDelegate()
self.addCoreDelegate(core: core)
return
}
if granted {
@ -102,10 +106,16 @@ final class ContactsManager: ObservableObject {
CNContactPostalAddressesKey, CNContactIdentifierKey,
CNInstantMessageAddressUsernameKey, CNContactInstantMessageAddressesKey,
CNContactOrganizationNameKey, CNContactImageDataAvailableKey, CNContactImageDataKey, CNContactThumbnailImageDataKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
let dispatchGroup = DispatchGroup()
do {
var contactCounter = 0
try store.enumerateContacts(with: request, usingBlock: { (contact, _) in
dispatchGroup.enter()
let newContact = Contact(
identifier: contact.identifier,
firstName: contact.givenName,
@ -126,51 +136,7 @@ final class ContactsManager: ObservableObject {
name: contact.givenName + contact.familyName,
prefix: "",
contact: newContact, linphoneFriend: false, existingFriend: nil) {
if (self.friendList?.friends.count ?? 0) == contactCounter {
// Every contact properly added, proceed
self.linphoneFriendList?.updateSubscriptions()
self.friendList?.updateSubscriptions()
if let friendListDelegate = self.friendListDelegate {
self.friendList?.removeDelegate(delegate: friendListDelegate)
}
self.friendListDelegate = FriendListDelegateStub(onNewSipAddressDiscovered: { (_: FriendList, linphoneFriend: Friend, sipUri: String) in
var addedAvatarListModel: [ContactAvatarModel] = []
linphoneFriend.phoneNumbers.forEach { _ in
let address = try? Factory.Instance.createAddress(addr: sipUri)
if address != nil {
linphoneFriend.edit()
linphoneFriend.addAddress(address: address!)
linphoneFriend.done()
let addressTmp = linphoneFriend.address?.clone()?.asStringUriOnly() ?? ""
addedAvatarListModel.append(
ContactAvatarModel(
friend: linphoneFriend,
name: linphoneFriend.name ?? "",
address: addressTmp,
withPresence: true
)
)
DispatchQueue.main.async {
NotificationCenter.default.post(
name: NSNotification.Name("ContactAdded"),
object: nil,
userInfo: ["address": addressTmp]
)
}
}
}
DispatchQueue.main.async {
self.avatarListModel += addedAvatarListModel
self.avatarListModel = self.avatarListModel.sorted { $0.name < $1.name }
}
})
self.friendList?.addDelegate(delegate: self.friendListDelegate!)
}
dispatchGroup.leave()
}
}
} else {
@ -180,66 +146,28 @@ final class ContactsManager: ObservableObject {
name: contact.givenName + contact.familyName,
prefix: "-default",
contact: newContact, linphoneFriend: false, existingFriend: nil) {
if (self.friendList?.friends.count ?? 0) == contactCounter {
// Every contact properly added, proceed
self.linphoneFriendList?.updateSubscriptions()
self.friendList?.updateSubscriptions()
if let friendListDelegate = self.friendListDelegate {
self.friendList?.removeDelegate(delegate: friendListDelegate)
}
self.friendListDelegate = FriendListDelegateStub(onNewSipAddressDiscovered: { (_: FriendList, linphoneFriend: Friend, sipUri: String) in
var addedAvatarListModel: [ContactAvatarModel] = []
linphoneFriend.phoneNumbers.forEach { _ in
let address = try? Factory.Instance.createAddress(addr: sipUri)
if address != nil {
linphoneFriend.edit()
linphoneFriend.addAddress(address: address!)
linphoneFriend.done()
let addressTmp = linphoneFriend.address?.clone()?.asStringUriOnly() ?? ""
addedAvatarListModel.append(
ContactAvatarModel(
friend: linphoneFriend,
name: linphoneFriend.name ?? "",
address: addressTmp,
withPresence: true
)
)
DispatchQueue.main.async {
NotificationCenter.default.post(
name: NSNotification.Name("ContactAdded"),
object: nil,
userInfo: ["address": addressTmp]
)
}
}
}
DispatchQueue.main.async {
self.avatarListModel += addedAvatarListModel
self.avatarListModel = self.avatarListModel.sorted { $0.name < $1.name }
}
})
self.friendList?.addDelegate(delegate: self.friendListDelegate!)
}
dispatchGroup.leave()
}
}
}
if !(contact.givenName.isEmpty && contact.familyName.isEmpty) {
contactCounter += 1
}
})
dispatchGroup.notify(queue: .main) {
self.addFriendListDelegate()
self.addCoreDelegate(core: core)
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
}
} catch let error {
print("\(#function) - Failed to enumerate contact", error)
self.addFriendListDelegate()
self.addCoreDelegate(core: core)
MagicSearchSingleton.shared.searchForContactsWithoutCoreThread(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
}
} else {
print("\(#function) - access denied")
self.addFriendListDelegate()
self.addCoreDelegate(core: core)
MagicSearchSingleton.shared.searchForContactsWithoutCoreThread(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
}
}
}
@ -453,6 +381,129 @@ final class ContactsManager: ObservableObject {
completion(self.getFriendWithAddress(address: address))
}
}
func addFriendListDelegate() {
self.linphoneFriendList?.updateSubscriptions()
self.friendList?.updateSubscriptions()
CoreContext.shared.mCore.friendsLists.forEach { friendList in
friendList.updateSubscriptions()
}
if let friendListDelegate = self.friendListDelegate {
CoreContext.shared.mCore.friendsLists.forEach { friendList in
friendList.removeDelegate(delegate: friendListDelegate)
}
}
self.friendListDelegate = FriendListDelegateStub(
onContactCreated: { (friendList: FriendList, linphoneFriend: Friend) in
Log.info("\(ContactsManager.TAG) FriendListDelegateStub onContactCreated")
},
onContactDeleted: { (friendList: FriendList, linphoneFriend: Friend) in
Log.info("\(ContactsManager.TAG) FriendListDelegateStub onContactDeleted")
},
onContactUpdated: { (friendList: FriendList, newFriend: Friend, oldFriend: Friend) in
Log.info("\(ContactsManager.TAG) FriendListDelegateStub onContactUpdated")
},
onSyncStatusChanged: { (friendList: FriendList, status: FriendList.SyncStatus?, message: String?) in
Log.info("\(ContactsManager.TAG) FriendListDelegateStub onSyncStatusChanged")
if status == .Successful {
friendList.friends.forEach { friend in
let addressTmp = friend.address?.clone()?.asStringUriOnly() ?? ""
let newContact = Contact(
identifier: UUID().uuidString,
firstName: friend.name ?? addressTmp,
lastName: "",
organizationName: "",
jobTitle: "",
displayName: friend.address?.displayName ?? "",
sipAddresses: friend.addresses.map { $0.asStringUriOnly() },
phoneNumbers: [],
imageData: ""
)
self.textToImageInMainThread(firstName: friend.name ?? addressTmp, lastName: "") { image in
self.saveImage(
image: image,
name: friend.name ?? addressTmp,
prefix: "-default",
contact: newContact, linphoneFriend: false, existingFriend: friend) {
}
}
}
}
MagicSearchSingleton.shared.searchForContactsWithoutCoreThread(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
},
onPresenceReceived: { (friendList: FriendList, friends: [Friend?]) in
Log.info("\(ContactsManager.TAG) FriendListDelegateStub onPresenceReceived \(friends.count)")
},
onNewSipAddressDiscovered: { (_: FriendList, linphoneFriend: Friend, sipUri: String) in
Log.info("\(ContactsManager.TAG) FriendListDelegateStub onNewSipAddressDiscovered \(linphoneFriend.name ?? "")")
var addedAvatarListModel: [ContactAvatarModel] = []
linphoneFriend.phoneNumbers.forEach { _ in
let address = try? Factory.Instance.createAddress(addr: sipUri)
if address != nil {
linphoneFriend.edit()
linphoneFriend.addAddress(address: address!)
linphoneFriend.done()
let addressTmp = linphoneFriend.address?.clone()?.asStringUriOnly() ?? ""
addedAvatarListModel.append(
ContactAvatarModel(
friend: linphoneFriend,
name: linphoneFriend.name ?? "",
address: addressTmp,
withPresence: true
)
)
DispatchQueue.main.async {
NotificationCenter.default.post(
name: NSNotification.Name("ContactAdded"),
object: nil,
userInfo: ["address": addressTmp]
)
}
}
}
DispatchQueue.main.async {
self.avatarListModel += addedAvatarListModel
self.avatarListModel = self.avatarListModel.sorted { $0.name < $1.name }
}
}
)
CoreContext.shared.mCore.friendsLists.forEach { friendList in
friendList.addDelegate(delegate: self.friendListDelegate!)
}
}
func addCoreDelegate(core: Core) {
self.coreDelegate = CoreDelegateStub(
onFriendListCreated: { (_: Core, friendList: FriendList) in
Log.info("\(ContactsManager.TAG) Friend list \(friendList.displayName) created")
if self.friendListDelegate != nil {
friendList.addDelegate(delegate: self.friendListDelegate!)
}
}, onFriendListRemoved: { (_: Core, friendList: FriendList) in
Log.info("\(ContactsManager.TAG) Friend list \(friendList.displayName) removed")
if self.friendListDelegate != nil {
friendList.removeDelegate(delegate: self.friendListDelegate!)
}
}, onDefaultAccountChanged: { (_: Core, _: Account?) in
Log.info("\(ContactsManager.TAG) Default account changed, update all contacts' model showTrust value")
//updateContactsModelDependingOnDefaultAccountMode()
}
)
if self.coreDelegate != nil {
core.addDelegate(delegate: self.coreDelegate!)
}
}
}
struct PhoneNumber {

View file

@ -26,7 +26,6 @@ import linphone // needed for unwrapped function linphone_core_set_push_and_app_
import Combine
import UniformTypeIdentifiers
import Network
import SwiftUI
#if USE_CRASHLYTICS
import Firebase
@ -262,8 +261,10 @@ final class CoreContext: ObservableObject {
}
DispatchQueue.main.async {
if status == ConfiguringState.Successful {
/*
ToastViewModel.shared.toastMessage = "Success_qr_code_validated"
ToastViewModel.shared.displayToast = true
*/
self.accounts = accountModels
}
}
@ -283,6 +284,9 @@ final class CoreContext: ObservableObject {
switch state {
case .Ok:
DispatchQueue.main.async {
NotificationCenter.default.post(name: NSNotification.Name("CoreStarted"), object: nil)
}
ContactsManager.shared.fetchContacts()
if self.mCore.consolidatedPresence != ConsolidatedPresence.Online {
self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Online)

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,6 @@
import Foundation
import linphonesw
import Combine
import SwiftUI
// swiftlint:disable line_length
// swiftlint:disable type_body_length

View file

@ -19,7 +19,6 @@
import Foundation
import linphonesw
import SwiftUI
class CallMediaEncryptionModel: ObservableObject {
var coreContext = CoreContext.shared

View file

@ -19,7 +19,6 @@
import Foundation
import linphonesw
import SwiftUI
class SentVideoWindow: ObservableObject {
var widthFactor: CGFloat = 1

View file

@ -19,7 +19,6 @@
import Foundation
import linphonesw
import SwiftUI
class ParticipantModel: ObservableObject {

View file

@ -21,7 +21,6 @@ import SwiftUI
import linphonesw
import AVFAudio
import Combine
import SwiftUI
// swiftlint:disable line_length
// swiftlint:disable type_body_length

View file

@ -19,7 +19,6 @@
import linphonesw
import Combine
import SwiftUI
// swiftlint:disable line_length
class ContactViewModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class ContactsListViewModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class EditContactViewModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class FavoriteContactsListViewModel: ObservableObject {

View file

@ -82,15 +82,18 @@ struct ContentView: View {
private let avatarSize = 45.0
@State private var imagePath: URL?
@State private var imageTmp: Image?
var body: some View {
let pub = NotificationCenter.default
let contactLoaded = NotificationCenter.default
.publisher(for: NSNotification.Name("ContactLoaded"))
let pub2 = NotificationCenter.default
let contactAdded = NotificationCenter.default
.publisher(for: NSNotification.Name("ContactAdded"))
.compactMap { $0.userInfo?["address"] as? String }
let imageChanged = NotificationCenter.default
.publisher(for: NSNotification.Name("ImageChanged"))
let coreStarted = NotificationCenter.default
.publisher(for: NSNotification.Name("CoreStarted"))
GeometryReader { geometry in
VStack(spacing: 0) {
if (telecomManager.callInProgress && !fullscreenVideo && ((!telecomManager.callDisplayed && callViewModel.callsCounter == 1) || callViewModel.callsCounter > 1)) || isShowConversationFragment {
@ -316,7 +319,8 @@ struct ContentView: View {
VStack(spacing: 0) {
if searchIsActive == false {
HStack {
if (accountProfileViewModel.accountModelIndex ?? 0) < CoreContext.shared.accounts.count {
if let accountModelIndex = accountProfileViewModel.accountModelIndex,
accountModelIndex < CoreContext.shared.accounts.count {
AsyncImage(url: imagePath) { image in
switch image {
case .empty:
@ -328,13 +332,31 @@ struct ContentView: View {
.aspectRatio(contentMode: .fill)
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
.onAppear {
imageTmp = image
}
case .failure:
Image(uiImage: contactsManager.textToImage(
firstName: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex ?? 0].avatarModel?.name ?? "",
lastName: ""))
.resizable()
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
if CoreContext.shared.accounts[accountModelIndex].avatarModel != nil {
let tmpImage = contactsManager.textToImage(
firstName: CoreContext.shared.accounts[accountModelIndex].avatarModel!.name,
lastName: "")
Image(uiImage: tmpImage)
.resizable()
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
.onAppear {
accountProfileViewModel.saveImage(image: tmpImage, name: CoreContext.shared.accounts[accountModelIndex].avatarModel!.name, prefix: "-default")
}
} else if let cachedImage = imageTmp {
cachedImage
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
} else {
ProgressView()
.frame(width: avatarSize, height: avatarSize)
}
@unknown default:
EmptyView()
}
@ -343,17 +365,13 @@ struct ContentView: View {
openMenu()
}
.onAppear {
if let accountModelIndex = accountProfileViewModel.accountModelIndex,
accountModelIndex < CoreContext.shared.accounts.count {
let imagePathTmp = CoreContext.shared.accounts[accountModelIndex].getImagePath()
if !(imagePathTmp.lastPathComponent.isEmpty || imagePathTmp.lastPathComponent == "Error" || imagePathTmp.lastPathComponent == "ImageError.png") {
imagePath = imagePathTmp
}
let imagePathTmp = CoreContext.shared.accounts[accountModelIndex].getImagePath()
if !(imagePathTmp.lastPathComponent.isEmpty || imagePathTmp.lastPathComponent == "Error" || imagePathTmp.lastPathComponent == "ImageError.png") {
imagePath = imagePathTmp
}
}
.onChange(of: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex ?? 0].usernaneAvatar) { _ in
if let accountModelIndex = accountProfileViewModel.accountModelIndex,
accountModelIndex < CoreContext.shared.accounts.count {
.onChange(of: CoreContext.shared.accounts[accountModelIndex].usernaneAvatar) { username in
if !username.isEmpty {
let imagePathTmp = CoreContext.shared.accounts[accountModelIndex].getImagePath()
if !(imagePathTmp.lastPathComponent.isEmpty || imagePathTmp.lastPathComponent == "Error" || imagePathTmp.lastPathComponent == "ImageError.png") {
sharedMainViewModel.changeDefaultAvatar(defaultAvatarURL: imagePathTmp)
@ -362,8 +380,7 @@ struct ContentView: View {
}
}
.onReceive(imageChanged) { _ in
if let accountModelIndex = accountProfileViewModel.accountModelIndex,
accountModelIndex < CoreContext.shared.accounts.count {
if !CoreContext.shared.accounts[accountModelIndex].usernaneAvatar.isEmpty {
let imagePathTmp = CoreContext.shared.accounts[accountModelIndex].getImagePath()
sharedMainViewModel.changeDefaultAvatar(defaultAvatarURL: imagePathTmp)
imagePath = imagePathTmp
@ -1366,13 +1383,16 @@ struct ContentView: View {
self.index = 2
}
}
.onReceive(pub) { _ in
.onReceive(contactLoaded) { _ in
conversationsListViewModel.updateChatRoomsList()
historyListViewModel.refreshHistoryAvatarModel()
}
.onReceive(pub2) { address in
.onReceive(contactAdded) { address in
conversationsListViewModel.updateChatRoom(address: address)
}
.onReceive(coreStarted) { _ in
accountProfileViewModel.setAvatarModel()
}
}
.overlay {
if isMenuOpen {
@ -1396,7 +1416,6 @@ struct ContentView: View {
orientation = UIDevice.current.orientation
if newPhase == .active {
conversationsListViewModel.computeChatRoomsList(filter: "")
accountProfileViewModel.setAvatarModel()
}
}
}

View file

@ -19,7 +19,6 @@
import linphonesw
import Combine
import SwiftUI
// swiftlint:disable line_length
class ConversationForwardMessageViewModel: ObservableObject {

View file

@ -20,7 +20,6 @@
import Foundation
import linphonesw
import Combine
import SwiftUI
// swiftlint:disable line_length
class ConversationsListViewModel: ObservableObject {

View file

@ -19,7 +19,6 @@
import linphonesw
import Combine
import SwiftUI
// swiftlint:disable line_length
class StartConversationViewModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class HelpViewModel: ObservableObject {
private let TAG = "[HelpViewModel]"

View file

@ -19,7 +19,6 @@
import linphonesw
import Combine
import SwiftUI
class HistoryListViewModel: ObservableObject {

View file

@ -19,7 +19,6 @@
import linphonesw
import Combine
import SwiftUI
// swiftlint:disable line_length
class StartCallViewModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class MeetingModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class AccountProfileViewModel: ObservableObject {
@ -35,36 +34,38 @@ class AccountProfileViewModel: ObservableObject {
func saveChangesWhenLeaving() {
if accountModelIndex != nil {
CoreContext.shared.doOnCoreQueue { _ in
let displayNameAccountModel = CoreContext.shared.accounts[self.accountModelIndex!].displayNameAvatar
let newParams = CoreContext.shared.accounts[self.accountModelIndex!].account.params?.clone()
if (displayNameAccountModel != newParams?.identityAddress?.displayName)
&& (newParams?.identityAddress?.displayName != nil || !displayNameAccountModel.isEmpty) {
if let newIdentityAddress = newParams?.identityAddress?.clone() {
try? newIdentityAddress.setDisplayname(newValue: displayNameAccountModel)
try? newParams?.setIdentityaddress(newValue: newIdentityAddress)
}
if self.getImagePath().lastPathComponent.contains("-default") || self.getImagePath().lastPathComponent == "Documents" {
let usernameTmp = CoreContext.shared.accounts[self.accountModelIndex!].usernaneAvatar
if self.accountModelIndex! < CoreContext.shared.accounts.count {
let displayNameAccountModel = CoreContext.shared.accounts[self.accountModelIndex!].displayNameAvatar
let newParams = CoreContext.shared.accounts[self.accountModelIndex!].account.params?.clone()
if (displayNameAccountModel != newParams?.identityAddress?.displayName)
&& (newParams?.identityAddress?.displayName != nil || !displayNameAccountModel.isEmpty) {
if let newIdentityAddress = newParams?.identityAddress?.clone() {
try? newIdentityAddress.setDisplayname(newValue: displayNameAccountModel)
try? newParams?.setIdentityaddress(newValue: newIdentityAddress)
}
DispatchQueue.main.async {
self.saveImage(
image: ContactsManager.shared.textToImage(
firstName: displayNameAccountModel.isEmpty ? usernameTmp : displayNameAccountModel, lastName: ""),
name: usernameTmp,
prefix: "-default")
if self.getImagePath().lastPathComponent.contains("-default") || self.getImagePath().lastPathComponent == "Documents" {
let usernameTmp = CoreContext.shared.accounts[self.accountModelIndex!].usernaneAvatar
DispatchQueue.main.async {
self.saveImage(
image: ContactsManager.shared.textToImage(
firstName: displayNameAccountModel.isEmpty ? usernameTmp : displayNameAccountModel, lastName: ""),
name: usernameTmp,
prefix: "-default")
}
}
}
if self.dialPlanSelected != nil
&& (self.dialPlanSelected!.countryCallingCode != newParams?.internationalPrefix || self.dialPlanSelected!.isoCountryCode != newParams?.internationalPrefixIsoCountryCode) {
newParams?.internationalPrefix = self.dialPlanSelected?.countryCallingCode
newParams?.internationalPrefixIsoCountryCode = self.dialPlanSelected?.isoCountryCode
newParams?.useInternationalPrefixForCallsAndChats = true
}
CoreContext.shared.accounts[self.accountModelIndex!].account.params = newParams
}
if self.dialPlanSelected != nil
&& (self.dialPlanSelected!.countryCallingCode != newParams?.internationalPrefix || self.dialPlanSelected!.isoCountryCode != newParams?.internationalPrefixIsoCountryCode) {
newParams?.internationalPrefix = self.dialPlanSelected?.countryCallingCode
newParams?.internationalPrefixIsoCountryCode = self.dialPlanSelected?.isoCountryCode
newParams?.useInternationalPrefixForCallsAndChats = true
}
CoreContext.shared.accounts[self.accountModelIndex!].account.params = newParams
}
}
}
@ -119,7 +120,7 @@ class AccountProfileViewModel: ObservableObject {
return
}
let photoAvatarModelKey = "photo_avatar_model" + CoreContext.shared.accounts[self.accountModelIndex!].usernaneAvatar
let photoAvatarModelKey = CoreContext.shared.accounts[self.accountModelIndex!].usernaneAvatar
ContactsManager.shared.awaitDataWrite(data: data, name: name, prefix: prefix) { _, result in
UserDefaults.standard.set(result, forKey: photoAvatarModelKey)

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class AccountSettingsViewModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class SettingsViewModel: ObservableObject {

View file

@ -98,47 +98,55 @@ class AccountModel: ObservableObject {
let preferences = UserDefaults.standard
let photoAvatarModelKey = "photo_avatar_model" + usernaneAvatarTmp
let photoAvatarModelKey = usernaneAvatarTmp
if preferences.object(forKey: photoAvatarModelKey) == nil {
preferences.set(photoAvatarModelKey, forKey: photoAvatarModelKey)
} else {
photoAvatarModelTmp = preferences.string(forKey: photoAvatarModelKey)!
}
DispatchQueue.main.async { [self] in
switch state {
case .Cleared, .None:
humanReadableRegistrationState = "drawer_menu_account_connection_status_cleared".localized()
summary = "manage_account_status_cleared_summary".localized()
registrationStateAssociatedUIColor = .orangeWarning600
case .Progress:
humanReadableRegistrationState = "drawer_menu_account_connection_status_progress".localized()
summary = "manage_account_status_progress_summary".localized()
registrationStateAssociatedUIColor = .greenSuccess500
case .Failed:
humanReadableRegistrationState = "drawer_menu_account_connection_status_failed".localized()
summary = "manage_account_status_failed_summary".localized()
registrationStateAssociatedUIColor = .redDanger500
case .Ok:
humanReadableRegistrationState = "drawer_menu_account_connection_status_connected".localized()
summary = "manage_account_status_connected_summary".localized()
registrationStateAssociatedUIColor = .greenSuccess500
case .Refreshing:
humanReadableRegistrationState = "drawer_menu_account_connection_status_refreshing".localized()
summary = "manage_account_status_progress_summary".localized()
registrationStateAssociatedUIColor = .grayMain2c500
if !photoAvatarModelKey.isEmpty {
if preferences.object(forKey: photoAvatarModelKey) == nil {
DispatchQueue.main.async {
self.saveImage(
image: ContactsManager.shared.textToImage(
firstName: usernaneAvatarTmp, lastName: ""),
name: usernaneAvatarTmp,
prefix: "-default")
}
} else {
photoAvatarModelTmp = preferences.string(forKey: photoAvatarModelKey)!
}
isRegistrered = state == .Ok
isDefaultAccount = isDefault
self.displayName = displayName
address.map {self.address = $0}
photoAvatarModel = photoAvatarModelTmp
displayNameAvatar = displayNameTmp
usernaneAvatar = usernaneAvatarTmp
imagePathAvatar = getImagePath()
DispatchQueue.main.async { [self] in
switch state {
case .Cleared, .None:
humanReadableRegistrationState = "drawer_menu_account_connection_status_cleared".localized()
summary = "manage_account_status_cleared_summary".localized()
registrationStateAssociatedUIColor = .orangeWarning600
case .Progress:
humanReadableRegistrationState = "drawer_menu_account_connection_status_progress".localized()
summary = "manage_account_status_progress_summary".localized()
registrationStateAssociatedUIColor = .greenSuccess500
case .Failed:
humanReadableRegistrationState = "drawer_menu_account_connection_status_failed".localized()
summary = "manage_account_status_failed_summary".localized()
registrationStateAssociatedUIColor = .redDanger500
case .Ok:
humanReadableRegistrationState = "drawer_menu_account_connection_status_connected".localized()
summary = "manage_account_status_connected_summary".localized()
registrationStateAssociatedUIColor = .greenSuccess500
case .Refreshing:
humanReadableRegistrationState = "drawer_menu_account_connection_status_refreshing".localized()
summary = "manage_account_status_progress_summary".localized()
registrationStateAssociatedUIColor = .grayMain2c500
}
isRegistrered = state == .Ok
isDefaultAccount = isDefault
self.displayName = displayName
address.map {self.address = $0}
photoAvatarModel = photoAvatarModelTmp
displayNameAvatar = displayNameTmp
usernaneAvatar = usernaneAvatarTmp
imagePathAvatar = getImagePath()
}
}
}
@ -248,6 +256,28 @@ class AccountModel: ObservableObject {
core.removeAccount(account: self.account)
}
}
func saveImage(image: UIImage, name: String, prefix: String) {
guard let data = image.jpegData(compressionQuality: 1) ?? image.pngData() else {
return
}
let photoAvatarModelKey = name
ContactsManager.shared.awaitDataWrite(data: data, name: name, prefix: prefix) { _, result in
UserDefaults.standard.set(result, forKey: photoAvatarModelKey)
self.photoAvatarModel = ""
self.imagePathAvatar = nil
NotificationCenter.default.post(name: NSNotification.Name("ImageChanged"), object: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.photoAvatarModel = result
self.imagePathAvatar = self.getImagePath()
NotificationCenter.default.post(name: NSNotification.Name("ImageChanged"), object: nil)
}
}
}
}
class AccountDeviceModel: ObservableObject {

View file

@ -18,7 +18,6 @@
*/
import linphonesw
import SwiftUI
class SharedMainViewModel: ObservableObject {

View file

@ -96,7 +96,7 @@ class Log: LoggingServiceDelegate {
#endif
}
func onLogMessageWritten(logService: LoggingService, domain: String, level: LogLevel, message: String) {
func onLogMessageWritten(logService: linphonesw.LoggingService, domain: String, level: linphonesw.LogLevel, message: String) {
output(message, level.rawValue, domain)
}

View file

@ -19,7 +19,6 @@
import linphonesw
import Combine
import SwiftUI
final class MagicSearchSingleton: ObservableObject {

View file

@ -0,0 +1,513 @@
/*
Localizable.strings
Linphone
*/
"" = "";
": %@" = ": %@";
"[https://sip.linphone.org](https://sip.linphone.org)" = "[https://sip.linphone.org](https://sip.linphone.org)";
"[linphone.org/contact](https://linphone.org/contact)" = "[linphone.org/contact](https://linphone.org/contact)";
"*" = "*";
"**%@**" = "**%@**";
"#" = "#";
"%@" = "%@";
"%lld" = "%lld";
"%lld %@" = "%1$lld %2$@";
"%lld%%" = "%lld%%";
"+" = "+";
"|" = "|";
"❤️" = "❤️";
"👍" = "👍";
"😂" = "😂";
"😢" = "😢";
"😮" = "😮";
"0" = "0";
"1" = "1";
"2" = "2";
"3" = "3";
"4" = "4";
"5" = "5";
"6" = "6";
"7" = "7";
"8" = "8";
"9" = "9";
"account_settings_audio_video_conference_factory_uri_title" = "Audio/video conference factory URI";
"account_settings_avpf_title" = "AVPF";
"account_settings_bundle_mode_title" = "Bundle mode";
"account_settings_ccmp_server_url_title" = "CCMP server URL";
"account_settings_conference_factory_uri_title" = "Conference factory URI";
"account_settings_cpim_in_basic_conversations_title" = "Use CPIM in \"basic\" conversations";
"account_settings_enable_ice_title" = "Enable ICE";
"account_settings_enable_turn_title" = "Enable TURN";
"account_settings_expire_title" = "Expire (in seconds)";
"account_settings_im_encryption_mandatory_title" = "IM encryption mandatory";
"account_settings_lime_server_url_title" = "E2E encryption keys server URL";
"account_settings_mwi_uri_title" = "MWI server URI (Message Waiting Indicator)";
"account_settings_nat_policy_title" = "NAT policy settings";
"account_settings_outbound_proxy_title" = "Outbound proxy";
"account_settings_push_notification_not_available_title" = "Push notifications aren't available!";
"account_settings_push_notification_title" = "Allow push notifications";
"account_settings_sip_proxy_url_title" = "SIP proxy server URL";
"account_settings_stun_server_url_title" = "STUN/TURN server URL";
"account_settings_title" = "Account settings";
"account_settings_turn_password_title" = "TURN password";
"account_settings_turn_username_title" = "TURN username";
"account_settings_update_password_title" = "Update password";
"account_settings_voicemail_uri_title" = "Voicemail URI";
"assistant_account_create" = "Create";
"assistant_account_creation_sms_confirmation_explanation" = "We have sent a verification code on your phone number %@.Please enter the verification code below:";
"assistant_account_creation_wrong_phone_number" = "Wrong number?";
"assistant_account_login" = "Login";
"assistant_account_login_forbidden_error" = "Wrong username or password";
"assistant_account_register" = "Register";
"assistant_account_register_push_notification_not_received_error" = "Push notification with auth token not received in 5 seconds, please try again later";
"assistant_account_register_unexpected_error" = "Unexpected error occurred, please try again later";
"assistant_already_have_an_account" = "Already have an account?";
"assistant_create_account_using_email_on_our_web_platform" = "Create an account with your email on:";
"assistant_dialog_confirm_phone_number_message" = "Are you sure you want to use %@ phone number?";
"assistant_dialog_confirm_phone_number_title" = "Confirm phone number";
"assistant_dialog_general_terms_and_privacy_policy_message" = "By continuing, you accept our %@ and %@.";
"assistant_dialog_general_terms_and_privacy_policy_title" = "General terms & privacy policy";
"assistant_dialog_general_terms_label" = "general terms";
"assistant_dialog_privacy_policy_label" = "privacy policy";
"assistant_forgotten_password" = "Forgotten password?";
"assistant_invalid_uri_toast" = "Invalid URI";
"assistant_login_third_party_sip_account" = "Use a third party SIP account";
"assistant_no_account_yet" = "No account yet?";
"assistant_permissions_access_camera_title" = "**Access camera:** To capture video during video calls and conferences.";
"assistant_permissions_grant_all_of_them" = "OK";
"assistant_permissions_post_notifications_title" = "**Post notifications:** To be informed when you receive a message or a call.";
"assistant_permissions_read_contacts_title" = "**Read contacts:** To display your contacts and find whom is using %@.";
"assistant_permissions_record_audio_title" = "**Record audio:** So your correspondent can hear you and to record voice messages.";
"assistant_permissions_skip_permissions" = "Do it later";
"assistant_permissions_subtitle" = "To fully enjoy %@ we need you to grant us the following permissions :";
"assistant_permissions_title" = "Grant permissions";
"assistant_qr_code_invalid_toast" = "Invalid QR code!";
"assistant_scan_qr_code" = "Scan QR code";
"assistant_sip_account_transport_protocol" = "Transport";
"assistant_third_party_sip_account_create_linphone_account" = "I prefer to create an account";
"assistant_third_party_sip_account_warning_explanation" = "Some features require a %@ account, such as group messaging, video conferences…\n\nThese features are hidden when you register with a third party SIP account.\n\nTo enable it in a commercial project, please contact us.";
"assistant_third_party_sip_account_warning_ok" = "I understand";
"assistant_web_platform_link" = "subscribe.linphone.org";
"bottom_navigation_calls_label" = "Calls";
"bottom_navigation_contacts_label" = "Contacts";
"bottom_navigation_conversations_label" = "Conversations";
"bottom_navigation_meetings_label" = "Meetings";
"call_action_attended_transfer" = "Attended transfer";
"call_action_blind_transfer" = "Transfer";
"call_action_change_layout" = "Layout";
"call_action_go_to_calls_list" = "Calls list";
"call_action_hang_up" = "Hang up";
"call_action_pause_call" = "Pause";
"call_action_record_call" = "Record";
"call_action_resume_call" = "Resume";
"call_action_show_dialer" = "Dialer";
"call_action_show_messages" = "Messages";
"call_action_start_new_call" = "New call";
"call_audio_device_type_bluetooth" = "Bluetooth (%@)";
"call_audio_device_type_earpiece" = "Earpiece";
"call_audio_device_type_headphones" = "Headphones";
"call_audio_device_type_speaker" = "Speaker";
"call_audio_incoming" = "Incoming call";
"call_can_be_trusted_toast" = "Authenticated device";
"call_dialog_zrtp_security_alert_message" = "This call confidentiality may be compromise!";
"call_dialog_zrtp_security_alert_title" = "Security alert";
"call_dialog_zrtp_security_alert_try_again" = "Try again";
"call_dialog_zrtp_validate_trust_letters_do_not_match" = "Nothing matches";
"call_dialog_zrtp_validate_trust_local_code_label" = "Your code:";
"call_dialog_zrtp_validate_trust_message" = "For your safety, we need to authenticate your correspondent device.Please exchange your codes:";
"call_dialog_zrtp_validate_trust_remote_code_label" = "Correspondent code:";
"call_dialog_zrtp_validate_trust_title" = "Validate the device";
"call_dialog_zrtp_validate_trust_warning_message" = "For your safety, we need to re-authenticate your correspondent device.Please re-exchange your codes:";
"call_do_zrtp_sas_validation_again" = "Validate ZRTP SAS again";
"call_history_deleted_toast" = "History has been deleted";
"call_not_encrypted" = "Call is not encrypted";
"call_outgoing" = "Outgoing call";
"call_srtp_point_to_point_encrypted" = "Point-to-point encrypted by SRTP";
"call_state_connected" = "Active";
"call_state_paused" = "Paused";
"call_state_paused_by_remote" = "Paused by remote";
"call_state_resuming" = "Resuming…";
"call_stats_audio_title" = "Audio";
"call_stats_media_encryption_title" = "Media encryption";
"call_stats_video_title" = "Video";
"call_transfer_current_call_title" = "Transfer call";
"call_transfer_failed_toast" = "Call transfer failed!";
"call_transfer_in_progress_toast" = "Call is being transferred";
"call_transfer_successful_toast" = "Call has been successfully transferred";
"call_waiting_for_encryption_info" = "Waiting for encryption…";
"call_zrtp_end_to_end_encrypted" = "End-to-end encrypted by ZRTP";
"call_zrtp_sas_validation_required" = "Validation required";
"call_zrtp_sas_validation_skip" = "Skip";
"calls_count_label" = "%@ calls";
"calls_list_dialog_merge_into_conference_label" = "Create conference";
"calls_list_dialog_merge_into_conference_title" = "Merge all calls into conference?";
"calls_list_title" = "Calls list";
"Ce mode vous permet dêtre interopérable avec dautres services SIP.\nVos communications seront chiffrées de point à point. " = "Ce mode vous permet dêtre interopérable avec dautres services SIP.\nVos communications seront chiffrées de point à point. ";
"Chiffrement de bout en bout de tous vos échanges, grâce au mode default vos communications sont à labri des regards." = "Chiffrement de bout en bout de tous vos échanges, grâce au mode default vos communications sont à labri des regards.";
"conference_action_screen_sharing" = "Screen share";
"conference_action_show_participants" = "Participants";
"conference_call_empty" = "Waiting for other participants…";
"conference_failed_to_create_group_call_toast" = "Failed to create a group call!";
"conference_layout_active_speaker" = "Speaker";
"conference_layout_audio_only" = "Audio only";
"conference_layout_grid" = "Mosaic";
"conference_name_error" = "Conference name error";
"conference_participant_joining_text" = "Joining…";
"conference_participant_paused_text" = "Paused";
"conference_share_link_title" = "Share invitation";
"contact_call_action" = "Call";
"contact_details_actions_title" = "Other actions";
"contact_details_add_to_favourites" = "Add to favourites";
"contact_details_delete" = "Delete";
"contact_details_edit" = "Edit";
"contact_details_numbers_and_addresses_title" = "Phone numbers &amp; SIP addresses";
"contact_details_remove_from_favourites" = "Remove from favourites";
"contact_details_share" = "Share";
"contact_dialog_delete_message" = "This contact will be definitively removed.";
"contact_dialog_delete_title" = "Delete %@?";
"contact_dialog_pick_phone_number_or_sip_address_title" = "Choose a number or a SIP address";
"contact_edit_title" = "Edit contact";
"contact_editor_company" = "Company";
"contact_editor_dialog_abort_confirmation_message" = "All changes will be lost";
"contact_editor_dialog_abort_confirmation_title" = "Don't save changes?";
"contact_editor_first_name" = "First name";
"contact_editor_job_title" = "Job title";
"contact_editor_last_name" = "Last name";
"contact_message_action" = "Message";
"contact_new_title" = "New contact";
"contact_video_call_action" = "Video call";
"contacts_list_all_contacts_title" = "All contacts";
"contacts_list_empty" = "No contact for the moment…";
"contacts_list_favourites_title" = "Favourites";
"contacts_list_filter_popup_see_all" = "See all";
"contacts_list_filter_popup_see_linphone_only" = "See %@ contacts";
"conversation_action_call" = "Call";
"conversation_action_configure_ephemeral_messages" = "Configure ephemeral messages";
"conversation_action_delete" = "Delete conversation";
"conversation_action_leave_group" = "Leave the group";
"conversation_action_mark_as_read" = "Mark as read";
"conversation_action_mute" = "Mute";
"conversation_action_unmute" = "Un-mute";
"conversation_add_participants_title" = "Add participants";
"conversation_composing_label_multiple" = "%@ are composing…";
"conversation_composing_label_single" = "%@ is composing…";
"conversation_dialog_edit_subject" = "Edit conversation subject";
"conversation_dialog_set_subject" = "Set conversation subject";
"conversation_dialog_subject_hint" = "Conversation subject";
"conversation_end_to_end_encrypted_bottom_sheet_link" = "https://linphone.org/en/features/#security";
"conversation_ephemeral_messages_duration_disabled" = "Disabled";
"conversation_ephemeral_messages_duration_one_day" = "1 day";
"conversation_ephemeral_messages_duration_one_hour" = "1 hour";
"conversation_ephemeral_messages_duration_one_minute" = "1 minute";
"conversation_ephemeral_messages_duration_one_week" = "1 week";
"conversation_ephemeral_messages_duration_three_days" = "3 days";
"conversation_ephemeral_messages_subtitle" = "New messages will be automatically deleted once read by everyone.\nChoose a duration:";
"conversation_ephemeral_messages_title" = "Ephemeral messages";
"conversation_event_admin_set" = "%@ is admin";
"conversation_event_admin_unset" = "%@ is no longer admin";
"conversation_event_conference_created" = "You have joined the group";
"conversation_event_conference_destroyed" = "You have left the group";
"conversation_event_device_added" = "New device for %@";
"conversation_event_device_removed" = "Device for %@ removed";
"conversation_event_ephemeral_messages_disabled" = "Ephemeral messages have been disabled";
"conversation_event_ephemeral_messages_enabled" = "Ephemeral messages have been enabled";
"conversation_event_ephemeral_messages_lifetime_changed" = "Ephemeral lifetime is now %@";
"conversation_event_participant_added" = "%@ has joined";
"conversation_event_participant_removed" = "%@ has left";
"conversation_event_subject_changed" = "New subject: %@";
"conversation_failed_to_create_toast" = "Failed to create conversation!";
"conversation_forward_message_title" = "Forward message to…";
"conversation_info_add_participants_label" = "Add participants";
"conversation_info_admin_menu_remove_participant" = "Remove from the group";
"conversation_info_admin_menu_set_participant_admin" = "Give admin rights";
"conversation_info_admin_menu_unset_participant_admin" = "Remove admin rights";
"conversation_info_confirm_start_group_call_dialog_message" = "All participants will receive a call.";
"conversation_info_confirm_start_group_call_dialog_title" = "Start a group call?";
"conversation_info_delete_history_action" = "Delete history";
"conversation_info_menu_add_to_contacts" = "Add to contacts";
"conversation_info_menu_go_to_contact" = "See contact profile";
"conversation_info_participant_is_admin_label" = "Admin";
"conversation_info_participants_list_title" = "Group members";
"conversation_invalid_participant_due_to_security_mode_toast" = "Can't create conversation with a participant not on the same domain due to security restrictions!";
"conversation_menu_configure_ephemeral_messages" = "Ephemeral messages";
"conversation_menu_go_to_info" = "Conversation info";
"conversation_message_forward_cancelled_toast" = "Message forward was cancelled";
"conversation_message_forwarded_toast" = "Message was forwarded";
"conversation_message_meeting_cancelled_label" = "Meeting has been cancelled!";
"conversation_message_meeting_updated_label" = "Meeting has been updated";
"conversation_one_to_one_hidden_subject" = "Dummy subject";
"conversation_reply_to_message_title" = "Replying to: ";
"conversation_text_field_hint" = "Say something…";
"conversations_list_empty" = "No conversation for the moment…";
"debug_logs_copied_to_clipboard_toast" = "Debug logs copied to clipboard";
"Default" = "Default";
"Default mode" = "Default mode";
"dialog_accept" = "Accept";
"dialog_call" = "Call";
"dialog_cancel" = "Cancel";
"dialog_close" = "Close";
"dialog_continue" = "Continue";
"dialog_deny" = "Deny";
"dialog_install" = "Install";
"dialog_no" = "No";
"dialog_ok" = "OK";
"dialog_yes" = "Yes";
"drawer_menu_account_connection_status_cleared" = "Disabled";
"drawer_menu_account_connection_status_connected" = "Connected";
"drawer_menu_account_connection_status_failed" = "Error";
"drawer_menu_account_connection_status_progress" = "Connecting…";
"drawer_menu_account_connection_status_refreshing" = "Refreshing ...";
"drawer_menu_add_account" = "Add an account";
"drawer_menu_manage_account" = "Manage the profile";
"drawer_menu_no_account_configured_yet" = "No account configured yet";
"DTLS" = "DTLS";
"Error" = "Error";
"failed_meeting_ics_invitation_not_sent_toast" = "Could not send ICS invitations to meeting to any participant";
"GC_MSG" = "You have been added to a chat room";
"generic_address_picker_suggestions_list_title" = "Suggestions";
"help_about_advanced_title" = "Advanced";
"help_about_check_for_update" = "Check update";
"help_about_contribute_translations_title" = "Contribute on Linphone translation";
"help_about_open_source_licenses_subtitle" = "© Belledonne Communications 2010-2024";
"help_about_open_source_licenses_title" = "GNU General Public License v3.0";
"help_about_privacy_policy_subtitle" = "What information Linphone collects and uses";
"help_about_privacy_policy_title" = "Privacy policy";
"help_about_title" = "About Linphone";
"help_about_version_title" = "Version";
"help_dialog_update_available_message" = "A new version %@ is available. Do you want to update?";
"help_dialog_update_available_title" = "Update available";
"help_error_checking_version_toast_message" = "An error occurred while checking for update";
"help_quit_title" = "Quit app";
"help_title" = "Help";
"help_troubleshooting_app_version_title" = "App version";
"help_troubleshooting_clean_logs" = "Clean logs";
"help_troubleshooting_clear_native_friends_in_database" = "Clear imported contacts from native address book";
"help_troubleshooting_debug_logs_cleaned_toast_message" = "Debug logs have been cleaned";
"help_troubleshooting_debug_logs_upload_error_toast_message" = "Failed to upload debug logs";
"help_troubleshooting_firebase_project_title" = "Firebase project ID";
"help_troubleshooting_print_logs_in_logcat" = "Print logs in logcat";
"help_troubleshooting_sdk_version_title" = "SDK version";
"help_troubleshooting_share_logs" = "Share logs";
"help_troubleshooting_share_logs_dialog_title" = "Share debug logs link using…";
"help_troubleshooting_show_config_file" = "Show configuration";
"help_troubleshooting_title" = "Troubleshooting";
"help_version_up_to_date_toast_message" = "Your version is up-to-date";
"history_call_start_create_group_call" = "Create a group call";
"history_call_start_search_bar_filter_hint" = "Search contact or history call";
"history_call_start_title" = "New call";
"history_dialog_delete_all_call_logs_message" = "All calls will be removed from the history";
"history_dialog_delete_all_call_logs_title" = "Do you really want to delete all calls history?";
"history_group_call_start_dialog_set_subject" = "Set group call subject";
"history_group_call_start_dialog_subject_hint" = "Group call subject";
"history_list_empty_history" = "No call for the moment…";
"history_list_empty_with_filter_history" = "No entries match your search";
"history_title" = "Call History";
"IM_MSG" = "You have received a message";
"Interoperable" = "Interoperable";
"Interoperable mode" = "Interoperable mode";
"list_filter_no_result_found" = "No result found…";
"manage_account_add_picture" = "Add a picture";
"manage_account_delete" = "Sign out";
"manage_account_details_title" = "Details";
"manage_account_device_last_connection" = "Last connection:";
"manage_account_device_remove" = "Remove";
"manage_account_devices_title" = "Devices";
"manage_account_dialog_international_prefix_help_message" = "Pick your country to allow Linphone to match your contacts.";
"manage_account_dialog_remove_account_message" = "If you wish to delete your account permanently, go to: https://sip.linphone.org";
"manage_account_dialog_remove_account_title" = "Sign out of your account?";
"manage_account_edit_picture" = "Edit picture";
"manage_account_international_prefix" = "International Prefix";
"manage_account_no_device" = "No device found…";
"manage_account_remove_picture" = "Remove picture";
"manage_account_settings" = "Account settings";
"manage_account_status_cleared_summary" = "Account has been disabled, you won't receive any call or message.";
"manage_account_status_connected_summary" = "This account in online, everybody can call you.";
"manage_account_status_failed_summary" = "Account connection failed, check your settings.";
"manage_account_status_progress_summary" = "Account is connecting to the server, please wait…";
"manage_account_title" = "Manage account";
"meeting_call_remove_no_participants" = "No participant for the moment…";
"meeting_call_remove_participant_confirmation_message" = "Are you sure you wish to remove %@ ?";
"meeting_call_remove_participant_confirmation_title" = "Remove a participant";
"meeting_exported_as_calendar_event" = "Meeting added to iPhone calendar";
"meeting_failed_to_edit_toast" = "Failed to edit meeting";
"meeting_failed_to_schedule_toast" = "Failed to schedule meeting!";
"meeting_failed_to_send_invites_toast" = "Failed to send all invites to meeting!";
"meeting_failed_to_send_part_of_invites_toast" = "Failed to send invites to some participants of the meeting!";
"meeting_info_cancelled_toast" = "Meeting has been cancelled";
"meeting_info_created_toast" = "Meeting has been created";
"meeting_info_delete" = "Delete meeting";
"meeting_info_deleted_toast" = "Meeting has been deleted";
"meeting_info_export_as_calendar_event" = "Create calendar event";
"meeting_info_join_title" = "Join the meeting now";
"meeting_info_organizer_label" = "Organizer";
"meeting_info_updated_toast" = "Meeting has been updated";
"meeting_schedule_add_participants_title" = "Add participants";
"meeting_schedule_cancel_dialog_message" = "Do you want to cancel the meeting and send a notification to all participants?";
"meeting_schedule_cancel_dialog_title" = "Cancel the meeting?";
"meeting_schedule_description_hint" = "Add description";
"meeting_schedule_description_title" = "Description";
"meeting_schedule_edit_title" = "Edit meeting";
"meeting_schedule_failed_no_subject_or_participant_toast" = "A subject and at least one participant is required to create a meeting";
"meeting_schedule_meeting_label" = "Meeting";
"meeting_schedule_pick_end_time_title" = "Choose the end time";
"meeting_schedule_pick_start_date_title" = "Choose the start date";
"meeting_schedule_pick_start_time_title" = "Choose the start time";
"meeting_schedule_send_invitations_title" = "Send invitation to participants";
"meeting_schedule_subject_hint" = "Add title…";
"meeting_schedule_timezone_title" = "Timezone";
"meeting_schedule_title" = "New meeting";
"meeting_waiting_room_cancel" = "Cancel";
"meeting_waiting_room_join" = "Join";
"meeting_waiting_room_joining_subtitle" = "You\\'ll be joining in a short moment";
"meeting_waiting_room_joining_title" = "Connection in progress";
"meetings_list_empty" = "No meeting for the moment…";
"meetings_list_no_meeting_for_today" = "No meeting scheduled for today";
"menu_add_address_to_contacts" = "Add to contacts";
"menu_block_address" = "Block the address";
"menu_block_number" = "Block the number";
"menu_copy_chat_message" = "Copy";
"menu_copy_phone_number" = "Copy phone number";
"menu_copy_sip_address" = "Copy SIP addres";
"menu_delete_history" = "Delete history";
"menu_delete_selected_item" = "Delete";
"menu_forward_chat_message" = "Forward";
"menu_invite" = "Invite";
"menu_reply_to_chat_message" = "Reply";
"menu_resend_chat_message" = "Re-send";
"menu_see_existing_contact" = "See contact";
"message_copied_to_clipboard_toast" = "Message copied into clipboard";
"message_delivery_info_error_title" = "Error";
"message_delivery_info_read_title" = "Read";
"message_delivery_info_received_title" = "Received";
"message_delivery_info_sent_title" = "Sent";
"message_forwarded_label" = "Forwarded";
"message_meeting_invitation_cancelled_notification" = "📅 Meeting has been cancelled";
"message_meeting_invitation_notification" = "📅 You are invited to a meeting";
"message_meeting_invitation_updated_notification" = "📅 Meeting has been updated";
"message_reaction_click_to_remove_label" = "Click to remove";
"message_reactions_info_all_title" = "Reactions";
"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";
"new_conversation_search_bar_filter_hint" = "Search contact";
"new_conversation_title" = "New conversation";
"next" = "Next";
"None" = "None";
"notification_chat_message_reaction_received" = "%@ reacted by %@ to: %@";
"notification_chat_message_received_title" = "Message received";
"notification_missed_call_title" = "Missed call";
"operation_in_progress_overlay" = "Operation in progress, please wait";
"or" = "or";
"password" = "Password";
"Personnalize your profil mode" ="Personnalize your profil mode";
"phone_number" = "Phone number";
"picker_categories" = "Categories";
"qr_code_validated" = "QR code validated";
"recordings_title" = "Recordings";
"selected_participants_count" = "%@ selected participants";
"settings_advanced_accept_early_media_title" = "Accept early media";
"settings_advanced_allow_outgoing_early_media_title" = "Allow outgoing early media";
"settings_advanced_audio_codecs_title" = "Audio codecs";
"settings_advanced_audio_devices_title" = "Audio devices";
"settings_advanced_device_id" = "Device ID";
"settings_advanced_device_id_hint" = "Alpha-numerical characters only";
"settings_advanced_download_apply_remote_provisioning" = "Download & apply";
"settings_advanced_input_audio_device_title" = "Default input audio device";
"settings_advanced_media_encryption_mandatory_title" = "Media encryption mandatory";
"settings_advanced_output_audio_device_title" = "Default output audio device";
"settings_advanced_remote_provisioning_url" = "Remote provisioning URL";
"settings_advanced_title" = "Advanced settings";
"settings_advanced_upload_server_url" = "File sharing server URL";
"settings_advanced_video_codecs_title" = "Video codecs";
"settings_calls_adaptive_rate_control_title" = "Adaptive rate control";
"settings_calls_auto_record_title" = "Automatically start recording calls";
"settings_calls_calibrate_echo_canceller_done" = "%@ ms";
"settings_calls_calibrate_echo_canceller_done_no_echo" = "no echo";
"settings_calls_calibrate_echo_canceller_failed" = "failed";
"settings_calls_calibrate_echo_canceller_in_progress" = "in progress";
"settings_calls_calibrate_echo_canceller_title" = "Calibrate echo canceller";
"settings_calls_change_ringtone_title" = "Change ringtone";
"settings_calls_echo_canceller_subtitle" = "Prevents echo from being heard by remote end if no hardware echo canceller is available";
"settings_calls_echo_canceller_title" = "Use software echo canceller";
"settings_calls_enable_fec_title" = "Enable video FEC";
"settings_calls_enable_video_title" = "Enable video";
"settings_calls_title" = "Calls";
"settings_calls_vibrate_while_ringing_title" = "Vibrate while incoming call is ringing";
"settings_contacts_add_carddav_server_title" = "Add CardDAV address book";
"settings_contacts_add_ldap_server_title" = "Add LDAP server";
"settings_contacts_carddav_deleted_toast" = "CardDAV account deleted";
"settings_contacts_carddav_mandatory_field_not_filled_toast" = "Please fill in at least the display name and server URL";
"settings_contacts_carddav_name_title" = "Display name";
"settings_contacts_carddav_password_title" = "Password";
"settings_contacts_carddav_realm_title" = "Authentication realm";
"settings_contacts_carddav_server_url_title" = "Server URL";
"settings_contacts_carddav_sync_error_toast" = "Synchronization error!";
"settings_contacts_carddav_sync_successful_toast" = "Synchronization successful";
"settings_contacts_carddav_use_as_default_title" = "Store newly created contacts here";
"settings_contacts_carddav_username_title" = "Username";
"settings_contacts_edit_carddav_server_title" = "Edit CardDAV address book";
"settings_contacts_edit_ldap_server_title" = "Edit LDAP server";
"settings_contacts_ldap_bind_dn_title" = "Bind DN";
"settings_contacts_ldap_bind_user_password_title" = "Bind user password";
"settings_contacts_ldap_max_results_title" = "Maximum results";
"settings_contacts_ldap_password_title" = "Password";
"settings_contacts_ldap_request_timeout_title" = "Request timeout";
"settings_contacts_ldap_search_base_title" = "Search base (can't be empty)";
"settings_contacts_ldap_search_filter_title" = "Filter";
"settings_contacts_ldap_server_url_title" = "Server URL (can't be empty)";
"settings_contacts_ldap_use_tls_title" = "Use TLS";
"settings_contacts_title" = "Contacts";
"settings_conversations_auto_download_title" = "Auto-download files";
"settings_conversations_mark_as_read_when_dismissing_notif_title" = "Mark conversation as read when dismissing message notification";
"settings_conversations_title" = "Conversations";
"settings_meetings_default_layout_title" = "Default layout";
"settings_meetings_layout_active_speaker_label" = "Active speaker";
"settings_meetings_layout_mosaic_label" = "Mosaic";
"settings_meetings_title" = "Meetings";
"settings_network_allow_ipv6" = "Allow IPv6";
"settings_network_title" = "Network";
"settings_network_use_wifi_only" = "Use only Wi-Fi networks";
"settings_security_enable_vfs_subtitle" = "Warning: once enabled it can't be disabled!";
"settings_security_enable_vfs_title" = "Encrypt everything";
"settings_security_prevent_screenshots_title" = "Prevent interface from being recorded";
"settings_security_title" = "Security";
"settings_title" = "Settings";
"sip_address" = "SIP Address";
"sip_address_copied_to_clipboard_toast" = "SIP address copied into clipboard";
"sip_address_display_name" = "Display name";
"sip_address_domain" = "Domain";
"sip.linphone.org" = "sip.linphone.org";
"SRTP" = "SRTP";
"start" = "Start";
"TCP" = "TCP";
"Temp Help" = "Temp Help";
"text_copied_to_clipboard_toast" = "Text copied into clipboard";
"TLS" = "TLS";
"UDP" = "UDP";
"uri_handler_bad_call_address_failed_toast" = "Unable to call, invalid address";
"uri_handler_bad_config_address_failed_toast" = "Unable to retrieve configuration, invalid address";
"uri_handler_call_failed_toast" = "Call failed";
"uri_handler_config_failed_toast" = "Configuration failed";
"uri_handler_config_success_toast" = "Configuration successfully applied";
"username" = "Username";
"username_error" = "Username error";
"web_platform_forgotten_password_url" = "https://subscribe.linphone.org/";
"web_platform_register_email_url" = "https://subscribe.linphone.org/register/email";
"website_contact_url" = "https://linphone.org/contact";
"website_download_url" = "https://linphone.org/linphone-softphone";
"website_open_source_licences_usage_url" = "https://wiki.linphone.org/xwiki/wiki/public/view/Linphone/Third%20party%20components%20/";
"website_privacy_policy_url" = "https://linphone.org/en/privacy-policy";
"website_terms_and_conditions_url" = "https://www.linphone.org/en/terms-of-use";
"website_translate_weblate_url" = "https://weblate.linphone.org/";
"welcome_carousel_skip" = "Skip";
"welcome_page_1_message" = "A **secured**, **open source** and **French** communication app.";
"welcome_page_2_message" = "Your communications are safe thanks to our **end-to-end encryption**.";
"welcome_page_2_title" = "Secured";
"welcome_page_3_message" = "A **free** and open source application since **2001**.";
"welcome_page_3_title" = "Open source";
"welcome_page_subtitle" = "in %@";
"welcome_page_title" = "Welcome";
"You will change this mode later" = "You will change this mode later";
"ZRTP" = "ZRTP";

View file

@ -0,0 +1,513 @@
/*
Localizable.strings
Linphone
*/
"" = "";
": %@" = ": %@";
"[https://sip.linphone.org](https://sip.linphone.org)" = "[https://sip.linphone.org](https://sip.linphone.org)";
"[linphone.org/contact](https://linphone.org/contact)" = "[linphone.org/contact](https://linphone.org/contact)";
"*" = "*";
"**%@**" = "**%@**";
"#" = "#";
"%@" = "%@";
"%lld" = "%lld";
"%lld %@" = "%1$lld %2$@";
"%lld%%" = "%lld%%";
"+" = "+";
"|" = "|";
"❤️" = "❤️";
"👍" = "👍";
"😂" = "😂";
"😢" = "😢";
"😮" = "😮";
"0" = "0";
"1" = "1";
"2" = "2";
"3" = "3";
"4" = "4";
"5" = "5";
"6" = "6";
"7" = "7";
"8" = "8";
"9" = "9";
"account_settings_audio_video_conference_factory_uri_title" = "URI du serveur de réunions";
"account_settings_avpf_title" = "AVPF";
"account_settings_bundle_mode_title" = "Mode \"bundle\"";
"account_settings_ccmp_server_url_title" = "URL du serveur CCMP";
"account_settings_conference_factory_uri_title" = "URI du serveur de conversations";
"account_settings_cpim_in_basic_conversations_title" = "Utiliser CPIM dans les conversations \"basiques\"";
"account_settings_enable_ice_title" = "Activer ICE";
"account_settings_enable_turn_title" = "Activer TURN";
"account_settings_expire_title" = "Expiration (en secondes)";
"account_settings_im_encryption_mandatory_title" = "Chiffrement obligatoire des conversations";
"account_settings_lime_server_url_title" = "URL du serveur d'échange de clés de chiffrement";
"account_settings_mwi_uri_title" = "URI du serveur MWI (Message Waiting Indicator)";
"account_settings_nat_policy_title" = "Paramètres de politique NAT";
"account_settings_outbound_proxy_title" = "Serveur mandataire sortant";
"account_settings_push_notification_not_available_title" = "Notifications push non disponibles";
"account_settings_push_notification_title" = "Activer les notifications";
"account_settings_sip_proxy_url_title" = "URL du serveur mandataire";
"account_settings_stun_server_url_title" = "URL du serveur STUN/TURN";
"account_settings_title" = "Paramètres de compte";
"account_settings_turn_password_title" = "Mot de passe TURN";
"account_settings_turn_username_title" = "Utilisateur TURN";
"account_settings_update_password_title" = "Mettre à jour le mot de passe";
"account_settings_voicemail_uri_title" = "URI de la messagerie vocale";
"assistant_account_create" = "Créer";
"assistant_account_creation_sms_confirmation_explanation" = "On vous a envoyé un code de vérification par SMS au numéro %@.Merci de le saisir ci-dessous :";
"assistant_account_creation_wrong_phone_number" = "Numéro incorrect ?";
"assistant_account_login" = "Connexion";
"assistant_account_login_forbidden_error" = "Mauvais nom dutilisateur ou mot de passe";
"assistant_account_register" = "Sinscrire";
"assistant_account_register_push_notification_not_received_error" = "Notification push non reçue, merci de réessayer plus tard";
"assistant_account_register_unexpected_error" = "Un erreur inattendue est survenue, merci de réessayer plus tard";
"assistant_already_have_an_account" = "Vous avez déjà un compte ?";
"assistant_create_account_using_email_on_our_web_platform" = "Créez un compte avec votre email ici :";
"assistant_dialog_confirm_phone_number_message" = "Êtes-vous sûr de vouloir utiliser ce numéro de téléphone ?";
"assistant_dialog_confirm_phone_number_title" = "Confirmez votre numéro de téléphone";
"assistant_dialog_general_terms_and_privacy_policy_message" = "En continuant, vous acceptez nos %@ et %@.";
"assistant_dialog_general_terms_and_privacy_policy_title" = "Conditions de service & politique de confidentialité";
"assistant_dialog_general_terms_label" = "conditions de service";
"assistant_dialog_privacy_policy_label" = "politique de confidentialité";
"assistant_forgotten_password" = "Mot de passe oublié ?";
"assistant_invalid_uri_toast" = "URI invalide";
"assistant_login_third_party_sip_account" = "Jai un compte SIP tiers";
"assistant_no_account_yet" = "Pas encore de compte ?";
"assistant_permissions_access_camera_title" = "**Caméra :** Pour capturer votre vidéo lors des appels et des conférences.";
"assistant_permissions_grant_all_of_them" = "OK";
"assistant_permissions_post_notifications_title" = "**Notifications :** Pour vous informer quand vous recevez un message ou un appel.";
"assistant_permissions_read_contacts_title" = "**Contacts :** Pour vous afficher vos contacts et retrouver qui utilise %@.";
"assistant_permissions_record_audio_title" = "**Microphone :** Pour permettre à vos correspondants de vous entendre.";
"assistant_permissions_skip_permissions" = "Plus tard";
"assistant_permissions_subtitle" = "Pour vous permettre de vous profitez pleinement de %@, nous avons besoin des autorisations suivantes :";
"assistant_permissions_title" = "Donner les permissions";
"assistant_qr_code_invalid_toast" = "Ce QR code est invalide !";
"assistant_scan_qr_code" = "Scanner un QR code";
"assistant_sip_account_transport_protocol" = "Transport";
"assistant_third_party_sip_account_create_linphone_account" = "Je préfère créer un compte";
"assistant_third_party_sip_account_warning_explanation" = "Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %@.\n\nCes fonctionnalités seront masquées si vous utilisez un compte SIP tiers.\n\nPour les activer dans un projet commercial, merci de nous contacter.";
"assistant_third_party_sip_account_warning_ok" = "Jai compris";
"assistant_web_platform_link" = "subscribe.linphone.org";
"bottom_navigation_calls_label" = "Appels";
"bottom_navigation_contacts_label" = "Contacts";
"bottom_navigation_conversations_label" = "Conversations";
"bottom_navigation_meetings_label" = "Réunions";
"call_action_attended_transfer" = "Transfert";
"call_action_blind_transfer" = "Transfert";
"call_action_change_layout" = "Disposition";
"call_action_go_to_calls_list" = "Liste des appels";
"call_action_hang_up" = "Raccrocher";
"call_action_pause_call" = "Mettre en pause";
"call_action_record_call" = "Enregistrer";
"call_action_resume_call" = "Reprendre";
"call_action_show_dialer" = "Pavé";
"call_action_show_messages" = "Messages";
"call_action_start_new_call" = "Nouvel appel";
"call_audio_device_type_bluetooth" = "Bluetooth (%@)";
"call_audio_device_type_earpiece" = "Oreillette";
"call_audio_device_type_headphones" = "Écouteurs";
"call_audio_device_type_speaker" = "Haut parleur";
"call_audio_incoming" = "Appel entrant";
"call_can_be_trusted_toast" = "Appareil authentifié";
"call_dialog_zrtp_security_alert_message" = "La confidentialité de votre appel peut être compromise !";
"call_dialog_zrtp_security_alert_title" = "Alerte de sécurité";
"call_dialog_zrtp_security_alert_try_again" = "Réessayer";
"call_dialog_zrtp_validate_trust_letters_do_not_match" = "Aucune correspondance";
"call_dialog_zrtp_validate_trust_local_code_label" = "Votre code :";
"call_dialog_zrtp_validate_trust_message" = "Pour garantir le chiffrement, nous avons besoin dauthentifier lappareil de votre correspondant.Veuillez échanger vos codes :";
"call_dialog_zrtp_validate_trust_remote_code_label" = "Code correspondant :";
"call_dialog_zrtp_validate_trust_title" = "Vérification de sécurité";
"call_dialog_zrtp_validate_trust_warning_message" = "Pour garantir le chiffrement, nous avons besoin de réauthentifier lappareil de votre correspondant.Veuillez ré-échanger vos codes :";
"call_do_zrtp_sas_validation_again" = "Faire la vérification à nouveau";
"call_history_deleted_toast" = "Historique supprimé";
"call_not_encrypted" = "Appel non chiffré";
"call_outgoing" = "Appel sortant";
"call_srtp_point_to_point_encrypted" = "Appel chiffré de point à point";
"call_state_connected" = "Actif";
"call_state_paused" = "En pause";
"call_state_paused_by_remote" = "Mis en pause par le correspondant";
"call_state_resuming" = "Reprise…";
"call_stats_audio_title" = "Audio";
"call_stats_media_encryption_title" = "Chiffrement du média";
"call_stats_video_title" = "Video";
"call_transfer_current_call_title" = "Transférer lappel";
"call_transfer_failed_toast" = "Echec du transfert";
"call_transfer_in_progress_toast" = "Transfert en cours";
"call_transfer_successful_toast" = "Appel transféré";
"call_waiting_for_encryption_info" = "En attente du chiffrement…";
"call_zrtp_end_to_end_encrypted" = "Appel chiffré de bout en bout";
"call_zrtp_sas_validation_required" = "Vérification nécessaire";
"call_zrtp_sas_validation_skip" = "Passer";
"calls_count_label" = "%@ appels";
"calls_list_dialog_merge_into_conference_label" = "Créer une conférence";
"calls_list_dialog_merge_into_conference_title" = "Fusionner les appels en une conférence ?";
"calls_list_title" = "Liste des appels";
"Ce mode vous permet dêtre interopérable avec dautres services SIP.\nVos communications seront chiffrées de point à point. " = "Ce mode vous permet dêtre interopérable avec dautres services SIP.\nVos communications seront chiffrées de point à point. ";
"Chiffrement de bout en bout de tous vos échanges, grâce au mode default vos communications sont à labri des regards." = "Chiffrement de bout en bout de tous vos échanges, grâce au mode default vos communications sont à labri des regards.";
"conference_action_screen_sharing" = "Partage décran";
"conference_action_show_participants" = "Participants";
"conference_call_empty" = "En attente dautres participants…";
"conference_failed_to_create_group_call_toast" = "Echec de lappel de groupe";
"conference_layout_active_speaker" = "Intervenant actif";
"conference_layout_audio_only" = "Audio uniquement";
"conference_layout_grid" = "Mosaïque";
"conference_name_error" = "Nom de réunion invalide";
"conference_participant_joining_text" = "En train de rejoindre…";
"conference_participant_paused_text" = "En pause";
"conference_share_link_title" = "Partager le lien";
"contact_call_action" = "Appel";
"contact_details_actions_title" = "Autres actions";
"contact_details_add_to_favourites" = "Ajouter aux favoris";
"contact_details_delete" = "Supprimer";
"contact_details_edit" = "Modifier";
"contact_details_numbers_and_addresses_title" = "Coordonnées";
"contact_details_remove_from_favourites" = "Retirer des favoris";
"contact_details_share" = "Partager";
"contact_dialog_delete_message" = "Ce contact sera définitivement supprimé.";
"contact_dialog_delete_title" = "Supprimer %@ ?";
"contact_dialog_pick_phone_number_or_sip_address_title" = "Choisissez un numéro ou adresse SIP";
"contact_edit_title" = "Modifier contact";
"contact_editor_company" = "Entreprise";
"contact_editor_dialog_abort_confirmation_message" = "Toutes vos modifications seront perdues.";
"contact_editor_dialog_abort_confirmation_title" = "Ignorer les modifications ?";
"contact_editor_first_name" = "Prénom";
"contact_editor_job_title" = "Poste";
"contact_editor_last_name" = "Nom de famille";
"contact_message_action" = "Message";
"contact_new_title" = "Nouveau contact";
"contact_video_call_action" = "Appel vidéo";
"contacts_list_all_contacts_title" = "Tous les contacts";
"contacts_list_empty" = "Aucun contact pour le moment…";
"contacts_list_favourites_title" = "Favoris";
"contacts_list_filter_popup_see_all" = "Tous les contacts";
"contacts_list_filter_popup_see_linphone_only" = "Contacts %@";
"conversation_action_call" = "Appeler";
"conversation_action_configure_ephemeral_messages" = "Configurer les messages éphémères";
"conversation_action_delete" = "Supprimer la conversation";
"conversation_action_leave_group" = "Quitter la conversation";
"conversation_action_mark_as_read" = "Marquer comme lu";
"conversation_action_mute" = "Mettre en sourdine";
"conversation_action_unmute" = "Réactiver les notifications";
"conversation_add_participants_title" = "Ajouter des participants";
"conversation_composing_label_multiple" = "%@ sont en train d'écrire…";
"conversation_composing_label_single" = "%@ est en train d'écrire…";
"conversation_dialog_edit_subject" = "Renommer la conversation";
"conversation_dialog_set_subject" = "Nommer la conversation";
"conversation_dialog_subject_hint" = "Nom de la conversation";
"conversation_end_to_end_encrypted_bottom_sheet_link" = "https://linphone.org/en/features/#security";
"conversation_ephemeral_messages_duration_disabled" = "Désactiver";
"conversation_ephemeral_messages_duration_one_day" = "1 jour";
"conversation_ephemeral_messages_duration_one_hour" = "1 heure";
"conversation_ephemeral_messages_duration_one_minute" = "1 minute";
"conversation_ephemeral_messages_duration_one_week" = "1 semaine";
"conversation_ephemeral_messages_duration_three_days" = "3 jours";
"conversation_ephemeral_messages_subtitle" = "Les messages éphémères seront automatiquement supprimés après avoir été lus par tous et une fois le délai suivant écoulé :";
"conversation_ephemeral_messages_title" = "Messages éphémères";
"conversation_event_admin_set" = "%@ est admin";
"conversation_event_admin_unset" = "%@ n'est plus admin";
"conversation_event_conference_created" = "Vous avez rejoint la conversation";
"conversation_event_conference_destroyed" = "Vous avez quitté la conversation";
"conversation_event_device_added" = "Nouvel appareil pour %@";
"conversation_event_device_removed" = "Appareil supprimé pour %@";
"conversation_event_ephemeral_messages_disabled" = "Messages éphémères désactivés";
"conversation_event_ephemeral_messages_enabled" = "Messages éphémères activés";
"conversation_event_ephemeral_messages_lifetime_changed" = "Messages éphémères %@";
"conversation_event_participant_added" = "%@ a rejoint la conversation";
"conversation_event_participant_removed" = "%@ a quitté la conversation";
"conversation_event_subject_changed" = "La conversation a été renommée : %@";
"conversation_failed_to_create_toast" = "Échec de création de la conversation !";
"conversation_forward_message_title" = "Transférer à…";
"conversation_info_add_participants_label" = "Ajouter des participants";
"conversation_info_admin_menu_remove_participant" = "Retirer participant";
"conversation_info_admin_menu_set_participant_admin" = "Donner les droits admin";
"conversation_info_admin_menu_unset_participant_admin" = "Retirer les droits admin";
"conversation_info_confirm_start_group_call_dialog_message" = "Tous les participants de la conversation recevront un appel.";
"conversation_info_confirm_start_group_call_dialog_title" = "Lancer un appel de groupe ?";
"conversation_info_delete_history_action" = "Supprimer l'historique";
"conversation_info_menu_add_to_contacts" = "Ajouter aux contacts";
"conversation_info_menu_go_to_contact" = "Voir le contact";
"conversation_info_participant_is_admin_label" = "Administrateur";
"conversation_info_participants_list_title" = "Participants";
"conversation_invalid_participant_due_to_security_mode_toast" = "Pour des raisons de sécurité, la création d'une conversation avec un participant d'un domaine tiers est désactivé.";
"conversation_menu_configure_ephemeral_messages" = "Messages éphémères";
"conversation_menu_go_to_info" = "Informations";
"conversation_message_forward_cancelled_toast" = "Transfert annulé";
"conversation_message_forwarded_toast" = "Message transféré";
"conversation_message_meeting_cancelled_label" = "La réunion a été annulée";
"conversation_message_meeting_updated_label" = "La réunion a été mise à jour";
"conversation_one_to_one_hidden_subject" = "Dummy subject";
"conversation_reply_to_message_title" = "En réponse à : ";
"conversation_text_field_hint" = "Dites quelque chose…";
"conversations_list_empty" = "Aucune conversation pour le moment…";
"debug_logs_copied_to_clipboard_toast" = "Les journaux ont été ajoutés au presse-papier";
"Default" = "Default";
"Default mode" = "Default mode";
"dialog_accept" = "Accepter";
"dialog_call" = "Appeler";
"dialog_cancel" = "Annuler";
"dialog_close" = "Fermer";
"dialog_continue" = "Continuer";
"dialog_deny" = "Refuser";
"dialog_install" = "Installer";
"dialog_no" = "Non";
"dialog_ok" = "OK";
"dialog_yes" = "Oui";
"drawer_menu_account_connection_status_cleared" = "Désactivé";
"drawer_menu_account_connection_status_connected" = "Connecté";
"drawer_menu_account_connection_status_failed" = "Erreur";
"drawer_menu_account_connection_status_progress" = "Connexion…";
"drawer_menu_account_connection_status_refreshing" = "Rafraîchissement…";
"drawer_menu_add_account" = "Ajouter un compte";
"drawer_menu_manage_account" = "Mon compte";
"drawer_menu_no_account_configured_yet" = "Aucun compte configuré";
"DTLS" = "DTLS";
"Error" = "Erreur";
"failed_meeting_ics_invitation_not_sent_toast" = "Echec de lenvoi des invitations ICS de la réunion aux participants";
"GC_MSG" = "Vous avez été ajouté à une conversation";
"generic_address_picker_suggestions_list_title" = "Suggestions";
"help_about_advanced_title" = "Avancé";
"help_about_check_for_update" = "Vérifier les mises à jour";
"help_about_contribute_translations_title" = "Aider à traduire Linphone";
"help_about_open_source_licenses_subtitle" = "© Belledonne Communications 2010-2024";
"help_about_open_source_licenses_title" = "GNU General Public License v3.0";
"help_about_privacy_policy_subtitle" = "Quelles informations Linphone collecte et utilise";
"help_about_privacy_policy_title" = "Politique de confidentialité";
"help_about_title" = "À propos de Linphone";
"help_about_version_title" = "Version";
"help_dialog_update_available_message" = "Une nouvelle version %@ est disponible. Voulez-vous mettre à jour ?";
"help_dialog_update_available_title" = "Mise à jour disponible";
"help_error_checking_version_toast_message" = "Une erreur est survenue";
"help_quit_title" = "Quitter l'application";
"help_title" = "Aide";
"help_troubleshooting_app_version_title" = "Version de l'application";
"help_troubleshooting_clean_logs" = "Nettoyer les journaux";
"help_troubleshooting_clear_native_friends_in_database" = "Supprimer les contacts natifs importés";
"help_troubleshooting_debug_logs_cleaned_toast_message" = "Les journaux ont été nettoyés";
"help_troubleshooting_debug_logs_upload_error_toast_message" = "Echec à l'envoi des journaux";
"help_troubleshooting_firebase_project_title" = "ID du projet Firebase";
"help_troubleshooting_print_logs_in_logcat" = "Imprimer les journaux dans logcat";
"help_troubleshooting_sdk_version_title" = "Version du SDK";
"help_troubleshooting_share_logs" = "Partager les journaux";
"help_troubleshooting_share_logs_dialog_title" = "Partager le lien vers journaux avec…";
"help_troubleshooting_show_config_file" = "Afficher la configuration";
"help_troubleshooting_title" = "Dépannage";
"help_version_up_to_date_toast_message" = "Votre version est à jour";
"history_call_start_create_group_call" = "Démarrer un appel de groupe";
"history_call_start_search_bar_filter_hint" = "Cherchez un contact ou une suggestion";
"history_call_start_title" = "Nouvel appel";
"history_dialog_delete_all_call_logs_message" = "Lensemble de votre historique dappels sera définitivement supprimé.";
"history_dialog_delete_all_call_logs_title" = "Supprimer lhistorique dappels ?";
"history_group_call_start_dialog_set_subject" = "Nommer l'appel de groupe";
"history_group_call_start_dialog_subject_hint" = "Nom de l'appel de groupe";
"history_list_empty_history" = "Aucun appel dans votre historique…";
"history_list_empty_with_filter_history" = "Aucune entrée ne correspond à votre recherche";
"history_title" = "Historique dappel";
"IM_MSG" = "Vous avez reçu un message";
"Interoperable" = "Interoperable";
"Interoperable mode" = "Interoperable mode";
"list_filter_no_result_found" = "Aucun résultat…";
"manage_account_add_picture" = "Ajouter une image";
"manage_account_delete" = "Se déconnecter";
"manage_account_details_title" = "Détails";
"manage_account_device_last_connection" = "Dernière connexion :";
"manage_account_device_remove" = "Supprimer";
"manage_account_devices_title" = "Appareils";
"manage_account_dialog_international_prefix_help_message" = "Choisissez votre pays pour permettre à Linphone de faire le lien avec vos contacts.";
"manage_account_dialog_remove_account_message" = "Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org";
"manage_account_dialog_remove_account_title" = "Se déconnecter du compte ?";
"manage_account_edit_picture" = "Modifier";
"manage_account_international_prefix" = "Indicatif international";
"manage_account_no_device" = "Aucun appareil n'a été trouvé…";
"manage_account_remove_picture" = "Supprimer";
"manage_account_settings" = "Mon compte";
"manage_account_status_cleared_summary" = "Compte désactivé, vous ne recevrez ni appel ni message.";
"manage_account_status_connected_summary" = "Vous êtes en ligne, on peut vous joindre.";
"manage_account_status_failed_summary" = "Erreur de connexion, vérifiez vos paramètres.";
"manage_account_status_progress_summary" = "Connexion en cours, merci de patienter…";
"manage_account_title" = "Mon compte";
"meeting_call_remove_no_participants" = "Aucun participant pour linstant…";
"meeting_call_remove_participant_confirmation_message" = "Voulez vous vraiment exclure %@ ?";
"meeting_call_remove_participant_confirmation_title" = "Exclure un participant";
"meeting_exported_as_calendar_event" = "Réunion ajoutée au calendrier de liPhone";
"meeting_failed_to_edit_toast" = "Échec de la modification de la réunion";
"meeting_failed_to_schedule_toast" = "Échec de création de la réunion !";
"meeting_failed_to_send_invites_toast" = "Échec de l'envoi des invitations à la réunion !";
"meeting_failed_to_send_part_of_invites_toast" = "Échec de l'envoi des invitations à certains des participants !";
"meeting_info_cancelled_toast" = "Réunion annulée";
"meeting_info_created_toast" = "Réunion créée";
"meeting_info_delete" = "Supprimer la réunion";
"meeting_info_deleted_toast" = "Réunion supprimée";
"meeting_info_export_as_calendar_event" = "Ajouter dans le calendrier";
"meeting_info_join_title" = "Rejoindre la réunion";
"meeting_info_organizer_label" = "Organisateur";
"meeting_info_updated_toast" = "Réunion mise à jour";
"meeting_schedule_add_participants_title" = "Ajouter des participants";
"meeting_schedule_cancel_dialog_message" = "Voulez-vous annuler la réunion et envoyer une notification aux participants ?";
"meeting_schedule_cancel_dialog_title" = "Annuler la réunion ?";
"meeting_schedule_description_hint" = "Ajouter une description";
"meeting_schedule_description_title" = "Description";
"meeting_schedule_edit_title" = "Modifier la réunion";
"meeting_schedule_failed_no_subject_or_participant_toast" = "Il faut au moins un sujet et un participant pour créer une réunion";
"meeting_schedule_meeting_label" = "Réunion";
"meeting_schedule_pick_end_time_title" = "Heure de fin";
"meeting_schedule_pick_start_date_title" = "Date de début";
"meeting_schedule_pick_start_time_title" = "Heure de début";
"meeting_schedule_send_invitations_title" = "Envoyer linvitation par message aux participants";
"meeting_schedule_subject_hint" = "Ajouter un titre…";
"meeting_schedule_timezone_title" = "Fuseau horaire";
"meeting_schedule_title" = "Nouvelle réunion";
"meeting_waiting_room_cancel" = "Annuler";
"meeting_waiting_room_join" = "Rejoindre";
"meeting_waiting_room_joining_subtitle" = "Vous allez rejoindre la réunion dans quelques instants…";
"meeting_waiting_room_joining_title" = "Connexion à la réunion";
"meetings_list_empty" = "Aucune réunion pour le moment…";
"meetings_list_no_meeting_for_today" = "Aucune réunion aujourd\\'hui";
"menu_add_address_to_contacts" = "Ajouter aux contacts";
"menu_block_address" = "Bloquer l'adresse";
"menu_block_number" = "Bloquer le numéro";
"menu_copy_chat_message" = "Copier le texte";
"menu_copy_phone_number" = "Copier le numéro";
"menu_copy_sip_address" = "Copier l\\'adresse SIP";
"menu_delete_history" = "Supprimer l\\'historique d\\'appels";
"menu_delete_selected_item" = "Supprimer";
"menu_forward_chat_message" = "Transférer";
"menu_invite" = "Inviter";
"menu_reply_to_chat_message" = "Répondre";
"menu_resend_chat_message" = "Ré-envoyer";
"menu_see_existing_contact" = "Voir le contact";
"message_copied_to_clipboard_toast" = "Message copié dans le presse-papier";
"message_delivery_info_error_title" = "En erreur";
"message_delivery_info_read_title" = "Lu";
"message_delivery_info_received_title" = "Reçu";
"message_delivery_info_sent_title" = "Envoyé";
"message_forwarded_label" = "Transféré";
"message_meeting_invitation_cancelled_notification" = "📅 Réunion annulée";
"message_meeting_invitation_notification" = "📅 Invitation à une réunion";
"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";
"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";
"new_conversation_search_bar_filter_hint" = "Chercher un contact";
"new_conversation_title" = "Créer une conversation";
"next" = "Suivant";
"None" = "None";
"notification_chat_message_reaction_received" = "%@ a réagi par %@ à : %@";
"notification_chat_message_received_title" = "Message reçu";
"notification_missed_call_title" = "Appel manqué";
"operation_in_progress_overlay" = "Opération en cours, merci de patienter...";
"or" = "ou";
"password" = "Mot de passe";
"Personnalize your profil mode" = "Personnalize your profil mode";
"phone_number" = "Numéro de téléphone";
"picker_categories" = "Catégories";
"qr_code_validated" = "QR code validé";
"recordings_title" = "Enregistrements";
"selected_participants_count" = "%@ participants selectionnés";
"settings_advanced_accept_early_media_title" = "Accepter l'early media";
"settings_advanced_allow_outgoing_early_media_title" = "Autoriser l'early media pour les appels sortants";
"settings_advanced_audio_codecs_title" = "Codecs audio";
"settings_advanced_audio_devices_title" = "Périphériques audio";
"settings_advanced_device_id" = "Nom de l'appareil";
"settings_advanced_device_id_hint" = "Caractères alpha-numériques uniquement";
"settings_advanced_download_apply_remote_provisioning" = "Télécharger & appliquer";
"settings_advanced_input_audio_device_title" = "Périphérique de capture par défaut";
"settings_advanced_media_encryption_mandatory_title" = "Rendre le chiffrement du média obligatoire";
"settings_advanced_output_audio_device_title" = "Périphérique d'écoute par défaut";
"settings_advanced_remote_provisioning_url" = "URL de configuration distante";
"settings_advanced_title" = "Paramètres avancés";
"settings_advanced_upload_server_url" = "URL du serveur de partage de fichier";
"settings_advanced_video_codecs_title" = "Codecs vidéo";
"settings_calls_adaptive_rate_control_title" = "Contrôle automatique de la qualité";
"settings_calls_auto_record_title" = "Enregistrement automatique des appels";
"settings_calls_calibrate_echo_canceller_done" = "%@ ms";
"settings_calls_calibrate_echo_canceller_done_no_echo" = "pas d'écho";
"settings_calls_calibrate_echo_canceller_failed" = "échec";
"settings_calls_calibrate_echo_canceller_in_progress" = "en cours";
"settings_calls_calibrate_echo_canceller_title" = "Calibrer l'annulateur d'écho";
"settings_calls_change_ringtone_title" = "Changer de sonnerie";
"settings_calls_echo_canceller_subtitle" = "Évite que de l'écho soit entendu par votre correspondant si un annulateur matériel n'est pas disponible";
"settings_calls_echo_canceller_title" = "Utiliser l'annulateur d'écho logiciel";
"settings_calls_enable_fec_title" = "Activer la FEC vidéo";
"settings_calls_enable_video_title" = "Autoriser la vidéo";
"settings_calls_title" = "Appels";
"settings_calls_vibrate_while_ringing_title" = "Vibration lors de lappel";
"settings_contacts_add_carddav_server_title" = "Ajouter un carnet d'adresse CardDAV";
"settings_contacts_add_ldap_server_title" = "Ajouter un serveur LDAP";
"settings_contacts_carddav_deleted_toast" = "Compte CardDAV supprimé";
"settings_contacts_carddav_mandatory_field_not_filled_toast" = "Veuillez remplir au moins le nom d'affichage et l'URL du serveur";
"settings_contacts_carddav_name_title" = "Nom d'affichage";
"settings_contacts_carddav_password_title" = "Mot de passe";
"settings_contacts_carddav_realm_title" = "Domaine d'authentification";
"settings_contacts_carddav_server_url_title" = "URL du serveur";
"settings_contacts_carddav_sync_error_toast" = "Erreur de synchronization !";
"settings_contacts_carddav_sync_successful_toast" = "Synchronization réussie";
"settings_contacts_carddav_use_as_default_title" = "Stocker ici les contacts nouvellement crées";
"settings_contacts_carddav_username_title" = "Nom d'utilisateur";
"settings_contacts_edit_carddav_server_title" = "Editer le carnet d'adresse CardDAV";
"settings_contacts_edit_ldap_server_title" = "Editer le serveur LDAP";
"settings_contacts_ldap_bind_dn_title" = "Bind DN";
"settings_contacts_ldap_bind_user_password_title" = "Mot de passe de l'utilisateur Bind";
"settings_contacts_ldap_max_results_title" = "Nombre de résultats maximum";
"settings_contacts_ldap_password_title" = "Mot de passe";
"settings_contacts_ldap_request_timeout_title" = "Délai d'attente de la requête";
"settings_contacts_ldap_search_base_title" = "Base de recherche (ne peut être vide)";
"settings_contacts_ldap_search_filter_title" = "Filtre";
"settings_contacts_ldap_server_url_title" = "URL du serveur (ne peut être vide)";
"settings_contacts_ldap_use_tls_title" = "Utiliser TLS";
"settings_contacts_title" = "Contacts";
"settings_conversations_auto_download_title" = "Télécharger automatiquement les fichiers";
"settings_conversations_mark_as_read_when_dismissing_notif_title" = "Marquer la conversation comme lue lorsqu'une notification de message est supprimée";
"settings_conversations_title" = "Conversations";
"settings_meetings_default_layout_title" = "Disposition par défaut";
"settings_meetings_layout_active_speaker_label" = "Intervenant actif";
"settings_meetings_layout_mosaic_label" = "Mosaïque";
"settings_meetings_title" = "Réunions";
"settings_network_allow_ipv6" = "Autoriser l'IPv6";
"settings_network_title" = "Réseau";
"settings_network_use_wifi_only" = "Se connecter uniquement via le Wi-Fi";
"settings_security_enable_vfs_subtitle" = "Attention, vous ne pourrez pas revenir en arrière !";
"settings_security_enable_vfs_title" = "Chiffrer tous les fichiers";
"settings_security_prevent_screenshots_title" = "Empêcher l'interface d'être enregistrée";
"settings_security_title" = "Securité";
"settings_title" = "Paramètres";
"sip_address" = "Adresse SIP";
"sip_address_copied_to_clipboard_toast" = "Adresse copiée";
"sip_address_display_name" = "Nom d'affichage";
"sip_address_domain" = "Domaine";
"sip.linphone.org" = "sip.linphone.org";
"SRTP" = "SRTP";
"start" = "Commencer";
"TCP" ="TCP";
"Temp Help" ="Temp Help";
"text_copied_to_clipboard_toast" = "Texte copié dans le presse-papier";
"TLS" = "TLS";
"UDP" = "UDP";
"uri_handler_bad_call_address_failed_toast" = "Echec de lappel, ladresse est invalide";
"uri_handler_bad_config_address_failed_toast" = "Echec de la configuration, ladresse est invalide";
"uri_handler_call_failed_toast" = "Echec de lappel";
"uri_handler_config_failed_toast" = "Echec de la configuration";
"uri_handler_config_success_toast" = "Configuration appliquée avec succè";
"username" = "Nom dutilisateur";
"username_error" = "Erreur dans le nom d'utilisateur";
"web_platform_forgotten_password_url" = "https://subscribe.linphone.org/";
"web_platform_register_email_url" = "https://subscribe.linphone.org/register/email";
"website_contact_url" = "https://linphone.org/contact";
"website_download_url" = "https://linphone.org/linphone-softphone";
"website_open_source_licences_usage_url" = "https://wiki.linphone.org/xwiki/wiki/public/view/Linphone/Third%20party%20components%20/";
"website_privacy_policy_url" = "https://linphone.org/en/privacy-policy";
"website_terms_and_conditions_url" = "https://www.linphone.org/en/terms-of-use";
"website_translate_weblate_url" = "https://weblate.linphone.org/";
"welcome_carousel_skip" = "Passer";
"welcome_page_1_message" = "Une application de communication **sécurisée**, **open source** et **française**.";
"welcome_page_2_message" = "Vos communications sont en sécurité grâce au **chiffrement de bout en bout**.";
"welcome_page_2_title" = "Sécurisé";
"welcome_page_3_message" = "Une application open source et un **service gratuit** depuis **2001**.";
"welcome_page_3_title" = "Open source";
"welcome_page_subtitle" = "sur %@";
"welcome_page_title" = "Bienvenue";
"You will change this mode later" = "You will change this mode later";
"ZRTP" = "ZRTP";

View file

@ -4,6 +4,12 @@ source "https://gitlab.linphone.org/BC/public/podspec.git"
source "https://github.com/CocoaPods/Specs.git"
def basic_pods
if ENV['PODFILE_PATH'].nil?
pod 'linphone-sdk', '~> 5.4.0-alpha'
else
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
end
crashlytics
end