mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 02:58:07 +00:00
Add emoji picker
This commit is contained in:
parent
cfcd55a622
commit
c6179c973c
6 changed files with 316 additions and 157 deletions
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,6 +918,7 @@ struct ConversationFragment: View {
|
|||
Spacer()
|
||||
|
||||
VStack {
|
||||
if !isSheetVisible {
|
||||
HStack {
|
||||
if conversationViewModel.selectedMessage!.message.isOutgoing {
|
||||
Spacer()
|
||||
|
|
@ -948,17 +975,20 @@ struct ConversationFragment: View {
|
|||
.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 ? 50 : iconSize, height: iconSize > 50 ? 50 : iconSize, alignment: .leading)
|
||||
.frame(width: iconSize > 50 ? 55 : iconSize + 5, height: iconSize > 50 ? 55 : iconSize + 5, alignment: .leading)
|
||||
}
|
||||
.padding(.trailing, 5)
|
||||
*/
|
||||
.padding(.top, 3)
|
||||
.padding(.leading, 2)
|
||||
.padding(.trailing, 6)
|
||||
.cornerRadius(10)
|
||||
}
|
||||
.padding(.vertical, 5)
|
||||
.padding(.horizontal, 10)
|
||||
|
|
@ -973,13 +1003,16 @@ struct ConversationFragment: View {
|
|||
.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)
|
||||
|
||||
if !isSheetVisible {
|
||||
HStack {
|
||||
if conversationViewModel.selectedMessage!.message.isOutgoing {
|
||||
Spacer()
|
||||
|
|
@ -1085,6 +1118,7 @@ struct ConversationFragment: View {
|
|||
.shadow(color: .black.opacity(0.1), radius: 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(minHeight: geometry.size.height)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
79
Linphone/Utils/EmojiPickerView.swift
Normal file
79
Linphone/Utils/EmojiPickerView.swift
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = "<group>"; };
|
||||
D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountProfileFragment.swift; sourceTree = "<group>"; };
|
||||
D7DC09702CFDBF8300A6D47C /* AccountProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountProfileViewModel.swift; sourceTree = "<group>"; };
|
||||
D7DF8BE82E2104E5003A3BC7 /* EmojiPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerView.swift; sourceTree = "<group>"; };
|
||||
D7E2E69E2CE356C90080DA0D /* PopupViewWithTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupViewWithTextField.swift; sourceTree = "<group>"; };
|
||||
D7E6ADF22B9875C20009A2BC /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
|
||||
D7E6ADF42B9876ED0009A2BC /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -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 = "<group>";
|
||||
|
|
@ -1039,6 +1045,13 @@
|
|||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D7DF8BE52E2104DC003A3BC7 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* 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 */;
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue