diff --git a/.gitignore b/.gitignore index 8e65697610..2dc70ad0f4 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,8 @@ Package.resolved *.generated.swift /.env-vars + +## CI artifacts +BuildForSimulator/ +ipaDerivedData/ +build/ \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml index 244a9c7571..ce9d049a41 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -44,8 +44,10 @@ excluded: - Pods - Tests - Brand/NCBrand.swift + - Brand/NCBrand-IONOS.swift - iOSClient/NCGlobal.swift - iOSClient/Utility/NCLivePhoto.swift - DerivedData + - ipaDerivedData reporter: "xcode" diff --git a/Brand/Alpha/File_Provider_Extension.entitlements b/Brand/Alpha/File_Provider_Extension.entitlements new file mode 100755 index 0000000000..2078b93e0e --- /dev/null +++ b/Brand/Alpha/File_Provider_Extension.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/File_Provider_Extension.plist b/Brand/Alpha/File_Provider_Extension.plist new file mode 100755 index 0000000000..c3068c30cc --- /dev/null +++ b/Brand/Alpha/File_Provider_Extension.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionFileProviderDocumentGroup + group.com.viseven.ionos.easystorage + NSExtensionFileProviderSupportsEnumeration + + NSExtensionFileProviderSupportsPickingFolders + + NSExtensionPointIdentifier + com.apple.fileprovider-nonui + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).FileProviderExtension + + + diff --git a/Brand/Alpha/File_Provider_Extension_UI.entitlements b/Brand/Alpha/File_Provider_Extension_UI.entitlements new file mode 100644 index 0000000000..2078b93e0e --- /dev/null +++ b/Brand/Alpha/File_Provider_Extension_UI.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/File_Provider_Extension_UI.plist b/Brand/Alpha/File_Provider_Extension_UI.plist new file mode 100644 index 0000000000..cdaaf4dd7a --- /dev/null +++ b/Brand/Alpha/File_Provider_Extension_UI.plist @@ -0,0 +1,44 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionFileProviderActions + + + NSExtensionFileProviderActionActivationRule + TRUEPREDICATE + NSExtensionFileProviderActionIdentifier + com.mycompany.FileProviderUI.CustomAction + NSExtensionFileProviderActionName + Custom Action + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.fileprovider-actionsui + + NSHumanReadableCopyright + + + diff --git a/Brand/Alpha/Notification_Service_Extension.entitlements b/Brand/Alpha/Notification_Service_Extension.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/Brand/Alpha/Notification_Service_Extension.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/Notification_Service_Extension.plist b/Brand/Alpha/Notification_Service_Extension.plist new file mode 100644 index 0000000000..7cba1da5f6 --- /dev/null +++ b/Brand/Alpha/Notification_Service_Extension.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Notification Service Extension + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/Brand/Alpha/Share.entitlements b/Brand/Alpha/Share.entitlements new file mode 100755 index 0000000000..2e5c24b65c --- /dev/null +++ b/Brand/Alpha/Share.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/Share.plist b/Brand/Alpha/Share.plist new file mode 100755 index 0000000000..248b825a4d --- /dev/null +++ b/Brand/Alpha/Share.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionAttributes + + NSExtensionActivationRule + SUBQUERY (extensionItems, $extensionItem, SUBQUERY ($extensionItem.attachments,$attachment,(ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.data")).@count == $extensionItem.attachments.@count).@count > 0 + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.share-services + + + diff --git a/Brand/Alpha/Widget.entitlements b/Brand/Alpha/Widget.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/Brand/Alpha/Widget.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/Widget.plist b/Brand/Alpha/Widget.plist new file mode 100644 index 0000000000..d4e598ee31 --- /dev/null +++ b/Brand/Alpha/Widget.plist @@ -0,0 +1,16 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/Brand/Alpha/WidgetDashboardIntentHandler.entitlements b/Brand/Alpha/WidgetDashboardIntentHandler.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/Brand/Alpha/WidgetDashboardIntentHandler.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/WidgetDashboardIntentHandler.plist b/Brand/Alpha/WidgetDashboardIntentHandler.plist new file mode 100644 index 0000000000..9b9988eb82 --- /dev/null +++ b/Brand/Alpha/WidgetDashboardIntentHandler.plist @@ -0,0 +1,30 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionAttributes + + IntentsRestrictedWhileLocked + + IntentsRestrictedWhileProtectedDataUnavailable + + IntentsSupported + + AccountIntent + DashboardIntent + + + NSExtensionPointIdentifier + com.apple.intents-service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).IntentHandler + + + diff --git a/Brand/Alpha/iOSClient.entitlements b/Brand/Alpha/iOSClient.entitlements new file mode 100755 index 0000000000..e564d0c656 --- /dev/null +++ b/Brand/Alpha/iOSClient.entitlements @@ -0,0 +1,28 @@ + + + + + aps-environment + development + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.network.client + + com.apple.security.personal-information.location + + com.apple.security.personal-information.photos-library + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Brand/Alpha/iOSClient.plist b/Brand/Alpha/iOSClient.plist new file mode 100755 index 0000000000..ceb43840d4 --- /dev/null +++ b/Brand/Alpha/iOSClient.plist @@ -0,0 +1,202 @@ + + + + + BGTaskSchedulerPermittedIdentifiers + + com.nextcloud.refreshTask + com.nextcloud.processingTask + + CFBundleAllowMixedLocalizations + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + it.twsweb.Nextcloud + CFBundleURLSchemes + + nextcloud + + + + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + + ITSEncryptionExportComplianceCode + 8e9f9874-938e-460b-a9be-f82cb3393971 + LSApplicationQueriesSchemes + + nextcloudtalk + nextcloudnotes + + LSMinimumSystemVersion + 12.3 + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + Camera access is required to scan documents and make photo and video. + NSFaceIDUsageDescription + Face ID is required to authenticate using face recognition. + NSLocationAlwaysAndWhenInUseUsageDescription + The app will show your location on a map. + NSLocationAlwaysUsageDescription + The app will show your location on a map. + NSLocationWhenInUseUsageDescription + The app will show your location on a map. + NSMicrophoneUsageDescription + Microphone access is required to create voice notes. + NSPhotoLibraryAddUsageDescription + Photo library access is required to upload your photos and videos to your cloud. + NSPhotoLibraryUsageDescription + Photo library access is required to upload your photos and videos to your cloud. + NSUserActivityTypes + + AccountIntent + DashboardIntent + + NSUserTrackingUsageDescription + In order to measure the quality of the programming of the app and to find crashes and errors and their cause, anonymized data from the program flow is evaluated. At no time are individual users identified, your identity remains protected. + PHPhotoLibraryPreventAutomaticLimitedAccessAlert + + UIAppFonts + + Inconsolata-Light.ttf + Inconsolata-Regular.ttf + Inconsolata-ExtraLight.ttf + Inconsolata-Medium.ttf + Inconsolata-Bold.ttf + Inconsolata-ExtraBold.ttf + Inconsolata-Black.ttf + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UIBackgroundModes + + audio + fetch + processing + remote-notification + location + + UIDesignRequiresCompatibility + + UIFileSharingEnabled + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleLightContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + UIViewControllerBasedStatusBarAppearance + + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.movie + + UTTypeDescription + Matroska Video File + UTTypeIconFiles + + UTTypeIdentifier + com.apple.quicktime.mkv + UTTypeReferenceURL + http://www.matroska.org/ + UTTypeTagSpecification + + public.filename-extension + + mkv + + + + + UTTypeConformsTo + + public.text + + UTTypeDescription + SRT Subtitle Format + UTTypeIconFiles + + UTTypeIdentifier + com.company.srt + UTTypeReferenceURL + + UTTypeTagSpecification + + public.filename-extension + + srt + + + + + + diff --git a/Brand/AppStore/File_Provider_Extension.entitlements b/Brand/AppStore/File_Provider_Extension.entitlements new file mode 100755 index 0000000000..9af7946e13 --- /dev/null +++ b/Brand/AppStore/File_Provider_Extension.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/File_Provider_Extension.plist b/Brand/AppStore/File_Provider_Extension.plist new file mode 100755 index 0000000000..d95aa09ed4 --- /dev/null +++ b/Brand/AppStore/File_Provider_Extension.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionFileProviderDocumentGroup + group.com.ionos.hidrivenext + NSExtensionFileProviderSupportsEnumeration + + NSExtensionPointIdentifier + com.apple.fileprovider-nonui + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).FileProviderExtension + + + diff --git a/Brand/AppStore/File_Provider_Extension_UI.entitlements b/Brand/AppStore/File_Provider_Extension_UI.entitlements new file mode 100644 index 0000000000..9af7946e13 --- /dev/null +++ b/Brand/AppStore/File_Provider_Extension_UI.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/File_Provider_Extension_UI.plist b/Brand/AppStore/File_Provider_Extension_UI.plist new file mode 100644 index 0000000000..cdaaf4dd7a --- /dev/null +++ b/Brand/AppStore/File_Provider_Extension_UI.plist @@ -0,0 +1,44 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionFileProviderActions + + + NSExtensionFileProviderActionActivationRule + TRUEPREDICATE + NSExtensionFileProviderActionIdentifier + com.mycompany.FileProviderUI.CustomAction + NSExtensionFileProviderActionName + Custom Action + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.fileprovider-actionsui + + NSHumanReadableCopyright + + + diff --git a/Brand/AppStore/Notification_Service_Extension.entitlements b/Brand/AppStore/Notification_Service_Extension.entitlements new file mode 100644 index 0000000000..3f397ad76f --- /dev/null +++ b/Brand/AppStore/Notification_Service_Extension.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/Notification_Service_Extension.plist b/Brand/AppStore/Notification_Service_Extension.plist new file mode 100644 index 0000000000..7cba1da5f6 --- /dev/null +++ b/Brand/AppStore/Notification_Service_Extension.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Notification Service Extension + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/Brand/AppStore/Share.entitlements b/Brand/AppStore/Share.entitlements new file mode 100755 index 0000000000..3f397ad76f --- /dev/null +++ b/Brand/AppStore/Share.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/Share.plist b/Brand/AppStore/Share.plist new file mode 100755 index 0000000000..45d00bfa98 --- /dev/null +++ b/Brand/AppStore/Share.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionAttributes + + NSExtensionActivationRule + SUBQUERY (extensionItems, $extensionItem, SUBQUERY ($extensionItem.attachments,$attachment,(ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.data")).@count == $extensionItem.attachments.@count).@count > 0 + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.share-services + + + diff --git a/Brand/AppStore/Widget.entitlements b/Brand/AppStore/Widget.entitlements new file mode 100644 index 0000000000..3f397ad76f --- /dev/null +++ b/Brand/AppStore/Widget.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/Widget.plist b/Brand/AppStore/Widget.plist new file mode 100644 index 0000000000..d4e598ee31 --- /dev/null +++ b/Brand/AppStore/Widget.plist @@ -0,0 +1,16 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/Brand/AppStore/WidgetDashboardIntentHandler.entitlements b/Brand/AppStore/WidgetDashboardIntentHandler.entitlements new file mode 100644 index 0000000000..3f397ad76f --- /dev/null +++ b/Brand/AppStore/WidgetDashboardIntentHandler.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/WidgetDashboardIntentHandler.plist b/Brand/AppStore/WidgetDashboardIntentHandler.plist new file mode 100644 index 0000000000..9b9988eb82 --- /dev/null +++ b/Brand/AppStore/WidgetDashboardIntentHandler.plist @@ -0,0 +1,30 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionAttributes + + IntentsRestrictedWhileLocked + + IntentsRestrictedWhileProtectedDataUnavailable + + IntentsSupported + + AccountIntent + DashboardIntent + + + NSExtensionPointIdentifier + com.apple.intents-service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).IntentHandler + + + diff --git a/Brand/AppStore/iOSClient.entitlements b/Brand/AppStore/iOSClient.entitlements new file mode 100755 index 0000000000..0d00dc85a2 --- /dev/null +++ b/Brand/AppStore/iOSClient.entitlements @@ -0,0 +1,28 @@ + + + + + aps-environment + development + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.ionos.hidrivenext + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.network.client + + com.apple.security.personal-information.location + + com.apple.security.personal-information.photos-library + + keychain-access-groups + + $(AppIdentifierPrefix)com.ionos.hidrivenext + + + diff --git a/Brand/AppStore/iOSClient.plist b/Brand/AppStore/iOSClient.plist new file mode 100755 index 0000000000..07abec1067 --- /dev/null +++ b/Brand/AppStore/iOSClient.plist @@ -0,0 +1,198 @@ + + + + + BGTaskSchedulerPermittedIdentifiers + + com.nextcloud.refreshTask + com.nextcloud.processingTask + + CFBundleAllowMixedLocalizations + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + it.twsweb.Nextcloud + CFBundleURLSchemes + + nextcloud + + + + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + + LSApplicationQueriesSchemes + + nextcloudtalk + nextcloudnotes + + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + Camera access is required to scan documents and make photo and video. + NSFaceIDUsageDescription + Face ID is required to authenticate using face recognition. + NSLocationAlwaysAndWhenInUseUsageDescription + The app will show your location on a map. + NSLocationAlwaysUsageDescription + The app will show your location on a map. + NSLocationWhenInUseUsageDescription + The app will show your location on a map. + NSMicrophoneUsageDescription + Microphone access is required to create voice notes. + NSPhotoLibraryAddUsageDescription + Photo library access is required to upload your photos and videos to your cloud. + NSPhotoLibraryUsageDescription + Photo library access is required to upload your photos and videos to your cloud. + NSUserActivityTypes + + AccountIntent + DashboardIntent + + NSUserTrackingUsageDescription + In order to measure the quality of the programming of the app and to find crashes and errors and their cause, anonymized data from the program flow is evaluated. At no time are individual users identified, your identity remains protected. + PHPhotoLibraryPreventAutomaticLimitedAccessAlert + + UIAppFonts + + Inconsolata-Light.ttf + Inconsolata-Regular.ttf + Inconsolata-ExtraLight.ttf + Inconsolata-Medium.ttf + Inconsolata-Bold.ttf + Inconsolata-ExtraBold.ttf + Inconsolata-Black.ttf + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UIBackgroundModes + + audio + fetch + processing + remote-notification + location + + UIDesignRequiresCompatibility + + UIFileSharingEnabled + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleLightContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + UIViewControllerBasedStatusBarAppearance + + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.movie + + UTTypeDescription + Matroska Video File + UTTypeIconFiles + + UTTypeIdentifier + com.apple.quicktime.mkv + UTTypeReferenceURL + http://www.matroska.org/ + UTTypeTagSpecification + + public.filename-extension + + mkv + + + + + UTTypeConformsTo + + public.text + + UTTypeDescription + SRT Subtitle Format + UTTypeIconFiles + + UTTypeIdentifier + com.company.srt + UTTypeReferenceURL + + UTTypeTagSpecification + + public.filename-extension + + srt + + + + + + diff --git a/Brand/Beta/File_Provider_Extension.entitlements b/Brand/Beta/File_Provider_Extension.entitlements new file mode 100755 index 0000000000..ac861b128b --- /dev/null +++ b/Brand/Beta/File_Provider_Extension.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/File_Provider_Extension.plist b/Brand/Beta/File_Provider_Extension.plist new file mode 100755 index 0000000000..180107953c --- /dev/null +++ b/Brand/Beta/File_Provider_Extension.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionFileProviderDocumentGroup + group.de.strato.ionos.easystorage.beta + NSExtensionFileProviderSupportsEnumeration + + NSExtensionPointIdentifier + com.apple.fileprovider-nonui + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).FileProviderExtension + + + diff --git a/Brand/Beta/File_Provider_Extension_UI.entitlements b/Brand/Beta/File_Provider_Extension_UI.entitlements new file mode 100644 index 0000000000..ac861b128b --- /dev/null +++ b/Brand/Beta/File_Provider_Extension_UI.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/File_Provider_Extension_UI.plist b/Brand/Beta/File_Provider_Extension_UI.plist new file mode 100644 index 0000000000..cdaaf4dd7a --- /dev/null +++ b/Brand/Beta/File_Provider_Extension_UI.plist @@ -0,0 +1,44 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionFileProviderActions + + + NSExtensionFileProviderActionActivationRule + TRUEPREDICATE + NSExtensionFileProviderActionIdentifier + com.mycompany.FileProviderUI.CustomAction + NSExtensionFileProviderActionName + Custom Action + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.fileprovider-actionsui + + NSHumanReadableCopyright + + + diff --git a/Brand/Beta/Notification_Service_Extension.entitlements b/Brand/Beta/Notification_Service_Extension.entitlements new file mode 100644 index 0000000000..6b405d1193 --- /dev/null +++ b/Brand/Beta/Notification_Service_Extension.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/Notification_Service_Extension.plist b/Brand/Beta/Notification_Service_Extension.plist new file mode 100644 index 0000000000..7cba1da5f6 --- /dev/null +++ b/Brand/Beta/Notification_Service_Extension.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Notification Service Extension + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/Brand/Beta/Share.entitlements b/Brand/Beta/Share.entitlements new file mode 100755 index 0000000000..6b405d1193 --- /dev/null +++ b/Brand/Beta/Share.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/Share.plist b/Brand/Beta/Share.plist new file mode 100755 index 0000000000..567991a236 --- /dev/null +++ b/Brand/Beta/Share.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + Nextcloud + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionAttributes + + NSExtensionActivationRule + SUBQUERY (extensionItems, $extensionItem, SUBQUERY ($extensionItem.attachments,$attachment,(ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.data")).@count == $extensionItem.attachments.@count).@count > 0 + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.share-services + + + diff --git a/Brand/Beta/Widget.entitlements b/Brand/Beta/Widget.entitlements new file mode 100644 index 0000000000..6b405d1193 --- /dev/null +++ b/Brand/Beta/Widget.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/Widget.plist b/Brand/Beta/Widget.plist new file mode 100644 index 0000000000..d4e598ee31 --- /dev/null +++ b/Brand/Beta/Widget.plist @@ -0,0 +1,16 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/Brand/Beta/WidgetDashboardIntentHandler.entitlements b/Brand/Beta/WidgetDashboardIntentHandler.entitlements new file mode 100644 index 0000000000..6b405d1193 --- /dev/null +++ b/Brand/Beta/WidgetDashboardIntentHandler.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/WidgetDashboardIntentHandler.plist b/Brand/Beta/WidgetDashboardIntentHandler.plist new file mode 100644 index 0000000000..9b9988eb82 --- /dev/null +++ b/Brand/Beta/WidgetDashboardIntentHandler.plist @@ -0,0 +1,30 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionAttributes + + IntentsRestrictedWhileLocked + + IntentsRestrictedWhileProtectedDataUnavailable + + IntentsSupported + + AccountIntent + DashboardIntent + + + NSExtensionPointIdentifier + com.apple.intents-service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).IntentHandler + + + diff --git a/Brand/Beta/iOSClient.entitlements b/Brand/Beta/iOSClient.entitlements new file mode 100755 index 0000000000..fee0b15832 --- /dev/null +++ b/Brand/Beta/iOSClient.entitlements @@ -0,0 +1,28 @@ + + + + + aps-environment + development + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.de.strato.ionos.easystorage.beta + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.network.client + + com.apple.security.personal-information.location + + com.apple.security.personal-information.photos-library + + keychain-access-groups + + $(AppIdentifierPrefix)de.strato.ionos.easystorage.beta + + + diff --git a/Brand/Beta/iOSClient.plist b/Brand/Beta/iOSClient.plist new file mode 100755 index 0000000000..094b1a6b58 --- /dev/null +++ b/Brand/Beta/iOSClient.plist @@ -0,0 +1,200 @@ + + + + + BGTaskSchedulerPermittedIdentifiers + + com.nextcloud.refreshTask + com.nextcloud.processingTask + + CFBundleAllowMixedLocalizations + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + HiDrive Next + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + it.twsweb.Nextcloud + CFBundleURLSchemes + + nextcloud + + + + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + + ITSEncryptionExportComplianceCode + 8e9f9874-938e-460b-a9be-f82cb3393971 + LSApplicationQueriesSchemes + + nextcloudtalk + nextcloudnotes + + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + Camera access is required to scan documents and make photo and video. + NSFaceIDUsageDescription + Face ID is required to authenticate using face recognition. + NSLocationAlwaysAndWhenInUseUsageDescription + The app will show your location on a map. + NSLocationAlwaysUsageDescription + The app will show your location on a map. + NSLocationWhenInUseUsageDescription + The app will show your location on a map. + NSMicrophoneUsageDescription + Microphone access is required to create voice notes. + NSPhotoLibraryAddUsageDescription + Photo library access is required to upload your photos and videos to your cloud. + NSPhotoLibraryUsageDescription + Photo library access is required to upload your photos and videos to your cloud. + NSUserActivityTypes + + AccountIntent + DashboardIntent + + NSUserTrackingUsageDescription + In order to measure the quality of the programming of the app and to find crashes and errors and their cause, anonymized data from the program flow is evaluated. At no time are individual users identified, your identity remains protected. + PHPhotoLibraryPreventAutomaticLimitedAccessAlert + + UIAppFonts + + Inconsolata-Light.ttf + Inconsolata-Regular.ttf + Inconsolata-ExtraLight.ttf + Inconsolata-Medium.ttf + Inconsolata-Bold.ttf + Inconsolata-ExtraBold.ttf + Inconsolata-Black.ttf + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UIBackgroundModes + + audio + fetch + processing + remote-notification + location + + UIDesignRequiresCompatibility + + UIFileSharingEnabled + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleLightContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + UIViewControllerBasedStatusBarAppearance + + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.movie + + UTTypeDescription + Matroska Video File + UTTypeIconFiles + + UTTypeIdentifier + com.apple.quicktime.mkv + UTTypeReferenceURL + http://www.matroska.org/ + UTTypeTagSpecification + + public.filename-extension + + mkv + + + + + UTTypeConformsTo + + public.text + + UTTypeDescription + SRT Subtitle Format + UTTypeIconFiles + + UTTypeIdentifier + com.company.srt + UTTypeReferenceURL + + UTTypeTagSpecification + + public.filename-extension + + srt + + + + + + diff --git a/Brand/File_Provider_Extension.entitlements b/Brand/File_Provider_Extension.entitlements index 4ecc3f0d13..b2d34ed1b5 100755 --- a/Brand/File_Provider_Extension.entitlements +++ b/Brand/File_Provider_Extension.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.it.twsweb.Crypto-Cloud + group.com.viseven.ionos.easystorage keychain-access-groups diff --git a/Brand/LaunchScreen.storyboard b/Brand/LaunchScreen.storyboard index 26840f6195..98ab5fbb66 100755 --- a/Brand/LaunchScreen.storyboard +++ b/Brand/LaunchScreen.storyboard @@ -1,10 +1,9 @@ - - + + - - + @@ -12,22 +11,46 @@ + + + + - + - - + + + + + + + + - - + - - - - + + + + + + + + + + + + + + + + + + + @@ -36,6 +59,7 @@ - + + diff --git a/Brand/NCBrand-IONOS.swift b/Brand/NCBrand-IONOS.swift new file mode 100644 index 0000000000..f05e71ef5d --- /dev/null +++ b/Brand/NCBrand-IONOS.swift @@ -0,0 +1,165 @@ +// +// NCBrand-IONOS.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 26.06.2024. +// Copyright © 2024 STRATO GmbH +// + +import Foundation +import UIKit + +class NCBrandOptionsIONOS: NCBrandOptions, @unchecked Sendable { + + private let custom_brand = "IONOS HiDrive Next" + private let custom_textCopyrightNextcloudiOS = "HiDrive Next iOS %@ © 2026" + private let custom_loginBaseUrl = "https://storage.ionos.fr" + private let custom_privacy = "https://wl.hidrive.com/easy/ios/privacy.html" + private let custom_sourceCode = "https://wl.hidrive.com/easy/0181" + + + //MARK: - override custom values if not default (changed by Brander) + override var brand: String { + get { + if super.brand == "Nextcloud" { + return custom_brand + } + return super.brand + } + set { + super.brand = newValue + } + } + + override var textCopyrightNextcloudiOS: String { + get { + if super.textCopyrightNextcloudiOS == "Nextcloud Matheria for iOS %@ © 2026" { + return custom_textCopyrightNextcloudiOS + } + return super.textCopyrightNextcloudiOS + } + set { + super.textCopyrightNextcloudiOS = newValue + } + } + + override var loginBaseUrl: String { + get { + if super.loginBaseUrl == "https://cloud.nextcloud.com" { + return custom_loginBaseUrl + } + return super.loginBaseUrl + } + set { + super.loginBaseUrl = newValue + } + } + + override var privacy: String { + get { + if super.privacy == "https://nextcloud.com/privacy" { + return custom_privacy + } + return super.privacy + } + set { + super.privacy = newValue + } + } + + override var sourceCode: String { + get { + if super.sourceCode == "https://github.com/nextcloud/ios" { + return custom_sourceCode + } + return super.sourceCode + } + set { + super.sourceCode = newValue + } + } + + //MARK: - + override init() { + super.init() + disable_intro = true + disable_request_login_url = true + disable_crash_service = true + +#if ALPHA + capabilitiesGroup = "group.com.viseven.ionos.easystorage" +#elseif BETA + capabilitiesGroup = "group.de.strato.ionos.easystorage.beta" +#elseif APPSTORE + capabilitiesGroup = "group.com.ionos.hidrivenext" +#else + capabilitiesGroup = "group.com.viseven.ionos.easystorage" +#endif + } +} + +extension NCBrandOptions { + var acknowloedgements: String { + "https://wl.hidrive.com/easy/0171" + } +} + +class NCBrandColorIONOS: NCBrandColor, @unchecked Sendable { + + static let ionosBrand = UIColor(red: 20.0 / 255.0, green: 116.0 / 255.0, blue: 196.0 / 255.0, alpha: 1.0) // BLUE IONOS : #1474C4 + + override func getElement(account: String?) -> UIColor { + if customer == UIColor(red: 0.0 / 255.0, green: 130.0 / 255.0, blue: 201.0 / 255.0, alpha: 1.0) { // default NC color + return NCBrandColorIONOS.ionosBrand + } + return super.getElement(account: account) + } +} + +extension NCBrandColor { + var brandElement: UIColor { + return customer + } + +#if !EXTENSION || EXTENSION_SHARE + var menuIconColor: UIColor { + UIColor(resource: .FileMenu.icon) + } + + var menuFolderIconColor: UIColor { + UIColor(resource: .FileMenu.folderIcon) + } + + var appBackgroundColor: UIColor { + UIColor(resource: .AppBackground.main) + } + + var formBackgroundColor: UIColor { + UIColor(resource: .AppBackground.form) + } + + var formRowBackgroundColor: UIColor { + UIColor(resource: .AppBackground.formRow) + } + + var formSeparatorColor: UIColor { + UIColor(resource: .formSeparator) + } +#endif + + var switchColor: UIColor { + return UIColor { traits in + let light = self.brandElement + let dark = UIColor(red: 17.0 / 255.0, green: 199.0 / 255.0, blue: 230.0 / 255.0, alpha: 1.0) + return traits.userInterfaceStyle == .dark ? dark : light + } + } + + var hudBackgroundColor: UIColor { + UIColor(resource: .AppBackground.main) + } + + var hudTextColor: UIColor { + UIColor(resource: .ListCell.title) + } +} diff --git a/Brand/NCBrand.swift b/Brand/NCBrand.swift index c53e2e82a5..ecc93d46c5 100755 --- a/Brand/NCBrand.swift +++ b/Brand/NCBrand.swift @@ -7,21 +7,12 @@ import NextcloudKit let userAgent: String = { let appVersion: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String - // Original Nextcloud useragent "Mozilla/5.0 (iOS) Nextcloud-iOS/\(appVersion)-Nextcloud" - let suffixBrand = NCBrandOptions.shared.brandUserAgent.isEmpty ? "" : "-\(NCBrandOptions.shared.brandUserAgent)" - return "Mozilla/5.0 (iOS) Nextcloud-iOS/\(appVersion)\(suffixBrand)" + // Original Nextcloud useragent "Mozilla/5.0 (iOS) Nextcloud-iOS/\(appVersion)" + return "Mozilla/5.0 (iOS) IONOS HiDrive Next/\(appVersion)" }() - /* - Codename Matheria - - Matheria represents a pivotal step forward in the evolution of our software. This release delivers substantial architectural enhancements, increased performance, and a robust foundation for future innovations. - - The codename embodies the concept of dynamic, living matter — reflecting our vision of a platform that is not only powerful and reliable, but also capable of continuous transformation and intelligent adaptation. - */ - -final class NCBrandOptions: @unchecked Sendable { - static let shared = NCBrandOptions() +class NCBrandOptions: @unchecked Sendable { + static let shared = NCBrandOptionsIONOS() var brand: String = "Nextcloud" var brandUserAgent: String = "" @@ -145,8 +136,8 @@ final class NCBrandOptions: @unchecked Sendable { } } -final class NCBrandColor: @unchecked Sendable { - static let shared = NCBrandColor() +class NCBrandColor: @unchecked Sendable { + static let shared = NCBrandColorIONOS() // This is rewrited from customet theme, default is Nextcloud color let customer: UIColor = UIColor(red: 0.0 / 255.0, green: 130.0 / 255.0, blue: 201.0 / 255.0, alpha: 1.0) // Nextcloud : #0082C9 @@ -158,7 +149,7 @@ final class NCBrandColor: @unchecked Sendable { private var themingColorText = ThreadSafeDictionary() var userColors: [CGColor] = [] - let yellowFavorite: UIColor = UIColor(red: 0.6118, green: 0.4549, blue: 0.1451, alpha: 1.0) + let yellowFavorite: UIColor = UIColor(red: 248.0 / 255.0, green: 205.0 / 255.0, blue: 70.0 / 255.0, alpha: 1.0) let iconImageColor: UIColor = .label let iconImageColor2: UIColor = .secondaryLabel let iconImageMultiColors: [UIColor] = [.secondaryLabel, .label] diff --git a/Brand/iOSClient.plist b/Brand/iOSClient.plist index cff62ea040..898210ad88 100755 --- a/Brand/iOSClient.plist +++ b/Brand/iOSClient.plist @@ -83,6 +83,8 @@ AccountIntent DashboardIntent + NSUserTrackingUsageDescription + In order to measure the quality of the programming of the app and to find crashes and errors and their cause, anonymized data from the program flow is evaluated. At no time are individual users identified, your identity remains protected. PHPhotoLibraryPreventAutomaticLimitedAccessAlert UIAppFonts @@ -120,6 +122,8 @@ remote-notification location + UIDesignRequiresCompatibility + UIFileSharingEnabled UILaunchStoryboardName diff --git a/File Provider Extension UI/File Provider Extension UIDebug.entitlements b/File Provider Extension UI/File Provider Extension UIDebug.entitlements new file mode 100644 index 0000000000..2078b93e0e --- /dev/null +++ b/File Provider Extension UI/File Provider Extension UIDebug.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/File Provider Extension/File Provider ExtensionDebug.entitlements b/File Provider Extension/File Provider ExtensionDebug.entitlements new file mode 100644 index 0000000000..2078b93e0e --- /dev/null +++ b/File Provider Extension/File Provider ExtensionDebug.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/File Provider Extension/FileProviderItem.swift b/File Provider Extension/FileProviderItem.swift index fc77dbbe40..e0e1356520 100644 --- a/File Provider Extension/FileProviderItem.swift +++ b/File Provider Extension/FileProviderItem.swift @@ -112,6 +112,9 @@ class FileProviderItem: NSObject, NSFileProviderItem { } } /// Sharing + var isShared: Bool { + return !metadata.shareType.isEmpty + } /// Managing Metadata var tagData: Data? { return nil diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index bd63ff8683..594d8e7080 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -3,16 +3,70 @@ archiveVersion = 1; classes = { }; - objectVersion = 70; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ + 0F08D6B92C94270600136502 /* ButtonStyleGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F08D6B82C94270600136502 /* ButtonStyleGuide.swift */; }; + 0F08D6BB2C94275600136502 /* CircleItemSpinner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F08D6BA2C94275600136502 /* CircleItemSpinner.swift */; }; + 0F4AA77C2DE083D600138679 /* NCMainTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F4AA77B2DE083D600138679 /* NCMainTabBar.swift */; }; + 0F4AA7812DE0A3F700138679 /* NCLoginNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F4AA77E2DE0A3F700138679 /* NCLoginNavigationController.swift */; }; + 0F5090CE2C786F04009348D9 /* FileActionsHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5090CD2C786F04009348D9 /* FileActionsHeader.swift */; }; + 0F8615AC2CBE6AC20056B4F2 /* UITabBarGuideline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F8615AB2CBE6AC20056B4F2 /* UITabBarGuideline.swift */; }; + 0F8B9A5B2C7887F60041C17D /* FileActionsHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0F8B9A5A2C7887F60041C17D /* FileActionsHeader.xib */; }; + 0F9DB9BA2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9DB9BB2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9DB9BC2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9DB9BD2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9DB9BE2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9DB9BF2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9DB9C12DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */; }; + 0F9E787D2DD77EB8007980BF /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; + 0F9E787E2DD77EB8007980BF /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; + 0F9E787F2DD77ECE007980BF /* Custom.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F700222B1EC479840080073F /* Custom.xcassets */; }; + 0F9E78802DD77ECE007980BF /* Custom.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F700222B1EC479840080073F /* Custom.xcassets */; }; + 0F9E78812DD77F0A007980BF /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; + 0F9E78822DD77F0A007980BF /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; 2C1D5D7623E2DE3300334ABB /* NCManageDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BAADB51ED5A87C00B7EAD4 /* NCManageDatabase.swift */; }; 2C1D5D7923E2DE9100334ABB /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; }; 2C33C48223E2C475005F963B /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C33C48123E2C475005F963B /* NotificationService.swift */; }; 2C33C48623E2C475005F963B /* Notification Service Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2C33C47F23E2C475005F963B /* Notification Service Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 2F96A1BAFB10ACFEAC68EF1C /* NCContextMenuPlayerTracks.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C7A5B36D1ED178FB6B76CB /* NCContextMenuPlayerTracks.swift */; }; - 370D26AF248A3D7A00121797 /* NCCellMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D26AE248A3D7A00121797 /* NCCellMain.swift */; }; + 420216572F557C9100BBD630 /* NCMediaCoordinatorVLCStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420216562F557C7F00BBD630 /* NCMediaCoordinatorVLCStrategy.swift */; }; + 420216592F557CB100BBD630 /* NCMediaCoordinatorAVKitStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420216582F557CA300BBD630 /* NCMediaCoordinatorAVKitStrategy.swift */; }; + 4202165D2F5586D800BBD630 /* NCMediaCoordinatorStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4202165C2F5586D300BBD630 /* NCMediaCoordinatorStrategy.swift */; }; + 420274712F11558400ECB06B /* NCCellMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4202746F2F11557500ECB06B /* NCCellMedia.swift */; }; + 421657AB2D2AF2BF003BC9D5 /* HiDriveCollectionViewCommonSelectToolbarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421657AA2D2AF2BF003BC9D5 /* HiDriveCollectionViewCommonSelectToolbarDelegate.swift */; }; + 421DC45F2F6D38F3001EE5E3 /* ItemShareState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421DC45E2F6D38F3001EE5E3 /* ItemShareState.swift */; }; + 4232DC0A2C9D7C44008D546D /* UIView+GridSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4232DC092C9D7C44008D546D /* UIView+GridSelection.swift */; }; + 4232DC0B2C9D7C44008D546D /* UIView+GridSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4232DC092C9D7C44008D546D /* UIView+GridSelection.swift */; }; + 4240DB4E2C5646B400E72FC0 /* BurgerMenuAttachController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4240DB4D2C5646B400E72FC0 /* BurgerMenuAttachController.swift */; }; + 4240DB502C5648E300E72FC0 /* BurgerMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4240DB4F2C5648E300E72FC0 /* BurgerMenuViewController.swift */; }; + 4240DB522C5649A900E72FC0 /* BurgerMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4240DB512C5649A900E72FC0 /* BurgerMenuView.swift */; }; + 4250C8472E2E53BA00349A8A /* NCMediaCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4250C8462E2E53B400349A8A /* NCMediaCoordinator.swift */; }; + 425F57AF2D2E83DB006D5FD1 /* IonosImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 425F57AE2D2E83DA006D5FD1 /* IonosImages.xcassets */; }; + 425F57B02D2E83DB006D5FD1 /* IonosImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 425F57AE2D2E83DA006D5FD1 /* IonosImages.xcassets */; }; + 425F57B12D2E83DB006D5FD1 /* IonosImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 425F57AE2D2E83DA006D5FD1 /* IonosImages.xcassets */; }; + 426533642F698AD70092B12B /* NCCellMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 426533632F698AD70092B12B /* NCCellMain.swift */; }; + 426533652F698AD70092B12B /* NCCellMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 426533632F698AD70092B12B /* NCCellMain.swift */; }; + 42678ABE2C57C5FB00307DEF /* BurgerMenuViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42678ABD2C57C5FB00307DEF /* BurgerMenuViewModel.swift */; }; + 426D0F892D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 426D0F872D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbar.swift */; }; + 426D0F8A2D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 426D0F882D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbarView.swift */; }; + 426E38DD2F571E8D0073EE47 /* NCMediaCoordinatorConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 426E38DC2F571E890073EE47 /* NCMediaCoordinatorConstants.swift */; }; + 428915312F226C1500B41486 /* PlaybackProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 428915302F226C1500B41486 /* PlaybackProgressView.swift */; }; + 4294B88B2CA5550B002E6FED /* LinkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4294B88A2CA5550B002E6FED /* LinkButton.swift */; }; + 42C684B42CA1806000DD46F0 /* SecondaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C684B32CA1806000DD46F0 /* SecondaryButton.swift */; }; + 42C684B72CA1A20100DD46F0 /* CommonButtonConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C684B62CA1A20100DD46F0 /* CommonButtonConstants.swift */; }; + 42D34FD92D79A5B00020C106 /* ShareSearchField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42D34FD82D79A5B00020C106 /* ShareSearchField.swift */; }; + 42D3D0972C94284C008A5AD4 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; + 42E5D36B2D678F9C007150DE /* HiDriveMainNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E5D36A2D678F95007150DE /* HiDriveMainNavigationController.swift */; }; + 42F504802C6F553D001AA432 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; + 42F89EB12D71F30C00550A07 /* NCCollectionViewCommon+FileActionsHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F89EB02D71F30C00550A07 /* NCCollectionViewCommon+FileActionsHeader.swift */; }; + 42F907DE2D2C424900BCDC36 /* View+Design.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F907DD2D2C424100BCDC36 /* View+Design.swift */; }; + 6256F5462C9846DE0032A1CF /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8A390295DC5E0006CB2D0 /* View+Extension.swift */; }; + 625EC26E2C6CA285006411D1 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 625EC26D2C6CA285006411D1 /* FirebaseAnalytics */; }; + 625EC2712C6CAABD006411D1 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 625EC2702C6CAABD006411D1 /* GoogleService-Info.plist */; }; + 62A63F2E2C8AF5320048653E /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8A390295DC5E0006CB2D0 /* View+Extension.swift */; }; + 62A63F302C8AF7730048653E /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F5047F2C6F553D001AA432 /* Colors.xcassets */; }; A5A87F9E4B0E4441A6A4BC20 /* NCContextMenuProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7697C94BA14450A0867940 /* NCContextMenuProfile.swift */; }; AA3C85E82D36B08C00F74F12 /* UITestBackend.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3C85E72D36B08C00F74F12 /* UITestBackend.swift */; }; AA3C85EB2D36BBFB00F74F12 /* OCSResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3C85EA2D36BBF400F74F12 /* OCSResponse.swift */; }; @@ -83,10 +137,25 @@ AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; }; AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* Shareable.swift */; }; CB3666201AF7550816B5CD6A /* NCContextMenuComment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8932E90EC4278026D86CCCC9 /* NCContextMenuComment.swift */; }; + D52D53EF2F0DCD1600D824BF /* NCMediaSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420113DB2D1303E00063BF54 /* NCMediaSelectTabBar.swift */; }; + D52D53F32F0DD53300D824BF /* AccountButtonFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52D53F22F0DD53300D824BF /* AccountButtonFactory.swift */; }; + D52D54022F0DE1BE00D824BF /* NCManageDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340EB2EBDE7420056F538 /* NCManageDatabase.swift */; }; + D59793B62CF7A73A00C44F4E /* DataProtectionAgreementManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59793B52CF7A73A00C44F4E /* DataProtectionAgreementManager.swift */; }; + D59D37CC2F0ECAEC0072C824 /* NCManageDatabase+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340FB2EBDF64A0056F538 /* NCManageDatabase+Tag.swift */; }; + D59D37CE2F0EDAEC0072C824 /* UIDevice+VirtualOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59D37CD2F0EDAEC0072C824 /* UIDevice+VirtualOrientation.swift */; }; + D59D37D02F0EE97C0072C824 /* TransfersListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59D37CF2F0EE97C0072C824 /* TransfersListener.swift */; }; + D59D37D72F1082F60072C824 /* NCBackgroundLocationUploadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59D37D22F1082F50072C824 /* NCBackgroundLocationUploadManager.swift */; }; D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */; }; + D5C2D21F2C9DC0EF00E7579D /* PrimaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C2D21E2C9DC0EF00E7579D /* PrimaryButton.swift */; }; + D5C5133B2C91970B00AE35CA /* NCImagesRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C5133A2C91970B00AE35CA /* NCImagesRepository.swift */; }; + D5C5133E2C919B8500AE35CA /* NCImagesRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C5133A2C91970B00AE35CA /* NCImagesRepository.swift */; }; + D5E1D4FC2CF4A99300813AB6 /* DataProtectionAgreementScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E1D4FB2CF4A99200813AB6 /* DataProtectionAgreementScreen.swift */; }; + D5E1D4FE2CF4E7C600813AB6 /* DataProtectionSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E1D4FD2CF4E7C600813AB6 /* DataProtectionSettingsScreen.swift */; }; + D5E1D5002CF4EB3900813AB6 /* DataProtectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E1D4FF2CF4EB3900813AB6 /* DataProtectionModel.swift */; }; + D5E1D5042CF665C100813AB6 /* DataProtectionHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E1D5032CF665C100813AB6 /* DataProtectionHostingController.swift */; }; + D5EB5DD42F490D2F009D88B1 /* NCContextMenuPlayerTracks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5EB5DD32F490D2E009D88B1 /* NCContextMenuPlayerTracks.swift */; }; F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */; }; F317C82E2E844C5300761AEA /* ClientIntegrationUIViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F317C82D2E844C5300761AEA /* ClientIntegrationUIViewer.swift */; }; - F321DA8A2B71205A00DDA0E6 /* NCTrashSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */; }; F32FADA92D1176E3007035E2 /* UIButton+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32FADA82D1176DE007035E2 /* UIButton+Extension.swift */; }; F3374A812D64AB9F002A38F9 /* StatusInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3374A802D64AB9E002A38F9 /* StatusInfo.swift */; }; F3374A842D64AC31002A38F9 /* AssistantLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3374A832D64AC2C002A38F9 /* AssistantLabelStyle.swift */; }; @@ -143,7 +212,6 @@ F3754A7D2CF87D600009312E /* SetupPasscodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3754A7C2CF87D600009312E /* SetupPasscodeView.swift */; }; F376A3742E5CC6030067EE25 /* ContextMenuActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F376A3732E5CC5FF0067EE25 /* ContextMenuActions.swift */; }; F389C9F52CEE383300049762 /* SelectAlbumView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F389C9F42CEE383300049762 /* SelectAlbumView.swift */; }; - F38F71252B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F38F71242B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift */; }; F39170AD2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; F39170AF2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; F39298972A3B12CB00509762 /* BaseNCMoreCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39298962A3B12CB00509762 /* BaseNCMoreCell.swift */; }; @@ -250,7 +318,6 @@ F717402D24F699A5000C87D5 /* NCFavorite.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F717402B24F699A5000C87D5 /* NCFavorite.storyboard */; }; F717402E24F699A5000C87D5 /* NCFavorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = F717402C24F699A5000C87D5 /* NCFavorite.swift */; }; F718C24E254D507B00C5C256 /* NCViewerMediaDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F718C24D254D507B00C5C256 /* NCViewerMediaDetailView.swift */; }; - F718E25A2DF2D5D1004038AF /* NCBackgroundLocationUploadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F718E2572DF2D5C3004038AF /* NCBackgroundLocationUploadManager.swift */; }; F71916122E2901FB00E13E96 /* NCNetworking+Upload.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71916102E2901E800E13E96 /* NCNetworking+Upload.swift */; }; F71916142E2901FB00E13E96 /* NCNetworking+Upload.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71916102E2901E800E13E96 /* NCNetworking+Upload.swift */; }; F719D9E0288D37A300762E33 /* NCColorPicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F719D9DF288D37A300762E33 /* NCColorPicker.storyboard */; }; @@ -266,7 +333,6 @@ F71F6D0C2B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71F6D062B6A6A5E00F1EB15 /* ThreadSafeArray.swift */; }; F71F6D0D2B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71F6D062B6A6A5E00F1EB15 /* ThreadSafeArray.swift */; }; F71FA7992F3508C600E86192 /* NCNetworking+WebDAV.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7327E2F2B73A86700A462C7 /* NCNetworking+WebDAV.swift */; }; - F722133B2D40EF9D002F7438 /* NCFilesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F722133A2D40EF8C002F7438 /* NCFilesNavigationController.swift */; }; F7226EDC1EE4089300EBECB1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7226EDB1EE4089300EBECB1 /* Main.storyboard */; }; F722F0112CFF569500065FB5 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F722F0102CFF569500065FB5 /* MainInterface.storyboard */; }; F723985C253C95CE00257F49 /* NCViewerRichdocument.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F723985B253C95CE00257F49 /* NCViewerRichdocument.storyboard */; }; @@ -362,7 +428,6 @@ F73F537F1E929C8500F8678D /* NCMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73F537E1E929C8500F8678D /* NCMore.swift */; }; F740BEF02A35C2AD00E9B6D5 /* UILabel+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7EE66AC2A20B226009AE765 /* UILabel+Extension.swift */; }; F7411C552D7B26D700F57358 /* NCNetworking+ServerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7411C532D7B26C600F57358 /* NCNetworking+ServerError.swift */; }; - F741C2242B6B9FD600E849BB /* NCMediaSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F741C2232B6B9FD600E849BB /* NCMediaSelectTabBar.swift */; }; F74230F32C79B57200CA1ACA /* NCNetworking+Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74230F22C79B57200CA1ACA /* NCNetworking+Task.swift */; }; F7434B3820E2400600417916 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; }; F743C89E2E5B25A1000173A9 /* UIScene+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F743C89D2E5B2595000173A9 /* UIScene+Extension.swift */; }; @@ -442,7 +507,6 @@ F761856B29E98543006EB3B0 /* NCIntroViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F761856729E98543006EB3B0 /* NCIntroViewController.swift */; }; F761856C29E98543006EB3B0 /* NCIntroCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F761856829E98543006EB3B0 /* NCIntroCollectionViewCell.swift */; }; F761856D29E98543006EB3B0 /* NCIntroCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F761856929E98543006EB3B0 /* NCIntroCollectionViewCell.xib */; }; - F76340ED2EBDE74C0056F538 /* NCManageDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340EB2EBDE7420056F538 /* NCManageDatabase.swift */; }; F76340EE2EBDE74C0056F538 /* NCManageDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340EB2EBDE7420056F538 /* NCManageDatabase.swift */; }; F76340F42EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340F32EBDE9740056F538 /* NCManageDatabaseCore.swift */; }; F76340F52EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340F32EBDE9740056F538 /* NCManageDatabaseCore.swift */; }; @@ -490,6 +554,7 @@ F76882282C0DD1E7001CF441 /* NCEndToEndInitialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = F768820F2C0DD1E7001CF441 /* NCEndToEndInitialize.swift */; }; F76882292C0DD1E7001CF441 /* NCManageE2EEModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76882102C0DD1E7001CF441 /* NCManageE2EEModel.swift */; }; F768822A2C0DD1E7001CF441 /* NCSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76882112C0DD1E7001CF441 /* NCSettingsModel.swift */; }; + F768822B2C0DD1E7001CF441 /* (null) in Resources */ = {isa = PBXBuildFile; }; F768822C2C0DD1E7001CF441 /* NCPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76882132C0DD1E7001CF441 /* NCPreferences.swift */; }; F768822D2C0DD1E7001CF441 /* Acknowledgements.rtf in Resources */ = {isa = PBXBuildFile; fileRef = F76882142C0DD1E7001CF441 /* Acknowledgements.rtf */; }; F768822E2C0DD1E7001CF441 /* NCSettingsBundleHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76882152C0DD1E7001CF441 /* NCSettingsBundleHelper.swift */; }; @@ -640,7 +705,6 @@ F793E59D28B761E7005E4B02 /* NCNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75A9EE523796C6F0044CFCE /* NCNetworking.swift */; }; F794E13D2BBBFF2E003693D7 /* NCMainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F794E13C2BBBFF2E003693D7 /* NCMainTabBarController.swift */; }; F794E13F2BBC0F70003693D7 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F794E13E2BBC0F70003693D7 /* SceneDelegate.swift */; }; - F79699E72E689F68000EC82A /* NCMediaNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79699E62E689F68000EC82A /* NCMediaNavigationController.swift */; }; F798F0E225880608000DAFFD /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extension.swift */; }; F798F0EC2588060A000DAFFD /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extension.swift */; }; F799DF822C4B7DCC003410B5 /* NCSectionFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F799DF812C4B7DCC003410B5 /* NCSectionFooter.swift */; }; @@ -661,9 +725,6 @@ F79EDAA526B004980007D134 /* NCPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79EDAA126B004980007D134 /* NCPlayer.swift */; }; F79FFB262A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */; }; F79FFB272A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */; }; - F7A03E2F2D425A14007AA677 /* NCFavoriteNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A03E2E2D425A14007AA677 /* NCFavoriteNavigationController.swift */; }; - F7A03E332D426115007AA677 /* NCMoreNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A03E322D426115007AA677 /* NCMoreNavigationController.swift */; }; - F7A03E352D427312007AA677 /* NCMainNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A03E342D427308007AA677 /* NCMainNavigationController.swift */; }; F7A0D1352591FBC5008F8A13 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; }; F7A0D1362591FBC5008F8A13 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; }; F7A1050E29E587AF00FFD92B /* TagListView in Frameworks */ = {isa = PBXBuildFile; productRef = F7A1050D29E587AF00FFD92B /* TagListView */; }; @@ -708,7 +769,6 @@ F7B769AB2B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B769A72B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift */; }; F7B769AE2B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B769A72B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift */; }; F7B82F182EBFA3B700F5F242 /* NCNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75A9EE523796C6F0044CFCE /* NCNetworking.swift */; }; - F7B8B83025681C3400967775 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = F7B8B82F25681C3400967775 /* GoogleService-Info.plist */; }; F7B8F6142EAB64AD006A70D6 /* JDStatusBarNotification in Frameworks */ = {isa = PBXBuildFile; productRef = F7B8F6132EAB64AD006A70D6 /* JDStatusBarNotification */; }; F7B8F6162EAB7503006A70D6 /* JDStatusBarNotification in Frameworks */ = {isa = PBXBuildFile; productRef = F7B8F6152EAB7503006A70D6 /* JDStatusBarNotification */; }; F7B8F6182EAB7516006A70D6 /* JDStatusBarNotification in Frameworks */ = {isa = PBXBuildFile; productRef = F7B8F6172EAB7516006A70D6 /* JDStatusBarNotification */; }; @@ -831,7 +891,6 @@ F7D61EAA2EBF1694007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D61EA52EBF168E007F865B /* NCManageDatabase+TableCapabilities.swift */; }; F7D61EAB2EBF16B6007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D61EA52EBF168E007F865B /* NCManageDatabase+TableCapabilities.swift */; }; F7D61EAC2EBF16B6007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D61EA52EBF168E007F865B /* NCManageDatabase+TableCapabilities.swift */; }; - F7D61EBD2EBF1878007F865B /* NCManageDatabase+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340FB2EBDF64A0056F538 /* NCManageDatabase+Tag.swift */; }; F7D61EBE2EBF1878007F865B /* NCManageDatabase+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340FB2EBDF64A0056F538 /* NCManageDatabase+Tag.swift */; }; F7D61EBF2EBF1878007F865B /* NCManageDatabase+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340FB2EBDF64A0056F538 /* NCManageDatabase+Tag.swift */; }; F7D61EC02EBF1878007F865B /* NCManageDatabase+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76340FB2EBDF64A0056F538 /* NCManageDatabase+Tag.swift */; }; @@ -879,7 +938,6 @@ F7EB9B132BBC12F300EDF036 /* UIApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7EB9B122BBC12F300EDF036 /* UIApplication+Extension.swift */; }; F7ED547C25EEA65400956C55 /* QRCodeReader in Frameworks */ = {isa = PBXBuildFile; productRef = F7ED547B25EEA65400956C55 /* QRCodeReader */; }; F7EDE4D6262D7B9600414FE6 /* NCListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78ACD4121903CE00088454D /* NCListCell.swift */; }; - F7EDE4DB262D7BA200414FE6 /* NCCellMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D26AE248A3D7A00121797 /* NCCellMain.swift */; }; F7EDE509262DA9D600414FE6 /* NCSelectCommandViewSelect.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7EDE508262DA9D600414FE6 /* NCSelectCommandViewSelect.xib */; }; F7EDE514262DC2CD00414FE6 /* NCSelectCommandViewSelect+CreateFolder.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7EDE513262DC2CD00414FE6 /* NCSelectCommandViewSelect+CreateFolder.xib */; }; F7EDE51B262DD0C400414FE6 /* NCSelectCommandViewCopyMove.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7EDE51A262DD0C400414FE6 /* NCSelectCommandViewCopyMove.xib */; }; @@ -922,6 +980,8 @@ F7FDFF702E437E55000D7688 /* NCAccountRequest.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7FDFF512E437E55000D7688 /* NCAccountRequest.storyboard */; }; F7FDFF722E437E55000D7688 /* NCAccountRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7FDFF522E437E55000D7688 /* NCAccountRequest.swift */; }; F7FF2CB12842159500EBB7A1 /* NCSectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7FF2CB02842159500EBB7A1 /* NCSectionHeader.xib */; }; + FC930DC52CEDE33000C9B237 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC930DC42CEDE33000C9B237 /* Colors.xcassets */; }; + FC930DC72CEE377700C9B237 /* WidgetCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC930DC62CEE377700C9B237 /* WidgetCommon.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1111,66 +1171,67 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0F08D6B82C94270600136502 /* ButtonStyleGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonStyleGuide.swift; sourceTree = ""; }; + 0F08D6BA2C94275600136502 /* CircleItemSpinner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleItemSpinner.swift; sourceTree = ""; }; + 0F4374A82D8442BA0081F7C3 /* config */ = {isa = PBXFileReference; lastKnownFileType = text; path = config; sourceTree = ""; }; + 0F4AA77B2DE083D600138679 /* NCMainTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMainTabBar.swift; sourceTree = ""; }; + 0F4AA77E2DE0A3F700138679 /* NCLoginNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginNavigationController.swift; sourceTree = ""; }; + 0F5090CD2C786F04009348D9 /* FileActionsHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileActionsHeader.swift; sourceTree = ""; }; + 0F85B8942DB7D61100D089AE /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 0F8615AB2CBE6AC20056B4F2 /* UITabBarGuideline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarGuideline.swift; sourceTree = ""; }; + 0F8B9A5A2C7887F60041C17D /* FileActionsHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FileActionsHeader.xib; sourceTree = ""; }; + 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCBrand-IONOS.swift"; sourceTree = ""; }; + 0FAEC1B32DBA3F2A001A60D9 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 2C33C47F23E2C475005F963B /* Notification Service Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Notification Service Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 2C33C48123E2C475005F963B /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; 2C33C48A23E2CC26005F963B /* Notification_Service_Extension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Notification_Service_Extension-Bridging-Header.h"; sourceTree = ""; }; - 370D26AE248A3D7A00121797 /* NCCellMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCellMain.swift; sourceTree = ""; }; + 420113DB2D1303E00063BF54 /* NCMediaSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaSelectTabBar.swift; sourceTree = ""; }; + 420216562F557C7F00BBD630 /* NCMediaCoordinatorVLCStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaCoordinatorVLCStrategy.swift; sourceTree = ""; }; + 420216582F557CA300BBD630 /* NCMediaCoordinatorAVKitStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaCoordinatorAVKitStrategy.swift; sourceTree = ""; }; + 4202165C2F5586D300BBD630 /* NCMediaCoordinatorStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaCoordinatorStrategy.swift; sourceTree = ""; }; + 4202746F2F11557500ECB06B /* NCCellMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCellMedia.swift; sourceTree = ""; }; + 4216512A2E28F654002E19D6 /* NextcloudDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NextcloudDebug.entitlements; sourceTree = ""; }; + 4216512B2E28F685002E19D6 /* WidgetDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetDebug.entitlements; sourceTree = ""; }; + 4216512C2E28F6A4002E19D6 /* WidgetDashboardIntentHandlerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetDashboardIntentHandlerDebug.entitlements; sourceTree = ""; }; + 4216512D2E28F6BB002E19D6 /* ShareDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareDebug.entitlements; sourceTree = ""; }; + 4216512E2E28F6D3002E19D6 /* File Provider ExtensionDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "File Provider ExtensionDebug.entitlements"; sourceTree = ""; }; + 4216512F2E28F6DC002E19D6 /* File Provider Extension UIDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "File Provider Extension UIDebug.entitlements"; sourceTree = ""; }; + 421651302E28F6ED002E19D6 /* Notification Service ExtensionDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Notification Service ExtensionDebug.entitlements"; sourceTree = ""; }; + 421657AA2D2AF2BF003BC9D5 /* HiDriveCollectionViewCommonSelectToolbarDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiDriveCollectionViewCommonSelectToolbarDelegate.swift; sourceTree = ""; }; + 421DC45E2F6D38F3001EE5E3 /* ItemShareState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemShareState.swift; sourceTree = ""; }; + 42226BFC2FB76B7E0018A519 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intent.strings; sourceTree = ""; }; + 4232DC092C9D7C44008D546D /* UIView+GridSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+GridSelection.swift"; sourceTree = ""; }; + 4240DB4D2C5646B400E72FC0 /* BurgerMenuAttachController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurgerMenuAttachController.swift; sourceTree = ""; }; + 4240DB4F2C5648E300E72FC0 /* BurgerMenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurgerMenuViewController.swift; sourceTree = ""; }; + 4240DB512C5649A900E72FC0 /* BurgerMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurgerMenuView.swift; sourceTree = ""; }; + 4250C8462E2E53B400349A8A /* NCMediaCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaCoordinator.swift; sourceTree = ""; }; + 425F57AE2D2E83DA006D5FD1 /* IonosImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = IonosImages.xcassets; sourceTree = ""; }; + 426533632F698AD70092B12B /* NCCellMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCellMain.swift; sourceTree = ""; }; + 42678ABD2C57C5FB00307DEF /* BurgerMenuViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurgerMenuViewModel.swift; sourceTree = ""; }; + 426D0F872D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiDriveCollectionViewCommonSelectToolbar.swift; sourceTree = ""; }; + 426D0F882D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiDriveCollectionViewCommonSelectToolbarView.swift; sourceTree = ""; }; + 426E38DC2F571E890073EE47 /* NCMediaCoordinatorConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaCoordinatorConstants.swift; sourceTree = ""; }; + 428915302F226C1500B41486 /* PlaybackProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackProgressView.swift; sourceTree = ""; }; + 4294B88A2CA5550B002E6FED /* LinkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkButton.swift; sourceTree = ""; }; + 42C684B32CA1806000DD46F0 /* SecondaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondaryButton.swift; sourceTree = ""; }; + 42C684B62CA1A20100DD46F0 /* CommonButtonConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonButtonConstants.swift; sourceTree = ""; }; + 42D34FD82D79A5B00020C106 /* ShareSearchField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareSearchField.swift; sourceTree = ""; }; + 42E5D36A2D678F95007150DE /* HiDriveMainNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiDriveMainNavigationController.swift; sourceTree = ""; }; + 42F5047F2C6F553D001AA432 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; + 42F89EB02D71F30C00550A07 /* NCCollectionViewCommon+FileActionsHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+FileActionsHeader.swift"; sourceTree = ""; }; + 42F907DD2D2C424100BCDC36 /* View+Design.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Design.swift"; sourceTree = ""; }; + 625EC2702C6CAABD006411D1 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; }; 8932E90EC4278026D86CCCC9 /* NCContextMenuComment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuComment.swift; sourceTree = ""; }; AA3C85E72D36B08C00F74F12 /* UITestBackend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestBackend.swift; sourceTree = ""; }; AA3C85EA2D36BBF400F74F12 /* OCSResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OCSResponse.swift; sourceTree = ""; }; AA3C85ED2D36BCCB00F74F12 /* SharesResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharesResponse.swift; sourceTree = ""; }; AA3C85F12D394B3600F74F12 /* DownloadLimitResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadLimitResponse.swift; sourceTree = ""; }; AA517B7F2D660EFE00F8D37C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = "Supporting Files/en.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B842D660F5200F8D37C /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = eu; path = "Supporting Files/eu.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B852D660F5800F8D37C /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ca; path = "Supporting Files/ca.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B862D660F6100F8D37C /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hans"; path = "Supporting Files/zh-Hans.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B872D660F6200F8D37C /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hant-TW"; path = "Supporting Files/zh-Hant-TW.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B882D660F6300F8D37C /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hr; path = "Supporting Files/hr.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B892D660F6400F8D37C /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "cs-CZ"; path = "Supporting Files/cs-CZ.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B8A2D660F6500F8D37C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = da; path = "Supporting Files/da.lproj/Localizable.stringsdict"; sourceTree = ""; }; AA517B8B2D660F6600F8D37C /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nl; path = "Supporting Files/nl.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B8C2D660F6600F8D37C /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "en-GB"; path = "Supporting Files/en-GB.lproj/Localizable.stringsdict"; sourceTree = ""; }; AA517B8D2D660F6A00F8D37C /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fr; path = "Supporting Files/fr.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B8E2D660F6B00F8D37C /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = gl; path = "Supporting Files/gl.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B8F2D660F6B00F8D37C /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "ka-GE"; path = "Supporting Files/ka-GE.lproj/Localizable.stringsdict"; sourceTree = ""; }; AA517B902D660F6C00F8D37C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = de; path = "Supporting Files/de.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B912D660F6D00F8D37C /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = el; path = "Supporting Files/el.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B922D660F6E00F8D37C /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hu; path = "Supporting Files/hu.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B932D660F6F00F8D37C /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = is; path = "Supporting Files/is.lproj/Localizable.stringsdict"; sourceTree = ""; }; AA517B942D660F6F00F8D37C /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = "Supporting Files/it.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B952D660F7000F8D37C /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "ja-JP"; path = "Supporting Files/ja-JP.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B962D660F7100F8D37C /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = "Supporting Files/ko.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B972D660F7100F8D37C /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lo; path = "Supporting Files/lo.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B982D660F7200F8D37C /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "nb-NO"; path = "Supporting Files/nb-NO.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B992D660F7300F8D37C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = "Supporting Files/pl.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B9A2D660F7300F8D37C /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "pt-PT"; path = "Supporting Files/pt-PT.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B9B2D660F7400F8D37C /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "pt-BR"; path = "Supporting Files/pt-BR.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B9C2D660F7500F8D37C /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = "Supporting Files/ru.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B9D2D660F7500F8D37C /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sr; path = "Supporting Files/sr.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B9E2D660F7600F8D37C /* sk-SK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "sk-SK"; path = "Supporting Files/sk-SK.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517B9F2D660F7700F8D37C /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sl; path = "Supporting Files/sl.lproj/Localizable.stringsdict"; sourceTree = ""; }; AA517BA02D660F7700F8D37C /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = "Supporting Files/es.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA12D660F7800F8D37C /* es-CL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-CL"; path = "Supporting Files/es-CL.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA22D660F7800F8D37C /* es-CO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-CO"; path = "Supporting Files/es-CO.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA32D660F7900F8D37C /* es-CR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-CR"; path = "Supporting Files/es-CR.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA42D660F7A00F8D37C /* es-DO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-DO"; path = "Supporting Files/es-DO.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA52D660F7B00F8D37C /* es-EC */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-EC"; path = "Supporting Files/es-EC.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA62D660F7C00F8D37C /* es-SV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-SV"; path = "Supporting Files/es-SV.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA72D660F7D00F8D37C /* es-GT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-GT"; path = "Supporting Files/es-GT.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA82D660F7E00F8D37C /* es-HN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-HN"; path = "Supporting Files/es-HN.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BA92D660F8200F8D37C /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "Supporting Files/es-419.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BAA2D660F8300F8D37C /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-MX"; path = "Supporting Files/es-MX.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BAB2D660F8600F8D37C /* es-NI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-NI"; path = "Supporting Files/es-NI.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BAC2D660F8700F8D37C /* es-PA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-PA"; path = "Supporting Files/es-PA.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BAD2D660F8700F8D37C /* es-PY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-PY"; path = "Supporting Files/es-PY.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BAE2D660F8800F8D37C /* es-PE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-PE"; path = "Supporting Files/es-PE.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BAF2D660F8900F8D37C /* es-PR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-PR"; path = "Supporting Files/es-PR.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BB02D660F8900F8D37C /* es-UY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-UY"; path = "Supporting Files/es-UY.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BB12D660F8A00F8D37C /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = "Supporting Files/sv.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA517BB22D660F8B00F8D37C /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = "Supporting Files/tr.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA52EB2C2D4297570089C348 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Intent.strings; sourceTree = ""; }; - AA52EB2D2D4297570089C348 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = ""; }; - AA52EB2E2D4297570089C348 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/InfoPlist.strings; sourceTree = ""; }; AA52EB452D42AC5A0089C348 /* Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = ""; }; AA74AA962D3172CE00BE3458 /* UITestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestError.swift; sourceTree = ""; }; AA8D31522D41052300FE2775 /* NCManageDatabase+DownloadLimit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+DownloadLimit.swift"; sourceTree = ""; }; @@ -1184,24 +1245,11 @@ AA8E03DB2D2FBAAD00E7E89C /* DownloadLimitUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadLimitUITests.swift; sourceTree = ""; }; AA8E041C2D300FDE00E7E89C /* NCShareNetworkingDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareNetworkingDelegate.swift; sourceTree = ""; }; AA8E041E2D3114E200E7E89C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - AA9B6A8D2DF1D8F7009D805D /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Intent.strings; sourceTree = ""; }; - AA9B6A8E2DF1D8F7009D805D /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = ""; }; - AA9B6A8F2DF1D8F7009D805D /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = et; path = "Supporting Files/et.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AA9B6A902DF1D8F7009D805D /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/InfoPlist.strings; sourceTree = ""; }; AAA7BC2D2D3E39EC008F1A22 /* CapabilitiesResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapabilitiesResponse.swift; sourceTree = ""; }; AAA7BC2F2D3E3B83008F1A22 /* CapabilityResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapabilityResponse.swift; sourceTree = ""; }; AABD0C862D5F58C400F009E6 /* Server.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = Server.sh; sourceTree = ""; }; AABD0C892D5F67A200F009E6 /* XCUIElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIElement.swift; sourceTree = ""; }; AABD0C9A2D5F73FA00F009E6 /* Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = ""; }; - AACCAB522CFE041F00DA1786 /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Intent.strings; sourceTree = ""; }; - AACCAB532CFE041F00DA1786 /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Localizable.strings; sourceTree = ""; }; - AACCAB542CFE041F00DA1786 /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/InfoPlist.strings; sourceTree = ""; }; - AACCAB5E2CFE04C200DA1786 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Intent.strings; sourceTree = ""; }; - AACCAB5F2CFE04C200DA1786 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = ""; }; - AACCAB602CFE04C200DA1786 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/InfoPlist.strings; sourceTree = ""; }; - AACCAB622CFE04F700DA1786 /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lo; path = lo.lproj/Intent.strings; sourceTree = ""; }; - AACCAB632CFE04F700DA1786 /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lo; path = lo.lproj/Localizable.strings; sourceTree = ""; }; - AACCAB642CFE04F700DA1786 /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lo; path = lo.lproj/InfoPlist.strings; sourceTree = ""; }; AAE330032D2ED1FF00B04903 /* NCShareNavigationTitleSetting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareNavigationTitleSetting.swift; sourceTree = ""; }; AF1A9B6327D0CA1E00F17A9E /* UIAlertController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Extension.swift"; sourceTree = ""; }; AF22B20B277C6F4D00DAB0CC /* NCShareCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCell.swift; sourceTree = ""; }; @@ -1231,14 +1279,24 @@ AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extension.swift"; sourceTree = ""; }; AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCells.swift; sourceTree = ""; }; AFCE353827E5DE0400FEA6C2 /* Shareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shareable.swift; sourceTree = ""; }; - B4C7A5B36D1ED178FB6B76CB /* NCContextMenuPlayerTracks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuPlayerTracks.swift; sourceTree = ""; }; BB7697C94BA14450A0867940 /* NCContextMenuProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuProfile.swift; sourceTree = ""; }; C0046CDA2A17B98400D87C9D /* NextcloudUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C04E2F202A17BB4D001BAD85 /* NextcloudIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D52D53F22F0DD53300D824BF /* AccountButtonFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountButtonFactory.swift; sourceTree = ""; }; + D59793B52CF7A73A00C44F4E /* DataProtectionAgreementManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionAgreementManager.swift; sourceTree = ""; }; + D59D37CD2F0EDAEC0072C824 /* UIDevice+VirtualOrientation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+VirtualOrientation.swift"; sourceTree = ""; }; + D59D37CF2F0EE97C0072C824 /* TransfersListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransfersListener.swift; sourceTree = ""; }; + D59D37D22F1082F50072C824 /* NCBackgroundLocationUploadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCBackgroundLocationUploadManager.swift; sourceTree = ""; }; D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = ""; }; + D5C2D21E2C9DC0EF00E7579D /* PrimaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryButton.swift; sourceTree = ""; }; + D5C5133A2C91970B00AE35CA /* NCImagesRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCImagesRepository.swift; sourceTree = ""; }; + D5E1D4FB2CF4A99200813AB6 /* DataProtectionAgreementScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionAgreementScreen.swift; sourceTree = ""; }; + D5E1D4FD2CF4E7C600813AB6 /* DataProtectionSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionSettingsScreen.swift; sourceTree = ""; }; + D5E1D4FF2CF4EB3900813AB6 /* DataProtectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionModel.swift; sourceTree = ""; }; + D5E1D5032CF665C100813AB6 /* DataProtectionHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionHostingController.swift; sourceTree = ""; }; + D5EB5DD32F490D2E009D88B1 /* NCContextMenuPlayerTracks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuPlayerTracks.swift; sourceTree = ""; }; F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCViewerMedia+VisionKit.swift"; sourceTree = ""; }; F317C82D2E844C5300761AEA /* ClientIntegrationUIViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientIntegrationUIViewer.swift; sourceTree = ""; }; - F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrashSelectTabBar.swift; sourceTree = ""; }; F32FADA82D1176DE007035E2 /* UIButton+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Extension.swift"; sourceTree = ""; }; F3374A802D64AB9E002A38F9 /* StatusInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusInfo.swift; sourceTree = ""; }; F3374A832D64AC2C002A38F9 /* AssistantLabelStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssistantLabelStyle.swift; sourceTree = ""; }; @@ -1260,7 +1318,6 @@ F3754A7C2CF87D600009312E /* SetupPasscodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupPasscodeView.swift; sourceTree = ""; }; F376A3732E5CC5FF0067EE25 /* ContextMenuActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuActions.swift; sourceTree = ""; }; F389C9F42CEE383300049762 /* SelectAlbumView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectAlbumView.swift; sourceTree = ""; }; - F38F71242B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCollectionViewCommonSelectTabBar.swift; sourceTree = ""; }; F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileAutoRenamer+Extensions.swift"; sourceTree = ""; }; F39298962A3B12CB00509762 /* BaseNCMoreCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNCMoreCell.swift; sourceTree = ""; }; F39A1EE12D0AF8A200DAD522 /* Albums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Albums.swift; sourceTree = ""; }; @@ -1309,7 +1366,6 @@ F70898662EDDB39300EF85BD /* NCNetworking+TransferDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+TransferDelegate.swift"; sourceTree = ""; }; F70898682EDDB51200EF85BD /* NCSelectOpen+SelectDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCSelectOpen+SelectDelegate.swift"; sourceTree = ""; }; F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCLivePhoto.swift; sourceTree = ""; }; - F70A07C8205285FB00DC1231 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = ""; }; F70BFC7320E0FA7C00C67599 /* NCUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCUtility.swift; sourceTree = ""; }; F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCEndToEndEncryption.h; sourceTree = ""; }; F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCEndToEndEncryption.m; sourceTree = ""; }; @@ -1330,12 +1386,9 @@ F7148046262EBE4B00693E51 /* Share-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Share-Bridging-Header.h"; sourceTree = ""; }; F714A1462ED84AF00050A43B /* HudBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HudBannerView.swift; sourceTree = ""; }; F7151A811D477A4B00E6AF45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - F7169A301EE59BB70086BD69 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; - F7169A4C1EE59C640086BD69 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; F717402B24F699A5000C87D5 /* NCFavorite.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCFavorite.storyboard; sourceTree = ""; }; F717402C24F699A5000C87D5 /* NCFavorite.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCFavorite.swift; sourceTree = ""; }; F718C24D254D507B00C5C256 /* NCViewerMediaDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerMediaDetailView.swift; sourceTree = ""; }; - F718E2572DF2D5C3004038AF /* NCBackgroundLocationUploadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCBackgroundLocationUploadManager.swift; sourceTree = ""; }; F71916102E2901E800E13E96 /* NCNetworking+Upload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+Upload.swift"; sourceTree = ""; }; F719D9DF288D37A300762E33 /* NCColorPicker.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCColorPicker.storyboard; sourceTree = ""; }; F719D9E1288D396100762E33 /* NCColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCColorPicker.swift; sourceTree = ""; }; @@ -1343,7 +1396,6 @@ F71CFA662F2A07C6007A3AE9 /* NCMedia+Netwoking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCMedia+Netwoking.swift"; sourceTree = ""; }; F71D2FB62E09BBD700B751CC /* NCAutoUploadModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCAutoUploadModel.swift; sourceTree = ""; }; F71F6D062B6A6A5E00F1EB15 /* ThreadSafeArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadSafeArray.swift; sourceTree = ""; }; - F722133A2D40EF8C002F7438 /* NCFilesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCFilesNavigationController.swift; sourceTree = ""; }; F7226EDB1EE4089300EBECB1 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; F722F0102CFF569500065FB5 /* MainInterface.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MainInterface.storyboard; sourceTree = ""; }; F723985B253C95CE00257F49 /* NCViewerRichdocument.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewerRichdocument.storyboard; sourceTree = ""; }; @@ -1368,8 +1420,6 @@ F72EC7252F45C90600A2135C /* NCContextMenuNavigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuNavigation.swift; sourceTree = ""; }; F72EC7272F45FF0600A2135C /* NCContextMenuPlus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuPlus.swift; sourceTree = ""; }; F72FD3B4297ED49A00075D28 /* NCManageDatabase+E2EE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+E2EE.swift"; sourceTree = ""; }; - F7320934201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; - F732093B201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Localizable.strings"; sourceTree = ""; }; F7327E1F2B73A42F00A462C7 /* NCNetworking+Download.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+Download.swift"; sourceTree = ""; }; F7327E2F2B73A86700A462C7 /* NCNetworking+WebDAV.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+WebDAV.swift"; sourceTree = ""; }; F7327E342B73AEDE00A462C7 /* NCNetworking+LivePhoto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+LivePhoto.swift"; sourceTree = ""; }; @@ -1395,7 +1445,6 @@ F73EFF9A2DB11EB900FD434C /* NCFiles+UIScrollViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCFiles+UIScrollViewDelegate.swift"; sourceTree = ""; }; F73F537E1E929C8500F8678D /* NCMore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMore.swift; sourceTree = ""; }; F7411C532D7B26C600F57358 /* NCNetworking+ServerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+ServerError.swift"; sourceTree = ""; }; - F741C2232B6B9FD600E849BB /* NCMediaSelectTabBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMediaSelectTabBar.swift; sourceTree = ""; }; F74230F22C79B57200CA1ACA /* NCNetworking+Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+Task.swift"; sourceTree = ""; }; F743C89D2E5B2595000173A9 /* UIScene+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScene+Extension.swift"; sourceTree = ""; }; F745B252222D88AE00346520 /* NCLoginQRCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginQRCode.swift; sourceTree = ""; }; @@ -1412,9 +1461,6 @@ F751247A2C42919C00E63DB8 /* NCPhotoCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCPhotoCell.swift; sourceTree = ""; }; F751247B2C42919C00E63DB8 /* NCPhotoCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCPhotoCell.xib; sourceTree = ""; }; F752BA042E58C05200616A26 /* Maintenance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Maintenance.swift; sourceTree = ""; }; - F753701822723D620041C76C /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Localizable.strings; sourceTree = ""; }; - F753701922723E0D0041C76C /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Localizable.strings; sourceTree = ""; }; - F753701A22723EC80041C76C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; F755BD9A20594AC7008C5FBB /* NCService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCService.swift; sourceTree = ""; }; F755CB3F2B8CB13C00CE27E9 /* NCMediaLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMediaLayout.swift; sourceTree = ""; }; F757CC8129E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Groupfolders.swift"; sourceTree = ""; }; @@ -1425,8 +1471,6 @@ F758B45F212C56A400515F55 /* NCScan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCScan.swift; sourceTree = ""; }; F75A9EE523796C6F0044CFCE /* NCNetworking.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCNetworking.swift; sourceTree = ""; }; F75B91E21ECAE17800199C96 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; - F75B91F71ECAE26300199C96 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; }; - F75B923D1ECAE55E00199C96 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; F75C0C4723D1FAE300163CC8 /* NCRichWorkspaceCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCRichWorkspaceCommon.swift; sourceTree = ""; }; F75CA1462962F13700B01130 /* NCHUDView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCHUDView.swift; sourceTree = ""; }; F75D19E225EFE09000D74598 /* NCContextMenuTrash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCContextMenuTrash.swift; sourceTree = ""; }; @@ -1495,24 +1539,6 @@ F7725A5E251F33BB00D125E0 /* NCFiles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCFiles.swift; sourceTree = ""; }; F7725A5F251F33BB00D125E0 /* NCFiles.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCFiles.storyboard; sourceTree = ""; }; F774264822EB4D0000B23912 /* NCSearchUserDropDownCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCSearchUserDropDownCell.xib; sourceTree = ""; }; - F77438EB1FCD694900662C46 /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ka-GE"; path = "ka-GE.lproj/Localizable.strings"; sourceTree = ""; }; - F77438F21FCD69D300662C46 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = ""; }; - F77438F91FCD6A0D00662C46 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.strings"; sourceTree = ""; }; - F77439001FCD6B7F00662C46 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Localizable.strings; sourceTree = ""; }; - F77439071FCD6BF000662C46 /* es-CL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CL"; path = "es-CL.lproj/Localizable.strings"; sourceTree = ""; }; - F774390E1FCD6C0C00662C46 /* es-CO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CO"; path = "es-CO.lproj/Localizable.strings"; sourceTree = ""; }; - F77439151FCD6C4A00662C46 /* es-CR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CR"; path = "es-CR.lproj/Localizable.strings"; sourceTree = ""; }; - F774391C1FCD6C6700662C46 /* es-DO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-DO"; path = "es-DO.lproj/Localizable.strings"; sourceTree = ""; }; - F77439231FCD6C8700662C46 /* es-EC */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-EC"; path = "es-EC.lproj/Localizable.strings"; sourceTree = ""; }; - F774392A1FCD6CAA00662C46 /* es-GT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-GT"; path = "es-GT.lproj/Localizable.strings"; sourceTree = ""; }; - F77439311FCD6CC400662C46 /* es-HN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-HN"; path = "es-HN.lproj/Localizable.strings"; sourceTree = ""; }; - F77439381FCD6CDE00662C46 /* es-NI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-NI"; path = "es-NI.lproj/Localizable.strings"; sourceTree = ""; }; - F774393F1FCD6D0B00662C46 /* es-PA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PA"; path = "es-PA.lproj/Localizable.strings"; sourceTree = ""; }; - F77439461FCD6D2300662C46 /* es-PE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PE"; path = "es-PE.lproj/Localizable.strings"; sourceTree = ""; }; - F774394D1FCD6D3E00662C46 /* es-PR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PR"; path = "es-PR.lproj/Localizable.strings"; sourceTree = ""; }; - F77439541FCD6D6100662C46 /* es-PY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PY"; path = "es-PY.lproj/Localizable.strings"; sourceTree = ""; }; - F774395B1FCD6D8200662C46 /* es-SV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-SV"; path = "es-SV.lproj/Localizable.strings"; sourceTree = ""; }; - F77439621FCD6D9C00662C46 /* es-UY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-UY"; path = "es-UY.lproj/Localizable.strings"; sourceTree = ""; }; F7743A112C33F0A20034F670 /* NCCollectionViewCommon+CollectionViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+CollectionViewDelegate.swift"; sourceTree = ""; }; F7743A132C33F13A0034F670 /* NCCollectionViewCommon+CollectionViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+CollectionViewDataSource.swift"; sourceTree = ""; }; F77444F322281649000D5EB0 /* NCMediaCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMediaCell.swift; sourceTree = ""; }; @@ -1555,18 +1581,12 @@ F78B87E62B62527100C65ADC /* NCMediaDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaDataSource.swift; sourceTree = ""; }; F78B87E82B62550800C65ADC /* NCMediaDownloadThumbnail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaDownloadThumbnail.swift; sourceTree = ""; }; F78C6FDD296D677300C952C3 /* NCContextMenuMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuMain.swift; sourceTree = ""; }; - F78D6F461F0B7CB9002F9619 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Localizable.strings"; sourceTree = ""; }; - F78D6F4D1F0B7CE4002F9619 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nb-NO"; path = "nb-NO.lproj/Localizable.strings"; sourceTree = ""; }; - F78D6F541F0B7D47002F9619 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; F78E2D6429AF02DB0024D4F3 /* Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; F78F74332163757000C2ADAD /* NCTrash.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCTrash.storyboard; sourceTree = ""; }; F78F74352163781100C2ADAD /* NCTrash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrash.swift; sourceTree = ""; }; F790110D21415BF600D7B136 /* NCViewerRichDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerRichDocument.swift; sourceTree = ""; }; - F79131C628AFB86E00577277 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = ""; }; - F79131C728AFB86E00577277 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/InfoPlist.strings; sourceTree = ""; }; F794E13C2BBBFF2E003693D7 /* NCMainTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMainTabBarController.swift; sourceTree = ""; }; F794E13E2BBC0F70003693D7 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - F79699E62E689F68000EC82A /* NCMediaNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaNavigationController.swift; sourceTree = ""; }; F799DF812C4B7DCC003410B5 /* NCSectionFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSectionFooter.swift; sourceTree = ""; }; F799DF842C4B7E56003410B5 /* NCSectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSectionHeader.swift; sourceTree = ""; }; F799DF872C4B83CC003410B5 /* NCCollectionViewCommon+EasyTipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+EasyTipView.swift"; sourceTree = ""; }; @@ -1578,9 +1598,6 @@ F79EDA9F26B004980007D134 /* NCPlayerToolBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCPlayerToolBar.swift; sourceTree = ""; }; F79EDAA126B004980007D134 /* NCPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = NCPlayer.swift; sourceTree = ""; }; F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EEMarkFolder.swift; sourceTree = ""; }; - F7A03E2E2D425A14007AA677 /* NCFavoriteNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCFavoriteNavigationController.swift; sourceTree = ""; }; - F7A03E322D426115007AA677 /* NCMoreNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMoreNavigationController.swift; sourceTree = ""; }; - F7A03E342D427308007AA677 /* NCMainNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMainNavigationController.swift; sourceTree = ""; }; F7A0D1342591FBC5008F8A13 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = ""; }; F7A3DB8F2DDE238C008F7EC8 /* NCDebouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCDebouncer.swift; sourceTree = ""; }; F7A48414297028FC00BD1B49 /* Nextcloud Hub.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Nextcloud Hub.png"; sourceTree = SOURCE_ROOT; }; @@ -1589,48 +1606,10 @@ F7A573682E190377009C9257 /* NCShareExtensionData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareExtensionData.swift; sourceTree = ""; }; F7A7FDDB2C2DBD6200E9A93A /* NCDeepLinkHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCDeepLinkHandler.swift; sourceTree = ""; }; F7A846DD2BB01ACB0024816F /* NCTrashCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrashCellProtocol.swift; sourceTree = ""; }; - F7AA41B827C7CF4600494705 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41B927C7CF4B00494705 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41BA27C7CF5000494705 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41BB27C7CF5100494705 /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "cs-CZ"; path = "cs-CZ.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41BC27C7CF5300494705 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; F7AA41BD27C7CF5400494705 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41BE27C7CF5600494705 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/InfoPlist.strings"; sourceTree = ""; }; F7AA41BF27C7CF5700494705 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C027C7CF5800494705 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41C127C7CF5900494705 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C227C7CF5A00494705 /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ka-GE"; path = "ka-GE.lproj/InfoPlist.strings"; sourceTree = ""; }; F7AA41C327C7CF5B00494705 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C427C7CF5C00494705 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C527C7CF5D00494705 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C627C7CF5E00494705 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C727C7CF6000494705 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41C827C7CF6200494705 /* es-HN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-HN"; path = "es-HN.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41C927C7CF6300494705 /* es-DO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-DO"; path = "es-DO.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41CA27C7CF6400494705 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41CB27C7CF6500494705 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nb-NO"; path = "nb-NO.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41CC27C7CF6600494705 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41CD27C7CF6700494705 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41CE27C7CF6800494705 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41CF27C7CF6900494705 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41D027C7CF6900494705 /* sk-SK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sk-SK"; path = "sk-SK.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41D127C7CF6A00494705 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41D227C7CF6C00494705 /* es-CO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CO"; path = "es-CO.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41D327C7CF6D00494705 /* es-CL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CL"; path = "es-CL.lproj/InfoPlist.strings"; sourceTree = ""; }; F7AA41D427C7CF6E00494705 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41D527C7CF6F00494705 /* es-CR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CR"; path = "es-CR.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41D627C7CF7100494705 /* es-GT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-GT"; path = "es-GT.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41D727C7CF7200494705 /* es-SV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-SV"; path = "es-SV.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41D827C7CF7300494705 /* es-EC */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-EC"; path = "es-EC.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41D927C7CF7500494705 /* es-PR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PR"; path = "es-PR.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41DA27C7CF7600494705 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; - F7AA41DB27C7CF7800494705 /* es-UY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-UY"; path = "es-UY.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41DC27C7CF7900494705 /* es-PE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PE"; path = "es-PE.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41DD27C7CF7B00494705 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41DE27C7CF7D00494705 /* es-PA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PA"; path = "es-PA.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41DF27C7CF7E00494705 /* es-PY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PY"; path = "es-PY.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41E027C7CF8000494705 /* es-NI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-NI"; path = "es-NI.lproj/InfoPlist.strings"; sourceTree = ""; }; - F7AA41E127C7CF8100494705 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/InfoPlist.strings"; sourceTree = ""; }; F7AC1CAF28AB94490032D99F /* Array+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extension.swift"; sourceTree = ""; }; F7AC9349296193050002BC0F /* Reasons to use Nextcloud.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Reasons to use Nextcloud.pdf"; sourceTree = SOURCE_ROOT; }; F7AE00F4230D5F9E007ACF8A /* NCLoginProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginProvider.swift; sourceTree = ""; }; @@ -1641,59 +1620,18 @@ F7B6B70327C4E7FA00A7F6EB /* NCScan+CollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCScan+CollectionView.swift"; sourceTree = ""; }; F7B7504A2397D38E004E13EC /* UIImage+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = ""; }; F7B769A72B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Metadata+Session.swift"; sourceTree = ""; }; - F7B8B82F25681C3400967775 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; }; F7B934FD2BDCFE1E002B2FC9 /* NCDragDrop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCDragDrop.swift; sourceTree = ""; }; F7BAADB51ED5A87C00B7EAD4 /* NCManageDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCManageDatabase.swift; sourceTree = ""; }; - F7BB04851FD58ACB00BBFD2A /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "cs-CZ"; path = "cs-CZ.lproj/Localizable.strings"; sourceTree = ""; }; F7BC287D26663F6C004D46C5 /* NCViewCertificateDetails.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewCertificateDetails.storyboard; sourceTree = ""; }; F7BC287F26663F85004D46C5 /* NCViewCertificateDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewCertificateDetails.swift; sourceTree = ""; }; F7BD09FF2C468925003A4A6D /* NCMedia+CollectionViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCMedia+CollectionViewDataSource.swift"; sourceTree = ""; }; F7BD0A012C4689A4003A4A6D /* NCMedia+CollectionViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCMedia+CollectionViewDelegate.swift"; sourceTree = ""; }; F7BD0A032C4689E9003A4A6D /* NCMedia+MediaLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCMedia+MediaLayout.swift"; sourceTree = ""; }; F7BE7C25290AC8C9002ABB61 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C27290ADEFD002ABB61 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C29290ADEFD002ABB61 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C2B290ADEFE002ABB61 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C2D290ADEFF002ABB61 /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "cs-CZ"; path = "cs-CZ.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C2F290ADF00002ABB61 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Intent.strings"; sourceTree = ""; }; F7BE7C31290ADF00002ABB61 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C33290ADF01002ABB61 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C35290ADF03002ABB61 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C37290ADF03002ABB61 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C39290ADF04002ABB61 /* es-UY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-UY"; path = "es-UY.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C3B290ADF04002ABB61 /* es-PR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PR"; path = "es-PR.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C3D290ADF05002ABB61 /* es-PE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PE"; path = "es-PE.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C3F290ADF06002ABB61 /* es-PY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PY"; path = "es-PY.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C41290ADF06002ABB61 /* es-PA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PA"; path = "es-PA.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C43290ADF06002ABB61 /* es-NI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-NI"; path = "es-NI.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C45290ADF07002ABB61 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C47290ADF07002ABB61 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C49290ADF08002ABB61 /* es-HN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-HN"; path = "es-HN.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C4B290ADF09002ABB61 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C4D290ADF0A002ABB61 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C4F290ADF0A002ABB61 /* sk-SK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sk-SK"; path = "sk-SK.lproj/Intent.strings"; sourceTree = ""; }; F7BE7C51290ADF0B002ABB61 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C53290ADF0B002ABB61 /* es-CL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CL"; path = "es-CL.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C55290ADF0C002ABB61 /* es-CO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CO"; path = "es-CO.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C57290ADF0C002ABB61 /* es-CR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CR"; path = "es-CR.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C59290ADF0D002ABB61 /* es-DO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-DO"; path = "es-DO.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C5B290ADF0D002ABB61 /* es-EC */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-EC"; path = "es-EC.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C5D290ADF0E002ABB61 /* es-SV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-SV"; path = "es-SV.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C5F290ADF0E002ABB61 /* es-GT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-GT"; path = "es-GT.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C61290ADF10002ABB61 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Intent.strings"; sourceTree = ""; }; F7BE7C63290ADF10002ABB61 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C65290ADF10002ABB61 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C67290ADF11002ABB61 /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ka-GE"; path = "ka-GE.lproj/Intent.strings"; sourceTree = ""; }; F7BE7C69290ADF11002ABB61 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C6B290ADF12002ABB61 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C6D290ADF12002ABB61 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C6F290ADF13002ABB61 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C71290ADF13002ABB61 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C73290ADF14002ABB61 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C75290ADF14002ABB61 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nb-NO"; path = "nb-NO.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C77290ADF15002ABB61 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Intent.strings; sourceTree = ""; }; - F7BE7C79290ADF16002ABB61 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Intent.strings"; sourceTree = ""; }; - F7BE7C7B290ADF16002ABB61 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Intent.strings"; sourceTree = ""; }; F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+LayoutForView.swift"; sourceTree = ""; }; F7C1EEA425053A9C00866ACC /* NCCollectionViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCollectionViewDataSource.swift; sourceTree = ""; }; F7C30DF5291BC0CA0017149B /* NCNetworkingE2EEUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EEUpload.swift; sourceTree = ""; }; @@ -1761,17 +1699,12 @@ F7D4BF282CA2E8D800A5E746 /* TOPasscodeSettingsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TOPasscodeSettingsViewController.m; sourceTree = ""; }; F7D4BF292CA2E8D800A5E746 /* TOPasscodeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TOPasscodeViewController.h; sourceTree = ""; }; F7D4BF2A2CA2E8D800A5E746 /* TOPasscodeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TOPasscodeViewController.m; sourceTree = ""; }; - F7D532461F5D4123006568B1 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Localizable.strings; sourceTree = ""; }; F7D5324D1F5D4137006568B1 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; - F7D532541F5D4155006568B1 /* sk-SK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sk-SK"; path = "sk-SK.lproj/Localizable.strings"; sourceTree = ""; }; - F7D5328F1F5D443B006568B1 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = ""; }; - F7D532A41F5D4461006568B1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; F7D60CAE2C941ACB008FBFDD /* NCMediaPinchGesture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaPinchGesture.swift; sourceTree = ""; }; F7D61EA52EBF168E007F865B /* NCManageDatabase+TableCapabilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+TableCapabilities.swift"; sourceTree = ""; }; F7D68FCB28CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+DashboardWidget.swift"; sourceTree = ""; }; F7D7A76B2DCDD437003D2007 /* NCManageDatabase+AutoUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+AutoUpload.swift"; sourceTree = ""; }; F7D890742BD25C570050B8A6 /* NCCollectionViewCommon+DragDrop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+DragDrop.swift"; sourceTree = ""; }; - F7DE9AB01F482FA5008DFE10 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; F7DF7B3E2F1A2EE400514020 /* BannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannerView.swift; sourceTree = ""; }; F7DF7B412F1A36B600514020 /* HelperBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelperBanner.swift; sourceTree = ""; }; F7E0710028B13BB00001B882 /* DashboardData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardData.swift; sourceTree = ""; }; @@ -1780,7 +1713,6 @@ F7E402302BA891EB007E5609 /* NCTrash+SelectTabBarDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCTrash+SelectTabBarDelegate.swift"; sourceTree = ""; }; F7E402322BA89551007E5609 /* NCTrash+Networking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCTrash+Networking.swift"; sourceTree = ""; }; F7E41315294A19B300839300 /* UIView+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extension.swift"; sourceTree = ""; }; - F7E45E6D21E75BF200579249 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Localizable.strings"; sourceTree = ""; }; F7E4D9C322ED929B003675FD /* NCShareCommentsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCommentsCell.swift; sourceTree = ""; }; F7E7AEA42BA32C6500512E52 /* NCCollectionViewDownloadThumbnail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCollectionViewDownloadThumbnail.swift; sourceTree = ""; }; F7E8A390295DC5E0006CB2D0 /* View+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extension.swift"; sourceTree = ""; }; @@ -1818,12 +1750,10 @@ F7FDFF572E437E55000D7688 /* NCAccountSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCAccountSettingsView.swift; sourceTree = ""; }; F7FDFF592E437E55000D7688 /* NCAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCAccount.swift; sourceTree = ""; }; F7FF2CB02842159500EBB7A1 /* NCSectionHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCSectionHeader.xib; sourceTree = ""; }; + FC930DC42CEDE33000C9B237 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; + FC930DC62CEE377700C9B237 /* WidgetCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetCommon.swift; sourceTree = ""; }; /* End PBXFileReference section */ -/* Begin PBXFileSystemSynchronizedRootGroup section */ - AA517BB42D66149900F8D37C /* .tx */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = .tx; sourceTree = ""; }; -/* End PBXFileSystemSynchronizedRootGroup section */ - /* Begin PBXFrameworksBuildPhase section */ 2C33C47C23E2C475005F963B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -1950,6 +1880,7 @@ F7BB7E4727A18C56009B9F29 /* Parchment in Frameworks */, F33EE6E12BF4BDA500CA1A51 /* NIOSSL in Frameworks */, F734B06628E75C0100E180D5 /* TLPhotoPicker in Frameworks */, + 625EC26E2C6CA285006411D1 /* FirebaseAnalytics in Frameworks */, F760DE032AE66EA80027D78A /* KeychainAccess in Frameworks */, F3374AF62D78B01B002A38F9 /* HashTreeCollections in Frameworks */, F33EE6F02BF4C0FF00CA1A51 /* NIO in Frameworks */, @@ -1990,9 +1921,35 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0F08D6B52C9426B800136502 /* Style */ = { + isa = PBXGroup; + children = ( + 0F08D6BA2C94275600136502 /* CircleItemSpinner.swift */, + ); + path = Style; + sourceTree = ""; + }; + 0F4374A92D8442BA0081F7C3 /* .tx */ = { + isa = PBXGroup; + children = ( + 0F4374A82D8442BA0081F7C3 /* config */, + ); + path = .tx; + sourceTree = ""; + }; + 0F5090CC2C786EC8009348D9 /* ActionsHeader */ = { + isa = PBXGroup; + children = ( + 0F5090CD2C786F04009348D9 /* FileActionsHeader.swift */, + 0F8B9A5A2C7887F60041C17D /* FileActionsHeader.xib */, + ); + path = ActionsHeader; + sourceTree = ""; + }; 2C33C48023E2C475005F963B /* Notification Service Extension */ = { isa = PBXGroup; children = ( + 421651302E28F6ED002E19D6 /* Notification Service ExtensionDebug.entitlements */, 2C33C48123E2C475005F963B /* NotificationService.swift */, 2C33C48A23E2CC26005F963B /* Notification_Service_Extension-Bridging-Header.h */, ); @@ -2002,13 +1959,13 @@ 371B5A2F23D0B04B00FAFAE9 /* Menu */ = { isa = PBXGroup; children = ( + D5EB5DD32F490D2E009D88B1 /* NCContextMenuPlayerTracks.swift */, F376A3732E5CC5FF0067EE25 /* ContextMenuActions.swift */, F78C6FDD296D677300C952C3 /* NCContextMenuMain.swift */, BB7697C94BA14450A0867940 /* NCContextMenuProfile.swift */, 8932E90EC4278026D86CCCC9 /* NCContextMenuComment.swift */, F72EC7252F45C90600A2135C /* NCContextMenuNavigation.swift */, F72EC7272F45FF0600A2135C /* NCContextMenuPlus.swift */, - B4C7A5B36D1ED178FB6B76CB /* NCContextMenuPlayerTracks.swift */, F7FAFD3928BFA947000777FE /* NCContextMenuNotification.swift */, AF93471127E2341B002537EE /* NCContextMenuShare.swift */, F75D19E225EFE09000D74598 /* NCContextMenuTrash.swift */, @@ -2017,6 +1974,58 @@ path = Menu; sourceTree = ""; }; + 420216552F55791E00BBD630 /* NCMediaCoordinator */ = { + isa = PBXGroup; + children = ( + 426E38DC2F571E890073EE47 /* NCMediaCoordinatorConstants.swift */, + 4250C8462E2E53B400349A8A /* NCMediaCoordinator.swift */, + 4202165C2F5586D300BBD630 /* NCMediaCoordinatorStrategy.swift */, + 420216562F557C7F00BBD630 /* NCMediaCoordinatorVLCStrategy.swift */, + 420216582F557CA300BBD630 /* NCMediaCoordinatorAVKitStrategy.swift */, + ); + path = NCMediaCoordinator; + sourceTree = ""; + }; + 4240DB4C2C56446D00E72FC0 /* BurgerMenu */ = { + isa = PBXGroup; + children = ( + 4240DB4D2C5646B400E72FC0 /* BurgerMenuAttachController.swift */, + 4240DB4F2C5648E300E72FC0 /* BurgerMenuViewController.swift */, + 42678ABD2C57C5FB00307DEF /* BurgerMenuViewModel.swift */, + 4240DB512C5649A900E72FC0 /* BurgerMenuView.swift */, + ); + path = BurgerMenu; + sourceTree = ""; + }; + 424AC92F2E9004B300D92A38 /* Recovered References */ = { + isa = PBXGroup; + children = ( + ); + name = "Recovered References"; + sourceTree = ""; + }; + 426D0F862D2826B200F76A65 /* Toolbar */ = { + isa = PBXGroup; + children = ( + 426D0F872D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbar.swift */, + 421657AA2D2AF2BF003BC9D5 /* HiDriveCollectionViewCommonSelectToolbarDelegate.swift */, + 426D0F882D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbarView.swift */, + ); + path = Toolbar; + sourceTree = ""; + }; + 42C684B52CA1A17300DD46F0 /* Buttons */ = { + isa = PBXGroup; + children = ( + 42C684B62CA1A20100DD46F0 /* CommonButtonConstants.swift */, + D5C2D21E2C9DC0EF00E7579D /* PrimaryButton.swift */, + 42C684B32CA1806000DD46F0 /* SecondaryButton.swift */, + 4294B88A2CA5550B002E6FED /* LinkButton.swift */, + 0F08D6B82C94270600136502 /* ButtonStyleGuide.swift */, + ); + path = Buttons; + sourceTree = ""; + }; AA3C85E92D36BBDE00F74F12 /* UITestBackend */ = { isa = PBXGroup; children = ( @@ -2102,6 +2111,36 @@ path = NextcloudIntegrationTests; sourceTree = ""; }; + D5AF19722F127D9700D4F47F /* Account */ = { + isa = PBXGroup; + children = ( + F7FDFF592E437E55000D7688 /* NCAccount.swift */, + F7FDFF552E437E55000D7688 /* Account Request */, + F7FDFF582E437E55000D7688 /* Account Settings */, + ); + path = Account; + sourceTree = ""; + }; + D5C2D21D2C9DC0D800E7579D /* Components */ = { + isa = PBXGroup; + children = ( + 42C684B52CA1A17300DD46F0 /* Buttons */, + ); + path = Components; + sourceTree = ""; + }; + D5E1D4FA2CF4A86F00813AB6 /* DataProtection */ = { + isa = PBXGroup; + children = ( + D5E1D4FB2CF4A99200813AB6 /* DataProtectionAgreementScreen.swift */, + D5E1D4FD2CF4E7C600813AB6 /* DataProtectionSettingsScreen.swift */, + D5E1D4FF2CF4EB3900813AB6 /* DataProtectionModel.swift */, + D5E1D5032CF665C100813AB6 /* DataProtectionHostingController.swift */, + D59793B52CF7A73A00C44F4E /* DataProtectionAgreementManager.swift */, + ); + path = DataProtection; + sourceTree = ""; + }; F30A962A2A27A9C800D7BCFE /* Tests */ = { isa = PBXGroup; children = ( @@ -2228,10 +2267,12 @@ F7DFB7E9219C5A0500680748 /* Create */, F7226EDB1EE4089300EBECB1 /* Main.storyboard */, F7B934FD2BDCFE1E002B2FC9 /* NCDragDrop.swift */, + 0F8615AB2CBE6AC20056B4F2 /* UITabBarGuideline.swift */, F794E13C2BBBFF2E003693D7 /* NCMainTabBarController.swift */, + 0F4AA77B2DE083D600138679 /* NCMainTabBar.swift */, F737DA9C2B7B893C0063BAFC /* NCPasscode.swift */, F77444F7222816D5000D5EB0 /* NCPickerViewController.swift */, - F7A03E342D427308007AA677 /* NCMainNavigationController.swift */, + 42E5D36A2D678F95007150DE /* HiDriveMainNavigationController.swift */, ); path = Main; sourceTree = ""; @@ -2268,6 +2309,7 @@ F70716E42987F81500E72C1D /* File Provider Extension UI */ = { isa = PBXGroup; children = ( + 4216512F2E28F6DC002E19D6 /* File Provider Extension UIDebug.entitlements */, F70716E52987F81500E72C1D /* DocumentActionViewController.swift */, F722F0102CFF569500065FB5 /* MainInterface.storyboard */, ); @@ -2362,6 +2404,7 @@ AF2D7C7D2742559100ADF566 /* NCShareUserCell.swift */, AF93471727E2361E002537EE /* NCShareHeader.xib */, AF93471527E2361E002537EE /* NCShareHeader.swift */, + 42D34FD82D79A5B00020C106 /* ShareSearchField.swift */, AFCE353827E5DE0400FEA6C2 /* Shareable.swift */, AA8E03D92D2ED83300E7E89C /* TransientShare.swift */, ); @@ -2401,7 +2444,9 @@ F7346E1428B0EF5B006CE2D2 /* Widget */ = { isa = PBXGroup; children = ( + 4216512B2E28F685002E19D6 /* WidgetDebug.entitlements */, F7346E2228B0FEBA006CE2D2 /* Assets.xcassets */, + FC930DC42CEDE33000C9B237 /* Colors.xcassets */, F72EA95528B7BAD100C88F0C /* Dashboard */, F72EA95628B7BAE700C88F0C /* Files */, F76DEE9A28F808BC0041B1C9 /* Lockscreen */, @@ -2409,6 +2454,7 @@ F75DD764290AB369002EB562 /* Intent */, F7346E2028B0FA3A006CE2D2 /* Widget-Brinding-header.h */, F7346E1528B0EF5C006CE2D2 /* Widget.swift */, + FC930DC62CEE377700C9B237 /* WidgetCommon.swift */, ); path = Widget; sourceTree = ""; @@ -2488,7 +2534,8 @@ F75FE06B2BB01D0D00A0EFEF /* Cell */ = { isa = PBXGroup; children = ( - 370D26AE248A3D7A00121797 /* NCCellMain.swift */, + 426533632F698AD70092B12B /* NCCellMain.swift */, + 4202746F2F11557500ECB06B /* NCCellMedia.swift */, F78ACD4121903CE00088454D /* NCListCell.swift */, F78ACD3F21903CC20088454D /* NCGridCell.swift */, F751247A2C42919C00E63DB8 /* NCPhotoCell.swift */, @@ -2498,6 +2545,8 @@ F75D901E2D2BE12E003E740B /* NCRecommendationsCell.xib */, F75D90202D2BE26C003E740B /* NCRecommendationsCell.swift */, F36C514D2E89393C0097E5F7 /* UIView+BlurVibrancy.swift */, + 428915302F226C1500B41486 /* PlaybackProgressView.swift */, + 421DC45E2F6D38F3001EE5E3 /* ItemShareState.swift */, ); path = Cell; sourceTree = ""; @@ -2505,8 +2554,10 @@ F7603298252F0E550015A421 /* Collection Common */ = { isa = PBXGroup; children = ( + 0F5090CC2C786EC8009348D9 /* ActionsHeader */, F75FE06B2BB01D0D00A0EFEF /* Cell */, F70D7C3525FFBF81002B9E34 /* NCCollectionViewCommon.swift */, + 42F89EB02D71F30C00550A07 /* NCCollectionViewCommon+FileActionsHeader.swift */, F7CAFE172F164B9200DB35A5 /* NCCollectionViewCommon+CellDelegate.swift */, F7743A132C33F13A0034F670 /* NCCollectionViewCommon+CollectionViewDataSource.swift */, F74D50342C9855A000BBBF4C /* NCCollectionViewCommon+CollectionViewDataSourcePrefetching.swift */, @@ -2520,7 +2571,6 @@ F36E64F62B9245210085ABB5 /* NCCollectionViewCommon+SelectTabBarDelegate.swift */, F7CCAB502ECF315F00F8E68B /* NCCollectionViewCommon+SyncMetadata.swift */, F7D4BF002CA1831600A5E746 /* NCCollectionViewCommonPinchGesture.swift */, - F38F71242B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift */, F7C1EEA425053A9C00866ACC /* NCCollectionViewDataSource.swift */, F7E7AEA42BA32C6500512E52 /* NCCollectionViewDownloadThumbnail.swift */, F78ACD50219046AC0088454D /* Section Header Footer */, @@ -2687,6 +2737,7 @@ F771E3D120E2392D00AFB62D /* File Provider Extension */ = { isa = PBXGroup; children = ( + 4216512E2E28F6D3002E19D6 /* File Provider ExtensionDebug.entitlements */, F76340EB2EBDE7420056F538 /* NCManageDatabase.swift */, F771E3F220E239A600AFB62D /* FileProviderData.swift */, F76673EC22C901F5007ED366 /* FileProviderDomain.swift */, @@ -2706,7 +2757,6 @@ F7725A5F251F33BB00D125E0 /* NCFiles.storyboard */, F7725A5E251F33BB00D125E0 /* NCFiles.swift */, F73EFF9A2DB11EB900FD434C /* NCFiles+UIScrollViewDelegate.swift */, - F722133A2D40EF8C002F7438 /* NCFilesNavigationController.swift */, ); path = Files; sourceTree = ""; @@ -2757,7 +2807,6 @@ AF3FDCC12796ECC300710F60 /* NCTrash+CollectionView.swift */, F7E402322BA89551007E5609 /* NCTrash+Networking.swift */, F7E402302BA891EB007E5609 /* NCTrash+SelectTabBarDelegate.swift */, - F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */, ); path = Trash; sourceTree = ""; @@ -2765,11 +2814,12 @@ F79018B1240962C7007C9B6D /* NCViewerMedia */ = { isa = PBXGroup; children = ( - F70753EA2542A99800972D44 /* NCViewerMediaPage.swift */, + 420216552F55791E00BBD630 /* NCMediaCoordinator */, F718C24D254D507B00C5C256 /* NCViewerMediaDetailView.swift */, + F70753F62542A9C000972D44 /* NCViewerMediaPage.storyboard */, + F70753EA2542A99800972D44 /* NCViewerMediaPage.swift */, F70753F02542A9A200972D44 /* NCViewerMedia.swift */, F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */, - F70753F62542A9C000972D44 /* NCViewerMediaPage.storyboard */, F79EDA9E26B004980007D134 /* NCPlayer */, ); path = NCViewerMedia; @@ -2849,8 +2899,10 @@ F77BB747289985270090FC19 /* UITabBarController+Extension.swift */, AFCE353227E4ED1900FEA6C2 /* UIToolbar+Extension.swift */, F7E41315294A19B300839300 /* UIView+Extension.swift */, + 4232DC092C9D7C44008D546D /* UIView+GridSelection.swift */, F77BB745289984CA0090FC19 /* UIViewController+Extension.swift */, F7E8A390295DC5E0006CB2D0 /* View+Extension.swift */, + 42F907DD2D2C424100BCDC36 /* View+Design.swift */, ); path = Extensions; sourceTree = ""; @@ -2860,7 +2912,6 @@ children = ( F717402B24F699A5000C87D5 /* NCFavorite.storyboard */, F717402C24F699A5000C87D5 /* NCFavorite.swift */, - F7A03E2E2D425A14007AA677 /* NCFavoriteNavigationController.swift */, ); path = Favorites; sourceTree = ""; @@ -2938,6 +2989,7 @@ children = ( F702F2F025EE5CDA008F8E80 /* NCLogin.storyboard */, F702F2F625EE5CEC008F8E80 /* NCLogin.swift */, + 0F4AA77E2DE0A3F700138679 /* NCLoginNavigationController.swift */, F745B252222D88AE00346520 /* NCLoginQRCode.swift */, F7AE00F4230D5F9E007ACF8A /* NCLoginProvider.swift */, F7BC287D26663F6C004D46C5 /* NCViewCertificateDetails.storyboard */, @@ -2949,6 +3001,8 @@ F7BFFA991A24D7BB0044ED85 /* Utility */ = { isa = PBXGroup; children = ( + D59D37CD2F0EDAEC0072C824 /* UIDevice+VirtualOrientation.swift */, + D52D53F22F0DD53300D824BF /* AccountButtonFactory.swift */, F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */, F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */, F752BA042E58C05200616A26 /* Maintenance.swift */, @@ -2982,6 +3036,7 @@ F7C0F46D1C8880540059EC54 /* Share */ = { isa = PBXGroup; children = ( + 4216512D2E28F6BB002E19D6 /* ShareDebug.entitlements */, F714803A262EBE3900693E51 /* MainInterface.storyboard */, F7148040262EBE4000693E51 /* NCShareExtension.swift */, F7A573682E190377009C9257 /* NCShareExtensionData.swift */, @@ -3002,6 +3057,7 @@ F7362A1E220C853A005101B5 /* LaunchScreen.storyboard */, F78E2D6429AF02DB0024D4F3 /* Database.swift */, F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */, + 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */, ); path = Brand; sourceTree = ""; @@ -3027,6 +3083,7 @@ F7C9739328F17131002C43E2 /* WidgetDashboardIntentHandler */ = { isa = PBXGroup; children = ( + 4216512C2E28F6A4002E19D6 /* WidgetDashboardIntentHandlerDebug.entitlements */, F7C9739428F17131002C43E2 /* IntentHandler.swift */, ); path = WidgetDashboardIntentHandler; @@ -3049,7 +3106,6 @@ F3BB46502A39EC2D00461F6E /* Cells */, F7CB68992541676B0050EC94 /* NCMore.storyboard */, F73F537E1E929C8500F8678D /* NCMore.swift */, - F7A03E322D426115007AA677 /* NCMoreNavigationController.swift */, ); path = More; sourceTree = ""; @@ -3160,6 +3216,7 @@ F7E9C41320F4CA870040CF18 /* Transfers */ = { isa = PBXGroup; children = ( + D59D37CF2F0EE97C0072C824 /* TransfersListener.swift */, F78026112E9CFA6000B63436 /* NCTransfersModel.swift */, F780260F2E9CF9DE00B63436 /* NCTransfersView.swift */, ); @@ -3181,11 +3238,10 @@ F71CFA662F2A07C6007A3AE9 /* NCMedia+Netwoking.swift */, F7E2B64E2DDCC5C30075B4D0 /* NCMedia+TransferDelegate.swift */, F78B87E62B62527100C65ADC /* NCMediaDataSource.swift */, + 420113DB2D1303E00063BF54 /* NCMediaSelectTabBar.swift */, F78B87E82B62550800C65ADC /* NCMediaDownloadThumbnail.swift */, F755CB3F2B8CB13C00CE27E9 /* NCMediaLayout.swift */, - F79699E62E689F68000EC82A /* NCMediaNavigationController.swift */, F7D60CAE2C941ACB008FBFDD /* NCMediaPinchGesture.swift */, - F741C2232B6B9FD600E849BB /* NCMediaSelectTabBar.swift */, ); path = Media; sourceTree = ""; @@ -3241,8 +3297,9 @@ F7F67B9F1A24D27800EE80DA = { isa = PBXGroup; children = ( + 4216512A2E28F654002E19D6 /* NextcloudDebug.entitlements */, AA8E041E2D3114E200E7E89C /* README.md */, - F7B8B82F25681C3400967775 /* GoogleService-Info.plist */, + 625EC2702C6CAABD006411D1 /* GoogleService-Info.plist */, F7C1CDD91E6DFC6F005D92BE /* Brand */, F7F67BAA1A24D27800EE80DA /* iOSClient */, F7F67BAB1A24D27800EE80DA /* Supporting Files */, @@ -3264,29 +3321,38 @@ C04E2F202A17BB4D001BAD85 /* NextcloudIntegrationTests.xctest */, C0046CDA2A17B98400D87C9D /* NextcloudUITests.xctest */, F7F1FBA62E27D13700C79E20 /* Frameworks */, + 424AC92F2E9004B300D92A38 /* Recovered References */, ); sourceTree = ""; }; F7F67BAA1A24D27800EE80DA /* iOSClient */ = { isa = PBXGroup; children = ( - AA517BB42D66149900F8D37C /* .tx */, + D5AF19722F127D9700D4F47F /* Account */, + D59D37D22F1082F50072C824 /* NCBackgroundLocationUploadManager.swift */, + 426D0F862D2826B200F76A65 /* Toolbar */, + D5E1D4FA2CF4A86F00813AB6 /* DataProtection */, + D5C2D21D2C9DC0D800E7579D /* Components */, + 0F4374A92D8442BA0081F7C3 /* .tx */, F702F2CC25EE5B4F008F8E80 /* AppDelegate.swift */, F7CAFE1A2F16AA8600DB35A5 /* main.swift */, F794E13E2BBC0F70003693D7 /* SceneDelegate.swift */, F7CF067A2E0FF38F0063AD04 /* NCAppStateManager.swift */, F77DD6A72C5CC093009448FB /* NCSession.swift */, F76B649B2ADFFAED00014640 /* NCImageCache.swift */, + D5C5133A2C91970B00AE35CA /* NCImagesRepository.swift */, F702F2CE25EE5B5C008F8E80 /* NCGlobal.swift */, - F718E2572DF2D5C3004038AF /* NCBackgroundLocationUploadManager.swift */, F7E402282BA85D1D007E5609 /* PrivacyInfo.xcprivacy */, F73CB5771ED46807005F2A5A /* NCBridgeSwift.h */, F70F96AF2874394B006C8379 /* Nextcloud-Bridging-Header.h */, F7F67BB81A24D27800EE80DA /* Images.xcassets */, + 425F57AE2D2E83DA006D5FD1 /* IonosImages.xcassets */, + 42F5047F2C6F553D001AA432 /* Colors.xcassets */, + 0F08D6B52C9426B800136502 /* Style */, + 4240DB4C2C56446D00E72FC0 /* BurgerMenu */, F769CA1B2966EF4F00039397 /* GUI */, F317C82C2E844C3C00761AEA /* Client Integration */, F70211F31BAC56E9003FC03E /* Main */, - F7FDFF5A2E437E55000D7688 /* Account */, F7A321621E9E37960069AD1B /* Activity */, F76687042B7D067400779E3F /* AudioRecorder */, F3A0478E2BD2668800658E7B /* Assistant */, @@ -3374,16 +3440,6 @@ path = "Account Settings"; sourceTree = ""; }; - F7FDFF5A2E437E55000D7688 /* Account */ = { - isa = PBXGroup; - children = ( - F7FDFF552E437E55000D7688 /* Account Request */, - F7FDFF582E437E55000D7688 /* Account Settings */, - F7FDFF592E437E55000D7688 /* NCAccount.swift */, - ); - path = Account; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -3615,6 +3671,7 @@ F77B0F981D118A16002130FE /* Embed Foundation Extensions */, AFBFD01327551A54002244BC /* ShellScript */, F76DA934277B75710082465B /* Embed Frameworks */, + D5FE6AC22C88A5AC0071802E /* Run Script Firebase dSYM upload */, ); buildRules = ( ); @@ -3652,6 +3709,7 @@ F33EE6E02BF4BDA500CA1A51 /* NIOSSL */, F33EE6EF2BF4C0FF00CA1A51 /* NIO */, F7D4BF532CA2ED9D00A5E746 /* VLCKitSPM */, + 625EC26D2C6CA285006411D1 /* FirebaseAnalytics */, F3374AEF2D78B01B002A38F9 /* BitCollections */, F3374AF12D78B01B002A38F9 /* Collections */, F3374AF32D78B01B002A38F9 /* DequeModule */, @@ -3698,12 +3756,11 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1430; - LastUpgradeCheck = 1630; - ORGANIZATIONNAME = "Marino Faggiana"; + LastUpgradeCheck = 1400; + ORGANIZATIONNAME = "STRATO GmbH"; TargetAttributes = { 2C33C47E23E2C475005F963B = { CreatedOnToolsVersion = 11.3.1; - ProvisioningStyle = Automatic; }; AF8ED1F82757821000B8DBC4 = { CreatedOnToolsVersion = 13.1; @@ -3737,11 +3794,9 @@ F771E3CF20E2392D00AFB62D = { CreatedOnToolsVersion = 9.4.1; LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; }; F77B0DEB1D118A16002130FE = { LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Push = { enabled = 1; @@ -3765,52 +3820,9 @@ Base, de, fr, - "pt-BR", - ru, - it, - tr, - "es-MX", - "nb-NO", - pl, - sv, es, - is, nl, - "sk-SK", - "en-GB", - "zh-Hans", - "ka-GE", - hu, - "zh-Hant-TW", - sr, - "es-CL", - "es-CO", - "es-CR", - "es-DO", - "es-EC", - "es-GT", - "es-HN", - "es-NI", - "es-PA", - "es-PE", - "es-PR", - "es-PY", - "es-SV", - "es-UY", - "cs-CZ", - ko, - "es-419", - "pt-PT", - "ja-JP", - gl, - ca, - da, - eu, - sl, - hr, - lo, - el, - et, + it, ); mainGroup = F7F67B9F1A24D27800EE80DA; packageReferences = ( @@ -3865,6 +3877,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62A63F302C8AF7730048653E /* Colors.xcassets in Resources */, F7E4022F2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, F746EC53273906C50052598D /* NCViewCertificateDetails.storyboard in Resources */, ); @@ -3898,6 +3911,7 @@ F7490E8D29882F5B009DCE94 /* Custom.xcassets in Resources */, F7490E8E2988334A009DCE94 /* Localizable.strings in Resources */, F7E4022E2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, + 0F9E787E2DD77EB8007980BF /* Colors.xcassets in Resources */, AA517B812D660EFE00F8D37C /* Localizable.stringsdict in Resources */, F722F0112CFF569500065FB5 /* MainInterface.storyboard in Resources */, ); @@ -3907,6 +3921,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 42D3D0972C94284C008A5AD4 /* Colors.xcassets in Resources */, + 425F57B12D2E83DB006D5FD1 /* IonosImages.xcassets in Resources */, F714803B262EBE3900693E51 /* MainInterface.storyboard in Resources */, F7148054262ED51000693E51 /* NCListCell.xib in Resources */, F7E4022C2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, @@ -3929,10 +3945,14 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0F9E78812DD77F0A007980BF /* Colors.xcassets in Resources */, F7C7B25128B8B0C400E7115D /* Images.xcassets in Resources */, F7C7B25028B8AD4500E7115D /* Localizable.strings in Resources */, + FC930DC52CEDE33000C9B237 /* Colors.xcassets in Resources */, F7E4022A2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, + 425F57B02D2E83DB006D5FD1 /* IonosImages.xcassets in Resources */, AA517B832D660EFE00F8D37C /* Localizable.stringsdict in Resources */, + 0F9E787F2DD77ECE007980BF /* Custom.xcassets in Resources */, F7346E2328B0FEBA006CE2D2 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3941,6 +3961,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0F9E787D2DD77EB8007980BF /* Colors.xcassets in Resources */, F7E4022D2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, F746EC52273906C40052598D /* NCViewCertificateDetails.storyboard in Resources */, ); @@ -3969,6 +3990,7 @@ F765F73225237E3F00391DBE /* NCRecent.storyboard in Resources */, F78F74342163757000C2ADAD /* NCTrash.storyboard in Resources */, F702F30225EE5D2C008F8E80 /* english.txt in Resources */, + 0F8B9A5B2C7887F60041C17D /* FileActionsHeader.xib in Resources */, F757CC8C29E82D0500F31428 /* NCGroupfolders.storyboard in Resources */, F79A65C32191D90F00FF6DCC /* NCSelect.storyboard in Resources */, F7226EDC1EE4089300EBECB1 /* Main.storyboard in Resources */, @@ -3982,7 +4004,6 @@ F7A48415297028FC00BD1B49 /* Nextcloud Hub.png in Resources */, F74C0437253F1CDC009762AB /* NCShares.storyboard in Resources */, F7F4F10C27ECDBDB008676F9 /* Inconsolata-Regular.ttf in Resources */, - F7B8B83025681C3400967775 /* GoogleService-Info.plist in Resources */, F7381EE5218218C9000B1560 /* NCOffline.storyboard in Resources */, F768822D2C0DD1E7001CF441 /* Acknowledgements.rtf in Resources */, F76D3CF32428B94E005DFA87 /* NCViewerPDFSearchCell.xib in Resources */, @@ -4005,6 +4026,7 @@ F7E402292BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, F7C9555321F0C4CA0024296E /* NCActivity.storyboard in Resources */, F7BC287E26663F6C004D46C5 /* NCViewCertificateDetails.storyboard in Resources */, + 625EC2712C6CAABD006411D1 /* GoogleService-Info.plist in Resources */, F78ACD54219047D40088454D /* NCSectionFooter.xib in Resources */, F751247E2C42919C00E63DB8 /* NCPhotoCell.xib in Resources */, F704B5E32430AA6F00632F5F /* NCCreateFormUploadConflict.storyboard in Resources */, @@ -4020,6 +4042,9 @@ F774264A22EB4D0000B23912 /* NCSearchUserDropDownCell.xib in Resources */, F7CB689A2541676B0050EC94 /* NCMore.storyboard in Resources */, F77B0F7D1D118A16002130FE /* Images.xcassets in Resources */, + 425F57AF2D2E83DB006D5FD1 /* IonosImages.xcassets in Resources */, + 42F504802C6F553D001AA432 /* Colors.xcassets in Resources */, + F768822B2C0DD1E7001CF441 /* (null) in Resources */, F73CB3B222E072A000AD728E /* NCShareHeaderView.xib in Resources */, F7AE00FA230E81EB007ACF8A /* NCBrowserWeb.storyboard in Resources */, F7EDE514262DC2CD00414FE6 /* NCSelectCommandViewSelect+CreateFolder.xib in Resources */, @@ -4033,6 +4058,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0F9E78822DD77F0A007980BF /* Colors.xcassets in Resources */, + 0F9E78802DD77ECE007980BF /* Custom.xcassets in Resources */, F7E4022B2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4058,6 +4085,25 @@ shellPath = /bin/sh; shellScript = "if test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; + D5FE6AC22C88A5AC0071802E /* Run Script Firebase dSYM upload */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Run Script Firebase dSYM upload"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "${BUILD_DIR%Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -4090,6 +4136,7 @@ AA8D31592D41052900FE2775 /* NCManageDatabase+DownloadLimit.swift in Sources */, F749B64F297B0CBB00087535 /* NCManageDatabase+Share.swift in Sources */, F73EF7AD2B0223900087E6E9 /* NCManageDatabase+Comments.swift in Sources */, + 0F9DB9BA2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, F76340F52EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */, F7C9B9232B582F550064EA91 /* NCManageDatabase+SecurityGuard.swift in Sources */, F7CF06832E1127460063AD04 /* NCManageDatabase+CreateMetadata.swift in Sources */, @@ -4162,7 +4209,6 @@ F7490E6E29882B56009DCE94 /* NCBrand.swift in Sources */, F7D61E942EBF1366007F865B /* UIColor+Extension.swift in Sources */, F71F6D0C2B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */, - F76340ED2EBDE74C0056F538 /* NCManageDatabase.swift in Sources */, F7D61EAC2EBF16B6007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */, F763413C2EBE5DB60056F538 /* FileProviderExtension+Actions.swift in Sources */, F76341022EBDF6710056F538 /* NCManageDatabase+Tag.swift in Sources */, @@ -4180,6 +4226,7 @@ F7490E6B29882A92009DCE94 /* NCGlobal.swift in Sources */, F763413E2EBE5DC00056F538 /* FileProviderItem.swift in Sources */, F7490E8729882CA8009DCE94 /* ThreadSafeDictionary.swift in Sources */, + 0F9DB9BE2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, F7E742FA2EC0A5BC00E2362A /* NCManageDatabase+Metadata.swift in Sources */, F7E742FC2EC0A5FD00E2362A /* NCManageDatabase+Metadata+Session.swift in Sources */, F3E173C52C9B1067006D177A /* AwakeMode.swift in Sources */, @@ -4187,6 +4234,7 @@ F7E742F82EC0A4CD00E2362A /* NCManageDatabase+LocalFile.swift in Sources */, F7E742F62EC0A3DD00E2362A /* NCManageDatabase+Directory.swift in Sources */, F763413F2EBE5DC40056F538 /* FileProviderUtility.swift in Sources */, + D52D54022F0DE1BE00D824BF /* NCManageDatabase.swift in Sources */, F763413A2EBE5DAB0056F538 /* FileProviderEnumerator.swift in Sources */, F763412F2EBE255B0056F538 /* NCNetworking+NextcloudKitDelegate.swift in Sources */, ); @@ -4197,11 +4245,13 @@ buildActionMask = 2147483647; files = ( F7864ACF2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */, + 426533652F698AD70092B12B /* NCCellMain.swift in Sources */, F71F6D0A2B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */, F7245925289BB59100474787 /* ThreadSafeDictionary.swift in Sources */, F72EC7292F4617F600A2135C /* NotificationCenter+Extension.swift in Sources */, F7BF9D852934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */, F79EC78926316AC4004E59D6 /* NCPopupViewController.swift in Sources */, + 62A63F2E2C8AF5320048653E /* View+Extension.swift in Sources */, F7C30DFB291BCF790017149B /* NCNetworkingE2EECreateFolder.swift in Sources */, F73EF7DA2B0226080087E6E9 /* NCManageDatabase+Tip.swift in Sources */, F70557BF2ED44F1800135623 /* UploadBannerView.swift in Sources */, @@ -4220,6 +4270,7 @@ F70BFC7520E0FA7D00C67599 /* NCUtility.swift in Sources */, AF22B20C277C6F4D00DAB0CC /* NCShareCell.swift in Sources */, F7B769AB2B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift in Sources */, + D5C5133E2C919B8500AE35CA /* NCImagesRepository.swift in Sources */, F7E98C1727E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */, F76340F82EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */, F79ED0F12D2FCA5B00A389D9 /* NCSectionFirstHeader.swift in Sources */, @@ -4227,6 +4278,7 @@ F77C973A2953143A00FDDD09 /* NCCameraRoll.swift in Sources */, F740BEF02A35C2AD00E9B6D5 /* UILabel+Extension.swift in Sources */, F7C30E01291BD2610017149B /* NCNetworkingE2EERename.swift in Sources */, + 0F9DB9BF2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, AF4BF61A27562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */, AF4BF615275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */, F798F0E225880608000DAFFD /* UIColor+Extension.swift in Sources */, @@ -4276,7 +4328,6 @@ F799DF862C4B7E56003410B5 /* NCSectionHeader.swift in Sources */, F702F2D025EE5B5C008F8E80 /* NCGlobal.swift in Sources */, F72437802C10B92400C7C68D /* NCSharePermissions.swift in Sources */, - F7EDE4DB262D7BA200414FE6 /* NCCellMain.swift in Sources */, F72944F62A8424F800246839 /* NCEndToEndMetadataV1.swift in Sources */, F73EF7BA2B0224AB0087E6E9 /* NCManageDatabase+ExternalSites.swift in Sources */, F711A4EB2AF9327D00095DD8 /* UIImage+animatedGIF.m in Sources */, @@ -4296,6 +4347,7 @@ F757CC8529E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */, F768823A2C0DD230001CF441 /* NCPreferences.swift in Sources */, F737DA9E2B7B893C0063BAFC /* NCPasscode.swift in Sources */, + 4232DC0B2C9D7C44008D546D /* UIView+GridSelection.swift in Sources */, F7C30DF7291BC0D30017149B /* NCNetworkingE2EEUpload.swift in Sources */, F7C687EC2D22BDE5004757BC /* NCManageDatabase+RecommendedFiles.swift in Sources */, F33918C72C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */, @@ -4323,6 +4375,7 @@ buildActionMask = 2147483647; files = ( F76DEE9928F808AF0041B1C9 /* LockscreenWidgetView.swift in Sources */, + 0F9DB9BC2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, F78302F928B4C3E600B84583 /* NCManageDatabase+Account.swift in Sources */, F7E0710128B13BB00001B882 /* DashboardData.swift in Sources */, F783030328B4C4DD00B84583 /* ThreadSafeDictionary.swift in Sources */, @@ -4333,7 +4386,7 @@ F7D61EAA2EBF1694007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */, F78302F828B4C3E100B84583 /* NCManageDatabase+Activity.swift in Sources */, F711A4E92AF9327600095DD8 /* UIImage+animatedGIF.m in Sources */, - F7D61EBD2EBF1878007F865B /* NCManageDatabase+Tag.swift in Sources */, + FC930DC72CEE377700C9B237 /* WidgetCommon.swift in Sources */, F783030228B4C4B800B84583 /* NCUtility.swift in Sources */, F711D63128F44801003F43C8 /* IntentHandler.swift in Sources */, F76DEE9728F808AF0041B1C9 /* LockscreenData.swift in Sources */, @@ -4357,6 +4410,7 @@ F757CC8329E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */, F73EF7A82B0223900087E6E9 /* NCManageDatabase+Comments.swift in Sources */, F74B6D962A7E239A00F03C5F /* NCManageDatabase+Chunk.swift in Sources */, + D59D37CC2F0ECAEC0072C824 /* NCManageDatabase+Tag.swift in Sources */, F711A4E32AF9310400095DD8 /* NCUtility+Image.swift in Sources */, F749B652297B0F2400087535 /* NCManageDatabase+Avatar.swift in Sources */, F763D29E2A249C4500A3C901 /* NCManageDatabase+Capabilities.swift in Sources */, @@ -4401,11 +4455,13 @@ F702F2D125EE5B5C008F8E80 /* NCGlobal.swift in Sources */, F76341012EBDF6710056F538 /* NCManageDatabase+Tag.swift in Sources */, F7434B3820E2400600417916 /* NCBrand.swift in Sources */, + 0F9DB9BD2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, F785EE9E2461A09900B3F945 /* NCNetworking.swift in Sources */, F771E3D320E2392D00AFB62D /* FileProviderExtension.swift in Sources */, F7D61EAB2EBF16B6007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */, F771E3D520E2392D00AFB62D /* FileProviderItem.swift in Sources */, F3E173C42C9B1067006D177A /* AwakeMode.swift in Sources */, + 6256F5462C9846DE0032A1CF /* View+Extension.swift in Sources */, F7D61E932EBF1366007F865B /* UIColor+Extension.swift in Sources */, F76340F42EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */, F7CAFE212F17A37C00DB35A5 /* NCNetworking+Actor.swift in Sources */, @@ -4431,11 +4487,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D52D53EF2F0DCD1600D824BF /* NCMediaSelectTabBar.swift in Sources */, F77444F522281649000D5EB0 /* NCMediaCell.swift in Sources */, F78C6FDE296D677300C952C3 /* NCContextMenuMain.swift in Sources */, A5A87F9E4B0E4441A6A4BC20 /* NCContextMenuProfile.swift in Sources */, CB3666201AF7550816B5CD6A /* NCContextMenuComment.swift in Sources */, - 2F96A1BAFB10ACFEAC68EF1C /* NCContextMenuPlayerTracks.swift in Sources */, F7E402332BA89551007E5609 /* NCTrash+Networking.swift in Sources */, F73EF7A72B0223900087E6E9 /* NCManageDatabase+Comments.swift in Sources */, F33918C42C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */, @@ -4447,7 +4503,6 @@ F3C6F6F62F34CC0900C531B6 /* NCAssistantChatConversationsModel.swift in Sources */, F76340FC2EBDF64D0056F538 /* NCManageDatabase+Tag.swift in Sources */, F733598125C1C188002ABA72 /* NCAskAuthorization.swift in Sources */, - 370D26AF248A3D7A00121797 /* NCCellMain.swift in Sources */, F32FADA92D1176E3007035E2 /* UIButton+Extension.swift in Sources */, F7DF7B3F2F1A2EF900514020 /* BannerView.swift in Sources */, F768822C2C0DD1E7001CF441 /* NCPreferences.swift in Sources */, @@ -4457,15 +4512,17 @@ F73EF7D72B0226080087E6E9 /* NCManageDatabase+Tip.swift in Sources */, F3374A842D64AC31002A38F9 /* AssistantLabelStyle.swift in Sources */, F74BAE172C7E2F4E0028D4FA /* FileProviderDomain.swift in Sources */, + 4232DC0A2C9D7C44008D546D /* UIView+GridSelection.swift in Sources */, + D5E1D5002CF4EB3900813AB6 /* DataProtectionModel.swift in Sources */, F76882402C0DD30B001CF441 /* ViewOnAppear.swift in Sources */, F790110E21415BF600D7B136 /* NCViewerRichDocument.swift in Sources */, F78ACD4021903CC20088454D /* NCGridCell.swift in Sources */, F7D890752BD25C570050B8A6 /* NCCollectionViewCommon+DragDrop.swift in Sources */, F7BD0A042C4689E9003A4A6D /* NCMedia+MediaLayout.swift in Sources */, - F718E25A2DF2D5D1004038AF /* NCBackgroundLocationUploadManager.swift in Sources */, + 426E38DD2F571E8D0073EE47 /* NCMediaCoordinatorConstants.swift in Sources */, F761856B29E98543006EB3B0 /* NCIntroViewController.swift in Sources */, F7743A142C33F13A0034F670 /* NCCollectionViewCommon+CollectionViewDataSource.swift in Sources */, - F321DA8A2B71205A00DDA0E6 /* NCTrashSelectTabBar.swift in Sources */, + 4240DB4E2C5646B400E72FC0 /* BurgerMenuAttachController.swift in Sources */, F76882282C0DD1E7001CF441 /* NCEndToEndInitialize.swift in Sources */, F702F2CD25EE5B4F008F8E80 /* AppDelegate.swift in Sources */, F769454022E9F077000A798A /* NCSharePaging.swift in Sources */, @@ -4490,12 +4547,14 @@ F757CC8229E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */, F7B769A82B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift in Sources */, F79EDAA326B004980007D134 /* NCPlayerToolBar.swift in Sources */, + D5EB5DD42F490D2F009D88B1 /* NCContextMenuPlayerTracks.swift in Sources */, F7B934FE2BDCFE1E002B2FC9 /* NCDragDrop.swift in Sources */, F77444F8222816D5000D5EB0 /* NCPickerViewController.swift in Sources */, F77BB74A2899857B0090FC19 /* UINavigationController+Extension.swift in Sources */, F70898672EDDB39B00EF85BD /* NCNetworking+TransferDelegate.swift in Sources */, F769454622E9F1B0000A798A /* NCShareCommon.swift in Sources */, F70753F12542A9A200972D44 /* NCViewerMedia.swift in Sources */, + 420274712F11558400ECB06B /* NCCellMedia.swift in Sources */, F799DF822C4B7DCC003410B5 /* NCSectionFooter.swift in Sources */, F76B649C2ADFFAED00014640 /* NCImageCache.swift in Sources */, F76341182EBE0BC60056F538 /* NCNetworking+NextcloudKitDelegate.swift in Sources */, @@ -4504,25 +4563,30 @@ F768822E2C0DD1E7001CF441 /* NCSettingsBundleHelper.swift in Sources */, F72408332B8A27C900F128E2 /* NCMedia+Command.swift in Sources */, F755CB402B8CB13C00CE27E9 /* NCMediaLayout.swift in Sources */, + 426D0F892D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbar.swift in Sources */, + 426D0F8A2D2826D600F76A65 /* HiDriveCollectionViewCommonSelectToolbarView.swift in Sources */, F73EF7B72B0224AB0087E6E9 /* NCManageDatabase+ExternalSites.swift in Sources */, AF4BF61927562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */, F78A18B623CDD07D00F681F3 /* NCViewerRichWorkspaceWebView.swift in Sources */, AFA2AC8527849604008E1EA7 /* NCActivityCommentView.swift in Sources */, AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */, + 0F5090CE2C786F04009348D9 /* FileActionsHeader.swift in Sources */, F75A9EE623796C6F0044CFCE /* NCNetworking.swift in Sources */, F72EC7282F45FF1400A2135C /* NCContextMenuPlus.swift in Sources */, AA8D31552D41052300FE2775 /* NCManageDatabase+DownloadLimit.swift in Sources */, F758B460212C56A400515F55 /* NCScan.swift in Sources */, F76882262C0DD1E7001CF441 /* NCSettingsView.swift in Sources */, F78ACD52219046DC0088454D /* NCSectionFirstHeader.swift in Sources */, + 42D34FD92D79A5B00020C106 /* ShareSearchField.swift in Sources */, F743C89E2E5B25A1000173A9 /* UIScene+Extension.swift in Sources */, F72944F52A8424F800246839 /* NCEndToEndMetadataV1.swift in Sources */, F710D2022405826100A6033D /* NCViewerContextMenu.swift in Sources */, + 428915312F226C1500B41486 /* PlaybackProgressView.swift in Sources */, F765E9CD295C585800A09ED8 /* NCUploadScanDocument.swift in Sources */, - F741C2242B6B9FD600E849BB /* NCMediaSelectTabBar.swift in Sources */, F7BF9D822934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */, AA8D31662D411FA100FE2775 /* NCShareDateCell.swift in Sources */, F3F442EE2DDE292D00FD701F /* NCMetadataPermissions.swift in Sources */, + 420216592F557CB100BBD630 /* NCMediaCoordinatorAVKitStrategy.swift in Sources */, F3374A812D64AB9F002A38F9 /* StatusInfo.swift in Sources */, AF7E504E27A2D8FF00B5E4AF /* UIBarButton+Extension.swift in Sources */, AA8D31682D41224800FE2775 /* NCShareToggleCell.swift in Sources */, @@ -4531,10 +4595,12 @@ F78A10BF29322E8A008499B8 /* NCManageDatabase+Directory.swift in Sources */, F7743A122C33F0A20034F670 /* NCCollectionViewCommon+CollectionViewDelegate.swift in Sources */, F7D60CAF2C941ACB008FBFDD /* NCMediaPinchGesture.swift in Sources */, + 0F08D6B92C94270600136502 /* ButtonStyleGuide.swift in Sources */, F71916142E2901FB00E13E96 /* NCNetworking+Upload.swift in Sources */, F704B5E92430C0B800632F5F /* NCCreateFormUploadConflictCell.swift in Sources */, F72D404923D2082500A97FD0 /* NCViewerNextcloudText.swift in Sources */, AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */, + 421DC45F2F6D38F3001EE5E3 /* ItemShareState.swift in Sources */, F77BB746289984CA0090FC19 /* UIViewController+Extension.swift in Sources */, F700510522DF6A89003A3356 /* NCShare.swift in Sources */, F72D1007210B6882009C96B7 /* NCPushNotificationEncryption.m in Sources */, @@ -4542,6 +4608,7 @@ F785EE9D246196DF00B3F945 /* NCNetworkingE2EE.swift in Sources */, F724377B2C10B83E00C7C68D /* NCSharePermissions.swift in Sources */, F317C82E2E844C5300761AEA /* ClientIntegrationUIViewer.swift in Sources */, + 420216572F557C9100BBD630 /* NCMediaCoordinatorVLCStrategy.swift in Sources */, F794E13D2BBBFF2E003693D7 /* NCMainTabBarController.swift in Sources */, F7CBC1252BAC8B0000EC1D55 /* NCSectionFirstHeaderEmptyData.swift in Sources */, F7D4BF3D2CA2E8D800A5E746 /* TOPasscodeKeypadView.m in Sources */, @@ -4573,6 +4640,7 @@ F7DF7B422F1A36C100514020 /* HelperBanner.swift in Sources */, F78ACD4A21903F850088454D /* NCTrashListCell.swift in Sources */, F7386E482DA90E0F009A00F6 /* NCAppVersionManager.swift in Sources */, + 4250C8472E2E53BA00349A8A /* NCMediaCoordinator.swift in Sources */, F76882352C0DD1E7001CF441 /* NCWebBrowserView.swift in Sources */, F3A047972BD2668800658E7B /* NCAssistantEmptyView.swift in Sources */, F757CC8D29E82D0500F31428 /* NCGroupfolders.swift in Sources */, @@ -4580,6 +4648,8 @@ F7F3E58E2D3BB65600A32B14 /* NCNetworking+Recommendations.swift in Sources */, F7A0D1352591FBC5008F8A13 /* String+Extension.swift in Sources */, F7CEE6012BA9A5C9003EFD89 /* NCTrashGridCell.swift in Sources */, + 42678ABE2C57C5FB00307DEF /* BurgerMenuViewModel.swift in Sources */, + 0F08D6BB2C94275600136502 /* CircleItemSpinner.swift in Sources */, F70557BD2ED44F1800135623 /* UploadBannerView.swift in Sources */, F7F9D1BB25397CE000D9BFF5 /* NCViewer.swift in Sources */, F7E7AEA52BA32C6500512E52 /* NCCollectionViewDownloadThumbnail.swift in Sources */, @@ -4588,6 +4658,7 @@ F78F74362163781100C2ADAD /* NCTrash.swift in Sources */, F39298972A3B12CB00509762 /* BaseNCMoreCell.swift in Sources */, AF2D7C7C2742556F00ADF566 /* NCShareLinkCell.swift in Sources */, + 0F4AA7812DE0A3F700138679 /* NCLoginNavigationController.swift in Sources */, F7E41316294A19B300839300 /* UIView+Extension.swift in Sources */, F7C30E00291BD2610017149B /* NCNetworkingE2EERename.swift in Sources */, F74AF3A4247FB6AE00AC767B /* NCUtilityFileSystem.swift in Sources */, @@ -4595,7 +4666,9 @@ F73EF7BF2B02250B0087E6E9 /* NCManageDatabase+GPS.swift in Sources */, F39A1EE22D0AF8A400DAD522 /* Albums.swift in Sources */, F71F6D072B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */, + D5C2D21F2C9DC0EF00E7579D /* PrimaryButton.swift in Sources */, F761856C29E98543006EB3B0 /* NCIntroCollectionViewCell.swift in Sources */, + 4240DB522C5649A900E72FC0 /* BurgerMenuView.swift in Sources */, F75DD765290ABB25002EB562 /* Intent.intentdefinition in Sources */, F7D4BF012CA1831900A5E746 /* NCCollectionViewCommonPinchGesture.swift in Sources */, F74B6D952A7E239A00F03C5F /* NCManageDatabase+Chunk.swift in Sources */, @@ -4604,6 +4677,8 @@ F7EB9B132BBC12F300EDF036 /* UIApplication+Extension.swift in Sources */, F75D90212D2BE26F003E740B /* NCRecommendationsCell.swift in Sources */, F7E98C1627E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */, + D5C5133B2C91970B00AE35CA /* NCImagesRepository.swift in Sources */, + 4202165D2F5586D800BBD630 /* NCMediaCoordinatorStrategy.swift in Sources */, F76882222C0DD1E7001CF441 /* NCCapabilitiesView.swift in Sources */, F3CA337D2D0B2B6C00672333 /* AlbumModel.swift in Sources */, AF93471A27E2361E002537EE /* NCShareHeader.swift in Sources */, @@ -4629,6 +4704,8 @@ F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */, AFCE353527E4ED5900FEA6C2 /* DateFormatter+Extension.swift in Sources */, F718C24E254D507B00C5C256 /* NCViewerMediaDetailView.swift in Sources */, + D5E1D5042CF665C100813AB6 /* DataProtectionHostingController.swift in Sources */, + 0F4AA77C2DE083D600138679 /* NCMainTabBar.swift in Sources */, F33EE6F22BF4C9B200CA1A51 /* PKCS12.swift in Sources */, F7145610296433C80038D028 /* NCDocumentCamera.swift in Sources */, F34E1AD72ECB937D00FA10C3 /* NCStatusMessageView.swift in Sources */, @@ -4636,10 +4713,13 @@ F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */, F751247C2C42919C00E63DB8 /* NCPhotoCell.swift in Sources */, F7A509252C26BD5D00326106 /* NCCreate.swift in Sources */, + 0F8615AC2CBE6AC20056B4F2 /* UITabBarGuideline.swift in Sources */, + F7A509252C26BD5D00326106 /* NCCreate.swift in Sources */, F7FA80002C0F4F3B0072FC60 /* NCUploadAssetsModel.swift in Sources */, F719D9E2288D396100762E33 /* NCColorPicker.swift in Sources */, F73EF7DF2B02266D0087E6E9 /* NCManageDatabase+Trash.swift in Sources */, F79B646026CA661600838ACA /* UIControl+Extension.swift in Sources */, + 42C684B42CA1806000DD46F0 /* SecondaryButton.swift in Sources */, F768823E2C0DD305001CF441 /* LazyView.swift in Sources */, F7CAFE1B2F16AA8D00DB35A5 /* main.swift in Sources */, F3E173B02C9AF637006D177A /* ScreenAwakeManager.swift in Sources */, @@ -4647,9 +4727,10 @@ F765F73125237E3F00391DBE /* NCRecent.swift in Sources */, F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */, F7FA7FFC2C0F4EE40072FC60 /* NCViewerQuickLookView.swift in Sources */, + 426533642F698AD70092B12B /* NCCellMain.swift in Sources */, + D52D53F32F0DD53300D824BF /* AccountButtonFactory.swift in Sources */, F3A0479B2BD2668800658E7B /* NCAssistant.swift in Sources */, F359D8672A7D03420023F405 /* NCUtility+Exif.swift in Sources */, - F7A03E352D427312007AA677 /* NCMainNavigationController.swift in Sources */, F769CA192966EA3C00039397 /* ComponentView.swift in Sources */, F7C9B91D2B582F550064EA91 /* NCManageDatabase+SecurityGuard.swift in Sources */, AF93474C27E34120002537EE /* NCUtility+Image.swift in Sources */, @@ -4661,9 +4742,11 @@ F7CF06882E1127460063AD04 /* NCManageDatabase+CreateMetadata.swift in Sources */, F72FD3B5297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */, F7BD0A022C4689A4003A4A6D /* NCMedia+CollectionViewDelegate.swift in Sources */, + 42F89EB12D71F30C00550A07 /* NCCollectionViewCommon+FileActionsHeader.swift in Sources */, F3A047982BD2668800658E7B /* NCAssistantCreateNewTask.swift in Sources */, AF93471227E2341B002537EE /* NCContextMenuShare.swift in Sources */, F7EFA47825ADBA500083159A /* NCViewerProviderContextMenu.swift in Sources */, + 42E5D36B2D678F9C007150DE /* HiDriveMainNavigationController.swift in Sources */, F755BD9B20594AC7008C5FBB /* NCService.swift in Sources */, F376A3742E5CC6030067EE25 /* ContextMenuActions.swift in Sources */, F7E8A391295DC5E0006CB2D0 /* View+Extension.swift in Sources */, @@ -4676,6 +4759,8 @@ F76882322C0DD1E7001CF441 /* NCAutoUploadView.swift in Sources */, F36E64F72B9245210085ABB5 /* NCCollectionViewCommon+SelectTabBarDelegate.swift in Sources */, F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */, + 42F907DE2D2C424900BCDC36 /* View+Design.swift in Sources */, + F75D19E325EFE09000D74598 /* NCContextMenuTrash.swift in Sources */, F75D19E325EFE09000D74598 /* NCContextMenuTrash.swift in Sources */, F34E1ADB2ECC842B00FA10C3 /* NCStatusMessageModel.swift in Sources */, F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */, @@ -4685,18 +4770,18 @@ AA8D31702D4123B200FE2775 /* DownloadLimitViewModel.swift in Sources */, AA8D31712D4123B200FE2775 /* NCShareDownloadLimitViewController.swift in Sources */, AF93471B27E2361E002537EE /* NCShareAdvancePermission.swift in Sources */, + D59D37D72F1082F60072C824 /* NCBackgroundLocationUploadManager.swift in Sources */, F77BC3ED293E528A005F2B08 /* NCConfigServer.swift in Sources */, F7A560422AE1593700BE8FD6 /* NCOperationSaveLivePhoto.swift in Sources */, F7D1C4AC2C9484FD00EC6D44 /* NCMedia+CollectionViewDataSourcePrefetching.swift in Sources */, F7D368DF2DAFE19E0037E7C6 /* NCActivityNavigationController.swift in Sources */, - F7A03E332D426115007AA677 /* NCMoreNavigationController.swift in Sources */, F7E402312BA891EB007E5609 /* NCTrash+SelectTabBarDelegate.swift in Sources */, + D5E1D4FE2CF4E7C600813AB6 /* DataProtectionSettingsScreen.swift in Sources */, F70753EB2542A99800972D44 /* NCViewerMediaPage.swift in Sources */, F7817CF829801A3500FFBC65 /* Data+Extension.swift in Sources */, F749B651297B0F2400087535 /* NCManageDatabase+Avatar.swift in Sources */, F7FAFD3A28BFA948000777FE /* NCContextMenuNotification.swift in Sources */, F74C0436253F1CDC009762AB /* NCShares.swift in Sources */, - F79699E72E689F68000EC82A /* NCMediaNavigationController.swift in Sources */, F7AC1CB028AB94490032D99F /* Array+Extension.swift in Sources */, F7AE00F5230D5F9E007ACF8A /* NCLoginProvider.swift in Sources */, F707C26521A2DC5200F6181E /* NCStoreReview.swift in Sources */, @@ -4710,9 +4795,10 @@ F343A4B32A1E01FF00DDA874 /* PHAsset+Extension.swift in Sources */, F70968A424212C4E00ED60E5 /* NCLivePhoto.swift in Sources */, F7C30DFA291BCF790017149B /* NCNetworkingE2EECreateFolder.swift in Sources */, - F722133B2D40EF9D002F7438 /* NCFilesNavigationController.swift in Sources */, F7BC288026663F85004D46C5 /* NCViewCertificateDetails.swift in Sources */, F78B87E92B62550800C65ADC /* NCMediaDownloadThumbnail.swift in Sources */, + 4240DB502C5648E300E72FC0 /* BurgerMenuViewController.swift in Sources */, + 0F9DB9C12DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */, F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */, F7FDFF6B2E437E55000D7688 /* NCAccountRequest.swift in Sources */, @@ -4724,14 +4810,15 @@ F749B64A297B0CBB00087535 /* NCManageDatabase+Share.swift in Sources */, F7C9555521F0C5470024296E /* NCActivity.swift in Sources */, F7725A60251F33BB00D125E0 /* NCFiles.swift in Sources */, + D59D37CE2F0EDAEC0072C824 /* UIDevice+VirtualOrientation.swift in Sources */, F3BB46522A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift in Sources */, F704B5E52430AA8000632F5F /* NCCreateFormUploadConflict.swift in Sources */, F765608F23BF813600765969 /* NCContentPresenter.swift in Sources */, F7865FF12F39D32F00D09AE4 /* NCCollectionViewCommon+Search.swift in Sources */, F7327E352B73AEDE00A462C7 /* NCNetworking+LivePhoto.swift in Sources */, F76687072B7D067400779E3F /* NCAudioRecorderViewController.swift in Sources */, + 421657AB2D2AF2BF003BC9D5 /* HiDriveCollectionViewCommonSelectToolbarDelegate.swift in Sources */, AA8E03DA2D2ED83300E7E89C /* TransientShare.swift in Sources */, - F7A03E2F2D425A14007AA677 /* NCFavoriteNavigationController.swift in Sources */, F343A4BB2A1E734600DDA874 /* Optional+Extension.swift in Sources */, F76882232C0DD1E7001CF441 /* NCCapabilitiesModel.swift in Sources */, F3DDFE212F1F953000A784C8 /* NCAssistantChatConversations.swift in Sources */, @@ -4745,6 +4832,7 @@ AA8E041D2D300FDE00E7E89C /* NCShareNetworkingDelegate.swift in Sources */, F78E2D6529AF02DB0024D4F3 /* Database.swift in Sources */, F70CEF5623E9C7E50007035B /* UIColor+Extension.swift in Sources */, + 42C684B72CA1A20100DD46F0 /* CommonButtonConstants.swift in Sources */, F76882242C0DD1E7001CF441 /* NCSettingsAdvancedView.swift in Sources */, F785129C2D7989B30087DDD0 /* NCNetworking+TermsOfService.swift in Sources */, F77C3F5B2D9BF8CD00F3C471 /* UITabBar+Extension.swift in Sources */, @@ -4755,19 +4843,21 @@ F752BA052E58C05200616A26 /* Maintenance.swift in Sources */, F763D29D2A249C4500A3C901 /* NCManageDatabase+Capabilities.swift in Sources */, F76882252C0DD1E7001CF441 /* NCSettingsAdvancedModel.swift in Sources */, + 4294B88B2CA5550B002E6FED /* LinkButton.swift in Sources */, F7C7B489245EBA4100D93E60 /* NCViewerQuickLook.swift in Sources */, F758B45E212C569D00515F55 /* NCScanCell.swift in Sources */, + D5E1D4FC2CF4A99300813AB6 /* DataProtectionAgreementScreen.swift in Sources */, F78B87E72B62527100C65ADC /* NCMediaDataSource.swift in Sources */, F76882272C0DD1E7001CF441 /* NCManageE2EEView.swift in Sources */, F7864ACC2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */, F7327E302B73A86700A462C7 /* NCNetworking+WebDAV.swift in Sources */, + D59793B62CF7A73A00C44F4E /* DataProtectionAgreementManager.swift in Sources */, F3DDFE1E2F1F8EC600A784C8 /* ChatInputField.swift in Sources */, F7D61EA82EBF1694007F865B /* NCManageDatabase+TableCapabilities.swift in Sources */, F79FFB262A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */, F70D8D8124A4A9BF000A5756 /* NCNetworkingProcess.swift in Sources */, F3A0479A2BD2668800658E7B /* NCAssistantTaskDetail.swift in Sources */, F71D2FB72E09BBD700B751CC /* NCAutoUploadModel.swift in Sources */, - F38F71252B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift in Sources */, F7E4D9C422ED929B003675FD /* NCShareCommentsCell.swift in Sources */, F73EFF9B2DB11EC900FD434C /* NCFiles+UIScrollViewDelegate.swift in Sources */, F7327E202B73A42F00A462C7 /* NCNetworking+Download.swift in Sources */, @@ -4775,6 +4865,7 @@ AA62DF602D5DF1F1009E8894 /* PHAssetCollection+Extension.swift in Sources */, F717402E24F699A5000C87D5 /* NCFavorite.swift in Sources */, AF2D7C7E2742559100ADF566 /* NCShareUserCell.swift in Sources */, + D59D37D02F0EE97C0072C824 /* TransfersListener.swift in Sources */, AF4BF614275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */, F76340FA2EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */, F3E173C02C9B1067006D177A /* AwakeMode.swift in Sources */, @@ -4824,6 +4915,7 @@ F7CF06852E1127460063AD04 /* NCManageDatabase+CreateMetadata.swift in Sources */, F7A8D73928F17E25008BBE1C /* NCManageDatabase+Metadata.swift in Sources */, F7D7A7722DCDD437003D2007 /* NCManageDatabase+AutoUpload.swift in Sources */, + 0F9DB9BB2DD2381B00E31A24 /* NCBrand-IONOS.swift in Sources */, F72FD3B7297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */, F7A8D74128F18254008BBE1C /* UIColor+Extension.swift in Sources */, F76340F62EBDE9760056F538 /* NCManageDatabaseCore.swift in Sources */, @@ -4896,54 +4988,11 @@ isa = PBXVariantGroup; children = ( AA517B7F2D660EFE00F8D37C /* en */, - AA517B842D660F5200F8D37C /* eu */, - AA517B852D660F5800F8D37C /* ca */, - AA517B862D660F6100F8D37C /* zh-Hans */, - AA517B872D660F6200F8D37C /* zh-Hant-TW */, - AA517B882D660F6300F8D37C /* hr */, - AA517B892D660F6400F8D37C /* cs-CZ */, - AA517B8A2D660F6500F8D37C /* da */, AA517B8B2D660F6600F8D37C /* nl */, - AA517B8C2D660F6600F8D37C /* en-GB */, AA517B8D2D660F6A00F8D37C /* fr */, - AA517B8E2D660F6B00F8D37C /* gl */, - AA517B8F2D660F6B00F8D37C /* ka-GE */, AA517B902D660F6C00F8D37C /* de */, - AA517B912D660F6D00F8D37C /* el */, - AA517B922D660F6E00F8D37C /* hu */, - AA517B932D660F6F00F8D37C /* is */, AA517B942D660F6F00F8D37C /* it */, - AA517B952D660F7000F8D37C /* ja-JP */, - AA517B962D660F7100F8D37C /* ko */, - AA517B972D660F7100F8D37C /* lo */, - AA517B982D660F7200F8D37C /* nb-NO */, - AA517B992D660F7300F8D37C /* pl */, - AA517B9A2D660F7300F8D37C /* pt-PT */, - AA517B9B2D660F7400F8D37C /* pt-BR */, - AA517B9C2D660F7500F8D37C /* ru */, - AA517B9D2D660F7500F8D37C /* sr */, - AA517B9E2D660F7600F8D37C /* sk-SK */, - AA517B9F2D660F7700F8D37C /* sl */, AA517BA02D660F7700F8D37C /* es */, - AA517BA12D660F7800F8D37C /* es-CL */, - AA517BA22D660F7800F8D37C /* es-CO */, - AA517BA32D660F7900F8D37C /* es-CR */, - AA517BA42D660F7A00F8D37C /* es-DO */, - AA517BA52D660F7B00F8D37C /* es-EC */, - AA517BA62D660F7C00F8D37C /* es-SV */, - AA517BA72D660F7D00F8D37C /* es-GT */, - AA517BA82D660F7E00F8D37C /* es-HN */, - AA517BA92D660F8200F8D37C /* es-419 */, - AA517BAA2D660F8300F8D37C /* es-MX */, - AA517BAB2D660F8600F8D37C /* es-NI */, - AA517BAC2D660F8700F8D37C /* es-PA */, - AA517BAD2D660F8700F8D37C /* es-PY */, - AA517BAE2D660F8800F8D37C /* es-PE */, - AA517BAF2D660F8900F8D37C /* es-PR */, - AA517BB02D660F8900F8D37C /* es-UY */, - AA517BB12D660F8A00F8D37C /* sv */, - AA517BB22D660F8B00F8D37C /* tr */, - AA9B6A8F2DF1D8F7009D805D /* et */, ); name = Localizable.stringsdict; sourceTree = ""; @@ -4952,54 +5001,11 @@ isa = PBXVariantGroup; children = ( F72685E827C78E490019EF5E /* en */, - F7AA41B827C7CF4600494705 /* ca */, - F7AA41B927C7CF4B00494705 /* zh-Hans */, - F7AA41BA27C7CF5000494705 /* zh-Hant-TW */, - F7AA41BB27C7CF5100494705 /* cs-CZ */, - F7AA41BC27C7CF5300494705 /* da */, F7AA41BD27C7CF5400494705 /* nl */, - F7AA41BE27C7CF5600494705 /* ja-JP */, F7AA41BF27C7CF5700494705 /* fr */, - F7AA41C027C7CF5800494705 /* en-GB */, - F7AA41C127C7CF5900494705 /* gl */, - F7AA41C227C7CF5A00494705 /* ka-GE */, F7AA41C327C7CF5B00494705 /* de */, - F7AA41C427C7CF5C00494705 /* hu */, - F7AA41C527C7CF5D00494705 /* is */, - F7AA41C627C7CF5E00494705 /* it */, - F7AA41C727C7CF6000494705 /* tr */, - F7AA41C827C7CF6200494705 /* es-HN */, - F7AA41C927C7CF6300494705 /* es-DO */, - F7AA41CA27C7CF6400494705 /* ko */, - F7AA41CB27C7CF6500494705 /* nb-NO */, - F7AA41CC27C7CF6600494705 /* pl */, - F7AA41CD27C7CF6700494705 /* pt-BR */, - F7AA41CE27C7CF6800494705 /* pt-PT */, - F7AA41CF27C7CF6900494705 /* ru */, - F7AA41D027C7CF6900494705 /* sk-SK */, - F7AA41D127C7CF6A00494705 /* sr */, - F7AA41D227C7CF6C00494705 /* es-CO */, - F7AA41D327C7CF6D00494705 /* es-CL */, F7AA41D427C7CF6E00494705 /* es */, - F7AA41D527C7CF6F00494705 /* es-CR */, - F7AA41D627C7CF7100494705 /* es-GT */, - F7AA41D727C7CF7200494705 /* es-SV */, - F7AA41D827C7CF7300494705 /* es-EC */, - F7AA41D927C7CF7500494705 /* es-PR */, - F7AA41DA27C7CF7600494705 /* sv */, - F7AA41DB27C7CF7800494705 /* es-UY */, - F7AA41DC27C7CF7900494705 /* es-PE */, - F7AA41DD27C7CF7B00494705 /* es-419 */, - F7AA41DE27C7CF7D00494705 /* es-PA */, - F7AA41DF27C7CF7E00494705 /* es-PY */, - F7AA41E027C7CF8000494705 /* es-NI */, - F7AA41E127C7CF8100494705 /* es-MX */, - F79131C728AFB86E00577277 /* eu */, - AACCAB542CFE041F00DA1786 /* sl */, - AACCAB602CFE04C200DA1786 /* hr */, - AACCAB642CFE04F700DA1786 /* lo */, - AA52EB2E2D4297570089C348 /* el */, - AA9B6A902DF1D8F7009D805D /* et */, + 0FAEC1B32DBA3F2A001A60D9 /* it */, ); name = InfoPlist.strings; path = "Supporting Files"; @@ -5010,54 +5016,11 @@ children = ( F75DD768290ABB25002EB562 /* Base */, F7BE7C25290AC8C9002ABB61 /* en */, - F7BE7C27290ADEFD002ABB61 /* eu */, - F7BE7C29290ADEFD002ABB61 /* ca */, - F7BE7C2B290ADEFE002ABB61 /* zh-Hans */, - F7BE7C2D290ADEFF002ABB61 /* cs-CZ */, - F7BE7C2F290ADF00002ABB61 /* zh-Hant-TW */, F7BE7C31290ADF00002ABB61 /* nl */, - F7BE7C33290ADF01002ABB61 /* da */, - F7BE7C35290ADF03002ABB61 /* tr */, - F7BE7C37290ADF03002ABB61 /* sv */, - F7BE7C39290ADF04002ABB61 /* es-UY */, - F7BE7C3B290ADF04002ABB61 /* es-PR */, - F7BE7C3D290ADF05002ABB61 /* es-PE */, - F7BE7C3F290ADF06002ABB61 /* es-PY */, - F7BE7C41290ADF06002ABB61 /* es-PA */, - F7BE7C43290ADF06002ABB61 /* es-NI */, - F7BE7C45290ADF07002ABB61 /* es-MX */, - F7BE7C47290ADF07002ABB61 /* es-419 */, - F7BE7C49290ADF08002ABB61 /* es-HN */, - F7BE7C4B290ADF09002ABB61 /* ru */, - F7BE7C4D290ADF0A002ABB61 /* sr */, - F7BE7C4F290ADF0A002ABB61 /* sk-SK */, F7BE7C51290ADF0B002ABB61 /* es */, - F7BE7C53290ADF0B002ABB61 /* es-CL */, - F7BE7C55290ADF0C002ABB61 /* es-CO */, - F7BE7C57290ADF0C002ABB61 /* es-CR */, - F7BE7C59290ADF0D002ABB61 /* es-DO */, - F7BE7C5B290ADF0D002ABB61 /* es-EC */, - F7BE7C5D290ADF0E002ABB61 /* es-SV */, - F7BE7C5F290ADF0E002ABB61 /* es-GT */, - F7BE7C61290ADF10002ABB61 /* en-GB */, F7BE7C63290ADF10002ABB61 /* fr */, - F7BE7C65290ADF10002ABB61 /* gl */, - F7BE7C67290ADF11002ABB61 /* ka-GE */, F7BE7C69290ADF11002ABB61 /* de */, - F7BE7C6B290ADF12002ABB61 /* hu */, - F7BE7C6D290ADF12002ABB61 /* is */, - F7BE7C6F290ADF13002ABB61 /* it */, - F7BE7C71290ADF13002ABB61 /* ja-JP */, - F7BE7C73290ADF14002ABB61 /* ko */, - F7BE7C75290ADF14002ABB61 /* nb-NO */, - F7BE7C77290ADF15002ABB61 /* pl */, - F7BE7C79290ADF16002ABB61 /* pt-BR */, - F7BE7C7B290ADF16002ABB61 /* pt-PT */, - AACCAB522CFE041F00DA1786 /* sl */, - AACCAB5E2CFE04C200DA1786 /* hr */, - AACCAB622CFE04F700DA1786 /* lo */, - AA52EB2C2D4297570089C348 /* el */, - AA9B6A8D2DF1D8F7009D805D /* et */, + 42226BFC2FB76B7E0018A519 /* it */, ); name = Intent.intentdefinition; sourceTree = ""; @@ -5068,52 +5031,9 @@ F7151A811D477A4B00E6AF45 /* en */, F7B1A7761EBB3C8000BFB6D1 /* de */, F75B91E21ECAE17800199C96 /* fr */, - F75B91F71ECAE26300199C96 /* pt-BR */, - F75B923D1ECAE55E00199C96 /* ru */, - F7169A301EE59BB70086BD69 /* it */, - F7169A4C1EE59C640086BD69 /* tr */, - F78D6F461F0B7CB9002F9619 /* es-MX */, - F78D6F4D1F0B7CE4002F9619 /* nb-NO */, - F78D6F541F0B7D47002F9619 /* pl */, - F7DE9AB01F482FA5008DFE10 /* sv */, F7CC04E61F5AD50D00378CEF /* es */, - F7D532461F5D4123006568B1 /* is */, F7D5324D1F5D4137006568B1 /* nl */, - F7D532541F5D4155006568B1 /* sk-SK */, - F7D5328F1F5D443B006568B1 /* en-GB */, - F7D532A41F5D4461006568B1 /* zh-Hans */, - F77438EB1FCD694900662C46 /* ka-GE */, - F77438F21FCD69D300662C46 /* hu */, - F77438F91FCD6A0D00662C46 /* zh-Hant-TW */, - F77439001FCD6B7F00662C46 /* sr */, - F77439071FCD6BF000662C46 /* es-CL */, - F774390E1FCD6C0C00662C46 /* es-CO */, - F77439151FCD6C4A00662C46 /* es-CR */, - F774391C1FCD6C6700662C46 /* es-DO */, - F77439231FCD6C8700662C46 /* es-EC */, - F774392A1FCD6CAA00662C46 /* es-GT */, - F77439311FCD6CC400662C46 /* es-HN */, - F77439381FCD6CDE00662C46 /* es-NI */, - F774393F1FCD6D0B00662C46 /* es-PA */, - F77439461FCD6D2300662C46 /* es-PE */, - F774394D1FCD6D3E00662C46 /* es-PR */, - F77439541FCD6D6100662C46 /* es-PY */, - F774395B1FCD6D8200662C46 /* es-SV */, - F77439621FCD6D9C00662C46 /* es-UY */, - F7BB04851FD58ACB00BBFD2A /* cs-CZ */, - F7320934201B812F008A0888 /* ko */, - F732093B201B81E4008A0888 /* es-419 */, - F70A07C8205285FB00DC1231 /* pt-PT */, - F7E45E6D21E75BF200579249 /* ja-JP */, - F753701822723D620041C76C /* gl */, - F753701922723E0D0041C76C /* ca */, - F753701A22723EC80041C76C /* da */, - F79131C628AFB86E00577277 /* eu */, - AACCAB532CFE041F00DA1786 /* sl */, - AACCAB5F2CFE04C200DA1786 /* hr */, - AACCAB632CFE04F700DA1786 /* lo */, - AA52EB2D2D4297570089C348 /* el */, - AA9B6A8E2DF1D8F7009D805D /* et */, + 0F85B8942DB7D61100D089AE /* it */, ); name = Localizable.strings; path = "Supporting Files"; @@ -5122,106 +5042,142 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 2C33C48723E2C475005F963B /* Debug */ = { + 0F8968702DD349B700810B87 /* Alpha */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Notification_Service_Extension.entitlements"; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 21; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = R7V5Z67X53; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_TESTING_SEARCH_PATHS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", - EXTENSION, - EXTENSION_NOTIFICATION_SERVICE, + DEBUG, + NC, ); - INFOPLIST_FILE = "$(SRCROOT)/Brand/Notification_Service_Extension.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.Notification-Service-Extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; - SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 30.0.2; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC DEBUG"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; }; - name = Debug; + name = Alpha; }; - 2C33C48823E2C475005F963B /* Release */ = { + 0F8968712DD349B700810B87 /* Alpha */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Notification_Service_Extension.entitlements"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - EXTENSION, - EXTENSION_NOTIFICATION_SERVICE, - ); - INFOPLIST_FILE = "$(SRCROOT)/Brand/Notification_Service_Extension.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.Notification-Service-Extension"; + ASSETCATALOG_COMPILER_APPICON_NAME = IONOSAppIcon; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha/iOSClient.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/iOSClient.plist"; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; - SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; - }; - name = Release; - }; - AF8ED1FF2757821000B8DBC4 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(TEST_HOST)"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - ENABLE_HARDENED_RUNTIME = YES; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.NextcloudTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO; }; - name = Debug; + name = Alpha; }; - AF8ED2002757821000B8DBC4 /* Release */ = { + 0F8968722DD349B700810B87 /* Alpha */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(TEST_HOST)"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - ENABLE_HARDENED_RUNTIME = YES; + ALWAYS_SEARCH_USER_PATHS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha/Widget.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_WIDGET, + ); GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.NextcloudTests; + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/Widget.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Nextcloud; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.Widget; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Widget"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Widget"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGET"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Widget/Widget-Brinding-header.h"; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; }; - name = Release; + name = Alpha; }; - C0046CE22A17B98400D87C9D /* Debug */ = { + 0F8968732DD349B700810B87 /* Alpha */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + ALWAYS_SEARCH_USER_PATHS = YES; CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -5229,48 +5185,1083 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha//WidgetDashboardIntentHandler.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = NKUJUXUJ3B; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", "$(inherited)", + EXTENSION, + EXTENSION_WIDGETDASHBOARDINTENTHANDLER, ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - MARKETING_VERSION = 1.0; + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/WidgetDashboardIntentHandler.plist"; + INFOPLIST_KEY_CFBundleDisplayName = WidgetDashboardIntentHandler; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - OTHER_CFLAGS = "-v"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.NextcloudUITests.NextcloudUITests; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.WidgetDashboardIntentHandler; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage WidgetDashboardIntentHandler"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage WidgetDashboardIntentHandler"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGETDASHBOARDINTENTHANDLER"; + SWIFT_EMIT_LOC_STRINGS = YES; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(TEST_HOST)"; - TEST_TARGET_NAME = Nextcloud; + }; + name = Alpha; + }; + 0F8968742DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha/Share.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_SHARE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/Share.plist"; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.Share; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Share"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Share"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_SHARE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Share/Share-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Alpha; + }; + 0F8968752DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha/File_Provider_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/File_Provider_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.File-Provider-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage File-Provider-Extension"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage File-Provider-Extension"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Alpha; + }; + 0F8968762DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha/File_Provider_Extension_UI.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION_UI, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/File_Provider_Extension_UI.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "File Provider Extension UI"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.File-Provider-Extension-UI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage File-Provider-Extension-UI"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage File-Provider-Extension-UI"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION_UI"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Alpha; + }; + 0F8968772DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Alpha/Notification_Service_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Viseven Europe Ou (R7V5Z67X53)"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_NOTIFICATION_SERVICE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Alpha/Notification_Service_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.Notification-Service-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Notification-Service-Extension"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Notification-Service-Extension"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Alpha; + }; + 0F8968782DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + }; + name = Alpha; + }; + 0F8968792DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudIntegrationTests.NextcloudIntegrationTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + }; + name = Alpha; + }; + 0F89687A2DD349B700810B87 /* Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudUITests.NextcloudUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(TEST_HOST)"; + TEST_TARGET_NAME = Nextcloud; + }; + name = Alpha; + }; + 2C33C48723E2C475005F963B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "Notification Service Extension/Notification Service ExtensionDebug.entitlements"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_NOTIFICATION_SERVICE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Notification_Service_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.Notification-Service-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Dev ionos.easystorage.NotificationServiceExtension"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Dev ionos.easystorage.NotificationServiceExtension"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2C33C48823E2C475005F963B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Notification_Service_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_NOTIFICATION_SERVICE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Notification_Service_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.Notification-Service-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Notification-Service-Extension"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + AF8ED1FF2757821000B8DBC4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; }; name = Debug; }; - C0046CE32A17B98400D87C9D /* Release */ = { + AF8ED2002757821000B8DBC4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + }; + name = Release; + }; + C0046CE22A17B98400D87C9D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudUITests.NextcloudUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(TEST_HOST)"; + TEST_TARGET_NAME = Nextcloud; + }; + name = Debug; + }; + C0046CE32A17B98400D87C9D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudUITests.NextcloudUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(TEST_HOST)"; + TEST_TARGET_NAME = Nextcloud; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C04E2F272A17BB4E001BAD85 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudIntegrationTests.NextcloudIntegrationTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + }; + name = Debug; + }; + C04E2F282A17BB4E001BAD85 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudIntegrationTests.NextcloudIntegrationTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + D5C2D2122C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 21; + DEVELOPMENT_TEAM = R7V5Z67X53; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_TESTING_SEARCH_PATHS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + NC, + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 30.0.2; + ONLY_ACTIVE_ARCH = YES; + OTHER_SWIFT_FLAGS = "-D BETA"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Beta; + }; + D5C2D2132C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ALWAYS_SEARCH_USER_PATHS = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = IONOSAppIcon; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta/iOSClient.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + NC, + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/iOSClient.plist"; + PRODUCT_BUNDLE_IDENTIFIER = de.strato.ionos.easystorage.beta; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Beta; + }; + D5C2D2142C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta/Widget.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_WIDGET, + ); + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/Widget.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Nextcloud; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = de.strato.ionos.easystorage.beta.Widget; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta Widget"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta Widget"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGET"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Widget/Widget-Brinding-header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Beta; + }; + D5C2D2152C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta//WidgetDashboardIntentHandler.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + ENABLE_NS_ASSERTIONS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_WIDGETDASHBOARDINTENTHANDLER, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/WidgetDashboardIntentHandler.plist"; + INFOPLIST_KEY_CFBundleDisplayName = WidgetDashboardIntentHandler; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = de.strato.ionos.easystorage.beta.WidgetDashboardIntentHandler; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta WidgetDashboard"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta WidgetDashboard"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGETDASHBOARDINTENTHANDLER"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Beta; + }; + D5C2D2162C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta/Share.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_SHARE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/Share.plist"; + PRODUCT_BUNDLE_IDENTIFIER = de.strato.ionos.easystorage.beta.Share; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta Share"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta Share"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_SHARE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Share/Share-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Beta; + }; + D5C2D2172C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta/File_Provider_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/File_Provider_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "de.strato.ionos.easystorage.beta.File-Provider-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta File-Provider-Extension"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta File-Provider-Extension"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Beta; + }; + D5C2D2182C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta/File_Provider_Extension_UI.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION_UI, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/File_Provider_Extension_UI.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "File Provider Extension UI"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "de.strato.ionos.easystorage.beta.File-Provider-Extension-UI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta File-Provider-Extension-U"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta File-Provider-Extension-U"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION_UI"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Beta; + }; + D5C2D2192C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Beta/Notification_Service_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6UU53QCET7; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_NOTIFICATION_SERVICE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/Beta/Notification_Service_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "de.strato.ionos.easystorage.beta.Notification-Service-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Beta Notification-Service"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ad Hoc Easy Storage Beta Notification-Service"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Beta; + }; + D5C2D21A2C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + }; + name = Beta; + }; + D5C2D21B2C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudIntegrationTests.NextcloudIntegrationTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + VALIDATE_PRODUCT = YES; + }; + name = Beta; + }; + D5C2D21C2C9AC00B00E7579D /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudUITests.NextcloudUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(TEST_HOST)"; + TEST_TARGET_NAME = Nextcloud; + VALIDATE_PRODUCT = YES; + }; + name = Beta; + }; + D5C617962CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 21; + DEVELOPMENT_TEAM = R7V5Z67X53; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_TESTING_SEARCH_PATHS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + NC, + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 30.0.2; + ONLY_ACTIVE_ARCH = YES; + OTHER_SWIFT_FLAGS = "-D APPSTORE"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = AppStore; + }; + D5C617972CABE20500105DC6 /* AppStore */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ALWAYS_SEARCH_USER_PATHS = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = IONOSAppIcon; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore/iOSClient.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5TDLCVD243; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + NC, + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/iOSClient.plist"; + PRODUCT_BUNDLE_IDENTIFIER = com.ionos.hidrivenext; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "AppStore com.ionos.hidrivenext"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = AppStore; + }; + D5C617982CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore/Widget.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_WIDGET, + ); + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/Widget.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Nextcloud; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.ionos.hidrivenext.Widget; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext.Widget"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGET"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Widget/Widget-Brinding-header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = AppStore; + }; + D5C617992CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -5278,39 +6269,169 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore//WidgetDashboardIntentHandler.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = NKUJUXUJ3B; ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_WIDGETDASHBOARDINTENTHANDLER, + ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - MARKETING_VERSION = 1.0; + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/WidgetDashboardIntentHandler.plist"; + INFOPLIST_KEY_CFBundleDisplayName = WidgetDashboardIntentHandler; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.ionos.hidrivenext.WidgetDashboardIntentHandler; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext.WidgetDashboard"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGETDASHBOARDINTENTHANDLER"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = AppStore; + }; + D5C6179A2CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore/Share.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_SHARE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/Share.plist"; + PRODUCT_BUNDLE_IDENTIFIER = com.ionos.hidrivenext.Share; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext.Share"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_SHARE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Share/Share-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = AppStore; + }; + D5C6179B2CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore/File_Provider_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/File_Provider_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.ionos.hidrivenext.File-Provider-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext.File-Provider-Ext"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = AppStore; + }; + D5C6179C2CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore/File_Provider_Extension_UI.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION, + EXTENSION_FILE_PROVIDER_EXTENSION_UI, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/File_Provider_Extension_UI.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "File Provider Extension UI"; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - OTHER_CFLAGS = "-v"; + PRODUCT_BUNDLE_IDENTIFIER = "com.ionos.hidrivenext.File-Provider-Extension-UI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext.File-Provider-ExtUI"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION_UI"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = AppStore; + }; + D5C6179D2CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/AppStore/Notification_Service_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + EXTENSION, + EXTENSION_NOTIFICATION_SERVICE, + ); + INFOPLIST_FILE = "$(SRCROOT)/Brand/AppStore/Notification_Service_Extension.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.ionos.hidrivenext.Notification-Service-Extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "AppStore com.ionos.hidrivenext.Notification"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_NOTIFICATION_SERVICE"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Notification Service Extension/Notification_Service_Extension-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = AppStore; + }; + D5C6179E2CABE20500105DC6 /* AppStore */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + BUNDLE_LOADER = "$(TEST_HOST)"; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.NextcloudUITests.NextcloudUITests; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudTests; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(TEST_HOST)"; - TEST_TARGET_NAME = Nextcloud; - VALIDATE_PRODUCT = YES; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; }; - name = Release; + name = AppStore; }; - C04E2F272A17BB4E001BAD85 /* Debug */ = { + D5C6179F2CABE20500105DC6 /* AppStore */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -5324,45 +6445,34 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = NKUJUXUJ3B; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.NextcloudIntegrationTests.NextcloudIntegrationTests; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudIntegrationTests.NextcloudIntegrationTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = AppStore; }; - C04E2F282A17BB4E001BAD85 /* Release */ = { + D5C617A02CABE20500105DC6 /* AppStore */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -5372,10 +6482,8 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = NKUJUXUJ3B; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -5385,8 +6493,9 @@ MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.NextcloudIntegrationTests.NextcloudIntegrationTests; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.Nextcloud.NextcloudUITests.NextcloudUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -5396,17 +6505,20 @@ SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_PRECOMPILE_BRIDGING_HEADER = YES; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Nextcloud.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Nextcloud"; + TEST_HOST = "$(TEST_HOST)"; + TEST_TARGET_NAME = Nextcloud; VALIDATE_PRODUCT = YES; }; - name = Release; + name = AppStore; }; F70716EE2987F81600E72C1D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/File_Provider_Extension_UI.entitlements"; + CODE_SIGN_ENTITLEMENTS = "File Provider Extension UI/File Provider Extension UIDebug.entitlements"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, @@ -5415,16 +6527,19 @@ ); INFOPLIST_FILE = "$(SRCROOT)/Brand/File_Provider_Extension_UI.plist"; INFOPLIST_KEY_CFBundleDisplayName = "File Provider Extension UI"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension-UI"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.File-Provider-Extension-UI"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Dev ionos.easystorage.File-Provider-Extension-UI"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Dev ionos.easystorage.File-Provider-Extension-UI"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION_UI"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5433,6 +6548,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/File_Provider_Extension_UI.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, @@ -5441,16 +6557,18 @@ ); INFOPLIST_FILE = "$(SRCROOT)/Brand/File_Provider_Extension_UI.plist"; INFOPLIST_KEY_CFBundleDisplayName = "File Provider Extension UI"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension-UI"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.File-Provider-Extension-UI"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage File-Provider-Extension-UI"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION_UI"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -5458,22 +6576,25 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Share.entitlements"; + CODE_SIGN_ENTITLEMENTS = Share/ShareDebug.entitlements; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, EXTENSION_SHARE, ); INFOPLIST_FILE = "$(SRCROOT)/Brand/Share.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.Share; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Develop com.viseven.ionos.easystorage.Share"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Develop com.viseven.ionos.easystorage.Share"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_SHARE"; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Share/Share-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5482,21 +6603,23 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Share.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, EXTENSION_SHARE, ); INFOPLIST_FILE = "$(SRCROOT)/Brand/Share.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.Share; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Share"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_SHARE"; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Share/Share-Bridging-Header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -5509,7 +6632,8 @@ CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Widget.entitlements"; + CODE_SIGN_ENTITLEMENTS = Widget/WidgetDebug.entitlements; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, @@ -5518,11 +6642,13 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "$(SRCROOT)/Brand/Widget.plist"; INFOPLIST_KEY_CFBundleDisplayName = Nextcloud; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Widget; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.Widget; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Develop com.viseven.ionos.easystorage.Widget"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Develop com.viseven.ionos.easystorage.Widget"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; @@ -5530,6 +6656,7 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGET"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Widget/Widget-Brinding-header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5543,6 +6670,7 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/Widget.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, @@ -5551,11 +6679,12 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "$(SRCROOT)/Brand/Widget.plist"; INFOPLIST_KEY_CFBundleDisplayName = Nextcloud; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Widget; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.Widget; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage Widget"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; @@ -5563,6 +6692,7 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGET"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Widget/Widget-Brinding-header.h"; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -5571,21 +6701,24 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/File_Provider_Extension.entitlements"; + CODE_SIGN_ENTITLEMENTS = "File Provider Extension/File Provider ExtensionDebug.entitlements"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, EXTENSION_FILE_PROVIDER_EXTENSION, ); INFOPLIST_FILE = "$(SRCROOT)/Brand/File_Provider_Extension.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.File-Provider-Extension"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Dev ionos.easystorage.File-Provider-Extension"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Dev ionos.easystorage.File-Provider-Extension"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5594,20 +6727,22 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/File_Provider_Extension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, EXTENSION_FILE_PROVIDER_EXTENSION, ); INFOPLIST_FILE = "$(SRCROOT)/Brand/File_Provider_Extension.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension"; + PRODUCT_BUNDLE_IDENTIFIER = "com.viseven.ionos.easystorage.File-Provider-Extension"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage File-Provider-Extension"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_FILE_PROVIDER_EXTENSION"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -5616,17 +6751,22 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/iOSClient.entitlements"; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + CODE_SIGN_ENTITLEMENTS = NextcloudDebug.entitlements; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R7V5Z67X53; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INFOPLIST_FILE = "$(SRCROOT)/Brand/iOSClient.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Develop com.viseven.ionos.easystorage"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Develop com.viseven.ionos.easystorage"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; 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 = NO; }; name = Debug; @@ -5636,17 +6776,20 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand/iOSClient.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INFOPLIST_FILE = "$(SRCROOT)/Brand/iOSClient.plist"; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; 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 = NO; }; name = Release; @@ -5663,7 +6806,9 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand//WidgetDashboardIntentHandler.entitlements"; + CODE_SIGN_ENTITLEMENTS = WidgetDashboardIntentHandler/WidgetDashboardIntentHandlerDebug.entitlements; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", EXTENSION, @@ -5674,17 +6819,20 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "$(SRCROOT)/Brand/WidgetDashboardIntentHandler.plist"; INFOPLIST_KEY_CFBundleDisplayName = WidgetDashboardIntentHandler; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.WidgetDashboardIntentHandler; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.WidgetDashboardIntentHandler; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Develop ionos.easystorage.WidgetDashboardIntentHan"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Develop ionos.easystorage.WidgetDashboardIntentHan"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGETDASHBOARDINTENTHANDLER"; SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5701,6 +6849,8 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/Brand//WidgetDashboardIntentHandler.entitlements"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -5712,17 +6862,20 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "$(SRCROOT)/Brand/WidgetDashboardIntentHandler.plist"; INFOPLIST_KEY_CFBundleDisplayName = WidgetDashboardIntentHandler; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Nextcloud. All rights reserved."; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.WidgetDashboardIntentHandler; + PRODUCT_BUNDLE_IDENTIFIER = com.viseven.ionos.easystorage.WidgetDashboardIntentHandler; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Ad Hoc Easy Storage WidgetDashboardIntentHandler"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) EXTENSION EXTENSION_WIDGETDASHBOARDINTENTHANDLER"; SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; name = Release; }; @@ -5753,10 +6906,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 21; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = NKUJUXUJ3B; + DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_TESTING_SEARCH_PATHS = YES; @@ -5781,10 +6935,9 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 33.0.2; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "-v"; - OTHER_LDFLAGS = ""; + SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC DEBUG"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -5819,9 +6972,10 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = NKUJUXUJ3B; + CURRENT_PROJECT_VERSION = 21; + DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_TESTING_SEARCH_PATHS = YES; @@ -5844,10 +6998,9 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 33.0.2; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "-v"; - OTHER_LDFLAGS = ""; + SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC"; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; @@ -5863,7 +7016,10 @@ isa = XCConfigurationList; buildConfigurations = ( 2C33C48723E2C475005F963B /* Debug */, + 0F8968772DD349B700810B87 /* Alpha */, 2C33C48823E2C475005F963B /* Release */, + D5C2D2192C9AC00B00E7579D /* Beta */, + D5C6179D2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5872,7 +7028,10 @@ isa = XCConfigurationList; buildConfigurations = ( AF8ED1FF2757821000B8DBC4 /* Debug */, + 0F8968782DD349B700810B87 /* Alpha */, AF8ED2002757821000B8DBC4 /* Release */, + D5C2D21A2C9AC00B00E7579D /* Beta */, + D5C6179E2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5881,7 +7040,10 @@ isa = XCConfigurationList; buildConfigurations = ( C0046CE22A17B98400D87C9D /* Debug */, + 0F89687A2DD349B700810B87 /* Alpha */, C0046CE32A17B98400D87C9D /* Release */, + D5C2D21C2C9AC00B00E7579D /* Beta */, + D5C617A02CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5890,7 +7052,10 @@ isa = XCConfigurationList; buildConfigurations = ( C04E2F272A17BB4E001BAD85 /* Debug */, + 0F8968792DD349B700810B87 /* Alpha */, C04E2F282A17BB4E001BAD85 /* Release */, + D5C2D21B2C9AC00B00E7579D /* Beta */, + D5C6179F2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5899,7 +7064,10 @@ isa = XCConfigurationList; buildConfigurations = ( F70716EE2987F81600E72C1D /* Debug */, + 0F8968762DD349B700810B87 /* Alpha */, F70716EF2987F81600E72C1D /* Release */, + D5C2D2182C9AC00B00E7579D /* Beta */, + D5C6179C2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5908,7 +7076,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7145A261D12E3B700CAFEEC /* Debug */, + 0F8968742DD349B700810B87 /* Alpha */, F7145A271D12E3B700CAFEEC /* Release */, + D5C2D2162C9AC00B00E7579D /* Beta */, + D5C6179A2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5917,7 +7088,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7346E1D28B0EF5E006CE2D2 /* Debug */, + 0F8968722DD349B700810B87 /* Alpha */, F7346E1E28B0EF5E006CE2D2 /* Release */, + D5C2D2142C9AC00B00E7579D /* Beta */, + D5C617982CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5926,7 +7100,10 @@ isa = XCConfigurationList; buildConfigurations = ( F771E3F020E2392E00AFB62D /* Debug */, + 0F8968752DD349B700810B87 /* Alpha */, F771E3F120E2392E00AFB62D /* Release */, + D5C2D2172C9AC00B00E7579D /* Beta */, + D5C6179B2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5935,7 +7112,10 @@ isa = XCConfigurationList; buildConfigurations = ( F77B0F9B1D118A16002130FE /* Debug */, + 0F8968712DD349B700810B87 /* Alpha */, F77B0F9C1D118A16002130FE /* Release */, + D5C2D2132C9AC00B00E7579D /* Beta */, + D5C617972CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5944,7 +7124,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7C9739B28F17132002C43E2 /* Debug */, + 0F8968732DD349B700810B87 /* Alpha */, F7C9739C28F17132002C43E2 /* Release */, + D5C2D2152C9AC00B00E7579D /* Beta */, + D5C617992CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5953,7 +7136,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7F67BC91A24D27800EE80DA /* Debug */, + 0F8968702DD349B700810B87 /* Alpha */, F7F67BCA1A24D27800EE80DA /* Release */, + D5C2D2122C9AC00B00E7579D /* Beta */, + D5C617962CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -6014,7 +7200,7 @@ repositoryURL = "https://github.com/realm/realm-swift"; requirement = { kind = exactVersion; - version = 10.54.6; + version = 20.0.3; }; }; F72DA9B225F53E4E00B87DB1 /* XCRemoteSwiftPackageReference "SwiftRichString" */ = { @@ -6174,12 +7360,17 @@ repositoryURL = "https://github.com/1024jp/GzipSwift"; requirement = { kind = exactVersion; - version = 6.0.0; + version = 6.0.1; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 625EC26D2C6CA285006411D1 /* FirebaseAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = F70B86732642CE3B00ED5349 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalytics; + }; F3374AEF2D78B01B002A38F9 /* BitCollections */ = { isa = XCSwiftPackageProductDependency; package = F3374AEE2D78B01B002A38F9 /* XCRemoteSwiftPackageReference "swift-collections" */; diff --git a/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme b/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme deleted file mode 100755 index ca3cdc4b3f..0000000000 --- a/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme b/Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme index 796a251f27..ec965fd92b 100755 --- a/Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme +++ b/Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme @@ -137,26 +137,22 @@ + + + + - - - - - - @@ -183,7 +179,7 @@ buildConfiguration = "Debug"> diff --git a/NextcloudDebug.entitlements b/NextcloudDebug.entitlements new file mode 100644 index 0000000000..e564d0c656 --- /dev/null +++ b/NextcloudDebug.entitlements @@ -0,0 +1,28 @@ + + + + + aps-environment + development + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.network.client + + com.apple.security.personal-information.location + + com.apple.security.personal-information.photos-library + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Notification Service Extension/Notification Service ExtensionDebug.entitlements b/Notification Service Extension/Notification Service ExtensionDebug.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/Notification Service Extension/Notification Service ExtensionDebug.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Notification Service Extension/NotificationService.swift b/Notification Service Extension/NotificationService.swift index fefe26ca70..a81953fb8a 100644 --- a/Notification Service Extension/NotificationService.swift +++ b/Notification Service Extension/NotificationService.swift @@ -37,7 +37,7 @@ class NotificationService: UNNotificationServiceExtension { if let bestAttemptContent = bestAttemptContent { bestAttemptContent.title = "" - bestAttemptContent.body = "Nextcloud notification" + bestAttemptContent.body = "HiDrive Next notification" do { if let message = bestAttemptContent.userInfo["subject"] as? String { for tableAccount in NCManageDatabase.shared.getAllTableAccount() { @@ -86,7 +86,7 @@ class NotificationService: UNNotificationServiceExtension { // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { bestAttemptContent.title = "" - bestAttemptContent.body = "Nextcloud Notification Time Will Expire" + bestAttemptContent.body = "HiDrive Next notification" contentHandler(bestAttemptContent) } } diff --git a/Share/NCShareCell.swift b/Share/NCShareCell.swift index 27b6051522..0d078f8926 100644 --- a/Share/NCShareCell.swift +++ b/Share/NCShareCell.swift @@ -29,7 +29,7 @@ class NCShareCell: UITableViewCell { self.account = account self.iconName = iconName - backgroundColor = .systemBackground + backgroundColor = NCBrandColor.shared.appBackgroundColor imageCell?.layer.cornerRadius = 6 imageCell?.layer.masksToBounds = true diff --git a/Share/NCShareExtension+DataSource.swift b/Share/NCShareExtension+DataSource.swift index 5cb80c8e74..0bdc761923 100644 --- a/Share/NCShareExtension+DataSource.swift +++ b/Share/NCShareExtension+DataSource.swift @@ -97,10 +97,7 @@ extension NCShareExtension: UICollectionViewDataSource { setupDirectoryCell(cell, indexPath: indexPath, with: metadata) } - if metadata.favorite { - cell.imageFavorite.image = NCImageCache.shared.getImageFavorite() - } - + cell.imageFavorite.image = metadata.favorite ? NCImageCache.shared.getImageFavorite() : nil cell.imageSelect.isHidden = true cell.backgroundView = nil cell.hideButtonMore(true) @@ -131,11 +128,11 @@ extension NCShareExtension: UICollectionViewDataSource { if metadata.e2eEncrypted { cell.imageItem.image = NCImageCache.shared.getFolderEncrypted(account: metadata.account) } else if isShare { - cell.imageItem.image = NCImageCache.shared.getFolderSharedWithMe(account: metadata.account) + cell.imageItem.image = NCImageCache.shared.getFolderSharedWithMe() } else if !metadata.shareType.isEmpty { metadata.shareType.contains(3) ? (cell.imageItem.image = NCImageCache.shared.getFolderPublic(account: metadata.account)) : - (cell.imageItem.image = NCImageCache.shared.getFolderSharedWithMe(account: metadata.account)) + (cell.imageItem.image = NCImageCache.shared.getFolderSharedWithMe()) } else if metadata.mountType == "group" { cell.imageItem.image = NCImageCache.shared.getFolderGroup(account: metadata.account) } else if isMounted { diff --git a/Share/ShareDebug.entitlements b/Share/ShareDebug.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/Share/ShareDebug.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/Tests/NextcloudSnapshotTests/Extensions/SwiftUIView+Extensions.swift b/Tests/NextcloudSnapshotTests/Extensions/SwiftUIView+Extensions.swift new file mode 100644 index 0000000000..c9fc8ed243 --- /dev/null +++ b/Tests/NextcloudSnapshotTests/Extensions/SwiftUIView+Extensions.swift @@ -0,0 +1,33 @@ +// +// SwiftUIView+Extensions.swift +// Nextcloud +// +// Created by Milen on 06.06.23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +import Foundation +import SwiftUI + +extension SwiftUI.View { + func toVC() -> UIViewController { + let vc = UIHostingController (rootView: self) + vc.view.frame = UIScreen.main.bounds + return vc + } +} diff --git a/Tests/NextcloudSnapshotTests/NextcloudSnapshotTests.swift b/Tests/NextcloudSnapshotTests/NextcloudSnapshotTests.swift new file mode 100644 index 0000000000..9b3e56fcd8 --- /dev/null +++ b/Tests/NextcloudSnapshotTests/NextcloudSnapshotTests.swift @@ -0,0 +1,37 @@ +// +// NextcloudSnapshotTests.swift +// NextcloudSnapshotTests +// +// Created by Milen on 06.06.23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +import XCTest +import SnapshotTesting +import SnapshotTestingHEIC +import PreviewSnapshotsTesting +import SwiftUI +@testable import Nextcloud + +final class NextcloudSnapshotTests: XCTestCase { + func test_HUDView() { + HUDView_Previews.snapshots.assertSnapshots(as: .imageHEIC) + } + + func test_CapalitiesView() { + NCCapabilitiesView_Previews.snapshots.assertSnapshots(as: .imageHEIC) + } +} diff --git a/Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_CapalitiesView.DefaultPreviewConfiguration.heic b/Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_CapalitiesView.DefaultPreviewConfiguration.heic new file mode 100644 index 0000000000..7b099a3dfe Binary files /dev/null and b/Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_CapalitiesView.DefaultPreviewConfiguration.heic differ diff --git a/Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_HUDView.DefaultPreviewConfiguration.heic b/Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_HUDView.DefaultPreviewConfiguration.heic new file mode 100644 index 0000000000..d0c5ba1c50 Binary files /dev/null and b/Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_HUDView.DefaultPreviewConfiguration.heic differ diff --git a/Widget/Assets.xcassets/Cloud_Checkmark.imageset/Cloud_Checkmark.svg b/Widget/Assets.xcassets/Cloud_Checkmark.imageset/Cloud_Checkmark.svg new file mode 100644 index 0000000000..82e33eef4e --- /dev/null +++ b/Widget/Assets.xcassets/Cloud_Checkmark.imageset/Cloud_Checkmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Assets.xcassets/Cloud_Checkmark.imageset/Contents.json b/Widget/Assets.xcassets/Cloud_Checkmark.imageset/Contents.json new file mode 100644 index 0000000000..e50bbe2113 --- /dev/null +++ b/Widget/Assets.xcassets/Cloud_Checkmark.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Cloud_Checkmark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Assets.xcassets/Cloud_Xmark.imageset/Cloud_Xmark.svg b/Widget/Assets.xcassets/Cloud_Xmark.imageset/Cloud_Xmark.svg new file mode 100644 index 0000000000..5a462aedb8 --- /dev/null +++ b/Widget/Assets.xcassets/Cloud_Xmark.imageset/Cloud_Xmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Assets.xcassets/Cloud_Xmark.imageset/Contents.json b/Widget/Assets.xcassets/Cloud_Xmark.imageset/Contents.json new file mode 100644 index 0000000000..7aabf1d99a --- /dev/null +++ b/Widget/Assets.xcassets/Cloud_Xmark.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Cloud_Xmark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/Contents.json b/Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/Contents.json new file mode 100644 index 0000000000..f1df926fcf --- /dev/null +++ b/Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "file_unsupported_widget.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/file_unsupported_widget.svg b/Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/file_unsupported_widget.svg new file mode 100644 index 0000000000..7303b08a56 --- /dev/null +++ b/Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/file_unsupported_widget.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Assets.xcassets/Media.imageset/Contents.json b/Widget/Assets.xcassets/Media.imageset/Contents.json new file mode 100644 index 0000000000..ba2d9e1ce8 --- /dev/null +++ b/Widget/Assets.xcassets/Media.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Media.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Assets.xcassets/Media.imageset/Media.svg b/Widget/Assets.xcassets/Media.imageset/Media.svg new file mode 100644 index 0000000000..6afd5adc83 --- /dev/null +++ b/Widget/Assets.xcassets/Media.imageset/Media.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Assets.xcassets/AccentColor.colorset/Contents.json b/Widget/Assets.xcassets/Mic.imageset/Contents.json similarity index 70% rename from Widget/Assets.xcassets/AccentColor.colorset/Contents.json rename to Widget/Assets.xcassets/Mic.imageset/Contents.json index eb87897008..4526994e79 100644 --- a/Widget/Assets.xcassets/AccentColor.colorset/Contents.json +++ b/Widget/Assets.xcassets/Mic.imageset/Contents.json @@ -1,6 +1,7 @@ { - "colors" : [ + "images" : [ { + "filename" : "Mic.svg", "idiom" : "universal" } ], diff --git a/Widget/Assets.xcassets/Mic.imageset/Mic.svg b/Widget/Assets.xcassets/Mic.imageset/Mic.svg new file mode 100644 index 0000000000..475621d6a2 --- /dev/null +++ b/Widget/Assets.xcassets/Mic.imageset/Mic.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json b/Widget/Assets.xcassets/Note.imageset/Contents.json similarity index 70% rename from Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json rename to Widget/Assets.xcassets/Note.imageset/Contents.json index eb87897008..6fa66e29e3 100644 --- a/Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json +++ b/Widget/Assets.xcassets/Note.imageset/Contents.json @@ -1,6 +1,7 @@ { - "colors" : [ + "images" : [ { + "filename" : "Note.svg", "idiom" : "universal" } ], diff --git a/Widget/Assets.xcassets/Note.imageset/Note.svg b/Widget/Assets.xcassets/Note.imageset/Note.svg new file mode 100644 index 0000000000..e3df93daef --- /dev/null +++ b/Widget/Assets.xcassets/Note.imageset/Note.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Assets.xcassets/Scan.imageset/Contents.json b/Widget/Assets.xcassets/Scan.imageset/Contents.json new file mode 100644 index 0000000000..065c7beaa5 --- /dev/null +++ b/Widget/Assets.xcassets/Scan.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Scan.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Assets.xcassets/Scan.imageset/Scan.svg b/Widget/Assets.xcassets/Scan.imageset/Scan.svg new file mode 100644 index 0000000000..f5c9dda684 --- /dev/null +++ b/Widget/Assets.xcassets/Scan.imageset/Scan.svg @@ -0,0 +1,3 @@ + + + diff --git a/Widget/Colors.xcassets/Background.colorset/Contents.json b/Widget/Colors.xcassets/Background.colorset/Contents.json new file mode 100644 index 0000000000..4eea21fecd --- /dev/null +++ b/Widget/Colors.xcassets/Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2B", + "green" : "0x10", + "red" : "0x02" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Colors.xcassets/BottomElementForeground.colorset/Contents.json b/Widget/Colors.xcassets/BottomElementForeground.colorset/Contents.json new file mode 100644 index 0000000000..76547d8302 --- /dev/null +++ b/Widget/Colors.xcassets/BottomElementForeground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Colors.xcassets/Contents.json b/Widget/Colors.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/Widget/Colors.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Colors.xcassets/Divider.colorset/Contents.json b/Widget/Colors.xcassets/Divider.colorset/Contents.json new file mode 100644 index 0000000000..531e0c9336 --- /dev/null +++ b/Widget/Colors.xcassets/Divider.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Colors.xcassets/Subtitle.colorset/Contents.json b/Widget/Colors.xcassets/Subtitle.colorset/Contents.json new file mode 100644 index 0000000000..3288e04f17 --- /dev/null +++ b/Widget/Colors.xcassets/Subtitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Colors.xcassets/Text.colorset/Contents.json b/Widget/Colors.xcassets/Text.colorset/Contents.json new file mode 100644 index 0000000000..fafa476721 --- /dev/null +++ b/Widget/Colors.xcassets/Text.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Colors.xcassets/Title.colorset/Contents.json b/Widget/Colors.xcassets/Title.colorset/Contents.json new file mode 100644 index 0000000000..cfbec998e7 --- /dev/null +++ b/Widget/Colors.xcassets/Title.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Widget/Dashboard/DashboardData.swift b/Widget/Dashboard/DashboardData.swift index b16f2d9953..74c79227ee 100644 --- a/Widget/Dashboard/DashboardData.swift +++ b/Widget/Dashboard/DashboardData.swift @@ -48,10 +48,10 @@ let dashboardDatasTest: [DashboardData] = [ func getDashboardItems(displaySize: CGSize, withButton: Bool) -> Int { if withButton { - let items = Int((displaySize.height - 90) / 55) + let items = Int((displaySize.height - 90) / 59) return items } else { - let items = Int((displaySize.height - 50) / 55) + let items = Int((displaySize.height - 50) / 59) return items } } diff --git a/Widget/Dashboard/DashboardWidgetView.swift b/Widget/Dashboard/DashboardWidgetView.swift index 3ae749bdd9..2fef4db3f9 100644 --- a/Widget/Dashboard/DashboardWidgetView.swift +++ b/Widget/Dashboard/DashboardWidgetView.swift @@ -1,5 +1,7 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2022 Marino Faggiana +// SPDX-FileCopyrightText: 2024 STRATO GmbH +// SPDX-FileCopyrightText: 2022 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later import SwiftUI @@ -10,19 +12,8 @@ struct DashboardWidgetView: View { var body: some View { GeometryReader { geo in if entry.isEmpty { - VStack(alignment: .center) { - Image(systemName: "checkmark") - .resizable() - .scaledToFit() - .font(Font.system(.body).weight(.light)) - .frame(width: 50, height: 50) - Text(NSLocalizedString("_no_items_", comment: "")) - .font(.system(size: 25)) - .padding() - Text(NSLocalizedString("_check_back_later_", comment: "")) - .font(.system(size: 15)) - } - .frame(width: geo.size.width, height: geo.size.height) + EmptyWidgetContentView() + .frame(width: geo.size.width, height: geo.size.height) } ZStack(alignment: .topLeading) { @@ -52,7 +43,8 @@ struct DashboardWidgetView: View { if entry.isPlaceholder { Circle() .fill(Color(.systemGray4)) - .frame(width: 35, height: 35) + .frame(width: WidgetConstants.elementIconWidthHeight, + height: WidgetConstants.elementIconWidthHeight) } else if let color = element.imageColor { Image(uiImage: element.icon) .renderingMode(.template) @@ -71,27 +63,28 @@ struct DashboardWidgetView: View { Image(uiImage: element.icon) .resizable() .scaledToFill() - .frame(width: 35, height: 35) + .frame(width: WidgetConstants.elementIconWidthHeight, + height: WidgetConstants.elementIconWidthHeight) .clipShape(Circle()) } else { Image(uiImage: element.icon) .resizable() .scaledToFill() - .frame(width: 35, height: 35) + .frame(width: WidgetConstants.elementIconWidthHeight, + height: WidgetConstants.elementIconWidthHeight) .clipped() - .cornerRadius(5) } } - VStack(alignment: .leading, spacing: 2) { - - Text(element.title) - .font(.system(size: 12)) - .fontWeight(.regular) - - Text(element.subTitle) - .font(.system(size: CGFloat(10))) - .foregroundColor(subTitleColor) + VStack(alignment: .leading, spacing: 2) { + Text(element.title) + .font(WidgetConstants.elementTileFont) + .foregroundStyle(Color(.title)) + if !element.subTitle.isEmpty { + Text(element.subTitle) + .font(WidgetConstants.elementSubtitleFont) + .foregroundStyle(Color(.subtitle)) + } } Spacer() } @@ -100,19 +93,20 @@ struct DashboardWidgetView: View { } if element != entry.datas.last { Divider() - .padding(.leading, 54) + .overlay(Color(.divider)) } } } } - .padding(.top, 35) + .padding(.top, 40) .redacted(reason: entry.isPlaceholder ? .placeholder : []) } if let buttons = entry.buttons, !buttons.isEmpty, !entry.isPlaceholder { HStack(spacing: 10) { - let brandColor = Color(NCBrandColor.shared.getElement(account: entry.account)) - let brandTextColor = Color(NCBrandColor.shared.getText(account: entry.account)) + + let brandColor = Color(NCBrandColor.shared.brandElement) + let brandTextColor = Color(.text) ForEach(buttons, id: \.index) { element in Link(destination: URL(string: element.link)!, label: { @@ -124,6 +118,7 @@ struct DashboardWidgetView: View { .foregroundColor(brandTextColor) .border(brandColor, width: 1) .cornerRadius(.infinity) + .padding(.bottom, 12) }) } } @@ -147,7 +142,7 @@ struct DashboardWidgetView: View { .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) } } - .containerBackground(.background, for: .widget) + .containerBackground(Color(.AppBackground.main), for: .widget) } } diff --git a/Widget/Files/FilesData.swift b/Widget/Files/FilesData.swift index 78d8ecbaf4..de45acaa09 100644 --- a/Widget/Files/FilesData.swift +++ b/Widget/Files/FilesData.swift @@ -27,6 +27,7 @@ struct FilesData: Identifiable, Hashable { var subTitle: String var url: URL var useTypeIconFile: Bool = false + var color: UIColor? } let filesDatasTest: [FilesData] = [ @@ -237,4 +238,21 @@ func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySi } else { return(FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: datas.isEmpty, userId: activeTableAccount.userId, url: activeTableAccount.urlBase, account: activeTableAccount.account, tile: title, footerImage: "checkmark.icloud", footerText: footerText)) } + + @Sendable func colorByImageName(_ name: String) -> UIColor { + switch name { + case NKTypeIconFile.audio.rawValue, + NKTypeIconFile.code.rawValue, + NKTypeIconFile.compress.rawValue, + NKTypeIconFile.image.rawValue, + NKTypeIconFile.video.rawValue, + NKTypeIconFile.txt.rawValue, + NKTypeIconFile.url.rawValue: return NCBrandColor.shared.iconImageColor2 + case NKTypeIconFile.document.rawValue: return NCBrandColor.shared.documentIconColor + case NKTypeIconFile.ppt.rawValue: return NCBrandColor.shared.presentationIconColor + case NKTypeIconFile.xls.rawValue: return NCBrandColor.shared.spreadsheetIconColor + + default: return NCBrandColor.shared.brandElement + } + } } diff --git a/Widget/Files/FilesWidgetProvider.swift b/Widget/Files/FilesWidgetProvider.swift index 4ccce19047..7e51e5145d 100644 --- a/Widget/Files/FilesWidgetProvider.swift +++ b/Widget/Files/FilesWidgetProvider.swift @@ -14,7 +14,7 @@ struct FilesWidgetProvider: IntentTimelineProvider { func placeholder(in context: Context) -> Entry { let datasPlaceholder = Array(filesDatasTest[0...4]) let title = getTitleFilesWidget(tableAccount: nil) - return Entry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", account: "", tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files") + return Entry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", account: "", tile: title, footerImage: "Cloud_Checkmark", footerText: NCBrandOptions.shared.brand + " files") } func getSnapshot(for configuration: AccountIntent, in context: Context, completion: @escaping (Entry) -> Void) { diff --git a/Widget/Files/FilesWidgetView.swift b/Widget/Files/FilesWidgetView.swift index 770d90766a..cf1ea6978a 100644 --- a/Widget/Files/FilesWidgetView.swift +++ b/Widget/Files/FilesWidgetView.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2024 STRATO GmbH // SPDX-FileCopyrightText: 2022 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -6,181 +7,168 @@ import SwiftUI import WidgetKit struct FilesWidgetView: View { + var entry: FilesDataEntry + var body: some View { - let parameterLink = "&user=\(entry.userId)&url=\(entry.url)" - let linkNoAction: URL = URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink)! : URL(string: NCGlobal.shared.widgetActionNoAction)! - let linkActionUploadAsset: URL = URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink)! : URL(string: NCGlobal.shared.widgetActionUploadAsset)! - let linkActionScanDocument: URL = URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionScanDocument)! - let linkActionTextDocument: URL = URL(string: NCGlobal.shared.widgetActionTextDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionTextDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionTextDocument)! - let linkActionVoiceMemo: URL = URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink)! : URL(string: NCGlobal.shared.widgetActionVoiceMemo)! GeometryReader { geo in if entry.isEmpty { - VStack(alignment: .center) { - Image(systemName: "checkmark") - .resizable() - .scaledToFit() - .font(Font.system(.body).weight(.light)) - .frame(width: 50, height: 50) - Text(NSLocalizedString("_no_items_", comment: "")) - .font(.system(size: 25)) - .padding() - Text(NSLocalizedString("_check_back_later_", comment: "")) - .font(.system(size: 15)) - } - .frame(width: geo.size.width, height: geo.size.height) + EmptyWidgetContentView() + .frame(width: geo.size.width, height: geo.size.height) } - ZStack(alignment: .topLeading) { - HStack { - Text(entry.tile) - .font(.system(size: 12)) - .fontWeight(.bold) - .multilineTextAlignment(.center) - .textCase(.uppercase) - .lineLimit(1) - } - .frame(width: geo.size.width - 20) - .padding([.top, .leading, .trailing], 10) + HeaderView(title: entry.tile) + .padding(.top, 7) + + VStack(spacing: 5) { if !entry.isEmpty { - VStack(alignment: .leading) { - VStack(spacing: 0) { - ForEach(entry.datas, id: \.id) { element in - Link(destination: element.url) { - HStack(spacing: 10) { - Group { - if element.useTypeIconFile { - Image(uiImage: element.image) - .resizable() - .renderingMode(.template) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor2)) - .scaledToFit() - .frame(width: 35, height: 35) - } else { - Image(uiImage: element.image) - .resizable() - .frame(width: 35, height: 35) - .background(Color(.secondarySystemBackground)) - .clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous)) - } - } - - VStack(alignment: .leading, spacing: 2) { - Text(element.title) - .font(.system(size: 12)) - .lineLimit(1) - .truncationMode(.tail) - Text(element.subTitle) - .font(.system(size: 10)) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor2)) - .lineLimit(1) - .truncationMode(.tail) - } - Spacer(minLength: 0) - } - .padding(.horizontal, 10) - .frame(height: 44) - } - if element != entry.datas.last { - Divider() - .padding(.leading, 52) - } - } - } - } - .padding(.top, 30) - .redacted(reason: entry.isPlaceholder ? .placeholder : []) + WidgetContentView(entry: entry) + .padding(.top, 35) + .redacted(reason: entry.isPlaceholder ? .placeholder : []) } - HStack(spacing: 10) { - let buttonSize: CGFloat = 40 - - Link(destination: entry.isPlaceholder ? linkNoAction : linkActionUploadAsset) { - Image(systemName: "photo.badge.plus") - .resizable() - .renderingMode(.template) - .scaledToFit() - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .frame(width: 18, height: 18) - .padding(11) - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - .clipShape(Circle()) - .frame(width: buttonSize, height: buttonSize) - } - .frame(maxWidth: .infinity) - - Link(destination: entry.isPlaceholder ? linkNoAction : linkActionScanDocument) { - Image(systemName: "doc.text.viewfinder") - .resizable() - .renderingMode(.template) - .scaledToFit() - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .frame(width: 18, height: 18) - .padding(11) - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - .clipShape(Circle()) - .frame(width: buttonSize, height: buttonSize) - } - .frame(maxWidth: .infinity) - - Link(destination: entry.isPlaceholder ? linkNoAction : linkActionTextDocument) { - Image("note.text") - .resizable() - .renderingMode(.template) - .scaledToFit() - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .frame(width: 18, height: 18) - .padding(11) - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - .clipShape(Circle()) - .frame(width: buttonSize, height: buttonSize) + Spacer() + + LinkActionsToolbarView(entry: entry, geo: geo) + .frame(width: geo.size.width, + height: 48, + alignment: .bottom) + .redacted(reason: entry.isPlaceholder ? .placeholder : []) + + FooterView(imageName: entry.footerImage, + text: entry.footerText, + isPlaceholder: entry.isPlaceholder) + .padding(.horizontal, 15.0) + .padding(.top, 5.0) + .padding(.bottom, 5.0) + .frame(maxWidth: geo.size.width, + maxHeight: 30, + alignment: .bottomTrailing) + } + } + .widgetBackground(Color(.background)) + } +} + +fileprivate struct WidgetContentView: View { + let entry: FilesDataEntry + + var body: some View { + VStack(alignment: .leading) { + VStack(spacing: 0) { + ForEach(entry.datas, id: \.id) { element in + Link(destination: element.url) { + HStack { + if element.useTypeIconFile { + Image(uiImage: element.image) + .resizable() + .renderingMode(.template) + .foregroundStyle(Color(element.color ?? NCBrandColor.shared.iconImageColor)) + .scaledToFit() + .aspectRatio(1.1, contentMode: .fit) + .frame(width: WidgetConstants.elementIconWidthHeight, + height: WidgetConstants.elementIconWidthHeight) + } else { + Image(uiImage: element.image) + .resizable() + .scaledToFill() + .frame(width: WidgetConstants.elementIconWidthHeight, + height: WidgetConstants.elementIconWidthHeight) + .clipped() + } + + VStack(alignment: .leading, spacing: 2) { + Text(element.title) + .font(WidgetConstants.elementTileFont) + .foregroundStyle(Color(.title)) + Text(element.subTitle) + .font(WidgetConstants.elementSubtitleFont) + .foregroundStyle(Color(.subtitle)) + } + Spacer() + } + .padding(.leading, 10) + .frame(maxHeight: .infinity) } - .frame(maxWidth: .infinity) - - Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo) { - Image("microphone") - .resizable() - .renderingMode(.template) - .scaledToFit() - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .frame(width: 18, height: 18) - .padding(11) - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - .clipShape(Circle()) - .frame(width: buttonSize, height: buttonSize) + if element != entry.datas.last { + Divider() + .overlay(Color(.divider)) } - .frame(maxWidth: .infinity) - } - .padding(.horizontal, 10) - .frame(maxWidth: .infinity, maxHeight: geo.size.height - 25, alignment: .bottom) - .redacted(reason: entry.isPlaceholder ? .placeholder : []) - - HStack { - Image(systemName: entry.footerImage) - .resizable() - .scaledToFit() - .frame(width: 15, height: 15) - .font(Font.system(.body).weight(.light)) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - - Text(entry.footerText) - .font(.caption2) - .lineLimit(1) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) } } - .containerBackground(.background, for: .widget) + } +} + +struct LinkActionsToolbarView: View { + let entry: FilesDataEntry + let geo: GeometryProxy + + var body: some View { + let parameterLink = "&user=\(entry.userId)&url=\(entry.url)" + + let linkNoAction: URL = URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink)! : URL(string: NCGlobal.shared.widgetActionNoAction)! + let linkActionUploadAsset: URL = URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink)! : URL(string: NCGlobal.shared.widgetActionUploadAsset)! + let linkActionScanDocument: URL = URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionScanDocument)! + let linkActionVoiceMemo: URL = URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink)! : URL(string: NCGlobal.shared.widgetActionVoiceMemo)! + + HStack(spacing: -6) { + + let height: CGFloat = 48 + let width = geo.size.width / 3 + + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionUploadAsset, label: { + Image(uiImage: UIImage(resource: .media)) + .resizable() + .renderingMode(.template) + .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(.text)) + .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement)) + .clipShape(Circle()) + .scaledToFit() + .frame(width: width, height: height) + }) + + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionScanDocument, label: { + Image(uiImage: UIImage(resource: .scan)) + .resizable() + .renderingMode(.template) + .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(.text)) + .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement)) + .clipShape(Circle()) + .scaledToFit() + .font(Font.system(.body).weight(.light)) + .frame(width: width, height: height) + }) + + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo, label: { + Image(uiImage: UIImage(resource: .mic)) + .resizable() + .renderingMode(.template) + .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(.text)) + .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement)) + .clipShape(Circle()) + .scaledToFit() + .frame(width: width, height: height) + }) + } } } struct FilesWidget_Previews: PreviewProvider { static var previews: some View { let datas = Array(filesDatasTest[0...4]) - let entry = FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: false, userId: "", url: "", account: "", tile: "Good afternoon, Marino Faggiana", footerImage: "checkmark.icloud", footerText: "Nextcloud files") - FilesWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge)) + let entry = FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: true, userId: "", url: "", account: "", tile: "Good afternoon, Marino Faggiana", footerImage: "Cloud_Checkmark", footerText: "Nextcloud files") + if #available(iOSApplicationExtension 17.0, *) { + FilesWidgetView(entry: entry) + .previewContext(WidgetPreviewContext(family: .systemLarge)) + .containerBackground(for: .widget) { + Color.red + } + } else { + FilesWidgetView(entry: entry) + .previewContext(WidgetPreviewContext(family: .systemLarge)) + } } } diff --git a/Widget/Toolbar/ToolbarData.swift b/Widget/Toolbar/ToolbarData.swift index 0306f1d911..eebb3c2b47 100644 --- a/Widget/Toolbar/ToolbarData.swift +++ b/Widget/Toolbar/ToolbarData.swift @@ -38,9 +38,13 @@ func getToolbarDataEntry(isPreview: Bool, completion: @escaping (_ entry: Toolba account = activeTableAccount.account } + if isPreview { + return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, account: account, footerImage: "Cloud_Checkmark", footerText: NCBrandOptions.shared.brand + " toolbar")) + } + if NCManageDatabase.shared.getActiveTableAccount() == nil { - return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, account: account, footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: ""))) + return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, account: account, footerImage: "Cloud_Xmark", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: ""))) } - completion(ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: userId, url: url, account: account, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")) + completion(ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: userId, url: url, account: account, footerImage: "Cloud_Checkmark", footerText: NCBrandOptions.shared.brand + " toolbar")) } diff --git a/Widget/Toolbar/ToolbarWidgetProvider.swift b/Widget/Toolbar/ToolbarWidgetProvider.swift index f9bba1ba47..e8a8dc5d1f 100644 --- a/Widget/Toolbar/ToolbarWidgetProvider.swift +++ b/Widget/Toolbar/ToolbarWidgetProvider.swift @@ -10,7 +10,7 @@ struct ToolbarWidgetProvider: TimelineProvider { typealias Entry = ToolbarDataEntry func placeholder(in context: Context) -> Entry { - return Entry(date: Date(), isPlaceholder: true, userId: "", url: "", account: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar") + return Entry(date: Date(), isPlaceholder: true, userId: "", url: "", account: "", footerImage: "Cloud_Checkmark", footerText: NCBrandOptions.shared.brand + " toolbar") } func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) { diff --git a/Widget/Toolbar/ToolbarWidgetView.swift b/Widget/Toolbar/ToolbarWidgetView.swift index dd43fb0756..12b48ae44e 100644 --- a/Widget/Toolbar/ToolbarWidgetView.swift +++ b/Widget/Toolbar/ToolbarWidgetView.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2024 STRATO GmbH // SPDX-FileCopyrightText: 2022 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -11,97 +12,76 @@ struct ToolbarWidgetView: View { @ViewBuilder var body: some View { mainContent - .containerBackground(Color.black, for: .widget) + .containerBackground(Color(.background), for: .widget) } private var mainContent: some View { let parameterLink = "&user=\(entry.userId)&url=\(entry.url)" - let safeUrl = { (base: String) in - URL(string: base + parameterLink) ?? URL(string: base)! - } - let linkNoAction = safeUrl(NCGlobal.shared.widgetActionNoAction) - let linkActionUploadAsset = safeUrl(NCGlobal.shared.widgetActionUploadAsset) - let linkActionScanDocument = safeUrl(NCGlobal.shared.widgetActionScanDocument) - let linkActionTextDocument = safeUrl(NCGlobal.shared.widgetActionTextDocument) - let linkActionVoiceMemo = safeUrl(NCGlobal.shared.widgetActionVoiceMemo) - let sizeButton: CGFloat = 65 + let linkNoAction: URL = URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink)! : URL(string: NCGlobal.shared.widgetActionNoAction)! + let linkActionUploadAsset: URL = URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink)! : URL(string: NCGlobal.shared.widgetActionUploadAsset)! + let linkActionScanDocument: URL = URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionScanDocument)! + let linkActionVoiceMemo: URL = URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink)! : URL(string: NCGlobal.shared.widgetActionVoiceMemo)! return GeometryReader { geo in ZStack(alignment: .topLeading) { HStack(spacing: 0) { + let height: CGFloat = 60 + let width = geo.size.width / 3 + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionUploadAsset, label: { - Image(systemName: "photo.badge.plus") + Image(uiImage: UIImage(resource: .media)) .resizable() .renderingMode(.template) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .padding() - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) + .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(.text)) + .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement)) .clipShape(Circle()) .scaledToFit() - .frame(width: geo.size.width / 4, height: sizeButton) + .frame(width: width, height: height) }) Link(destination: entry.isPlaceholder ? linkNoAction : linkActionScanDocument, label: { - Image(systemName: "doc.text.viewfinder") + Image(uiImage: UIImage(resource: .scan)) .resizable() .renderingMode(.template) .font(Font.system(.body).weight(.light)) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .padding() - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - .clipShape(Circle()) - .scaledToFit() - .frame(width: geo.size.width / 4, height: sizeButton) - }) - - Link(destination: entry.isPlaceholder ? linkNoAction : linkActionTextDocument, label: { - Image("note.text") - .resizable() - .renderingMode(.template) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .padding() - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) + .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(.text)) + .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement)) .clipShape(Circle()) .scaledToFit() - .frame(width: geo.size.width / 4, height: sizeButton) + .frame(width: width, height: height) }) - Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo, label: { - Image("microphone") - .resizable() - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account))) - .padding() - .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - .clipShape(Circle()) - .scaledToFit() - .frame(width: geo.size.width / 4, height: sizeButton) - }) + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo, label: { + Image(uiImage: UIImage(resource: .mic)) + .resizable() + .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(.text)) + .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement)) + .clipShape(Circle()) + .scaledToFit() + .frame(width: width, height: height) + }) } .frame(width: geo.size.width, height: geo.size.height, alignment: .center) + .padding(.vertical, geo.size.height / 2 * -0.25) .redacted(reason: entry.isPlaceholder ? .placeholder : []) - HStack { - Image(systemName: entry.footerImage) - .resizable() - .font(Font.system(.body).weight(.light)) - .scaledToFit() - .frame(width: 15, height: 15) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - - Text(entry.footerText) - .font(.caption2) - .padding(.trailing, 13.0) - .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account))) - } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) + FooterView(imageName: entry.footerImage, + text: entry.footerText, + isPlaceholder: entry.isPlaceholder) + .padding(.horizontal, 15.0) + .padding(.bottom, 10.0) + .frame(maxWidth: geo.size.width - 5, + maxHeight: geo.size.height - 2, + alignment: .bottomTrailing) } } + .widgetBackground(Color(.background)) } } struct ToolbarWidget_Previews: PreviewProvider { static var previews: some View { - let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: "", url: "", account: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar") + let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: "", url: "", account: "", footerImage: "Cloud_Checkmark", footerText: NCBrandOptions.shared.brand + " toolbar") ToolbarWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemMedium)) } } diff --git a/Widget/Widget.swift b/Widget/Widget.swift index 469b8339d3..af251ed991 100644 --- a/Widget/Widget.swift +++ b/Widget/Widget.swift @@ -10,10 +10,8 @@ import SwiftUI struct NextcloudWidgetBundle: WidgetBundle { @WidgetBundleBuilder var body: some Widget { - DashboardWidget() FilesWidget() ToolbarWidget() - LockscreenWidget() } } diff --git a/Widget/WidgetCommon.swift b/Widget/WidgetCommon.swift new file mode 100644 index 0000000000..52c4c22890 --- /dev/null +++ b/Widget/WidgetCommon.swift @@ -0,0 +1,76 @@ +// +// WidgetCommon.swift +// Widget +// +// Created by Oleh Shcherba on 20.11.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +struct WidgetConstants { + static let bottomTextFont: Font = .system(size: 16) + static let bottomImageWidthHeight = 16.0 + static let elementIconWidthHeight = 36.0 + static let titleTextFont: Font = .system(size: 24, weight: .semibold) + static let elementTileFont: Font = .system(size: 16, weight: .semibold) + static let elementSubtitleFont: Font = .system(size: 14, weight: .semibold) +} + +struct EmptyWidgetContentView: View { + var body: some View { + VStack(alignment: .center) { + Image(systemName: "checkmark") + .resizable() + .scaledToFit() + .font(Font.system(.body).weight(.light)) + .foregroundStyle(Color(.title)) + .frame(width: 50, height: 50) + Text(NSLocalizedString("_no_items_", comment: "")) + .font(.system(size: 25)) + .foregroundStyle(Color(.title)) + .padding() + Text(NSLocalizedString("_check_back_later_", comment: "")) + .font(.system(size: 15)) + .foregroundStyle(Color(.title)) + } + } +} + +struct HeaderView: View { + let title: String + + var body: some View { + Text(title.firstUppercased) + .font(WidgetConstants.titleTextFont) + .foregroundStyle(Color(.title)) + .minimumScaleFactor(0.7) + .lineLimit(1) + .padding(.horizontal, 13) + } +} + +struct FooterView: View { + let imageName: String + let text: String + let isPlaceholder: Bool + + var body: some View { + HStack(spacing: 8) { + Image(uiImage: UIImage(named: imageName) ?? UIImage()) + .resizable() + .renderingMode(.template) + .scaledToFit() + .frame(width: WidgetConstants.bottomImageWidthHeight, + height: WidgetConstants.bottomImageWidthHeight) + .font(Font.system(.body).weight(.light)) + .foregroundColor(isPlaceholder ? Color(.systemGray4) : Color(.bottomElementForeground)) + + Text(text) + .font(WidgetConstants.bottomTextFont) + .lineLimit(1) + .minimumScaleFactor(0.7) + .foregroundColor(isPlaceholder ? Color(.systemGray4) : Color(.bottomElementForeground)) + } + } +} diff --git a/Widget/WidgetDebug.entitlements b/Widget/WidgetDebug.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/Widget/WidgetDebug.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/WidgetDashboardIntentHandler/WidgetDashboardIntentHandlerDebug.entitlements b/WidgetDashboardIntentHandler/WidgetDashboardIntentHandlerDebug.entitlements new file mode 100644 index 0000000000..2e5c24b65c --- /dev/null +++ b/WidgetDashboardIntentHandler/WidgetDashboardIntentHandlerDebug.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.viseven.ionos.easystorage + + com.apple.security.network.client + + keychain-access-groups + + $(AppIdentifierPrefix)com.viseven.ionos.easystorage + + + diff --git a/iOSClient/Account/Account Settings/NCAccountSettingsModel.swift b/iOSClient/Account/Account Settings/NCAccountSettingsModel.swift index d7742e9f4c..7b06e804fe 100644 --- a/iOSClient/Account/Account Settings/NCAccountSettingsModel.swift +++ b/iOSClient/Account/Account Settings/NCAccountSettingsModel.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2024 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -77,24 +78,24 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling { /// Triggered when the view appears. func onViewAppear() { - var indexActiveAccount = 0 - let tableAccounts = database.getAllTableAccount() - var alias = "" - - for (index, account) in tableAccounts.enumerated() { - if account.active { - tblAccount = account - indexActiveAccount = index - alias = account.alias - } - } - - self.indexActiveAccount = indexActiveAccount - self.tblAccounts = tableAccounts - self.tblAccount = tblAccount - self.alias = alias + var indexActiveAccount = 0 + let tableAccounts = database.getAllTableAccount() + var alias = "" + + for (index, account) in tableAccounts.enumerated() { + if account.active { + tblAccount = account + indexActiveAccount = index + alias = account.alias + } + } + + self.indexActiveAccount = indexActiveAccount + self.tblAccounts = tableAccounts + self.tblAccount = tblAccount + self.alias = alias } - + /// Func to get the user display name + alias func getUserName() -> String { guard let tblAccount else { return "" } @@ -129,12 +130,8 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling { /// Is the user an Admin func isAdminGroup() -> Bool { guard let tblAccount else { return false } -#if DEBUG - return true -#else let groups = database.getAccountGroups(account: tblAccount.account) return groups.contains(NCGlobal.shared.groupAdmin) -#endif } /// Function to know the height of "account" data @@ -165,8 +162,15 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling { if let tableAccount = database.getTableAccount(predicate: NSPredicate(format: "account == %@", account)) { self.tblAccount = tableAccount self.alias = tableAccount.alias + Task { + await NCAccount().changeAccount(tableAccount.account, userProfile: nil, controller: self.controller) + } } } + + func openLogin() { + self.appDelegate.openLogin(selector: NCGlobal.shared.introLogin) + } /// Function to delete the current account func deleteAccount() { diff --git a/iOSClient/Account/Account Settings/NCAccountSettingsView.swift b/iOSClient/Account/Account Settings/NCAccountSettingsView.swift index faa766acb3..f4dd0ac839 100644 --- a/iOSClient/Account/Account Settings/NCAccountSettingsView.swift +++ b/iOSClient/Account/Account Settings/NCAccountSettingsView.swift @@ -9,6 +9,7 @@ struct NCAccountSettingsView: View { @ObservedObject var model: NCAccountSettingsModel @State private var isExpanded: Bool = false + @State private var showUserStatus = false @State private var showServerCertificate = false @State private var showPushCertificate = false @State private var showDeleteAccountAlert: Bool = false @@ -24,255 +25,28 @@ struct NCAccountSettingsView: View { var body: some View { NavigationView { Form { - Section(content: { - TabView(selection: $model.indexActiveAccount) { - ForEach(0.. UIMenu? { - return nil - } +class NCActivityNavigationController: HiDriveMainNavigationController { } diff --git a/iOSClient/AppDelegate.swift b/iOSClient/AppDelegate.swift index aaaab0eac9..205ce7fa07 100644 --- a/iOSClient/AppDelegate.swift +++ b/iOSClient/AppDelegate.swift @@ -16,6 +16,8 @@ import RealmSwift class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var backgroundSessionCompletionHandler: (() -> Void)? + var activeLogin: NCLogin? + var activeLoginWeb: NCLoginProvider? var isUiTestingEnabled: Bool { return ProcessInfo.processInfo.arguments.contains("UI_TESTING") } @@ -50,12 +52,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD NCSettingsBundleHelper.checkAndExecuteSettings(delay: 0) UserDefaults.standard.register(defaults: ["UserAgent": userAgent]) - - #if !DEBUG - if !NCPreferences().disableCrashservice, !NCBrandOptions.shared.disable_crash_service { - FirebaseApp.configure() - } - #endif + FirebaseApp.configure() + DataProtectionAgreementManager.shared.setupAnalyticsCollection() NCBrandColor.shared.createUserColors() @@ -114,6 +112,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD self.handleProcessingTask(processingTask) } scheduleAppProcessing() + + UISwitch.appearance().onTintColor = NCBrandColor.shared.switchColor + UISlider.appearance().thumbTintColor = UIColor(Color(.QualitySlider.thumb)) + UISlider.appearance().maximumTrackTintColor = UIColor(Color(.QualitySlider.maximumTrack)) if NCBrandOptions.shared.enforce_passcode_lock { NCPreferences().requestPasscodeAtStart = true @@ -452,6 +454,47 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD } } + // MARK: - Login + + func openLogin(selector: Int, window: UIWindow? = nil) { + UIApplication.shared.allSceneSessionDestructionExceptFirst() + + func showLoginViewController(_ viewController: UIViewController?) { + guard let viewController else { return } + let navigationController = NCLoginNavigationController(rootViewController: viewController) + + navigationController.modalPresentationStyle = .fullScreen + navigationController.navigationBar.barStyle = .black + navigationController.navigationBar.tintColor = NCBrandColor.shared.customerText + navigationController.navigationBar.barTintColor = NCBrandColor.shared.customer + navigationController.navigationBar.isTranslucent = false + + if let controller = UIApplication.shared.mainAppWindow?.rootViewController { + if let presentedVC = controller.presentedViewController, !(presentedVC is NCLoginNavigationController) { + presentedVC.dismiss(animated: false) { + controller.present(navigationController, animated: true) + } + } else { + controller.present(navigationController, animated: true) + } + } else { + window?.rootViewController = navigationController + window?.makeKeyAndVisible() + } + } + + if activeLogin?.view.window == nil { + if selector == NCGlobal.shared.introSignUpWithProvider { + // MERGE: HiDrive Next doesn't support choosing providers + } else { + // Regular login + activeLogin = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin + activeLogin?.urlBase = NCBrandOptions.shared.disable_request_login_url ? NCBrandOptions.shared.loginBaseUrl : "" + showLoginViewController(activeLogin) + } + } + } + // MARK: - func trustCertificateError(host: String) { diff --git a/iOSClient/BurgerMenu/BurgerMenuAttachController.swift b/iOSClient/BurgerMenu/BurgerMenuAttachController.swift new file mode 100644 index 0000000000..d9346e7473 --- /dev/null +++ b/iOSClient/BurgerMenu/BurgerMenuAttachController.swift @@ -0,0 +1,69 @@ +// +// BurgerMenuAttachController.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 28.07.2024. +// Copyright © 2024 STRATO GmbH +// + +import Foundation +import SwiftUI + +class BurgerMenuAttachController { + private weak var presentingScreen: NCMainTabBarController? + private var sideMenu: BurgerMenuViewController? + + init(with presentingViewController: NCMainTabBarController) { + self.presentingScreen = presentingViewController + } + + func showMenu() { + sideMenu = BurgerMenuViewController(delegate: self) + guard let sideMenu = sideMenu else { + return + } + sideMenu.modalPresentationStyle = .overFullScreen + presentingScreen?.present(sideMenu, animated: false) + } +} + +extension BurgerMenuAttachController: BurgerMenuViewModelDelegate { + func burgerMenuViewModelDidHideMenu(_ viewModel: BurgerMenuViewModel) { + sideMenu?.dismiss(animated: false) + } + + func burgerMenuViewModelWantsOpenRecent(_ viewModel: BurgerMenuViewModel) { + sideMenu?.dismiss(animated: false) + let storyboard = UIStoryboard(name: "NCRecent", bundle: nil) + present(vc: storyboard.instantiateInitialViewController()) + } + + func burgerMenuViewModelWantsOpenOffline(_ viewModel: BurgerMenuViewModel) { + sideMenu?.dismiss(animated: false) + let storyboard = UIStoryboard(name: "NCOffline", bundle: nil) + present(vc: storyboard.instantiateInitialViewController()) + } + + func burgerMenuViewModelWantsOpenDeletedFiles(_ viewModel: BurgerMenuViewModel) { + sideMenu?.dismiss(animated: false) + let storyboard = UIStoryboard(name: "NCTrash", bundle: nil) + present(vc: storyboard.instantiateInitialViewController()) + } + + func burgerMenuViewModelWantsOpenSettings(_ viewModel: BurgerMenuViewModel) { + sideMenu?.dismiss(animated: false) + let settingsView = NCSettingsView(model: NCSettingsModel(controller: presentingScreen)) + let settingsController = UIHostingController(rootView: settingsView) + present(vc: settingsController) + } + + private func present(vc: UIViewController?) { + guard let vc = vc else { + return + } + let navVC = HiDriveMainNavigationController(rootViewController: vc) + navVC.modalPresentationStyle = .overCurrentContext + navVC.setNavigationBarAppearance() + presentingScreen?.present(navVC, animated: true) + } +} diff --git a/iOSClient/BurgerMenu/BurgerMenuView.swift b/iOSClient/BurgerMenu/BurgerMenuView.swift new file mode 100644 index 0000000000..401f7e7d41 --- /dev/null +++ b/iOSClient/BurgerMenu/BurgerMenuView.swift @@ -0,0 +1,258 @@ +// +// BurgerMenuView.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 28.07.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +private enum _Constants { + static let font = Font.system(size: 16).weight(.medium) + static let buttonPressedFont = font.weight(.semibold) + static let spacingBetweenItems: CGFloat = 12 + static let buttonLeadingPadding: CGFloat = 12 +} + +struct BurgerMenuView: View { + @ObservedObject var viewModel: BurgerMenuViewModel + + var body: some View { + GeometryReader { geometry in + let width = geometry.size.width + ZStack(alignment: .leading) { + Color(.BurgerMenu.overlay) + .ignoresSafeArea() + .onTapGesture { + viewModel.hideMenu() + } + HStack(spacing: 0, content: { + VStack(alignment: .leading, spacing: _Constants.spacingBetweenItems) { + Image(.ionosEasyStorageLogo) + .resizable() + .renderingMode(.template) + .foregroundStyle(Color(.NavigationBar.logoTint)) + .scaledToFit() + .padding(EdgeInsets(top: 24, + leading: 0, + bottom: 8, + trailing: 0)) + .frame(height: 54) + Button(action: { + viewModel.hideMenu() + }, label: { + HStack(spacing: 12) { + Image(.BurgerMenu.chevronLeft) + .renderingMode(.template) + .resizable() + .scaledToFit() + .frame(width: 10, height: 16) + Text(NSLocalizedString("_back_", tableName: nil, bundle: Bundle.main, value: "Back", comment: "")) + .font(_Constants.font) + } + .foregroundStyle(Color(.BurgerMenu.buttonForeground)) + }) + .frame(height: 48) + if #available(iOS 16.4, *) { + BurgerMenuMainSectionView(viewModel: viewModel) + .scrollBounceBehavior(.basedOnSize) + } else { + BurgerMenuMainSectionView(viewModel: viewModel) + } + } + .padding(EdgeInsets(top: 0, leading: 24, bottom: 0, trailing: 24)) + .frame(width: min(width * 0.75, 300), alignment: .leading) + .background(Color(.BurgerMenu.background)) + .offset(x: viewModel.isVisible ? 0 : -width) + }) + } + } + .opacity(viewModel.isVisible ? 1 : 0) + .animation(.easeInOut(duration: viewModel.appearingAnimationIntervalInSec), + value: viewModel.isVisible) + } +} + +private struct BurgerMenuMainSectionView: View { + @ObservedObject var viewModel: BurgerMenuViewModel + + var body: some View { + GeometryReader { geometry in + ScrollView { + VStack(spacing: _Constants.spacingBetweenItems, content: { + BurgerMenuViewButton(image: .BurgerMenu.recent, + title: NSLocalizedString("_recent_", + comment: ""), + action: { + viewModel.openRecent() + }) + BurgerMenuViewButton(image: .BurgerMenu.offline, + title: NSLocalizedString("_offline_", + comment: ""), + action: { + viewModel.openOffline() + }) + BurgerMenuViewButton(image: .BurgerMenu.deleted, + title: NSLocalizedString("_trash_view_", + comment: ""), + action: { + viewModel.openDeletedFiles() + }) + Spacer() + BurgerMenuViewButton(image: .BurgerMenu.settings, + title: NSLocalizedString("_settings_", + comment: ""), + action: { + viewModel.openSettings() + }) + VStack(alignment: .leading, spacing: 0, content: { + HStack(spacing: 12, content: { + Image(.BurgerMenu.cloud) + .buttonIconStyled() + Text(NSLocalizedString("_storage_used_", tableName: nil, bundle: Bundle.main, value: "Storage used", + comment: "")) + .font(_Constants.font.weight(.semibold)) + }) + .frame(height: 48) + CustomProgressView(progress: viewModel.progressUsedSpace) + Spacer().frame(height: 8) + Text(viewModel.messageUsedSpace) + .font(.system(size: 16)) + }) + .foregroundStyle(Color(.BurgerMenu.buttonForeground)) + .padding(EdgeInsets(top: 0, leading: _Constants.buttonLeadingPadding, bottom: 0, trailing: 0)) + }) + .padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 0)) + .frame(minHeight: geometry.size.height) + } + } + } +} + +private struct BurgerMenuViewButton: View { + let image: ImageResource + let title: String + let action: () -> Void + var body: some View { + Button(action: { + action() + }, label: { + HStack(spacing: 12) { + Image(image) + .buttonIconStyled() + Text(title) + Spacer() + } + .makeAllButtonSpaceTappable() + .foregroundStyle(Color(.BurgerMenu.buttonForeground)) + .frame(height: 48) + .padding(EdgeInsets(top: 0, leading: _Constants.buttonLeadingPadding, bottom: 0, trailing: 0)) + }) + .buttonStyle(CustomBackgroundOnPressButtonStyle()) + } +} + +private struct CustomBackgroundOnPressButtonStyle: ButtonStyle { + func makeBody(configuration: Configuration) -> some View { + configuration + .label + .font(configuration.isPressed ? _Constants.buttonPressedFont : _Constants.font) + .background { + if configuration.isPressed { + GeometryReader { geometry in + Color(.BurgerMenu.pressedButton) + .clipShape(RoundedRectangle(cornerRadius: geometry.size.height / 2)) + } + } else { + EmptyView() + } + } + } +} + +private struct CustomProgressView: View { + private let height: CGFloat = 8 + private let cornerRadius: CGFloat = 13 + private let blurRadius: CGFloat = 2 + let progress: Double + var body: some View { + GeometryReader { geometry in + ZStack { + Color(.BurgerMenu.progressBarBackground) + .overlay { + RoundedRectangle(cornerRadius: cornerRadius) + .stroke(Color(.BurgerMenu.commonShadow).opacity(0.6), + lineWidth: 1) + .frame(width: geometry.size.width + blurRadius, + height: 2 * geometry.size.height) + .blur(radius: blurRadius) + .offset(x: blurRadius / 2, + y: geometry.size.height / 2) + .clipShape(RoundedRectangle(cornerRadius: cornerRadius)) + } + } + .clipShape(RoundedRectangle(cornerRadius: cornerRadius)) + Color(NCBrandColor.shared.brandElement) + .frame(width: geometry.size.width * progress + height) + .clipShape(RoundedRectangle(cornerRadius: cornerRadius)) + .offset(x: -height) + .clipShape(RoundedRectangle(cornerRadius: cornerRadius)) + .shadow(color: Color(.BurgerMenu.commonShadow).opacity(0.25), + radius: 2, + x: 0, + y: 1) + } + .frame(height: height) + } +} + +private extension Image { + func buttonIconStyled() -> some View { + self + .renderingMode(.template) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 16, height: 16) + } +} + +private extension View { + func makeAllButtonSpaceTappable() -> some View { + self.contentShape(Rectangle()) + } +} + +#Preview { + class BurgerMenuViewModelMock: BurgerMenuViewModel { + override init(delegate: (any BurgerMenuViewModelDelegate)?, + controller: NCMainTabBarController?) { + super.init(delegate: delegate, controller: nil) + progressUsedSpace = 0.3 + messageUsedSpace = "62,5 MB of 607,21 GB used" + isVisible = true + } + } + + struct CustomPreviewView: View { + @StateObject var viewModel = BurgerMenuViewModelMock(delegate: nil, controller: nil) + var body: some View { + return NavigationView { + BurgerMenuView(viewModel: viewModel) + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button(action: { + viewModel.isVisible.toggle() + }, label: { + Image(systemName: + "line.3.horizontal") + }) + } + } + .navigationBarHidden(viewModel.isVisible) + } + } + } + + return CustomPreviewView() +} diff --git a/iOSClient/BurgerMenu/BurgerMenuViewController.swift b/iOSClient/BurgerMenu/BurgerMenuViewController.swift new file mode 100644 index 0000000000..ac6af5464d --- /dev/null +++ b/iOSClient/BurgerMenu/BurgerMenuViewController.swift @@ -0,0 +1,31 @@ +// +// BurgerMenuViewController.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 28.07.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +class BurgerMenuViewController: UIHostingController { + + private var viewModel: BurgerMenuViewModel? + + convenience init(delegate: BurgerMenuViewModelDelegate?) { + let viewModel = BurgerMenuViewModel(delegate: delegate, controller: nil) + self.init(rootView: BurgerMenuView(viewModel: viewModel)) + viewModel.controller = self.mainTabBarController + self.viewModel = viewModel + } + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = UIColor.clear + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + viewModel?.showMenu() + } +} diff --git a/iOSClient/BurgerMenu/BurgerMenuViewModel.swift b/iOSClient/BurgerMenu/BurgerMenuViewModel.swift new file mode 100644 index 0000000000..18815c47f5 --- /dev/null +++ b/iOSClient/BurgerMenu/BurgerMenuViewModel.swift @@ -0,0 +1,103 @@ +// +// BurgerMenuViewModel.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 29.07.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +protocol BurgerMenuViewModelDelegate: AnyObject { + func burgerMenuViewModelDidHideMenu(_ viewModel: BurgerMenuViewModel) + func burgerMenuViewModelWantsOpenRecent(_ viewModel: BurgerMenuViewModel) + func burgerMenuViewModelWantsOpenOffline(_ viewModel: BurgerMenuViewModel) + func burgerMenuViewModelWantsOpenDeletedFiles(_ viewModel: BurgerMenuViewModel) + func burgerMenuViewModelWantsOpenSettings(_ viewModel: BurgerMenuViewModel) +} + +class BurgerMenuViewModel: ObservableObject { + weak var delegate: BurgerMenuViewModelDelegate? + + @Published var progressUsedSpace: Double = 0 + @Published var messageUsedSpace: String = "" + + @Published var isVisible: Bool = false + + private let database = NCManageDatabase.shared + + weak var controller: NCMainTabBarController? + private var session: NCSession.Session { + NCSession.shared.getSession(controller: controller) + } + + let appearingAnimationIntervalInSec = 0.5 + + init(delegate: BurgerMenuViewModelDelegate?, controller: NCMainTabBarController?) { + self.delegate = delegate + } + + func showMenu() { + progressUsedSpace = getUsedSpaceProgress() + messageUsedSpace = getUsedSpaceMessage() + isVisible = true + } + + func hideMenu() { + isVisible = false + DispatchQueue.main.asyncAfter(deadline: .now().advanced(by: .milliseconds(Int(appearingAnimationIntervalInSec*1000)))) { + self.delegate?.burgerMenuViewModelDidHideMenu(self) + } + } + + func openRecent() { + delegate?.burgerMenuViewModelWantsOpenRecent(self) + } + + func openOffline() { + delegate?.burgerMenuViewModelWantsOpenOffline(self) + } + + func openDeletedFiles() { + delegate?.burgerMenuViewModelWantsOpenDeletedFiles(self) + } + + func openSettings() { + delegate?.burgerMenuViewModelWantsOpenSettings(self) + } + + private func getUsedSpaceMessage() -> String { + guard let activeAccount = getActiveAccount() else { + return "" + } + + let utilityFileSystem = NCUtilityFileSystem() + var quota = "" + switch activeAccount.quotaTotal { + case -1: + quota = "0" + case -2: + quota = NSLocalizedString("_quota_space_unknown_", comment: "") + case -3: + quota = NSLocalizedString("_quota_space_unlimited_", comment: "") + default: + quota = utilityFileSystem.transformedSize(activeAccount.quotaTotal) + } + + let quotaUsed: String = utilityFileSystem.transformedSize(activeAccount.quotaUsed) + + let messageUsed = String.localizedStringWithFormat(NSLocalizedString("_used_of_space_", tableName: nil, bundle: Bundle.main, value: "%@ of %@ used", comment: ""), quotaUsed, quota) + return messageUsed + } + + private func getUsedSpaceProgress() -> Double { + if let activeAccount = getActiveAccount(), activeAccount.quotaRelative > 0 { + return activeAccount.quotaRelative/100.0 + } + return 0 + } + + private func getActiveAccount() -> tableAccount? { + return self.database.getTableAccount(predicate: NSPredicate(format: "account == %@", session.account)) + } +} diff --git a/iOSClient/Colors.xcassets/AppBackground/Color.colorset/Contents.json b/iOSClient/Colors.xcassets/AppBackground/Color.colorset/Contents.json new file mode 100644 index 0000000000..92ef031708 --- /dev/null +++ b/iOSClient/Colors.xcassets/AppBackground/Color.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/AppBackground/Contents.json b/iOSClient/Colors.xcassets/AppBackground/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/AppBackground/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/AppBackground/DataProtection.colorset/Contents.json b/iOSClient/Colors.xcassets/AppBackground/DataProtection.colorset/Contents.json new file mode 100644 index 0000000000..ba531aa92c --- /dev/null +++ b/iOSClient/Colors.xcassets/AppBackground/DataProtection.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2B", + "green" : "0x10", + "red" : "0x02" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/AppBackground/Form.colorset/Contents.json b/iOSClient/Colors.xcassets/AppBackground/Form.colorset/Contents.json new file mode 100644 index 0000000000..58fea2e6e4 --- /dev/null +++ b/iOSClient/Colors.xcassets/AppBackground/Form.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0xF5", + "red" : "0xF2" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2B", + "green" : "0x10", + "red" : "0x02" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/AppBackground/FormRow.colorset/Contents.json b/iOSClient/Colors.xcassets/AppBackground/FormRow.colorset/Contents.json new file mode 100644 index 0000000000..30150f426c --- /dev/null +++ b/iOSClient/Colors.xcassets/AppBackground/FormRow.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/AppBackground/Main.colorset/Contents.json b/iOSClient/Colors.xcassets/AppBackground/Main.colorset/Contents.json new file mode 100644 index 0000000000..4eea21fecd --- /dev/null +++ b/iOSClient/Colors.xcassets/AppBackground/Main.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2B", + "green" : "0x10", + "red" : "0x02" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/Background.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/Background.colorset/Contents.json new file mode 100644 index 0000000000..9aae19efec --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "66", + "green" : "45", + "red" : "29" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/ButtonForeground.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/ButtonForeground.colorset/Contents.json new file mode 100644 index 0000000000..76547d8302 --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/ButtonForeground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/CommonShadow.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/CommonShadow.colorset/Contents.json new file mode 100644 index 0000000000..7e8f38fe3b --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/CommonShadow.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/NavigationBarButton.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/NavigationBarButton.colorset/Contents.json new file mode 100644 index 0000000000..76547d8302 --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/NavigationBarButton.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/Overlay.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/Overlay.colorset/Contents.json new file mode 100644 index 0000000000..01a011cad8 --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/Overlay.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.750", + "blue" : "28", + "green" : "18", + "red" : "10" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/PressedButton.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/PressedButton.colorset/Contents.json new file mode 100644 index 0000000000..f406f3e681 --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/PressedButton.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "232", + "green" : "226", + "red" : "219" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "96", + "green" : "67", + "red" : "46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/BurgerMenu/ProgressBarBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/BurgerMenu/ProgressBarBackground.colorset/Contents.json new file mode 100644 index 0000000000..ad3491157b --- /dev/null +++ b/iOSClient/Colors.xcassets/BurgerMenu/ProgressBarBackground.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD7", + "green" : "0xCD", + "red" : "0xBD" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Contents.json b/iOSClient/Colors.xcassets/Button/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Link/Contents.json b/iOSClient/Colors.xcassets/Button/Link/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Link/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Link/Text/Contents.json b/iOSClient/Colors.xcassets/Button/Link/Text/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Link/Text/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Link/Text/Disabled.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Link/Text/Disabled.colorset/Contents.json new file mode 100644 index 0000000000..86fcec9584 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Link/Text/Disabled.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Link/Text/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Link/Text/Normal.colorset/Contents.json new file mode 100644 index 0000000000..9a25e29b6a --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Link/Text/Normal.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD6", + "green" : "0x96", + "red" : "0x31" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Link/Text/Selected.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Link/Text/Selected.colorset/Contents.json new file mode 100644 index 0000000000..9ac2a3ca03 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Link/Text/Selected.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB1", + "green" : "0x5B", + "red" : "0x09" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEB", + "green" : "0xCA", + "red" : "0x95" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Background/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Background/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Background/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Background/Disabled.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Background/Disabled.colorset/Contents.json new file mode 100644 index 0000000000..15ed672f08 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Background/Disabled.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Background/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Background/Normal.colorset/Contents.json new file mode 100644 index 0000000000..7507e897dc --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Background/Normal.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x63", + "green" : "0x2A", + "red" : "0x0B" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Background/Selected.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Background/Selected.colorset/Contents.json new file mode 100644 index 0000000000..0235ade8e3 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Background/Selected.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB1", + "green" : "0x5B", + "red" : "0x09" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Text/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Text/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Text/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Text/Disabled.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Text/Disabled.colorset/Contents.json new file mode 100644 index 0000000000..6a5b0cbede --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Text/Disabled.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Text/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Text/Normal.colorset/Contents.json new file mode 100644 index 0000000000..fafa476721 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Text/Normal.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Primary/Text/Selected.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Primary/Text/Selected.colorset/Contents.json new file mode 100644 index 0000000000..fafa476721 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Primary/Text/Selected.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Background/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Background/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Background/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Background/Disabled.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Background/Disabled.colorset/Contents.json new file mode 100644 index 0000000000..0ffe309025 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Background/Disabled.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Background/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Background/Normal.colorset/Contents.json new file mode 100644 index 0000000000..05df57f13c --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Background/Normal.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Background/Selected.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Background/Selected.colorset/Contents.json new file mode 100644 index 0000000000..76547d8302 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Background/Selected.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Border/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Border/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Border/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Border/Disabled.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Border/Disabled.colorset/Contents.json new file mode 100644 index 0000000000..86fcec9584 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Border/Disabled.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Border/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Border/Normal.colorset/Contents.json new file mode 100644 index 0000000000..43e189b930 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Border/Normal.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x63", + "green" : "0x2A", + "red" : "0x0B" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Text/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Text/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Text/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Text/Disabled.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Text/Disabled.colorset/Contents.json new file mode 100644 index 0000000000..86fcec9584 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Text/Disabled.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Text/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Text/Normal.colorset/Contents.json new file mode 100644 index 0000000000..19d79bc389 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Text/Normal.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x63", + "green" : "0x2A", + "red" : "0x0B" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Button/Secondary/Text/Selected.colorset/Contents.json b/iOSClient/Colors.xcassets/Button/Secondary/Text/Selected.colorset/Contents.json new file mode 100644 index 0000000000..3372dfac60 --- /dev/null +++ b/iOSClient/Colors.xcassets/Button/Secondary/Text/Selected.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x63", + "green" : "0x2A", + "red" : "0x0B" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/Background.colorset/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/Background.colorset/Contents.json new file mode 100644 index 0000000000..5e94fd9c0b --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/ImageTypeBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/ImageTypeBackground.colorset/Contents.json new file mode 100644 index 0000000000..9e7da42377 --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/ImageTypeBackground.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x95", + "green" : "0x80", + "red" : "0x71" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/ImageTypeText.colorset/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/ImageTypeText.colorset/Contents.json new file mode 100644 index 0000000000..fafa476721 --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/ImageTypeText.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/Text.colorset/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/Text.colorset/Contents.json new file mode 100644 index 0000000000..dd438e4fd3 --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/Text.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/TitleBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/TitleBackground.colorset/Contents.json new file mode 100644 index 0000000000..d7f5932ec0 --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/TitleBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD4", + "green" : "0xC8", + "red" : "0xBC" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/CameraInformation/TitleText.colorset/Contents.json b/iOSClient/Colors.xcassets/CameraInformation/TitleText.colorset/Contents.json new file mode 100644 index 0000000000..fb688699e8 --- /dev/null +++ b/iOSClient/Colors.xcassets/CameraInformation/TitleText.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Contents.json b/iOSClient/Colors.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/iOSClient/Colors.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/DataProtection/Contents.json b/iOSClient/Colors.xcassets/DataProtection/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/DataProtection/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/DataProtection/Link.colorset/Contents.json b/iOSClient/Colors.xcassets/DataProtection/Link.colorset/Contents.json new file mode 100644 index 0000000000..42e6d8fe13 --- /dev/null +++ b/iOSClient/Colors.xcassets/DataProtection/Link.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD6", + "green" : "0x96", + "red" : "0x31" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/DataProtection/ListRow.colorset/Contents.json b/iOSClient/Colors.xcassets/DataProtection/ListRow.colorset/Contents.json new file mode 100644 index 0000000000..4eea21fecd --- /dev/null +++ b/iOSClient/Colors.xcassets/DataProtection/ListRow.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2B", + "green" : "0x10", + "red" : "0x02" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/DataProtection/ListRowSubtitle.colorset/Contents.json b/iOSClient/Colors.xcassets/DataProtection/ListRowSubtitle.colorset/Contents.json new file mode 100644 index 0000000000..d9e6ba9b68 --- /dev/null +++ b/iOSClient/Colors.xcassets/DataProtection/ListRowSubtitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x95", + "green" : "0x80", + "red" : "0x71" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/DataProtection/ListSeparator.colorset/Contents.json b/iOSClient/Colors.xcassets/DataProtection/ListSeparator.colorset/Contents.json new file mode 100644 index 0000000000..86fcec9584 --- /dev/null +++ b/iOSClient/Colors.xcassets/DataProtection/ListSeparator.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/DataProtection/NavigationBarTint.colorset/Contents.json b/iOSClient/Colors.xcassets/DataProtection/NavigationBarTint.colorset/Contents.json new file mode 100644 index 0000000000..76547d8302 --- /dev/null +++ b/iOSClient/Colors.xcassets/DataProtection/NavigationBarTint.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/DestructiveAction.colorset/Contents.json b/iOSClient/Colors.xcassets/DestructiveAction.colorset/Contents.json new file mode 100644 index 0000000000..6a76417301 --- /dev/null +++ b/iOSClient/Colors.xcassets/DestructiveAction.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0x59", + "green" : "0x61", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileActionsHeader/ButtonTint.colorset/Contents.json b/iOSClient/Colors.xcassets/FileActionsHeader/ButtonTint.colorset/Contents.json new file mode 100644 index 0000000000..23d70e9bc1 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileActionsHeader/ButtonTint.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "65", + "green" : "27", + "red" : "0" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "250", + "green" : "247", + "red" : "244" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileActionsHeader/Contents.json b/iOSClient/Colors.xcassets/FileActionsHeader/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/FileActionsHeader/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/FileActionsHeader/GrayButtonTint.colorset/Contents.json b/iOSClient/Colors.xcassets/FileActionsHeader/GrayButtonTint.colorset/Contents.json new file mode 100644 index 0000000000..7357195116 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileActionsHeader/GrayButtonTint.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "149", + "green" : "128", + "red" : "113" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "212", + "green" : "200", + "red" : "188" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeButtonBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeButtonBackground.colorset/Contents.json new file mode 100644 index 0000000000..60f618d19a --- /dev/null +++ b/iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeButtonBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "232", + "green" : "226", + "red" : "219" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "66", + "green" : "45", + "red" : "29" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeHeaderBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeHeaderBackground.colorset/Contents.json new file mode 100644 index 0000000000..7aaba07537 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeHeaderBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "250", + "green" : "247", + "red" : "244" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "66", + "green" : "45", + "red" : "29" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileActionsHeader/SortButtonText.colorset/Contents.json b/iOSClient/Colors.xcassets/FileActionsHeader/SortButtonText.colorset/Contents.json new file mode 100644 index 0000000000..9565e80856 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileActionsHeader/SortButtonText.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "65", + "green" : "27", + "red" : "0" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "232", + "green" : "226", + "red" : "219" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/Background.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/Background.colorset/Contents.json new file mode 100644 index 0000000000..bef5b1fb34 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0xF5", + "red" : "0xF2" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/Contents.json b/iOSClient/Colors.xcassets/FileMenu/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/FolderIcon.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/FolderIcon.colorset/Contents.json new file mode 100644 index 0000000000..3186f64eac --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/FolderIcon.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/Grabber.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/Grabber.colorset/Contents.json new file mode 100644 index 0000000000..28362f57e7 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/Grabber.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC2", + "green" : "0xC4", + "red" : "0xC2" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD4", + "green" : "0xC8", + "red" : "0xBC" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/Icon.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/Icon.colorset/Contents.json new file mode 100644 index 0000000000..3dc78f800a --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/Icon.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "250", + "green" : "247", + "red" : "244" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/Overlay.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/Overlay.colorset/Contents.json new file mode 100644 index 0000000000..90aa6236f8 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/Overlay.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.200", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.500", + "blue" : "0x1C", + "green" : "0x12", + "red" : "0x0A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/SelectedRow.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/SelectedRow.colorset/Contents.json new file mode 100644 index 0000000000..67e578b81e --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/SelectedRow.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0xD6", + "green" : "0xD1", + "red" : "0xD1" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileMenu/Text.colorset/Contents.json b/iOSClient/Colors.xcassets/FileMenu/Text.colorset/Contents.json new file mode 100644 index 0000000000..6fc4297bd8 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileMenu/Text.colorset/Contents.json @@ -0,0 +1,36 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "extended-gray", + "components" : { + "alpha" : "1.000", + "white" : "0.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/FileSelection/Contents.json b/iOSClient/Colors.xcassets/FileSelection/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/FileSelection/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/FileSelection/list_item_deselected.colorset/Contents.json b/iOSClient/Colors.xcassets/FileSelection/list_item_deselected.colorset/Contents.json new file mode 100644 index 0000000000..a06d3338c8 --- /dev/null +++ b/iOSClient/Colors.xcassets/FileSelection/list_item_deselected.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x95", + "green" : "0x80", + "red" : "0x71" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD4", + "green" : "0xC8", + "red" : "0xBC" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/ListCell/Contents.json b/iOSClient/Colors.xcassets/ListCell/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/ListCell/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/ListCell/Separator.colorset/Contents.json b/iOSClient/Colors.xcassets/ListCell/Separator.colorset/Contents.json new file mode 100644 index 0000000000..531e0c9336 --- /dev/null +++ b/iOSClient/Colors.xcassets/ListCell/Separator.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/ListCell/Subtitle.colorset/Contents.json b/iOSClient/Colors.xcassets/ListCell/Subtitle.colorset/Contents.json new file mode 100644 index 0000000000..1d45457642 --- /dev/null +++ b/iOSClient/Colors.xcassets/ListCell/Subtitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD4", + "green" : "0xC8", + "red" : "0xBC" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/ListCell/Title.colorset/Contents.json b/iOSClient/Colors.xcassets/ListCell/Title.colorset/Contents.json new file mode 100644 index 0000000000..cfbec998e7 --- /dev/null +++ b/iOSClient/Colors.xcassets/ListCell/Title.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/MediaPlayer/Contents.json b/iOSClient/Colors.xcassets/MediaPlayer/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/MediaPlayer/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/MediaPlayer/IconTint.colorset/Contents.json b/iOSClient/Colors.xcassets/MediaPlayer/IconTint.colorset/Contents.json new file mode 100644 index 0000000000..0e8d7fe21a --- /dev/null +++ b/iOSClient/Colors.xcassets/MediaPlayer/IconTint.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/MediaPlayer/SliderMaxColor.colorset/Contents.json b/iOSClient/Colors.xcassets/MediaPlayer/SliderMaxColor.colorset/Contents.json new file mode 100644 index 0000000000..531e0c9336 --- /dev/null +++ b/iOSClient/Colors.xcassets/MediaPlayer/SliderMaxColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/MediaPlayer/SliderMinColor.colorset/Contents.json b/iOSClient/Colors.xcassets/MediaPlayer/SliderMinColor.colorset/Contents.json new file mode 100644 index 0000000000..4f15531cb5 --- /dev/null +++ b/iOSClient/Colors.xcassets/MediaPlayer/SliderMinColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0xF5", + "red" : "0xF2" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/MediaPlayer/SliderThumb.colorset/Contents.json b/iOSClient/Colors.xcassets/MediaPlayer/SliderThumb.colorset/Contents.json new file mode 100644 index 0000000000..0e8d7fe21a --- /dev/null +++ b/iOSClient/Colors.xcassets/MediaPlayer/SliderThumb.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/NavigationBar/Contents.json b/iOSClient/Colors.xcassets/NavigationBar/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/NavigationBar/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/NavigationBar/LogoTint.colorset/Contents.json b/iOSClient/Colors.xcassets/NavigationBar/LogoTint.colorset/Contents.json new file mode 100644 index 0000000000..4d53e40479 --- /dev/null +++ b/iOSClient/Colors.xcassets/NavigationBar/LogoTint.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x8F", + "green" : "0x3D", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/QualitySlider/Contents.json b/iOSClient/Colors.xcassets/QualitySlider/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/QualitySlider/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/QualitySlider/MaximumTrackColor.colorset/Contents.json b/iOSClient/Colors.xcassets/QualitySlider/MaximumTrackColor.colorset/Contents.json new file mode 100644 index 0000000000..f24bfec494 --- /dev/null +++ b/iOSClient/Colors.xcassets/QualitySlider/MaximumTrackColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD4", + "green" : "0xC8", + "red" : "0xBC" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/QualitySlider/ThumbColor.colorset/Contents.json b/iOSClient/Colors.xcassets/QualitySlider/ThumbColor.colorset/Contents.json new file mode 100644 index 0000000000..1126a18b0a --- /dev/null +++ b/iOSClient/Colors.xcassets/QualitySlider/ThumbColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x63", + "green" : "0x2A", + "red" : "0x0B" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/SearchBarBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/SearchBarBackground.colorset/Contents.json new file mode 100644 index 0000000000..3897a6cbc8 --- /dev/null +++ b/iOSClient/Colors.xcassets/SearchBarBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x3F", + "green" : "0x28", + "red" : "0x1E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/SelectToolbar/CancelTint.colorset/Contents.json b/iOSClient/Colors.xcassets/SelectToolbar/CancelTint.colorset/Contents.json new file mode 100644 index 0000000000..9565e80856 --- /dev/null +++ b/iOSClient/Colors.xcassets/SelectToolbar/CancelTint.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "65", + "green" : "27", + "red" : "0" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "232", + "green" : "226", + "red" : "219" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/SelectToolbar/Contents.json b/iOSClient/Colors.xcassets/SelectToolbar/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/SelectToolbar/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/SelectToolbar/ItemStateActive.colorset/Contents.json b/iOSClient/Colors.xcassets/SelectToolbar/ItemStateActive.colorset/Contents.json new file mode 100644 index 0000000000..d6fad5c4ad --- /dev/null +++ b/iOSClient/Colors.xcassets/SelectToolbar/ItemStateActive.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/SelectToolbar/ItemStateInactive.colorset/Contents.json b/iOSClient/Colors.xcassets/SelectToolbar/ItemStateInactive.colorset/Contents.json new file mode 100644 index 0000000000..3ff1badcaa --- /dev/null +++ b/iOSClient/Colors.xcassets/SelectToolbar/ItemStateInactive.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x95", + "green" : "0x80", + "red" : "0x71" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/SelectToolbar/ItemStateSelected.colorset/Contents.json b/iOSClient/Colors.xcassets/SelectToolbar/ItemStateSelected.colorset/Contents.json new file mode 100644 index 0000000000..0c6a3dd673 --- /dev/null +++ b/iOSClient/Colors.xcassets/SelectToolbar/ItemStateSelected.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "66", + "green" : "45", + "red" : "29" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Background.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Background.colorset/Contents.json new file mode 100644 index 0000000000..03baf522f9 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFE" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundHighlighted.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundHighlighted.colorset/Contents.json new file mode 100644 index 0000000000..c07aaad39c --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundHighlighted.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundNormal.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundNormal.colorset/Contents.json new file mode 100644 index 0000000000..30150f426c --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundNormal.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Cell/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Cell/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Cell/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Cell/Subtitle.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Cell/Subtitle.colorset/Contents.json new file mode 100644 index 0000000000..a3de7b2175 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Cell/Subtitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.600", + "blue" : "0.260", + "green" : "0.240", + "red" : "0.240" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Cell/Title.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Cell/Title.colorset/Contents.json new file mode 100644 index 0000000000..ffaecd67bf --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Cell/Title.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Border.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Border.colorset/Contents.json new file mode 100644 index 0000000000..cbd99b7e21 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Border.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Placeholder.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Placeholder.colorset/Contents.json new file mode 100644 index 0000000000..15dc7557b6 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/SearchField/Placeholder.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/SectionTitle.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/SectionTitle.colorset/Contents.json new file mode 100644 index 0000000000..306a907c82 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/SectionTitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.600", + "blue" : "0.260", + "green" : "0.240", + "red" : "0.240" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/SectionTitleBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/SectionTitleBackground.colorset/Contents.json new file mode 100644 index 0000000000..d6e3b6e7e5 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/SectionTitleBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Advanced/TableCellSeparator.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Advanced/TableCellSeparator.colorset/Contents.json new file mode 100644 index 0000000000..a3fbad6780 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Advanced/TableCellSeparator.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.290", + "blue" : "0.260", + "green" : "0.240", + "red" : "0.240" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x95", + "green" : "0x80", + "red" : "0x71" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Comment/Contents.json b/iOSClient/Colors.xcassets/Share/Comment/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Comment/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/Comment/TextFieldBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Comment/TextFieldBackground.colorset/Contents.json new file mode 100644 index 0000000000..4f7da9b2d6 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Comment/TextFieldBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.970", + "green" : "0.950", + "red" : "0.950" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Comment/TextFieldBorder.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/Comment/TextFieldBorder.colorset/Contents.json new file mode 100644 index 0000000000..a6dfb502b0 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Comment/TextFieldBorder.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFE" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/CommonIconTint.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/CommonIconTint.colorset/Contents.json new file mode 100644 index 0000000000..9a25e29b6a --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/CommonIconTint.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD6", + "green" : "0x96", + "red" : "0x31" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/Contents.json b/iOSClient/Colors.xcassets/Share/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Contents.json b/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Normal.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Normal.colorset/Contents.json new file mode 100644 index 0000000000..30150f426c --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Normal.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Pressed.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Pressed.colorset/Contents.json new file mode 100644 index 0000000000..5c46b8d208 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Pressed.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE3", + "green" : "0xE3", + "red" : "0xE3" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x60", + "green" : "0x43", + "red" : "0x2E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/SearchUserCell/Contents.json b/iOSClient/Colors.xcassets/Share/SearchUserCell/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/SearchUserCell/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Share/SearchUserCell/Title.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/SearchUserCell/Title.colorset/Contents.json new file mode 100644 index 0000000000..49c5cc3eb9 --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/SearchUserCell/Title.colorset/Contents.json @@ -0,0 +1,36 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "gray-gamma-22", + "components" : { + "alpha" : "1.000", + "white" : "0.330" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/SearchUserCell/UserType.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/SearchUserCell/UserType.colorset/Contents.json new file mode 100644 index 0000000000..ffaecd67bf --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/SearchUserCell/UserType.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Share/TabTitle.colorset/Contents.json b/iOSClient/Colors.xcassets/Share/TabTitle.colorset/Contents.json new file mode 100644 index 0000000000..86b9080fbc --- /dev/null +++ b/iOSClient/Colors.xcassets/Share/TabTitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0xE2", + "red" : "0xDB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Tabbar/ActiveItem.colorset/Contents.json b/iOSClient/Colors.xcassets/Tabbar/ActiveItem.colorset/Contents.json new file mode 100644 index 0000000000..78a4c616b5 --- /dev/null +++ b/iOSClient/Colors.xcassets/Tabbar/ActiveItem.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEB", + "green" : "0xCA", + "red" : "0x95" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Tabbar/Background.colorset/Contents.json b/iOSClient/Colors.xcassets/Tabbar/Background.colorset/Contents.json new file mode 100644 index 0000000000..d1aea6fe2d --- /dev/null +++ b/iOSClient/Colors.xcassets/Tabbar/Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF7", + "red" : "0xF4" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x42", + "green" : "0x2D", + "red" : "0x1D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Tabbar/Contents.json b/iOSClient/Colors.xcassets/Tabbar/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Tabbar/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Tabbar/FabButton.colorset/Contents.json b/iOSClient/Colors.xcassets/Tabbar/FabButton.colorset/Contents.json new file mode 100644 index 0000000000..168cfbf5b3 --- /dev/null +++ b/iOSClient/Colors.xcassets/Tabbar/FabButton.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x8F", + "green" : "0x3D", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC4", + "green" : "0x74", + "red" : "0x14" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Tabbar/InactiveItem.colorset/Contents.json b/iOSClient/Colors.xcassets/Tabbar/InactiveItem.colorset/Contents.json new file mode 100644 index 0000000000..d6fad5c4ad --- /dev/null +++ b/iOSClient/Colors.xcassets/Tabbar/InactiveItem.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xA3", + "red" : "0x97" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Transfers/ButtonBackground.colorset/Contents.json b/iOSClient/Colors.xcassets/Transfers/ButtonBackground.colorset/Contents.json new file mode 100644 index 0000000000..a50911a940 --- /dev/null +++ b/iOSClient/Colors.xcassets/Transfers/ButtonBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xBE", + "green" : "0x72", + "red" : "0x36" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD1", + "green" : "0x94", + "red" : "0x50" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Transfers/Cell/Contents.json b/iOSClient/Colors.xcassets/Transfers/Cell/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Transfers/Cell/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/Transfers/Cell/Subtitle.colorset/Contents.json b/iOSClient/Colors.xcassets/Transfers/Cell/Subtitle.colorset/Contents.json new file mode 100644 index 0000000000..8c8c693a3e --- /dev/null +++ b/iOSClient/Colors.xcassets/Transfers/Cell/Subtitle.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x75", + "green" : "0x5A", + "red" : "0x46" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFE" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Transfers/Cell/Title.colorset/Contents.json b/iOSClient/Colors.xcassets/Transfers/Cell/Title.colorset/Contents.json new file mode 100644 index 0000000000..a07820a935 --- /dev/null +++ b/iOSClient/Colors.xcassets/Transfers/Cell/Title.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x41", + "green" : "0x1B", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFE" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/Transfers/Contents.json b/iOSClient/Colors.xcassets/Transfers/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/Transfers/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/UserButton/Background.colorset/Contents.json b/iOSClient/Colors.xcassets/UserButton/Background.colorset/Contents.json new file mode 100644 index 0000000000..788f7540b3 --- /dev/null +++ b/iOSClient/Colors.xcassets/UserButton/Background.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "244", + "green" : "236", + "red" : "245" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/UserButton/Contents.json b/iOSClient/Colors.xcassets/UserButton/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/Colors.xcassets/UserButton/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/Colors.xcassets/UserButton/Tint.colorset/Contents.json b/iOSClient/Colors.xcassets/UserButton/Tint.colorset/Contents.json new file mode 100644 index 0000000000..b6b5c8a9ad --- /dev/null +++ b/iOSClient/Colors.xcassets/UserButton/Tint.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "153", + "green" : "77", + "red" : "169" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Colors.xcassets/formSeparator.colorset/Contents.json b/iOSClient/Colors.xcassets/formSeparator.colorset/Contents.json new file mode 100644 index 0000000000..965cbd969a --- /dev/null +++ b/iOSClient/Colors.xcassets/formSeparator.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xDD", + "green" : "0xDD", + "red" : "0xDD" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Components/Buttons/ButtonStyleGuide.swift b/iOSClient/Components/Buttons/ButtonStyleGuide.swift new file mode 100644 index 0000000000..2ee4bbf8f8 --- /dev/null +++ b/iOSClient/Components/Buttons/ButtonStyleGuide.swift @@ -0,0 +1,208 @@ +// +// ButtonStyleGuide.swift +// Nextcloud +// +// Created by Vitaliy Tolkach on 13.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +// MARK: - Primary +struct ButtonStylePrimary: ButtonStyle { + @Environment(\.isEnabled) private var isEnabled: Bool + + var maxWidth: CGFloat? = nil + + private func foregroundColor(for configuration: Configuration) -> Color { + isEnabled ? Color(.Button.Primary.Text.normal): Color(.Button.Primary.Text.disabled) + } + + private func backgroundColor(for configuration: Configuration) -> Color { + if isEnabled { + return configuration.isPressed ? Color(.Button.Primary.Background.selected) : Color(.Button.Primary.Background.normal) + } + return Color(.Button.Primary.Background.disabled) + } + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(CommonButtonConstants.defaultFont) + .frame(maxWidth: maxWidth, + minHeight: CommonButtonConstants.defaultHeight) + .padding([.leading, .trailing], 24) + .foregroundStyle(foregroundColor(for: configuration)) + .background{ + Capsule(style: .circular) + .stroke(backgroundColor(for: configuration), lineWidth: CommonButtonConstants.defaultBorderWidth) + .background(content: { + Capsule().fill(backgroundColor(for: configuration)) + }) + } + } +} + +extension ButtonStyle where Self == ButtonStylePrimary { + static var primary: Self { + return .init() + } +} + +// MARK: - Secondary +struct ButtonStyleSecondary: ButtonStyle { + @Environment(\.isEnabled) private var isEnabled: Bool + + var maxWidth: CGFloat? = nil + + private func foregroundColor(for configuration: Configuration) -> Color { + if isEnabled { + return configuration.isPressed ? Color(.Button.Secondary.Text.selected) : Color(.Button.Secondary.Text.normal) + } + return Color(.Button.Secondary.Text.disabled) + } + + private func borderColor(for configuration: Configuration) -> Color { + isEnabled ? Color(.Button.Secondary.Border.normal) : Color(.Button.Secondary.Border.disabled) + } + + private func backgroundColor(for configuration: Configuration) -> Color { + configuration.isPressed ? Color(.Button.Secondary.Background.selected) : Color(.Button.Secondary.Background.normal) + } + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(CommonButtonConstants.defaultFont) + .frame(maxWidth: maxWidth, + minHeight: CommonButtonConstants.defaultHeight) + .padding([.leading, .trailing], 24) + .foregroundStyle(foregroundColor(for: configuration)) + .background{ + Capsule(style: .circular) + .stroke(borderColor(for: configuration), lineWidth: CommonButtonConstants.defaultBorderWidth) + .background(content: { + Capsule().fill(backgroundColor(for: configuration)) + }) + } + .makeAllButtonSpaceTappable() + } +} + +private extension View { + func makeAllButtonSpaceTappable() -> some View { + self.contentShape(Rectangle()) + } +} + +extension ButtonStyle where Self == ButtonStyleSecondary { + static var secondary: Self { + return .init() + } +} + +// MARK SaveButtonStyle +struct SaveButtonStyle: ButtonStyle { + @Environment(\.isEnabled) private var isEnabled: Bool + + var maxWidth: CGFloat? = nil + + private func foregroundColor(for configuration: Configuration) -> Color { + isEnabled ? Color(.Button.Primary.Text.normal) : Color(.Button.Primary.Text.disabled) + } + + private func backgroundColor(for configuration: Configuration) -> Color { + isEnabled ? Color(.Button.Primary.Background.selected) : Color(.Button.Primary.Background.disabled) + } + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(CommonButtonConstants.defaultFont) + .frame(maxWidth: maxWidth, + minHeight: CommonButtonConstants.defaultHeight) + .padding([.leading, .trailing], 24) + .foregroundStyle(foregroundColor(for: configuration)) + .background{ + Capsule(style: .circular) + .stroke(backgroundColor(for: configuration), lineWidth: CommonButtonConstants.defaultBorderWidth) + .background(content: { + Capsule().fill(backgroundColor(for: configuration)) + }) + } + } +} + +extension ButtonStyle where Self == SaveButtonStyle { + static var saveButton: Self { + return .init() + } +} + +#Preview { + VStack(spacing: 30) { + VStack { + Button { + } label: { + Text("Primary default state") + } + .buttonStyle(.primary) + + Button { + } label: { + Text("Primary disabled state") + } + .buttonStyle(.primary) + .disabled(true) + + Spacer() + .frame(height: 30) + + Button { + } label: { + Text("Secondary default state") + } + .buttonStyle(.secondary) + + Button { + } label: { + Text("Secondary disabled state") + } + .buttonStyle(.secondary) + .disabled(true) + } + .frame(width: 300, height: 300) + .background(Color(.AppBackground.main)) + .environment(\.colorScheme, .light) + VStack { + Button { + } label: { + Text("Primary default state") + } + .buttonStyle(.primary) + + Button { + } label: { + Text("Primary disabled state") + } + .buttonStyle(.primary) + .disabled(true) + + Spacer() + .frame(height: 30) + + Button { + } label: { + Text("Secondary default state") + } + .buttonStyle(.secondary) + + Button { + } label: { + Text("Secondary disabled state") + } + .buttonStyle(.secondary) + .disabled(true) + } + .frame(width: 300, height: 300) + .background(Color(.AppBackground.main)) + .environment(\.colorScheme, .dark) + } +} diff --git a/iOSClient/Components/Buttons/CommonButtonConstants.swift b/iOSClient/Components/Buttons/CommonButtonConstants.swift new file mode 100644 index 0000000000..370204bb0f --- /dev/null +++ b/iOSClient/Components/Buttons/CommonButtonConstants.swift @@ -0,0 +1,23 @@ +// +// CommonButtonConstants.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 23.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import Foundation +import SwiftUI + +enum CommonButtonConstants { + static let defaultFont: Font = .system(size: 14, weight: .semibold) + static let defaultUIFont: UIFont = .systemFont(ofSize: 14, weight: .semibold) + + static let defaultBorderWidth: CGFloat = 2.0 + + static let intrinsicContentSize: CGSize = .init(width: defaultWidth, height: defaultHeight) + static let defaultHeight: CGFloat = 48 + static var defaultWidth: CGFloat { + UIDevice.current.userInterfaceIdiom == .phone ? 100 : 240 + } +} diff --git a/iOSClient/Components/Buttons/LinkButton.swift b/iOSClient/Components/Buttons/LinkButton.swift new file mode 100644 index 0000000000..f6fb0f2158 --- /dev/null +++ b/iOSClient/Components/Buttons/LinkButton.swift @@ -0,0 +1,50 @@ +// +// LinkButton.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 26.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import UIKit + +class LinkButton: UIButton { + override func awakeFromNib() { + super.awakeFromNib() + + titleLabel?.font = .systemFont(ofSize: 16, weight: .semibold) + backgroundColor = .clear + updateApperance() + } + + override var intrinsicContentSize: CGSize { + return CommonButtonConstants.intrinsicContentSize + } + + override public var isEnabled: Bool { + didSet { + updateApperance() + } + } + + override open var isHighlighted: Bool { + didSet { + updateApperance() + } + } + + private func updateApperance() { + setTitleColor(titleColor(), for: .normal) + } + + private func titleColor() -> UIColor { + guard isEnabled else { + return UIColor(resource: .Button.Link.Text.disabled) + } + if isHighlighted { + return UIColor(resource: .Button.Link.Text.selected) + } + return UIColor(resource: .Button.Link.Text.normal) + } + +} diff --git a/iOSClient/Components/Buttons/PrimaryButton.swift b/iOSClient/Components/Buttons/PrimaryButton.swift new file mode 100644 index 0000000000..dd18446e15 --- /dev/null +++ b/iOSClient/Components/Buttons/PrimaryButton.swift @@ -0,0 +1,67 @@ +// +// PrimaryButton.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 20.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import UIKit + +class PrimaryButton: UIButton { + + override func awakeFromNib() { + super.awakeFromNib() + + layer.masksToBounds = true + updateApperance() + titleLabel?.font = CommonButtonConstants.defaultUIFont + } + + override var intrinsicContentSize: CGSize { + return CommonButtonConstants.intrinsicContentSize + } + + override public var isEnabled: Bool { + didSet { + updateApperance() + } + } + + override open var isHighlighted: Bool { + didSet { + updateApperance() + } + } + + override func layoutSubviews() { + layer.cornerRadius = bounds.height/2.0 + super.layoutSubviews() + } + + private func updateApperance() { + setTitleColor(titleColor(), for: .normal) + backgroundColor = backgroundColor() + } + + private func backgroundColor() -> UIColor { + guard isEnabled else { + return UIColor(resource: .Button.Primary.Background.disabled) + } + if isHighlighted { + return UIColor(resource: .Button.Primary.Background.selected) + } + return UIColor(resource: .Button.Primary.Background.normal) + } + + private func titleColor() -> UIColor { + guard isEnabled else { + return UIColor(resource: .Button.Primary.Text.disabled) + } + if isHighlighted { + return UIColor(resource: .Button.Primary.Text.selected) + } + return UIColor(resource: .Button.Primary.Text.normal) + } +} + diff --git a/iOSClient/Components/Buttons/SecondaryButton.swift b/iOSClient/Components/Buttons/SecondaryButton.swift new file mode 100644 index 0000000000..73a400dea3 --- /dev/null +++ b/iOSClient/Components/Buttons/SecondaryButton.swift @@ -0,0 +1,82 @@ +// +// SecondaryButton.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 23.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import UIKit + +class SecondaryButton: UIButton { + + override func awakeFromNib() { + super.awakeFromNib() + + layer.masksToBounds = true + layer.borderWidth = CommonButtonConstants.defaultBorderWidth + + updateApperance() + + titleLabel?.font = CommonButtonConstants.defaultUIFont + } + + override var intrinsicContentSize: CGSize { + return CommonButtonConstants.intrinsicContentSize + } + + override public var isEnabled: Bool { + didSet { + updateApperance() + } + } + + override open var isHighlighted: Bool { + didSet { + updateApperance() + } + } + + override func layoutSubviews() { + layer.cornerRadius = bounds.height/2.0 + super.layoutSubviews() + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) { + updateApperance() + } + } + + private func updateApperance() { + setTitleColor(titleColor(), for: .normal) + backgroundColor = backgroundColor() + layer.borderColor = borderColor() + tintColor = titleColor() + } + + private func borderColor() -> CGColor { + return UIColor(resource: isEnabled ? .Button.Secondary.Border.normal : .Button.Secondary.Border.disabled).resolvedColor(with: self.traitCollection).cgColor + } + + private func backgroundColor() -> UIColor { + guard isEnabled else { + return UIColor(resource: .Button.Secondary.Background.disabled) + } + if isHighlighted { + return UIColor(resource: .Button.Secondary.Background.selected) + } + return UIColor(resource: .Button.Secondary.Background.normal) + } + + private func titleColor() -> UIColor { + guard isEnabled else { + return UIColor(resource: .Button.Secondary.Text.disabled) + } + if isHighlighted { + return UIColor(resource: .Button.Secondary.Text.selected) + } + return UIColor(resource: .Button.Secondary.Text.normal) + } +} diff --git a/iOSClient/Data/NCManageDatabase+Metadata.swift b/iOSClient/Data/NCManageDatabase+Metadata.swift index 8436ac37d3..3b118ef461 100644 --- a/iOSClient/Data/NCManageDatabase+Metadata.swift +++ b/iOSClient/Data/NCManageDatabase+Metadata.swift @@ -170,6 +170,10 @@ extension tableMetadata { var isImage: Bool { return classFile == NKTypeClassFile.image.rawValue } + + var isURL: Bool { + return classFile == NKTypeClassFile.url.rawValue + } var isSavebleAsImage: Bool { classFile == NKTypeClassFile.image.rawValue && contentType != "image/svg+xml" diff --git a/iOSClient/Data/NCManageDatabase+Video.swift b/iOSClient/Data/NCManageDatabase+Video.swift index 74e4ab9592..804003e388 100644 --- a/iOSClient/Data/NCManageDatabase+Video.swift +++ b/iOSClient/Data/NCManageDatabase+Video.swift @@ -29,7 +29,7 @@ extension NCManageDatabase { // MARK: - Realm write - func addVideo(metadata: tableMetadata, position: Float? = nil, width: Int? = nil, height: Int? = nil, length: Int? = nil, currentAudioTrackIndex: Int? = nil, currentVideoSubTitleIndex: Int? = nil) { + func addVideoOrAudio(metadata: tableMetadata, position: Float? = nil, width: Int? = nil, height: Int? = nil, length: Int? = nil, currentAudioTrackIndex: Int? = nil, currentVideoSubTitleIndex: Int? = nil) { if metadata.isLivePhoto { return } core.performRealmWrite { realm in @@ -81,7 +81,7 @@ extension NCManageDatabase { } } - func deleteVideoAsync(_ ocId: String) async { + func deleteVideoOrAudioAsync(_ ocId: String) async { await core.performRealmWriteAsync { realm in if let result = realm.objects(tableVideo.self) .filter("ocId == %@", ocId) @@ -93,7 +93,7 @@ extension NCManageDatabase { // MARK: - Realm read - func getVideo(metadata: tableMetadata?) -> tableVideo? { + func getVideoOrAudio(metadata: tableMetadata?) -> tableVideo? { guard let metadata else { return nil } return core.performRealmRead { realm in diff --git a/iOSClient/DataProtection/DataProtectionAgreementManager.swift b/iOSClient/DataProtection/DataProtectionAgreementManager.swift new file mode 100644 index 0000000000..db95460893 --- /dev/null +++ b/iOSClient/DataProtection/DataProtectionAgreementManager.swift @@ -0,0 +1,144 @@ +// +// DataProtectionAgreementManager.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 27.11.2024. +// Copyright © 2024 STRATO GmbH +// + +import UIKit +import AppTrackingTransparency +import FirebaseAnalytics +import Firebase + +class DataProtectionAgreementManager { + private(set) static var shared = DataProtectionAgreementManager() + + private var rootViewController: UIViewController + + struct DataProtectionKeys { + static let agreementWasShown = "data_protection_agreement_was_shown" + } + + private init() { + rootViewController = DataProtectionHostingController(rootView: DataProtectionAgreementScreen()) + } + + func dismissView() { + guard Thread.current.isMainThread else { + return DispatchQueue.main.async { [weak self] in + self?.dismissView() + } + } + + rootViewController.dismiss(animated: false) { [weak self] in + self?.setupAnalyticsCollection() + } + } + + private func showPrivacyAgreementScreen(over viewController: UIViewController) { + guard Thread.current.isMainThread else { + return DispatchQueue.main.async { [weak self] in + self?.showPrivacyAgreementScreen(over: viewController) + } + } + + guard rootViewController.presentingViewController != viewController else { + return + } + + rootViewController = DataProtectionHostingController(rootView: DataProtectionAgreementScreen()) + rootViewController.modalPresentationStyle = .fullScreen + viewController.present(rootViewController, animated: false) + } + + func showAgreement(viewController: UIViewController) { + let wasAgreementShown = UserDefaults.standard.bool(forKey: DataProtectionKeys.agreementWasShown) + if !wasAgreementShown { + showPrivacyAgreementScreen(over: viewController) + } + } + + func setupAnalyticsCollection() { + let isAllowed = isAllowedAnalysisOfDataCollection() + Analytics.setAnalyticsCollectionEnabled(isAllowed) + Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(isAllowed) + } + + func acceptAgreement() { + agreementWasShown(true) + askForTrackingPermission { [weak self] _ in + self?.dismissView() + } + } + + func saveSettings() { + agreementWasShown(true) + dismissView() + } + + func rejectAgreement() { + agreementWasShown(true) + askForTrackingPermission { [weak self] granted in + if granted { + self?.redirectToSettings() + } else { + self?.dismissView() + } + } + } + + func onAccountCreated() { + agreementWasShown(false) + } + + private func agreementWasShown(_ wasShown: Bool) { + UserDefaults.standard.set(wasShown, forKey: DataProtectionKeys.agreementWasShown) + } + + func allowAnalysisOfDataCollection(_ allowAnalysisOfDataCollection: Bool, redirectToSettings: (() -> Void)?) { + askForTrackingPermission { granted in + if granted != allowAnalysisOfDataCollection { + redirectToSettings?() + } + } + } + + func isAllowedAnalysisOfDataCollection() -> Bool { + return ATTrackingManager.trackingAuthorizationStatus == .authorized + } + + private func askForTrackingPermission(completion: ((_ isPermissionGranted: Bool) -> Void)?) { + switch ATTrackingManager.trackingAuthorizationStatus { + case .notDetermined: handleNotDetermined(completion: completion) + case .authorized: completion?(true) + case .restricted, + .denied: completion?(false) + @unknown default: return + } + } + + private func handleNotDetermined(completion: ((_ isPermissionGranted: Bool) -> Void)?) { + ATTrackingManager.requestTrackingAuthorization { [weak self] _ in + self?.askForTrackingPermission(completion: completion) + } + } + + private func redirectToSettings() { + let alert = UIAlertController(title: NSLocalizedString("_alert_tracking_access", comment: ""), message: nil, preferredStyle: .alert) + + alert.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel, handler: { _ in })) + + alert.addAction(UIAlertAction(title: NSLocalizedString("_settings_", comment: ""), style: .default, handler: { (_) in + DispatchQueue.main.async { + if let settingsURL = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) + } + } + })) + + DispatchQueue.main.async { [weak self] in + self?.rootViewController.present(alert, animated: false) + } + } +} diff --git a/iOSClient/DataProtection/DataProtectionAgreementScreen.swift b/iOSClient/DataProtection/DataProtectionAgreementScreen.swift new file mode 100644 index 0000000000..c8e5113c1d --- /dev/null +++ b/iOSClient/DataProtection/DataProtectionAgreementScreen.swift @@ -0,0 +1,98 @@ +// +// DataProtectionAgreementScreen.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 25.11.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +struct DataProtectionAgreementScreen: View { + + var isIPad: Bool { + UIDevice.current.userInterfaceIdiom == .pad + } + + @State private var isShowingSettingsView = false + @State private var isShowPrivacyPolicy = false + + var body: some View { + let titleFont = Font.system(size: isIPad ? 36.0 : 18.0, weight: .bold) + let textFont = Font.system(size: isIPad ? 18.0 : 14.0) + let textBoxRatio = isIPad ? 0.6 : 0.9 + GeometryReader { geometry in + let size = geometry.size + + NavigationView { + VStack(alignment: .center, spacing: 16.0) { + HStack { + Spacer() + Image(.dataProtection) + .resizable() + .scaledToFit() + .frame(height: isIPad ? 128: 64) + Spacer() + }.padding([.top, .bottom], isIPad ? 80.0 : 32.0) + + VStack(alignment: .leading) { + Text(NSLocalizedString("_privacy_settings_", comment: "")) + .font(titleFont) + .foregroundStyle(.white) + .padding(.bottom, 12.0) + + ScrollView { + Text(.init(NSLocalizedString("_privacy_settings_description_", comment: ""))) + .font(textFont) + .multilineTextAlignment(.leading) + .foregroundStyle(.white) + .accentColor(Color(.DataProtection.link)) + .environment(\.openURL, OpenURLAction { url in + if url.absoluteString == "link://privacypolicy" { + isShowPrivacyPolicy = true + } + else if url.absoluteString == "link://reject" { + DataProtectionAgreementManager.shared.rejectAgreement() + } + return .discarded + }) + } + .padding(.bottom, 24) + } + .frame(width: size.width * textBoxRatio) + .sheet(isPresented: $isShowPrivacyPolicy) { + NCBrowserWebView(urlBase: URL(string: NCBrandOptions.shared.privacy)!, browserTitle: NSLocalizedString("_privacy_legal_", comment: "")) + } + + NavigationLink(destination: DataProtectionSettingsScreen(model: DataProtectionModel(), isShowing: $isShowingSettingsView), isActive: $isShowingSettingsView) { EmptyView() } + + Button(NSLocalizedString("_data_protection_settings_", comment: "")) { + isShowingSettingsView = true + } + .buttonStyle(ButtonStyleSecondary(maxWidth: 288.0)) + + Button(NSLocalizedString("_agree_", comment: "")) { + DataProtectionAgreementManager.shared.acceptAgreement() + } + .buttonStyle(ButtonStylePrimary(maxWidth: 288.0)) + } + .environment(\.colorScheme, .dark) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .padding(16.0) + .background { + Image(.gradientBackground) + .resizable() + .ignoresSafeArea() + } + .navigationTitle("") + .navigationBarHidden(true) + } + .accentColor(Color(.DataProtection.navigationBarTint)) + .navigationViewStyle(StackNavigationViewStyle()) + } + } +} + +#Preview { + DataProtectionAgreementScreen() +} diff --git a/iOSClient/DataProtection/DataProtectionHostingController.swift b/iOSClient/DataProtection/DataProtectionHostingController.swift new file mode 100644 index 0000000000..ac4b01fbb2 --- /dev/null +++ b/iOSClient/DataProtection/DataProtectionHostingController.swift @@ -0,0 +1,16 @@ +// +// DataProtectionHostingController.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 26.11.2024. +// Copyright © 2024 STRATO GmbH +// + +import Foundation +import SwiftUI + +class DataProtectionHostingController: UIHostingController { + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + return .portrait + } +} diff --git a/iOSClient/DataProtection/DataProtectionModel.swift b/iOSClient/DataProtection/DataProtectionModel.swift new file mode 100644 index 0000000000..9030f16686 --- /dev/null +++ b/iOSClient/DataProtection/DataProtectionModel.swift @@ -0,0 +1,46 @@ +// +// DataProtectionModel.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 25.11.2024. +// Copyright © 2024 STRATO GmbH +// + +import Foundation + +class DataProtectionModel: ObservableObject { + + @Published var requiredDataCollection: Bool = true + @Published var analysisOfDataCollection: Bool + @Published var redirectToSettings: Bool = false + + var isShownFromSettings: Bool = false + + init(showFromSettings: Bool = false) { + self.isShownFromSettings = showFromSettings + self.analysisOfDataCollection = DataProtectionAgreementManager.shared.isAllowedAnalysisOfDataCollection() + } + + func allowAnalysisOfDataCollection(_ allowAnalysisOfDataCollection: Bool) { + DataProtectionAgreementManager.shared.allowAnalysisOfDataCollection(allowAnalysisOfDataCollection) { + [weak self] in self?.redirectToSettings = true + } + } + + func cancelOpenSettings() { + self.analysisOfDataCollection = DataProtectionAgreementManager.shared.isAllowedAnalysisOfDataCollection() + } + + func openSettings() { + DispatchQueue.main.async { + if let settingsURL = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) + } + } + self.analysisOfDataCollection = DataProtectionAgreementManager.shared.isAllowedAnalysisOfDataCollection() + } + + func saveSettings() { + DataProtectionAgreementManager.shared.saveSettings() + } +} diff --git a/iOSClient/DataProtection/DataProtectionSettingsScreen.swift b/iOSClient/DataProtection/DataProtectionSettingsScreen.swift new file mode 100644 index 0000000000..12dc3e8df0 --- /dev/null +++ b/iOSClient/DataProtection/DataProtectionSettingsScreen.swift @@ -0,0 +1,189 @@ +// +// DataProtectionSettingsScreen.swift +// Nextcloud +// +// Created by Mariia Perehozhuk on 25.11.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +struct DataProtectionSettingsScreen: View { + + @ObservedObject var model: DataProtectionModel + @Binding var isShowing: Bool + + var isIPad: Bool { + UIDevice.current.userInterfaceIdiom == .pad + } + + var body: some View { + if isIPad { + iPadView() + } else { + iPhoneView() + } + } + + private func iPhoneView() -> some View { + VStack { + ScrollView { + VStack(alignment: .leading){ + header() + .padding(EdgeInsets(top: 16.0, + leading: 16.0, + bottom: 32.0, + trailing: 16.0)) + + VStack{ + divider() + + VStack(alignment: .leading) { + requiredDataCollectionToggle() + requiredDataCollectionFooter() + } + .padding(EdgeInsets(top: 12.0, + leading: 16.0, + bottom: 12.0, + trailing: 16.0)) + + divider() + + VStack(alignment: .leading) { + analysisOfDataCollectionToggle() + analysisOfDataCollectionFooter() + } + .padding(EdgeInsets(top: 12.0, + leading: 16.0, + bottom: 12.0, + trailing: 16.0)) + + divider() + } + .background(Color(.DataProtection.listRow)) + } + } + .background(Color(.AppBackground.dataProtection)) + + Spacer() + saveSettingsButton() + } + .background(Color(.AppBackground.dataProtection)) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .navigationTitle(NSLocalizedString("_data_protection_", comment:"")) + .navigationBarTitleDisplayMode(.inline) + } + + private func iPadView() -> some View { + VStack(alignment: .leading) { + header() + .padding(EdgeInsets(top: 10.0, + leading: 16.0, + bottom: 0.0, + trailing: 16.0)) + + Form { + Section(content: { + requiredDataCollectionToggle() + }, footer: { + requiredDataCollectionFooter() + }).applyGlobalFormSectionStyle() + + Section(content: { + analysisOfDataCollectionToggle() + }, footer: { + analysisOfDataCollectionFooter() + }).applyGlobalFormSectionStyle() + } + .applyGlobalFormStyle() + + Spacer() + + HStack { + Spacer() + saveSettingsButton() + Spacer() + } + } + .background(Color(.AppBackground.dataProtection)) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .navigationTitle(NSLocalizedString("_data_protection_", comment:"")) + .navigationBarTitleDisplayMode(.large) + } + + private func divider() -> some View { + Divider() + .background(Color(.DataProtection.listSeparator)) + .frame(height: 1.0) + } + + private func header() -> some View { + let textFont = Font.system(size: 16.0) + return Text("_data_usage_for_app_optimization_description_") + .font(textFont) + .multilineTextAlignment(.leading) + .foregroundStyle(Color(.ListCell.title)) + } + + private func requiredDataCollectionToggle() -> some View { + let listRowTitleFont = Font.system(size: 16.0, weight: .bold) + return Toggle(NSLocalizedString("_required_data_collection_", comment: ""), isOn: $model.requiredDataCollection) + .tint(Color(NCBrandColor.shared.switchColor)) + .font(listRowTitleFont) + .foregroundStyle(Color(.ListCell.title)) + .disabled(true) + } + + private func requiredDataCollectionFooter() -> some View { + let listRowSubtitleFont = Font.system(size: 16.0) + return Text("_required_data_collection_description_") + .font(listRowSubtitleFont) + .multilineTextAlignment(.leading) + .foregroundStyle(Color(.DataProtection.listRowSubtitle)) + } + + private func analysisOfDataCollectionToggle() -> some View { + let listRowTitleFont = Font.system(size: 16.0, weight: .bold) + return Toggle(NSLocalizedString("_analysis_of_data_collection_", comment: ""), isOn: $model.analysisOfDataCollection) + .tint(Color(NCBrandColor.shared.switchColor)) + .font(listRowTitleFont) + .foregroundStyle(Color(.ListCell.title)) + .onChange(of: model.analysisOfDataCollection) { allowAnalysis in + model.allowAnalysisOfDataCollection(allowAnalysis) + } + .alert(NSLocalizedString("_alert_tracking_access", comment: ""), isPresented: $model.redirectToSettings, actions: { + Button(NSLocalizedString("_cancel_", comment: ""), + role: .none, + action: { + model.cancelOpenSettings() + }) + Button(NSLocalizedString("_settings_", comment: ""), + role: .none, + action: { + model.openSettings() + }) + }) + } + + private func analysisOfDataCollectionFooter() -> some View { + let listRowSubtitleFont = Font.system(size: 16.0) + return Text("_analysis_of_data_collection_description_") + .font(listRowSubtitleFont) + .multilineTextAlignment(.leading) + .foregroundStyle(Color(.DataProtection.listRowSubtitle)) + } + + private func saveSettingsButton() -> some View { + Button(NSLocalizedString("_save_settings_", comment: "")) { + isShowing = false + model.saveSettings() + } + .buttonStyle(ButtonStylePrimary(maxWidth: 288.0)) + .padding(16.0) + .hiddenConditionally(isHidden: model.isShownFromSettings) + } +} + +#Preview { + DataProtectionSettingsScreen(model: DataProtectionModel(), isShowing: .constant(true)) +} diff --git a/iOSClient/Extensions/UIColor+Extension.swift b/iOSClient/Extensions/UIColor+Extension.swift index 86915a3d9c..5a0daf7a05 100644 --- a/iOSClient/Extensions/UIColor+Extension.swift +++ b/iOSClient/Extensions/UIColor+Extension.swift @@ -25,6 +25,7 @@ import Foundation import UIKit extension UIColor { + var inverted: UIColor { var r: CGFloat = 0.0, g: CGFloat = 0.0, b: CGFloat = 0.0, a: CGFloat = 0.0 self.getRed(&r, green: &g, blue: &b, alpha: &a) diff --git a/iOSClient/Extensions/UINavigationController+Extension.swift b/iOSClient/Extensions/UINavigationController+Extension.swift index 46b9a063fb..6f6c7ac886 100644 --- a/iOSClient/Extensions/UINavigationController+Extension.swift +++ b/iOSClient/Extensions/UINavigationController+Extension.swift @@ -12,21 +12,17 @@ extension UINavigationController { return self.visibleViewController!.topMostViewController() } - func setNavigationBarAppearance(textColor: UIColor = NCBrandColor.shared.iconImageColor, backgroundColor: UIColor? = .systemBackground) { + func setNavigationBarAppearance(textColor: UIColor = NCBrandColor.shared.textColor, backgroundColor: UIColor? = NCBrandColor.shared.appBackgroundColor) { let appearance = UINavigationBarAppearance() - if #available(iOS 26.0, *) { - appearance.configureWithDefaultBackground() + appearance.configureWithTransparentBackground() + if topViewController is NCMedia { + // transparent } else { - appearance.configureWithTransparentBackground() - if topViewController is NCMedia { - // transparent - } else { - appearance.backgroundColor = backgroundColor - } - appearance.shadowColor = .clear - appearance.shadowImage = UIImage() + appearance.backgroundColor = backgroundColor } + appearance.shadowColor = .clear + appearance.shadowImage = UIImage() appearance.titleTextAttributes = [.foregroundColor: textColor] navigationBar.standardAppearance = appearance @@ -34,7 +30,7 @@ extension UINavigationController { navigationBar.compactAppearance = appearance navigationBar.compactScrollEdgeAppearance = appearance - navigationBar.tintColor = textColor + navigationBar.tintColor = NCBrandColor.shared.iconImageColor navigationBar.prefersLargeTitles = false } } diff --git a/iOSClient/Extensions/UIView+Extension.swift b/iOSClient/Extensions/UIView+Extension.swift index 193198ec46..b4f253cf2d 100644 --- a/iOSClient/Extensions/UIView+Extension.swift +++ b/iOSClient/Extensions/UIView+Extension.swift @@ -30,4 +30,8 @@ extension UIView { self.layer.cornerRadius = self.frame.size.width / 2 self.layer.masksToBounds = true } + + var bottomCenter: CGRect { + return CGRect(origin: CGPoint(x: center.x, y: bounds.height), size: CGSizeZero) + } } diff --git a/iOSClient/Extensions/UIView+GridSelection.swift b/iOSClient/Extensions/UIView+GridSelection.swift new file mode 100644 index 0000000000..02444c0859 --- /dev/null +++ b/iOSClient/Extensions/UIView+GridSelection.swift @@ -0,0 +1,23 @@ +// +// UIView+GridSelection.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 20.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import Foundation + +extension UIView { + func setBorderForGridViewCell(isSelected: Bool) { + if isSelected { + layer.borderWidth = 2 + layer.borderColor = NCBrandColor.shared.brandElement.cgColor + layer.cornerRadius = 4 + } else { + layer.borderWidth = 0 + layer.borderColor = UIColor.clear.cgColor + layer.cornerRadius = 0 + } + } +} diff --git a/iOSClient/Extensions/UIViewController+Extension.swift b/iOSClient/Extensions/UIViewController+Extension.swift index 4f9cc274ba..f416b51a79 100644 --- a/iOSClient/Extensions/UIViewController+Extension.swift +++ b/iOSClient/Extensions/UIViewController+Extension.swift @@ -4,6 +4,7 @@ // // Created by Marino Faggiana on 02/08/2022. // Copyright © 2022 Marino Faggiana. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Marino Faggiana // @@ -63,6 +64,33 @@ extension UIViewController { return false } } + + var mainTabBarController: NCMainTabBarController? { + if let tabBarController = self.tabBarController as? NCMainTabBarController { + return tabBarController + } + return self.view.window?.rootViewController as? NCMainTabBarController + } + + func setNavigationBarLogo() { + let logo = UIImage(resource: .ionosEasyStorageLogo) + .withTintColor(UIColor(resource: .NavigationBar.logoTint)) + let imageView = UIImageView(image: logo) + + let originalSize = logo.size + let multiplier = 0.89 + imageView.translatesAutoresizingMaskIntoConstraints = false + navigationItem.titleView = imageView + + NSLayoutConstraint.activate([ + imageView.widthAnchor.constraint(equalToConstant: originalSize.width * multiplier), + imageView.heightAnchor.constraint(equalToConstant: originalSize.height * multiplier) + ]) + } + + func isCurrentScreenInMainTabBar() -> Bool { + return self.tabBarController is NCMainTabBarController + } } extension UIViewController: @retroactive MFMailComposeViewControllerDelegate { diff --git a/iOSClient/Extensions/View+Design.swift b/iOSClient/Extensions/View+Design.swift new file mode 100644 index 0000000000..ec298fb314 --- /dev/null +++ b/iOSClient/Extensions/View+Design.swift @@ -0,0 +1,37 @@ +// +// View+Design.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 06.01.2025. +// Copyright © 2025 Viseven Europe OÜ. All rights reserved. +// + +import SwiftUI + +extension View { + func applyScrollContentBackground() -> some View { + self.modifier(ScrollContentBackgroundModifier()) + } + + func applyGlobalFormStyle() -> some View { + self + .applyScrollContentBackground() + .background(Color(NCBrandColor.shared.formBackgroundColor)) + } + + func applyGlobalFormSectionStyle() -> some View { + self + .listRowBackground(Color(NCBrandColor.shared.formRowBackgroundColor)) + .listRowSeparatorTint(Color(NCBrandColor.shared.formSeparatorColor)) + } +} + +struct ScrollContentBackgroundModifier: ViewModifier { + func body(content: Content) -> some View { + if #available(iOS 16.0, *) { + content.scrollContentBackground(.hidden) + } else { + content + } + } +} diff --git a/iOSClient/Extensions/View+Extension.swift b/iOSClient/Extensions/View+Extension.swift index 77aab3bea7..b78a0fd1df 100644 --- a/iOSClient/Extensions/View+Extension.swift +++ b/iOSClient/Extensions/View+Extension.swift @@ -4,6 +4,7 @@ // // Created by Marino Faggiana on 29/12/22. // Copyright © 2022 Marino Faggiana. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Marino Faggiana // @@ -24,6 +25,7 @@ import SwiftUI extension View { + func complexModifier(@ViewBuilder _ closure: (Self) -> V) -> some View { closure(self) } diff --git a/iOSClient/Favorites/NCFavorite.storyboard b/iOSClient/Favorites/NCFavorite.storyboard index 730995f7f8..8c56bb2470 100644 --- a/iOSClient/Favorites/NCFavorite.storyboard +++ b/iOSClient/Favorites/NCFavorite.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,7 +17,7 @@ - + @@ -31,18 +31,31 @@ + + + + + + + + + + - - + + + + + diff --git a/iOSClient/Favorites/NCFavorite.swift b/iOSClient/Favorites/NCFavorite.swift index 4a020f53af..cca8e49aea 100644 --- a/iOSClient/Favorites/NCFavorite.swift +++ b/iOSClient/Favorites/NCFavorite.swift @@ -13,8 +13,6 @@ class NCFavorite: NCCollectionViewCommon { layoutKey = NCGlobal.shared.layoutViewFavorite enableSearchBar = false headerRichWorkspaceDisable = true - emptyImageName = "star.fill" - emptyImageColors = [NCBrandColor.shared.yellowFavorite] emptyTitle = "_favorite_no_files_" emptyDescription = "_tutorial_favorite_view_" } diff --git a/iOSClient/Favorites/NCFavoriteNavigationController.swift b/iOSClient/Favorites/NCFavoriteNavigationController.swift deleted file mode 100644 index 032b254765..0000000000 --- a/iOSClient/Favorites/NCFavoriteNavigationController.swift +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-FileCopyrightText: Nextcloud GmbH -// SPDX-FileCopyrightText: 2025 Marino Faggiana -// SPDX-License-Identifier: GPL-3.0-or-later - -import UIKit - -class NCFavoriteNavigationController: NCMainNavigationController { - - // MARK: - Right - - override func createOptionMenu() async -> UIMenu? { - guard let collectionViewCommon, - let items = await NCContextMenuNavigation().viewMenuOption( - collectionViewCommon: collectionViewCommon, - mainNavigationController: self, - session: session - ) else { - return nil - } - - if collectionViewCommon.layoutKey == global.layoutViewFavorite { - let fileSettings = UIMenu(title: "", options: .displayInline, children: [items.directoryOnTop, items.hiddenFiles]) - - return UIMenu(children: [items.select, items.viewStyleSubmenu, items.sortSubmenu, fileSettings]) - } else { - let fileSettings = UIMenu(title: "", options: .displayInline, children: [items.directoryOnTop, items.hiddenFiles]) - let additionalSettings = UIMenu(title: "", options: .displayInline, children: [items.showDescription]) - - return UIMenu(children: [items.select, items.viewStyleSubmenu, items.sortSubmenu, fileSettings, additionalSettings]) - } - } -} diff --git a/iOSClient/Files/NCFiles+UIScrollViewDelegate.swift b/iOSClient/Files/NCFiles+UIScrollViewDelegate.swift index 5a853f85fa..264d58c9db 100644 --- a/iOSClient/Files/NCFiles+UIScrollViewDelegate.swift +++ b/iOSClient/Files/NCFiles+UIScrollViewDelegate.swift @@ -3,35 +3,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later extension NCFiles { - func scrollViewDidScroll(_ scrollView: UIScrollView) { + override func scrollViewDidScroll(_ scrollView: UIScrollView) { let currentOffsetY = scrollView.contentOffset.y let currentTime = CACurrentMediaTime() let deltaY = currentOffsetY - lastOffsetY let deltaTime = currentTime - lastScrollTime let velocity = deltaTime > 0 ? deltaY / CGFloat(deltaTime) : 0 - if deltaY > 0 { - // Scroll down → accumulate - - accumulatedScrollDown += deltaY - if accumulatedScrollDown > 150, - let menuToolBar = self.mainNavigationController?.menuToolbar { // threshold before decreasing alpha - UIView.animate(withDuration: 0.2) { - menuToolBar.alpha = max(0.4, menuToolBar.alpha - 0.02) - } - } - } else if deltaY < 0 { - // Scroll up → reset and maybe increase alpha - - accumulatedScrollDown = 0 - if abs(velocity) > 700, - let menuToolBar = self.mainNavigationController?.menuToolbar { // speed before increasing alpha - UIView.animate(withDuration: 0.2) { - menuToolBar.alpha = min(1.0, menuToolBar.alpha + 0.1) - } - } - } - lastOffsetY = currentOffsetY lastScrollTime = currentTime } diff --git a/iOSClient/Files/NCFiles.storyboard b/iOSClient/Files/NCFiles.storyboard index fd07820e6c..7f20ca992d 100644 --- a/iOSClient/Files/NCFiles.storyboard +++ b/iOSClient/Files/NCFiles.storyboard @@ -1,8 +1,9 @@ - + - + + @@ -15,8 +16,8 @@ - - + + @@ -30,18 +31,31 @@ + + + + + + + - - - - + + + + + + + + + + diff --git a/iOSClient/Files/NCFiles.swift b/iOSClient/Files/NCFiles.swift index a1a0956228..f3a3b34f44 100644 --- a/iOSClient/Files/NCFiles.swift +++ b/iOSClient/Files/NCFiles.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2020 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -27,6 +28,8 @@ class NCFiles: NCCollectionViewCommon { // MARK: - View Life Cycle override func viewDidLoad() { + enableSearchBar = !isOpenedFromSearchResults() + super.viewDidLoad() NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil, queue: nil) { notification in @@ -35,7 +38,6 @@ class NCFiles: NCCollectionViewCommon { let account = userInfo["account"] as? String, self.controller?.account == account { let color = NCBrandColor.shared.getElement(account: account) - self.mainNavigationController?.menuToolbar.items?.forEach { $0.tintColor = color } } } } @@ -65,9 +67,6 @@ class NCFiles: NCCollectionViewCommon { if let userInfo = notification.userInfo, let account = userInfo["account"] as? String { let color = NCBrandColor.shared.getElement(account: account) - self.mainNavigationController?.menuToolbar.items?.forEach { - $0.tintColor = color - } } self.navigationController?.popToRootViewController(animated: false) @@ -88,7 +87,7 @@ class NCFiles: NCCollectionViewCommon { self.titleCurrentFolder = self.getNavigationTitle() self.navigationItem.title = self.titleCurrentFolder - await (self.navigationController as? NCMainNavigationController)?.setNavigationLeftItems() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationLeftItems() await self.reloadDataSource() await self.getServerData() } @@ -114,8 +113,7 @@ class NCFiles: NCCollectionViewCommon { Task { // Plus Menu reload - await self.mainNavigationController?.menuPlus?.create(session: session) - + let capabilities = await database.getCapabilities(account: self.session.account) ?? NKCapabilities.Capabilities() // Server data if !isSearchingMode { await getServerData() @@ -152,16 +150,6 @@ class NCFiles: NCCollectionViewCommon { } if let metadataFolder { nkLog(info: "Inside metadata folder \(metadataFolder.fileName) with permissions: \(metadataFolder.permissions)") - - // disable + button if no create permission - let color = NCBrandColor.shared.getElement(account: self.session.account) - - if let items = self.mainNavigationController?.menuToolbar.items { - for item in items { - item.isEnabled = metadataFolder.isCreatable - item.tintColor = metadataFolder.isCreatable ? color : .lightGray - } - } } let metadatas = await self.database.getMetadatasAsyncDataSource(withServerUrl: self.serverUrl, @@ -381,6 +369,12 @@ class NCFiles: NCCollectionViewCommon { } await didSelectMetadata(metadata, withOcIds: false) } + + private func isOpenedFromSearchResults() -> Bool { + return self.navigationController?.viewControllers.contains(where: { viewController in + return (viewController as? NCCollectionViewCommon)?.isSearchingMode ?? false + }) ?? false + } // MARK: - NCAccountSettingsModelDelegate @@ -407,7 +401,7 @@ class NCFiles: NCCollectionViewCommon { } Task { - await (self.navigationController as? NCMainNavigationController)?.setNavigationLeftItems() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationLeftItems() } } } diff --git a/iOSClient/Files/NCFilesNavigationController.swift b/iOSClient/Files/NCFilesNavigationController.swift deleted file mode 100644 index 2d9187f09e..0000000000 --- a/iOSClient/Files/NCFilesNavigationController.swift +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-FileCopyrightText: Nextcloud GmbH -// SPDX-FileCopyrightText: 2025 Marino Faggiana -// SPDX-License-Identifier: GPL-3.0-or-later - -import UIKit -import SwiftUI -import NextcloudKit - -class NCFilesNavigationController: NCMainNavigationController { - override func viewDidLoad() { - super.viewDidLoad() - - NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterReloadAvatar), object: nil, queue: nil) { notification in - DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { - self.collectionViewCommon?.showTipAccounts() - } - guard let userInfo = notification.userInfo as NSDictionary?, - let error = userInfo["error"] as? NKError, - error.errorCode != self.global.errorNotModified - else { - return - } - - Task { - await self.setNavigationLeftItems() - } - } - } - - // MARK: - Right - - override func createOptionMenu() async -> UIMenu? { - guard let collectionViewCommon, - let items = await NCContextMenuNavigation().viewMenuOption( - collectionViewCommon: collectionViewCommon, - mainNavigationController: self, - session: self.session) - else { - return nil - } - - if collectionViewCommon.serverUrl == utilityFileSystem.getHomeServer(session: session) { - let fileSettings = UIMenu(title: "", options: .displayInline, children: [items.personalFilesOnly, items.favoriteOnTop, items.directoryOnTop, items.hiddenFiles]) - var children: [UIMenuElement] = [items.showDescription] - if let showRecommendedFiles = items.showRecommendedFiles { - children.insert(showRecommendedFiles, at: 0) - } - let additionalSettings = UIMenu(title: "", options: .displayInline, children: children) - - return UIMenu(children: [items.select, items.viewStyleSubmenu, items.sortSubmenu, fileSettings, additionalSettings]) - } else { - let fileSettings = UIMenu(title: "", options: .displayInline, children: [items.favoriteOnTop, items.directoryOnTop, items.hiddenFiles, items.showDescription]) - let additionalSettings = UIMenu(title: "", options: .displayInline, children: [items.showDescription]) - - return UIMenu(children: [items.select, items.viewStyleSubmenu, items.sortSubmenu, fileSettings, additionalSettings]) - } - } - - // MARK: - Left - - override func setNavigationLeftItems() async { - guard let tableAccount = database.getTableAccount(predicate: NSPredicate(format: "account == %@", self.session.account)) - else { - self.collectionViewCommon?.navigationItem.leftBarButtonItems = nil - return - } - let image = utility.loadUserImage(for: tableAccount.user, displayName: tableAccount.displayName, urlBase: tableAccount.urlBase) - - class AccountSwitcherButton: UIButton { - var onMenuOpened: (() -> Void)? - - override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willDisplayMenuFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) { - super.contextMenuInteraction(interaction, willDisplayMenuFor: configuration, animator: animator) - onMenuOpened?() - } - } - - @MainActor - func createLeftMenu() async -> UIMenu? { - var childrenAccountSubmenu: [UIMenuElement] = [] - let accounts = await database.getAllAccountOrderAliasAsync() - guard !accounts.isEmpty, - let controller = collectionViewCommon?.controller - else { - return nil - } - - let accountActions: [UIAction] = accounts.map { account in - let image = utility.loadUserImage(for: account.user, displayName: account.displayName, urlBase: account.urlBase) - var name: String = "" - var url: String = "" - - if account.alias.isEmpty { - name = account.displayName - url = (URL(string: account.urlBase)?.host ?? "") - } else { - name = account.alias - } - - let attributes: UIMenuElement.Attributes = account.account == controller.account ? [.disabled] : [] - let action = UIAction(title: name, image: image, attributes: attributes, state: account.account == controller.account ? .on : .off) { _ in - Task { @MainActor in - await NCAccount().changeAccount(account.account, userProfile: nil, controller: self.controller) - await self.collectionViewCommon?.setEditMode(false) - } - } - - action.subtitle = url - return action - } - - let addAccountAction = UIAction(title: NSLocalizedString("_add_account_", comment: ""), image: utility.loadImage(named: "person.crop.circle.badge.plus", colors: NCBrandColor.shared.iconImageMultiColors)) { _ in - if NCBrandOptions.shared.disable_intro { - if let viewController = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin { - viewController.controller = self.controller - let navigationController = UINavigationController(rootViewController: viewController) - navigationController.modalPresentationStyle = .fullScreen - self.present(navigationController, animated: true) - } - } else { - if let navigationController = UIStoryboard(name: "NCIntro", bundle: nil).instantiateInitialViewController() as? UINavigationController { - if let viewController = navigationController.topViewController as? NCIntroViewController { - viewController.controller = nil - } - navigationController.modalPresentationStyle = .fullScreen - self.present(navigationController, animated: true) - } - } - } - - let settingsAccountAction = UIAction(title: NSLocalizedString("_account_settings_", comment: ""), image: utility.loadImage(named: "gear", colors: [NCBrandColor.shared.iconImageColor])) { _ in - let accountSettingsModel = NCAccountSettingsModel(controller: self.controller, delegate: self.collectionViewCommon) - let accountSettingsView = NCAccountSettingsView(model: accountSettingsModel) - let accountSettingsController = UIHostingController(rootView: accountSettingsView) - - self.present(accountSettingsController, animated: true, completion: nil) - } - - if !NCBrandOptions.shared.disable_multiaccount { - childrenAccountSubmenu.append(addAccountAction) - } - childrenAccountSubmenu.append(settingsAccountAction) - - let addAccountSubmenu = UIMenu(title: "", options: .displayInline, children: childrenAccountSubmenu) - let menu = UIMenu(children: accountActions + [addAccountSubmenu]) - - return menu - } - - if self.topViewController != self.viewControllers.first { - return - } - - if self.collectionViewCommon?.navigationItem.leftBarButtonItems == nil { - let accountButton = AccountSwitcherButton(type: .custom) - - accountButton.accessibilityIdentifier = "accountSwitcher" - accountButton.setImage(image, for: .normal) - accountButton.semanticContentAttribute = .forceLeftToRight - accountButton.sizeToFit() - - accountButton.menu = await createLeftMenu() - accountButton.showsMenuAsPrimaryAction = true - - accountButton.onMenuOpened = { - self.collectionViewCommon?.dismissTip() - } - - self.collectionViewCommon?.navigationItem.setLeftBarButtonItems([UIBarButtonItem(customView: accountButton)], animated: true) - - } else { - - let accountButton = self.collectionViewCommon?.navigationItem.leftBarButtonItems?.first?.customView as? UIButton - accountButton?.setImage(image, for: .normal) - accountButton?.menu = await createLeftMenu() - } - } -} diff --git a/iOSClient/Images.xcassets/folder.imageset/folder.svg b/iOSClient/Images.xcassets/folder.imageset/folder.svg deleted file mode 100644 index b3bf667783..0000000000 --- a/iOSClient/Images.xcassets/folder.imageset/folder.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/folderAutomaticUpload.imageset/folder_photo.svg b/iOSClient/Images.xcassets/folderAutomaticUpload.imageset/folder_photo.svg deleted file mode 100644 index f46eb94656..0000000000 --- a/iOSClient/Images.xcassets/folderAutomaticUpload.imageset/folder_photo.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/folderEncrypted.imageset/folder_encrypted.svg b/iOSClient/Images.xcassets/folderEncrypted.imageset/folder_encrypted.svg deleted file mode 100644 index 4f9e6b487e..0000000000 --- a/iOSClient/Images.xcassets/folderEncrypted.imageset/folder_encrypted.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/folder_external.imageset/Contents.json b/iOSClient/Images.xcassets/folder_external.imageset/Contents.json deleted file mode 100644 index 741bbee824..0000000000 --- a/iOSClient/Images.xcassets/folder_external.imageset/Contents.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "images" : [ - { - "filename" : "folder_external.svg", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - }, - "properties" : { - "preserves-vector-representation" : true, - "template-rendering-intent" : "template" - } -} diff --git a/iOSClient/Images.xcassets/folder_external.imageset/folder_external.svg b/iOSClient/Images.xcassets/folder_external.imageset/folder_external.svg deleted file mode 100644 index c6a0db5b35..0000000000 --- a/iOSClient/Images.xcassets/folder_external.imageset/folder_external.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/folder_group.imageset/folder_group.svg b/iOSClient/Images.xcassets/folder_group.imageset/folder_group.svg deleted file mode 100644 index 960ab84ec1..0000000000 --- a/iOSClient/Images.xcassets/folder_group.imageset/folder_group.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/folder_public.imageset/folder_link.svg b/iOSClient/Images.xcassets/folder_public.imageset/folder_link.svg deleted file mode 100644 index 8966f9a61a..0000000000 --- a/iOSClient/Images.xcassets/folder_public.imageset/folder_link.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/folder_shared_with_me.imageset/Contents.json b/iOSClient/Images.xcassets/folder_shared_with_me.imageset/Contents.json deleted file mode 100644 index 8b5e688724..0000000000 --- a/iOSClient/Images.xcassets/folder_shared_with_me.imageset/Contents.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "images" : [ - { - "filename" : "folder_shared_with_me.svg", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - }, - "properties" : { - "preserves-vector-representation" : true, - "template-rendering-intent" : "template" - } -} diff --git a/iOSClient/Images.xcassets/folder_shared_with_me.imageset/folder_shared_with_me.svg b/iOSClient/Images.xcassets/folder_shared_with_me.imageset/folder_shared_with_me.svg deleted file mode 100644 index d115211941..0000000000 --- a/iOSClient/Images.xcassets/folder_shared_with_me.imageset/folder_shared_with_me.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iOSClient/Images.xcassets/gear.imageset/gear.pdf b/iOSClient/Images.xcassets/gear.imageset/gear.pdf deleted file mode 100644 index 7182936e45..0000000000 Binary files a/iOSClient/Images.xcassets/gear.imageset/gear.pdf and /dev/null differ diff --git a/iOSClient/Images.xcassets/gitHub.imageset/Contents.json b/iOSClient/Images.xcassets/gitHub.imageset/Contents.json deleted file mode 100644 index fa786f3290..0000000000 --- a/iOSClient/Images.xcassets/gitHub.imageset/Contents.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "images" : [ - { - "filename" : "github.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "github@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "github@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - }, - "properties" : { - "preserves-vector-representation" : true - } -} diff --git a/iOSClient/Images.xcassets/gitHub.imageset/github.png b/iOSClient/Images.xcassets/gitHub.imageset/github.png deleted file mode 100644 index 2d1b03610d..0000000000 Binary files a/iOSClient/Images.xcassets/gitHub.imageset/github.png and /dev/null differ diff --git a/iOSClient/Images.xcassets/gitHub.imageset/github@2x.png b/iOSClient/Images.xcassets/gitHub.imageset/github@2x.png deleted file mode 100644 index 335c309931..0000000000 Binary files a/iOSClient/Images.xcassets/gitHub.imageset/github@2x.png and /dev/null differ diff --git a/iOSClient/Images.xcassets/gitHub.imageset/github@3x.png b/iOSClient/Images.xcassets/gitHub.imageset/github@3x.png deleted file mode 100644 index 487bc8bada..0000000000 Binary files a/iOSClient/Images.xcassets/gitHub.imageset/github@3x.png and /dev/null differ diff --git a/iOSClient/Images.xcassets/lock.imageset/lock-outline.svg b/iOSClient/Images.xcassets/lock.imageset/lock-outline.svg deleted file mode 100644 index ea1b2fabaa..0000000000 --- a/iOSClient/Images.xcassets/lock.imageset/lock-outline.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/iOSClient/Images.xcassets/lock_open.imageset/lock-open-variant-outline.svg b/iOSClient/Images.xcassets/lock_open.imageset/lock-open-variant-outline.svg deleted file mode 100644 index d1e4c56ff4..0000000000 --- a/iOSClient/Images.xcassets/lock_open.imageset/lock-open-variant-outline.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/iOSClient/Images.xcassets/media.imageset/tabBarMedia.pdf b/iOSClient/Images.xcassets/media.imageset/tabBarMedia.pdf deleted file mode 100644 index 515ca27a10..0000000000 Binary files a/iOSClient/Images.xcassets/media.imageset/tabBarMedia.pdf and /dev/null differ diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/Contents.json new file mode 100644 index 0000000000..c063e0dfe0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "bars.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/bars.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/bars.svg new file mode 100644 index 0000000000..2daaa4931d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/bars.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/Contents.json new file mode 100644 index 0000000000..6698d77844 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "chevronLeft.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/chevronLeft.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/chevronLeft.svg new file mode 100644 index 0000000000..a2daa8af27 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/chevronLeft.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/Contents.json new file mode 100644 index 0000000000..a383c1ab2b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "cloud.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/cloud.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/cloud.svg new file mode 100644 index 0000000000..195d5aa3f1 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/cloud.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/Contents.json new file mode 100644 index 0000000000..8b922f808d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "deleted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/deleted.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/deleted.svg new file mode 100644 index 0000000000..457dacb7e0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/deleted.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/Contents.json new file mode 100644 index 0000000000..f127dc034a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "offline.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/offline.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/offline.svg new file mode 100644 index 0000000000..787c5e2f04 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/offline.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/Contents.json new file mode 100644 index 0000000000..90b1371bf3 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "recent.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/recent.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/recent.svg new file mode 100644 index 0000000000..93b496fd89 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/recent.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/Contents.json b/iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/Contents.json new file mode 100644 index 0000000000..8446dd85dd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "settings.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/settings.svg b/iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/settings.svg new file mode 100644 index 0000000000..f6ac0b5535 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Contents.json b/iOSClient/IonosImages.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileFolderCell/Contents.json b/iOSClient/IonosImages.xcassets/FileFolderCell/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileFolderCell/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/Contents.json new file mode 100644 index 0000000000..fb87640df4 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "star.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/star.svg b/iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/star.svg new file mode 100644 index 0000000000..f6a2d18050 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/star.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/Contents.json new file mode 100644 index 0000000000..35be49c57d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "files_selection_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "files_selection_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_dark.svg b/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_dark.svg new file mode 100644 index 0000000000..42fc4ade84 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_light.svg b/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_light.svg new file mode 100644 index 0000000000..18ef5ba003 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_light.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/Contents.json new file mode 100644 index 0000000000..af3bc0e95b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "grid_item_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/grid_item_selected.svg b/iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/grid_item_selected.svg new file mode 100644 index 0000000000..5cfb397249 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/grid_item_selected.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/Contents.json new file mode 100644 index 0000000000..c0c1d104bf --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "list_item_deselected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/list_item_deselected.svg b/iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/list_item_deselected.svg new file mode 100644 index 0000000000..413d290c78 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/list_item_deselected.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/Contents.json new file mode 100644 index 0000000000..ae8263e6cb --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "list_item_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/list_item_selected.svg b/iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/list_item_selected.svg new file mode 100644 index 0000000000..5cfb397249 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/list_item_selected.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/Contents.json new file mode 100644 index 0000000000..27ae0631bd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "list_item_some_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/list_item_some_selected.svg b/iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/list_item_some_selected.svg new file mode 100644 index 0000000000..31d5f2a7e9 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/list_item_some_selected.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/Contents.json new file mode 100644 index 0000000000..54dded32e5 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "selection_mode_close_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "selection_mode_close_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_dark.svg b/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_dark.svg new file mode 100644 index 0000000000..e520f79859 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_light.svg b/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_light.svg new file mode 100644 index 0000000000..30c68b1d73 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/Contents.json new file mode 100644 index 0000000000..8b0062ba92 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "view_mode_grid.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/view_mode_grid.svg b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/view_mode_grid.svg new file mode 100644 index 0000000000..5c342bc466 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/view_mode_grid.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/Contents.json b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/Contents.json new file mode 100644 index 0000000000..742361aa3d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "view_mode_list.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/view_mode_list.svg b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/view_mode_list.svg new file mode 100644 index 0000000000..e400c26ddf --- /dev/null +++ b/iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/view_mode_list.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/AppIcon.png b/iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/AppIcon.png new file mode 100644 index 0000000000..32154cc06f Binary files /dev/null and b/iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/AppIcon.png differ diff --git a/iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/Contents.json b/iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..cefcc878e0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "AppIcon.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/Contents.json new file mode 100644 index 0000000000..6f64e04406 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "IONOSEasyStorageLogo.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/IONOSEasyStorageLogo.svg b/iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/IONOSEasyStorageLogo.svg new file mode 100644 index 0000000000..81090a9b3f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/IONOSEasyStorageLogo.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOSLogo.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOSLogo.imageset/Contents.json new file mode 100644 index 0000000000..657215e93d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOSLogo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "logo@3x 2.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOSLogo.imageset/logo@3x 2.png b/iOSClient/IonosImages.xcassets/IONOSLogo.imageset/logo@3x 2.png new file mode 100644 index 0000000000..1893643244 Binary files /dev/null and b/iOSClient/IonosImages.xcassets/IONOSLogo.imageset/logo@3x 2.png differ diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/Contents.json new file mode 100644 index 0000000000..8686639ce6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "allowEdit.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/allowEdit.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/allowEdit.svg new file mode 100644 index 0000000000..8c0c0fc3ae --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/allowEdit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/Contents.json new file mode 100644 index 0000000000..da848e1701 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "createFolder.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/createFolder.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/createFolder.svg new file mode 100644 index 0000000000..4bd04bebe7 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/createFolder.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/Contents.json new file mode 100644 index 0000000000..eb80eb30ed --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "data_protection@3x.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/data_protection@3x.png b/iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/data_protection@3x.png new file mode 100644 index 0000000000..8da8586587 Binary files /dev/null and b/iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/data_protection@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/Contents.json new file mode 100644 index 0000000000..a64df6f921 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "details.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/details.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/details.svg new file mode 100644 index 0000000000..b5872eb395 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/details.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/Contents.json new file mode 100644 index 0000000000..28cbd7e04b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "goToPage.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/goToPage.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/goToPage.svg new file mode 100644 index 0000000000..9abc66d052 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/goToPage.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/Images.xcassets/media.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/Contents.json similarity index 86% rename from iOSClient/Images.xcassets/media.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/Contents.json index 988c574d50..8da9cac0d7 100644 --- a/iOSClient/Images.xcassets/media.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "tabBarMedia.pdf", + "filename" : "item.lock.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/item.lock.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/item.lock.svg new file mode 100644 index 0000000000..e1fb6e2058 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/item.lock.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/Images.xcassets/folder_group.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/Contents.json similarity index 85% rename from iOSClient/Images.xcassets/folder_group.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/Contents.json index 2c54bdc970..9f5ea921f7 100644 --- a/iOSClient/Images.xcassets/folder_group.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "folder_group.svg", + "filename" : "item.lock.open.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/item.lock.open.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/item.lock.open.svg new file mode 100644 index 0000000000..32ba7d81ac --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/item.lock.open.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/Images.xcassets/folder.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/Contents.json similarity index 87% rename from iOSClient/Images.xcassets/folder.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/Contents.json index 68fa26d8d7..129d8c9786 100644 --- a/iOSClient/Images.xcassets/folder.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "folder.svg", + "filename" : "media.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/media.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/media.svg new file mode 100644 index 0000000000..a1f220bd44 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/media.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/Contents.json new file mode 100644 index 0000000000..c7941177aa --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "menu.add.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/menu.add.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/menu.add.svg new file mode 100644 index 0000000000..a914655f03 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/menu.add.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/Contents.json new file mode 100644 index 0000000000..d3a11eae5a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "menu.search.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/menu.search.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/menu.search.svg new file mode 100644 index 0000000000..7bf599db8e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/menu.search.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/Images.xcassets/folder_public.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/Contents.json similarity index 86% rename from iOSClient/Images.xcassets/folder_public.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/Contents.json index ce84569fca..2635c73980 100644 --- a/iOSClient/Images.xcassets/folder_public.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "folder_link.svg", + "filename" : "menu.share.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/menu.share.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/menu.share.svg new file mode 100644 index 0000000000..2cc6980daf --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/menu.share.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/Contents.json new file mode 100644 index 0000000000..0f0104ed61 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "modifyWithQuickLook.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/modifyWithQuickLook.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/modifyWithQuickLook.svg new file mode 100644 index 0000000000..dd7ff22c7b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/modifyWithQuickLook.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/Contents.json new file mode 100644 index 0000000000..51e54de5f4 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "moveOrCopy.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/moveOrCopy.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/moveOrCopy.svg new file mode 100644 index 0000000000..b96a316ccd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/moveOrCopy.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/Contents.json new file mode 100644 index 0000000000..8fa31683df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "offline.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/offline.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/offline.svg new file mode 100644 index 0000000000..1c13f1c859 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/offline.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/Contents.json new file mode 100644 index 0000000000..d37b0f16da --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "photoOrVideo.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/photoOrVideo.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/photoOrVideo.svg new file mode 100644 index 0000000000..a1f220bd44 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/photoOrVideo.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/Contents.json new file mode 100644 index 0000000000..16dcef10c2 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "qrcode.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/qrcode.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/qrcode.svg new file mode 100644 index 0000000000..c64b825b7c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/qrcode.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/Contents.json new file mode 100644 index 0000000000..57ed664b11 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "readOnly.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/readOnly.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/readOnly.svg new file mode 100644 index 0000000000..85fbf6bba0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/readOnly.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/Images.xcassets/folderAutomaticUpload.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/Contents.json similarity index 85% rename from iOSClient/Images.xcassets/folderAutomaticUpload.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/Contents.json index 51ff0d5d02..4e1c2863fb 100644 --- a/iOSClient/Images.xcassets/folderAutomaticUpload.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "folder_photo.svg", + "filename" : "rename.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/rename.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/rename.svg new file mode 100644 index 0000000000..555a6d6ddd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/rename.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/Contents.json new file mode 100644 index 0000000000..23eba5b7ae --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "scan.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/scan.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/scan.svg new file mode 100644 index 0000000000..6eda7e4976 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/scan.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/Contents.json new file mode 100644 index 0000000000..e1822cd489 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "star.filled.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/star.filled.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/star.filled.svg new file mode 100644 index 0000000000..b82a0324bc --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/star.filled.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/Contents.json new file mode 100644 index 0000000000..0c63309766 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "star.hollow.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/star.hollow.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/star.hollow.svg new file mode 100644 index 0000000000..dfd1f57e0a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/star.hollow.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/Contents.json new file mode 100644 index 0000000000..3c4a0e48e6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "synced.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/synced.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/synced.svg new file mode 100644 index 0000000000..a27f3fa02f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/synced.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/Contents.json new file mode 100644 index 0000000000..568d58e066 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "trash_icon.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/trash_icon.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/trash_icon.svg new file mode 100644 index 0000000000..791a447eb0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/trash_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/Contents.json new file mode 100644 index 0000000000..c4cc63d4d0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "unshare.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/unshare.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/unshare.svg new file mode 100644 index 0000000000..baf0f77268 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/unshare.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/Contents.json b/iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/Contents.json new file mode 100644 index 0000000000..92ff400200 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "viewInFolder.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/viewInFolder.svg b/iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/viewInFolder.svg new file mode 100644 index 0000000000..4f5a949d4f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/viewInFolder.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/CloseFullscreen.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/CloseFullscreen.svg new file mode 100644 index 0000000000..5abe918a24 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/CloseFullscreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/Contents.json new file mode 100644 index 0000000000..fcf9f2510f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "CloseFullscreen.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Contents.json new file mode 100644 index 0000000000..57bc8b85dd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Forward.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Forward.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Forward.svg new file mode 100644 index 0000000000..05003673f4 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Forward.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Contents.json new file mode 100644 index 0000000000..91c010c033 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Fullscreen.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Fullscreen.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Fullscreen.svg new file mode 100644 index 0000000000..58b1314fca --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Fullscreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Contents.json new file mode 100644 index 0000000000..c590a5b8a4 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Message.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Message.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Message.svg new file mode 100644 index 0000000000..64deb1f13d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Message.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Contents.json new file mode 100644 index 0000000000..8c7abd5ca9 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Pause.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Pause.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Pause.svg new file mode 100644 index 0000000000..edd847cf29 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Pause.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Contents.json new file mode 100644 index 0000000000..aa0a07fe4c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Play.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Play.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Play.svg new file mode 100644 index 0000000000..cb338acbf4 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Play.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Contents.json new file mode 100644 index 0000000000..d5e457a819 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Rewind.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Rewind.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Rewind.svg new file mode 100644 index 0000000000..7a865a3236 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Rewind.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Contents.json b/iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Contents.json new file mode 100644 index 0000000000..35a2d6a428 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Sound.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Sound.svg b/iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Sound.svg new file mode 100644 index 0000000000..1a907cf577 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Sound.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/Contents.json new file mode 100644 index 0000000000..01b166d2af --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "copy.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/copy.svg b/iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/copy.svg new file mode 100644 index 0000000000..c758646e5e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/Contents.json new file mode 100644 index 0000000000..1af2d3ddf1 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "trash-can.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/trash-can.svg b/iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/trash-can.svg new file mode 100644 index 0000000000..a83633f209 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/trash-can.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/Images.xcassets/folderEncrypted.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/Contents.json similarity index 84% rename from iOSClient/Images.xcassets/folderEncrypted.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/Contents.json index d5a0abaa2c..ca7708d919 100644 --- a/iOSClient/Images.xcassets/folderEncrypted.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "folder_encrypted.svg", + "filename" : "cloud-arrow-down.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/cloud-arrow-down.svg b/iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/cloud-arrow-down.svg new file mode 100644 index 0000000000..01435b2f49 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/cloud-arrow-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/Contents.json new file mode 100644 index 0000000000..169d8021cd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "unlock.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/unlock.svg b/iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/unlock.svg new file mode 100644 index 0000000000..82a1c90225 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/unlock.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/Contents.json new file mode 100644 index 0000000000..ee2dbed774 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "rotate-left.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/rotate-left.svg b/iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/rotate-left.svg new file mode 100644 index 0000000000..561d4d5117 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/rotate-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/Contents.json new file mode 100644 index 0000000000..0785af5309 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : ".svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git "a/iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/\356\202\232.svg" "b/iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/\356\202\232.svg" new file mode 100644 index 0000000000..f813d1fdcc --- /dev/null +++ "b/iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/\356\202\232.svg" @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/Contents.json b/iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/Contents.json new file mode 100644 index 0000000000..c534a82ed8 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "lock.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/lock.svg b/iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/lock.svg new file mode 100644 index 0000000000..a0c7918df8 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/lock.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/AutoUpload/Contents.json b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/400-folder.svg b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/400-folder.svg new file mode 100644 index 0000000000..df9048c778 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/400-folder.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/Contents.json new file mode 100644 index 0000000000..169927c48f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "400-folder.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/400-folder-open.svg b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/400-folder-open.svg new file mode 100644 index 0000000000..01dcc3730b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/400-folder-open.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/Contents.json new file mode 100644 index 0000000000..acdc636ebc --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "400-folder-open.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/Contents.json b/iOSClient/IonosImages.xcassets/Settings/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/Contents.json new file mode 100644 index 0000000000..29731a44f6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "autoupload.folder.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/autoupload.folder.svg b/iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/autoupload.folder.svg new file mode 100644 index 0000000000..f6bfbdf098 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/autoupload.folder.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/Contents.json new file mode 100644 index 0000000000..fa8a86ab74 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bulletlist.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/bulletlist.svg b/iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/bulletlist.svg new file mode 100644 index 0000000000..7e0e057e1f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/bulletlist.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/Contents.json new file mode 100644 index 0000000000..dde7152a80 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "calendar.user.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/calendar.user.svg b/iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/calendar.user.svg new file mode 100644 index 0000000000..981e30a453 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/calendar.user.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/camera.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/camera.imageset/Contents.json new file mode 100644 index 0000000000..82cb0eeb52 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/camera.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "camera.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/camera.imageset/camera.svg b/iOSClient/IonosImages.xcassets/Settings/camera.imageset/camera.svg new file mode 100644 index 0000000000..5ffef4a313 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/camera.imageset/camera.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/Contents.json new file mode 100644 index 0000000000..7cd1cb21ad --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "dataprivacy.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/dataprivacy.svg b/iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/dataprivacy.svg new file mode 100644 index 0000000000..2796a8af60 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/dataprivacy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/Contents.json new file mode 100644 index 0000000000..13f00331b9 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "folder.gear.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/folder.gear.svg b/iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/folder.gear.svg new file mode 100644 index 0000000000..dd7383eb85 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/folder.gear.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/gear.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/gear.imageset/Contents.json new file mode 100644 index 0000000000..8353f0456c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/gear.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "gear.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/gear.imageset/gear.svg b/iOSClient/IonosImages.xcassets/Settings/gear.imageset/gear.svg new file mode 100644 index 0000000000..b51d206a3a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/gear.imageset/gear.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/github.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/github.imageset/Contents.json new file mode 100644 index 0000000000..746c02c4f1 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/github.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "github.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/github.imageset/github.svg b/iOSClient/IonosImages.xcassets/Settings/github.imageset/github.svg new file mode 100644 index 0000000000..bf27fa578a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/github.imageset/github.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/handshake.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/handshake.imageset/Contents.json new file mode 100644 index 0000000000..9144f89aa8 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/handshake.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "handshake.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/handshake.imageset/handshake.svg b/iOSClient/IonosImages.xcassets/Settings/handshake.imageset/handshake.svg new file mode 100644 index 0000000000..3128becc4e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/handshake.imageset/handshake.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/Contents.json new file mode 100644 index 0000000000..c22699c49e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "shield.halved.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/shield.halved.svg b/iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/shield.halved.svg new file mode 100644 index 0000000000..12d06e9ff6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/shield.halved.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Settings/xmark.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Settings/xmark.imageset/Contents.json new file mode 100644 index 0000000000..d5403d2121 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/xmark.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "xmark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/Settings/xmark.imageset/xmark.svg b/iOSClient/IonosImages.xcassets/Settings/xmark.imageset/xmark.svg new file mode 100644 index 0000000000..0c9345af80 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Settings/xmark.imageset/xmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/Contents.json new file mode 100644 index 0000000000..4201e3210f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "copy_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "copy_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_dark.svg new file mode 100644 index 0000000000..3026738097 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_dark.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_light.svg b/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_light.svg new file mode 100644 index 0000000000..f5630435ff --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/Contents.json new file mode 100644 index 0000000000..2a2bdfd707 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "downloading_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "downloading_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_dark.svg new file mode 100644 index 0000000000..c2b6c0baf6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_light.svg b/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_light.svg new file mode 100644 index 0000000000..a46c40cda1 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/error.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/error.imageset/Contents.json new file mode 100644 index 0000000000..0ced9acb07 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/error.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "error_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "error_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_dark.svg new file mode 100644 index 0000000000..84c1d0bc97 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_dark.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_light.svg b/iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_light.svg new file mode 100644 index 0000000000..e2a4dbd7a5 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/Contents.json new file mode 100644 index 0000000000..09723030c2 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "favorite_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "favorite_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_dark.svg new file mode 100644 index 0000000000..6d4f7db7e5 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_light.svg b/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_light.svg new file mode 100644 index 0000000000..a4b25a9f96 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/move.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/move.imageset/Contents.json new file mode 100644 index 0000000000..7638a95b17 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/move.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "move_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "move_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_dark.svg new file mode 100644 index 0000000000..e9286f6d34 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_light.svg b/iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_light.svg new file mode 100644 index 0000000000..b809775cbd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/Contents.json new file mode 100644 index 0000000000..5faddd05a3 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "rename_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "rename_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_dark.svg new file mode 100644 index 0000000000..892634803e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_light.svg b/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_light.svg new file mode 100644 index 0000000000..972e425cd7 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/Contents.json new file mode 100644 index 0000000000..5d90fca9e7 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "stop_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "stop_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_dark.svg new file mode 100644 index 0000000000..801db52766 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_light.svg b/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_light.svg new file mode 100644 index 0000000000..3568727310 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/Contents.json new file mode 100644 index 0000000000..9316576563 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "trash_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "trash_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_dark.svg new file mode 100644 index 0000000000..549a48a225 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_light.svg b/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_light.svg new file mode 100644 index 0000000000..54482bf2ee --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/Contents.json new file mode 100644 index 0000000000..c0da23caac --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "upload_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "upload_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_dark.svg new file mode 100644 index 0000000000..2d3b1f1b44 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_light.svg b/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_light.svg new file mode 100644 index 0000000000..9ab37c385f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/Contents.json new file mode 100644 index 0000000000..56d357b7a6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "wait_to_download_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "wait_to_download_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_dark.svg new file mode 100644 index 0000000000..73474bbc18 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_light.svg b/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_light.svg new file mode 100644 index 0000000000..bb5cef0021 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/Contents.json b/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/Contents.json new file mode 100644 index 0000000000..d65815fcff --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "waiting_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "waiting_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_dark.svg b/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_dark.svg new file mode 100644 index 0000000000..3d767a5c16 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_light.svg b/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_light.svg new file mode 100644 index 0000000000..fb04fe8cf9 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/accountCheckmark.imageset/Contents.json b/iOSClient/IonosImages.xcassets/accountCheckmark.imageset/Contents.json new file mode 100644 index 0000000000..e3179b8a31 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/accountCheckmark.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "accountCheckmark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/accountCheckmark.imageset/accountCheckmark.svg b/iOSClient/IonosImages.xcassets/accountCheckmark.imageset/accountCheckmark.svg new file mode 100644 index 0000000000..48d664bc84 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/accountCheckmark.imageset/accountCheckmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/Contents.json b/iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/Contents.json new file mode 100644 index 0000000000..cf93f1e9ba --- /dev/null +++ b/iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "checkmarkIcon.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/checkmarkIcon.svg b/iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/checkmarkIcon.svg new file mode 100644 index 0000000000..48d664bc84 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/checkmarkIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/contactsIcon.imageset/Contents.json b/iOSClient/IonosImages.xcassets/contactsIcon.imageset/Contents.json new file mode 100644 index 0000000000..0aa9ebee58 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/contactsIcon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "contactsIcon_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "contactsIcon_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_dark.svg b/iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_dark.svg new file mode 100644 index 0000000000..1f10f2a24e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_light.svg b/iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_light.svg new file mode 100644 index 0000000000..035cadc70f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/delete.imageset/Contents.json b/iOSClient/IonosImages.xcassets/delete.imageset/Contents.json new file mode 100644 index 0000000000..22b685c78d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/delete.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "delete.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/delete.imageset/delete.svg b/iOSClient/IonosImages.xcassets/delete.imageset/delete.svg new file mode 100644 index 0000000000..791a447eb0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/delete.imageset/delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/deleted.imageset/Contents.json b/iOSClient/IonosImages.xcassets/deleted.imageset/Contents.json new file mode 100644 index 0000000000..8b922f808d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/deleted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "deleted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/deleted.imageset/deleted.svg b/iOSClient/IonosImages.xcassets/deleted.imageset/deleted.svg new file mode 100644 index 0000000000..457dacb7e0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/deleted.imageset/deleted.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/Images.xcassets/lock.imageset/Contents.json b/iOSClient/IonosImages.xcassets/favorites.imageset/Contents.json similarity index 83% rename from iOSClient/Images.xcassets/lock.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/favorites.imageset/Contents.json index b0c59c9baa..4fe3bbcf6a 100644 --- a/iOSClient/Images.xcassets/lock.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/favorites.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "lock-outline.svg", + "filename" : "favorites.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/favorites.imageset/favorites.svg b/iOSClient/IonosImages.xcassets/favorites.imageset/favorites.svg new file mode 100644 index 0000000000..ef62a7e554 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/favorites.imageset/favorites.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/file_unsupported.imageset/Contents.json b/iOSClient/IonosImages.xcassets/file_unsupported.imageset/Contents.json new file mode 100644 index 0000000000..b6fef97558 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/file_unsupported.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "file_unsupported_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "file_unsupported_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_dark.svg b/iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_dark.svg new file mode 100644 index 0000000000..20edf36392 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_light.svg b/iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_light.svg new file mode 100644 index 0000000000..fc1497094c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/folder.imageset/Contents.json b/iOSClient/IonosImages.xcassets/folder.imageset/Contents.json new file mode 100644 index 0000000000..3d32767cc8 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "folder_icon_light_mode.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "folder_icon_dark_mode.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "original" + } +} diff --git a/iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_dark_mode.svg b/iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_dark_mode.svg new file mode 100644 index 0000000000..4a16d8a38f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_dark_mode.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_light_mode.svg b/iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_light_mode.svg new file mode 100644 index 0000000000..c823d5b3d3 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_light_mode.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/Contents.json b/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/Contents.json new file mode 100644 index 0000000000..0b2f580359 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "folderAutomaticUpload_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "folderAutomaticUpload_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "original" + } +} diff --git a/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_dark.svg b/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_dark.svg new file mode 100644 index 0000000000..6c1c1bbf53 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_light.svg b/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_light.svg new file mode 100644 index 0000000000..d5228039de --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/Contents.json b/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/Contents.json new file mode 100644 index 0000000000..ee1583f476 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "folder_icon_light_mode.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "folder_icon_dark_mode.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_dark_mode.svg b/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_dark_mode.svg new file mode 100644 index 0000000000..4a16d8a38f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_dark_mode.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_light_mode.svg b/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_light_mode.svg new file mode 100644 index 0000000000..c823d5b3d3 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_light_mode.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folder_external.imageset/Contents.json b/iOSClient/IonosImages.xcassets/folder_external.imageset/Contents.json new file mode 100644 index 0000000000..ee1583f476 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder_external.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "folder_icon_light_mode.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "folder_icon_dark_mode.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_dark_mode.svg b/iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_dark_mode.svg new file mode 100644 index 0000000000..4a16d8a38f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_dark_mode.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_light_mode.svg b/iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_light_mode.svg new file mode 100644 index 0000000000..c823d5b3d3 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_light_mode.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/iOSClient/IonosImages.xcassets/folder_group.imageset/Contents.json b/iOSClient/IonosImages.xcassets/folder_group.imageset/Contents.json new file mode 100644 index 0000000000..bdc320951e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder_group.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "folder_group_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "folder_group_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "original" + } +} diff --git a/iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_dark.svg b/iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_dark.svg new file mode 100644 index 0000000000..017e95d53c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_light.svg b/iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_light.svg new file mode 100644 index 0000000000..ecdc7a8f1e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/gradientBackground.imageset/Contents.json b/iOSClient/IonosImages.xcassets/gradientBackground.imageset/Contents.json new file mode 100644 index 0000000000..8d19a75c09 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/gradientBackground.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "GradientBackgroundPhone.svg", + "idiom" : "iphone" + }, + { + "filename" : "GradientBackgroundPad.svg", + "idiom" : "ipad" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPad.svg b/iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPad.svg new file mode 100644 index 0000000000..195a4fb301 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPad.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPhone.svg b/iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPhone.svg new file mode 100644 index 0000000000..af13dc0786 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPhone.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/iOSClient/Images.xcassets/gear.imageset/Contents.json b/iOSClient/IonosImages.xcassets/home.imageset/Contents.json similarity index 86% rename from iOSClient/Images.xcassets/gear.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/home.imageset/Contents.json index 8dfa77c79d..7ba806a97d 100644 --- a/iOSClient/Images.xcassets/gear.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/home.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "gear.pdf", + "filename" : "home.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/home.imageset/home.svg b/iOSClient/IonosImages.xcassets/home.imageset/home.svg new file mode 100644 index 0000000000..09fab0e8f6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/home.imageset/home.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/Images.xcassets/lock_open.imageset/Contents.json b/iOSClient/IonosImages.xcassets/local.imageset/Contents.json similarity index 78% rename from iOSClient/Images.xcassets/lock_open.imageset/Contents.json rename to iOSClient/IonosImages.xcassets/local.imageset/Contents.json index d6fb0c7a01..8d0cdde65d 100644 --- a/iOSClient/Images.xcassets/lock_open.imageset/Contents.json +++ b/iOSClient/IonosImages.xcassets/local.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "lock-open-variant-outline.svg", + "filename" : "local.svg", "idiom" : "universal" } ], diff --git a/iOSClient/IonosImages.xcassets/local.imageset/local.svg b/iOSClient/IonosImages.xcassets/local.imageset/local.svg new file mode 100644 index 0000000000..0abdd25c8d --- /dev/null +++ b/iOSClient/IonosImages.xcassets/local.imageset/local.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/more.imageset/Contents.json b/iOSClient/IonosImages.xcassets/more.imageset/Contents.json new file mode 100644 index 0000000000..6d5404f0eb --- /dev/null +++ b/iOSClient/IonosImages.xcassets/more.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "filename" : "more_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "more_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/more.imageset/more_dark.svg b/iOSClient/IonosImages.xcassets/more.imageset/more_dark.svg new file mode 100644 index 0000000000..234390501b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/more.imageset/more_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/more.imageset/more_light.svg b/iOSClient/IonosImages.xcassets/more.imageset/more_light.svg new file mode 100644 index 0000000000..6ed01ab95c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/more.imageset/more_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/offlineFlag.imageset/Contents.json b/iOSClient/IonosImages.xcassets/offlineFlag.imageset/Contents.json new file mode 100644 index 0000000000..282dc917cb --- /dev/null +++ b/iOSClient/IonosImages.xcassets/offlineFlag.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "filename" : "offlineFlag_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "offlineFlag_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_dark.svg b/iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_dark.svg new file mode 100644 index 0000000000..761e98cb81 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_light.svg b/iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_light.svg new file mode 100644 index 0000000000..1f5e5417cc --- /dev/null +++ b/iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/restore.imageset/Contents.json b/iOSClient/IonosImages.xcassets/restore.imageset/Contents.json new file mode 100644 index 0000000000..9263531fea --- /dev/null +++ b/iOSClient/IonosImages.xcassets/restore.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "restore.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/iOSClient/IonosImages.xcassets/restore.imageset/restore.svg b/iOSClient/IonosImages.xcassets/restore.imageset/restore.svg new file mode 100644 index 0000000000..065444ce9b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/restore.imageset/restore.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/Contents.json b/iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/Contents.json new file mode 100644 index 0000000000..9f6c3312dd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "restoreFromDeleted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/restoreFromDeleted.svg b/iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/restoreFromDeleted.svg new file mode 100644 index 0000000000..065444ce9b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/restoreFromDeleted.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/Contents.json b/iOSClient/IonosImages.xcassets/share/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/share/canShare.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/canShare.imageset/Contents.json new file mode 100644 index 0000000000..9c38a17166 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/canShare.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "filename" : "canShare_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "canShare_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_dark.svg b/iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_dark.svg new file mode 100644 index 0000000000..6263150715 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_light.svg b/iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_light.svg new file mode 100644 index 0000000000..cf6943381b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/share/folder/Contents.json b/iOSClient/IonosImages.xcassets/share/folder/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/folder/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/Contents.json new file mode 100644 index 0000000000..a8eb66a529 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "shared_by_link_folder@3x.png", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_by_link_folder 1@3x.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder 1@3x.png b/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder 1@3x.png new file mode 100644 index 0000000000..8701bb2aaa Binary files /dev/null and b/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder 1@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder@3x.png b/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder@3x.png new file mode 100644 index 0000000000..aa33bb469c Binary files /dev/null and b/iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/Contents.json new file mode 100644 index 0000000000..90bde523be --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "shared_internally_folder@3x.png", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_internally_folder 1@3x.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder 1@3x.png b/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder 1@3x.png new file mode 100644 index 0000000000..cd868857b8 Binary files /dev/null and b/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder 1@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder@3x.png b/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder@3x.png new file mode 100644 index 0000000000..20a5a6f8a4 Binary files /dev/null and b/iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/Contents.json new file mode 100644 index 0000000000..aee486c017 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "shared_with_me_folder@3x.png", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_with_me_folder 1@3x.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder 1@3x.png b/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder 1@3x.png new file mode 100644 index 0000000000..67e197f719 Binary files /dev/null and b/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder 1@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder@3x.png b/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder@3x.png new file mode 100644 index 0000000000..c1ffd21f46 Binary files /dev/null and b/iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder@3x.png differ diff --git a/iOSClient/IonosImages.xcassets/share/icon/Contents.json b/iOSClient/IonosImages.xcassets/share/icon/Contents.json new file mode 100644 index 0000000000..6e965652df --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/Contents.json new file mode 100644 index 0000000000..c72dd7f7f0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "shared_by_link_icon.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_by_link_icon 1.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon 1.svg b/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon 1.svg new file mode 100644 index 0000000000..94af3bb4a6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon 1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon.svg b/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon.svg new file mode 100644 index 0000000000..ef7408fe7c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/Contents.json new file mode 100644 index 0000000000..8b9388ee25 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "shared_internally_icon.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_internally_icon 1.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon 1.svg b/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon 1.svg new file mode 100644 index 0000000000..f6a0a85023 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon 1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon.svg b/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon.svg new file mode 100644 index 0000000000..2ab64b67da --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/Contents.json new file mode 100644 index 0000000000..c8e0ca2f82 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "shared_with_me_icon.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_with_me_icon 1.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon 1.svg b/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon 1.svg new file mode 100644 index 0000000000..f19ba72d23 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon 1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon.svg b/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon.svg new file mode 100644 index 0000000000..1b123284b9 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/internalLink.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/internalLink.imageset/Contents.json new file mode 100644 index 0000000000..f8e70f58a8 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/internalLink.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "internalLink_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "internalLink_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_dark.svg b/iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_dark.svg new file mode 100644 index 0000000000..4df5733c91 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_light.svg b/iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_light.svg new file mode 100644 index 0000000000..1176614db6 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/Contents.json new file mode 100644 index 0000000000..2d97b56ef0 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "lnk_l.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "lnk_d.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_d.svg b/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_d.svg new file mode 100644 index 0000000000..61e798611f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_d.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_l.svg b/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_l.svg new file mode 100644 index 0000000000..bbcdc1d415 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_l.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/Contents.json new file mode 100644 index 0000000000..e9afe39795 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "magnifyingGlass_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "magnifyingGlass_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_dark.svg b/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_dark.svg new file mode 100644 index 0000000000..cd50472dcb --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_light.svg b/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_light.svg new file mode 100644 index 0000000000..78b9080aa8 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/plus.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/plus.imageset/Contents.json new file mode 100644 index 0000000000..e6da59e03f --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/plus.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "plus_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "plus_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/plus.imageset/plus_dark.svg b/iOSClient/IonosImages.xcassets/share/plus.imageset/plus_dark.svg new file mode 100644 index 0000000000..dafd1ba62a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/plus.imageset/plus_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/plus.imageset/plus_light.svg b/iOSClient/IonosImages.xcassets/share/plus.imageset/plus_light.svg new file mode 100644 index 0000000000..2ce5621cd7 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/plus.imageset/plus_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/shared.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/shared.imageset/Contents.json new file mode 100644 index 0000000000..f47e0b7301 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/shared.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "filename" : "shared_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "shared_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/share/shared.imageset/shared_dark.svg b/iOSClient/IonosImages.xcassets/share/shared.imageset/shared_dark.svg new file mode 100644 index 0000000000..93e5eb179b --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/shared.imageset/shared_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/shared.imageset/shared_light.svg b/iOSClient/IonosImages.xcassets/share/shared.imageset/shared_light.svg new file mode 100644 index 0000000000..b6eb6a8505 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/shared.imageset/shared_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/Contents.json new file mode 100644 index 0000000000..f6a2f1f63c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "sq_l.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "sq_drk.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_drk.svg b/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_drk.svg new file mode 100644 index 0000000000..d1fa673b78 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_drk.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_l.svg b/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_l.svg new file mode 100644 index 0000000000..558fbc8fc1 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_l.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/iOSClient/IonosImages.xcassets/share/threeDots.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/threeDots.imageset/Contents.json new file mode 100644 index 0000000000..f58aa0a9cd --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/threeDots.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "threeDots_lights.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "threeDots_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_dark.svg b/iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_dark.svg new file mode 100644 index 0000000000..defd48728a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_lights.svg b/iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_lights.svg new file mode 100644 index 0000000000..3ebec761cc --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_lights.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/userContacts.imageset/Contents.json b/iOSClient/IonosImages.xcassets/share/userContacts.imageset/Contents.json new file mode 100644 index 0000000000..0c49af404c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/userContacts.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "userContacts_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "userContacts_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_dark.svg b/iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_dark.svg new file mode 100644 index 0000000000..eff06a4270 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_light.svg b/iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_light.svg new file mode 100644 index 0000000000..5091ab6757 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/shares.imageset/Contents.json b/iOSClient/IonosImages.xcassets/shares.imageset/Contents.json new file mode 100644 index 0000000000..489053d91a --- /dev/null +++ b/iOSClient/IonosImages.xcassets/shares.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "shares.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/shares.imageset/shares.svg b/iOSClient/IonosImages.xcassets/shares.imageset/shares.svg new file mode 100644 index 0000000000..a536b5b310 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/shares.imageset/shares.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOSClient/IonosImages.xcassets/uploadFile.imageset/Contents.json b/iOSClient/IonosImages.xcassets/uploadFile.imageset/Contents.json new file mode 100644 index 0000000000..acd1e0ab0c --- /dev/null +++ b/iOSClient/IonosImages.xcassets/uploadFile.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "uploadFile.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/uploadFile.imageset/uploadFile.svg b/iOSClient/IonosImages.xcassets/uploadFile.imageset/uploadFile.svg new file mode 100644 index 0000000000..0dd4ada493 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/uploadFile.imageset/uploadFile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/userAvatar.imageset/Contents.json b/iOSClient/IonosImages.xcassets/userAvatar.imageset/Contents.json new file mode 100644 index 0000000000..232e34b25e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/userAvatar.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "filename" : "userAvatar_light.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "userAvatar_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_dark.svg b/iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_dark.svg new file mode 100644 index 0000000000..423ce1423e --- /dev/null +++ b/iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_light.svg b/iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_light.svg new file mode 100644 index 0000000000..5c9aa259d4 --- /dev/null +++ b/iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOSClient/Login/NCLogin.storyboard b/iOSClient/Login/NCLogin.storyboard index 981eadcc58..e3e08286d1 100644 --- a/iOSClient/Login/NCLogin.storyboard +++ b/iOSClient/Login/NCLogin.storyboard @@ -4,9 +4,8 @@ - + - @@ -18,134 +17,128 @@ - - - - - - + + - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - + + - + + + - + @@ -157,55 +150,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + + + + + + + + + diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index 892d88885d..32e484a004 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -11,15 +11,13 @@ import SwiftUI import SafariServices class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { - @IBOutlet weak var imageBrand: UIImageView! - @IBOutlet weak var imageBrandConstraintY: NSLayoutConstraint! - @IBOutlet weak var baseUrlTextField: UITextField! - @IBOutlet weak var loginAddressDetail: UILabel! - @IBOutlet weak var loginButton: UIButton! - @IBOutlet weak var qrCode: UIButton! - @IBOutlet weak var certificate: UIButton! - @IBOutlet weak var enforceServersButton: UIButton! - @IBOutlet weak var enforceServersDropdownImage: UIImageView! + + @IBOutlet weak var loginButton: PrimaryButton! + @IBOutlet weak var qrCode: SecondaryButton! + @IBOutlet weak var lblWelcome: UILabel! + @IBOutlet weak var lblDescription: UILabel! + @IBOutlet weak var loginContentView: UIView! + @IBOutlet weak var spinner: UIActivityIndicatorView! private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)! private var textColor: UIColor = .white @@ -51,56 +49,32 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { override func viewDidLoad() { super.viewDidLoad() - // Text color - if NCBrandColor.shared.customer.isTooLight() { - textColor = .black - textColorOpponent = .white - } else if NCBrandColor.shared.customer.isTooDark() { - textColor = .white - textColorOpponent = .black - } else { - textColor = .white - textColorOpponent = .black - } + self.overrideUserInterfaceStyle = .dark - // Image Brand - imageBrand.image = UIImage(named: "logo") + // Login Button + loginButton.setTitle(NSLocalizedString("_log_in_", comment: ""), for: .normal) - // Url - baseUrlTextField.textColor = textColor - baseUrlTextField.tintColor = textColor - baseUrlTextField.layer.cornerRadius = 10 - baseUrlTextField.layer.borderWidth = 1 - baseUrlTextField.layer.borderColor = textColor.cgColor - baseUrlTextField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 15, height: baseUrlTextField.frame.height)) - baseUrlTextField.leftViewMode = .always - baseUrlTextField.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: baseUrlTextField.frame.height)) - baseUrlTextField.rightViewMode = .always - baseUrlTextField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("_login_url_", comment: ""), attributes: [NSAttributedString.Key.foregroundColor: textColor.withAlphaComponent(0.5)]) - baseUrlTextField.delegate = self + // qrcode + qrCode.setTitle(NSLocalizedString("_login_with_qrcode_", tableName: nil, bundle: Bundle.main, value: "Scan QR code", comment: ""), for: .normal) - baseUrlTextField.isEnabled = !NCBrandOptions.shared.disable_request_login_url + // Labels + lblWelcome.text = NSLocalizedString("_login_welcome_", tableName: nil, bundle: Bundle.main, value: "Welcome to the cloud storage", comment: "") + lblDescription.text = NSLocalizedString("_login_description_", tableName: nil, bundle: Bundle.main, value: "You need to login over browser", comment: "") - // Login button - loginAddressDetail.textColor = textColor - loginAddressDetail.text = String.localizedStringWithFormat(NSLocalizedString("_login_address_detail_", comment: ""), NCBrandOptions.shared.brand) + // Navigation Controller + navigationController?.isNavigationBarHidden = true - // QR code button - qrCode.tintColor = NCBrandColor.shared.customer.isTooLight() ? .black : .white + if !NCManageDatabase.shared.getAllTableAccount().isEmpty { + let navigationItemCancel = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(self.actionCancel)) + navigationItemCancel.tintColor = textColor + navigationItem.leftBarButtonItem = navigationItemCancel + } // brand if NCBrandOptions.shared.disable_request_login_url { - baseUrlTextField.isEnabled = false - baseUrlTextField.isUserInteractionEnabled = false - baseUrlTextField.alpha = 0.5 urlBase = NCBrandOptions.shared.loginBaseUrl } - // certificate - certificate.setImage(UIImage(named: "certificate")?.image(color: textColor, size: 100), for: .normal) - certificate.isHidden = true - certificate.isEnabled = false - // navigation let navBarAppearance = UINavigationBarAppearance() navBarAppearance.configureWithTransparentBackground() @@ -138,38 +112,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") view.backgroundColor = NCBrandColor.shared.customer - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - handleLoginWithAppConfig() - baseUrlTextField.text = urlBase - - enforceServersButton.setTitle(NSLocalizedString("_select_server_", comment: ""), for: .normal) - - let enforceServers = NCBrandOptions.shared.enforce_servers - - if !enforceServers.isEmpty { - baseUrlTextField.isHidden = true - enforceServersDropdownImage.isHidden = false - enforceServersButton.isHidden = false - - let actions = enforceServers.map { server in - UIAction(title: server.name, handler: { [self] _ in - enforceServersButton.setTitle(server.name, for: .normal) - baseUrlTextField.text = server.url - }) - } - - enforceServersButton.layer.cornerRadius = 10 - enforceServersButton.menu = .init(title: NSLocalizedString("_servers_", comment: ""), children: actions) - enforceServersButton.showsMenuAsPrimaryAction = true - enforceServersButton.configuration?.titleTextAttributesTransformer = - UIConfigurationTextAttributesTransformer { incoming in - var outgoing = incoming - outgoing.font = UIFont.systemFont(ofSize: 13) - return outgoing - } - } NCNetworking.shared.certificateDelegate = self } @@ -249,27 +192,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { self.activeTextField = textField } - // MARK: - Keyboard notification - - @objc internal func keyboardWillShow(_ notification: Notification?) { - activeTextfieldDiff = 0 - if let info = notification?.userInfo, let centerObject = self.activeTextField.superview?.convert(self.activeTextField.center, to: nil) { - - let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey - if let keyboardFrame = info[frameEndUserInfoKey] as? CGRect { - let diff = keyboardFrame.origin.y - centerObject.y - self.activeTextField.frame.height - if diff < 0 { - activeTextfieldDiff = diff - imageBrandConstraintY.constant += diff - } - } - } - } - - @objc func keyboardWillHide(_ notification: Notification) { - imageBrandConstraintY.constant -= activeTextfieldDiff - } - // MARK: - Action @objc func actionCancel(_ sender: Any?) { @@ -277,6 +199,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } @IBAction func actionButtonLogin(_ sender: Any) { + spinner.startAnimating() NCNetworking.shared.p12Data = nil NCNetworking.shared.p12Password = nil login() @@ -287,10 +210,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { qrCode.scan() } - @IBAction func actionCertificate(_ sender: Any) { - - } - // MARK: - Share accounts View Controller @objc func openShareAccountsViewController(_ sender: Any?) { @@ -312,7 +231,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { // MARK: - Login private func login() { - guard var url = baseUrlTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) else { return } + var url = urlBase if url.hasSuffix("/") { url = String(url.dropLast()) } if url.isEmpty { return } @@ -320,7 +239,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { if url.hasPrefix("https") == false && url.hasPrefix("http") == false { url = "https://" + url } - self.baseUrlTextField.text = url isUrlValid(url: url) } @@ -350,6 +268,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } } case .failure(let error): + spinner.stopAnimating() loginButton.hideSpinnerAndShowButton() loginButton.isEnabled = true @@ -482,7 +401,6 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { alertEnterPassword.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in NCNetworking.shared.p12Data = try? Data(contentsOf: urls[0]) NCNetworking.shared.p12Password = alertEnterPassword.textFields?[0].text - self.login() })) alertEnterPassword.addTextField { textField in textField.isSecureTextEntry = true @@ -507,6 +425,7 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { extension NCLogin: NCLoginProviderDelegate { func onBack() { + spinner.stopAnimating() loginButton.isEnabled = true loginButton.hideSpinnerAndShowButton() activeLoginProvider?.cancel() diff --git a/iOSClient/Login/NCLoginNavigationController.swift b/iOSClient/Login/NCLoginNavigationController.swift new file mode 100644 index 0000000000..6774bb1e17 --- /dev/null +++ b/iOSClient/Login/NCLoginNavigationController.swift @@ -0,0 +1,28 @@ +// +// NCLoginNavigationController.swift +// Nextcloud +// +// Created by Marino Faggiana on 30/11/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +import Foundation +import UIKit + +class NCLoginNavigationController: UINavigationController { +} diff --git a/iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.swift b/iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.swift new file mode 100644 index 0000000000..656d7f8419 --- /dev/null +++ b/iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.swift @@ -0,0 +1,160 @@ +// +// FileActionsHeader.swift +// Nextcloud +// +// Created by Vitaliy Tolkach on 23.08.2024. +// Copyright © 2024 STRATO GmbH +// + +import UIKit + +enum FileActionsHeaderSelectionState { + case none + case some(Int) + case all +} + +class FileActionsHeader: UIView { + @IBOutlet weak var contentView: UIView! + + // MARK: - non-editign mode view + @IBOutlet weak private var vHeaderNonEditingMode: UIView? + @IBOutlet weak private var btnSort: UIButton? + @IBOutlet weak private var btnSelect: UIButton? + @IBOutlet weak private var btnViewMode: UIButton? + + @IBAction func onBtnSelectTap(_ sender: Any) { + setIsEditingMode(isEditingMode: true) + onSelectModeChange?(true) + } + + // MARK: - editign mode view + @IBOutlet weak private var vHeaderEditingMode: UIView? + @IBOutlet weak private var btnSelectAll: UIButton? + @IBOutlet weak private var btnCloseSelection: UIButton? + @IBOutlet weak private var lblSelectionDescription: UILabel? + + private var grayButtonTintColor: UIColor { + UIColor(resource: .FileActionsHeader.grayButtonTint) + } + + @IBAction func onBtnSelectAllTap(_ sender: Any) { + onSelectAll?() + } + + @IBAction func onBtnCloseSelectionTap(_ sender: Any) { + setIsEditingMode(isEditingMode: false) + onSelectModeChange?(false) + } + + + override init(frame: CGRect) { + super.init(frame: frame) + commonInit() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + commonInit() + } + + private func commonInit() { + Bundle.main.loadNibNamed(String(describing:FileActionsHeader.self), + owner: self, + options: nil) + addSubview(contentView) + contentView.backgroundColor = NCBrandColor.shared.appBackgroundColor + contentView.frame = bounds + contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + } + + // MARK: - public + func enableSorting(enable: Bool) { + btnSort?.isHidden = !enable + } + + func enableSelection(enable: Bool) { + btnSelect?.isHidden = !enable + } + + var onSelectModeChange: ((_ isSelectionMode: Bool) -> Void)? + var onSelectAll: (() -> Void)? + + func setSortingMenu(sortingMenuElements: [UIMenuElement], title: String?, image: UIImage?) { + btnSort?.menu = UIMenu(children: sortingMenuElements) + btnSort?.showsMenuAsPrimaryAction = true + btnSort?.setTitle(title, for: .normal) + btnSort?.setImage(image?.templateRendered(), for: .normal) + btnSort?.semanticContentAttribute = UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft + } + + func setViewModeMenu(viewMenuElements: [UIMenuElement], image: UIImage?) { + btnViewMode?.menu = UIMenu(children: viewMenuElements) + btnViewMode?.showsMenuAsPrimaryAction = true + btnViewMode?.setImage(image?.templateRendered(), for: .normal) + } + + func showViewModeButton(_ show: Bool) { + btnViewMode?.isHidden = !show + } + + func setIsEditingMode(isEditingMode: Bool) { + vHeaderEditingMode?.isHidden = !isEditingMode + vHeaderNonEditingMode?.isHidden = isEditingMode + } + + func setSelectionState(selectionState: FileActionsHeaderSelectionState) { + var textDescription = "" + var imageResource: ImageResource = .FileSelection.listItemDeselected + var selectAllImageColor: UIColor = .clear + + // MARK: Files Header + switch selectionState { + case .none: + textDescription = NSLocalizedString("_select_selectionLabel_selectAll_", tableName: nil, bundle: Bundle.main, value: "select all", comment: "") + imageResource = .FileSelection.listItemDeselected + selectAllImageColor = grayButtonTintColor + case .some(let count): + textDescription = selectionDescription(for: count) + imageResource = .FileSelection.listItemSomeSelected + selectAllImageColor = NCBrandColor.shared.brandElement + case .all: + textDescription = NSLocalizedString("_select_selectionLabel_deselectAll_", tableName: nil, bundle: Bundle.main, value: "deselect all", comment: "") + imageResource = .FileSelection.listItemSelected + selectAllImageColor = NCBrandColor.shared.brandElement + } + + lblSelectionDescription?.text = textDescription + + var selectAllImage = UIImage(resource: imageResource) + var closeImage = UIImage(resource: .FileSelection.selectionModeClose) + + closeImage = closeImage.withTintColor(grayButtonTintColor) + selectAllImage = selectAllImage.withTintColor(selectAllImageColor) + + btnSelectAll?.setBackgroundImage(selectAllImage, for: .normal) + btnCloseSelection?.setBackgroundImage(closeImage, for: .normal) + + func selectionDescription(for count: Int) -> String { + if count == 1 { + return NSLocalizedString("_select_selectionLabel_oneItemSelected_", tableName: nil, bundle: Bundle.main, value: "one item selected", comment: "") + } + return String.localizedStringWithFormat(NSLocalizedString("_select_selectionLabel_manyItemsSelected_", tableName: nil, bundle: Bundle.main, value: "%@ items selected", comment: ""), "\(count)") + } + } + + override func awakeFromNib() { + super.awakeFromNib() + if let selectionButtonWidth = btnSelect?.bounds.width { + btnSelect?.layer.cornerRadius = selectionButtonWidth / 2 + } + btnSelect?.imageView?.contentMode = .scaleToFill + btnSelect?.setImage(UIImage(resource: .FileSelection.filesSelection), for: .normal) + } +} + +extension UIImage { + func templateRendered() -> UIImage? { + self.withRenderingMode(.alwaysTemplate) + } +} diff --git a/iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.xib b/iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.xib new file mode 100644 index 0000000000..c8fda03430 --- /dev/null +++ b/iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.xib @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Main/Collection Common/Cell/ItemShareState.swift b/iOSClient/Main/Collection Common/Cell/ItemShareState.swift new file mode 100644 index 0000000000..60ffc65d44 --- /dev/null +++ b/iOSClient/Main/Collection Common/Cell/ItemShareState.swift @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2026 Serhii Kaliberda +// SPDX-License-Identifier: GPL-3.0-or-later + +import NextcloudKit + +enum ItemShareState { + case notShared + case sharedOnMe + case sharedInternally + case sharedByLink + + static func state(by metadata: tableMetadata, isShare: Bool) -> ItemShareState { + if isShare { + return .sharedOnMe + } + + if metadata.shareType.isEmpty { + return .notShared + } + + if metadata.shareType.contains(NKShare.ShareType.publicLink.rawValue) { + return .sharedByLink + } + + return .sharedInternally + } + + var iconImage: UIImage { + let imageCache = NCImageCache.shared + switch self { + case .notShared: return imageCache.getImageCanShare() + case .sharedOnMe: return imageCache.getIconSharedWithMe() + case .sharedInternally: return imageCache.getIconSharedInternally() + case .sharedByLink: return imageCache.getIconSharedByLink() + } + } + + var folderImage: UIImage { + let imageCache = NCImageCache.shared + switch self { + case .notShared: return imageCache.getFolder() + case .sharedOnMe: return imageCache.getFolderSharedWithMe() + case .sharedInternally: return imageCache.getFolderSharedInternally() + case .sharedByLink: return imageCache.getFolderSharedByLink() + } + } +} diff --git a/iOSClient/Main/Collection Common/Cell/NCCellMain.swift b/iOSClient/Main/Collection Common/Cell/NCCellMain.swift index 82d5d1b68b..d553074069 100644 --- a/iOSClient/Main/Collection Common/Cell/NCCellMain.swift +++ b/iOSClient/Main/Collection Common/Cell/NCCellMain.swift @@ -89,16 +89,11 @@ extension NCCollectionViewCommon { isMounted: Bool) { let tblDirectory = database.getTableDirectory(ocId: metadata.ocId) + let canHaveShareIcon = isShare || !metadata.shareType.isEmpty if metadata.e2eEncrypted { cell.previewImg?.image = imageCache.getFolderEncrypted(account: metadata.account) - } else if isShare { - cell.previewImg?.image = imageCache.getFolderSharedWithMe(account: metadata.account) - } else if !metadata.shareType.isEmpty { - metadata.shareType.contains(NKShare.ShareType.publicLink.rawValue) ? - (cell.previewImg?.image = imageCache.getFolderPublic(account: metadata.account)) : - (cell.previewImg?.image = imageCache.getFolderSharedWithMe(account: metadata.account)) - } else if !metadata.shareType.isEmpty && metadata.shareType.contains(NKShare.ShareType.publicLink.rawValue) { - cell.previewImg?.image = imageCache.getFolderPublic(account: metadata.account) + } else if canHaveShareIcon { + cell.previewImg?.image = ItemShareState.state(by: metadata, isShare: isShare).folderImage } else if metadata.mountType == "group" { cell.previewImg?.image = imageCache.getFolderGroup(account: metadata.account) } else if isMounted { diff --git a/iOSClient/Main/Collection Common/Cell/NCCellMedia.swift b/iOSClient/Main/Collection Common/Cell/NCCellMedia.swift new file mode 100644 index 0000000000..2498e7c915 --- /dev/null +++ b/iOSClient/Main/Collection Common/Cell/NCCellMedia.swift @@ -0,0 +1,13 @@ +// +// NCCellMedia.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 09.01.2026. +// Copyright © 2026 STRATO GmbH. All rights reserved. +// + +#if !EXTENSION +protocol NCCellMedia { + func setupPlaybackProgress(visible: Bool) +} +#endif diff --git a/iOSClient/Main/Collection Common/Cell/NCGridCell.swift b/iOSClient/Main/Collection Common/Cell/NCGridCell.swift index 50f4b187f3..098feeac03 100644 --- a/iOSClient/Main/Collection Common/Cell/NCGridCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCGridCell.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2018 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -6,6 +7,7 @@ import Foundation import UIKit import NextcloudKit import RealmSwift +import Combine protocol NCGridCellDelegate: AnyObject { func onMenuIntent(with metadata: tableMetadata?) @@ -27,6 +29,11 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP @IBOutlet weak var imageVisualEffect: UIVisualEffectView! @IBOutlet weak var iconsStackView: UIStackView! + @IBOutlet weak var progressView: UIProgressView! + + #if !EXTENSION + private var playbackProgressView = PlaybackProgressView() + #endif weak var delegate: NCGridCellDelegate? @@ -79,8 +86,9 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP imageItem.image = nil imageItem.layer.cornerRadius = 6 imageItem.layer.masksToBounds = true + imageSelect.isHidden = true - imageSelect.image = NCImageCache.shared.getImageCheckedYes() + imageSelect.image = UIImage(resource: .FileSelection.gridItemSelected) imageStatus.image = nil imageFavorite.image = nil imageLocal.image = nil @@ -89,18 +97,22 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP labelInfo.text = "" labelSubinfo.text = "" - imageVisualEffect.layer.cornerRadius = 6 - imageVisualEffect.clipsToBounds = true - imageVisualEffect.alpha = 0.5 - - iconsStackView.addBlurBackground(style: .systemMaterial) - iconsStackView.layer.cornerRadius = 8 - iconsStackView.clipsToBounds = true - buttonMore.menu = nil buttonMore.showsMenuAsPrimaryAction = true - contentView.bringSubviewToFront(buttonMore) + + #if !EXTENSION + if playbackProgressView.superview == nil { + addSubview(playbackProgressView) + playbackProgressView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + playbackProgressView.leadingAnchor.constraint(equalTo: progressView.leadingAnchor), + playbackProgressView.trailingAnchor.constraint(equalTo: progressView.trailingAnchor), + playbackProgressView.topAnchor.constraint(equalTo: progressView.topAnchor), + playbackProgressView.bottomAnchor.constraint(equalTo: progressView.bottomAnchor) + ]) + } + #endif } override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { @@ -123,21 +135,15 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP buttonMore.isHidden = status } - func selected(_ status: Bool, isEditMode: Bool) { + func selected(_ isSelected: Bool, isEditMode: Bool) { if isEditMode { buttonMore.isHidden = true accessibilityCustomActions = nil } else { buttonMore.isHidden = false } - if status { - imageSelect.isHidden = false - imageSelect.image = NCImageCache.shared.getImageCheckedYes() - imageVisualEffect.isHidden = false - } else { - imageSelect.isHidden = true - imageVisualEffect.isHidden = true - } + setBorderForGridViewCell(isSelected: isSelected) + imageSelect.isHidden = !isSelected } func writeInfoDateSize(date: NSDate, size: Int64) { @@ -156,6 +162,15 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } } +#if !EXTENSION +extension NCGridCell: NCCellMedia { + func setupPlaybackProgress(visible: Bool) { + guard let ocId = metadata?.ocId else { return } + playbackProgressView.setupPlaybackProgress(ocId: ocId, visible: visible) + } +} +#endif + // MARK: - Grid Layout class NCGridLayout: UICollectionViewFlowLayout { diff --git a/iOSClient/Main/Collection Common/Cell/NCGridCell.xib b/iOSClient/Main/Collection Common/Cell/NCGridCell.xib index b5cacdc258..140763ff50 100644 --- a/iOSClient/Main/Collection Common/Cell/NCGridCell.xib +++ b/iOSClient/Main/Collection Common/Cell/NCGridCell.xib @@ -1,9 +1,8 @@ - + - - + @@ -11,36 +10,49 @@ - + - + - + - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + - - - - - - - + + + + + + - + - - + - + - - - + + + + - - - diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.swift b/iOSClient/Main/Collection Common/Cell/NCListCell.swift index df8de370c8..4d67ae9abb 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2018 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -21,11 +22,11 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP @IBOutlet weak var imageLocal: UIImageView! @IBOutlet weak var imageShared: UIImageView! @IBOutlet weak var imageMore: UIImageView! + @IBOutlet weak var progressView: UIProgressView! @IBOutlet weak var labelTitle: UILabel! @IBOutlet weak var labelInfo: UILabel! @IBOutlet weak var labelSubinfo: UILabel! - @IBOutlet weak var labelInfoSeparator: UILabel! @IBOutlet weak var tag0: UILabel! @IBOutlet weak var tag1: UILabel! @@ -36,6 +37,15 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP @IBOutlet weak var imageItemLeftConstraint: NSLayoutConstraint! @IBOutlet weak var separatorHeightConstraint: NSLayoutConstraint! @IBOutlet weak var titleTrailingConstraint: NSLayoutConstraint! + @IBOutlet weak var subInfoTrailingConstraint: NSLayoutConstraint! + + #if !EXTENSION + private var playbackProgressView = PlaybackProgressView() + #endif + + var separatorBackground: UIColor? { + UIColor(named: "ListCell/Separator") + } weak var delegate: NCListCellDelegate? @@ -47,7 +57,9 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } var avatarImg: UIImageView? { get { return imageShared } - set { imageShared = newValue } + set { + imageShared = newValue + } } var previewImg: UIImageView? { get { return imageItem } @@ -115,17 +127,37 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP labelTitle.text = "" labelInfo.text = "" labelSubinfo.text = "" - labelInfoSeparator.text = "" tag0.text = "" tag1.text = "" - separatorHeightConstraint.constant = 0.5 + separator.backgroundColor = separatorBackground + separatorHeightConstraint.constant = 1 buttonMore.menu = nil buttonMore.showsMenuAsPrimaryAction = true titleTrailingConstraint.constant = 90 + labelTitle.text = "" + labelInfo.text = "" + labelSubinfo.text = "" + labelTitle.textColor = UIColor(resource: .ListCell.title) + labelInfo.textColor = UIColor(resource: .ListCell.subtitle) + labelSubinfo.textColor = UIColor(resource: .ListCell.subtitle) + + #if !EXTENSION + if playbackProgressView.superview == nil { + addSubview(playbackProgressView) + playbackProgressView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + playbackProgressView.leadingAnchor.constraint(equalTo: progressView.leadingAnchor), + playbackProgressView.trailingAnchor.constraint(equalTo: progressView.trailingAnchor), + playbackProgressView.topAnchor.constraint(equalTo: progressView.topAnchor), + playbackProgressView.bottomAnchor.constraint(equalTo: progressView.bottomAnchor) + ]) + } + #endif + contentView.bringSubviewToFront(buttonMore) } @@ -186,21 +218,12 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP buttonMore.isHidden = false backgroundView = nil } + if status { - var blurEffectView: UIView? - blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) - blurEffectView?.backgroundColor = .lightGray - blurEffectView?.frame = self.bounds - blurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - imageSelect.image = NCImageCache.shared.getImageCheckedYes() - backgroundView = blurEffectView - separator.isHidden = true + imageSelect.image = NCImageCache.shared.getImageCheckedYes().withTintColor(NCBrandColor.shared.brandElement) } else { - imageSelect.image = NCImageCache.shared.getImageCheckedNo() - backgroundView = nil - separator.isHidden = false + imageSelect.image = NCImageCache.shared.getImageCheckedNo().withTintColor(UIColor(resource: .FileSelection.listItemDeselected)) } - } func writeInfoDateSize(date: NSDate, size: Int64) { @@ -219,13 +242,11 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP tag1.isHidden = true labelInfo.isHidden = false labelSubinfo.isHidden = false - labelInfoSeparator.isHidden = false } else { tag0.isHidden = false tag1.isHidden = true labelInfo.isHidden = true labelSubinfo.isHidden = true - labelInfoSeparator.isHidden = true if let tag = tags.first { tag0.text = tag @@ -238,29 +259,10 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } func setIconOutlines() { - [imageStatus, imageLocal].forEach { imageView in - imageView.makeCircularBackground(withColor: imageView.image != nil ? .systemBackground : .clear) - } - - if imageFavorite.image != nil { - let outlineView = UIImageView() - outlineView.translatesAutoresizingMaskIntoConstraints = false - outlineView.image = UIImage(systemName: "star") - outlineView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(pointSize: 16, weight: .thin) - outlineView.tintColor = .systemBackground - - imageFavorite.addSubview(outlineView) - NSLayoutConstraint.activate([ - outlineView.leadingAnchor.constraint(equalTo: imageFavorite.leadingAnchor, constant: -1), - outlineView.trailingAnchor.constraint(equalTo: imageFavorite.trailingAnchor, constant: 1), - outlineView.topAnchor.constraint(equalTo: imageFavorite.topAnchor, constant: -1), - outlineView.bottomAnchor.constraint(equalTo: imageFavorite.bottomAnchor, constant: 1) - ]) - imageFavorite.sendSubviewToBack(outlineView) + if imageStatus.image != nil { + imageStatus.makeCircularBackground(withColor: .systemBackground) } else { - imageFavorite.subviews.forEach { view in - view.removeFromSuperview() - } + imageStatus.backgroundColor = .clear } } @@ -276,10 +278,21 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } } +#if !EXTENSION +extension NCListCell: NCCellMedia { + func setupPlaybackProgress(visible: Bool) { + guard let ocId = metadata?.ocId else { + return + } + playbackProgressView.setupPlaybackProgress(ocId: ocId, visible: visible) + } +} +#endif + // MARK: - List Layout class NCListLayout: UICollectionViewFlowLayout { - var itemHeight: CGFloat = 60 + var itemHeight: CGFloat = 64 override init() { super.init() @@ -456,15 +469,7 @@ extension NCCollectionViewCommon { } // Share image - if isShare { - cell.imageShared?.image = imageCache.getImageShared() - } else if !metadata.shareType.isEmpty { - metadata.shareType.contains(NKShare.ShareType.publicLink.rawValue) ? - (cell.imageShared?.image = imageCache.getImageShareByLink()) : - (cell.imageShared?.image = imageCache.getImageShared()) - } else { - cell.imageShared?.image = imageCache.getImageCanShare() - } + cell.imageShared?.image = ItemShareState.state(by: metadata, isShare: isShare).iconImage // Button More if metadata.lock == true { @@ -484,21 +489,22 @@ extension NCCollectionViewCommon { cell.avatarImg?.contentMode = .scaleAspectFill cell.avatarImg?.image = image } else { - self.database.getImageAvatarLoaded(fileName: fileName) { image, tblAvatar in - if let image { - cell.avatarImg?.contentMode = .scaleAspectFill - cell.avatarImg?.image = image - NCImageCache.shared.addImageCache(image: image, key: fileName) - } else { - cell.avatarImg?.contentMode = .scaleAspectFill - cell.avatarImg?.image = self.utility.loadUserImage(for: metadata.ownerId, displayName: metadata.ownerDisplayName, urlBase: metadata.urlBase) - } - - if !(tblAvatar?.loaded ?? false), - self.networking.downloadAvatarQueue.operations.filter({ ($0 as? NCOperationDownloadAvatar)?.fileName == fileName }).isEmpty { - self.networking.downloadAvatarQueue.addOperation(NCOperationDownloadAvatar(user: metadata.ownerId, fileName: fileName, account: metadata.account, view: self.collectionView)) - } - } +// MERGE: HiDrive Next doesn't show avatar +// self.database.getImageAvatarLoaded(fileName: fileName) { image, tblAvatar in +// if let image { +// cell.avatarImg?.contentMode = .scaleAspectFill +// cell.avatarImg?.image = image +// NCImageCache.shared.addImageCache(image: image, key: fileName) +// } else { +// cell.avatarImg?.contentMode = .scaleAspectFill +// cell.avatarImg?.image = self.utility.loadUserImage(for: metadata.ownerId, displayName: metadata.ownerDisplayName, urlBase: metadata.urlBase) +// } +// +// if !(tblAvatar?.loaded ?? false), +// self.networking.downloadAvatarQueue.operations.filter({ ($0 as? NCOperationDownloadAvatar)?.fileName == fileName }).isEmpty { +// self.networking.downloadAvatarQueue.addOperation(NCOperationDownloadAvatar(user: metadata.ownerId, fileName: fileName, account: metadata.account, view: self.collectionView)) +// } +// } } } @@ -543,11 +549,6 @@ extension NCCollectionViewCommon { // TAGS cell.setTags(tags: Array(metadata.tags)) - // SearchingMode - TAG Separator Hidden - if isSearchingMode { - cell.labelInfoSeparator.isHidden = true - } - // Hide buttons if metadata.name != global.appName { cell.titleInfoTrailingFull() diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.xib b/iOSClient/Main/Collection Common/Cell/NCListCell.xib index be2b91f06c..dfe5a88eb9 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.xib +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.xib @@ -1,125 +1,123 @@ - + - + + + - - + + - + - - + + - - + + - + - - + + - - + + + - - + + - - + + + - - + + - + - + + - - - + + + + + + - - - - - - + + + + + - + + + - - + - + + + + - - @@ -224,11 +228,12 @@ - + + @@ -237,19 +242,12 @@ - - - - - - - - + - + - + diff --git a/iOSClient/Main/Collection Common/Cell/PlaybackProgressView.swift b/iOSClient/Main/Collection Common/Cell/PlaybackProgressView.swift new file mode 100644 index 0000000000..b96cc13dab --- /dev/null +++ b/iOSClient/Main/Collection Common/Cell/PlaybackProgressView.swift @@ -0,0 +1,114 @@ +// +// PlaybackProgressView.swift +// Nextcloud +// +// Created by Auto on 09.01.2026. +// Copyright © 2026 STRATO GmbH. All rights reserved. +// + +#if !EXTENSION +import UIKit +import Combine + +class PlaybackProgressView: UIView { + private let progressView: UIProgressView + private var cancellables = Set() + private var currentOcId: String? + + override init(frame: CGRect) { + progressView = UIProgressView() + super.init(frame: frame) + setupProgressView() + } + + required init?(coder: NSCoder) { + progressView = UIProgressView() + super.init(coder: coder) + setupProgressView() + } + + private func setupProgressView() { + progressView.translatesAutoresizingMaskIntoConstraints = false + addSubview(progressView) + + NSLayoutConstraint.activate([ + progressView.topAnchor.constraint(equalTo: topAnchor), + progressView.leadingAnchor.constraint(equalTo: leadingAnchor), + progressView.trailingAnchor.constraint(equalTo: trailingAnchor), + progressView.bottomAnchor.constraint(equalTo: bottomAnchor) + ]) + + progressView.tintColor = NCBrandColor.shared.brandElement + progressView.trackTintColor = UIColor(resource: .BurgerMenu.progressBarBackground) + progressView.isHidden = true + progressView.progress = 0 + } + + func setupPlaybackProgress(ocId: String, visible: Bool) { + cancellables.removeAll() + currentOcId = ocId + + guard visible else { + progressView.isHidden = true + progressView.progress = 0 + return + } + + let mediaCoordinator = NCMediaCoordinator.shared + + mediaCoordinator.positionPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] position in + guard let self = self else { return } + if self.currentOcId == mediaCoordinator.item?.ocId { + self.progressView.progress = position + self.progressView.isHidden = false + } else { + self.progressView.isHidden = true + self.progressView.progress = 0 + } + } + .store(in: &cancellables) + + mediaCoordinator.metadataSwitchPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] _, newItem in + guard let self = self else { return } + if self.currentOcId == newItem?.ocId { + let currentPosition = mediaCoordinator.position + self.progressView.progress = currentPosition + self.progressView.isHidden = false + } else { + self.progressView.isHidden = true + self.progressView.progress = 0 + } + } + .store(in: &cancellables) + + mediaCoordinator.statePublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] state in + guard let self = self else { return } + if self.currentOcId == mediaCoordinator.item?.ocId { + switch state { + case .stopped, .ended, .error: + self.progressView.isHidden = true + self.progressView.progress = 0 + default: + self.progressView.isHidden = false + } + } + } + .store(in: &cancellables) + + if ocId == mediaCoordinator.item?.ocId { + let currentPosition = mediaCoordinator.position + progressView.progress = currentPosition + progressView.isHidden = false + } else { + progressView.isHidden = true + progressView.progress = 0 + } + } +} +#endif diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon+CollectionViewDelegate.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon+CollectionViewDelegate.swift index abb7b406ec..944d96a25a 100644 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommon+CollectionViewDelegate.swift +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon+CollectionViewDelegate.swift @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2024 Marino Faggiana +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda // SPDX-License-Identifier: GPL-3.0-or-later import Foundation @@ -70,52 +71,67 @@ extension NCCollectionViewCommon: UICollectionViewDelegate { if metadata.directory { pushMetadata(metadata) + } else if metadata.isURL, + let url = URL(string: metadata.serverUrl)?.appendingPathComponent(metadata.url), + UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, completionHandler: nil) } else { - let image = utility.getImage(ocId: metadata.ocId, etag: metadata.etag, ext: self.global.previewExt1024, userId: metadata.userId, urlBase: metadata.urlBase) - let fileExists = utilityFileSystem.fileProviderStorageExists(metadata) - - // --- E2EE ------- - if metadata.isDirectoryE2EE { - if fileExists { - if let vc = await NCViewer().getViewerController(metadata: metadata, delegate: self) { - self.navigationController?.pushViewController(vc, animated: true) + Task { @MainActor in + let image = utility.getImage(ocId: metadata.ocId, etag: metadata.etag, ext: self.global.previewExt1024, userId: metadata.userId, urlBase: metadata.urlBase) + let fileExists = utilityFileSystem.fileProviderStorageExists(metadata) + + // --- E2EE ------- + if metadata.isDirectoryE2EE { + if fileExists { + if let vc = await NCViewer().getViewerController(metadata: metadata, delegate: self) { + self.navigationController?.pushViewController(vc, animated: true) + } + } else { + await downloadFile() } - } else { - await downloadFile() - } - return - } - // --------------- - - if metadata.isImage || metadata.isAudioOrVideo { - let metadatas = self.dataSource.getMetadatas() - let ocIds = metadatas.filter { $0.classFile == NKTypeClassFile.image.rawValue || - $0.classFile == NKTypeClassFile.video.rawValue || - $0.classFile == NKTypeClassFile.audio.rawValue }.map(\.ocId) - - if let vc = await NCViewer().getViewerController(metadata: metadata, ocIds: withOcIds ? ocIds : nil, image: image, delegate: self) { - self.navigationController?.pushViewController(vc, animated: true) - } - } else if !metadata.isDirectoryE2EE, metadata.isAvailableEditorView || utilityFileSystem.fileProviderStorageExists(metadata) || metadata.name == self.global.talkName { - if let vc = await NCViewer().getViewerController(metadata: metadata, image: image, delegate: self) { - self.navigationController?.pushViewController(vc, animated: true) - } - } else if NextcloudKit.shared.isNetworkReachable() { - guard let metadata = await database.setMetadataSessionInWaitDownloadAsync(ocId: metadata.ocId, - session: self.networking.sessionDownload, - selector: global.selectorLoadFileView, - sceneIdentifier: self.controller?.sceneIdentifier) else { return } + // --------------- + + if metadata.isImage || metadata.isAudioOrVideo { + let metadatas = self.dataSource.getMetadatas() + + let siblingMedia: [tableMetadata] + let siblingMetadatasOcIds: [String] + if self.layoutKey == NCGlobal.shared.layoutViewFiles { + siblingMedia = metadatas.filter { $0.classFile == metadata.classFile } + siblingMetadatasOcIds = siblingMedia.map(\.ocId) + } else { + siblingMedia = [metadata] + siblingMetadatasOcIds = metadatas.filter { $0.classFile == NKTypeClassFile.image.rawValue || + $0.classFile == NKTypeClassFile.video.rawValue || + $0.classFile == NKTypeClassFile.audio.rawValue }.map(\.ocId) + } - if metadata.name == "files" { - await downloadFile() - } else if !metadata.url.isEmpty, - let vc = await NCViewer().getViewerController(metadata: metadata, delegate: self) { - self.navigationController?.pushViewController(vc, animated: true) + if let vc = await NCViewer().getViewerController(metadata: metadata, ocIds: withOcIds ? siblingMetadatasOcIds : nil, siblingMedia: siblingMedia, image: image, delegate: self) { + self.navigationController?.pushViewController(vc, animated: true) + } + } else if !metadata.isDirectoryE2EE, metadata.isAvailableEditorView || utilityFileSystem.fileProviderStorageExists(metadata) || metadata.name == self.global.talkName { + if let vc = await NCViewer().getViewerController(metadata: metadata, image: image, delegate: self) { + self.navigationController?.pushViewController(vc, animated: true) + } + } else if NextcloudKit.shared.isNetworkReachable() { + guard let metadata = await database.setMetadataSessionInWaitDownloadAsync(ocId: metadata.ocId, + session: self.networking.sessionDownload, + selector: global.selectorLoadFileView, + sceneIdentifier: self.controller?.sceneIdentifier) else { + return + } + + if metadata.name == "files" { + await downloadFile() + } else if !metadata.url.isEmpty, + let vc = await NCViewer().getViewerController(metadata: metadata, delegate: self) { + self.navigationController?.pushViewController(vc, animated: true) + } + } else { + await showErrorBanner(controller: controller, text: "_go_online_", errorCode: NCGlobal.shared.errorOffline) } - } else { - await showErrorBanner(controller: controller, text: "_go_online_", errorCode: NCGlobal.shared.errorOffline) } } } @@ -134,6 +150,8 @@ extension NCCollectionViewCommon: UICollectionViewDelegate { self.collectionView.reloadItems(at: [indexPath]) self.tabBarSelect?.update(fileSelect: self.fileSelect, metadatas: self.getSelectedMetadatas(), userId: metadata.userId) self.collectionView.collectionViewLayout.invalidateLayout() + + self.fileActionsHeader?.setSelectionState(selectionState: self.selectionState) return } @@ -178,4 +196,8 @@ extension NCCollectionViewCommon: UICollectionViewDelegate { } } } + + func scrollViewDidScroll(_ scrollView: UIScrollView) { + headerTop?.constant = max(0, -scrollView.contentOffset.y) + } } diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon+FileActionsHeader.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon+FileActionsHeader.swift new file mode 100644 index 0000000000..d680cbe1f1 --- /dev/null +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon+FileActionsHeader.swift @@ -0,0 +1,167 @@ +// +// NCCollectionViewCommon+FileActionsHeader.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 28.02.2025. +// Copyright © 2025 STRATO GmbH. All rights reserved. +// + +import Foundation + +extension NCCollectionViewCommon { + // MARK: - Headers view + + func updateHeadersView() { + fileActionsHeader?.isHidden = isSearchingMode + collectionViewTop?.constant = isSearchingMode ? 0 : fileActionsHeader?.bounds.height ?? 0 + fileActionsHeader?.setIsEditingMode(isEditingMode: isEditMode) + fileActionsHeader?.enableSelection(enable: !self.dataSource.isEmpty()) + + fileActionsHeader?.setSortingMenu(sortingMenuElements: createSortMenuActions(), title: sortTitle, image: sortDirectionImage) + fileActionsHeader?.setViewModeMenu(viewMenuElements: createViewModeMenuActions(), image: viewModeImage?.templateRendered()) + + fileActionsHeader?.onSelectModeChange = { [weak self] isSelectionMode in + self?.setEditMode(isSelectionMode) + (self?.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() + self?.updateHeadersView() + self?.fileActionsHeader?.setSelectionState(selectionState: .none) + } + + fileActionsHeader?.onSelectAll = { [weak self] in + guard let self = self else { return } + self.selectAll() + let selectionState: FileActionsHeaderSelectionState = self.fileSelect.count == 0 ? .none : .all + self.fileActionsHeader?.setSelectionState(selectionState: selectionState) + } + } + + private func createSortMenuActions() -> [UIMenuElement] { + let layoutForView = NCManageDatabase.shared.getLayoutForView(account: session.account, key: layoutKey, serverUrl: serverUrl) + + let ascending = layoutForView.ascending + let ascendingChevronImage = utility.loadImage(named: ascending ? "chevron.up" : "chevron.down") + let isName = layoutForView.sort == "fileName" + let isDate = layoutForView.sort == "date" + let isSize = layoutForView.sort == "size" + + let byName = UIAction(title: NSLocalizedString("_name_", comment: ""), image: isName ? ascendingChevronImage : nil, state: isName ? .on : .off) { [weak self] _ in + if isName { // repeated press + layoutForView.ascending = !layoutForView.ascending + } + layoutForView.sort = "fileName" + self?.notifyAboutLayoutChange(layoutForView) + } + + let byNewest = UIAction(title: NSLocalizedString("_date_", comment: ""), image: isDate ? ascendingChevronImage : nil, state: isDate ? .on : .off) { [weak self] _ in + if isDate { // repeated press + layoutForView.ascending = !layoutForView.ascending + } + layoutForView.sort = "date" + self?.notifyAboutLayoutChange(layoutForView) + } + + let byLargest = UIAction(title: NSLocalizedString("_size_", comment: ""), image: isSize ? ascendingChevronImage : nil, state: isSize ? .on : .off) { [weak self] _ in + if isSize { // repeated press + layoutForView.ascending = !layoutForView.ascending + } + layoutForView.sort = "size" + self?.notifyAboutLayoutChange(layoutForView) + } + + let sortSubmenu = UIMenu(title: NSLocalizedString("_order_by_", comment: ""), options: .displayInline, children: [byName, byNewest, byLargest]) + + let directoryOnTop = NCPreferences().getDirectoryOnTop(account: self.session.account) + let directoryOnTopAction = UIAction(title: NSLocalizedString("_directory_on_top_", comment: ""), state: directoryOnTop ? .on : .off) { _ in + Task { + NCPreferences().setDirectoryOnTop(account: self.session.account, value: !directoryOnTop) + await NCNetworking.shared.transferDispatcher.notifyAllDelegates { delegate in + delegate.transferReloadDataSource(serverUrl: self.serverUrl, requestData: true, status: nil) + } + } + } + + let additionalSubmenu = UIMenu(title: "", options: .displayInline, children: [directoryOnTopAction]) + return [sortSubmenu, additionalSubmenu] + } + + private func createViewModeMenuActions() -> [UIMenuElement] { + let layoutForView = NCManageDatabase.shared.getLayoutForView(account: session.account, key: layoutKey, serverUrl: serverUrl) + + let listImage = UIImage(resource: .FileSelection.viewModeList).templateRendered() + let gridImage = UIImage(resource: .FileSelection.viewModeGrid).templateRendered() + + let list = UIAction(title: NSLocalizedString("_list_", comment: ""), image: listImage, state: layoutForView.layout == NCGlobal.shared.layoutList ? .on : .off) { _ in + layoutForView.layout = self.global.layoutList + self.notifyAboutLayoutChange(layoutForView) + } + + let grid = UIAction(title: NSLocalizedString("_icons_", comment: ""), image: gridImage, state: layoutForView.layout == NCGlobal.shared.layoutGrid ? .on : .off) { _ in + layoutForView.layout = self.global.layoutGrid + self.notifyAboutLayoutChange(layoutForView) + } + + let menuPhoto = UIMenu(title: "", options: .displayInline, children: [ + UIAction(title: NSLocalizedString("_media_square_", comment: ""), image: gridImage, state: layoutForView.layout == NCGlobal.shared.layoutPhotoSquare ? .on : .off) { _ in + layoutForView.layout = self.global.layoutPhotoSquare + self.notifyAboutLayoutChange(layoutForView) + }, + UIAction(title: NSLocalizedString("_media_ratio_", comment: ""), image: gridImage, state: layoutForView.layout == NCGlobal.shared.layoutPhotoRatio ? .on : .off) { _ in + layoutForView.layout = self.global.layoutPhotoRatio + self.notifyAboutLayoutChange(layoutForView) + } + ]) + + return [list, grid, UIMenu(title: NSLocalizedString("_media_view_options_", comment: ""), children: [menuPhoto])] + } + + private func notifyAboutLayoutChange(_ layoutForView: NCDBLayoutForView) { + changeLayout(layoutForView: layoutForView) + } + + private var sortTitle: String? { + let layoutForView = NCManageDatabase.shared.getLayoutForView(account: session.account, key: layoutKey, serverUrl: serverUrl) + + switch layoutForView.sort { + case "fileName": return NSLocalizedString("_name_", comment: "") + case "date": return NSLocalizedString("_date_", comment: "") + case "size": return NSLocalizedString("_size_", comment: "") + default: return nil + } + } + + private var sortDirectionImage: UIImage? { + let layoutForView = NCManageDatabase.shared.getLayoutForView(account: session.account, key: layoutKey, serverUrl: serverUrl) + let imageName = layoutForView.ascending ? "arrow.up" : "arrow.down" + return UIImage(systemName: imageName, withConfiguration: UIImage.SymbolConfiguration(pointSize: 16, weight: .semibold)) + } + + private var viewModeImage: UIImage? { + var imageResource: ImageResource? + + switch layoutType { + case NCGlobal.shared.layoutList: imageResource = .FileSelection.viewModeList + case NCGlobal.shared.layoutGrid, NCGlobal.shared.layoutPhotoRatio, NCGlobal.shared.layoutPhotoSquare: imageResource = .FileSelection.viewModeGrid + default: break + } + + if let imageResource { + return UIImage(resource: imageResource) + } + return nil + } + + func setNavigationBarLogoIfNeeded() { + if isCurrentScreenInMainTabBar() && self.navigationController?.viewControllers.count == 1 { + setNavigationBarLogo() + } + } + + var selectionState: FileActionsHeaderSelectionState { + let selectedItemsCount = fileSelect.count + if selectedItemsCount == dataSource.getMetadatas().count { + return .all + } + + return selectedItemsCount == 0 ? .none : .some(selectedItemsCount) + } +} diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift index 5de0f83192..238b347e45 100644 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2024 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -6,7 +7,7 @@ import UIKit import Foundation import NextcloudKit -extension NCCollectionViewCommon: NCCollectionViewCommonSelectTabBarDelegate { +extension NCCollectionViewCommon: HiDriveCollectionViewCommonSelectToolbarDelegate { func selectAll() { if !fileSelect.isEmpty, self.dataSource.getMetadatas().count == fileSelect.count { fileSelect = [] @@ -118,25 +119,31 @@ extension NCCollectionViewCommon: NCCollectionViewCommonSelectTabBarDelegate { return selectedMetadatas } - @MainActor - func setEditMode(_ editMode: Bool) async { - isEditMode = editMode - fileSelect.removeAll() + func setEditMode(_ editMode: Bool) { + Task { + isEditMode = editMode + fileSelect.removeAll() - navigationItem.hidesBackButton = editMode - navigationController?.interactivePopGestureRecognizer?.isEnabled = !editMode - searchController(enabled: !editMode) + navigationItem.hidesBackButton = editMode + navigationController?.interactivePopGestureRecognizer?.isEnabled = !editMode + searchController(enabled: !editMode) - // (+) - mainNavigationController?.menuPlus?.hiddenPlusButton(editMode) + if editMode { + navigationItem.leftBarButtonItems = nil + } else { + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationLeftItems() + } + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() - if editMode { - navigationItem.leftBarButtonItems = nil - } else { - await (self.navigationController as? NCMainNavigationController)?.setNavigationLeftItems() + self.collectionView.reloadData() } - await (self.navigationController as? NCMainNavigationController)?.setNavigationRightItems() + } - self.collectionView.reloadData() + func toolbarWillAppear() { + self.tabBarController?.tabBar.isHidden = true + } + + func toolbarWillDisappear() { + self.tabBarController?.tabBar.isHidden = false } } diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift index 17b4515ed4..d26cf46451 100644 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2020 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -12,6 +13,9 @@ import LucidBanner class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, UIGestureRecognizerDelegate, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate, UIAdaptivePresentationControllerDelegate, UIContextMenuInteractionDelegate { @IBOutlet weak var collectionView: UICollectionView! + @IBOutlet weak var headerTop: NSLayoutConstraint? + @IBOutlet weak var collectionViewTop: NSLayoutConstraint? + @IBOutlet weak var fileActionsHeader: FileActionsHeader? internal let database = NCManageDatabase.shared internal let global = NCGlobal.shared @@ -29,7 +33,13 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, internal var searchController: UISearchController? internal var backgroundImageView = UIImageView() internal var serverUrl: String = "" - internal var isEditMode = false + internal var isEditMode = false { + didSet { + DispatchQueue.main.async { [weak self] in + self?.updateHeadersView() + } + } + } internal var isDirectoryE2EE = false internal var fileSelect: [String] = [] internal var metadataFolder: tableMetadata? @@ -44,9 +54,15 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, internal var listLayout = NCListLayout() internal var gridLayout = NCGridLayout() internal var mediaLayout = NCMediaLayout() - internal var layoutType = NCGlobal.shared.layoutList + internal var layoutType = NCGlobal.shared.layoutList { + didSet { + DispatchQueue.main.async { [weak self] in + self?.updateHeadersView() + } + } + } - internal var tabBarSelect: NCCollectionViewCommonSelectTabBar? + internal var tabBarSelect: HiDriveCollectionViewCommonSelectToolbar? internal var attributesZoomIn: UIMenuElement.Attributes = [] internal var attributesZoomOut: UIMenuElement.Attributes = [] @@ -56,7 +72,13 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, // Search // - internal var isSearchingMode: Bool = false + internal var isSearchingMode: Bool = false { + didSet { + DispatchQueue.main.async { [weak self] in + self?.updateHeadersView() + } + } + } internal var networkSearchInProgress: Bool = false internal var searchOperationHandle = NKOperationHandle() internal var searchTask: URLSessionTask? @@ -126,15 +148,15 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, @MainActor internal var controller: NCMainTabBarController? { - self.tabBarController as? NCMainTabBarController + self.mainTabBarController } - internal var mainNavigationController: NCMainNavigationController? { - self.navigationController as? NCMainNavigationController + internal var mainNavigationController: HiDriveMainNavigationController? { + self.navigationController as? HiDriveMainNavigationController } internal var sceneIdentifier: String { - (self.tabBarController as? NCMainTabBarController)?.sceneIdentifier ?? "" + self.mainTabBarController?.sceneIdentifier ?? "" } internal var isNumberOfItemsInAllSectionsNull: Bool { @@ -176,9 +198,9 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, collectionView.alwaysBounceVertical = true collectionView.accessibilityIdentifier = "NCCollectionViewCommon" - view.backgroundColor = .systemBackground - collectionView.backgroundColor = .systemBackground - refreshControl.tintColor = .clear + view.backgroundColor = NCBrandColor.shared.appBackgroundColor + collectionView.backgroundColor = NCBrandColor.shared.appBackgroundColor + refreshControl.tintColor = NCBrandColor.shared.textColor2 definesPresentationContext = true if enableSearchBar { @@ -186,14 +208,14 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, searchController?.searchResultsUpdater = self searchController?.obscuresBackgroundDuringPresentation = false searchController?.delegate = self - - let searchBar = searchController?.searchBar - searchBar?.delegate = self - searchBar?.autocapitalizationType = .none - + searchController?.searchBar.delegate = self + searchController?.searchBar.autocapitalizationType = .none + searchController?.searchBar.searchTextField.backgroundColor = UIColor(resource: .searchBarBackground) + searchController?.searchBar.searchTextField.layer.cornerRadius = 10 + searchController?.searchBar.searchTextField.layer.masksToBounds = true + searchController?.searchBar.setSearchFieldBackgroundImage(UIImage(), for: .normal) navigationItem.searchController = searchController - navigationItem.hidesSearchBarWhenScrolling = false - navigationItem.preferredSearchBarPlacement = .inline + navigationItem.hidesSearchBarWhenScrolling = true } // Cell @@ -225,7 +247,6 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, // Wait 1.5 seconds before resetting the button alpha try? await Task.sleep(for: .seconds(1.5)) - self.mainNavigationController?.menuPlus?.resetPlusButtonAlpha() } } @@ -298,16 +319,17 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, navigationItem.title = titleCurrentFolder if tabBarSelect == nil { - tabBarSelect = NCCollectionViewCommonSelectTabBar(controller: self.controller, viewController: self, delegate: self) + tabBarSelect = HiDriveCollectionViewCommonSelectToolbar(controller: controller, delegate: self) } isEditMode = false + setNavigationBarLogoIfNeeded() Task { await NCNetworking.shared.transferDispatcher.addDelegate(self) - await (self.navigationController as? NCMainNavigationController)?.setNavigationLeftItems() - await (self.navigationController as? NCMainNavigationController)?.setNavigationRightItems() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationLeftItems() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() } layoutForView = database.getLayoutForView(account: session.account, key: layoutKey, serverUrl: serverUrl) @@ -326,6 +348,7 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, } collectionView.reloadData() + updateHeadersView() } override func viewDidAppear(_ animated: Bool) { @@ -333,6 +356,8 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, NotificationCenter.default.addObserver(self, selector: #selector(applicationWillResignActive(_:)), name: UIApplication.willResignActiveNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(closeRichWorkspaceWebView), name: NSNotification.Name(rawValue: global.notificationCenterCloseRichWorkspaceWebView), object: nil) + + tabBarSelect?.controller = controller } override func viewWillDisappear(_ animated: Bool) { @@ -373,6 +398,11 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, return true } + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + tabBarSelect?.onViewWillLayoutSubviews() + } + func presentationControllerDidDismiss( _ presentationController: UIPresentationController) { let viewController = presentationController.presentedViewController @@ -384,7 +414,8 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, // MARK: - NotificationCenter @objc func applicationWillResignActive(_ notification: NSNotification) { - self.mainNavigationController?.menuPlus?.resetPlusButtonAlpha() +// MERGE: HiDrive Next doesn't use new menuPlus in HiDrive Next +// self.mainNavigationController?.menuPlus?.resetPlusButtonAlpha() } @objc func closeRichWorkspaceWebView() { @@ -425,6 +456,10 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, } internal func setLayout(layoutForView: NCDBLayoutForView, withSubFolders: Bool = false) async { + defer { + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() + self.updateHeadersView() + } self.layoutForView = self.database.setLayoutForView(layoutForView: layoutForView, withSubFolders: withSubFolders) layoutForView.layout = layoutForView.layout self.layoutType = layoutForView.layout @@ -485,6 +520,7 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, self.dataSource.setGetServerData(true) self.navigationItem.titleView = nil self.navigationItem.title = self.titleCurrentFolder + setNavigationBarLogoIfNeeded() } // MARK: - SEARCH @@ -510,8 +546,9 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, // TIP dismissTip() - // (+) - self.mainNavigationController?.menuPlus?.hiddenPlusButton(true) +// MERGE: HiDrive Next doesn't use new menuPlus in HiDrive Next +// (+) +// self.mainNavigationController?.menuPlus?.hiddenPlusButton(true) if !isSearchingMode { self.isSearchingMode = true @@ -530,8 +567,9 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { - // (+) - self.mainNavigationController?.menuPlus?.hiddenPlusButton(false) +// MERGE: HiDrive Next doesn't use new menuPlus in HiDrive Next +// // (+) +// self.mainNavigationController?.menuPlus?.hiddenPlusButton(false) self.isSearchingMode = false self.networkSearchInProgress = false @@ -710,7 +748,8 @@ class NCCollectionViewCommon: UIViewController, NCAccountSettingsModelDelegate, delegate.transferReloadData(serverUrl: self.serverUrl) } - await mainNavigationController?.updateMenuOption() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() + self.updateHeadersView() } func getServerData(forced: Bool = false) async { } diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommonSelectTabBar.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommonSelectTabBar.swift deleted file mode 100644 index 0ddda4f4d8..0000000000 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommonSelectTabBar.swift +++ /dev/null @@ -1,229 +0,0 @@ -// SPDX-FileCopyrightText: Nextcloud GmbH -// SPDX-FileCopyrightText: 2024 Marino Faggiana -// SPDX-License-Identifier: GPL-3.0-or-later - -import Foundation -import UIKit -import SwiftUI -import NextcloudKit - -protocol NCCollectionViewCommonSelectTabBarDelegate: AnyObject { - func selectAll() - func delete() - func move() - func share() - func saveAsAvailableOffline(isAnyOffline: Bool) - func lock(isAnyLocked: Bool) -} - -class NCCollectionViewCommonSelectTabBar: ObservableObject { - var controller: NCMainTabBarController? - var hostingController: UIViewController? - open weak var delegate: NCCollectionViewCommonSelectTabBarDelegate? - - @Published var isAnyOffline = false - @Published var canSetAsOffline = false - @Published var isAnyDirectory = false - @Published var isAllDirectory = false - @Published var isAnyLocked = false - @Published var canUnlock = true - @Published var enableLock = false - @Published var isSelectedEmpty = true - @Published var metadatas: [tableMetadata] = [] - - var isFilesLockCapabilityEnabled: Bool { - let capabilities = NCNetworking.shared.capabilities[controller?.account ?? ""] ?? NKCapabilities.Capabilities() - return !capabilities.filesLockVersion.isEmpty - } - - init(controller: NCMainTabBarController? = nil, viewController: UIViewController, delegate: NCCollectionViewCommonSelectTabBarDelegate? = nil) { - guard let controller else { - return - } - let rootView = NCCollectionViewCommonSelectTabBarView(tabBarSelect: self) - let bottomAreaInsets: CGFloat = controller.tabBar.safeAreaInsets.bottom == 0 ? 34 : 0 - let height = controller.tabBar.frame.height + bottomAreaInsets - hostingController = UIHostingController(rootView: rootView) - guard let hostingController else { - return - } - - self.controller = controller - self.delegate = delegate - - hostingController.view.translatesAutoresizingMaskIntoConstraints = false - hostingController.view.backgroundColor = .clear - hostingController.view.isHidden = true - - viewController.view.addSubview(hostingController.view) - - NSLayoutConstraint.activate([ - hostingController.view.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor), - hostingController.view.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor), - hostingController.view.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor), - hostingController.view.heightAnchor.constraint(equalToConstant: height) - ]) - } - - func show() { - guard let controller, - let hostingController else { - return - } - - controller.hide() - - if hostingController.view.isHidden { - hostingController.view.isHidden = false - hostingController.view.transform = .init(translationX: 0, y: hostingController.view.frame.height) - UIView.animate(withDuration: 0.3) { - hostingController.view.transform = .identity - } - } - } - - func hide() { - guard let controller, - let hostingController else { - return - } - - hostingController.view.isHidden = true - controller.show() - } - - func update(fileSelect: [String], metadatas: [tableMetadata]? = nil, userId: String? = nil) { - if let metadatas { - isAnyOffline = false - canSetAsOffline = true - isAnyDirectory = false - isAllDirectory = true - isAnyLocked = false - canUnlock = true - self.metadatas = metadatas - - for metadata in metadatas { - if metadata.directory { - isAnyDirectory = true - } else { - isAllDirectory = false - } - - if !metadata.canSetAsAvailableOffline { - canSetAsOffline = false - } - - if metadata.lock { - isAnyLocked = true - if metadata.lockOwner != userId { - canUnlock = false - } - } - - guard !isAnyOffline else { continue } - - if metadata.directory, - let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", - metadata.account, - metadata.serverUrlFileName)) { - isAnyOffline = directory.offline - } else if let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) { - isAnyOffline = localFile.offline - } // else: file is not offline, continue - } - // let capabilities = NCNetworking.shared.capabilities[controller?.account ?? ""] ?? NKCapabilities.Capabilities() - enableLock = !isAnyDirectory && canUnlock && isFilesLockCapabilityEnabled - } - self.isSelectedEmpty = fileSelect.isEmpty - } -} - -struct NCCollectionViewCommonSelectTabBarView: View { - @ObservedObject var tabBarSelect: NCCollectionViewCommonSelectTabBar - @Environment(\.verticalSizeClass) var sizeClass - - var body: some View { - VStack { - Spacer().frame(height: sizeClass == .compact ? 5 : 10) - - HStack { - Button { - tabBarSelect.delegate?.share() - } label: { - Image(systemName: "square.and.arrow.up") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(Color(NCBrandColor.shared.iconImageColor)) - .frame(maxWidth: .infinity) - .disabled(tabBarSelect.isSelectedEmpty || tabBarSelect.isAllDirectory) - - Button { - tabBarSelect.delegate?.move() - } label: { - Image(systemName: "rectangle.portrait.and.arrow.right") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(Color(NCBrandColor.shared.iconImageColor)) - .frame(maxWidth: .infinity) - .disabled(tabBarSelect.isSelectedEmpty) - - Button { - tabBarSelect.delegate?.delete() - } label: { - Image(systemName: "trash") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(.red) - .frame(maxWidth: .infinity) - .disabled(tabBarSelect.isSelectedEmpty) - - Menu { - Button(action: { - tabBarSelect.delegate?.saveAsAvailableOffline(isAnyOffline: tabBarSelect.isAnyOffline) - }, label: { - Label(NSLocalizedString(tabBarSelect.isAnyOffline ? "_remove_available_offline_" : "_set_available_offline_", comment: ""), systemImage: tabBarSelect.isAnyOffline ? "icloud.slash" : "icloud.and.arrow.down") - - if !tabBarSelect.canSetAsOffline && !tabBarSelect.isAnyOffline { - Text(NSLocalizedString("_e2ee_set_as_offline_", comment: "")) - } - }) - .disabled(!tabBarSelect.isAnyOffline && (!tabBarSelect.canSetAsOffline || tabBarSelect.isSelectedEmpty)) - - if tabBarSelect.isFilesLockCapabilityEnabled { - Button(action: { - tabBarSelect.delegate?.lock(isAnyLocked: tabBarSelect.isAnyLocked) - }, label: { - Label(NSLocalizedString(tabBarSelect.isAnyLocked ? "_unlock_" : "_lock_", comment: ""), systemImage: tabBarSelect.isAnyLocked ? "lock.open" : "lock") - - if !tabBarSelect.enableLock { - Text(NSLocalizedString("_lock_no_permissions_selected_", comment: "")) - } - }) - .disabled(!tabBarSelect.enableLock || tabBarSelect.isSelectedEmpty) - } - Button(action: { - tabBarSelect.delegate?.selectAll() - }, label: { - Label(NSLocalizedString("_select_all_", comment: ""), systemImage: "checkmark") - }) - } label: { - Image(systemName: "ellipsis.circle") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(Color(NCBrandColor.shared.iconImageColor)) - .frame(maxWidth: .infinity) - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - .background(.thinMaterial) - .overlay(Rectangle().frame(width: nil, height: 0.5, alignment: .top).foregroundColor(Color(UIColor.separator)), alignment: .top) - } -} - -#Preview { - NCCollectionViewCommonSelectTabBarView(tabBarSelect: NCCollectionViewCommonSelectTabBar(controller: nil, viewController: UIViewController(), delegate: nil)) -} diff --git a/iOSClient/Main/Collection Common/Section Header Footer/NCSectionFooter.xib b/iOSClient/Main/Collection Common/Section Header Footer/NCSectionFooter.xib index 95ea89d710..d005602c3a 100644 --- a/iOSClient/Main/Collection Common/Section Header Footer/NCSectionFooter.xib +++ b/iOSClient/Main/Collection Common/Section Header Footer/NCSectionFooter.xib @@ -2,7 +2,9 @@ - + + + @@ -13,8 +15,8 @@ - - - - - + @@ -103,7 +104,7 @@ - + @@ -125,17 +126,14 @@ - - - + + + + + + - - - - - - - + diff --git a/iOSClient/Select/NCSelectCommandViewSelect+CreateFolder.xib b/iOSClient/Select/NCSelectCommandViewSelect+CreateFolder.xib index bd1453a63a..f40f08c552 100644 --- a/iOSClient/Select/NCSelectCommandViewSelect+CreateFolder.xib +++ b/iOSClient/Select/NCSelectCommandViewSelect+CreateFolder.xib @@ -1,9 +1,10 @@ - - + + - + + @@ -12,41 +13,43 @@ - + - - + - - + @@ -74,17 +77,14 @@ - - - + + + + + + - - - - - - - + diff --git a/iOSClient/Select/NCSelectCommandViewSelect.xib b/iOSClient/Select/NCSelectCommandViewSelect.xib index 255f461331..c2297af1e2 100644 --- a/iOSClient/Select/NCSelectCommandViewSelect.xib +++ b/iOSClient/Select/NCSelectCommandViewSelect.xib @@ -1,9 +1,10 @@ - - + + - + + @@ -12,26 +13,25 @@ - + - - + @@ -39,7 +39,7 @@ - + @@ -56,17 +56,14 @@ - - - + + + + + + - - - - - - - + diff --git a/iOSClient/Select/NCSelectOpen+SelectDelegate.swift b/iOSClient/Select/NCSelectOpen+SelectDelegate.swift index f88347deec..69027e7a55 100644 --- a/iOSClient/Select/NCSelectOpen+SelectDelegate.swift +++ b/iOSClient/Select/NCSelectOpen+SelectDelegate.swift @@ -85,7 +85,7 @@ final class NCSelectOpen: NCSelectDelegate { navigationController?.modalPresentationStyle = .formSheet if let navigationController = navigationController { - controller?.present(navigationController, animated: true, completion: nil) + controller?.currentViewController()?.present(navigationController, animated: true, completion: nil) } } } diff --git a/iOSClient/Settings/Advanced/File Name/NCFileNameView.swift b/iOSClient/Settings/Advanced/File Name/NCFileNameView.swift index b75e9f038d..8b35c16d30 100644 --- a/iOSClient/Settings/Advanced/File Name/NCFileNameView.swift +++ b/iOSClient/Settings/Advanced/File Name/NCFileNameView.swift @@ -13,7 +13,7 @@ struct NCFileNameView: View { Section(header: Text(NSLocalizedString("_mode_filename_", comment: ""))) { Toggle(NSLocalizedString("_maintain_original_filename_", comment: ""), isOn: $model.maintainFilenameOriginal) .font(.system(size: 16)) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .onChange(of: model.maintainFilenameOriginal) { _, newValue in model.toggleMaintainFilenameOriginal(newValue: newValue) model.getFileName() @@ -22,13 +22,13 @@ struct NCFileNameView: View { if !model.maintainFilenameOriginal { Toggle(NSLocalizedString("_add_filenametype_", comment: ""), isOn: $model.addFileNameType) .font(.system(size: 16)) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .onChange(of: model.addFileNameType) { _, newValue in model.toggleAddFilenameType(newValue: newValue) model.getFileName() } } - } + }.applyGlobalFormSectionStyle() .transition(.slide) .animation(.easeInOut, value: model.maintainFilenameOriginal) @@ -38,6 +38,7 @@ struct NCFileNameView: View { } .navigationBarTitle(NSLocalizedString("_mode_filename_", comment: "")) .defaultViewModifier(model) + .applyGlobalFormStyle() .padding(.top, 0) .transition(.slide) } @@ -65,19 +66,19 @@ struct NCFileNameView: View { .font(.system(size: 16)) .foregroundColor(Color(UIColor.lightGray)) }, header: { - Text(NSLocalizedString("_filename_", comment: "")) + Text(NSLocalizedString("_filename_", comment: "")).listRowBackground(Color.clear) }, footer: { - Text(String(format: NSLocalizedString("_preview_filename_", comment: ""), "MM, MMM, DD, YY, YYYY, HH, hh, mm, ss, ampm")) - }) + Text(String(format: NSLocalizedString("_preview_filename_", comment: ""), "MM, MMM, DD, YY, YYYY, HH, hh, mm, ss, ampm")).listRowBackground(Color.clear) + }).applyGlobalFormSectionStyle() } else { Section(content: { Text("IMG_0001.JPG") .foregroundColor(Color(UIColor.lightGray)) }, header: { - Text(NSLocalizedString("_filename_", comment: "")) + Text(NSLocalizedString("_filename_", comment: "")).listRowBackground(Color.clear) }, footer: { - Text(NSLocalizedString("_default_preview_filename_footer_", comment: "")) - }) + Text(NSLocalizedString("_default_preview_filename_footer_", comment: "")).listRowBackground(Color.clear) + }).applyGlobalFormSectionStyle() } } diff --git a/iOSClient/Settings/Advanced/NCSettingsAdvancedModel.swift b/iOSClient/Settings/Advanced/NCSettingsAdvancedModel.swift index 4d79b432c3..47a3cfccb5 100644 --- a/iOSClient/Settings/Advanced/NCSettingsAdvancedModel.swift +++ b/iOSClient/Settings/Advanced/NCSettingsAdvancedModel.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2024 Aditya Tyagi // SPDX-FileCopyrightText: 2024 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -48,9 +49,7 @@ class NCSettingsAdvancedModel: ObservableObject, ViewOnAppearHandling { func onViewAppear() { let groups = NCManageDatabase.shared.getAccountGroups(account: session.account) isAdminGroup = groups.contains(NCGlobal.shared.groupAdmin) -#if DEBUG - isAdminGroup = true -#endif + mostCompatible = keychain.formatCompatibility livePhoto = keychain.livePhoto removeFromCameraRoll = keychain.removePhotoCameraRoll @@ -165,7 +164,7 @@ class NCSettingsAdvancedModel: ObservableObject, ViewOnAppearHandling { metadata: nil ) - controller?.present(viewerQuickLook, animated: true, completion: nil) + controller?.currentViewController()?.present(viewerQuickLook, animated: true, completion: nil) } } diff --git a/iOSClient/Settings/Advanced/NCSettingsAdvancedView.swift b/iOSClient/Settings/Advanced/NCSettingsAdvancedView.swift index 7e844e2ae9..f740939eb3 100644 --- a/iOSClient/Settings/Advanced/NCSettingsAdvancedView.swift +++ b/iOSClient/Settings/Advanced/NCSettingsAdvancedView.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2024 STRATO GmbH // SPDX-FileCopyrightText: 2024 Aditya Tyagi // SPDX-FileCopyrightText: 2024 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,244 +8,241 @@ import SwiftUI import NextcloudKit struct NCSettingsAdvancedView: View { - @ObservedObject var model: NCSettingsAdvancedModel - // State variable for indicating whether the exit alert is shown. - @State var showExitAlert: Bool = false - // State variable for indicating whether the cache alert is shown. - @State var showCacheAlert: Bool = false - // State variable for indicating whether to disable crash reporter. - @State var showCrashReporter: Bool = false + @ObservedObject var model: NCSettingsAdvancedModel + /// State variable for indicating whether the exit alert is shown. + @State var showExitAlert: Bool = false + /// State variable for indicating whether the cache alert is shown. + @State var showCacheAlert: Bool = false + /// State variable for indicating whether to disable crash reporter. + @State var showCrashReporter: Bool = false - var body: some View { - Form { - // file name - Section(content: { - NavigationLink(destination: LazyView { - NCFileNameView(model: NCFileNameModel(controller: model.controller)) - }) { - Text(NSLocalizedString("_filenamemask_", comment: "")) - } - }, footer: { - Text(fileNameMaskFooter) - }) - // Most Compatible & Enable Live Photo - Section(content: { - Toggle(NSLocalizedString("_format_compatibility_", comment: ""), isOn: $model.mostCompatible) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - .onChange(of: model.mostCompatible) { - model.updateMostCompatible() - } - }, footer: { - Text(NSLocalizedString("_format_compatibility_footer_", comment: "")) - }) + var body: some View { + Form { + /// file name + Section(content: { + NavigationLink(destination: LazyView { + NCFileNameView(model: NCFileNameModel(controller: model.controller)) + }) { + Text(NSLocalizedString("_filenamemask_", comment: "")) + } + }, footer: { + Text(fileNameMaskFooter) + }) + .applyGlobalFormSectionStyle() + /// Most Compatible & Enable Live Photo + Section(content: { + Toggle(NSLocalizedString("_format_compatibility_", comment: ""), isOn: $model.mostCompatible) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.mostCompatible) { _ in + model.updateMostCompatible() + } + }, footer: { + Text(NSLocalizedString("_format_compatibility_footer_", comment: "")) + }) + .applyGlobalFormSectionStyle() - Section(content: { - Toggle(NSLocalizedString("_upload_mov_livephoto_", comment: ""), isOn: $model.livePhoto) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - .onChange(of: model.livePhoto) { - model.updateLivePhoto() - } - }, footer: { - Text(NSLocalizedString("_upload_mov_livephoto_footer_", comment: "")) - }) + Section(content: { + Toggle(NSLocalizedString("_upload_mov_livephoto_", comment: ""), isOn: $model.livePhoto) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.livePhoto) { _ in + model.updateLivePhoto() + } + }, footer: { + Text(NSLocalizedString("_upload_mov_livephoto_footer_", comment: "")) + }) + .applyGlobalFormSectionStyle() - // Remove from Camera Roll - Section(content: { - Toggle(NSLocalizedString("_remove_photo_CameraRoll_", comment: ""), isOn: $model.removeFromCameraRoll) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - .onChange(of: model.removeFromCameraRoll) { - model.updateRemoveFromCameraRoll() - } - }, footer: { - Text(NSLocalizedString("_remove_photo_CameraRoll_desc_", comment: "")) - }) - // Section : Files App - if !NCBrandOptions.shared.disable_openin_file { - Section(content: { - Toggle(NSLocalizedString("_disable_files_app_", comment: ""), isOn: $model.appIntegration) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - .onChange(of: model.appIntegration) { - model.updateAppIntegration() - } - }, footer: { - Text(NSLocalizedString("_disable_files_app_footer_", comment: "")) - }) - } - // Section: Privacy - if !NCBrandOptions.shared.disable_crash_service { - Section(content: { - Toggle(NSLocalizedString("_crashservice_title_", comment: ""), isOn: $model.crashReporter) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - .onChange(of: model.crashReporter) { - model.updateCrashReporter() - showCrashReporter.toggle() - } - .alert(NSLocalizedString("_crashservice_title_", comment: ""), isPresented: $showCrashReporter, actions: { - Button(NSLocalizedString("OK", comment: ""), role: .cancel) { - model.exitNextCloud(ext: showCrashReporter) - } - }, message: { - Text(NSLocalizedString("_crashservice_alert_", comment: "")) - }) - }, header: { - Text(NSLocalizedString("_privacy_", comment: "")) - }, footer: { - Text(NSLocalizedString("_privacy_footer_", comment: "")) - }) - } - // Section: Diagnostic - if !NCBrandOptions.shared.disable_log { - Section(content: { - /// View Log File - Button(action: { - model.viewLogFile() - }, label: { - HStack { - Image(systemName: "doc.badge.gearshape") - .resizable() - .scaledToFit() - .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) - Text(NSLocalizedString("_view_log_", comment: "")) - } - }) - .tint(Color(UIColor.label)) - // Set Log Level() - Picker(NSLocalizedString("_set_log_level_", comment: ""), selection: $model.selectedLogLevel) { - ForEach(NKLogLevel.allCases) { level in - Text(level.displayText).tag(level) - } - } - .onChange(of: model.selectedLogLevel) { - model.updateSelectedLogLevel() - } - // Clear Log File - Button(action: { - model.clearLogFile() - }, label: { - HStack { - Image(systemName: "xmark") - .resizable() - .scaledToFit() - .frame(width: 25, height: 15) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) - Text(NSLocalizedString("_clear_log_", comment: "")) - } - }) - .tint(Color(UIColor.label)) - }, header: { - Text(NSLocalizedString("_diagnostics_", comment: "")) - }, footer: { - Text(NSLocalizedString("_diagnostics_footer_", comment: "")) - }) - // Set Log Level() & Capabilities - if model.isAdminGroup { - Section(content: { - NavigationLink(destination: LazyView { - NCCapabilitiesView(model: NCCapabilitiesModel(controller: model.controller)) - }) { - HStack { - Image(systemName: "list.bullet") - .resizable() - .scaledToFit() - .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) - Text(NSLocalizedString("_capabilities_", comment: "")) - } - } - }, header: { - Text(NSLocalizedString("_capabilities_", comment: "")) - }, footer: { - Text(NSLocalizedString("_capabilities_footer_", comment: "")) - }) - } - } - // Delete in Cache & Clear Cache - Section(content: { - Picker(NSLocalizedString("_delete_old_files_", comment: ""), selection: $model.selectedInterval) { - ForEach(CacheDeletionInterval.allCases) { interval in - Text(interval.displayText).tag(interval) - } - } - .pickerStyle(.automatic) - .onChange(of: model.selectedInterval) { - model.updateSelectedInterval() - } - Button(action: { - showCacheAlert.toggle() - }, label: { - HStack { - Image(systemName: "xmark") - .resizable() - .scaledToFit() - .frame(width: 15, height: 15) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) - Text(NSLocalizedString("_clear_cache_", comment: "")) - } - }) - .tint(Color(UIColor.label)) - .alert(NSLocalizedString("_want_delete_cache_", comment: ""), isPresented: $showCacheAlert) { - Button(NSLocalizedString("_yes_", comment: ""), role: .destructive) { - model.clearCache() - } - Button(NSLocalizedString("_cancel_", comment: ""), role: .cancel) { } - } - }, header: { - Text(NSLocalizedString("_delete_files_desc_", comment: "")) - }, footer: { - Text("_clear_cache_footer_") + /// Remove from Camera Roll + Section(content: { + Toggle(NSLocalizedString("_remove_photo_CameraRoll_", comment: ""), isOn: $model.removeFromCameraRoll) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.removeFromCameraRoll) { _ in + model.updateRemoveFromCameraRoll() + } + }, footer: { + Text(NSLocalizedString("_remove_photo_CameraRoll_desc_", comment: "")) + }) + .applyGlobalFormSectionStyle() + /// Section : Files App + if !NCBrandOptions.shared.disable_openin_file { + Section(content: { + Toggle(NSLocalizedString("_disable_files_app_", comment: ""), isOn: $model.appIntegration) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.appIntegration) { _ in + model.updateAppIntegration() + } + }, footer: { + Text(NSLocalizedString("_disable_files_app_footer_", comment: "")) + }) + .applyGlobalFormSectionStyle() + } + /// Section: Privacy + if !NCBrandOptions.shared.disable_crash_service { + Section(content: { + Toggle(NSLocalizedString("_crashservice_title_", comment: ""), isOn: $model.crashReporter) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.crashReporter) { _ in + model.updateCrashReporter() + showCrashReporter.toggle() + } + .alert(NSLocalizedString("_crashservice_title_", comment: ""), isPresented: $showCrashReporter, actions: { + Button(NSLocalizedString("OK", comment: ""), role: .cancel) { + model.exitNextCloud(ext: showCrashReporter) + } + }, message: { + Text(NSLocalizedString("_crashservice_alert_", comment: "")) + }) + }, header: { + Text(NSLocalizedString("_privacy_", comment: "")) + }, footer: { + Text(NSLocalizedString("_privacy_footer_", comment: "")) + }) + .applyGlobalFormSectionStyle() + } + /// Section: Diagnostic LOG + if !NCBrandOptions.shared.disable_log { + Section(content: { + /// View Log File + Button(action: { + model.viewLogFile() + }, label: { + HStack { + Image(.Settings.folderGear) + .resizable() + .scaledToFit() + .frame(width: 20, height: 20) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + Text(NSLocalizedString("_view_log_", comment: "")) + } + }) + .tint(Color(UIColor.label)) + /// Set Log Level() + Picker(NSLocalizedString("_set_log_level_", comment: ""), selection: $model.selectedLogLevel) { + ForEach(NKLogLevel.allCases) { level in + Text(level.displayText).tag(level) + } + } + .onChange(of: model.selectedLogLevel) { + model.updateSelectedLogLevel() + } + }, header: { + Text(NSLocalizedString("_diagnostics_", comment: "")) + }, footer: { + Text(NSLocalizedString("_diagnostics_footer_", comment: "")) + }) + .applyGlobalFormSectionStyle() + /// Set Log Level() & Capabilities + if model.isAdminGroup { + Section(content: { + NavigationLink(destination: LazyView { + NCCapabilitiesView(model: NCCapabilitiesModel(controller: model.controller)) + }) { + HStack { + Image(systemName: "list.bullet") + .resizable() + .scaledToFit() + .frame(width: 25, height: 25) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + Text(NSLocalizedString("_capabilities_", comment: "")) + } + } + }, header: { + Text(NSLocalizedString("_capabilities_", comment: "")) + }, footer: { + Text(NSLocalizedString("_capabilities_footer_", comment: "")) + }) + .applyGlobalFormSectionStyle() + } + } + /// Delete in Cache & Clear Cache + Section(content: { + Picker(NSLocalizedString("_delete_old_files_", comment: ""), selection: $model.selectedInterval) { + ForEach(CacheDeletionInterval.allCases) { interval in + Text(interval.displayText).tag(interval) + } + } + .pickerStyle(.automatic) + .onChange(of: model.selectedInterval) { _ in + model.updateSelectedInterval() + } + Button(action: { + showCacheAlert.toggle() + }, label: { + HStack { + Image(.Settings.xmark) + .resizable() + .scaledToFit() + .frame(width: 15, height: 15) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + Text(NSLocalizedString("_clear_cache_", comment: "")) + } + }) + .tint(Color(UIColor.label)) + .alert(NSLocalizedString("_want_delete_cache_", comment: ""), isPresented: $showCacheAlert) { + Button(NSLocalizedString("_yes_", comment: ""), role: .destructive) { + model.clearCache() + } + Button(NSLocalizedString("_cancel_", comment: ""), role: .cancel) { } + } + }, header: { + Text(NSLocalizedString("_delete_files_desc_", comment: "")) + }, footer: { + Text("_clear_cache_footer_") .multilineTextAlignment(.leading) - }) - // Reset Application - Section(content: { - Button(action: { - showExitAlert.toggle() - }, label: { - HStack { - Image(systemName: "xmark") - .resizable() - .scaledToFit() - .frame(width: 15, height: 15) - .foregroundColor(Color(UIColor.systemRed)) - Text(NSLocalizedString("_exit_", comment: "")) - .foregroundColor(Color(UIColor.systemRed)) - } - }) - .tint(Color(UIColor.label)) - .alert(NSLocalizedString("_want_exit_", comment: ""), isPresented: $showExitAlert) { - Button(NSLocalizedString("_ok_", comment: ""), role: .destructive) { - model.resetNextCloud() - } - Button(NSLocalizedString("_cancel_", comment: ""), role: .cancel) { } - } - }, footer: { - ( - Text(NSLocalizedString("_exit_footer_", comment: "")) - + - Text("\n\n") - ) - }) - } - .navigationBarTitle(NSLocalizedString("_advanced_", comment: "")) - .navigationBarTitleDisplayMode(.inline) - .defaultViewModifier(model) - } + }) + .applyGlobalFormSectionStyle() + /// Reset Application + Section(content: { + Button(action: { + showExitAlert.toggle() + }, label: { + HStack { + Image(.Settings.xmark) + .resizable() + .scaledToFit() + .frame(width: 15, height: 15) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + Text(NSLocalizedString("_exit_", comment: "")) + .foregroundColor(Color(UIColor(resource: .destructiveAction))) + } + }) + .tint(Color(UIColor.label)) + .alert(NSLocalizedString("_want_exit_", comment: ""), isPresented: $showExitAlert) { + Button(NSLocalizedString("_ok_", comment: ""), role: .destructive) { + model.resetNextCloud() + } + Button(NSLocalizedString("_cancel_", comment: ""), role: .cancel) { } + } + }, footer: { + ( + Text(NSLocalizedString("_exit_footer_", comment: "")) + + + Text("\n\n") + ) + }) + .applyGlobalFormSectionStyle() + } + .navigationBarTitle(NSLocalizedString("_advanced_", comment: "")) + .navigationBarTitleDisplayMode(.inline) + .defaultViewModifier(model) + .applyGlobalFormStyle() + } - private var fileNameMaskFooter: AttributedString { - let boldPart = NSLocalizedString("_filenamemask_format_", comment: "") - let localizedString = String( - format: NSLocalizedString("_filenamemask_footer_", comment: ""), - boldPart - ) + private var fileNameMaskFooter: AttributedString { + let boldPart = NSLocalizedString("_filenamemask_format_", comment: "") + let localizedString = String( + format: NSLocalizedString("_filenamemask_footer_", comment: ""), + boldPart + ) - var attributedString = AttributedString(localizedString) + var attributedString = AttributedString(localizedString) - if let range = attributedString.range(of: boldPart) { - attributedString[range].font = .footnote.weight(.semibold) - } + if let range = attributedString.range(of: boldPart) { + attributedString[range].font = .footnote.weight(.semibold) + } - return attributedString - } + return attributedString + } } #Preview { diff --git a/iOSClient/Settings/AutoUpload/NCAutoUploadModel.swift b/iOSClient/Settings/AutoUpload/NCAutoUploadModel.swift index a017f4aa35..3dcc5ad40e 100644 --- a/iOSClient/Settings/AutoUpload/NCAutoUploadModel.swift +++ b/iOSClient/Settings/AutoUpload/NCAutoUploadModel.swift @@ -225,10 +225,10 @@ class NCAutoUploadModel: ObservableObject, ViewOnAppearHandling { await NCManageDatabase.shared.deleteAutoUploadTransferAsync(account: session.account, autoUploadServerUrlBase: autoUploadServerUrlBase) } } - + /// Updates the auto-upload create subfolder setting. func handleLocationChange(newValue: Bool) { - if let controller = self.controller { + if let controller = (self.controller?.presentedViewController as? UINavigationController)?.topViewController { if newValue { Task { @MainActor in let result = await NCBackgroundLocationUploadManager.shared.requestAuthorizationAlwaysAsync(from: controller) diff --git a/iOSClient/Settings/AutoUpload/NCAutoUploadView.swift b/iOSClient/Settings/AutoUpload/NCAutoUploadView.swift index e652a724c0..28ab41d853 100644 --- a/iOSClient/Settings/AutoUpload/NCAutoUploadView.swift +++ b/iOSClient/Settings/AutoUpload/NCAutoUploadView.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2024 Aditya Tyagi // SPDX-FileCopyrightText: 2024 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -41,6 +42,7 @@ struct NCAutoUploadView: View { .onDisappear { model.setAutoUploadDirectory(serverUrl: model.serverUrl) } + .ignoresSafeArea() } .sheet(isPresented: $showSelectAlbums) { SelectAlbumView(model: albumModel) @@ -60,10 +62,10 @@ struct NCAutoUploadView: View { showUploadFolder.toggle() }, label: { HStack { - Image(systemName: "folder") + Image(.Settings.AutoUpload.folder) .resizable() .scaledToFit() - .frame(width: 25, height: 25) + .frame(width: 20, height: 20) .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) .opacity(model.autoUploadStart ? 0.15 : 1) Text(NSLocalizedString("_destination_", comment: "")) @@ -76,6 +78,7 @@ struct NCAutoUploadView: View { } }) }) + .applyGlobalFormSectionStyle() Section(content: { NavigationLink(destination: SelectAlbumView(model: albumModel)) { @@ -83,10 +86,10 @@ struct NCAutoUploadView: View { showSelectAlbums.toggle() }, label: { HStack { - Image(systemName: "person.2.crop.square.stack") + Image(.Settings.AutoUpload.folderOpened) .resizable() .scaledToFit() - .frame(width: 25, height: 25) + .frame(width: 20, height: 20) .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) .opacity(model.autoUploadStart ? 0.3 : 1) Text(NSLocalizedString("_upload_from_", comment: "")) @@ -106,7 +109,7 @@ struct NCAutoUploadView: View { model.handleAutoUploadOnlyNew(newValue: newValue) } )) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .accessibilityIdentifier("NewPhotosToggle") }, footer: { @@ -114,11 +117,12 @@ struct NCAutoUploadView: View { Text(String(format: NSLocalizedString("_new_photos_starting_", comment: ""), NCUtility().longDate(date))) } }) + .applyGlobalFormSectionStyle() // Auto Upload Photo Section(content: { Toggle(NSLocalizedString("_autoupload_photos_", comment: ""), isOn: $model.autoUploadImage) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .onChange(of: model.autoUploadImage) { _, newValue in if !newValue { model.autoUploadVideo = true } @@ -127,18 +131,19 @@ struct NCAutoUploadView: View { if model.autoUploadImage { Toggle(NSLocalizedString("_wifi_only_", comment: ""), isOn: $model.autoUploadWWAnPhoto) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .onChange(of: model.autoUploadWWAnPhoto) { _, newValue in model.handleAutoUploadWWAnPhotoChange(newValue: newValue) } } }) + .applyGlobalFormSectionStyle() // Auto Upload Video Section(content: { Toggle(NSLocalizedString("_autoupload_videos_", comment: ""), isOn: $model.autoUploadVideo) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .onChange(of: model.autoUploadVideo) { _, newValue in if !newValue { model.autoUploadImage = true } @@ -147,18 +152,19 @@ struct NCAutoUploadView: View { if model.autoUploadVideo { Toggle(NSLocalizedString("_wifi_only_", comment: ""), isOn: $model.autoUploadWWAnVideo) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .onChange(of: model.autoUploadWWAnVideo) { _, newValue in model.handleAutoUploadWWAnVideoChange(newValue: newValue) } } }) + .applyGlobalFormSectionStyle() // Auto Upload create subfolder Section(content: { Toggle(NSLocalizedString("_autoupload_create_subfolder_", comment: ""), isOn: $model.autoUploadCreateSubfolder) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .onChange(of: model.autoUploadCreateSubfolder) { _, newValue in model.handleAutoUploadCreateSubfolderChange(newValue: newValue) @@ -178,11 +184,12 @@ struct NCAutoUploadView: View { }, footer: { Text(NSLocalizedString("_autoupload_create_subfolder_footer_", comment: "")) }) - + .applyGlobalFormSectionStyle() + // Location Section(content: { Toggle(NSLocalizedString("_enable_background_location_title_", comment: ""), isOn: $model.permissionGranted) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .opacity(model.autoUploadStart ? 0.15 : 1) .onChange(of: model.permissionGranted) { _, newValue in model.handleLocationChange(newValue: newValue) @@ -190,6 +197,8 @@ struct NCAutoUploadView: View { }, footer: { Text(NSLocalizedString("_enable_background_location_footer_", comment: "")) }) + .applyGlobalFormSectionStyle() + } .disabled(model.autoUploadStart) } @@ -198,6 +207,7 @@ struct NCAutoUploadView: View { .frame(maxWidth: .infinity) .padding(.bottom, 10) } + .applyGlobalFormStyle() } @ViewBuilder @@ -215,16 +225,24 @@ struct NCAutoUploadView: View { } .font(.headline) - if #available(iOS 26.0, *) { - toggle - .toggleStyle(.button) - .buttonStyle(.glass) - } else { - toggle - .toggleStyle(AutoUploadProminentButtonStyle(model: model)) - } + toggle + .toggleStyle(AutoUploadProminentButtonStyle(model: model)) }) } + + private var auToggleTextColor: Color { + if #available(iOS 16.0, *) { + return Color(NCBrandColor.shared.customerText) + } + return Color(red: 0.078, green: 0.455, blue: 0.769) + } + + private var auToggleBackground: Color { + if #available(iOS 16.0, *) { + return Color(.Button.Primary.Background.selected) + } + return Color(.systemBackground) + } } @ViewBuilder @@ -236,16 +254,16 @@ var noPermissionsView: some View { } .padding(16) .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color(UIColor.systemGroupedBackground)) + .background(Color(NCBrandColor.shared.appBackgroundColor)) } // Custom prominent brand button style used for Toggle-as-Button private struct AutoUploadProminentButtonStyle: ToggleStyle { let model: NCAutoUploadModel - private var onBackground: Color { Color(NCBrandColor.shared.getElement(account: model.session.account)) } - private let offBackground = Color(UIColor.systemGray5) - private let onForeground = Color.white - private let offForeground = Color.primary + private var onBackground: Color { Color(.Button.Primary.Background.selected) } + private let offBackground = Color(.Button.Primary.Background.selected) + private let onForeground = Color(.Button.Primary.Text.selected) + private let offForeground = Color(.Button.Primary.Text.selected) private let cornerRadius: CGFloat = 40 func makeBody(configuration: Configuration) -> some View { diff --git a/iOSClient/Settings/Display/NCDisplayModel.swift b/iOSClient/Settings/Display/NCDisplayModel.swift index bf0cb68bc1..89d1941420 100644 --- a/iOSClient/Settings/Display/NCDisplayModel.swift +++ b/iOSClient/Settings/Display/NCDisplayModel.swift @@ -27,8 +27,7 @@ class NCDisplayModel: ObservableObject, ViewOnAppearHandling { } /// Initializes the view model with default values. - init(controller: NCMainTabBarController?) { - self.controller = controller + init() { onViewAppear() } diff --git a/iOSClient/Settings/Display/NCDisplayView.swift b/iOSClient/Settings/Display/NCDisplayView.swift index 7cb496e61a..1c909ea35b 100644 --- a/iOSClient/Settings/Display/NCDisplayView.swift +++ b/iOSClient/Settings/Display/NCDisplayView.swift @@ -23,7 +23,7 @@ struct NCDisplayView: View { .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_light_", comment: "")) Image(systemName: colorScheme == .light ? "checkmark.circle.fill" : "circle") - .foregroundColor(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .foregroundColor(Color(NCBrandColor.shared.brandElement)) .imageScale(.large) .font(Font.system(.body).weight(.light)) .frame(width: 50, height: 50) @@ -41,7 +41,7 @@ struct NCDisplayView: View { .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_dark_", comment: "")) Image(systemName: colorScheme == .dark ? "checkmark.circle.fill" : "circle") - .foregroundColor(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .foregroundColor(Color(NCBrandColor.shared.brandElement)) .imageScale(.large) .font(Font.system(.body).weight(.light)) .frame(width: 50, height: 50) @@ -55,7 +55,7 @@ struct NCDisplayView: View { .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: -50)) Toggle(NSLocalizedString("_use_system_style_", comment: ""), isOn: $model.appearanceAutomatic) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) + .tint(Color(NCBrandColor.shared.switchColor)) .onChange(of: model.appearanceAutomatic) { model.updateAppearanceAutomatic() } @@ -83,5 +83,5 @@ struct NCDisplayView: View { } #Preview { - NCDisplayView(model: NCDisplayModel(controller: nil)) + NCDisplayView(model: NCDisplayModel()) } diff --git a/iOSClient/Settings/NCPreferences.swift b/iOSClient/Settings/NCPreferences.swift index 87810b4f66..5971b6488a 100644 --- a/iOSClient/Settings/NCPreferences.swift +++ b/iOSClient/Settings/NCPreferences.swift @@ -12,7 +12,10 @@ final class NCPreferences: NSObject { var showDescription: Bool { get { - return getBoolPreference(key: "showDescription", defaultValue: true) + if let value = try? keychain.get("showDescription"), let result = Bool(value) { + return result + } + return false } set { setUserDefaults(newValue, forKey: "showDescription") diff --git a/iOSClient/Settings/SelectAlbum/SelectAlbumView.swift b/iOSClient/Settings/SelectAlbum/SelectAlbumView.swift index bb8b24e78f..f6eade83be 100644 --- a/iOSClient/Settings/SelectAlbum/SelectAlbumView.swift +++ b/iOSClient/Settings/SelectAlbum/SelectAlbumView.swift @@ -15,13 +15,16 @@ struct SelectAlbumView: View { Section { SelectionButton(model: model, album: model.allPhotosCollection, assetCount: model.allPhotosCollection?.assetCount ?? 0, selection: $selectedAlbums) } + .applyGlobalFormSectionStyle() if !model.smartAlbums.isEmpty { AlbumView(model: model, selectedAlbums: $selectedAlbums, albums: model.smartAlbums, sectionTitle: "_smart_albums_") + .applyGlobalFormSectionStyle() } if !model.userAlbums.isEmpty { AlbumView(model: model, selectedAlbums: $selectedAlbums, albums: model.userAlbums, sectionTitle: "_albums_") + .applyGlobalFormSectionStyle() } } .safeAreaInset(edge: .bottom, content: { @@ -45,6 +48,7 @@ struct SelectAlbumView: View { } .navigationBarTitle(NSLocalizedString("_upload_from_", comment: "")) .navigationBarTitleDisplayMode(.inline) + .applyGlobalFormStyle() } } diff --git a/iOSClient/Settings/Settings/NCSettingsModel.swift b/iOSClient/Settings/Settings/NCSettingsModel.swift index 826b359cfe..f92d875d2b 100644 --- a/iOSClient/Settings/Settings/NCSettingsModel.swift +++ b/iOSClient/Settings/Settings/NCSettingsModel.swift @@ -28,15 +28,6 @@ class NCSettingsModel: ObservableObject, ViewOnAppearHandling { @Published var controller: NCMainTabBarController? // Footer var footerApp = "" - var footerServer = "" - var footerSlogan = "" - // Get session - @MainActor - var session: NCSession.Session { - NCSession.shared.getSession(controller: controller) - } - - var changePasscode = false /// Initializes the view model with default values. init(controller: NCMainTabBarController?) { @@ -54,8 +45,6 @@ class NCSettingsModel: ObservableObject, ViewOnAppearHandling { resetWrongAttempts = keychain.resetAppCounterFail accountRequest = keychain.accountRequest footerApp = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility().getVersionBuild()) + "\n\n" - footerServer = String(format: NCBrandOptions.shared.textCopyrightNextcloudServer, capabilities.serverVersion) + "\n" - footerSlogan = capabilities.themingName + " - " + capabilities.themingSlogan + "\n\n" } // MARK: - All functions @@ -95,4 +84,8 @@ class NCSettingsModel: ObservableObject, ViewOnAppearHandling { func updateAccountRequest() { keychain.accountRequest = accountRequest } + + func dismiss() { + controller?.dismiss(animated: true) + } } diff --git a/iOSClient/Settings/Settings/NCSettingsView.swift b/iOSClient/Settings/Settings/NCSettingsView.swift index 08ad3c3740..4dc56bcf99 100644 --- a/iOSClient/Settings/Settings/NCSettingsView.swift +++ b/iOSClient/Settings/Settings/NCSettingsView.swift @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2024 Aditya Tyagi // SPDX-FileCopyrightText: 2024 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later @@ -26,31 +27,30 @@ struct NCSettingsView: View { } var body: some View { - Form { + Form(content: { // `Auto Upload` Section Section(content: { NavigationLink(destination: LazyView { NCAutoUploadView(model: NCAutoUploadModel(controller: model.controller), albumModel: AlbumModel(controller: model.controller)) }) { HStack { - Image(systemName: "photo.on.rectangle.angled") + Image(.Settings.camera) .resizable() .scaledToFit() - .frame(width: 25, height: 25) + .frame(width: 20, height: 20) .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_settings_autoupload_", comment: "")) } } - }, footer: { - Text(NSLocalizedString("_autoupload_description_", comment: "")) }) - // `Privacy` Section + .listRowBackground(Color(NCBrandColor.shared.formRowBackgroundColor)) + /// `Privacy` Section Section(content: { Button(action: { showPasscode.toggle() }, label: { HStack { - Image(systemName: model.isLockActive ? "lock" : "lock.open") + lockImage(isLocked: model.isLockActive) .resizable() .scaledToFit() .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) @@ -60,92 +60,36 @@ struct NCSettingsView: View { } }) .tint(Color(NCBrandColor.shared.textColor)) - .disabled(NCBrandOptions.shared.enforce_passcode_lock) - }, header: { - Text(NSLocalizedString("_privacy_", comment: "")) - }, footer: { - if NCBrandOptions.shared.enforce_passcode_lock { - Text(NSLocalizedString("_lock_cannot_disable_mdm_", comment: "")) - } - }) - - if model.isLockActive { - Section(content: { - Group { - // Change passcode - Button(action: { - showChangePasscode.toggle() - }, label: { - VStack { - Text(NSLocalizedString("_change_lock_passcode_", comment: "")) - .tint(Color(NCBrandColor.shared.textColor)) - } - }) - // Enable Touch ID - Toggle(NSLocalizedString("_enable_touch_face_id_", comment: ""), isOn: $model.enableTouchFaceID) - .onChange(of: model.enableTouchFaceID) { - model.updateTouchIDSetting() - } - - if !NCBrandOptions.shared.enforce_passcode_lock { - // Do not ask for passcode on startup - Toggle(NSLocalizedString("_lock_protection_no_screen_", comment: ""), isOn: $model.lockScreen) - .onChange(of: model.lockScreen) { - model.updateLockScreenSetting() - } - } - - // Reset app wrong attempts - Toggle(NSLocalizedString("_reset_wrong_passcode_option_", comment: ""), isOn: $model.resetWrongAttempts) - .onChange(of: model.resetWrongAttempts) { - model.updateResetWrongAttemptsSetting() - } + /// Enable Touch ID + Toggle(NSLocalizedString("_enable_touch_face_id_", comment: ""), isOn: $model.enableTouchFaceID) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.enableTouchFaceID) { _ in + model.updateTouchIDSetting() } - }, footer: { - Text(String(format: NSLocalizedString("_reset_wrong_passcode_desc_", comment: ""), NCBrandOptions.shared.resetAppPasscodeAttempts)) - }) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - } - - if !NCBrandOptions.shared.enforce_privacyScreenEnabled { - Section(content: { - // Splash screen when app inactive - Toggle(NSLocalizedString("_privacy_screen_", comment: ""), isOn: $model.privacyScreen) - .onChange(of: model.privacyScreen) { - model.updatePrivacyScreenSetting() - } - }, footer: { - Text(NSLocalizedString("_privacy_screen_footer_", comment: "")) - }) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - } - - // Display - Section(header: Text(NSLocalizedString("_display_", comment: "")), content: { - NavigationLink(destination: LazyView { - NCDisplayView(model: NCDisplayModel(controller: model.controller)) - }) { - HStack { - Image(systemName: "sun.max.circle") - .resizable() - .scaledToFit() - .frame(width: 20, height: 20) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) - Text(NSLocalizedString("_display_", comment: "")) + /// Reset app wrong attempts + Toggle(NSLocalizedString("_reset_wrong_passcode_", comment: ""), isOn: $model.resetWrongAttempts) + .tint(Color(NCBrandColor.shared.switchColor)) + .onChange(of: model.resetWrongAttempts) { _ in + model.updateResetWrongAttemptsSetting() } - } - }) - // Calender & Contacts + }, header: { + Text(NSLocalizedString("_privacy_", comment: "")).listRowBackground(Color.clear) + }, footer: { + Text(String(format: NSLocalizedString("_reset_wrong_passcode_desc_", comment: ""), NCBrandOptions.shared.resetAppPasscodeAttempts)) + .listRowBackground(Color.clear) + .lineSpacing(1) + }).applyGlobalFormSectionStyle() + /// Calender & Contacts if !NCBrandOptions.shared.disable_mobileconfig { Section(content: { Button(action: { model.getConfigFiles() }, label: { HStack { - Image(systemName: "calendar.badge.plus") + Image(.Settings.calendarUser) .resizable() .scaledToFit() - .frame(width: 25, height: 25) + .frame(width: 23, height: 20) .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_mobile_config_", comment: "")) } @@ -158,25 +102,9 @@ struct NCSettingsView: View { Text(NSLocalizedString("_calendar_contacts_footer_warning_", comment: "")) Spacer() Text(NSLocalizedString("_calendar_contacts_footer_", comment: "")) - } + }.listRowBackground(Color.clear) - }) - } - // Users - Section(content: { - Toggle(NSLocalizedString("_settings_account_request_", comment: ""), isOn: $model.accountRequest) - .tint(Color(NCBrandColor.shared.getElement(account: model.session.account))) - .onChange(of: model.accountRequest) { - model.updateAccountRequest() - } - }, header: { - Text(NSLocalizedString("_users_", comment: "")) - }, footer: { - Text(NSLocalizedString("_users_footer_", comment: "")) - }) - // E2EEncryption` Section - if capabilities.e2EEEnabled && NCGlobal.shared.e2eeCompatibleVersions.contains(capabilities.e2EEApiVersion) { - E2EESection(model: model) + }).applyGlobalFormSectionStyle() } // `Advanced` Section Section { @@ -184,43 +112,57 @@ struct NCSettingsView: View { NCSettingsAdvancedView(model: NCSettingsAdvancedModel(controller: model.controller), showExitAlert: false, showCacheAlert: false) }) { HStack { - Image(systemName: "gear") + Image(.Settings.gear) .resizable() .scaledToFit() - .frame(width: 25, height: 25) + .frame(width: 20, height: 20) .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_advanced_", comment: "")) } } - } - // `Information` Section + + NavigationLink(destination: LazyView { + DataProtectionSettingsScreen(model: DataProtectionModel(showFromSettings: true), isShowing: .constant(true)) + }) { + HStack { + Image(.Settings.dataprivacy) + .resizable() + .scaledToFit() + .frame(width: 20, height: 20) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + Text(NSLocalizedString("_data_protection_", comment: "")) + } + } + }.applyGlobalFormSectionStyle() + /// `Information` Section Section(header: Text(NSLocalizedString("_information_", comment: "")), content: { // Acknowledgements Button(action: { showAcknowledgements.toggle() }, label: { HStack { - Image("acknowledgements") + Image(.Settings.handshake) .resizable() - .renderingMode(.template) - .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + .scaledToFit() + .frame(width: 25, height: 20) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_acknowledgements_", comment: "")) } }) .tint(Color(NCBrandColor.shared.textColor)) .sheet(isPresented: $showAcknowledgements) { - NCAcknowledgementsView(browserTitle: NSLocalizedString("_acknowledgements_", comment: "")) + NCBrowserWebView(urlBase: URL(string: NCBrandOptions.shared.acknowloedgements)!, browserTitle: NSLocalizedString("_acknowledgements_", comment: "")) + .ignoresSafeArea() } // Terms & Privacy Conditions Button(action: { showBrowser.toggle() }, label: { HStack { - Image(systemName: "shield.checkerboard") + Image(.Settings.shieldHalved) .resizable() .scaledToFit() - .frame(width: 25, height: 25) + .frame(width: 20, height: 20) .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) Text(NSLocalizedString("_privacy_legal_", comment: "")) } @@ -228,33 +170,31 @@ struct NCSettingsView: View { .tint(Color(NCBrandColor.shared.textColor)) .sheet(isPresented: $showBrowser) { NCBrowserWebView(urlBase: URL(string: NCBrandOptions.shared.privacy)!, browserTitle: NSLocalizedString("_privacy_legal_", comment: "")) + .ignoresSafeArea() } - // Source Code Nextcloud App - if !NCBrandOptions.shared.disable_source_code_in_settings { - Button(action: { - showSourceCode.toggle() - }, label: { - HStack { - Image("gitHub") - .resizable() - .renderingMode(.template) - .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) - Text(NSLocalizedString("_source_code_", comment: "")) - } - }) - .tint(Color(NCBrandColor.shared.textColor)) - .sheet(isPresented: $showSourceCode) { - NCBrowserWebView(urlBase: URL(string: NCBrandOptions.shared.sourceCode)!, browserTitle: NSLocalizedString("_source_code_", comment: "")) + /// Source Code + Button(action: { + showSourceCode.toggle() + }, label: { + HStack { + Image(.Settings.github) + .resizable() + .frame(width: 20, height: 20) + .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + Text(NSLocalizedString("_source_code_", comment: "")) } + }) + .tint(Color(NCBrandColor.shared.textColor)) + .sheet(isPresented: $showSourceCode) { + NCBrowserWebView(urlBase: URL(string: NCBrandOptions.shared.sourceCode)!, browserTitle: NSLocalizedString("_source_code_", comment: "")) } - }) - // `Watermark` Section + }).applyGlobalFormSectionStyle() + /// `Watermark` Section Section(content: { }, footer: { - Text(model.footerApp + model.footerServer + model.footerSlogan) - }) - } + Text(model.footerApp).listRowBackground(Color.clear) + }).applyGlobalFormSectionStyle() + }) .sheet(isPresented: $showPasscode) { SetupPasscodeView(isLockActive: $model.isLockActive) } @@ -262,8 +202,23 @@ struct NCSettingsView: View { SetupPasscodeView(isLockActive: $model.isLockActive, changePasscode: true) } .navigationBarTitle(NSLocalizedString("_settings_", comment: "")) + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button(action: { + model.dismiss() + }, label: { + Text(NSLocalizedString("_close_", comment: "")) + .foregroundStyle(Color(NCBrandColor.shared.iconImageColor)) + }) + } + } .defaultViewModifier(model) + .applyGlobalFormStyle() } + + private func lockImage(isLocked: Bool) -> Image { + isLocked ? Image(.itemLock) : Image(.itemLockOpen) + } } struct E2EESection: View { diff --git a/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitTableViewController.swift b/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitTableViewController.swift index 783e3096c2..7e365ff4a4 100644 --- a/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitTableViewController.swift +++ b/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitTableViewController.swift @@ -41,6 +41,12 @@ class NCShareDownloadLimitTableViewController: UITableViewController { @IBOutlet var limitSwitch: UISwitch! @IBOutlet var limitTextField: UITextField! + override func viewDidLoad() { + super.viewDidLoad() + tableView.backgroundColor = UIColor(resource: .Share.Advanced.background) + tableView.separatorColor = UIColor(resource: .Share.Advanced.tableCellSeparator) + } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) diff --git a/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitViewController.swift b/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitViewController.swift index f21e12f356..348d507bfe 100644 --- a/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitViewController.swift +++ b/iOSClient/Share/Advanced/DownloadLimit/NCShareDownloadLimitViewController.swift @@ -20,7 +20,8 @@ class NCShareDownloadLimitViewController: UIViewController, NCShareNavigationTit override func viewDidLoad() { super.viewDidLoad() self.setNavigationTitle() - + self.navigationController?.setNavigationBarAppearance(backgroundColor: UIColor(resource: .Share.Advanced.background)) + // Set up header view. guard let headerView = (Bundle.main.loadNibNamed("NCShareHeader", owner: self, options: nil)?.first as? NCShareHeader) else { return } diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift index d84ddf3a79..e789dc3a5c 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift +++ b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift @@ -4,6 +4,7 @@ // // Created by T-systems on 09/08/21. // Copyright © 2022 Henrik Storch. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Henrik Storch // @@ -26,6 +27,7 @@ import NextcloudKit import CloudKit class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDelegate, NCShareNavigationTitleSetting { + let database = NCManageDatabase.shared var oldTableShare: tableShare? @@ -60,6 +62,9 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg super.viewDidLoad() self.shareConfig = NCShareConfig(parentMetadata: metadata, share: share) + tableView.backgroundColor = UIColor(resource: .Share.Advanced.background) + tableView.separatorColor = UIColor(resource: .Share.Advanced.tableCellSeparator) + // Only persisted shares have tokens which are provided by the server. // A download limit requires a token to exist. // Hence it can only be looked up if the share is already persisted at this point. @@ -77,9 +82,12 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg tableView.estimatedRowHeight = tableView.rowHeight tableView.rowHeight = UITableView.automaticDimension + self.setNavigationTitle() self.navigationItem.hidesBackButton = true - // disable pull to dimiss + self.navigationController?.setNavigationBarAppearance(backgroundColor: UIColor(resource: .Share.Advanced.background)) + + // disbale pull to dimiss isModalInPresentation = true } @@ -124,6 +132,21 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg return NSLocalizedString("_advanced_", comment: "") } else { return nil } } + + override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { + guard let headerView = view as? UITableViewHeaderFooterView else { return } + + var contentConfiguration = UIListContentConfiguration.plainHeader() + contentConfiguration.text = self.tableView(tableView, titleForHeaderInSection: section) + contentConfiguration.textProperties.color = UIColor(resource: .Share.Advanced.sectionTitle) + headerView.contentConfiguration = contentConfiguration + + headerView.configurationUpdateHandler = { (headerFooterView: UITableViewHeaderFooterView, state: UIViewConfigurationState) -> Void in + var backgroundConfiguration = UIBackgroundConfiguration.clear() + backgroundConfiguration.backgroundColor = state.isPinned ? UIColor(resource: .Share.Advanced.sectionTitleBackground) : .clear + headerView.backgroundConfiguration = backgroundConfiguration + } + } override func numberOfSections(in tableView: UITableView) -> Int { return 2 @@ -148,6 +171,13 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg noteCell.detailTextLabel?.numberOfLines = 0 return noteCell } + + cell.configurationUpdateHandler = { (cell: UITableViewCell, state: UICellConfigurationState) -> Void in + var backgroundConfiguration = UIBackgroundConfiguration.clear() + backgroundConfiguration.backgroundColor = UIColor(resource: state.isHighlighted ? .Share.Advanced.Cell.backgroundHighlighted : .Share.Advanced.Cell.backgroundNormal) + cell.backgroundConfiguration = backgroundConfiguration + } + if let cell = cell as? NCShareDateCell { cell.onReload = tableView.reloadData } return cell } diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift index dfee243827..d4b6c61f24 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift @@ -4,6 +4,7 @@ // // Created by T-systems on 09/08/21. // Copyright © 2022 Henrik Storch. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Henrik Storch // @@ -30,7 +31,7 @@ protocol NCShareAdvanceFotterDelegate: AnyObject { class NCShareAdvancePermissionFooter: UIView { @IBOutlet weak var buttonCancel: UIButton! - @IBOutlet weak var buttonNext: UIButton! + @IBOutlet weak var buttonNext: PrimaryButton! weak var delegate: NCShareAdvanceFotterDelegate? func setupUI(delegate: NCShareAdvanceFotterDelegate?, account: String) { @@ -38,20 +39,10 @@ class NCShareAdvancePermissionFooter: UIView { backgroundColor = .clear buttonCancel.setTitle(NSLocalizedString("_cancel_", comment: ""), for: .normal) - buttonCancel.layer.cornerRadius = 25 - buttonCancel.layer.masksToBounds = true - buttonCancel.layer.borderWidth = 1 - buttonCancel.layer.borderColor = NCBrandColor.shared.textColor2.cgColor - buttonCancel.backgroundColor = .secondarySystemBackground buttonCancel.addTarget(self, action: #selector(cancelClicked(_:)), for: .touchUpInside) - buttonCancel.setTitleColor(NCBrandColor.shared.textColor2, for: .normal) buttonNext.setTitle(NSLocalizedString(delegate?.isNewShare == true ? "_share_" : "_save_", comment: ""), for: .normal) - buttonNext.layer.cornerRadius = 25 - buttonNext.layer.masksToBounds = true - buttonNext.backgroundColor = NCBrandColor.shared.getElement(account: account) buttonNext.addTarget(self, action: #selector(nextClicked(_:)), for: .touchUpInside) - buttonNext.setTitleColor(.white, for: .normal) } @objc func cancelClicked(_ sender: Any?) { diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib index b4ec72ed06..df7953ebb5 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib @@ -15,7 +15,7 @@ - - + @@ -137,9 +117,8 @@ - - - + + @@ -309,6 +288,7 @@ + @@ -321,6 +301,7 @@ + @@ -394,21 +375,17 @@ - + + + - - - - - - diff --git a/iOSClient/Share/NCShare.swift b/iOSClient/Share/NCShare.swift index fbe1b89155..5fb4018747 100644 --- a/iOSClient/Share/NCShare.swift +++ b/iOSClient/Share/NCShare.swift @@ -5,6 +5,7 @@ // Created by Marino Faggiana on 17/07/2019. // Copyright © 2019 Marino Faggiana. All rights reserved. // Copyright © 2022 Henrik Storch. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Marino Faggiana // Author Henrik Storch @@ -36,8 +37,10 @@ class NCShare: UIViewController, NCSharePagingContent { @IBOutlet weak var sharedWithYouByImage: UIImageView! @IBOutlet weak var sharedWithYouByLabel: UILabel! @IBOutlet weak var searchFieldTopConstraint: NSLayoutConstraint! - @IBOutlet weak var searchField: UISearchBar! - var textField: UIView? { searchField } + + @IBOutlet weak var searchPlaceholder: UIView! + private var shareSearchHost: ShareSearchFieldHost? + var textField: UIView? { shareSearchHost?.view } @IBOutlet weak var tableView: UITableView! @IBOutlet weak var btnContact: UIButton! @@ -73,18 +76,31 @@ class NCShare: UIViewController, NCSharePagingContent { override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .systemBackground + view.backgroundColor = NCBrandColor.shared.appBackgroundColor viewContainerConstraint.constant = height searchFieldTopConstraint.constant = 0 - searchField.placeholder = NSLocalizedString("_shareLinksearch_placeholder_", comment: "") - searchField.autocorrectionType = .no + shareSearchHost = ShareSearchFieldHost(onSearchTextChanged: { [weak self] text in + self?.searchTextDidChange(text) + }, onContactButtonTap: { [weak self] in + self?.selectContactClicked() + }) + shareSearchHost?.placeholder = NSLocalizedString("_shareLinksearch_placeholder_", comment: "") + if let shareSearchHost { + searchPlaceholder.addSubview(shareSearchHost.view) + shareSearchHost.view.translatesAutoresizingMaskIntoConstraints = false + searchPlaceholder.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([searchPlaceholder.leadingAnchor.constraint(equalTo: shareSearchHost.view.leadingAnchor), + searchPlaceholder.trailingAnchor.constraint(equalTo: shareSearchHost.view.trailingAnchor), + searchPlaceholder.topAnchor.constraint(equalTo: shareSearchHost.view.topAnchor), + searchPlaceholder.bottomAnchor.constraint(equalTo: shareSearchHost.view.bottomAnchor)]) + } tableView.dataSource = self tableView.delegate = self tableView.allowsSelection = false - tableView.backgroundColor = .systemBackground + tableView.backgroundColor = NCBrandColor.shared.appBackgroundColor tableView.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 10, right: 0) tableView.register(UINib(nibName: "NCShareLinkCell", bundle: nil), forCellReuseIdentifier: "cellLink") @@ -99,8 +115,6 @@ class NCShare: UIViewController, NCSharePagingContent { if capabilities.e2EEApiVersion == "1.2" || (NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) && metadataDirectory?.e2eEncrypted ?? false) { searchFieldTopConstraint.constant = -50 - searchField.alpha = 0 - btnContact.alpha = 0 } } else { checkSharedWithYou() @@ -111,8 +125,6 @@ class NCShare: UIViewController, NCSharePagingContent { networking = NCShareNetworking(metadata: metadata, view: self.view, delegate: self, session: session) let isVisible = (self.navigationController?.topViewController as? NCSharePaging)?.page == .sharing networking?.readShare(showLoadingIndicator: isVisible) - searchField.searchTextField.font = .systemFont(ofSize: 14) - searchField.delegate = self } } @@ -133,10 +145,11 @@ class NCShare: UIViewController, NCSharePagingContent { guard !metadata.ownerId.isEmpty, metadata.ownerId != session.userId else { return } if !canReshare { - searchField.isUserInteractionEnabled = false - searchField.alpha = 0.5 - searchField.placeholder = NSLocalizedString("_share_reshare_disabled_", comment: "") - btnContact.isEnabled = false + if let shareSearchHost { + shareSearchHost.view.isUserInteractionEnabled = false + shareSearchHost.view.alpha = 0.5 + shareSearchHost.placeholder = NSLocalizedString("_share_reshare_disabled_", comment: "") + } } searchFieldTopConstraint.constant = 45 @@ -157,37 +170,37 @@ class NCShare: UIViewController, NCSharePagingContent { ]) avatarButton.showsMenuAsPrimaryAction = true avatarButton.menu = NCContextMenuProfile(userId: metadata.ownerId, session: session, viewController: self).viewMenu() - - let fileName = NCSession.shared.getFileName(urlBase: session.urlBase, user: metadata.ownerId) - let results = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) - - if results.image == nil { - let etag = self.database.getTableAvatar(fileName: fileName)?.etag - let fileNameLocalPath = utilityFileSystem.createServerUrl(serverUrl: utilityFileSystem.directoryUserData, fileName: fileName) - - NextcloudKit.shared.downloadAvatar( - user: metadata.ownerId, - fileNameLocalPath: fileNameLocalPath, - sizeImage: NCGlobal.shared.avatarSize, - avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, - etagResource: etag, - account: metadata.account) { task in - Task { - let identifier = await NCNetworking.shared.networkingTasks.createIdentifier(account: self.metadata.account, - path: self.metadata.ownerId, - name: "downloadAvatar") - await NCNetworking.shared.networkingTasks.track(identifier: identifier, task: task) - } - } completion: { _, imageAvatar, _, etag, _, error in - if error == .success, let etag = etag, let imageAvatar = imageAvatar { - self.database.addAvatar(fileName: fileName, etag: etag) - self.sharedWithYouByImage.image = imageAvatar - self.reloadData() - } else if error.errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = self.database.setAvatarLoaded(fileName: fileName) { - self.sharedWithYouByImage.image = imageAvatar - } - } - } +// MERGE: HiDrive Next doesn't display avatar +// let fileName = NCSession.shared.getFileName(urlBase: session.urlBase, user: metadata.ownerId) +// let results = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) +// +// if results.image == nil { +// let etag = self.database.getTableAvatar(fileName: fileName)?.etag +// let fileNameLocalPath = utilityFileSystem.createServerUrl(serverUrl: utilityFileSystem.directoryUserData, fileName: fileName) +// +// NextcloudKit.shared.downloadAvatar( +// user: metadata.ownerId, +// fileNameLocalPath: fileNameLocalPath, +// sizeImage: NCGlobal.shared.avatarSize, +// avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, +// etagResource: etag, +// account: metadata.account) { task in +// Task { +// let identifier = await NCNetworking.shared.networkingTasks.createIdentifier(account: self.metadata.account, +// path: self.metadata.ownerId, +// name: "downloadAvatar") +// await NCNetworking.shared.networkingTasks.track(identifier: identifier, task: task) +// } +// } completion: { _, imageAvatar, _, etag, _, error in +// if error == .success, let etag = etag, let imageAvatar = imageAvatar { +// self.database.addAvatar(fileName: fileName, etag: etag) +// self.sharedWithYouByImage.image = imageAvatar +// self.reloadData() +// } else if error.errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = self.database.setAvatarLoaded(fileName: fileName) { +// self.sharedWithYouByImage.image = imageAvatar +// } +// } +// } reloadData() } @@ -216,7 +229,7 @@ class NCShare: UIViewController, NCSharePagingContent { self.present(UIAlertController.password(titleKey: "_enforce_password_protection_", completion: completion), animated: true) } - @IBAction func selectContactClicked(_ sender: Any) { + private func selectContactClicked() { let cnPicker = CNContactPickerViewController() cnPicker.delegate = self cnPicker.displayedPropertyKeys = [CNContactEmailAddressesKey] @@ -313,6 +326,7 @@ class NCShare: UIViewController, NCSharePagingContent { // MARK: - NCShareNetworkingDelegate extension NCShare: NCShareNetworkingDelegate { + func readShareCompleted() { NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataNCShare) reloadData() @@ -347,13 +361,15 @@ extension NCShare: NCShareNetworkingDelegate { let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = CGRect(x: 0, y: 0, width: 500, height: 20) - appearance.backgroundColor = .systemBackground + appearance.backgroundColor = UIColor(resource: .Share.SearchUserCell.Background.normal) + appearance.selectionBackgroundColor = UIColor(resource: .Share.SearchUserCell.Background.pressed) appearance.cornerRadius = 10 appearance.shadowColor = .black appearance.shadowOpacity = 0.2 appearance.shadowRadius = 30 appearance.animationduration = 0.25 - appearance.textColor = .darkGray + appearance.textColor = UIColor(resource: .Share.SearchUserCell.title) + appearance.selectedTextColor = UIColor(resource: .Share.SearchUserCell.title) let account = NCManageDatabase.shared.getTableAccount(account: metadata.account) let existingShares = NCManageDatabase.shared.getTableShares(metadata: metadata) @@ -361,7 +377,7 @@ extension NCShare: NCShareNetworkingDelegate { for sharee in sharees { if sharee.shareWith == account?.user { continue } // do not show your own account if let shares = existingShares.share, shares.contains(where: {$0.shareWith == sharee.shareWith}) { continue } // do not show already existing sharees - if metadata.ownerDisplayName == sharee.shareWith { continue } // do not show owner of the share + if metadata.ownerDisplayName == sharee.shareWith { continue } // do not show owner of the share var label = sharee.label if sharee.shareType == NKShare.ShareType.team.rawValue { label += " (\(sharee.circleInfo), \(sharee.circleOwner))" @@ -370,10 +386,12 @@ extension NCShare: NCShareNetworkingDelegate { dropDown.dataSource.append(label) } - dropDown.anchorView = searchField - dropDown.bottomOffset = CGPoint(x: 10, y: searchField.bounds.height) - dropDown.width = searchField.bounds.width - 20 - dropDown.direction = .bottom + if let shareSearchHost { + dropDown.anchorView = shareSearchHost.view + dropDown.bottomOffset = CGPoint(x: 10, y: shareSearchHost.view.bounds.height) + dropDown.width = shareSearchHost.view.bounds.width - 20 + dropDown.direction = .bottom + } dropDown.cellNib = UINib(nibName: "NCSearchUserDropDownCell", bundle: nil) dropDown.customCellConfiguration = { (index: Index, _, cell: DropDownCell) in @@ -406,6 +424,12 @@ extension NCShare: NCShareNetworkingDelegate { func downloadLimitSet(to limit: Int, by token: String) { database.createDownloadLimit(account: metadata.account, count: 0, limit: limit, token: token) } + + func showOKAlert(title: String?, message: String?) { + let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) + return present(alertController, animated: true) + } } // MARK: - UITableViewDelegate @@ -490,6 +514,7 @@ extension NCShare: UITableViewDataSource { cell.delegate = self cell.setupCellUI(userId: session.userId, session: session, metadata: metadata) + cell.imageItem.image = NCUtility().userImage cell.buttonMenu.menu = NCContextMenuShare(share: tableShare, isDirectory: metadata.isDirectory, canReshare: canReshare, shareController: self).viewMenu() cell.buttonMenu.showsMenuAsPrimaryAction = true @@ -508,7 +533,7 @@ extension NCShare: CNContactPickerDelegate { if contact.emailAddresses.count > 1 { showEmailList(arrEmail: contact.emailAddresses.map({$0.value as String}), sender: picker) } else if let email = contact.emailAddresses.first?.value as? String { - searchField?.text = email + shareSearchHost?.text = email networking?.getSharees(searchString: email) } } @@ -518,7 +543,7 @@ extension NCShare: CNContactPickerDelegate { for email in arrEmail { alert.addAction(UIAlertAction(title: email, style: .default) { _ in - self.searchField?.text = email + self.shareSearchHost?.text = email self.networking?.getSharees(searchString: email) }) } @@ -541,7 +566,7 @@ extension NCShare: CNContactPickerDelegate { // MARK: - UISearchBarDelegate extension NCShare: UISearchBarDelegate { - func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + func searchTextDidChange(_ searchText: String) { NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(searchSharees(_:)), object: nil) if searchText.isEmpty { @@ -552,7 +577,7 @@ extension NCShare: UISearchBarDelegate { } @objc private func searchSharees(_ sender: Any?) { - guard let searchString = searchField.text?.trimmingCharacters(in: .whitespacesAndNewlines), !searchString.isEmpty else { return } + guard let searchString = shareSearchHost?.text.trimmingCharacters(in: .whitespacesAndNewlines), !searchString.isEmpty else { return } if searchString.contains("@"), !isValidEmail(searchString) { return } networking?.getSharees(searchString: searchString) } diff --git a/iOSClient/Share/NCShareHeader.swift b/iOSClient/Share/NCShareHeader.swift index 3d38815179..928efc4502 100644 --- a/iOSClient/Share/NCShareHeader.swift +++ b/iOSClient/Share/NCShareHeader.swift @@ -44,7 +44,9 @@ class NCShareHeader: UIView { imageView.isHidden = true } else { if metadata.directory { - imageView.image = metadata.e2eEncrypted ? NCImageCache.shared.getFolderEncrypted(account: metadata.account) : NCImageCache.shared.getFolder(account: metadata.account) + imageView.image = (metadata.e2eEncrypted ? UIImage(resource: .folderEncrypted) : UIImage(resource: .folder)) + .withTintColor(UIColor(resource: .Share.commonIconTint)) + .withRenderingMode(.alwaysOriginal) } else if !metadata.iconName.isEmpty { imageView.image = NCUtility().loadImage(named: metadata.iconName, useTypeIconFile: true, account: metadata.account) } else { @@ -60,6 +62,9 @@ class NCShareHeader: UIView { info.text = utilityFileSystem.transformedSize(metadata.size) + ", " + NCUtility().getRelativeDateTitle(metadata.date as Date) tagListView.addTags(Array(metadata.tags)) + + tagListView.backgroundColor = .clear + backgroundColor = UIColor(resource: .Share.Advanced.background) setNeedsLayout() layoutIfNeeded() diff --git a/iOSClient/Share/NCShareLinkCell.swift b/iOSClient/Share/NCShareLinkCell.swift index 2ec69b2b50..efa956251a 100644 --- a/iOSClient/Share/NCShareLinkCell.swift +++ b/iOSClient/Share/NCShareLinkCell.swift @@ -4,6 +4,7 @@ // // Created by Henrik Storch on 15.11.2021. // Copyright © 2021 Henrik Storch. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Henrik Storch // @@ -48,23 +49,26 @@ class NCShareLinkCell: UITableViewCell { } func setupCellUI(titleAppendString: String? = nil) { - var menuImageName = "ellipsis" + var menuImageResource: ImageResource = .Share.threeDots + let commonIconTint = UIColor(resource: .Share.commonIconTint) menuButton.isHidden = isInternalLink descriptionLabel.isHidden = !isInternalLink + descriptionLabel.textColor = UIColor(resource: .Share.Advanced.Cell.subtitle) copyButton.isHidden = !isInternalLink && tableShare == nil statusStackView.isHidden = isInternalLink copyButton.setImage(UIImage(systemName: "doc.on.doc")?.withTintColor(.label, renderingMode: .alwaysOriginal), for: .normal) copyButton.accessibilityLabel = NSLocalizedString("_copy_", comment: "") - + copyButton.setImage(UIImage(resource: .Share.internalLink).withTintColor(commonIconTint), for: .normal) + copyButton.imageView?.contentMode = .scaleAspectFit menuButton.accessibilityLabel = NSLocalizedString("_more_", comment: "") menuButton.accessibilityIdentifier = "showShareLinkDetails" if isInternalLink { labelTitle.text = NSLocalizedString("_share_internal_link_", comment: "") descriptionLabel.text = NSLocalizedString("_share_internal_link_des_", comment: "") - imageItem.image = NCUtility().loadImage(named: "square.and.arrow.up.circle.fill", colors: [NCBrandColor.shared.iconImageColor2]) + imageItem.image = UIImage(resource: .Share.squareAndArrowUpCircleFill) } else { labelTitle.text = NSLocalizedString("_share_link_", comment: "") @@ -77,19 +81,18 @@ class NCShareLinkCell: UITableViewCell { labelTitle.text? += " (\(tableShare.label))" } } else { - menuImageName = "plus" + menuImageResource = .Share.plus menuButton.accessibilityLabel = NSLocalizedString("_add_", comment: "") menuButton.accessibilityIdentifier = "addShareLink" } - imageItem.image = NCUtility().loadImage(named: "link.circle.fill", colors: [NCBrandColor.shared.getElement(account: tableShare?.account)]) - menuButton.setImage(NCUtility().loadImage(named: menuImageName, colors: [NCBrandColor.shared.iconImageColor]), for: .normal) + imageItem.image = UIImage(resource: .Share.linkCircleFill) + menuButton.setImage(UIImage(resource: menuImageResource).withTintColor(commonIconTint), for: .normal) } labelTitle.textColor = NCBrandColor.shared.textColor statusStackView.isHidden = true - if let tableShare { statusStackView.isHidden = false labelQuickStatus.text = NSLocalizedString("_custom_permissions_", comment: "") @@ -106,7 +109,7 @@ class NCShareLinkCell: UITableViewCell { if tableShare.shareType == NKShare.ShareType.email.rawValue { labelTitle.text = tableShare.shareWithDisplayname - imageItem.image = NCUtility().loadImage(named: "envelope.circle.fill", colors: [NCBrandColor.shared.getElement(account: tableShare.account)]) + imageItem.image = utility.userImage } } diff --git a/iOSClient/Share/NCShareLinkCell.xib b/iOSClient/Share/NCShareLinkCell.xib index 3311593091..6b6ff6c764 100755 --- a/iOSClient/Share/NCShareLinkCell.xib +++ b/iOSClient/Share/NCShareLinkCell.xib @@ -17,23 +17,23 @@ - - + + - + - + - - + + - @@ -88,7 +79,7 @@ - + @@ -138,9 +129,9 @@ - - - + + + diff --git a/iOSClient/Share/ShareSearchField.swift b/iOSClient/Share/ShareSearchField.swift new file mode 100644 index 0000000000..77e42e6d2e --- /dev/null +++ b/iOSClient/Share/ShareSearchField.swift @@ -0,0 +1,122 @@ +// +// ShareSearchField.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 06.03.2025. +// Copyright © 2025 STRATO GmbH. All rights reserved. +// + +import SwiftUI +import Combine + +struct ShareSearchField: View { + class Model: ObservableObject { + @Published var placeholder: String = "" + @Published var text: String = "" + } + + @ObservedObject var model: Model + let onContactButtonTap: () -> Void + + var body: some View { + HStack(spacing: 0) { + Image(.Share.magnifyingGlass) + .padding(.leading, 16) + .padding(.trailing, 11) + if #available(iOS 16.0, *) { + TextField("", + text: $model.text, + prompt: Text(model.placeholder).foregroundColor(Color(.Share.Advanced.SearchField.placeholder))) + .font(.system(size: 16)) + .autocorrectionDisabled() + } else { + ZStack(alignment: .leading) { + if model.text.isEmpty { + Text(model.placeholder).foregroundColor(Color(.Share.Advanced.SearchField.placeholder)) + } + TextField("", text: $model.text) + } + .font(.system(size: 16)) + .autocorrectionDisabled() + } + Button { + onContactButtonTap() + } label: { + Image(.Share.userContacts) + } + .padding(.leading, 11) + .padding(.trailing, 12) + } + .frame(height: 48) + .background( + RoundedRectangle(cornerRadius: 8) + .stroke(Color(.Share.Advanced.SearchField.border), + lineWidth: 1) + ) + } +} + +#Preview { + ShareSearchField(model: ShareSearchField.Model(), + onContactButtonTap: {}) + .padding(10) + .background(Color(.AppBackground.main)) + .environment(\.colorScheme, .light) + ShareSearchField(model: ShareSearchField.Model(), + onContactButtonTap: {}) + .padding(10) + .background(Color(.AppBackground.main)) + .environment(\.colorScheme, .dark) +} + +class ShareSearchFieldHost: UIHostingController { + + private var cancellables: [AnyCancellable] = [] + private var model: ShareSearchField.Model! + + override init(rootView: ShareSearchField) { + super.init(rootView: rootView) + } + + var placeholder: String { + get { + return model.placeholder + } + set(newValue) { + model.placeholder = newValue + } + } + + var text: String { + get { + return model.text + } + set(newValue) { + model.text = newValue + } + } + + convenience init(onSearchTextChanged: @escaping ((_ text: String) -> Void), + onContactButtonTap: @escaping (() -> Void)) { + let model = ShareSearchField.Model() + let shareSearch = ShareSearchField(model: model, + onContactButtonTap: onContactButtonTap) + self.init(rootView: shareSearch) + self.view.backgroundColor = .clear + self.model = model + + self.model + .$text + .throttle(for: 0.5, + scheduler: DispatchQueue.main, + latest: true) + .removeDuplicates() + .sink { text in + onSearchTextChanged(text) + }.store(in: &cancellables) + } + + @MainActor @preconcurrency required dynamic init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/iOSClient/Shares/NCShares.storyboard b/iOSClient/Shares/NCShares.storyboard index 90ac73d009..0749d14e29 100644 --- a/iOSClient/Shares/NCShares.storyboard +++ b/iOSClient/Shares/NCShares.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,7 +17,7 @@ - + @@ -31,18 +31,31 @@ + + + + + + + + + + - - + + + + + diff --git a/iOSClient/Style/CircleItemSpinner.swift b/iOSClient/Style/CircleItemSpinner.swift new file mode 100644 index 0000000000..6abd59dbbc --- /dev/null +++ b/iOSClient/Style/CircleItemSpinner.swift @@ -0,0 +1,43 @@ +// +// CircleItemSpinner.swift +// Nextcloud +// +// Created by Vitaliy Tolkach on 13.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import SwiftUI + +struct CircleItemSpinner: View { + @State private var degree = 270 + let itemsCount: Int = 7 + let itemSide: CGFloat = 8 + let spinerSide: CGFloat = 60 + + var body: some View { + GeometryReader { bounds in + ForEach(0.. NSStringLocalizedFormatKey %#@downloads@ + downloads + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + %d download rimanente consentito + other + %d download rimanenti consentiti + diff --git a/iOSClient/Supporting Files/nl.lproj/Localizable.strings b/iOSClient/Supporting Files/nl.lproj/Localizable.strings index 1c8045538b..984021d6b1 100644 Binary files a/iOSClient/Supporting Files/nl.lproj/Localizable.strings and b/iOSClient/Supporting Files/nl.lproj/Localizable.strings differ diff --git a/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbar.swift b/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbar.swift new file mode 100644 index 0000000000..991beb46bb --- /dev/null +++ b/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbar.swift @@ -0,0 +1,186 @@ +// +// NCCollectionViewCommonSelectionTabBar.swift +// Nextcloud +// +// Created by Milen on 01.02.24. +// Copyright © 2024 Marino Faggiana. All rights reserved. +// Copyright © 2024 STRATO GmbH +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +import Foundation +import SwiftUI +import NextcloudKit + +class HiDriveCollectionViewCommonSelectToolbar: ObservableObject { + enum TabButton { + case share + case moveOrCopy + case delete + case download + case lockOrUnlock + case restore + } + + private var hostingController: UIViewController? + weak var controller: NCMainTabBarController? + + open weak var delegate: HiDriveCollectionViewCommonSelectToolbarDelegate? + + @Published var isAnyOffline = false + @Published var canSetAsOffline = false + @Published var isAnyDirectory = false + @Published var isAllDirectory = false + @Published var isAnyLocked = false + @Published var canUnlock = true + @Published var enableLock = false + @Published var isSelectedEmpty = true + + let displayedButtons: [TabButton] + + init(controller: NCMainTabBarController?, + delegate: HiDriveCollectionViewCommonSelectToolbarDelegate? = nil, + displayedButtons: [TabButton] = [.share, .moveOrCopy, .delete, .download, .lockOrUnlock]) { + self.delegate = delegate + self.displayedButtons = displayedButtons + self.controller = controller + setupHostingController() + setupOrientationObserver() + } + + private func setupOrientationObserver() { + NotificationCenter.default.addObserver( + self, + selector: #selector(deviceOrientationDidChange), + name: UIDevice.orientationDidChangeNotification, + object: nil + ) + } + + @objc private func deviceOrientationDidChange() { + DispatchQueue.main.async { [weak self] in + self?.updateToolbarFrame() + } + } + + private func setupHostingController() { + let rootView = HiDriveCollectionViewCommonSelectToolbarView(tabBarSelect: self) + hostingController = UIHostingController(rootView: rootView) + hostingController?.view.isHidden = true + } + + private func updateToolbarFrame() { + guard let controller = self.controller, + let hostingController = self.hostingController else { + return + } + + hostingController.view.frame = controller.tabBar.frame + hostingController.view.backgroundColor = .clear + } + + func show() { + guard let hostingController, let currentViewController = controller?.currentViewController() else { return } + + if hostingController.view.isHidden { + delegate?.toolbarWillAppear() + currentViewController.view.addSubview(hostingController.view) + + updateToolbarFrame() + animateToolbarAppearance(for: hostingController) + } + } + + private func animateToolbarAppearance(for hostingController: UIViewController) { + hostingController.view.isHidden = false + hostingController.view.transform = CGAffineTransform(translationX: 0, y: hostingController.view.frame.height) + + UIView.animate(withDuration: 0.2) { + hostingController.view.transform = .identity + } + } + + func hide() { + delegate?.toolbarWillDisappear() + hostingController?.view.isHidden = true + } + + func isHidden() -> Bool { + return hostingController?.view.isHidden ?? false + } + + func update(fileSelect: [String], metadatas: [tableMetadata]? = nil, userId: String? = nil) { + let capabilities = NCNetworking.shared.capabilities[controller?.account ?? ""] ?? NKCapabilities.Capabilities() + if let metadatas { + isAnyOffline = false + canSetAsOffline = true + isAnyDirectory = false + isAllDirectory = true + isAnyLocked = false + canUnlock = true + + for metadata in metadatas { + if metadata.directory { + isAnyDirectory = true + } else { + isAllDirectory = false + } + + if !metadata.canSetAsAvailableOffline { + canSetAsOffline = false + } + + if metadata.lock { + isAnyLocked = true + if metadata.lockOwner != userId { + canUnlock = false + } + } + + guard !isAnyOffline else { continue } + + if metadata.directory, + let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", + metadata.account, + metadata.serverUrl + "/" + metadata.fileName)) { + isAnyOffline = directory.offline + } else if let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) { + isAnyOffline = localFile.offline + } // else: file is not offline, continue + } + enableLock = !isAnyDirectory && canUnlock && !capabilities.filesLockVersion.isEmpty + } + isSelectedEmpty = fileSelect.isEmpty + } + + private func updateOfflineStatus(for metadata: tableMetadata) { + if metadata.directory, + let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl + "/" + metadata.fileName)) { + isAnyOffline = directory.offline + } else if let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) { + isAnyOffline = localFile.offline + } + } + + func onViewWillLayoutSubviews() { + updateToolbarFrame() + } + + deinit { + NotificationCenter.default.removeObserver(self) + } +} diff --git a/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarDelegate.swift b/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarDelegate.swift new file mode 100644 index 0000000000..33be69e414 --- /dev/null +++ b/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarDelegate.swift @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2020 Marino Faggiana +// SPDX-License-Identifier: GPL-3.0-or-later + +protocol HiDriveCollectionViewCommonSelectToolbarDelegate: AnyObject { + func selectAll() + func delete() + func move() + func share() + func recover() + func saveAsAvailableOffline(isAnyOffline: Bool) + func lock(isAnyLocked: Bool) + func toolbarWillAppear() + func toolbarWillDisappear() +} + +extension HiDriveCollectionViewCommonSelectToolbarDelegate { + func selectAll() { } + func delete() { } + func move() { } + func share() { } + func recover() { } + func saveAsAvailableOffline(isAnyOffline: Bool) { } + func lock(isAnyLocked: Bool) { } + func toolbarWillAppear() { } + func toolbarWillDisappear() { } +} diff --git a/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarView.swift b/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarView.swift new file mode 100644 index 0000000000..4d1137535e --- /dev/null +++ b/iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarView.swift @@ -0,0 +1,166 @@ +// +// File.swift +// Nextcloud +// +// Created by Andrey Gubarev on 03.09.2024. +// Copyright © 2024 STRATO GmbH +// + + +import SwiftUI + +struct HiDriveCollectionViewCommonSelectToolbarView: View { + @ObservedObject var tabBarSelect: HiDriveCollectionViewCommonSelectToolbar + + static let wideScreenMinSize: CGFloat = 460 + + var body: some View { + GeometryReader { geometry in + let isWideScreen = geometry.size.width > Self.wideScreenMinSize + VStack { + Spacer().frame(height: 10) + + HStack(alignment: .top) { + if tabBarSelect.displayedButtons.contains(.share) { + TabButton( + action: {tabBarSelect.delegate?.share()}, + image: .SelectTabBar.share, + label: "_share_", + isDisabled: tabBarSelect.isSelectedEmpty || tabBarSelect.isAllDirectory, + isOneRowStyle: isWideScreen + ) + } + if tabBarSelect.displayedButtons.contains(.moveOrCopy) { + TabButton( + action: {tabBarSelect.delegate?.move()}, + image: .SelectTabBar.copy, + label: "_move_or_copy_", + isDisabled: tabBarSelect.isSelectedEmpty, + isOneRowStyle: isWideScreen + ) + } + if tabBarSelect.displayedButtons.contains(.restore) { + TabButton( + action: { tabBarSelect.delegate?.recover() }, + image: .SelectTabBar.restoreFromTrash, + label: "_restore_" , + isDisabled: tabBarSelect.isSelectedEmpty, + isOneRowStyle: isWideScreen + ) + } + if tabBarSelect.displayedButtons.contains(.delete) { + TabButton( + action: {tabBarSelect.delegate?.delete()}, + image: .SelectTabBar.delete, + label: "_delete_", + isDisabled: tabBarSelect.isSelectedEmpty, + isOneRowStyle: isWideScreen + ) + } + if tabBarSelect.displayedButtons.contains(.download) { + TabButton( + action: {tabBarSelect.delegate?.saveAsAvailableOffline(isAnyOffline: tabBarSelect.isAnyOffline)}, + image: .SelectTabBar.download, + label: "_download_", + isDisabled: !tabBarSelect.isAnyOffline && (!tabBarSelect.canSetAsOffline || tabBarSelect.isSelectedEmpty), + isOneRowStyle: isWideScreen + ) + } + if tabBarSelect.displayedButtons.contains(.lockOrUnlock) { + TabButton( + action: {tabBarSelect.delegate?.lock(isAnyLocked: tabBarSelect.isAnyLocked)}, + image: (tabBarSelect.isAnyLocked ? .SelectTabBar.unlock : .SelectTabBar.lock), + label: tabBarSelect.isAnyLocked ? "_unlock_" : "_lock_", + isDisabled: !tabBarSelect.enableLock || tabBarSelect.isSelectedEmpty, + isOneRowStyle: isWideScreen + ) + } + } + .frame(maxWidth: isWideScreen ? geometry.size.width * 0.85 : .infinity) + } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .background(Color(.Tabbar.background)) + } + } +} + +struct TabButton: View { + let action: (() -> Void)? + let image: ImageResource + let label: String + let isDisabled: Bool + let isOneRowStyle: Bool + + var body: some View { + Button(action: { + action?() + }, label: { + if isOneRowStyle { + HStack { + IconWithText(image: image, label: label) + } + .frame(maxWidth: .infinity) + } else { + VStack { + IconWithText(image: image, label: label) + } + .frame(maxWidth: .infinity) + } + }) + .frame(maxWidth: .infinity) + .buttonStyle(CustomBackgroundOnPressButtonStyle(isDisabled: isDisabled)) + .disabled(isDisabled) + .complexModifier{ view in + // ios 15 fix: didn't tap on ios 15 + if #available(iOS 16.0, *) { + view + } else { + view.onTapGesture { + if !isDisabled { + action?() + } + } + } + } + } +} + +private struct IconWithText: View { + @Environment(\.verticalSizeClass) var sizeClass + var image: ImageResource + var label: String + + var body: some View { + let iconWidth = CGFloat(sizeClass == .compact ? 28 : 34) + let iconHeight = iconWidth - 10 + Image(image) + .resizable() + .font(Font.system(.body).weight(.light)) + .scaledToFit() + .frame(width: iconWidth, height: iconHeight) + Text(NSLocalizedString(label, comment: "")) + .font(.system(size: 12)) + .multilineTextAlignment(.center) + .lineLimit(2) + .tint(Color(NCBrandColor.shared.textColor)) + } +} + +private struct CustomBackgroundOnPressButtonStyle: ButtonStyle { + var isDisabled: Bool + + func makeBody(configuration: Configuration) -> some View { + if isDisabled { + configuration.label.foregroundColor(Color(.SelectToolbar.itemStateInactive)) + } else if configuration.isPressed { + configuration.label.foregroundColor(Color(.SelectToolbar.itemStateSelected)) + } else { + configuration.label.foregroundColor(Color(.SelectToolbar.itemStateActive)) + } + } +} + +#Preview { + HiDriveCollectionViewCommonSelectToolbarView(tabBarSelect: HiDriveCollectionViewCommonSelectToolbar(controller: nil)) +} + diff --git a/iOSClient/Transfers/TransfersListener.swift b/iOSClient/Transfers/TransfersListener.swift new file mode 100644 index 0000000000..07364aed01 --- /dev/null +++ b/iOSClient/Transfers/TransfersListener.swift @@ -0,0 +1,48 @@ +// +// TransfersListener.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 23.04.2025. +// Copyright © 2025 STRATO GmbH. All rights reserved. +// + +import Combine + +class TransfersListener { + + static let shared = TransfersListener() + + private var timer: Timer? + + let activeTransfersListener: PassthroughSubject = .init() + private(set) var areActiveTransfersPresent: Bool = false + + init() { + NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { _ in + self.timer?.invalidate() + self.timer = nil + } + + NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { _ in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + if UIApplication.shared.applicationState == .active { + self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in + self.onTimerTick() + }) + } + } + } + } + + private func onTimerTick() { + Task { + areActiveTransfersPresent = await calculatePresenceOfActiveTransfers() + activeTransfersListener.send() + } + } + + private func calculatePresenceOfActiveTransfers() async -> Bool { + let resultsCount = await NCManageDatabase.shared.getMetadatasAsync(predicate: NSPredicate(format: "status != %i", NCGlobal.shared.metadataStatusNormal))?.count ?? 0 + return resultsCount > 0 + } +} diff --git a/iOSClient/Trash/Cell/NCTrashCellProtocol.swift b/iOSClient/Trash/Cell/NCTrashCellProtocol.swift index 8c82abf6db..b57933646c 100644 --- a/iOSClient/Trash/Cell/NCTrashCellProtocol.swift +++ b/iOSClient/Trash/Cell/NCTrashCellProtocol.swift @@ -37,7 +37,7 @@ extension NCTrashCellProtocol where Self: UICollectionViewCell { mutating func setupCellUI(tableTrash: tableTrash, image: UIImage?) { self.objectId = tableTrash.fileId self.labelTitle.text = tableTrash.trashbinFileName - self.labelTitle.textColor = NCBrandColor.shared.textColor + self.labelTitle.textColor = UIColor(resource: .ListCell.title) if self is NCTrashListCell { self.labelInfo?.text = NCUtility().getRelativeDateTitle(tableTrash.trashbinDeletionTime as Date) } else { diff --git a/iOSClient/Trash/Cell/NCTrashGridCell.swift b/iOSClient/Trash/Cell/NCTrashGridCell.swift index 5c03bbb5b4..30891b5a8e 100644 --- a/iOSClient/Trash/Cell/NCTrashGridCell.swift +++ b/iOSClient/Trash/Cell/NCTrashGridCell.swift @@ -4,6 +4,7 @@ // // Created by Marino Faggiana on 19/03/2024. // Copyright © 2024 Marino Faggiana. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Marino Faggiana // @@ -34,7 +35,6 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { @IBOutlet weak var labelInfo: UILabel! @IBOutlet weak var labelSubinfo: UILabel! @IBOutlet weak var buttonMore: UIButton! - @IBOutlet weak var imageVisualEffect: UIVisualEffectView! weak var delegate: NCTrashGridCellDelegate? var objectId = "" @@ -61,13 +61,11 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { imageItem.layer.cornerRadius = 6 imageItem.layer.masksToBounds = true - imageVisualEffect.layer.cornerRadius = 6 - imageVisualEffect.clipsToBounds = true - imageVisualEffect.alpha = 0.5 - labelTitle.text = "" labelInfo.text = "" labelSubinfo.text = "" + + imageSelect.image = UIImage(resource: .FileSelection.gridItemSelected) } override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { @@ -100,14 +98,8 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { buttonMore.isHidden = false setA11yActions() } - if status { - imageSelect.image = NCImageCache.shared.getImageCheckedYes() - imageSelect.isHidden = false - imageVisualEffect.isHidden = false - } else { - imageSelect.isHidden = true - imageVisualEffect.isHidden = true - } + setBorderForGridViewCell(isSelected: status) + imageSelect.isHidden = !status } func writeInfoDateSize(date: NSDate, size: Int64) { diff --git a/iOSClient/Trash/Cell/NCTrashGridCell.xib b/iOSClient/Trash/Cell/NCTrashGridCell.xib index 607f2744c6..47c93eec3a 100644 --- a/iOSClient/Trash/Cell/NCTrashGridCell.xib +++ b/iOSClient/Trash/Cell/NCTrashGridCell.xib @@ -1,9 +1,9 @@ - + - + @@ -21,15 +21,6 @@ - @@ -88,10 +79,8 @@ - - @@ -108,8 +97,6 @@ - - @@ -118,15 +105,14 @@ - + - diff --git a/iOSClient/Trash/Cell/NCTrashListCell.swift b/iOSClient/Trash/Cell/NCTrashListCell.swift index 5bd89e1615..dabe732d78 100644 --- a/iOSClient/Trash/Cell/NCTrashListCell.swift +++ b/iOSClient/Trash/Cell/NCTrashListCell.swift @@ -72,13 +72,13 @@ class NCTrashListCell: UICollectionViewCell, NCTrashCellProtocol { ] - imageRestore.image = NCUtility().loadImage(named: "arrow.counterclockwise", colors: [NCBrandColor.shared.iconImageColor]) - imageMore.image = NCUtility().loadImage(named: "trash", colors: [.red]) + imageRestore.image = UIImage(resource: .restoreFromDeleted).withTintColor(NCBrandColor.shared.iconImageColor) + imageMore.image = NCImagesRepository.menuIconTrash.image(color: .red) imageItem.layer.cornerRadius = 6 imageItem.layer.masksToBounds = true - separator.backgroundColor = .separator - separatorHeightConstraint.constant = 0.5 + separator.backgroundColor = UIColor(resource: .ListCell.separator) + separatorHeightConstraint.constant = 1 } @IBAction func touchUpInsideMore(_ sender: Any) { @@ -107,18 +107,9 @@ class NCTrashListCell: UICollectionViewCell, NCTrashCellProtocol { backgroundView = nil } if status { - var blurEffectView: UIView? - blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) - blurEffectView?.backgroundColor = .lightGray - blurEffectView?.frame = self.bounds - blurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - imageSelect.image = NCImageCache.shared.getImageCheckedYes() - backgroundView = blurEffectView - separator.isHidden = true + imageSelect.image = NCImageCache.shared.getImageCheckedYes().withTintColor(NCBrandColor.shared.brandElement) } else { - imageSelect.image = NCImageCache.shared.getImageCheckedNo() - backgroundView = nil - separator.isHidden = false + imageSelect.image = NCImageCache.shared.getImageCheckedNo().withTintColor(UIColor(resource: .FileSelection.listItemDeselected)) } } diff --git a/iOSClient/Trash/Cell/NCTrashListCell.xib b/iOSClient/Trash/Cell/NCTrashListCell.xib index 15946f2a5b..7f72e6a54e 100644 --- a/iOSClient/Trash/Cell/NCTrashListCell.xib +++ b/iOSClient/Trash/Cell/NCTrashListCell.xib @@ -1,9 +1,10 @@ - + - + + @@ -11,35 +12,35 @@ - + - + - + + - - + - - + + - + - - + + - + @@ -79,10 +80,10 @@ - + - - + + @@ -91,23 +92,23 @@ - + - + - + + + - - - + @@ -128,4 +129,12 @@ + + + + + + + + diff --git a/iOSClient/Trash/NCTrash+CollectionView.swift b/iOSClient/Trash/NCTrash+CollectionView.swift index 694f174be3..a646d8a250 100644 --- a/iOSClient/Trash/NCTrash+CollectionView.swift +++ b/iOSClient/Trash/NCTrash+CollectionView.swift @@ -4,6 +4,7 @@ // // Created by Henrik Storch on 18.01.22. // Copyright © 2022 Henrik Storch. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Henrik Storch // @@ -24,8 +25,17 @@ import UIKit import RealmSwift -// MARK: UICollectionViewDelegate +// MARK: UICollectionViewDelegate extension NCTrash: UICollectionViewDelegate { + var selectionState: FileActionsHeaderSelectionState { + let selectedItemsCount = selectOcId.count + if selectedItemsCount == datasource?.count { + return .all + } + + return selectedItemsCount == 0 ? .none : .some(selectedItemsCount) + } + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let resultTableTrash = datasource?[indexPath.item] else { return } guard !isEditMode else { @@ -34,8 +44,9 @@ extension NCTrash: UICollectionViewDelegate { } else { selectOcId.append(resultTableTrash.fileId) } + vHeader.setSelectionState(selectionState: selectionState) collectionView.reloadItems(at: [indexPath]) - tabBarSelect.update(selectOcId: selectOcId) + selectionToolbar.update(fileSelect: selectOcId) return } diff --git a/iOSClient/Trash/NCTrash+SelectTabBarDelegate.swift b/iOSClient/Trash/NCTrash+SelectTabBarDelegate.swift index 677047688c..7a73dd69d9 100644 --- a/iOSClient/Trash/NCTrash+SelectTabBarDelegate.swift +++ b/iOSClient/Trash/NCTrash+SelectTabBarDelegate.swift @@ -22,7 +22,7 @@ import Foundation import UIKit -extension NCTrash: NCTrashSelectTabBarDelegate { +extension NCTrash: HiDriveCollectionViewCommonSelectToolbarDelegate { func onListSelected() { if layoutForView?.layout == NCGlobal.shared.layoutGrid { layoutForView?.layout = NCGlobal.shared.layoutList @@ -50,7 +50,7 @@ extension NCTrash: NCTrashSelectTabBarDelegate { } else { selectOcId = datasource.compactMap({ $0.fileId }) } - tabBarSelect.update(selectOcId: selectOcId) + selectionToolbar.update(fileSelect: selectOcId) collectionView.reloadData() } @@ -80,15 +80,14 @@ extension NCTrash: NCTrashSelectTabBarDelegate { func setEditMode(_ editMode: Bool) { Task { - isEditMode = editMode - selectOcId.removeAll() + isEditMode = editMode + selectOcId.removeAll() - navigationItem.hidesBackButton = editMode - navigationController?.interactivePopGestureRecognizer?.isEnabled = !editMode + updateSelectionToolbar() - await (self.navigationController as? NCMainNavigationController)?.setNavigationRightItems() - - collectionView.reloadData() + navigationController?.interactivePopGestureRecognizer?.isEnabled = !editMode + navigationItem.hidesBackButton = editMode + collectionView.reloadData() } } } diff --git a/iOSClient/Trash/NCTrash.storyboard b/iOSClient/Trash/NCTrash.storyboard index c7dbd8669c..5aee6d656e 100644 --- a/iOSClient/Trash/NCTrash.storyboard +++ b/iOSClient/Trash/NCTrash.storyboard @@ -1,10 +1,11 @@ - + - + + @@ -16,8 +17,15 @@ + + + + + + + - + @@ -36,13 +44,17 @@ + + + - + + @@ -50,4 +62,9 @@ + + + + + diff --git a/iOSClient/Trash/NCTrash.swift b/iOSClient/Trash/NCTrash.swift index ea7bd3489d..1e4fd0829d 100644 --- a/iOSClient/Trash/NCTrash.swift +++ b/iOSClient/Trash/NCTrash.swift @@ -5,6 +5,7 @@ // Created by Marino Faggiana on 02/10/2018. // Copyright © 2018 Marino Faggiana. All rights reserved. // Copyright © 2022 Henrik Storch. All rights reserved. +// Copyright © 2024 STRATO GmbH // // Author Henrik Storch // Author Marino Faggiana @@ -30,15 +31,22 @@ import RealmSwift class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegate { @IBOutlet weak var collectionView: UICollectionView! + @IBOutlet weak var vHeader: FileActionsHeader! + var filePath = "" var titleCurrentFolder = NSLocalizedString("_trash_view_", comment: "") var blinkFileId: String? let utilityFileSystem = NCUtilityFileSystem() let database = NCManageDatabase.shared let utility = NCUtility() - var isEditMode = false + var isEditMode = false { + didSet { + vHeader.setIsEditingMode(isEditingMode: isEditMode) + updateSelectionToolbar() + } + } var selectOcId: [String] = [] - var tabBarSelect: NCTrashSelectTabBar! + var selectionToolbar: HiDriveCollectionViewCommonSelectToolbar! var datasource: [tableTrash]? var layoutForView: NCDBLayoutForView? var listLayout: NCListLayout! @@ -53,20 +61,21 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat } var controller: NCMainTabBarController? { - self.tabBarController as? NCMainTabBarController + self.mainTabBarController } - var mainNavigationController: NCMainNavigationController? { - self.navigationController as? NCMainNavigationController + var mainNavigationController: HiDriveMainNavigationController? { + self.navigationController as? HiDriveMainNavigationController } // MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() - navigationController?.setNavigationBarAppearance() + selectionToolbar = HiDriveCollectionViewCommonSelectToolbar(controller: nil, delegate: self, displayedButtons: [.restore, .delete]) - view.backgroundColor = .systemBackground + view.backgroundColor = NCBrandColor.shared.appBackgroundColor + self.navigationController?.navigationBar.prefersLargeTitles = false collectionView.register(UINib(nibName: "NCTrashListCell", bundle: nil), forCellWithReuseIdentifier: "listCell") collectionView.register(UINib(nibName: "NCTrashGridCell", bundle: nil), forCellWithReuseIdentifier: "gridCell") @@ -75,7 +84,7 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat collectionView.register(UINib(nibName: "NCSectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "sectionFooter") collectionView.alwaysBounceVertical = true - collectionView.backgroundColor = .systemBackground + collectionView.backgroundColor = NCBrandColor.shared.appBackgroundColor listLayout = NCListLayout() gridLayout = NCGridLayout() @@ -88,15 +97,33 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat await self.loadListingTrash() } } + + updateHeadersView() } + private func updateHeadersView() { + vHeader?.setIsEditingMode(isEditingMode: isEditMode) + vHeader?.setViewModeMenu(viewMenuElements: createViewModeMenuActions(), image: viewModeImage?.templateRendered()) + vHeader?.enableSelection(enable: !(datasource?.isEmpty ?? true)) + + vHeader?.onSelectModeChange = { [weak self] isSelectionMode in + self?.setEditMode(isSelectionMode) + self?.updateHeadersView() + self?.vHeader?.setSelectionState(selectionState: .none) + } + + vHeader?.onSelectAll = { [weak self] in + guard let self = self else { return } + self.selectAll() + let selectionState: FileActionsHeaderSelectionState = self.selectOcId.count == 0 ? .none : .all + self.vHeader?.setSelectionState(selectionState: selectionState) + } + updateSelectionToolbar() + } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - if tabBarSelect == nil { - tabBarSelect = NCTrashSelectTabBar(controller: tabBarController, viewController: self, delegate: self) - } - navigationController?.setNavigationBarAppearance() navigationItem.title = titleCurrentFolder @@ -109,13 +136,20 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat } isEditMode = false - + setNavigationLeftItems() + updateHeadersView() + Task { - await (self.navigationController as? NCMainNavigationController)?.setNavigationRightItems() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() await self.reloadDataSource() await loadListingTrash() } } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + selectionToolbar.controller = mainTabBarController + } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) @@ -128,6 +162,35 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat NCNetworking.shared.downloadThumbnailTrashQueue.cancelAll() } + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + selectionToolbar.onViewWillLayoutSubviews() + } + + // MARK: - Layout + + func updateSelectionToolbar() { + if isEditMode { + selectionToolbar.update(fileSelect: selectOcId) + selectionToolbar.show() + } else if navigationItem.rightBarButtonItems == nil || (!isEditMode && !selectionToolbar.isHidden()) { + selectionToolbar.hide() + } + } + + func setNavigationLeftItems() { + if layoutKey == NCGlobal.shared.layoutViewTrash { + navigationItem.leftItemsSupplementBackButton = true + if navigationController?.viewControllers.count == 1 { + navigationItem.setLeftBarButtonItems([UIBarButtonItem(title: NSLocalizedString("_close_", comment: ""), + style: .plain, + action: { [weak self] in + self?.dismiss(animated: true) + })], animated: true) + } + } + } + // MARK: TAP EVENT func tapRestoreListItem(with id: String, image: UIImage?, sender: Any) { @@ -166,11 +229,12 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat func reloadDataSource(withQueryDB: Bool = true) async { let results = await self.database.getTableTrashAsync(filePath: getFilePath(), account: session.account) - await mainNavigationController?.updateMenuOption() + (self.navigationController as? HiDriveMainNavigationController)?.setNavigationRightItems() await MainActor.run { self.datasource = results self.collectionView.reloadData() + self.updateHeadersView() guard let blinkFileId = self.blinkFileId else { return } @@ -202,3 +266,29 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat } } } + + +extension NCTrash { + private var viewModeImage: UIImage? { + let imageResource: ImageResource = collectionView.collectionViewLayout == listLayout ? .FileSelection.viewModeList : .FileSelection.viewModeGrid + return UIImage(resource: imageResource) + } + + func createViewModeMenuActions() -> [UIMenuElement] { + let layoutForView = collectionView.collectionViewLayout + + let listImage = UIImage(resource: .FileSelection.viewModeList).templateRendered() + let gridImage = UIImage(resource: .FileSelection.viewModeGrid).templateRendered() + + let list = UIAction(title: NSLocalizedString("_list_", comment: ""), image: listImage, state: layoutForView == listLayout ? .on : .off) { [weak self] _ in + self?.onListSelected() + self?.updateHeadersView() + } + + let grid = UIAction(title: NSLocalizedString("_icons_", comment: ""), image: gridImage, state: layoutForView == gridLayout ? .on : .off) { [weak self] _ in + self?.onGridSelected() + self?.updateHeadersView() + } + return [list, grid] + } +} diff --git a/iOSClient/Trash/NCTrashSelectTabBar.swift b/iOSClient/Trash/NCTrashSelectTabBar.swift deleted file mode 100644 index bc90132fa8..0000000000 --- a/iOSClient/Trash/NCTrashSelectTabBar.swift +++ /dev/null @@ -1,165 +0,0 @@ -// -// NCTrashSelectTabBar.swift -// Nextcloud -// -// Created by Milen on 05.02.24. -// Copyright © 2024 Marino Faggiana. All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -import Foundation -import UIKit -import SwiftUI - -protocol NCTrashSelectTabBarDelegate: AnyObject { - func selectAll() - func recover() - func delete() -} - -class NCTrashSelectTabBar: ObservableObject { - var controller: UITabBarController? - var hostingController: UIViewController? - open weak var delegate: NCTrashSelectTabBarDelegate? - - @Published var isSelectedEmpty = true - - init(controller: UITabBarController? = nil, viewController: UIViewController, delegate: NCTrashSelectTabBarDelegate? = nil) { - guard let controller else { - return - } - let rootView = NCTrashSelectTabBarView(tabBarSelect: self) - let bottomAreaInsets: CGFloat = controller.tabBar.safeAreaInsets.bottom == 0 ? 34 : 0 - let height = controller.tabBar.frame.height + bottomAreaInsets - hostingController = UIHostingController(rootView: rootView) - guard let hostingController else { - return - } - - self.controller = controller - self.delegate = delegate - - hostingController.view.translatesAutoresizingMaskIntoConstraints = false - hostingController.view.backgroundColor = .clear - hostingController.view.isHidden = true - - viewController.view.addSubview(hostingController.view) - - NSLayoutConstraint.activate([ - hostingController.view.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor), - hostingController.view.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor), - hostingController.view.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor), - hostingController.view.heightAnchor.constraint(equalToConstant: height) - ]) - } - - func show() { - guard let controller, - let hostingController else { - return - } - - if #available(iOS 18.0, *) { - controller.setTabBarHidden(true, animated: true) - } else { - controller.tabBar.isHidden = true - } - - if hostingController.view.isHidden { - hostingController.view.isHidden = false - - hostingController.view.transform = .init(translationX: 0, y: hostingController.view.frame.height) - - UIView.animate(withDuration: 0.2) { - hostingController.view.transform = .init(translationX: 0, y: 0) - } - } - } - - func hide() { - guard let controller, - let hostingController else { - return - } - - hostingController.view.isHidden = true - - if #available(iOS 18.0, *) { - controller.setTabBarHidden(false, animated: true) - } else { - controller.tabBar.isHidden = false - } - } - - func update(selectOcId: [String]) { - isSelectedEmpty = selectOcId.isEmpty - } - - func isHidden() -> Bool { - guard let hostingController else { return false } - return hostingController.view.isHidden - } -} - -struct NCTrashSelectTabBarView: View { - @ObservedObject var tabBarSelect: NCTrashSelectTabBar - @Environment(\.verticalSizeClass) var sizeClass - - var body: some View { - VStack { - Spacer().frame(height: sizeClass == .compact ? 5 : 10) - HStack { - Button { - tabBarSelect.delegate?.recover() - } label: { - Image(systemName: "arrow.counterclockwise") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(Color(NCBrandColor.shared.iconImageColor)) - .frame(maxWidth: .infinity) - .disabled(tabBarSelect.isSelectedEmpty) - - Button { - tabBarSelect.delegate?.delete() - } label: { - Image(systemName: "trash") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(.red) - .frame(maxWidth: .infinity) - .disabled(tabBarSelect.isSelectedEmpty) - - Button { - tabBarSelect.delegate?.selectAll() - } label: { - Image(systemName: "checkmark") - .font(Font.system(.body).weight(.light)) - .imageScale(sizeClass == .compact ? .medium : .large) - } - .tint(Color(NCBrandColor.shared.iconImageColor)) - .frame(maxWidth: .infinity) - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - .background(.thinMaterial) - .overlay(Rectangle().frame(width: nil, height: 0.5, alignment: .top).foregroundColor(Color(UIColor.separator)), alignment: .top) - } -} - -#Preview { - NCTrashSelectTabBarView(tabBarSelect: NCTrashSelectTabBar(viewController: UIViewController())) -} diff --git a/iOSClient/Utility/AccountButtonFactory.swift b/iOSClient/Utility/AccountButtonFactory.swift new file mode 100644 index 0000000000..b88451e86c --- /dev/null +++ b/iOSClient/Utility/AccountButtonFactory.swift @@ -0,0 +1,81 @@ +// +// AccountButtonFactory.swift +// Nextcloud +// +// Created by Sergey Kaliberda on 12.09.2024. +// Copyright © 2024 STRATO GmbH +// + +import UIKit +import SwiftUI +import RealmSwift +import NextcloudKit +import EasyTipView + +class AccountButtonFactory { + let database = NCManageDatabase.shared + let utility = NCUtility() + let appDelegate = (UIApplication.shared.delegate as? AppDelegate)! + private let controller: NCMainTabBarController? + + private var onAccountDetailsOpen: (() -> Void) + private var presentVC: ((UIViewController) -> Void) + private var onMenuOpened: (() -> Void)? + + init(controller: NCMainTabBarController?, + onAccountDetailsOpen: (@escaping () -> Void), + presentVC: (@escaping (UIViewController) -> Void), + onMenuOpened: (() -> Void)? = nil) { + self.controller = controller + self.onAccountDetailsOpen = onAccountDetailsOpen + self.presentVC = presentVC + self.onMenuOpened = onMenuOpened + } + + func createAccountButton() -> UIBarButtonItem { + let session = NCSession.shared.getSession(controller: controller) + guard let tableAccount = self.database.getTableAccount(predicate: NSPredicate(format: "account == %@", session.account)) else { + return UIBarButtonItem() + } + let image = utility.loadUserImage(for: tableAccount.account, displayName: tableAccount.displayName, urlBase: tableAccount.urlBase) + let accountButton = AccountSwitcherButton(type: .custom) + let accounts = NCManageDatabase.shared.getAllAccountOrderAlias() + + accountButton.setImage(image, for: .normal) + accountButton.setImage(image, for: .highlighted) + accountButton.semanticContentAttribute = .forceLeftToRight + accountButton.sizeToFit() + accountButton.action(for: .touchUpInside, { [weak self] _ in + let accountSettingsModel = NCAccountSettingsModel(controller: self?.controller, delegate: self) + let accountSettingsView = NCAccountSettingsView(model: accountSettingsModel) + let accountSettingsController = UIHostingController(rootView: accountSettingsView) + self?.presentVC(accountSettingsController) + }) + return UIBarButtonItem(customView: accountButton) + } +} + +extension AccountButtonFactory: NCAccountSettingsModelDelegate { + func accountSettingsDidDismiss(tblAccount tableAccount: tableAccount?, controller: NCMainTabBarController?) { + let session = NCSession.shared.getSession(controller: controller) + let currentAccount = session.account + if database.getAllTableAccount().isEmpty { + appDelegate.openLogin(selector: NCGlobal.shared.introLogin) + } else if let account = tableAccount?.account, account != currentAccount { + Task { + await NCAccount().changeAccount(account, userProfile: nil, controller: controller) + } + } + } +} + +// MARK: - + +private class AccountSwitcherButton: UIButton { + var onMenuOpened: (() -> Void)? + + override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willDisplayMenuFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) { + super.contextMenuInteraction(interaction, willDisplayMenuFor: configuration, animator: animator) + onMenuOpened?() + } +} diff --git a/iOSClient/Utility/NCAskAuthorization.swift b/iOSClient/Utility/NCAskAuthorization.swift index 3834fa9a28..265e255cc2 100644 --- a/iOSClient/Utility/NCAskAuthorization.swift +++ b/iOSClient/Utility/NCAskAuthorization.swift @@ -32,10 +32,8 @@ class NCAskAuthorization: NSObject { case .undetermined: AVAudioApplication.requestRecordPermission { granted in - if granted { - completion(true) - } else { - completion(false) + DispatchQueue.main.async { + completion(granted) } } default: diff --git a/iOSClient/Utility/NCUtility+Image.swift b/iOSClient/Utility/NCUtility+Image.swift index 583789726f..0c60675861 100644 --- a/iOSClient/Utility/NCUtility+Image.swift +++ b/iOSClient/Utility/NCUtility+Image.swift @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2023 Marino Faggiana +// SPDX-FileCopyrightText: 2024 STRATO GmbH // SPDX-License-Identifier: GPL-3.0-or-later import Foundation @@ -28,7 +29,7 @@ extension NCUtility { case NKTypeIconFile.txt.rawValue: image = UIImage(systemName: "doc.text", withConfiguration: UIImage.SymbolConfiguration(weight: .thin))?.applyingSymbolConfiguration(UIImage.SymbolConfiguration(paletteColors: [NCBrandColor.shared.iconImageColor2])) case NKTypeIconFile.url.rawValue: image = UIImage(systemName: "network", withConfiguration: UIImage.SymbolConfiguration(weight: .thin))?.applyingSymbolConfiguration(UIImage.SymbolConfiguration(paletteColors: [NCBrandColor.shared.iconImageColor2])) case NKTypeIconFile.xls.rawValue: image = UIImage(systemName: "tablecells", withConfiguration: UIImage.SymbolConfiguration(weight: .thin))?.applyingSymbolConfiguration(UIImage.SymbolConfiguration(paletteColors: [NCBrandColor.shared.spreadsheetIconColor])) - default: image = UIImage(systemName: "doc", withConfiguration: UIImage.SymbolConfiguration(weight: .thin))?.applyingSymbolConfiguration(UIImage.SymbolConfiguration(paletteColors: [NCBrandColor.shared.iconImageColor2])) + default: image = UIImage(resource: .fileUnsupported) } } @@ -63,25 +64,12 @@ extension NCUtility { } } + var userImage: UIImage { + UIImage(resource: .userAvatar) + } + func loadUserImage(for user: String, displayName: String?, urlBase: String) -> UIImage { - let fileName = NCSession.shared.getFileName(urlBase: urlBase, user: user) - let localFilePath = utilityFileSystem.createServerUrl(serverUrl: utilityFileSystem.directoryUserData, fileName: fileName) - - if var localImage = UIImage(contentsOfFile: localFilePath) { - let rect = CGRect(x: 0, y: 0, width: 30, height: 30) - UIGraphicsBeginImageContextWithOptions(rect.size, false, 3.0) - UIBezierPath(roundedRect: rect, cornerRadius: rect.size.height).addClip() - localImage.draw(in: rect) - localImage = UIGraphicsGetImageFromCurrentImageContext() ?? localImage - UIGraphicsEndImageContext() - return localImage - } else if let image = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName).image { - return image - } else if let displayName, !displayName.isEmpty, let avatarImg = createAvatar(displayName: displayName, size: 30) { - return avatarImg - } else { - return loadImage(named: "person.crop.circle", colors: [NCBrandColor.shared.iconImageColor]) - } + userImage } func imageFromVideo(url: URL, at time: TimeInterval) -> UIImage? { diff --git a/iOSClient/Utility/UIDevice+VirtualOrientation.swift b/iOSClient/Utility/UIDevice+VirtualOrientation.swift new file mode 100644 index 0000000000..58ae30c74f --- /dev/null +++ b/iOSClient/Utility/UIDevice+VirtualOrientation.swift @@ -0,0 +1,19 @@ +// +// UIDevice+VirtualOrientation.swift +// Nextcloud +// +// Created by Vitaliy Tolkach on 23.04.2025. +// Copyright © 2025 STRATO GmbH. All rights reserved. +// + +import UIKit + +extension UIDevice { + var isVirtualOrientationLandscape: Bool { + guard !UIDevice.current.orientation.isLandscape else { return true } + if let orientation = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.windows.first?.windowScene?.interfaceOrientation { + return orientation.isLandscape + } + return false + } +} diff --git a/iOSClient/Viewer/NCViewer.swift b/iOSClient/Viewer/NCViewer.swift index 5729b80ae5..60a898148a 100644 --- a/iOSClient/Viewer/NCViewer.swift +++ b/iOSClient/Viewer/NCViewer.swift @@ -1,5 +1,7 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2020 Marino Faggiana +// SPDX-FileCopyrightText: 2025 STRATO GmbH +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda // SPDX-License-Identifier: GPL-3.0-or-later import UIKit @@ -13,7 +15,7 @@ class NCViewer: NSObject { private var viewerQuickLook: NCViewerQuickLook? @MainActor - func getViewerController(metadata: tableMetadata, ocIds: [String]? = nil, image: UIImage? = nil, delegate: UIViewController? = nil) async -> UIViewController? { + func getViewerController(metadata: tableMetadata, ocIds: [String]? = nil, siblingMedia: [tableMetadata] = [], image: UIImage? = nil, delegate: UIViewController? = nil) async -> UIViewController? { let session = NCSession.shared.getSession(account: metadata.account) // Set Last Opening Date await self.database.setLocalFileLastOpeningDateAsync(metadata: metadata) @@ -40,19 +42,27 @@ class NCViewer: NSObject { } // IMAGE AUDIO VIDEO - else if metadata.isImage || metadata.isAudioOrVideo { - let viewerMediaPageContainer = UIStoryboard(name: "NCViewerMediaPage", bundle: nil).instantiateInitialViewController() as? NCViewerMediaPage + else if metadata.isImage || metadata.isAudioOrVideo, + let viewerMediaPageContainer = UIStoryboard(name: "NCViewerMediaPage", bundle: nil).instantiateInitialViewController() as? NCViewerMediaPage { + if metadata.isAudioOrVideo { + let mediaCoordinator = NCMediaCoordinator.shared + mediaCoordinator.finishMediaSession() + if metadata.isAudio { + mediaCoordinator.items = siblingMedia + } else { + mediaCoordinator.items = [metadata] + } + } - viewerMediaPageContainer?.delegateViewController = delegate - if let ocIds { - viewerMediaPageContainer?.currentIndex = ocIds.firstIndex(where: { $0 == metadata.ocId }) ?? 0 - viewerMediaPageContainer?.ocIds = ocIds - } else { - viewerMediaPageContainer?.currentIndex = 0 - viewerMediaPageContainer?.ocIds = [metadata.ocId] - } + if let ocIds { + viewerMediaPageContainer.currentIndex = ocIds.firstIndex(where: { $0 == metadata.ocId }) ?? 0 + viewerMediaPageContainer.ocIds = ocIds + } else { + viewerMediaPageContainer.currentIndex = 0 + viewerMediaPageContainer.ocIds = [metadata.ocId] + } - return viewerMediaPageContainer + return viewerMediaPageContainer } // DOCUMENTS @@ -84,7 +94,9 @@ class NCViewer: NSObject { NCActivityIndicator.shared.stop() guard results.error == .success, let url = results.url else { - await showErrorBanner(controller: delegate?.tabBarController as? NCMainTabBarController, text: results.error.errorDescription, errorCode: results.error.errorCode) + await showErrorBanner(controller: delegate?.mainTabBarController, + text: results.error.errorDescription, + errorCode: results.error.errorCode) return nil } @@ -138,7 +150,9 @@ class NCViewer: NSObject { NCActivityIndicator.shared.stop() guard results.error == .success, let url = results.url else { - await showErrorBanner(controller: delegate?.tabBarController as? NCMainTabBarController, text: results.error.errorDescription, errorCode: results.error.errorCode) + await showErrorBanner(controller: delegate?.mainTabBarController, + text: results.error.errorDescription, + errorCode: results.error.errorCode) return nil } @@ -187,7 +201,7 @@ class NCViewer: NSObject { delegate?.present(viewerQuickLook, animated: true) } else { // Document Interaction Controller - if let controller = delegate?.tabBarController as? NCMainTabBarController { + if let controller = delegate?.mainTabBarController { Task { await NCCreate().createActivityViewController(selectedMetadata: [metadata], controller: controller, sender: nil) } diff --git a/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinator.swift b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinator.swift new file mode 100644 index 0000000000..4056364cde --- /dev/null +++ b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinator.swift @@ -0,0 +1,712 @@ +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda +// SPDX-License-Identifier: GPL-3.0-or-later + +import Foundation +import Combine +import MediaPlayer +import NextcloudKit +import Alamofire + +enum NCPlayerState: Equatable { + static func == (lhs: NCPlayerState, rhs: NCPlayerState) -> Bool { + switch (lhs, rhs) { + case (.stopped, .stopped): return true + case (.opening, .opening): return true + case (.buffering, .buffering): return true + case (.ended, .ended): return true + case (.error(let lhsError), .error(let rhsError)): return rhsError == lhsError + case (.playing, .playing): return true + case (.paused, .paused): return true + case (.gettingURL, .gettingURL): return true + case (.downloading(let lhsProgress), .downloading(let rhsProgress)): return lhsProgress == rhsProgress + case (.downloaded, .downloaded): return true + default: return false + } + } + + case stopped + case opening + case buffering + case ended + case error(error: NKError?) + case playing + case paused + case gettingURL + case downloading(progress: Double) + case downloaded + case streamAdded +} + +class NCMediaCoordinator: NSObject { + + enum MediaTrackType { + case audio + case subtitle + } + + static let secondsIn5Minutes: Int = 300 + static let secondsToSeek: Int = 10 + + private let database = NCManageDatabase.shared + private let utility = NCUtility() + private let global = NCGlobal.shared + private let utilityFileSystem = NCUtilityFileSystem() + private let networking = NCNetworking.shared + + static let shared = NCMediaCoordinator() + + // MARK: - Strategy + private var strategy: NCMediaCoordinatorStrategy? + + // MARK: - Delegate + weak var delegate: NCMediaCoordinatorVLCStrategyDelegate? { + didSet { + (strategy as? NCMediaCoordinatorVLCStrategy)?.delegate = delegate + } + } + + // MARK: - Picture in Picture Properties + private(set) var isPictureInPictureActive: Bool = false { + didSet(oldValue) { + guard oldValue != isPictureInPictureActive else { return } + isPictureInPictureActiveSubject.send(isPictureInPictureActive) + } + } + private(set) var isPictureInPictureSupported: Bool = false { + didSet(oldValue) { + guard oldValue != isPictureInPictureSupported else { return } + isPictureInPictureSupportedSubject + .send(isPictureInPictureSupported) + } + } + + // MARK: - Command Center Properties + private var playCommand: Any? + private var pauseCommand: Any? + private var previousTrackCommand: Any? + private var nextTrackCommand: Any? + private var skipBackwardCommand: Any? + private var skipForwardCommand: Any? + + private var url: URL? { + didSet { + if let url = url { + strategy?.url = url + } else { + strategy?.url = nil + } + } + } + + // MARK: - Publishers + private let metadataSwitchSubject = PassthroughSubject<(old: tableMetadata?, new: tableMetadata?), Never>() + private let positionSubject = PassthroughSubject() + private let isPlayingSubject = PassthroughSubject() + private let stateSubject = PassthroughSubject() + private let isPictureInPictureSupportedSubject = PassthroughSubject() + private let isPictureInPictureActiveSubject = PassthroughSubject() + + // MARK: - Public Publishers + var metadataSwitchPublisher: AnyPublisher<(old: tableMetadata?, new: tableMetadata?), Never> { + metadataSwitchSubject.eraseToAnyPublisher() + } + + var positionPublisher: AnyPublisher { + positionSubject.eraseToAnyPublisher() + } + + var statePublisher: AnyPublisher { + stateSubject.eraseToAnyPublisher() + } + + var isPictureInPictureSupportedPublisher: AnyPublisher { + isPictureInPictureSupportedSubject + .receive(on: DispatchQueue.main) + .eraseToAnyPublisher() + } + + var isPictureInPictureActivePublisher: AnyPublisher { + isPictureInPictureActiveSubject.eraseToAnyPublisher() + } + + var isPlayingPublisher: AnyPublisher { + isPlayingSubject.eraseToAnyPublisher() + } + + var currentItemIndex: Int? { + guard let item else { + return nil + } + return items.firstIndex(where: { $0.ocId == item.ocId }) + } + var items: [tableMetadata] = [] + var item: tableMetadata? { + didSet { + if oldValue?.ocId != item?.ocId { + metadataSwitchSubject.send((oldValue, item)) + updateCoverImage() + } + } + } + private var coverImage: UIImage? { + didSet { + updateNowPlayingImage(coverImage) + } + } + + var playRepeat: Bool = false + + var fileName: String { + item?.fileName ?? "" + } + + private weak var viewToPutVideoOutputView: UIView? + func putVideoOutputView(in view: UIView) { + viewToPutVideoOutputView = view + strategy?.putVideoOutputView(in: view) + } + + var position: Float { + get { + return strategy?.position ?? 0 + } + set { + strategy?.position = newValue + positionSubject.send(newValue) + } + } + + var length: Float { + return strategy?.length ?? 0 + } + + var isPlaying: Bool { + return strategy?.isPlaying ?? false + } + + private(set) var state: NCPlayerState = .stopped { + didSet { + stateSubject.send(state) + } + } + + var currentAudioTrackIndex: Int32 { + get { return strategy?.currentAudioTrackIndex ?? 0 } + set { strategy?.currentAudioTrackIndex = newValue } + } + + var currentVideoSubTitleIndex: Int32 { + get { return strategy?.currentVideoSubTitleIndex ?? 0 } + set { strategy?.currentVideoSubTitleIndex = newValue } + } + + var playedTime: String { + return strategy?.playedTime ?? "" + } + + var remainingTime: String { + return strategy?.remainingTime ?? "" + } + + var videoSubTitlesNames: [String] { + return strategy?.videoSubTitlesNames ?? [] + } + + var videoSubTitlesIndexes: [Int32] { + return strategy?.videoSubTitlesIndexes ?? [] + } + + var audioTrackNames: [String] { + return strategy?.audioTrackNames ?? [] + } + + var audioTrackIndexes: [Int32] { + return strategy?.audioTrackIndexes ?? [] + } + + var videoSize: CGSize { + return strategy?.videoSize ?? .zero + } + + private override init() { + super.init() + } + + func stop() { + savePosition() + strategy?.stop() + } + + func play(restart: Bool = false) { + if !restart, isPlayerInErrorState(), let item { + play(item: item) + return + } + strategy?.play(restart: restart) + } + + func play(item: tableMetadata) { + if (self.item?.ocId == item.ocId) && !isPlayerInErrorState() { + play() + } else { + self.item = item + setNowPlayingInfo() + prepareAndStartPlayback(for: item) + } + } + + internal func isPlayerInErrorState() -> Bool { + switch state { + case .error: return true + default: return false + } + } + + func pause() { + savePosition() + strategy?.pause() + } + + func jumpForward(_ seconds: Int32) { + strategy?.play() + strategy?.jumpForward(seconds) + } + + func jumpBackward(_ seconds: Int32) { + strategy?.play() + strategy?.jumpBackward(seconds) + } + + private func savePosition() { + guard let metadata = self.item, let strategy = self.strategy else { return } + guard currentMediaIsInPlayer() else { return } + guard strategy.currentMediaLengthInSeconds() > Self.secondsIn5Minutes else { return } + self.database.addVideoOrAudio(metadata: metadata, position: position) + } + + private func resetSavedPosition() { + guard let metadata = self.item, currentMediaIsInPlayer() else { return } + self.database.addVideoOrAudio(metadata: metadata, position: 0) + } + + func addPlaybackTrack(_ trackURL: URL, type mediaTrackType: MediaTrackType, enforce enforceSelection: Bool) { + guard strategy != nil else { return } + + if let vlcStrategy = strategy as? NCMediaCoordinatorVLCStrategy { + vlcStrategy.addPlaybackTrack(trackURL, + type: mediaTrackType, + enforce: enforceSelection) + return + } + + guard let currentURL = url else { + return + } + + stop() + + let vlcStrategy = NCMediaCoordinatorVLCStrategy(context: self) + vlcStrategy.delegate = delegate + + strategy = vlcStrategy + + vlcStrategy.url = currentURL + if let viewToPutVideoOutputView { + vlcStrategy.putVideoOutputView(in: viewToPutVideoOutputView) + } + + isPictureInPictureSupported = vlcStrategy.isPictureInPictureSupported + + vlcStrategy.play(restart: false) + + vlcStrategy.addPlaybackTrack(trackURL, + type: mediaTrackType, + enforce: enforceSelection) + } + + private var downloadRequest: DownloadRequest? + private func prepareAndStartPlayback(for metadata: tableMetadata) { + self.state = .gettingURL + networking.getVideoUrl(metadata: metadata) { url, error in + if error == .success, let url = url { + self.onReceived(playbackURL: url, metadata: metadata) + } else { + Task { @MainActor in + guard let metadata = await self.database.setMetadataSessionInWaitDownloadAsync(ocId: metadata.ocId, + session: self.networking.sessionDownload, + selector: "") else { + return + } + let results = await self.networking.downloadFile(metadata: metadata) { request in + self.downloadRequest = request + } progressHandler: { progress in + self.state = .downloading(progress: progress.fractionCompleted) + } + if results.nkError == .success { + self.state = .downloaded + if self.utilityFileSystem.fileProviderStorageExists(metadata) { + let url = URL(fileURLWithPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, fileName: metadata.fileNameView, userId: metadata.userId, urlBase: metadata.urlBase)) + self.onReceived(playbackURL: url, metadata: metadata) + } + } else { + self.state = .error(error: results.nkError) + } + } + } + } + } + + func cancelDownload() { + downloadRequest?.cancel() + downloadRequest = nil + } + + private func onReceived(playbackURL url: URL, metadata: tableMetadata) { + guard self.item?.ocId == metadata.ocId else { return } + + if metadata.isVideo { + Task { @MainActor in + self.strategy = await createStrategy(for: url) + self.url = url + self.play() + } + } else { + self.strategy = NCMediaCoordinatorVLCStrategy(context: self) + self.url = url + self.play() + } + } + + func forward() { + guard let metadata = self.item, + let index = items.firstIndex(where: { $0.ocId == metadata.ocId }), + index < items.count - 1 else { + return + } + let nextItemIndex = items.index(after: index) + let nextMetadata = items[nextItemIndex] + pause() + play(item: nextMetadata) + } + + private var needToRestartOnRewindAfterPlayedSeconds: Int = 5 + func rewind() { + guard let item, let strategy else { return } + if strategy.playedTimeInSeconds > needToRestartOnRewindAfterPlayedSeconds { + self.database.addVideoOrAudio(metadata: item, position: 0) + position = 0 + return + } + + guard let metadata = self.item, + let index = items.firstIndex(where: { $0.ocId == metadata.ocId }), + index > 0 else { + return + } + let prevItemIndex = items.index(before: index) + let prevMetadata = items[prevItemIndex] + pause() + play(item: prevMetadata) + } + + func finishMediaSession(clearQueue: Bool = true) { + savePosition() + strategy?.finishMediaSession() + isPlayingSubject.send(false) + strategy = nil + item = nil + playRepeat = false + if clearQueue { + items.removeAll() + } + clearNowPlaying() + isPictureInPictureSupported = false + isPictureInPictureActive = false + } + + // MARK: - Command Center + + private func setNowPlayingInfo() { + var nowPlayingInfo = [String: Any]() + + UIApplication.shared.beginReceivingRemoteControlEvents() + + // Add handler for Play Command + MPRemoteCommandCenter.shared().playCommand.isEnabled = true + if playCommand == nil { + playCommand = MPRemoteCommandCenter.shared().playCommand.addTarget { _ in + if !self.isPlaying { + self.play() + return .success + } + return .commandFailed + } + } + + // Add handler for Pause Command + MPRemoteCommandCenter.shared().pauseCommand.isEnabled = true + if pauseCommand == nil { + pauseCommand = MPRemoteCommandCenter.shared().pauseCommand.addTarget { _ in + if self.isPlaying { + self.pause() + return .success + } + return .commandFailed + } + } + + if item?.isVideo == true { + // Seek Backward + MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = true + if skipBackwardCommand == nil { + skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand.addTarget { _ in + self.jumpBackward(Int32(Self.secondsToSeek)) + return .success + } + } + // Seek Forward + MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = true + if skipForwardCommand == nil { + skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { _ in + self.jumpForward(Int32(Self.secondsToSeek)) + return .success + } + } + } else { + // Previous Track + MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = true + if previousTrackCommand == nil { + previousTrackCommand = MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { _ in + self.rewind() + return .success + } + } + + // Next Track + MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = true + if nextTrackCommand == nil { + nextTrackCommand = MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { _ in + self.forward() + return .success + } + } + } + + nowPlayingInfo[MPMediaItemPropertyTitle] = item?.fileName + if let coverImage { + nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: coverImage.size) { _ in + return coverImage + } + } + + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo + } + + private func updateNowPlayingTime() { + var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:] + + let length = self.length / 1000 + let positionInSecond = position * length + + nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = length + nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = positionInSecond + + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo + } + + private func updateNowPlayingPlaybackRate(isPlaying: Bool) { + var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:] + nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1 : 0 + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo + } + + private func updateNowPlayingImage(_ image: UIImage?) { + var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:] + if let image = image { + nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in + return image + } + } else { + nowPlayingInfo.removeValue(forKey: MPMediaItemPropertyArtwork) + } + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo + } + + private func clearNowPlaying() { + UIApplication.shared.endReceivingRemoteControlEvents() + MPNowPlayingInfoCenter.default().nowPlayingInfo = [:] + + MPRemoteCommandCenter.shared().playCommand.isEnabled = false + MPRemoteCommandCenter.shared().pauseCommand.isEnabled = false + MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = false + MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = false + MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = false + MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = false + + if let playCommand = playCommand { + MPRemoteCommandCenter.shared().playCommand.removeTarget(playCommand) + self.playCommand = nil + } + if let pauseCommand = pauseCommand { + MPRemoteCommandCenter.shared().pauseCommand.removeTarget(pauseCommand) + self.pauseCommand = nil + } + if let previousTrackCommand = previousTrackCommand { + MPRemoteCommandCenter.shared().previousTrackCommand.removeTarget(previousTrackCommand) + self.previousTrackCommand = nil + } + if let nextTrackCommand = nextTrackCommand { + MPRemoteCommandCenter.shared().nextTrackCommand.removeTarget(nextTrackCommand) + self.nextTrackCommand = nil + } + if let skipBackwardCommand = skipBackwardCommand { + MPRemoteCommandCenter.shared().skipBackwardCommand.removeTarget(skipBackwardCommand) + self.skipBackwardCommand = nil + } + if let skipForwardCommand = skipForwardCommand { + MPRemoteCommandCenter.shared().skipForwardCommand.removeTarget(skipForwardCommand) + self.skipForwardCommand = nil + } + } + + private func updateCoverImage() { + guard let item else { return } + + self.coverImage = nil + + if item.isVideo && !item.hasPreview { + utility.createImageFileFrom(metadata: item) + self.coverImage = utility.getImage(ocId: item.ocId, + etag: item.etag, + ext: global.previewExt1024, + userId: item.userId, + urlBase: item.urlBase) + } else if let image = UIImage(contentsOfFile: utilityFileSystem.getDirectoryProviderStorageImageOcId(item.ocId, + etag: item.etag, + ext: global.previewExt1024, + userId: item.userId, + urlBase: item.urlBase)) { + self.coverImage = image + } else if item.isAudio { + self.coverImage = utility.loadImage(named: "waveform", colors: [NCBrandColor.shared.iconImageColor2]) + } + } + + private func onItemPlaybackEnded() { + guard let ocId = item?.ocId, + let endedItemIndex = items.firstIndex(where: { $0.ocId == ocId }) else { return } + + if endedItemIndex < items.count - 1 { + url = nil + let nextItemIndex = items.index(after: endedItemIndex) + let metadata = items[nextItemIndex] + play(item: metadata) + } else { + resetSavedPosition() + strategy?.onItemPlaybackEnded() + } + } + + private func currentMediaIsInPlayer() -> Bool { + guard let strategy else { return false } + return strategy.currentMediaIsInPlayer() + } + + // MARK: - Picture in Picture + + func switchPictureInPicture() { + guard isPictureInPictureSupported else { return } + + if isPictureInPictureActive { + strategy?.stopPictureInPicture() + } else { + strategy?.startPictureInPicture() + } + } + + @MainActor + private func createStrategy(for url: URL) async -> NCMediaCoordinatorStrategy { + let avKitStrategy = NCMediaCoordinatorAVKitStrategy(context: self, url: url) + let isPlayableByAVKit = await avKitStrategy.isSupported() + + let strategy: NCMediaCoordinatorStrategy + if isPlayableByAVKit { + strategy = avKitStrategy + } else { + let vlcStrategy = NCMediaCoordinatorVLCStrategy(context: self) + vlcStrategy.delegate = delegate + strategy = vlcStrategy + } + + if let viewToPutVideoOutputView { + strategy.putVideoOutputView(in: viewToPutVideoOutputView) + } + isPictureInPictureSupported = strategy.isPictureInPictureSupported + return strategy + } +} + +extension NCMediaCoordinator: NCMediaCoordinatorVLCStrategyContext, NCMediaCoordinatorAVKitStrategyContext { + var currentItem: tableMetadata? { item } + + func savedPosition(for metadata: tableMetadata) -> Float? { + database.getVideoOrAudio(metadata: metadata)?.position + } + + func handleMediaPlayerStateChanged(isPlaying: Bool, state: NCPlayerState) { + updateNowPlayingPlaybackRate(isPlaying: isPlaying) + isPlayingSubject.send(isPlaying) + self.state = state + switch state { + case .ended: + if playRepeat { + self.play(restart: true) + } else { + onItemPlaybackEnded() + } + default: break + } + } + + func handleMediaPlayerTimeChanged() { + updateNowPlayingTime() + positionSubject.send(position) + } + + func handlePictureInPictureStateChanged(isActive: Bool, dueToPlaybackEnded: Bool) { + guard isPictureInPictureActive != isActive else { return } + if !isActive && !dueToPlaybackEnded { + pause() + } + isPictureInPictureActive = isActive + } + + func restoreUserInterfaceForPictureInPictureStop() { + guard let metadata = item, metadata.isVideo else { return } + + Task { @MainActor in + // Resolve the tab bar controller for the scene where this media was opened + let controller: NCMainTabBarController? + if let sceneIdentifier = metadata.sceneIdentifier { + controller = SceneManager.shared.getController(sceneIdentifier: sceneIdentifier) + } else { + controller = SceneManager.shared.getControllers().first + } + + guard let tabBarController = controller, + let navigationController = tabBarController.currentViewController() as? UINavigationController else { return } + + if let existingViewer = navigationController.viewControllers.last as? NCViewerMediaPage, + existingViewer.currentViewController.metadata.ocId == metadata.ocId { + return + } + + guard let viewerMediaPageContainer = await NCViewer().getViewerController(metadata: metadata) else { + return + } + + navigationController.pushViewController(viewerMediaPageContainer, animated: true) + } + } +} diff --git a/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorAVKitStrategy.swift b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorAVKitStrategy.swift new file mode 100644 index 0000000000..ca91b3ed9b --- /dev/null +++ b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorAVKitStrategy.swift @@ -0,0 +1,542 @@ +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2026 Serhii Kaliberda +// SPDX-License-Identifier: GPL-3.0-or-later + +import AVKit +import AVFoundation +import UIKit + +protocol NCMediaCoordinatorAVKitStrategyContext: AnyObject { + var currentItem: tableMetadata? { get } + + func play(item: tableMetadata) + func savedPosition(for metadata: tableMetadata) -> Float? + + func handleMediaPlayerStateChanged(isPlaying: Bool, state: NCPlayerState) + func handleMediaPlayerTimeChanged() + + func handlePictureInPictureStateChanged(isActive: Bool, dueToPlaybackEnded: Bool) + func restoreUserInterfaceForPictureInPictureStop() +} + +private class NCMediaCoordinatorAVKitVideoView: UIView { + override class var layerClass: AnyClass { + AVPlayerLayer.self + } + + var playerLayer: AVPlayerLayer { + // swiftlint:disable force_cast + return layer as! AVPlayerLayer + // swiftlint:enable force_cast + } +} + +class NCMediaCoordinatorAVKitStrategy: NSObject, NCMediaCoordinatorStrategy { + + private static let preferredTimescale: CMTimeScale = 600 + + private let context: NCMediaCoordinatorAVKitStrategyContext + + private let videoOutputView = NCMediaCoordinatorAVKitVideoView() + private var player: AVPlayer? + private var playerItem: AVPlayerItem? + + private var positionToSeekToOnFirstPlay: Double = Double.nan + + private var timeObserverToken: Any? + private var playbackEndedObserver: Any? + private var playingTimeControlStatusObserver: NSKeyValueObservation? + + private let pictureInPictureController: AVPictureInPictureController? + + private var isAudioSessionActive: Bool = false + private let session = AVAudioSession.sharedInstance() + + private(set) var state: NCPlayerState = .stopped + + var isPictureInPictureSupported: Bool { + return AVPictureInPictureController.isPictureInPictureSupported() + } + + init(context: NCMediaCoordinatorAVKitStrategyContext, url: URL) { + self.context = context + self.url = url + self.playerItem = AVPlayerItem(url: url) + self.pictureInPictureController = AVPictureInPictureController(playerLayer: videoOutputView.playerLayer) + self.pictureInPictureController?.canStartPictureInPictureAutomaticallyFromInline = true + super.init() + self.pictureInPictureController?.delegate = self + } + + deinit { + removeObservers() + } + + func isSupported() async -> Bool { + let isPlayable = try? await playerItem?.asset.load(.isPlayable) + return isPlayable == true + } + + // MARK: - NCMediaCoordinatorStrategy + + var url: URL? { + didSet(oldValue) { + guard oldValue != url else { return } + if let url { + playerItem = AVPlayerItem(url: url) + } else { + playerItem = nil + } + } + } + + var position: Float { + get { + guard isVideoDurationAvailable(), let currentItem = player?.currentItem else { + return 0 + } + + let currentTime = player?.currentTime() ?? .zero + let ratio = currentTime.seconds / currentItem.duration.seconds + return Float(ratio) + } + set { + guard isVideoDurationAvailable(), let currentItem = player?.currentItem else { + return + } + + let seconds = currentItem.duration.seconds * Double(newValue) + let time = CMTime(seconds: max(0, seconds), preferredTimescale: Self.preferredTimescale) + player?.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) + } + } + + var length: Float { + guard let duration = player?.currentItem?.duration, duration.isNumeric else { return 0 } + return Float(duration.seconds * 1000) + } + + var isPlaying: Bool { + return player?.timeControlStatus == .playing + } + + var currentAudioTrackIndex: Int32 { + get { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .audible), + let selected = item.currentMediaSelection.selectedMediaOption(in: group), + let index = group.options.firstIndex(of: selected) else { + return 0 + } + return Int32(index) + } + set { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .audible) else { + return + } + + let options = group.options + let idx = Int(newValue) + guard options.indices.contains(idx) else { return } + + let option = options[idx] + item.select(option, in: group) + } + } + + var currentVideoSubTitleIndex: Int32 { + get { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .legible), + let selected = item.currentMediaSelection.selectedMediaOption(in: group), + let index = group.options.firstIndex(of: selected) else { + return 0 + } + return Int32(index) + } + set { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else { + return + } + + let options = group.options + let idx = Int(newValue) + guard options.indices.contains(idx) else { return } + + let option = options[idx] + item.select(option, in: group) + } + } + + var videoSubTitlesNames: [String] { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else { + return [] + } + + return group.options.map { $0.displayName } + } + + var videoSubTitlesIndexes: [Int32] { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else { + return [] + } + + return group.options.indices.map { Int32($0) } + } + + var audioTrackNames: [String] { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .audible) + else { return [] } + + return group.options.map { $0.displayName } + } + + var audioTrackIndexes: [Int32] { + guard let item = player?.currentItem, + let group = item.asset.mediaSelectionGroup(forMediaCharacteristic: .audible) else { + return [] + } + + return group.options.indices.map { Int32($0) } + } + + var videoSize: CGSize { + return player?.currentItem?.presentationSize ?? .zero + } + + var playedTimeInSeconds: Int { + let seconds = player?.currentTime().seconds ?? 0 + guard seconds.isFinite && seconds >= 0 else { return 0 } + return Int(seconds) + } + + var playedTime: String { + return formattedTime(for: player?.currentTime()) + } + + var remainingTime: String { + guard let item = player?.currentItem, + item.duration.isNumeric else { + return NCMediaCoordinatorConstants.emptyTime + } + + let currentSeconds = player?.currentTime().seconds ?? 0 + let totalSeconds = item.duration.seconds + + guard totalSeconds.isFinite && totalSeconds > 0 else { + return NCMediaCoordinatorConstants.emptyTime + } + + let remaining = max(0, totalSeconds - currentSeconds) + return "-\(formattedTime(for: CMTime(seconds: remaining, preferredTimescale: Self.preferredTimescale)))" + } + + func finishMediaSession() { + player?.pause() + player?.seek(to: .zero) + removeObservers() + pictureInPictureController?.stopPictureInPicture() + player = nil + playerItem = nil + url = nil + updateState(isPlaying: false, state: .stopped) + deactivateAudioSessionIfNeeded() + videoOutputView.removeFromSuperview() + } + + func onItemPlaybackEnded() { + removeObservers() + pictureInPictureController?.stopPictureInPicture() + context.handlePictureInPictureStateChanged(isActive: false, dueToPlaybackEnded: true) + player = nil + deactivateAudioSessionIfNeeded() + } + + func putVideoOutputView(in view: UIView) { + guard videoOutputView.superview !== view else { return } + + videoOutputView.removeFromSuperview() + videoOutputView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(videoOutputView) + + NSLayoutConstraint.activate([ + videoOutputView.topAnchor.constraint(equalTo: view.topAnchor), + videoOutputView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + videoOutputView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + videoOutputView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + + if let player { + videoOutputView.playerLayer.player = player + videoOutputView.playerLayer.videoGravity = .resizeAspect + } + } + + func startPictureInPicture() { + guard isPictureInPictureSupported else { return } + + if pictureInPictureController?.isPictureInPictureActive ?? false { + return + } + + pictureInPictureController?.startPictureInPicture() + } + + func stopPictureInPicture() { + guard pictureInPictureController?.isPictureInPictureActive ?? false else { + return + } + + pictureInPictureController?.stopPictureInPicture() + } + + func play() { + player?.play() + } + + func play(restart: Bool) { + guard !isPlayerInErrorState() else { + if let item = context.currentItem { + context.play(item: item) + } + return + } + + if player == nil, let url { + playerItem = AVPlayerItem(url: url) + setUpPlayer() + } + + if restart { + player?.seek(to: .zero) + } else if let item = context.currentItem, let savedPosition = context.savedPosition(for: item) { + positionToSeekToOnFirstPlay = Double(savedPosition) + } + + activateAudioSessionIfNeeded() + player?.audiovisualBackgroundPlaybackPolicy = .continuesIfPossible + player?.play() + } + + func pause() { + player?.pause() + } + + func stop() { + player?.pause() + player?.seek(to: .zero) + updateState(isPlaying: false, state: .stopped) + deactivateAudioSessionIfNeeded() + } + + func jumpForward(_ seconds: Int32) { + seek(by: TimeInterval(seconds)) + } + + func jumpBackward(_ seconds: Int32) { + seek(by: -TimeInterval(seconds)) + } + + func currentMediaLengthInSeconds() -> Int { + guard let duration = player?.currentItem?.duration, duration.isNumeric else { return 0 } + return Int(duration.seconds) + } + + func currentMediaIsInPlayer() -> Bool { + guard let currentItem = player?.currentItem, + let asset = currentItem.asset as? AVURLAsset, + let url else { + return false + } + + return asset.url == url + } + + // MARK: - Private helpers + + private func setUpPlayer() { + removeObservers() + + guard let playerItem else { return } + + let player = AVPlayer(playerItem: playerItem) + self.player = player + + videoOutputView.playerLayer.player = player + videoOutputView.playerLayer.videoGravity = .resizeAspect + + addObservers() + } + + private func seek(by delta: TimeInterval) { + guard let player else { return } + + let currentSeconds = player.currentTime().seconds + guard currentSeconds.isFinite else { return } + + let targetSeconds = max(0, currentSeconds + delta) + let time = CMTime(seconds: targetSeconds, preferredTimescale: Self.preferredTimescale) + player.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) + } + + private func isPlayerInErrorState() -> Bool { + switch state { + case .error: return true + default: return false + } + } + + private func addObservers() { + guard let player else { return } + + timeObserverToken = player.addPeriodicTimeObserver( + forInterval: CMTime(seconds: 0.5, preferredTimescale: Self.preferredTimescale), + queue: .main + ) { [weak self] _ in + guard let self else { return } + self.seekToPositionToSeekToOnFirstPlay() + self.context.handleMediaPlayerTimeChanged() + } + + playbackEndedObserver = NotificationCenter.default.addObserver( + forName: .AVPlayerItemDidPlayToEndTime, + object: player.currentItem, + queue: .main + ) { [weak self] _ in + guard let self else { return } + self.updateState(isPlaying: false, state: .ended) + self.context.handleMediaPlayerTimeChanged() + } + + playingTimeControlStatusObserver = player.observe(\.timeControlStatus, options: [.new]) { [weak self] player, _ in + guard let self = self else { return } + switch player.timeControlStatus { + case .playing: + self.updateState(isPlaying: true, state: .playing) + case .paused: + self.updateState(isPlaying: false, state: .paused) + case .waitingToPlayAtSpecifiedRate: + self.updateState(isPlaying: false, state: .buffering) + @unknown default: + break + } + } + } + + private func seekToPositionToSeekToOnFirstPlay() { + guard !positionToSeekToOnFirstPlay.isNaN, + isVideoDurationAvailable(), + let currentItem = player?.currentItem else { + return + } + let seconds = currentItem.duration.seconds * positionToSeekToOnFirstPlay + let time = CMTime(seconds: max(0, seconds), preferredTimescale: Self.preferredTimescale) + player?.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) + positionToSeekToOnFirstPlay = Double.nan + } + + private func isVideoDurationAvailable() -> Bool { + guard let currentItem = player?.currentItem, + currentItem.duration.isNumeric, + currentItem.duration.seconds > 0 else { + return false + } + return true + } + + private func removeObservers() { + if let token = timeObserverToken { + player?.removeTimeObserver(token) + timeObserverToken = nil + } + + if let playbackEndedObserver { + NotificationCenter.default.removeObserver(playbackEndedObserver) + self.playbackEndedObserver = nil + } + + if let playingTimeControlStatusObserver { + playingTimeControlStatusObserver.invalidate() + self.playingTimeControlStatusObserver = nil + } + } + + private func updateState(isPlaying: Bool, state: NCPlayerState) { + self.state = state + context.handleMediaPlayerStateChanged(isPlaying: isPlaying, state: state) + } + + private func activateAudioSessionIfNeeded() { + guard !isAudioSessionActive else { return } + + do { + try session.setCategory(.playback, mode: .moviePlayback) + try session.setActive(true) + isAudioSessionActive = true + } catch { + isAudioSessionActive = false + #if DEBUG + print("Failed to activate AVAudioSession: \(error)") + #endif + } + } + + private func deactivateAudioSessionIfNeeded() { + guard isAudioSessionActive else { return } + + do { + pause() + try session.setActive(false) + isAudioSessionActive = false + } catch { + #if DEBUG + print("Failed to deactivate AVAudioSession: \(error)") + #endif + } + } + + private func formattedTime(for time: CMTime?) -> String { + guard let time, + time.isNumeric else { + return NCMediaCoordinatorConstants.emptyTime + } + + let totalSeconds = Int(time.seconds) + let seconds = totalSeconds % 60 + let minutes = (totalSeconds / 60) % 60 + let hours = totalSeconds / 3600 + + if hours > 0 { + return String(format: "%d:%02d:%02d", hours, minutes, seconds) + } else { + return String(format: "%02d:%02d", minutes, seconds) + } + } +} + +extension NCMediaCoordinatorAVKitStrategy: AVPictureInPictureControllerDelegate { + + func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) { + context.handlePictureInPictureStateChanged(isActive: true, dueToPlaybackEnded: false) + } + + func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) { + context.handlePictureInPictureStateChanged(isActive: false, dueToPlaybackEnded: false) + } + + func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) { + context.handlePictureInPictureStateChanged(isActive: false, dueToPlaybackEnded: false) + } + + func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, + restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) { + context.handlePictureInPictureStateChanged(isActive: false, dueToPlaybackEnded: false) + context.restoreUserInterfaceForPictureInPictureStop() + completionHandler(true) + } +} diff --git a/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorConstants.swift b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorConstants.swift new file mode 100644 index 0000000000..4bd71361e8 --- /dev/null +++ b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorConstants.swift @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2026 Serhii Kaliberda +// SPDX-License-Identifier: GPL-3.0-or-later + +enum NCMediaCoordinatorConstants { + static let emptyTime: String = "--:--" +} diff --git a/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorStrategy.swift b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorStrategy.swift new file mode 100644 index 0000000000..3a3f4a9679 --- /dev/null +++ b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorStrategy.swift @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2026 Serhii Kaliberda +// SPDX-License-Identifier: GPL-3.0-or-later + +protocol NCMediaCoordinatorStrategy { + + var url: URL? { get set } + + var position: Float { get set } + var length: Float { get } + var isPlaying: Bool { get } + var currentAudioTrackIndex: Int32 { get set } + var currentVideoSubTitleIndex: Int32 { get set } + var videoSubTitlesNames: [String] { get } + var videoSubTitlesIndexes: [Int32] { get } + var audioTrackNames: [String] { get } + var audioTrackIndexes: [Int32] { get } + var videoSize: CGSize { get } + + var playedTimeInSeconds: Int { get } + var playedTime: String { get } + var remainingTime: String { get } + + var state: NCPlayerState { get } + + var isPictureInPictureSupported: Bool { get } + func startPictureInPicture() + func stopPictureInPicture() + + func finishMediaSession() + + func onItemPlaybackEnded() + + func putVideoOutputView(in view: UIView) + + func play() + func play(restart: Bool) + func pause() + func stop() + func jumpForward(_ seconds: Int32) + func jumpBackward(_ seconds: Int32) + + func currentMediaLengthInSeconds() -> Int + func currentMediaIsInPlayer() -> Bool +} diff --git a/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorVLCStrategy.swift b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorVLCStrategy.swift new file mode 100644 index 0000000000..d0b24e5187 --- /dev/null +++ b/iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorVLCStrategy.swift @@ -0,0 +1,340 @@ +// SPDX-FileCopyrightText: STRATO GmbH +// SPDX-FileCopyrightText: 2026 Serhii Kaliberda +// SPDX-License-Identifier: GPL-3.0-or-later + +import MobileVLCKit +import UIKit + +private class PassThroughVLCVideoView: UIView { + override func addSubview(_ view: UIView) { + super.addSubview(view) + view.isUserInteractionEnabled = false + } +} + +protocol NCMediaCoordinatorVLCStrategyContext: AnyObject { + var currentItem: tableMetadata? { get } + + func play(item: tableMetadata) + func savedPosition(for metadata: tableMetadata) -> Float? + + func handleMediaPlayerStateChanged(isPlaying: Bool, state: NCPlayerState) + func handleMediaPlayerTimeChanged() +} + +protocol NCMediaCoordinatorVLCStrategyDelegate: AnyObject { + func showError(withTitle title: String, message: String) + func showAlert(alert: UIAlertController) + func showLogin(withTitle title: String, message: String, defaultUsername username: String?, askingForStorage: Bool, withReference reference: NSValue) + func showProgress(withTitle title: String, message: String, isIndeterminate: Bool, position: Float, cancel cancelString: String?, withReference reference: NSValue) + func updateProgress(withReference reference: NSValue, message: String?, position: Float) + func cancelDialog(withReference reference: NSValue) +} + +extension NCPlayerState { + init(vlcState: VLCMediaPlayerState) { + switch vlcState { + case .stopped: self = .stopped + case .opening: self = .opening + case .buffering: self = .buffering + case .ended: self = .ended + case .error: self = .error(error: nil) + case .playing: self = .playing + case .paused: self = .paused + case .esAdded: self = .streamAdded + default: self = .stopped + } + } +} + +extension NCMediaCoordinator.MediaTrackType { + var vlcType: VLCMediaPlaybackSlaveType { + switch self { + case .audio: return .audio + case .subtitle: return .subtitle + } + } +} + +class NCMediaCoordinatorVLCStrategy: NSObject, NCMediaCoordinatorStrategy { + + var context: NCMediaCoordinatorVLCStrategyContext + var delegate: NCMediaCoordinatorVLCStrategyDelegate? + + private var dialogProvider: VLCDialogProvider? + + private let videoOutputView = PassThroughVLCVideoView() + + // VLC-specific properties moved from NCMediaCoordinator + private var media: VLCMedia? + private var player: VLCMediaPlayer? + + // Exposed accessors for coordinator + var drawableView: UIView { + videoOutputView + } + + var vlcMedia: VLCMedia? { + get { media } + set { media = newValue } + } + + var vlcPlayer: VLCMediaPlayer? { + get { player } + set { player = newValue } + } + + var url: URL? { + didSet { + if let url = url { + media = VLCMedia(url: url) + media?.addOption(":http-user-agent=\(userAgent)") + } else { + media = nil + } + } + } + + var position: Float { + get { + return player?.position ?? 0 + } + set { + player?.position = newValue + } + } + + var length: Float { + return Float(media?.length.intValue ?? 0) + } + + var isPlaying: Bool { + return player?.isPlaying ?? false + } + + var currentAudioTrackIndex: Int32 { + get { return player?.currentAudioTrackIndex ?? 0 } + set { player?.currentAudioTrackIndex = newValue } + } + + var currentVideoSubTitleIndex: Int32 { + get { return player?.currentVideoSubTitleIndex ?? 0 } + set { player?.currentVideoSubTitleIndex = newValue } + } + + var videoSubTitlesNames: [String] { + return player?.videoSubTitlesNames.compactMap { $0 as? String } ?? [] + } + + var videoSubTitlesIndexes: [Int32] { + return player?.videoSubTitlesIndexes.compactMap { $0 as? Int32 } ?? [] + } + + var audioTrackNames: [String] { + return player?.audioTrackNames.compactMap { $0 as? String } ?? [] + } + + var audioTrackIndexes: [Int32] { + return player?.audioTrackIndexes.compactMap { $0 as? Int32 } ?? [] + } + + var videoSize: CGSize { + return player?.videoSize ?? .zero + } + + var playedTimeInSeconds: Int { + return Int(player?.time.intValue ?? 0) / 1000 + } + + var playedTime: String { + return player?.time.stringValue ?? "" + } + + var remainingTime: String { + return player?.remainingTime?.stringValue ?? "" + } + + var state: NCPlayerState { + return NCPlayerState(vlcState: player?.state ?? .stopped) + } + + var isPictureInPictureSupported: Bool { + return false + } + + func startPictureInPicture() { + // Not supported + } + + func stopPictureInPicture() { + // Not supported + } + + init(context: NCMediaCoordinatorVLCStrategyContext) { + self.context = context + } + + func finishMediaSession() { + player?.stop() + position = 0 + player = nil + url = nil + dialogProvider = nil + videoOutputView.removeFromSuperview() + } + + func onItemPlaybackEnded() { + player = nil + position = 0 + } + + func putVideoOutputView(in view: UIView) { + guard videoOutputView.superview != view else { return } + videoOutputView.removeFromSuperview() + videoOutputView.translatesAutoresizingMaskIntoConstraints = false + videoOutputView.isUserInteractionEnabled = false + view.addSubview(videoOutputView) + NSLayoutConstraint.activate([ + videoOutputView.topAnchor.constraint(equalTo: view.topAnchor), + videoOutputView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + videoOutputView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + videoOutputView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + + func play(restart: Bool) { + guard !isPlayerInErrorState() else { + if let item = context.currentItem { + context.play(item: item) + } + return + } + guard let player, currentMediaIsInPlayer() && !restart else { + stop() + setUpDialogProvider() + player = VLCMediaPlayer() + player?.drawable = drawableView + player?.media = vlcMedia + player?.delegate = self + + var position: Float = 0 + if !restart, let item = context.currentItem, let resultPosition = context.savedPosition(for: item) { + position = resultPosition + } + + player?.play() + player?.position = position + return + } + player.play() + } + + private func isPlayerInErrorState() -> Bool { + switch state { + case .error: return true + default: return false + } + } + + func play() { + player?.play() + } + + func pause() { + player?.pause() + } + + func stop() { + player?.stop() + } + + func jumpForward(_ seconds: Int32) { + player?.jumpForward(seconds) + } + + func jumpBackward(_ seconds: Int32) { + player?.jumpBackward(seconds) + } + + func currentMediaLengthInSeconds() -> Int { + return media?.lengthInSeconds ?? 0 + } + + func currentMediaIsInPlayer() -> Bool { + guard let player else { return false } + return (player.media?.compare(media) == .orderedSame) + } + + func addPlaybackTrack(_ trackURL: URL, + type mediaTrackType: NCMediaCoordinator.MediaTrackType, + enforce enforceSelection: Bool) { + guard let player else { return } + player.addPlaybackSlave(trackURL, type: mediaTrackType.vlcType, enforce: enforceSelection) + } +} + +extension NCMediaCoordinatorVLCStrategy: VLCMediaPlayerDelegate { + func mediaPlayerStateChanged(_ aNotification: Notification) { + context.handleMediaPlayerStateChanged(isPlaying: isPlaying, state: state) + } + + func mediaPlayerTimeChanged(_ aNotification: Notification) { + context.handleMediaPlayerTimeChanged() + } +} + +private extension VLCMedia { + var lengthInSeconds: Int { + return Int(length.intValue) / 1000 + } +} + +extension NCMediaCoordinatorVLCStrategy: VLCCustomDialogRendererProtocol { + private func setUpDialogProvider() { + guard dialogProvider == nil else { return } + dialogProvider = VLCDialogProvider(library: VLCLibrary.shared(), customUI: true) + dialogProvider?.customRenderer = self + } + + func showError(withTitle error: String, message: String) { + delegate?.showError(withTitle: error, message: message) + } + + func showLogin(withTitle title: String, message: String, defaultUsername username: String?, askingForStorage: Bool, withReference reference: NSValue) { + delegate?.showLogin(withTitle: title, message: message, defaultUsername: username, askingForStorage: askingForStorage, withReference: reference) + } + + func showQuestion(withTitle title: String, message: String, type questionType: VLCDialogQuestionType, cancel cancelString: String?, action1String: String?, action2String: String?, withReference reference: NSValue) { + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + + if let action1String = action1String { + alert.addAction(UIAlertAction(title: action1String, style: .default, handler: { _ in + self.dialogProvider?.postAction(1, forDialogReference: reference) + })) + } + if let action2String = action2String { + alert.addAction(UIAlertAction(title: action2String, style: .default, handler: { _ in + self.dialogProvider?.postAction(2, forDialogReference: reference) + })) + } + if let cancelString = cancelString { + alert.addAction(UIAlertAction(title: cancelString, style: .cancel, handler: { _ in + self.dialogProvider?.postAction(3, forDialogReference: reference) + })) + } + + delegate?.showAlert(alert: alert) + } + + func showProgress(withTitle title: String, message: String, isIndeterminate: Bool, position: Float, cancel cancelString: String?, withReference reference: NSValue) { + delegate?.showProgress(withTitle: title, message: message, isIndeterminate: isIndeterminate, position: position, cancel: cancelString, withReference: reference) + } + + func updateProgress(withReference reference: NSValue, message: String?, position: Float) { + delegate?.updateProgress(withReference: reference, message: message, position: position) + } + + func cancelDialog(withReference reference: NSValue) { + delegate?.cancelDialog(withReference: reference) + } +} diff --git a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift index 15e991f3fb..2dfdf58e31 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift +++ b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift @@ -1,338 +1,110 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2021 Marino Faggiana +// SPDX-FileCopyrightText: 2025 STRATO GmbH // SPDX-License-Identifier: GPL-3.0-or-later import Foundation import NextcloudKit import UIKit import MobileVLCKit +import Combine -class NCPlayer: NSObject, VLCMediaDelegate { - internal var url: URL? - internal var player = VLCMediaPlayer() - internal var dialogProvider: VLCDialogProvider? - internal var metadata: tableMetadata - internal var singleTapGestureRecognizer: UITapGestureRecognizer? - internal var activityIndicator: UIActivityIndicatorView +class NCPlayer: NSObject { + private var mediaCoordinator = NCMediaCoordinator.shared + private var metadata: tableMetadata internal let database = NCManageDatabase.shared internal var width: Int? internal var height: Int? internal var length: Int? - internal var pauseAfterPlay: Bool = false - internal weak var playerToolBar: NCPlayerToolBar? + private weak var playerToolBar: NCPlayerToolBar? internal weak var viewerMediaPage: NCViewerMediaPage? - weak var imageVideoContainer: UIImageView? - - internal var counterSeconds: Double = 0 - // MARK: - View Life Cycle - init(imageVideoContainer: UIImageView, playerToolBar: NCPlayerToolBar?, metadata: tableMetadata, viewerMediaPage: NCViewerMediaPage?) { - self.imageVideoContainer = imageVideoContainer + init(playerToolBar: NCPlayerToolBar?, metadata: tableMetadata, viewerMediaPage: NCViewerMediaPage?) { self.playerToolBar = playerToolBar self.metadata = metadata self.viewerMediaPage = viewerMediaPage - self.activityIndicator = UIActivityIndicatorView(style: .large) - self.activityIndicator.color = .white - self.activityIndicator.hidesWhenStopped = true - self.activityIndicator.translatesAutoresizingMaskIntoConstraints = false - - if let viewerMediaPage = viewerMediaPage { - viewerMediaPage.view.addSubview(activityIndicator) - NSLayoutConstraint.activate([ - activityIndicator.centerXAnchor.constraint(equalTo: viewerMediaPage.view.centerXAnchor), - activityIndicator.centerYAnchor.constraint(equalTo: viewerMediaPage.view.centerYAnchor) - ]) - } - super.init() + + configurePlayingUI() } deinit { - player.stop() print("deinit NCPlayer with ocId \(metadata.ocId)") - NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerStoppedPlaying) } - func openAVPlayer(url: URL, autoplay: Bool = false) { - var position: Float = 0 - let userAgent = userAgent - - self.url = url - self.singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSingleTapWith(gestureRecognizer:))) - - print("Playing URL: \(url)") - let media = VLCMedia(url: url) - - media.parse(options: url.isFileURL ? .fetchLocal : .fetchNetwork) - - player.media = media - player.delegate = self - - dialogProvider = VLCDialogProvider(library: VLCLibrary.shared(), customUI: true) - dialogProvider?.customRenderer = self - - player.media?.addOption(":http-user-agent=\(userAgent)") - - if let result = self.database.getVideo(metadata: metadata), - let resultPosition = result.position { - position = resultPosition - } - - if metadata.isVideo { - player.drawable = imageVideoContainer - if let view = player.drawable as? UIView, let singleTapGestureRecognizer = singleTapGestureRecognizer { - view.isUserInteractionEnabled = true - view.addGestureRecognizer(singleTapGestureRecognizer) - } - } - - player.play() - player.position = position - - if autoplay { - pauseAfterPlay = false - } else { - pauseAfterPlay = true - } - - playerToolBar?.setBarPlayer(position: position, ncplayer: self, metadata: metadata, viewerMediaPage: viewerMediaPage) - - NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil) - } - - func restartAVPlayer(position: Float, pauseAfterPlay: Bool) { - if let url = self.url, !player.isPlaying { - - player.media = VLCMedia(url: url) - player.position = position - playerToolBar?.setBarPlayer(position: position) - viewerMediaPage?.changeScreenMode(mode: .normal) - self.pauseAfterPlay = pauseAfterPlay - player.play() - - if metadata.isVideo { - if position == 0 { - imageVideoContainer?.image = NCUtility().getImage(ocId: metadata.ocId, etag: metadata.etag, ext: NCGlobal.shared.previewExt1024, userId: metadata.userId, urlBase: metadata.urlBase) - } else { - imageVideoContainer?.image = nil - } - } - } - } - - // MARK: - UIGestureRecognizerDelegate - - @objc func didSingleTapWith(gestureRecognizer: UITapGestureRecognizer) { - changeScreenMode() - } - - func changeScreenMode() { - guard let viewerMediaPage = viewerMediaPage else { return } - - if viewerMediaScreenMode == .full { - viewerMediaPage.changeScreenMode(mode: .normal) - } else { - viewerMediaPage.changeScreenMode(mode: .full) - } - } - - // MARK: - NotificationCenter - - @objc func applicationDidEnterBackground(_ notification: NSNotification) { - if metadata.isVideo { - playerPause() - } + private func configurePlayingUI() { + playerToolBar?.setBarPlayer(position: 0, ncplayer: self, metadata: metadata, viewerMediaPage: viewerMediaPage) + playerToolBar?.playerButtonView?.isHidden = false } // MARK: - func isPlaying() -> Bool { - return player.isPlaying + return mediaCoordinator.isPlaying } func playerPlay() { - playerToolBar?.playbackSliderEvent = .began - - if let result = self.database.getVideo(metadata: metadata), let position = result.position { - player.position = position - playerToolBar?.playbackSliderEvent = .moved + guard metadata.ocId == mediaCoordinator.item?.ocId else { + mediaCoordinator.play(item: metadata) + return } + playerToolBar?.playbackSliderEvent = .began - player.play() + mediaCoordinator.play() DispatchQueue.main.asyncAfter(deadline: .now() + 1) { self.playerToolBar?.playbackSliderEvent = .ended } } - @objc func playerStop() { - savePosition() - player.stop() - } - @objc func playerPause() { - savePosition() - player.pause() + mediaCoordinator.pause() } func playerPosition(_ position: Float) { - self.database.addVideo(metadata: metadata, position: position) - player.position = position - } - - func savePosition() { - guard metadata.isVideo, isPlaying() else { return } - self.database.addVideo(metadata: metadata, position: player.position) + mediaCoordinator.position = position } func jumpForward(_ seconds: Int32) { - player.play() - player.jumpForward(seconds) + mediaCoordinator.jumpForward(seconds) } func jumpBackward(_ seconds: Int32) { - player.play() - player.jumpBackward(seconds) + mediaCoordinator.jumpBackward(seconds) } -} - -extension NCPlayer: VLCMediaPlayerDelegate { - func mediaPlayerStateChanged(_ aNotification: Notification) { - - if player.state == .buffering && player.isPlaying { - activityIndicator.startAnimating() - } else { - activityIndicator.stopAnimating() - } - - switch player.state { - case .stopped: - playerToolBar?.showPlayButton() - - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerStoppedPlaying) - print("Player mode: STOPPED") - case .opening: - print("Player mode: OPENING") - case .buffering: - print("Player mode: BUFFERING") - case .ended: - self.database.addVideo(metadata: self.metadata, position: 0) - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - if let playRepeat = self.playerToolBar?.playRepeat { - self.restartAVPlayer(position: 0, pauseAfterPlay: !playRepeat) - } - } - playerToolBar?.showPlayButton() - print("Player mode: ENDED") - case .error: - print("Player mode: ERROR") - case .playing: - guard let playerToolBar = playerToolBar else { return } - if playerToolBar.playerButtonView.isHidden { - playerToolBar.playerButtonView.isHidden = false - viewerMediaPage?.changeScreenMode(mode: .normal) - } - if pauseAfterPlay { - player.pause() - pauseAfterPlay = false - self.viewerMediaPage?.updateCommandCenter(ncplayer: self, title: metadata.fileNameView) - } else { - playerToolBar.showPauseButton() - // Set track audio/subtitle - let data = self.database.getVideo(metadata: metadata) - if let currentAudioTrackIndex = data?.currentAudioTrackIndex { - player.currentAudioTrackIndex = Int32(currentAudioTrackIndex) - } - if let currentVideoSubTitleIndex = data?.currentVideoSubTitleIndex { - player.currentVideoSubTitleIndex = Int32(currentVideoSubTitleIndex) - } - } - let size = player.videoSize - if let mediaLength = player.media?.length.intValue { - self.length = Int(mediaLength) - } - self.width = Int(size.width) - self.height = Int(size.height) - playerToolBar.updatePlaybackPosition() - playerToolBar.updateTopToolBar(videoSubTitlesIndexes: player.videoSubTitlesIndexes, audioTrackIndexes: player.audioTrackIndexes) - self.database.addVideo(metadata: metadata, width: self.width, height: self.height, length: self.length) - - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerIsPlaying) - - print("Player mode: PLAYING") - case .paused: - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerStoppedPlaying) - - playerToolBar?.showPlayButton() - print("Player mode: PAUSED") - default: break - } + var videoSubTitlesNames: [Any] { + mediaCoordinator.videoSubTitlesNames } - func mediaPlayerTimeChanged(_ aNotification: Notification) { - activityIndicator.stopAnimating() - playerToolBar?.updatePlaybackPosition() - } -} - -extension NCPlayer: VLCMediaThumbnailerDelegate { - func mediaThumbnailerDidTimeOut(_ mediaThumbnailer: VLCMediaThumbnailer) { } - func mediaThumbnailer(_ mediaThumbnailer: VLCMediaThumbnailer, didFinishThumbnail thumbnail: CGImage) { } -} - -extension NCPlayer: VLCCustomDialogRendererProtocol { - func showError(withTitle error: String, message: String) { - let alert = UIAlertController(title: error, message: message, preferredStyle: .alert) - - alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in - self.playerToolBar?.removeFromSuperview() - self.viewerMediaPage?.navigationController?.popViewController(animated: true) - })) - - self.viewerMediaPage?.present(alert, animated: true) + var videoSubTitlesIndexes: [Any] { + mediaCoordinator.videoSubTitlesIndexes } - func showLogin(withTitle title: String, message: String, defaultUsername username: String?, askingForStorage: Bool, withReference reference: NSValue) { - // UIAlertController other states... + var currentVideoSubTitleIndex: Int32 { + get { mediaCoordinator.currentVideoSubTitleIndex } + set { mediaCoordinator.currentVideoSubTitleIndex = newValue } } - func showQuestion(withTitle title: String, message: String, type questionType: VLCDialogQuestionType, cancel cancelString: String?, action1String: String?, action2String: String?, withReference reference: NSValue) { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - - if let action1String = action1String { - alert.addAction(UIAlertAction(title: action1String, style: .default, handler: { _ in - self.dialogProvider?.postAction(1, forDialogReference: reference) - })) - } - if let action2String = action2String { - alert.addAction(UIAlertAction(title: action2String, style: .default, handler: { _ in - self.dialogProvider?.postAction(2, forDialogReference: reference) - })) - } - if let cancelString = cancelString { - alert.addAction(UIAlertAction(title: cancelString, style: .cancel, handler: { _ in - self.dialogProvider?.postAction(3, forDialogReference: reference) - })) - } - - self.viewerMediaPage?.present(alert, animated: true) + var audioTrackNames: [Any] { + mediaCoordinator.audioTrackNames } - func showProgress(withTitle title: String, message: String, isIndeterminate: Bool, position: Float, cancel cancelString: String?, withReference reference: NSValue) { - // UIAlertController other states... + var audioTrackIndexes: [Any] { + mediaCoordinator.audioTrackIndexes } - func updateProgress(withReference reference: NSValue, message: String?, position: Float) { - // UIAlertController other states... + var currentAudioTrackIndex: Int32 { + get { mediaCoordinator.currentAudioTrackIndex } + set { mediaCoordinator.currentAudioTrackIndex = newValue } } - func cancelDialog(withReference reference: NSValue) { - // UIAlertController other states... + func addPlaybackTrack(_ trackURL: URL, type mediaTrackType: NCMediaCoordinator.MediaTrackType, enforce enforceSelection: Bool) { + mediaCoordinator.addPlaybackTrack(trackURL, type: mediaTrackType, enforce: enforceSelection) } } diff --git a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift index 27445079e0..ba1cc425e9 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift +++ b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift @@ -1,22 +1,22 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2021 Marino Faggiana +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda // SPDX-License-Identifier: GPL-3.0-or-later import Foundation import NextcloudKit -import CoreMedia import UIKit -import AVKit -import MediaPlayer -import MobileVLCKit import Alamofire import LucidBanner +import Combine class NCPlayerToolBar: UIView { @IBOutlet weak var utilityView: UIView! @IBOutlet weak var fullscreenButton: UIButton! @IBOutlet weak var subtitleButton: UIButton! @IBOutlet weak var audioButton: UIButton! + @IBOutlet weak var pictureInPictureButton: UIButton! @IBOutlet weak var playerButtonView: UIStackView! @IBOutlet weak var backButton: UIButton! @@ -27,7 +27,8 @@ class NCPlayerToolBar: UIView { @IBOutlet weak var playbackSlider: NCPlayerToolBarSlider! @IBOutlet weak var labelLeftTime: UILabel! @IBOutlet weak var labelCurrentTime: UILabel! - @IBOutlet weak var repeatButton: UIButton! + + private var mediaCoordinator = NCMediaCoordinator.shared enum sliderEventType { case none @@ -38,11 +39,9 @@ class NCPlayerToolBar: UIView { var playbackSliderEvent: sliderEventType = .none var isFullscreen: Bool = false - var playRepeat: Bool = false private var ncplayer: NCPlayer? private var metadata: tableMetadata? - private let audioSession = AVAudioSession.sharedInstance() private var pointSize: CGFloat = 0 private let utilityFileSystem = NCUtilityFileSystem() private let utility = NCUtility() @@ -51,6 +50,8 @@ class NCPlayerToolBar: UIView { private weak var viewerMediaPage: NCViewerMediaPage? private var buttonImage = UIImage() + private var cancellables = Set() + // MARK: - View Life Cycle override func awakeFromNib() { @@ -58,16 +59,21 @@ class NCPlayerToolBar: UIView { self.backgroundColor = UIColor.black.withAlphaComponent(0.1) - fullscreenButton.setImage(utility.loadImage(named: "arrow.up.left.and.arrow.down.right", colors: [.white]), for: .normal) + fullscreenButton.setImage(NCImagesRepository.mediaIconFullscreen, for: .normal) - subtitleButton.setImage(utility.loadImage(named: "captions.bubble", colors: [.white]), for: .normal) + subtitleButton.setImage(NCImagesRepository.mediaIconMessage, for: .normal) subtitleButton.isEnabled = false subtitleButton.showsMenuAsPrimaryAction = true - audioButton.setImage(utility.loadImage(named: "speaker.zzz", colors: [.white]), for: .normal) + audioButton.setImage(NCImagesRepository.mediaIconSound, for: .normal) audioButton.isEnabled = false audioButton.showsMenuAsPrimaryAction = true + pictureInPictureButton.setImage(UIImage(systemName: "pip.enter")!.withTintColor(.white, + renderingMode: .alwaysOriginal), + for: .normal) + pictureInPictureButton.isHidden = true + if UIDevice.current.userInterfaceIdiom == .pad { pointSize = 60 } else { @@ -77,21 +83,22 @@ class NCPlayerToolBar: UIView { playerButtonView.spacing = pointSize playerButtonView.isHidden = true - buttonImage = UIImage(systemName: "gobackward.10", withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize))!.withTintColor(.white, renderingMode: .alwaysOriginal) + buttonImage = NCImagesRepository.mediaIconRewind backButton.setImage(buttonImage, for: .normal) - buttonImage = UIImage(systemName: "play.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize))!.withTintColor(.white, renderingMode: .alwaysOriginal) + buttonImage = NCImagesRepository.mediaIconRewind playButton.setImage(buttonImage, for: .normal) - buttonImage = UIImage(systemName: "goforward.10", withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize))!.withTintColor(.white, renderingMode: .alwaysOriginal) + buttonImage = NCImagesRepository.mediaIconRewind forwardButton.setImage(buttonImage, for: .normal) playbackSlider.addTapGesture() playbackSlider.setThumbImage(UIImage(systemName: "circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15)), for: .normal) playbackSlider.value = 0 - playbackSlider.tintColor = .white + playbackSlider.thumbTintColor = UIColor(resource: .MediaPlayer.sliderThumb) + playbackSlider.minimumTrackTintColor = UIColor(resource: .MediaPlayer.sliderMin) + playbackSlider.maximumTrackTintColor = UIColor(resource: .MediaPlayer.sliderMax) playbackSlider.addTarget(self, action: #selector(playbackValChanged(slider:event:)), for: .valueChanged) - repeatButton.setImage(utility.loadImage(named: "repeat", colors: [NCBrandColor.shared.iconImageColor2]), for: .normal) utilityView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap(gestureRecognizer:)))) playbackSliderView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap(gestureRecognizer:)))) @@ -104,6 +111,23 @@ class NCPlayerToolBar: UIView { // Normally hide self.alpha = 0 self.isHidden = true + + NCMediaCoordinator.shared.isPictureInPictureSupportedPublisher.sink { [weak self] isPictureInPictureSupported in + self?.pictureInPictureButton.isHidden = !isPictureInPictureSupported + }.store(in: &cancellables) + + NCMediaCoordinator.shared.isPictureInPictureActivePublisher.sink { [weak self] isPictureInPictureActive in + self?.updatePictureInPictureButtonImage(isPictureInPictureActive) + }.store(in: &cancellables) + + NCMediaCoordinator.shared.metadataSwitchPublisher.sink { [weak self] _, newItem in + self?.subtitleButton.isEnabled = newItem?.isVideo == true + self?.audioButton.isEnabled = newItem?.isVideo == true + }.store(in: &cancellables) + + NCMediaCoordinator.shared.isPlayingPublisher.sink { [weak self] isPlaying in + self?.updatePlayButtonImage(isPlaying) + }.store(in: &cancellables) } required init?(coder aDecoder: NSCoder) { @@ -134,8 +158,8 @@ class NCPlayerToolBar: UIView { playbackSlider.value = position - labelCurrentTime.text = "--:--" - labelLeftTime.text = "--:--" + labelCurrentTime.text = NCMediaCoordinatorConstants.emptyTime + labelLeftTime.text = NCMediaCoordinatorConstants.emptyTime if viewerMediaScreenMode == .normal { show() @@ -143,45 +167,17 @@ class NCPlayerToolBar: UIView { hide() } - MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = position - setupSubtitleButton() setupAudioButton() } - public func updatePlaybackPosition() { - guard let ncplayer = self.ncplayer, - let media = ncplayer.player.media else { - return - } - - let length = media.length.intValue - - let position = ncplayer.player.position - - let currentSeconds = Double(position) * (Double(length) / 1000.0) - - let currentTimeObj = VLCTime(int: Int32(currentSeconds * 1000)) - let remainingTimeObj = VLCTime(int: Int32((Double(length) / 1000.0) - currentSeconds) * 1000) - - labelCurrentTime.text = currentTimeObj.stringValue == "--:--" ? "00:00" : currentTimeObj.stringValue - - let remaining = remainingTimeObj.stringValue - labelLeftTime.text = "-\(remaining)" - - if playbackSliderEvent == .ended { + public func update(position: Float, length: Float, playedTime: String, remainingTime: String?) { + // SLIDER & TIME + if playbackSliderEvent != .began && playbackSliderEvent != .moved { playbackSlider.value = position } - - MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPMediaItemPropertyPlaybackDuration] = length / 1000 - MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentSeconds - } - - public func updateTopToolBar(videoSubTitlesIndexes: [Any], audioTrackIndexes: [Any]) { - if let metadata = metadata, metadata.isVideo { - self.subtitleButton.isEnabled = true - self.audioButton.isEnabled = true - } + labelCurrentTime.text = playedTime + labelLeftTime.text = remainingTime } // MARK: - @@ -202,16 +198,24 @@ class NCPlayerToolBar: UIView { }) } - func showPauseButton() { + // MARK: - Update Play Button Image + + private func updatePlayButtonImage(_ isPlaying: Bool) { + if isPlaying && (mediaCoordinator.item?.ocId == metadata?.ocId) { + showPauseButton() + } else { + showPlayButton() + } + } + + private func showPauseButton() { buttonImage = UIImage(systemName: "pause.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize))!.withTintColor(.white, renderingMode: .alwaysOriginal) playButton.setImage(buttonImage, for: .normal) - MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 1 } - func showPlayButton() { + private func showPlayButton() { buttonImage = UIImage(systemName: "play.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize))!.withTintColor(.white, renderingMode: .alwaysOriginal) playButton.setImage(buttonImage, for: .normal) - MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 0 } // MARK: - Event / Gesture @@ -257,48 +261,60 @@ class NCPlayerToolBar: UIView { viewerMediaPage?.changeScreenMode(mode: viewerMediaScreenMode) } - private func setupSubtitleButton() { - guard let player = ncplayer?.player else { return } - - var currentIndex: Int? - if let data = database.getVideo(metadata: metadata), let idx = data.currentVideoSubTitleIndex { - currentIndex = idx - } else { - currentIndex = Int(player.currentVideoSubTitleIndex) - } - - subtitleButton.menu = NCContextMenuPlayerTracks( - trackType: .subtitle, - tracks: player.videoSubTitlesNames, - trackIndexes: player.videoSubTitlesIndexes, - currentIndex: currentIndex, - ncplayer: ncplayer, - metadata: metadata, - viewerMediaPage: viewerMediaPage - ).viewMenu() + @IBAction func tapPictureInPicture(_ sender: Any) { + mediaCoordinator.switchPictureInPicture() } - private func setupAudioButton() { - guard let player = ncplayer?.player else { return } - - var currentIndex: Int? - if let data = database.getVideo(metadata: metadata), let idx = data.currentAudioTrackIndex { - currentIndex = idx + private func updatePictureInPictureButtonImage(_ isPictureInPictureActive: Bool) { + if isPictureInPictureActive { + pictureInPictureButton.setImage(UIImage(systemName: "pip.exit")?.withTintColor(.white, renderingMode: .alwaysOriginal), for: .normal) } else { - currentIndex = Int(player.currentAudioTrackIndex) + pictureInPictureButton.setImage(UIImage(systemName: "pip.enter")?.withTintColor(.white, renderingMode: .alwaysOriginal), for: .normal) } - - audioButton.menu = NCContextMenuPlayerTracks( - trackType: .audio, - tracks: player.audioTrackNames, - trackIndexes: player.audioTrackIndexes, - currentIndex: currentIndex, - ncplayer: ncplayer, - metadata: metadata, - viewerMediaPage: viewerMediaPage - ).viewMenu() } + private func setupSubtitleButton() { + guard let player = ncplayer else { return } + + var currentIndex: Int? + if let data = database.getVideoOrAudio(metadata: metadata), let idx = data.currentVideoSubTitleIndex { + currentIndex = idx + } else { + currentIndex = Int(player.currentVideoSubTitleIndex) + } + + subtitleButton.menu = NCContextMenuPlayerTracks( + trackType: .subtitle, + tracks: player.videoSubTitlesNames, + trackIndexes: player.videoSubTitlesIndexes, + currentIndex: currentIndex, + ncplayer: ncplayer, + metadata: metadata, + viewerMediaPage: viewerMediaPage + ).viewMenu() + } + + private func setupAudioButton() { + guard let player = ncplayer else { return } + + var currentIndex: Int? + if let data = database.getVideoOrAudio(metadata: metadata), let idx = data.currentAudioTrackIndex { + currentIndex = idx + } else { + currentIndex = Int(player.currentAudioTrackIndex) + } + + audioButton.menu = NCContextMenuPlayerTracks( + trackType: .audio, + tracks: player.audioTrackNames, + trackIndexes: player.audioTrackIndexes, + currentIndex: currentIndex, + ncplayer: ncplayer, + metadata: metadata, + viewerMediaPage: viewerMediaPage + ).viewMenu() + } + @IBAction func tapPlayerPause(_ sender: Any) { guard let ncplayer = ncplayer else { return } @@ -324,16 +340,6 @@ class NCPlayerToolBar: UIView { ncplayer.jumpBackward(10) self.viewerMediaPage?.startTimerAutoHide() } - - @IBAction func tapRepeat(_ sender: Any) { - if playRepeat { - playRepeat = false - repeatButton.setImage(utility.loadImage(named: "repeat", colors: [NCBrandColor.shared.iconImageColor2]), for: .normal) - } else { - playRepeat = true - repeatButton.setImage(utility.loadImage(named: "repeat", colors: [.white]), for: .normal) - } - } } extension NCPlayerToolBar: NCSelectDelegate { @@ -343,7 +349,7 @@ extension NCPlayerToolBar: NCSelectDelegate { let scene = SceneManager.shared.getWindow(controller: viewerMediaPage.tabBarController)?.windowScene if utilityFileSystem.fileProviderStorageExists(metadata) { - addPlaybackSlave(type: type, metadata: metadata) + addPlaybackTrack(type: type, metadata: metadata) } else { var downloadRequest: DownloadRequest? let token = showHudBanner(scene: scene, @@ -387,7 +393,7 @@ extension NCPlayerToolBar: NCSelectDelegate { etag: etag) if error == .success { - self.addPlaybackSlave(type: type, metadata: metadata) + self.addPlaybackTrack(type: type, metadata: metadata) } else if error.errorCode != 200 { await showErrorBanner(scene: scene, text: error.errorDescription, errorCode: error.errorCode) } @@ -398,14 +404,14 @@ extension NCPlayerToolBar: NCSelectDelegate { } // swiftlint:disable inclusive_language - func addPlaybackSlave(type: String, metadata: tableMetadata) { + func addPlaybackTrack(type: String, metadata: tableMetadata) { // swiftlint:enable inclusive_language let fileNameLocalPath = utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, fileName: metadata.fileNameView, userId: metadata.userId, urlBase: metadata.urlBase) if type == "subtitle" { - self.ncplayer?.player.addPlaybackSlave(URL(fileURLWithPath: fileNameLocalPath), type: .subtitle, enforce: true) + self.ncplayer?.addPlaybackTrack(URL(fileURLWithPath: fileNameLocalPath), type: .subtitle, enforce: true) } else if type == "audio" { - self.ncplayer?.player.addPlaybackSlave(URL(fileURLWithPath: fileNameLocalPath), type: .audio, enforce: true) + self.ncplayer?.addPlaybackTrack(URL(fileURLWithPath: fileNameLocalPath), type: .audio, enforce: true) } } } diff --git a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.xib b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.xib index deaf0d7558..7393a505bb 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.xib +++ b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.xib @@ -3,6 +3,7 @@ + @@ -14,108 +15,146 @@ - + - - - + + + + + + + + + + + + + + + - + - - - - - + - - + + - - + + + + - + + + + + - - - + - - + @@ -130,7 +169,7 @@ - + @@ -139,11 +178,11 @@ + - @@ -151,12 +190,21 @@ - - - - - - - + + + + + + + + + + + + + + + + diff --git a/iOSClient/Viewer/NCViewerMedia/NCViewerMedia.swift b/iOSClient/Viewer/NCViewerMedia/NCViewerMedia.swift index b06d71c602..a3a958b216 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCViewerMedia.swift +++ b/iOSClient/Viewer/NCViewerMedia/NCViewerMedia.swift @@ -1,5 +1,7 @@ // SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: STRATO GmbH // SPDX-FileCopyrightText: 2020 Marino Faggiana +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda // SPDX-License-Identifier: GPL-3.0-or-later import UIKit @@ -9,8 +11,10 @@ import SwiftUI import MobileVLCKit import Alamofire import LucidBanner +import Combine -public protocol NCViewerMediaViewDelegate: AnyObject { +protocol NCViewerMediaViewDelegate: AnyObject { + func movedToAnotherItem(oldItem: tableMetadata, newItem: tableMetadata) func didOpenDetail() func didCloseDetail() } @@ -25,7 +29,7 @@ class NCViewerMedia: UIViewController { @IBOutlet weak var statusLabel: UILabel! @IBOutlet weak var detailView: NCViewerMediaDetailView! - private let player = VLCMediaPlayer() + private let player = VLCMediaPlayer() // Live photos display private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)! let utilityFileSystem = NCUtilityFileSystem() let utility = NCUtility() @@ -35,7 +39,8 @@ class NCViewerMedia: UIViewController { weak var viewerMediaPage: NCViewerMediaPage? var playerToolBar: NCPlayerToolBar? var ncplayer: NCPlayer? - var image: UIImage? { + private let mediaCoordinator = NCMediaCoordinator.shared + private(set) var image: UIImage? { didSet { if metadata.isImage { analyzeCurrentImage() @@ -48,14 +53,18 @@ class NCViewerMedia: UIViewController { var imageViewConstraint: CGFloat = 0 var isDetailViewInitializze: Bool = false weak var delegate: NCViewerMediaViewDelegate? + private var hudToken: Int? private var allowOpeningDetails = true private var tipView: EasyTipView? + private var activityIndicator: UIActivityIndicatorView? var sceneIdentifier: String { - (self.tabBarController as? NCMainTabBarController)?.sceneIdentifier ?? "" + self.mainTabBarController?.sceneIdentifier ?? "" } + private var cancellables: Set = [] + // MARK: - View Life Cycle required init?(coder aDecoder: NSCoder) { @@ -76,6 +85,7 @@ class NCViewerMedia: UIViewController { scrollView.delegate = self scrollView.maximumZoomScale = 4 scrollView.minimumZoomScale = 1 + scrollView.backgroundColor = metadata.isVideo ? .black : NCBrandColor.shared.appBackgroundColor view.addGestureRecognizer(doubleTapGestureRecognizer) @@ -98,7 +108,22 @@ class NCViewerMedia: UIViewController { playerToolBar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true } - self.ncplayer = NCPlayer(imageVideoContainer: self.imageVideoContainer, playerToolBar: self.playerToolBar, metadata: self.metadata, viewerMediaPage: self.viewerMediaPage) + activityIndicator = UIActivityIndicatorView(style: .large) + activityIndicator?.color = .white + activityIndicator?.hidesWhenStopped = true + activityIndicator?.translatesAutoresizingMaskIntoConstraints = false + + if let activityIndicator = activityIndicator { + view.addSubview(activityIndicator) + NSLayoutConstraint.activate([ + activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), + activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor) + ]) + } + + mediaCoordinator.delegate = self + + self.ncplayer = NCPlayer(playerToolBar: self.playerToolBar, metadata: self.metadata, viewerMediaPage: self.viewerMediaPage) } detailViewTopConstraint.constant = 0 @@ -115,12 +140,7 @@ class NCViewerMedia: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - if #available(iOS 18.0, *) { - tabBarController?.setTabBarHidden(true, animated: true) - } else { - tabBarController?.tabBar.isHidden = true - } - + tabBarController?.tabBar.isHidden = true viewerMediaPage?.navigationItem.title = (metadata.fileNameView as NSString).deletingPathExtension if metadata.isImage, let viewerMediaPage = self.viewerMediaPage { @@ -140,61 +160,20 @@ class NCViewerMedia: UIViewController { await NCNetworking.shared.transferDispatcher.addDelegate(self) } - viewerMediaPage?.clearCommandCenter() - if metadata.isAudioOrVideo { - if let ncplayer = self.ncplayer { - if ncplayer.url == nil { - NCActivityIndicator.shared.startActivity(backgroundView: self.view, style: .medium) - self.networking.getVideoUrl(metadata: metadata) { url, autoplay, error in - NCActivityIndicator.shared.stop() - if error == .success, let url = url { - ncplayer.openAVPlayer(url: url, autoplay: autoplay) - } else { - Task { @MainActor in - guard let metadata = await self.database.setMetadataSessionInWaitDownloadAsync(ocId: self.metadata.ocId, - session: self.networking.sessionDownload, - selector: "") else { - return - } - let scene = SceneManager.shared.getWindow(controller: self.tabBarController)?.windowScene - var downloadRequest: DownloadRequest? - let token = showHudBanner(scene: scene, - title: NSLocalizedString("_download_in_progress_", comment: ""), - stage: .button) { - if let request = downloadRequest { - request.cancel() - } - } - - let results = await self.networking.downloadFile(metadata: metadata) { request in - downloadRequest = request - } progressHandler: { progress in - Task {@MainActor in - LucidBanner.shared.update( - payload: LucidBannerPayload.Update(progress: progress.fractionCompleted), - for: token) - } - } - LucidBanner.shared.dismiss() - - if results.nkError == .success { - if self.utilityFileSystem.fileProviderStorageExists(self.metadata) { - let url = URL(fileURLWithPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(self.metadata.ocId, fileName: self.metadata.fileNameView, userId: self.metadata.userId, urlBase: self.metadata.urlBase)) - ncplayer.openAVPlayer(url: url, autoplay: autoplay) - } - } - } - } - } - } else { - var position: Float = 0 - if let result = self.database.getVideo(metadata: metadata), let resultPosition = result.position { - position = resultPosition - } - ncplayer.restartAVPlayer(position: position, pauseAfterPlay: true) + mediaCoordinator.metadataSwitchPublisher.sink { [weak self] old, new in + guard let old, let new else { return } + self?.playerMovedToAnotherItem(oldItem: old, newItem: new) + }.store(in: &cancellables) + mediaCoordinator.statePublisher.sink { [weak self] state in + DispatchQueue.main.async { + self?.mediaCoordinator(changedPlaybackState: state) } - } + }.store(in: &cancellables) + mediaCoordinator.positionPublisher.sink { [weak self] position in + self?.mediaCoordinator(didChangePosition: position) + }.store(in: &cancellables) + mediaCoordinator.putVideoOutputView(in: self.imageVideoContainer) } else if metadata.isImage { DispatchQueue.main.asyncAfter(deadline: .now() + 1) { self.showTip() @@ -212,35 +191,35 @@ class NCViewerMedia: UIViewController { override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) - Task { await NCNetworking.shared.transferDispatcher.removeDelegate(self) } - - if let ncplayer, ncplayer.isPlaying() { - ncplayer.playerPause() - } } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) - let wasShownDetail = detailView.isShown + let wasShown = detailView.isShown if UIDevice.current.orientation.isValidInterfaceOrientation { - if wasShownDetail { - closeDetail(animate: false) - } + + if wasShown { closeDetail(animate: false) } dismissTip() + if metadata.isVideo { + self.imageVideoContainer.isHidden = true + } coordinator.animate(alongsideTransition: { _ in // back to the original size - if self.scrollView.zoomScale != self.scrollView.minimumZoomScale { - self.scrollView.zoom(to: CGRect(x: 0, y: 0, width: self.scrollView.bounds.width, height: self.scrollView.bounds.height), animated: false) - self.view.layoutIfNeeded() - } + self.scrollView.zoom(to: CGRect(x: 0, y: 0, width: self.scrollView.bounds.width, height: self.scrollView.bounds.height), animated: false) + self.view.layoutIfNeeded() }, completion: { _ in - if wasShownDetail { + if self.metadata.isVideo { + self.imageVideoContainer.isHidden = false + } else if self.metadata.isImage { + self.showTip() + } + if wasShown { self.openDetail(animate: true) } }) @@ -282,11 +261,6 @@ class NCViewerMedia: UIViewController { self.image = image self.imageVideoContainer.image = self.image return - } else if metadata.isAudio { - let image = utility.loadImage(named: "waveform", colors: [NCBrandColor.shared.iconImageColor2]) - self.image = image - self.imageVideoContainer.image = self.image - return } else if metadata.isImage { if fileNameExtension == "GIF" { if !NCUtility().existsImage(ocId: metadata.ocId, etag: metadata.etag, ext: global.previewExt1024, userId: metadata.userId, urlBase: metadata.urlBase) { @@ -338,6 +312,11 @@ class NCViewerMedia: UIViewController { urlBase: metadata.urlBase)) { self.image = image self.imageVideoContainer.image = self.image + } else if metadata.isAudio { + let image = utility.loadImage(named: "waveform", colors: [NCBrandColor.shared.iconImageColor2]) + self.image = image + self.imageVideoContainer.image = self.image + return } else { NextcloudKit.shared.downloadPreview(fileId: metadata.fileId, etag: metadata.etag, @@ -457,6 +436,12 @@ class NCViewerMedia: UIViewController { } extension NCViewerMedia { + @objc func playerMovedToAnotherItem(oldItem: tableMetadata, newItem: tableMetadata) { + guard oldItem.ocId == metadata.ocId else { return } + + delegate?.movedToAnotherItem(oldItem: oldItem, newItem: newItem) + } + @objc func openDetail(_ notification: NSNotification) { if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String, ocId == metadata.ocId { allowOpeningDetails = true @@ -546,6 +531,101 @@ extension NCViewerMedia { } } } + + // MARK: - Activity Indicator + + func startActivityIndicator() { + activityIndicator?.startAnimating() + } + + func stopActivityIndicator() { + activityIndicator?.stopAnimating() + } + + // MARK: - Media Coordinator Events + + func mediaCoordinator(changedPlaybackState state: NCPlayerState) { + if (state == .buffering) || (state == .gettingURL) { + startActivityIndicator() + } else { + stopActivityIndicator() + } + + switch state { + case .stopped: + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerStoppedPlaying) + case .downloading(let progress): + addDownloadHudIfNeeded() + LucidBanner.shared.update( + payload: LucidBannerPayload.Update(progress: progress), + for: hudToken + ) + case .error(let error): + let sceneIdentifier = self.sceneIdentifier + Task { + if let nkError = error { + await showErrorBanner(sceneIdentifier: sceneIdentifier, + text: nkError.errorDescription, + errorCode: nkError.errorCode) + } else { + await showErrorBanner(sceneIdentifier: sceneIdentifier, + text: "_error_something_wrong_", + errorCode: 0) + } + } + hudToken = nil + case .downloaded: + addDownloadHudIfNeeded() + completeHudBannerSuccess(token: hudToken) + hudToken = nil + case .playing: + guard let playerToolBar = playerToolBar else { return } + if playerToolBar.playerButtonView.isHidden { + playerToolBar.playerButtonView.isHidden = false + viewerMediaPage?.changeScreenMode(mode: .normal) + } + // Set track audio/subtitle + let data = database.getVideoOrAudio(metadata: metadata) + if let currentAudioTrackIndex = data?.currentAudioTrackIndex { + mediaCoordinator.currentAudioTrackIndex = Int32(currentAudioTrackIndex) + } + if let currentVideoSubTitleIndex = data?.currentVideoSubTitleIndex { + mediaCoordinator.currentVideoSubTitleIndex = Int32(currentVideoSubTitleIndex) + } + let size = mediaCoordinator.videoSize + ncplayer?.length = Int(mediaCoordinator.length) + ncplayer?.width = Int(size.width) + ncplayer?.height = Int(size.height) + database.addVideoOrAudio(metadata: metadata, width: ncplayer?.width, height: ncplayer?.height, length: ncplayer?.length) + + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerIsPlaying) + case .paused: + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterPlayerStoppedPlaying) + default: break + } + } + + func mediaCoordinator(didChangePosition position: Float) { + stopActivityIndicator() + guard metadata.ocId == mediaCoordinator.item?.ocId else { return } + playerToolBar?.update(position: position, + length: Float(mediaCoordinator.length / 1000), + playedTime: mediaCoordinator.playedTime, + remainingTime: mediaCoordinator.remainingTime) + } + + private func addDownloadHudIfNeeded() { + if hudToken != nil { return } + + let scene = SceneManager.shared.getWindow(controller: self.tabBarController)?.windowScene + hudToken = showHudBanner( + scene: scene, + title: NSLocalizedString("_downloading_", comment: ""), + stage: .button) { [weak self] in + self?.mediaCoordinator.cancelDownload() + LucidBanner.shared.dismiss() + } + } } extension NCViewerMedia: UIScrollViewDelegate { @@ -643,3 +723,42 @@ extension NCViewerMedia: NCTransferDelegate { } } } + +// MARK: - NCMediaCoordinatorDelegate + +extension NCViewerMedia: NCMediaCoordinatorVLCStrategyDelegate { + func showError(withTitle title: String, message: String) { + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + + alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), + style: .default, + handler: { [weak self] _ in + guard let self = self else { return } + self.playerToolBar?.removeFromSuperview() + self.viewerMediaPage?.navigationController?.popViewController(animated: true) + self.mediaCoordinator.finishMediaSession() + })) + + self.present(alert, animated: true) + } + + func showAlert(alert: UIAlertController) { + self.present(alert, animated: true) + } + + func showLogin(withTitle title: String, message: String, defaultUsername username: String?, askingForStorage: Bool, withReference reference: NSValue) { + // UIAlertController other states... + } + + func showProgress(withTitle title: String, message: String, isIndeterminate: Bool, position: Float, cancel cancelString: String?, withReference reference: NSValue) { + // UIAlertController other states... + } + + func updateProgress(withReference reference: NSValue, message: String?, position: Float) { + // UIAlertController other states... + } + + func cancelDialog(withReference reference: NSValue) { + // UIAlertController other states... + } +} diff --git a/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.storyboard b/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.storyboard index 0e982c9edd..c1b8cbcfac 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.storyboard +++ b/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.storyboard @@ -1,8 +1,10 @@ - + - + + + @@ -27,7 +29,7 @@ - + @@ -89,16 +91,16 @@ - + - + @@ -180,7 +182,7 @@ @@ -192,11 +194,11 @@ - + @@ -222,7 +224,7 @@ - + @@ -241,7 +243,7 @@ @@ -250,38 +252,38 @@ - + @@ -292,73 +294,73 @@ - + @@ -408,14 +410,14 @@ - + - + @@ -436,20 +438,18 @@ - + - diff --git a/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift b/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift index 665248650d..6ef2354f33 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift +++ b/iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2020 Marino Faggiana +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda // SPDX-License-Identifier: GPL-3.0-or-later import UIKit @@ -18,19 +19,14 @@ class NCViewerMediaPage: UIViewController { // Parameters var ocIds: [String] = [] var currentIndex: Int = 0 - var delegateViewController: UIViewController? var modifiedOcId: [String] = [] - var nextIndex: Int? + private var nextIndex: Int? var panGestureRecognizer: UIPanGestureRecognizer! var singleTapGestureRecognizer: UITapGestureRecognizer! var longtapGestureRecognizer: UILongPressGestureRecognizer! - var playCommand: Any? - var pauseCommand: Any? - var skipForwardCommand: Any? - var skipBackwardCommand: Any? - var nextTrackCommand: Any? - var previousTrackCommand: Any? + var textColor: UIColor = NCBrandColor.shared.textColor + let utilityFileSystem = NCUtilityFileSystem() let global = NCGlobal.shared let database = NCManageDatabase.shared @@ -47,7 +43,10 @@ class NCViewerMediaPage: UIViewController { primaryAction: nil, menu: UIMenu(title: "", children: [ UIDeferredMenuElement.uncached { [self] completion in - if let menu = NCViewerContextMenu(metadata: currentViewController.metadata, controller: self.tabBarController as? NCMainTabBarController, webView: false, sender: self).viewMenu() { + if let menu = NCViewerContextMenu(metadata: currentViewController.metadata, + controller: self.mainTabBarController, + webView: false, + sender: self).viewMenu() { completion(menu.children) } } @@ -72,7 +71,7 @@ class NCViewerMediaPage: UIViewController { } var sceneIdentifier: String { - (self.tabBarController as? NCMainTabBarController)?.sceneIdentifier ?? "" + self.mainTabBarController?.sceneIdentifier ?? "" } // MARK: - View Life Cycle @@ -152,12 +151,7 @@ class NCViewerMediaPage: UIViewController { super.viewWillAppear(animated) changeScreenMode(mode: viewerMediaScreenMode) - - if #available(iOS 18.0, *) { - self.tabBarController?.setTabBarHidden(true, animated: true) - } else { - self.tabBarController?.tabBar.isHidden = true - } + tabBarController?.tabBar.isHidden = true } override func viewDidAppear(_ animated: Bool) { @@ -167,6 +161,7 @@ class NCViewerMediaPage: UIViewController { await NCNetworking.shared.transferDispatcher.addDelegate(self) } + changeScreenMode(mode: viewerMediaScreenMode) startTimerAutoHide() } @@ -174,12 +169,7 @@ class NCViewerMediaPage: UIViewController { super.viewWillDisappear(animated) changeScreenMode(mode: .normal) - - if #available(iOS 18.0, *) { - self.tabBarController?.setTabBarHidden(false, animated: true) - } else { - self.tabBarController?.tabBar.isHidden = false - } + tabBarController?.tabBar.isHidden = false } override func viewDidDisappear(_ animated: Bool) { @@ -189,9 +179,7 @@ class NCViewerMediaPage: UIViewController { await NCNetworking.shared.transferDispatcher.removeDelegate(self) } - currentViewController.ncplayer?.playerStop() timerAutoHide?.invalidate() - clearCommandCenter() } override var preferredStatusBarStyle: UIStatusBarStyle { @@ -210,7 +198,7 @@ class NCViewerMediaPage: UIViewController { return hideStatusBar } - func getViewerMedia(index: Int, metadata: tableMetadata) -> NCViewerMedia { + private func getViewerMedia(index: Int, metadata: tableMetadata) -> NCViewerMedia { // swiftlint:disable force_cast let viewerMedia = UIStoryboard(name: "NCViewerMediaPage", bundle: nil).instantiateViewController(withIdentifier: "NCViewerMedia") as! NCViewerMedia // swiftlint:enable force_cast @@ -246,14 +234,13 @@ class NCViewerMediaPage: UIViewController { } if metadata.isAudioOrVideo { - navigationController?.setNavigationBarAppearance(textColor: .white, backgroundColor: .black) currentViewController.playerToolBar?.show() view.backgroundColor = .black - moreNavigationItem.image = NCImageCache.shared.getImageButtonMore(colors: [.white]) + textColor = .white } else { navigationController?.setNavigationBarAppearance() view.backgroundColor = .systemBackground - moreNavigationItem.image = NCImageCache.shared.getImageButtonMore() + textColor = NCBrandColor.shared.textColor } } else if !currentViewController.detailView.isShown { @@ -267,6 +254,7 @@ class NCViewerMediaPage: UIViewController { } view.backgroundColor = .black + textColor = .white } if fullscreen { @@ -302,100 +290,6 @@ class NCViewerMediaPage: UIViewController { progressView.progress = 0 changeScreenMode(mode: .normal) } - - // MARK: - Command Center - - func updateCommandCenter(ncplayer: NCPlayer, title: String) { - var nowPlayingInfo = [String: Any]() - - UIApplication.shared.beginReceivingRemoteControlEvents() - - // Add handler for Play Command - MPRemoteCommandCenter.shared().playCommand.isEnabled = true - playCommand = MPRemoteCommandCenter.shared().playCommand.addTarget { _ in - - if !ncplayer.isPlaying() { - ncplayer.playerPlay() - return .success - } - return .commandFailed - } - - // Add handler for Pause Command - MPRemoteCommandCenter.shared().pauseCommand.isEnabled = true - pauseCommand = MPRemoteCommandCenter.shared().pauseCommand.addTarget { _ in - - if ncplayer.isPlaying() { - ncplayer.playerPause() - return .success - } - return .commandFailed - } - - // >> - MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = true - skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { event in - - let seconds = Int32((event as? MPSkipIntervalCommandEvent)?.interval ?? 0) - ncplayer.player.jumpForward(seconds) - return.success - } - - // << - MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = true - skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand.addTarget { event in - - let seconds = Int32((event as? MPSkipIntervalCommandEvent)?.interval ?? 0) - ncplayer.player.jumpBackward(seconds) - return.success - } - - nowPlayingInfo[MPMediaItemPropertyTitle] = title - if let image = currentViewController.image { - nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in - return image - } - } - MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo - } - - func clearCommandCenter() { - - UIApplication.shared.endReceivingRemoteControlEvents() - MPNowPlayingInfoCenter.default().nowPlayingInfo = nil - - MPRemoteCommandCenter.shared().playCommand.isEnabled = false - MPRemoteCommandCenter.shared().pauseCommand.isEnabled = false - MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = false - MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = false - MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = false - MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = false - - if let playCommand = playCommand { - MPRemoteCommandCenter.shared().playCommand.removeTarget(playCommand) - self.playCommand = nil - } - if let pauseCommand = pauseCommand { - MPRemoteCommandCenter.shared().pauseCommand.removeTarget(pauseCommand) - self.pauseCommand = nil - } - if let skipForwardCommand = skipForwardCommand { - MPRemoteCommandCenter.shared().skipForwardCommand.removeTarget(skipForwardCommand) - self.skipForwardCommand = nil - } - if let skipBackwardCommand = skipBackwardCommand { - MPRemoteCommandCenter.shared().skipBackwardCommand.removeTarget(skipBackwardCommand) - self.skipBackwardCommand = nil - } - if let nextTrackCommand = nextTrackCommand { - MPRemoteCommandCenter.shared().nextTrackCommand.removeTarget(nextTrackCommand) - self.nextTrackCommand = nil - } - if let previousTrackCommand = previousTrackCommand { - MPRemoteCommandCenter.shared().previousTrackCommand.removeTarget(previousTrackCommand) - self.previousTrackCommand = nil - } - } } // MARK: - UIPageViewController Delegate Datasource @@ -406,16 +300,14 @@ extension NCViewerMediaPage: UIPageViewControllerDelegate, UIPageViewControllerD guard currentIndex > 0, let metadata = database.getMetadataFromOcId(ocIds[currentIndex - 1]) else { return nil } - let viewerMedia = getViewerMedia(index: currentIndex - 1, metadata: metadata) - return viewerMedia + return getViewerMedia(index: currentIndex - 1, metadata: metadata) } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { guard currentIndex < ocIds.count - 1, let metadata = database.getMetadataFromOcId(ocIds[currentIndex + 1]) else { return nil } - let viewerMedia = getViewerMedia(index: currentIndex + 1, metadata: metadata) - return viewerMedia + return getViewerMedia(index: currentIndex + 1, metadata: metadata) } // START TRANSITION @@ -450,12 +342,13 @@ extension NCViewerMediaPage: UIPageViewControllerDelegate, UIPageViewControllerD if completed && nextIndex != nil { previousViewControllers.forEach { viewController in let viewerMedia = viewController as? NCViewerMedia - viewerMedia?.ncplayer?.playerStop() viewerMedia?.closeDetail() } currentIndex = nextIndex! } - + if completed { + NCMediaCoordinator.shared.finishMediaSession(clearQueue: false) + } changeScreenMode(mode: viewerMediaScreenMode) startTimerAutoHide() @@ -473,7 +366,7 @@ extension NCViewerMediaPage: UIGestureRecognizerDelegate { var velocityCheck: Bool = false - if UIDevice.current.orientation.isLandscape { + if UIDevice.current.isVirtualOrientationLandscape { velocityCheck = velocity.x < 0 } else { velocityCheck = velocity.y < 0 @@ -519,11 +412,10 @@ extension NCViewerMediaPage: UIGestureRecognizerDelegate { if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: currentViewController.metadata), utilityFileSystem.fileProviderStorageExists(metadataLive) { AudioServicesPlaySystemSound(1519) // peek feedback - currentViewController.playLivePhoto(filePath: utilityFileSystem.getDirectoryProviderStorageOcId( - metadataLive.ocId, - fileName: metadataLive.fileName, - userId: metadataLive.userId, - urlBase: metadataLive.urlBase)) + currentViewController.playLivePhoto(filePath: utilityFileSystem.getDirectoryProviderStorageOcId(metadataLive.ocId, + fileName: metadataLive.fileName, + userId: metadataLive.userId, + urlBase: metadataLive.urlBase)) } } else if gestureRecognizer.state == .ended { currentViewController.stopLivePhoto() @@ -532,6 +424,7 @@ extension NCViewerMediaPage: UIGestureRecognizerDelegate { } extension UIPageViewController { + @objc func enableSwipeGesture() { for view in self.view.subviews { if let subView = view as? UIScrollView { @@ -550,6 +443,14 @@ extension UIPageViewController { } extension NCViewerMediaPage: NCViewerMediaViewDelegate { + func movedToAnotherItem(oldItem: tableMetadata, newItem: tableMetadata) { + guard currentIndex < ocIds.count - 1 else { return } + + currentIndex = NCMediaCoordinator.shared.currentItemIndex ?? 0 + let viewerMedia = getViewerMedia(index: currentIndex, metadata: newItem) + pageViewController.setViewControllers([viewerMedia], direction: .forward, animated: false) + } + func didOpenDetail() { changeScreenMode(mode: .normal) imageDetailNavigationItem.image = NCUtility().loadImage(named: "info.circle.fill") @@ -615,21 +516,7 @@ extension NCViewerMediaPage: NCTransferDelegate { } self.progressView.progress = 0 - if metadata.isAudioOrVideo, let ncplayer = self.currentViewController.ncplayer { - let url = URL(fileURLWithPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, - fileName: metadata.fileNameView, - userId: metadata.userId, - urlBase: metadata.urlBase)) - if ncplayer.isPlaying() { - ncplayer.playerPause() - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - ncplayer.openAVPlayer(url: url) - ncplayer.playerPlay() - } - } else { - ncplayer.openAVPlayer(url: url) - } - } else if metadata.isImage { + if metadata.isImage { await self.currentViewController.loadImage() } // UPLOAD @@ -646,6 +533,26 @@ extension NCViewerMediaPage: NCTransferDelegate { } } + func transferChange(status: String, metadatasError: [tableMetadata: NKError]) { + DispatchQueue.main.async { + switch status { + // DELETE + case NCGlobal.shared.networkingStatusDelete: + let hasAtLeastOneSuccess = metadatasError.contains { key, value in + self.ocIds.contains(key.ocId) && value == .success + } + if hasAtLeastOneSuccess { + if let ncplayer = self.currentViewController.ncplayer, ncplayer.isPlaying() { + ncplayer.playerPause() + } + self.navigationController?.popViewController(animated: true) + } + default: + break + } + } + } + func transferProgressDidUpdate(progress: Float, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String) { DispatchQueue.main.async { if progress == 1 { diff --git a/iOSClient/Viewer/NCViewerNextcloudText/NCViewerNextcloudText.swift b/iOSClient/Viewer/NCViewerNextcloudText/NCViewerNextcloudText.swift index ce7d2e8f03..0a631df886 100644 --- a/iOSClient/Viewer/NCViewerNextcloudText/NCViewerNextcloudText.swift +++ b/iOSClient/Viewer/NCViewerNextcloudText/NCViewerNextcloudText.swift @@ -17,7 +17,7 @@ class NCViewerNextcloudText: UIViewController, WKNavigationDelegate, WKScriptMes var items: [UIBarButtonItem] = [] var sceneIdentifier: String { - (self.tabBarController as? NCMainTabBarController)?.sceneIdentifier ?? "" + self.mainTabBarController?.sceneIdentifier ?? "" } // MARK: - View Life Cycle @@ -35,7 +35,10 @@ class NCViewerNextcloudText: UIViewController, WKNavigationDelegate, WKScriptMes primaryAction: nil, menu: UIMenu(title: "", children: [ UIDeferredMenuElement.uncached { [self] completion in - if let menu = NCViewerContextMenu(metadata: self.metadata, controller: self.tabBarController as? NCMainTabBarController, webView: true, sender: self).viewMenu() { + if let menu = NCViewerContextMenu(metadata: self.metadata, + controller: self.mainTabBarController, + webView: true, + sender: self).viewMenu() { completion(menu.children) } } diff --git a/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift b/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift index efb81667f3..148666f7bf 100644 --- a/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift +++ b/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift @@ -41,7 +41,7 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate { private var tipView: EasyTipView? var sceneIdentifier: String { - (self.tabBarController as? NCMainTabBarController)?.sceneIdentifier ?? "" + self.mainTabBarController?.sceneIdentifier ?? "" } // MARK: - View Life Cycle @@ -68,13 +68,16 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate { UIDeferredMenuElement.uncached { [self] completion in guard let metadata = self.metadata else { return } - if let menu = NCViewerContextMenu(metadata: metadata, controller: self.tabBarController as? NCMainTabBarController, webView: false, sender: self).viewMenu() { + if let menu = NCViewerContextMenu(metadata: metadata, + controller: self.mainTabBarController, + webView: false, + sender: self).viewMenu() { completion(menu.children) } } ])) } - defaultBackgroundColor = pdfView.backgroundColor + defaultBackgroundColor = NCBrandColor.shared.appBackgroundColor view.backgroundColor = defaultBackgroundColor // PDF CONTAINER @@ -108,7 +111,7 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate { ]) // MODAL - if self.navigationController?.presentingViewController != nil { + if (self.navigationController?.presentingViewController != nil) && ((self.navigationController?.viewControllers.count ?? 0) <= 1) { self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_close_", comment: ""), style: .plain, target: self, action: #selector(viewDismiss)) } @@ -155,6 +158,7 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate { pdfThumbnailView.translatesAutoresizingMaskIntoConstraints = false pdfThumbnailView.pdfView = pdfView + pdfThumbnailView.pdfView?.backgroundColor = NCBrandColor.shared.appBackgroundColor pdfThumbnailView.layoutMode = .vertical pdfThumbnailView.thumbnailSize = CGSize(width: thumbnailViewHeight, height: thumbnailViewHeight) pdfThumbnailView.backgroundColor = .clear diff --git a/iOSClient/Viewer/NCViewerProviderContextMenu.swift b/iOSClient/Viewer/NCViewerProviderContextMenu.swift index 219dd590f3..d53ee0cc9a 100644 --- a/iOSClient/Viewer/NCViewerProviderContextMenu.swift +++ b/iOSClient/Viewer/NCViewerProviderContextMenu.swift @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: Nextcloud GmbH // SPDX-FileCopyrightText: 2021 Marino Faggiana +// SPDX-FileCopyrightText: 2025 Serhii Kaliberda // SPDX-License-Identifier: GPL-3.0-or-later import UIKit @@ -179,7 +180,10 @@ class NCViewerProviderContextMenu: UIViewController { } private func viewVideo(metadata: tableMetadata) { - self.networking.getVideoUrl(metadata: metadata) { url, _, _ in + if NCMediaCoordinator.shared.isPlaying { + return + } + self.networking.getVideoUrl(metadata: metadata) { url, _ in if let url = url { self.player.media = VLCMedia(url: url) self.player.delegate = self diff --git a/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift b/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift index 3f4eaea468..410fb68c89 100644 --- a/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift +++ b/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift @@ -177,7 +177,7 @@ private var hasChangesQuickLook: Bool = false let cropViewController = Mantis.cropViewController(image: image, config: config, cropToolbar: toolbar) cropViewController.delegate = self - cropViewController.backgroundColor = .systemBackground + cropViewController.backgroundColor = NCBrandColor.shared.appBackgroundColor cropViewController.modalPresentationStyle = .fullScreen self.present(cropViewController, animated: true) diff --git a/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLookView.swift b/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLookView.swift index 816b467464..70f302d3ac 100644 --- a/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLookView.swift +++ b/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLookView.swift @@ -150,7 +150,7 @@ struct NCViewerQuickLookView: UIViewControllerRepresentable { let cropViewController = Mantis.cropViewController(image: image, config: config, cropToolbar: toolbar) cropViewController.delegate = self - cropViewController.backgroundColor = .systemBackground + cropViewController.backgroundColor = NCBrandColor.shared.appBackgroundColor cropViewController.modalPresentationStyle = .fullScreen viewController?.present(cropViewController, animated: true) diff --git a/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichDocument.swift b/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichDocument.swift index 759c32da5a..0edbe02566 100644 --- a/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichDocument.swift +++ b/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichDocument.swift @@ -22,7 +22,7 @@ class NCViewerRichDocument: UIViewController, WKNavigationDelegate, WKScriptMess } var sceneIdentifier: String { - (self.tabBarController as? NCMainTabBarController)?.sceneIdentifier ?? "" + self.mainTabBarController?.sceneIdentifier ?? "" } // MARK: - View Life Cycle @@ -40,7 +40,10 @@ class NCViewerRichDocument: UIViewController, WKNavigationDelegate, WKScriptMess primaryAction: nil, menu: UIMenu(title: "", children: [ UIDeferredMenuElement.uncached { [self] completion in - if let menu = NCViewerContextMenu(metadata: self.metadata, controller: self.tabBarController as? NCMainTabBarController, webView: true, sender: self).viewMenu() { + if let menu = NCViewerContextMenu(metadata: self.metadata, + controller: self.mainTabBarController, + webView: true, + sender: self).viewMenu() { completion(menu.children) } } @@ -66,6 +69,8 @@ class NCViewerRichDocument: UIViewController, WKNavigationDelegate, WKScriptMess webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: 0).isActive = true webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true + webView.backgroundColor = NCBrandColor.shared.appBackgroundColor + webView.scrollView.backgroundColor = NCBrandColor.shared.appBackgroundColor bottomConstraint = webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0) bottomConstraint?.isActive = true @@ -169,7 +174,7 @@ class NCViewerRichDocument: UIViewController, WKNavigationDelegate, WKScriptMess viewController.includeImages = true viewController.type = "" viewController.session = session - viewController.controller = self.tabBarController as? NCMainTabBarController + viewController.controller = self.mainTabBarController self.present(navigationController, animated: true, completion: nil) }