Files
damus/damus/Views/Profile/EditPictureControl.swift
ericholguin 4a851501a1 ux: Simplify Onboarding
This patch simplifies the onboarding flow based on Jeroen's suggestions.

Setup view:
  - Removes extra nostr information
  - Only shows two buttons, create account and sign in.

Create Account view:
  - When a user uploads a photo it is now displayed
  - Name is now required
  - Public key is now hidden
  - Create account model has been updated to match metadata

Save Keys view:
  - Removes the requirement to copy the nsec
  - Simplified explanation
  - Only shows two buttons, save and not now

Testing
——
iPhone 15 Pro Max (17.0) Light Mode:
https://v.nostr.build/3P75x.mp4

iPhone SE (3rd generation) (16.4) Dark Mode:
https://v.nostr.build/wGBQL.mp4

——

Changelog-Fixed: Create Account model now uses correct metadata
Changelog-Changed: Onboarding design
2024-06-22 11:46:53 -06:00

155 lines
5.8 KiB
Swift

//
// EditPictureControl.swift
// damus
//
// Created by Joel Klabo on 3/30/23.
//
import SwiftUI
import Kingfisher
class ImageUploadingObserver: ObservableObject {
@Published var isLoading: Bool = false
}
struct EditPictureControl: View {
let uploader: MediaUploader
let pubkey: Pubkey
var size: CGFloat? = 25
var setup: Bool? = false
@Binding var image_url: URL?
@ObservedObject var uploadObserver: ImageUploadingObserver
let callback: (URL?) -> Void
@StateObject var image_upload: ImageUploadModel = ImageUploadModel()
@State private var show_camera = false
@State private var show_library = false
@State var image_upload_confirm: Bool = false
@State var preUploadedMedia: PreUploadedMedia? = nil
var body: some View {
Menu {
Button(action: {
self.show_library = true
}) {
Text("Choose from Library", comment: "Option to select photo from library")
}
Button(action: {
self.show_camera = true
}) {
Text("Take Photo", comment: "Option to take a photo with the camera")
}
} label: {
if uploadObserver.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: DamusColors.purple))
.frame(width: size, height: size)
.padding(10)
.background(DamusColors.white.opacity(0.7))
.clipShape(Circle())
.shadow(color: DamusColors.purple, radius: 15, x: 0, y: 0)
} else if let url = image_url {
KFAnimatedImage(url)
.imageContext(.pfp, disable_animation: false)
.onFailure(fallbackUrl: URL(string: robohash(pubkey)), cacheKey: url.absoluteString)
.cancelOnDisappear(true)
.configure { view in
view.framePreloadCount = 3
}
.scaledToFill()
.frame(width: (size ?? 25) + 10, height: (size ?? 25) + 10)
.foregroundColor(DamusColors.white)
.clipShape(Circle())
.overlay(Circle().stroke(.white, lineWidth: 4))
} else {
if setup ?? false {
Image(systemName: "person")
.resizable()
.scaledToFit()
.frame(width: size, height: size)
.foregroundColor(DamusColors.white)
.padding(20)
.clipShape(Circle())
.background {
Circle()
.fill(PinkGradient, strokeBorder: .white, lineWidth: 4)
}
} else {
Image("camera")
.resizable()
.scaledToFit()
.frame(width: size, height: size)
.foregroundColor(DamusColors.purple)
.padding(10)
.background(DamusColors.white.opacity(0.7))
.clipShape(Circle())
.background {
Circle()
.fill(DamusColors.purple, strokeBorder: .white, lineWidth: 2)
}
}
}
}
.sheet(isPresented: $show_camera) {
CameraController(uploader: uploader) {
self.show_camera = false
self.show_library = true
}
}
.sheet(isPresented: $show_library) {
MediaPicker(image_upload_confirm: $image_upload_confirm, imagesOnly: true) { media in
self.preUploadedMedia = media
}
.alert(NSLocalizedString("Are you sure you want to upload this image?", comment: "Alert message asking if the user wants to upload an image."), isPresented: $image_upload_confirm) {
Button(NSLocalizedString("Upload", comment: "Button to proceed with uploading."), role: .none) {
if let mediaToUpload = generateMediaUpload(preUploadedMedia) {
self.handle_upload(media: mediaToUpload)
self.show_library = false
}
}
Button(NSLocalizedString("Cancel", comment: "Button to cancel the upload."), role: .cancel) {}
}
}
}
private func handle_upload(media: MediaUpload) {
uploadObserver.isLoading = true
Task {
let res = await image_upload.start(media: media, uploader: uploader)
switch res {
case .success(let urlString):
let url = URL(string: urlString)
image_url = url
callback(url)
case .failed(let error):
if let error {
print("Error uploading profile image \(error.localizedDescription)")
} else {
print("Error uploading image :(")
}
callback(nil)
}
uploadObserver.isLoading = false
}
}
}
struct EditPictureControl_Previews: PreviewProvider {
static var previews: some View {
let url = Binding<URL?>.constant(URL(string: "https://damus.io")!)
let observer = ImageUploadingObserver()
ZStack {
Color.gray
EditPictureControl(uploader: .nostrBuild, pubkey: test_pubkey, size: 100, setup: false, image_url: url, uploadObserver: observer) { _ in
//
}
}
}
}