From c6179c973cef4dbb6f6beec2ef0179c14f7fff48 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Fri, 11 Jul 2025 11:16:46 +0200 Subject: [PATCH] Add emoji picker --- .../Contacts/Model/ContactAvatarModel.swift | 2 + .../Fragments/ConversationFragment.swift | 342 ++++++++++-------- .../ViewModel/ConversationViewModel.swift | 11 +- Linphone/Utils/EmojiPickerView.swift | 79 ++++ LinphoneApp.xcodeproj/project.pbxproj | 28 ++ .../xcshareddata/swiftpm/Package.resolved | 11 +- 6 files changed, 316 insertions(+), 157 deletions(-) create mode 100644 Linphone/Utils/EmojiPickerView.swift diff --git a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift index df9e04340..65957a71f 100644 --- a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift +++ b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift @@ -47,6 +47,8 @@ class ContactAvatarModel: ObservableObject, Identifiable { private var friendDelegate: FriendDelegate? init(friend: Friend?, name: String, address: String, withPresence: Bool?) { + self.name = name + self.address = address self.resetContactAvatarModel(friend: friend, name: name, address: address, withPresence: withPresence) } diff --git a/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift b/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift index b6f81ea76..aebaeccb8 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift @@ -19,6 +19,7 @@ import SwiftUI import UniformTypeIdentifiers +import ElegantEmojiPicker // swiftlint:disable line_length // swiftlint:disable type_body_length @@ -81,6 +82,10 @@ struct ConversationFragment: View { @State var messageText: String = "" + @State private var chosen: String? + @State private var showPicker = false + @State private var isSheetVisible = false + var body: some View { NavigationView { GeometryReader { geometry in @@ -141,6 +146,17 @@ struct ConversationFragment: View { }) .edgesIgnoringSafeArea(.all) }) + .sheet(isPresented: $showPicker) { + EmojiPickerView(selected: $chosen, isSheetVisible: $isSheetVisible) + .presentationDetents([.medium]) + .edgesIgnoringSafeArea(.all) + } + .onChange(of: chosen ?? "") { newValue in + if !newValue.isEmpty { + conversationViewModel.sendReaction(emoji: newValue) + chosen = nil + } + } .fullScreenCover(isPresented: $isShowCamera) { ImagePicker(selectedMedia: self.$conversationViewModel.mediasToSend) .environmentObject(conversationViewModel) @@ -185,6 +201,16 @@ struct ConversationFragment: View { } .edgesIgnoringSafeArea(.all) }) + .sheet(isPresented: $showPicker) { + EmojiPickerView(selected: $chosen, isSheetVisible: $isSheetVisible) + .edgesIgnoringSafeArea(.all) + } + .onChange(of: chosen ?? "") { newValue in + if !newValue.isEmpty { + conversationViewModel.sendReaction(emoji: newValue) + chosen = nil + } + } .fullScreenCover(isPresented: $isShowCamera) { ImagePicker(selectedMedia: self.$conversationViewModel.mediasToSend) .environmentObject(conversationViewModel) @@ -892,136 +918,117 @@ struct ConversationFragment: View { Spacer() VStack { - HStack { - if conversationViewModel.selectedMessage!.message.isOutgoing { - Spacer() - } - + if !isSheetVisible { HStack { - Button { - conversationViewModel.sendReaction(emoji: "👍") - } label: { - Text("👍") - .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + if conversationViewModel.selectedMessage!.message.isOutgoing { + Spacer() } - .padding(.horizontal, 8) - .background(conversationViewModel.selectedMessage?.message.ownReaction == "👍" ? Color.gray200 : .white) - .cornerRadius(10) - Button { - conversationViewModel.sendReaction(emoji: "❤️") - } label: { - Text("❤️") - .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + HStack { + Button { + conversationViewModel.sendReaction(emoji: "👍") + } label: { + Text("👍") + .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + } + .padding(.horizontal, 8) + .background(conversationViewModel.selectedMessage?.message.ownReaction == "👍" ? Color.gray200 : .white) + .cornerRadius(10) + + Button { + conversationViewModel.sendReaction(emoji: "❤️") + } label: { + Text("❤️") + .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + } + .padding(.horizontal, 8) + .background(conversationViewModel.selectedMessage?.message.ownReaction == "❤️" ? Color.gray200 : .white) + .cornerRadius(10) + + Button { + conversationViewModel.sendReaction(emoji: "😂") + } label: { + Text("😂") + .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + } + .padding(.horizontal, 8) + .background(conversationViewModel.selectedMessage?.message.ownReaction == "😂" ? Color.gray200 : .white) + .cornerRadius(10) + + Button { + conversationViewModel.sendReaction(emoji: "😮") + } label: { + Text("😮") + .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + } + .padding(.horizontal, 8) + .background(conversationViewModel.selectedMessage?.message.ownReaction == "😮" ? Color.gray200 : .white) + .cornerRadius(10) + + Button { + conversationViewModel.sendReaction(emoji: "😢") + } label: { + Text("😢") + .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + } + .padding(.horizontal, 8) + .background(conversationViewModel.selectedMessage?.message.ownReaction == "😢" ? Color.gray200 : .white) + .cornerRadius(10) + + Button { + showPicker = true + isSheetVisible = true + } label: { + Image("plus-circle") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c500) + .frame(width: iconSize > 50 ? 55 : iconSize + 5, height: iconSize > 50 ? 55 : iconSize + 5, alignment: .leading) + } + .padding(.top, 3) + .padding(.leading, 2) + .padding(.trailing, 6) + .cornerRadius(10) } - .padding(.horizontal, 8) - .background(conversationViewModel.selectedMessage?.message.ownReaction == "❤️" ? Color.gray200 : .white) - .cornerRadius(10) + .padding(.vertical, 5) + .padding(.horizontal, 10) + .background(.white) + .cornerRadius(20) - Button { - conversationViewModel.sendReaction(emoji: "😂") - } label: { - Text("😂") - .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) + if !conversationViewModel.selectedMessage!.message.isOutgoing { + Spacer() } - .padding(.horizontal, 8) - .background(conversationViewModel.selectedMessage?.message.ownReaction == "😂" ? Color.gray200 : .white) - .cornerRadius(10) - - Button { - conversationViewModel.sendReaction(emoji: "😮") - } label: { - Text("😮") - .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) - } - .padding(.horizontal, 8) - .background(conversationViewModel.selectedMessage?.message.ownReaction == "😮" ? Color.gray200 : .white) - .cornerRadius(10) - - Button { - conversationViewModel.sendReaction(emoji: "😢") - } label: { - Text("😢") - .default_text_style(styleSize: iconSize > 50 ? 50 : iconSize) - } - .padding(.horizontal, 8) - .background(conversationViewModel.selectedMessage?.message.ownReaction == "😢" ? Color.gray200 : .white) - .cornerRadius(10) - - /* - Button { - } label: { - Image("plus-circle") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.grayMain2c500) - .frame(width: iconSize > 50 ? 50 : iconSize, height: iconSize > 50 ? 50 : iconSize, alignment: .leading) - } - .padding(.trailing, 5) - */ } - .padding(.vertical, 5) + .frame(maxWidth: .infinity) .padding(.horizontal, 10) - .background(.white) - .cornerRadius(20) - - if !conversationViewModel.selectedMessage!.message.isOutgoing { - Spacer() - } + .padding(.leading, SharedMainViewModel.shared.displayedConversation!.isGroup ? 43 : 0) + .shadow(color: .black.opacity(0.1), radius: 10) } - .frame(maxWidth: .infinity) - .padding(.horizontal, 10) - .padding(.leading, SharedMainViewModel.shared.displayedConversation!.isGroup ? 43 : 0) - .shadow(color: .black.opacity(0.1), radius: 10) ChatBubbleView(eventLogMessage: conversationViewModel.selectedMessage!, geometryProxy: geometry) .environmentObject(conversationViewModel) .padding(.horizontal, 10) .padding(.vertical, 1) .shadow(color: .black.opacity(0.1), radius: 10) + .offset(y: isSheetVisible ? -(UIScreen.main.bounds.height * 0.5) - 10 : 0) - HStack { - if conversationViewModel.selectedMessage!.message.isOutgoing { - Spacer() - } - - VStack { - Button { - let indexMessage = conversationViewModel.conversationMessagesSection[0].rows.firstIndex(where: {$0.message.id == conversationViewModel.selectedMessage!.message.id}) - conversationViewModel.selectedMessage = nil - conversationViewModel.replyToMessage(index: indexMessage ?? 0) - } label: { - HStack { - Text("menu_reply_to_chat_message") - .default_text_style(styleSize: 15) - Spacer() - Image("reply") - .resizable() - .frame(width: 20, height: 20, alignment: .leading) - } - .padding(.vertical, 5) - .padding(.horizontal, 20) + if !isSheetVisible { + HStack { + if conversationViewModel.selectedMessage!.message.isOutgoing { + Spacer() } - Divider() - - if !conversationViewModel.selectedMessage!.message.text.isEmpty { + VStack { Button { - UIPasteboard.general.setValue( - conversationViewModel.selectedMessage?.message.text ?? "Error_message_not_available", - forPasteboardType: UTType.plainText.identifier - ) - - ToastViewModel.shared.toastMessage = "Success_message_copied_into_clipboard" - ToastViewModel.shared.displayToast = true - + let indexMessage = conversationViewModel.conversationMessagesSection[0].rows.firstIndex(where: {$0.message.id == conversationViewModel.selectedMessage!.message.id}) conversationViewModel.selectedMessage = nil + conversationViewModel.replyToMessage(index: indexMessage ?? 0) } label: { HStack { - Text("menu_copy_chat_message") + Text("menu_reply_to_chat_message") .default_text_style(styleSize: 15) Spacer() - Image("copy") + Image("reply") .resizable() .frame(width: 20, height: 20, alignment: .leading) } @@ -1030,59 +1037,86 @@ struct ConversationFragment: View { } Divider() + + if !conversationViewModel.selectedMessage!.message.text.isEmpty { + Button { + UIPasteboard.general.setValue( + conversationViewModel.selectedMessage?.message.text ?? "Error_message_not_available", + forPasteboardType: UTType.plainText.identifier + ) + + ToastViewModel.shared.toastMessage = "Success_message_copied_into_clipboard" + ToastViewModel.shared.displayToast = true + + conversationViewModel.selectedMessage = nil + } label: { + HStack { + Text("menu_copy_chat_message") + .default_text_style(styleSize: 15) + Spacer() + Image("copy") + .resizable() + .frame(width: 20, height: 20, alignment: .leading) + } + .padding(.vertical, 5) + .padding(.horizontal, 20) + } + + Divider() + } + + Button { + withAnimation { + isShowConversationForwardMessageFragment = true + } + } label: { + HStack { + Text("menu_forward_chat_message") + .default_text_style(styleSize: 15) + Spacer() + Image("forward") + .resizable() + .frame(width: 20, height: 20, alignment: .leading) + } + .padding(.vertical, 5) + .padding(.horizontal, 20) + } + + Divider() + + Button { + conversationViewModel.deleteMessage() + } label: { + HStack { + Text("menu_delete_selected_item") + .foregroundStyle(.red) + .default_text_style(styleSize: 15) + Spacer() + Image("trash-simple-red") + .renderingMode(.template) + .resizable() + .foregroundStyle(.red) + .frame(width: 20, height: 20, alignment: .leading) + } + .padding(.vertical, 5) + .padding(.horizontal, 20) + } } + .frame(maxWidth: geometry.size.width / 1.5) + .padding(.vertical, 8) + .background(.white) + .cornerRadius(20) - Button { - withAnimation { - isShowConversationForwardMessageFragment = true - } - } label: { - HStack { - Text("menu_forward_chat_message") - .default_text_style(styleSize: 15) - Spacer() - Image("forward") - .resizable() - .frame(width: 20, height: 20, alignment: .leading) - } - .padding(.vertical, 5) - .padding(.horizontal, 20) - } - - Divider() - - Button { - conversationViewModel.deleteMessage() - } label: { - HStack { - Text("menu_delete_selected_item") - .foregroundStyle(.red) - .default_text_style(styleSize: 15) - Spacer() - Image("trash-simple-red") - .renderingMode(.template) - .resizable() - .foregroundStyle(.red) - .frame(width: 20, height: 20, alignment: .leading) - } - .padding(.vertical, 5) - .padding(.horizontal, 20) + if !conversationViewModel.selectedMessage!.message.isOutgoing { + Spacer() } } - .frame(maxWidth: geometry.size.width / 1.5) - .padding(.vertical, 8) - .background(.white) - .cornerRadius(20) - - if !conversationViewModel.selectedMessage!.message.isOutgoing { - Spacer() - } + .frame(maxWidth: .infinity) + .padding(.horizontal, 10) + .padding(.bottom, 20) + .padding(.leading, SharedMainViewModel.shared.displayedConversation!.isGroup ? 43 : 0) + .shadow(color: .black.opacity(0.1), radius: 10) } - .frame(maxWidth: .infinity) - .padding(.horizontal, 10) - .padding(.bottom, 20) - .padding(.leading, SharedMainViewModel.shared.displayedConversation!.isGroup ? 43 : 0) - .shadow(color: .black.opacity(0.1), radius: 10) } } .frame(maxWidth: .infinity) diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift index a5963308d..2571d7827 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift @@ -2261,8 +2261,15 @@ class ConversationViewModel: ObservableObject { if chatMessageReaction.fromAddress != nil { dispatchGroup.enter() ContactAvatarModel.getAvatarModelFromAddress(address: chatMessageReaction.fromAddress!) { avatarResult in - if core.defaultAccount != nil && core.defaultAccount!.contactAddress != nil && core.defaultAccount!.contactAddress!.asStringUriOnly().contains(avatarResult.address) { - let innerSheetCat = InnerSheetCategory(contact: avatarResult, detail: chatMessageReaction.body, isMe: true) + if let account = core.defaultAccount, + let contactAddress = account.contactAddress, + contactAddress.asStringUriOnly().contains(avatarResult.address) { + + let innerSheetCat = InnerSheetCategory( + contact: avatarResult, + detail: chatMessageReaction.body, + isMe: true + ) participantList[0].append(innerSheetCat) } else { let innerSheetCat = InnerSheetCategory(contact: avatarResult, detail: chatMessageReaction.body) diff --git a/Linphone/Utils/EmojiPickerView.swift b/Linphone/Utils/EmojiPickerView.swift new file mode 100644 index 000000000..38012b61b --- /dev/null +++ b/Linphone/Utils/EmojiPickerView.swift @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import SwiftUI +import ElegantEmojiPicker + +struct EmojiPickerView: UIViewControllerRepresentable { + @Binding var selected: String? + @Binding var isSheetVisible: Bool + + var configuration = ElegantConfiguration(showRandom: false, showReset: false) + + func makeUIViewController(context: Context) -> UIViewController { + let picker = ElegantEmojiPicker(delegate: context.coordinator, + configuration: configuration, + localization: .init()) + + let container = NotifyingViewController() + container.onWillDisappear = { + isSheetVisible = false + } + + container.addChild(picker) + container.view.addSubview(picker.view) + picker.view.frame = container.view.bounds + picker.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] + picker.didMove(toParent: container) + + return container + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + class NotifyingViewController: UIViewController { + var onWillDisappear: (() -> Void)? + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + onWillDisappear?() + } + } + + final class Coordinator: NSObject, ElegantEmojiPickerDelegate { + let parent: EmojiPickerView + init(_ parent: EmojiPickerView) { self.parent = parent } + + func emojiPicker(_ picker: ElegantEmojiPicker, didSelectEmoji emoji: Emoji?) { + parent.selected = emoji?.emoji + picker.dismiss(animated: true) + } + + func emojiPicker(_ picker: ElegantEmojiPicker, + loadEmojiSections withConfiguration: ElegantConfiguration, + _ withLocalization: ElegantLocalization) -> [EmojiSection] { + return ElegantEmojiPicker.getDefaultEmojiSections() + } + } +} diff --git a/LinphoneApp.xcodeproj/project.pbxproj b/LinphoneApp.xcodeproj/project.pbxproj index 09c58d249..91997b2d9 100644 --- a/LinphoneApp.xcodeproj/project.pbxproj +++ b/LinphoneApp.xcodeproj/project.pbxproj @@ -182,6 +182,8 @@ D7DA67642ACCB31700E95002 /* ProfileModeFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA67632ACCB31700E95002 /* ProfileModeFragment.swift */; }; D7DC096F2CFA1D7600A6D47C /* AccountProfileFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */; }; D7DC09712CFDBF9A00A6D47C /* AccountProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DC09702CFDBF8300A6D47C /* AccountProfileViewModel.swift */; }; + D7DF8BE72E2104DC003A3BC7 /* ElegantEmojiPicker in Frameworks */ = {isa = PBXBuildFile; productRef = D7DF8BE62E2104DC003A3BC7 /* ElegantEmojiPicker */; }; + D7DF8BE92E2104EC003A3BC7 /* EmojiPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DF8BE82E2104E5003A3BC7 /* EmojiPickerView.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 */; }; @@ -400,6 +402,7 @@ D7DA67632ACCB31700E95002 /* ProfileModeFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileModeFragment.swift; sourceTree = ""; }; D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountProfileFragment.swift; sourceTree = ""; }; D7DC09702CFDBF8300A6D47C /* AccountProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountProfileViewModel.swift; sourceTree = ""; }; + D7DF8BE82E2104E5003A3BC7 /* EmojiPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerView.swift; sourceTree = ""; }; D7E2E69E2CE356C90080DA0D /* PopupViewWithTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupViewWithTextField.swift; sourceTree = ""; }; D7E6ADF22B9875C20009A2BC /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; }; D7E6ADF42B9876ED0009A2BC /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = ""; }; @@ -445,6 +448,7 @@ buildActionMask = 2147483647; files = ( D7D5AD7F2DD34F0E00016721 /* AppAuth in Frameworks */, + D7DF8BE72E2104DC003A3BC7 /* ElegantEmojiPicker in Frameworks */, C618BF562D75CA03005A00E0 /* linphonesw in Frameworks */, D7D5AD832DD34F2300016721 /* FirebaseCrashlytics in Frameworks */, D7D5AD812DD34F1A00016721 /* FirebaseAnalytics in Frameworks */, @@ -575,6 +579,7 @@ D717071C2AC591EF0037746F /* Utils */ = { isa = PBXGroup; children = ( + D7DF8BE82E2104E5003A3BC7 /* EmojiPickerView.swift */, D703F7072DC8C5FF005B8F75 /* FilePicker.swift */, D717A10D2CEB770D00849D92 /* ShareSheetController.swift */, 66C491F72B24D25A00CEA16D /* Extensions */, @@ -602,6 +607,7 @@ D719ABB52ABC67BF00B41C10 /* Linphone */, 660AAF7C2B839272004C0FA6 /* msgNotificationService */, D7458F302E0BDCF4000C957A /* linphoneExtension */, + D7DF8BE52E2104DC003A3BC7 /* Frameworks */, D719ABB42ABC67BF00B41C10 /* Products */, ); sourceTree = ""; @@ -1039,6 +1045,13 @@ path = ViewModel; sourceTree = ""; }; + D7DF8BE52E2104DC003A3BC7 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1140,6 +1153,7 @@ D7D5AD7B2DD34E4D00016721 /* XCRemoteSwiftPackageReference "AppAuth-iOS" */, D7D5AD7C2DD34E7C00016721 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, D7BEB1152E1FF670004B25A3 /* XCRemoteSwiftPackageReference "linphone-sdk-swift-ios" */, + D7DF8BE42E2104D0003A3BC7 /* XCRemoteSwiftPackageReference "Elegant-Emoji-Picker" */, ); productRefGroup = D719ABB42ABC67BF00B41C10 /* Products */; projectDirPath = ""; @@ -1244,6 +1258,7 @@ D7B5678E2B28888F00DE63EB /* CallView.swift in Sources */, D71A0E192B485ADF0002C6CD /* ViewExtension.swift in Sources */, D759CB642C3FBD4200AC35E8 /* StartConversationFragment.swift in Sources */, + D7DF8BE92E2104EC003A3BC7 /* EmojiPickerView.swift in Sources */, 66FDB7812C7C689A00561566 /* EventEditViewController.swift in Sources */, D750D3392AD3E6EE00EC99C5 /* PopupLoadingView.swift in Sources */, D7E6D0492AE933AD00A57AAF /* FavoriteContactsListFragment.swift in Sources */, @@ -1889,6 +1904,14 @@ minimumVersion = 11.12.0; }; }; + D7DF8BE42E2104D0003A3BC7 /* XCRemoteSwiftPackageReference "Elegant-Emoji-Picker" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Finalet/Elegant-Emoji-Picker"; + requirement = { + branch = main; + kind = branch; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -1927,6 +1950,11 @@ package = D7D5AD7C2DD34E7C00016721 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseCrashlytics; }; + D7DF8BE62E2104DC003A3BC7 /* ElegantEmojiPicker */ = { + isa = XCSwiftPackageProductDependency; + package = D7DF8BE42E2104D0003A3BC7 /* XCRemoteSwiftPackageReference "Elegant-Emoji-Picker" */; + productName = ElegantEmojiPicker; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = D719ABAB2ABC67BF00B41C10 /* Project object */; diff --git a/LinphoneApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LinphoneApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 7d8de5c2e..84c5f0c30 100644 --- a/LinphoneApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LinphoneApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "5293adb495d47691babe33d739eb8e74cee00c05a442b57ef6079701fee324f1", + "originHash" : "7ed0929d53447e6dba6aae5d5c6617250fb4460459e56cf06feaf0f1397ae64e", "pins" : [ { "identity" : "abseil-cpp-binary", @@ -28,6 +28,15 @@ "version" : "2.0.0" } }, + { + "identity" : "elegant-emoji-picker", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Finalet/Elegant-Emoji-Picker", + "state" : { + "branch" : "main", + "revision" : "12c1a2be1adbe7a774ebdd2c48f02d95b8884df6" + } + }, { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl",