Skip to content
Merged
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
6 changes: 3 additions & 3 deletions Shared/Data/CoreData/CoreDataManager+Certificates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,9 @@ extension CoreDataManager {
}
}

/// Clear the update state for a signed app
/// Clear the update state for a signed app (alternative implementation)
/// - Parameter signedApp: The app to update
func clearUpdateState(for signedApp: SignedApps) throws {
func clearUpdateStateForCertificate(for signedApp: SignedApps) throws {
let ctx = try context

// Make sure we have the app in the right context
Expand All @@ -526,7 +526,7 @@ extension CoreDataManager {
domain: "CoreDataManager",
code: 1016,
userInfo: [NSLocalizedDescriptionKey: "App not found in context"]
)
) as Error
}
appInContext = fetchedApp
} else {
Expand Down
15 changes: 15 additions & 0 deletions Shared/Management/ImageCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ final class ImageCache {

/// Shared instance of the image cache
static let shared = ImageCache()

/// Save an image to the cache for a specific URL
/// - Parameters:
/// - image: The image to save
/// - url: The URL associated with the image
func saveImage(_ image: UIImage, for url: URL) {
// Save to memory cache
let key = url.absoluteString as NSString
memoryCache.setObject(image, forKey: key)

// Save to disk in the background
diskQueue.async { [weak self] in
self?.saveImageToDisk(image: image, url: url)
}
}

// MARK: - Cache Storage

Expand Down
4 changes: 2 additions & 2 deletions iOS/Views/Apps/LibraryViewController+IconFix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ extension LibraryViewController {
let image = UIImage(contentsOfFile: imagePath.path) {
setImageWithLEDEffect(cell: cell, image: image)

// Save to CoreData cache for future use
CoreDataManager.shared.saveImage(image, at: imagePath)
// Save to image cache for future use
ImageCache.shared.saveImage(image, for: imagePath)
return
}

Expand Down
2 changes: 1 addition & 1 deletion iOS/Views/Apps/LibraryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ extension LibraryViewController {
guard let self = self else { return }
self.popupVC.dismiss(animated: true)
do {
try CoreDataManager.shared.clearUpdateState(for: signedApp)
try CoreDataManager.shared.clearUpdateStateCompat(for: signedApp)
self.tableView.reloadRows(at: [indexPath], with: .none)
} catch {
backdoor.Debug.shared.log(message: "Error clearing update state: \(error)", type: LogType.error)
Expand Down
23 changes: 20 additions & 3 deletions iOS/Views/Extra/PopupViewController+MenuFix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ extension PopupViewController {

// Prevent user from dismissing by dragging (forces use of buttons)
if hasUpdate {
sheet.prefersModalPresentation = true
if #available(iOS 15.0, *) {
sheet.prefersGrabberVisible = false
sheet.detents = [.medium()]
}
}
}
}
Expand Down Expand Up @@ -282,7 +285,14 @@ extension PopupViewController {
// Refresh sheet presentation if needed
if let presentationController = presentationController as? UISheetPresentationController {
// Force update the presentation controller's layout
presentationController.invalidateDetents()
if #available(iOS 16.0, *) {
presentationController.invalidateDetents()
} else {
// Fall back for iOS 15
if let sheet = presentationController as? UISheetPresentationController {
sheet.detents = [.medium(), .large()]
}
}
}

// Ensure buttons are still correctly displayed
Expand All @@ -296,7 +306,14 @@ extension PopupViewController {
// Fix presentation issues that might occur when app returns to foreground
if let presentationController = presentationController as? UISheetPresentationController {
// Force update the presentation controller's layout
presentationController.invalidateDetents()
if #available(iOS 16.0, *) {
presentationController.invalidateDetents()
} else {
// Fall back for iOS 15
if let sheet = presentationController as? UISheetPresentationController {
sheet.detents = [.medium(), .large()]
}
}

// Ensure buttons are still correctly displayed
view.setNeedsLayout()
Expand Down
7 changes: 6 additions & 1 deletion iOS/Views/Home/Core/DirectoryViewControllerExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ extension DirectoryViewController {
// Import file option
let importAction = UIAlertAction(title: "Import File", style: .default) { [weak self] _ in
guard let self = self else { return }
self.importFile()
if let homeVC = self as? HomeViewController {
homeVC.importFile()
} else {
// Handle the case where self is not a HomeViewController
Debug.shared.log(message: "importFile called on non-HomeViewController", type: .warning)
}
}
importAction.setValue(UIImage(systemName: "square.and.arrow.down"), forKey: "image")

Expand Down
35 changes: 21 additions & 14 deletions iOS/Views/Home/Core/HomeViewController+FileUploadFix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ extension HomeViewController {
/// Process a single imported file
private func processImportedFile(url: URL) throws {
// Get a unique filename that won't conflict with existing files
let fileName = getUniqueFileName(for: url.lastPathComponent)
let fileName = HomeViewController.getUniqueFileNameShared(for: url.lastPathComponent)
let destinationURL = documentsDirectory.appendingPathComponent(fileName)

Debug.shared.log(message: "Processing import: \(url.path) to \(destinationURL.path)", type: .info)
Expand Down Expand Up @@ -274,22 +274,29 @@ extension HomeViewController {
}
}

/// LED indicator types if not already defined
fileprivate enum LEDIndicatorType {
case success
case error
case warning
case info

var backgroundColor: UIColor {
switch self {
case .success: return UIColor.systemGreen.withAlphaComponent(0.8)
case .error: return UIColor.systemRed.withAlphaComponent(0.8)
case .warning: return UIColor.systemOrange.withAlphaComponent(0.8)
case .info: return UIColor.systemBlue.withAlphaComponent(0.8)
// Using the LED effect from UIView+LED extension instead
extension HomeViewController {
func showUploadStatusIndicator(type: UploadStatus) {
let color: UIColor
switch type {
case .success: color = UIColor.systemGreen
case .error: color = UIColor.systemRed
case .warning: color = UIColor.systemOrange
case .info: color = UIColor.systemBlue
}

// Apply LED effect using the existing extension
self.view.addLEDEffect(color: color, intensity: 0.8, spread: 5, animated: true)
}

enum UploadStatus {
case success
case error
case warning
case info
}
}

var glowColor: UIColor {
switch self {
case .success: return .systemGreen
Expand Down
16 changes: 11 additions & 5 deletions iOS/Views/Home/Core/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ class HomeViewController: UIViewController, UISearchResultsUpdating, UIDocumentP
activityIndicator.startAnimating()

// Generate a unique name if a file with the same name exists
let fileName = getUniqueFileName(for: url.lastPathComponent)
let fileName = HomeViewController.getUniqueFileNameShared(for: url.lastPathComponent)
let destinationURL = documentsDirectory.appendingPathComponent(fileName)

Debug.shared.log(message: "Importing file from \(url.path) to \(destinationURL.path)", type: .info)
Expand Down Expand Up @@ -446,11 +446,17 @@ class HomeViewController: UIViewController, UISearchResultsUpdating, UIDocumentP
/// Generates a unique filename if the original already exists
/// - Parameter filename: The original filename
/// - Returns: A unique filename
private func getUniqueFileName(for filename: String) -> String {
let fileURL = documentsDirectory.appendingPathComponent(filename)
// Changed to static method so it can be shared
static func getUniqueFileNameShared(for filename: String) -> String {
// Get documents directory since we're in a static context
guard let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("files") else {
return filename + "_unique"
}

let fileURL = documentsDir.appendingPathComponent(filename)

// If the file doesn't exist, return the original name
if !fileManager.fileExists(atPath: fileURL.path) {
if !FileManager.default.fileExists(atPath: fileURL.path) {
return filename
}

Expand Down Expand Up @@ -1203,7 +1209,7 @@ class HomeViewController: UIViewController, UISearchResultsUpdating, UIDocumentP
// Check if destination already exists
if self.fileManager.fileExists(atPath: destinationURL.path) {
// Create a unique name if needed
let uniqueName = self.getUniqueFileName(for: destinationName)
let uniqueName = HomeViewController.getUniqueFileNameShared(for: destinationName)
let uniqueURL = self.documentsDirectory.appendingPathComponent(uniqueName)

// Create extraction directory
Expand Down
16 changes: 15 additions & 1 deletion iOS/Views/Signing/SigningData/SigningOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,22 @@ struct SigningOptions: Codable {

// Added missing properties
var useOfflineCertificates: Bool = false
var customEntitlements: [String: Any]? = nil

// Note: These properties need special handling for Codable conformance
private var _customEntitlements: [String: String]? = nil
var additionalData: [String: String]? = nil

// Use computed property for type that doesn't conform to Codable
var customEntitlements: [String: Any]? {
get {
return _customEntitlements as [String: Any]?
}
set {
if let newValue = newValue as? [String: String] {
_customEntitlements = newValue
}
}
}
}

extension UserDefaults {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,17 +468,48 @@ extension Array {

// MARK: - SigningDataWrapper Extension

extension SigningDataWrapper.SigningOptions {
/// Custom entitlements dictionary
var customEntitlements: [String: Any]? {
get {
return additionalData["customEntitlements"] as? [String: Any]
// Extension to provide customEntitlements access
extension SigningDataWrapper {
// Add an accessor to get to the SigningOptions
var signingOptionsWithEntitlements: SigningOptions {
return signingOptions
}
}

// Helper extension to store entitlements
extension SigningOptions {
/// Helper to access entitlements through additionalData
func getEntitlementsFromAdditionalData() -> [String: Any]? {
guard let entitlementsJson = additionalData?["customEntitlements"] else {
return customEntitlements
}

if let data = entitlementsJson.data(using: .utf8),
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
return dict
}

return customEntitlements
}

/// Helper to store entitlements in additionalData
mutating func setEntitlementsToAdditionalData(_ entitlements: [String: Any]?) {
if additionalData == nil {
additionalData = [:]
}
set {
if additionalData == nil {
additionalData = [:]
// Convert to JSON string for storage
if let entitlements = entitlements {
do {
let data = try JSONSerialization.data(withJSONObject: entitlements, options: [])
if let jsonString = String(data: data, encoding: .utf8) {
additionalData?["customEntitlements"] = jsonString
}
} catch {
Debug.shared.log(message: "Failed to serialize entitlements: \(error)", type: .error)
}
} else {
additionalData?["customEntitlements"] = nil
}
additionalData?["customEntitlements"] = newValue
}
}
}
7 changes: 3 additions & 4 deletions iOS/Views/Terminal/TerminalViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -863,11 +863,10 @@ extension TerminalService {
/// Get the current session ID
func getCurrentSessionId(completion: @escaping (String?) -> Void) {
// Get current session ID from the service
// This is a placeholder method - implement according to your TerminalService
// It should return the active session ID or fetch it if needed
// Use the sessionId property directly

if let currentSessionId = self.currentSessionId {
completion(currentSessionId)
if let sessionId = self.sessionId {
completion(sessionId)
return
}

Expand Down