Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
see four updated commits in Update_2023 by reidsp · Pull Request #40 · LightSys/iOSEventApp · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' see four updated commits in Update_2023 by reidsp · Pull Request #40 · LightSys/iOSEventApp · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' see four updated commits in Update_2023 by reidsp · Pull Request #40 · LightSys/iOSEventApp · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' see four updated commits in Update_2023 by reidsp · Pull Request #40 · LightSys/iOSEventApp · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' see four updated commits in Update_2023 by reidsp · Pull Request #40 · LightSys/iOSEventApp · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); see four updated commits in Update_2023 by reidsp · Pull Request #40 · LightSys/iOSEventApp · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added2023 Update Notes.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Info.plist
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
Expand Down
5 changes: 2 additions & 3 deletions QRScannerViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,9 +108,8 @@ AVCaptureMetadataOutputObjectsDelegate {
if captureSession.inputs.count == 0 {
setupSession() //needed for camera permissions
}
//self.captureSession.startRunning()
// If they arrive on the scanner, they have come back from the main container – and need to (re)scan.
if captureSession?.isRunning == false {
if captureSession.isRunning == false {
captureSession.startRunning() //needed to run the camera
}
}
Expand DownExpand Up@@ -146,7 +145,7 @@ AVCaptureMetadataOutputObjectsDelegate {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue, completion: { (success) in
if success == true {
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil)
self.performSegue(withIdentifier: "PresentMainContainer", sender: nil) //program crashes here
}
else {
self.captureSession.startRunning()
Expand Down
9 changes: 5 additions & 4 deletions SettingsViewController.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,8 +83,8 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

var labelText = ""
switch indexPath.row {
case 0:
labelText = "Scan new QR code"
/*case 0:
labelText = "Scan new QR code"*/
case 1:
labelText = "Refresh event data now"
case 2:
Expand All@@ -108,9 +108,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
/*case 0:
loadDevEvents = 0
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)
navigationController?.pushViewController(QRScannerViewController.init(), animated: true)*/

case 1:
if loadDevEvents == 1 {
loadDevEvents += 1
Expand Down
226 changes: 226 additions & 0 deletions SidebarTableViewController.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
//
// SidebarTableViewController.swift
// iOSEventApp
//
// Created by Nathaniel Brown on 3/6/18.
// Copyright © 2018 LightSys. All rights reserved.
//

import UIKit

protocol MenuDelegate:AnyObject {
func switchTo(vcName: String, entityNameForData: String?, informationPageName pageName: String?)
func swipedToClose()
}

/// Inserts padding around an Image
extension UIImage {

func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
let width: CGFloat = size.width + x
let height: CGFloat = size.height + y
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
draw(at: origin)
let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return imageWithPadding
}
}

/**
Loads the SidebarAppearances and tells the RootViewController what view controller to load with what data.
*/
class SidebarTableViewController: UITableViewController {

weak var menuDelegate: MenuDelegate?

var themes: [Theme]?
var _variableSidebarItems = [SidebarAppearance]()
var variableSidebarItems: [SidebarAppearance] {
get {
return _variableSidebarItems
}
set {
_variableSidebarItems = newValue
tableView.reloadData()
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
}
}

func loadSidebarItemsIfNeeded() {
guard variableSidebarItems.count == 0 else {
return
}
reloadSidebarItems()
}

func reloadSidebarItems() {
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
let loader = DataController(newPersistentContainer: container)
themes = loader.fetchAllObjects(onContext: container.viewContext, forName: "Theme") as? [Theme]
let context = container.viewContext

let sidebarItems = (loader.fetchAllObjects(onContext: context, forName: "SidebarAppearance")
as! [SidebarAppearance]).sorted(by: { (item1, item2) -> Bool in
return item1.order! < item2.order!
})
variableSidebarItems = sidebarItems

if let data = (loader.fetchAllObjects(onContext: context, forName: "General")?.first as? General)?.logo, let imageData = Data(base64Encoded: data) {
let image = UIImage(data: imageData)
let imageView = UIImageView(image: image?.addImagePadding(x: 150, y: 100))
// Shrink image view's width (and keep aspect ratio)
let maxWidth = view.frame.size.width
if imageView.frame.size.width > maxWidth {
imageView.frame.size.height *= maxWidth / imageView.frame.size.width
imageView.frame.size.width = maxWidth
}
// Shrink image view's height (and keep aspect ratio)
let maxHeight: CGFloat = 160
if imageView.frame.size.height > maxHeight {
imageView.frame.size.width *= maxHeight / imageView.frame.size.height
imageView.frame.size.height = maxHeight
}
// To prevent the image view from stretching and provide a background.
let containingView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: imageView.frame.size.height))

// Background
let background = CAGradientLayer()
background.colors = getThemeColors()
// Make the gradient horizontal instead of vertical
background.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
background.frame = containingView.frame // Must come after the transform

// Add views and layers
containingView.layer.addSublayer(background)
containingView.addSubview(imageView)
tableView.tableHeaderView = containingView
}
else {
tableView.tableHeaderView = nil
}

tableView.reloadData()
}

@IBAction func swipedLeft(_ sender: Any) {
menuDelegate?.swipedToClose()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard variableSidebarItems.count > 0 else {
return 3 // Welcome, About, Settings
}
// Welcome not shown
return variableSidebarItems.count + 3 // About, Settings, and Map are constant
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0...(variableSidebarItems.count == 0 ? 0 : variableSidebarItems.count-1):
if variableSidebarItems.count > 0 {
if variableSidebarItems[indexPath.row].category == "Notifications" {
menuDelegate?.switchTo(vcName: "notifications", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "ContactPage" {
menuDelegate?.switchTo(vcName: "contacts", entityNameForData: nil, informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Housing" {
menuDelegate?.switchTo(vcName: "housing", entityNameForData: "HousingUnit", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "Schedule" {
menuDelegate?.switchTo(vcName: "schedule", entityNameForData: "ScheduleDay", informationPageName: nil)
}
else if variableSidebarItems[indexPath.row].category == "PrayerPartners" {
menuDelegate?.switchTo(vcName: "prayerPartners", entityNameForData: "PrayerPartnerGroup", informationPageName: nil)
}
else {
menuDelegate?.switchTo(vcName: "informationPage", entityNameForData: "InformationPage", informationPageName: variableSidebarItems[indexPath.row].nav)
}
} else {
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
case variableSidebarItems.count, 1:
// Case one is covered earlier if data is loaded. By default switch statements don't fall through in swift.
menuDelegate?.switchTo(vcName: "about", entityNameForData: nil, informationPageName: nil)
case variableSidebarItems.count + 1, 2:
menuDelegate?.switchTo(vcName: "settings", entityNameForData: nil, informationPageName: nil)
default:
// Map is always at index 3 or greater
menuDelegate?.switchTo(vcName: "welcome", entityNameForData: nil, informationPageName: nil)
}
tableView.deselectRow(at: indexPath, animated: true)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableViewCell

let row = indexPath.row
if row < variableSidebarItems.count {
cell.sideImageView.image = UIImage(named: variableSidebarItems[row].icon!)
cell.label.text = variableSidebarItems[row].nav!
}
else if row == 0 {
// Only if data isn't loaded
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Welcome"
}
else if row == variableSidebarItems.count || row == 1 {
// After welcome or all variable items
cell.sideImageView.image = UIImage(named: "ic_info")
cell.label.text = "About"
}
else if row == variableSidebarItems.count + 1 || row == 2 {
// Settings
cell.sideImageView.image = UIImage(named: "settingsIcon")
cell.label.text = "Settings"
}
else {
// Map (if data loaded)
cell.sideImageView.image = UIImage(named: "ic_camera")
cell.label.text = "Scan QR Code"
}
// set cell color to light theme
cell.contentView.backgroundColor = UIColor(cgColor: getThemeColors()[0])
return cell
}

func getThemeColors() -> [CGColor] {
let themeArray: [Theme]? = themes
// set default values
var result: [CGColor] = [UIColor(red: 0x60/256.0, green: 0x80/256.0, blue: 0xC0/256.0, alpha: 1).cgColor, UIColor(red: 0x30/256.0, green: 0x40/256.0, blue: 0x60/256.0, alpha: 1).cgColor]
for theme in themeArray ?? [] {
if (theme.themeName == "themeColor") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[0] = themeColor
} else if (theme.themeName == "themeDark") {
let themeRGB: String = String((theme.themeValue?.split(separator: "#")[0])!)
let greenStartIdx = themeRGB.index(themeRGB.startIndex, offsetBy: 2)
let blueStartIdx = themeRGB.index(greenStartIdx, offsetBy: 2)
let themeRed:Int = Int(String(themeRGB[..<greenStartIdx]), radix:16)!
let themeGreen:Int = Int(String(themeRGB[greenStartIdx..<blueStartIdx]), radix:16)!
let themeBlue:Int = Int(String(themeRGB[blueStartIdx..<themeRGB.endIndex]), radix:16)!
let themeColor = UIColor(red: CGFloat(themeRed)/256.0, green: CGFloat(themeGreen)/256.0, blue: CGFloat(themeBlue)/256.0, alpha: 1).cgColor
result[1] = themeColor
}
}

return result
}
}