From 08bb8ed8e6148daa3a48a435fcc878130088feca Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:11:21 +0000 Subject: [PATCH 1/7] Update --- Mlem.xcodeproj/project.pbxproj | 4 ++ .../Tabs/Settings/AccountSettingsView.swift | 6 ++ .../Tabs/Settings/ProfileSettingsView.swift | 66 +++++++++++++++++++ .../App/Views/Shared/MarkdownTextEditor.swift | 2 +- .../Shared/Navigation/SettingsPage.swift | 8 ++- Mlem/Localizable.xcstrings | 15 +++++ 6 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift diff --git a/Mlem.xcodeproj/project.pbxproj b/Mlem.xcodeproj/project.pbxproj index ea6067147..3cbb7d3db 100644 --- a/Mlem.xcodeproj/project.pbxproj +++ b/Mlem.xcodeproj/project.pbxproj @@ -153,6 +153,7 @@ 0389DDD32C39E4D40005B808 /* PasteLinkButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0389DDD22C39E4D40005B808 /* PasteLinkButtonView.swift */; }; 0389DDD52C39F1290005B808 /* CommunityListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0389DDD42C39F1290005B808 /* CommunityListRow.swift */; }; 0389DDDB2C3AB6340005B808 /* ActionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0389DDDA2C3AB6340005B808 /* ActionBuilder.swift */; }; + 0391E0F92CFF17AE0040CCA8 /* ProfileSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0391E0F82CFF17AE0040CCA8 /* ProfileSettingsView.swift */; }; 0397D4602C66113F002C6CDC /* CommentBodyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0397D45F2C66113F002C6CDC /* CommentBodyView.swift */; }; 0397D4622C676B46002C6CDC /* ApiSortType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0397D4612C676B46002C6CDC /* ApiSortType+Extensions.swift */; }; 0397D4642C676CA8002C6CDC /* FeedSortPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0397D4632C676CA8002C6CDC /* FeedSortPicker.swift */; }; @@ -569,6 +570,7 @@ 0389DDD22C39E4D40005B808 /* PasteLinkButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteLinkButtonView.swift; sourceTree = "<group>"; }; 0389DDD42C39F1290005B808 /* CommunityListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommunityListRow.swift; sourceTree = "<group>"; }; 0389DDDA2C3AB6340005B808 /* ActionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionBuilder.swift; sourceTree = "<group>"; }; + 0391E0F82CFF17AE0040CCA8 /* ProfileSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSettingsView.swift; sourceTree = "<group>"; }; 0397D45F2C66113F002C6CDC /* CommentBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentBodyView.swift; sourceTree = "<group>"; }; 0397D4612C676B46002C6CDC /* ApiSortType+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ApiSortType+Extensions.swift"; sourceTree = "<group>"; }; 0397D4632C676CA8002C6CDC /* FeedSortPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedSortPicker.swift; sourceTree = "<group>"; }; @@ -898,6 +900,7 @@ 03267D832BED49CE009D6268 /* AccountSettingsView.swift */, 037DE0742CE023E3007F7B92 /* BlockListView.swift */, 03AB48512CBC042E00567FF9 /* AccountGeneralSettingsView.swift */, + 0391E0F82CFF17AE0040CCA8 /* ProfileSettingsView.swift */, 03AB48542CBC0B8000567FF9 /* AccountAdvancedSettingsView.swift */, 03AB48562CBC0DFC00567FF9 /* AccountSignInSettingsView.swift */, 03AB48582CBC14CE00567FF9 /* AccountEmailSettingsView.swift */, @@ -2466,6 +2469,7 @@ 039F58972C7B68F100C61658 /* AboutMlemView.swift in Sources */, 035EDEFB2C2DF98700F51144 /* CommunityListRowBody.swift in Sources */, CD77437F2C1BA5CE0085BB43 /* MultiplatformView.swift in Sources */, + 0391E0F92CFF17AE0040CCA8 /* ProfileSettingsView.swift in Sources */, 03E614E72C0BCDC200F692A4 /* FullyQualifiedLinkView.swift in Sources */, B1B78D642A51D53900F72485 /* AppDelegate.swift in Sources */, ); diff --git a/Mlem/App/Views/Root/Tabs/Settings/AccountSettingsView.swift b/Mlem/App/Views/Root/Tabs/Settings/AccountSettingsView.swift index a91a29b0a..1bee94464 100644 --- a/Mlem/App/Views/Root/Tabs/Settings/AccountSettingsView.swift +++ b/Mlem/App/Views/Root/Tabs/Settings/AccountSettingsView.swift @@ -33,6 +33,12 @@ struct AccountSettingsView: View { if appState.firstSession is UserSession { Section { + NavigationLink( + "My Profile", + systemImage: Icons.personFill, + destination: .settings(.profile) + ) + .tint(palette.colorfulAccent(5)) NavigationLink( "Sign-In & Security", systemImage: "key.fill", diff --git a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift new file mode 100644 index 000000000..c9a363158 --- /dev/null +++ b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift @@ -0,0 +1,66 @@ +// +// ProfileSettingsView.swift +// Mlem +// +// Created by Sjmarf on 2024-12-03. +// + +import SwiftUI + +struct ProfileSettingsView: View { + let session: UserSession + @State var displayName: String = "" + + @State var bioTextView: UITextView = .init() + @State var uploadHistory: ImageUploadHistoryManager = .init() + + var minTextEditorHeight: CGFloat { + UIFont.preferredFont(forTextStyle: .body).lineHeight * 6 + 20 + } + + var body: some View { + Form { + Section("Display Name") { + TextField("Display Name", text: $displayName, prompt: Text(session.account.name)) + } footer: { + Text("The name that is displayed on your profile. This is not the same as your username, which cannot be changed.") + } + Section("Biography") { + MarkdownTextEditor( + onChange: { _ in + }, + prompt: "Write a bit about yourself...", + textView: bioTextView, + insets: .init(), +// insets: .init( +// top: Constants.main.standardSpacing, +// left: Constants.main.standardSpacing, +// bottom: Constants.main.standardSpacing, +// right: Constants.main.standardSpacing +// ), + firstResponder: false, + content: { + MarkdownEditorToolbarView( + textView: bioTextView, + uploadHistory: uploadHistory, + imageUploadApi: session.api + ) + } + ) + .frame( + maxWidth: .infinity, + minHeight: minTextEditorHeight, + maxHeight: .infinity, + alignment: .topLeading + ) + .listRowInsets(.init( + top: Constants.main.standardSpacing, + leading: Constants.main.standardSpacing, + bottom: Constants.main.standardSpacing, + trailing: Constants.main.standardSpacing + )) + } + } + .navigationTitle("My Profile") + } +} diff --git a/Mlem/App/Views/Shared/MarkdownTextEditor.swift b/Mlem/App/Views/Shared/MarkdownTextEditor.swift index 8532d2d31..25dc795d3 100644 --- a/Mlem/App/Views/Shared/MarkdownTextEditor.swift +++ b/Mlem/App/Views/Shared/MarkdownTextEditor.swift @@ -84,7 +84,7 @@ struct MarkdownTextEditor<Content: View>: UIViewRepresentable { placeholderLabel.sizeToFit() textView.addSubview(placeholderLabel) placeholderLabel.frame.origin = CGPoint( - x: 15, + x: insets.left + 5, y: insets.top + 1 ) placeholderLabel.textColor = UIColor(Palette.main.tertiary) diff --git a/Mlem/App/Views/Shared/Navigation/SettingsPage.swift b/Mlem/App/Views/Shared/Navigation/SettingsPage.swift index f1c92dc62..1d7667512 100644 --- a/Mlem/App/Views/Shared/Navigation/SettingsPage.swift +++ b/Mlem/App/Views/Shared/Navigation/SettingsPage.swift @@ -11,7 +11,7 @@ import SwiftUI enum SettingsPage: Hashable { case root case accounts, account - case accountGeneral, accountAdvanced, accountSignIn, accountChangeEmail + case profile, accountGeneral, accountAdvanced, accountSignIn, accountChangeEmail case general, links, sorting case importExportSettings case theme, icon @@ -29,6 +29,12 @@ enum SettingsPage: Hashable { SettingsView() case .account: AccountSettingsView() + case .profile: + if let session = AppState.main.firstSession as? UserSession { + ProfileSettingsView(session: session) + } else { + Text(verbatim: "Error: No active user account") + } case .accountGeneral: AccountGeneralSettingsView() case .accountSignIn: diff --git a/Mlem/Localizable.xcstrings b/Mlem/Localizable.xcstrings index 40ba22316..4daafd11d 100644 --- a/Mlem/Localizable.xcstrings +++ b/Mlem/Localizable.xcstrings @@ -246,6 +246,9 @@ }, "Behavior" : { + }, + "Biography" : { + }, "Block" : { @@ -479,6 +482,9 @@ }, "Dismiss" : { + }, + "Display Name" : { + }, "Divider" : { @@ -898,6 +904,9 @@ }, "Most Comments" : { + }, + "My Profile" : { + }, "Never" : { @@ -1445,6 +1454,9 @@ } } } + }, + "The name that is displayed on your profile. This is not the same as your username, which cannot be changed." : { + }, "The number of child comments that are shown in a chain before the \"More Replies\" button is shown." : { @@ -1697,6 +1709,9 @@ }, "Wrap Code Block Lines" : { + }, + "Write a bit about yourself..." : { + }, "Year" : { From 9816015e91e77db2d60b2ab0cb0de80e5542d958 Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:16:46 +0000 Subject: [PATCH 2/7] Update --- .../Tabs/Settings/ProfileSettingsView.swift | 23 ++++++++----------- .../App/Views/Shared/MarkdownTextEditor.swift | 6 ++++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift index c9a363158..2b8a84ddd 100644 --- a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift +++ b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift @@ -14,6 +14,8 @@ struct ProfileSettingsView: View { @State var bioTextView: UITextView = .init() @State var uploadHistory: ImageUploadHistoryManager = .init() + @State var avatarManager: ImageUploadManager? + var minTextEditorHeight: CGFloat { UIFont.preferredFont(forTextStyle: .body).lineHeight * 6 + 20 } @@ -31,14 +33,14 @@ struct ProfileSettingsView: View { }, prompt: "Write a bit about yourself...", textView: bioTextView, - insets: .init(), -// insets: .init( -// top: Constants.main.standardSpacing, -// left: Constants.main.standardSpacing, -// bottom: Constants.main.standardSpacing, -// right: Constants.main.standardSpacing -// ), + insets: .init( + top: Constants.main.standardSpacing, + left: Constants.main.standardSpacing, + bottom: Constants.main.standardSpacing, + right: Constants.main.standardSpacing + ), firstResponder: false, + sizingOffset: 10, content: { MarkdownEditorToolbarView( textView: bioTextView, @@ -53,12 +55,7 @@ struct ProfileSettingsView: View { maxHeight: .infinity, alignment: .topLeading ) - .listRowInsets(.init( - top: Constants.main.standardSpacing, - leading: Constants.main.standardSpacing, - bottom: Constants.main.standardSpacing, - trailing: Constants.main.standardSpacing - )) + .listRowInsets(.init()) } } .navigationTitle("My Profile") diff --git a/Mlem/App/Views/Shared/MarkdownTextEditor.swift b/Mlem/App/Views/Shared/MarkdownTextEditor.swift index 25dc795d3..fa8ffa5fc 100644 --- a/Mlem/App/Views/Shared/MarkdownTextEditor.swift +++ b/Mlem/App/Views/Shared/MarkdownTextEditor.swift @@ -15,6 +15,7 @@ struct MarkdownTextEditor<Content: View>: UIViewRepresentable { let textView: UITextView let placeholderLabel: UILabel = .init() let font: UIFont + let sizingOffset: CGFloat let onChange: (String) -> Void @@ -35,6 +36,8 @@ struct MarkdownTextEditor<Content: View>: UIViewRepresentable { right: Constants.main.standardSpacing ), firstResponder: Bool = true, + // In forms this needs to be set to ~10 (I don't know why this is the case) + sizingOffset: CGFloat = 1, @ViewBuilder content: () -> Content ) { self.prompt = String(localized: prompt) @@ -43,6 +46,7 @@ struct MarkdownTextEditor<Content: View>: UIViewRepresentable { self.font = font self.insets = insets self.firstResponder = firstResponder + self.sizingOffset = sizingOffset self.onChange = onChange } @@ -126,7 +130,7 @@ struct MarkdownTextEditor<Content: View>: UIViewRepresentable { // of the rounding logic above; it still happens when simply using `contentSize`. return .init( width: dimensions.width, - height: calculatedHeight + 1 + height: calculatedHeight + sizingOffset ) } From 34a8a6016f3bcfde31ac26312b58d7ef05d735fc Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Sat, 7 Dec 2024 13:36:41 +0000 Subject: [PATCH 3/7] Update --- Mlem.xcodeproj/project.pbxproj | 4 + .../Tabs/Settings/ProfileSettingsView.swift | 105 +++++++++++++++++- Mlem/App/Views/Shared/ImageUploadMenu.swift | 38 +++++++ .../Images/Wrappers/LargeImageView.swift | 15 ++- .../Shared/MarkdownEditorToolbarView.swift | 13 +-- .../Shared/Navigation/SettingsPage.swift | 4 +- Mlem/Localizable.xcstrings | 6 + 7 files changed, 164 insertions(+), 21 deletions(-) create mode 100644 Mlem/App/Views/Shared/ImageUploadMenu.swift diff --git a/Mlem.xcodeproj/project.pbxproj b/Mlem.xcodeproj/project.pbxproj index 3cbb7d3db..094634557 100644 --- a/Mlem.xcodeproj/project.pbxproj +++ b/Mlem.xcodeproj/project.pbxproj @@ -154,6 +154,7 @@ 0389DDD52C39F1290005B808 /* CommunityListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0389DDD42C39F1290005B808 /* CommunityListRow.swift */; }; 0389DDDB2C3AB6340005B808 /* ActionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0389DDDA2C3AB6340005B808 /* ActionBuilder.swift */; }; 0391E0F92CFF17AE0040CCA8 /* ProfileSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0391E0F82CFF17AE0040CCA8 /* ProfileSettingsView.swift */; }; + 0391E0FB2D0066240040CCA8 /* ImageUploadMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0391E0FA2D0066240040CCA8 /* ImageUploadMenu.swift */; }; 0397D4602C66113F002C6CDC /* CommentBodyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0397D45F2C66113F002C6CDC /* CommentBodyView.swift */; }; 0397D4622C676B46002C6CDC /* ApiSortType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0397D4612C676B46002C6CDC /* ApiSortType+Extensions.swift */; }; 0397D4642C676CA8002C6CDC /* FeedSortPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0397D4632C676CA8002C6CDC /* FeedSortPicker.swift */; }; @@ -571,6 +572,7 @@ 0389DDD42C39F1290005B808 /* CommunityListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommunityListRow.swift; sourceTree = "<group>"; }; 0389DDDA2C3AB6340005B808 /* ActionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionBuilder.swift; sourceTree = "<group>"; }; 0391E0F82CFF17AE0040CCA8 /* ProfileSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSettingsView.swift; sourceTree = "<group>"; }; + 0391E0FA2D0066240040CCA8 /* ImageUploadMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageUploadMenu.swift; sourceTree = "<group>"; }; 0397D45F2C66113F002C6CDC /* CommentBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentBodyView.swift; sourceTree = "<group>"; }; 0397D4612C676B46002C6CDC /* ApiSortType+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ApiSortType+Extensions.swift"; sourceTree = "<group>"; }; 0397D4632C676CA8002C6CDC /* FeedSortPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedSortPicker.swift; sourceTree = "<group>"; }; @@ -1506,6 +1508,7 @@ 0355F9482C16406E00605248 /* Line.swift */, 03D2A6402C011F3E00ED4FF2 /* ListRow */, 03B431C12C45BA00001A1EB5 /* MarkdownEditorToolbarView.swift */, + 0391E0FA2D0066240040CCA8 /* ImageUploadMenu.swift */, 034B94842C09348400039AF4 /* MarkdownImageView.swift */, 03B431B32C4481C3001A1EB5 /* MarkdownTextEditor.swift */, 03D3A1EE2BB9CA1D009DE55E /* MenuButton.swift */, @@ -2326,6 +2329,7 @@ CD4D59162B87B38C00B82964 /* UIApplication+Extensions.swift in Sources */, CDB41E8A2C83C24400BD2DE9 /* Section.swift in Sources */, CDCA44B22C17675600C092B3 /* Haptic.swift in Sources */, + 0391E0FB2D0066240040CCA8 /* ImageUploadMenu.swift in Sources */, 035BE08B2BDD903100F77D73 /* NavigationModel.swift in Sources */, 033F84BB2C2ACB96002E3EDF /* CommentView.swift in Sources */, 03AFD0E52C3C14D50054B8AD /* InstanceStubProviding+Extensions.swift in Sources */, diff --git a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift index 2b8a84ddd..a64e20151 100644 --- a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift +++ b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift @@ -5,16 +5,31 @@ // Created by Sjmarf on 2024-12-03. // +import MlemMiddleware import SwiftUI struct ProfileSettingsView: View { - let session: UserSession + @Environment(Palette.self) var palette + + let person: Person4 @State var displayName: String = "" @State var bioTextView: UITextView = .init() @State var uploadHistory: ImageUploadHistoryManager = .init() - @State var avatarManager: ImageUploadManager? + @State var avatarUrl: URL? + @State var avatarManager: ImageUploadManager = .init() + + @State var bannerUrl: URL? + @State var bannerManager: ImageUploadManager = .init() + + init(person: Person4) { + self.person = person + self.displayName = person.displayName == person.name ? "" : person.displayName + bioTextView.text = person.description ?? "" + self._avatarUrl = .init(wrappedValue: person.avatar) + self._bannerUrl = .init(wrappedValue: person.banner) + } var minTextEditorHeight: CGFloat { UIFont.preferredFont(forTextStyle: .body).lineHeight * 6 + 20 @@ -23,7 +38,7 @@ struct ProfileSettingsView: View { var body: some View { Form { Section("Display Name") { - TextField("Display Name", text: $displayName, prompt: Text(session.account.name)) + TextField("Display Name", text: $displayName, prompt: Text(person.name)) } footer: { Text("The name that is displayed on your profile. This is not the same as your username, which cannot be changed.") } @@ -45,7 +60,7 @@ struct ProfileSettingsView: View { MarkdownEditorToolbarView( textView: bioTextView, uploadHistory: uploadHistory, - imageUploadApi: session.api + imageUploadApi: person.api ) } ) @@ -57,7 +72,89 @@ struct ProfileSettingsView: View { ) .listRowInsets(.init()) } + avatarSection + bannerSection } .navigationTitle("My Profile") + .scrollDismissesKeyboard(.interactively) + } + + @ViewBuilder + var avatarSection: some View { + Section { + HStack(spacing: 15) { + CircleCroppedImageView(url: avatarUrl, frame: 48, fallback: .person) + .id(avatarUrl) + Text("Avatar") + Spacer() + CircleImageUploadButton(imageManager: avatarManager, url: $avatarUrl, api: person.api) + } + .onChange(of: avatarManager.image?.url) { + avatarUrl = avatarManager.image?.url + } + } + } + + @ViewBuilder + var bannerSection: some View { + Section { + VStack(spacing: 0) { + if let bannerUrl { + LargeImageView(url: bannerUrl, shouldBlur: false, cornerRadius: 0) + .id(bannerUrl) + .aspectRatio(contentMode: .fill) + .frame(height: 150) + .clipped() + } else { + palette.tertiaryGroupedBackground + .frame(height: 150) + } + HStack(spacing: 15) { + Text("Banner") + Spacer() + CircleImageUploadButton(imageManager: bannerManager, url: $bannerUrl, api: person.api) + } + .padding(.horizontal, 15) + .padding(.vertical, 10) + } + .onChange(of: bannerManager.image?.url) { + bannerUrl = bannerManager.image?.url + } + } + .listRowInsets(.init()) + } +} + +private struct CircleImageUploadButton: View { + let imageManager: ImageUploadManager + @Binding var url: URL? + let api: ApiClient + + var body: some View { + Group { + if url != nil { + Button { + url = nil + } label: { + Image(systemName: "xmark.circle.fill") + .resizable() + } + } else { + switch imageManager.state { + case .uploading: + ProgressView() + .controlSize(.extraLarge) + default: + ImageUploadMenu(imageManager: imageManager, imageUploadApi: api) { + Image(systemName: "plus.circle.fill") + .resizable() + } + } + } + } + .aspectRatio(contentMode: .fit) + .frame(height: 48) + .symbolRenderingMode(.hierarchical) + .fontWeight(.thin) } } diff --git a/Mlem/App/Views/Shared/ImageUploadMenu.swift b/Mlem/App/Views/Shared/ImageUploadMenu.swift new file mode 100644 index 000000000..579a2bd61 --- /dev/null +++ b/Mlem/App/Views/Shared/ImageUploadMenu.swift @@ -0,0 +1,38 @@ +// +// ImageUploadMenu.swift +// Mlem +// +// Created by Sjmarf on 2024-12-04. +// + +import MlemMiddleware +import SwiftUI + +struct ImageUploadMenu<Label: View>: View { + @Environment(NavigationLayer.self) var navigation + + let imageManager: ImageUploadManager + let imageUploadApi: ApiClient + @ViewBuilder let label: () -> Label + + init(imageManager: ImageUploadManager, imageUploadApi: ApiClient, @ViewBuilder label: @escaping () -> Label) { + self.imageManager = imageManager + self.imageUploadApi = imageUploadApi + self.label = label + } + + var body: some View { + Menu(content: { + Button("Photo Library", systemImage: Icons.photo) { + navigation.showPhotosPicker(for: imageManager, api: imageUploadApi) + } + Button("Choose File", systemImage: "folder") { + navigation.showFilePicker(for: imageManager, api: imageUploadApi) + } + Button("Paste", systemImage: Icons.paste) { + navigation.uploadImageFromClipboard(for: imageManager, api: imageUploadApi) + } + }, label: label) + .disabled(imageManager.state != .idle) + } +} diff --git a/Mlem/App/Views/Shared/Images/Wrappers/LargeImageView.swift b/Mlem/App/Views/Shared/Images/Wrappers/LargeImageView.swift index 9081e3b78..b267b9f51 100644 --- a/Mlem/App/Views/Shared/Images/Wrappers/LargeImageView.swift +++ b/Mlem/App/Views/Shared/Images/Wrappers/LargeImageView.swift @@ -17,22 +17,29 @@ struct LargeImageView: View { let url: URL? let shouldBlur: Bool - var onTapActions: (() -> Void)? + let onTapActions: (() -> Void)? + let cornerRadius: CGFloat @State var blurred: Bool = false - init(url: URL?, shouldBlur: Bool, onTapActions: (() -> Void)? = nil) { + init( + url: URL?, + shouldBlur: Bool, + cornerRadius: CGFloat = Constants.main.mediumItemCornerRadius, + onTapActions: (() -> Void)? = nil + ) { self.url = url self.onTapActions = onTapActions self.shouldBlur = shouldBlur + self.cornerRadius = cornerRadius self._blurred = .init(wrappedValue: shouldBlur) } @State private var loading: MediaLoadingState? var body: some View { - DynamicMediaView(url: url) + DynamicMediaView(url: url, cornerRadius: cornerRadius) .dynamicBlur(blurred: blurred) - .clipShape(.rect(cornerRadius: Constants.main.mediumItemCornerRadius)) + .clipShape(.rect(cornerRadius: cornerRadius)) .overlay { NsfwOverlay(blurred: $blurred, shouldBlur: shouldBlur) } diff --git a/Mlem/App/Views/Shared/MarkdownEditorToolbarView.swift b/Mlem/App/Views/Shared/MarkdownEditorToolbarView.swift index 173012294..1c8417516 100644 --- a/Mlem/App/Views/Shared/MarkdownEditorToolbarView.swift +++ b/Mlem/App/Views/Shared/MarkdownEditorToolbarView.swift @@ -120,18 +120,9 @@ struct MarkdownEditorToolbarView: View { textView.toggleQuoteAtCursor() } if let imageUploadApi { - Menu("Image", systemImage: Icons.uploadImage) { - Button("Photo Library", systemImage: Icons.photo) { - navigation.showPhotosPicker(for: imageManager, api: imageUploadApi) - } - Button("Choose File", systemImage: "folder") { - navigation.showFilePicker(for: imageManager, api: imageUploadApi) - } - Button("Paste", systemImage: Icons.paste) { - navigation.uploadImageFromClipboard(for: imageManager, api: imageUploadApi) - } + ImageUploadMenu(imageManager: imageManager, imageUploadApi: imageUploadApi) { + Label("Image", systemImage: Icons.uploadImage) } - .disabled(imageManager.state != .idle) } Button("Spoiler", systemImage: Icons.spoiler) { textView.wrapSelectionWithSpoiler() diff --git a/Mlem/App/Views/Shared/Navigation/SettingsPage.swift b/Mlem/App/Views/Shared/Navigation/SettingsPage.swift index 1d7667512..a2af22d4f 100644 --- a/Mlem/App/Views/Shared/Navigation/SettingsPage.swift +++ b/Mlem/App/Views/Shared/Navigation/SettingsPage.swift @@ -30,8 +30,8 @@ enum SettingsPage: Hashable { case .account: AccountSettingsView() case .profile: - if let session = AppState.main.firstSession as? UserSession { - ProfileSettingsView(session: session) + if let person = AppState.main.firstPerson { + ProfileSettingsView(person: person) } else { Text(verbatim: "Error: No active user account") } diff --git a/Mlem/Localizable.xcstrings b/Mlem/Localizable.xcstrings index 4daafd11d..c86e240da 100644 --- a/Mlem/Localizable.xcstrings +++ b/Mlem/Localizable.xcstrings @@ -222,6 +222,9 @@ }, "Autoplay Media" : { + }, + "Avatar" : { + }, "Average: %@" : { @@ -243,6 +246,9 @@ }, "Banned from Instance" : { + }, + "Banner" : { + }, "Behavior" : { From b84a573c909ed9225a9026e777df433e0a2af6c1 Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:01:45 +0000 Subject: [PATCH 4/7] Update --- Mlem.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- .../Root/Tabs/Profile/Profile View.swift | 7 ++ .../Tabs/Settings/ProfileSettingsView.swift | 72 +++++++++++++++++-- 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/Mlem.xcodeproj/project.pbxproj b/Mlem.xcodeproj/project.pbxproj index 094634557..223ede56b 100644 --- a/Mlem.xcodeproj/project.pbxproj +++ b/Mlem.xcodeproj/project.pbxproj @@ -2934,8 +2934,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/mlemgroup/MlemMiddleware"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.49.0; + branch = "sjmarf/profile-settings"; + kind = branch; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3644c91b7..7d4a6fed0 100644 --- a/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -51,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mlemgroup/MlemMiddleware", "state" : { - "revision" : "0d307c21af9b588ea5583a512b312443b8fca059", - "version" : "0.49.0" + "branch" : "sjmarf/profile-settings", + "revision" : "ee8d65661e41ebd85516b92f9ef20c685111b1f7" } }, { diff --git a/Mlem/App/Views/Root/Tabs/Profile/Profile View.swift b/Mlem/App/Views/Root/Tabs/Profile/Profile View.swift index 2dda148af..b8ff71c0d 100644 --- a/Mlem/App/Views/Root/Tabs/Profile/Profile View.swift +++ b/Mlem/App/Views/Root/Tabs/Profile/Profile View.swift @@ -17,6 +17,13 @@ struct ProfileView: View { var body: some View { if let person = appState.firstPerson { PersonView(person: .init(person), isProfileTab: true) + .toolbar { + ToolbarItem(placement: .secondaryAction) { + Button("Edit", systemImage: Icons.edit) { + navigation.openSheet(.settings(.profile)) + } + } + } .id(person.actorId) } else if let instance = appState.firstSession.instance { InstanceView(instance: instance) diff --git a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift index a64e20151..0f6dacf0a 100644 --- a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift +++ b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift @@ -9,12 +9,17 @@ import MlemMiddleware import SwiftUI struct ProfileSettingsView: View { + @Environment(NavigationLayer.self) var navigation @Environment(Palette.self) var palette + @Environment(\.colorScheme) var colorScheme + @Environment(\.dismiss) var dismiss + let person: Person4 - @State var displayName: String = "" + @State var displayName: String @State var bioTextView: UITextView = .init() + @State var bioHasChanged: Bool = false @State var uploadHistory: ImageUploadHistoryManager = .init() @State var avatarUrl: URL? @@ -23,9 +28,11 @@ struct ProfileSettingsView: View { @State var bannerUrl: URL? @State var bannerManager: ImageUploadManager = .init() + @State var isSubmitting: Bool = false + init(person: Person4) { self.person = person - self.displayName = person.displayName == person.name ? "" : person.displayName + self._displayName = .init(wrappedValue: person.displayName == person.name ? "" : person.displayName) bioTextView.text = person.description ?? "" self._avatarUrl = .init(wrappedValue: person.avatar) self._bannerUrl = .init(wrappedValue: person.banner) @@ -39,12 +46,15 @@ struct ProfileSettingsView: View { Form { Section("Display Name") { TextField("Display Name", text: $displayName, prompt: Text(person.name)) + .autocorrectionDisabled() + .textInputAutocapitalization(.never) } footer: { Text("The name that is displayed on your profile. This is not the same as your username, which cannot be changed.") } Section("Biography") { MarkdownTextEditor( - onChange: { _ in + onChange: { newValue in + bioHasChanged = (person.description ?? "") != newValue }, prompt: "Write a bit about yourself...", textView: bioTextView, @@ -76,7 +86,44 @@ struct ProfileSettingsView: View { bannerSection } .navigationTitle("My Profile") + .navigationBarTitleDisplayMode(.inline) .scrollDismissesKeyboard(.interactively) + .navigationBarBackButtonHidden(showToolbarOptions) + .interactiveDismissDisabled(showToolbarOptions) + .toolbar { + if showToolbarOptions { + ToolbarItem(placement: .topBarLeading) { + Button("Cancel") { + displayName = person.displayName == person.name ? "" : person.displayName + bioTextView.text = person.description ?? "" + bioHasChanged = false + avatarUrl = person.avatar + bannerUrl = person.banner + } + .disabled(isSubmitting) + } + ToolbarItem(placement: .topBarTrailing) { + if isSubmitting { + ProgressView() + } else { + Button("Save") { + Task { @MainActor in + await submit() + } + } + } + } + } else if navigation.isInsideSheet { + ToolbarItem(placement: .topBarTrailing) { + CloseButtonView() + } + } + } + } + + var showToolbarOptions: Bool { + let originalDisplayName = (person.displayName == person.name) ? "" : person.displayName + return bioHasChanged || displayName != originalDisplayName || avatarUrl != person.avatar || bannerUrl != person.banner } @ViewBuilder @@ -106,7 +153,7 @@ struct ProfileSettingsView: View { .frame(height: 150) .clipped() } else { - palette.tertiaryGroupedBackground + palette.secondary.opacity(0.5) .frame(height: 150) } HStack(spacing: 15) { @@ -123,6 +170,23 @@ struct ProfileSettingsView: View { } .listRowInsets(.init()) } + + @MainActor + func submit() async { + isSubmitting = true + do { + try await person.updateProfile( + displayName: displayName.isEmpty ? nil : displayName, + description: bioTextView.text.isEmpty ? nil : bioTextView.text, + avatar: avatarUrl, + banner: bannerUrl + ) + dismiss() + } catch { + handleError(error) + } + isSubmitting = false + } } private struct CircleImageUploadButton: View { From 5949babb3879f795afbbfd1c7017254444752fe7 Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Sun, 8 Dec 2024 18:18:38 +0000 Subject: [PATCH 5/7] Create Package.resolved --- .../xcshareddata/swiftpm/Package.resolved | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..7d4a6fed0 --- /dev/null +++ b/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,168 @@ +{ + "originHash" : "e91c2cec61691543665fad5843f30eafc5288bb40fc3a60d50c7d7e9194f3135", + "pins" : [ + { + "identity" : "combine-schedulers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/combine-schedulers", + "state" : { + "revision" : "ec62f32d21584214a4b27c8cee2b2ad70ab2c38a", + "version" : "0.11.0" + } + }, + { + "identity" : "gifu", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kaishin/Gifu", + "state" : { + "branch" : "master", + "revision" : "639e40d5dbd86dfa94fc61296c270b49af6f8a2a" + } + }, + { + "identity" : "keychainaccess", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", + "state" : { + "branch" : "master", + "revision" : "e0c7eebc5a4465a3c4680764f26b7a61f567cdaf" + } + }, + { + "identity" : "lemmymarkdownui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mlemgroup/LemmyMarkdownUI", + "state" : { + "revision" : "b42b1e301194fd56a144cf199ab2b807a0413a97", + "version" : "0.5.2" + } + }, + { + "identity" : "libwebp-xcode", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/libwebp-Xcode.git", + "state" : { + "revision" : "b2b1d20a90b14d11f6ef4241da6b81c1d3f171e4", + "version" : "1.3.2" + } + }, + { + "identity" : "mlemmiddleware", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mlemgroup/MlemMiddleware", + "state" : { + "branch" : "sjmarf/profile-settings", + "revision" : "ee8d65661e41ebd85516b92f9ef20c685111b1f7" + } + }, + { + "identity" : "nuke", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kean/Nuke", + "state" : { + "revision" : "0ead44350d2737db384908569c012fe67c421e4d", + "version" : "12.8.0" + } + }, + { + "identity" : "sdwebimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImage.git", + "state" : { + "revision" : "8a1be70a625683bc04d6903e2935bf23f3c6d609", + "version" : "5.19.7" + } + }, + { + "identity" : "sdwebimageswiftui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImageSwiftUI", + "state" : { + "revision" : "5aa947356f4ea49a0c3b9968564267f6ea5abea7", + "version" : "3.1.2" + } + }, + { + "identity" : "sdwebimagewebpcoder", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImageWebPCoder", + "state" : { + "revision" : "f534cfe830a7807ecc3d0332127a502426cfa067", + "version" : "0.14.6" + } + }, + { + "identity" : "semaphore", + "kind" : "remoteSourceControl", + "location" : "https://github.com/groue/Semaphore", + "state" : { + "revision" : "2543679282aa6f6c8ecf2138acd613ed20790bc2", + "version" : "0.1.0" + } + }, + { + "identity" : "swift-clocks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-clocks", + "state" : { + "revision" : "0fbaebfc013715dab44d715a4d350ba37f297e4d", + "version" : "0.4.0" + } + }, + { + "identity" : "swift-concurrency-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-concurrency-extras", + "state" : { + "revision" : "a46265bb4f75808b0e15d971eebc408f557870a3", + "version" : "0.1.2" + } + }, + { + "identity" : "swift-dependencies", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-dependencies", + "state" : { + "revision" : "16fd42ae04c6e7f74a6a86395d04722c641cccee", + "version" : "0.6.0" + } + }, + { + "identity" : "swiftui-flow", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tevelee/SwiftUI-Flow", + "state" : { + "revision" : "b528bd06ae70fbd2936d9561a456fb6ea65bc7ff", + "version" : "2.5.0" + } + }, + { + "identity" : "swiftui-introspect", + "kind" : "remoteSourceControl", + "location" : "https://github.com/siteline/SwiftUI-Introspect", + "state" : { + "revision" : "807f73ce09a9b9723f12385e592b4e0aaebd3336", + "version" : "1.3.0" + } + }, + { + "identity" : "swiftyjson", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftyJSON/SwiftyJSON.git", + "state" : { + "revision" : "2b6054efa051565954e1d2b9da831680026cd768", + "version" : "4.3.0" + } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "50843cbb8551db836adec2290bb4bc6bac5c1865", + "version" : "0.9.0" + } + } + ], + "version" : 3 +} From eae6b63b7a3d482e58e44b5710fb5350dda296e8 Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:52:09 +0000 Subject: [PATCH 6/7] Update --- Mlem.xcodeproj/project.pbxproj | 14 +- .../xcshareddata/swiftpm/Package.resolved | 168 ++++++++++++++++++ 2 files changed, 171 insertions(+), 11 deletions(-) create mode 100644 Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Mlem.xcodeproj/project.pbxproj b/Mlem.xcodeproj/project.pbxproj index 11d38ca68..48484e0d1 100644 --- a/Mlem.xcodeproj/project.pbxproj +++ b/Mlem.xcodeproj/project.pbxproj @@ -195,9 +195,9 @@ 03AB48552CBC0B8000567FF9 /* AccountAdvancedSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AB48542CBC0B8000567FF9 /* AccountAdvancedSettingsView.swift */; }; 03AB48572CBC0DFC00567FF9 /* AccountSignInSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AB48562CBC0DFC00567FF9 /* AccountSignInSettingsView.swift */; }; 03AB48592CBC14CE00567FF9 /* AccountEmailSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AB48582CBC14CE00567FF9 /* AccountEmailSettingsView.swift */; }; + 03AD09E82CF88007001EF9F7 /* MoreRepliesButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AD09E72CF88007001EF9F7 /* MoreRepliesButton.swift */; }; 03AD0A822CFDBFA0001EF9F7 /* AccountLocalSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AD0A812CFDBFA0001EF9F7 /* AccountLocalSettingsView.swift */; }; 03AD0A842CFDC557001EF9F7 /* AccountNicknameFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AD0A832CFDC557001EF9F7 /* AccountNicknameFieldView.swift */; }; - 03AD09E82CF88007001EF9F7 /* MoreRepliesButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AD09E72CF88007001EF9F7 /* MoreRepliesButton.swift */; }; 03AF91DD2C1B23E500E56644 /* ImageViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AF91DC2C1B23E500E56644 /* ImageViewer.swift */; }; 03AF91DF2C1B243D00E56644 /* ZoomableContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AF91DE2C1B243D00E56644 /* ZoomableContainer.swift */; }; 03AF91E12C1B25DE00E56644 /* UIDevice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AF91E02C1B25DE00E56644 /* UIDevice+Extensions.swift */; }; @@ -614,9 +614,9 @@ 03AB48542CBC0B8000567FF9 /* AccountAdvancedSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountAdvancedSettingsView.swift; sourceTree = "<group>"; }; 03AB48562CBC0DFC00567FF9 /* AccountSignInSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSignInSettingsView.swift; sourceTree = "<group>"; }; 03AB48582CBC14CE00567FF9 /* AccountEmailSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountEmailSettingsView.swift; sourceTree = "<group>"; }; + 03AD09E72CF88007001EF9F7 /* MoreRepliesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreRepliesButton.swift; sourceTree = "<group>"; }; 03AD0A812CFDBFA0001EF9F7 /* AccountLocalSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLocalSettingsView.swift; sourceTree = "<group>"; }; 03AD0A832CFDC557001EF9F7 /* AccountNicknameFieldView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountNicknameFieldView.swift; sourceTree = "<group>"; }; - 03AD09E72CF88007001EF9F7 /* MoreRepliesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreRepliesButton.swift; sourceTree = "<group>"; }; 03AF91DC2C1B23E500E56644 /* ImageViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewer.swift; sourceTree = "<group>"; }; 03AF91DE2C1B243D00E56644 /* ZoomableContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableContainer.swift; sourceTree = "<group>"; }; 03AF91E02C1B25DE00E56644 /* UIDevice+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Extensions.swift"; sourceTree = "<group>"; }; @@ -2927,7 +2927,7 @@ repositoryURL = "https://github.com/mlemgroup/MlemMiddleware"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.51.0; + minimumVersion = 0.52.0; }; }; CDE4AC402CA3706400981010 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */ = { @@ -2946,14 +2946,6 @@ minimumVersion = 0.14.6; }; }; - CDFA5CAE2CEAB8AF00FDF998 /* XCRemoteSwiftPackageReference "MlemMiddleware" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/mlemgroup/MlemMiddleware"; - requirement = { - branch = "sjmarf/profile-settings"; - kind = branch; - }; - }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ diff --git a/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..53c8be7e0 --- /dev/null +++ b/Mlem.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,168 @@ +{ + "originHash" : "e91c2cec61691543665fad5843f30eafc5288bb40fc3a60d50c7d7e9194f3135", + "pins" : [ + { + "identity" : "combine-schedulers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/combine-schedulers", + "state" : { + "revision" : "ec62f32d21584214a4b27c8cee2b2ad70ab2c38a", + "version" : "0.11.0" + } + }, + { + "identity" : "gifu", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kaishin/Gifu", + "state" : { + "branch" : "master", + "revision" : "639e40d5dbd86dfa94fc61296c270b49af6f8a2a" + } + }, + { + "identity" : "keychainaccess", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", + "state" : { + "branch" : "master", + "revision" : "e0c7eebc5a4465a3c4680764f26b7a61f567cdaf" + } + }, + { + "identity" : "lemmymarkdownui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mlemgroup/LemmyMarkdownUI", + "state" : { + "revision" : "b42b1e301194fd56a144cf199ab2b807a0413a97", + "version" : "0.5.2" + } + }, + { + "identity" : "libwebp-xcode", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/libwebp-Xcode.git", + "state" : { + "revision" : "b2b1d20a90b14d11f6ef4241da6b81c1d3f171e4", + "version" : "1.3.2" + } + }, + { + "identity" : "mlemmiddleware", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mlemgroup/MlemMiddleware", + "state" : { + "revision" : "51db2875046e216fb01c8233cc43eadd147dd240", + "version" : "0.52.0" + } + }, + { + "identity" : "nuke", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kean/Nuke", + "state" : { + "revision" : "0ead44350d2737db384908569c012fe67c421e4d", + "version" : "12.8.0" + } + }, + { + "identity" : "sdwebimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImage.git", + "state" : { + "revision" : "8a1be70a625683bc04d6903e2935bf23f3c6d609", + "version" : "5.19.7" + } + }, + { + "identity" : "sdwebimageswiftui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImageSwiftUI", + "state" : { + "revision" : "5aa947356f4ea49a0c3b9968564267f6ea5abea7", + "version" : "3.1.2" + } + }, + { + "identity" : "sdwebimagewebpcoder", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImageWebPCoder", + "state" : { + "revision" : "f534cfe830a7807ecc3d0332127a502426cfa067", + "version" : "0.14.6" + } + }, + { + "identity" : "semaphore", + "kind" : "remoteSourceControl", + "location" : "https://github.com/groue/Semaphore", + "state" : { + "revision" : "2543679282aa6f6c8ecf2138acd613ed20790bc2", + "version" : "0.1.0" + } + }, + { + "identity" : "swift-clocks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-clocks", + "state" : { + "revision" : "0fbaebfc013715dab44d715a4d350ba37f297e4d", + "version" : "0.4.0" + } + }, + { + "identity" : "swift-concurrency-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-concurrency-extras", + "state" : { + "revision" : "a46265bb4f75808b0e15d971eebc408f557870a3", + "version" : "0.1.2" + } + }, + { + "identity" : "swift-dependencies", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-dependencies", + "state" : { + "revision" : "16fd42ae04c6e7f74a6a86395d04722c641cccee", + "version" : "0.6.0" + } + }, + { + "identity" : "swiftui-flow", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tevelee/SwiftUI-Flow", + "state" : { + "revision" : "b528bd06ae70fbd2936d9561a456fb6ea65bc7ff", + "version" : "2.5.0" + } + }, + { + "identity" : "swiftui-introspect", + "kind" : "remoteSourceControl", + "location" : "https://github.com/siteline/SwiftUI-Introspect", + "state" : { + "revision" : "807f73ce09a9b9723f12385e592b4e0aaebd3336", + "version" : "1.3.0" + } + }, + { + "identity" : "swiftyjson", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftyJSON/SwiftyJSON.git", + "state" : { + "revision" : "2b6054efa051565954e1d2b9da831680026cd768", + "version" : "4.3.0" + } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "50843cbb8551db836adec2290bb4bc6bac5c1865", + "version" : "0.9.0" + } + } + ], + "version" : 3 +} From 28c1103299bcf091b351e2269b939973ba5d94cf Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:54:13 +0000 Subject: [PATCH 7/7] Implement requested changes --- Mlem/App/Configuration/Icons.swift | 2 ++ .../App/Views/Pages/PostEditor/PostEditorView+ImageView.swift | 2 +- Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift | 4 ++-- Mlem/App/Views/Shared/ImageUploadMenu.swift | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Mlem/App/Configuration/Icons.swift b/Mlem/App/Configuration/Icons.swift index 472fdf4a1..d5b61bd68 100644 --- a/Mlem/App/Configuration/Icons.swift +++ b/Mlem/App/Configuration/Icons.swift @@ -201,6 +201,7 @@ enum Icons { static let close: String = "multiply" static let closeCircle: String = "xmark.circle" static let closeCircleFill: String = "xmark.circle.fill" + static let addCircleFill: String = "plus.circle.fill" static let cakeDay: String = "birthday.cake" static let cakeDayFill: String = "birthday.cake.fill" static let undoCircleFill: String = "arrow.uturn.backward.circle.fill" @@ -246,6 +247,7 @@ enum Icons { static let refresh: String = "arrow.clockwise" static let select: String = "selection.pin.in.out" static let crossPost: String = "shuffle" + static let chooseFile: String = "folder" // settings static let upvoteOnSave: String = "arrow.up.heart" diff --git a/Mlem/App/Views/Pages/PostEditor/PostEditorView+ImageView.swift b/Mlem/App/Views/Pages/PostEditor/PostEditorView+ImageView.swift index afa542ebf..5c8480433 100644 --- a/Mlem/App/Views/Pages/PostEditor/PostEditorView+ImageView.swift +++ b/Mlem/App/Views/Pages/PostEditor/PostEditorView+ImageView.swift @@ -91,7 +91,7 @@ extension PostEditorView { guard let imageManager else { return } navigation.showPhotosPicker(for: imageManager, api: primaryApi) } - Button("Files", systemImage: "folder") { + Button("Files", systemImage: Icons.chooseFile) { guard let imageManager else { return } navigation.showFilePicker(for: imageManager, api: primaryApi) } diff --git a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift index 0f6dacf0a..bda4eb8d4 100644 --- a/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift +++ b/Mlem/App/Views/Root/Tabs/Settings/ProfileSettingsView.swift @@ -200,7 +200,7 @@ private struct CircleImageUploadButton: View { Button { url = nil } label: { - Image(systemName: "xmark.circle.fill") + Image(systemName: Icons.closeCircleFill) .resizable() } } else { @@ -210,7 +210,7 @@ private struct CircleImageUploadButton: View { .controlSize(.extraLarge) default: ImageUploadMenu(imageManager: imageManager, imageUploadApi: api) { - Image(systemName: "plus.circle.fill") + Image(systemName: Icons.addCircleFill) .resizable() } } diff --git a/Mlem/App/Views/Shared/ImageUploadMenu.swift b/Mlem/App/Views/Shared/ImageUploadMenu.swift index 579a2bd61..2f3649f8b 100644 --- a/Mlem/App/Views/Shared/ImageUploadMenu.swift +++ b/Mlem/App/Views/Shared/ImageUploadMenu.swift @@ -26,7 +26,7 @@ struct ImageUploadMenu<Label: View>: View { Button("Photo Library", systemImage: Icons.photo) { navigation.showPhotosPicker(for: imageManager, api: imageUploadApi) } - Button("Choose File", systemImage: "folder") { + Button("Choose File", systemImage: Icons.chooseFile) { navigation.showFilePicker(for: imageManager, api: imageUploadApi) } Button("Paste", systemImage: Icons.paste) {