Browse Source

dark mode

marinofaggiana 5 years ago
parent
commit
fad86977f0

+ 8 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -556,6 +556,9 @@
 		F7DFB7F6219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7DFB7F5219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard */; };
 		F7E0E1DC22327885006B0911 /* NCAudioRecorderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E0E1DB22327885006B0911 /* NCAudioRecorderViewController.swift */; };
 		F7E0E1DE22327DBA006B0911 /* NCAudioRecorderViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */; };
+		F7E1ACCA234238C800AA040D /* NCCustomizableAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E1ACC9234238C800AA040D /* NCCustomizableAlertController.swift */; };
+		F7E1ACCB234238C800AA040D /* NCCustomizableAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E1ACC9234238C800AA040D /* NCCustomizableAlertController.swift */; };
+		F7E1ACCC234238C800AA040D /* NCCustomizableAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E1ACC9234238C800AA040D /* NCCustomizableAlertController.swift */; };
 		F7E4D9C422ED929B003675FD /* NCShareComments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E4D9C322ED929B003675FD /* NCShareComments.swift */; };
 		F7E9C41B20F4CA870040CF18 /* CCTransfers.m in Sources */ = {isa = PBXBuildFile; fileRef = F7E9C41820F4CA870040CF18 /* CCTransfers.m */; };
 		F7ECBA6D1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7ECBA6C1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift */; };
@@ -1336,6 +1339,7 @@
 		F7DFB7F5219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCCreateFormUploadRichdocuments.storyboard; sourceTree = "<group>"; };
 		F7E0E1DB22327885006B0911 /* NCAudioRecorderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCAudioRecorderViewController.swift; sourceTree = "<group>"; };
 		F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCAudioRecorderViewController.storyboard; sourceTree = "<group>"; };
+		F7E1ACC9234238C800AA040D /* NCCustomizableAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCCustomizableAlertController.swift; sourceTree = "<group>"; };
 		F7E45E6D21E75BF200579249 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F7E4D9C322ED929B003675FD /* NCShareComments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareComments.swift; sourceTree = "<group>"; };
 		F7E9C41520F4CA870040CF18 /* CCTransfers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTransfers.h; sourceTree = "<group>"; };
@@ -2419,6 +2423,7 @@
 			children = (
 				F70BFC7320E0FA7C00C67599 /* NCUtility.swift */,
 				F718088C2341FEB20039A736 /* NCActionSheetAppearance.swift */,
+				F7E1ACC9234238C800AA040D /* NCCustomizableAlertController.swift */,
 				F707C26421A2DC5200F6181E /* NCStoreReview.swift */,
 				F78E7064219F096B006F23E4 /* NCAvatar.swift */,
 				F76C3B871C638A4C00DC4301 /* CCError.h */,
@@ -3338,6 +3343,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				F7E1ACCB234238C800AA040D /* NCCustomizableAlertController.swift in Sources */,
 				F71459B81D12E3B700CAFEEC /* CCError.m in Sources */,
 				F73CC0701E813DFF006E3047 /* BKPasscodeInputView.m in Sources */,
 				F71459BA1D12E3B700CAFEEC /* NSString+TruncateToWidth.m in Sources */,
@@ -3442,6 +3448,7 @@
 				F7434B5B20E241D100417916 /* NCEndToEndMetadata.swift in Sources */,
 				F7B6ACDD22FC2D15008AB646 /* NCComments.m in Sources */,
 				F7434B5D20E241E800417916 /* CCUtility.m in Sources */,
+				F7E1ACCC234238C800AA040D /* NCCustomizableAlertController.swift in Sources */,
 				F7434B5220E2409900417916 /* OCXMLShareByLinkParser.m in Sources */,
 				F771E3D520E2392D00AFB62D /* FileProviderItem.swift in Sources */,
 				F7434B3620E23FE000417916 /* NCManageDatabase.swift in Sources */,
@@ -3572,6 +3579,7 @@
 				F70022E91EC4C9100080073F /* OCXMLShareByLinkParser.m in Sources */,
 				F77B0E311D118A16002130FE /* CCExifGeo.m in Sources */,
 				F73B4F0E1F470D9100BBEE4B /* nsMBCSGroupProber.cpp in Sources */,
+				F7E1ACCA234238C800AA040D /* NCCustomizableAlertController.swift in Sources */,
 				F7D423831F0596C6009C9782 /* ReaderThumbFetch.m in Sources */,
 				F73B4F171F470D9100BBEE4B /* uchardet.cpp in Sources */,
 				F7D4237A1F0596C6009C9782 /* ReaderConstants.m in Sources */,

+ 8 - 10
iOSClient/Main/NCPhotosPickerViewController.swift

@@ -85,19 +85,17 @@ class customPhotoPickerViewController: TLPhotosPickerViewController {
     override func makeUI() {
         super.makeUI()
         
-        self.customNavItem.leftBarButtonItem?.tintColor = NCBrandColor.sharedInstance.textView
-        self.customNavItem.rightBarButtonItem?.tintColor = NCBrandColor.sharedInstance.textView
+        self.navigationBar.barTintColor = NCBrandColor.sharedInstance.brand
+        self.navigationBar.tintColor = NCBrandColor.sharedInstance.brandText
         
-        self.titleLabel.textColor = NCBrandColor.sharedInstance.icon
-        self.subTitleLabel.textColor = NCBrandColor.sharedInstance.graySoft
-        self.subTitleArrowImageView.image = CCGraphics.changeThemingColorImage(self.subTitleArrowImageView.image, multiplier: 1, color: NCBrandColor.sharedInstance.graySoft)
+//        self.titleLabel.textColor = NCBrandColor.sharedInstance.brandText
+//        self.subTitleLabel.textColor = NCBrandColor.sharedInstance.brandText
+        self.subTitleArrowImageView.image = CCGraphics.changeThemingColorImage(self.subTitleArrowImageView.image, multiplier: 1, color: NCBrandColor.sharedInstance.brandText)
         
         self.collectionView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
         self.view.backgroundColor = NCBrandColor.sharedInstance.backgroundView
-        if CCUtility.getDarkMode() {
-            self.navigationBar.barStyle = .black
-        }
-        self.titleLabel.textColor = NCBrandColor.sharedInstance.textView
-        self.subTitleLabel.textColor = NCBrandColor.sharedInstance.textView
+    }
+    
+    open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
     }
 }

+ 334 - 0
iOSClient/Utility/NCCustomizableAlertController.swift

@@ -0,0 +1,334 @@
+//
+//  NCCustomizableAlertController.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 30/09/19.
+//  Copyright © 2018 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/>.
+//
+
+// Medium article
+//
+// https://medium.com/@Daniel_illescas/hacking-ios-alerts-with-swift-61aefce9736a
+
+import UIKit
+
+final class DarkAlertController: NCCustomizableAlertController {
+	
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		
+		self.visualEffectView?.effect = UIBlurEffect(style: .dark)
+		self.tintColor = UIColor(red: 0.4, green: 0.5, blue: 1.0, alpha: 1.0)
+		self.contentView?.backgroundColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 0.7)
+
+		let whiteStringAttribute = StringAttribute(key: .foregroundColor, value: UIColor.white)
+		self.titleAttributes = [whiteStringAttribute]
+		self.messageAttributes = [whiteStringAttribute]
+	}
+}
+
+//
+
+open class NCCustomizableAlertController: UIAlertController {
+	
+	open lazy var visualEffectView: UIVisualEffectView? = {
+		return self.view.visualEffectView
+	}()
+	
+	open lazy var lazyContentView: UIView? = {
+		return self.contentView
+	}()
+	
+	open lazy var tintColor: UIColor? = {
+		return self.view.tintColor
+	}()
+	
+	override open func viewWillAppear(_ animated: Bool) {
+		super.viewDidAppear(animated)
+		self.view.tintColor = self.tintColor
+	}
+	
+	func addParallaxEffect(x: Int = 20, y: Int = 20) {
+		let horizontal = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.x", type: .tiltAlongHorizontalAxis)
+		horizontal.minimumRelativeValue = -x
+		horizontal.maximumRelativeValue = x
+		
+		let vertical = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.y", type: .tiltAlongVerticalAxis)
+		vertical.minimumRelativeValue = -y
+		vertical.maximumRelativeValue = y
+		
+		let motionEffectsGroup = UIMotionEffectGroup()
+		motionEffectsGroup.motionEffects = [horizontal, vertical]
+		
+		self.view.addMotionEffect(motionEffectsGroup)
+	}
+}
+
+//
+
+extension UIAlertController {
+	
+	private var visualEffectView: UIVisualEffectView? {
+		return self.view.visualEffectView
+	}
+	
+	var contentView: UIView? {
+		return self.view.subviews.first?.subviews.first?.subviews.first
+	}
+	
+	var titleAttributes: [StringAttribute] {
+		get { return self.attributedTitle_?.attributes ?? [] }
+		set { self.attributedTitle_ = newValue.suitableAttributedText(forText: self.title) }
+	}
+	
+	var messageAttributes: [StringAttribute] {
+		get { return self.attributedMessage_?.attributes ?? [] }
+		set { self.attributedMessage_ = newValue.suitableAttributedText(forText: self.message) }
+	}
+}
+
+extension UIAlertAction {
+	
+	var label: UILabel? {
+		return (self.value(forKey: "__representer") as? NSObject)?.value(forKey: "label") as? UILabel
+	}
+	
+	var titleAttributes: [StringAttribute] {
+		get { return self.label?.attributedText?.attributes ?? [] }
+		set { self.label?.textAttributes = newValue }
+	}
+	
+	var titleTextColor: UIColor? {
+		get { return self.titleTextColor_ }
+		set { self.titleTextColor_ = newValue }
+	}
+	
+	var accessoryImage: UIImage? {
+		get { return self.image_ }
+		set { self.image_ = newValue }
+	}
+	
+	var contentElementViewController: ElementViewController? {
+		get { return self.contentViewController_ as? ElementViewController }
+		set {
+			if accessoryImage != nil {
+				print("The accessory image might overlap with the content of the contentViewController")
+			}
+			self.contentViewController_ = newValue
+		}
+	}
+	
+	var contentViewController: UIViewController? {
+		get { return self.contentViewController_ }
+		set {
+			if accessoryImage != nil {
+				print("The accessory image might overlap with the content of the contentViewController")
+			}
+			self.contentViewController_ = newValue
+		}
+	}
+	
+	var tableViewController: UITableViewController? {
+		get { return self.contentViewController_ as? UITableViewController }
+		set {
+			if accessoryImage != nil {
+				print("The accessory image might overlap with the content of the contentViewController")
+			}
+			self.contentViewController_ = newValue
+		}
+	}
+	
+	var accessoryView: UIView? {
+		get { return contentElementViewController?.elementView }
+		set {
+			let elementViewController = ElementViewController()
+			elementViewController.elementView = newValue
+			self.contentViewController = elementViewController
+		}
+	}
+}
+
+extension UILabel {
+	var textAttributes: [StringAttribute] {
+		get { return self.attributedText?.attributes ?? [] }
+		set { self.attributedText = newValue.suitableAttributedText(forText: self.text) }
+	}
+}
+
+extension NSAttributedString {
+	
+	struct StringAttribute {
+		
+		let key: NSAttributedString.Key
+		let value: Any
+		var range: NSRange? = nil
+		
+		init(key: NSAttributedString.Key, value: Any, range: NSRange? = nil) {
+			self.key = key
+			self.value = value
+			self.range = range
+		}
+	}
+	
+	var attributes: [StringAttribute] {
+		
+		var savedAttributes: [StringAttribute] = []
+		
+		let rawAttributes = self.attributes(at: 0, longestEffectiveRange: nil, in: NSRange(location: 0, length: self.length))
+		
+		for rawAttribute in rawAttributes {
+			savedAttributes.append(StringAttribute(key: rawAttribute.key, value: rawAttribute.value))
+		}
+		return savedAttributes
+	}
+	convenience init(string: String?, attributes: [StringAttribute]) {
+		
+		guard let validString = string else { self.init(string: "", attributes: [:]); return }
+		
+		var attributesDict: [NSAttributedString.Key: Any] = [:]
+		for attribute in attributes {
+			attributesDict[attribute.key] = attribute.value
+		}
+		self.init(string: validString, attributes: attributesDict)
+	}
+}
+
+extension NSMutableAttributedString {
+	var mutableAttributes: [StringAttribute] {
+		get { return self.attributes }
+		set {
+			let defaultRange = NSRange(location: 0, length: self.length)
+			for attribute in newValue {
+				self.addAttribute(attribute.key, value: attribute.value, range: attribute.range ?? defaultRange)
+			}
+		}
+	}
+	convenience init(string: String?, mutableAttributes: [StringAttribute]) {
+		guard let text = string else { self.init(string: ""); return }
+		self.init(string: text)
+		self.mutableAttributes = mutableAttributes
+	}
+}
+
+class ElementViewController: UIViewController {
+	
+	var elementView: UIView? = nil
+	
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		
+		if let validView = self.elementView  {
+		
+			self.view.addSubview(validView)
+			
+			validView.translatesAutoresizingMaskIntoConstraints = false
+			
+			let margins = self.view.layoutMarginsGuide
+			
+			validView.centerYAnchor.constraint(equalTo: margins.topAnchor, constant: validView.frame.height).isActive = true
+			validView.centerXAnchor.constraint(equalTo: margins.centerXAnchor).isActive = true
+			validView.widthAnchor.constraint(equalTo: margins.widthAnchor).isActive = true
+			validView.heightAnchor.constraint(equalTo: margins.heightAnchor).isActive = true
+		}
+	}
+}
+
+//
+
+typealias StringAttribute = NSAttributedString.StringAttribute
+
+extension Array where Element == StringAttribute {
+	func suitableAttributedText(forText text: String?) -> NSAttributedString {
+		if self.compactMap({ $0.range }).isEmpty {
+			return NSAttributedString(string: text, attributes: self)
+		}
+		return NSMutableAttributedString(string: text, mutableAttributes: self)
+	}
+}
+
+extension UIView {
+	func mapEverySubview(predicate: (UIView) -> Void) {
+		predicate(self)
+		for subview in self.subviews {
+			subview.mapEverySubview(predicate: predicate)
+		}
+	}
+}
+private extension UIView {
+	var visualEffectView: UIVisualEffectView? {
+		
+		if self is UIVisualEffectView {
+			return self as? UIVisualEffectView
+		}
+		
+		for subview in self.subviews {
+			if let validView = subview.visualEffectView {
+				return validView
+			}
+		}
+		return nil
+	}
+}
+
+private extension UIAlertController {
+	
+	private var attributedTitle_: NSAttributedString? {
+		get {
+			return self.value(forKey: "attributedTitle") as? NSAttributedString
+		} set {
+			self.setValue(newValue, forKey: "attributedTitle")
+		}
+	}
+	
+	private var attributedMessage_: NSAttributedString? {
+		get {
+			return self.value(forKey: "attributedMessage") as? NSAttributedString
+		} set {
+			self.setValue(newValue, forKey: "attributedMessage")
+		}
+	}
+}
+
+private extension UIAlertAction {
+	
+	// idea from: https://medium.com/@maximbilan/ios-uialertcontroller-customization-5cfd88140db8
+	private var image_: UIImage? {
+		get {
+			return self.value(forKey: "image") as? UIImage
+		} set {
+//			let imageWithGoodDimensions = newValue?.scale(to: CGSize(width: 30, height: 30))
+//			self.setValue(imageWithGoodDimensions?.withRenderingMode(.alwaysOriginal), forKey: "image")
+		}
+	}
+	
+	private var contentViewController_: UIViewController? {
+		get {
+			return self.value(forKey: "contentViewController") as? UIViewController
+		} set {
+			self.setValue(newValue, forKey: "contentViewController")
+		}
+	}
+	
+	private var titleTextColor_: UIColor? {
+		get {
+			return self.value(forKey: "titleTextColor") as? UIColor
+		} set {
+			self.setValue(newValue, forKey: "titleTextColor")
+		}
+	}
+}