From f9038eb97926c64b38b0df95d096ed90f72431c5 Mon Sep 17 00:00:00 2001 From: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> Date: Wed, 6 May 2026 12:58:46 +0300 Subject: [PATCH 1/4] release 1.1.0 Signed-off-by: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> --- .gitignore | 5 + .swiftlint.yml | 2 + .../File_Provider_Extension.entitlements | 14 + Brand/Alpha/File_Provider_Extension.plist | 42 + .../File_Provider_Extension_UI.entitlements | 14 + Brand/Alpha/File_Provider_Extension_UI.plist | 44 + ...otification_Service_Extension.entitlements | 18 + .../Notification_Service_Extension.plist | 31 + Brand/Alpha/Share.entitlements | 18 + Brand/Alpha/Share.plist | 42 + Brand/Alpha/Widget.entitlements | 18 + Brand/Alpha/Widget.plist | 16 + .../WidgetDashboardIntentHandler.entitlements | 18 + .../Alpha/WidgetDashboardIntentHandler.plist | 30 + Brand/Alpha/iOSClient.entitlements | 28 + Brand/Alpha/iOSClient.plist | 202 ++ .../File_Provider_Extension.entitlements | 14 + Brand/AppStore/File_Provider_Extension.plist | 40 + .../File_Provider_Extension_UI.entitlements | 14 + .../AppStore/File_Provider_Extension_UI.plist | 44 + ...otification_Service_Extension.entitlements | 18 + .../Notification_Service_Extension.plist | 31 + Brand/AppStore/Share.entitlements | 18 + Brand/AppStore/Share.plist | 42 + Brand/AppStore/Widget.entitlements | 18 + Brand/AppStore/Widget.plist | 16 + .../WidgetDashboardIntentHandler.entitlements | 18 + .../WidgetDashboardIntentHandler.plist | 30 + Brand/AppStore/iOSClient.entitlements | 28 + Brand/AppStore/iOSClient.plist | 198 ++ .../Beta/File_Provider_Extension.entitlements | 14 + Brand/Beta/File_Provider_Extension.plist | 40 + .../File_Provider_Extension_UI.entitlements | 14 + Brand/Beta/File_Provider_Extension_UI.plist | 44 + ...otification_Service_Extension.entitlements | 18 + .../Beta/Notification_Service_Extension.plist | 31 + Brand/Beta/Share.entitlements | 18 + Brand/Beta/Share.plist | 42 + Brand/Beta/Widget.entitlements | 18 + Brand/Beta/Widget.plist | 16 + .../WidgetDashboardIntentHandler.entitlements | 18 + Brand/Beta/WidgetDashboardIntentHandler.plist | 30 + Brand/Beta/iOSClient.entitlements | 28 + Brand/Beta/iOSClient.plist | 200 ++ Brand/File_Provider_Extension.entitlements | 2 +- Brand/LaunchScreen.storyboard | 52 +- Brand/NCBrand-IONOS.swift | 165 ++ Brand/NCBrand.swift | 23 +- Brand/iOSClient.plist | 4 + ...le Provider Extension UIDebug.entitlements | 14 + .../File Provider ExtensionDebug.entitlements | 14 + .../FileProviderItem.swift | 3 + Nextcloud.xcodeproj/project.pbxproj | 2485 ++++++++++++----- .../File Provider Extension.xcscheme | 164 -- .../xcshareddata/xcschemes/Nextcloud.xcscheme | 26 +- NextcloudDebug.entitlements | 28 + ...cation Service ExtensionDebug.entitlements | 18 + .../NotificationService.swift | 4 +- Share/NCShareCell.swift | 2 +- Share/NCShareExtension+DataSource.swift | 9 +- Share/ShareDebug.entitlements | 18 + .../Extensions/SwiftUIView+Extensions.swift | 33 + .../NextcloudSnapshotTests.swift | 37 + ...itiesView.DefaultPreviewConfiguration.heic | Bin 0 -> 32097 bytes ...t_HUDView.DefaultPreviewConfiguration.heic | Bin 0 -> 18202 bytes .../Cloud_Checkmark.svg | 3 + .../Cloud_Checkmark.imageset/Contents.json | 12 + .../Cloud_Xmark.imageset/Cloud_Xmark.svg | 3 + .../Cloud_Xmark.imageset/Contents.json | 12 + .../Contents.json | 12 + .../file_unsupported_widget.svg | 3 + .../Media.imageset/Contents.json | 12 + .../Assets.xcassets/Media.imageset/Media.svg | 3 + .../Contents.json | 3 +- Widget/Assets.xcassets/Mic.imageset/Mic.svg | 3 + .../Contents.json | 3 +- Widget/Assets.xcassets/Note.imageset/Note.svg | 3 + .../Scan.imageset/Contents.json | 12 + Widget/Assets.xcassets/Scan.imageset/Scan.svg | 3 + .../Background.colorset/Contents.json | 38 + .../Contents.json | 38 + Widget/Colors.xcassets/Contents.json | 6 + .../Divider.colorset/Contents.json | 20 + .../Subtitle.colorset/Contents.json | 38 + .../Text.colorset/Contents.json | 20 + .../Title.colorset/Contents.json | 38 + Widget/Dashboard/DashboardData.swift | 4 +- Widget/Dashboard/DashboardWidgetView.swift | 57 +- Widget/Files/FilesData.swift | 18 + Widget/Files/FilesWidgetProvider.swift | 2 +- Widget/Files/FilesWidgetView.swift | 296 +- Widget/Toolbar/ToolbarData.swift | 8 +- Widget/Toolbar/ToolbarWidgetProvider.swift | 2 +- Widget/Toolbar/ToolbarWidgetView.swift | 94 +- Widget/Widget.swift | 2 - Widget/WidgetCommon.swift | 76 + Widget/WidgetDebug.entitlements | 18 + ...etDashboardIntentHandlerDebug.entitlements | 18 + .../NCAccountSettingsModel.swift | 46 +- .../NCAccountSettingsView.swift | 539 ++-- iOSClient/Activity/NCActivity.swift | 19 +- .../NCActivityNavigationController.swift | 5 +- iOSClient/AppDelegate.swift | 55 +- .../BurgerMenuAttachController.swift | 69 + iOSClient/BurgerMenu/BurgerMenuView.swift | 258 ++ .../BurgerMenu/BurgerMenuViewController.swift | 31 + .../BurgerMenu/BurgerMenuViewModel.swift | 103 + .../Color.colorset/Contents.json | 38 + .../AppBackground/Contents.json | 9 + .../DataProtection.colorset/Contents.json | 38 + .../AppBackground/Form.colorset/Contents.json | 38 + .../FormRow.colorset/Contents.json | 38 + .../AppBackground/Main.colorset/Contents.json | 38 + .../Background.colorset/Contents.json | 38 + .../ButtonForeground.colorset/Contents.json | 38 + .../CommonShadow.colorset/Contents.json | 20 + .../Colors.xcassets/BurgerMenu/Contents.json | 9 + .../Contents.json | 38 + .../BurgerMenu/Overlay.colorset/Contents.json | 20 + .../PressedButton.colorset/Contents.json | 38 + .../Contents.json | 20 + .../Colors.xcassets/Button/Contents.json | 9 + .../Colors.xcassets/Button/Link/Contents.json | 9 + .../Button/Link/Text/Contents.json | 9 + .../Link/Text/Disabled.colorset/Contents.json | 38 + .../Link/Text/Normal.colorset/Contents.json | 38 + .../Link/Text/Selected.colorset/Contents.json | 38 + .../Button/Primary/Background/Contents.json | 9 + .../Disabled.colorset/Contents.json | 38 + .../Background/Normal.colorset/Contents.json | 38 + .../Selected.colorset/Contents.json | 38 + .../Button/Primary/Contents.json | 9 + .../Button/Primary/Text/Contents.json | 9 + .../Text/Disabled.colorset/Contents.json | 38 + .../Text/Normal.colorset/Contents.json | 20 + .../Text/Selected.colorset/Contents.json | 20 + .../Button/Secondary/Background/Contents.json | 9 + .../Disabled.colorset/Contents.json | 20 + .../Background/Normal.colorset/Contents.json | 20 + .../Selected.colorset/Contents.json | 38 + .../Button/Secondary/Border/Contents.json | 9 + .../Border/Disabled.colorset/Contents.json | 38 + .../Border/Normal.colorset/Contents.json | 38 + .../Button/Secondary/Contents.json | 9 + .../Button/Secondary/Text/Contents.json | 9 + .../Text/Disabled.colorset/Contents.json | 38 + .../Text/Normal.colorset/Contents.json | 38 + .../Text/Selected.colorset/Contents.json | 38 + .../Background.colorset/Contents.json | 38 + .../CameraInformation/Contents.json | 9 + .../Contents.json | 20 + .../ImageTypeText.colorset/Contents.json | 20 + .../Text.colorset/Contents.json | 38 + .../TitleBackground.colorset/Contents.json | 38 + .../TitleText.colorset/Contents.json | 38 + iOSClient/Colors.xcassets/Contents.json | 6 + .../DataProtection/Contents.json | 9 + .../Link.colorset/Contents.json | 20 + .../ListRow.colorset/Contents.json | 38 + .../ListRowSubtitle.colorset/Contents.json | 38 + .../ListSeparator.colorset/Contents.json | 38 + .../NavigationBarTint.colorset/Contents.json | 38 + .../DestructiveAction.colorset/Contents.json | 20 + .../ButtonTint.colorset/Contents.json | 38 + .../FileActionsHeader/Contents.json | 9 + .../GrayButtonTint.colorset/Contents.json | 38 + .../Contents.json | 38 + .../Contents.json | 38 + .../SortButtonText.colorset/Contents.json | 38 + .../Background.colorset/Contents.json | 38 + .../Colors.xcassets/FileMenu/Contents.json | 9 + .../FolderIcon.colorset/Contents.json | 20 + .../FileMenu/Grabber.colorset/Contents.json | 38 + .../FileMenu/Icon.colorset/Contents.json | 38 + .../FileMenu/Overlay.colorset/Contents.json | 38 + .../SelectedRow.colorset/Contents.json | 38 + .../FileMenu/Text.colorset/Contents.json | 36 + .../FileSelection/Contents.json | 9 + .../Contents.json | 38 + .../Colors.xcassets/ListCell/Contents.json | 9 + .../ListCell/Separator.colorset/Contents.json | 20 + .../ListCell/Subtitle.colorset/Contents.json | 38 + .../ListCell/Title.colorset/Contents.json | 38 + .../Colors.xcassets/MediaPlayer/Contents.json | 9 + .../IconTint.colorset/Contents.json | 20 + .../SliderMaxColor.colorset/Contents.json | 20 + .../SliderMinColor.colorset/Contents.json | 20 + .../SliderThumb.colorset/Contents.json | 20 + .../NavigationBar/Contents.json | 9 + .../LogoTint.colorset/Contents.json | 38 + .../QualitySlider/Contents.json | 9 + .../MaximumTrackColor.colorset/Contents.json | 20 + .../ThumbColor.colorset/Contents.json | 20 + .../Contents.json | 38 + .../CancelTint.colorset/Contents.json | 38 + .../SelectToolbar/Contents.json | 9 + .../ItemStateActive.colorset/Contents.json | 38 + .../ItemStateInactive.colorset/Contents.json | 38 + .../ItemStateSelected.colorset/Contents.json | 38 + .../Background.colorset/Contents.json | 38 + .../Contents.json | 38 + .../BackgroundNormal.colorset/Contents.json | 38 + .../Share/Advanced/Cell/Contents.json | 9 + .../Cell/Subtitle.colorset/Contents.json | 38 + .../Cell/Title.colorset/Contents.json | 38 + .../Share/Advanced/Contents.json | 9 + .../SearchField/Border.colorset/Contents.json | 38 + .../Share/Advanced/SearchField/Contents.json | 9 + .../Placeholder.colorset/Contents.json | 38 + .../SectionTitle.colorset/Contents.json | 38 + .../Contents.json | 38 + .../TableCellSeparator.colorset/Contents.json | 38 + .../Share/Comment/Contents.json | 9 + .../Contents.json | 38 + .../TextFieldBorder.colorset/Contents.json | 38 + .../CommonIconTint.colorset/Contents.json | 38 + iOSClient/Colors.xcassets/Share/Contents.json | 9 + .../SearchUserCell/Background/Contents.json | 9 + .../Background/Normal.colorset/Contents.json | 38 + .../Background/Pressed.colorset/Contents.json | 38 + .../Share/SearchUserCell/Contents.json | 9 + .../Title.colorset/Contents.json | 36 + .../UserType.colorset/Contents.json | 38 + .../Share/TabTitle.colorset/Contents.json | 38 + .../Tabbar/ActiveItem.colorset/Contents.json | 38 + .../Tabbar/Background.colorset/Contents.json | 38 + .../Colors.xcassets/Tabbar/Contents.json | 9 + .../Tabbar/FabButton.colorset/Contents.json | 38 + .../InactiveItem.colorset/Contents.json | 38 + .../ButtonBackground.colorset/Contents.json | 38 + .../Transfers/Cell/Contents.json | 9 + .../Cell/Subtitle.colorset/Contents.json | 38 + .../Cell/Title.colorset/Contents.json | 38 + .../Colors.xcassets/Transfers/Contents.json | 9 + .../Background.colorset/Contents.json | 20 + .../Colors.xcassets/UserButton/Contents.json | 9 + .../UserButton/Tint.colorset/Contents.json | 20 + .../formSeparator.colorset/Contents.json | 20 + .../Components/Buttons/ButtonStyleGuide.swift | 208 ++ .../Buttons/CommonButtonConstants.swift | 23 + iOSClient/Components/Buttons/LinkButton.swift | 50 + .../Components/Buttons/PrimaryButton.swift | 67 + .../Components/Buttons/SecondaryButton.swift | 82 + .../Data/NCManageDatabase+Metadata.swift | 4 + iOSClient/Data/NCManageDatabase+Video.swift | 6 +- .../DataProtectionAgreementManager.swift | 144 + .../DataProtectionAgreementScreen.swift | 98 + .../DataProtectionHostingController.swift | 16 + .../DataProtection/DataProtectionModel.swift | 46 + .../DataProtectionSettingsScreen.swift | 189 ++ iOSClient/Extensions/UIColor+Extension.swift | 1 + .../UINavigationController+Extension.swift | 20 +- iOSClient/Extensions/UIView+Extension.swift | 4 + .../Extensions/UIView+GridSelection.swift | 23 + .../UIViewController+Extension.swift | 28 + iOSClient/Extensions/View+Design.swift | 37 + iOSClient/Extensions/View+Extension.swift | 2 + iOSClient/Favorites/NCFavorite.storyboard | 23 +- iOSClient/Favorites/NCFavorite.swift | 2 - .../NCFavoriteNavigationController.swift | 32 - .../Files/NCFiles+UIScrollViewDelegate.swift | 24 +- iOSClient/Files/NCFiles.storyboard | 30 +- iOSClient/Files/NCFiles.swift | 30 +- .../Files/NCFilesNavigationController.swift | 178 -- .../folder.imageset/folder.svg | 10 - .../folder_photo.svg | 10 - .../folder_encrypted.svg | 10 - .../folder_external.imageset/Contents.json | 16 - .../folder_external.svg | 10 - .../folder_group.imageset/folder_group.svg | 10 - .../folder_public.imageset/folder_link.svg | 10 - .../Contents.json | 16 - .../folder_shared_with_me.svg | 10 - .../Images.xcassets/gear.imageset/gear.pdf | Bin 58844 -> 0 bytes .../gitHub.imageset/Contents.json | 26 - .../gitHub.imageset/github.png | Bin 922 -> 0 bytes .../gitHub.imageset/github@2x.png | Bin 1834 -> 0 bytes .../gitHub.imageset/github@3x.png | Bin 2729 -> 0 bytes .../lock.imageset/lock-outline.svg | 4 - .../lock-open-variant-outline.svg | 4 - .../media.imageset/tabBarMedia.pdf | Bin 58260 -> 0 bytes .../BurgerMenu/Contents.json | 9 + .../BurgerMenu/bars.imageset/Contents.json | 12 + .../BurgerMenu/bars.imageset/bars.svg | 3 + .../chevronLeft.imageset/Contents.json | 12 + .../chevronLeft.imageset/chevronLeft.svg | 3 + .../BurgerMenu/cloud.imageset/Contents.json | 12 + .../BurgerMenu/cloud.imageset/cloud.svg | 3 + .../BurgerMenu/deleted.imageset/Contents.json | 12 + .../BurgerMenu/deleted.imageset/deleted.svg | 3 + .../BurgerMenu/offline.imageset/Contents.json | 12 + .../BurgerMenu/offline.imageset/offline.svg | 10 + .../BurgerMenu/recent.imageset/Contents.json | 12 + .../BurgerMenu/recent.imageset/recent.svg | 10 + .../settings.imageset/Contents.json | 12 + .../BurgerMenu/settings.imageset/settings.svg | 3 + iOSClient/IonosImages.xcassets/Contents.json | 6 + .../FileFolderCell/Contents.json | 9 + .../star.imageset/Contents.json | 12 + .../FileFolderCell/star.imageset/star.svg | 10 + .../FileSelection/Contents.json | 9 + .../files_selection.imageset/Contents.json | 22 + .../files_selection_dark.svg | 5 + .../files_selection_light.svg | 5 + .../grid_item_selected.imageset/Contents.json | 12 + .../grid_item_selected.svg | 7 + .../Contents.json | 12 + .../list_item_deselected.svg | 3 + .../list_item_selected.imageset/Contents.json | 12 + .../list_item_selected.svg | 7 + .../Contents.json | 12 + .../list_item_some_selected.svg | 7 + .../Contents.json | 22 + .../selection_mode_close_dark.svg | 3 + .../selection_mode_close_light.svg | 3 + .../view_mode_grid.imageset/Contents.json | 12 + .../view_mode_grid.svg | 3 + .../view_mode_list.imageset/Contents.json | 12 + .../view_mode_list.svg | 3 + .../IONOSAppIcon.appiconset/AppIcon.png | Bin 0 -> 10876 bytes .../IONOSAppIcon.appiconset/Contents.json | 14 + .../Contents.json | 12 + .../IONOSEasyStorageLogo.svg | 78 + .../IONOSLogo.imageset/Contents.json | 12 + .../IONOSLogo.imageset/logo@3x 2.png | Bin 0 -> 79628 bytes .../IONOS_icons/Contents.json | 6 + .../allowEdit.imageset/Contents.json | 15 + .../allowEdit.imageset/allowEdit.svg | 4 + .../createFolder.imageset/Contents.json | 15 + .../createFolder.imageset/createFolder.svg | 3 + .../data_protection.imageset/Contents.json | 15 + .../data_protection@3x.png | Bin 0 -> 24699 bytes .../details.imageset/Contents.json | 15 + .../IONOS_icons/details.imageset/details.svg | 10 + .../goToPage.imageset/Contents.json | 15 + .../goToPage.imageset/goToPage.svg | 4 + .../item.lock.imageset}/Contents.json | 2 +- .../item.lock.imageset/item.lock.svg | 3 + .../item.lock.open.imageset}/Contents.json | 2 +- .../item.lock.open.svg | 3 + .../IONOS_icons/media.imageset}/Contents.json | 2 +- .../IONOS_icons/media.imageset/media.svg | 3 + .../menu.add.imageset/Contents.json | 15 + .../menu.add.imageset/menu.add.svg | 3 + .../menu.search.imageset/Contents.json | 15 + .../menu.search.imageset/menu.search.svg | 10 + .../menu.share.imageset}/Contents.json | 2 +- .../menu.share.imageset/menu.share.svg | 10 + .../Contents.json | 15 + .../modifyWithQuickLook.svg | 11 + .../moveOrCopy.imageset/Contents.json | 15 + .../moveOrCopy.imageset/moveOrCopy.svg | 3 + .../offline.imageset/Contents.json | 15 + .../IONOS_icons/offline.imageset/offline.svg | 3 + .../photoOrVideo.imageset/Contents.json | 15 + .../photoOrVideo.imageset/photoOrVideo.svg | 3 + .../IONOS_icons/qrcode.imageset/Contents.json | 15 + .../IONOS_icons/qrcode.imageset/qrcode.svg | 3 + .../readOnly.imageset/Contents.json | 15 + .../readOnly.imageset/readOnly.svg | 3 + .../rename.imageset}/Contents.json | 2 +- .../IONOS_icons/rename.imageset/rename.svg | 10 + .../IONOS_icons/scan.imageset/Contents.json | 15 + .../IONOS_icons/scan.imageset/scan.svg | 10 + .../star.filled.imageset/Contents.json | 16 + .../star.filled.imageset/star.filled.svg | 10 + .../star.hollow.imageset/Contents.json | 15 + .../star.hollow.imageset/star.hollow.svg | 10 + .../IONOS_icons/synced.imageset/Contents.json | 16 + .../IONOS_icons/synced.imageset/synced.svg | 3 + .../trash_icon.imageset/Contents.json | 16 + .../trash_icon.imageset/trash_icon.svg | 3 + .../unshare.imageset/Contents.json | 15 + .../IONOS_icons/unshare.imageset/unshare.svg | 4 + .../viewInFolder.imageset/Contents.json | 15 + .../viewInFolder.imageset/viewInFolder.svg | 11 + .../CloseFullscreen.svg | 3 + .../CloseFullscreen.imageset/Contents.json | 12 + .../MediaPlayer/Contents.json | 9 + .../Forward.imageset/Contents.json | 12 + .../MediaPlayer/Forward.imageset/Forward.svg | 11 + .../Fullscreen.imageset/Contents.json | 12 + .../Fullscreen.imageset/Fullscreen.svg | 3 + .../Message.imageset/Contents.json | 12 + .../MediaPlayer/Message.imageset/Message.svg | 3 + .../MediaPlayer/Pause.imageset/Contents.json | 12 + .../MediaPlayer/Pause.imageset/Pause.svg | 10 + .../MediaPlayer/Play.imageset/Contents.json | 12 + .../MediaPlayer/Play.imageset/Play.svg | 10 + .../MediaPlayer/Rewind.imageset/Contents.json | 12 + .../MediaPlayer/Rewind.imageset/Rewind.svg | 11 + .../MediaPlayer/Sound.imageset/Contents.json | 12 + .../MediaPlayer/Sound.imageset/Sound.svg | 3 + .../SelectTabBar/Contents.json | 9 + .../SelectTabBar/copy.imageset/Contents.json | 16 + .../SelectTabBar/copy.imageset/copy.svg | 3 + .../delete.imageset/Contents.json | 16 + .../delete.imageset/trash-can.svg | 3 + .../download.imageset}/Contents.json | 2 +- .../download.imageset/cloud-arrow-down.svg | 3 + .../SelectTabBar/lock.imageset/Contents.json | 16 + .../SelectTabBar/lock.imageset/unlock.svg | 3 + .../restoreFromTrash.imageset/Contents.json | 16 + .../restoreFromTrash.imageset/rotate-left.svg | 3 + .../SelectTabBar/share.imageset/Contents.json | 16 + .../share.imageset/\356\202\232.svg" | 3 + .../unlock.imageset/Contents.json | 16 + .../SelectTabBar/unlock.imageset/lock.svg | 3 + .../Settings/AutoUpload/Contents.json | 9 + .../AutoUpload/folder.imageset/400-folder.svg | 3 + .../AutoUpload/folder.imageset/Contents.json | 15 + .../400-folder-open.svg | 3 + .../folder.opened.imageset/Contents.json | 15 + .../Settings/Contents.json | 9 + .../autoupload.folder.imageset/Contents.json | 15 + .../autoupload.folder.svg | 3 + .../bulletlist.imageset/Contents.json | 15 + .../bulletlist.imageset/bulletlist.svg | 3 + .../calendar.user.imageset/Contents.json | 15 + .../calendar.user.imageset/calendar.user.svg | 3 + .../Settings/camera.imageset/Contents.json | 15 + .../Settings/camera.imageset/camera.svg | 3 + .../dataprivacy.imageset/Contents.json | 15 + .../dataprivacy.imageset/dataprivacy.svg | 4 + .../folder.gear.imageset/Contents.json | 15 + .../folder.gear.imageset/folder.gear.svg | 3 + .../Settings/gear.imageset/Contents.json | 15 + .../Settings/gear.imageset/gear.svg | 3 + .../Settings/github.imageset/Contents.json | 15 + .../Settings/github.imageset/github.svg | 10 + .../Settings/handshake.imageset/Contents.json | 15 + .../Settings/handshake.imageset/handshake.svg | 3 + .../shield.halved.imageset/Contents.json | 15 + .../shield.halved.imageset/shield.halved.svg | 3 + .../Settings/xmark.imageset/Contents.json | 15 + .../Settings/xmark.imageset/xmark.svg | 3 + .../Transfers/Contents.json | 9 + .../Transfers/copy.imageset/Contents.json | 22 + .../Transfers/copy.imageset/copy_dark.svg | 12 + .../Transfers/copy.imageset/copy_light.svg | 12 + .../downloading.imageset/Contents.json | 22 + .../downloading.imageset/downloading_dark.svg | 11 + .../downloading_light.svg | 11 + .../Transfers/error.imageset/Contents.json | 22 + .../Transfers/error.imageset/error_dark.svg | 12 + .../Transfers/error.imageset/error_light.svg | 12 + .../Transfers/favorite.imageset/Contents.json | 22 + .../favorite.imageset/favorite_dark.svg | 11 + .../favorite.imageset/favorite_light.svg | 11 + .../Transfers/move.imageset/Contents.json | 22 + .../Transfers/move.imageset/move_dark.svg | 4 + .../Transfers/move.imageset/move_light.svg | 4 + .../Transfers/rename.imageset/Contents.json | 22 + .../Transfers/rename.imageset/rename_dark.svg | 11 + .../rename.imageset/rename_light.svg | 11 + .../Transfers/stop.imageset/Contents.json | 22 + .../Transfers/stop.imageset/stop_dark.svg | 3 + .../Transfers/stop.imageset/stop_light.svg | 3 + .../Transfers/trash.imageset/Contents.json | 22 + .../Transfers/trash.imageset/trash_dark.svg | 11 + .../Transfers/trash.imageset/trash_light.svg | 11 + .../Transfers/upload.imageset/Contents.json | 22 + .../Transfers/upload.imageset/upload_dark.svg | 11 + .../upload.imageset/upload_light.svg | 11 + .../waitToDownload.imageset/Contents.json | 22 + .../wait_to_download_dark.svg | 4 + .../wait_to_download_light.svg | 4 + .../Transfers/waiting.imageset/Contents.json | 22 + .../waiting.imageset/waiting_dark.svg | 11 + .../waiting.imageset/waiting_light.svg | 11 + .../accountCheckmark.imageset/Contents.json | 15 + .../accountCheckmark.svg | 3 + .../checkmarkIcon.imageset/Contents.json | 12 + .../checkmarkIcon.imageset/checkmarkIcon.svg | 3 + .../contactsIcon.imageset/Contents.json | 22 + .../contactsIcon_dark.svg | 3 + .../contactsIcon_light.svg | 3 + .../delete.imageset/Contents.json | 12 + .../delete.imageset/delete.svg | 3 + .../deleted.imageset/Contents.json | 12 + .../deleted.imageset/deleted.svg | 3 + .../favorites.imageset}/Contents.json | 2 +- .../favorites.imageset/favorites.svg | 3 + .../file_unsupported.imageset/Contents.json | 22 + .../file_unsupported_dark.svg | 3 + .../file_unsupported_light.svg | 3 + .../folder.imageset/Contents.json | 26 + .../folder.imageset/folder_icon_dark_mode.svg | 39 + .../folder_icon_light_mode.svg | 39 + .../Contents.json | 26 + .../folderAutomaticUpload_dark.svg | 11 + .../folderAutomaticUpload_light.svg | 11 + .../folderEncrypted.imageset/Contents.json | 26 + .../folder_icon_dark_mode.svg | 39 + .../folder_icon_light_mode.svg | 39 + .../folder_external.imageset/Contents.json | 26 + .../folder_icon_dark_mode.svg | 39 + .../folder_icon_light_mode.svg | 39 + .../folder_group.imageset/Contents.json | 26 + .../folder_group_dark.svg | 4 + .../folder_group_light.svg | 4 + .../gradientBackground.imageset/Contents.json | 16 + .../GradientBackgroundPad.svg | 9 + .../GradientBackgroundPhone.svg | 9 + .../home.imageset}/Contents.json | 2 +- .../home.imageset/home.svg | 3 + .../local.imageset}/Contents.json | 2 +- .../local.imageset/local.svg | 4 + .../more.imageset/Contents.json | 25 + .../more.imageset/more_dark.svg | 3 + .../more.imageset/more_light.svg | 3 + .../offlineFlag.imageset/Contents.json | 25 + .../offlineFlag.imageset/offlineFlag_dark.svg | 4 + .../offlineFlag_light.svg | 4 + .../restore.imageset/Contents.json | 16 + .../restore.imageset/restore.svg | 3 + .../restoreFromDeleted.imageset/Contents.json | 12 + .../restoreFromDeleted.svg | 3 + .../IonosImages.xcassets/share/Contents.json | 9 + .../share/canShare.imageset/Contents.json | 25 + .../share/canShare.imageset/canShare_dark.svg | 10 + .../canShare.imageset/canShare_light.svg | 10 + .../share/folder/Contents.json | 9 + .../folder/byLink.imageset/Contents.json | 22 + .../shared_by_link_folder 1@3x.png | Bin 0 -> 19352 bytes .../shared_by_link_folder@3x.png | Bin 0 -> 19790 bytes .../folder/internally.imageset/Contents.json | 22 + .../shared_internally_folder 1@3x.png | Bin 0 -> 19141 bytes .../shared_internally_folder@3x.png | Bin 0 -> 19494 bytes .../folder/withMe.imageset/Contents.json | 22 + .../shared_with_me_folder 1@3x.png | Bin 0 -> 14486 bytes .../shared_with_me_folder@3x.png | Bin 0 -> 14769 bytes .../share/icon/Contents.json | 9 + .../share/icon/byLink.imageset/Contents.json | 22 + .../byLink.imageset/shared_by_link_icon 1.svg | 4 + .../byLink.imageset/shared_by_link_icon.svg | 4 + .../icon/internally.imageset/Contents.json | 22 + .../shared_internally_icon 1.svg | 4 + .../shared_internally_icon.svg | 4 + .../share/icon/withMe.imageset/Contents.json | 22 + .../withMe.imageset/shared_with_me_icon 1.svg | 4 + .../withMe.imageset/shared_with_me_icon.svg | 4 + .../share/internalLink.imageset/Contents.json | 22 + .../internalLink_dark.svg | 3 + .../internalLink_light.svg | 3 + .../linkCircleFill.imageset/Contents.json | 22 + .../share/linkCircleFill.imageset/lnk_d.svg | 16 + .../share/linkCircleFill.imageset/lnk_l.svg | 16 + .../magnifyingGlass.imageset/Contents.json | 22 + .../magnifyingGlass_dark.svg | 3 + .../magnifyingGlass_light.svg | 3 + .../share/plus.imageset/Contents.json | 22 + .../share/plus.imageset/plus_dark.svg | 3 + .../share/plus.imageset/plus_light.svg | 3 + .../share/shared.imageset/Contents.json | 25 + .../share/shared.imageset/shared_dark.svg | 4 + .../share/shared.imageset/shared_light.svg | 4 + .../Contents.json | 22 + .../sq_drk.svg | 16 + .../sq_l.svg | 11 + .../share/threeDots.imageset/Contents.json | 22 + .../threeDots.imageset/threeDots_dark.svg | 3 + .../threeDots.imageset/threeDots_lights.svg | 3 + .../share/userContacts.imageset/Contents.json | 22 + .../userContacts_dark.svg | 3 + .../userContacts_light.svg | 3 + .../shares.imageset/Contents.json | 15 + .../shares.imageset/shares.svg | 3 + .../uploadFile.imageset/Contents.json | 15 + .../uploadFile.imageset/uploadFile.svg | 4 + .../userAvatar.imageset/Contents.json | 25 + .../userAvatar.imageset/userAvatar_dark.svg | 4 + .../userAvatar.imageset/userAvatar_light.svg | 4 + iOSClient/Login/NCLogin.storyboard | 275 +- iOSClient/Login/NCLogin.swift | 133 +- .../Login/NCLoginNavigationController.swift | 28 + .../ActionsHeader/FileActionsHeader.swift | 160 ++ .../ActionsHeader/FileActionsHeader.xib | 191 ++ .../Cell/ItemShareState.swift | 48 + .../Collection Common/Cell/NCCellMain.swift | 11 +- .../Collection Common/Cell/NCCellMedia.swift | 13 + .../Collection Common/Cell/NCGridCell.swift | 53 +- .../Collection Common/Cell/NCGridCell.xib | 127 +- .../Collection Common/Cell/NCListCell.swift | 141 +- .../Collection Common/Cell/NCListCell.xib | 186 +- .../Cell/PlaybackProgressView.swift | 114 + ...ionViewCommon+CollectionViewDelegate.swift | 102 +- ...llectionViewCommon+FileActionsHeader.swift | 167 ++ ...ctionViewCommon+SelectTabBarDelegate.swift | 39 +- .../NCCollectionViewCommon.swift | 95 +- .../NCCollectionViewCommonSelectTabBar.swift | 229 -- .../Section Header Footer/NCSectionFooter.xib | 8 +- iOSClient/Main/Create/NCCreate.swift | 2 +- .../NCCreateFormUploadConflict.storyboard | 17 +- .../Create/NCCreateFormUploadConflict.swift | 27 +- .../Upload Assets/NCUploadAssetsView.swift | 14 +- .../HiDriveMainNavigationController.swift | 146 + iOSClient/Main/Main.storyboard | 184 +- .../Main/NCMainNavigationController.swift | 450 --- iOSClient/Main/NCMainTabBar.swift | 245 ++ iOSClient/Main/NCMainTabBarController.swift | 86 +- iOSClient/Main/NCPickerViewController.swift | 5 - iOSClient/Main/UITabBarGuideline.swift | 83 + iOSClient/Media/Cell/NCMediaCell.swift | 17 +- iOSClient/Media/Cell/NCMediaCell.xib | 24 +- .../NCMedia+CollectionViewDelegate.swift | 7 +- iOSClient/Media/NCMedia+Command.swift | 170 +- iOSClient/Media/NCMedia.storyboard | 55 +- iOSClient/Media/NCMedia.swift | 460 +-- iOSClient/Media/NCMediaDataSource.swift | 9 +- .../Media/NCMediaNavigationController.swift | 172 -- iOSClient/Media/NCMediaPinchGesture.swift | 1 - iOSClient/Menu/ContextMenuActions.swift | 28 +- iOSClient/Menu/NCContextMenuMain.swift | 52 +- iOSClient/Menu/NCContextMenuNavigation.swift | 4 +- .../Menu/NCContextMenuPlayerTracks.swift | 26 +- iOSClient/Menu/NCContextMenuPlus.swift | 263 +- iOSClient/Menu/NCContextMenuProfile.swift | 2 +- iOSClient/Menu/NCContextMenuShare.swift | 70 +- iOSClient/Menu/NCViewerContextMenu.swift | 20 +- iOSClient/More/NCMore.swift | 4 - .../More/NCMoreNavigationController.swift | 58 - iOSClient/NCGlobal.swift | 2 +- iOSClient/NCImageCache.swift | 71 +- iOSClient/NCImagesRepository.swift | 224 ++ .../E2EE/NCNetworkingE2EEDelete.swift | 4 +- .../NCNetworking+TransferDelegate.swift | 4 +- .../Networking/NCNetworking+WebDAV.swift | 20 +- iOSClient/Notification/NCNotification.swift | 6 +- iOSClient/Offline/NCOffline.storyboard | 23 +- iOSClient/Recent/NCRecent.storyboard | 23 +- iOSClient/Recent/NCRecent.swift | 5 + .../RichWorkspace/NCViewerRichWorkspace.swift | 5 +- iOSClient/Scan document/NCScan.swift | 9 +- .../Scan document/NCUploadScanDocument.swift | 19 +- iOSClient/SceneDelegate.swift | 14 +- iOSClient/Select/NCSelect.swift | 74 +- .../Select/NCSelectCommandViewCopyMove.xib | 72 +- ...NCSelectCommandViewSelect+CreateFolder.xib | 56 +- .../Select/NCSelectCommandViewSelect.xib | 43 +- .../Select/NCSelectOpen+SelectDelegate.swift | 2 +- .../Advanced/File Name/NCFileNameView.swift | 19 +- .../Advanced/NCSettingsAdvancedModel.swift | 7 +- .../Advanced/NCSettingsAdvancedView.swift | 458 ++- .../AutoUpload/NCAutoUploadModel.swift | 4 +- .../AutoUpload/NCAutoUploadView.swift | 68 +- .../Settings/Display/NCDisplayModel.swift | 3 +- .../Settings/Display/NCDisplayView.swift | 8 +- iOSClient/Settings/NCPreferences.swift | 5 +- .../SelectAlbum/SelectAlbumView.swift | 4 + .../Settings/Settings/NCSettingsModel.swift | 15 +- .../Settings/Settings/NCSettingsView.swift | 223 +- ...hareDownloadLimitTableViewController.swift | 6 + .../NCShareDownloadLimitViewController.swift | 3 +- .../Advanced/NCShareAdvancePermission.swift | 32 +- .../NCShareAdvancePermissionFooter.swift | 13 +- .../NCShareAdvancePermissionFooter.xib | 6 +- iOSClient/Share/Advanced/NCShareCells.swift | 10 +- .../Advanced/NCShareNewUserAddComment.swift | 18 + .../Share/Advanced/NCShareToggleCell.swift | 13 +- iOSClient/Share/NCShare.storyboard | 59 +- iOSClient/Share/NCShare.swift | 139 +- iOSClient/Share/NCShareHeader.swift | 7 +- iOSClient/Share/NCShareLinkCell.swift | 19 +- iOSClient/Share/NCShareLinkCell.xib | 38 +- iOSClient/Share/NCShareNetworking.swift | 39 +- .../Share/NCShareNetworkingDelegate.swift | 2 + iOSClient/Share/NCSharePaging.swift | 21 +- iOSClient/Share/NCShareUserCell.swift | 34 +- iOSClient/Share/NCShareUserCell.xib | 17 +- iOSClient/Share/ShareSearchField.swift | 122 + iOSClient/Shares/NCShares.storyboard | 23 +- iOSClient/Style/CircleItemSpinner.swift | 43 + .../de.lproj/Localizable.strings | Bin 102674 -> 104588 bytes .../en.lproj/Localizable.strings | 53 +- .../es.lproj/Localizable.strings | Bin 101210 -> 103328 bytes .../fr.lproj/Localizable.strings | Bin 104334 -> 107032 bytes .../it.lproj/Localizable.strings | Bin 100672 -> 102564 bytes .../it.lproj/Localizable.stringsdict | 11 + .../nl.lproj/Localizable.strings | Bin 95902 -> 97862 bytes ...iveCollectionViewCommonSelectToolbar.swift | 186 ++ ...ctionViewCommonSelectToolbarDelegate.swift | 28 + ...ollectionViewCommonSelectToolbarView.swift | 166 ++ iOSClient/Transfers/TransfersListener.swift | 48 + .../Trash/Cell/NCTrashCellProtocol.swift | 2 +- iOSClient/Trash/Cell/NCTrashGridCell.swift | 18 +- iOSClient/Trash/Cell/NCTrashGridCell.xib | 20 +- iOSClient/Trash/Cell/NCTrashListCell.swift | 21 +- iOSClient/Trash/Cell/NCTrashListCell.xib | 73 +- iOSClient/Trash/NCTrash+CollectionView.swift | 15 +- .../Trash/NCTrash+SelectTabBarDelegate.swift | 17 +- iOSClient/Trash/NCTrash.storyboard | 25 +- iOSClient/Trash/NCTrash.swift | 120 +- iOSClient/Trash/NCTrashSelectTabBar.swift | 165 -- iOSClient/Utility/AccountButtonFactory.swift | 81 + iOSClient/Utility/NCAskAuthorization.swift | 6 +- iOSClient/Utility/NCUtility+Image.swift | 26 +- .../Utility/UIDevice+VirtualOrientation.swift | 19 + iOSClient/Viewer/NCViewer.swift | 44 +- .../NCMediaCoordinator.swift | 712 +++++ .../NCMediaCoordinatorAVKitStrategy.swift | 542 ++++ .../NCMediaCoordinatorConstants.swift | 7 + .../NCMediaCoordinatorStrategy.swift | 45 + .../NCMediaCoordinatorVLCStrategy.swift | 340 +++ .../NCViewerMedia/NCPlayer/NCPlayer.swift | 304 +- .../NCPlayer/NCPlayerToolBar.swift | 216 +- .../NCPlayer/NCPlayerToolBar.xib | 176 +- .../Viewer/NCViewerMedia/NCViewerMedia.swift | 285 +- .../NCViewerMediaPage.storyboard | 106 +- .../NCViewerMedia/NCViewerMediaPage.swift | 205 +- .../NCViewerNextcloudText.swift | 7 +- .../Viewer/NCViewerPDF/NCViewerPDF.swift | 12 +- .../Viewer/NCViewerProviderContextMenu.swift | 6 +- .../NCViewerQuickLook/NCViewerQuickLook.swift | 2 +- .../NCViewerQuickLookView.swift | 2 +- .../NCViewerRichDocument.swift | 11 +- 716 files changed, 19945 insertions(+), 6098 deletions(-) create mode 100755 Brand/Alpha/File_Provider_Extension.entitlements create mode 100755 Brand/Alpha/File_Provider_Extension.plist create mode 100644 Brand/Alpha/File_Provider_Extension_UI.entitlements create mode 100644 Brand/Alpha/File_Provider_Extension_UI.plist create mode 100644 Brand/Alpha/Notification_Service_Extension.entitlements create mode 100644 Brand/Alpha/Notification_Service_Extension.plist create mode 100755 Brand/Alpha/Share.entitlements create mode 100755 Brand/Alpha/Share.plist create mode 100644 Brand/Alpha/Widget.entitlements create mode 100644 Brand/Alpha/Widget.plist create mode 100644 Brand/Alpha/WidgetDashboardIntentHandler.entitlements create mode 100644 Brand/Alpha/WidgetDashboardIntentHandler.plist create mode 100755 Brand/Alpha/iOSClient.entitlements create mode 100755 Brand/Alpha/iOSClient.plist create mode 100755 Brand/AppStore/File_Provider_Extension.entitlements create mode 100755 Brand/AppStore/File_Provider_Extension.plist create mode 100644 Brand/AppStore/File_Provider_Extension_UI.entitlements create mode 100644 Brand/AppStore/File_Provider_Extension_UI.plist create mode 100644 Brand/AppStore/Notification_Service_Extension.entitlements create mode 100644 Brand/AppStore/Notification_Service_Extension.plist create mode 100755 Brand/AppStore/Share.entitlements create mode 100755 Brand/AppStore/Share.plist create mode 100644 Brand/AppStore/Widget.entitlements create mode 100644 Brand/AppStore/Widget.plist create mode 100644 Brand/AppStore/WidgetDashboardIntentHandler.entitlements create mode 100644 Brand/AppStore/WidgetDashboardIntentHandler.plist create mode 100755 Brand/AppStore/iOSClient.entitlements create mode 100755 Brand/AppStore/iOSClient.plist create mode 100755 Brand/Beta/File_Provider_Extension.entitlements create mode 100755 Brand/Beta/File_Provider_Extension.plist create mode 100644 Brand/Beta/File_Provider_Extension_UI.entitlements create mode 100644 Brand/Beta/File_Provider_Extension_UI.plist create mode 100644 Brand/Beta/Notification_Service_Extension.entitlements create mode 100644 Brand/Beta/Notification_Service_Extension.plist create mode 100755 Brand/Beta/Share.entitlements create mode 100755 Brand/Beta/Share.plist create mode 100644 Brand/Beta/Widget.entitlements create mode 100644 Brand/Beta/Widget.plist create mode 100644 Brand/Beta/WidgetDashboardIntentHandler.entitlements create mode 100644 Brand/Beta/WidgetDashboardIntentHandler.plist create mode 100755 Brand/Beta/iOSClient.entitlements create mode 100755 Brand/Beta/iOSClient.plist create mode 100644 Brand/NCBrand-IONOS.swift create mode 100644 File Provider Extension UI/File Provider Extension UIDebug.entitlements create mode 100644 File Provider Extension/File Provider ExtensionDebug.entitlements delete mode 100755 Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme create mode 100644 NextcloudDebug.entitlements create mode 100644 Notification Service Extension/Notification Service ExtensionDebug.entitlements create mode 100644 Share/ShareDebug.entitlements create mode 100644 Tests/NextcloudSnapshotTests/Extensions/SwiftUIView+Extensions.swift create mode 100644 Tests/NextcloudSnapshotTests/NextcloudSnapshotTests.swift create mode 100644 Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_CapalitiesView.DefaultPreviewConfiguration.heic create mode 100644 Tests/NextcloudSnapshotTests/__Snapshots__/NextcloudSnapshotTests/test_HUDView.DefaultPreviewConfiguration.heic create mode 100644 Widget/Assets.xcassets/Cloud_Checkmark.imageset/Cloud_Checkmark.svg create mode 100644 Widget/Assets.xcassets/Cloud_Checkmark.imageset/Contents.json create mode 100644 Widget/Assets.xcassets/Cloud_Xmark.imageset/Cloud_Xmark.svg create mode 100644 Widget/Assets.xcassets/Cloud_Xmark.imageset/Contents.json create mode 100644 Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/Contents.json create mode 100644 Widget/Assets.xcassets/FileUnsupported_NoPadding.imageset/file_unsupported_widget.svg create mode 100644 Widget/Assets.xcassets/Media.imageset/Contents.json create mode 100644 Widget/Assets.xcassets/Media.imageset/Media.svg rename Widget/Assets.xcassets/{AccentColor.colorset => Mic.imageset}/Contents.json (70%) create mode 100644 Widget/Assets.xcassets/Mic.imageset/Mic.svg rename Widget/Assets.xcassets/{WidgetBackground.colorset => Note.imageset}/Contents.json (70%) create mode 100644 Widget/Assets.xcassets/Note.imageset/Note.svg create mode 100644 Widget/Assets.xcassets/Scan.imageset/Contents.json create mode 100644 Widget/Assets.xcassets/Scan.imageset/Scan.svg create mode 100644 Widget/Colors.xcassets/Background.colorset/Contents.json create mode 100644 Widget/Colors.xcassets/BottomElementForeground.colorset/Contents.json create mode 100644 Widget/Colors.xcassets/Contents.json create mode 100644 Widget/Colors.xcassets/Divider.colorset/Contents.json create mode 100644 Widget/Colors.xcassets/Subtitle.colorset/Contents.json create mode 100644 Widget/Colors.xcassets/Text.colorset/Contents.json create mode 100644 Widget/Colors.xcassets/Title.colorset/Contents.json create mode 100644 Widget/WidgetCommon.swift create mode 100644 Widget/WidgetDebug.entitlements create mode 100644 WidgetDashboardIntentHandler/WidgetDashboardIntentHandlerDebug.entitlements create mode 100644 iOSClient/BurgerMenu/BurgerMenuAttachController.swift create mode 100644 iOSClient/BurgerMenu/BurgerMenuView.swift create mode 100644 iOSClient/BurgerMenu/BurgerMenuViewController.swift create mode 100644 iOSClient/BurgerMenu/BurgerMenuViewModel.swift create mode 100644 iOSClient/Colors.xcassets/AppBackground/Color.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/AppBackground/Contents.json create mode 100644 iOSClient/Colors.xcassets/AppBackground/DataProtection.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/AppBackground/Form.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/AppBackground/FormRow.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/AppBackground/Main.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/Background.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/ButtonForeground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/CommonShadow.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/NavigationBarButton.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/Overlay.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/PressedButton.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/BurgerMenu/ProgressBarBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Link/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Link/Text/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Link/Text/Disabled.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Link/Text/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Link/Text/Selected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Background/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Background/Disabled.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Background/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Background/Selected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Text/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Text/Disabled.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Text/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Primary/Text/Selected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Background/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Background/Disabled.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Background/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Background/Selected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Border/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Border/Disabled.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Border/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Text/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Text/Disabled.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Text/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Button/Secondary/Text/Selected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/Background.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/ImageTypeBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/ImageTypeText.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/Text.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/TitleBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/CameraInformation/TitleText.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Contents.json create mode 100644 iOSClient/Colors.xcassets/DataProtection/Contents.json create mode 100644 iOSClient/Colors.xcassets/DataProtection/Link.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/DataProtection/ListRow.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/DataProtection/ListRowSubtitle.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/DataProtection/ListSeparator.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/DataProtection/NavigationBarTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/DestructiveAction.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileActionsHeader/ButtonTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileActionsHeader/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileActionsHeader/GrayButtonTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeButtonBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileActionsHeader/SelectionModeHeaderBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileActionsHeader/SortButtonText.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/Background.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/FolderIcon.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/Grabber.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/Icon.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/Overlay.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/SelectedRow.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileMenu/Text.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileSelection/Contents.json create mode 100644 iOSClient/Colors.xcassets/FileSelection/list_item_deselected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/ListCell/Contents.json create mode 100644 iOSClient/Colors.xcassets/ListCell/Separator.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/ListCell/Subtitle.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/ListCell/Title.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/MediaPlayer/Contents.json create mode 100644 iOSClient/Colors.xcassets/MediaPlayer/IconTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/MediaPlayer/SliderMaxColor.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/MediaPlayer/SliderMinColor.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/MediaPlayer/SliderThumb.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/NavigationBar/Contents.json create mode 100644 iOSClient/Colors.xcassets/NavigationBar/LogoTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/QualitySlider/Contents.json create mode 100644 iOSClient/Colors.xcassets/QualitySlider/MaximumTrackColor.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/QualitySlider/ThumbColor.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/SearchBarBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/SelectToolbar/CancelTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/SelectToolbar/Contents.json create mode 100644 iOSClient/Colors.xcassets/SelectToolbar/ItemStateActive.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/SelectToolbar/ItemStateInactive.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/SelectToolbar/ItemStateSelected.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Background.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundHighlighted.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Cell/BackgroundNormal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Cell/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Cell/Subtitle.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Cell/Title.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/SearchField/Border.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/SearchField/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/SearchField/Placeholder.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/SectionTitle.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/SectionTitleBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Advanced/TableCellSeparator.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Comment/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Comment/TextFieldBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Comment/TextFieldBorder.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/CommonIconTint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Normal.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/SearchUserCell/Background/Pressed.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/SearchUserCell/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/SearchUserCell/Title.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/SearchUserCell/UserType.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Share/TabTitle.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Tabbar/ActiveItem.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Tabbar/Background.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Tabbar/Contents.json create mode 100644 iOSClient/Colors.xcassets/Tabbar/FabButton.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Tabbar/InactiveItem.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Transfers/ButtonBackground.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Transfers/Cell/Contents.json create mode 100644 iOSClient/Colors.xcassets/Transfers/Cell/Subtitle.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Transfers/Cell/Title.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/Transfers/Contents.json create mode 100644 iOSClient/Colors.xcassets/UserButton/Background.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/UserButton/Contents.json create mode 100644 iOSClient/Colors.xcassets/UserButton/Tint.colorset/Contents.json create mode 100644 iOSClient/Colors.xcassets/formSeparator.colorset/Contents.json create mode 100644 iOSClient/Components/Buttons/ButtonStyleGuide.swift create mode 100644 iOSClient/Components/Buttons/CommonButtonConstants.swift create mode 100644 iOSClient/Components/Buttons/LinkButton.swift create mode 100644 iOSClient/Components/Buttons/PrimaryButton.swift create mode 100644 iOSClient/Components/Buttons/SecondaryButton.swift create mode 100644 iOSClient/DataProtection/DataProtectionAgreementManager.swift create mode 100644 iOSClient/DataProtection/DataProtectionAgreementScreen.swift create mode 100644 iOSClient/DataProtection/DataProtectionHostingController.swift create mode 100644 iOSClient/DataProtection/DataProtectionModel.swift create mode 100644 iOSClient/DataProtection/DataProtectionSettingsScreen.swift create mode 100644 iOSClient/Extensions/UIView+GridSelection.swift create mode 100644 iOSClient/Extensions/View+Design.swift delete mode 100644 iOSClient/Favorites/NCFavoriteNavigationController.swift delete mode 100644 iOSClient/Files/NCFilesNavigationController.swift delete mode 100644 iOSClient/Images.xcassets/folder.imageset/folder.svg delete mode 100644 iOSClient/Images.xcassets/folderAutomaticUpload.imageset/folder_photo.svg delete mode 100644 iOSClient/Images.xcassets/folderEncrypted.imageset/folder_encrypted.svg delete mode 100644 iOSClient/Images.xcassets/folder_external.imageset/Contents.json delete mode 100644 iOSClient/Images.xcassets/folder_external.imageset/folder_external.svg delete mode 100644 iOSClient/Images.xcassets/folder_group.imageset/folder_group.svg delete mode 100644 iOSClient/Images.xcassets/folder_public.imageset/folder_link.svg delete mode 100644 iOSClient/Images.xcassets/folder_shared_with_me.imageset/Contents.json delete mode 100644 iOSClient/Images.xcassets/folder_shared_with_me.imageset/folder_shared_with_me.svg delete mode 100644 iOSClient/Images.xcassets/gear.imageset/gear.pdf delete mode 100644 iOSClient/Images.xcassets/gitHub.imageset/Contents.json delete mode 100644 iOSClient/Images.xcassets/gitHub.imageset/github.png delete mode 100644 iOSClient/Images.xcassets/gitHub.imageset/github@2x.png delete mode 100644 iOSClient/Images.xcassets/gitHub.imageset/github@3x.png delete mode 100644 iOSClient/Images.xcassets/lock.imageset/lock-outline.svg delete mode 100644 iOSClient/Images.xcassets/lock_open.imageset/lock-open-variant-outline.svg delete mode 100644 iOSClient/Images.xcassets/media.imageset/tabBarMedia.pdf create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/bars.imageset/bars.svg create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/chevronLeft.imageset/chevronLeft.svg create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/cloud.imageset/cloud.svg create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/deleted.imageset/deleted.svg create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/offline.imageset/offline.svg create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/recent.imageset/recent.svg create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/BurgerMenu/settings.imageset/settings.svg create mode 100644 iOSClient/IonosImages.xcassets/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileFolderCell/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileFolderCell/star.imageset/star.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/files_selection.imageset/files_selection_light.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/grid_item_selected.imageset/grid_item_selected.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/list_item_deselected.imageset/list_item_deselected.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/list_item_selected.imageset/list_item_selected.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/list_item_some_selected.imageset/list_item_some_selected.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/selection_mode_close.imageset/selection_mode_close_light.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/view_mode_grid.imageset/view_mode_grid.svg create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/FileSelection/view_mode_list.imageset/view_mode_list.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/AppIcon.png create mode 100644 iOSClient/IonosImages.xcassets/IONOSAppIcon.appiconset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOSEasyStorageLogo.imageset/IONOSEasyStorageLogo.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOSLogo.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOSLogo.imageset/logo@3x 2.png create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/allowEdit.imageset/allowEdit.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/createFolder.imageset/createFolder.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/data_protection.imageset/data_protection@3x.png create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/details.imageset/details.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/goToPage.imageset/goToPage.svg rename iOSClient/{Images.xcassets/media.imageset => IonosImages.xcassets/IONOS_icons/item.lock.imageset}/Contents.json (86%) create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.imageset/item.lock.svg rename iOSClient/{Images.xcassets/folder_group.imageset => IonosImages.xcassets/IONOS_icons/item.lock.open.imageset}/Contents.json (85%) create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/item.lock.open.imageset/item.lock.open.svg rename iOSClient/{Images.xcassets/folder.imageset => IonosImages.xcassets/IONOS_icons/media.imageset}/Contents.json (87%) create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/media.imageset/media.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/menu.add.imageset/menu.add.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/menu.search.imageset/menu.search.svg rename iOSClient/{Images.xcassets/folder_public.imageset => IonosImages.xcassets/IONOS_icons/menu.share.imageset}/Contents.json (86%) create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/menu.share.imageset/menu.share.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/modifyWithQuickLook.imageset/modifyWithQuickLook.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/moveOrCopy.imageset/moveOrCopy.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/offline.imageset/offline.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/photoOrVideo.imageset/photoOrVideo.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/qrcode.imageset/qrcode.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/readOnly.imageset/readOnly.svg rename iOSClient/{Images.xcassets/folderAutomaticUpload.imageset => IonosImages.xcassets/IONOS_icons/rename.imageset}/Contents.json (85%) create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/rename.imageset/rename.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/scan.imageset/scan.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/star.filled.imageset/star.filled.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/star.hollow.imageset/star.hollow.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/synced.imageset/synced.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/trash_icon.imageset/trash_icon.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/unshare.imageset/unshare.svg create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/IONOS_icons/viewInFolder.imageset/viewInFolder.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/CloseFullscreen.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/CloseFullscreen.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Forward.imageset/Forward.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Fullscreen.imageset/Fullscreen.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Message.imageset/Message.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Pause.imageset/Pause.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Play.imageset/Play.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Rewind.imageset/Rewind.svg create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/MediaPlayer/Sound.imageset/Sound.svg create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/copy.imageset/copy.svg create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/delete.imageset/trash-can.svg rename iOSClient/{Images.xcassets/folderEncrypted.imageset => IonosImages.xcassets/SelectTabBar/download.imageset}/Contents.json (84%) create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/download.imageset/cloud-arrow-down.svg create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/lock.imageset/unlock.svg create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/restoreFromTrash.imageset/rotate-left.svg create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/Contents.json create mode 100644 "iOSClient/IonosImages.xcassets/SelectTabBar/share.imageset/\356\202\232.svg" create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/SelectTabBar/unlock.imageset/lock.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/AutoUpload/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/400-folder.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/400-folder-open.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/AutoUpload/folder.opened.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/autoupload.folder.imageset/autoupload.folder.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/bulletlist.imageset/bulletlist.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/calendar.user.imageset/calendar.user.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/camera.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/camera.imageset/camera.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/dataprivacy.imageset/dataprivacy.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/folder.gear.imageset/folder.gear.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/gear.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/gear.imageset/gear.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/github.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/github.imageset/github.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/handshake.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/handshake.imageset/handshake.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/shield.halved.imageset/shield.halved.svg create mode 100644 iOSClient/IonosImages.xcassets/Settings/xmark.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Settings/xmark.imageset/xmark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/copy.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/copy.imageset/copy_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/downloading.imageset/downloading_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/error.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/error.imageset/error_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/favorite.imageset/favorite_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/move.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/move.imageset/move_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/rename.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/rename.imageset/rename_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/stop.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/stop.imageset/stop_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/trash.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/trash.imageset/trash_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/upload.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/upload.imageset/upload_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/waitToDownload.imageset/wait_to_download_light.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/Transfers/waiting.imageset/waiting_light.svg create mode 100644 iOSClient/IonosImages.xcassets/accountCheckmark.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/accountCheckmark.imageset/accountCheckmark.svg create mode 100644 iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/checkmarkIcon.imageset/checkmarkIcon.svg create mode 100644 iOSClient/IonosImages.xcassets/contactsIcon.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/contactsIcon.imageset/contactsIcon_light.svg create mode 100644 iOSClient/IonosImages.xcassets/delete.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/delete.imageset/delete.svg create mode 100644 iOSClient/IonosImages.xcassets/deleted.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/deleted.imageset/deleted.svg rename iOSClient/{Images.xcassets/lock.imageset => IonosImages.xcassets/favorites.imageset}/Contents.json (83%) create mode 100644 iOSClient/IonosImages.xcassets/favorites.imageset/favorites.svg create mode 100644 iOSClient/IonosImages.xcassets/file_unsupported.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/file_unsupported.imageset/file_unsupported_light.svg create mode 100644 iOSClient/IonosImages.xcassets/folder.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_dark_mode.svg create mode 100644 iOSClient/IonosImages.xcassets/folder.imageset/folder_icon_light_mode.svg create mode 100644 iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/folderAutomaticUpload.imageset/folderAutomaticUpload_light.svg create mode 100644 iOSClient/IonosImages.xcassets/folderEncrypted.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_dark_mode.svg create mode 100644 iOSClient/IonosImages.xcassets/folderEncrypted.imageset/folder_icon_light_mode.svg create mode 100644 iOSClient/IonosImages.xcassets/folder_external.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_dark_mode.svg create mode 100644 iOSClient/IonosImages.xcassets/folder_external.imageset/folder_icon_light_mode.svg create mode 100644 iOSClient/IonosImages.xcassets/folder_group.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/folder_group.imageset/folder_group_light.svg create mode 100644 iOSClient/IonosImages.xcassets/gradientBackground.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPad.svg create mode 100644 iOSClient/IonosImages.xcassets/gradientBackground.imageset/GradientBackgroundPhone.svg rename iOSClient/{Images.xcassets/gear.imageset => IonosImages.xcassets/home.imageset}/Contents.json (86%) create mode 100644 iOSClient/IonosImages.xcassets/home.imageset/home.svg rename iOSClient/{Images.xcassets/lock_open.imageset => IonosImages.xcassets/local.imageset}/Contents.json (78%) create mode 100644 iOSClient/IonosImages.xcassets/local.imageset/local.svg create mode 100644 iOSClient/IonosImages.xcassets/more.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/more.imageset/more_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/more.imageset/more_light.svg create mode 100644 iOSClient/IonosImages.xcassets/offlineFlag.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/offlineFlag.imageset/offlineFlag_light.svg create mode 100644 iOSClient/IonosImages.xcassets/restore.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/restore.imageset/restore.svg create mode 100644 iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/restoreFromDeleted.imageset/restoreFromDeleted.svg create mode 100644 iOSClient/IonosImages.xcassets/share/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/canShare.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/canShare.imageset/canShare_light.svg create mode 100644 iOSClient/IonosImages.xcassets/share/folder/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder 1@3x.png create mode 100644 iOSClient/IonosImages.xcassets/share/folder/byLink.imageset/shared_by_link_folder@3x.png create mode 100644 iOSClient/IonosImages.xcassets/share/folder/internally.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder 1@3x.png create mode 100644 iOSClient/IonosImages.xcassets/share/folder/internally.imageset/shared_internally_folder@3x.png create mode 100644 iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder 1@3x.png create mode 100644 iOSClient/IonosImages.xcassets/share/folder/withMe.imageset/shared_with_me_folder@3x.png create mode 100644 iOSClient/IonosImages.xcassets/share/icon/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon 1.svg create mode 100644 iOSClient/IonosImages.xcassets/share/icon/byLink.imageset/shared_by_link_icon.svg create mode 100644 iOSClient/IonosImages.xcassets/share/icon/internally.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon 1.svg create mode 100644 iOSClient/IonosImages.xcassets/share/icon/internally.imageset/shared_internally_icon.svg create mode 100644 iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon 1.svg create mode 100644 iOSClient/IonosImages.xcassets/share/icon/withMe.imageset/shared_with_me_icon.svg create mode 100644 iOSClient/IonosImages.xcassets/share/internalLink.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/internalLink.imageset/internalLink_light.svg create mode 100644 iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_d.svg create mode 100644 iOSClient/IonosImages.xcassets/share/linkCircleFill.imageset/lnk_l.svg create mode 100644 iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/magnifyingGlass.imageset/magnifyingGlass_light.svg create mode 100644 iOSClient/IonosImages.xcassets/share/plus.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/plus.imageset/plus_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/plus.imageset/plus_light.svg create mode 100644 iOSClient/IonosImages.xcassets/share/shared.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/shared.imageset/shared_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/shared.imageset/shared_light.svg create mode 100644 iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_drk.svg create mode 100644 iOSClient/IonosImages.xcassets/share/squareAndArrowUpCircleFill.imageset/sq_l.svg create mode 100644 iOSClient/IonosImages.xcassets/share/threeDots.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/threeDots.imageset/threeDots_lights.svg create mode 100644 iOSClient/IonosImages.xcassets/share/userContacts.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/share/userContacts.imageset/userContacts_light.svg create mode 100644 iOSClient/IonosImages.xcassets/shares.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/shares.imageset/shares.svg create mode 100644 iOSClient/IonosImages.xcassets/uploadFile.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/uploadFile.imageset/uploadFile.svg create mode 100644 iOSClient/IonosImages.xcassets/userAvatar.imageset/Contents.json create mode 100644 iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_dark.svg create mode 100644 iOSClient/IonosImages.xcassets/userAvatar.imageset/userAvatar_light.svg create mode 100644 iOSClient/Login/NCLoginNavigationController.swift create mode 100644 iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.swift create mode 100644 iOSClient/Main/Collection Common/ActionsHeader/FileActionsHeader.xib create mode 100644 iOSClient/Main/Collection Common/Cell/ItemShareState.swift create mode 100644 iOSClient/Main/Collection Common/Cell/NCCellMedia.swift create mode 100644 iOSClient/Main/Collection Common/Cell/PlaybackProgressView.swift create mode 100644 iOSClient/Main/Collection Common/NCCollectionViewCommon+FileActionsHeader.swift delete mode 100644 iOSClient/Main/Collection Common/NCCollectionViewCommonSelectTabBar.swift create mode 100644 iOSClient/Main/HiDriveMainNavigationController.swift delete mode 100644 iOSClient/Main/NCMainNavigationController.swift create mode 100644 iOSClient/Main/NCMainTabBar.swift create mode 100644 iOSClient/Main/UITabBarGuideline.swift delete mode 100644 iOSClient/Media/NCMediaNavigationController.swift delete mode 100644 iOSClient/More/NCMoreNavigationController.swift create mode 100644 iOSClient/NCImagesRepository.swift create mode 100644 iOSClient/Share/ShareSearchField.swift create mode 100644 iOSClient/Style/CircleItemSpinner.swift create mode 100644 iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbar.swift create mode 100644 iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarDelegate.swift create mode 100644 iOSClient/Toolbar/HiDriveCollectionViewCommonSelectToolbarView.swift create mode 100644 iOSClient/Transfers/TransfersListener.swift delete mode 100644 iOSClient/Trash/NCTrashSelectTabBar.swift create mode 100644 iOSClient/Utility/AccountButtonFactory.swift create mode 100644 iOSClient/Utility/UIDevice+VirtualOrientation.swift create mode 100644 iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinator.swift create mode 100644 iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorAVKitStrategy.swift create mode 100644 iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorConstants.swift create mode 100644 iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorStrategy.swift create mode 100644 iOSClient/Viewer/NCViewerMedia/NCMediaCoordinator/NCMediaCoordinatorVLCStrategy.swift 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..512abf32b0 --- /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 %@ © 2025" + 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 Hydrogen for iOS %@ © 2025" { + 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..7ed4cdf961 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,66 @@ /* 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 = ""; }; + 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 +1244,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 +1278,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 +1317,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 +1365,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 +1385,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 +1395,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 +1419,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 +1444,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 +1460,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 +1470,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 +1538,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 +1580,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 +1597,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 +1605,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 +1619,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 +1698,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 +1712,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 +1749,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 +1879,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 +1920,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 +1958,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 +1973,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 +2110,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 +2266,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 +2308,7 @@ F70716E42987F81500E72C1D /* File Provider Extension UI */ = { isa = PBXGroup; children = ( + 4216512F2E28F6DC002E19D6 /* File Provider Extension UIDebug.entitlements */, F70716E52987F81500E72C1D /* DocumentActionViewController.swift */, F722F0102CFF569500065FB5 /* MainInterface.storyboard */, ); @@ -2362,6 +2403,7 @@ AF2D7C7D2742559100ADF566 /* NCShareUserCell.swift */, AF93471727E2361E002537EE /* NCShareHeader.xib */, AF93471527E2361E002537EE /* NCShareHeader.swift */, + 42D34FD82D79A5B00020C106 /* ShareSearchField.swift */, AFCE353827E5DE0400FEA6C2 /* Shareable.swift */, AA8E03D92D2ED83300E7E89C /* TransientShare.swift */, ); @@ -2401,7 +2443,9 @@ F7346E1428B0EF5B006CE2D2 /* Widget */ = { isa = PBXGroup; children = ( + 4216512B2E28F685002E19D6 /* WidgetDebug.entitlements */, F7346E2228B0FEBA006CE2D2 /* Assets.xcassets */, + FC930DC42CEDE33000C9B237 /* Colors.xcassets */, F72EA95528B7BAD100C88F0C /* Dashboard */, F72EA95628B7BAE700C88F0C /* Files */, F76DEE9A28F808BC0041B1C9 /* Lockscreen */, @@ -2409,6 +2453,7 @@ F75DD764290AB369002EB562 /* Intent */, F7346E2028B0FA3A006CE2D2 /* Widget-Brinding-header.h */, F7346E1528B0EF5C006CE2D2 /* Widget.swift */, + FC930DC62CEE377700C9B237 /* WidgetCommon.swift */, ); path = Widget; sourceTree = ""; @@ -2488,7 +2533,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 +2544,8 @@ F75D901E2D2BE12E003E740B /* NCRecommendationsCell.xib */, F75D90202D2BE26C003E740B /* NCRecommendationsCell.swift */, F36C514D2E89393C0097E5F7 /* UIView+BlurVibrancy.swift */, + 428915302F226C1500B41486 /* PlaybackProgressView.swift */, + 421DC45E2F6D38F3001EE5E3 /* ItemShareState.swift */, ); path = Cell; sourceTree = ""; @@ -2505,8 +2553,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 +2570,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 +2736,7 @@ F771E3D120E2392D00AFB62D /* File Provider Extension */ = { isa = PBXGroup; children = ( + 4216512E2E28F6D3002E19D6 /* File Provider ExtensionDebug.entitlements */, F76340EB2EBDE7420056F538 /* NCManageDatabase.swift */, F771E3F220E239A600AFB62D /* FileProviderData.swift */, F76673EC22C901F5007ED366 /* FileProviderDomain.swift */, @@ -2706,7 +2756,6 @@ F7725A5F251F33BB00D125E0 /* NCFiles.storyboard */, F7725A5E251F33BB00D125E0 /* NCFiles.swift */, F73EFF9A2DB11EB900FD434C /* NCFiles+UIScrollViewDelegate.swift */, - F722133A2D40EF8C002F7438 /* NCFilesNavigationController.swift */, ); path = Files; sourceTree = ""; @@ -2757,7 +2806,6 @@ AF3FDCC12796ECC300710F60 /* NCTrash+CollectionView.swift */, F7E402322BA89551007E5609 /* NCTrash+Networking.swift */, F7E402302BA891EB007E5609 /* NCTrash+SelectTabBarDelegate.swift */, - F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */, ); path = Trash; sourceTree = ""; @@ -2765,11 +2813,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 +2898,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 +2911,6 @@ children = ( F717402B24F699A5000C87D5 /* NCFavorite.storyboard */, F717402C24F699A5000C87D5 /* NCFavorite.swift */, - F7A03E2E2D425A14007AA677 /* NCFavoriteNavigationController.swift */, ); path = Favorites; sourceTree = ""; @@ -2938,6 +2988,7 @@ children = ( F702F2F025EE5CDA008F8E80 /* NCLogin.storyboard */, F702F2F625EE5CEC008F8E80 /* NCLogin.swift */, + 0F4AA77E2DE0A3F700138679 /* NCLoginNavigationController.swift */, F745B252222D88AE00346520 /* NCLoginQRCode.swift */, F7AE00F4230D5F9E007ACF8A /* NCLoginProvider.swift */, F7BC287D26663F6C004D46C5 /* NCViewCertificateDetails.storyboard */, @@ -2949,6 +3000,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 +3035,7 @@ F7C0F46D1C8880540059EC54 /* Share */ = { isa = PBXGroup; children = ( + 4216512D2E28F6BB002E19D6 /* ShareDebug.entitlements */, F714803A262EBE3900693E51 /* MainInterface.storyboard */, F7148040262EBE4000693E51 /* NCShareExtension.swift */, F7A573682E190377009C9257 /* NCShareExtensionData.swift */, @@ -3002,6 +3056,7 @@ F7362A1E220C853A005101B5 /* LaunchScreen.storyboard */, F78E2D6429AF02DB0024D4F3 /* Database.swift */, F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */, + 0F9DB9B92DD2381B00E31A24 /* NCBrand-IONOS.swift */, ); path = Brand; sourceTree = ""; @@ -3027,6 +3082,7 @@ F7C9739328F17131002C43E2 /* WidgetDashboardIntentHandler */ = { isa = PBXGroup; children = ( + 4216512C2E28F6A4002E19D6 /* WidgetDashboardIntentHandlerDebug.entitlements */, F7C9739428F17131002C43E2 /* IntentHandler.swift */, ); path = WidgetDashboardIntentHandler; @@ -3049,7 +3105,6 @@ F3BB46502A39EC2D00461F6E /* Cells */, F7CB68992541676B0050EC94 /* NCMore.storyboard */, F73F537E1E929C8500F8678D /* NCMore.swift */, - F7A03E322D426115007AA677 /* NCMoreNavigationController.swift */, ); path = More; sourceTree = ""; @@ -3160,6 +3215,7 @@ F7E9C41320F4CA870040CF18 /* Transfers */ = { isa = PBXGroup; children = ( + D59D37CF2F0EE97C0072C824 /* TransfersListener.swift */, F78026112E9CFA6000B63436 /* NCTransfersModel.swift */, F780260F2E9CF9DE00B63436 /* NCTransfersView.swift */, ); @@ -3181,11 +3237,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 +3296,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 +3320,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 +3439,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 +3670,7 @@ F77B0F981D118A16002130FE /* Embed Foundation Extensions */, AFBFD01327551A54002244BC /* ShellScript */, F76DA934277B75710082465B /* Embed Frameworks */, + D5FE6AC22C88A5AC0071802E /* Run Script Firebase dSYM upload */, ); buildRules = ( ); @@ -3652,6 +3708,7 @@ F33EE6E02BF4BDA500CA1A51 /* NIOSSL */, F33EE6EF2BF4C0FF00CA1A51 /* NIO */, F7D4BF532CA2ED9D00A5E746 /* VLCKitSPM */, + 625EC26D2C6CA285006411D1 /* FirebaseAnalytics */, F3374AEF2D78B01B002A38F9 /* BitCollections */, F3374AF12D78B01B002A38F9 /* Collections */, F3374AF32D78B01B002A38F9 /* DequeModule */, @@ -3698,12 +3755,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 +3793,9 @@ F771E3CF20E2392D00AFB62D = { CreatedOnToolsVersion = 9.4.1; LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; }; F77B0DEB1D118A16002130FE = { LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Push = { enabled = 1; @@ -3765,52 +3819,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 +3876,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62A63F302C8AF7730048653E /* Colors.xcassets in Resources */, F7E4022F2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, F746EC53273906C50052598D /* NCViewCertificateDetails.storyboard in Resources */, ); @@ -3898,6 +3910,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 +3920,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 +3944,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 +3960,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0F9E787D2DD77EB8007980BF /* Colors.xcassets in Resources */, F7E4022D2BA85D1D007E5609 /* PrivacyInfo.xcprivacy in Resources */, F746EC52273906C40052598D /* NCViewCertificateDetails.storyboard in Resources */, ); @@ -3969,6 +3989,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 +4003,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 +4025,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 +4041,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 +4057,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 +4084,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 +4135,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 +4208,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 +4225,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 +4233,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 +4244,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 +4269,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 +4277,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 +4327,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 +4346,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 +4374,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 +4385,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 +4409,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 +4454,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 +4486,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 +4502,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 +4511,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 +4546,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 +4562,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 +4594,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 +4607,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 +4639,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 +4647,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 +4657,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 +4665,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 +4676,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 +4703,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 +4712,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 +4726,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 +4741,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 +4758,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 +4769,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 +4794,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 +4809,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 +4831,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 +4842,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 +4864,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 +4914,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 +4987,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 +5000,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 +5015,10 @@ 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 */, ); name = Intent.intentdefinition; sourceTree = ""; @@ -5068,52 +5029,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 +5040,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 = 19; + 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 = 1.1.0; + 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 +5183,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 = 19; + 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 = 1.1.0; + 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 = 19; + 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 = 1.1.0; + 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 +6267,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 +6443,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 +6480,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 +6491,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 +6503,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 +6525,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 +6546,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 +6555,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 +6574,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 +6601,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 +6630,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 +6640,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 +6654,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 +6668,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 +6677,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 +6690,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 +6699,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 +6725,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 +6749,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 +6774,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 +6804,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 +6817,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 +6847,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 +6860,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 +6904,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 = 19; 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 +6933,9 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 33.0.2; + MARKETING_VERSION = 1.1.0; 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 +6970,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 = 19; + DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_TESTING_SEARCH_PATHS = YES; @@ -5844,10 +6996,9 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 33.0.2; + MARKETING_VERSION = 1.1.0; 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 +7014,10 @@ isa = XCConfigurationList; buildConfigurations = ( 2C33C48723E2C475005F963B /* Debug */, + 0F8968772DD349B700810B87 /* Alpha */, 2C33C48823E2C475005F963B /* Release */, + D5C2D2192C9AC00B00E7579D /* Beta */, + D5C6179D2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5872,7 +7026,10 @@ isa = XCConfigurationList; buildConfigurations = ( AF8ED1FF2757821000B8DBC4 /* Debug */, + 0F8968782DD349B700810B87 /* Alpha */, AF8ED2002757821000B8DBC4 /* Release */, + D5C2D21A2C9AC00B00E7579D /* Beta */, + D5C6179E2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5881,7 +7038,10 @@ isa = XCConfigurationList; buildConfigurations = ( C0046CE22A17B98400D87C9D /* Debug */, + 0F89687A2DD349B700810B87 /* Alpha */, C0046CE32A17B98400D87C9D /* Release */, + D5C2D21C2C9AC00B00E7579D /* Beta */, + D5C617A02CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5890,7 +7050,10 @@ isa = XCConfigurationList; buildConfigurations = ( C04E2F272A17BB4E001BAD85 /* Debug */, + 0F8968792DD349B700810B87 /* Alpha */, C04E2F282A17BB4E001BAD85 /* Release */, + D5C2D21B2C9AC00B00E7579D /* Beta */, + D5C6179F2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5899,7 +7062,10 @@ isa = XCConfigurationList; buildConfigurations = ( F70716EE2987F81600E72C1D /* Debug */, + 0F8968762DD349B700810B87 /* Alpha */, F70716EF2987F81600E72C1D /* Release */, + D5C2D2182C9AC00B00E7579D /* Beta */, + D5C6179C2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5908,7 +7074,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7145A261D12E3B700CAFEEC /* Debug */, + 0F8968742DD349B700810B87 /* Alpha */, F7145A271D12E3B700CAFEEC /* Release */, + D5C2D2162C9AC00B00E7579D /* Beta */, + D5C6179A2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5917,7 +7086,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7346E1D28B0EF5E006CE2D2 /* Debug */, + 0F8968722DD349B700810B87 /* Alpha */, F7346E1E28B0EF5E006CE2D2 /* Release */, + D5C2D2142C9AC00B00E7579D /* Beta */, + D5C617982CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5926,7 +7098,10 @@ isa = XCConfigurationList; buildConfigurations = ( F771E3F020E2392E00AFB62D /* Debug */, + 0F8968752DD349B700810B87 /* Alpha */, F771E3F120E2392E00AFB62D /* Release */, + D5C2D2172C9AC00B00E7579D /* Beta */, + D5C6179B2CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5935,7 +7110,10 @@ isa = XCConfigurationList; buildConfigurations = ( F77B0F9B1D118A16002130FE /* Debug */, + 0F8968712DD349B700810B87 /* Alpha */, F77B0F9C1D118A16002130FE /* Release */, + D5C2D2132C9AC00B00E7579D /* Beta */, + D5C617972CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5944,7 +7122,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7C9739B28F17132002C43E2 /* Debug */, + 0F8968732DD349B700810B87 /* Alpha */, F7C9739C28F17132002C43E2 /* Release */, + D5C2D2152C9AC00B00E7579D /* Beta */, + D5C617992CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -5953,7 +7134,10 @@ isa = XCConfigurationList; buildConfigurations = ( F7F67BC91A24D27800EE80DA /* Debug */, + 0F8968702DD349B700810B87 /* Alpha */, F7F67BCA1A24D27800EE80DA /* Release */, + D5C2D2122C9AC00B00E7579D /* Beta */, + D5C617962CABE20500105DC6 /* AppStore */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -6014,7 +7198,7 @@ repositoryURL = "https://github.com/realm/realm-swift"; requirement = { kind = exactVersion; - version = 10.54.6; + version = 20.0.3; }; }; F72DA9B225F53E4E00B87DB1 /* XCRemoteSwiftPackageReference "SwiftRichString" */ = { @@ -6174,12 +7358,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 0000000000000000000000000000000000000000..7b099a3dfe0dbccdbbfa1e6875ad6c3aa692cb10 GIT binary patch literal 32097 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 YBiY|R^Vj~(*?tgEjDOhpKVs~E1Ezi}z5oCK literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d0c5ba1c50f84af8e316c03952385d7aa3ae2790 GIT binary patch literal 18202 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 FUjQK_yB+`l literal 0 HcmV?d00001 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 7182936e451bb91c1289e67408b2103a37cbcca3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58844 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 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 2d1b03610da5da783907592b8a14781e8c5d992d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 922 zcmV;L17-Y)P))*a|DSX2xdSOMK0coDecw&00GS&y40Wt%MTn3qQoaj)!UOzujU}|dWwkR?m0ec4!C-IZD zdSGs@cCxQPu~@!amCt}|O7bq2fO~?Vdc5l}-9tWK9#Q2;hdct_0=^r>s48EpYS=Ni z1Fcf2w5uE6*a+99rb;((EC{N3Ks>MVxQISzt$b??=dHB{WS0oHsPbN;G1CI@yz>3P z4Zz+ga$g5>&>2ywG<}z~_9*|1?9(8q?!WTMfajIJ0rquF3)~R|)#GNpP0i7JAJ?QI z?_hiEY((^FSib{N)raGmsby1tRmAH4ZW z$vyAjog(VTeIm>^o6X1tP~}|__5;6*NJ~|pavb@xSS%loBK>g3j^Xcp-?wpsd_KR; zajw1{N zPAn|6TN?sl7_O?CNkBnfvQ{su@&xb|a4d>=J1JnTyx(VHkufsaS=-*O(@Y`0S`^bSmi=k>c#^Ot4`m6AFd$3nIJ-{04jiM2=%$sn_cZ0|X*f zsWcihZ^rZDYXv}~QGFTofGQ3!2^6f&Z0py_I`l^o?n{#Ys{lX{)IQE;-CI>i_@% 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 335c30993129836eef928397c6d6443f5a76e2a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1834 zcmV+_2i5qAP)bK%+!ekO(C~Ra>IwhDxO% zQA7noQDY(0ik7O~;(Et>@g)I-m=t~x)%K)28w;#bH3$I>Qj3ZLBG6ERfHV$@z~o1& z5>&M)KWZ$wwG(f$Gao;^yItG6Gh=(*suJ(7bI$jk@4T;O&Y5%0zy}<%T!}5qT5X!< zs_E&N*V4jNe}Dhfa*R_K1Ic91ZJww53`0My%64EY&^U)S1-vT4MODtkV)~NfIG2|? z_M#1Rc6PRjG(Re$4+7g3lS5Ts5s~Bh{N(ZB;o+-`$+2JqsZ?rhpE z-cpsp$;sBE&pvBUFQnsw3|Ln8{h$NDO$(A29j}3Qx~_97YKKS$(&_YyLP4^?Ba4<6 z9SXQ@ZL522+rAz~4mFTWCU5e6^Vh(RdZ>#IJq?BZuIs)X#0oT!Nc3$Ix$!c{$Lgvr zI!5yOhR+TUADO5{Flq(j@q=r?JNZ6}2iV!vRQOF#PtU4agsKK?+cuh-ZagQVcPyW_ zsL;LnygyVcTGhb#_}d48&s7OcnWn!9*dfAU;I%p^ydXli@9V9qdRq<7S1l{^aJ9g^ zInddexy3N}2hdc7|Dx*-eyLQkZ96tLHW3#wo&aqtHeXleO%dJ!xe6Ks)`6_6-~hZX zqJ7z{bE0wp%gS5=ZmBZ%glYQQj~+dGrLr+Lmt`1aYlsKrmCBlJ+XY~#qvO!eVzKLA z6p@ST*SC(=TK+mZ4y`lI!tEluITrJucO2*1yb*-+s#OiF@jT;6;DK5E%8F%W_5gpa zE*@01GnaE}zK`{QWo3qeM{9(A5##o3w*Q}{hPiX#8^P&~dTkv7AZvmIsCs>~8cK!7 zAMf1=+#8tsJz16X*5J4tm|5ayP&Qx~{#U3nCuXHq8CjybDEMPYd_{9}p}kZo8xYZZ zLOPzx&C_=w?O$7(rW8&86upim$)bx8XB4eE(CEz z_yiOUh_E?`tjd+3_;Nsm{{+W%Grao*0@rsD@#-ZkDpUzP%=kWQp=`it2qKHHpC7`8w7Y4?SczgKQ1r_&#G$p2Rv9 zl5<-smHJ41ePdWiZQo_X#vM8W)+l4X91`Te+p+QSi36%K0Bj2HA(vctU^~S*JNHO=5cqzXD*Dv)^i*$i zbIaYTqzPQ`KN)& zvOE>5scBVLHamFQ^QLzKXXj}74DbWP;F4u!CM~P`K-lPsM7qQG&DT}sm#UInn0Wbb zKHqS>vSrr0JTfwJZP%_(O^cN8gaqWC-Mjbr$BwzbyYtSyrwoG!ffaL8tLlYZZm>H{ z!nt#2&+p#7XFte-Z@5JyIW+X-tV@S^7h4-Pw7SgO%F1_AsnqtNp}{vmzYM%nCHYSY z`IZ!+s`C6ogctFb_3K-oncFzefNk3aRgE+IKw{XOCV1e zhWA`lB_a}azLYR2VmxNswm&adtsaR)<^d6YT)`=*>W+G>JY8LxdsR6Z&IG^%-S4{2 zuc`%W-cILogFgZJZbef}L|*Lb>V2VOt{bweok7GW;Dh$Lt}_rss`&(pP}d#kQ`JX+8^yMjs*(md1BEwC)4SsP z{#lWRol(R`#I%UsA0{5c4FHhKIX?pZ0_dAd*A|Mui^yHstn>3IXK|?#Q*>R07*qoM6N<$f&!OtumAu6 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 487bc8bada38ec0c7311c5817cb413b71068ddd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2729 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 - - - \ 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 515ca27a1096b641dd40b122d123fb412b158f1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58260 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 + + 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 0000000000000000000000000000000000000000..32154cc06f2555920105e8d8a1fee46a47153865 GIT binary patch literal 10876 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000000000000000000000000000000000000..1893643244a16af741f493d7449c34d36b2751a7 GIT binary patch literal 79628 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%0DM$ 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 DY&pFY literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8da858658748c4b59e848746c2067c2f53ec823d GIT binary patch literal 24699 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8701bb2aaad4d935e33018d80f8a5c7f8d6ae26e GIT binary patch literal 19352 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..aa33bb469cf1aace4973b0e68e2606db012f4b21 GIT binary patch literal 19790 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 it-Y=fzmvVzf2e=on|h^?? literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..cd868857b8e2cf598f40ab640c59d88b82ddab63 GIT binary patch literal 19141 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 LS3j3^P6vb!@PE}m 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 ZlsGIhvfN`U1b^sv{i>mE!IgV|{V&J9$pZiY literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c1ffd21f46ba77f7d712076ac30e42b0bf2d4ef9 GIT binary patch literal 14769 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 literal 0 HcmV?d00001 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..Y0TiOi<{d~jG`k5eHQ@9Q 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 HUYqhCo(A}; delta 3410 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 AMgRZ+ delta 3264 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 delta 3506 zcmai1ZETZO6u#GO?I>L-ZqRjQ>|HlL-Ud z^*a9avW7i;4rh6lW~~d_C)~bSG_T!L`5hmPi!_VH*gzlu#rY{CuJXz_m7EO(E%A^T z;`NwFvc#b15E0&6&5DNa2n?IkM!t^?SgdQ1T}rX+fY!5&*LLfZu#(hnCD^6z3CrU- z3GAo%RKNZZx%YO)>(AHpxyQ?g2(T#;W^7hTbo)X4L=1ko|4>%EDMH`wwrT zdy5x@p6#90qeguV{`vydG7Y-LLg9g4W< z)Wc!=ywRc^Tgqs(wZVR*X`h^Vp6wzzi1_loyGr0iFKg3;px)JsLT05`>s_OFyZKBv z?Ad2l|Kz5zrG7fN!J>=nU!zynub@*KM(js7u5i=-HZNUjTu7-N*O66)wEdiy<~Nnm zTMt*zF|Us{Z^=-f?PGuD(@2fa{;;)J(t}$*w{K~ykOlSPR%+S0QvW`^HDqtvx>>5` zXQYeHy%V7)wieUq=|X#a+nV4*{kf=zG@2RxjRc_xhBP)^8Z*cNRqXBN2#^}HHl*W8 z^7>B3p=np?su*LKPab=s2vs3 z$3B9!$cd9bXzb*7bOKWl`5DZxUf7PZ42rCepFuX{Wk5tI`g(|xC+8pODYJil+Fv~T zA569@pG(i8cYgKDUTQg5ua-5-Vmf#7PHH~bK$p&Y?Ym#y-$ln?^Qb>cWGz_G*!XI>89hFY&pxb`SucFMxq|QBf z0uPN-lWc`ucwzEp7z=gz-2`Dc$bfT(*=S5K3xx9BTc90E+|G--#Pw^6-_W3uR+C_p zScjr{-e=!fDbJJ)H?iX|HpHi#LUG0$ph4uAPsX*WE~B|2B%?pWo|yJy3JxWl;@yd~ zX)T~tgvql?ctki`aKC(aW_Gkit|%OC)k!vq8q$$CRsko{W?JT;h8QWufCa@I*v)=E zsHR0n*mARu#c90xMGY%lyoFGe{cVd3O;e@Wo7!bdA$|3VPnE~yG8%i;GZW-V^C6z& z>aNYQN_}*Typeu69i|hXx@g3XsOHT)maZJ&nmN5t`MbEV8;f1)P&s#;v30V-?7wi) zPd}fo)rZC}`m0T+aYl1zjp_y7R(6qy(BIgL|k2s%jGJyMEcbDA~{br zN?E3?Mcgdr-t1S8CgkH)6M*xXgoX?poPdw|msXS2;-$v7=N9RGiZ+x6jXh2ip90Ld z6=`mh^em!AzbBB-c8p$hPNqZl%Y>X=(zceL4ZU)8t7EC=NZMErSdESW&Rb#~e^BE| z-E|xSp@Lx3P!g4}SKLGLx1b7VXXl-4=fuAmtf4O302qXlD(4X{RZ2y}~` zdN4F`XyD&Q-s#~Tb7M1S&3Hm8!1ulE3(6fM2n{7JmWx=iHWd>+^j=k|+w}5`s&AHc zX12au*oN@~B+yiyYCx2zMKBcXhFxO~Z5E@UhgTqFMu4ee$fAmYUPSHckbw{!#StvQ zNV`_1L!}GX0?b-ZjWYwM%367{mp`6Ei^s~< zfPM@Xt9fbZpMg8ICZU!nMe1-B9^eRbV6vI&Y3>6K)KdXQlCN(v4la{-1LMwczAG)<=QWh#r?8IGyx|8JkBYH&vGB!Q;* oR>2`ogA)b>)t#M_eRj9J;*(+Z*HO7VyX2_6tst9xQJ%WtZ-62lw*UYD diff --git a/iOSClient/Supporting Files/it.lproj/Localizable.strings b/iOSClient/Supporting Files/it.lproj/Localizable.strings index 048810312659e07f85c83b5555b2b08d61a22ad9..429a58751ec2677715195b7e47e100428b9013ce 100644 GIT binary patch delta 4705 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 G1^)##EGA0; delta 2530 zcmZ`*eQZ-z6u)O{yHX!**R5U4I`)RFZU`Gg5Hi4x5Mdxl-3CM;+a9!ZHLNY|Hqj6$ z2pU8N;Y4mEs6&ZgAfipI5*ZVXAQ}Y!F;OyyA;#bbhNuAr;yJIYETVboySMkA`#WF1 zbM8B^-_*a`bfhP*xKn5%CR#ei8wt$p^~&pE2~I4 zLi1`}K16#O{SSyRZp>@Kc%B35@Z5TjY$*XVCeMt>)!AYV&AJG=N~k!`wKG>0e%$_!~#h~iGwiQUufsb9U8GCVupB#*ejfM*}_qW?!To|@^#K7XN%tOFBX@>iwC z-**bIf1%kJ;-KQSx=qF^a=1!rHYiT*sc$smdnRk@>itJ8_(GFH06y$(bjgdg;Eugr8P|#1hW3N)mDL7>ydqXu1ra&}f}GP=z0E zElzFN`cq#1ZHY*2+VQOwS8ns-dDVhF`{twiq!$=9F7?r*XU%pqgT!6o}`P%GEiU^HHw?B(U$FiS6of<;^!0aCMup1TMpMvtn8u7d)b z&;!WeTsk}^r~ufkIC;ro%#>+_yndX18Xm84%Ck05p(=gZ21QVGd5lWc#g1_`vv`bV z*U}~Vu-GkstAL5Jw-OX0$3)yQzg(WFgof$`x-Bb7kmJc(7@b=ICzYW($fD>_5f9=w z+FaQ;4lG7hl#2l26s5l#2RD`7mkn4r%AUukxM`HlaLNS_!)W>4RPYwCw~WP<81g;c zIt|v^aPOe6ocE$)CG7=uUzu{Z;?zY}MMWInp5iIt#u1_ath`<);Vg1>6-l#Bc%T6L zo_D2xX@KN^@GQO64-;~@mEnr-E%Iz5v}64#1F8pI*fYnHZfSxUfNvbN%E`?zUZ;<| z-UQwppDG8Z!>BzK#DaU9LB&Cz=^sv5@bDpvOg;c+xw#qK_{f>edEC|N#^eP%o`2P0 zkW*0`)`hH^&1hSP3ozlU(w(^*i{*bL!Z96V@{`@CS0e=dOvOg?A90nX_q6qsW&L(rg+#$a1C>b2UM4F7+_w zgE_L(nr#!@<2rN_2MOp_Ah|cT5?nij$(kTkV$4bHRRdEI zH<|418qq!0(eN0SmvFgrX+=p(R!6q*SK+yn9@#es6uEaXC?(ve5_;g7Kta+s%vFSl z6MqSt(65=DT&Aoull~zod~0qIZa82vvV#fKEKck>>Bc$jKH25~3#wzyc>bhBsE6eFJA_fG&F@iai2@*>baGJR2D#mASc;zS! zTz3vX#@CTXx#Le94p4&rk;}4fJvDJ<0*tXSV{Yw)aNCVi9cIFCm|?M`oN#pi6>m9f zJrv=J->sFyMKiZYHf4Hf^%QYpHQauqSiaN)j&x55+&ML?$uw?K{5{3A?4}_uCwkH9G^dCFmaL(UccBsz) diff --git a/iOSClient/Supporting Files/it.lproj/Localizable.stringsdict b/iOSClient/Supporting Files/it.lproj/Localizable.stringsdict index 7097c7c1b8..e2c1c8b9b6 100644 --- a/iOSClient/Supporting Files/it.lproj/Localizable.stringsdict +++ b/iOSClient/Supporting Files/it.lproj/Localizable.stringsdict @@ -6,6 +6,17 @@ 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 1c8045538b17f54d7df3fbe9a78b79cc7626f04d..984021d6b175ac4af8f3c82b9e0106a38a98f7da 100644 GIT binary patch delta 5399 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 MLRjuD=;D(90uv8~Bme*a delta 2851 zcmaJ@du&r>6u%$qx~<%G-J|PXZg=nCpxYD>$8%Ybi9!b(kdVmMm2Gqz+gLmHAc3Kv zLKK06ergP0VrBx03tcFQLx>vv$0!&~5KWN8zYyaH31ULf^ZV|)XJVG!``z=M_xYW3 z`pu*0lYd4JACIBYv{)*OvBvMz{91=rukF;lS|1%7&ZWmUttCONQ!|)`JHL7lXiZEh zRaEAjq)JbfNDrNkIcKK}mmK?iEZM<-O`1;&@^d>&nA*HdHTbrd-&I;WpL*17fVsN0 z-RkLPjyi1zYY*_reD*LuGzBK~K@;@iCcw`w{_A8N%+<;l^VJp98XQ!RpZ&^MH=j)N z1~Wr>n`RnBuu#*&bT4awr0Mi}KKJq2H{md}Lw6I2eaYk&8F8g5K`bjzd4-F9Ppv>E zoIT8j{I#%v89Vz+31d#Vy<9l_omw+r%+?Q&o>Sq#haJk704r$bQ;;J;43M0RX}gNj z%e3Bc?jXm3GPJPQ{q)vJr^k%X!-)vki=koOWqI){=?!=KwDe0GlM zCJlK;=tqq`Ex_IwxJX{vsb6hdyDAw&kh>9Y{~3l7XkbZW=3FW zBEXA-pbzgC#)AUHqoLe%?SstFm3^PYB+f41E3bWPr;US22|!E>r`#I}exXRFqwiGk zWfAFNJ>-zp4fLzcMkgK?(C~mxWqGy)6bX=SVd;RjGPLgRU4k0=tu7yvyOoR6SmeK{ zq9j!Ck3+AlW@pU?GbaU{MSlal06S)cS9Nrx|4|`iD9DnG7}^lbl(uMLrxQM0I3@1lTBM0*nHHT`Gg1;>*XuaHn&2OAlqru|lEC;Uyw1{BpF=#oWL0 z4DCgh=7|x0+bYssT=+71_6gz7U#)yb`@lR(1ozB&*2{0kntUN!_-XKdQuvE(k)+da z7i{@}liAmi`GZM=9z^)?k?Wk0ESluCCxtUwvC=Ve(#W=y@U{}sWv45fGUmY!dI>${ zf;Hdwe`cW$K0!6p2qxLOy9ap@Ipc4;gZ zRvNqEm}H=oFCFr@T@*lzsFU7mkt~~6i!5P;_pcW5QFQnxoBVnWn{P;urLl4gZTulg z&Z!n}|BwP=ZL<^;~JM=BHhHI(2GMyYYOD#qUc8iHkU@4csws1Mjy@Ymwh3EMn z;BROAO(Fn5fuxBA%dFg(aWXmcdFU^M}b*uP)h~d~=~FrG`IjmEFoBz>dux=^3;n=0DKvRl{bo zExMS}&3>7U>!W*@UGj{V8+7X$p=ZKNG&2eat@TP;#YwjtU4T^aMy6v?Vx`XHH>U9C z9B|S$x0N1TPNMfW7tm3+9cS5BD)cz0>_tRyfbKT(*4V1&_o#_tPRA~#ylqMju*JLR z*7aO6oY}c`_+l+)Ak)KjbMD;oY^}(NR`ZmBTS!+wij|MJu)H?R!CA$rMmE8hjOt?f zce7LD`6TaCIVDx9I@8xjB;PZ#%&VkSj?{|Om!>KMlJVOJKNY8zB*2tB_I^44=kX6a zfMB|rh~!K&r|y?4Go4e-%*128O5gNa{=d1I8fI0O<6A&==aRxHTg1b7I(#T2T-GCg MoD=?jkLa88AJNLOy#N3J 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) } From a0ffd71af2ce09392104de8c08e8ce8198efd978 Mon Sep 17 00:00:00 2001 From: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> Date: Fri, 15 May 2026 14:04:23 +0300 Subject: [PATCH 2/4] fixed bugs Signed-off-by: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> --- Brand/NCBrand-IONOS.swift | 4 ++-- iOSClient/Networking/NCNetworking+TransferDelegate.swift | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Brand/NCBrand-IONOS.swift b/Brand/NCBrand-IONOS.swift index 512abf32b0..f05e71ef5d 100644 --- a/Brand/NCBrand-IONOS.swift +++ b/Brand/NCBrand-IONOS.swift @@ -12,7 +12,7 @@ import UIKit class NCBrandOptionsIONOS: NCBrandOptions, @unchecked Sendable { private let custom_brand = "IONOS HiDrive Next" - private let custom_textCopyrightNextcloudiOS = "HiDrive Next iOS %@ © 2025" + 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" @@ -33,7 +33,7 @@ class NCBrandOptionsIONOS: NCBrandOptions, @unchecked Sendable { override var textCopyrightNextcloudiOS: String { get { - if super.textCopyrightNextcloudiOS == "Nextcloud Hydrogen for iOS %@ © 2025" { + if super.textCopyrightNextcloudiOS == "Nextcloud Matheria for iOS %@ © 2026" { return custom_textCopyrightNextcloudiOS } return super.textCopyrightNextcloudiOS diff --git a/iOSClient/Networking/NCNetworking+TransferDelegate.swift b/iOSClient/Networking/NCNetworking+TransferDelegate.swift index 5234e8fc6c..ea1fc9962f 100644 --- a/iOSClient/Networking/NCNetworking+TransferDelegate.swift +++ b/iOSClient/Networking/NCNetworking+TransferDelegate.swift @@ -180,7 +180,7 @@ extension NCNetworking: NCTransferDelegate { let viewController = navigationController.presentedViewController as? NCScan viewController?.serverUrl = controller.currentServerUrl() viewController?.controller = controller - controller.present(navigationController, animated: true, completion: nil) + controller.currentViewController()?.present(navigationController, animated: true, completion: nil) } case NCGlobal.shared.selectorOpenDetail: @@ -310,6 +310,10 @@ extension NCNetworking: NCTransferDelegate { let session = NCSession.shared.getSession(controller: controller) var serverUrlPush = self.utilityFileSystem.getHomeServer(session: session) + if let presentedViewController = controller.presentedViewController { + presentedViewController.dismiss(animated: false) + } + navigationController.popToRootViewController(animated: false) controller.selectedIndex = 0 if serverUrlPush == serverUrl, From 0599e375662ec0b285d8f0b2590e44790bf18c1c Mon Sep 17 00:00:00 2001 From: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> Date: Fri, 15 May 2026 15:19:54 +0300 Subject: [PATCH 3/4] updated marketing version and build number Signed-off-by: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> --- Nextcloud.xcodeproj/project.pbxproj | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 7ed4cdf961..76af8e9dd1 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -5069,7 +5069,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19; + CURRENT_PROJECT_VERSION = 20; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -5096,7 +5096,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC DEBUG"; @@ -5750,7 +5750,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19; + CURRENT_PROJECT_VERSION = 20; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -5774,7 +5774,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "-D BETA"; SDKROOT = iphoneos; @@ -6151,7 +6151,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19; + CURRENT_PROJECT_VERSION = 20; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -6175,7 +6175,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "-D APPSTORE"; SDKROOT = iphoneos; @@ -6906,7 +6906,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19; + CURRENT_PROJECT_VERSION = 20; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -6933,7 +6933,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC DEBUG"; @@ -6972,7 +6972,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19; + CURRENT_PROJECT_VERSION = 20; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -6996,7 +6996,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 30.0.2; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) NC"; From 6c1f1738b5d1840ac4e4b78644aa17278b34900d Mon Sep 17 00:00:00 2001 From: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> Date: Mon, 18 May 2026 09:13:31 +0300 Subject: [PATCH 4/4] fixed Italian localization for Siri intent Signed-off-by: Serhii Kaliberda <169338670+s-kaliberda@users.noreply.github.com> --- Nextcloud.xcodeproj/project.pbxproj | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 76af8e9dd1..594d8e7080 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -1199,6 +1199,7 @@ 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 = ""; }; @@ -5019,6 +5020,7 @@ F7BE7C51290ADF0B002ABB61 /* es */, F7BE7C63290ADF10002ABB61 /* fr */, F7BE7C69290ADF11002ABB61 /* de */, + 42226BFC2FB76B7E0018A519 /* it */, ); name = Intent.intentdefinition; sourceTree = ""; @@ -5069,7 +5071,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -5750,7 +5752,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -6151,7 +6153,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -6906,7 +6908,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -6972,7 +6974,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEVELOPMENT_TEAM = R7V5Z67X53; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES;