From 0e7083539df52034f002f8db697c802b2a434fc5 Mon Sep 17 00:00:00 2001 From: Fabian Thies Date: Mon, 12 Dec 2022 19:18:57 +0100 Subject: [PATCH] [ADD] Search bar for BrowseView on iOS 15 --- AltStore/Extensions/StoreApp+Filterable.swift | 17 +++++++++ AltStore/Protocols/Filterable.swift | 23 ++++++++++++ AltStore/View Extensions/Modifiers.swift | 29 +++++++++++++++ .../Views/Browse/BrowseAppPreviewView.swift | 2 +- AltStore/Views/Browse/BrowseView.swift | 35 ++----------------- 5 files changed, 73 insertions(+), 33 deletions(-) create mode 100644 AltStore/Extensions/StoreApp+Filterable.swift create mode 100644 AltStore/Protocols/Filterable.swift create mode 100644 AltStore/View Extensions/Modifiers.swift diff --git a/AltStore/Extensions/StoreApp+Filterable.swift b/AltStore/Extensions/StoreApp+Filterable.swift new file mode 100644 index 00000000..9b228b36 --- /dev/null +++ b/AltStore/Extensions/StoreApp+Filterable.swift @@ -0,0 +1,17 @@ +// +// StoreApp+Searchable.swift +// SideStore +// +// Created by Fabian Thies on 01.12.22. +// Copyright © 2022 SideStore. All rights reserved. +// + +import AltStoreCore + +extension StoreApp: Filterable { + func matches(_ searchText: String) -> Bool { + searchText.isEmpty || + self.name.lowercased().contains(searchText.lowercased()) || + self.developerName.lowercased().contains(searchText.lowercased()) + } +} diff --git a/AltStore/Protocols/Filterable.swift b/AltStore/Protocols/Filterable.swift new file mode 100644 index 00000000..b5051799 --- /dev/null +++ b/AltStore/Protocols/Filterable.swift @@ -0,0 +1,23 @@ +// +// Filterable.swift +// SideStore +// +// Created by Fabian Thies on 01.12.22. +// Copyright © 2022 SideStore. All rights reserved. +// + +import Foundation + +protocol Filterable { + func matches(_ searchText: String) -> Bool +} + +extension Collection where Element: Filterable { + func matches(_ searchText: String) -> Bool { + self.contains(where: { $0.matches(searchText) }) + } + + func items(matching searchText: String) -> [Element] { + self.filter { $0.matches(searchText) } + } +} diff --git a/AltStore/View Extensions/Modifiers.swift b/AltStore/View Extensions/Modifiers.swift new file mode 100644 index 00000000..a4eb06ac --- /dev/null +++ b/AltStore/View Extensions/Modifiers.swift @@ -0,0 +1,29 @@ +// +// Modifiers.swift +// SideStore +// +// Created by Fabian Thies on 01.12.22. +// Copyright © 2022 SideStore. All rights reserved. +// + +import SwiftUI + +extension View { + + @ViewBuilder func `if`(_ condition: Bool, transform: (Self) -> Content) -> some View { + if condition { + transform(self) + } else { + self + } + } + + + @ViewBuilder func searchable(text: Binding, placeholder: String) -> some View { + if #available(iOS 15.0, *) { + self.searchable(text: text, prompt: Text(placeholder)) + } else { + self + } + } +} diff --git a/AltStore/Views/Browse/BrowseAppPreviewView.swift b/AltStore/Views/Browse/BrowseAppPreviewView.swift index da714c77..8df2cd84 100644 --- a/AltStore/Views/Browse/BrowseAppPreviewView.swift +++ b/AltStore/Views/Browse/BrowseAppPreviewView.swift @@ -14,7 +14,7 @@ struct BrowseAppPreviewView: View { let storeApp: StoreApp var body: some View { - VStack { + VStack(spacing: 16) { AppRowView(app: storeApp) if let subtitle = storeApp.subtitle { diff --git a/AltStore/Views/Browse/BrowseView.swift b/AltStore/Views/Browse/BrowseView.swift index b8b261bc..cd9fbba2 100644 --- a/AltStore/Views/Browse/BrowseView.swift +++ b/AltStore/Views/Browse/BrowseView.swift @@ -15,11 +15,11 @@ struct BrowseView: View { NSSortDescriptor(keyPath: \StoreApp.sortIndex, ascending: true), NSSortDescriptor(keyPath: \StoreApp.name, ascending: true), NSSortDescriptor(keyPath: \StoreApp.bundleIdentifier, ascending: true) - ]/*, predicate: NSPredicate(format: "%K != %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID)*/) + ], predicate: NSPredicate(format: "%K != %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID)) var apps: FetchedResults var filteredApps: [StoreApp] { - apps.filter { $0.matches(self.searchText) } + apps.items(matching: self.searchText) } @State @@ -31,7 +31,7 @@ struct BrowseView: View { var body: some View { ScrollView { - LazyVStack(spacing: 24) { + LazyVStack(spacing: 32) { ForEach(filteredApps, id: \.bundleIdentifier) { app in NavigationLink { AppDetailView(storeApp: app) @@ -68,32 +68,3 @@ struct BrowseView_Previews: PreviewProvider { BrowseView() } } - - -extension StoreApp { - func matches(_ searchText: String) -> Bool { - searchText.isEmpty || - self.name.lowercased().contains(searchText.lowercased()) || - self.developerName.lowercased().contains(searchText.lowercased()) - } -} - -extension View { - - @ViewBuilder func `if`(_ condition: Bool, transform: (Self) -> Content) -> some View { - if condition { - transform(self) - } else { - self - } - } - - - @ViewBuilder func searchable(text: Binding, placeholder: String) -> some View { - if #available(iOS 15.0, *) { - self.searchable(text: text, prompt: Text(placeholder)) - } else { - self - } - } -}