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
155 lines
5.8 KiB
Swift
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
|
|
//
|
|
}
|
|
}
|
|
}
|
|
}
|