Add private bool to edit profile.

This commit is contained in:
Marcin Czachursk 2023-03-25 17:45:50 +01:00
parent 88ca1a3f5c
commit 7205b14d32
26 changed files with 54 additions and 36 deletions

View File

@ -267,5 +267,7 @@
"editProfile.title.save" = "Save";
"editProfile.title.accountSaved" = "Profile has been updated.";
"editProfile.title.photoInfo" = "The changed photo will be visible in the app and on the website with a small delay.";
"editProfile.title.privateAccount" = "Private account";
"editProfile.title.privateAccountInfo" = "When your account is private, only people you approve can see your photos and videos on pixelfed. Your existing followers won't be affected.";
"editProfile.error.saveAccountFailed" = "Saving profile failed.";
"editProfile.error.loadingAvatarFailed" = "Loading avatar failed.";

View File

@ -267,5 +267,7 @@
"editProfile.title.save" = "Zapisz";
"editProfile.title.accountSaved" = "Profil zaktualizowano.";
"editProfile.title.photoInfo" = "Zmienione zdjęcie będzie widoczne w aplikacji oraz na stronie z małym opóźnieniem.";
"editProfile.title.privateAccount" = "Konto prywatne";
"editProfile.title.privateAccountInfo" = "Kiedy Twoje konto jest prywatne, tylko osoby, które zaakceptujesz mogą oglądać Twoje zdjęcia i filmy na Pixelfed. Nie wpłynie to na Twoich obecnych obserwujących.";
"editProfile.error.saveAccountFailed" = "Błąd podczas aktualizacji profilu.";
"editProfile.error.loadingAvatarFailed" = "Błąd podczas wczytywania zdjęcia.";

View File

@ -162,10 +162,10 @@ public extension PixelfedClientAuthenticated {
return try await downloadJson([Status].self, request: request)
}
func update(displayName: String, bio: String, website: String, image: Data?) async throws -> Account {
func update(displayName: String, bio: String, website: String, locked: Bool, image: Data?) async throws -> Account {
let request = try Self.request(
for: baseURL,
target: Pixelfed.Account.updateCredentials(displayName, bio, website, image),
target: Pixelfed.Account.updateCredentials(displayName, bio, website, locked, image),
withBearerToken: token)
return try await downloadJson(Account.self, request: request)

View File

@ -21,7 +21,7 @@ extension Pixelfed {
case unmute(EntityId)
case relationships([EntityId])
case search(SearchQuery, Int)
case updateCredentials(String, String, String, Data?)
case updateCredentials(String, String, String, Bool, Data?)
case updateAvatar(Data?)
}
}
@ -58,7 +58,7 @@ extension Pixelfed.Account: TargetType {
return "\(apiPath)/relationships"
case .search(_, _):
return "\(apiPath)/search"
case .updateCredentials(_, _, _, _):
case .updateCredentials(_, _, _, _, _):
return "\(apiPath)/update_credentials"
case .updateAvatar(_):
return "\(apiPath)/update_credentials"
@ -69,7 +69,7 @@ extension Pixelfed.Account: TargetType {
switch self {
case .follow(_), .unfollow(_), .block(_), .unblock(_), .mute(_), .unmute(_):
return .post
case .updateCredentials(_, _, _, _), .updateAvatar(_):
case .updateCredentials(_, _, _, _, _), .updateAvatar(_):
// Mastodon API uses PATCH, however in Pixelfed we have to use POST: https://github.com/pixelfed/pixelfed/issues/4250
// Also it seems that we have to speparatelly save text fields and avatar(?).
return .post
@ -118,7 +118,7 @@ extension Pixelfed.Account: TargetType {
minId = _minId
limit = _limit
page = _page
case .updateCredentials(_, _, _, _), .updateAvatar(_):
case .updateCredentials(_, _, _, _, _), .updateAvatar(_):
return [
("_pe", "1")
]
@ -151,7 +151,7 @@ extension Pixelfed.Account: TargetType {
public var headers: [String: String]? {
switch self {
case .updateCredentials(_, _, _, _), .updateAvatar(_):
case .updateCredentials(_, _, _, _, _), .updateAvatar(_):
return ["content-type": "multipart/form-data; boundary=\(multipartBoundary)"]
default:
return [:].contentTypeApplicationJson
@ -160,12 +160,13 @@ extension Pixelfed.Account: TargetType {
public var httpBody: Data? {
switch self {
case .updateCredentials(let displayName, let bio, let website, let image):
case .updateCredentials(let displayName, let bio, let website, let locked, let image):
let formDataBuilder = MultipartFormData(boundary: multipartBoundary)
formDataBuilder.addTextField(named: "display_name", value: displayName)
formDataBuilder.addTextField(named: "note", value: bio)
formDataBuilder.addTextField(named: "website", value: website)
formDataBuilder.addTextField(named: "locked", value: locked ? "true" : "false")
if let image {
formDataBuilder.addDataField(named: "avatar", fileName: "avatar.jpg", data: image, mimeType: "image/jpeg")

View File

@ -35,7 +35,7 @@ extension Pixelfed.Apps: TargetType {
}
}
fileprivate var apiPath: String { return "/api/v1/apps" }
private var apiPath: String { return "/api/v1/apps" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Blocks: TargetType {
fileprivate var apiPath: String { return "/api/v1/blocks" }
private var apiPath: String { return "/api/v1/blocks" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Bookmarks: TargetType {
fileprivate var apiPath: String { return "/api/v1/bookmarks" }
private var apiPath: String { return "/api/v1/bookmarks" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Favourites: TargetType {
fileprivate var apiPath: String { return "/api/v1/favourites" }
private var apiPath: String { return "/api/v1/favourites" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -15,7 +15,7 @@ extension Pixelfed {
}
extension Pixelfed.FollowRequests: TargetType {
fileprivate var apiPath: String { return "/api/v1/follow_requests" }
private var apiPath: String { return "/api/v1/follow_requests" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Follows: TargetType {
fileprivate var apiPath: String { return "/api/v1/follows" }
private var apiPath: String { return "/api/v1/follows" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Instances: TargetType {
fileprivate var apiPath: String { return "/api/v1/instance" }
private var apiPath: String { return "/api/v1/instance" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -19,7 +19,7 @@ extension Pixelfed {
}
extension Pixelfed.Markers: TargetType {
fileprivate var apiPath: String { return "/api/v1/markers" }
private var apiPath: String { return "/api/v1/markers" }
public var path: String {
return apiPath

View File

@ -6,8 +6,6 @@
import Foundation
fileprivate let multipartBoundary = UUID().uuidString
extension Pixelfed {
public enum Media {
case upload(Data, String, String)
@ -33,7 +31,8 @@ extension Pixelfed.Media: TargetType {
}
fileprivate var apiPath: String { return "/api" }
private var apiPath: String { return "/api" }
private var multipartBoundary: String { "b4673f7d-6f34-4413-a23c-e3783e0e7bdf" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Mutes: TargetType {
fileprivate var apiPath: String { return "/api/v1/mutes" }
private var apiPath: String { return "/api/v1/mutes" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -15,7 +15,7 @@ extension Pixelfed {
}
extension Pixelfed.Notifications: TargetType {
fileprivate var apiPath: String { return "/api/v1/notifications" }
private var apiPath: String { return "/api/v1/notifications" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -41,7 +41,7 @@ extension Pixelfed.OAuth: TargetType {
}
}
fileprivate var apiPath: String { return "/oauth/token" }
private var apiPath: String { return "/oauth/token" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -13,7 +13,7 @@ extension Pixelfed {
}
extension Pixelfed.Places: TargetType {
fileprivate var apiPath: String { return "/api/v1.1/compose/search/location" }
private var apiPath: String { return "/api/v1.1/compose/search/location" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -33,7 +33,7 @@ extension Pixelfed.Reports: TargetType {
}
}
fileprivate var apiPath: String { return "/api/v1/reports" }
private var apiPath: String { return "/api/v1/reports" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -20,7 +20,7 @@ extension Pixelfed.Search: TargetType {
case statuses = "statuses"
}
fileprivate var apiPath: String { return "/api/v2/search" }
private var apiPath: String { return "/api/v2/search" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -105,7 +105,7 @@ extension Pixelfed.Statuses: TargetType {
}
}
fileprivate var apiPath: String { return "/api/v1/statuses" }
private var apiPath: String { return "/api/v1/statuses" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -15,7 +15,7 @@ extension Pixelfed {
}
extension Pixelfed.Tags: TargetType {
fileprivate var apiPath: String { return "/api/v1/tags" }
private var apiPath: String { return "/api/v1/tags" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -15,7 +15,7 @@ extension Pixelfed {
}
extension Pixelfed.Timelines: TargetType {
fileprivate var apiPath: String { return "/api/v1/timelines" }
private var apiPath: String { return "/api/v1/timelines" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -21,7 +21,7 @@ extension Pixelfed.Trends: TargetType {
case yearly = "yearly"
}
fileprivate var apiPath: String { return "/api/v1.1/discover" }
private var apiPath: String { return "/api/v1.1/discover" }
/// The path to be appended to `baseURL` to form the full `URL`.
public var path: String {

View File

@ -1278,7 +1278,7 @@
CODE_SIGN_ENTITLEMENTS = VernissageWidget/VernissageWidgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 83;
CURRENT_PROJECT_VERSION = 84;
DEVELOPMENT_TEAM = B2U9FEKYP8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = VernissageWidget/Info.plist;
@ -1306,7 +1306,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = VernissageWidget/VernissageWidgetExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 83;
CURRENT_PROJECT_VERSION = 84;
DEVELOPMENT_TEAM = B2U9FEKYP8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = VernissageWidget/Info.plist;
@ -1454,7 +1454,7 @@
CODE_SIGN_ENTITLEMENTS = Vernissage/Vernissage.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 83;
CURRENT_PROJECT_VERSION = 84;
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
DEVELOPMENT_TEAM = B2U9FEKYP8;
ENABLE_PREVIEWS = YES;
@ -1494,7 +1494,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = Vernissage/Vernissage.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 83;
CURRENT_PROJECT_VERSION = 84;
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
DEVELOPMENT_TEAM = B2U9FEKYP8;
ENABLE_PREVIEWS = YES;

View File

@ -83,8 +83,12 @@ extension Client {
return try await pixelfedClient.bookmarks(limit: limit, page: page)
}
func update(displayName: String, bio: String, website: String, image: Data?) async throws -> Account {
return try await pixelfedClient.update(displayName: displayName, bio: bio, website: website, image: image)
func update(displayName: String, bio: String, website: String, locked: Bool, image: Data?) async throws -> Account {
return try await pixelfedClient.update(displayName: displayName,
bio: bio,
website: website,
locked: locked,
image: image)
}
func avatar(image: Data?) async throws -> Account {

View File

@ -19,6 +19,7 @@ struct EditProfileView: View {
@State private var displayName: String = ""
@State private var bio: String = ""
@State private var website: String = ""
@State private var isPrivate = false
@State private var avatarData: Data?
private let account: Account
@ -134,10 +135,17 @@ struct EditProfileView: View {
Text("\(self.website.count)/\(self.websiteMaxLength)")
}
}
Section {
Toggle("editProfile.title.privateAccount", isOn: $isPrivate)
} footer: {
Text("editProfile.title.privateAccountInfo", comment: "Private account info")
}
}
.toolbar {
ToolbarItem(placement: .primaryAction) {
ActionButton(showLoader: false) {
ActionButton(showLoader: true) {
await self.saveProfile()
} label: {
Text("editProfile.title.save", comment: "Save")
@ -150,6 +158,7 @@ struct EditProfileView: View {
.onAppear {
self.displayName = self.account.displayName ?? String.empty()
self.website = self.account.website ?? String.empty()
self.isPrivate = self.account.locked
let markdownBio = self.account.note?.asMarkdown ?? String.empty()
if let attributedString = try? AttributedString(markdown: markdownBio) {
@ -173,6 +182,7 @@ struct EditProfileView: View {
_ = try await self.client.accounts?.update(displayName: self.displayName,
bio: self.bio,
website: self.website,
locked: self.isPrivate,
image: nil)
if let avatarData = self.avatarData {