diff --git a/Cartfile.resolved b/Cartfile.resolved index ff19afd..f024131 100755 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,4 +1,4 @@ github "Daltron/NotificationBanner" "2.1.0" github "SnapKit/SnapKit" "4.2.0" github "cbpowell/MarqueeLabel" "3.2.1" -github "pusher/push-notifications-swift" "2.0.0" +github "pusher/push-notifications-swift" "2.0.2" diff --git a/DEV-Simple.xcodeproj/project.pbxproj b/DEV-Simple.xcodeproj/project.pbxproj index 2faabfe..d6f0024 100755 --- a/DEV-Simple.xcodeproj/project.pbxproj +++ b/DEV-Simple.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 16800D5B22CD05C300429E36 /* OfflineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16800D5A22CD05C300429E36 /* OfflineViewController.swift */; }; + 16800D5F22CD067D00429E36 /* DEVColorCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16800D5D22CD067D00429E36 /* DEVColorCollectionViewCell.swift */; }; + 16800D6022CD067D00429E36 /* DEVColorCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 16800D5E22CD067D00429E36 /* DEVColorCollectionViewCell.xib */; }; + 16800D6222CD0C9500429E36 /* DEVCanvasView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16800D6122CD0C9500429E36 /* DEVCanvasView.swift */; }; 1B032B1821E409FE00A2108A /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B032B1721E409FE00A2108A /* Globals.swift */; }; 1BA17C87220C8470007A8EF5 /* invertedImages.css in Resources */ = {isa = PBXBuildFile; fileRef = 1BA17C86220C8470007A8EF5 /* invertedImages.css */; }; 73D7673C218BA66700BD13B6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D7673B218BA66700BD13B6 /* AppDelegate.swift */; }; @@ -44,6 +48,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 16800D5A22CD05C300429E36 /* OfflineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineViewController.swift; sourceTree = ""; }; + 16800D5D22CD067D00429E36 /* DEVColorCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DEVColorCollectionViewCell.swift; sourceTree = ""; }; + 16800D5E22CD067D00429E36 /* DEVColorCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DEVColorCollectionViewCell.xib; sourceTree = ""; }; + 16800D6122CD0C9500429E36 /* DEVCanvasView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DEVCanvasView.swift; sourceTree = ""; }; 1B032B1721E409FE00A2108A /* Globals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Globals.swift; sourceTree = ""; }; 1BA17C86220C8470007A8EF5 /* invertedImages.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = invertedImages.css; sourceTree = ""; }; 73D76738218BA66700BD13B6 /* DEV-Simple.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DEV-Simple.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -99,11 +107,23 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 16800D5C22CD065300429E36 /* UICollectionViewCells */ = { + isa = PBXGroup; + children = ( + 16800D5D22CD067D00429E36 /* DEVColorCollectionViewCell.swift */, + 16800D5E22CD067D00429E36 /* DEVColorCollectionViewCell.xib */, + ); + path = UICollectionViewCells; + sourceTree = ""; + }; 1BA17C88220C847B007A8EF5 /* views */ = { isa = PBXGroup; children = ( + 16800D5C22CD065300429E36 /* UICollectionViewCells */, 73D7673D218BA66700BD13B6 /* ViewController.swift */, 73E8ACC62192165E009CE057 /* BrowserViewController.swift */, + 16800D5A22CD05C300429E36 /* OfflineViewController.swift */, + 16800D6122CD0C9500429E36 /* DEVCanvasView.swift */, ); path = views; sourceTree = ""; @@ -322,6 +342,7 @@ 73D76746218BA66B00BD13B6 /* LaunchScreen.storyboard in Resources */, 73D76743218BA66B00BD13B6 /* Assets.xcassets in Resources */, 73D76741218BA66700BD13B6 /* Main.storyboard in Resources */, + 16800D6022CD067D00429E36 /* DEVColorCollectionViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -392,8 +413,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 16800D5B22CD05C300429E36 /* OfflineViewController.swift in Sources */, 73D7673E218BA66700BD13B6 /* ViewController.swift in Sources */, + 16800D5F22CD067D00429E36 /* DEVColorCollectionViewCell.swift in Sources */, 73E8ACC72192165E009CE057 /* BrowserViewController.swift in Sources */, + 16800D6222CD0C9500429E36 /* DEVCanvasView.swift in Sources */, 73D7673C218BA66700BD13B6 /* AppDelegate.swift in Sources */, 1B032B1821E409FE00A2108A /* Globals.swift in Sources */, BD5C906C21B63CCC000D9F79 /* NetworkReachability.swift in Sources */, diff --git a/DEV-Simple/assets/Assets.xcassets/DEV-Rainbow.imageset/Contents.json b/DEV-Simple/assets/Assets.xcassets/DEV-Rainbow.imageset/Contents.json new file mode 100644 index 0000000..e908ea6 --- /dev/null +++ b/DEV-Simple/assets/Assets.xcassets/DEV-Rainbow.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "DEV-Rainbow.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DEV-Simple/assets/Assets.xcassets/DEV-Rainbow.imageset/DEV-Rainbow.png b/DEV-Simple/assets/Assets.xcassets/DEV-Rainbow.imageset/DEV-Rainbow.png new file mode 100644 index 0000000..1865245 Binary files /dev/null and b/DEV-Simple/assets/Assets.xcassets/DEV-Rainbow.imageset/DEV-Rainbow.png differ diff --git a/DEV-Simple/core/AppDelegate.swift b/DEV-Simple/core/AppDelegate.swift index ada61d2..f9abefd 100755 --- a/DEV-Simple/core/AppDelegate.swift +++ b/DEV-Simple/core/AppDelegate.swift @@ -17,7 +17,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let pushNotifications = PushNotifications.shared func application(_ application: UIApplication, didFinishLaunchingWithOptions - launchOptions:[UIApplication.LaunchOptionsKey:Any]?) -> Bool { + launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { self.pushNotifications.start(instanceId: "cdaf9857-fad0-4bfb-b360-64c1b2693ef3") self.pushNotifications.registerForRemoteNotifications() try? self.pushNotifications.addDeviceInterest(interest: "broadcast") diff --git a/DEV-Simple/core/Globals.swift b/DEV-Simple/core/Globals.swift index 340555d..78297cf 100755 --- a/DEV-Simple/core/Globals.swift +++ b/DEV-Simple/core/Globals.swift @@ -10,4 +10,5 @@ import Foundation struct DoAction { static var openExternalURL = "showExternalPage" + static let offlineViewController = "showOffline" } diff --git a/DEV-Simple/storyboards/Base.lproj/Main.storyboard b/DEV-Simple/storyboards/Base.lproj/Main.storyboard index 5b86f54..edc1543 100755 --- a/DEV-Simple/storyboards/Base.lproj/Main.storyboard +++ b/DEV-Simple/storyboards/Base.lproj/Main.storyboard @@ -82,6 +82,7 @@ + @@ -151,9 +152,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Cgo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Good news: You can draw a picture anywhere on this page while you wait to get it back! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DEV-Simple/views/DEVCanvasView.swift b/DEV-Simple/views/DEVCanvasView.swift new file mode 100644 index 0000000..0f951f8 --- /dev/null +++ b/DEV-Simple/views/DEVCanvasView.swift @@ -0,0 +1,47 @@ +// +// DEVCanvasView.swift +// DEV-Simple +// +// Created by Jacob Boyd on 7/3/19. +// Copyright © 2019 DEV. All rights reserved. +// + +import UIKit + +class DEVCanvasView: UIView { + var startingPoint: CGPoint! + var touchPoint: CGPoint! + var path: UIBezierPath! + var strokeColor: CGColor! = UIColor(red: 244/255, green: 144/255, blue: 142/255, alpha: 1).cgColor + + func setStrokeColor(_ color: UIColor) { + self.strokeColor = color.cgColor + } + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + let touch = touches.first + startingPoint = touch?.location(in: self) + } + + override func touchesMoved(_ touches: Set, with event: UIEvent?) { + let touch = touches.first + touchPoint = touch?.location(in: self) + + path = UIBezierPath() + path?.move(to: startingPoint) + path?.addLine(to: touchPoint) + startingPoint = touchPoint + drawShapeLayer() + } + + private func drawShapeLayer() { + let shapeLayer = CAShapeLayer() + shapeLayer.path = path.cgPath + shapeLayer.strokeColor = strokeColor + shapeLayer.lineWidth = 3 + shapeLayer.fillColor = UIColor.clear.cgColor + self.layer.addSublayer(shapeLayer) + self.setNeedsDisplay() + } + +} diff --git a/DEV-Simple/views/OfflineViewController.swift b/DEV-Simple/views/OfflineViewController.swift new file mode 100644 index 0000000..82aa7de --- /dev/null +++ b/DEV-Simple/views/OfflineViewController.swift @@ -0,0 +1,102 @@ +// +// OfflineViewController.swift +// DEV-Simple +// +// Created by Jacob Boyd on 7/3/19. +// Copyright © 2019 DEV. All rights reserved. +// + +import UIKit + +class OfflineViewController: UIViewController { + @IBOutlet weak var collectionView: UICollectionView! + @IBOutlet weak var drawingCanvas: DEVCanvasView! + var selectedCell: DEVColorCollectionViewCell? + + let colors = [ + // This are RGB values, just be sure to divide by 255 + UIColor(red: 244/255, green: 144/255, blue: 142/255, alpha: 1), + UIColor(red: 242/255, green: 240/255, blue: 151/255, alpha: 1), + UIColor(red: 136/255, green: 176/255, blue: 220/255, alpha: 1), + UIColor(red: 247/255, green: 181/255, blue: 209/255, alpha: 1), + UIColor(red: 83/255, green: 196/255, blue: 175/255, alpha: 1), + UIColor(red: 253/255, green: 227/255, blue: 140/255, alpha: 1) + ] + + override func viewDidLoad() { + super.viewDidLoad() + + // register the VC as the delegate, datasource and then connect + // the collectionViewCell with xib file + self.collectionView.delegate = self + self.collectionView.dataSource = self + self.collectionView.register( + UINib(nibName: "DEVColorCollectionViewCell", bundle: Bundle.main), + forCellWithReuseIdentifier: DEVColorCollectionViewCell.cellId) + + //Subscribe to reachability changes notifications + NotificationCenter.default.addObserver( + self, + selector: #selector(reachabilityChanged), + name: .flagsChanged, + object: Network.reachability) + } + + // MARK: - Reachability + @objc private func reachabilityChanged(note: Notification) { + guard let reachability = note.object as? Reachability else { + return + } + + // If the user gains connection, dismiss the VC + switch reachability.status { + case .wifi: + self.dismissBtnTapped(self) + case .wwan: + self.dismissBtnTapped(self) + default: + break + } + } + + @IBAction func dismissBtnTapped(_ sender: Any) { + if let presentingVC = self.presentingViewController { + presentingVC.dismiss(animated: true, completion: nil) + } + } + +} + +extension OfflineViewController: UICollectionViewDataSource, UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return colors.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) + -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: DEVColorCollectionViewCell.cellId, + for: indexPath) as? DEVColorCollectionViewCell else { + return UICollectionViewCell() + } + cell.configureCell(bgColor: colors[indexPath.item]) + // Set the selectedCell as the first color by default + if indexPath.item == 0 { + self.selectedCell = cell + cell.setSelected(true) + } + return cell + } + + // When a cell is selected, update the UI to reflect the selection + // and change the strokeColor for drawing + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if let cell = collectionView.cellForItem(at: indexPath) as? DEVColorCollectionViewCell, selectedCell != cell { + selectedCell?.setSelected(false) + cell.setSelected(true) + self.selectedCell = cell + + self.drawingCanvas.setStrokeColor(colors[indexPath.item]) + } + } +} diff --git a/DEV-Simple/views/UICollectionViewCells/DEVColorCollectionViewCell.swift b/DEV-Simple/views/UICollectionViewCells/DEVColorCollectionViewCell.swift new file mode 100644 index 0000000..f9cc90c --- /dev/null +++ b/DEV-Simple/views/UICollectionViewCells/DEVColorCollectionViewCell.swift @@ -0,0 +1,34 @@ +// +// DEVColorCollectionViewCell.swift +// DEV-Simple +// +// Created by Jacob Boyd on 7/3/19. +// Copyright © 2019 DEV. All rights reserved. +// + +import UIKit + +class DEVColorCollectionViewCell: UICollectionViewCell { + static let cellId = "DEVColorCell" + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + self.layer.borderColor = UIColor.darkGray.cgColor + } + + func configureCell(bgColor: UIColor) { + self.clipsToBounds = true + self.layer.cornerRadius = self.bounds.width / 2 + self.backgroundColor = bgColor + } + + func setSelected(_ selected: Bool) { + if selected { + self.layer.borderWidth = 2 + } else { + self.layer.borderWidth = 0 + } + } + +} diff --git a/DEV-Simple/views/UICollectionViewCells/DEVColorCollectionViewCell.xib b/DEV-Simple/views/UICollectionViewCells/DEVColorCollectionViewCell.xib new file mode 100644 index 0000000..7a52d6a --- /dev/null +++ b/DEV-Simple/views/UICollectionViewCells/DEVColorCollectionViewCell.xib @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DEV-Simple/views/ViewController.swift b/DEV-Simple/views/ViewController.swift index e38c4c5..c87c631 100755 --- a/DEV-Simple/views/ViewController.swift +++ b/DEV-Simple/views/ViewController.swift @@ -74,13 +74,6 @@ class ViewController: UIViewController { let darkBackgroundColor = UIColor(red: 13/255, green: 18/255, blue: 25/255, alpha: 1) let pushNotifications = PushNotifications.shared - lazy var errorBanner: NotificationBanner = { - let banner = NotificationBanner(title: "Network not reachable", style: .danger) - banner.autoDismiss = false - banner.dismissOnTap = true - return banner - }() - var devToURL = "https://dev.to" override func viewDidLoad() { @@ -124,12 +117,12 @@ class ViewController: UIViewController { switch reachability.status { case .wifi: - if errorBanner.isDisplaying { - errorBanner.dismiss() + if self.presentedViewController != nil { + self.dismiss(animated: true, completion: nil) } case .wwan: - if errorBanner.isDisplaying { - errorBanner.dismiss() + if self.presentedViewController != nil { + self.dismiss(animated: true, completion: nil) } default: break @@ -154,7 +147,7 @@ class ViewController: UIViewController { } // MARK: - Observers - override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey:Any]?, + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { backButton.isEnabled = webView.canGoBack forwardButton.isEnabled = webView.canGoForward @@ -317,10 +310,10 @@ extension ViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { let reachability = Network.reachability guard let isNetworkReachable = reachability?.isReachable, isNetworkReachable else { - errorBanner.show() + self.performSegue(withIdentifier: DoAction.offlineViewController, sender: self) return } - + activityIndicator.startAnimating() }