Add an option to delete the avatar or header (#2109)
* Endpoint: add Profile endpoint * EditAccount: add an option to delete the avatar or header * EditAccount: always display avatar view
This commit is contained in:
parent
2b8bc2ecd3
commit
f2ba08e1cc
|
@ -13465,6 +13465,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"account.edit.avatar.delete" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Delete avatar"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Supprimer l'avatar"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"account.edit.display-name" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
|
@ -13941,6 +13958,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"account.edit.header.delete" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Delete header"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Supprimer la bannière"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"account.edit.metadata-name-placeholder" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
|
|
|
@ -87,28 +87,45 @@ public struct EditAccountView: View {
|
|||
.frame(height: 150)
|
||||
}
|
||||
}
|
||||
if let avatar = viewModel.avatar {
|
||||
ZStack(alignment: .bottomLeading) {
|
||||
AvatarView(avatar, config: .account)
|
||||
Menu {
|
||||
Button("account.edit.avatar") {
|
||||
viewModel.isChangingAvatar = true
|
||||
viewModel.isPhotoPickerPresented = true
|
||||
}
|
||||
Button("account.edit.header") {
|
||||
viewModel.isChangingHeader = true
|
||||
viewModel.isPhotoPickerPresented = true
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "photo.badge.plus")
|
||||
.foregroundStyle(.white)
|
||||
ZStack(alignment: .bottomLeading) {
|
||||
AvatarView(viewModel.avatar, config: .account)
|
||||
Menu {
|
||||
Button("account.edit.avatar") {
|
||||
viewModel.isChangingAvatar = true
|
||||
viewModel.isPhotoPickerPresented = true
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.clipShape(Circle())
|
||||
.offset(x: -8, y: 8)
|
||||
Button("account.edit.header") {
|
||||
viewModel.isChangingHeader = true
|
||||
viewModel.isPhotoPickerPresented = true
|
||||
}
|
||||
if viewModel.avatar != nil || viewModel.header != nil {
|
||||
Divider()
|
||||
}
|
||||
if viewModel.avatar != nil {
|
||||
Button("account.edit.avatar.delete", role: .destructive) {
|
||||
Task {
|
||||
await viewModel.deleteAvatar()
|
||||
}
|
||||
}
|
||||
}
|
||||
if viewModel.header != nil {
|
||||
Button("account.edit.header.delete", role: .destructive) {
|
||||
Task {
|
||||
await viewModel.deleteHeader()
|
||||
}
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "photo.badge.plus")
|
||||
.foregroundStyle(.white)
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.clipShape(Circle())
|
||||
.offset(x: -8, y: 8)
|
||||
.padding(EdgeInsets(top: 0, leading: 0, bottom: 8, trailing: 0))
|
||||
}
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.overlay {
|
||||
if viewModel.isChangingAvatar || viewModel.isChangingHeader {
|
||||
ZStack(alignment: .center) {
|
||||
|
|
|
@ -82,8 +82,8 @@ import SwiftUI
|
|||
isBot = account.bot
|
||||
isLocked = account.locked
|
||||
isDiscoverable = account.discoverable ?? false
|
||||
avatar = account.avatar
|
||||
header = account.header
|
||||
avatar = account.haveAvatar ? account.avatar : nil
|
||||
header = account.haveHeader ? account.header : nil
|
||||
fields = account.source?.fields.map { .init(name: $0.name, value: $0.value.asRawText) } ?? []
|
||||
withAnimation {
|
||||
isLoading = false
|
||||
|
@ -112,6 +112,28 @@ import SwiftUI
|
|||
}
|
||||
}
|
||||
|
||||
func deleteAvatar() async -> Bool {
|
||||
guard let client else { return false }
|
||||
do {
|
||||
let response = try await client.delete(endpoint: Profile.deleteAvatar)
|
||||
avatar = nil
|
||||
return response?.statusCode == 200
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func deleteHeader() async -> Bool {
|
||||
guard let client else { return false }
|
||||
do {
|
||||
let response = try await client.delete(endpoint: Profile.deleteHeader)
|
||||
header = nil
|
||||
return response?.statusCode == 200
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func uploadHeader(data: Data) async -> Bool {
|
||||
guard let client else { return false }
|
||||
do {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import Foundation
|
||||
|
||||
public enum Profile: Endpoint {
|
||||
case deleteAvatar
|
||||
case deleteHeader
|
||||
|
||||
|
||||
public func path() -> String {
|
||||
switch self {
|
||||
case .deleteAvatar:
|
||||
"profile/avatar"
|
||||
case .deleteHeader:
|
||||
"profile/header"
|
||||
}
|
||||
}
|
||||
|
||||
public func queryItems() -> [URLQueryItem]? {
|
||||
switch self {
|
||||
case .deleteAvatar, .deleteHeader:
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue