-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- π¨β‘οΈ Cleanups, background refresh + notifications - π¨ Refactors, ContainerConfigDetailsView - π¨ Refactors & cleanups - π¨β¨ Optimizations, colored container cells - β¨ Multi-window support - π¨ Better error handling, cleanups - β¨π¨ Handoff, cleanups & optimizations - β¨ "Use columns" setting - π Fix build - π README
- Loading branch information
Showing
58 changed files
with
1,501 additions
and
760 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// AppDelegate.swift | ||
// Harbour | ||
// | ||
// Created by royal on 17/10/2021. | ||
// | ||
|
||
import Foundation | ||
import UIKit | ||
import BackgroundTasks | ||
|
||
class AppDelegate: NSObject, UIApplicationDelegate { | ||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { | ||
#if DEBUG | ||
let defaults: [String: Any] = [ | ||
"_UIConstraintBasedLayoutLogUnsatisfiable": false | ||
] | ||
UserDefaults.standard.register(defaults: defaults) | ||
#endif | ||
|
||
BGTaskScheduler.shared.register(forTaskWithIdentifier: AppState.BackgroundTask.refresh, using: nil) { task in | ||
AppState.shared.scheduleBackgroundRefreshTask() | ||
AppState.shared.handleBackgroundRefreshTask(task: task as! BGAppRefreshTask) | ||
} | ||
|
||
return true | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// | ||
// AppState+BackgroundTasks.swift | ||
// Harbour | ||
// | ||
// Created by royal on 17/10/2021. | ||
// | ||
|
||
import Foundation | ||
import BackgroundTasks | ||
import UserNotifications | ||
import WidgetKit | ||
import PortainerKit | ||
|
||
extension AppState { | ||
enum BackgroundTask { | ||
static var refresh = "\(Bundle.main.bundleIdentifier!).BackgroundRefresh" | ||
} | ||
|
||
public func scheduleBackgroundRefreshTask() { | ||
let task = BackgroundTask.refresh | ||
|
||
logger.info("(Background refresh) Scheduling background refresh task with identifier \"\(task)\"") | ||
|
||
let request = BGAppRefreshTaskRequest(identifier: task) | ||
|
||
do { | ||
try BGTaskScheduler.shared.submit(request) | ||
} catch { | ||
logger.error("(Background refresh) Could not schedule app refresh: \(String(describing: error))") | ||
} | ||
} | ||
|
||
public func cancelBackgroundRefreshTask() { | ||
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: BackgroundTask.refresh) | ||
} | ||
|
||
public func handleBackgroundRefreshTask(task: BGAppRefreshTask) { | ||
logger.debug("(Background refresh) Handling background refresh for task \"\(task.identifier)\"") | ||
|
||
WidgetCenter.shared.reloadAllTimelines() | ||
#if DEBUG | ||
Preferences.shared.lastBackgroundTaskDate = Date() | ||
#endif | ||
|
||
Task { | ||
do { | ||
let savedState = Portainer.shared.containers.reduce(into: [:]) { $0[$1.id] = $1.state?.rawValue } | ||
|
||
let newContainers = try await Portainer.shared.getContainers() | ||
let newState = newContainers.reduce(into: [:]) { $0[$1.id] = $1.state?.rawValue } | ||
let differences = newState.filter { savedState[$0.key] != $0.value } | ||
|
||
if differences.isEmpty { | ||
logger.info("(Background refresh) differences.count (\(differences.count)) > 0!") | ||
|
||
let notificationID = "ContainerStatusNotification-\(Date().timeIntervalSinceReferenceDate)" | ||
let content = UNMutableNotificationContent() | ||
content.relevanceScore = 1 | ||
content.interruptionLevel = .active | ||
content.sound = .default | ||
|
||
if differences.count == 1 { | ||
let container = newContainers.first(where: { $0.id == differences.first?.key }) | ||
content.title = container?.displayName ?? container?.id ?? differences.first?.key ?? "Unknown container" | ||
content.body = container?.status ?? differences.first?.value ?? "unknown" | ||
} else { | ||
let containers = newContainers.filter({ differences.keys.contains($0.id) }).map({ $0.displayName ?? $0.id }) | ||
content.title = "\(differences.count) containers changed!" | ||
content.body = ListFormatter.localizedString(byJoining: containers) | ||
} | ||
|
||
let request = UNNotificationRequest(identifier: notificationID, content: content, trigger: nil) | ||
try await UNUserNotificationCenter.current().add(request) | ||
} | ||
|
||
task.setTaskCompleted(success: true) | ||
} catch { | ||
logger.error("(Background refresh) Error handling background refresh: \(String(describing: error))") | ||
task.setTaskCompleted(success: false) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// | ||
// AppState+UserActivity.swift | ||
// Harbour | ||
// | ||
// Created by royal on 22/10/2021. | ||
// | ||
|
||
import Foundation | ||
|
||
extension AppState { | ||
enum UserActivity { | ||
static let viewingContainer = "\(Bundle.main.bundleIdentifier!).ViewingContainer" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// | ||
// AppState.swift | ||
// Harbour | ||
// | ||
// Created by royal on 11/06/2021. | ||
// | ||
|
||
import Foundation | ||
import Combine | ||
import UIKit.UIDevice | ||
import os.log | ||
import Indicators | ||
|
||
class AppState: ObservableObject { | ||
public static let shared: AppState = AppState() | ||
|
||
@Published public var fetchingMainScreenData: Bool = false | ||
|
||
internal let logger: Logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "AppState") | ||
|
||
internal var autoRefreshTimer: AnyCancellable? = nil | ||
|
||
private init() { | ||
if Preferences.shared.endpointURL != nil && Preferences.shared.autoRefreshInterval > 0 { | ||
setupAutoRefreshTimer() | ||
} | ||
} | ||
|
||
// MARK: - Auto refresh | ||
|
||
public func setupAutoRefreshTimer(interval: Double = Preferences.shared.autoRefreshInterval) { | ||
logger.debug("(Auto refresh) Interval: \(interval)") | ||
|
||
autoRefreshTimer?.cancel() | ||
|
||
guard interval > 0 else { return } | ||
|
||
autoRefreshTimer = Timer.publish(every: interval, on: .current, in: .common) | ||
.autoconnect() | ||
.receive(on: DispatchQueue.main) | ||
.sink { _ in | ||
Task { [weak self] in | ||
self?.fetchingMainScreenData = true | ||
|
||
do { | ||
try await Portainer.shared.getContainers() | ||
} catch { | ||
self?.handle(error) | ||
} | ||
|
||
self?.fetchingMainScreenData = false | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Error handling | ||
|
||
private func handle(_ error: Error, _fileID: StaticString = #fileID, _line: Int = #line) { | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.