198 lines
6.2 KiB
Swift
198 lines
6.2 KiB
Swift
import PhotosUI
|
|
import SwiftUI
|
|
|
|
/// Embedded profile editing content (no NavigationStack — lives inside SettingsView's).
|
|
/// Matches Telegram's edit screen: avatar + photo picker, name fields,
|
|
/// helper texts, "Add Another Account", and "Log Out".
|
|
struct ProfileEditView: View {
|
|
@Binding var displayName: String
|
|
@Binding var username: String
|
|
let publicKey: String
|
|
var onLogout: () -> Void
|
|
|
|
@State private var selectedPhotoItem: PhotosPickerItem?
|
|
@State private var selectedPhoto: UIImage?
|
|
|
|
private var initials: String {
|
|
RosettaColors.initials(name: displayName, publicKey: publicKey)
|
|
}
|
|
|
|
private var avatarColorIndex: Int {
|
|
RosettaColors.avatarColorIndex(for: displayName, publicKey: publicKey)
|
|
}
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
avatarSection
|
|
.padding(.bottom, 24)
|
|
|
|
nameSection
|
|
|
|
helperText("Enter your name and add an optional profile photo.")
|
|
.padding(.top, 8)
|
|
.padding(.bottom, 24)
|
|
|
|
addAccountSection
|
|
|
|
helperText("You can connect multiple accounts with different phone numbers.")
|
|
.padding(.top, 8)
|
|
.padding(.bottom, 24)
|
|
|
|
logoutSection
|
|
}
|
|
.padding(.horizontal, 16)
|
|
.padding(.top, 24)
|
|
.padding(.bottom, 100)
|
|
}
|
|
}
|
|
|
|
// MARK: - Avatar Section
|
|
|
|
private extension ProfileEditView {
|
|
var avatarSection: some View {
|
|
VStack(spacing: 12) {
|
|
if let selectedPhoto {
|
|
Image(uiImage: selectedPhoto)
|
|
.resizable()
|
|
.scaledToFill()
|
|
.frame(width: 80, height: 80)
|
|
.clipShape(Circle())
|
|
} else {
|
|
AvatarView(
|
|
initials: initials,
|
|
colorIndex: avatarColorIndex,
|
|
size: 80,
|
|
isSavedMessages: false
|
|
)
|
|
}
|
|
|
|
PhotosPicker(selection: $selectedPhotoItem, matching: .images) {
|
|
Text("Set New Photo")
|
|
.font(.system(size: 15, weight: .medium))
|
|
.foregroundStyle(RosettaColors.primaryBlue)
|
|
}
|
|
.buttonStyle(.plain)
|
|
.onChange(of: selectedPhotoItem) { _, item in
|
|
Task {
|
|
if let data = try? await item?.loadTransferable(type: Data.self),
|
|
let image = UIImage(data: data) {
|
|
selectedPhoto = image
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Name Section
|
|
|
|
private extension ProfileEditView {
|
|
var nameSection: some View {
|
|
GlassCard(cornerRadius: 26, fillOpacity: 0.08) {
|
|
VStack(spacing: 0) {
|
|
HStack {
|
|
TextField("First Name", text: $displayName)
|
|
.font(.system(size: 17))
|
|
.foregroundStyle(RosettaColors.Adaptive.text)
|
|
.autocorrectionDisabled()
|
|
.textInputAutocapitalization(.words)
|
|
|
|
if !displayName.isEmpty {
|
|
Button { displayName = "" } label: {
|
|
Image(systemName: "xmark.circle.fill")
|
|
.font(.system(size: 18))
|
|
.foregroundStyle(RosettaColors.tertiaryText)
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
.padding(.horizontal, 16)
|
|
.frame(height: 52)
|
|
|
|
Divider()
|
|
.background(RosettaColors.Adaptive.divider)
|
|
.padding(.leading, 16)
|
|
|
|
HStack {
|
|
TextField("Username", text: $username)
|
|
.font(.system(size: 17))
|
|
.foregroundStyle(RosettaColors.Adaptive.text)
|
|
.textInputAutocapitalization(.never)
|
|
.autocorrectionDisabled()
|
|
|
|
if !username.isEmpty {
|
|
Button { username = "" } label: {
|
|
Image(systemName: "xmark.circle.fill")
|
|
.font(.system(size: 18))
|
|
.foregroundStyle(RosettaColors.tertiaryText)
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
.padding(.horizontal, 16)
|
|
.frame(height: 52)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Add Account & Logout
|
|
|
|
private extension ProfileEditView {
|
|
var addAccountSection: some View {
|
|
GlassCard(cornerRadius: 26, fillOpacity: 0.08) {
|
|
Button {} label: {
|
|
HStack {
|
|
Spacer()
|
|
Text("Add Another Account")
|
|
.font(.system(size: 17))
|
|
.foregroundStyle(RosettaColors.primaryBlue)
|
|
Spacer()
|
|
}
|
|
.frame(height: 52)
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
|
|
var logoutSection: some View {
|
|
GlassCard(cornerRadius: 26, fillOpacity: 0.08) {
|
|
Button(action: onLogout) {
|
|
HStack {
|
|
Spacer()
|
|
Text("Log Out")
|
|
.font(.system(size: 17))
|
|
.foregroundStyle(RosettaColors.error)
|
|
Spacer()
|
|
}
|
|
.frame(height: 52)
|
|
}
|
|
}
|
|
}
|
|
|
|
func helperText(_ text: String) -> some View {
|
|
Text(text)
|
|
.font(.system(size: 13))
|
|
.foregroundStyle(RosettaColors.secondaryText)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(.horizontal, 16)
|
|
}
|
|
}
|
|
|
|
// MARK: - Preview
|
|
|
|
#Preview {
|
|
NavigationStack {
|
|
ScrollView {
|
|
ProfileEditView(
|
|
displayName: .constant("Gaidar"),
|
|
username: .constant("GaidarTheDev"),
|
|
publicKey: "028d1c9d0000000000000000000000000000000000000000000000000000008e03ec",
|
|
onLogout: {}
|
|
)
|
|
}
|
|
.background(RosettaColors.Adaptive.background)
|
|
}
|
|
.preferredColorScheme(.dark)
|
|
}
|