Add first edit photo view
This commit is contained in:
parent
59918cca0e
commit
39ef9557fd
|
@ -143,6 +143,7 @@
|
|||
F8FA9919299FA35A007AB130 /* PhotoAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8FA9918299FA35A007AB130 /* PhotoAttachment.swift */; };
|
||||
F8FA991C299FA8C2007AB130 /* ImageUploadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8FA991B299FA8C2007AB130 /* ImageUploadView.swift */; };
|
||||
F8FA991E299FAB92007AB130 /* PhotoEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8FA991D299FAB92007AB130 /* PhotoEditorView.swift */; };
|
||||
F8FA9920299FDDC3007AB130 /* TextInputField.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8FA991F299FDDC3007AB130 /* TextInputField.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
@ -280,6 +281,7 @@
|
|||
F8FA9918299FA35A007AB130 /* PhotoAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoAttachment.swift; sourceTree = "<group>"; };
|
||||
F8FA991B299FA8C2007AB130 /* ImageUploadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageUploadView.swift; sourceTree = "<group>"; };
|
||||
F8FA991D299FAB92007AB130 /* PhotoEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoEditorView.swift; sourceTree = "<group>"; };
|
||||
F8FA991F299FDDC3007AB130 /* TextInputField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextInputField.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -447,6 +449,7 @@
|
|||
F8764188298ABEC80057D362 /* ErrorView.swift */,
|
||||
F876418A298AC1B80057D362 /* NoDataView.swift */,
|
||||
F86FB554298BF83F000131F0 /* FavouriteTouch.swift */,
|
||||
F8FA991F299FDDC3007AB130 /* TextInputField.swift */,
|
||||
);
|
||||
path = Widgets;
|
||||
sourceTree = "<group>";
|
||||
|
@ -824,6 +827,7 @@
|
|||
F88FAD2D295F4AD7009B20C9 /* ApplicationState.swift in Sources */,
|
||||
F88E4D54297EA7EE0057491A /* MarkdownFormattedText.swift in Sources */,
|
||||
F866F6A1296040A8002E8F88 /* ApplicationSettings+CoreDataProperties.swift in Sources */,
|
||||
F8FA9920299FDDC3007AB130 /* TextInputField.swift in Sources */,
|
||||
F86A4303299A9AF500DF7645 /* TipsStore.swift in Sources */,
|
||||
F8C5E56229892CC300ADF6A7 /* FirstAppear.swift in Sources */,
|
||||
F8C14394296AF21B001FE31D /* Double+Round.swift in Sources */,
|
||||
|
|
|
@ -15,6 +15,10 @@ public class PhotoAttachment: ObservableObject, Identifiable, Equatable, Hashabl
|
|||
public var photoData: Data
|
||||
|
||||
@Published public var description = String.empty()
|
||||
@Published public var alt = String.empty()
|
||||
@Published public var sensitive = false
|
||||
@Published public var commentingOff = false
|
||||
|
||||
@Published public var uploadedAttachment: UploadedAttachment?
|
||||
@Published public var error: Error?
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ public class AuthorizationService {
|
|||
) async throws {
|
||||
dbAccount.username = account.username
|
||||
dbAccount.acct = account.acct
|
||||
dbAccount.displayName = account.displayName
|
||||
dbAccount.displayName = account.displayNameWithoutEmojis
|
||||
dbAccount.note = account.note
|
||||
dbAccount.url = account.url
|
||||
dbAccount.avatar = account.avatar
|
||||
|
|
|
@ -79,7 +79,11 @@ struct ComposeView: View {
|
|||
|
||||
HStack(alignment: .center) {
|
||||
ForEach(self.photosAttachment, id: \.id) { photoAttachment in
|
||||
ImageUploadView(photoAttachment: photoAttachment)
|
||||
ImageUploadView(photoAttachment: photoAttachment) {
|
||||
self.photosAttachment = self.photosAttachment.filter({ item in
|
||||
item != photoAttachment
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(8)
|
||||
|
|
|
@ -7,8 +7,15 @@
|
|||
import SwiftUI
|
||||
|
||||
struct PhotoEditorView: View {
|
||||
@State public var photoAttachment: PhotoAttachment
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
@State private var description: String = String.empty()
|
||||
@State public var alt = String.empty()
|
||||
@State public var sensitive = false
|
||||
@State public var commentingOff = false
|
||||
|
||||
@ObservedObject public var photoAttachment: PhotoAttachment
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
if let uiImage = UIImage(data: photoAttachment.photoData) {
|
||||
|
@ -22,14 +29,53 @@ struct PhotoEditorView: View {
|
|||
}
|
||||
}
|
||||
|
||||
TextField("Add description for the visually impaired.", text: $photoAttachment.description, axis: .vertical)
|
||||
.keyboardType(.default)
|
||||
.lineLimit(4, reservesSpace: true)
|
||||
.multilineTextAlignment(.leading)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
.padding(8)
|
||||
Form {
|
||||
Section(header: Text("Input")) {
|
||||
TextInputField("Alt text", text: $alt)
|
||||
.keyboardType(.default)
|
||||
.lineLimit(4)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
TextInputField("Add description for the visually impaired", text: $description)
|
||||
.keyboardType(.default)
|
||||
.lineLimit(4)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
Toggle("Sensitive/NSFW Media", isOn: $sensitive)
|
||||
Toggle("Turn off commenting", isOn: $commentingOff)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
self.description = self.photoAttachment.description
|
||||
self.alt = self.photoAttachment.alt
|
||||
self.sensitive = self.photoAttachment.sensitive
|
||||
self.commentingOff = self.photoAttachment.commentingOff
|
||||
}
|
||||
.navigationBarTitle("Description")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
self.getTrailingToolbar()
|
||||
}
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
private func getTrailingToolbar() -> some ToolbarContent {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
HapticService.shared.touch()
|
||||
self.photoAttachment.description = self.description
|
||||
self.photoAttachment.alt = self.alt
|
||||
self.photoAttachment.sensitive = self.sensitive
|
||||
self.photoAttachment.commentingOff = self.commentingOff
|
||||
|
||||
self.dismiss()
|
||||
} label: {
|
||||
Text("Update")
|
||||
}.buttonStyle(.borderedProminent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,36 @@ struct ImageUploadView: View {
|
|||
@EnvironmentObject public var routerPath: RouterPath
|
||||
@ObservedObject public var photoAttachment: PhotoAttachment
|
||||
|
||||
private let delete: () -> Void
|
||||
|
||||
public init(photoAttachment: PhotoAttachment, delete: @escaping () -> Void) {
|
||||
self.photoAttachment = photoAttachment
|
||||
self.delete = delete
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
if let uiImage = UIImage(data: photoAttachment.photoData) {
|
||||
|
||||
if photoAttachment.uploadedAttachment == nil {
|
||||
if photoAttachment.error != nil {
|
||||
Menu {
|
||||
Button(role: .destructive) {
|
||||
self.delete()
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash")
|
||||
.tint(.red)
|
||||
}
|
||||
} label: {
|
||||
ZStack {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.blur(radius: 10)
|
||||
.frame(width: 80, height: 80)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
|
||||
Image(systemName: "exclamationmark.triangle.fill")
|
||||
}
|
||||
}
|
||||
} else if photoAttachment.uploadedAttachment == nil {
|
||||
ZStack {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
|
@ -24,7 +50,17 @@ struct ImageUploadView: View {
|
|||
LoadingIndicator(isVisible: Binding.constant(true))
|
||||
}
|
||||
} else {
|
||||
NavigationLink(value: RouteurDestinations.photoEditor(photoAttachment: photoAttachment)) {
|
||||
Menu {
|
||||
NavigationLink(value: RouteurDestinations.photoEditor(photoAttachment: photoAttachment)) {
|
||||
Label("Edit", systemImage: "pencil")
|
||||
}
|
||||
|
||||
Button(role: .destructive) {
|
||||
self.delete()
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash")
|
||||
}
|
||||
} label: {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 80, height: 80)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct TextInputField: View {
|
||||
private var title: String
|
||||
@Binding private var text: String
|
||||
|
||||
init(_ title: String, text: Binding<String>) {
|
||||
self.title = title
|
||||
self._text = text
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .leading) {
|
||||
Text(title)
|
||||
.foregroundColor(text.isEmpty ? Color(.placeholderText) : .accentColor)
|
||||
.offset(y: text.isEmpty ? 0 : -25)
|
||||
.scaleEffect(text.isEmpty ? 1: 0.8, anchor: .leading)
|
||||
TextField("", text: $text)
|
||||
}
|
||||
.padding(.top, 15)
|
||||
.animation(.default, value: text)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue