Browse Source

Normalize view & new favorite view

marinofaggiana 4 years ago
parent
commit
574e438b61

+ 0 - 1
Cartfile

@@ -12,7 +12,6 @@ github "yannickl/QRCodeReader.swift" "10.1.1"
 github "weichsel/ZIPFoundation" "0.9.10"
 github "weichsel/ZIPFoundation" "0.9.10"
 github "rechsteiner/Parchment" "v2.4.0"
 github "rechsteiner/Parchment" "v2.4.0"
 github "WenchaoD/FSCalendar" "2.8.0"
 github "WenchaoD/FSCalendar" "2.8.0"
-github "AssistoLab/DropDown" "v2.3.13"
 github "krzyzanowskim/OpenSSL" "1.0.218"
 github "krzyzanowskim/OpenSSL" "1.0.218"
 github "huri000/SwiftEntryKit" "1.2.3"
 github "huri000/SwiftEntryKit" "1.2.3"
 github "scenee/FloatingPanel"
 github "scenee/FloatingPanel"

+ 0 - 285
Libraries external/DropdownMenu/DropUpMenu.swift

@@ -1,285 +0,0 @@
-//
-//  DropUpMenu.swift
-//  DropUpMenu
-//
-//  Created by Suric on 16/8/11.
-//  Copyright © 2016年 teambition. All rights reserved.
-//
-
-import UIKit
-
-public protocol DropUpMenuDelegate: class {
-    func dropUpMenu(_ dropUpMenu: DropUpMenu, cellForRowAt indexPath: IndexPath) -> UITableViewCell?
-    func dropUpMenu(_ dropUpMenu: DropUpMenu, didSelectRowAt indexPath: IndexPath)
-    func dropUpMenuCancel(_ dropUpMenu: DropUpMenu)
-    func dropUpMenuWillDismiss(_ dropUpMenu: DropUpMenu)
-    func dropUpMenuWillShow(_ dropUpMenu: DropUpMenu)
-}
-
-public extension DropUpMenuDelegate {
-    func dropUpMenu(_ dropUpMenu: DropUpMenu, cellForRowAt indexPath: IndexPath) -> UITableViewCell? {
-        return nil
-    }
-    
-    func dropUpMenu(_ dropUpMenu: DropUpMenu, didSelectRowAt indexPath: IndexPath) { }
-    
-    func dropUpMenuCancel(_ dropUpMenu: DropUpMenu) { }
-  
-    func dropUpMenuWillDismiss(_ dropUpMenu: DropUpMenu) { }
-  
-    func dropUpMenuWillShow(_ dropUpMenu: DropUpMenu) { }
-}
-
-private let screenRect = UIScreen.main.bounds
-
-open class DropUpMenu: UIView {
-    fileprivate var items: [DropdownItem] = []
-    fileprivate var selectedRow: Int
-    open var tableView: UITableView!
-    fileprivate var barCoverView: UIView!
-    fileprivate var isShow = false
-    fileprivate var addedWindow: UIWindow?
-    fileprivate var windowRootView: UIView?
-    fileprivate lazy var tapGestureRecognizer: UITapGestureRecognizer = {
-        return UITapGestureRecognizer(target: self, action: #selector(self.hideMenu))
-    }()
-    
-    open weak var delegate: DropUpMenuDelegate?
-    
-    open var animateDuration: TimeInterval = 0.25
-    
-    open var backgroudBeginColor: UIColor = UIColor.black.withAlphaComponent(0)
-    open var backgroudEndColor = UIColor(white: 0, alpha: 0.4)
-    
-    open var rowHeight: CGFloat = 50
-    open var tableViewHeight: CGFloat = 0
-    open var defaultBottonMargin: CGFloat = 150
-    
-    open var textColor: UIColor = UIColor(red: 56.0/255.0, green: 56.0/255.0, blue: 56.0/255.0, alpha: 1.0)
-    open var highlightColor: UIColor = UIColor(red: 3.0/255.0, green: 169.0/255.0, blue: 244.0/255.0, alpha: 1.0)
-    open var tableViewBackgroundColor: UIColor = UIColor(red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0) {
-        didSet {
-            tableView.backgroundColor = tableViewBackgroundColor
-        }
-    }
-    open var tableViewSeperatorColor = UIColor(red: 217.0/255.0, green: 217.0/255.0, blue: 217.0/255.0, alpha: 1.0) {
-        didSet {
-            tableView.separatorColor = tableViewSeperatorColor
-        }
-    }
-    open var cellBackgroundColor = UIColor.white
-
-    open var displaySelected: Bool = true
-    open var bottomOffsetY: CGFloat = 0
-    
-    required public init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    public init(items: [DropdownItem], selectedRow: Int = 0, bottomOffsetY: CGFloat = 0) {
-        self.items = items
-        self.selectedRow = selectedRow
-        self.bottomOffsetY = bottomOffsetY
-        
-        let frame = CGRect(x: 0, y: 0, width: screenRect.width, height: screenRect.height - bottomOffsetY)
-        super.init(frame: frame)
-        
-        clipsToBounds = true
-        setupGestureView()
-        initTableView()
-    }
-    
-    fileprivate func setupGestureView() {
-        let gestureView = UIView()
-        gestureView.backgroundColor = UIColor.clear
-        addSubview(gestureView)
-        gestureView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0)])
-        
-        gestureView.addGestureRecognizer(tapGestureRecognizer)
-    }
-    
-    fileprivate func initTableView() {
-        tableView = UITableView(frame: CGRect.zero, style: .grouped)
-        tableView?.delegate = self
-        tableView?.dataSource = self
-        tableView.estimatedSectionHeaderHeight = 0
-        tableView.estimatedSectionFooterHeight = 0
-        addSubview(tableView)
-    }
-    
-    fileprivate func layoutTableView() {
-        tableViewHeight = CGFloat(items.count) * rowHeight
-        let maxHeight = UIScreen.main.bounds.height - bottomOffsetY
-        if tableViewHeight > maxHeight {
-            tableViewHeight = maxHeight
-        }
-        
-        tableView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant:0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: tableViewHeight)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0)])
-    }
-    
-    fileprivate func setupBottomSeperatorView() {
-        let seperatorView = UIView()
-        seperatorView.backgroundColor = tableViewSeperatorColor
-        addSubview(seperatorView)
-        seperatorView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 0.5)])
-    }
-    
-    fileprivate func setupBottomCoverView(on view: UIView) {
-        barCoverView = UIView()
-        barCoverView.backgroundColor = UIColor.clear
-        barCoverView.translatesAutoresizingMaskIntoConstraints = false
-        view.addSubview(barCoverView)
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView as Any, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView as Any, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: bottomOffsetY)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView as Any, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView as Any, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: 0)])
-        barCoverView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hideMenu)))
-    }
-    
-    open func showMenu() {
-        delegate?.dropUpMenuWillShow(self)
-        if isShow {
-            hideMenu()
-            return
-        }
-        isShow = true
-        
-        layoutTableView()
-        setupBottomSeperatorView()
-        
-        if let rootView = UIApplication.shared.keyWindow {
-            windowRootView = rootView
-        } else {
-            addedWindow = UIWindow(frame: UIScreen.main.bounds)
-            addedWindow?.rootViewController = UIViewController()
-            addedWindow?.isHidden = false
-            addedWindow?.makeKeyAndVisible()
-            windowRootView = addedWindow!
-        }
-        setupBottomCoverView(on: windowRootView!)
-        windowRootView?.addSubview(self)
-        
-        translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .top, relatedBy: .equal, toItem: windowRootView, attribute: .top, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .bottom, relatedBy: .equal, toItem: windowRootView, attribute: .bottom, multiplier: 1.0, constant: -bottomOffsetY)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .left, relatedBy: .equal, toItem: windowRootView, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .right, relatedBy: .equal, toItem: windowRootView, attribute: .right, multiplier: 1.0, constant: 0)])
-        
-        backgroundColor = backgroudBeginColor
-        self.tableView.frame.origin.y = screenRect.height - bottomOffsetY
-        UIView.animate(withDuration: animateDuration, delay: 0, options: UIView.AnimationOptions(rawValue: 7<<16), animations: {
-            self.backgroundColor = self.backgroudEndColor
-            self.tableView.frame.origin.y = screenRect.height - self.bottomOffsetY - self.tableViewHeight
-            }, completion: nil)
-    }
-    
-    @objc open func hideMenu(isSelectAction: Bool = false) {
-        delegate?.dropUpMenuWillDismiss(self)
-        UIView.animate(withDuration: animateDuration, animations: {
-            self.backgroundColor = self.backgroudBeginColor
-            self.tableView.frame.origin.y = screenRect.height - self.bottomOffsetY
-        }, completion: { (finished) in
-            if !isSelectAction {
-                self.delegate?.dropUpMenuCancel(self)
-            }
-
-            self.barCoverView.removeFromSuperview()
-            self.removeFromSuperview()
-            self.isShow = false
-            
-            if let _ = self.addedWindow {
-                self.addedWindow?.isHidden = true
-                UIApplication.shared.keyWindow?.makeKey()
-            }
-        }) 
-    }
-}
-
-extension DropUpMenu: UITableViewDataSource {
-    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return items.count
-    }
-    
-    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        if let customCell = delegate?.dropUpMenu(self, cellForRowAt: indexPath) {
-            return customCell
-        }
-        
-        let item = items[(indexPath as NSIndexPath).row]
-        let cell = UITableViewCell(style: .default, reuseIdentifier: "dropUpMenuCell")
-        
-        switch item.style {
-        case .default:
-            cell.textLabel?.textColor = textColor
-            if let image = item.image {
-                cell.imageView?.image = image
-            }
-        case .highlight:
-            cell.textLabel?.textColor = highlightColor
-            if let image = item.image {
-                let highlightImage = image.withRenderingMode(.alwaysTemplate)
-                cell.imageView?.image = highlightImage
-                cell.imageView?.tintColor = highlightColor
-            }
-        }
-        
-        cell.textLabel?.text = item.title
-        cell.tintColor = highlightColor
-        cell.backgroundColor = cellBackgroundColor
-        
-        if displaySelected && (indexPath as NSIndexPath).row == selectedRow {
-            cell.accessoryType = .checkmark
-        } else {
-            cell.accessoryType = .none
-        }
-        
-        if let accesoryImage = item.accessoryImage {
-            cell.accessoryView = UIImageView(image: accesoryImage)
-        }
-        
-        return cell
-    }
-}
-
-extension DropUpMenu: UITableViewDelegate {
-    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        return rowHeight
-    }
-
-    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
-        return CGFloat.leastNonzeroMagnitude
-    }
-    
-    public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
-        return CGFloat.leastNormalMagnitude
-    }
-    
-    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        if displaySelected {
-            let item = items[(indexPath as NSIndexPath).row]
-            if item.accessoryImage  == nil {
-                let previousSelectedcell = tableView.cellForRow(at: IndexPath(row: selectedRow, section: 0))
-                previousSelectedcell?.accessoryType = .none
-                selectedRow = (indexPath as NSIndexPath).row
-                let cell = tableView.cellForRow(at: indexPath)
-                cell?.accessoryType = .checkmark
-            }
-        }
-        tableView.deselectRow(at: indexPath, animated: true)
-        hideMenu(isSelectAction: true)
-        delegate?.dropUpMenu(self, didSelectRowAt: indexPath)
-    }
-}
-

+ 0 - 38
Libraries external/DropdownMenu/DropdownItem.swift

@@ -1,38 +0,0 @@
-//
-//  DropdownItem.swift
-//  DropdownMenu
-//
-//  Created by Suric on 16/5/27.
-//  Copyright © 2016年 teambition. All rights reserved.
-//
-
-import UIKit
-
-public enum DropdownItemStyle: Int {
-    case `default`
-    case highlight
-}
-
-open class DropdownItem {
-    open var image: UIImage?
-    open var title: String
-    open var style: DropdownItemStyle
-    open var accessoryImage: UIImage?
-
-    public init(image: UIImage? = nil, title: String, style: DropdownItemStyle = .default, accessoryImage: UIImage? = nil) {
-        self.image = image
-        self.title = title
-        self.style = style
-        self.accessoryImage = accessoryImage
-    }
-}
-
-public struct DropdownSection {
-    public var sectionIdentifier: String
-    public var items: [DropdownItem]
-
-    public init (sectionIdentifier: String, items: [DropdownItem]) {
-        self.items = items
-        self.sectionIdentifier = sectionIdentifier
-    }
-}

+ 0 - 19
Libraries external/DropdownMenu/DropdownMenu.h

@@ -1,19 +0,0 @@
-//
-//  DropdownMenu.h
-//  DropdownMenu
-//
-//  Created by Suric on 16/5/26.
-//  Copyright © 2016年 teambition. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-//! Project version number for DropdownMenu.
-FOUNDATION_EXPORT double DropdownMenuVersionNumber;
-
-//! Project version string for DropdownMenu.
-FOUNDATION_EXPORT const unsigned char DropdownMenuVersionString[];
-
-// In this header, you should import all the public headers of your framework using statements like #import <DropdownMenu/PublicHeader.h>
-
-

+ 0 - 416
Libraries external/DropdownMenu/DropdownMenu.swift

@@ -1,416 +0,0 @@
-//
-//  DropdownMenu.swift
-//  DropdownMenu
-//
-//  Created by Suric on 16/5/26.
-//  Copyright © 2016年 teambition. All rights reserved.
-//
-
-import UIKit
-
-public protocol DropdownMenuDelegate: class {
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, cellForRowAt indexPath: IndexPath) -> UITableViewCell?
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, didSelectRowAt indexPath: IndexPath)
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, shouldUpdateSelectionAt indexPath: IndexPath) -> Bool
-    func dropdownMenuCancel(_ dropdownMenu: DropdownMenu)
-    func dropdownMenuWillDismiss(_ dropdownMenu: DropdownMenu)
-    func dropdownMenuWillShow(_ dropdownMenu: DropdownMenu)
-}
-
-public extension DropdownMenuDelegate {
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { }
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, cellForRowAt indexPath: IndexPath) -> UITableViewCell? { return nil }
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, didSelectRowAt indexPath: IndexPath) { }
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, shouldUpdateSelectionAt indexPath: IndexPath) -> Bool { return true }
-    func dropdownMenuCancel(_ dropdownMenu: DropdownMenu) { }
-    func dropdownMenuWillDismiss(_ dropdownMenu: DropdownMenu) { }
-    func dropdownMenuWillShow(_ dropdownMenu: DropdownMenu) { }
-}
-
-open class DropdownMenu: UIView {
-    fileprivate weak var navigationController: UINavigationController!
-   
-    fileprivate var sections: [DropdownSection] = []
-    fileprivate var selectedIndexPath: [IndexPath]
-    
-    open var tableView: UITableView!
-    fileprivate var barCoverView: UIView?
-    open var isShow = false
-    fileprivate var addedWindow: UIWindow?
-    fileprivate var windowRootView: UIView?
-    fileprivate var topConstraint: NSLayoutConstraint?
-    fileprivate var navigationBarCoverViewHeightConstraint: NSLayoutConstraint?
-    fileprivate let iPhoneXPortraitTopOffset: CGFloat = 88.0
-    fileprivate let portraitTopOffset: CGFloat = 64.0
-    fileprivate let landscapeTopOffset: CGFloat = 32.0
-    fileprivate var topLayoutConstraintConstant: CGFloat {
-        var offset: CGFloat = 0
-        if !navigationController.isNavigationBarHidden {
-          offset = navigationController.navigationBar.frame.height + navigationController.navigationBar.frame.origin.y
-        }
-        return offset + topOffsetY
-    }
-    
-    open weak var delegate: DropdownMenuDelegate?
-    open var token = ""
-    open var animateDuration: TimeInterval = 0.25
-    open var backgroudBeginColor: UIColor = UIColor.black.withAlphaComponent(0)
-    open var backgroudEndColor = UIColor(white: 0, alpha: 0.4)
-    open var rowHeight: CGFloat = 50
-    open var sectionHeaderHeight: CGFloat = 44
-    open var tableViewHeight: CGFloat = 0
-    open var defaultBottonMargin: CGFloat = 0
-    open var topOffsetY: CGFloat = 0
-    
-    open var textFont: UIFont = UIFont.systemFont(ofSize: 15.0)
-    open var textColor: UIColor = UIColor(red: 56.0/255.0, green: 56.0/255.0, blue: 56.0/255.0, alpha: 1.0)
-    open var highlightColor: UIColor = UIColor(red: 3.0/255.0, green: 169.0/255.0, blue: 244.0/255.0, alpha: 1.0)
-    open var tableViewBackgroundColor: UIColor = UIColor(red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0) {
-        didSet {
-            tableView.backgroundColor = tableViewBackgroundColor
-        }
-    }
-    open var separatorStyle: UITableViewCell.SeparatorStyle = .singleLine {
-        didSet {
-            tableView.separatorStyle = separatorStyle
-        }
-    }
-    open var tableViewSeperatorColor = UIColor(red: 217.0/255.0, green: 217.0/255.0, blue: 217.0/255.0, alpha: 1.0) {
-        didSet {
-            tableView.separatorColor = tableViewSeperatorColor
-        }
-    }
-    open var zeroInsetSeperatorIndexPaths: [IndexPath] = []
-    
-    open var cellBackgroundColor = UIColor.white
-    
-    open var displaySelected: Bool = true
-    open var displaySectionHeader: Bool = false
-    open var displayNavigationBarCoverView: Bool = true
-    
-    // section header sytle
-    open var sectionHeaderStyle: SectionHeaderStyle = SectionHeaderStyle()
-    
-    required public init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    public init(navigationController: UINavigationController, items: [DropdownItem], selectedRow: Int = 0) {
-        self.navigationController = navigationController
-        self.sections = [DropdownSection(sectionIdentifier: "", items: items)]
-        self.selectedIndexPath = [IndexPath(row: selectedRow, section: 0)]
-        
-        super.init(frame: CGRect.zero)
-        
-        clipsToBounds = true
-        setupGestureView()
-        initTableView()
-        
-        NotificationCenter.default.addObserver(self, selector: #selector(self.updateForOrientationChange(_:)), name: UIApplication.willChangeStatusBarOrientationNotification, object: nil)
-    }
-    
-    public init(navigationController: UINavigationController, sections: [DropdownSection], selectedIndexPath: [IndexPath], dispalySectionHeader: Bool = true, sectionHeaderStyle: SectionHeaderStyle = SectionHeaderStyle()) {
-        self.navigationController = navigationController
-        self.sections = sections
-        self.selectedIndexPath = selectedIndexPath
-        self.displaySectionHeader = dispalySectionHeader
-        
-        super.init(frame: CGRect.zero)
-        
-        clipsToBounds = true
-        setupGestureView()
-        initTableView()
-        
-        NotificationCenter.default.addObserver(self, selector: #selector(self.updateForOrientationChange(_:)), name: UIApplication.willChangeStatusBarOrientationNotification, object: nil)
-    }
-    
-    deinit {
-        NotificationCenter.default.removeObserver(self)
-    }
-    
-    @objc func updateForOrientationChange(_ nofication: Notification) {
-        
-        print("UIApplicationWillChangeStatusBarOrientation")
-        
-        self.hideMenu()
-        
-        /*
-        var insetTop: CGFloat = 0
-        if #available(iOS 11.0, *) {
-            insetTop = UIApplication.shared.keyWindow!.safeAreaInsets.top
-        }
-        
-        if let _ = (nofication as NSNotification).userInfo?[UIApplication.statusBarOrientationUserInfoKey] as? Int {
-            var topOffset = navigationController.navigationBar.frame.height + insetTop
-            /*
-            var topOffset: CGFloat = 0
-            switch oriention {
-            case UIInterfaceOrientation.landscapeLeft.rawValue, UIInterfaceOrientation.landscapeRight.rawValue:
-                if UIDevice.current.userInterfaceIdiom == .phone {
-                    topOffset = navigationController.navigationBar.frame.height + insetTop
-                } else {
-                    topOffset = navigationController.navigationBar.frame.height + insetTop
-                }
-                
-            case UIInterfaceOrientation.portrait.rawValue, UIInterfaceOrientation.portraitUpsideDown.rawValue:
-                topOffset = navigationController.navigationBar.frame.height + insetTop
-            
-            default:
-                break
-            }
-            */
-            topOffset = topOffset + topOffsetY
-            topConstraint?.constant = topOffset
-            navigationBarCoverViewHeightConstraint?.constant = topOffset
-            UIView.animate(withDuration: 0.1, animations: {
-                self.windowRootView?.layoutIfNeeded()
-            })
-        }
-        */
-    }
-    
-    fileprivate func setupGestureView() {
-        let gestureView = UIView()
-        gestureView.backgroundColor = UIColor.clear
-        addSubview(gestureView)
-        gestureView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: gestureView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0)])
-        
-        gestureView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hideMenu)))
-    }
-    
-    fileprivate func initTableView() {
-        tableView = UITableView(frame: CGRect.zero, style: .grouped)
-        tableView.separatorStyle = separatorStyle
-        tableView.delegate = self
-        tableView.dataSource = self
-        tableView.estimatedSectionFooterHeight = 0
-        tableView.estimatedSectionHeaderHeight = 0
-        addSubview(tableView)
-    }
-    
-    fileprivate func layoutTableView() {
-        tableView.translatesAutoresizingMaskIntoConstraints = false
-
-        tableViewHeight = tableviewHeight()
-        
-        let maxHeight = navigationController.view.frame.height - topLayoutConstraintConstant - defaultBottonMargin
-        
-        if tableViewHeight > maxHeight {
-            if displaySectionHeader {
-                tableViewHeight = maxHeight
-            } else {
-                tableViewHeight = round(maxHeight / rowHeight) * rowHeight
-            }
-        }
-        
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant:0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: tableViewHeight)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: tableView as Any, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0)])
-    }
-    
-    fileprivate func setupTopSeperatorView() {
-        let seperatorView = UIView()
-        seperatorView.backgroundColor = tableViewSeperatorColor
-        addSubview(seperatorView)
-        seperatorView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: seperatorView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 0.5)])
-    }
-    
-    fileprivate func setupNavigationBarCoverView(on view: UIView) {
-        barCoverView = UIView()
-        barCoverView?.backgroundColor = UIColor.clear
-        view.addSubview(barCoverView!)
-        barCoverView?.translatesAutoresizingMaskIntoConstraints = false
-        
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView!, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0)])
-        navigationBarCoverViewHeightConstraint = NSLayoutConstraint.init(item: barCoverView!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: topLayoutConstraintConstant)
-        NSLayoutConstraint.activate([navigationBarCoverViewHeightConstraint!])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView!, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: barCoverView!, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: 0)])
-        barCoverView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hideMenu)))
-    }
-    
-    fileprivate func tableviewHeight() -> CGFloat {
-        var height: CGFloat = 0
-        if displaySectionHeader {
-            height += sectionHeaderHeight * CGFloat(sections.count)
-        }
-        for section in sections {
-            height += CGFloat(section.items.count) * rowHeight
-        }
-        return height
-    }
-    
-    open func showMenu(isOnNavigaitionView: Bool = false) {
-        delegate?.dropdownMenuWillShow(self)
-        if isShow {
-            hideMenu()
-            return
-        }
-        
-        isShow = true
-        
-        layoutTableView()
-        setupTopSeperatorView()
-        
-        addedWindow = UIWindow(frame: self.navigationController.view.bounds)
-        addedWindow?.rootViewController = UIViewController()
-        addedWindow?.isHidden = false
-        addedWindow?.makeKeyAndVisible()
-        windowRootView = addedWindow!
-
-        if displayNavigationBarCoverView {
-            setupNavigationBarCoverView(on: windowRootView!)
-        }
-        
-        windowRootView?.addSubview(self)
-        
-        translatesAutoresizingMaskIntoConstraints = false
-        topConstraint = NSLayoutConstraint.init(item: self, attribute: .top, relatedBy: .equal, toItem: windowRootView, attribute: .top, multiplier: 1.0, constant: topLayoutConstraintConstant)
-        NSLayoutConstraint.activate([topConstraint!])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .bottom, relatedBy: .equal, toItem: windowRootView, attribute: .bottom, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .left, relatedBy: .equal, toItem: windowRootView, attribute: .left, multiplier: 1.0, constant: 0)])
-        NSLayoutConstraint.activate([NSLayoutConstraint.init(item: self, attribute: .right, relatedBy: .equal, toItem: windowRootView, attribute: .right, multiplier: 1.0, constant: 0)])
-        
-        backgroundColor = backgroudBeginColor
-        self.tableView.frame.origin.y = -self.tableViewHeight
-        UIView.animate(withDuration: animateDuration, delay: 0, options: UIView.AnimationOptions(rawValue: 7<<16), animations: {
-            self.backgroundColor = self.backgroudEndColor
-            self.tableView.frame.origin.y = 0
-        }, completion: nil)
-    }
-    
-    @objc open func hideMenu(isSelectAction: Bool = false) {
-        delegate?.dropdownMenuWillDismiss(self)
-        UIView.animate(withDuration: animateDuration, animations: {
-            self.backgroundColor = self.backgroudBeginColor
-            self.tableView.frame.origin.y = -self.tableViewHeight
-        }, completion: { (finished) in
-            if !isSelectAction {
-                self.delegate?.dropdownMenuCancel(self)
-            }
-            self.barCoverView?.removeFromSuperview()
-            self.removeFromSuperview()
-            self.isShow = false
-            
-            if let _ = self.addedWindow {
-                self.addedWindow?.isHidden = true
-                UIApplication.shared.keyWindow?.makeKey()
-            }
-        })
-    }
-}
-
-extension DropdownMenu: UITableViewDataSource {
-    public func numberOfSections(in tableView: UITableView) -> Int {
-        return sections.count
-    }
-    
-    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return sections[section].items.count
-    }
-    
-    public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
-        delegate?.dropdownMenu(self, willDisplay: cell, forRowAt: indexPath)
-    }
-    
-    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        if let customCell = delegate?.dropdownMenu(self, cellForRowAt: indexPath) {
-            return customCell
-        }
-        
-        let item = sections[indexPath.section].items[indexPath.row]
-        let cell = UITableViewCell(style: .default, reuseIdentifier: "dropdownMenuCell")
-        
-        switch item.style {
-        case .default:
-            cell.textLabel?.textColor = textColor
-            if let image = item.image {
-                cell.imageView?.image = image
-            }
-        case .highlight:
-            cell.textLabel?.textColor = highlightColor
-            if let image = item.image {
-                let highlightImage = image.withRenderingMode(.alwaysTemplate)
-                cell.imageView?.image = highlightImage
-                cell.imageView?.tintColor = highlightColor
-            }
-        }
-        
-        cell.textLabel?.text = item.title
-        cell.textLabel?.font = textFont
-        cell.tintColor = highlightColor
-        cell.backgroundColor = cellBackgroundColor
-        
-        if displaySelected && selectedIndexPath.contains(indexPath) {   //indexPath == selectedIndexPath {
-            cell.accessoryType = .checkmark
-        } else {
-            cell.accessoryType = .none
-        }
-        
-        if let accesoryImage = item.accessoryImage {
-            cell.accessoryView = UIImageView(image: accesoryImage)
-        }
-        
-        if zeroInsetSeperatorIndexPaths.contains(indexPath) {
-            cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
-        } else {
-            cell.separatorInset = UIEdgeInsets(top: 0, left: tableView.layoutMargins.left, bottom: 0, right: 0)
-        }
-        
-        return cell
-    }
-    
-    public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
-        return displaySectionHeader ? sections[section].sectionIdentifier : nil
-    }
-}
-
-extension DropdownMenu: UITableViewDelegate {
-    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        return rowHeight
-    }
-    
-    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
-        return displaySectionHeader ? sectionHeaderHeight : CGFloat.leastNormalMagnitude
-    }
-    
-    public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
-        return CGFloat.leastNormalMagnitude
-    }
-    
-    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        /*
-        let shouldUpdateSelection = delegate?.dropdownMenu(self, shouldUpdateSelectionAt: indexPath) ?? true
-        
-        if displaySelected && shouldUpdateSelection {
-            let item = sections[indexPath.section].items[indexPath.row]
-            if item.accessoryImage  == nil {
-                let previousSelectedcell = tableView.cellForRow(at: selectedIndexPath)
-                previousSelectedcell?.accessoryType = .none
-                selectedIndexPath = indexPath
-                let cell = tableView.cellForRow(at: indexPath)
-                cell?.accessoryType = .checkmark
-            }
-        }
-        */
-        tableView.deselectRow(at: indexPath, animated: true)
-        hideMenu(isSelectAction: true)
-        delegate?.dropdownMenu(self, didSelectRowAt: indexPath)
-    }
-    
-    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
-        let sectionHeader = SectionHeader(style: sectionHeaderStyle)
-        sectionHeader.titleLabel.text = sections[section].sectionIdentifier
-        return sectionHeader
-    }
-}

+ 0 - 76
Libraries external/DropdownMenu/SectionHeader.swift

@@ -1,76 +0,0 @@
-//
-//  SectionHeader.swift
-//  DropdownMenu
-//
-//  Created by WangWei on 2016/10/9.
-//  Copyright © 2016年 teambition. All rights reserved.
-//
-
-open class SectionHeader: UIView {
-    var titleLabel: UILabel!
-    var style: SectionHeaderStyle = SectionHeaderStyle()
-
-    convenience init(style: SectionHeaderStyle) {
-        self.init(frame: CGRect.zero)
-        self.style = style
-        commonInit()
-    }
-
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-    }
-
-    func commonInit() {
-        titleLabel = UILabel()
-        titleLabel.translatesAutoresizingMaskIntoConstraints = false
-        titleLabel.font = style.font
-        titleLabel.textColor = style.textColor
-        backgroundColor = style.backgroundColor
-        addSubview(titleLabel)
-        updateTitleLabelConstraint()
-    }
-
-    func updateTitleLabelConstraint() {
-        if #available(iOS 11.0, *) {
-            let leftConstraint = NSLayoutConstraint(item: titleLabel as Any, attribute: .left, relatedBy: .equal, toItem: safeAreaLayoutGuide, attribute: .left, multiplier: 1.0, constant: style.bottomPadding)
-            NSLayoutConstraint.activate([leftConstraint])
-        } else {
-            // Fallback on earlier versions
-            let constraints =  NSLayoutConstraint.constraints(withVisualFormat: "H:|-leftPadding-[titleLabel]->=20-|", options: [], metrics: ["leftPadding": style.leftPadding], views: ["titleLabel": titleLabel as Any])
-            addConstraints(constraints)
-        }
-        if style.shouldTitleCenterVertically {
-            let centerY = NSLayoutConstraint(item: titleLabel as Any, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0)
-            addConstraint(centerY)
-        } else {
-            let vConstraints = NSLayoutConstraint(item: titleLabel as Any, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: style.bottomPadding)
-            addConstraint(vConstraints)
-        }
-    }
-}
-
-
-public struct SectionHeaderStyle {
-    
-    /// leftPadding for title label, default is `20`
-    public var leftPadding: CGFloat = 20
-    /// bottom padding for title label, default is `10`,
-    /// will be ignored when `shouldTitleCenterVertically` is `true`
-    public var bottomPadding: CGFloat = 10
-    /// should title label center in axis Y, default is `true`
-    public var shouldTitleCenterVertically: Bool = true
-
-    /// title label font, default is `UIFont.systemFont(ofSize: 14)`
-    public var font: UIFont = UIFont.systemFont(ofSize: 14)
-    /// title label textColor, default is A6A6A6
-    public var textColor: UIColor = UIColor(red: 166.0/255.0, green: 166.0/255.0, blue: 166.0/255.0, alpha: 1.0)
-    /// backgroundColor for header, default is F2F2F2
-    public var backgroundColor: UIColor = UIColor(red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0)
-
-    public init() {
-    }
-}

+ 4 - 26
Nextcloud.xcodeproj/project.pbxproj

@@ -64,10 +64,6 @@
 		F710D20024057E5E00A6033D /* NCActionSheetHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F710D1FD24057E5E00A6033D /* NCActionSheetHeaderView.xib */; };
 		F710D20024057E5E00A6033D /* NCActionSheetHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F710D1FD24057E5E00A6033D /* NCActionSheetHeaderView.xib */; };
 		F710D2022405826100A6033D /* NCDetailNavigationController+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F710D2012405826100A6033D /* NCDetailNavigationController+Menu.swift */; };
 		F710D2022405826100A6033D /* NCDetailNavigationController+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F710D2012405826100A6033D /* NCDetailNavigationController+Menu.swift */; };
 		F710E8111EF95C9C00DC2427 /* ImagesIntro.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */; };
 		F710E8111EF95C9C00DC2427 /* ImagesIntro.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */; };
-		F711CD04246AC9B10009B204 /* DropdownItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F711CCFF246AC9B10009B204 /* DropdownItem.swift */; };
-		F711CD05246AC9B10009B204 /* DropUpMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F711CD00246AC9B10009B204 /* DropUpMenu.swift */; };
-		F711CD06246AC9B10009B204 /* DropdownMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F711CD02246AC9B10009B204 /* DropdownMenu.swift */; };
-		F711CD07246AC9B10009B204 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F711CD03246AC9B10009B204 /* SectionHeader.swift */; };
 		F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */ = {isa = PBXBuildFile; fileRef = F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */; };
 		F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */ = {isa = PBXBuildFile; fileRef = F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */; };
 		F71459BA1D12E3B700CAFEEC /* NSString+TruncateToWidth.m in Sources */ = {isa = PBXBuildFile; fileRef = F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */; };
 		F71459BA1D12E3B700CAFEEC /* NSString+TruncateToWidth.m in Sources */ = {isa = PBXBuildFile; fileRef = F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */; };
 		F71459C21D12E3B700CAFEEC /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C0F46F1C8880540059EC54 /* ShareViewController.m */; };
 		F71459C21D12E3B700CAFEEC /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C0F46F1C8880540059EC54 /* ShareViewController.m */; };
@@ -277,6 +273,7 @@
 		F7CA1ED720E7E3FE002CC65E /* PKDownloadButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1EC820E7E3FE002CC65E /* PKDownloadButton.m */; };
 		F7CA1ED720E7E3FE002CC65E /* PKDownloadButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1EC820E7E3FE002CC65E /* PKDownloadButton.m */; };
 		F7CA1ED820E7E3FE002CC65E /* PKBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1ECA20E7E3FE002CC65E /* PKBorderedButton.m */; };
 		F7CA1ED820E7E3FE002CC65E /* PKBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1ECA20E7E3FE002CC65E /* PKBorderedButton.m */; };
 		F7CA1ED920E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1ECE20E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m */; };
 		F7CA1ED920E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1ECE20E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m */; };
+		F7CBC31C24F78E79004D3812 /* NCSortMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CBC31B24F78E79004D3812 /* NCSortMenu.swift */; };
 		F7D1612023CF19E30039EBBF /* NCViewerRichWorkspace.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7D1611F23CF19E30039EBBF /* NCViewerRichWorkspace.storyboard */; };
 		F7D1612023CF19E30039EBBF /* NCViewerRichWorkspace.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7D1611F23CF19E30039EBBF /* NCViewerRichWorkspace.storyboard */; };
 		F7D2C773246470CA008513AE /* XLForm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7D2C772246470CA008513AE /* XLForm.framework */; };
 		F7D2C773246470CA008513AE /* XLForm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7D2C772246470CA008513AE /* XLForm.framework */; };
 		F7D6650720FF341600BFBA9E /* NCMainCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D6650620FF341600BFBA9E /* NCMainCommon.swift */; };
 		F7D6650720FF341600BFBA9E /* NCMainCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D6650620FF341600BFBA9E /* NCMainCommon.swift */; };
@@ -408,11 +405,6 @@
 		F710D1FD24057E5E00A6033D /* NCActionSheetHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCActionSheetHeaderView.xib; sourceTree = "<group>"; };
 		F710D1FD24057E5E00A6033D /* NCActionSheetHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCActionSheetHeaderView.xib; sourceTree = "<group>"; };
 		F710D2012405826100A6033D /* NCDetailNavigationController+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCDetailNavigationController+Menu.swift"; sourceTree = "<group>"; };
 		F710D2012405826100A6033D /* NCDetailNavigationController+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCDetailNavigationController+Menu.swift"; sourceTree = "<group>"; };
 		F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ImagesIntro.xcassets; sourceTree = "<group>"; };
 		F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ImagesIntro.xcassets; sourceTree = "<group>"; };
-		F711CCFF246AC9B10009B204 /* DropdownItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropdownItem.swift; sourceTree = "<group>"; };
-		F711CD00246AC9B10009B204 /* DropUpMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropUpMenu.swift; sourceTree = "<group>"; };
-		F711CD01246AC9B10009B204 /* DropdownMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DropdownMenu.h; sourceTree = "<group>"; };
-		F711CD02246AC9B10009B204 /* DropdownMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropdownMenu.swift; sourceTree = "<group>"; };
-		F711CD03246AC9B10009B204 /* SectionHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = "<group>"; };
 		F713FEFE2472764000214AF6 /* UIImage+animatedGIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+animatedGIF.h"; sourceTree = "<group>"; };
 		F713FEFE2472764000214AF6 /* UIImage+animatedGIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+animatedGIF.h"; sourceTree = "<group>"; };
 		F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+animatedGIF.m"; sourceTree = "<group>"; };
 		F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+animatedGIF.m"; sourceTree = "<group>"; };
 		F7151A811D477A4B00E6AF45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F7151A811D477A4B00E6AF45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -678,6 +670,7 @@
 		F7CA1ECD20E7E3FE002CC65E /* PKCircleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKCircleView.h; sourceTree = "<group>"; };
 		F7CA1ECD20E7E3FE002CC65E /* PKCircleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKCircleView.h; sourceTree = "<group>"; };
 		F7CA1ECE20E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+PKDownloadButton.m"; sourceTree = "<group>"; };
 		F7CA1ECE20E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+PKDownloadButton.m"; sourceTree = "<group>"; };
 		F7CA1ECF20E7E3FE002CC65E /* PKPendingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKPendingView.h; sourceTree = "<group>"; };
 		F7CA1ECF20E7E3FE002CC65E /* PKPendingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKPendingView.h; sourceTree = "<group>"; };
+		F7CBC31B24F78E79004D3812 /* NCSortMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSortMenu.swift; sourceTree = "<group>"; };
 		F7CC04E61F5AD50D00378CEF /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F7CC04E61F5AD50D00378CEF /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F7CE8AFA1DC1F8D8009CAE48 /* Nextcloud.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nextcloud.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		F7CE8AFA1DC1F8D8009CAE48 /* Nextcloud.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nextcloud.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		F7CE8AFB1DC1F8D8009CAE48 /* Share.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Share.appex; sourceTree = BUILT_PRODUCTS_DIR; };
 		F7CE8AFB1DC1F8D8009CAE48 /* Share.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Share.appex; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -802,6 +795,7 @@
 				3781B9AF23DB2B7E006B4B1D /* AppDelegate+Menu.swift */,
 				3781B9AF23DB2B7E006B4B1D /* AppDelegate+Menu.swift */,
 				3781B9B323DB2BC9006B4B1D /* NCFavorite+Menu.swift */,
 				3781B9B323DB2BC9006B4B1D /* NCFavorite+Menu.swift */,
 				3781B9B123DB2B9F006B4B1D /* CCMain+Menu.swift */,
 				3781B9B123DB2B9F006B4B1D /* CCMain+Menu.swift */,
+				F7CBC31B24F78E79004D3812 /* NCSortMenu.swift */,
 				F710D2012405826100A6033D /* NCDetailNavigationController+Menu.swift */,
 				F710D2012405826100A6033D /* NCDetailNavigationController+Menu.swift */,
 				371B5A2D23D0B04500FAFAE9 /* NCMainMenuTableViewController.swift */,
 				371B5A2D23D0B04500FAFAE9 /* NCMainMenuTableViewController.swift */,
 				3704EB2923D5A58400455C5B /* NCMenu.storyboard */,
 				3704EB2923D5A58400455C5B /* NCMenu.storyboard */,
@@ -861,7 +855,6 @@
 		F70F02A81C889183008DAB36 /* Libraries external */ = {
 		F70F02A81C889183008DAB36 /* Libraries external */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				F711CCFE246AC9B10009B204 /* DropdownMenu */,
 				F704FA5A232A341800BBA952 /* Imagemeter */,
 				F704FA5A232A341800BBA952 /* Imagemeter */,
 				F7B2DEEB1F976785007CF4D2 /* NYMnemonic */,
 				F7B2DEEB1F976785007CF4D2 /* NYMnemonic */,
 				F7CA1EBB20E7E3FE002CC65E /* PKDownloadButton */,
 				F7CA1EBB20E7E3FE002CC65E /* PKDownloadButton */,
@@ -891,18 +884,6 @@
 			path = Intro;
 			path = Intro;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
-		F711CCFE246AC9B10009B204 /* DropdownMenu */ = {
-			isa = PBXGroup;
-			children = (
-				F711CCFF246AC9B10009B204 /* DropdownItem.swift */,
-				F711CD00246AC9B10009B204 /* DropUpMenu.swift */,
-				F711CD01246AC9B10009B204 /* DropdownMenu.h */,
-				F711CD02246AC9B10009B204 /* DropdownMenu.swift */,
-				F711CD03246AC9B10009B204 /* SectionHeader.swift */,
-			);
-			path = DropdownMenu;
-			sourceTree = "<group>";
-		};
 		F7169A161EE590930086BD69 /* Shares */ = {
 		F7169A161EE590930086BD69 /* Shares */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -2044,7 +2025,6 @@
 				F7BAADC81ED5A87C00B7EAD4 /* NCDatabase.swift in Sources */,
 				F7BAADC81ED5A87C00B7EAD4 /* NCDatabase.swift in Sources */,
 				F75C0C4823D1FAE300163CC8 /* NCRichWorkspaceCommon.swift in Sources */,
 				F75C0C4823D1FAE300163CC8 /* NCRichWorkspaceCommon.swift in Sources */,
 				F78ACD4A21903F850088454D /* NCTrashListCell.swift in Sources */,
 				F78ACD4A21903F850088454D /* NCTrashListCell.swift in Sources */,
-				F711CD04246AC9B10009B204 /* DropdownItem.swift in Sources */,
 				F7682FE023C36B0500983A04 /* NCMainTabBar.swift in Sources */,
 				F7682FE023C36B0500983A04 /* NCMainTabBar.swift in Sources */,
 				F77B0E5F1D118A16002130FE /* CCSettings.m in Sources */,
 				F77B0E5F1D118A16002130FE /* CCSettings.m in Sources */,
 				F70460522499061800BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
 				F70460522499061800BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
@@ -2064,10 +2044,8 @@
 				F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */,
 				F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */,
 				F7B174C822FAC0A8000B7579 /* AppDelegate.m in Sources */,
 				F7B174C822FAC0A8000B7579 /* AppDelegate.m in Sources */,
 				F749C10B23C4A5340027D966 /* NCIntroCollectionViewCell.swift in Sources */,
 				F749C10B23C4A5340027D966 /* NCIntroCollectionViewCell.swift in Sources */,
-				F711CD07246AC9B10009B204 /* SectionHeader.swift in Sources */,
 				F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */,
 				F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */,
 				F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */,
 				F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */,
-				F711CD06246AC9B10009B204 /* DropdownMenu.swift in Sources */,
 				F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */,
 				F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */,
 				F7BF1B431D51E893000854F6 /* CCLogin.m in Sources */,
 				F7BF1B431D51E893000854F6 /* CCLogin.m in Sources */,
 				F769454422E9F142000A798A /* NCShareUserMenuView.swift in Sources */,
 				F769454422E9F142000A798A /* NCShareUserMenuView.swift in Sources */,
@@ -2102,6 +2080,7 @@
 				370D26B1248A3E1A00121797 /* CCCellMain.swift in Sources */,
 				370D26B1248A3E1A00121797 /* CCCellMain.swift in Sources */,
 				F7CA1ED220E7E3FE002CC65E /* PKCircleView.m in Sources */,
 				F7CA1ED220E7E3FE002CC65E /* PKCircleView.m in Sources */,
 				F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */,
 				F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */,
+				F7CBC31C24F78E79004D3812 /* NCSortMenu.swift in Sources */,
 				F7169A1C1EE590930086BD69 /* NCShares.m in Sources */,
 				F7169A1C1EE590930086BD69 /* NCShares.m in Sources */,
 				F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */,
 				F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */,
 				F7C9555521F0C5470024296E /* NCActivity.swift in Sources */,
 				F7C9555521F0C5470024296E /* NCActivity.swift in Sources */,
@@ -2116,7 +2095,6 @@
 				F758B45E212C569D00515F55 /* ScanCell.swift in Sources */,
 				F758B45E212C569D00515F55 /* ScanCell.swift in Sources */,
 				F7CA1ED920E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m in Sources */,
 				F7CA1ED920E7E3FE002CC65E /* NSLayoutConstraint+PKDownloadButton.m in Sources */,
 				F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */,
 				F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */,
-				F711CD05246AC9B10009B204 /* DropUpMenu.swift in Sources */,
 				F70D8D8124A4A9BF000A5756 /* NCNetworkingAutoUpload.swift in Sources */,
 				F70D8D8124A4A9BF000A5756 /* NCNetworkingAutoUpload.swift in Sources */,
 				F7D96FCC246ED7E200536D73 /* NCNetworkingCheckRemoteUser.swift in Sources */,
 				F7D96FCC246ED7E200536D73 /* NCNetworkingCheckRemoteUser.swift in Sources */,
 				F7E4D9C422ED929B003675FD /* NCShareComments.swift in Sources */,
 				F7E4D9C422ED929B003675FD /* NCShareComments.swift in Sources */,

+ 1 - 1
iOSClient/Activity/NCActivity.swift

@@ -58,8 +58,8 @@ class NCActivity: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelega
         tableView.tableFooterView = UIView()
         tableView.tableFooterView = UIView()
         tableView.contentInset = insets
         tableView.contentInset = insets
         
         
-        // changeTheming
         NotificationCenter.default.addObserver(self, selector: #selector(self.changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(self.changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        
         changeTheming()
         changeTheming()
     }
     }
     
     

+ 1 - 0
iOSClient/CCGlobal.h

@@ -271,6 +271,7 @@
 #define k_layout_view_trash                             @"LayoutTrash"
 #define k_layout_view_trash                             @"LayoutTrash"
 #define k_layout_view_offline                           @"LayoutOffline"
 #define k_layout_view_offline                           @"LayoutOffline"
 #define k_layout_view_favorite                          @"LayoutFavorite"
 #define k_layout_view_favorite                          @"LayoutFavorite"
+#define k_layout_view_main                              @"LayoutMain"
 
 
 // Rich Workspace
 // Rich Workspace
 #define k_fileNameRichWorkspace                         @"Readme.md"
 #define k_fileNameRichWorkspace                         @"Readme.md"

+ 62 - 0
iOSClient/Favorites/NCFavorite.storyboard

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="EFX-fO-Oip">
+    <device id="retina5_9" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Favorite-->
+        <scene sceneID="X4W-6b-l7s">
+            <objects>
+                <viewController storyboardIdentifier="NCFavorite.storyboard" extendedLayoutIncludesOpaqueBars="YES" id="EFX-fO-Oip" customClass="NCFavorite" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="QEs-gO-Cmp">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="Zaz-Cl-qpZ">
+                                <rect key="frame" x="0.0" y="44" width="375" height="734"/>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="fF1-wd-0xN">
+                                    <size key="itemSize" width="0.0" height="0.0"/>
+                                    <size key="headerReferenceSize" width="0.0" height="0.0"/>
+                                    <size key="footerReferenceSize" width="0.0" height="0.0"/>
+                                    <inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
+                                </collectionViewFlowLayout>
+                                <cells/>
+                                <connections>
+                                    <outlet property="dataSource" destination="EFX-fO-Oip" id="2On-qP-zuG"/>
+                                    <outlet property="delegate" destination="EFX-fO-Oip" id="s3n-CL-8X2"/>
+                                </connections>
+                            </collectionView>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <constraints>
+                            <constraint firstItem="Zaz-Cl-qpZ" firstAttribute="leading" secondItem="Meh-VD-wWh" secondAttribute="leading" id="1bp-sm-u0X"/>
+                            <constraint firstItem="Meh-VD-wWh" firstAttribute="trailing" secondItem="Zaz-Cl-qpZ" secondAttribute="trailing" id="aNd-UL-hmu"/>
+                            <constraint firstItem="Meh-VD-wWh" firstAttribute="bottom" secondItem="Zaz-Cl-qpZ" secondAttribute="bottom" id="aNr-tf-2AH"/>
+                            <constraint firstItem="Zaz-Cl-qpZ" firstAttribute="top" secondItem="Meh-VD-wWh" secondAttribute="top" id="tji-wt-R7s"/>
+                        </constraints>
+                        <viewLayoutGuide key="safeArea" id="Meh-VD-wWh"/>
+                    </view>
+                    <connections>
+                        <outlet property="collectionView" destination="Zaz-Cl-qpZ" id="8oA-Gx-z7T"/>
+                        <segue destination="rIl-hI-jAh" kind="showDetail" identifier="segueDetail" id="MHI-ti-PGq"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="JJ0-Le-6eT" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="256.80000000000001" y="228.93553223388307"/>
+        </scene>
+        <!--CCDetailNC-->
+        <scene sceneID="D5y-IR-BuC">
+            <objects>
+                <viewControllerPlaceholder storyboardName="Main" referencedIdentifier="CCDetailNC" id="rIl-hI-jAh" sceneMemberID="viewController"/>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="eCA-Ct-z68" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1080" y="228"/>
+        </scene>
+    </scenes>
+</document>

+ 517 - 0
iOSClient/Favorites/NCFavorite.swift

@@ -0,0 +1,517 @@
+//
+//  NCFavorite.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 26/08/2020.
+//  Copyright © 2020 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 <http://www.gnu.org/licenses/>.
+//
+
+import Foundation
+
+class NCFavorite: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate  {
+    
+    @IBOutlet fileprivate weak var collectionView: UICollectionView!
+
+    var titleCurrentFolder = NSLocalizedString("_favorites_", comment: "")
+    @objc var serverUrl = ""
+    
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
+   
+    private var metadataPush: tableMetadata?
+    private var isEditMode = false
+    private var selectocId: [String] = []
+    
+    private var sectionDatasource = CCSectionDataSourceMetadata()
+    
+    private var typeLayout = ""
+    private var datasourceGroupBy = ""
+    private var datasourceTitleButton = ""
+
+    private var autoUploadFileName = ""
+    private var autoUploadDirectory = ""
+    
+    private var listLayout: NCListLayout!
+    private var gridLayout: NCGridLayout!
+        
+    private let headerMenuHeight: CGFloat = 50
+    private let sectionHeaderHeight: CGFloat = 20
+    private let footerHeight: CGFloat = 50
+    
+    required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        
+        appDelegate.activeFavorite = self
+    }
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        // Cell
+        collectionView.register(UINib.init(nibName: "NCListCell", bundle: nil), forCellWithReuseIdentifier: "listCell")
+        collectionView.register(UINib.init(nibName: "NCGridCell", bundle: nil), forCellWithReuseIdentifier: "gridCell")
+        
+        // Header
+        collectionView.register(UINib.init(nibName: "NCSectionHeaderMenu", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "sectionHeaderMenu")
+        collectionView.register(UINib.init(nibName: "NCSectionHeader", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "sectionHeader")
+        
+        // Footer
+        collectionView.register(UINib.init(nibName: "NCSectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "sectionFooter")
+        
+        collectionView.alwaysBounceVertical = true
+
+        listLayout = NCListLayout()
+        gridLayout = NCGridLayout()
+        
+        // empty Data Source
+        self.collectionView.emptyDataSetDelegate = self
+        self.collectionView.emptyDataSetSource = self
+        
+        // 3D Touch peek and pop
+        if traitCollection.forceTouchCapability == .available {
+            registerForPreviewing(with: self, sourceView: view)
+        }
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_deleteFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSource), object: nil)
+
+        changeTheming()
+    }
+    
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+
+        self.navigationItem.title = titleCurrentFolder
+                
+        // get auto upload folder
+        autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
+        autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account)
+        
+        (typeLayout, _, _, datasourceGroupBy, _, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_favorite)
+        
+        if typeLayout == k_layout_list {
+            collectionView.collectionViewLayout = listLayout
+        } else {
+            collectionView.collectionViewLayout = gridLayout
+        }
+        
+        reloadDataSource()
+    }
+    
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        
+        if serverUrl == "" {
+            listingFavorites()
+        } else {
+            readFolder()
+        }
+    }
+    
+    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+        super.viewWillTransition(to: size, with: coordinator)
+        
+        coordinator.animate(alongsideTransition: nil) { _ in
+            self.collectionView.collectionViewLayout.invalidateLayout()
+        }
+    }
+    
+    //MARK: - NotificationCenter
+
+    @objc func deleteFile(_ notification: NSNotification) {
+        if self.view?.window == nil { return }
+        
+        if let userInfo = notification.userInfo as NSDictionary? {
+            if let errorCode = userInfo["errorCode"] as? Int, let errorDescription = userInfo["errorDescription"] as? String {
+                if errorCode == 0 {
+                    self.reloadDataSource()
+                } else {
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                }
+            }
+        }
+    }
+    
+    @objc func changeTheming() {
+        appDelegate.changeTheming(self, tableView: nil, collectionView: collectionView, form: false)
+    }
+    
+    // MARK: DZNEmpty
+    
+    func backgroundColor(forEmptyDataSet scrollView: UIScrollView) -> UIColor? {
+        return NCBrandColor.sharedInstance.backgroundView
+    }
+    
+    func image(forEmptyDataSet scrollView: UIScrollView) -> UIImage? {
+        return CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 300, height: 300, color: NCBrandColor.sharedInstance.yellowFavorite)
+    }
+    
+    func title(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
+        let text = "\n"+NSLocalizedString("_favorite_no_files_", comment: "")
+        let attributes = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20), NSAttributedString.Key.foregroundColor: UIColor.lightGray]
+        return NSAttributedString.init(string: text, attributes: attributes)
+    }
+    
+    func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
+        let text = "\n"+NSLocalizedString("_tutorial_favorite_view_", comment: "")
+        let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor.lightGray]
+        return NSAttributedString.init(string: text, attributes: attributes)
+    }
+    
+    func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView) -> Bool {
+        return true
+    }
+    
+    // MARK: TAP EVENT
+    
+    func tapSwitchHeader(sender: Any) {
+        
+        if collectionView.collectionViewLayout == gridLayout {
+            // list layout
+            UIView.animate(withDuration: 0.0, animations: {
+                self.collectionView.collectionViewLayout.invalidateLayout()
+                self.collectionView.setCollectionViewLayout(self.listLayout, animated: false, completion: { (_) in
+                    self.collectionView.reloadData()
+                    self.collectionView.setContentOffset(CGPoint(x:0,y:0), animated: false)
+                })
+            })
+            typeLayout = k_layout_list
+            NCUtility.shared.setLayoutForView(key: k_layout_view_favorite, layout: typeLayout)
+        } else {
+            // grid layout
+            UIView.animate(withDuration: 0.0, animations: {
+                self.collectionView.collectionViewLayout.invalidateLayout()
+                self.collectionView.setCollectionViewLayout(self.gridLayout, animated: false, completion: { (_) in
+                    self.collectionView.reloadData()
+                    self.collectionView.setContentOffset(CGPoint(x:0,y:0), animated: false)
+                })
+            })
+            typeLayout = k_layout_grid
+            NCUtility.shared.setLayoutForView(key: k_layout_view_favorite, layout: typeLayout)
+        }
+    }
+    
+    func tapOrderHeader(sender: Any) {
+        
+        let sortMenu = NCSortMenu()
+        sortMenu.toggleMenu(viewController: self, layout: k_layout_view_favorite, sortButton: sender as? UIButton, serverUrl: serverUrl)
+    }
+    
+    func tapMoreHeader(sender: Any) {
+        
+    }
+    
+    func tapMoreListItem(with objectId: String, sender: Any) {
+        tapMoreGridItem(with: objectId, sender: sender)
+    }
+    
+    func tapShareListItem(with objectId: String, sender: Any) {
+        
+        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", objectId)) else {
+            return
+        }
+        
+        NCMainCommon.sharedInstance.openShare(ViewController: self, metadata: metadata, indexPage: 2)
+    }
+    
+    func tapMoreGridItem(with objectId: String, sender: Any) {
+        
+        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", objectId)) else { return }
+        guard let tabBarController = self.tabBarController else { return }
+        
+        toggleMoreMenu(viewController: tabBarController, metadata: metadata)
+    }
+    
+    // MARK: SEGUE
+    
+    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
+        
+        let photoDataSource: NSMutableArray = []
+        
+        for ocId: String in sectionDatasource.allOcId as! [String] {
+            let metadata = sectionDatasource.allRecordsDataSource.object(forKey: ocId) as! tableMetadata
+            if metadata.typeFile == k_metadataTypeFile_image {
+                photoDataSource.add(metadata)
+            }
+        }
+        
+        if let segueNavigationController = segue.destination as? UINavigationController {
+            if let segueViewController = segueNavigationController.topViewController as? NCDetailViewController {
+            
+                segueViewController.metadata = metadataPush
+            }
+        }
+    }
+}
+
+// MARK: - 3D Touch peek and pop
+
+extension NCFavorite: UIViewControllerPreviewingDelegate {
+    
+    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
+        
+        guard let point = collectionView?.convert(location, from: collectionView?.superview) else { return nil }
+        guard let indexPath = collectionView?.indexPathForItem(at: point) else { return nil }
+        guard let metadata = NCMainCommon.sharedInstance.getMetadataFromSectionDataSourceIndexPath(indexPath, sectionDataSource: sectionDatasource) else { return nil }
+        guard let viewController = UIStoryboard(name: "CCPeekPop", bundle: nil).instantiateViewController(withIdentifier: "PeekPopImagePreview") as? CCPeekPop else { return nil }
+
+        viewController.metadata = metadata
+
+        if typeLayout == k_layout_grid {
+            guard let cell = collectionView?.cellForItem(at: indexPath) as? NCGridCell else { return nil }
+            previewingContext.sourceRect = cell.frame
+            viewController.imageFile = cell.imageItem.image
+        } else {
+            guard let cell = collectionView?.cellForItem(at: indexPath) as? NCListCell else { return nil }
+            previewingContext.sourceRect = cell.frame
+            viewController.imageFile = cell.imageItem.image
+        }
+        
+        viewController.showOpenIn = true
+        viewController.showOpenQuickLook = NCUtility.shared.isQuickLookDisplayable(metadata: metadata)
+        viewController.showShare = false
+        
+        return viewController
+    }
+    
+    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
+        
+        guard let indexPath = collectionView?.indexPathForItem(at: previewingContext.sourceRect.origin) else { return }
+        
+        collectionView(collectionView, didSelectItemAt: indexPath)
+    }
+}
+
+// MARK: - Collection View
+
+extension NCFavorite: UICollectionViewDelegate {
+
+    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        
+        guard let metadata = NCMainCommon.sharedInstance.getMetadataFromSectionDataSourceIndexPath(indexPath, sectionDataSource: sectionDatasource) else {
+            return
+        }
+        metadataPush = metadata
+        
+        if isEditMode {
+            if let index = selectocId.firstIndex(of: metadata.ocId) {
+                selectocId.remove(at: index)
+            } else {
+                selectocId.append(metadata.ocId)
+            }
+            collectionView.reloadItems(at: [indexPath])
+            return
+        }
+        
+        if metadata.directory {
+            
+            guard let serverUrlPush = CCUtility.stringAppendServerUrl(metadataPush!.serverUrl, addFileName: metadataPush!.fileName) else { return }
+            let ncFavorite:NCFavorite = UIStoryboard(name: "NCFavorite", bundle: nil).instantiateInitialViewController() as! NCFavorite
+            
+            ncFavorite.serverUrl = serverUrlPush
+            ncFavorite.titleCurrentFolder = metadataPush!.fileNameView
+            
+            self.navigationController?.pushViewController(ncFavorite, animated: true)
+            
+        } else {
+            
+            performSegue(withIdentifier: "segueDetail", sender: self)
+        }
+    }
+}
+
+extension NCFavorite: UICollectionViewDataSource {
+
+    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
+        
+        if (indexPath.section == 0) {
+            
+            if kind == UICollectionView.elementKindSectionHeader {
+                
+                let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeaderMenu", for: indexPath) as! NCSectionHeaderMenu
+                
+                if collectionView.collectionViewLayout == gridLayout {
+                    header.buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
+                } else {
+                    header.buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchGrid"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
+                }
+                
+                header.delegate = self
+                header.backgroundColor = NCBrandColor.sharedInstance.backgroundView
+                header.separator.backgroundColor = NCBrandColor.sharedInstance.separator
+                header.setStatusButton(count: sectionDatasource.allOcId.count)
+                header.setTitleSorted(datasourceTitleButton: self.datasourceTitleButton)
+                
+                if datasourceGroupBy == "none" {
+                    header.labelSection.isHidden = true
+                    header.labelSectionHeightConstraint.constant = 0
+                } else {
+                    header.labelSection.isHidden = false
+                    header.setTitleLabel(sectionDatasource: sectionDatasource, section: indexPath.section)
+                    header.labelSectionHeightConstraint.constant = sectionHeaderHeight
+                }
+                
+                return header
+                
+            } else {
+                
+                let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFooter", for: indexPath) as! NCSectionFooter
+                
+                footer.setTitleLabel(sectionDatasource: sectionDatasource)
+                
+                return footer
+            }
+            
+        } else {
+            
+            if kind == UICollectionView.elementKindSectionHeader {
+                
+                let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeader", for: indexPath) as! NCSectionHeader
+                
+                header.setTitleLabel(sectionDatasource: sectionDatasource, section: indexPath.section)
+                
+                return header
+                
+            } else {
+                
+                let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFooter", for: indexPath) as! NCSectionFooter
+                
+                footer.setTitleLabel(sectionDatasource: sectionDatasource)
+                
+                return footer
+            }
+        }
+    }
+    
+    func numberOfSections(in collectionView: UICollectionView) -> Int {
+        let sections = sectionDatasource.sectionArrayRow.allKeys.count
+        return sections
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        let key = sectionDatasource.sections.object(at: section)
+        let datasource = sectionDatasource.sectionArrayRow.object(forKey: key) as! [tableMetadata]
+        return datasource.count
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell: UICollectionViewCell
+        
+        guard let metadata = NCMainCommon.sharedInstance.getMetadataFromSectionDataSourceIndexPath(indexPath, sectionDataSource: sectionDatasource) else {
+            return collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
+        }
+        
+        if typeLayout == k_layout_grid {
+            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell
+        } else {
+            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
+            (cell as! NCListCell).separator.backgroundColor = NCBrandColor.sharedInstance.separator
+        }
+        
+        let shares = NCManageDatabase.sharedInstance.getTableShares(account: metadata.account, serverUrl: metadata.serverUrl, fileName: metadata.fileName)
+        
+        NCMainCommon.sharedInstance.collectionViewCellForItemAt(indexPath, collectionView: collectionView, cell: cell, metadata: metadata, metadataFolder: nil, serverUrl: metadata.serverUrl, isEditMode: isEditMode, selectocId: selectocId, autoUploadFileName: autoUploadFileName, autoUploadDirectory: autoUploadDirectory, hideButtonMore: false, downloadThumbnail: true, shares: shares, source: self)
+        
+        return cell
+    }
+}
+
+extension NCFavorite: UICollectionViewDelegateFlowLayout {
+
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
+        if section == 0 {
+            if datasourceGroupBy == "none" {
+                return CGSize(width: collectionView.frame.width, height: headerMenuHeight)
+            } else {
+                return CGSize(width: collectionView.frame.width, height: headerMenuHeight + sectionHeaderHeight)
+            }
+        } else {
+            return CGSize(width: collectionView.frame.width, height: sectionHeaderHeight)
+        }
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
+        let sections = sectionDatasource.sectionArrayRow.allKeys.count
+        if (section == sections - 1) {
+            return CGSize(width: collectionView.frame.width, height: footerHeight)
+        } else {
+            return CGSize(width: collectionView.frame.width, height: 0)
+        }
+    }
+}
+
+// MARK: - NC API & Algorithm
+
+extension NCFavorite {
+
+    @objc func reloadDataSource() {
+        
+        var datasourceSorted: String
+        var datasourceAscending: Bool
+        var datasourceDirectoryOnTop: Bool
+        
+        sectionDatasource = CCSectionDataSourceMetadata()
+        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_favorite)
+        
+        if serverUrl == "" {
+            
+            let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND favorite == true", appDelegate.account))
+            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, directoryOnTop:datasourceDirectoryOnTop, account: appDelegate.account)
+            
+        } else {
+            
+            let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl))
+            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, directoryOnTop:datasourceDirectoryOnTop, account: appDelegate.account)
+        }
+        
+        collectionView.reloadData()
+    }
+    
+    private func readFolder() {
+        NCNetworking.shared.readFolder(serverUrl: serverUrl, account: appDelegate.account) { (account, metadataFolder, metadatas, metadatasUpdate, metadatasLocalUpdate, errorCode, errorDescription) in
+            if errorCode == 0 {
+                for metadata in metadatas ?? [] {
+                    if !metadata.directory {
+                        let localFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+                        if localFile == nil || localFile?.etag != metadata.etag {
+                            NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
+                        }
+                    }
+                }
+                self.reloadDataSource()
+            }
+        }
+    }
+    
+    private func listingFavorites() {
+        NCNetworking.shared.listingFavoritescompletion(selector: selectorListingFavorite) { (account, metadatas, errorCode, errorDescription) in
+            if errorCode == 0 {
+                for metadata in metadatas ?? [] {
+                    if !metadata.directory && CCUtility.getFavoriteOffline() {
+                        let localFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+                        if localFile == nil || localFile?.etag != metadata.etag {
+                            NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
+                        }
+                    }
+                }
+                self.reloadDataSource()
+            }
+        }
+    }
+}

+ 2 - 2
iOSClient/Main/CCMain.m

@@ -1984,7 +1984,7 @@
         }
         }
         
         
         // [CCUtility getGroupBySettings]
         // [CCUtility getGroupBySettings]
-        sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:metadatas listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:@"fileName" ascending:NO account:appDelegate.account];
+        sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:metadatas listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:@"fileName" ascending:NO directoryOnTop:NO account:appDelegate.account];
 
 
         [self tableViewReloadData];
         [self tableViewReloadData];
         
         
@@ -2019,7 +2019,7 @@
         NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.account, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO];
         NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.account, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO];
         
         
         // [CCUtility getGroupBySettings]
         // [CCUtility getGroupBySettings]
-        CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:[CCUtility getOrderSettings] ascending:[CCUtility getAscendingSettings] account:appDelegate.account];
+        CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:[CCUtility getOrderSettings] ascending:[CCUtility getAscendingSettings] directoryOnTop:[CCUtility getDirectoryOnTop] account:appDelegate.account];
             
             
         dispatch_async(dispatch_get_main_queue(), ^{
         dispatch_async(dispatch_get_main_queue(), ^{
             sectionDataSource = sectionDataSourceTemp;
             sectionDataSource = sectionDataSourceTemp;

+ 1 - 2
iOSClient/Main/CCMore.swift

@@ -63,9 +63,8 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
 
 
         // Notification
         // Notification
         NotificationCenter.default.addObserver(self, selector: #selector(changeUserProfile), name: NSNotification.Name(rawValue: k_notificationCenter_changeUserProfile), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeUserProfile), name: NSNotification.Name(rawValue: k_notificationCenter_changeUserProfile), object: nil)
-
-        // Theming view
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        
         changeTheming()
         changeTheming()
     }
     }
 
 

+ 1 - 1
iOSClient/Main/CCSection.h

@@ -45,7 +45,7 @@
 
 
 @interface CCSectionMetadata : NSObject
 @interface CCSectionMetadata : NSObject
 
 
-+ (CCSectionDataSourceMetadata *)creataDataSourseSectionMetadata:(NSArray *)arrayMetadatas listProgressMetadata:(NSMutableDictionary *)listProgressMetadata groupByField:(NSString *)groupByField filterTypeFileImage:(BOOL)filterTypeFileImage filterTypeFileVideo:(BOOL)filterTypeFileVideo filterLivePhoto:(BOOL)filterLivePhoto sorted:(NSString *)sorted ascending:(BOOL)ascending account:(NSString *)account;
++ (CCSectionDataSourceMetadata *)creataDataSourseSectionMetadata:(NSArray *)arrayMetadatas listProgressMetadata:(NSMutableDictionary *)listProgressMetadata groupByField:(NSString *)groupByField filterTypeFileImage:(BOOL)filterTypeFileImage filterTypeFileVideo:(BOOL)filterTypeFileVideo filterLivePhoto:(BOOL)filterLivePhoto sorted:(NSString *)sorted ascending:(BOOL)ascending directoryOnTop:(BOOL)directoryOnTop account:(NSString *)account;
 
 
 + (void)removeAllObjectsSectionDataSource:(CCSectionDataSourceMetadata *)sectionDataSource;
 + (void)removeAllObjectsSectionDataSource:(CCSectionDataSourceMetadata *)sectionDataSource;
 
 

+ 1 - 2
iOSClient/Main/CCSection.m

@@ -76,7 +76,7 @@
 //
 //
 // orderByField : nil, date, typeFile
 // orderByField : nil, date, typeFile
 //
 //
-+ (CCSectionDataSourceMetadata *)creataDataSourseSectionMetadata:(NSArray *)arrayMetadatas listProgressMetadata:(NSMutableDictionary *)listProgressMetadata groupByField:(NSString *)groupByField filterTypeFileImage:(BOOL)filterTypeFileImage filterTypeFileVideo:(BOOL)filterTypeFileVideo filterLivePhoto:(BOOL)filterLivePhoto sorted:(NSString *)sorted ascending:(BOOL)ascending account:(NSString *)account
++ (CCSectionDataSourceMetadata *)creataDataSourseSectionMetadata:(NSArray *)arrayMetadatas listProgressMetadata:(NSMutableDictionary *)listProgressMetadata groupByField:(NSString *)groupByField filterTypeFileImage:(BOOL)filterTypeFileImage filterTypeFileVideo:(BOOL)filterTypeFileVideo filterLivePhoto:(BOOL)filterLivePhoto sorted:(NSString *)sorted ascending:(BOOL)ascending directoryOnTop:(BOOL)directoryOnTop account:(NSString *)account
 {
 {
     id dataSection;
     id dataSection;
     
     
@@ -124,7 +124,6 @@
     
     
     NSInteger numDirectory = 0;
     NSInteger numDirectory = 0;
     NSInteger numDirectoryFavorite = 0;
     NSInteger numDirectoryFavorite = 0;
-    BOOL directoryOnTop = [CCUtility getDirectoryOnTop];
     NSMutableArray *metadataFilesFavorite = [NSMutableArray new];
     NSMutableArray *metadataFilesFavorite = [NSMutableArray new];
     
     
     for (tableMetadata *metadata in arraySoprtedMetadatas) {
     for (tableMetadata *metadata in arraySoprtedMetadatas) {

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift

@@ -85,8 +85,8 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
             })
             })
         }
         }
         
         
-        // Theming view
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+
         changeTheming()
         changeTheming()
     }
     }
     
     

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift

@@ -74,8 +74,8 @@ import NCCommunication
         // title 
         // title 
         self.title = titleForm
         self.title = titleForm
       
       
-        // Theming view
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+
         changeTheming()
         changeTheming()
         
         
         // load the templates available
         // load the templates available

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift

@@ -81,8 +81,8 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         //        let rowCell = row.cell(forForm: self)
         //        let rowCell = row.cell(forForm: self)
         //        rowCell.becomeFirstResponder()
         //        rowCell.becomeFirstResponder()
         
         
-        // Theming view
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+
         changeTheming()
         changeTheming()
         
         
         let value = CCUtility.getTextRecognitionStatus()
         let value = CCUtility.getTextRecognitionStatus()

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift

@@ -87,8 +87,8 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
         progressView.progressTintColor = .green
         progressView.progressTintColor = .green
         progressView.trackTintColor = UIColor(red: 247.0/255.0, green: 247.0/255.0, blue: 247.0/255.0, alpha: 1.0)
         progressView.trackTintColor = UIColor(red: 247.0/255.0, green: 247.0/255.0, blue: 247.0/255.0, alpha: 1.0)
         
         
-        // Theming view
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+
         changeTheming()
         changeTheming()
     }
     }
     
     

+ 159 - 0
iOSClient/Main/Menu/NCSortMenu.swift

@@ -0,0 +1,159 @@
+//
+//  NCSortMenu.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 27/08/2020.
+//  Copyright © 2020 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 <http://www.gnu.org/licenses/>.
+//
+
+import FloatingPanel
+import NCCommunication
+
+class NCSortMenu: NSObject {
+    
+    private var sortButton: UIButton?
+    private var serverUrl: String?
+    private var hideDirectoryOnTop: Bool?
+    
+    private var layout = ""
+    private var typeLayout = ""
+    private var datasourceSorted = ""
+    private var datasourceAscending = true
+    private var datasourceGroupBy = ""
+    private var datasourceDirectoryOnTop = false
+    private var datasourceTitleButton = ""
+    
+    @objc func toggleMenu(viewController: UIViewController, layout: String, sortButton: UIButton?, serverUrl: String?, hideDirectoryOnTop: Bool = false) {
+        
+        self.layout = layout
+        self.sortButton = sortButton
+        self.serverUrl = serverUrl
+        self.hideDirectoryOnTop = hideDirectoryOnTop
+        
+        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: layout)
+
+        let mainMenuViewController = UIStoryboard.init(name: "NCMenu", bundle: nil).instantiateViewController(withIdentifier: "NCMainMenuTableViewController") as! NCMainMenuTableViewController
+        mainMenuViewController.actions = self.initSortMenu()
+
+        let menuPanelController = NCMenuPanelController()
+        menuPanelController.parentPresenter = viewController
+        menuPanelController.delegate = mainMenuViewController
+        menuPanelController.set(contentViewController: mainMenuViewController)
+        menuPanelController.track(scrollView: mainMenuViewController.tableView)
+
+        viewController.present(menuPanelController, animated: true, completion: nil)
+    }
+    
+    @objc func actionMenu() {
+                
+        switch datasourceSorted {
+        case "fileName":
+            self.datasourceTitleButton = datasourceAscending ? "_sorted_by_name_a_z_" : "_sorted_by_name_z_a_"
+        case "date":
+            self.datasourceTitleButton = datasourceAscending ? "_sorted_by_date_less_recent_" : "_sorted_by_date_more_recent_"
+        case "size":
+            self.datasourceTitleButton = datasourceAscending ? "_sorted_by_size_largest_" : "_sorted_by_size_smallest_"
+        default:
+            break
+        }
+        
+        self.sortButton?.setTitle(NSLocalizedString(self.datasourceTitleButton, comment: ""), for: .normal)
+        
+        NCUtility.shared.setLayoutForView(key: self.layout, layout: self.typeLayout, sort: self.datasourceSorted, ascending: self.datasourceAscending, groupBy: self.datasourceGroupBy, directoryOnTop: self.datasourceDirectoryOnTop, titleButton: self.datasourceTitleButton)
+        
+        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":self.serverUrl ?? ""])
+    }
+
+    private func initSortMenu() -> [NCMenuAction] {
+        var actions = [NCMenuAction]()
+
+        actions.append(
+            NCMenuAction(
+                title: NSLocalizedString("_order_by_name_a_z_", comment: ""),
+                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortFileNameAZ"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                onTitle: NSLocalizedString("_order_by_name_z_a_", comment: ""),
+                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortFileNameZA"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                selected: self.datasourceSorted == "fileName",
+                on: self.datasourceSorted == "fileName",
+                action: { menuAction in
+                    if self.datasourceSorted == "fileName" {
+                        self.datasourceAscending = !self.datasourceAscending
+                    } else {
+                        self.datasourceSorted = "fileName"
+                    }
+                    self.actionMenu()
+                }
+            )
+        )
+
+        actions.append(
+            NCMenuAction(
+                title: NSLocalizedString("_order_by_date_more_recent_", comment: ""),
+                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortDateMoreRecent"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                onTitle: NSLocalizedString("_order_by_date_less_recent_", comment: ""),
+                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortDateLessRecent"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                selected: self.datasourceSorted == "date",
+                on: self.datasourceSorted == "date",
+                action: { menuAction in
+                    if self.datasourceSorted == "date" {
+                        self.datasourceAscending = !self.datasourceAscending
+                    } else {
+                        self.datasourceSorted = "date"
+                    }
+                    self.actionMenu()
+                }
+            )
+        )
+
+        actions.append(
+            NCMenuAction(
+                title: NSLocalizedString("_order_by_size_smallest_", comment: ""),
+                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortSmallest"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                onTitle: NSLocalizedString("_order_by_size_largest_", comment: ""),
+                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortLargest"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                selected: self.datasourceSorted == "size",
+                on: self.datasourceSorted == "size",
+                action: { menuAction in
+                    if self.datasourceSorted == "size" {
+                        self.datasourceAscending = !self.datasourceAscending
+                    } else {
+                        self.datasourceSorted = "size"
+                    }
+                    self.actionMenu()
+                }
+            )
+        )
+
+        if !(hideDirectoryOnTop ?? false) {
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_directory_on_top_no_", comment: ""),
+                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "foldersOnTop"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+                    selected: self.datasourceDirectoryOnTop,
+                    on: self.datasourceDirectoryOnTop,
+                    action: { menuAction in
+                        self.datasourceDirectoryOnTop = !self.datasourceDirectoryOnTop
+                        self.actionMenu()
+                    }
+                )
+            )
+        }
+        
+        return actions
+    }
+}

+ 1 - 0
iOSClient/Main/NCMasterNavigationController.swift

@@ -32,6 +32,7 @@ class NCMasterNavigationController: UINavigationController {
         self.delegate = self
         self.delegate = self
         
         
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        
         changeTheming()
         changeTheming()
     }
     }
     
     

+ 3 - 20
iOSClient/Main/Section/NCSectionHeaderFooter.swift

@@ -42,7 +42,7 @@ class NCSectionHeaderMenu: UICollectionReusableView {
         buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         
         
         buttonOrder.setTitle("", for: .normal)
         buttonOrder.setTitle("", for: .normal)
-        buttonOrder.setTitleColor(NCBrandColor.sharedInstance.icon, for: .normal)
+        buttonOrder.setTitleColor(NCBrandColor.sharedInstance.brandElement, for: .normal)
         
         
         buttonMore.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         buttonMore.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         
         
@@ -51,26 +51,9 @@ class NCSectionHeaderMenu: UICollectionReusableView {
         self.backgroundColor = NCBrandColor.sharedInstance.backgroundView
         self.backgroundColor = NCBrandColor.sharedInstance.backgroundView
     }
     }
     
     
-    func setTitleOrder(datasourceSorted: String, datasourceAscending: Bool) {
+    func setTitleSorted(datasourceTitleButton: String) {
         
         
-        // Order (∨∧▽△)
-        var title = ""
-        
-        switch datasourceSorted {
-        case "fileName":
-            if datasourceAscending == true { title = NSLocalizedString("_order_by_name_a_z_", comment: "") }
-            if datasourceAscending == false { title = NSLocalizedString("_order_by_name_z_a_", comment: "") }
-        case "date":
-            if datasourceAscending == false { title = NSLocalizedString("_order_by_date_more_recent_", comment: "") }
-            if datasourceAscending == true { title = NSLocalizedString("_order_by_date_less_recent_", comment: "") }
-        case "size":
-            if datasourceAscending == true { title = NSLocalizedString("_order_by_size_smallest_", comment: "") }
-            if datasourceAscending == false { title = NSLocalizedString("_order_by_size_largest_", comment: "") }
-        default:
-            title = NSLocalizedString("_order_by_", comment: "") + " " + datasourceSorted
-        }
-        
-        title = title + "  ▽"
+        let title = NSLocalizedString(datasourceTitleButton, comment: "")
         let size = title.size(withAttributes:[.font: buttonOrder.titleLabel?.font as Any])
         let size = title.size(withAttributes:[.font: buttonOrder.titleLabel?.font as Any])
         
         
         buttonOrder.setTitle(title, for: .normal)
         buttonOrder.setTitle(title, for: .normal)

+ 1 - 1
iOSClient/Media/NCMedia.swift

@@ -24,7 +24,7 @@
 import Foundation
 import Foundation
 import NCCommunication
 import NCCommunication
 
 
-class NCMedia: UIViewController, DropdownMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, NCSelectDelegate {
+class NCMedia: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, NCSelectDelegate {
     
     
     @IBOutlet weak var collectionView : UICollectionView!
     @IBOutlet weak var collectionView : UICollectionView!
     
     

+ 26 - 155
iOSClient/Offline/NCOffline.swift

@@ -23,7 +23,7 @@
 
 
 import Foundation
 import Foundation
 
 
-class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DropdownMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate  {
+class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate  {
     
     
     @IBOutlet fileprivate weak var collectionView: UICollectionView!
     @IBOutlet fileprivate weak var collectionView: UICollectionView!
 
 
@@ -39,11 +39,9 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
     private var sectionDatasource = CCSectionDataSourceMetadata()
     private var sectionDatasource = CCSectionDataSourceMetadata()
     
     
     private var typeLayout = ""
     private var typeLayout = ""
-    private var datasourceSorted = ""
-    private var datasourceAscending = true
     private var datasourceGroupBy = ""
     private var datasourceGroupBy = ""
-    private var datasourceDirectoryOnTop = false
-    
+    private var datasourceTitleButton = ""
+
     private var autoUploadFileName = ""
     private var autoUploadFileName = ""
     private var autoUploadDirectory = ""
     private var autoUploadDirectory = ""
     
     
@@ -87,7 +85,7 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
         // Configure Refresh Control
         // Configure Refresh Control
         refreshControl.tintColor = NCBrandColor.sharedInstance.brandText
         refreshControl.tintColor = NCBrandColor.sharedInstance.brandText
         refreshControl.backgroundColor = NCBrandColor.sharedInstance.brandElement
         refreshControl.backgroundColor = NCBrandColor.sharedInstance.brandElement
-        refreshControl.addTarget(self, action: #selector(loadDatasource), for: .valueChanged)
+        refreshControl.addTarget(self, action: #selector(reloadDataSource), for: .valueChanged)
         
         
         // empty Data Source
         // empty Data Source
         self.collectionView.emptyDataSetDelegate = self
         self.collectionView.emptyDataSetDelegate = self
@@ -100,6 +98,7 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
         
         
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_deleteFile), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_deleteFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSource), object: nil)
 
 
         changeTheming()
         changeTheming()
     }
     }
@@ -108,20 +107,20 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
 
 
         self.navigationItem.title = titleCurrentFolder
         self.navigationItem.title = titleCurrentFolder
-        
-        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop) = NCUtility.shared.getLayoutForView(key: k_layout_view_offline)
-        
+                
         // get auto upload folder
         // get auto upload folder
         autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
         autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
         autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account)
         autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account)
         
         
+        (typeLayout, _, _, datasourceGroupBy, _, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_offline)
+
         if typeLayout == k_layout_list {
         if typeLayout == k_layout_list {
             collectionView.collectionViewLayout = listLayout
             collectionView.collectionViewLayout = listLayout
         } else {
         } else {
             collectionView.collectionViewLayout = gridLayout
             collectionView.collectionViewLayout = gridLayout
         }
         }
         
         
-        loadDatasource()
+        reloadDataSource()
     }
     }
     
     
     override func viewDidAppear(_ animated: Bool) {
     override func viewDidAppear(_ animated: Bool) {
@@ -148,7 +147,7 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
         if let userInfo = notification.userInfo as NSDictionary? {
         if let userInfo = notification.userInfo as NSDictionary? {
             if let errorCode = userInfo["errorCode"] as? Int, let errorDescription = userInfo["errorDescription"] as? String {
             if let errorCode = userInfo["errorCode"] as? Int, let errorDescription = userInfo["errorDescription"] as? String {
                 if errorCode == 0 {
                 if errorCode == 0 {
-                    self.loadDatasource()
+                    self.reloadDataSource()
                 } else {
                 } else {
                     NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
                     NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 }
                 }
@@ -194,7 +193,7 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
                 })
                 })
             })
             })
             typeLayout = k_layout_list
             typeLayout = k_layout_list
-            NCUtility.shared.setLayoutForView(key: k_layout_view_offline, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
+            NCUtility.shared.setLayoutForView(key: k_layout_view_offline, layout: typeLayout)
         } else {
         } else {
             // grid layout
             // grid layout
             UIView.animate(withDuration: 0.0, animations: {
             UIView.animate(withDuration: 0.0, animations: {
@@ -205,79 +204,14 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
                 })
                 })
             })
             })
             typeLayout = k_layout_grid
             typeLayout = k_layout_grid
-            NCUtility.shared.setLayoutForView(key: k_layout_view_offline, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
+            NCUtility.shared.setLayoutForView(key: k_layout_view_offline, layout: typeLayout)
         }
         }
     }
     }
     
     
     func tapOrderHeader(sender: Any) {
     func tapOrderHeader(sender: Any) {
         
         
-        var menuView: DropdownMenu?
-        var selectedIndexPath = [IndexPath()]
-        
-        let item1 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortFileNameAZ"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_name_a_z_", comment: ""))
-        let item2 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortFileNameZA"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_name_z_a_", comment: ""))
-        let item3 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortDateMoreRecent"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_date_more_recent_", comment: ""))
-        let item4 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortDateLessRecent"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_date_less_recent_", comment: ""))
-        let item5 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortSmallest"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_size_smallest_", comment: ""))
-        let item6 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortLargest"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_size_largest_", comment: ""))
-        
-        switch datasourceSorted {
-        case "fileName":
-            if datasourceAscending == true { item1.style = .highlight; selectedIndexPath.append(IndexPath(row: 0, section: 0)) }
-            if datasourceAscending == false { item2.style = .highlight; selectedIndexPath.append(IndexPath(row: 1, section: 0)) }
-        case "date":
-            if datasourceAscending == false { item3.style = .highlight; selectedIndexPath.append(IndexPath(row: 2, section: 0)) }
-            if datasourceAscending == true { item4.style = .highlight; selectedIndexPath.append(IndexPath(row: 3, section: 0)) }
-        case "size":
-            if datasourceAscending == true { item5.style = .highlight; selectedIndexPath.append(IndexPath(row: 4, section: 0)) }
-            if datasourceAscending == false { item6.style = .highlight; selectedIndexPath.append(IndexPath(row: 5, section: 0)) }
-        default:
-            ()
-        }
-        
-        let item7 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "MenuGroupByAlphabetic"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_group_alphabetic_no_", comment: ""))
-        let item8 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "MenuGroupByFile"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_group_typefile_no_", comment: ""))
-        let item9 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "MenuGroupByDate"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_group_date_no_", comment: ""))
-        
-        switch datasourceGroupBy {
-        case "alphabetic":
-            item7.style = .highlight; selectedIndexPath.append(IndexPath(row: 0, section: 1))
-        case "typefile":
-            item8.style = .highlight; selectedIndexPath.append(IndexPath(row: 1, section: 1))
-        case "date":
-            item9.style = .highlight; selectedIndexPath.append(IndexPath(row: 2, section: 1))
-        default:
-            ()
-        }
-        
-        let item10 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "foldersOnTop"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_directory_on_top_no_", comment: ""))
-        
-        if datasourceDirectoryOnTop {
-            item10.style = .highlight; selectedIndexPath.append(IndexPath(row: 0, section: 2))
-        }
-        
-        let sectionOrder = DropdownSection(sectionIdentifier: "", items: [item1, item2, item3, item4, item5, item6])
-        let sectionGroupBy = DropdownSection(sectionIdentifier: "", items: [item7, item8, item9])
-        let sectionFolderOnTop = DropdownSection(sectionIdentifier: "", items: [item10])
-        
-        menuView = DropdownMenu(navigationController: self.navigationController!, sections: [sectionOrder, sectionGroupBy, sectionFolderOnTop], selectedIndexPath: selectedIndexPath)
-        menuView?.token = "tapOrderHeaderMenu"
-        menuView?.delegate = self
-        menuView?.rowHeight = 45
-        menuView?.sectionHeaderHeight = 0.3
-        menuView?.highlightColor = NCBrandColor.sharedInstance.brandElement
-        menuView?.tableView.alwaysBounceVertical = false
-        menuView?.tableViewSeperatorColor = NCBrandColor.sharedInstance.separator
-        menuView?.tableViewBackgroundColor = NCBrandColor.sharedInstance.backgroundForm
-        menuView?.cellBackgroundColor = NCBrandColor.sharedInstance.backgroundForm
-        menuView?.textColor = NCBrandColor.sharedInstance.textView
-        
-        let header = (sender as? UIButton)?.superview
-        let headerRect = self.collectionView.convert(header!.bounds, from: self.view)
-        let menuOffsetY = headerRect.height - headerRect.origin.y - 2
-        menuView?.topOffsetY = CGFloat(menuOffsetY)
-        
-        menuView?.showMenu()
+        let sortMenu = NCSortMenu()
+        sortMenu.toggleMenu(viewController: self, layout: k_layout_view_offline, sortButton: sender as? UIButton, serverUrl: serverUrl)
     }
     }
     
     
     func tapMoreHeader(sender: Any) {
     func tapMoreHeader(sender: Any) {
@@ -334,7 +268,7 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
                             } else {
                             } else {
                                 NCManageDatabase.sharedInstance.setLocalFile(ocId: metadata.ocId, offline: false)
                                 NCManageDatabase.sharedInstance.setLocalFile(ocId: metadata.ocId, offline: false)
                             }
                             }
-                            self.loadDatasource()
+                            self.reloadDataSource()
                         }
                         }
                     )
                     )
                 )
                 )
@@ -376,74 +310,6 @@ class NCOffline: UIViewController, UIGestureRecognizerDelegate, NCListCellDelega
         }
         }
     }
     }
     
     
-    // MARK: DROP-DOWN-MENU
-
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, didSelectRowAt indexPath: IndexPath) {
-        
-        if dropdownMenu.token == "tapOrderHeaderMenu" {
-            
-            switch indexPath.section {
-            
-                    case 0: switch indexPath.row {
-                        
-                    case 0: datasourceSorted = "fileName"; datasourceAscending = true
-                    case 1: datasourceSorted = "fileName"; datasourceAscending = false
-                        
-                    case 2: datasourceSorted = "date"; datasourceAscending = false
-                    case 3: datasourceSorted = "date"; datasourceAscending = true
-                        
-                    case 4: datasourceSorted = "size"; datasourceAscending = true
-                    case 5: datasourceSorted = "size"; datasourceAscending = false
-                
-                    default: ()
-                    }
-                
-            case 1: switch indexPath.row {
-                
-                    case 0:
-                        if datasourceGroupBy == "alphabetic" {
-                            datasourceGroupBy = "none"
-                        } else {
-                            datasourceGroupBy = "alphabetic"
-                        }
-                    case 1:
-                        if datasourceGroupBy == "typefile" {
-                            datasourceGroupBy = "none"
-                        } else {
-                            datasourceGroupBy = "typefile"
-                        }
-                    case 2:
-                        if datasourceGroupBy == "date" {
-                            datasourceGroupBy = "none"
-                        } else {
-                            datasourceGroupBy = "date"
-                        }
-                
-                    default: ()
-                        }
-                    case 2:
-                        if datasourceDirectoryOnTop {
-                            datasourceDirectoryOnTop = false
-                        } else {
-                            datasourceDirectoryOnTop = true
-                        }
-                    default: ()
-                    }
-            
-            NCUtility.shared.setLayoutForView(key: k_layout_view_offline, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
-
-            loadDatasource()
-        }
-        
-        if dropdownMenu.token == "tapMoreHeaderMenu" {
-        
-        }
-        
-        if dropdownMenu.token == "tapMoreHeaderMenuSelect" {
-            
-        }
-    }
-    
     // MARK: SEGUE
     // MARK: SEGUE
     
     
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
@@ -562,7 +428,7 @@ extension NCOffline: UICollectionViewDataSource {
                 header.backgroundColor = NCBrandColor.sharedInstance.backgroundView
                 header.backgroundColor = NCBrandColor.sharedInstance.backgroundView
                 header.separator.backgroundColor = NCBrandColor.sharedInstance.separator
                 header.separator.backgroundColor = NCBrandColor.sharedInstance.separator
                 header.setStatusButton(count: sectionDatasource.allOcId.count)
                 header.setStatusButton(count: sectionDatasource.allOcId.count)
-                header.setTitleOrder(datasourceSorted: datasourceSorted, datasourceAscending: datasourceAscending)
+                header.setTitleSorted(datasourceTitleButton: self.datasourceTitleButton)
                 
                 
                 if datasourceGroupBy == "none" {
                 if datasourceGroupBy == "none" {
                     header.labelSection.isHidden = true
                     header.labelSection.isHidden = true
@@ -667,11 +533,16 @@ extension NCOffline: UICollectionViewDelegateFlowLayout {
 
 
 extension NCOffline {
 extension NCOffline {
 
 
-    @objc func loadDatasource() {
+    @objc func reloadDataSource() {
         
         
         var ocIds: [String] = []
         var ocIds: [String] = []
-        sectionDatasource = CCSectionDataSourceMetadata()
+        var datasourceSorted: String
+        var datasourceAscending: Bool
+        var datasourceDirectoryOnTop: Bool
         
         
+        sectionDatasource = CCSectionDataSourceMetadata()
+        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_offline)
+
         if serverUrl == "" {
         if serverUrl == "" {
             
             
             if let directories = NCManageDatabase.sharedInstance.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", appDelegate.account), sorted: "serverUrl", ascending: true) {
             if let directories = NCManageDatabase.sharedInstance.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", appDelegate.account), sorted: "serverUrl", ascending: true) {
@@ -686,12 +557,12 @@ extension NCOffline {
             }
             }
             
             
             let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND ocId IN %@", appDelegate.account, ocIds))
             let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND ocId IN %@", appDelegate.account, ocIds))
-            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, account: appDelegate.account)
+            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, directoryOnTop:datasourceDirectoryOnTop, account: appDelegate.account)
             
             
         } else {
         } else {
             
             
             let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl))
             let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl))
-            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, account: appDelegate.account)
+            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, directoryOnTop:datasourceDirectoryOnTop, account: appDelegate.account)
         }
         }
         
         
         self.refreshControl.endRefreshing()
         self.refreshControl.endRefreshing()
@@ -710,7 +581,7 @@ extension NCOffline {
                         }
                         }
                     }
                     }
                 }
                 }
-                self.loadDatasource()
+                self.reloadDataSource()
             }
             }
         }
         }
     }
     }

+ 24 - 147
iOSClient/Select/NCSelect.swift

@@ -28,7 +28,7 @@ import NCCommunication
     @objc func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, buttonType: String, overwrite: Bool)
     @objc func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, buttonType: String, overwrite: Bool)
 }
 }
 
 
-class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DropdownMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
+class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
     
     
     @IBOutlet fileprivate weak var collectionView: UICollectionView!
     @IBOutlet fileprivate weak var collectionView: UICollectionView!
     @IBOutlet fileprivate weak var toolbar: UIView!
     @IBOutlet fileprivate weak var toolbar: UIView!
@@ -76,11 +76,9 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegat
     private var sectionDatasource = CCSectionDataSourceMetadata()
     private var sectionDatasource = CCSectionDataSourceMetadata()
     
     
     private var typeLayout = ""
     private var typeLayout = ""
-    private var datasourceSorted = ""
-    private var datasourceAscending = true
     private var datasourceGroupBy = ""
     private var datasourceGroupBy = ""
-    private var datasourceDirectoryOnTop = false
-    
+    private var datasourceTitleButton = ""
+
     private var autoUploadFileName = ""
     private var autoUploadFileName = ""
     private var autoUploadDirectory = ""
     private var autoUploadDirectory = ""
     
     
@@ -148,8 +146,9 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegat
         buttonDone1.layer.backgroundColor = NCBrandColor.sharedInstance.graySoft.withAlphaComponent(0.5).cgColor
         buttonDone1.layer.backgroundColor = NCBrandColor.sharedInstance.graySoft.withAlphaComponent(0.5).cgColor
         buttonDone1.setTitleColor(.black, for: .normal)
         buttonDone1.setTitleColor(.black, for: .normal)
                 
                 
-        // changeTheming
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSource), object: nil)
+
         changeTheming()
         changeTheming()
     }
     }
     
     
@@ -173,13 +172,13 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegat
         if hideButtonCreateFolder {
         if hideButtonCreateFolder {
             buttonCreateFolder.isHidden = true
             buttonCreateFolder.isHidden = true
         }
         }
-        
-        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop) = NCUtility.shared.getLayoutForView(key: layoutViewSelect)
-        
+                
         // get auto upload folder
         // get auto upload folder
         autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
         autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
         autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account)
         autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account)
         
         
+        (typeLayout, _, _, datasourceGroupBy, _, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: layoutViewSelect)
+        
         if typeLayout == k_layout_list {
         if typeLayout == k_layout_list {
             collectionView.collectionViewLayout = listLayout
             collectionView.collectionViewLayout = listLayout
         } else {
         } else {
@@ -301,7 +300,7 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegat
                 })
                 })
             })
             })
             typeLayout = k_layout_list
             typeLayout = k_layout_list
-            NCUtility.shared.setLayoutForView(key: layoutViewSelect, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
+            NCUtility.shared.setLayoutForView(key: layoutViewSelect, layout: typeLayout)
         } else {
         } else {
             // grid layout
             // grid layout
             UIView.animate(withDuration: 0.0, animations: {
             UIView.animate(withDuration: 0.0, animations: {
@@ -312,79 +311,14 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegat
                 })
                 })
             })
             })
             typeLayout = k_layout_grid
             typeLayout = k_layout_grid
-            NCUtility.shared.setLayoutForView(key: layoutViewSelect, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
+            NCUtility.shared.setLayoutForView(key: layoutViewSelect, layout: typeLayout)
         }
         }
     }
     }
     
     
     func tapOrderHeader(sender: Any) {
     func tapOrderHeader(sender: Any) {
         
         
-        var menuView: DropdownMenu?
-        var selectedIndexPath = [IndexPath()]
-        
-        let item1 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortFileNameAZ"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_name_a_z_", comment: ""))
-        let item2 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortFileNameZA"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_name_z_a_", comment: ""))
-        let item3 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortDateMoreRecent"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_date_more_recent_", comment: ""))
-        let item4 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortDateLessRecent"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_date_less_recent_", comment: ""))
-        let item5 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortSmallest"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_size_smallest_", comment: ""))
-        let item6 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortLargest"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_order_by_size_largest_", comment: ""))
-        
-        switch datasourceSorted {
-        case "fileName":
-            if datasourceAscending == true { item1.style = .highlight; selectedIndexPath.append(IndexPath(row: 0, section: 0)) }
-            if datasourceAscending == false { item2.style = .highlight; selectedIndexPath.append(IndexPath(row: 1, section: 0)) }
-        case "date":
-            if datasourceAscending == false { item3.style = .highlight; selectedIndexPath.append(IndexPath(row: 2, section: 0)) }
-            if datasourceAscending == true { item4.style = .highlight; selectedIndexPath.append(IndexPath(row: 3, section: 0)) }
-        case "size":
-            if datasourceAscending == true { item5.style = .highlight; selectedIndexPath.append(IndexPath(row: 4, section: 0)) }
-            if datasourceAscending == false { item6.style = .highlight; selectedIndexPath.append(IndexPath(row: 5, section: 0)) }
-        default:
-            ()
-        }
-        
-        let item7 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "MenuGroupByAlphabetic"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_group_alphabetic_no_", comment: ""))
-        let item8 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "MenuGroupByFile"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_group_typefile_no_", comment: ""))
-        let item9 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "MenuGroupByDate"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_group_date_no_", comment: ""))
-        
-        switch datasourceGroupBy {
-        case "alphabetic":
-            item7.style = .highlight; selectedIndexPath.append(IndexPath(row: 0, section: 1))
-        case "typefile":
-            item8.style = .highlight; selectedIndexPath.append(IndexPath(row: 1, section: 1))
-        case "date":
-            item9.style = .highlight; selectedIndexPath.append(IndexPath(row: 2, section: 1))
-        default:
-            ()
-        }
-        
-        let item10 = DropdownItem(image: CCGraphics.changeThemingColorImage(UIImage.init(named: "foldersOnTop"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), title: NSLocalizedString("_directory_on_top_no_", comment: ""))
-        
-        if datasourceDirectoryOnTop {
-            item10.style = .highlight; selectedIndexPath.append(IndexPath(row: 0, section: 2))
-        }
-        
-        let sectionOrder = DropdownSection(sectionIdentifier: "", items: [item1, item2, item3, item4, item5, item6])
-        let sectionGroupBy = DropdownSection(sectionIdentifier: "", items: [item7, item8, item9])
-        let sectionFolderOnTop = DropdownSection(sectionIdentifier: "", items: [item10])
-        
-        menuView = DropdownMenu(navigationController: self.navigationController!, sections: [sectionOrder, sectionGroupBy, sectionFolderOnTop], selectedIndexPath: selectedIndexPath)
-        menuView?.token = "tapOrderHeaderMenu"
-        menuView?.delegate = self
-        menuView?.rowHeight = 45
-        menuView?.sectionHeaderHeight = 8
-        menuView?.highlightColor = NCBrandColor.sharedInstance.brandElement
-        menuView?.tableView.alwaysBounceVertical = false
-        menuView?.tableViewSeperatorColor = NCBrandColor.sharedInstance.separator
-        menuView?.tableViewBackgroundColor = NCBrandColor.sharedInstance.backgroundForm
-        menuView?.cellBackgroundColor = NCBrandColor.sharedInstance.backgroundForm
-        menuView?.textColor = NCBrandColor.sharedInstance.textView
-        
-        let header = (sender as? UIButton)?.superview
-        let headerRect = self.collectionView.convert(header!.bounds, from: self.view)
-        let menuOffsetY =  headerRect.height - headerRect.origin.y - 2
-        menuView?.topOffsetY = CGFloat(menuOffsetY)
-        
-        menuView?.showMenu()
+        let sortMenu = NCSortMenu()
+        sortMenu.toggleMenu(viewController: self, layout: layoutViewSelect, sortButton: sender as? UIButton, serverUrl: serverUrl)
     }
     }
     
     
     func tapMoreHeader(sender: Any) {
     func tapMoreHeader(sender: Any) {
@@ -398,72 +332,6 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegat
     
     
     func tapShareListItem(with objectId: String, sender: Any) {
     func tapShareListItem(with objectId: String, sender: Any) {
     }
     }
-    
-    // MARK: DROP-DOWN-MENU
-    
-    func dropdownMenu(_ dropdownMenu: DropdownMenu, didSelectRowAt indexPath: IndexPath) {
-        
-        if dropdownMenu.token == "tapOrderHeaderMenu" {
-            
-            switch indexPath.section {
-                
-            case 0: switch indexPath.row {
-                
-                    case 0: datasourceSorted = "fileName"; datasourceAscending = true
-                    case 1: datasourceSorted = "fileName"; datasourceAscending = false
-                
-                    case 2: datasourceSorted = "date"; datasourceAscending = false
-                    case 3: datasourceSorted = "date"; datasourceAscending = true
-                
-                    case 4: datasourceSorted = "size"; datasourceAscending = true
-                    case 5: datasourceSorted = "size"; datasourceAscending = false
-                
-                    default: ()
-                    }
-                
-            case 1: switch indexPath.row {
-                
-                    case 0:
-                        if datasourceGroupBy == "alphabetic" {
-                            datasourceGroupBy = "none"
-                        } else {
-                            datasourceGroupBy = "alphabetic"
-                        }
-                    case 1:
-                        if datasourceGroupBy == "typefile" {
-                            datasourceGroupBy = "none"
-                        } else {
-                            datasourceGroupBy = "typefile"
-                        }
-                    case 2:
-                        if datasourceGroupBy == "date" {
-                            datasourceGroupBy = "none"
-                        } else {
-                            datasourceGroupBy = "date"
-                        }
-                
-                    default: ()
-                        }
-                    case 2:
-                        if datasourceDirectoryOnTop {
-                            datasourceDirectoryOnTop = false
-                        } else {
-                            datasourceDirectoryOnTop = true
-                        }
-                    default: ()
-                    }
-            
-            NCUtility.shared.setLayoutForView(key: layoutViewSelect, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
-            
-            loadDatasource(withLoadFolder: false)
-        }
-        
-        if dropdownMenu.token == "tapMoreHeaderMenu" {
-        }
-        
-        if dropdownMenu.token == "tapMoreHeaderMenuSelect" {
-        }
-    }
 }
 }
 
 
 // MARK: - Collection View
 // MARK: - Collection View
@@ -540,7 +408,7 @@ extension NCSelect: UICollectionViewDataSource {
                 header.delegate = self
                 header.delegate = self
                 
                 
                 header.setStatusButton(count: sectionDatasource.allOcId.count)
                 header.setStatusButton(count: sectionDatasource.allOcId.count)
-                header.setTitleOrder(datasourceSorted: datasourceSorted, datasourceAscending: datasourceAscending)
+                header.setTitleSorted(datasourceTitleButton: self.datasourceTitleButton)
                 
                 
                 if datasourceGroupBy == "none" {
                 if datasourceGroupBy == "none" {
                     header.labelSection.isHidden = true
                     header.labelSection.isHidden = true
@@ -653,10 +521,19 @@ extension NCSelect: UICollectionViewDelegateFlowLayout {
 
 
 extension NCSelect {
 extension NCSelect {
 
 
+    @objc func reloadDataSource() {
+        loadDatasource(withLoadFolder: false)
+    }
+    
     @objc func loadDatasource(withLoadFolder: Bool) {
     @objc func loadDatasource(withLoadFolder: Bool) {
         
         
-        sectionDatasource = CCSectionDataSourceMetadata()
         var predicate: NSPredicate?
         var predicate: NSPredicate?
+        var datasourceSorted: String
+        var datasourceAscending: Bool
+        var datasourceDirectoryOnTop: Bool
+        
+        sectionDatasource = CCSectionDataSourceMetadata()
+        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: layoutViewSelect)
         
         
         if serverUrl == "" {
         if serverUrl == "" {
             
             
@@ -681,7 +558,7 @@ extension NCSelect {
         }
         }
         
         
         let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate!)
         let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate!)
-        sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: false, sorted: datasourceSorted, ascending: datasourceAscending, account: appDelegate.account)
+        sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: false, sorted: datasourceSorted, ascending: datasourceAscending, directoryOnTop:datasourceDirectoryOnTop, account: appDelegate.account)
         
         
         if withLoadFolder {
         if withLoadFolder {
             loadFolder()
             loadFolder()

+ 1 - 1
iOSClient/Transfers/CCTransfers.m

@@ -273,7 +273,7 @@
         
         
         CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionDataSourceMetadata new];
         CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionDataSourceMetadata new];
         
         
-        sectionDataSourceTemp  = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:appDelegate.listProgressMetadata groupByField:@"session" filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:NO sorted:@"fileName" ascending:YES account:appDelegate.account];
+        sectionDataSourceTemp  = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:appDelegate.listProgressMetadata groupByField:@"session" filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:NO sorted:@"fileName" ascending:YES directoryOnTop:NO account:appDelegate.account];
         
         
         dispatch_async(dispatch_get_main_queue(), ^{
         dispatch_async(dispatch_get_main_queue(), ^{
             sectionDataSource = sectionDataSourceTemp;
             sectionDataSource = sectionDataSourceTemp;

+ 21 - 96
iOSClient/Trash/NCTrash.swift

@@ -40,11 +40,9 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
     private var datasource: [tableTrash] = []
     private var datasource: [tableTrash] = []
     
     
     private var typeLayout = ""
     private var typeLayout = ""
-    private var datasourceSorted = ""
-    private var datasourceAscending = true
     private var datasourceGroupBy = "none"
     private var datasourceGroupBy = "none"
-    private var datasourceDirectoryOnTop = false
-    
+    private var datasourceTitleButton = ""
+
     private var listLayout: NCListLayout!
     private var listLayout: NCListLayout!
     private var gridLayout: NCGridLayout!
     private var gridLayout: NCGridLayout!
     
     
@@ -78,8 +76,9 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
         self.collectionView.emptyDataSetDelegate = self;
         self.collectionView.emptyDataSetDelegate = self;
         self.collectionView.emptyDataSetSource = self;
         self.collectionView.emptyDataSetSource = self;
         
         
-        // changeTheming
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSource), object: nil)
+
         changeTheming()
         changeTheming()
     }
     }
     
     
@@ -88,7 +87,7 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
         
         
         self.navigationItem.title = titleCurrentFolder
         self.navigationItem.title = titleCurrentFolder
 
 
-        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop) = NCUtility.shared.getLayoutForView(key: k_layout_view_trash)
+        (typeLayout, _, _, datasourceGroupBy, _, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_trash)
 
 
         if typeLayout == k_layout_list {
         if typeLayout == k_layout_list {
             collectionView.collectionViewLayout = listLayout
             collectionView.collectionViewLayout = listLayout
@@ -104,7 +103,7 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
         }
         }
         
         
         if (datasource.count == 0) {
         if (datasource.count == 0) {
-            loadDatasource()
+            reloadDataSource()
         }
         }
         
         
         loadListingTrash()
         loadListingTrash()
@@ -151,17 +150,6 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
         return true
         return true
     }
     }
     
     
-    func reloadSortOrder(){
-        NCUtility.shared.setLayoutForView(
-            key: k_layout_view_trash,
-            layout: self.typeLayout,
-            sort: self.datasourceSorted,
-            ascending: self.datasourceAscending,
-            groupBy: self.datasourceGroupBy,
-            directoryOnTop: self.datasourceDirectoryOnTop)
-        self.loadDatasource()
-    }
-
     // MARK: TAP EVENT
     // MARK: TAP EVENT
     
     
     func tapSwitchHeaderMenu(sender: Any) {
     func tapSwitchHeaderMenu(sender: Any) {
@@ -176,7 +164,7 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
                 })
                 })
             })
             })
             typeLayout = k_layout_list
             typeLayout = k_layout_list
-            NCUtility.shared.setLayoutForView(key: k_layout_view_trash, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
+            NCUtility.shared.setLayoutForView(key: k_layout_view_trash, layout: typeLayout)
         } else {
         } else {
             // grid layout
             // grid layout
             UIView.animate(withDuration: 0.0, animations: {
             UIView.animate(withDuration: 0.0, animations: {
@@ -187,81 +175,14 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
                 })
                 })
             })
             })
             typeLayout = k_layout_grid
             typeLayout = k_layout_grid
-            NCUtility.shared.setLayoutForView(key: k_layout_view_trash, layout: typeLayout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop)
+            NCUtility.shared.setLayoutForView(key: k_layout_view_trash, layout: typeLayout)
         }
         }
     }
     }
     
     
     func tapOrderHeaderMenu(sender: Any) {
     func tapOrderHeaderMenu(sender: Any) {
-        let mainMenuViewController = UIStoryboard.init(name: "NCMenu", bundle: nil).instantiateViewController(withIdentifier: "NCMainMenuTableViewController") as! NCMainMenuTableViewController
-        
-        var actions: [NCMenuAction] = []
-        
-        actions.append(
-            NCMenuAction(
-                title: NSLocalizedString("_order_by_name_a_z_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortFileNameAZ"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
-                onTitle: NSLocalizedString("_order_by_name_z_a_", comment: ""),
-                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortFileNameZA"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
-                selected: datasourceSorted == "fileName",
-                on: datasourceAscending,
-                action: { menuAction in
-                    if(self.datasourceSorted == "fileName"){
-                        self.datasourceAscending = !self.datasourceAscending
-                    } else {
-                        self.datasourceSorted = "fileName"
-                    }
-                    self.reloadSortOrder()
-                }
-            )
-        )
-        
-        actions.append(
-            NCMenuAction(
-                title: NSLocalizedString("_order_by_date_more_recent_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortDateMoreRecent"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
-                onTitle: NSLocalizedString("_order_by_date_less_recent_", comment: ""),
-                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortDateLessRecent"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
-                selected: datasourceSorted == "date",
-                on: datasourceAscending,
-                action: { menuAction in
-                    if(self.datasourceSorted == "date"){
-                        self.datasourceAscending = !self.datasourceAscending
-                    } else {
-                        self.datasourceSorted = "date"
-                    }
-                    self.reloadSortOrder()
-                }
-            )
-        )
-
-        actions.append(
-            NCMenuAction(
-                title: NSLocalizedString("_order_by_size_smallest_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortSmallest"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
-                onTitle: NSLocalizedString("_order_by_size_largest_", comment: ""),
-                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortLargest"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
-                selected: datasourceSorted == "size",
-                on: datasourceAscending,
-                action: { menuAction in
-                    if(self.datasourceSorted == "size"){
-                        self.datasourceAscending = !self.datasourceAscending
-                    } else {
-                        self.datasourceSorted = "size"
-                    }
-                    self.reloadSortOrder()
-                }
-            )
-        )
-    
-        mainMenuViewController.actions = actions
         
         
-        let menuPanelController = NCMenuPanelController()
-        menuPanelController.parentPresenter = self
-        menuPanelController.delegate = mainMenuViewController
-        menuPanelController.set(contentViewController: mainMenuViewController)
-        menuPanelController.track(scrollView: mainMenuViewController.tableView)
-
-        self.present(menuPanelController, animated: true, completion: nil)
+        let sortMenu = NCSortMenu()
+        sortMenu.toggleMenu(viewController: self, layout: k_layout_view_trash, sortButton: sender as? UIButton, serverUrl: nil, hideDirectoryOnTop: true)
     }
     }
     
     
     func tapMoreHeaderMenu(sender: Any) {
     func tapMoreHeaderMenu(sender: Any) {
@@ -501,8 +422,7 @@ extension NCTrash: UICollectionViewDataSource {
             trashHeader.backgroundColor = NCBrandColor.sharedInstance.backgroundView
             trashHeader.backgroundColor = NCBrandColor.sharedInstance.backgroundView
             trashHeader.separator.backgroundColor = NCBrandColor.sharedInstance.separator
             trashHeader.separator.backgroundColor = NCBrandColor.sharedInstance.separator
             trashHeader.setStatusButton(datasource: datasource)
             trashHeader.setStatusButton(datasource: datasource)
-            trashHeader.setTitleOrder(datasourceSorted: datasourceSorted, datasourceAscending: datasourceAscending)
-            
+            trashHeader.setTitleSorted(datasourceTitleButton: self.datasourceTitleButton)
             
             
             return trashHeader
             return trashHeader
             
             
@@ -632,7 +552,12 @@ extension NCTrash: UICollectionViewDelegateFlowLayout {
 
 
 extension NCTrash {
 extension NCTrash {
 
 
-    @objc func loadDatasource() {
+    @objc func reloadDataSource() {
+        
+        var datasourceSorted: String
+        var datasourceAscending: Bool
+        
+        (typeLayout, datasourceSorted, datasourceAscending, datasourceGroupBy, _, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_trash)
         
         
         datasource.removeAll()
         datasource.removeAll()
         
         
@@ -673,7 +598,7 @@ extension NCTrash {
                 print("[LOG] It has been changed user during networking process, error.")
                 print("[LOG] It has been changed user during networking process, error.")
             }
             }
             
             
-            self.loadDatasource()
+            self.reloadDataSource()
         }
         }
     }
     }
     
     
@@ -696,7 +621,7 @@ extension NCTrash {
         NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: true) { (account, errorCode, errorDescription) in
         NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: true) { (account, errorCode, errorDescription) in
             if errorCode == 0 && account == self.appDelegate.account {
             if errorCode == 0 && account == self.appDelegate.account {
                 NCManageDatabase.sharedInstance.deleteTrash(fileId: fileId, account: account)
                 NCManageDatabase.sharedInstance.deleteTrash(fileId: fileId, account: account)
-                self.loadDatasource()
+                self.reloadDataSource()
             }  else if errorCode != 0 {
             }  else if errorCode != 0 {
                 NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
             } else {
             } else {
@@ -717,7 +642,7 @@ extension NCTrash {
             } else {
             } else {
                 print("[LOG] It has been changed user during networking process, error.")
                 print("[LOG] It has been changed user during networking process, error.")
             }
             }
-            self.loadDatasource()
+            self.reloadDataSource()
         }
         }
     }
     }
     
     
@@ -732,7 +657,7 @@ extension NCTrash {
         NCCommunication.shared.deleteFileOrFolder(serverUrlFileName) { (account, errorCode, errorDescription) in
         NCCommunication.shared.deleteFileOrFolder(serverUrlFileName) { (account, errorCode, errorDescription) in
             if errorCode == 0 && account == self.appDelegate.account {
             if errorCode == 0 && account == self.appDelegate.account {
                 NCManageDatabase.sharedInstance.deleteTrash(fileId: fileId, account: account)
                 NCManageDatabase.sharedInstance.deleteTrash(fileId: fileId, account: account)
-                self.loadDatasource()
+                self.reloadDataSource()
             } else if errorCode != 0 {
             } else if errorCode != 0 {
                 NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
             } else {
             } else {

+ 3 - 20
iOSClient/Trash/Section/NCTrashSectionHeaderFooter.swift

@@ -39,7 +39,7 @@ class NCTrashSectionHeaderMenu: UICollectionReusableView {
         buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         
         
         buttonOrder.setTitle("", for: .normal)
         buttonOrder.setTitle("", for: .normal)
-        buttonOrder.setTitleColor(NCBrandColor.sharedInstance.icon, for: .normal)
+        buttonOrder.setTitleColor(NCBrandColor.sharedInstance.brandElement, for: .normal)
         
         
         buttonMore.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         buttonMore.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), multiplier: 2, color: NCBrandColor.sharedInstance.icon), for: .normal)
         
         
@@ -47,26 +47,9 @@ class NCTrashSectionHeaderMenu: UICollectionReusableView {
         backgroundColor = NCBrandColor.sharedInstance.backgroundView
         backgroundColor = NCBrandColor.sharedInstance.backgroundView
     }
     }
     
     
-    func setTitleOrder(datasourceSorted: String, datasourceAscending: Bool) {
+    func setTitleSorted(datasourceTitleButton: String) {
         
         
-        // Order (∨∧▽△)
-        var title = ""
-        
-        switch datasourceSorted {
-        case "fileName":
-            if datasourceAscending == true { title = NSLocalizedString("_order_by_name_a_z_", comment: "") }
-            if datasourceAscending == false { title = NSLocalizedString("_order_by_name_z_a_", comment: "") }
-        case "date":
-            if datasourceAscending == false { title = NSLocalizedString("_order_by_date_more_recent_", comment: "") }
-            if datasourceAscending == true { title = NSLocalizedString("_order_by_date_less_recent_", comment: "") }
-        case "size":
-            if datasourceAscending == true { title = NSLocalizedString("_order_by_size_smallest_", comment: "") }
-            if datasourceAscending == false { title = NSLocalizedString("_order_by_size_largest_", comment: "") }
-        default:
-            title = NSLocalizedString("_order_by_", comment: "") + " " + datasourceSorted
-        }
-        
-        title = title + "  ▽"
+        let title = NSLocalizedString(datasourceTitleButton, comment: "")
         let size = title.size(withAttributes:[.font: buttonOrder.titleLabel?.font as Any])
         let size = title.size(withAttributes:[.font: buttonOrder.titleLabel?.font as Any])
         
         
         buttonOrder.setTitle(title, for: .normal)
         buttonOrder.setTitle(title, for: .normal)

+ 29 - 8
iOSClient/Utility/NCUtility.swift

@@ -147,31 +147,52 @@ class NCUtility: NSObject {
         return blurEffectView
         return blurEffectView
     }
     }
     
     
-    func setLayoutForView(key: String, layout: String, sort: String, ascending: Bool, groupBy: String, directoryOnTop: Bool) {
+    func setLayoutForView(key: String, layout: String, sort: String, ascending: Bool, groupBy: String, directoryOnTop: Bool, titleButton: String) {
         
         
-        let string =  layout + "|" + sort + "|" + "\(ascending)" + "|" + groupBy + "|" + "\(directoryOnTop)"
+        let string =  layout + "|" + sort + "|" + "\(ascending)" + "|" + groupBy + "|" + "\(directoryOnTop)" + "|" + titleButton
         
         
         UICKeyChainStore.setString(string, forKey: key, service: k_serviceShareKeyChain)
         UICKeyChainStore.setString(string, forKey: key, service: k_serviceShareKeyChain)
     }
     }
     
     
-    func getLayoutForView(key: String) -> (String, String, Bool, String, Bool) {
+    func setLayoutForView(key: String, layout: String) {
+        
+        var datasourceSorted = ""
+        var datasourceAscending = true
+        var datasourceGroupBy = ""
+        var datasourceDirectoryOnTop = false
+        var datasourceTitleButton = ""
+
+        (_, datasourceSorted, datasourceAscending, datasourceGroupBy, datasourceDirectoryOnTop, datasourceTitleButton) = NCUtility.shared.getLayoutForView(key: k_layout_view_favorite)
+
+        setLayoutForView(key: key, layout: layout, sort: datasourceSorted, ascending: datasourceAscending, groupBy: datasourceGroupBy, directoryOnTop: datasourceDirectoryOnTop, titleButton: datasourceTitleButton)
+    }
+    
+    func getLayoutForView(key: String) -> (String) {
+        
+        var typeLayout = ""
+        
+        (typeLayout, _, _, _, _, _) = NCUtility.shared.getLayoutForView(key: key)
+        
+        return typeLayout
+    }
+    
+    func getLayoutForView(key: String) -> (String, String, Bool, String, Bool, String) {
         
         
         guard let string = UICKeyChainStore.string(forKey: key, service: k_serviceShareKeyChain) else {
         guard let string = UICKeyChainStore.string(forKey: key, service: k_serviceShareKeyChain) else {
-            return (k_layout_list, "fileName", true, "none", true)
+            return (k_layout_list, "fileName", true, "none", true, "_sorted_by_name_a_z_")
         }
         }
 
 
         let array = string.components(separatedBy: "|")
         let array = string.components(separatedBy: "|")
-        if array.count == 5 {
+        if array.count == 6 {
             let sort = NSString(string: array[2])
             let sort = NSString(string: array[2])
             let directoryOnTop = NSString(string: array[4])
             let directoryOnTop = NSString(string: array[4])
 
 
-            return (array[0], array[1], sort.boolValue, array[3], directoryOnTop.boolValue)
+            return (array[0], array[1], sort.boolValue, array[3], directoryOnTop.boolValue, array[5])
         }
         }
         
         
-        return (k_layout_list, "fileName", true, "none", true)
+        return (k_layout_list, "fileName", true, "none", true, "_sorted_by_name_a_z_")
     }
     }
     
     
-    
     func convertSVGtoPNGWriteToUserData(svgUrlString: String, fileName: String?, width: CGFloat?, rewrite: Bool, account: String, closure: @escaping (String?) -> ()) {
     func convertSVGtoPNGWriteToUserData(svgUrlString: String, fileName: String?, width: CGFloat?, rewrite: Bool, account: String, closure: @escaping (String?) -> ()) {
         
         
         var fileNamePNG = ""
         var fileNamePNG = ""