From 5164042594f5ac6242d5d2e66177bedcb4342b73 Mon Sep 17 00:00:00 2001 From: TSI-amrutwaghmare <96108296+TSI-amrutwaghmare@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:13:42 +0530 Subject: [PATCH] NMC 2237 - More option tab customisation changes --- Tests/NextcloudUnitTests/MoreTests.swift | 37 +++++ iOSClient/More/Cells/BaseNCMoreCell.swift | 14 -- iOSClient/More/Cells/NCMoreUserCell.xib | 76 +++++++++ iOSClient/More/NCMore.storyboard | 171 ++++++++++--------- iOSClient/More/NCMore.swift | 191 ++++++++++++---------- 5 files changed, 314 insertions(+), 175 deletions(-) create mode 100644 Tests/NextcloudUnitTests/MoreTests.swift create mode 100755 iOSClient/More/Cells/NCMoreUserCell.xib diff --git a/Tests/NextcloudUnitTests/MoreTests.swift b/Tests/NextcloudUnitTests/MoreTests.swift new file mode 100644 index 0000000000..0a96912994 --- /dev/null +++ b/Tests/NextcloudUnitTests/MoreTests.swift @@ -0,0 +1,37 @@ +// +// MoreTests.swift +// NextcloudTests +// +// Created by A200020526 on 09/06/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +@testable import Nextcloud +import XCTest + +final class MoreTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/iOSClient/More/Cells/BaseNCMoreCell.swift b/iOSClient/More/Cells/BaseNCMoreCell.swift index 3e1a10fc1e..c0d41bc513 100644 --- a/iOSClient/More/Cells/BaseNCMoreCell.swift +++ b/iOSClient/More/Cells/BaseNCMoreCell.swift @@ -28,20 +28,6 @@ class BaseNCMoreCell: UITableViewCell { let selectionColor: UIView = UIView() let defaultCornerRadius: CGFloat = 10.0 - override var frame: CGRect { - get { - return super.frame - } - set (newFrame) { - var frame = newFrame - let newWidth = frame.width * 0.90 - let space = (frame.width - newWidth) / 2 - frame.size.width = newWidth - frame.origin.x += space - super.frame = frame - } - } - override func awakeFromNib() { super.awakeFromNib() diff --git a/iOSClient/More/Cells/NCMoreUserCell.xib b/iOSClient/More/Cells/NCMoreUserCell.xib new file mode 100755 index 0000000000..477fe2539e --- /dev/null +++ b/iOSClient/More/Cells/NCMoreUserCell.xib @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/More/NCMore.storyboard b/iOSClient/More/NCMore.storyboard index 57caeedfce..794b3d16a6 100644 --- a/iOSClient/More/NCMore.storyboard +++ b/iOSClient/More/NCMore.storyboard @@ -1,102 +1,114 @@ - + - + - + - - + + - - + + + + + + + - + - - + + - - + + - - + + - - - - - + + + + + - - - - - - - - - - + + - - + + - - + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - - - + + + + + + + - + - - - - - + + + + + + + - + + diff --git a/iOSClient/More/NCMore.swift b/iOSClient/More/NCMore.swift index 7446084838..db2fd3d306 100644 --- a/iOSClient/More/NCMore.swift +++ b/iOSClient/More/NCMore.swift @@ -24,15 +24,16 @@ import UIKit import NextcloudKit import SafariServices -import SwiftUI -import Foundation class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { + @IBOutlet weak var tableView: UITableView! @IBOutlet weak var labelQuota: UILabel! @IBOutlet weak var labelQuotaExternalSite: UILabel! @IBOutlet weak var progressQuota: UIProgressView! @IBOutlet weak var viewQuota: UIView! + @IBOutlet weak var quotaLabel1: UILabel! + @IBOutlet weak var quotalabel2: UILabel! private var functionMenu: [NKExternalSite] = [] private var externalSiteMenu: [NKExternalSite] = [] @@ -48,10 +49,12 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { var type: SectionType enum SectionType { + case account case moreApps case regular } } + private var sections: [Section] = [] private var session: NCSession.Session { @@ -74,6 +77,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { tableView.delegate = self tableView.dataSource = self tableView.backgroundColor = .systemGroupedBackground + tableView.register(NCMoreUserCell.fromNib(), forCellReuseIdentifier: NCMoreUserCell.reuseIdentifier) tableView.register(NCMoreAppSuggestionsCell.fromNib(), forCellReuseIdentifier: NCMoreAppSuggestionsCell.reuseIdentifier) // create tap gesture recognizer @@ -84,13 +88,24 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - + appDelegate.activeViewController = self navigationController?.setGroupAppearance() loadItems() + changeTheming() tableView.reloadData() } // MARK: - + + @objc func changeTheming() { + viewQuota.backgroundColor = NCBrandColor.shared.memoryConsuptionBackground + quotaLabel1.textColor = NCBrandColor.shared.label + quotalabel2.textColor = NCBrandColor.shared.label + labelQuota.textColor = NCBrandColor.shared.label + labelQuotaExternalSite.textColor = NCBrandColor.shared.label + progressQuota.progressTintColor = NCBrandColor.shared.brandElement + progressQuota.trackTintColor = NCBrandColor.shared.commonViewInfoText + } func loadItems() { guard let tableAccount = self.database.getTableAccount(predicate: NSPredicate(format: "account == %@", session.account)) else { @@ -115,39 +130,37 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { item.icon = "arrow.left.arrow.right.circle" item.url = "segueTransfers" item.order = 10 - functionMenu.append(item) +// functionMenu.append(item) // ITEM : Recent item = NKExternalSite() item.name = "_recent_" - item.icon = "clock.arrow.circlepath" + item.icon = "recent" item.url = "segueRecent" item.order = 20 functionMenu.append(item) + + // ITEM : Notification + item = NKExternalSite() + item.name = "_notifications_" + item.icon = "notification" + item.url = "segueNotification" + item.order = 30 + functionMenu.append(item) // ITEM : Activity item = NKExternalSite() item.name = "_activity_" item.icon = "bolt" item.url = "segueActivity" - item.order = 30 - functionMenu.append(item) - - if capabilities.capabilityAssistantEnabled, NCBrandOptions.shared.disable_show_more_nextcloud_apps_in_settings { - // ITEM : Assistant - item = NKExternalSite() - item.name = "_assistant_" - item.icon = "sparkles" - item.url = "openAssistant" - item.order = 40 - functionMenu.append(item) - } + item.order = 40 +// functionMenu.append(item) // ITEM : Shares if capabilities.capabilityFileSharingApiEnabled { item = NKExternalSite() item.name = "_list_shares_" - item.icon = "person.badge.plus" + item.icon = "shareFill" item.url = "segueShares" item.order = 50 functionMenu.append(item) @@ -156,7 +169,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { // ITEM : Offline item = NKExternalSite() item.name = "_manage_file_offline_" - item.icon = "icloud.and.arrow.down" + item.icon = "offlineMenu" item.url = "segueOffline" item.order = 60 functionMenu.append(item) @@ -168,16 +181,15 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { item.icon = "person.2" item.url = "segueGroupfolders" item.order = 61 - functionMenu.append(item) +// functionMenu.append(item) } - // ITEM : Scan item = NKExternalSite() item.name = "_scanned_images_" item.icon = "doc.text.viewfinder" item.url = "openStoryboardNCScan" item.order = 70 - functionMenu.append(item) +// functionMenu.append(item) // ITEM : Trash if capabilities.capabilityServerVersionMajor >= NCGlobal.shared.nextcloudVersion15 { @@ -198,8 +210,8 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { // ITEM : Settings item = NKExternalSite() item.name = "_settings_" - item.icon = "gear" - item.url = "openSettings" + item.icon = "settings" + item.url = "segueSettings" settingsMenu.append(item) if !quotaMenu.isEmpty { @@ -208,50 +220,40 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { } // Display Name user & Quota + + if tableAccount.quotaRelative > 0 { - progressQuota.progress = Float(tableAccount.quotaRelative) / 100 - } else { - progressQuota.progress = 0 - } + progressQuota.progress = Float(tableAccount.quotaRelative) / 100 + } else { + progressQuota.progress = 0 + } - switch tableAccount.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(tableAccount.quotaTotal) - } - let quotaUsed: String = utilityFileSystem.transformedSize(tableAccount.quotaUsed) - - labelQuota.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_", comment: ""), quotaUsed, quota) - - // ITEM : External - if NCBrandOptions.shared.disable_more_external_site == false { - if let externalSites = self.database.getAllExternalSites(account: session.account) { - for externalSite in externalSites { - if !externalSite.name.isEmpty, !externalSite.url.isEmpty, let urlEncoded = externalSite.url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { - item = NKExternalSite() - item.name = externalSite.name - item.url = urlEncoded - item.icon = "network" - if externalSite.type == "settings" { - item.icon = "gear" - } - externalSiteMenu.append(item) - } - } + switch tableAccount.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(tableAccount.quotaTotal) } - } + + let quotaUsed: String = utilityFileSystem.transformedSize(tableAccount.quotaUsed) + let quota2: String = utilityFileSystem.transformedSize(tableAccount.quotaTotal) + let percentageUsedFormatted = "\(Int(progressQuota.progress * 100))%" + + labelQuota.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_percentage_", comment: ""), percentageUsedFormatted) + + quotaLabel1.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_", comment: ""), quotaUsed) + quotalabel2.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_of_", comment: ""), quota2) loadSections() } private func loadSections() { - if !NCBrandOptions.shared.disable_show_more_nextcloud_apps_in_settings { - sections.append(Section(items: [NKExternalSite()], type: .moreApps)) + if tabAccount != nil { + sections.append(Section(items: [NKExternalSite()], type: .account)) } if !functionMenu.isEmpty { @@ -270,6 +272,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { // MARK: - Action @objc func tapLabelQuotaExternalSite() { + if !quotaMenu.isEmpty { let item = quotaMenu[0] if let browserWebVC = UIStoryboard(name: "NCBrowserWeb", bundle: nil).instantiateInitialViewController() as? NCBrowserWeb { @@ -282,10 +285,21 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { } } + @objc func tapImageLogoManageAccount() { + + let controller = CCManageAccount() + + self.navigationController?.pushViewController(controller, animated: true) + } + // MARK: - func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return 50 + if sections[indexPath.section].type == .account { + return 100 + } else { + return NCGlobal.shared.heightCellSettings + } } func numberOfSections(in tableView: UITableView) -> Int { @@ -295,7 +309,9 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, heightForHeaderInSection index: Int) -> CGFloat { let section = sections[index] - if section.type == .moreApps || (index > 0 && sections[index - 1].type == .moreApps) { + if section.type == .account { + return 10 + } else if section.type == .moreApps || sections[index - 1].type == .moreApps { return 1 } else { return 20 @@ -309,7 +325,30 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let section = sections[indexPath.section] - if section.type == .moreApps { + if section.type == .account { + + guard let cell = tableView.dequeueReusableCell(withIdentifier: NCMoreUserCell.reuseIdentifier, for: indexPath) as? NCMoreUserCell else { return UITableViewCell() } + + cell.avatar.image = nil + cell.icon.image = nil + cell.status.text = "" + cell.displayName.text = "" + + if let account = tabAccount { + cell.avatar.image = UIImage.init(named: "user_settings")?.image(color: NCBrandColor.shared.iconColor, size: 25) + + if account.alias.isEmpty { + cell.displayName?.text = account.displayName + } else { + cell.displayName?.text = account.displayName + " (" + account.alias + ")" + } + cell.displayName.textColor = .label + } + cell.removeCornerRadius() + cell.icon.isHidden = true + return cell + + } else if section.type == .moreApps { guard let cell = tableView.dequeueReusableCell(withIdentifier: NCMoreAppSuggestionsCell.reuseIdentifier, for: indexPath) as? NCMoreAppSuggestionsCell else { return UITableViewCell() } cell.controller = self.controller return cell @@ -318,32 +357,11 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { let item = sections[indexPath.section].items[indexPath.row] - cell.imageIcon?.image = utility.loadImage(named: item.icon, colors: [NCBrandColor.shared.iconImageColor]) + cell.imageIcon?.image = utility.loadImage(named: item.icon).image(color: NCBrandColor.shared.iconColor, size: 25) cell.imageIcon?.contentMode = .scaleAspectFit cell.labelText?.text = NSLocalizedString(item.name, comment: "") - cell.labelText.textColor = NCBrandColor.shared.textColor - - cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator - - cell.separator.backgroundColor = .separator - cell.separatorHeigth.constant = 0.4 - + cell.labelText.textColor = .label cell.removeCornerRadius() - let rows = tableView.numberOfRows(inSection: indexPath.section) - - if indexPath.row == 0 { - cell.applyCornerRadius() - if indexPath.row == rows - 1 { - cell.separator.backgroundColor = .clear - cell.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner, .layerMaxXMaxYCorner, .layerMinXMaxYCorner] - } else { - cell.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] - } - } else if indexPath.row == rows - 1 { - cell.applyCornerRadius() - cell.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner] - cell.separator.backgroundColor = .clear - } return cell } @@ -375,6 +393,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { } } else if item.url == "logout" { let alertController = UIAlertController(title: "", message: NSLocalizedString("_want_delete_", comment: ""), preferredStyle: .alert) + let actionYes = UIAlertAction(title: NSLocalizedString("_yes_delete_", comment: ""), style: .default) { (_: UIAlertAction) in let appDelegate = (UIApplication.shared.delegate as? AppDelegate)! appDelegate.openLogin(selector: NCGlobal.shared.introLogin)