diff --git a/Mlem.xcodeproj/project.pbxproj b/Mlem.xcodeproj/project.pbxproj index 516a22e92..2b2bfe306 100644 --- a/Mlem.xcodeproj/project.pbxproj +++ b/Mlem.xcodeproj/project.pbxproj @@ -330,9 +330,9 @@ CD18DC6F2A5209C3002C56BC /* MarkPrivateMessageAsReadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD18DC6E2A5209C3002C56BC /* MarkPrivateMessageAsReadRequest.swift */; }; CD18DC732A522A7C002C56BC /* CreatePrivateMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD18DC722A522A7C002C56BC /* CreatePrivateMessageRequest.swift */; }; CD2053102AC878B50000AA38 /* UpdatedTimestampView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD20530F2AC878B50000AA38 /* UpdatedTimestampView.swift */; }; + CD2053122ACB72190000AA38 /* AccountTransitionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2053112ACB72190000AA38 /* AccountTransitionView.swift */; }; CD2053142ACBAF150000AA38 /* AvatarType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2053132ACBAF150000AA38 /* AvatarType.swift */; }; CD2053172ACBBB5A0000AA38 /* DefaultAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2053162ACBBB5A0000AA38 /* DefaultAvatarView.swift */; }; - CD2053122ACB72190000AA38 /* AccountTransitionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2053112ACB72190000AA38 /* AccountTransitionView.swift */; }; CD2BD6782A79F55800ECFF89 /* ImageSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2BD6772A79F55800ECFF89 /* ImageSize.swift */; }; CD2E182B2A3B708500224F8A /* Settings Options.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2E182A2A3B708500224F8A /* Settings Options.swift */; }; CD309C462A93FBD300988F95 /* Logo View.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD309C452A93FBD300988F95 /* Logo View.swift */; }; @@ -818,9 +818,9 @@ CD18DC6E2A5209C3002C56BC /* MarkPrivateMessageAsReadRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkPrivateMessageAsReadRequest.swift; sourceTree = ""; }; CD18DC722A522A7C002C56BC /* CreatePrivateMessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePrivateMessageRequest.swift; sourceTree = ""; }; CD20530F2AC878B50000AA38 /* UpdatedTimestampView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatedTimestampView.swift; sourceTree = ""; }; + CD2053112ACB72190000AA38 /* AccountTransitionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTransitionView.swift; sourceTree = ""; }; CD2053132ACBAF150000AA38 /* AvatarType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarType.swift; sourceTree = ""; }; CD2053162ACBBB5A0000AA38 /* DefaultAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultAvatarView.swift; sourceTree = ""; }; - CD2053112ACB72190000AA38 /* AccountTransitionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTransitionView.swift; sourceTree = ""; }; CD2BD6772A79F55800ECFF89 /* ImageSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageSize.swift; sourceTree = ""; }; CD2E182A2A3B708500224F8A /* Settings Options.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Settings Options.swift"; sourceTree = ""; }; CD309C452A93FBD300988F95 /* Logo View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Logo View.swift"; sourceTree = ""; }; @@ -1098,6 +1098,15 @@ path = User; sourceTree = ""; }; + 030D00832AD0842900953B1D /* Results */ = { + isa = PBXGroup; + children = ( + 03EEEAF22AB8DCDF0087F8D8 /* CommunityResultView.swift */, + 03B7AAF42ABEFA7A00068B23 /* UserResultView.swift */, + ); + path = Results; + sourceTree = ""; + }; 030E86422AC6F6CB000283A6 /* Search Bar */ = { isa = PBXGroup; children = ( @@ -1960,8 +1969,7 @@ 03EC92942AC064AE007BBE7E /* SearchHomeView.swift */, 036ED3BB2ABF1058009664BC /* SearchModel.swift */, 03EEEAF62AB8ED3C0087F8D8 /* SearchTabPicker.swift */, - 03EEEAF22AB8DCDF0087F8D8 /* CommunityResultView.swift */, - 03B7AAF42ABEFA7A00068B23 /* UserResultView.swift */, + 030D00832AD0842900953B1D /* Results */, ); path = Search; sourceTree = ""; diff --git a/Mlem/Extensions/Swipey Actions.swift b/Mlem/Extensions/Swipey Actions.swift index b58099bd6..b077631da 100644 --- a/Mlem/Extensions/Swipey Actions.swift +++ b/Mlem/Extensions/Swipey Actions.swift @@ -363,4 +363,11 @@ extension View { ) ) } + + @ViewBuilder + func addSwipeyActions(_ configuration: SwipeConfiguration) -> some View { + modifier( + SwipeyView(configuration: configuration) + ) + } } diff --git a/Mlem/Models/Trackers/RecentSearchesTracker.swift b/Mlem/Models/Trackers/RecentSearchesTracker.swift index 26fc495bf..72af815ec 100644 --- a/Mlem/Models/Trackers/RecentSearchesTracker.swift +++ b/Mlem/Models/Trackers/RecentSearchesTracker.swift @@ -61,6 +61,13 @@ class RecentSearchesTracker: ObservableObject { saveRecentSearches(accountId: accountId) } + func removeRecentSearch(_ item: AnyContentModel, accountId: String?) { + if let index = recentSearches.firstIndex(of: item) { + recentSearches.remove(at: index) + } + saveRecentSearches(accountId: accountId) + } + func clearRecentSearches(accountId: String?) { recentSearches.removeAll() saveRecentSearches(accountId: accountId) diff --git a/Mlem/Views/Tabs/Search/RecentSearchesView.swift b/Mlem/Views/Tabs/Search/RecentSearchesView.swift index d14dd36ab..cb96aaa1a 100644 --- a/Mlem/Views/Tabs/Search/RecentSearchesView.swift +++ b/Mlem/Views/Tabs/Search/RecentSearchesView.swift @@ -12,6 +12,16 @@ struct RecentSearchesView: View { @EnvironmentObject var recentSearchesTracker: RecentSearchesTracker @StateObject var contentTracker: ContentTracker = .init() + func deleteSwipeAction(_ item: AnyContentModel) -> SwipeAction { + return SwipeAction( + symbol: .init(emptyName: Icons.close, fillName: Icons.close), + color: .red, + action: { + recentSearchesTracker.removeRecentSearch(item, accountId: appState.currentActiveAccount?.stableIdString) + } + ) + } + var body: some View { Group { if !recentSearchesTracker.recentSearches.isEmpty { @@ -62,9 +72,17 @@ struct RecentSearchesView: View { ForEach(contentTracker.items, id: \.uid) { contentModel in Group { if let community = contentModel.wrappedValue as? CommunityModel { - CommunityResultView(community: community, showTypeLabel: true) + CommunityResultView( + community: community, + showTypeLabel: true, + swipeActions: .init(trailingActions: [deleteSwipeAction(contentModel)]) + ) } else if let user = contentModel.wrappedValue as? UserModel { - UserResultView(user: user, showTypeLabel: true) + UserResultView( + user: user, + showTypeLabel: true, + swipeActions: .init(trailingActions: [deleteSwipeAction(contentModel)]) + ) } } .simultaneousGesture(TapGesture().onEnded { diff --git a/Mlem/Views/Tabs/Search/CommunityResultView.swift b/Mlem/Views/Tabs/Search/Results/CommunityResultView.swift similarity index 96% rename from Mlem/Views/Tabs/Search/CommunityResultView.swift rename to Mlem/Views/Tabs/Search/Results/CommunityResultView.swift index 800c79c76..fa8cf3c7f 100644 --- a/Mlem/Views/Tabs/Search/CommunityResultView.swift +++ b/Mlem/Views/Tabs/Search/Results/CommunityResultView.swift @@ -13,9 +13,11 @@ struct CommunityResultView: View { @Dependency(\.hapticManager) var hapticManager @EnvironmentObject var contentTracker: ContentTracker + let community: CommunityModel let showTypeLabel: Bool - + var swipeActions: SwipeConfiguration? + var subscribeSwipeAction: SwipeAction { let (emptySymbolName, fullSymbolName) = community.subscribed ? (Icons.unsubscribePerson, Icons.unsubscribePersonFill) @@ -82,7 +84,6 @@ struct CommunityResultView: View { .buttonStyle(.plain) .padding(.vertical, 8) .background(.background) - .addSwipeyActions(trailing: [subscribeSwipeAction]) .draggable(community.community.actorId) { HStack { AvatarView(community: community.community, avatarSize: 24) @@ -101,5 +102,6 @@ struct CommunityResultView: View { systemImage: community.subscribed ? Icons.unsubscribe : Icons.subscribe) } } + .addSwipeyActions(swipeActions ?? .init(trailingActions: [subscribeSwipeAction])) } } diff --git a/Mlem/Views/Tabs/Search/UserResultView.swift b/Mlem/Views/Tabs/Search/Results/UserResultView.swift similarity index 97% rename from Mlem/Views/Tabs/Search/UserResultView.swift rename to Mlem/Views/Tabs/Search/Results/UserResultView.swift index 7385c75b2..346889b29 100644 --- a/Mlem/Views/Tabs/Search/UserResultView.swift +++ b/Mlem/Views/Tabs/Search/Results/UserResultView.swift @@ -13,8 +13,10 @@ struct UserResultView: View { @Dependency(\.hapticManager) var hapticManager @EnvironmentObject var contentTracker: ContentTracker + let user: UserModel let showTypeLabel: Bool + var swipeActions: SwipeConfiguration? var caption: String { if let host = user.user.actorId.host { @@ -87,5 +89,6 @@ struct UserResultView: View { .background(.background) .clipShape(RoundedRectangle(cornerRadius: 8)) } + .addSwipeyActions(swipeActions ?? .init()) } } diff --git a/Mlem/Views/Tabs/Search/SearchTabPicker.swift b/Mlem/Views/Tabs/Search/SearchTabPicker.swift index b61f3afec..9f0067c23 100644 --- a/Mlem/Views/Tabs/Search/SearchTabPicker.swift +++ b/Mlem/Views/Tabs/Search/SearchTabPicker.swift @@ -51,7 +51,7 @@ struct SearchTabPicker: View { } } ) - .animation(.spring(response: 0.15, dampingFraction: 0.825), value: selected) + .animation(.spring(response: 0.15, dampingFraction: 0.7), value: selected) } .buttonStyle(EmptyButtonStyle()) }