diff --git a/ownCloud.xcodeproj/project.pbxproj b/ownCloud.xcodeproj/project.pbxproj index 7821a9bb4..b1003649c 100644 --- a/ownCloud.xcodeproj/project.pbxproj +++ b/ownCloud.xcodeproj/project.pbxproj @@ -295,6 +295,7 @@ DC2A68D529D492B300BFF393 /* space.tvg in Resources */ = {isa = PBXBuildFile; fileRef = DC2A68D429D492B200BFF393 /* space.tvg */; }; DC2A68D729D4E93300BFF393 /* SharedKeyCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2A68D629D4E93300BFF393 /* SharedKeyCommands.swift */; }; DC2A8E6A2B57EA8F001F0522 /* AccountControllerSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2A8E692B57EA8F001F0522 /* AccountControllerSearchViewController.swift */; }; + DC2BB5402CD96C1600320384 /* ServerSideSearchScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2BB53F2CD96C1600320384 /* ServerSideSearchScope.swift */; }; DC36885824DC98BF00333600 /* OCFileProviderServiceSession.h in Headers */ = {isa = PBXBuildFile; fileRef = DC36885624DC98BF00333600 /* OCFileProviderServiceSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC36885924DC98BF00333600 /* OCFileProviderServiceSession.m in Sources */ = {isa = PBXBuildFile; fileRef = DC36885724DC98BF00333600 /* OCFileProviderServiceSession.m */; }; DC36885D24DD916800333600 /* ownCloudApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC0855C2293F1FD008CC05C /* ownCloudApp.framework */; }; @@ -1287,6 +1288,7 @@ DC2A68D429D492B200BFF393 /* space.tvg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = space.tvg; path = "img/filetypes-tvg/space.tvg"; sourceTree = SOURCE_ROOT; }; DC2A68D629D4E93300BFF393 /* SharedKeyCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedKeyCommands.swift; sourceTree = ""; }; DC2A8E692B57EA8F001F0522 /* AccountControllerSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountControllerSearchViewController.swift; sourceTree = ""; }; + DC2BB53F2CD96C1600320384 /* ServerSideSearchScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSideSearchScope.swift; sourceTree = ""; }; DC321260207EB01B00DB171D /* ThemeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeImage.swift; sourceTree = ""; }; DC3393A722E0C4ED00DD3DA4 /* icon-available-offline.tvg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "icon-available-offline.tvg"; path = "../img/filetypes-tvg/icon-available-offline.tvg"; sourceTree = ""; }; DC36885624DC98BF00333600 /* OCFileProviderServiceSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCFileProviderServiceSession.h; sourceTree = ""; }; @@ -2452,6 +2454,7 @@ DC24E10628B7BFD6002E4F5B /* ItemSearchScope.swift */, DC24E10A28B7C185002E4F5B /* SingleFolderSearchScope.swift */, DC24E10C28B7C19F002E4F5B /* AccountSearchScope.swift */, + DC2BB53F2CD96C1600320384 /* ServerSideSearchScope.swift */, ); path = Scopes; sourceTree = ""; @@ -4720,6 +4723,7 @@ files = ( DC0A357E24C0E43C00FB58FC /* ThemeStyle+Extensions.swift in Sources */, DCB1B8C829C8F84800BFF393 /* ThemeCSSProgressView.swift in Sources */, + DC2BB5402CD96C1600320384 /* ServerSideSearchScope.swift in Sources */, DC04FFC827F5B79000F22569 /* CollectionViewController.swift in Sources */, DC298CA72936250D009FA87F /* ClientSidebarViewController.swift in Sources */, DC825E352A05083C00BFF393 /* GitInfo.swift in Sources */, diff --git a/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCItem+UniversalItemListCellContentProvider.swift b/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCItem+UniversalItemListCellContentProvider.swift index 8106ddec5..8c566a7cb 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCItem+UniversalItemListCellContentProvider.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCItem+UniversalItemListCellContentProvider.swift @@ -177,6 +177,14 @@ extension OCItem: UniversalItemListCellContentProvider { // Details var detailItems: [SegmentViewItem] = [] + if configuration?.style.showPathDetails == true { + // - path breadcrumbs for style.showPathDetails == true + if let context, let parentLocation = location?.parent { + detailItems = OCLocation.composeSegments(breadcrumbs: parentLocation.breadcrumbs(in: context, includeServerName: false), in: context) + detailItems.append(SegmentViewItem(with: nil, title: "|", style: .plain)) + } + } + // - Cloud status let (cloudStatusIcon, cloudStatusIconAlpha, accessibilityLabel) = cloudStatus(in: context?.core) diff --git a/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell.swift b/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell.swift index a84dd300e..35bf98747 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell.swift @@ -1023,10 +1023,11 @@ public extension UICellAccessory { public extension CollectionViewCellStyle.StyleOptionKey { static let showRevealButton = CollectionViewCellStyle.StyleOptionKey(rawValue: "showRevealButton") static let showMoreButton = CollectionViewCellStyle.StyleOptionKey(rawValue: "showMoreButton") + static let showPathDetails = CollectionViewCellStyle.StyleOptionKey(rawValue: "showPathDetails") } public extension CollectionViewCellStyle { - var showRevealButton : Bool { + var showRevealButton: Bool { get { return options[.showRevealButton] as? Bool ?? false } @@ -1036,7 +1037,7 @@ public extension CollectionViewCellStyle { } } - var showMoreButton : Bool { + var showMoreButton: Bool { get { return options[.showMoreButton] as? Bool ?? true } @@ -1045,6 +1046,16 @@ public extension CollectionViewCellStyle { options[.showMoreButton] = newValue } } + + var showPathDetails: Bool { + get { + return options[.showPathDetails] as? Bool ?? false + } + + set { + options[.showPathDetails] = newValue + } + } } extension SegmentViewItem { diff --git a/ownCloudAppShared/Client/Search/Item Search/Scopes/ServerSideSearchScope.swift b/ownCloudAppShared/Client/Search/Item Search/Scopes/ServerSideSearchScope.swift new file mode 100644 index 000000000..bbf1df3b8 --- /dev/null +++ b/ownCloudAppShared/Client/Search/Item Search/Scopes/ServerSideSearchScope.swift @@ -0,0 +1,53 @@ +// +// ServerSideSearchScope.swift +// ownCloudAppShared +// +// Created by Felix Schwarz on 04.11.24. +// Copyright © 2024 ownCloud GmbH. All rights reserved. +// + +/* + * Copyright (C) 2024, ownCloud GmbH. + * + * This code is covered by the GNU Public License Version 3. + * + * For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/ + * You should have received a copy of this license along with this program. If not, see . + * + */ + +import UIKit +import ownCloudSDK +import ownCloudApp + +class ServerSideSearchScope: SearchScope { + var searchResult: OCSearchResult? + + public override init(with context: ClientContext, cellStyle: CollectionViewCellStyle?, localizedName name: String, localizedPlaceholder placeholder: String? = nil, icon: UIImage? = nil) { + var pathAndRevealCellStyle : CollectionViewCellStyle? + + if let cellStyle = cellStyle { + pathAndRevealCellStyle = CollectionViewCellStyle(from: cellStyle, changing: { cellStyle in + cellStyle.showRevealButton = true + cellStyle.showPathDetails = true + }) + } + + super.init(with: context, cellStyle: pathAndRevealCellStyle, localizedName: name, localizedPlaceholder: placeholder, icon: icon) + + tokenizer = SearchTokenizer(scope: self, clientContext: clientContext) + results = nil + } + + open override func updateFor(_ searchElements: [SearchElement]) { + let searchTerm = searchElements.composedSearchTerm + let kqlQuery = "*" + searchTerm + "*" + + if searchResult?.kqlQuery != kqlQuery, let core = clientContext.core { + searchResult?.cancel() + + searchResult = core.searchFiles(withPattern: kqlQuery, limit: 100) + results = searchResult?.results + } + } +} diff --git a/ownCloudAppShared/Client/Search/Scopes/SearchScope.swift b/ownCloudAppShared/Client/Search/Scopes/SearchScope.swift index 4b4c56837..f88db8068 100644 --- a/ownCloudAppShared/Client/Search/Scopes/SearchScope.swift +++ b/ownCloudAppShared/Client/Search/Scopes/SearchScope.swift @@ -107,6 +107,10 @@ extension SearchScope { return AccountSearchScope(with: context, cellStyle: cellStyle, localizedName: localizedName, localizedPlaceholder: OCLocalizedString("Search account", nil), icon: OCSymbol.icon(forSymbolName: "person")) } + static public func serverSideSearch(with context: ClientContext, cellStyle: CollectionViewCellStyle, localizedName: String) -> SearchScope { + return ServerSideSearchScope(with: context, cellStyle: cellStyle, localizedName: localizedName, localizedPlaceholder: OCLocalizedString("Search server", nil), icon: OCSymbol.icon(forSymbolName: "server.rack")) + } + static public func recipientSearch(with context: ClientContext, cellStyle: CollectionViewCellStyle, item: OCItem, localizedName: String) -> SearchScope { return RecipientSearchScope(with: context, cellStyle: cellStyle, item: item, localizedName: localizedName, localizedPlaceholder: OCLocalizedString("Search for users or groups", nil), icon: OCSymbol.icon(forSymbolName: "person.circle")) } diff --git a/ownCloudAppShared/Client/View Controllers/ClientItemViewController.swift b/ownCloudAppShared/Client/View Controllers/ClientItemViewController.swift index 2bba79f2d..6263a938e 100644 --- a/ownCloudAppShared/Client/View Controllers/ClientItemViewController.swift +++ b/ownCloudAppShared/Client/View Controllers/ClientItemViewController.swift @@ -1042,6 +1042,9 @@ open class ClientItemViewController: CollectionViewController, SortBarDelegate, // - Account scopes.append(.accountSearch(with: clientContext, cellStyle: cellStyle, localizedName: OCLocalizedString("Account", nil))) + // - Server + scopes.append(.serverSideSearch(with: clientContext, cellStyle: cellStyle, localizedName: OCLocalizedString("Server", nil))) + return scopes }