Skip to content
Open
Show file tree
Hide file tree
Changes from 15 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
28 changes: 28 additions & 0 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
AABD0C8A2D5F67A400F009E6 /* XCUIElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABD0C892D5F67A200F009E6 /* XCUIElement.swift */; };
AABD0C9B2D5F73FC00F009E6 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABD0C9A2D5F73FA00F009E6 /* Placeholder.swift */; };
AAE330042D2ED20200B04903 /* NCShareNavigationTitleSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE330032D2ED1FF00B04903 /* NCShareNavigationTitleSetting.swift */; };
AAFC0D042F9AA10000F0A001 /* NCFocusedAutoUploadIntroView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFC0D012F9AA10000F0A001 /* NCFocusedAutoUploadIntroView.swift */; };
AAFC0D052F9AA10000F0A001 /* NCFocusedAutoUploadProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFC0D022F9AA10000F0A001 /* NCFocusedAutoUploadProgressView.swift */; };
AAFC0D062F9AA10000F0A001 /* NCFocusedAutoUploadScreenDimmer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFC0D032F9AA10000F0A001 /* NCFocusedAutoUploadScreenDimmer.swift */; };
AAFC0D092F9AA10000F0A001 /* NCFocusedAutoUploadCloudAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFC0D082F9AA10000F0A001 /* NCFocusedAutoUploadCloudAnimation.swift */; };
AAFC0D0B2F9AA10000F0A001 /* NCAutoUploadCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFC0D0A2F9AA10000F0A001 /* NCAutoUploadCounter.swift */; };
AB6000012F60000100FE2775 /* NCTagEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB6000002F60000100FE2775 /* NCTagEditorModel.swift */; };
AB6000032F60000200FE2775 /* NCTagEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB6000022F60000200FE2775 /* NCTagEditorView.swift */; };
AF1A9B6427D0CA1E00F17A9E /* UIAlertController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF1A9B6327D0CA1E00F17A9E /* UIAlertController+Extension.swift */; };
Expand Down Expand Up @@ -1231,6 +1236,11 @@
AACCAB632CFE04F700DA1786 /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lo; path = lo.lproj/Localizable.strings; sourceTree = "<group>"; };
AACCAB642CFE04F700DA1786 /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lo; path = lo.lproj/InfoPlist.strings; sourceTree = "<group>"; };
AAE330032D2ED1FF00B04903 /* NCShareNavigationTitleSetting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareNavigationTitleSetting.swift; sourceTree = "<group>"; };
AAFC0D012F9AA10000F0A001 /* NCFocusedAutoUploadIntroView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCFocusedAutoUploadIntroView.swift; sourceTree = "<group>"; };
AAFC0D022F9AA10000F0A001 /* NCFocusedAutoUploadProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCFocusedAutoUploadProgressView.swift; sourceTree = "<group>"; };
AAFC0D032F9AA10000F0A001 /* NCFocusedAutoUploadScreenDimmer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCFocusedAutoUploadScreenDimmer.swift; sourceTree = "<group>"; };
AAFC0D082F9AA10000F0A001 /* NCFocusedAutoUploadCloudAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCFocusedAutoUploadCloudAnimation.swift; sourceTree = "<group>"; };
AAFC0D0A2F9AA10000F0A001 /* NCAutoUploadCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCAutoUploadCounter.swift; sourceTree = "<group>"; };
AB6000002F60000100FE2775 /* NCTagEditorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTagEditorModel.swift; sourceTree = "<group>"; };
AB6000022F60000200FE2775 /* NCTagEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTagEditorView.swift; sourceTree = "<group>"; };
AF1A9B6327D0CA1E00F17A9E /* UIAlertController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Extension.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2188,6 +2198,15 @@
path = StatusMessage;
sourceTree = "<group>";
};
F3896B062FCF2CF300DA2B18 /* Utility */ = {
isa = PBXGroup;
children = (
AAFC0D032F9AA10000F0A001 /* NCFocusedAutoUploadScreenDimmer.swift */,
AAFC0D0A2F9AA10000F0A001 /* NCAutoUploadCounter.swift */,
);
path = Utility;
sourceTree = "<group>";
};
F389C9F32CEE381E00049762 /* SelectAlbum */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2661,9 +2680,13 @@
F76882162C0DD1E7001CF441 /* AutoUpload */ = {
isa = PBXGroup;
children = (
F3896B062FCF2CF300DA2B18 /* Utility */,
F39A1EE12D0AF8A200DAD522 /* Albums.swift */,
F768821B2C0DD1E7001CF441 /* NCAutoUploadView.swift */,
F71D2FB62E09BBD700B751CC /* NCAutoUploadModel.swift */,
AAFC0D012F9AA10000F0A001 /* NCFocusedAutoUploadIntroView.swift */,
AAFC0D022F9AA10000F0A001 /* NCFocusedAutoUploadProgressView.swift */,
AAFC0D082F9AA10000F0A001 /* NCFocusedAutoUploadCloudAnimation.swift */,
);
path = AutoUpload;
sourceTree = "<group>";
Expand Down Expand Up @@ -4785,6 +4808,11 @@
F76D364628A4F8BF00214537 /* NCActivityIndicator.swift in Sources */,
F3A047992BD2668800658E7B /* NCAssistantModel.swift in Sources */,
F76882322C0DD1E7001CF441 /* NCAutoUploadView.swift in Sources */,
AAFC0D042F9AA10000F0A001 /* NCFocusedAutoUploadIntroView.swift in Sources */,
AAFC0D052F9AA10000F0A001 /* NCFocusedAutoUploadProgressView.swift in Sources */,
AAFC0D062F9AA10000F0A001 /* NCFocusedAutoUploadScreenDimmer.swift in Sources */,
AAFC0D092F9AA10000F0A001 /* NCFocusedAutoUploadCloudAnimation.swift in Sources */,
AAFC0D0B2F9AA10000F0A001 /* NCAutoUploadCounter.swift in Sources */,
F36E64F72B9245210085ABB5 /* NCCollectionViewCommon+SelectTabBarDelegate.swift in Sources */,
F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */,
F75D19E325EFE09000D74598 /* NCContextMenuTrash.swift in Sources */,
Expand Down
22 changes: 22 additions & 0 deletions iOSClient/Data/NCManageDatabase+AutoUpload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ extension NCManageDatabase {
}
}

func countAutoUploadMetadatasAsync(account: String,
autoUploadServerUrlBase: String) async -> (pending: Int, failed: Int) {
let global = NCGlobal.shared
let pendingStatuses = global.metadatasStatusInWaitingDownloadUpload + global.metadatasStatusDownloadingUploading
let failedStatuses = [global.metadataStatusUploadError]

let result = await core.performRealmReadAsync { realm -> (pending: Int, failed: Int) in
let scope = realm.objects(tableMetadata.self)
.filter("account == %@ AND autoUploadServerUrlBase == %@ AND directory == false AND sessionSelector == %@",
account,
autoUploadServerUrlBase,
global.selectorUploadAutoUpload)

let pendingCount = scope.filter("status IN %@", pendingStatuses).count
let failedCount = scope.filter("status IN %@", failedStatuses).count

return (pending: pendingCount, failed: failedCount)
}

return result ?? (pending: 0, failed: 0)
}

func existsAutoUpload(account: String,
autoUploadServerUrlBase: String) -> Bool {
return core.performRealmRead { realm in
Expand Down
1 change: 1 addition & 0 deletions iOSClient/DeepLink/NCDeepLinkHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class NCDeepLinkHandler {
navigationController.popToRootViewController(animated: false)

let autoUploadView = NCAutoUploadView(model: NCAutoUploadModel(controller: controller), albumModel: AlbumModel(controller: controller))
.environment(NCAutoUploadCounter())
let autoUploadController = UIHostingController(rootView: autoUploadView)
navigationController.pushViewController(autoUploadController, animated: true)
}
Expand Down
1 change: 1 addition & 0 deletions iOSClient/NCGlobal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ final class NCGlobal: Sendable {
let notificationCenterUserInteractionMonitor = "serInteractionMonitor"

let notificationCenterNetworkingProcess = "networkingProcess"
let notificationCenterTransferCountChanged = "transferCountChanged"

// Networking Status
let networkingStatusCreateFolder = "statusCreateFolder"
Expand Down
22 changes: 11 additions & 11 deletions iOSClient/Networking/NCNetworkingProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

private var enableControllingScreenAwake = true
private var currentAccount = ""
private var inWaitDownloadUploadCount: Int = 0
private var lastScheduledAndInProgressCount: Int = 0

private var timer: DispatchSourceTimer?
private let timerQueue = DispatchQueue(label: "com.nextcloud.timerProcess", qos: .utility)
Expand Down Expand Up @@ -70,7 +70,7 @@
guard let self else { return }

Task {
let count = await self.inWaitingDownloadUploadCount()
let count = await self.scheduledAndInProgressCount()
try? await UNUserNotificationCenter.current().setBadgeCount(count)

await self.stopTimer()
Expand Down Expand Up @@ -126,12 +126,10 @@
currentAccount = account
}

private func inWaitingDownloadUploadCount() async -> Int {
let countTransferDownloadingUploadingSuccess = await NCNetworking.shared.metadataTranfersSuccess.count(statuses: NCGlobal.shared.metadatasStatusDownloadingUploading)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await NCNetworking.shared.metadataTranfersSuccess.count(statuses: NCGlobal.shared.metadatasStatusDownloadingUploading)
actually checks when the in progress metadatas are done and flushed out, it does not check the actual in progress metadatas.
After this fix, we now count it properly.

Case 1:
If transfers screen shows 10 Scheduled and 10 In Progress:

  1. Badge shows 20
  2. Auto upload counter shows 20

Case 2:
If transfers screen shows 10 Scheduled (5 auto upload metadatas) and 10 In Progress (5 auto upload metadatas):

  1. Badge shows 20
  2. Auto upload counter shows 10

@marinofaggiana

let countWaitingDownloadUpload = await NCManageDatabase.shared.getMetadatasStatusCountAsync(status: NCGlobal.shared.metadatasStatusInWaitingDownloadUpload)
let count = max(0, countWaitingDownloadUpload - countTransferDownloadingUploadingSuccess)
private func scheduledAndInProgressCount() async -> Int {
let statuses = NCGlobal.shared.metadatasStatusInWaitingDownloadUpload + NCGlobal.shared.metadatasStatusDownloadingUploading

return count
return await NCManageDatabase.shared.getMetadatasStatusCountAsync(status: statuses)
}

func startTimer(interval: TimeInterval) async {
Expand Down Expand Up @@ -198,17 +196,19 @@
return
}

// UPDATE INWAIT DOWNLOAD UPLOAD & BADGE
// UPDATE SCHEDULED + IN PROGRESS & BADGE
//
let count = await inWaitingDownloadUploadCount()
if count != inWaitDownloadUploadCount {
inWaitDownloadUploadCount = count
let count = await scheduledAndInProgressCount()
if count != lastScheduledAndInProgressCount {
lastScheduledAndInProgressCount = count
Task { @MainActor in
if let controller = getRootController(),
let files = controller.tabBar.items?.first {
files.badgeValue = count == 0 ? nil : self.utility.formatBadgeCount(count)
}
}

NotificationCenter.default.post(name: NSNotification.Name(rawValue: global.notificationCenterTransferCountChanged), object: nil)
}

// METADATAS
Expand Down Expand Up @@ -263,7 +263,7 @@

await runMetadataPipelineAsync(metadatas: metadatas)

// TODO: Check temperature

Check warning on line 266 in iOSClient/Networking/NCNetworkingProcess.swift

View workflow job for this annotation

GitHub Actions / Lint

Todo Violation: TODOs should be resolved (Check temperature) (todo)

if networking.isOffline {
await startTimer(interval: offlineInterval)
Expand Down
55 changes: 34 additions & 21 deletions iOSClient/Settings/AutoUpload/NCAutoUploadModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,50 @@ enum AutoUploadTimespan: String, CaseIterable, Identifiable {

/// A model that allows the user to configure the `auto upload settings for Nextcloud`
class NCAutoUploadModel: ObservableObject, ViewOnAppearHandling {
// A state variable that indicates whether auto upload for photos is enabled or not
/// Whether auto upload for photos is enabled or not
@Published var autoUploadImage: Bool = false
// A state variable that indicates whether auto upload for photos is restricted to Wi-Fi only or not
/// Whether auto upload for photos is restricted to Wi-Fi only or not
@Published var autoUploadWWAnPhoto: Bool = false
// A state variable that indicates whether auto upload for videos is enabled or not
/// Whether auto upload for videos is enabled or not
@Published var autoUploadVideo: Bool = false
// A state variable that indicates whether auto upload for videos is enabled or not
/// Whether auto upload for videos is enabled or not
@Published var autoUploadWWAnVideo: Bool = false
// A state variable that indicates whether auto upload is enabled or not
/// Whether auto upload is enabled or not
@Published var autoUploadStart: Bool = false
// A state variable that indicates whether auto upload creates subfolders based on date or not
/// Whether auto upload creates subfolders based on date or not
@Published var autoUploadCreateSubfolder: Bool = false
// A state variable that indicates the granularity of the subfolders, either daily, monthly, or yearly
/// The granularity of the subfolders, either daily, monthly, or yearly
@Published var autoUploadSubfolderGranularity: Granularity = .monthly
// A state variable that indicates the date from when new photos/videos will be uploaded.
/// The date from when new photos/videos will be uploaded.
@Published var autoUploadSinceDate: Date?
// A state variable that indicates whether a warning should be shown if all photos must be uploaded.
/// Whether a warning should be shown if all photos must be uploaded.
@Published var showUploadAllPhotosWarning = false
// A state variable that indicates whether Photos permissions have been granted or not.
/// Whether Photos permissions have been granted or not.
@Published var photosPermissionsGranted = true
//
@Published var permissionGranted: Bool = false
/// Whether `Always` location authorization has been granted, enabling background location-based auto upload.
@Published var locationAutoUploadPermissionGranted: Bool = false

// A state variable that shows error in view in case of an error
/// Whether the error alert should be shown in the view.
@Published var showErrorAlert: Bool = false
/// The currently displayed section name.
@Published var sectionName = ""
/// Whether the user is authorized.
@Published var isAuthorized: Bool = false
// A string variable that contains error text
/// Error text shown to the user.
@Published var error: String = ""
/// Shared Nextcloud database instance.
let database = NCManageDatabase.shared

// Root View Controller
/// Root view controller used to present UI from this model.
var controller: NCMainTabBarController?
// A variable user for change the auto upload directory
/// Server URL used to change the auto-upload directory.
var serverUrl: String = ""
// Get session
/// The current account session.
var session: NCSession.Session {
NCSession.shared.getSession(controller: controller)
}

/// The active window scene, used for presenting banners.
var windowScene: UIWindowScene? {
SceneManager.shared.getWindowScene(controller: controller)
}
Expand Down Expand Up @@ -89,6 +93,7 @@ class NCAutoUploadModel: ObservableObject, ViewOnAppearHandling {

// MARK: - All functions

/// Requests Photos library authorization and warns the user if background app refresh is disabled.
func requestAuthorization() {
PHPhotoLibrary.requestAuthorization { status in
DispatchQueue.main.async { [self] in
Expand Down Expand Up @@ -133,6 +138,7 @@ class NCAutoUploadModel: ObservableObject, ViewOnAppearHandling {
}
}

/// Sets the cut-off date so only photos/videos created after it are uploaded.
func handleAutoUploadOnlyNew(newValue: Bool) {
if newValue {
autoUploadSinceDate = Date.now
Expand Down Expand Up @@ -209,6 +215,10 @@ class NCAutoUploadModel: ObservableObject, ViewOnAppearHandling {
}
}

/// Returns a display title for the selected auto-upload albums.
///
/// - Parameter autoUploadAlbumIds: The local identifiers of the selected albums.
/// - Returns: The album's localized title, "Camera Roll" for the user library, or a localized "multiple albums" string when more than one is selected.
func createAlbumTitle(autoUploadAlbumIds: Set<String>) -> String {
if autoUploadAlbumIds.count == 1 {
let album = PHAssetCollection.allAlbums.first(where: { autoUploadAlbumIds.first == $0.localIdentifier })
Expand All @@ -218,37 +228,40 @@ class NCAutoUploadModel: ObservableObject, ViewOnAppearHandling {
}
}

/// Whether any auto-upload entry exists for the current account.
func existsAutoUpload() -> Bool {
let autoUploadServerUrlBase = NCManageDatabase.shared.getAccountAutoUploadServerUrlBase(session: session)
return NCManageDatabase.shared.existsAutoUpload(account: session.account, autoUploadServerUrlBase: autoUploadServerUrlBase)
}

/// Deletes pending auto-upload transfers for the current account.
func deleteAutoUploadTransfer() {
Task {
let autoUploadServerUrlBase = await NCManageDatabase.shared.getAccountAutoUploadServerUrlBaseAsync(session: session)
await NCManageDatabase.shared.deleteAutoUploadTransferAsync(account: session.account, autoUploadServerUrlBase: autoUploadServerUrlBase)
}
}

/// Updates the auto-upload create subfolder setting.
/// Requests or revokes `Always` location authorization for background location-based auto upload.
func handleLocationChange(newValue: Bool) {
if let controller = self.controller {
if newValue {
Task { @MainActor in
let result = await NCBackgroundLocationUploadManager.shared.requestAuthorizationAlwaysAsync(from: controller)
self.permissionGranted = result
self.locationAutoUploadPermissionGranted = result
NCPreferences().location = result
}
} else {
self.permissionGranted = false
self.locationAutoUploadPermissionGranted = false
NCPreferences().location = false
}
}
}

/// Refreshes `locationAutoUploadPermissionGranted` from the current location authorization status and stored preference.
func checkPermission() {
let status = CLLocationManager().authorizationStatus
permissionGranted = (status == .authorizedAlways && NCPreferences().location)
locationAutoUploadPermissionGranted = (status == .authorizedAlways && NCPreferences().location)
}
}

Expand Down
Loading
Loading