Compare commits
No commits in common. "fa10e389cd70c005140a9fcd83498b6736ed5fd9" and "048b9eaf1c924a6f15833f313c6ab4188fde0b03" have entirely different histories.
fa10e389cd
...
048b9eaf1c
@ -3,22 +3,4 @@
|
|||||||
uuid = "AEE1609A-17B4-4FCC-80A6-0D556940F4D7"
|
uuid = "AEE1609A-17B4-4FCC-80A6-0D556940F4D7"
|
||||||
type = "1"
|
type = "1"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<Breakpoints>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "09699199-8124-4F89-892D-6880A0EB7C04"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "yobble/Views/Contacts/ContactEditView.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "74"
|
|
||||||
endingLineNumber = "74"
|
|
||||||
landmarkName = "ContactEditView"
|
|
||||||
landmarkType = "14">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
</Breakpoints>
|
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
|||||||
@ -97,8 +97,8 @@ struct ContactAddView: View {
|
|||||||
|
|
||||||
private var avatarInitial: String {
|
private var avatarInitial: String {
|
||||||
let trimmedName = displayName.trimmedNonEmpty ?? contact.preferredName
|
let trimmedName = displayName.trimmedNonEmpty ?? contact.preferredName
|
||||||
if let initials = initials(from: trimmedName) {
|
if let first = trimmedName.trimmingCharacters(in: .whitespacesAndNewlines).first {
|
||||||
return initials
|
return String(first).uppercased()
|
||||||
}
|
}
|
||||||
if let login = contact.login?.trimmingCharacters(in: .whitespacesAndNewlines), !login.isEmpty {
|
if let login = contact.login?.trimmingCharacters(in: .whitespacesAndNewlines), !login.isEmpty {
|
||||||
return String(login.prefix(1)).uppercased()
|
return String(login.prefix(1)).uppercased()
|
||||||
@ -185,12 +185,3 @@ private extension String {
|
|||||||
return value.isEmpty ? nil : value
|
return value.isEmpty ? nil : value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func initials(from text: String) -> String? {
|
|
||||||
let components = text
|
|
||||||
.split { $0.isWhitespace }
|
|
||||||
.filter { !$0.isEmpty }
|
|
||||||
let letters = components.prefix(2).compactMap { $0.first }
|
|
||||||
guard !letters.isEmpty else { return nil }
|
|
||||||
return letters.map { String($0).uppercased() }.joined()
|
|
||||||
}
|
|
||||||
|
|||||||
@ -203,8 +203,8 @@ struct ContactEditView: View {
|
|||||||
|
|
||||||
private var avatarInitial: String {
|
private var avatarInitial: String {
|
||||||
let trimmedName = displayName.trimmedNonEmpty ?? contact.preferredName
|
let trimmedName = displayName.trimmedNonEmpty ?? contact.preferredName
|
||||||
if let initials = initials(from: trimmedName) {
|
if let first = trimmedName.trimmingCharacters(in: .whitespacesAndNewlines).first {
|
||||||
return initials
|
return String(first).uppercased()
|
||||||
}
|
}
|
||||||
if let login = contact.login?.trimmingCharacters(in: .whitespacesAndNewlines), !login.isEmpty {
|
if let login = contact.login?.trimmingCharacters(in: .whitespacesAndNewlines), !login.isEmpty {
|
||||||
return String(login.prefix(1)).uppercased()
|
return String(login.prefix(1)).uppercased()
|
||||||
@ -336,12 +336,3 @@ private extension String {
|
|||||||
return value.isEmpty ? nil : value
|
return value.isEmpty ? nil : value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func initials(from text: String) -> String? {
|
|
||||||
let components = text
|
|
||||||
.split { $0.isWhitespace }
|
|
||||||
.filter { !$0.isEmpty }
|
|
||||||
let letters = components.prefix(2).compactMap { $0.first }
|
|
||||||
guard !letters.isEmpty else { return nil }
|
|
||||||
return letters.map { String($0).uppercased() }.joined()
|
|
||||||
}
|
|
||||||
|
|||||||
@ -22,10 +22,9 @@ struct EditProfileView: View {
|
|||||||
@State private var avatarViewerState: AvatarViewerState?
|
@State private var avatarViewerState: AvatarViewerState?
|
||||||
@State private var shareItems: [Any] = []
|
@State private var shareItems: [Any] = []
|
||||||
@State private var showShareSheet = false
|
@State private var showShareSheet = false
|
||||||
|
|
||||||
private let profileService = ProfileService()
|
private let profileService = ProfileService()
|
||||||
private let descriptionLimit = 1024
|
private let descriptionLimit = 1024
|
||||||
private let nameLimit = 32
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
@ -76,18 +75,13 @@ struct EditProfileView: View {
|
|||||||
|
|
||||||
Section(header: Text("Публичная информация")) {
|
Section(header: Text("Публичная информация")) {
|
||||||
TextField("Отображаемое имя", text: $displayName)
|
TextField("Отображаемое имя", text: $displayName)
|
||||||
.onChange(of: displayName) { newValue in
|
|
||||||
if newValue.count > nameLimit {
|
|
||||||
displayName = String(newValue.prefix(nameLimit))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 5) {
|
VStack(alignment: .leading, spacing: 5) {
|
||||||
Text("Описание")
|
Text("Описание")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
TextEditor(text: $description)
|
TextEditor(text: $description)
|
||||||
.frame(height: 150)
|
.frame(height: 150)
|
||||||
.onChange(of: description) { newValue in
|
.onChange(of: description) { newValue in
|
||||||
if newValue.count > descriptionLimit {
|
if newValue.count > descriptionLimit {
|
||||||
description = String(newValue.prefix(descriptionLimit))
|
description = String(newValue.prefix(descriptionLimit))
|
||||||
@ -160,27 +154,11 @@ struct EditProfileView: View {
|
|||||||
.fill(Color.secondary.opacity(0.2))
|
.fill(Color.secondary.opacity(0.2))
|
||||||
.frame(width: 120, height: 120)
|
.frame(width: 120, height: 120)
|
||||||
.overlay(
|
.overlay(
|
||||||
Text(profileInitials)
|
Image(systemName: "person.fill")
|
||||||
.font(.system(size: 48, weight: .semibold))
|
.font(.system(size: 60))
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var profileInitials: String {
|
|
||||||
if let initials = initials(from: displayName) {
|
|
||||||
return initials
|
|
||||||
}
|
|
||||||
if let profile = profile,
|
|
||||||
let name = profile.fullName?.trimmingCharacters(in: .whitespacesAndNewlines),
|
|
||||||
!name.isEmpty,
|
|
||||||
let initials = initials(from: name) {
|
|
||||||
return initials
|
|
||||||
}
|
|
||||||
if let username = profile?.login.trimmingCharacters(in: .whitespacesAndNewlines), !username.isEmpty {
|
|
||||||
return String(username.prefix(1)).uppercased()
|
|
||||||
}
|
|
||||||
return "?"
|
|
||||||
}
|
|
||||||
|
|
||||||
private func avatarUrl(for profile: ProfileDataPayload, fileId: String) -> URL? {
|
private func avatarUrl(for profile: ProfileDataPayload, fileId: String) -> URL? {
|
||||||
return URL(string: "\(AppConfig.API_SERVER)/v1/storage/download/avatar/\(profile.userId)?file_id=\(fileId)")
|
return URL(string: "\(AppConfig.API_SERVER)/v1/storage/download/avatar/\(profile.userId)?file_id=\(fileId)")
|
||||||
@ -382,15 +360,6 @@ struct EditProfileView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func initials(from text: String) -> String? {
|
|
||||||
let components = text
|
|
||||||
.split { $0.isWhitespace }
|
|
||||||
.filter { !$0.isEmpty }
|
|
||||||
let letters = components.prefix(2).compactMap { $0.first }
|
|
||||||
guard !letters.isEmpty else { return nil }
|
|
||||||
return letters.map { String($0).uppercased() }.joined()
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ImagePicker: UIViewControllerRepresentable {
|
struct ImagePicker: UIViewControllerRepresentable {
|
||||||
@Binding var image: UIImage?
|
@Binding var image: UIImage?
|
||||||
var allowsEditing: Bool = false
|
var allowsEditing: Bool = false
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user