Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion iOS/Delegates/AppDelegate+NetworkMonitoring.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ extension AppDelegate {
object: nil,
userInfo: [
"isConnected": isConnected,
"connectionType": connectionTypeToString(connectionType),
"connectionType": self.connectionTypeToString(connectionType),
"isOfflineSigningAvailable": offlineManager.isOfflineSigningEnabled
]
)
Expand Down
91 changes: 91 additions & 0 deletions iOS/Views/Apps/LibraryViewController+SearchExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Proprietary Software License Version 1.0
//
// Copyright (C) 2025 BDG
//
// Backdoor App Signer is proprietary software. You may not use, modify, or distribute it except as expressly
// permitted under the terms of the Proprietary Software License.

import UIKit

// MARK: - Search Extensions for LibraryViewController

extension LibraryViewController {
/// Configure the search controller for app filtering
func configureSearchBar() {
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"

navigationItem.searchController = searchController
definesPresentationContext = true
navigationItem.hidesSearchBarWhenScrolling = false
}

/// Check if search filtering is active
var isFiltering: Bool {
return searchController.isActive && !searchBarIsEmpty
}

/// Check if search bar is empty
var searchBarIsEmpty: Bool {
return searchController.searchBar.text?.isEmpty ?? true
}
}

// MARK: - UISearchResultsUpdating Implementation
extension LibraryViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchText = searchController.searchBar.text ?? ""
filterContentForSearchText(searchText)
tableView.reloadData()
}

/// Filter app content based on search text
private func filterContentForSearchText(_ searchText: String) {
let lowercasedSearchText = searchText.lowercased()

filteredSignedApps = signedApps?.filter { app in
guard let name = app.name?.lowercased() else { return false }
return name.contains(lowercasedSearchText)
} ?? []

filteredDownloadedApps = downloadedApps?.filter { app in
guard let name = app.name?.lowercased() else { return false }
return name.contains(lowercasedSearchText)
} ?? []
}
}

// MARK: - UISearchControllerDelegate Implementation
extension LibraryViewController: UISearchControllerDelegate, UISearchBarDelegate {
// Can be expanded with additional search-related methods as needed
}

// MARK: - UI Helper Extensions
extension LibraryViewController {
/// Create and configure a loading alert with spinner
func createLoaderAlert() -> UIAlertController {
let alert = UIAlertController(
title: nil,
message: "Please wait...",
preferredStyle: .alert
)

let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = .medium
loadingIndicator.startAnimating()

alert.view.addSubview(loadingIndicator)

// Add constraints for proper layout
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
loadingIndicator.centerXAnchor.constraint(equalTo: alert.view.centerXAnchor),
loadingIndicator.centerYAnchor.constraint(equalTo: alert.view.centerYAnchor),
])

return alert
}
}
67 changes: 67 additions & 0 deletions iOS/Views/Apps/LibraryViewController+UIActions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Proprietary Software License Version 1.0
//
// Copyright (C) 2025 BDG
//
// Backdoor App Signer is proprietary software. You may not use, modify, or distribute it except as expressly
// permitted under the terms of the Proprietary Software License.

import UIKit
import CoreData

// MARK: - UI Action Extensions for LibraryViewController

extension LibraryViewController {
/// Show certificate missing alert
func showNoCertificatesAlert() {
let alert = UIAlertController(
title: String.localized("APP_SIGNING_VIEW_CONTROLLER_NO_CERTS_ALERT_TITLE"),
message: String.localized("APP_SIGNING_VIEW_CONTROLLER_NO_CERTS_ALERT_DESCRIPTION"),
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: String.localized("LAME"), style: .default))
present(alert, animated: true)
}

/// Handle downloaded app actions
func handleDownloadedAppAction(app: DownloadedApps, indexPath: IndexPath) {
// Implementation would go here
// This is a placeholder to match method signature used in code
}

/// Show confirmation alert for installing an app
func showInstallConfirmationAlert(app: NSManagedObject, filePath: String) {
// Implementation would go here
// This is a placeholder to match method signature used in code
}

/// Configure popup detents for iOS 15+ sheet presentations
func configurePopupDetents(hasUpdate: Bool) {
// Implementation would go here
// This is a placeholder to match method signature used in code
}

/// Configure the presentation detents of a popup view controller
func configureSheetPresentationController(for viewController: UIViewController, hasUpdate: Bool = false) {
if #available(iOS 15.0, *) {
if let sheet = viewController.presentationController as? UISheetPresentationController {
sheet.detents = [.medium(), .large()]
sheet.prefersGrabberVisible = true
}
}
}
}

// MARK: - Table View Extensions
extension LibraryViewController {
// UITableView related overrides that comply with Swift rules

// These don't have 'override' as they're in extension blocks
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
// Implementation would go here - placeholder
return nil
}
}
17 changes: 6 additions & 11 deletions iOS/Views/Apps/LibraryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ class LibraryViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setupSearchController()
configureSearchBar()
fetchSources()
loaderAlert = presentLoader()
loaderAlert = createLoaderAlert()
}

override func viewWillAppear(_ animated: Bool) {
Expand Down Expand Up @@ -633,20 +633,15 @@ extension LibraryViewController {
}
}
)
}
}
} else {
showNoCertificatesAlert()
}
}

private func showNoCertificatesAlert() {
let alert = UIAlertController(
title: String.localized("APP_SIGNING_VIEW_CONTROLLER_NO_CERTS_ALERT_TITLE"),
message: String.localized("APP_SIGNING_VIEW_CONTROLLER_NO_CERTS_ALERT_DESCRIPTION"),
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: String.localized("LAME"), style: .default))
present(alert, animated: true)
// Method moved to LibraryViewController+UIActions.swift
private func showCertificatesAlert() {
showNoCertificatesAlert()
}

private func handleDownloadedAppAction(
Expand Down
2 changes: 1 addition & 1 deletion iOS/Views/Home/Core/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class HomeViewController: UIViewController, UISearchResultsUpdating, UIDocumentP
let uploadButton = UIBarButtonItem(customView: HomeViewUI.uploadButton)
let addButton = UIBarButtonItem(image: UIImage(systemName: "folder.badge.plus"), style: .plain, target: self, action: #selector(addDirectory))

HomeViewUI.uploadButton.addTarget(self, action: #selector(importFile), for: .touchUpInside)
HomeViewUI.uploadButton.addTarget(self, action: #selector(performFileImport), for: .touchUpInside)
HomeViewUI.uploadButton.addGradientBackground()
navItem.rightBarButtonItems = [menuButton, uploadButton, addButton]
HomeViewUI.navigationBar.setItems([navItem], animated: false)
Expand Down
12 changes: 8 additions & 4 deletions iOS/Views/Terminal/TerminalViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,9 @@ class TerminalViewController: UIViewController {
self.isExecuting = false

switch result {
case .success(let output):
self.appendToTerminal(output, isInput: false)
case .success:
// Result is Void, no output to display from HTTP mode
break
case .failure(let error):
self.appendToTerminal("Error: \(error.localizedDescription)", isInput: false)
}
Expand Down Expand Up @@ -640,13 +641,16 @@ class TerminalViewController: UIViewController {
self.logger.log(message: "Fetching WebDAV credentials for session \(sessionId)", type: .info)

// Get base URL from TerminalService
guard let baseURL = TerminalService.shared.baseURL else {
let serverBaseURL: String
if let baseURL = TerminalService.shared.baseURL {
serverBaseURL = baseURL
} else {
completion(.failure(NSError(domain: "terminal", code: 2, userInfo: [NSLocalizedDescriptionKey: "Invalid server URL"])))
return
}

// Create URL for WebDAV credentials
guard let url = URL(string: "\(baseURL)/api/webdav/credentials?session_id=\(sessionId)") else {
guard let url = URL(string: "\(serverBaseURL)/api/webdav/credentials?session_id=\(sessionId)") else {
completion(.failure(NSError(domain: "terminal", code: 2, userInfo: [NSLocalizedDescriptionKey: "Invalid URL for WebDAV credentials"])))
return
}
Expand Down