├── .gitignore
├── Podfile
├── Podfile.lock
├── README.md
├── ScalaDays Notifications
├── Info.plist
└── NotificationService.swift
├── ScalaDays.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ └── ScalaDays.xcscheme
├── ScalaDays.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── ScalaDays
├── AppDelegate+PushNoticications.swift
├── AppDelegate.swift
├── Base.lproj
├── LaunchScreen.xib
└── Main.storyboard
├── Bridging-Header.h
├── Controllers
├── SDAboutViewController.swift
├── SDAboutViewController.xib
├── SDContactViewController.swift
├── SDContactViewController.xib
├── SDNotificationViewController.swift
├── SDNotificationViewController.xib
├── SDPlacesViewController.swift
├── SDPlacesViewController.xib
├── SDScheduleDetailViewController.swift
├── SDScheduleDetailViewController.xib
├── SDScheduleViewController.swift
├── SDScheduleViewController.xib
├── SDSlideMenuViewController.swift
├── SDSlideMenuViewController.xib
├── SDSocialViewController.swift
├── SDSocialViewController.xib
├── SDSpeakersListViewController.swift
├── SDSpeakersListViewController.xib
├── SDSponsorViewController.swift
├── SDSponsorViewController.xib
├── SDVotesPopoverViewController.swift
├── SDVotesPopoverViewController.xib
├── SDWebViewController.swift
├── SDWebViewController.xib
└── ScalaDayViewController.swift
├── Extension
├── Array+Extension.swift
├── Bundle+Extension.swift
├── SDColor.swift
├── SDFonts.swift
├── SDImageView-Circular.swift
├── SDMapView-ZoomOut.swift
├── SDString+RemoveWhiteSpaces.swift
├── SDUIViewControllerExtension.swift
├── SDView-NibLoading.swift
├── SDZBarSymbolSet-Enumeration.swift
└── UIColor+Extension.swift
├── External
└── SlideMenuController.swift
├── Helpers
├── Alerts
│ └── SDAlertViewHelper.swift
├── Analytics
│ ├── Analytics.swift
│ └── FirebaseScalaDays.swift
├── Animation
│ └── SDAnimationHelper.swift
├── Contacts
│ ├── SDContactCreationHelper.h
│ └── SDContactCreationHelper.m
├── Dates
│ └── SDDateHandler.swift
├── Protocols
│ └── SDMenuControllerItem.swift
├── SDConstants.swift
├── Social
│ ├── SDSocialHandler.swift
│ ├── TWTRTweet+SDTweet.swift
│ └── TwitterSocialController.swift
└── Storing
│ ├── StoringHelper.swift
│ └── UserDefaults+Extension.swift
├── Images.xcassets
├── AppIcon.appiconset
│ ├── 1024x1024.png
│ ├── Contents.json
│ ├── icon-app-29x29.png
│ ├── icon-app-29x29@2x-1.png
│ ├── icon-app-29x29@2x.png
│ ├── icon-app-29x29@3x.png
│ ├── icon-app-40x40.png
│ ├── icon-app-40x40@2x-1.png
│ ├── icon-app-40x40@2x.png
│ ├── icon-app-40x40@3x.png
│ ├── icon-app-60x60@2x.png
│ ├── icon-app-60x60@3x.png
│ ├── icon-app-76x76.png
│ ├── icon-app-76x76@2x.png
│ └── icon-app-83.5x83.5@2x.png
├── Contents.json
├── LaunchImage.launchimage
│ ├── Contents.json
│ ├── splash-iphone4@2x.png
│ ├── splash-iphone5.png
│ ├── splash-iphone6-plus.png
│ ├── splash-iphone6.png
│ └── splash-iphonex.png
├── avatar.imageset
│ ├── Contents.json
│ ├── avatar.png
│ ├── avatar@2x.png
│ └── avatar@3x.png
├── empty_notifications.imageset
│ ├── Contents.json
│ ├── iconfinder_feature-available_4171950 (1).png
│ ├── iconfinder_feature-available_4171950 (2)-1.png
│ └── iconfinder_feature-available_4171950.png
├── list_icon_vote_like.imageset
│ ├── Contents.json
│ ├── list_icon_vote_like.png
│ ├── list_icon_vote_like@2x.png
│ └── list_icon_vote_like@3x.png
├── list_icon_vote_neutral.imageset
│ ├── Contents.json
│ ├── list_icon_vote_neutral.png
│ ├── list_icon_vote_neutral@2x.png
│ └── list_icon_vote_neutral@3x.png
├── list_icon_vote_unlike.imageset
│ ├── Contents.json
│ ├── list_icon_vote_unlike.png
│ ├── list_icon_vote_unlike@2x.png
│ └── list_icon_vote_unlike@3x.png
├── logo_47deg.imageset
│ ├── Contents.json
│ ├── logo_47deg.png
│ ├── logo_47deg@2x.png
│ └── logo_47deg@3x.png
├── map_popover.imageset
│ ├── Contents.json
│ ├── map_popover.png
│ ├── map_popover@2x.png
│ └── map_popover@3x.png
├── map_pushpin.imageset
│ ├── Contents.json
│ ├── map_pushpin.png
│ ├── map_pushpin@2x.png
│ └── map_pushpin@3x.png
├── menu_header_select_arrow.imageset
│ ├── Contents.json
│ ├── menu_header_select_arrow.png
│ ├── menu_header_select_arrow@2x.png
│ └── menu_header_select_arrow@3x.png
├── menu_icon_about.imageset
│ ├── Contents.json
│ ├── menu_icon_about.png
│ ├── menu_icon_about@2x.png
│ └── menu_icon_about@3x.png
├── menu_icon_contact.imageset
│ ├── Contents.json
│ ├── menu_icon_contact.png
│ ├── menu_icon_contact@2x.png
│ └── menu_icon_contact@3x.png
├── menu_icon_notification.imageset
│ ├── Contents.json
│ ├── bell@1x.png
│ ├── bell@2x.png
│ └── bell@3x.png
├── menu_icon_places.imageset
│ ├── Contents.json
│ ├── menu_icon_places.png
│ ├── menu_icon_places@2x.png
│ └── menu_icon_places@3x.png
├── menu_icon_schedule.imageset
│ ├── Contents.json
│ ├── menu_icon_schedule.png
│ ├── menu_icon_schedule@2x.png
│ └── menu_icon_schedule@3x.png
├── menu_icon_social.imageset
│ ├── Contents.json
│ ├── menu_icon_social.png
│ ├── menu_icon_social@2x.png
│ └── menu_icon_social@3x.png
├── menu_icon_speakers.imageset
│ ├── Contents.json
│ ├── menu_icon_speakers.png
│ ├── menu_icon_speakers@2x.png
│ └── menu_icon_speakers@3x.png
├── menu_icon_sponsors.imageset
│ ├── Contents.json
│ ├── menu_icon_sponsors.png
│ ├── menu_icon_sponsors@2x.png
│ └── menu_icon_sponsors@3x.png
├── menu_icon_ticket.imageset
│ ├── Contents.json
│ ├── menu_icon_ticket.png
│ ├── menu_icon_ticket@2x.png
│ └── menu_icon_ticket@3x.png
├── navigation_bar_icon_arrow.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_arrow.png
│ ├── navigation_bar_icon_arrow@2x.png
│ └── navigation_bar_icon_arrow@3x.png
├── navigation_bar_icon_clock.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_clock.png
│ ├── navigation_bar_icon_clock@2x.png
│ └── navigation_bar_icon_clock@3x.png
├── navigation_bar_icon_create.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_create.png
│ ├── navigation_bar_icon_create@2x.png
│ └── navigation_bar_icon_create@3x.png
├── navigation_bar_icon_favorite_default.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_favorite_default.png
│ ├── navigation_bar_icon_favorite_default@2x.png
│ └── navigation_bar_icon_favorite_default@3x.png
├── navigation_bar_icon_favorite_selected.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_favorite_selected.png
│ ├── navigation_bar_icon_favorite_selected@2x.png
│ └── navigation_bar_icon_favorite_selected@3x.png
├── navigation_bar_icon_filter.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_filter.png
│ ├── navigation_bar_icon_filter@2x.png
│ └── navigation_bar_icon_filter@3x.png
├── navigation_bar_icon_menu.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_menu.png
│ ├── navigation_bar_icon_menu@2x.png
│ └── navigation_bar_icon_menu@3x.png
├── navigation_bar_icon_options.imageset
│ ├── Contents.json
│ ├── navigation_bar_icon_options.png
│ ├── navigation_bar_icon_options@2x.png
│ └── navigation_bar_icon_options@3x.png
├── navigation_bar_post_tweet.imageset
│ ├── Contents.json
│ ├── iconfinder_Sed-17_2236318 (1).png
│ └── iconfinder_Sed-17_2236318.png
├── placeholder_contact.imageset
│ ├── Contents.json
│ ├── placeholder_contact.png
│ ├── placeholder_contact@2x.png
│ └── placeholder_contact@3x.png
├── placeholder_error.imageset
│ ├── Contents.json
│ ├── placeholder_error.png
│ ├── placeholder_error@2x.png
│ └── placeholder_error@3x.png
├── placeholder_general.imageset
│ ├── Contents.json
│ ├── placeholder_general.png
│ ├── placeholder_general@2x.png
│ └── placeholder_general@3x.png
├── placeholder_menu.imageset
│ ├── Contents.json
│ ├── placeholder_menu.png
│ ├── placeholder_menu@2x.png
│ └── placeholder_menu@3x.png
├── placeholder_sponsors.imageset
│ ├── Contents.json
│ ├── placeholder_sponsors.png
│ ├── placeholder_sponsors@2x.png
│ └── placeholder_sponsors@3x.png
├── popup_icon_vote_like.imageset
│ ├── Contents.json
│ ├── popup_icon_vote_like.png
│ ├── popup_icon_vote_like@2x.png
│ └── popup_icon_vote_like@3x.png
├── popup_icon_vote_like_disabled.imageset
│ ├── Contents.json
│ ├── popup_icon_vote_like_disabled.png
│ ├── popup_icon_vote_like_disabled@2x.png
│ └── popup_icon_vote_like_disabled@3x.png
├── popup_icon_vote_neutral.imageset
│ ├── Contents.json
│ ├── popup_icon_vote_neutral.png
│ ├── popup_icon_vote_neutral@2x.png
│ └── popup_icon_vote_neutral@3x.png
├── popup_icon_vote_neutral_disabled.imageset
│ ├── Contents.json
│ ├── popup_icon_vote_neutral_disabled.png
│ ├── popup_icon_vote_neutral_disabled@2x.png
│ └── popup_icon_vote_neutral_disabled@3x.png
├── popup_icon_vote_unlike.imageset
│ ├── Contents.json
│ ├── popup_icon_vote_unlike.png
│ ├── popup_icon_vote_unlike@2x.png
│ └── popup_icon_vote_unlike@3x.png
├── popup_icon_vote_unlike_disabled.imageset
│ ├── Contents.json
│ ├── popup_icon_vote_unlike_disabled.png
│ ├── popup_icon_vote_unlike_disabled@2x.png
│ └── popup_icon_vote_unlike_disabled@3x.png
├── schedule_icon_details.imageset
│ ├── Contents.json
│ ├── calendar@1x-1.png
│ ├── calendar@2x-1.png
│ └── calendar@3x-1.png
└── schedule_tag_favorite.imageset
│ ├── Contents.json
│ ├── schedule_tag_favorite.png
│ ├── schedule_tag_favorite@2x.png
│ └── schedule_tag_favorite@3x.png
├── Info.plist
├── Models
├── Conference.swift
├── Extensions
│ └── DateFormatter+Decoders.swift
├── SDMapAnnotation.swift
├── SDNotifications.swift
├── SDTweet.swift
└── Vote.swift
├── ScalaDays.entitlements
├── Service
├── DataManager.swift
├── FirebaseNotifications.swift
├── NotificationManager.swift
├── Response
│ └── conferences_2020.json
└── UserManager.swift
├── UI
├── CellPosition.swift
├── CustomViews
│ ├── SDErrorPlaceholderView.swift
│ ├── SDErrorPlaceholderView.xib
│ ├── SDQRScannerOverlayView.swift
│ ├── SDQRScannerOverlayView.xib
│ ├── SDSpeakerDetailView.swift
│ ├── SDSpeakerDetailView.xib
│ ├── SDSpeakerScheduleView.swift
│ └── SDSpeakerScheduleView.xib
├── TableViewCells
│ ├── SDConferenceTableViewCell.swift
│ ├── SDConferenceTableViewCell.xib
│ ├── SDNotificationTableViewCell.swift
│ ├── SDNotificationTableViewCell.xib
│ ├── SDScheduleListTableViewCell.swift
│ ├── SDScheduleListTableViewCell.xib
│ ├── SDSocialTableViewCell.swift
│ ├── SDSocialTableViewCell.xib
│ ├── SDSpeakersTableViewCell.swift
│ ├── SDSpeakersTableViewCell.xib
│ ├── SDSponsorsTableViewCell.swift
│ ├── SDSponsorsTableViewCell.xib
│ └── SDTableHeaderView.swift
└── Utils
│ ├── UITableView+Cells.swift
│ └── UITextView+HTML.swift
└── en.lproj
└── Localizable.strings
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.moved-aside
14 | DerivedData
15 | .idea/
16 | *.hmap
17 | *.xccheckout
18 |
19 | #CocoaPods
20 | Pods
21 | /ScalaDays/Podfile.lock
22 |
23 | #Local keys file
24 | SDExternalKeys.plist
25 | GoogleService-Info.plist
26 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 | platform :ios, 10.0
3 | use_frameworks!
4 | use_modular_headers!
5 | inhibit_all_warnings!
6 |
7 | def firebase
8 | # enabled Analytics
9 | pod 'Firebase/Analytics'
10 |
11 | # enabled push notifications
12 | pod 'Firebase'
13 | pod 'Firebase/Messaging'
14 | pod 'Firebase/InAppMessaging'
15 |
16 | # enabled Crashlytics (Firebase)
17 | pod 'Fabric', '~> 1.10.2'
18 | pod 'Crashlytics', '~> 3.14.0'
19 |
20 | # enabled Performance Monitoring
21 | pod 'Firebase/Performance'
22 | end
23 |
24 |
25 | target 'ScalaDays' do
26 | firebase
27 |
28 | pod 'Alamofire', '~> 5.0'
29 | pod 'TwitterKit', '3.4.2'
30 | pod 'ZBarSDK', '~> 1.3.1'
31 |
32 | # UI
33 | pod 'SDWebImage', '~> 3.5'
34 | pod 'SVProgressHUD', '~> 1.0'
35 | pod 'UIView+AutoLayout', '~> 1.3'
36 |
37 | # Utils
38 | pod 'NSDate+TimeAgo', '~> 1.0.2'
39 |
40 | target 'ScalaDays Notifications' do
41 | inherit! :search_paths
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ScalaDays for iOS
2 | The official [Scala Days](http://www.scaladays.org) App for Android handcrafted by 47 Degrees. You can download Scala Days from the [App Store](https://itunes.apple.com/us/app/scaladays/id883566471?mt=8 ). If you enjoy the application, please take a moment and rate it in the App Store :-)
3 |
4 | ## Setup
5 |
6 | This project uses the Cocoapods dependency management system for managing all third party dependencies that are utilized as part of this application. For a list of all of the third party dependencies, view the Podfile.
7 |
8 | For setup instructions please see [cocoapods.org](http://cocoapods.org/)
9 |
10 | ## Project Installation
11 |
12 | To download all of the dependencies, run 'pod install' from the terminal in the folder with the 'Podfile' file.
13 |
14 | Once the dependencies are downloaded Cocoapods will create a workspace file. Use the workspace to open the project in Xcode instead of the project file.
15 |
16 | ## External Keys
17 |
18 | As this project uses TwitterKit and Firebase (Analytics + Crashlytics + Cloud Messaging) frameworks, you need to provide the whole API keys (not included in the repo for security reasons). They are distributed in two external `plist files`, located in the *External/Keys* folder.
19 |
20 | **SDExternalKeys.plist**
21 |
22 |
23 | TwitterConsumerKey
24 | ***********
25 | TwitterConsumerSecret
26 | ***********
27 |
28 |
29 | **GoogleService-Info.plist**
30 |
31 | You can find this plist in your [Firebase console](https://firebase.google.com/).
32 |
33 | ## Crash Reporting
34 |
35 | Crash reporting is handled through Crashlytics. All uncaught exceptions are sent to Firebase/Crashlytics.
36 |
37 | ## License
38 | Copyright (C) 2015-2020 47 Degrees, LLC http://47deg.com hello@47deg.com
39 |
40 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
41 |
42 | http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
43 |
--------------------------------------------------------------------------------
/ScalaDays Notifications/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | ScalaDays Notifications
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSExtension
24 |
25 | NSExtensionPointIdentifier
26 | com.apple.usernotifications.service
27 | NSExtensionPrincipalClass
28 | $(PRODUCT_MODULE_NAME).NotificationService
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ScalaDays Notifications/NotificationService.swift:
--------------------------------------------------------------------------------
1 | import UserNotifications
2 | import FirebaseMessaging
3 |
4 | class NotificationService: UNNotificationServiceExtension {
5 | var contentHandler: ((UNNotificationContent) -> Void)?
6 | var bestAttemptContent: UNMutableNotificationContent?
7 |
8 | override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
9 | guard let content = request.content.mutableCopy() as? UNMutableNotificationContent else { return }
10 | self.contentHandler = contentHandler
11 | self.bestAttemptContent = content
12 |
13 | FIRMessagingExtensionHelper().populateNotificationContent(content, withContentHandler: contentHandler)
14 | }
15 |
16 | override func serviceExtensionTimeWillExpire() {
17 | guard let contentHandler = contentHandler,
18 | let bestAttemptContent = bestAttemptContent else { return }
19 |
20 | contentHandler(bestAttemptContent)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ScalaDays.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScalaDays.xcodeproj/xcshareddata/xcschemes/ScalaDays.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/ScalaDays.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ScalaDays.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ScalaDays/AppDelegate+PushNoticications.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Firebase
3 | import UserNotifications
4 |
5 | extension AppDelegate: UNUserNotificationCenterDelegate, MessagingDelegate {
6 | private static let SHOW_DEVICE_TOKEN = false
7 |
8 | // MARK: Registration
9 | func initializeNotifications(application: UIApplication) {
10 | registerPushNotifications(application: application)
11 | registerMessaging()
12 | }
13 |
14 | private func registerPushNotifications(application: UIApplication) {
15 | UNUserNotificationCenter.current().delegate = self
16 | UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (_, _) in }
17 | application.registerForRemoteNotifications()
18 | }
19 |
20 | private func registerMessaging() {
21 | Messaging.messaging().delegate = self
22 | }
23 |
24 | // MARK: Push Notifications
25 | func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
26 | let userInfo = notification.request.content.userInfo
27 | show(userInfo: userInfo)
28 | completionHandler(.alert)
29 | }
30 |
31 | func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
32 | let userInfo = response.notification.request.content.userInfo
33 | show(userInfo: userInfo)
34 | didTapOnNotification(userInfo: userInfo)
35 | completionHandler()
36 | }
37 |
38 | private func didTapOnNotification(userInfo: [AnyHashable: Any]) {
39 | guard let conferenceId = userInfo["conferenceId"] as? String else { return }
40 |
41 | if let jsonReload = userInfo["jsonReload"] as? String, jsonReload.lowercased() == "true" {
42 | DataManager.sharedInstance.lastConnectionAttemptDate = nil
43 | menuViewController.askControllersToReload()
44 | }
45 |
46 | menuViewController.showNotifications(conferenceId: conferenceId)
47 | }
48 |
49 | // MARK: Messaging
50 | public func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
51 | if AppDelegate.SHOW_DEVICE_TOKEN {
52 | showDeviceToken()
53 | showRegistrationToken()
54 | }
55 |
56 | NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: ["token": fcmToken])
57 | // Note: This callback is fired at each app startup and whenever a new token is generated.
58 | // If necessary send token to application server.
59 | }
60 |
61 | // MARK: - Helpers
62 | private func show(userInfo: [AnyHashable : Any]) {
63 | if let messageID = userInfo[UserInfo.gcmMessageIDKey] {
64 | print("Message ID: \(messageID)")
65 | }
66 |
67 | print("User Info: \(userInfo)")
68 | }
69 |
70 | private func showRegistrationToken() {
71 | InstanceID.instanceID().instanceID { (result, error) in
72 | if let error = error {
73 | print("Error fetching remote instance ID: \(error)")
74 | } else if let result = result {
75 | print("Firebase registration token: \(result.token)")
76 | }
77 | }
78 | }
79 |
80 | private func showDeviceToken() {
81 | guard let deviceToken = Messaging.messaging().apnsToken else { return }
82 | let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
83 | print("DEVICE TOKEN\n------------------\n\(deviceTokenString)\n------------------")
84 | }
85 |
86 | // MARK: - Constants
87 | enum UserInfo {
88 | static let gcmMessageIDKey = "gcm.message_id"
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/ScalaDays/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import SVProgressHUD
3 | import TwitterKit
4 | import Firebase
5 |
6 | @UIApplicationMain
7 | class AppDelegate: UIResponder, UIApplicationDelegate {
8 | var window: UIWindow?
9 | var menuViewController: SDSlideMenuViewController!
10 | private var analytics: ScalaDaysAnalytics!
11 |
12 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
13 | setupThirdParties(application: application, launchOptions: launchOptions)
14 | initAppearence()
15 | createMenuView()
16 |
17 | return true
18 | }
19 |
20 | // MARK: setup
21 | private func createMenuView() {
22 | let scheduleViewController = SDScheduleViewController(analytics: analytics)
23 | menuViewController = SDSlideMenuViewController(analytics: analytics)
24 | let nvc: UINavigationController = UINavigationController(rootViewController: scheduleViewController)
25 |
26 | menuViewController.scheduleViewController = nvc
27 | let slideMenuController = SlideMenuController(mainViewController: nvc, leftMenuViewController: menuViewController)
28 |
29 | window = UIWindow(frame: UIScreen.main.bounds)
30 | if let window = window {
31 | window.backgroundColor = UIColor.appColor()
32 | window.rootViewController = slideMenuController
33 | window.makeKeyAndVisible()
34 | }
35 | }
36 |
37 | private func initAppearence() {
38 | UINavigationBar.appearance().barTintColor = UIColor.appColor()
39 | UINavigationBar.appearance().tintColor = UIColor.white
40 | UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
41 | UINavigationBar.appearance().backIndicatorImage = UIImage(named: "navigation_bar_icon_arrow")
42 | UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "navigation_bar_icon_arrow")
43 | SVProgressHUD.setBackgroundColor(UIColor.clear)
44 | }
45 | }
46 |
47 | // MARK: Configure 3rd-party libraries
48 | extension AppDelegate {
49 |
50 | func setupThirdParties(application: UIApplication, launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
51 | firebase(application: application)
52 | twitter(application: application)
53 | }
54 |
55 | private func firebase(application: UIApplication) {
56 | FirebaseApp.configure()
57 | analytics = ScalaDaysAnalytics()
58 | initializeNotifications(application: application)
59 | }
60 |
61 | private func twitter(application: UIApplication) {
62 | guard let path = Bundle.main.path(forResource: kExternalKeysPlistFilename, ofType: "plist"),
63 | let keysDict = NSDictionary(contentsOfFile: path),
64 | let twitterConsumerKey = keysDict[kExternalKeysDKTwitterConsumerKey] as? String,
65 | let twitterConsumerSecret = keysDict[kExternalKeysDKTwitterConsumerSecret] as? String else { return }
66 |
67 | TWTRTwitter.sharedInstance().start(withConsumerKey: twitterConsumerKey, consumerSecret: twitterConsumerSecret)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ScalaDays/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ScalaDays/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/ScalaDays/Bridging-Header.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 |
19 | #ifndef ScalaDays_Bridging_Header_h
20 | #define ScalaDays_Bridging_Header_h
21 |
22 | #import
23 | #import
24 | #import "SDContactCreationHelper.h"
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/SDPlacesViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/SDSpeakersListViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/SDSponsorViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/SDVotesPopoverViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | protocol SDVotesPopoverViewControllerDelegate: class {
20 | func didSelectVoteValue(_ voteType: VoteType)
21 | }
22 |
23 | class SDVotesPopoverViewController: UIViewController, UIPopoverPresentationControllerDelegate {
24 | @IBOutlet weak var lblTalkTitle: UILabel!
25 |
26 | private let analytics: Analytics
27 | weak var delegate: SDVotesPopoverViewControllerDelegate?
28 |
29 | init(analytics: Analytics, delegate: SDVotesPopoverViewControllerDelegate) {
30 | self.analytics = analytics
31 | self.delegate = delegate
32 | super.init(nibName: String(describing: SDVotesPopoverViewController.self), bundle: nil)
33 | }
34 |
35 | required init?(coder: NSCoder) {
36 | fatalError("init(coder:) has not been implemented")
37 | }
38 |
39 | override func viewDidAppear(_ animated: Bool) {
40 | super.viewDidAppear(animated)
41 | analytics.logScreenName(.votes, class: SDVotesPopoverViewController.self)
42 | }
43 |
44 | @IBAction func didVoteLike(_ sender: AnyObject) {
45 | self.sendVoteElection(VoteType.like)
46 | }
47 |
48 | @IBAction func didVoteNeutral(_ sender: AnyObject) {
49 | self.sendVoteElection(VoteType.neutral)
50 | }
51 |
52 | @IBAction func didVoteDontLike(_ sender: AnyObject) {
53 | self.sendVoteElection(VoteType.unlike)
54 | }
55 |
56 | func sendVoteElection(_ vote: VoteType) {
57 | delegate?.didSelectVoteValue(vote)
58 | self.dismiss(animated: true, completion: nil)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/SDWebViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDWebViewController: UIViewController {
20 |
21 | @IBOutlet weak var webView: UIWebView!
22 | var url: URL?
23 | private let analytics: Analytics
24 |
25 | init(analytics: Analytics) {
26 | self.analytics = analytics
27 | super.init(nibName: String(describing: SDWebViewController.self), bundle: nil)
28 | }
29 |
30 | required init?(coder: NSCoder) {
31 | fatalError("init(coder:) has not been implemented")
32 | }
33 |
34 | override func viewDidLoad() {
35 | super.viewDidLoad()
36 | webView.scalesPageToFit = true
37 | if let _url = url {
38 | loadUrl(_url)
39 | }
40 | }
41 |
42 | override func viewDidAppear(_ animated: Bool) {
43 | super.viewDidAppear(animated)
44 | analytics.logScreenName(.webView, class: SDWebViewController.self)
45 | }
46 |
47 | func loadUrl(_ url: URL) {
48 | webView.loadRequest(URLRequest(url: url))
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/SDWebViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ScalaDays/Controllers/ScalaDayViewController.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | protocol ScalaDayViewController: UIViewController {
4 | func updateConference(_ conference: Conference)
5 | }
6 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/Array+Extension.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | extension Array {
4 |
5 | public subscript(safe index: Int) -> Element? {
6 | guard index >= 0 && index < count else { return nil }
7 | return self[index]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/Bundle+Extension.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | private class DummyBundle { }
4 |
5 | extension Bundle {
6 | static var local: Bundle {
7 | return Bundle(for: DummyBundle.self)
8 | }
9 |
10 | static var localModuleName: String {
11 | guard let dictionary = Bundle.local.infoDictionary else { return "" }
12 | return dictionary[kCFBundleNameKey as String] as? String ?? ""
13 | }
14 |
15 | static func loadView(nibName: String) -> UIView? {
16 | return Bundle.local.loadNibNamed(nibName, owner: self, options: nil)?.first as? UIView
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDColor.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | extension UIColor {
20 |
21 | class func grayScaleColor(_ grayScale: CGFloat) -> UIColor {
22 | return UIColor(red: grayScale / 255.0, green: grayScale / 255.0, blue: grayScale / 255.0, alpha: 1.0)
23 | }
24 |
25 | class func appColor() -> UIColor {
26 | return UIColor(red: 54/255, green: 69/255, blue: 80/255, alpha: 255/255)
27 | }
28 |
29 | class func selectedCellMenu() -> UIColor {
30 | return UIColor(red: 43/255, green: 56/255, blue: 65/255, alpha: 255/255)
31 | }
32 |
33 | class func appRedColor() -> UIColor {
34 | return UIColor(red: 224/255, green: 95/255, blue: 94/255, alpha: 255/255)
35 | }
36 |
37 | class func appScheduleBlueBackgroundColor() -> UIColor {
38 | return UIColor(red: 108/255, green: 207/255, blue: 233/255, alpha: 255/255)
39 | }
40 |
41 | class func appScheduleTimeBlueBackgroundColor() -> UIColor {
42 | return UIColor(red: 108/255, green: 207/255, blue: 233/255, alpha: 255/255)
43 | }
44 |
45 | class func appSeparatorLineColor() -> UIColor {
46 | return UIColor(red: 54/255, green: 69/255, blue: 80/255, alpha: 0.3)
47 | }
48 |
49 | class func disabledButtonColor() -> UIColor {
50 | return grayScaleColor(190.0)
51 | }
52 |
53 | class func enabledSendVoteButtonColor() -> UIColor {
54 | return grayScaleColor(12.0)
55 | }
56 |
57 | class func grayButtonBorder() -> UIColor {
58 | return grayScaleColor(218.0)
59 | }
60 |
61 | class func grayCommentsPlaceholder() -> UIColor {
62 | return grayScaleColor(185.0)
63 | }
64 |
65 | class func blackForCommentsNormalText() -> UIColor {
66 | return UIColor(red: 41.0/255.0, green: 53.0/255.0, blue: 63.0/255.0, alpha: 1.0)
67 | }
68 |
69 | }
70 |
71 |
72 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDFonts.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | extension UIFont {
20 |
21 | class func fontHelveticaNeue(_ fontSize: CGFloat) -> UIFont {
22 | return UIFont(name: "HelveticaNeue", size: fontSize)!
23 | }
24 |
25 | class func fontHelveticaNeueItalic(_ fontSize: CGFloat) -> UIFont {
26 | return UIFont(name: "HelveticaNeue-Italic", size: fontSize)!
27 | }
28 |
29 | class func fontHelveticaNeueBold(_ fontSize: CGFloat) -> UIFont {
30 | return UIFont(name: "HelveticaNeue-Bold", size: fontSize)!
31 | }
32 |
33 | class func fontHelveticaNeueMedium(_ fontSize: CGFloat) -> UIFont {
34 | return UIFont(name: "HelveticaNeue-Medium", size: fontSize)!
35 | }
36 |
37 | class func fontHelveticaNeueLight(_ fontSize: CGFloat) -> UIFont {
38 | return UIFont(name: "HelveticaNeue-Light", size: fontSize)!
39 | }
40 |
41 | }
42 |
43 | extension UILabel {
44 |
45 | @discardableResult
46 | func setCustomFont(_ typeFont: UIFont, colorFont: UIColor) -> UILabel {
47 | self.font = typeFont
48 | self.textColor = colorFont
49 | self.sizeToFit()
50 | return self
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDImageView-Circular.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | extension UIImageView {
20 |
21 | func circularImage() -> Void {
22 | self.layer.cornerRadius = self.frame.size.width / 2
23 | self.layer.masksToBounds = true
24 | self.clipsToBounds = true
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDMapView-ZoomOut.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 | import MapKit
19 |
20 | extension MKMapView {
21 |
22 | // TODO: the ideal approach to this would be to use a recursive function to calculate the middle point of
23 | // our map's annotations in order to avoid mutability. But sadly it seems that while Swift uses tail call
24 | // optimization *sometimes*, it won't guarantee that in any way.
25 | //
26 | // You can find more information about this in this blog post from Natasha The Robot:
27 | // http://natashatherobot.com/functional-swift-tail-recursion/
28 |
29 | func zoomToFitMapAnnotations() {
30 | guard self.annotations.count != 0 else { return }
31 |
32 | let kZoomOutRatio = 50.0
33 | var topLeftCoord = CLLocationCoordinate2D(latitude: -90, longitude: 180)
34 | var bottomRightCoord = CLLocationCoordinate2D(latitude: 90, longitude: -180)
35 | for annotation in self.annotations {
36 | topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
37 | topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
38 | bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
39 | bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
40 | }
41 | let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5,
42 | longitude: topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5),
43 | span: MKCoordinateSpan(latitudeDelta: fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * kZoomOutRatio, longitudeDelta: fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * kZoomOutRatio))
44 |
45 | let regionFits = self.regionThatFits(region)
46 | guard !regionFits.isInvalid else { return }
47 | self.setRegion(regionFits, animated: true)
48 | }
49 | }
50 |
51 |
52 | // MARK: - Helpers
53 | extension MKCoordinateRegion {
54 | var isInvalid: Bool { span.isInvalid }
55 | }
56 |
57 | extension MKCoordinateSpan {
58 | var isInvalid: Bool { latitudeDelta.isNaN || longitudeDelta.isNaN }
59 | }
60 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDString+RemoveWhiteSpaces.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 |
19 | extension String {
20 | func removeWhitespace() -> String {
21 | components(separatedBy: CharacterSet.whitespacesAndNewlines)
22 | .filter { !$0.isEmpty }
23 | .joined(separator: " ")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDUIViewControllerExtension.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | extension UIViewController {
20 |
21 | func setNavigationBarItem() {
22 | self.addLeftBarButtonWithImage(UIImage(named: "navigation_bar_icon_menu")!)
23 | self.navigationController?.navigationBar.isTranslucent = false
24 | self.navigationController?.navigationBar.shadowImage = UIImage()
25 | self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDView-NibLoading.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 | // FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
19 | // Consider refactoring the code to use the non-optional operators.
20 | fileprivate func < (lhs: T?, rhs: T?) -> Bool {
21 | switch (lhs, rhs) {
22 | case let (l?, r?):
23 | return l < r
24 | case (nil, _?):
25 | return true
26 | default:
27 | return false
28 | }
29 | }
30 |
31 | // FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
32 | // Consider refactoring the code to use the non-optional operators.
33 | fileprivate func > (lhs: T?, rhs: T?) -> Bool {
34 | switch (lhs, rhs) {
35 | case let (l?, r?):
36 | return l > r
37 | default:
38 | return rhs < lhs
39 | }
40 | }
41 |
42 |
43 | extension UIView {
44 |
45 | func loadNibSubviewsFromNib(_ nibName: String) -> UIView? {
46 | let objects = Bundle.main.loadNibNamed(nibName, owner: self, options: nil)
47 |
48 | objects?.filter({$0 is UIView})
49 | if objects?.count > 0 {
50 | let containerView = objects![0] as! UIView
51 | containerView.translatesAutoresizingMaskIntoConstraints = false
52 | addSubview(containerView)
53 | needsUpdateConstraints()
54 |
55 | return containerView
56 | }
57 | return nil
58 | }
59 |
60 | func updateCustomConstraints(_ customConstraints : NSMutableArray, containerView: UIView!) {
61 |
62 | for object in customConstraints {
63 | if let const = object as? NSLayoutConstraint {
64 | removeConstraint(const)
65 | }
66 | }
67 | customConstraints.removeAllObjects()
68 |
69 | if containerView != nil {
70 | let viewDictionary : NSDictionary = ["view" : containerView]
71 | customConstraints.addObjects(from: NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: viewDictionary as! [String : AnyObject]))
72 | customConstraints.addObjects(from: NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: viewDictionary as! [String:AnyObject]))
73 |
74 | for object in customConstraints {
75 | if let const = object as? NSLayoutConstraint {
76 | addConstraint(const)
77 | }
78 | }
79 | }
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/SDZBarSymbolSet-Enumeration.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 | import ZBarSDK
19 |
20 | extension ZBarSymbolSet: Sequence {
21 | public func makeIterator() -> NSFastEnumerationIterator {
22 | return NSFastEnumerationIterator(self)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ScalaDays/Extension/UIColor+Extension.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | extension UIColor {
4 |
5 | var hex: String? {
6 | guard let components = cgColor.components,
7 | let r = components[safe: 0],
8 | let g = components[safe: 1],
9 | let b = components[safe: 2] else { return nil }
10 |
11 | let a = components[safe: 3] ?? 1.0
12 |
13 | return String(format: "%02X%02X%02X%02X",
14 | lroundf(Float(r) * 255.0),
15 | lroundf(Float(g) * 255.0),
16 | lroundf(Float(b) * 255.0),
17 | lroundf(Float(a) * 255.0))
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Alerts/SDAlertViewHelper.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDAlertViewHelper: NSObject {
20 | class func showSimpleAlertViewOnViewController(_ viewController: UIViewController!, title: String?, message: String?, cancelButtonTitle: String!, otherButtonTitle: String?, tag: Int?, delegate: UIAlertViewDelegate?, handler: ((UIAlertAction?) -> Void)?) {
21 | if isIOS8OrLater() {
22 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
23 | let actionCancel = UIAlertAction(title: cancelButtonTitle, style: .cancel, handler: handler)
24 | if let otherButton = otherButtonTitle {
25 | let actionOther = UIAlertAction(title: otherButton, style: .default, handler: handler)
26 | alertController.addAction(actionOther)
27 | }
28 |
29 | alertController.addAction(actionCancel)
30 | viewController.present(alertController, animated: true, completion: nil)
31 | } else {
32 | let alertView = UIAlertView()
33 | if let unwrappedTitle = title {
34 | alertView.title = unwrappedTitle
35 | }
36 | alertView.message = message
37 | alertView.delegate = delegate
38 | alertView.addButton(withTitle: cancelButtonTitle)
39 | alertView.cancelButtonIndex = 0
40 | if let unwrappedOtherButton = otherButtonTitle {
41 | alertView.addButton(withTitle: unwrappedOtherButton)
42 | }
43 | if let unwrappedTag = tag {
44 | alertView.tag = unwrappedTag
45 | }
46 | alertView.show()
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Analytics/Analytics.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | enum AnalyticEvent {
4 | enum ScreenName: String {
5 | case slideMenu = "Slide Menu"
6 | case schedule = "Schedule"
7 | case social = "Social"
8 | case speakers = "Speakers"
9 | case tickets = "Tickets"
10 | case contact = "Contact"
11 | case sponsors = "Sponsors"
12 | case places = "Places"
13 | case about = "About"
14 | case menu = "Menu"
15 | case votes = "Votes"
16 | case webView = "Web View"
17 | case notification = "Notifications"
18 | }
19 |
20 | enum Category: String {
21 | case filter = "Filter"
22 | case favorites = "Favorites"
23 | case navigate = "Navigate"
24 | case vote = "Vote"
25 | }
26 |
27 | enum Action: String {
28 | case filterAll = "All"
29 | case filterFavorites = "Favorites"
30 | case goToDetail = "Go to Detail"
31 | case addToFavorite = "Add"
32 | case removeToFavorite = "Remove"
33 | case goToTweet = "Go to Tweet"
34 | case postTweet = "Post Tweet"
35 | case cancelTweet = "Cancel Tweet"
36 | case goToUser = "Go to User"
37 | case goToTicket = "Go to Ticket"
38 | case scanContact = "Scan Contact"
39 | case goToSponsor = "Go to Sponsor"
40 | case goToMap = "Go to Map"
41 | case goToSite = "Go to 47Deg Website"
42 | case goToFeedbackForm = "Go to anonymous feedback"
43 | case menuChangeConference = "Change Conference"
44 | case showVotingDialog = "Show Voting Dialog"
45 | case sendVote = "Send Vote"
46 | }
47 | }
48 |
49 |
50 | protocol Analytics {
51 | func logScreenName(_ screen: AnalyticEvent.ScreenName, class: UIViewController.Type)
52 | func logEvent(screenName: AnalyticEvent.ScreenName, category: AnalyticEvent.Category, action: AnalyticEvent.Action)
53 | func logEvent(screenName: AnalyticEvent.ScreenName, category: AnalyticEvent.Category, action: AnalyticEvent.Action, label: String)
54 | }
55 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Analytics/FirebaseScalaDays.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Firebase
3 |
4 | struct ScalaDaysAnalytics: Analytics {
5 |
6 | func logScreenName(_ screen: AnalyticEvent.ScreenName, class screenClass: UIViewController.Type) {
7 | Firebase.Analytics.setScreenName("\(screen)", screenClass: String(describing: screenClass))
8 | }
9 |
10 | func logEvent(screenName: AnalyticEvent.ScreenName, category: AnalyticEvent.Category, action: AnalyticEvent.Action) {
11 | log(screenName: screenName, category: category, action: action, label: nil)
12 | }
13 |
14 | func logEvent(screenName: AnalyticEvent.ScreenName, category: AnalyticEvent.Category, action: AnalyticEvent.Action, label: String) {
15 | log(screenName: screenName, category: category, action: action, label: label)
16 | }
17 |
18 | // MARK: private methods
19 | func log(screenName: AnalyticEvent.ScreenName, category: AnalyticEvent.Category, action: AnalyticEvent.Action, label: String?) {
20 | Firebase.Analytics.logEvent("\(screenName)", parameters: [
21 | "category": "\(category)" as NSObject,
22 | "action": "\(action)" as NSObject,
23 | "label": "\(label ?? "nil")" as NSObject
24 | ])
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Animation/SDAnimationHelper.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDAnimationHelper: NSObject {
20 |
21 | class func showViewWithFadeInAnimation(_ view: UIView) {
22 | SDAnimationHelper.showViewWithFadeInAnimation(view, maxAlphaValue: 1.0)
23 | }
24 |
25 | class func showViewWithFadeInAnimation(_ view: UIView, maxAlphaValue: CGFloat) {
26 | view.alpha = 0
27 | view.isHidden = false
28 | UIView.animate(withDuration: kAnimationShowHideTimeInterval, animations: { () -> Void in
29 | view.alpha = maxAlphaValue
30 | })
31 | }
32 |
33 | class func hideViewWithFadeOutAnimation(_ view: UIView) {
34 | UIView.animate(withDuration: kAnimationShowHideTimeInterval, animations: { () -> Void in
35 | view.alpha = 0
36 | }, completion: { (animated) -> Void in
37 | view.isHidden = true
38 | })
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Contacts/SDContactCreationHelper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface SDContactCreationHelper : NSObject
20 |
21 | typedef NS_ENUM(int, SDContactCreationHelperError) {
22 | SDContactCreationHelperErrorNoError,
23 | SDContactCreationHelperErrorInvalidVCardData,
24 | SDContactCreationHelperErrorUnknown
25 | };
26 | typedef void (^SDContactCreationHelperCompletionHandler)(SDContactCreationHelperError error);
27 |
28 | + (void)createContactInAddressBookFromVCardString:(NSString *)vCardString completion:(SDContactCreationHelperCompletionHandler)completion;
29 | + (NSString *)contactNameFromVCardString:(NSString *)vCardString;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Contacts/SDContactCreationHelper.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "SDContactCreationHelper.h"
18 | #import
19 |
20 | @implementation SDContactCreationHelper
21 |
22 | + (void)createContactInAddressBookFromVCardString:(NSString *)vCardString completion:(SDContactCreationHelperCompletionHandler)completion {
23 | CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];
24 | ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
25 | ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
26 | CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
27 | if (vCardPeople != nil && CFArrayGetCount(vCardPeople) > 0) {
28 | ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, 0);
29 | if (ABAddressBookAddRecord(book, person, NULL) && ABAddressBookSave(book, NULL)) {
30 | completion(SDContactCreationHelperErrorNoError);
31 | return;
32 | } else {
33 | completion(SDContactCreationHelperErrorUnknown);
34 | return;
35 | }
36 | } else {
37 | completion(SDContactCreationHelperErrorInvalidVCardData);
38 | return;
39 | }
40 | }
41 |
42 | + (NSString *)contactNameFromABRecord:(ABRecordRef)person {
43 | NSString *name = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
44 | NSString *lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
45 | NSString *nameToReturn = nil;
46 | if(name != nil && lastName != nil) {
47 | nameToReturn = [NSString stringWithFormat:@"%@ %@", name, lastName];
48 | } else if(name != nil) {
49 | nameToReturn = name;
50 | } else if(lastName != nil){
51 | nameToReturn = lastName;
52 | }
53 | return nameToReturn;
54 | }
55 |
56 | + (NSString *)contactNameFromVCardString:(NSString *)vCardString {
57 | CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];
58 | ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
59 | ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
60 | CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
61 | if (vCardPeople != nil && CFArrayGetCount(vCardPeople) > 0) {
62 | ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, 0);
63 | return [SDContactCreationHelper contactNameFromABRecord:person];
64 | }
65 | return nil;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Protocols/SDMenuControllerItem.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | @objc protocol SDMenuControllerItem {
18 |
19 | var isDataLoaded : Bool { get set }
20 |
21 | func loadData()
22 |
23 | }
24 |
25 | @objc protocol SDSliderMenuBar {
26 |
27 | func didCloseMenu()
28 |
29 | }
--------------------------------------------------------------------------------
/ScalaDays/Helpers/SDConstants.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 | import UIKit
19 |
20 | let kExternalKeysPlistFilename = "SDExternalKeys"
21 | let kExternalKeysDKTwitterConsumerKey = "TwitterConsumerKey"
22 | let kExternalKeysDKTwitterConsumerSecret = "TwitterConsumerSecret"
23 |
24 | let IS_IPHONE5 = UIScreen.main.bounds.size.height == 480;
25 |
26 | let icon_menu_schedule = "menu_icon_schedule"
27 | let icon_menu_social = "menu_icon_social"
28 | let icon_menu_contact = "menu_icon_contact"
29 | let icon_menu_ticket = "menu_icon_ticket"
30 | let icon_menu_sponsors = "menu_icon_sponsors"
31 | let icon_menu_places = "menu_icon_places"
32 | let icon_menu_about = "menu_icon_about"
33 | let icon_menu_speakers = "menu_icon_speakers"
34 |
35 | let Height_Row_Menu: CGFloat = 50
36 | let Height_Header_Menu: CGFloat = 130
37 | let kEstimatedDynamicCellsRowHeightHigh : CGFloat = 160.0
38 | let kEstimatedDynamicCellsRowHeightLow : CGFloat = 132.0
39 |
40 | let kAnimationShowHideTimeInterval : TimeInterval = 0.3
41 | let kTweetCount = 100
42 | let kGlobalPadding : CGFloat = 15.0
43 |
44 | let kMinimumTimeToDownloadDataFromApiInSeconds : TimeInterval = 5*60
45 |
46 | let lastModifiedDate = "Last-Modified"
47 | let url47Website = "http://www.47deg.com"
48 | let kAlphaValueFull: CGFloat = 1.0
49 |
50 | let isIOS8OrLater = {() -> Bool in
51 | switch UIDevice.current.systemVersion.compare("8.0.0", options: NSString.CompareOptions.numeric) {
52 | case .orderedSame, .orderedDescending:
53 | return true
54 | case .orderedAscending:
55 | return false
56 | }
57 | }
58 |
59 | @discardableResult
60 | func launchSafariToUrl(_ url: URL) -> Bool {
61 | guard UIApplication.shared.canOpenURL(url) else { return false }
62 | UIApplication.shared.openURL(url)
63 | return true
64 | }
65 |
66 | let screenBounds = UIScreen.main.bounds
67 | let colorScheduleTime = UIColor(red: 70/255, green: 149/255, blue: 174/255, alpha: 1)
68 | let colorScheduleTimeActive = UIColor(red: 51/255, green: 116/255, blue: 136/255, alpha: 1)
69 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Social/SDSocialHandler.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 | import TwitterKit
19 |
20 | // MARK: Tweet dictionary keys
21 |
22 | private let kTweetDKStatus = "status"
23 | private let kTwitterBaseURL = "http://www.twitter.com/"
24 | private let kTwitterBaseAppURL = "twitter://status?id="
25 | private let kTwitterBaseAppURLUser = "twitter://user?screen_name="
26 |
27 | enum SDGetTweetsError: Int {
28 | case invalidRequest
29 | case unknown
30 | case unauthorized
31 | }
32 |
33 | enum SDGetTweetsResult {
34 | case success(tweets: [SDTweet])
35 | case failure(error: SDGetTweetsError)
36 | }
37 |
38 | class SDSocialHandler {
39 |
40 | func fetchTweetList(withHashtag hashtag: String, count: Int, completion: @escaping (SDGetTweetsResult) -> Void) {
41 | guard let hashtag = hashtag.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else {
42 | completion(.failure(error: .invalidRequest))
43 | return
44 | }
45 |
46 | let userID = TWTRTwitter.sharedInstance().sessionStore.session()?.userID
47 | let apiClient = TWTRAPIClient(userID: userID)
48 | let searchTimelineDataSource = TWTRSearchTimelineDataSource(searchQuery: hashtag,
49 | apiClient: apiClient,
50 | languageCode: nil,
51 | maxTweetsPerRequest: UInt(max(count, 0)),
52 | resultType: nil)
53 |
54 | searchTimelineDataSource.loadPreviousTweets(beforePosition: nil) { (tweets, _, error) in
55 | if let tweets = tweets {
56 | completion(.success(tweets: tweets.map { $0.sdTweet() }))
57 | } else if let _ = error, let userId = userID {
58 | TWTRTwitter.sharedInstance().sessionStore.logOutUserID(userId)
59 | completion(.failure(error: .unauthorized))
60 | } else {
61 | completion(.failure(error: .unknown))
62 | }
63 | }
64 | }
65 | }
66 |
67 | // MARK: - Tweet detail URL creation
68 |
69 | extension SDSocialHandler {
70 | class func urlForTweetDetail(_ tweet: SDTweet) -> URL? {
71 | return URL(string: (((kTwitterBaseURL as NSString).appendingPathComponent(tweet.username) as NSString)
72 | .appendingPathComponent(kTweetDKStatus) as NSString)
73 | .appendingPathComponent(tweet.id))
74 | }
75 |
76 | class func urlAppForTweetDetail(_ tweet: SDTweet) -> URL? {
77 | return URL(string: kTwitterBaseAppURL + tweet.id)
78 | }
79 |
80 | class func urlForTwitterAccount(_ twitterAccount: String) -> URL? {
81 | return URL(string: (kTwitterBaseURL as NSString).appendingPathComponent(twitterAccount))
82 | }
83 |
84 | class func urlAppForTwitterAccount(_ twitterAccount: String) -> URL? {
85 | return URL(string: (kTwitterBaseAppURLUser as NSString).appendingPathComponent(twitterAccount))
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Social/TWTRTweet+SDTweet.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 | import TwitterKit
19 |
20 | extension TWTRTweet {
21 | func sdTweet() -> SDTweet {
22 | return SDTweet(username: author.name,
23 | fullName: author.screenName,
24 | tweetText: text,
25 | profileImage: author.profileImageURL,
26 | date: createdAt,
27 | id: tweetID)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Social/TwitterSocialController.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Social
3 |
4 | enum TwitterSocialController {
5 | static func present(in vc: UIViewController, text: String) {
6 | guard TwitterSocialController.installed,
7 | let composeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter) else { return }
8 |
9 | composeViewController.title = "Scala Days"
10 | composeViewController.setInitialText("\(text) ")
11 |
12 | vc.present(composeViewController, animated: true)
13 | }
14 |
15 | static var installed: Bool {
16 | guard let url = URL(string: "twitter://") else { return false }
17 | return UIApplication.shared.canOpenURL(url)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Storing/StoringHelper.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 |
19 | class StoringHelper {
20 |
21 | let kMainConferenceStoringFilename = "sdConferencesNew.data"
22 | let kVotesFilename = "sdVotesNew.data"
23 | let kVotesFilenameOld = "sdVotes.data"
24 |
25 | class var sharedInstance: StoringHelper {
26 | struct Static {
27 | static let instance: StoringHelper = StoringHelper()
28 | }
29 | return Static.instance
30 | }
31 |
32 | // MARK: - Conference storing
33 |
34 | func storeConferenceData(_ conferences: Conferences) {
35 | storeDataToFileWithFilename(conferences, filename: kMainConferenceStoringFilename)
36 | }
37 |
38 | func loadConferenceData() -> Conferences? {
39 | return loadDataFromFileWithFilename(kMainConferenceStoringFilename)
40 | }
41 |
42 | // MARK: - Votes storing
43 |
44 | func storeVotesData(_ votes: [String: Vote]) {
45 | storeDataToFileWithFilename(votes, filename: kVotesFilename)
46 | }
47 |
48 | func loadVotesData() -> [String: Vote]? {
49 | return loadDataFromFileWithFilename(kVotesFilename)
50 | }
51 |
52 | func storedVoteForConferenceId(_ conferenceId: Int, talkId: Int) -> Vote? {
53 | if let votes = loadVotesData() {
54 | let key = "\(conferenceId)\(talkId)"
55 | return votes[key]
56 | }
57 | return nil
58 | }
59 |
60 | // MARK: - Utility functions
61 |
62 | class func documentsFolderPath() -> String {
63 | return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
64 | }
65 |
66 | func loadDataFromFileWithFilename(_ filename: String) -> T? {
67 | let fileManager = FileManager.default
68 | let dataPath = (StoringHelper.documentsFolderPath() as NSString).appendingPathComponent(filename)
69 |
70 | guard fileManager.fileExists(atPath: dataPath),
71 | let data = NSKeyedUnarchiver.unarchiveObject(withFile: dataPath) as? Data else {
72 | return nil
73 | }
74 |
75 | return try? JSONDecoder().decode(T.self, from: data)
76 | }
77 |
78 | func storeDataToFileWithFilename(_ value: T, filename: String) {
79 | let conferenceDataPath = (StoringHelper.documentsFolderPath() as NSString).appendingPathComponent(filename)
80 | guard let data = try? JSONEncoder().encode(value) else { return }
81 |
82 | NSKeyedArchiver.archiveRootObject(data, toFile: conferenceDataPath)
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/ScalaDays/Helpers/Storing/UserDefaults+Extension.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | @propertyWrapper
4 | struct UserDefault {
5 | let key: String
6 | let defaultValue: T
7 |
8 | init(_ key: String, defaultValue: T) {
9 | self.key = key
10 | self.defaultValue = defaultValue
11 | }
12 |
13 | var wrappedValue: T {
14 | get {
15 | guard let raw = UserDefaults.standard.data(forKey: key),
16 | let value = try? PropertyListDecoder().decode(T.self, from: raw) else { return defaultValue }
17 | return value
18 | }
19 | set {
20 | let valueRaw = try? PropertyListEncoder().encode(newValue)
21 | UserDefaults.standard.set(valueRaw, forKey: key)
22 | UserDefaults.standard.synchronize()
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/1024x1024.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "size" : "29x29",
15 | "idiom" : "iphone",
16 | "filename" : "icon-app-29x29@2x.png",
17 | "scale" : "2x"
18 | },
19 | {
20 | "size" : "29x29",
21 | "idiom" : "iphone",
22 | "filename" : "icon-app-29x29@3x.png",
23 | "scale" : "3x"
24 | },
25 | {
26 | "size" : "40x40",
27 | "idiom" : "iphone",
28 | "filename" : "icon-app-40x40@2x-1.png",
29 | "scale" : "2x"
30 | },
31 | {
32 | "size" : "40x40",
33 | "idiom" : "iphone",
34 | "filename" : "icon-app-40x40@3x.png",
35 | "scale" : "3x"
36 | },
37 | {
38 | "size" : "60x60",
39 | "idiom" : "iphone",
40 | "filename" : "icon-app-60x60@2x.png",
41 | "scale" : "2x"
42 | },
43 | {
44 | "size" : "60x60",
45 | "idiom" : "iphone",
46 | "filename" : "icon-app-60x60@3x.png",
47 | "scale" : "3x"
48 | },
49 | {
50 | "idiom" : "ipad",
51 | "size" : "20x20",
52 | "scale" : "1x"
53 | },
54 | {
55 | "idiom" : "ipad",
56 | "size" : "20x20",
57 | "scale" : "2x"
58 | },
59 | {
60 | "size" : "29x29",
61 | "idiom" : "ipad",
62 | "filename" : "icon-app-29x29.png",
63 | "scale" : "1x"
64 | },
65 | {
66 | "size" : "29x29",
67 | "idiom" : "ipad",
68 | "filename" : "icon-app-29x29@2x-1.png",
69 | "scale" : "2x"
70 | },
71 | {
72 | "size" : "40x40",
73 | "idiom" : "ipad",
74 | "filename" : "icon-app-40x40.png",
75 | "scale" : "1x"
76 | },
77 | {
78 | "size" : "40x40",
79 | "idiom" : "ipad",
80 | "filename" : "icon-app-40x40@2x.png",
81 | "scale" : "2x"
82 | },
83 | {
84 | "size" : "76x76",
85 | "idiom" : "ipad",
86 | "filename" : "icon-app-76x76.png",
87 | "scale" : "1x"
88 | },
89 | {
90 | "size" : "76x76",
91 | "idiom" : "ipad",
92 | "filename" : "icon-app-76x76@2x.png",
93 | "scale" : "2x"
94 | },
95 | {
96 | "size" : "83.5x83.5",
97 | "idiom" : "ipad",
98 | "filename" : "icon-app-83.5x83.5@2x.png",
99 | "scale" : "2x"
100 | },
101 | {
102 | "size" : "1024x1024",
103 | "idiom" : "ios-marketing",
104 | "filename" : "1024x1024.png",
105 | "scale" : "1x"
106 | }
107 | ],
108 | "info" : {
109 | "version" : 1,
110 | "author" : "xcode"
111 | }
112 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29@2x-1.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-29x29@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40@2x-1.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-40x40@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-60x60@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-60x60@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-76x76.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-76x76@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/AppIcon.appiconset/icon-app-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "2436h",
7 | "filename" : "splash-iphonex.png",
8 | "minimum-system-version" : "11.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "orientation" : "landscape",
14 | "idiom" : "iphone",
15 | "extent" : "full-screen",
16 | "minimum-system-version" : "11.0",
17 | "subtype" : "2436h",
18 | "scale" : "3x"
19 | },
20 | {
21 | "extent" : "full-screen",
22 | "idiom" : "iphone",
23 | "subtype" : "736h",
24 | "filename" : "splash-iphone6-plus.png",
25 | "minimum-system-version" : "8.0",
26 | "orientation" : "portrait",
27 | "scale" : "3x"
28 | },
29 | {
30 | "orientation" : "landscape",
31 | "idiom" : "iphone",
32 | "extent" : "full-screen",
33 | "minimum-system-version" : "8.0",
34 | "subtype" : "736h",
35 | "scale" : "3x"
36 | },
37 | {
38 | "extent" : "full-screen",
39 | "idiom" : "iphone",
40 | "subtype" : "667h",
41 | "filename" : "splash-iphone6.png",
42 | "minimum-system-version" : "8.0",
43 | "orientation" : "portrait",
44 | "scale" : "2x"
45 | },
46 | {
47 | "orientation" : "portrait",
48 | "idiom" : "iphone",
49 | "filename" : "splash-iphone4@2x.png",
50 | "extent" : "full-screen",
51 | "minimum-system-version" : "7.0",
52 | "scale" : "2x"
53 | },
54 | {
55 | "extent" : "full-screen",
56 | "idiom" : "iphone",
57 | "subtype" : "retina4",
58 | "filename" : "splash-iphone5.png",
59 | "minimum-system-version" : "7.0",
60 | "orientation" : "portrait",
61 | "scale" : "2x"
62 | },
63 | {
64 | "orientation" : "portrait",
65 | "idiom" : "iphone",
66 | "extent" : "full-screen",
67 | "scale" : "1x"
68 | },
69 | {
70 | "orientation" : "portrait",
71 | "idiom" : "iphone",
72 | "extent" : "full-screen",
73 | "scale" : "2x"
74 | },
75 | {
76 | "orientation" : "portrait",
77 | "idiom" : "iphone",
78 | "extent" : "full-screen",
79 | "subtype" : "retina4",
80 | "scale" : "2x"
81 | }
82 | ],
83 | "info" : {
84 | "version" : 1,
85 | "author" : "xcode"
86 | }
87 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone4@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone5.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone6-plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone6-plus.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphone6.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphonex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/LaunchImage.launchimage/splash-iphonex.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/avatar.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "avatar.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "avatar@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "avatar@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/avatar.imageset/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/avatar.imageset/avatar.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/avatar.imageset/avatar@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/avatar.imageset/avatar@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/avatar.imageset/avatar@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/avatar.imageset/avatar@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/empty_notifications.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "iconfinder_feature-available_4171950 (1).png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "iconfinder_feature-available_4171950 (2)-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "iconfinder_feature-available_4171950.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/empty_notifications.imageset/iconfinder_feature-available_4171950 (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/empty_notifications.imageset/iconfinder_feature-available_4171950 (1).png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/empty_notifications.imageset/iconfinder_feature-available_4171950 (2)-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/empty_notifications.imageset/iconfinder_feature-available_4171950 (2)-1.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/empty_notifications.imageset/iconfinder_feature-available_4171950.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/empty_notifications.imageset/iconfinder_feature-available_4171950.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "list_icon_vote_like.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "list_icon_vote_like@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "list_icon_vote_like@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/list_icon_vote_like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/list_icon_vote_like.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/list_icon_vote_like@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/list_icon_vote_like@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/list_icon_vote_like@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_like.imageset/list_icon_vote_like@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "list_icon_vote_neutral.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "list_icon_vote_neutral@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "list_icon_vote_neutral@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/list_icon_vote_neutral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/list_icon_vote_neutral.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/list_icon_vote_neutral@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/list_icon_vote_neutral@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/list_icon_vote_neutral@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_neutral.imageset/list_icon_vote_neutral@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "list_icon_vote_unlike.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "list_icon_vote_unlike@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "list_icon_vote_unlike@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/list_icon_vote_unlike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/list_icon_vote_unlike.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/list_icon_vote_unlike@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/list_icon_vote_unlike@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/list_icon_vote_unlike@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/list_icon_vote_unlike.imageset/list_icon_vote_unlike@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/logo_47deg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "logo_47deg.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "logo_47deg@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "logo_47deg@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/logo_47deg.imageset/logo_47deg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/logo_47deg.imageset/logo_47deg.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/logo_47deg.imageset/logo_47deg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/logo_47deg.imageset/logo_47deg@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/logo_47deg.imageset/logo_47deg@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/logo_47deg.imageset/logo_47deg@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_popover.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "map_popover.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "map_popover@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "map_popover@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_popover.imageset/map_popover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/map_popover.imageset/map_popover.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_popover.imageset/map_popover@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/map_popover.imageset/map_popover@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_popover.imageset/map_popover@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/map_popover.imageset/map_popover@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_pushpin.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "map_pushpin.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "map_pushpin@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "map_pushpin@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_pushpin.imageset/map_pushpin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/map_pushpin.imageset/map_pushpin.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_pushpin.imageset/map_pushpin@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/map_pushpin.imageset/map_pushpin@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/map_pushpin.imageset/map_pushpin@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/map_pushpin.imageset/map_pushpin@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_header_select_arrow.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_header_select_arrow@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_header_select_arrow@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/menu_header_select_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/menu_header_select_arrow.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/menu_header_select_arrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/menu_header_select_arrow@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/menu_header_select_arrow@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_header_select_arrow.imageset/menu_header_select_arrow@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_about.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_about.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_about@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_about@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_about.imageset/menu_icon_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_about.imageset/menu_icon_about.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_about.imageset/menu_icon_about@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_about.imageset/menu_icon_about@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_about.imageset/menu_icon_about@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_about.imageset/menu_icon_about@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_contact.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_contact.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_contact@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_contact@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_contact.imageset/menu_icon_contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_contact.imageset/menu_icon_contact.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_contact.imageset/menu_icon_contact@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_contact.imageset/menu_icon_contact@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_contact.imageset/menu_icon_contact@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_contact.imageset/menu_icon_contact@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_notification.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bell@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "bell@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "bell@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_notification.imageset/bell@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_notification.imageset/bell@1x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_notification.imageset/bell@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_notification.imageset/bell@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_notification.imageset/bell@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_notification.imageset/bell@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_places.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_places.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_places@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_places@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_places.imageset/menu_icon_places.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_places.imageset/menu_icon_places.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_places.imageset/menu_icon_places@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_places.imageset/menu_icon_places@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_places.imageset/menu_icon_places@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_places.imageset/menu_icon_places@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_schedule.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_schedule@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_schedule@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/menu_icon_schedule.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/menu_icon_schedule.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/menu_icon_schedule@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/menu_icon_schedule@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/menu_icon_schedule@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_schedule.imageset/menu_icon_schedule@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_social.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_social.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_social@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_social@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_social.imageset/menu_icon_social.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_social.imageset/menu_icon_social.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_social.imageset/menu_icon_social@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_social.imageset/menu_icon_social@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_social.imageset/menu_icon_social@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_social.imageset/menu_icon_social@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_speakers.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_speakers@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_speakers@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/menu_icon_speakers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/menu_icon_speakers.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/menu_icon_speakers@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/menu_icon_speakers@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/menu_icon_speakers@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_speakers.imageset/menu_icon_speakers@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_sponsors.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_sponsors@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_sponsors@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/menu_icon_sponsors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/menu_icon_sponsors.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/menu_icon_sponsors@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/menu_icon_sponsors@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/menu_icon_sponsors@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_sponsors.imageset/menu_icon_sponsors@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "menu_icon_ticket.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "menu_icon_ticket@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "menu_icon_ticket@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/menu_icon_ticket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/menu_icon_ticket.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/menu_icon_ticket@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/menu_icon_ticket@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/menu_icon_ticket@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/menu_icon_ticket.imageset/menu_icon_ticket@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_arrow.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_arrow@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_arrow@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/navigation_bar_icon_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/navigation_bar_icon_arrow.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/navigation_bar_icon_arrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/navigation_bar_icon_arrow@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/navigation_bar_icon_arrow@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_arrow.imageset/navigation_bar_icon_arrow@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_clock.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_clock@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_clock@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/navigation_bar_icon_clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/navigation_bar_icon_clock.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/navigation_bar_icon_clock@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/navigation_bar_icon_clock@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/navigation_bar_icon_clock@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_clock.imageset/navigation_bar_icon_clock@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_create.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_create@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_create@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/navigation_bar_icon_create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/navigation_bar_icon_create.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/navigation_bar_icon_create@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/navigation_bar_icon_create@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/navigation_bar_icon_create@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_create.imageset/navigation_bar_icon_create@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_favorite_default.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_favorite_default@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_favorite_default@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/navigation_bar_icon_favorite_default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/navigation_bar_icon_favorite_default.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/navigation_bar_icon_favorite_default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/navigation_bar_icon_favorite_default@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/navigation_bar_icon_favorite_default@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_default.imageset/navigation_bar_icon_favorite_default@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_favorite_selected.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_favorite_selected@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_favorite_selected@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/navigation_bar_icon_favorite_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/navigation_bar_icon_favorite_selected.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/navigation_bar_icon_favorite_selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/navigation_bar_icon_favorite_selected@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/navigation_bar_icon_favorite_selected@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_favorite_selected.imageset/navigation_bar_icon_favorite_selected@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_filter.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_filter@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_filter@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/navigation_bar_icon_filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/navigation_bar_icon_filter.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/navigation_bar_icon_filter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/navigation_bar_icon_filter@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/navigation_bar_icon_filter@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_filter.imageset/navigation_bar_icon_filter@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_menu.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_menu@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_menu@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/navigation_bar_icon_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/navigation_bar_icon_menu.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/navigation_bar_icon_menu@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/navigation_bar_icon_menu@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/navigation_bar_icon_menu@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_menu.imageset/navigation_bar_icon_menu@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "navigation_bar_icon_options.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "navigation_bar_icon_options@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "navigation_bar_icon_options@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/navigation_bar_icon_options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/navigation_bar_icon_options.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/navigation_bar_icon_options@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/navigation_bar_icon_options@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/navigation_bar_icon_options@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_icon_options.imageset/navigation_bar_icon_options@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_post_tweet.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "iconfinder_Sed-17_2236318 (1).png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "iconfinder_Sed-17_2236318.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "template"
24 | }
25 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_post_tweet.imageset/iconfinder_Sed-17_2236318 (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_post_tweet.imageset/iconfinder_Sed-17_2236318 (1).png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/navigation_bar_post_tweet.imageset/iconfinder_Sed-17_2236318.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/navigation_bar_post_tweet.imageset/iconfinder_Sed-17_2236318.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_contact.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "placeholder_contact.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "placeholder_contact@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "placeholder_contact@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_contact.imageset/placeholder_contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_contact.imageset/placeholder_contact.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_contact.imageset/placeholder_contact@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_contact.imageset/placeholder_contact@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_contact.imageset/placeholder_contact@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_contact.imageset/placeholder_contact@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_error.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "placeholder_error.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "placeholder_error@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "placeholder_error@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_error.imageset/placeholder_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_error.imageset/placeholder_error.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_error.imageset/placeholder_error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_error.imageset/placeholder_error@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_error.imageset/placeholder_error@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_error.imageset/placeholder_error@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_general.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "placeholder_general.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "placeholder_general@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "placeholder_general@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_general.imageset/placeholder_general.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_general.imageset/placeholder_general.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_general.imageset/placeholder_general@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_general.imageset/placeholder_general@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_general.imageset/placeholder_general@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_general.imageset/placeholder_general@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_menu.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "placeholder_menu.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "placeholder_menu@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "placeholder_menu@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_menu.imageset/placeholder_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_menu.imageset/placeholder_menu.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_menu.imageset/placeholder_menu@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_menu.imageset/placeholder_menu@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_menu.imageset/placeholder_menu@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_menu.imageset/placeholder_menu@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "placeholder_sponsors.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "placeholder_sponsors@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "placeholder_sponsors@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/placeholder_sponsors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/placeholder_sponsors.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/placeholder_sponsors@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/placeholder_sponsors@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/placeholder_sponsors@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/placeholder_sponsors.imageset/placeholder_sponsors@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "popup_icon_vote_like.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "popup_icon_vote_like@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "popup_icon_vote_like@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/popup_icon_vote_like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/popup_icon_vote_like.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/popup_icon_vote_like@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/popup_icon_vote_like@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/popup_icon_vote_like@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_like.imageset/popup_icon_vote_like@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "popup_icon_vote_like_disabled.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "popup_icon_vote_like_disabled@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "popup_icon_vote_like_disabled@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/popup_icon_vote_like_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/popup_icon_vote_like_disabled.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/popup_icon_vote_like_disabled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/popup_icon_vote_like_disabled@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/popup_icon_vote_like_disabled@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_like_disabled.imageset/popup_icon_vote_like_disabled@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "popup_icon_vote_neutral.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "popup_icon_vote_neutral@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "popup_icon_vote_neutral@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/popup_icon_vote_neutral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/popup_icon_vote_neutral.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/popup_icon_vote_neutral@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/popup_icon_vote_neutral@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/popup_icon_vote_neutral@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_neutral.imageset/popup_icon_vote_neutral@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "popup_icon_vote_neutral_disabled.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "popup_icon_vote_neutral_disabled@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "popup_icon_vote_neutral_disabled@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/popup_icon_vote_neutral_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/popup_icon_vote_neutral_disabled.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/popup_icon_vote_neutral_disabled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/popup_icon_vote_neutral_disabled@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/popup_icon_vote_neutral_disabled@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_neutral_disabled.imageset/popup_icon_vote_neutral_disabled@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "popup_icon_vote_unlike.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "popup_icon_vote_unlike@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "popup_icon_vote_unlike@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/popup_icon_vote_unlike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/popup_icon_vote_unlike.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/popup_icon_vote_unlike@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/popup_icon_vote_unlike@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/popup_icon_vote_unlike@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_unlike.imageset/popup_icon_vote_unlike@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "popup_icon_vote_unlike_disabled.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "popup_icon_vote_unlike_disabled@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "popup_icon_vote_unlike_disabled@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/popup_icon_vote_unlike_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/popup_icon_vote_unlike_disabled.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/popup_icon_vote_unlike_disabled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/popup_icon_vote_unlike_disabled@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/popup_icon_vote_unlike_disabled@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/popup_icon_vote_unlike_disabled.imageset/popup_icon_vote_unlike_disabled@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_icon_details.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "calendar@1x-1.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "calendar@2x-1.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "calendar@3x-1.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_icon_details.imageset/calendar@1x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/schedule_icon_details.imageset/calendar@1x-1.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_icon_details.imageset/calendar@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/schedule_icon_details.imageset/calendar@2x-1.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_icon_details.imageset/calendar@3x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/schedule_icon_details.imageset/calendar@3x-1.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "schedule_tag_favorite.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "schedule_tag_favorite@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "schedule_tag_favorite@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/schedule_tag_favorite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/schedule_tag_favorite.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/schedule_tag_favorite@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/schedule_tag_favorite@2x.png
--------------------------------------------------------------------------------
/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/schedule_tag_favorite@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xebia-functional/scala-days-ios/d4570914a8fc92d43935169e5668daf11f494779/ScalaDays/Images.xcassets/schedule_tag_favorite.imageset/schedule_tag_favorite@3x.png
--------------------------------------------------------------------------------
/ScalaDays/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleSignature
20 | ????
21 | CFBundleURLTypes
22 |
23 |
24 | CFBundleTypeRole
25 | Editor
26 | CFBundleURLSchemes
27 |
28 | ampf03c22cb2db72bc6c180ece-0741609a-b833-11e4-2cc5-004a77f8b47f
29 |
30 |
31 |
32 | CFBundleVersion
33 | $(CURRENT_PROJECT_VERSION)
34 | ITSAppUsesNonExemptEncryption
35 |
36 | LSApplicationCategoryType
37 | public.app-category.utilities
38 | LSApplicationQueriesSchemes
39 |
40 | twitter
41 | twitterauth
42 |
43 | LSRequiresIPhoneOS
44 |
45 | NSAppTransportSecurity
46 |
47 | NSAllowsArbitraryLoads
48 |
49 | NSExceptionDomains
50 |
51 | public.localytics.s3.amazonaws.com
52 |
53 | NSExceptionAllowsInsecureHTTPLoads
54 |
55 |
56 | pushapi.localytics.com
57 |
58 | NSExceptionAllowsInsecureHTTPLoads
59 |
60 |
61 |
62 |
63 | NSCameraUsageDescription
64 | for scanning QR codes.
65 | NSContactsUsageDescription
66 | for saving new scanned contacts.
67 | NSLocationAlwaysUsageDescription
68 | This app may use GPS to track your location for the use of Google Maps and directions to and from pertinent locations for the event.
69 | NSLocationWhenInUseUsageDescription
70 | This app may use GPS to track your location for the use of Google Maps and directions to and from pertinent locations for the event.
71 | NSPhotoLibraryUsageDescription
72 | This app needs access to your Photo Library.
73 | UIBackgroundModes
74 |
75 | fetch
76 | remote-notification
77 |
78 | UIRequiredDeviceCapabilities
79 |
80 | armv7
81 |
82 | UIStatusBarStyle
83 | UIStatusBarStyleLightContent
84 | UISupportedInterfaceOrientations
85 |
86 | UIInterfaceOrientationPortrait
87 |
88 | UISupportedInterfaceOrientations~ipad
89 |
90 | UIInterfaceOrientationPortrait
91 | UIInterfaceOrientationPortraitUpsideDown
92 | UIInterfaceOrientationLandscapeLeft
93 | UIInterfaceOrientationLandscapeRight
94 |
95 | UIUserInterfaceStyle
96 | Light
97 | UIViewControllerBasedStatusBarAppearance
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/ScalaDays/Models/Extensions/DateFormatter+Decoders.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | extension DateFormatter {
4 |
5 | static let notificationsDateFormatter: DateFormatter = {
6 | let formatter = DateFormatter()
7 | formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
8 | return formatter
9 | }()
10 | }
11 |
12 |
13 | // MARK - Decoders
14 |
15 | extension JSONDecoder {
16 |
17 | static func using(_ dateFormatter: DateFormatter) -> JSONDecoder {
18 | let jsonDecoder = JSONDecoder()
19 | jsonDecoder.dateDecodingStrategy = .formatted(dateFormatter)
20 | return jsonDecoder
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ScalaDays/Models/SDMapAnnotation.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 | import MapKit
19 |
20 | class SDMapAnnotation: NSObject, MKAnnotation {
21 | let coordinate : CLLocationCoordinate2D
22 | let title, subtitle : String?
23 |
24 | init(title: String, subtitle: String, coordinate: CLLocationCoordinate2D) {
25 | self.title = title
26 | self.subtitle = subtitle
27 | self.coordinate = coordinate
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ScalaDays/Models/SDNotifications.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct SDNotifications: Codable {
4 | let conferenceId: Int
5 | let notifications: [SDNotification]
6 | }
7 |
8 | struct SDNotification: Codable, Equatable {
9 | let date: Date
10 | let title: String
11 | let message: String
12 | let iosDelivered: Bool
13 |
14 | enum CodingKeys: String, CodingKey {
15 | case date = "timestamp"
16 | case title
17 | case message
18 | case iosDelivered
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ScalaDays/Models/SDTweet.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 |
19 | class SDTweet: NSObject {
20 | let username: String
21 | let fullName: String
22 | let tweetText: String
23 | let profileImage: String
24 | let date: Date
25 | let id: String
26 |
27 | init(username: String, fullName: String, tweetText: String, profileImage: String, date: Date, id: String) {
28 | self.username = username
29 | self.fullName = fullName
30 | self.tweetText = tweetText
31 | self.profileImage = profileImage
32 | self.date = date
33 | self.id = id
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/ScalaDays/Models/Vote.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Foundation
18 |
19 | enum VoteType: Int {
20 | case unlike = 0
21 | case neutral = 1
22 | case like = 2
23 |
24 | func iconNameForVoteType() -> String {
25 | switch self {
26 | case .unlike: return "list_icon_vote_unlike.png"
27 | case .neutral: return "list_icon_vote_neutral.png"
28 | case .like: return "list_icon_vote_like.png"
29 | }
30 | }
31 | }
32 |
33 | class Vote: NSObject, Codable {
34 | let voteValue: Int
35 | let talkId: Int
36 | let conferenceId: Int
37 | let comments: String?
38 |
39 | init(_voteValue: Int, _talkId: Int, _conferenceId: Int, _comments: String?) {
40 | voteValue = _voteValue
41 | talkId = _talkId
42 | conferenceId = _conferenceId
43 | comments = _comments
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ScalaDays/ScalaDays.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ScalaDays/Service/FirebaseNotifications.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Firebase
3 |
4 | protocol SubscriberNotification {
5 | func subscribe(conferences: Conferences)
6 | }
7 |
8 | class FirebaseSubscriber: SubscriberNotification {
9 | func subscribe(conferences: Conferences) {
10 | conferences.conferences.map(\.info.id).forEach { conferenceId in
11 | Messaging.messaging().subscribe(toTopic: "\(conferenceId)_\(environment)_ios".lowercased())
12 | }
13 | Messaging.messaging().subscribe(toTopic: "\(environment)_ios".lowercased())
14 | }
15 |
16 | private var environment: String {
17 | #if DEBUG
18 | return "debug"
19 | #else
20 | return "release"
21 | #endif
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ScalaDays/Service/NotificationManager.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Alamofire
3 |
4 | enum NotificationManagerError: Error {
5 | case invalidEndpoint
6 | case empty
7 | }
8 |
9 | class NotificationManager {
10 | private let endpoint = "https://scaladays-backend.herokuapp.com/notifications"
11 | private var cached: [SDNotification] = []
12 |
13 | func notifications(conference: Conference, callback: @escaping (Result<[SDNotification], NotificationManagerError>) -> Void) {
14 | guard let endpoint = endpoint(conferenceId: conference.info.id) else {
15 | callback(.failure(.invalidEndpoint)); return
16 | }
17 |
18 | if cached.count > 0 { callback(.success(cached)) }
19 | reloadNotifications(endpoint: endpoint, callback: callback)
20 | }
21 |
22 | func reset() {
23 | self.cached = []
24 | }
25 |
26 | // MARK: GET
27 | private func reloadNotifications(endpoint: URL, callback: @escaping (Result<[SDNotification], NotificationManagerError>) -> Void) {
28 | AF.request(endpoint).responseJSON { response in
29 | guard let data = response.data,
30 | let res = try? JSONDecoder.using(.notificationsDateFormatter).decode(SDNotifications.self, from: data) else {
31 | callback(.failure(.empty)); return
32 | }
33 |
34 | let notifications = res.notifications.filter { $0.iosDelivered }
35 | .sorted { notification1, notification2 in notification1.date > notification2.date }
36 |
37 | self.cached = notifications
38 | callback(notifications.count == 0 ? .failure(.empty) : .success(notifications))
39 | }
40 | }
41 |
42 | // MARK: helpers
43 | private func endpoint(conferenceId: Int) -> URL? {
44 | URL(string: "\(endpoint)?conferenceId=\(conferenceId)")
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/ScalaDays/Service/UserManager.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | class UserManager {
4 | @UserDefault("UserManager.SelectedConference", defaultValue: nil) private var selectedConference: Conference?
5 |
6 | var selectedConferenceId: Int { selectedConference?.info.id ?? -1 }
7 |
8 | func select(conference: Conference) {
9 | self.selectedConference = conference
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ScalaDays/UI/CellPosition.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | enum CellPosition {
4 | case top
5 | case middle
6 | case bottom
7 | case only
8 | }
9 |
--------------------------------------------------------------------------------
/ScalaDays/UI/CustomViews/SDErrorPlaceholderView.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | @objc protocol SDErrorPlaceholderViewDelegate {
20 |
21 | @objc optional func didTapRefreshButtonInErrorPlaceholder()
22 |
23 | }
24 |
25 | class SDErrorPlaceholderView: UIView {
26 |
27 | @IBOutlet weak var lblErrorMessage: UILabel!
28 | @IBOutlet weak var imgIcon: UIImageView!
29 | @IBOutlet weak var btnRefresh: UIButton!
30 | @IBOutlet weak var constraintForImgIconTopSpace: NSLayoutConstraint!
31 | weak var delegate : SDErrorPlaceholderViewDelegate?
32 |
33 | let kTopSpaceForImgIconInSmallerIphones : CGFloat = 15.0
34 |
35 | let customConstraints : NSMutableArray = NSMutableArray()
36 | var containerView: UIView!
37 |
38 | required init?(coder aDecoder: NSCoder) {
39 | super.init(coder: aDecoder)
40 | commonInit()
41 | }
42 |
43 | override init(frame: CGRect) {
44 | super.init(frame: frame)
45 | commonInit()
46 | }
47 |
48 | func commonInit() {
49 | // This init function loads our custom view from the nib:
50 | if let container = loadNibSubviewsFromNib("SDErrorPlaceholderView") {
51 | containerView = container
52 | }
53 | self.isHidden = true
54 |
55 | if IS_IPHONE5 {
56 | constraintForImgIconTopSpace.constant = kTopSpaceForImgIconInSmallerIphones
57 | }
58 | }
59 |
60 | override func updateConstraints() {
61 | self.updateCustomConstraints(customConstraints, containerView: containerView)
62 | super.updateConstraints()
63 | }
64 |
65 | @IBAction func didTapRefreshButton() {
66 | delegate?.didTapRefreshButtonInErrorPlaceholder?()
67 | }
68 |
69 | func show(_ message: String) {
70 | show(message, isGeneralMessage: false)
71 | }
72 |
73 | func show(_ message: String, isGeneralMessage: Bool) {
74 | show(message, isGeneralMessage: isGeneralMessage, buttonTitle: NSLocalizedString("error_placeholder_button_refresh", comment: ""))
75 | }
76 |
77 | func show(_ message: String, isGeneralMessage: Bool, buttonTitle: String) {
78 | if self.isHidden {
79 | self.alpha = 0
80 | self.isHidden = false
81 | self.btnRefresh.setTitle(buttonTitle, for: UIControl.State())
82 | self.lblErrorMessage.text = message
83 | self.imgIcon.image = isGeneralMessage ? UIImage(named: "placeholder_general") : UIImage(named: "placeholder_error")
84 | UIView.animate(withDuration: kAnimationShowHideTimeInterval, animations: { () -> Void in
85 | self.alpha = 1
86 | })
87 | }
88 | }
89 |
90 | func hide() {
91 | if !self.isHidden {
92 | UIView.animate(withDuration: kAnimationShowHideTimeInterval, animations: { () -> Void in
93 | self.alpha = 0
94 | }, completion: { (completed) -> Void in
95 | self.isHidden = true
96 | self.alpha = 1
97 | })
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/ScalaDays/UI/CustomViews/SDQRScannerOverlayView.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | @objc protocol SDQRScannerOverlayViewDelegate {
20 |
21 | @objc optional func didTapCancelButtonInQRScanner()
22 |
23 | }
24 |
25 | class SDQRScannerOverlayView: UIView {
26 |
27 | @IBOutlet weak var btnCancel: UIBarButtonItem!
28 |
29 | let customConstraints : NSMutableArray = NSMutableArray()
30 | var containerView: UIView!
31 | weak var delegate : SDQRScannerOverlayViewDelegate?
32 |
33 | required init?(coder aDecoder: NSCoder) {
34 | super.init(coder: aDecoder)
35 | commonInit()
36 | }
37 |
38 | override init(frame: CGRect) {
39 | super.init(frame: frame)
40 | commonInit()
41 | }
42 |
43 | func commonInit() {
44 | // This init function loads our custom view from the nib:
45 | if let container = self.loadNibSubviewsFromNib("SDQRScannerOverlayView") {
46 | containerView = container
47 | }
48 | btnCancel.title = NSLocalizedString("common_cancel", comment: "Cancel")
49 | btnCancel.target = self
50 | btnCancel.action = #selector(SDQRScannerOverlayView.didTapCancelButton)
51 | }
52 |
53 | override func updateConstraints() {
54 | self.updateCustomConstraints(customConstraints, containerView: containerView)
55 | super.updateConstraints()
56 | }
57 |
58 | // MARK: - Cancel scanning handling
59 |
60 | @objc func didTapCancelButton() {
61 | delegate?.didTapCancelButtonInQRScanner?()
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/ScalaDays/UI/CustomViews/SDQRScannerOverlayView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/ScalaDays/UI/CustomViews/SDSpeakerScheduleView.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 |
20 | class SDSpeakerScheduleView: UIView {
21 |
22 | let customConstraints: NSMutableArray = NSMutableArray()
23 | let tapTwitter = UITapGestureRecognizer()
24 |
25 | var containerView: UIView!
26 | @IBOutlet weak var imgView: UIImageView!
27 | @IBOutlet weak var lblName: UILabel!
28 | @IBOutlet weak var lblUsername: UILabel!
29 |
30 | let kCellHeight: CGFloat = 36.0
31 | let kborderWidth: CGFloat = 1.0
32 |
33 |
34 | required init?(coder aDecoder: NSCoder) {
35 | super.init(coder: aDecoder)!
36 | commonInit()
37 | }
38 |
39 | override init(frame: CGRect) {
40 | super.init(frame: frame)
41 | commonInit()
42 | }
43 |
44 | func commonInit() {
45 | // This init function loads our custom view from the nib:
46 | if let container = loadNibSubviewsFromNib("SDSpeakerScheduleView") {
47 | containerView = container
48 | imgView.circularImage()
49 | imgView.layer.borderColor = UIColor.white.cgColor
50 | imgView.layer.borderWidth = kborderWidth
51 | }
52 | }
53 |
54 | override func updateConstraints() {
55 | self.updateCustomConstraints(customConstraints, containerView: containerView)
56 | super.updateConstraints()
57 | }
58 |
59 | func drawSpeakerData(_ speaker: Speaker) {
60 | lblName.text = speaker.name
61 | if let twitterUsername = speaker.twitter {
62 | if twitterUsername.contains("@") {
63 | lblUsername.text = twitterUsername
64 | } else {
65 | lblUsername.text = "@\(twitterUsername)"
66 | }
67 | } else {
68 | lblUsername.text = ""
69 | }
70 | if let pictureUrlString = speaker.picture {
71 | if let pictureUrl = URL(string: pictureUrlString) {
72 | imgView.sd_setImage(with: pictureUrl, placeholderImage: UIImage(named: "avatar")!)
73 | }
74 | }
75 | layoutSubviews()
76 | }
77 |
78 | func contentHeight() -> CGFloat {
79 | return kCellHeight
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDConferenceTableViewCell.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDConferenceTableViewCell: UITableViewCell {
20 |
21 | @IBOutlet weak var lblConferenceName: UILabel!
22 | @IBOutlet weak var conferenceImageView: UIImageView!
23 |
24 | override func awakeFromNib() {
25 | super.awakeFromNib()
26 | self.conferenceImageView.circularImage()
27 | self.lblConferenceName.numberOfLines = 0
28 | self.lblConferenceName.setCustomFont(UIFont.fontHelveticaNeue(15), colorFont: UIColor(white: 1, alpha: 0.9))
29 | self.backgroundColor = UIColor.appColor()
30 | let bgColorView = UIView()
31 | bgColorView.backgroundColor = UIColor.selectedCellMenu()
32 | self.selectedBackgroundView = bgColorView
33 | }
34 |
35 | func drawConferenceData(_ conference: Conference) {
36 | self.lblConferenceName.text = conference.info.longName
37 | if let pictureUrl = URL(string: conference.info.pictures[0].url) {
38 | conferenceImageView.sd_setImage(with: pictureUrl, placeholderImage: UIImage(named: "menu_icon_places"))
39 | }
40 | layoutSubviews()
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDConferenceTableViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDNotificationTableViewCell.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | class SDNotificationTableViewCell: UITableViewCell {
4 | @IBOutlet weak var timelineTop: UIView!
5 | @IBOutlet weak var timelineMiddle: UIView!
6 | @IBOutlet weak var timelineBotton: UIView!
7 |
8 | @IBOutlet weak var bullet: UIView!
9 |
10 | @IBOutlet weak var time: UILabel!
11 | @IBOutlet weak var date: UILabel!
12 | @IBOutlet weak var title: UILabel!
13 | @IBOutlet weak var message: UILabel!
14 |
15 | private var position: CellPosition = .only { didSet { updateTimelineView() }}
16 |
17 | func draw(notification: SDNotification, position: CellPosition) {
18 | setupStyle()
19 | updateBulletState(isPending: Date() < notification.date)
20 |
21 | self.position = position
22 | self.time.text = time(date: notification.date)
23 | self.date.text = day(date: notification.date)
24 | self.title.text = notification.title
25 | self.message.text = notification.message
26 | }
27 |
28 | // MARK: setup appareance
29 | private func setupStyle() {
30 | timelineTop.backgroundColor = UIColor.appRedColor()
31 | timelineMiddle.backgroundColor = UIColor.appRedColor()
32 | timelineBotton.backgroundColor = UIColor.appRedColor()
33 | time.textColor = UIColor.appRedColor()
34 | date.textColor = UIColor.appRedColor()
35 | }
36 |
37 | private func updateBulletState(isPending: Bool) {
38 | bullet.layer.cornerRadius = bullet.frame.width * 0.5
39 | bullet.layer.borderColor = UIColor.appRedColor().cgColor
40 | bullet.layer.borderWidth = 1.25
41 | bullet.backgroundColor = isPending ? .white : UIColor.appRedColor()
42 | }
43 |
44 | private func updateTimelineView() {
45 | switch position {
46 | case .top:
47 | timelineTop.isHidden = false
48 | timelineMiddle.isHidden = true
49 | timelineBotton.isHidden = true
50 | case .middle:
51 | timelineTop.isHidden = true
52 | timelineMiddle.isHidden = false
53 | timelineBotton.isHidden = true
54 | case .bottom:
55 | timelineTop.isHidden = true
56 | timelineMiddle.isHidden = true
57 | timelineBotton.isHidden = false
58 | case .only:
59 | timelineTop.isHidden = true
60 | timelineMiddle.isHidden = true
61 | timelineBotton.isHidden = true
62 | }
63 | }
64 |
65 | // MARK: helpers
66 | private func time(date: Date) -> String {
67 | let formatter = DateFormatter()
68 | formatter.dateFormat = "hh:mm a"
69 | return formatter.string(from: date)
70 | }
71 |
72 | private func day(date: Date) -> String {
73 | let formatter = DateFormatter()
74 | formatter.timeStyle = .none
75 | formatter.dateStyle = .medium
76 | return formatter.string(from: date)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDSocialTableViewCell.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 | import NSDate_TimeAgo
19 |
20 | class SDSocialTableViewCell: UITableViewCell {
21 | @IBOutlet weak var imgView : UIImageView!
22 | @IBOutlet weak var lblFullName : UILabel!
23 | @IBOutlet weak var lblUsername : UILabel!
24 | @IBOutlet weak var lblContent : UILabel!
25 | @IBOutlet weak var lblDate : UILabel!
26 |
27 | let kWidthForImgView : CGFloat = 40.0
28 |
29 | override func awakeFromNib() {
30 | self.imgView.circularImage()
31 | self.lblContent.numberOfLines = 0
32 | self.lblContent.setCustomFont(UIFont.fontHelveticaNeueLight(15), colorFont: UIColor.appColor())
33 | self.lblFullName.setCustomFont(UIFont.fontHelveticaNeueMedium(15), colorFont: UIColor.appColor())
34 | self.lblDate.setCustomFont(UIFont.fontHelveticaNeue(12), colorFont: UIColor.appColor())
35 | self.lblDate.alpha = 0.7
36 | self.lblUsername.setCustomFont(UIFont.fontHelveticaNeue(15), colorFont: UIColor.appRedColor())
37 | }
38 |
39 | override func layoutSubviews() {
40 | super.layoutSubviews()
41 | lblContent?.preferredMaxLayoutWidth = self.frame.size.width - kWidthForImgView - (kGlobalPadding * 3)
42 | }
43 |
44 | internal func drawTweetData(_ tweet: SDTweet) {
45 | lblFullName.text = tweet.username
46 | lblUsername.text = "@\(tweet.fullName)"
47 | lblContent.attributedText = tweet.tweetText.tweetAttributedText
48 | lblDate.text = (tweet.date as NSDate).timeAgoSimple()
49 | let imageUrl = URL(string: tweet.profileImage)
50 | if let profileImageUrl = imageUrl {
51 | imgView.sd_setImage(with: profileImageUrl)
52 | }
53 | layoutSubviews()
54 | }
55 | }
56 |
57 | // MARK: - Tweets style
58 |
59 | private extension String {
60 | var tweetAttributedText: NSAttributedString {
61 | let attributedText = NSMutableAttributedString(string: self)
62 | guard let regexHastags = Regex.hastagsOrMentions.regularExpression,
63 | let regexURLs = NSTextCheckingResult.CheckingType.link.regularExpression else {
64 | return attributedText
65 | }
66 |
67 | regexHastags.matches(in: attributedText.string).forEach { range in
68 | attributedText.addAttribute(.foregroundColor, value: Color.highlight, range: range)
69 | }
70 |
71 | regexURLs.matches(in: attributedText.string).forEach { range in
72 | attributedText.addAttribute(.foregroundColor, value: Color.highlight, range: range)
73 | }
74 |
75 | return attributedText
76 | }
77 |
78 | enum Regex {
79 | static let hastagsOrMentions = "\\B([\\#|\\@][a-zA-Z0-9_]+\\b)(?!;)"
80 | }
81 |
82 | enum Color {
83 | static let highlight = UIColor.init(red: 27/255.0, green: 149/255.0, blue: 224/255.0, alpha: 1)
84 | }
85 | }
86 |
87 | private extension String {
88 | var regularExpression: NSRegularExpression? {
89 | try? NSRegularExpression(pattern: self, options: [])
90 | }
91 | }
92 |
93 | private extension NSTextCheckingResult.CheckingType {
94 | var regularExpression: NSRegularExpression? {
95 | try? NSDataDetector(types: rawValue)
96 | }
97 | }
98 |
99 | private extension NSRegularExpression {
100 | func matches(in input: String) -> [NSRange] {
101 | matches(in: input, options: [], range: NSMakeRange(0, input.utf16.count)).map(\.range)
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDSpeakersTableViewCell.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDSpeakersTableViewCell: SDSocialTableViewCell {
20 | override func awakeFromNib() {
21 | self.imgView.circularImage()
22 | self.lblContent.numberOfLines = 0
23 | self.lblContent.setCustomFont(UIFont.fontHelveticaNeueLight(15), colorFont: UIColor.appColor())
24 | self.lblFullName.setCustomFont(UIFont.fontHelveticaNeueMedium(15), colorFont: UIColor.appColor())
25 | self.lblUsername.setCustomFont(UIFont.fontHelveticaNeue(15), colorFont: UIColor.appRedColor())
26 | }
27 |
28 | func drawSpeakerData(_ speaker: Speaker) {
29 | lblFullName.text = speaker.name
30 | if let twitterUsername = speaker.twitter {
31 | if twitterUsername.contains("@") {
32 | lblUsername.text = twitterUsername
33 | } else {
34 | lblUsername.text = "@\(twitterUsername)"
35 | }
36 | } else {
37 | lblUsername.text = ""
38 | }
39 | lblContent.text = speaker.bio.trimmingCharacters(in: CharacterSet.whitespaces)
40 |
41 | if let pictureUrlString = speaker.picture {
42 | if let pictureUrl = URL(string: pictureUrlString) {
43 | imgView.sd_setImage(with: pictureUrl, placeholderImage: UIImage(named: "avatar")!)
44 | }
45 | }
46 | layoutSubviews()
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDSponsorsTableViewCell.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDSponsorsTableViewCell: UITableViewCell {
20 |
21 | @IBOutlet weak var imgView: UIImageView!
22 | @IBOutlet weak var constraintForImageHeight: NSLayoutConstraint!
23 |
24 | func drawSponsorData(_ sponsor: Sponsor) {
25 | imgView.sd_setImage(with: URL(string: sponsor.logo), placeholderImage: UIImage(named: "placeholder_sponsors"))
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDSponsorsTableViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/ScalaDays/UI/TableViewCells/SDTableHeaderView.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import UIKit
18 |
19 | class SDTableHeaderView: UIView {
20 |
21 | let kHeaderTextPadding : CGPoint = CGPoint(x: 16, y: 11)
22 | let kHeaderTextInitialWidth : CGFloat = 300.0
23 | let kHeaderTextInitialHeight : CGFloat = 15.0
24 |
25 | var lblDate: UILabel!
26 |
27 | override init(frame: CGRect) {
28 | super.init(frame: frame)
29 |
30 | self.backgroundColor = UIColor.appScheduleTimeBlueBackgroundColor()
31 | lblDate = UILabel(frame: CGRect(x: kHeaderTextPadding.x, y: kHeaderTextPadding.y, width: kHeaderTextInitialWidth, height: kHeaderTextInitialHeight))
32 | lblDate.backgroundColor = UIColor.clear
33 | lblDate.setCustomFont(UIFont.fontHelveticaNeue(15), colorFont: UIColor.white)
34 | self.addSubview(lblDate)
35 | }
36 |
37 | required init?(coder aDecoder: NSCoder) {
38 | super.init(coder: aDecoder)!
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/ScalaDays/UI/Utils/UITableView+Cells.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | extension UITableView {
4 | func registerCell(_: T.Type) {
5 | register(T.nib, forCellReuseIdentifier: T.reuseIdentifier)
6 | }
7 |
8 | func dequeueCell(for indexPath: IndexPath) -> T {
9 | guard let cell = dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
10 | fatalError()
11 | }
12 | return cell
13 | }
14 | }
15 |
16 | extension UIView {
17 | static var nib: UINib {
18 | return UINib(nibName: String(describing: self), bundle: Bundle.local)
19 | }
20 | }
21 |
22 | protocol ReusableCell {
23 | static var reuseIdentifier: String { get }
24 | }
25 |
26 | extension ReusableCell where Self: UIView {
27 | static var reuseIdentifier: String {
28 | return String(describing: self)
29 | }
30 | }
31 |
32 | extension UITableViewCell: ReusableCell {}
33 |
--------------------------------------------------------------------------------
/ScalaDays/UI/Utils/UITextView+HTML.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | extension UITextView {
4 | var textHTML: String? {
5 | get { text }
6 | set(value) {
7 | setTextHTML(value ?? "",
8 | font: self.font ?? UIFont.systemFont(ofSize: UIFont.systemFontSize))
9 | }
10 | }
11 |
12 | func setHTMLAppareance(_ appareance: [NSAttributedString.Key : Any], textColor: UIColor? = nil, font: UIFont? = nil) {
13 | self.textColor = textColor ?? self.textColor
14 | self.font = font ?? self.font
15 | self.linkTextAttributes = appareance
16 | }
17 |
18 | // MARK: - private
19 | private func setTextHTML(_ text: String, font: UIFont) {
20 | guard !text.isEmpty,
21 | let attributedText = "\(styleHTML(font: font))\(text.plain2HTML)".htmlAttributedString else { return }
22 |
23 | self.attributedText = attributedText
24 | }
25 |
26 | private func styleHTML(font: UIFont) -> String {
27 | """
28 |
35 | """
36 | }
37 | }
38 |
39 | // MARK: Helpers
40 | private extension String {
41 |
42 | var htmlAttributedString: NSAttributedString? {
43 | guard let data = data(using: .utf16) else { return nil }
44 | return try? NSAttributedString(data: data,
45 | options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf16.rawValue],
46 | documentAttributes: nil)
47 | }
48 |
49 | var plain2HTML: String {
50 | replacingOccurrences(of: "\n", with: "")
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/ScalaDays/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Common
18 |
19 | "common_ok" = "OK";
20 | "common_cancel" = "Cancel";
21 | "common_back" = "Back";
22 |
23 | // Menu
24 | "schedule" = "Schedule";
25 | "social" = "Social";
26 | "contacts" = "Contacts";
27 | "tickets" = "Tickets";
28 | "sponsors" = "Sponsors";
29 | "places" = "Places";
30 | "about" = "About";
31 | "speakers" = "Speakers";
32 | "notification" = "Notifications";
33 | "code_conduct" = "Code of conduct";
34 |
35 | // Schedule
36 |
37 | "schedule_action_sheet_filter_title" = "Filter Events";
38 | "schedule_action_sheet_filter_message_all" = "All Events";
39 | "schedule_action_sheet_filter_message_favorites" = "Favorites";
40 | "schedule_location_title" = "Room: ";
41 | "schedule_action_sheet_filter_message_favorites" = "My Favorites";
42 | "schedule_error_vote_title" = "Error";
43 | "schedule_error_vote_message" = "There was a problem while trying to send your vote. Please try again in a few moments.";
44 | "schedule_vote_comments_placeholder" = "Leave a comment on your opinion of this talk to help out the speaker.";
45 | "schedule_vote_comments_cancel_warning_title" = "Cancel vote";
46 | "schedule_vote_comments_cancel_warning_message" = "Your vote and comments will be lost. Are you sure you want to exit?";
47 | "schedule_vote_comments_cancel_warning_btn_exit" = "Exit";
48 |
49 | // Social
50 |
51 | "social_error_no_valid_tweets" = "Something happened while trying to retrieve the latest Scala Days tweets. Please tap on this message to try again in a few minutes.";
52 | "social_error_no_tweets_for_current_hashtag" = "We haven't found any tweets about this conference yet. Please tap on this message to try again in a few minutes.";
53 |
54 | // Contacts
55 |
56 | "contacts_regular_feedback_message" = "You can add a contact by tapping on \"SCAN CONTACT\" and scanning the corresponding QR Code.";
57 | "contacts_regular_feedback_error_no_access" = "Scala Days needs permission to access your Address Book in order to create a new contact. You can grant access to this app in the \"Settings\" app of your device.";
58 | "contacts_regular_feedback_error_invalid_qr_code" = "The QR Code seems to be invalid. Please try again by tapping on \"SCAN CONTACT\".";
59 | "contacts_regular_feedback_error_unknown" = "There was an error while scanning the QR Code. Please try again by tapping on \"SCAN CONTACT\".";
60 | "contacts_add_contact_success_message" = "Contact was successfully added to your Address Book!";
61 | "contacts_add_contact_request" = "Do you really want to add %@ to your Address Book?";
62 | "contacts_add_contact_request_no_name" = "Scanned contact doesn't have a first or last name, do you really want to add it to your Address Book?";
63 |
64 | // Error placeholder
65 |
66 | "error_placeholder_button_refresh" = "RELOAD";
67 | "error_message_no_data_available" = "There was an error while trying to retrieve the latest Scala Days information. Please tap on the \"RELOAD\" button to try again.";
68 | "error_insufficient_content" = "We haven't found any data for this section yet. Please tap on the \"RELOAD\" button to try again.";
69 | "error_no_favorites" = "You haven't favorited any events yet. You can select an event and mark it as a favorite by tapping on the button at the upper-right part of the screen.";
70 |
71 | // About
72 | "feeback_button" = "Send anonymous feedback";
73 |
74 | // Notifications
75 | "empty_notification_message" = "No notifications have been sent yet";
76 |
--------------------------------------------------------------------------------