Fix avatar and displayname in ConversationInfoFragment

This commit is contained in:
Benoit Martins 2024-12-20 16:59:39 +01:00
parent fdd0925184
commit b7446f6d26
7 changed files with 177 additions and 126 deletions

View file

@ -79,10 +79,13 @@ struct ContentView: View {
@State private var isShowLoginFragment: Bool = false
private let avatarSize = 45.0
@State private var imagePath: URL?
var body: some View {
let pub = NotificationCenter.default
.publisher(for: NSNotification.Name("ContactLoaded"))
let imageChanged = NotificationCenter.default
.publisher(for: NSNotification.Name("ImageChanged"))
GeometryReader { geometry in
VStack(spacing: 0) {
if (telecomManager.callInProgress && !fullscreenVideo && ((!telecomManager.callDisplayed && callViewModel.callsCounter == 1) || callViewModel.callsCounter > 1)) || isShowConversationFragment {
@ -308,30 +311,41 @@ struct ContentView: View {
VStack(spacing: 0) {
if searchIsActive == false {
HStack {
AsyncImage(url: accountProfileViewModel.getImagePath()) { image in
switch image {
case .empty:
ProgressView()
.frame(width: avatarSize, height: avatarSize)
case .success(let image):
image
if (accountProfileViewModel.accountModelIndex ?? 0) < CoreContext.shared.accounts.count {
AsyncImage(url: imagePath) { image in
switch image {
case .empty:
ProgressView()
.frame(width: avatarSize, height: avatarSize)
case .success(let image):
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
case .failure:
Image(uiImage: contactsManager.textToImage(
firstName: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex ?? 0].avatarModel?.name ?? "",
lastName: ""))
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
case .failure:
Image(uiImage: contactsManager.textToImage(
firstName: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex ?? 0].avatarModel?.name ?? "",
lastName: ""))
.resizable()
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
@unknown default:
EmptyView()
@unknown default:
EmptyView()
}
}
.onTapGesture {
openMenu()
}
.onAppear {
imagePath = CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].getImagePath()
}
.onChange(of: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].usernaneAvatar) { _ in
imagePath = CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].getImagePath()
}
.onReceive(imageChanged) { _ in
imagePath = CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].getImagePath()
}
}
.onTapGesture {
openMenu()
}
Text(String(localized: index == 0 ? "bottom_navigation_contacts_label" : (index == 1 ? "bottom_navigation_calls_label" : (index == 2 ? "bottom_navigation_conversations_label" : "bottom_navigation_meetings_label"))))
@ -1338,6 +1352,9 @@ struct ContentView: View {
.onChange(of: scenePhase) { newPhase in
CoreContext.shared.enteredForeground = newPhase == .active
orientation = UIDevice.current.orientation
if newPhase == .active {
accountProfileViewModel.setAvatarModel()
}
}
}

View file

@ -293,7 +293,7 @@ struct ConversationInfoFragment: View {
Avatar(contactAvatarModel: participantConversationModel, avatarSize: 50)
} else {
let avatarSize = 50.0
AsyncImage(url: accountProfileViewModel.getImagePath()) { image in
AsyncImage(url: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].imagePathAvatar) { image in
switch image {
case .empty:
ProgressView()

View file

@ -265,7 +265,7 @@ class ConversationModel: ObservableObject, Identifiable {
subjectTmp = self.chatRoom.participants.first!.address!.displayName != nil
? self.chatRoom.participants.first!.address!.displayName!
: (self.chatRoom.participants.first!.address!.username ?? self.chatRoom.participants.first!.address!.asStringUriOnly())
: (self.chatRoom.participants.first!.address!.username ?? String(self.chatRoom.participants.first!.address!.asStringUriOnly().dropFirst(4)))
}
}

View file

@ -35,7 +35,7 @@ struct SideMenuAccountRow: View {
var body: some View {
HStack {
AsyncImage(url: accountProfileViewModel.getImagePath()) { image in
AsyncImage(url: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].imagePathAvatar) { image in
switch image {
case .empty:
ProgressView()

View file

@ -99,7 +99,7 @@ struct AccountProfileFragment: View {
&& !accountModel.photoAvatarModel!.isEmpty
&& selectedImage == nil && !removedImage {
AsyncImage(url: accountProfileViewModel.getImagePath()) { image in
AsyncImage(url: CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex!].imagePathAvatar) { image in
switch image {
case .empty:
ProgressView()
@ -265,39 +265,40 @@ struct AccountProfileFragment: View {
}
if detailIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
HStack {
Text(String(localized: "sip_address") + ":")
.default_text_style_700(styleSize: 15)
Text(accountModel.avatarModel!.address)
.foregroundStyle(Color.grayMain2c700)
.default_text_style(styleSize: 15)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(1)
Button(action: {
UIPasteboard.general.setValue(
accountModel.avatarModel!.address,
forPasteboardType: UTType.plainText.identifier
)
if accountModel.avatarModel != nil {
VStack(spacing: 0) {
VStack(spacing: 30) {
HStack {
Text(String(localized: "sip_address") + ":")
.default_text_style_700(styleSize: 15)
ToastViewModel.shared.toastMessage = "Success_address_copied_into_clipboard"
ToastViewModel.shared.displayToast.toggle()
}, label: {
Image("copy")
.resizable()
.frame(width: 20, height: 20)
})
}
VStack(alignment: .leading) {
Text("sip_address_display_name")
.default_text_style_700(styleSize: 15)
.padding(.bottom, -5)
Text(accountModel.avatarModel!.address)
.foregroundStyle(Color.grayMain2c700)
.default_text_style(styleSize: 15)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(1)
Button(action: {
UIPasteboard.general.setValue(
accountModel.avatarModel!.address,
forPasteboardType: UTType.plainText.identifier
)
ToastViewModel.shared.toastMessage = "Success_address_copied_into_clipboard"
ToastViewModel.shared.displayToast.toggle()
}, label: {
Image("copy")
.resizable()
.frame(width: 20, height: 20)
})
}
TextField(accountModel.displayNameAvatar, text: Binding(
VStack(alignment: .leading) {
Text("sip_address_display_name")
.default_text_style_700(styleSize: 15)
.padding(.bottom, -5)
TextField(accountModel.displayNameAvatar, text: Binding(
get: { accountModel.displayNameAvatar },
set: { newValue in
accountModel.displayNameAvatar = newValue
@ -315,66 +316,67 @@ struct AccountProfileFragment: View {
.stroke(isDisplayNameFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
)
.focused($isDisplayNameFocused)
}
VStack(alignment: .leading) {
HStack {
Text("manage_account_international_prefix")
.default_text_style_700(styleSize: 15)
.padding(.bottom, -5)
.lineLimit(1)
Button(action: {
isShowPopup = true
}, label: {
Image("question")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c600)
.frame(width: 20, height: 20)
})
.padding(.bottom, -5)
}
Menu {
Picker("", selection: $accountProfileViewModel.dialPlanValueSelected) {
ForEach(registerViewModel.dialPlansLabelList, id: \.self) { dialPlan in
Text(dialPlan).tag(dialPlan)
}
}
.onChange(of: accountProfileViewModel.dialPlanValueSelected) { newValue in
accountProfileViewModel.updateDialPlan(newDialPlan: newValue)
}
} label: {
VStack(alignment: .leading) {
HStack {
Text(accountProfileViewModel.dialPlanValueSelected)
.default_text_style(styleSize: 15)
.frame(maxWidth: .infinity, alignment: .leading)
Text("manage_account_international_prefix")
.default_text_style_700(styleSize: 15)
.padding(.bottom, -5)
.lineLimit(1)
Image("caret-down")
.resizable()
.frame(width: 20, height: 20)
Button(action: {
isShowPopup = true
}, label: {
Image("question")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c600)
.frame(width: 20, height: 20)
})
.padding(.bottom, -5)
}
Menu {
Picker("", selection: $accountProfileViewModel.dialPlanValueSelected) {
ForEach(registerViewModel.dialPlansLabelList, id: \.self) { dialPlan in
Text(dialPlan).tag(dialPlan)
}
}
.onChange(of: accountProfileViewModel.dialPlanValueSelected) { newValue in
accountProfileViewModel.updateDialPlan(newDialPlan: newValue)
}
} label: {
HStack {
Text(accountProfileViewModel.dialPlanValueSelected)
.default_text_style(styleSize: 15)
.frame(maxWidth: .infinity, alignment: .leading)
Image("caret-down")
.resizable()
.frame(width: 20, height: 20)
}
.frame(height: 25)
.padding(.horizontal, 20)
.padding(.vertical, 15)
.background(.white)
.cornerRadius(60)
.overlay(
RoundedRectangle(cornerRadius: 60)
.inset(by: 0.5)
.stroke(Color.gray200, lineWidth: 1)
)
}
.frame(height: 25)
.padding(.horizontal, 20)
.padding(.vertical, 15)
.background(.white)
.cornerRadius(60)
.overlay(
RoundedRectangle(cornerRadius: 60)
.inset(by: 0.5)
.stroke(Color.gray200, lineWidth: 1)
)
}
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-1)
.transition(.move(edge: .top))
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-1)
.transition(.move(edge: .top))
}
VStack(spacing: 0) {
@ -383,7 +385,7 @@ struct AccountProfileFragment: View {
Toggle("", isOn: $flag)
.labelsHidden()
Text("drawer_menu_account_connection_status_connected")
Text(accountModel.humanReadableRegistrationState)
.default_text_style_700(styleSize: 15)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.bottom, -5)
@ -403,6 +405,7 @@ struct AccountProfileFragment: View {
.cornerRadius(15)
.padding(.all)
/*
HStack(alignment: .center) {
Text("manage_account_details_title")
.default_text_style_800(styleSize: 18)
@ -456,6 +459,7 @@ struct AccountProfileFragment: View {
.background(.white)
.cornerRadius(15)
.padding(.all)
*/
}
.frame(maxWidth: sharedMainViewModel.maxWidth)
}
@ -487,11 +491,13 @@ struct AccountProfileFragment: View {
func saveImage() {
let accountModel = CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex ?? 0]
let usernameTmp = CoreContext.shared.accounts[accountProfileViewModel.accountModelIndex ?? 0].usernaneAvatar
accountProfileViewModel.saveImage(
image: selectedImage
?? ContactsManager.shared.textToImage(
firstName: accountModel.avatarModel!.name, lastName: ""),
name: accountModel.avatarModel!.name,
name: usernameTmp,
prefix: ((selectedImage == nil) ? "-default" : ""))
}
}

View file

@ -42,11 +42,13 @@ class AccountProfileViewModel: ObservableObject {
}
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 ? CoreContext.shared.accounts[self.accountModelIndex!].account.displayName() : displayNameAccountModel, lastName: ""),
name: displayNameAccountModel.isEmpty ? CoreContext.shared.accounts[self.accountModelIndex!].account.displayName() : displayNameAccountModel,
firstName: displayNameAccountModel.isEmpty ? usernameTmp : displayNameAccountModel, lastName: ""),
name: usernameTmp,
prefix: "-default")
}
}
@ -67,10 +69,8 @@ class AccountProfileViewModel: ObservableObject {
func setAvatarModel() {
if accountModelIndex != nil {
CoreContext.shared.doOnCoreQueue { _ in
let photoAvatarAccountModel = CoreContext.shared.accounts[self.accountModelIndex!].photoAvatarModel
let displayNameTmp = CoreContext.shared.accounts[self.accountModelIndex!].account.params?.identityAddress?.displayName ?? ""
let contactAddressTmp = CoreContext.shared.accounts[self.accountModelIndex!].account.params?.identityAddress?.asStringUriOnly() ?? ""
var photoAvatarModelTmp = ""
let prefix = CoreContext.shared.accounts[self.accountModelIndex!].account.params?.internationalPrefix ?? ""
let isoCountryCode = CoreContext.shared.accounts[self.accountModelIndex!].account.params?.internationalPrefixIsoCountryCode ?? ""
@ -88,17 +88,8 @@ class AccountProfileViewModel: ObservableObject {
}
}
let preferences = UserDefaults.standard
let accountDisplayName = CoreContext.shared.accounts[self.accountModelIndex!].account.displayName()
let photoAvatarModelKey = "photo_avatar_model" + CoreContext.shared.accounts[self.accountModelIndex!].address
if preferences.object(forKey: photoAvatarModelKey) == nil {
preferences.set(photoAvatarAccountModel ?? "", forKey: photoAvatarModelKey)
} else {
photoAvatarModelTmp = preferences.string(forKey: photoAvatarModelKey)!
}
DispatchQueue.main.async {
CoreContext.shared.accounts[self.accountModelIndex!].avatarModel = ContactAvatarModel(
friend: nil,
@ -107,8 +98,6 @@ class AccountProfileViewModel: ObservableObject {
withPresence: false
)
CoreContext.shared.accounts[self.accountModelIndex!].photoAvatarModel = photoAvatarModelTmp
CoreContext.shared.accounts[self.accountModelIndex!].displayNameAvatar = displayNameTmp
self.dialPlanValueSelected = dialPlanValueSelectedTmp
}
}
@ -127,11 +116,20 @@ class AccountProfileViewModel: ObservableObject {
return
}
let photoAvatarModelKey = "photo_avatar_model" + CoreContext.shared.accounts[self.accountModelIndex ?? 0].address
let photoAvatarModelKey = "photo_avatar_model" + CoreContext.shared.accounts[self.accountModelIndex!].usernaneAvatar
ContactsManager.shared.awaitDataWrite(data: data, name: name, prefix: prefix) { _, result in
UserDefaults.standard.set(result, forKey: photoAvatarModelKey)
CoreContext.shared.accounts[self.accountModelIndex ?? 0].photoAvatarModel = result
CoreContext.shared.accounts[self.accountModelIndex ?? 0].photoAvatarModel = ""
CoreContext.shared.accounts[self.accountModelIndex ?? 0].imagePathAvatar = nil
NotificationCenter.default.post(name: NSNotification.Name("ImageChanged"), object: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
CoreContext.shared.accounts[self.accountModelIndex ?? 0].photoAvatarModel = result
CoreContext.shared.accounts[self.accountModelIndex ?? 0].imagePathAvatar = CoreContext.shared.accounts[self.accountModelIndex ?? 0].getImagePath()
NotificationCenter.default.post(name: NSNotification.Name("ImageChanged"), object: nil)
}
}
}

View file

@ -33,6 +33,8 @@ class AccountModel: ObservableObject {
@Published var avatarModel: ContactAvatarModel?
@Published var photoAvatarModel: String?
@Published var displayNameAvatar: String = ""
@Published var usernaneAvatar: String = ""
@Published var imagePathAvatar: URL?
private var accountDelegate: AccountDelegate?
private var coreDelegate: CoreDelegate?
@ -78,6 +80,21 @@ class AccountModel: ObservableObject {
}
let displayName = account.displayName()
let address = account.params?.identityAddress?.asString()
let displayNameTmp = account.params?.identityAddress?.displayName ?? ""
let usernaneAvatarTmp = account.contactAddress?.username ?? ""
var photoAvatarModelTmp = ""
let preferences = UserDefaults.standard
let photoAvatarModelKey = "photo_avatar_model" + 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:
@ -99,6 +116,11 @@ class AccountModel: ObservableObject {
isDefaultAccount = isDefault
self.displayName = displayName
address.map {self.address = $0}
photoAvatarModel = photoAvatarModelTmp
displayNameAvatar = displayNameTmp
usernaneAvatar = usernaneAvatarTmp
imagePathAvatar = getImagePath()
}
}
@ -114,4 +136,12 @@ class AccountModel: ObservableObject {
self.account.refreshRegister()
}
}
func getImagePath() -> URL {
let imagePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(
photoAvatarModel ?? "Error"
)
return imagePath
}
}