Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to keep screen on while transferring files #3062

Merged
merged 9 commits into from
Oct 7, 2024
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
30 changes: 30 additions & 0 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@
F3BB464D2A39ADCC00461F6E /* NCMoreAppSuggestionsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F3BB464C2A39ADCC00461F6E /* NCMoreAppSuggestionsCell.xib */; };
F3BB46522A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3BB46512A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift */; };
F3BB46542A3A1E9D00461F6E /* CCCellMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3BB46532A3A1E9D00461F6E /* CCCellMore.swift */; };
F3E173B02C9AF637006D177A /* ScreenAwakeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173AF2C9AF637006D177A /* ScreenAwakeManager.swift */; };
F3E173C02C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3E173C12C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3E173C22C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3E173C32C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3E173C42C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3E173C52C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3E173C62C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; };
F3EF2E0C2BFCF3810025EF46 /* NCLoginPoll.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EF2E0B2BFCF3810025EF46 /* NCLoginPoll.swift */; };
F3F0419B2B9F7E6700D5155F /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = F3F0419A2B9F7E6700D5155F /* RealmSwift */; };
F3F0419D2B9F7E6E00D5155F /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = F3F0419C2B9F7E6E00D5155F /* RealmSwift */; };
Expand Down Expand Up @@ -1210,6 +1218,8 @@
F3BB464C2A39ADCC00461F6E /* NCMoreAppSuggestionsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NCMoreAppSuggestionsCell.xib; sourceTree = "<group>"; };
F3BB46512A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMoreAppSuggestionsCell.swift; sourceTree = "<group>"; };
F3BB46532A3A1E9D00461F6E /* CCCellMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCCellMore.swift; sourceTree = "<group>"; };
F3E173AF2C9AF637006D177A /* ScreenAwakeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenAwakeManager.swift; sourceTree = "<group>"; };
F3E173BF2C9B1067006D177A /* AwakeMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AwakeMode.swift; sourceTree = "<group>"; };
F3EF2E0B2BFCF3810025EF46 /* NCLoginPoll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginPoll.swift; sourceTree = "<group>"; };
F700222B1EC479840080073F /* Custom.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Custom.xcassets; sourceTree = "<group>"; };
F700510022DF63AC003A3356 /* NCShare.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCShare.storyboard; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2127,6 +2137,15 @@
path = Cells;
sourceTree = "<group>";
};
F3E173BE2C9B1057006D177A /* ScreenAwakeManager */ = {
isa = PBXGroup;
children = (
F3E173AF2C9AF637006D177A /* ScreenAwakeManager.swift */,
F3E173BF2C9B1067006D177A /* AwakeMode.swift */,
);
path = ScreenAwakeManager;
sourceTree = "<group>";
};
F70211F31BAC56E9003FC03E /* Main */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2819,6 +2838,7 @@
F7BFFA991A24D7BB0044ED85 /* Utility */ = {
isa = PBXGroup;
children = (
F3E173BE2C9B1057006D177A /* ScreenAwakeManager */,
F702F2FC25EE5D2C008F8E80 /* NYMnemonic */,
F7D4BF2B2CA2E8D800A5E746 /* TOPasscodeViewController */,
F76D364528A4F8BF00214537 /* NCActivityIndicator.swift */,
Expand Down Expand Up @@ -4016,6 +4036,7 @@
F702F2D225EE5B5C008F8E80 /* NCGlobal.swift in Sources */,
F7707689263A896A00A1BA94 /* UIImage+Extension.swift in Sources */,
F72FD3BA297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */,
F3E173C62C9B1067006D177A /* AwakeMode.swift in Sources */,
F73EF7DD2B0226080087E6E9 /* NCManageDatabase+Tip.swift in Sources */,
F73EF7ED2B0226B90087E6E9 /* NCManageDatabase+UserStatus.swift in Sources */,
F7E98C1927E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */,
Expand Down Expand Up @@ -4145,6 +4166,7 @@
F73EF7B42B0224350087E6E9 /* NCManageDatabase+DirectEditing.swift in Sources */,
F7490E8229882C80009DCE94 /* NCManageDatabase+E2EE.swift in Sources */,
F7490E7829882C28009DCE94 /* NCUtility.swift in Sources */,
F3E173C52C9B1067006D177A /* AwakeMode.swift in Sources */,
F71433E62C778FFB00E20B5A /* NotificationCenter+MainThread.swift in Sources */,
F33918C92C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */,
F7490E7F29882C73009DCE94 /* NCManageDatabase+Activity.swift in Sources */,
Expand Down Expand Up @@ -4238,6 +4260,7 @@
F749B64D297B0CBB00087535 /* NCManageDatabase+Share.swift in Sources */,
F72FD3B8297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */,
F7A76DC8256A71CD00119AB3 /* UIImage+Extension.swift in Sources */,
F3E173C32C9B1067006D177A /* AwakeMode.swift in Sources */,
F711A4E52AF9310500095DD8 /* NCUtility+Image.swift in Sources */,
F73EF7AA2B0223900087E6E9 /* NCManageDatabase+Comments.swift in Sources */,
F763D2A02A249C4500A3C901 /* NCManageDatabase+Capabilities.swift in Sources */,
Expand Down Expand Up @@ -4347,6 +4370,7 @@
F78302FF28B4C45000B84583 /* NCUtilityFileSystem.swift in Sources */,
F73EF7B82B0224AB0087E6E9 /* NCManageDatabase+ExternalSites.swift in Sources */,
F73EF7C02B02250B0087E6E9 /* NCManageDatabase+GPS.swift in Sources */,
F3E173C12C9B1067006D177A /* AwakeMode.swift in Sources */,
F73EF7B02B0224350087E6E9 /* NCManageDatabase+DirectEditing.swift in Sources */,
F75DD766290ABB25002EB562 /* Intent.intentdefinition in Sources */,
F7D68FCD28CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift in Sources */,
Expand Down Expand Up @@ -4386,6 +4410,7 @@
F7327E382B73AEDE00A462C7 /* NCNetworking+LivePhoto.swift in Sources */,
F771E3D320E2392D00AFB62D /* FileProviderExtension.swift in Sources */,
F771E3D520E2392D00AFB62D /* FileProviderItem.swift in Sources */,
F3E173C42C9B1067006D177A /* AwakeMode.swift in Sources */,
AF4BF616275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */,
F343A4B72A1E084300DDA874 /* PHAsset+Extension.swift in Sources */,
F7434B3620E23FE000417916 /* NCManageDatabase.swift in Sources */,
Expand Down Expand Up @@ -4631,6 +4656,7 @@
F73EF7DF2B02266D0087E6E9 /* NCManageDatabase+Trash.swift in Sources */,
F79B646026CA661600838ACA /* UIControl+Extension.swift in Sources */,
F768823E2C0DD305001CF441 /* LazyView.swift in Sources */,
F3E173B02C9AF637006D177A /* ScreenAwakeManager.swift in Sources */,
F7CA212D25F1333300826ABB /* NCAccountRequest.swift in Sources */,
F747EB0D2C4AC1FF00F959A8 /* NCCollectionViewCommon+CollectionViewDelegateFlowLayout.swift in Sources */,
F765F73125237E3F00391DBE /* NCRecent.swift in Sources */,
Expand Down Expand Up @@ -4733,6 +4759,7 @@
AF2D7C7E2742559100ADF566 /* NCShareUserCell.swift in Sources */,
F74DE14325135B6800917068 /* NCTransfers.swift in Sources */,
AF4BF614275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */,
F3E173C02C9B1067006D177A /* AwakeMode.swift in Sources */,
F711A4DC2AF92CAE00095DD8 /* NCUtility+Date.swift in Sources */,
AF4BF61E27562B3F0081CEEF /* NCManageDatabase+Activity.swift in Sources */,
);
Expand Down Expand Up @@ -4778,6 +4805,7 @@
F72FD3B7297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */,
F7A8D74128F18254008BBE1C /* UIColor+Extension.swift in Sources */,
F73EF7D92B0226080087E6E9 /* NCManageDatabase+Tip.swift in Sources */,
F3E173C22C9B1067006D177A /* AwakeMode.swift in Sources */,
F7864ACE2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
F7B769AA2B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift in Sources */,
F7A8D74028F18212008BBE1C /* UIImage+Extension.swift in Sources */,
Expand Down Expand Up @@ -5530,6 +5558,7 @@
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h";
TARGETED_DEVICE_FAMILY = "1,2";
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES;
};
name = Debug;
};
Expand All @@ -5552,6 +5581,7 @@
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h";
TARGETED_DEVICE_FAMILY = "1,2";
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES;
};
name = Release;
};
Expand Down
6 changes: 3 additions & 3 deletions iOSClient/Networking/NCNetworkingProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ class NCNetworkingProcess {
let hasSynchronizationTask = tasks.contains { $0.taskDescription == NCGlobal.shared.taskDescriptionSynchronization }
let resultsTransfer = self.database.getResultsMetadatas(predicate: NSPredicate(format: "status IN %@", self.global.metadataStatusInTransfer))

if resultsTransfer == nil && !hasSynchronizationTask {
// No tranfer, disable
if resultsTransfer.isEmptyOrNil && !hasSynchronizationTask {
ScreenAwakeManager.shared.mode = .off
} else {
// transfer enable
ScreenAwakeManager.shared.mode = NCKeychain().screenAwakeMode
}
}

Expand Down
9 changes: 9 additions & 0 deletions iOSClient/Settings/Display/NCDisplayModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ class NCDisplayModel: ObservableObject, ViewOnAppearHandling {
@Published var controller: NCMainTabBarController?
/// State variable for enabling the automatic appreance
@Published var appearanceAutomatic: Bool = false

/// State variable for keeping the screen on or off during file transfering
@Published var screenAwakeState = AwakeMode.off {
didSet {
keychain.screenAwakeMode = screenAwakeState
}
}

/// Get session
var session: NCSession.Session {
NCSession.shared.getSession(controller: controller)
Expand All @@ -30,6 +38,7 @@ class NCDisplayModel: ObservableObject, ViewOnAppearHandling {
/// Triggered when the view appears.
func onViewAppear() {
appearanceAutomatic = keychain.appearanceAutomatic
screenAwakeState = keychain.screenAwakeMode
}

// MARK: - All functions
Expand Down
12 changes: 12 additions & 0 deletions iOSClient/Settings/Display/NCDisplayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ struct NCDisplayView: View {
}
}
.font(.system(size: 16))

Section(header: Text(NSLocalizedString("_additional_options_", comment: ""))) {

Picker(NSLocalizedString("_keep_screen_awake_", comment: ""),
selection: $model.screenAwakeState) {
Text(NSLocalizedString("_off_", comment: "")).tag(AwakeMode.off)
Text(NSLocalizedString("_on_", comment: "")).tag(AwakeMode.on)
Text(NSLocalizedString("_while_charging_", comment: "")).tag(AwakeMode.whileCharging)
}
.frame(height: 50)
}
.pickerStyle(.menu)
}
.navigationBarTitle(NSLocalizedString("_display_", comment: ""))
.defaultViewModifier(model)
Expand Down
24 changes: 24 additions & 0 deletions iOSClient/Settings/NCKeychain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,30 @@ import KeychainAccess
}
}

var screenAwakeMode: AwakeMode {
get {
if let value = try? keychain.get("screenAwakeMode") {
if value == "off" {
return .off
} else if value == "on" {
return .on
} else {
return .whileCharging
}
}
return .off
}
set {
if newValue == .off {
keychain["screenAwakeMode"] = "off"
} else if newValue == .on {
keychain["screenAwakeMode"] = "on"
} else {
keychain["screenAwakeMode"] = "whileCharging"
}
}
}

var fileNameType: Bool {
get {
if let value = try? keychain.get("fileNameType"), let result = Bool(value) {
Expand Down
3 changes: 3 additions & 0 deletions iOSClient/Supporting Files/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,9 @@
"_users_" = "Users";
"_users_footer_" = "Every time the app is reactivated, the account will be requested.";
"_additional_view_options_" = "Additional view options";
"_while_charging_" = "While charging";
"_additional_options_" = "Additional options";
"_keep_screen_awake_" = "Keep screen awake while transfering files";

// Video
"_select_trace_" = "Select the trace";
Expand Down
34 changes: 34 additions & 0 deletions iOSClient/Utility/ScreenAwakeManager/AwakeMode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// AwakeMode.swift
// Nextcloud
//
// Created by Milen Pivchev on 18.09.24.
// Copyright © 2024 Marino Faggiana. All rights reserved.
//

import Foundation

/**
Modes:

- `disabled`: Nothing will change (disabled functionality).
- `always`: Device will never timeout and lock.
- `whenCharging`: Device will stay active as long as it's connected to charger.

*/
enum AwakeMode: CaseIterable, Identifiable {
/**
Nothing will change (disabled functionality).
*/
case off
/**
Device will never timeout and lock.
*/
case on
/**
Device will stay active as long as it's connected to charger.
*/
case whileCharging

var id: Self { self }
}
90 changes: 90 additions & 0 deletions iOSClient/Utility/ScreenAwakeManager/ScreenAwakeManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// ScreenAwakeManager.swift
// Nextcloud
//
// Created by Milen Pivchev on 18.09.24.
// Copyright © 2024 Marino Faggiana. All rights reserved.
//

// Modified from https://github.com/ochococo/Insomnia
import UIKit

/**

Sometimes you want your iPhone to stay active a little bit longer is it an import or just game interface.

This simple class aims to simplify the code and give you a well tested solution.

*/
class ScreenAwakeManager {
static let shared: ScreenAwakeManager = {
let instance = ScreenAwakeManager()
return instance
}()

/**
This mode will change the behavior:

- `disabled`: Nothing will change (disabled functionality).
- `always`: Your iOS device will never timeout and lock.
- `whenCharging`: Device will stay active as long as it's connected to charger.

*/
var mode: AwakeMode = .off {
didSet {
updateMode()
}
}

private unowned let device = UIDevice.current
private unowned let notificationCenter = NotificationCenter.default
private unowned let application = UIApplication.shared

private init() {}

private func startMonitoring() {
device.isBatteryMonitoringEnabled = true
notificationCenter.addObserver(self,
selector: #selector(batteryStateDidChange),
name: UIDevice.batteryStateDidChangeNotification, object: nil)
}

private func stopMonitoring() {
notificationCenter.removeObserver(self)
device.isBatteryMonitoringEnabled = false
}

@objc private func batteryStateDidChange(notification: NSNotification) {
updateMode()
}

private func updateMode() {
DispatchQueue.main.async { [self] in
switch mode {
case .whileCharging:
startMonitoring()
application.isIdleTimerDisabled = isPlugged
case .on:
stopMonitoring()
application.isIdleTimerDisabled = true
case .off:
stopMonitoring()
application.isIdleTimerDisabled = false
}
}
}

private var isPlugged: Bool {
switch device.batteryState {
case .unknown, .unplugged:
return false
default:
return true
}
}

deinit {
stopMonitoring()
application.isIdleTimerDisabled = false
}
}
Loading