├── .circleci └── config.yml ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── let-s-report-a-bug.md ├── .gitignore ├── .gitmodules ├── CONTRIBUTING.md ├── FOSSAsia.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── FOSSAsia.xcscheme ├── FOSSAsia.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── FOSSAsia ├── ApiClient.swift ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── App Icon-1024.png │ │ ├── App Icon-29.png │ │ ├── App Icon-29@2x-1.png │ │ ├── App Icon-29@2x.png │ │ ├── App Icon-29@3x.png │ │ ├── App Icon-40.png │ │ ├── App Icon-40@2x-1.png │ │ ├── App Icon-40@2x.png │ │ ├── App Icon-40@3x.png │ │ ├── App Icon-60@2x.png │ │ ├── App Icon-60@3x.png │ │ ├── App Icon-76.png │ │ ├── App Icon-76@2x.png │ │ ├── App Icon-83.5.png │ │ └── Contents.json │ ├── Contents.json │ ├── arrow_next_disabled.imageset │ │ ├── Contents.json │ │ ├── arrow_next_disabled.png │ │ ├── arrow_next_disabled@2x.png │ │ └── arrow_next_disabled@3x.png │ ├── arrow_next_enabled.imageset │ │ ├── Contents.json │ │ ├── arrow_next_enabled.png │ │ ├── arrow_next_enabled@2x.png │ │ └── arrow_next_enabled@3x.png │ ├── arrow_prev_disabled.imageset │ │ ├── Contents.json │ │ ├── arrow_prev_disabled.png │ │ ├── arrow_prev_disabled@2x.png │ │ └── arrow_prev_disabled@3x.png │ ├── arrow_prev_enabled.imageset │ │ ├── Contents.json │ │ ├── arrow_prev_enabled.png │ │ ├── arrow_prev_enabled@2x.png │ │ └── arrow_prev_enabled@3x.png │ ├── avatar.imageset │ │ ├── Contents.json │ │ ├── smackProfileIcon.png │ │ ├── smackProfileIcon@2x.png │ │ └── smackProfileIcon@3x.png │ ├── back.imageset │ │ ├── Contents.json │ │ ├── backicon-1.png │ │ ├── backicon-2.png │ │ └── backicon.png │ ├── browse_events_btn.imageset │ │ ├── Contents.json │ │ ├── browse_events_btn.png │ │ ├── browse_events_btn@2x.png │ │ └── browse_events_btn@3x.png │ ├── browse_events_btn_selected.imageset │ │ ├── Contents.json │ │ ├── browse_events_btn_selected.png │ │ ├── browse_events_btn_selected@2x.png │ │ └── browse_events_btn_selected@3x.png │ ├── cal_unselected.imageset │ │ ├── Contents.json │ │ ├── cal_unselected.png │ │ ├── cal_unselected@2x.png │ │ └── cal_unselected@3x.png │ ├── calendar_add_btn.imageset │ │ ├── Contents.json │ │ ├── calendar_add_btn.png │ │ ├── calendar_add_btn@2x.png │ │ └── calendar_add_btn@3x.png │ ├── calendar_add_btn_selected.imageset │ │ ├── Contents.json │ │ ├── calendar_add_btn_selected.png │ │ ├── calendar_add_btn_selected@2x.png │ │ └── calendar_add_btn_selected@3x.png │ ├── cell_favorite.imageset │ │ ├── Contents.json │ │ ├── cell_favorite.png │ │ ├── cell_favorite@2x.png │ │ └── cell_favorite@3x.png │ ├── cell_favorite_selected.imageset │ │ ├── Contents.json │ │ ├── cell_favorite_selected.png │ │ ├── cell_favorite_selected@2x.png │ │ └── cell_favorite_selected@3x.png │ ├── favorites_icon.imageset │ │ ├── Contents.json │ │ ├── favorites_icon.png │ │ ├── favorites_icon@2x.png │ │ └── favorites_icon@3x.png │ ├── favorites_unselected.imageset │ │ ├── Contents.json │ │ ├── favorites_unselected.png │ │ ├── favorites_unselected@2x.png │ │ └── favorites_unselected@3x.png │ ├── fossasia_logo.imageset │ │ ├── Contents.json │ │ ├── fossasia_logo-1.png │ │ ├── fossasia_logo-2.png │ │ └── fossasia_logo.png │ ├── heart_icon.imageset │ │ ├── Contents.json │ │ ├── heart_icon-1.png │ │ ├── heart_icon-2.png │ │ └── heart_icon.png │ ├── loading_indicator.imageset │ │ ├── Contents.json │ │ ├── loading_indicator.png │ │ ├── loading_indicator@2x.png │ │ └── loading_indicator@3x.png │ ├── login_unselected.imageset │ │ ├── Contents.json │ │ ├── login_unselectd-1.png │ │ ├── login_unselectd-2.png │ │ └── login_unselectd.png │ ├── loginicon.imageset │ │ ├── Contents.json │ │ ├── login-1.png │ │ ├── login-2.png │ │ └── login.png │ ├── logout.imageset │ │ ├── Contents.json │ │ ├── logout-1.png │ │ ├── logout-2.png │ │ └── logout.png │ ├── mailing_list_icon.imageset │ │ ├── Contents.json │ │ ├── mailing_list_icon.png │ │ ├── mailing_list_icon@2x.png │ │ └── mailing_list_icon@3x.png │ ├── map_icon.imageset │ │ ├── Contents.json │ │ └── map_icon.png │ ├── more.imageset │ │ ├── Contents.json │ │ ├── more.png │ │ ├── more@2x.png │ │ └── more@3x.png │ ├── navbar_fave.imageset │ │ ├── Contents.json │ │ ├── navbar_fave.png │ │ ├── navbar_fave@2x.png │ │ └── navbar_fave@3x.png │ ├── navbar_fave_highlighted.imageset │ │ ├── Contents.json │ │ ├── navbar_fave_highlighted.png │ │ ├── navbar_fave_highlighted@2x.png │ │ └── navbar_fave_highlighted@3x.png │ ├── profile.imageset │ │ ├── Contents.json │ │ ├── profile-1.png │ │ ├── profile-2.png │ │ └── profile.png │ ├── profile_unselected.imageset │ │ ├── Contents.json │ │ ├── profile_unselected-1.png │ │ ├── profile_unselected-2.png │ │ └── profile_unselected.png │ ├── safari_icon.imageset │ │ ├── Contents.json │ │ ├── safari_icon.png │ │ ├── safari_icon@2x.png │ │ └── safari_icon@3x.png │ ├── session_cell_favorite.imageset │ │ ├── Contents.json │ │ ├── session_cell_favorite.png │ │ ├── session_cell_favorite@2x.png │ │ └── session_cell_favorite@3x.png │ ├── signup_unselected.imageset │ │ ├── Contents.json │ │ ├── signup_unselected-1.png │ │ ├── signup_unselected-2.png │ │ └── signup_unselected.png │ ├── signupselected.imageset │ │ ├── Contents.json │ │ ├── signupselected-1.png │ │ ├── signupselected-2.png │ │ └── signupselected.png │ ├── tell_a_friend.imageset │ │ ├── Contents.json │ │ ├── tell_a_friend.png │ │ ├── tell_a_friend@2x.png │ │ └── tell_a_friend@3x.png │ ├── twitter_icon.imageset │ │ ├── Contents.json │ │ ├── twitter_icon.png │ │ ├── twitter_icon@2x.png │ │ └── twitter_icon@3x.png │ └── welcome_glyph.imageset │ │ ├── Contents.json │ │ ├── welcome_glyph.png │ │ ├── welcome_glyph@2x.png │ │ └── welcome_glyph@3x.png ├── AuthTabBarViewController.swift ├── Base.lproj │ ├── Favorites.storyboard │ ├── LaunchScreen.storyboard │ ├── Main.storyboard │ └── Signup~.storyboard ├── Client.swift ├── Colors.swift ├── Constants.swift ├── Convenience.swift ├── DecisionViewController.swift ├── Error.swift ├── Event.swift ├── EventCell.swift ├── EventInfo.swift ├── EventInfoView.swift ├── EventListBrowsingProtocol.swift ├── EventProvider.swift ├── EventViewController.swift ├── EventViewModel.swift ├── EventsBaseListViewController.swift ├── EventsBaseViewController.swift ├── EventsListViewController.swift ├── EventsListViewModel.swift ├── EventsResultsViewController.swift ├── FavoriteEventsListViewController.swift ├── FavoritesScheduleViewController.swift ├── FetchDataService.swift ├── FilterCell.swift ├── FilterListViewController.swift ├── FossAsiaAPI.swift ├── FossAsiaEventsService.swift ├── Fossasia-Bridging-Header.h ├── IndividualEvent.storyboard ├── Info.plist ├── LoadingViewController.swift ├── LoginVCMethods.swift ├── LoginViewController.swift ├── MapViewController.swift ├── Microlocation.swift ├── More.storyboard ├── MoreViewController.swift ├── Observable.swift ├── Profile.storyboard ├── ProfileViewController.swift ├── RangeExtension.swift ├── Schedule.swift ├── ScheduleBrowsingProtocol.swift ├── SchedulePagingView.swift ├── ScheduleVC.storyboard ├── ScheduleViewController.swift ├── ScheduleViewControllerDelegate.swift ├── ScheduleViewModel.swift ├── ScheduleViewModelDelegate.swift ├── Sessions.storyboard ├── SettingsManager.swift ├── SignupVcMethods.swift ├── SignupViewController.swift ├── Speaker.swift ├── SpeakerViewModel.swift ├── SwiftHEXColors.swift └── TrackViewModel.swift ├── FOSSAsiaUITests ├── FOSSAsiaUITests.swift ├── Info.plist └── SnapshotHelper.swift ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── Scripts ├── before_install.sh ├── build_for_testing.sh └── update_dependencies.sh ├── build.sh └── docs └── gitconfiguration.md /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | jobs: 4 | build-and-test: 5 | macos: 6 | xcode: "9.3.0" 7 | steps: 8 | - checkout 9 | - run: 10 | name: Update Dependencies 11 | command: sh ./Scripts/update_dependencies.sh 12 | - run: 13 | name: Build for testing 14 | command: sh ./Scripts/build_for_testing.sh 15 | 16 | 17 | 18 | workflows: 19 | version: 2 20 | build_and_test: 21 | jobs: 22 | - build-and-test 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for Open Event iOS 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | 13 | **Describe the solution you'd like** 14 | 15 | 16 | **Describe alternatives you've considered** 17 | 18 | 19 | **Additional context** 20 | 21 | 22 | **Would you like to work on the issue?** 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/let-s-report-a-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Let's report a bug 3 | about: Report a bug which you have noticed, to help us improve Open Event iOS 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Please follow the issue template to **report a bug** 11 | 12 | **Actual Behaviour** 13 | 14 | 15 | 16 | **Expected Behaviour** 17 | 18 | 19 | 20 | **Steps to reproduce it** 21 | 22 | 23 | 24 | **LogCat for the issue** 25 | 26 | 27 | 28 | **Screenshots of the issue** 29 | 30 | 31 | 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Xcode version: [Version 10.1 (10B61)] 35 | 36 | **Would you like to work on the issue?** 37 | 38 | 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Xcode 3 | # 4 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 5 | 6 | ## Build generated 7 | build/ 8 | DerivedData/ 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata/ 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xccheckout 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/screenshots 64 | 65 | # Ignore MacOS DS_Store files 66 | *.DS_Store 67 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/.gitmodules -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to open-event-ios 2 | 3 | ### So... you've decided to contribute to this repository... 4 | 5 | Welcome! Thank you so much for the interest. Below here are some guidelines we've put together to help you get started quickly 6 | 7 | ## Getting Started 8 | - Download the file of finalized designs [here](https://www.dropbox.com/s/u043hd7idld9wl2/Mockups%20Fossasia%20iOS.pdf?dl=0) 9 | - If there's a bug/issue you've found, [create the issue](http://github.com/fossasia/open-event-ios/issues/) 10 | - Fork and clone the repository 11 | - Create a branch with the work you're going to do 12 | - When finished with changes, create a PR against the development branch of this repository 13 | 14 | ## What to Work On 15 | Check the list of [issues](https://github.com/fossasia/open-event-ios/issues) 16 | 17 | ## Contribution Guidelines 18 | 19 | ### Any PRs are welcome 20 | Spot a typo? Send a pull request! Use of mutable values at the wrong places? Send a pull request! 21 | 22 | Basically, if you have something to contribute, we'll be more than happy to merge it if it fits the goals for the app. 23 | 24 | ### Making Changes 25 | This is **important**. So read this part carefully. 26 | 27 | If you're writing something that introduces a new design or requires the modification of the existing user interface, please create an issue with the `design` tag and discuss your proposed changes before writing any code. Even if design is not your forte, raising that issue can give someone else the opportunity to contribute a design. This is to help maintain and regulate a high standard of user experience in the app. 28 | 29 | _Note: the .sketch file will soon be made available once the app has been finalised and released on the App Store_ 30 | 31 | ### Bug Reports 32 | Guidelines for bug reports: 33 | 34 | 1. Check Github Issues - see if bug has already been reported 35 | 2. Check if issue is fixed - attempt to reproduce with latest `master` 36 | 3. Identify if your issue relates to one of the following: Design/Frontend or Bug 37 | 4. Use the bug report template below and create a new issue 38 | 39 | Example: 40 | ``` 41 | Short and descriptive example bug report summary (title) 42 | 43 | ### Environment 44 | 45 | The OS environment in which the issue occurs. (Version of iOS, device type etc) 46 | 47 | ### Steps to Reproduce 48 | If suitable, include the steps required to reproduce the bug. 49 | 50 | 1. This is the first step 51 | 2. This is the second step 52 | 3. Further steps, etc. 53 | 54 | Any other information you want to share that is relevant to the issue being reported. Especially, why do you consider this to be a bug? What do you expect to happen instead? 55 | 56 | ### Technical details: 57 | 58 | * Version: beta 0.1.0-1234 59 | ``` 60 | 61 | ### Feature Requests 62 | Before you submit be sure to do the following: 63 | 64 | 1. Search existing issues for similar requests and comment on that one instead of creating a new issue 65 | 2. Take a moment and think if the feature fits the scope of the application and such feature will positively benefit a user's conference-going experience 66 | 3. Provide as much detail and context and possible with a few use cases that will help make your feature request more _convincing_ 67 | -------------------------------------------------------------------------------- /FOSSAsia.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FOSSAsia.xcodeproj/xcshareddata/xcschemes/FOSSAsia.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 79 | 80 | 81 | 82 | 83 | 84 | 90 | 92 | 98 | 99 | 100 | 101 | 103 | 104 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /FOSSAsia.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /FOSSAsia.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FOSSAsia/ApiClient.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApiClient.swift 3 | // FOSSAsia 4 | // 5 | // Created by Pratik Todi on 27/02/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | typealias ApiRequestCompletionHandler = (Data?, Error?) -> Void 12 | 13 | struct ApiClient { 14 | 15 | static let url = "https://raw.githubusercontent.com/fossasia/open-event-scraper/master/out/" 16 | 17 | let eventInfo: EventInfo 18 | 19 | func sendGetRequest(_ completionHandler: @escaping ApiRequestCompletionHandler) { 20 | let sessionConfig = URLSessionConfiguration.default 21 | let session = URLSession(configuration: sessionConfig) 22 | let request = URLRequest(url: URL(string: getUrl(eventInfo))!) 23 | let task = session.dataTask(with: request, completionHandler: { (data, response, networkError) -> Void in 24 | if let _ = networkError { 25 | let error = Error(errorCode: .networkRequestFailed) 26 | completionHandler(nil, error) 27 | return 28 | } 29 | 30 | guard let unwrappedData = data else { 31 | let error = Error(errorCode: .jsonSerializationFailed) 32 | completionHandler(nil, error) 33 | return 34 | } 35 | 36 | self.processResponse(unwrappedData, completionHandler: { (error) -> Void in 37 | guard error == nil else { 38 | completionHandler(nil, error) 39 | return 40 | } 41 | completionHandler(unwrappedData, nil) 42 | }) 43 | 44 | }) 45 | task.resume() 46 | } 47 | 48 | fileprivate func getUrl(_ eventInfo: EventInfo) -> String { 49 | return ApiClient.url + eventInfo.rawValue + Constants.jsonFileExtension 50 | } 51 | 52 | fileprivate func processResponse(_ data: Data, completionHandler: CommitmentCompletionHandler) { 53 | if let dir: NSString = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true).first as NSString? { 54 | let path = dir.appendingPathComponent(SettingsManager.getLocalFileName(eventInfo)) 55 | try? data.write(to: URL(fileURLWithPath: path), options: []) 56 | completionHandler(nil) 57 | } 58 | completionHandler(Error(errorCode: .jsonSystemReadingFailed)) 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /FOSSAsia/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import UserNotifications 11 | import IQKeyboardManagerSwift 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { 15 | 16 | var window: UIWindow? 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 19 | // Override point for customization after application launch. 20 | UITabBar.appearance().tintColor = Colors.mainRedColor 21 | UINavigationBar.appearance().tintColor = Colors.creamTintColor 22 | UIApplication.shared.isStatusBarHidden = false 23 | UIApplication.shared.statusBarStyle = .lightContent 24 | 25 | UserDefaults.standard.register(defaults: [Constants.UserDefaultsKey.FilteredTrackIds: (1...Constants.numberOfTracks).toArray()]) 26 | // Set the Local Notification Delegate 27 | let center = UNUserNotificationCenter.current() 28 | center.delegate = self 29 | IQKeyboardManager.sharedManager().enable = true 30 | return true 31 | } 32 | 33 | func applicationWillResignActive(_ application: UIApplication) { 34 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 35 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 36 | } 37 | 38 | func applicationDidEnterBackground(_ application: UIApplication) { 39 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | } 42 | 43 | func applicationWillEnterForeground(_ application: UIApplication) { 44 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 45 | } 46 | 47 | func applicationDidBecomeActive(_ application: UIApplication) { 48 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 49 | } 50 | 51 | func applicationWillTerminate(_ application: UIApplication) { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-1024.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29@2x-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-29@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40@2x-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-40@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-60@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-60@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-76.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-76@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-83.5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/AppIcon.appiconset/App Icon-83.5.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.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" : "App Icon-29@2x.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "App Icon-29@3x.png", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "40x40", 27 | "idiom" : "iphone", 28 | "filename" : "App Icon-40@2x.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "size" : "40x40", 33 | "idiom" : "iphone", 34 | "filename" : "App Icon-40@3x.png", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "size" : "60x60", 39 | "idiom" : "iphone", 40 | "filename" : "App Icon-60@2x.png", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "size" : "60x60", 45 | "idiom" : "iphone", 46 | "filename" : "App Icon-60@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" : "App Icon-29.png", 63 | "scale" : "1x" 64 | }, 65 | { 66 | "size" : "29x29", 67 | "idiom" : "ipad", 68 | "filename" : "App Icon-29@2x-1.png", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "size" : "40x40", 73 | "idiom" : "ipad", 74 | "filename" : "App Icon-40.png", 75 | "scale" : "1x" 76 | }, 77 | { 78 | "size" : "40x40", 79 | "idiom" : "ipad", 80 | "filename" : "App Icon-40@2x-1.png", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "size" : "76x76", 85 | "idiom" : "ipad", 86 | "filename" : "App Icon-76.png", 87 | "scale" : "1x" 88 | }, 89 | { 90 | "size" : "76x76", 91 | "idiom" : "ipad", 92 | "filename" : "App Icon-76@2x.png", 93 | "scale" : "2x" 94 | }, 95 | { 96 | "size" : "83.5x83.5", 97 | "idiom" : "ipad", 98 | "filename" : "App Icon-83.5.png", 99 | "scale" : "2x" 100 | }, 101 | { 102 | "size" : "1024x1024", 103 | "idiom" : "ios-marketing", 104 | "filename" : "App Icon-1024.png", 105 | "scale" : "1x" 106 | } 107 | ], 108 | "info" : { 109 | "version" : 1, 110 | "author" : "xcode" 111 | } 112 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "arrow_next_disabled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "arrow_next_disabled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "arrow_next_disabled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/arrow_next_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/arrow_next_disabled.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/arrow_next_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/arrow_next_disabled@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/arrow_next_disabled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_next_disabled.imageset/arrow_next_disabled@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "arrow_next_enabled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "arrow_next_enabled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "arrow_next_enabled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/arrow_next_enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/arrow_next_enabled.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/arrow_next_enabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/arrow_next_enabled@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/arrow_next_enabled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_next_enabled.imageset/arrow_next_enabled@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "arrow_prev_disabled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "arrow_prev_disabled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "arrow_prev_disabled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/arrow_prev_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/arrow_prev_disabled.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/arrow_prev_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/arrow_prev_disabled@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/arrow_prev_disabled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_prev_disabled.imageset/arrow_prev_disabled@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "arrow_prev_enabled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "arrow_prev_enabled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "arrow_prev_enabled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/arrow_prev_enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/arrow_prev_enabled.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/arrow_prev_enabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/arrow_prev_enabled@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/arrow_prev_enabled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/arrow_prev_enabled.imageset/arrow_prev_enabled@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/avatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "smackProfileIcon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "smackProfileIcon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "smackProfileIcon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/avatar.imageset/smackProfileIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/avatar.imageset/smackProfileIcon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/avatar.imageset/smackProfileIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/avatar.imageset/smackProfileIcon@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/avatar.imageset/smackProfileIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/avatar.imageset/smackProfileIcon@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "backicon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "backicon-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "backicon-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/back.imageset/backicon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/back.imageset/backicon-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/back.imageset/backicon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/back.imageset/backicon-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/back.imageset/backicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/back.imageset/backicon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "browse_events_btn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "browse_events_btn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "browse_events_btn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn.imageset/browse_events_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/browse_events_btn.imageset/browse_events_btn.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn.imageset/browse_events_btn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/browse_events_btn.imageset/browse_events_btn@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn.imageset/browse_events_btn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/browse_events_btn.imageset/browse_events_btn@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "browse_events_btn_selected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "browse_events_btn_selected@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "browse_events_btn_selected@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/browse_events_btn_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/browse_events_btn_selected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/browse_events_btn_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/browse_events_btn_selected@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/browse_events_btn_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/browse_events_btn_selected.imageset/browse_events_btn_selected@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cal_unselected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cal_unselected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "cal_unselected@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "cal_unselected@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cal_unselected.imageset/cal_unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cal_unselected.imageset/cal_unselected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cal_unselected.imageset/cal_unselected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cal_unselected.imageset/cal_unselected@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cal_unselected.imageset/cal_unselected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cal_unselected.imageset/cal_unselected@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "calendar_add_btn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "calendar_add_btn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "calendar_add_btn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/calendar_add_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/calendar_add_btn.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/calendar_add_btn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/calendar_add_btn@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/calendar_add_btn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/calendar_add_btn.imageset/calendar_add_btn@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "calendar_add_btn_selected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "calendar_add_btn_selected@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "calendar_add_btn_selected@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/calendar_add_btn_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/calendar_add_btn_selected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/calendar_add_btn_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/calendar_add_btn_selected@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/calendar_add_btn_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/calendar_add_btn_selected.imageset/calendar_add_btn_selected@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cell_favorite.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "cell_favorite@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "cell_favorite@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite.imageset/cell_favorite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cell_favorite.imageset/cell_favorite.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite.imageset/cell_favorite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cell_favorite.imageset/cell_favorite@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite.imageset/cell_favorite@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cell_favorite.imageset/cell_favorite@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cell_favorite_selected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "cell_favorite_selected@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "cell_favorite_selected@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/cell_favorite_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/cell_favorite_selected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/cell_favorite_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/cell_favorite_selected@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/cell_favorite_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/cell_favorite_selected.imageset/cell_favorite_selected@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "favorites_icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "favorites_icon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "favorites_icon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_icon.imageset/favorites_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/favorites_icon.imageset/favorites_icon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_icon.imageset/favorites_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/favorites_icon.imageset/favorites_icon@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_icon.imageset/favorites_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/favorites_icon.imageset/favorites_icon@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_unselected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "favorites_unselected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "favorites_unselected@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "favorites_unselected@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_unselected.imageset/favorites_unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/favorites_unselected.imageset/favorites_unselected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_unselected.imageset/favorites_unselected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/favorites_unselected.imageset/favorites_unselected@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/favorites_unselected.imageset/favorites_unselected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/favorites_unselected.imageset/favorites_unselected@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/fossasia_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "fossasia_logo.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "fossasia_logo-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "fossasia_logo-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/fossasia_logo.imageset/fossasia_logo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/fossasia_logo.imageset/fossasia_logo-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/fossasia_logo.imageset/fossasia_logo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/fossasia_logo.imageset/fossasia_logo-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/fossasia_logo.imageset/fossasia_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/fossasia_logo.imageset/fossasia_logo.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/heart_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "heart_icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "heart_icon-2.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "heart_icon-1.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/heart_icon.imageset/heart_icon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/heart_icon.imageset/heart_icon-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/heart_icon.imageset/heart_icon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/heart_icon.imageset/heart_icon-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/heart_icon.imageset/heart_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/heart_icon.imageset/heart_icon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loading_indicator.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading_indicator.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading_indicator@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "loading_indicator@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loading_indicator.imageset/loading_indicator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/loading_indicator.imageset/loading_indicator.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loading_indicator.imageset/loading_indicator@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/loading_indicator.imageset/loading_indicator@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loading_indicator.imageset/loading_indicator@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/loading_indicator.imageset/loading_indicator@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/login_unselected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "login_unselectd-1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "login_unselectd.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "login_unselectd-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/login_unselected.imageset/login_unselectd-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/login_unselected.imageset/login_unselectd-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/login_unselected.imageset/login_unselectd-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/login_unselected.imageset/login_unselectd-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/login_unselected.imageset/login_unselectd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/login_unselected.imageset/login_unselectd.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loginicon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "login.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "login-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "login-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loginicon.imageset/login-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/loginicon.imageset/login-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loginicon.imageset/login-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/loginicon.imageset/login-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/loginicon.imageset/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/loginicon.imageset/login.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/logout.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "logout.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "logout-2.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "logout-1.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/logout.imageset/logout-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/logout.imageset/logout-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/logout.imageset/logout-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/logout.imageset/logout-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/logout.imageset/logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/logout.imageset/logout.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mailing_list_icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "mailing_list_icon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "mailing_list_icon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/mailing_list_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/mailing_list_icon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/mailing_list_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/mailing_list_icon@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/mailing_list_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/mailing_list_icon.imageset/mailing_list_icon@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/map_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "map_icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/map_icon.imageset/map_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/map_icon.imageset/map_icon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/more.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "more.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "more@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "more@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/more.imageset/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/more.imageset/more.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/more.imageset/more@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/more.imageset/more@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/more.imageset/more@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/more.imageset/more@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "navbar_fave.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "navbar_fave@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "navbar_fave@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave.imageset/navbar_fave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/navbar_fave.imageset/navbar_fave.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave.imageset/navbar_fave@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/navbar_fave.imageset/navbar_fave@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave.imageset/navbar_fave@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/navbar_fave.imageset/navbar_fave@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "navbar_fave_highlighted.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "navbar_fave_highlighted@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "navbar_fave_highlighted@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/navbar_fave_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/navbar_fave_highlighted.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/navbar_fave_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/navbar_fave_highlighted@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/navbar_fave_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/navbar_fave_highlighted.imageset/navbar_fave_highlighted@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "profile.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "profile-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "profile-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile.imageset/profile-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/profile.imageset/profile-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile.imageset/profile-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/profile.imageset/profile-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile.imageset/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/profile.imageset/profile.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile_unselected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "profile_unselected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "profile_unselected-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "profile_unselected-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile_unselected.imageset/profile_unselected-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/profile_unselected.imageset/profile_unselected-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile_unselected.imageset/profile_unselected-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/profile_unselected.imageset/profile_unselected-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/profile_unselected.imageset/profile_unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/profile_unselected.imageset/profile_unselected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/safari_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "safari_icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "safari_icon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "safari_icon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/safari_icon.imageset/safari_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/safari_icon.imageset/safari_icon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/safari_icon.imageset/safari_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/safari_icon.imageset/safari_icon@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/safari_icon.imageset/safari_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/safari_icon.imageset/safari_icon@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "session_cell_favorite.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "session_cell_favorite@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "session_cell_favorite@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/session_cell_favorite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/session_cell_favorite.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/session_cell_favorite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/session_cell_favorite@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/session_cell_favorite@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/session_cell_favorite.imageset/session_cell_favorite@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signup_unselected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "signup_unselected.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "signup_unselected-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "signup_unselected-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signup_unselected.imageset/signup_unselected-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/signup_unselected.imageset/signup_unselected-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signup_unselected.imageset/signup_unselected-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/signup_unselected.imageset/signup_unselected-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signup_unselected.imageset/signup_unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/signup_unselected.imageset/signup_unselected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signupselected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "signupselected-1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "signupselected.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "signupselected-2.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signupselected.imageset/signupselected-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/signupselected.imageset/signupselected-1.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signupselected.imageset/signupselected-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/signupselected.imageset/signupselected-2.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/signupselected.imageset/signupselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/signupselected.imageset/signupselected.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/tell_a_friend.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "tell_a_friend.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "tell_a_friend@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "tell_a_friend@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/tell_a_friend.imageset/tell_a_friend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/tell_a_friend.imageset/tell_a_friend.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/tell_a_friend.imageset/tell_a_friend@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/tell_a_friend.imageset/tell_a_friend@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/tell_a_friend.imageset/tell_a_friend@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/tell_a_friend.imageset/tell_a_friend@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/twitter_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "twitter_icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "twitter_icon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "twitter_icon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/twitter_icon.imageset/twitter_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/twitter_icon.imageset/twitter_icon.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/twitter_icon.imageset/twitter_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/twitter_icon.imageset/twitter_icon@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/twitter_icon.imageset/twitter_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/twitter_icon.imageset/twitter_icon@3x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/welcome_glyph.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "welcome_glyph.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "welcome_glyph@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "welcome_glyph@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/welcome_glyph.imageset/welcome_glyph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/welcome_glyph.imageset/welcome_glyph.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/welcome_glyph.imageset/welcome_glyph@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/welcome_glyph.imageset/welcome_glyph@2x.png -------------------------------------------------------------------------------- /FOSSAsia/Assets.xcassets/welcome_glyph.imageset/welcome_glyph@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-ios/c11e8f34c3464f2093aec00cdc1ac99765cdde2a/FOSSAsia/Assets.xcassets/welcome_glyph.imageset/welcome_glyph@3x.png -------------------------------------------------------------------------------- /FOSSAsia/AuthTabBarViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class AuthTabBarViewController: UITabBarController { 4 | 5 | @IBOutlet weak var backButton: UIBarButtonItem! 6 | 7 | override func viewDidLoad() { 8 | super.viewDidLoad() 9 | setBackButton() 10 | } 11 | 12 | func setBackButton() { 13 | let button = UIButton(type: .custom) 14 | button.setImage(UIImage(named: "back"), for: .normal) 15 | button.addTarget(self, action: #selector(AuthTabBarViewController.backAction), for: .touchUpInside) 16 | button.frame = CGRect(x: 0, y: 0, width: 53, height: 31) 17 | button.imageEdgeInsets = UIEdgeInsetsMake(1, -32, 1, 32) 18 | let label = UILabel(frame: CGRect(x: 3, y: 5, width: 50, height: 20)) 19 | label.text = "Back" 20 | label.textAlignment = .center 21 | label.textColor = UIColor.white 22 | label.backgroundColor = UIColor.clear 23 | button.addSubview(label) 24 | let barButton = UIBarButtonItem(customView: button) 25 | self.navigationItem.leftBarButtonItem = barButton 26 | } 27 | 28 | 29 | @objc func backAction() { 30 | 31 | let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main) 32 | guard let vc: UITabBarController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarController") as? UITabBarController else { 33 | fatalError("Cannot Cast to UITabBarController") 34 | } 35 | vc.modalPresentationStyle = .fullScreen 36 | vc.selectedIndex = 0 37 | self.present(vc, animated: true, completion: nil) 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /FOSSAsia/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /FOSSAsia/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /FOSSAsia/Base.lproj/Signup~.storyboard: -------------------------------------------------------------------------------- 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 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /FOSSAsia/Client.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Client.swift 3 | // FOSSAsia 4 | // 5 | // Created by Apple on 28/06/18. 6 | // Copyright © 2018 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Alamofire 11 | 12 | class Client: NSObject { 13 | 14 | static let sharedInstance = Client() 15 | var session: URLSession 16 | 17 | private override init() { 18 | session = URLSession.shared 19 | } 20 | 21 | func makeRequest(_ url: String, _ httpMethod: HTTPMethod, _ headers: HTTPHeaders, parameters: [String: AnyObject], completion: @escaping (_ result: AnyObject?,_ statuscode: Int?,_ error: NSError?) -> Void) { 22 | 23 | func sendError(_ error: String) { 24 | debugPrint(error) 25 | completion(nil, nil,NSError(domain: "makeRequestMethod", code: 1)) 26 | } 27 | 28 | 29 | Alamofire.request(url, method: httpMethod, parameters: parameters, encoding: JSONEncoding.default, headers: headers).validate(statusCode: 200..<409) 30 | .responseJSON { (response: DataResponse) in 31 | 32 | print(response) 33 | print(response.request?.url ?? "Error: invalid URL") 34 | 35 | switch(response.result) { 36 | 37 | case .success(_): 38 | if let data = response.result.value as? Dictionary { 39 | 40 | completion(data as AnyObject?,response.response?.statusCode, nil) 41 | } 42 | else { 43 | 44 | completion(nil,nil, NSError(domain: Constants.ResponseMessages.ServerError,code: 1)) 45 | } 46 | break 47 | 48 | case .failure( _): 49 | sendError(Constants.ResponseMessages.ServerError) 50 | break 51 | } 52 | 53 | } 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /FOSSAsia/Colors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 31/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct Colors { 12 | static let mainRedColor = UIColor(hexString: "D90300") 13 | static let creamTintColor = UIColor(hexString: "FEFAD5") 14 | static let favoriteOrangeColor = UIColor(hexString: "F5A623") 15 | static let highlightedBackgroundColor = UIColor(hexString: "FFF5F5") 16 | static let statusBarOrangeColor = UIColor(hexString: "D30005") 17 | } 18 | -------------------------------------------------------------------------------- /FOSSAsia/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 5/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Constants { 12 | 13 | static let numberOfTracks = 15 14 | static let jsonFileExtension = ".json" 15 | static let localNotificationIdentifier = "LocalNotification" 16 | static let sessionsStoryboardName = "Sessions" 17 | static let individualEventStoryboard = "IndividualEvent" 18 | static let eventViewControllerID = "EventViewController" 19 | static let okTitle = "OK" 20 | static let cancelTitle = "Cancel" 21 | static let appStoreAlertTitle = "Open App Store?" 22 | static let appStoreAlertMessage = "Tapping OK will temporarily exit this application and open the app's page on the App Store" 23 | 24 | struct UserDefaultsKey { 25 | static let FilteredTrackIds = "FilteredTrackIds" 26 | static let dataJsonKey = "data" 27 | static let attributesJsonKey = "attributes" 28 | static let emailJsonKey = "email" 29 | static let passwordJsonKey = "password" 30 | static let typeJsonKey = "type" 31 | static let userJsonValue = "user" 32 | static let firstName = "firstName" 33 | static let lastName = "lastName" 34 | static let acessToken = "acessToken" 35 | 36 | } 37 | 38 | struct Url { 39 | static let registerUrl = "https://open-event-api-dev.herokuapp.com/v1/users" 40 | 41 | static let loginUrl = "https://open-event-api-dev.herokuapp.com/auth/session" 42 | 43 | 44 | } 45 | 46 | struct alertMessage { 47 | static let logoutMessageTitle = "Do you want to Logout?" 48 | static let logoutMessage = "Click Yes to Logout!" 49 | static let noTitle = "No" 50 | static let yesTitle = "Yes" 51 | } 52 | 53 | struct Header { 54 | static let contentType = "Content-Type" 55 | 56 | static let contentTypeValueSignup = "application/vnd.api+json" 57 | static let contentTypeValueLogin = "application/json" 58 | 59 | } 60 | 61 | struct ResponseMessages { 62 | static let InvalidParams = "Email ID / Password incorrect" 63 | static let ServerError = "Problem connecting to server!" 64 | static let successMessageSignup = "Successfully Signed Up" 65 | static let successMessageLogin = "Successfully Logged In" 66 | static let checkParameter = "Please Check Parameters Entered" 67 | 68 | } 69 | 70 | 71 | struct Sessions { 72 | static let track = "track" 73 | static let id = "id" 74 | static let sessionId = "session_id" 75 | static let title = "title" 76 | static let description = "description" 77 | static let location = "location" 78 | static let speakers = "speakers" 79 | static let startTime = "start_time" 80 | static let endTime = "end_time" 81 | static let speakerName = "name" 82 | } 83 | 84 | struct Location { 85 | static let lattitude = 1.288424 86 | static let longitude = 103.846694 87 | static let spanCoordinate = 0.0002 88 | static let annotationTitle = "FOSSASIA" 89 | } 90 | 91 | struct SettingsManager { 92 | static let keyForEvent = "HasEvents" 93 | static let keyForMicrolocations = "HasMicrolocations" 94 | static let favesJSON = "faves.json" 95 | } 96 | 97 | struct Images { 98 | static let navbarFaveHighlighted = "navbar_fave_highlighted" 99 | static let navbarFave = "navbar_fave" 100 | } 101 | struct MoreViewController { 102 | static let message = "I am using the Open Event iOS , for browsing information about the event visit https://fossasia.org/ " 103 | static let subject = "Check out the Open Event iOS!" 104 | static let Title = "Subject" 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /FOSSAsia/Convenience.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Convenience.swift 3 | // FOSSAsia 4 | // 5 | // Created by Apple on 29/06/18. 6 | // Copyright © 2018 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | 12 | extension Client { 13 | 14 | 15 | 16 | func registerUser(_ params: [String: AnyObject], _ completion: @escaping(_ success: Bool, _ error: String) -> Void) { 17 | 18 | let url = Constants.Url.registerUrl 19 | 20 | let headerSignup = [ 21 | Constants.Header.contentType: Constants.Header.contentTypeValueSignup 22 | ] 23 | 24 | _ = makeRequest(url, .post, headerSignup, parameters: params, completion: { (results, status, message) in 25 | 26 | 27 | 28 | if let _ = message { 29 | completion(false, Constants.ResponseMessages.ServerError) 30 | } else if results != nil { 31 | 32 | 33 | completion(true, Constants.ResponseMessages.successMessageSignup) 34 | 35 | } 36 | 37 | 38 | return 39 | 40 | }) 41 | 42 | } 43 | 44 | 45 | func loginUser(_ params: [String: AnyObject], _ completion: @escaping(_ success: Bool, _ results: [String: AnyObject]?, _ error: String) -> Void) { 46 | 47 | let url = Constants.Url.loginUrl 48 | 49 | let headerLogin = [ 50 | Constants.Header.contentType: Constants.Header.contentTypeValueLogin 51 | ] 52 | 53 | _ = makeRequest(url, .post, headerLogin, parameters: params, completion: { (results, status, message) in 54 | 55 | 56 | if results != nil && status == 200 { 57 | completion(true, results as? [String: AnyObject], Constants.ResponseMessages.successMessageLogin) 58 | } else { 59 | completion(false, nil, Constants.ResponseMessages.InvalidParams) 60 | } 61 | 62 | 63 | return 64 | 65 | }) 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /FOSSAsia/DecisionViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class DecisionViewController: UIViewController { 4 | 5 | override func viewDidLoad() { 6 | super.viewDidLoad() 7 | // Do any additional setup after loading the view. 8 | } 9 | 10 | override func viewWillAppear(_ animated: Bool) { 11 | setAuthentication() 12 | } 13 | 14 | func setAuthentication() { 15 | if UserDefaults.exists(key: Constants.UserDefaultsKey.acessToken) { 16 | let profileStoryboard = UIStoryboard(name: "Profile", bundle: Bundle.main) 17 | let profileVC = profileStoryboard.instantiateViewController(withIdentifier: "ProfileViewController") 18 | self.navigationController?.pushViewController(profileVC, animated: false) 19 | } else { 20 | let profileStoryboard = UIStoryboard(name: "Profile", bundle: Bundle.main) 21 | guard let vc: UITabBarController = profileStoryboard.instantiateViewController(withIdentifier: "AuthTabBarController") as? UITabBarController else { 22 | fatalError("Cannot Cast to UITabBarController") 23 | } 24 | vc.selectedIndex = 0 25 | self.navigationController?.pushViewController(vc, animated: false) 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /FOSSAsia/Error.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Error.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 1/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Error { 12 | enum Code: Int { 13 | case urlError = -6000 14 | case networkRequestFailed = -6001 15 | case jsonSerializationFailed = -6002 16 | case jsonParsingFailed = -6003 17 | case jsonSystemReadingFailed = -6004 18 | case writingOnDiskFailed = -6005 19 | } 20 | 21 | let errorCode: Code 22 | } 23 | -------------------------------------------------------------------------------- /FOSSAsia/Event.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Event.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Event { 12 | enum Track: Int, CustomStringConvertible { 13 | case openTechIOT = 1 14 | case openTech, techKids1, techKids2, techKids3, hardwareIOT, devOps, webTech, python, bigOpenData, databases, isc, privSec, scienceHackDay, linux, design, exhibition, social 15 | var description: String { 16 | switch self { 17 | case .techKids1: return "Tech Kids I" 18 | case .techKids2: return "Tech Kids II" 19 | case .techKids3: return "Tech Kids III" 20 | case .openTechIOT: return "OpenTech and IOT" 21 | case .openTech: return "OpenTech Workshops" 22 | case .webTech: return "WebTech" 23 | case .exhibition: return "Exhibition" 24 | case .hardwareIOT: return "Hardware and IOT" 25 | case .python: return "Python" 26 | case .databases: return "Databases" 27 | case .bigOpenData: return "Big Data/Open Data" 28 | case .devOps: return "DevOps" 29 | case .privSec: return "Privacy and Security" 30 | case .isc: return "Internet, Society, Community" 31 | case .scienceHackDay: return "Science Hack Day" 32 | case .linux: return "Linux and MiniDebConf" 33 | case .design: return "Design, VR, 3D" 34 | case .social: return "Social Event" 35 | } 36 | } 37 | 38 | func getTrackColor() -> UIColor { 39 | switch self { 40 | case .techKids1, .techKids2, .techKids3: 41 | return UIColor(hexString: "8E8E93")! 42 | case .openTechIOT: 43 | return UIColor(hexString: "FF4D4D")! 44 | case .openTech: 45 | return UIColor(hexString: "FF8E4C")! 46 | case .webTech: 47 | return UIColor(hexString: "FFCF4C")! 48 | case .exhibition, .social: 49 | return UIColor(hexString: "EAFF4C")! 50 | case .hardwareIOT: 51 | return UIColor(hexString: "B8FF4C")! 52 | case .python: 53 | return UIColor(hexString: "85FF4C")! 54 | case .databases: 55 | return UIColor(hexString: "50E3C2")! 56 | case .bigOpenData: 57 | return UIColor(hexString: "4CFFE7")! 58 | case .devOps: 59 | return UIColor(hexString: "4CDBFF")! 60 | case .privSec: 61 | return UIColor(hexString: "4CA9FF")! 62 | case .isc: 63 | return UIColor(hexString: "7C4CFF")! 64 | case .scienceHackDay: 65 | return UIColor(hexString: "9D4CFF")! 66 | case .linux: 67 | return UIColor(hexString: "ED4CFF")! 68 | case .design: 69 | return UIColor(hexString: "FF4CCC")! 70 | } 71 | } 72 | } 73 | 74 | let id: String 75 | let trackCode: Track 76 | let title: String 77 | let shortDescription: String 78 | let speakers: [Speaker]? 79 | let location: String 80 | let startDateTime: Date 81 | let endDateTime: Date 82 | var favorite: Bool 83 | } 84 | -------------------------------------------------------------------------------- /FOSSAsia/EventCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventCell.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MGSwipeTableCell 11 | 12 | typealias EventCellWithTypePresentable = EventTypePresentable & EventDetailsPresentable 13 | 14 | class EventCell: MGSwipeTableCell { 15 | @IBOutlet weak var favoriteImage: UIImageView! 16 | @IBOutlet weak var typeView: UIView! 17 | @IBOutlet weak var titleLabel: UILabel! 18 | @IBOutlet weak var timingLabel: UILabel! 19 | 20 | fileprivate var viewModel: EventCellWithTypePresentable? 21 | 22 | func configure(withPresenter presenter: EventCellWithTypePresentable) { 23 | viewModel = presenter 24 | titleLabel.text = viewModel!.eventName 25 | typeView.backgroundColor = viewModel!.typeColor 26 | timingLabel.text = viewModel!.timing 27 | if (viewModel!.isFavorite) { 28 | favoriteImage.transform = CGAffineTransform.identity 29 | favoriteImage.alpha = 1.0 30 | } else { 31 | favoriteImage.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) 32 | favoriteImage.alpha = 0.0 33 | } 34 | } 35 | 36 | override func setSelected(_ selected: Bool, animated: Bool) { 37 | let color = typeView.backgroundColor 38 | super.setSelected(selected, animated: animated) 39 | 40 | if selected { 41 | typeView.backgroundColor = color 42 | self.contentView.backgroundColor = Colors.highlightedBackgroundColor 43 | } 44 | } 45 | 46 | override func setHighlighted(_ highlighted: Bool, animated: Bool) { 47 | let color = typeView.backgroundColor 48 | super.setHighlighted(highlighted, animated: animated) 49 | 50 | if highlighted { 51 | typeView.backgroundColor = color 52 | 53 | self.contentView.backgroundColor = Colors.highlightedBackgroundColor 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /FOSSAsia/EventInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Type.swift 3 | // FOSSAsia 4 | // 5 | // Created by Pratik Todi on 27/02/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum EventInfo: String { 12 | case Events = "sessions" 13 | case Tracks = "tracks" 14 | case Microlocations = "microlocations" 15 | case Speakers = "speakers" 16 | } 17 | -------------------------------------------------------------------------------- /FOSSAsia/EventInfoView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventInfoView.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 31/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class EventInfoView: UIView { 12 | @IBOutlet weak var eventLabel: UILabel! 13 | @IBOutlet weak var speakerLabel: UILabel! 14 | @IBOutlet weak var locationLabel: UILabel! 15 | 16 | fileprivate var delegate: EventDetailsPresentable? 17 | 18 | func configure(_ presenter: EventDetailsPresentable) { 19 | delegate = presenter 20 | 21 | if let delegate = self.delegate { 22 | eventLabel.text = delegate.eventName 23 | speakerLabel.text = delegate.speakerNames 24 | locationLabel.text = delegate.timing 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /FOSSAsia/EventListBrowsingProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventListBrowsingProtocol.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 12/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Pages 11 | 12 | typealias EventListBrowsingByDate = EventsPresentable & SchedulePagingViewDelegate & PagesControllerDelegate 13 | 14 | protocol EventsPresentable { 15 | func getEventsListViewModel() -> EventsListViewModel 16 | } 17 | 18 | extension EventsPresentable where Self: EventsBaseListViewController { 19 | func getEventsListViewModel() -> EventsListViewModel { 20 | return EventsListViewModel() 21 | } 22 | } 23 | 24 | extension EventsPresentable where Self: FavoriteEventsListViewController { 25 | func getEventsListViewModel() -> EventsListViewModel { 26 | var eventsViewModel = EventsListViewModel() 27 | eventsViewModel.setFavoritesOnly(true) 28 | return eventsViewModel 29 | } 30 | } 31 | 32 | protocol SchedulePagingViewDelegate: class { 33 | func nextButtonDidPress(_ sender: SchedulePagingView) 34 | func prevButtonDidPress(_ sender: SchedulePagingView) 35 | } 36 | -------------------------------------------------------------------------------- /FOSSAsia/EventViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 31/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import EventKit 11 | import EventKitUI 12 | 13 | typealias IndividualEventPresentable = EventDetailsPresentable & EventDescriptionPresentable & EventAddToCalendarPresentable 14 | 15 | class EventViewController: UIViewController { 16 | 17 | // Constants for Storyboard/VC 18 | struct StoryboardConstants { 19 | static let storyboardName = Constants.individualEventStoryboard 20 | static let viewControllerId = Constants.eventViewControllerID 21 | } 22 | 23 | // MARK: - Properties 24 | var eventViewModel: EventViewModel? { 25 | didSet { 26 | eventViewModel?.favorite.observe({ (newValue) -> Void in 27 | self.navBarButtonItem.image = newValue ? UIImage(named: Constants.Images.navbarFaveHighlighted) : UIImage(named: Constants.Images.navbarFave) 28 | }) 29 | } 30 | } 31 | var presenter: IndividualEventPresentable? 32 | 33 | @IBOutlet weak var contentView: UIView! 34 | @IBOutlet weak var scrollView: UIScrollView! 35 | @IBOutlet weak var eventDescriptionTextView: UITextView! 36 | @IBOutlet weak var eventInfoView: EventInfoView! 37 | @IBOutlet weak var eventDateTimeLabel: UILabel! 38 | @IBOutlet weak var eventAddToCalendarButton: UIButton! 39 | @IBOutlet weak var eventAddToCalendarButtonBottomConstraint: NSLayoutConstraint! 40 | @IBOutlet weak var navBarButtonItem: UIBarButtonItem! 41 | 42 | // MARK: - Initialization 43 | class func eventViewControllerForEvent(_ event: EventViewModel) -> EventViewController { 44 | let storyboard = UIStoryboard(name: EventViewController.StoryboardConstants.storyboardName, bundle: nil) 45 | 46 | let viewController = storyboard.instantiateViewController(withIdentifier: EventViewController.StoryboardConstants.viewControllerId) as! EventViewController 47 | viewController.eventViewModel = event 48 | 49 | return viewController 50 | } 51 | 52 | override func viewDidLoad() { 53 | if let viewModel = eventViewModel { 54 | self.configure(viewModel) 55 | } 56 | 57 | navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem 58 | navigationItem.leftItemsSupplementBackButton = true 59 | } 60 | 61 | override func viewDidLayoutSubviews() { 62 | self.scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width, height: self.eventAddToCalendarButton.frame.maxY + eventAddToCalendarButtonBottomConstraint.constant) 63 | } 64 | 65 | func configure(_ presenter: IndividualEventPresentable) { 66 | eventDescriptionTextView.text = presenter.eventDescription 67 | eventInfoView.configure(presenter) 68 | eventDateTimeLabel.text = "\(presenter.eventDay), \(presenter.eventDate) \(presenter.eventMonth), \(presenter.eventStartTime) - \(presenter.eventEndTime)" 69 | self.presenter = presenter 70 | } 71 | 72 | @IBAction func eventAddToCalendar(_ sender: UIButton) { 73 | let store = EKEventStore() 74 | 75 | store.requestAccess(to: .event) {(granted, error) in 76 | if !granted { return } 77 | let event = EKEvent(eventStore: store) 78 | event.title = (self.presenter?.eventName)! 79 | event.startDate = (self.presenter?.eventStartDate)! as Date 80 | event.endDate = (self.presenter?.eventEndDate)! as Date 81 | event.calendar = store.defaultCalendarForNewEvents 82 | 83 | OperationQueue.main.addOperation({ () -> Void in 84 | let eventVC = EKEventEditViewController() 85 | eventVC.navigationBar.tintColor = Colors.mainRedColor 86 | eventVC.event = event 87 | eventVC.eventStore = store 88 | eventVC.editViewDelegate = self 89 | self.present(eventVC, animated: true, completion: nil) 90 | }) 91 | } 92 | } 93 | @IBAction func favoriteEvent(_ sender: AnyObject) { 94 | self.eventViewModel?.favoriteEvent { [weak self] (eventViewModel, error) -> Void in 95 | if let masterNavVC = self?.splitViewController?.viewControllers[0] as? UINavigationController { 96 | if let masterVC = masterNavVC.topViewController as? EventsBaseListViewController { 97 | OperationQueue.main.addOperation({ () -> Void in 98 | masterVC.currentViewController.tableView.reloadData() 99 | }) 100 | } 101 | } 102 | } 103 | } 104 | } 105 | 106 | extension EventViewController: EKEventEditViewDelegate { 107 | func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) { 108 | self.dismiss(animated: true, completion: nil) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /FOSSAsia/EventsBaseListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventsBaseListViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 12/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Pages 11 | 12 | class EventsBaseListViewController: UIViewController, EventListBrowsingByDate, UIViewControllerPreviewingDelegate { 13 | fileprivate var collapseDetailViewController = true 14 | weak var pagesVC: PagesController! 15 | @IBOutlet weak var pagingView: SchedulePagingView! 16 | 17 | var currentViewController: EventsBaseViewController! { 18 | didSet { 19 | self.registerForPreviewing(with: self, sourceView: currentViewController.tableView) 20 | currentViewController.delegate = self 21 | } 22 | } 23 | var viewModel: EventsListViewModel? { 24 | didSet { 25 | viewModel?.allSchedules.observe { 26 | [unowned self] in 27 | guard $0.count > 0 else { 28 | return 29 | } 30 | self.onViewModelScheduleChange($0) 31 | } 32 | } 33 | } 34 | 35 | override func viewDidLoad() { 36 | super.viewDidLoad() 37 | viewModel = getEventsListViewModel() 38 | pagingView.delegate = self 39 | navigationController?.splitViewController?.delegate = self 40 | splitViewController?.preferredDisplayMode = .allVisible 41 | } 42 | 43 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 44 | if (segue.identifier == "EventsPageViewController") { 45 | if let embeddedPageVC = segue.destination as? PagesController { 46 | self.pagesVC = embeddedPageVC 47 | let storyboard = UIStoryboard(name: LoadingViewController.StoryboardConstants.storyboardName, bundle: nil) 48 | let loadingVC = storyboard.instantiateViewController(withIdentifier: LoadingViewController.StoryboardConstants.viewControllerId) 49 | self.pagesVC.add([loadingVC]) 50 | self.pagesVC.enableSwipe = false 51 | self.pagesVC.pagesDelegate = self 52 | } 53 | } 54 | } 55 | 56 | func onViewModelScheduleChange(_ newSchedule: [ScheduleViewModel]) { 57 | let viewControllers = newSchedule.map { viewModel in 58 | return ScheduleViewController.scheduleViewControllerFor(viewModel) 59 | } 60 | self.pagesVC.add(viewControllers) 61 | } 62 | } 63 | 64 | // MARK: - ScheduleViewControllerDelegate Conformance { 65 | extension EventsBaseListViewController: ScheduleViewControllerDelegate { 66 | func eventDidGetSelected(_ tableView: UITableView, atIndexPath: IndexPath) { 67 | collapseDetailViewController = false 68 | } 69 | } 70 | 71 | // MARK: - UISplitViewControllerDelegate Conformance 72 | extension EventsBaseListViewController: UISplitViewControllerDelegate { 73 | func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool { 74 | return collapseDetailViewController 75 | } 76 | } 77 | 78 | // MARK: - UIViewControllerPreviewingDelegate Conformance 79 | extension EventsBaseListViewController { 80 | func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { 81 | guard let indexPath = self.currentViewController.tableView.indexPathForRow(at: location) else { 82 | return nil 83 | } 84 | 85 | let eventVM = self.currentViewController.eventViewModelForIndexPath(indexPath) 86 | if let eventCell = self.currentViewController.tableView.cellForRow(at: indexPath) { 87 | previewingContext.sourceRect = eventCell.frame 88 | } 89 | 90 | let eventVC = EventViewController.eventViewControllerForEvent(eventVM) 91 | return eventVC 92 | } 93 | 94 | @objc(previewingContext:commitViewController:) func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { 95 | navigationController?.pushViewController(viewControllerToCommit, animated: true) 96 | } 97 | } 98 | 99 | extension EventsBaseListViewController { 100 | func nextButtonDidPress(_ sender: SchedulePagingView) { 101 | self.pagesVC.moveForward() 102 | 103 | } 104 | func prevButtonDidPress(_ sender: SchedulePagingView) { 105 | self.pagesVC.moveBack() 106 | } 107 | 108 | func pageViewController(_ pageViewController: UIPageViewController, setViewController viewController: UIViewController, atPage page: Int) { 109 | guard let currentVC = viewController as? EventsBaseViewController else { 110 | return 111 | } 112 | pagingView.dateLabel.text = ((currentVC.viewModel?.date.value)! as NSDate).formattedDate(withFormat: "EEEE, MMM dd") 113 | 114 | // Govern Previous Button 115 | if page == 1 { 116 | pagingView.prevButton.isEnabled = false 117 | } else { 118 | pagingView.prevButton.isEnabled = true 119 | } 120 | 121 | // Govern Next Button 122 | if let scheduleViewModels = viewModel { 123 | if page == scheduleViewModels.count.value { 124 | pagingView.nextButton.isEnabled = false 125 | } else { 126 | pagingView.nextButton.isEnabled = true 127 | } 128 | } 129 | 130 | self.currentViewController = currentVC 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /FOSSAsia/EventsBaseViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventsBaseViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 7/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class EventsBaseViewController: UIViewController { 12 | weak var delegate: ScheduleViewControllerDelegate? 13 | static let kEventCellReuseIdentifier = "EventCell" 14 | var allEvents: [EventViewModel] = [] 15 | 16 | @IBOutlet weak var tableView: UITableView! 17 | 18 | var viewModel: ScheduleViewModel? { 19 | didSet { 20 | viewModel?.events.observe { 21 | [unowned self] in 22 | self.allEvents = $0 23 | } 24 | } 25 | } 26 | 27 | override func viewWillAppear(_ animated: Bool) { 28 | super.viewWillAppear(animated) 29 | viewModel?.refresh() 30 | self.tableView.reloadData() 31 | } 32 | 33 | override func viewDidLoad() { 34 | super.viewDidLoad() 35 | // Do any additional setup after loading the view, typically from a nib. 36 | tableView.dataSource = self 37 | tableView.delegate = self 38 | tableView.rowHeight = 70 39 | 40 | tableView.tableFooterView = UIView(frame: CGRect.zero) 41 | } 42 | 43 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 44 | if (segue.identifier == "ShowEventDetail") { 45 | if let selectedIndexPath = self.tableView.indexPathForSelectedRow { 46 | if let eventNavigationController = segue.destination as? UINavigationController { 47 | let eventViewController = eventNavigationController.topViewController as! EventViewController 48 | eventViewController.eventViewModel = allEvents[(selectedIndexPath as NSIndexPath).row] 49 | } 50 | } 51 | } 52 | } 53 | 54 | func eventViewModelForIndexPath(_ path: IndexPath) -> EventViewModel { 55 | return allEvents[(path as NSIndexPath).row] 56 | } 57 | 58 | } 59 | 60 | extension EventsBaseViewController: UITableViewDelegate { 61 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 62 | delegate?.eventDidGetSelected(tableView, atIndexPath: indexPath) 63 | } 64 | } 65 | 66 | extension EventsBaseViewController: UITableViewDataSource { 67 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 68 | let cell = tableView.dequeueReusableCell(withIdentifier: EventsBaseViewController.kEventCellReuseIdentifier, for: indexPath) as! EventCell 69 | let eventViewModel = allEvents[(indexPath as NSIndexPath).row] 70 | cell.configure(withPresenter: eventViewModel) 71 | 72 | return cell 73 | } 74 | 75 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 76 | return allEvents.count 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /FOSSAsia/EventsListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventsListViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 10/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Pages 11 | 12 | class EventsListViewController: EventsBaseListViewController { 13 | var searchController: UISearchController! 14 | var resultsTableController: EventsResultsViewController! 15 | 16 | var filterString: String? = nil { 17 | didSet { 18 | guard let scheduleVC = currentViewController as? ScheduleViewController else { 19 | return 20 | } 21 | 22 | scheduleVC.filterString = filterString 23 | resultsTableController.visibleEvents = scheduleVC.filteredEvents 24 | resultsTableController.tableView.reloadData() 25 | 26 | } 27 | } 28 | override var currentViewController: EventsBaseViewController! { 29 | didSet { 30 | if resultsTableController != nil { 31 | resultsTableController.allEvents = currentViewController.allEvents 32 | } 33 | } 34 | } 35 | 36 | override func viewDidLoad() { 37 | super.viewDidLoad() 38 | viewModel = self.getEventsListViewModel() 39 | pagingView.delegate = self 40 | 41 | let storyboard = UIStoryboard(name: EventsResultsViewController.StoryboardConstants.storyboardName, bundle: nil) 42 | resultsTableController = storyboard.instantiateViewController(withIdentifier: EventsResultsViewController.StoryboardConstants.viewControllerId) as! EventsResultsViewController 43 | 44 | searchController = UISearchController(searchResultsController: resultsTableController) 45 | searchController.searchResultsUpdater = self 46 | searchController.hidesNavigationBarDuringPresentation = false 47 | 48 | // We want to be the delegate for our filtered table so didSelectRowAtIndexPath(_:) is called for both tables. 49 | // calling .view will force Storyboards to render the view hierarchy to make tableView accessible 50 | _ = searchController.view 51 | resultsTableController.tableView.delegate = self 52 | 53 | searchController.searchBar.searchBarStyle = .minimal 54 | searchController.searchBar.tintColor = Colors.creamTintColor 55 | searchController.searchBar.placeholder = "Search" 56 | if let textFieldInSearchBar = searchController.searchBar.value(forKey: "searchField") as? UITextField { 57 | textFieldInSearchBar.textColor = Colors.creamTintColor 58 | } 59 | 60 | navigationItem.titleView = searchController.searchBar 61 | 62 | definesPresentationContext = true 63 | } 64 | 65 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 66 | if (segue.identifier == "EventsPageViewController") { 67 | if let embeddedPageVC = segue.destination as? PagesController { 68 | self.pagesVC = embeddedPageVC 69 | let loadingVC = self.storyboard!.instantiateViewController(withIdentifier: LoadingViewController.StoryboardConstants.viewControllerId) 70 | self.pagesVC.add([loadingVC]) 71 | self.pagesVC.enableSwipe = false 72 | self.pagesVC.pagesDelegate = self 73 | } 74 | } 75 | } 76 | 77 | fileprivate func delay(_ delay: Double, closure:@escaping ()->Void) { 78 | DispatchQueue.main.asyncAfter( 79 | deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure) 80 | } 81 | } 82 | 83 | extension EventsListViewController: UISearchResultsUpdating { 84 | func updateSearchResults(for searchController: UISearchController) { 85 | guard searchController.isActive else { 86 | return 87 | } 88 | filterString = searchController.searchBar.text 89 | } 90 | } 91 | 92 | extension EventsListViewController: UITableViewDelegate { 93 | // This delegate is for the UISearchController. 94 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 95 | let selectedEventViewModel: EventViewModel 96 | 97 | selectedEventViewModel = resultsTableController.visibleEvents[(indexPath as NSIndexPath).row] 98 | 99 | let storyboard = UIStoryboard(name: EventViewController.StoryboardConstants.storyboardName, bundle: nil) 100 | if let nvc = storyboard.instantiateViewController(withIdentifier: "IndividualEventNavController") as? UINavigationController { 101 | if let eventVC = nvc.topViewController as? EventViewController { 102 | eventVC.eventViewModel = selectedEventViewModel 103 | splitViewController?.showDetailViewController(nvc, sender: self) 104 | searchController.searchBar.resignFirstResponder() 105 | } 106 | } 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /FOSSAsia/EventsListViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventsListViewModel.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 10/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EventsListViewModel { 12 | // MARK: - Properties 13 | let allSchedules: Observable<[ScheduleViewModel]> = Observable([]) 14 | let count: Observable 15 | var isFavoritesOnly: Observable = Observable(false) 16 | 17 | // MARK: - Errors 18 | let hasError: Observable 19 | let errorMessage: Observable 20 | 21 | // MARK: - Services 22 | fileprivate var eventsService: EventProvider 23 | 24 | init () { 25 | hasError = Observable(false) 26 | errorMessage = Observable(nil) 27 | 28 | self.count = Observable(1) 29 | 30 | // Dependency Injections 31 | eventsService = EventProvider() 32 | 33 | refreshDates() 34 | } 35 | 36 | func refreshDates() { 37 | // Retrieve all dates 38 | eventsService.getEvents(nil, trackIds: nil) { (events, error) -> Void in 39 | if let eventsArray = events { 40 | var dates = Set() 41 | for event in eventsArray { 42 | let newDate = NSDate(year: (event.startDateTime as NSDate).year(), month: (event.startDateTime as NSDate).month(), day: (event.startDateTime as NSDate).day()) 43 | dates.insert(newDate! as Date) 44 | } 45 | let sortedDates = dates.sorted(by: {$0.compare($1) == .orderedAscending}) 46 | self.update(self.retrieveSchedule(sortedDates)) 47 | } 48 | } 49 | } 50 | 51 | mutating func setFavoritesOnly(_ isFavoritesOnly: Bool) { 52 | self.isFavoritesOnly = Observable(true) 53 | refreshDates() 54 | } 55 | 56 | fileprivate func update(_ allSchedule: [ScheduleViewModel]) { 57 | self.allSchedules.value = allSchedule 58 | self.count.value = allSchedule.count 59 | } 60 | 61 | fileprivate func retrieveSchedule(_ dates: [Date]) -> [ScheduleViewModel] { 62 | let allSchedules = dates.map { date in 63 | return ScheduleViewModel(date, favoritesOnly: (isFavoritesOnly.value ? true : false)) 64 | } 65 | return allSchedules 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /FOSSAsia/EventsResultsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SessionsSearchViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 7/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class EventsResultsViewController: EventsBaseViewController { 12 | 13 | struct StoryboardConstants { 14 | static let storyboardName = "ScheduleVC" 15 | static let viewControllerId = String(describing: EventsResultsViewController.self) 16 | } 17 | 18 | lazy var visibleEvents: [EventViewModel] = self.allEvents 19 | 20 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 21 | if (segue.identifier == "ShowEventDetail") { 22 | if let selectedIndexPath = self.tableView.indexPathForSelectedRow { 23 | if let eventNavigationController = segue.destination as? UINavigationController { 24 | let eventViewController = eventNavigationController.topViewController as! EventViewController 25 | eventViewController.eventViewModel = visibleEvents[(selectedIndexPath as NSIndexPath).row] 26 | } 27 | } 28 | } 29 | } 30 | } 31 | 32 | // MARK: UITableViewDataSource 33 | extension EventsResultsViewController { 34 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 35 | return visibleEvents.count 36 | } 37 | 38 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 39 | let cell = tableView.dequeueReusableCell(withIdentifier: EventsBaseViewController.kEventCellReuseIdentifier, for: indexPath) as! EventCell 40 | let eventViewModel = visibleEvents[(indexPath as NSIndexPath).row] 41 | cell.configure(withPresenter: eventViewModel) 42 | 43 | return cell 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /FOSSAsia/FavoriteEventsListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavoriteEventsListViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 12/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Pages 11 | 12 | class FavoriteEventsListViewController: EventsBaseListViewController { 13 | override func viewDidLoad() { 14 | viewModel = getEventsListViewModel() 15 | super.viewDidLoad() 16 | if let currentVC = currentViewController { 17 | self.registerForPreviewing(with: self, sourceView: currentVC.tableView) 18 | } 19 | } 20 | 21 | override func onViewModelScheduleChange(_ newSchedule: [ScheduleViewModel]) { 22 | let viewControllers = newSchedule.map { viewModel in 23 | return FavoritesScheduleViewController.scheduleViewControllerFor(viewModel) 24 | } 25 | self.pagesVC.add(viewControllers) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /FOSSAsia/FetchDataService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Events.swift 3 | // FOSSAsia 4 | // 5 | // Created by Pratik Todi on 27/02/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct FetchDataService { 12 | 13 | func fetchData(_ eventInfo: EventInfo, completionHandler: @escaping ApiRequestCompletionHandler) { 14 | let apiClient = ApiClient(eventInfo: eventInfo) 15 | apiClient.sendGetRequest { (data, error) -> Void in 16 | guard let unwrappedData = data else { 17 | completionHandler(nil, error) 18 | return 19 | } 20 | completionHandler(unwrappedData, nil) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /FOSSAsia/FilterCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FilterCell.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 4/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | typealias TrackDetailsWithSwitchPresentable = TrackDetailsPresentable & TrackStatusPresentable & TrackColorPresentable 12 | 13 | class FilterCell: UITableViewCell { 14 | @IBOutlet weak var trackLabel: UILabel! 15 | @IBOutlet weak var trackIndicator: UIView! 16 | @IBOutlet weak var trackSwitch: UISwitch! 17 | 18 | fileprivate var delegate: TrackDetailsWithSwitchPresentable? 19 | 20 | func configure(_ presenter: TrackDetailsWithSwitchPresentable) { 21 | delegate = presenter 22 | trackLabel.text = presenter.trackName 23 | trackIndicator.backgroundColor = presenter.trackColor 24 | if let filterPrefs = UserDefaults.standard.object(forKey: Constants.UserDefaultsKey.FilteredTrackIds) as? [Int] { 25 | trackSwitch.isOn = filterPrefs.contains(presenter.trackId) 26 | } 27 | trackSwitch.addTarget(self, action: #selector(FilterCell.switchFlipped(_:)), for: .valueChanged) 28 | } 29 | 30 | @objc func switchFlipped(_ sender: AnyObject) { 31 | if let filterSwitch = sender as? UISwitch { 32 | delegate?.changeFilterPreference(filterSwitch.isOn) 33 | } 34 | } 35 | 36 | override func layoutSubviews() { 37 | super.layoutSubviews() 38 | trackIndicator.layer.cornerRadius = trackIndicator.frame.size.width / 2 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /FOSSAsia/FilterListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FilterListViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 4/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FilterListViewController: UIViewController { 12 | fileprivate let kFilterCellReuseIdentifier = "FilterCell" 13 | @IBOutlet weak var filterTableView: UITableView! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | filterTableView.dataSource = self 18 | self.navigationController?.navigationBar.tintColor = Colors.mainRedColor 19 | } 20 | 21 | @IBAction func doneButtonPressed(_ sender: AnyObject) { 22 | self.navigationController?.dismiss(animated: true, completion: nil) 23 | } 24 | } 25 | 26 | extension FilterListViewController: UITableViewDataSource { 27 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 28 | return Constants.numberOfTracks 29 | } 30 | 31 | func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 32 | if section == 0 { 33 | return "Tracks" 34 | } 35 | return "" 36 | } 37 | 38 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 39 | let cell = self.filterTableView.dequeueReusableCell(withIdentifier: kFilterCellReuseIdentifier, for: indexPath) as! FilterCell 40 | let trackId = (indexPath as NSIndexPath).row + 1 41 | let trackViewModel = TrackViewModel(Event.Track(rawValue: trackId)!) 42 | 43 | cell.configure(trackViewModel) 44 | 45 | return cell 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /FOSSAsia/FossAsiaAPI.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FossAsiaAPI.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 28/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct FossAsiaAPI { 12 | private let urlPath = "https://raw.githubusercontent.com/fossasia/open-event/master/testapi/" 13 | 14 | func getEventsFromNetwork(completionHandler: APINetworkCompletionHandler) { 15 | let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration() 16 | let session = NSURLSession(configuration: sessionConfig) 17 | 18 | let url = urlPath + "event/1/sessions" 19 | let request = NSURLRequest(URL: NSURL(string: url)!) 20 | let task = session.dataTaskWithRequest(request) { (data, response, networkError) -> Void in 21 | if networkError != nil { 22 | let error = Error(errorCode: .NetworkRequestFailed) 23 | completionHandler(nil, error) 24 | } 25 | 26 | guard let unwrappedData = data else { 27 | let error = Error(errorCode: .JSONSerializationFailed) 28 | completionHandler(nil, error) 29 | return 30 | } 31 | 32 | completionHandler(unwrappedData, nil) 33 | } 34 | 35 | task.resume() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FOSSAsia/Fossasia-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Fossasia-Bridging-Header.h 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | #ifndef Fossasia_Bridging_Header_h 10 | #define Fossasia_Bridging_Header_h 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | #endif /* Fossasia_Bridging_Header_h */ 18 | -------------------------------------------------------------------------------- /FOSSAsia/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIViewControllerBasedStatusBarAppearance 6 | 7 | NSCalendarsUsageDescription 8 | $(PRODUCT_NAME) calendar events 9 | UIStatusBarHidden 10 | 11 | CFBundleDevelopmentRegion 12 | en 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | $(PRODUCT_NAME) 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | 1.0 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 91 29 | LSRequiresIPhoneOS 30 | 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UIStatusBarTintParameters 40 | 41 | UINavigationBar 42 | 43 | Style 44 | UIBarStyleDefault 45 | Translucent 46 | 47 | 48 | 49 | UISupportedInterfaceOrientations 50 | 51 | UIInterfaceOrientationPortrait 52 | UIInterfaceOrientationLandscapeLeft 53 | UIInterfaceOrientationLandscapeRight 54 | 55 | UISupportedInterfaceOrientations~ipad 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationPortraitUpsideDown 59 | UIInterfaceOrientationLandscapeLeft 60 | UIInterfaceOrientationLandscapeRight 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /FOSSAsia/LoadingViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoadingViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 12/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LoadingViewController: UIViewController { 12 | struct StoryboardConstants { 13 | static let storyboardName = Constants.sessionsStoryboardName 14 | static let viewControllerId = String(describing: LoadingViewController.self) 15 | } 16 | lazy var loadAnimating = true 17 | 18 | @IBOutlet weak var loadingImageView: UIImageView! 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | // self.spinLoadingIndicatorWithOptions(UIViewAnimationOptions()) 22 | 23 | } 24 | 25 | override func viewDidAppear(_ animated: Bool) { 26 | super.viewDidAppear(animated) 27 | 28 | // moved spinLoadingIndicatorWithOptions from viewDidLoad to viewDidAppear 29 | self.spinLoadingIndicatorWithOptions(UIViewAnimationOptions()) 30 | } 31 | 32 | fileprivate func spinLoadingIndicatorWithOptions(_ options: UIViewAnimationOptions) { 33 | 34 | UIView.animate(withDuration: 0.15, delay: 0, options: options, animations: { () -> Void in 35 | self.loadingImageView.transform = self.loadingImageView.transform.rotated(by: CGFloat(Double.pi / 2)) 36 | }) { (finished) -> Void in 37 | if finished { 38 | if self.loadAnimating { 39 | self.spinLoadingIndicatorWithOptions([.curveLinear]) 40 | } else if (options != UIViewAnimationOptions()) { 41 | self.spinLoadingIndicatorWithOptions(UIViewAnimationOptions()) 42 | } 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /FOSSAsia/LoginVCMethods.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import SwiftValidators 3 | 4 | extension LoginViewController { 5 | 6 | func addTapGesture() { 7 | let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) 8 | view.addGestureRecognizer(tap) 9 | } 10 | 11 | 12 | func prepareUserNameField() { 13 | 14 | emailTextField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) 15 | } 16 | 17 | // Configures Password Text Field 18 | func preparePasswordField() { 19 | 20 | passwordTextField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) 21 | } 22 | 23 | 24 | 25 | // Configure Login Button 26 | func prepareLoginButton() { 27 | loginButton.addTarget(self, action: #selector(performLogin), for: .touchUpInside) 28 | } 29 | 30 | @objc func performLogin() { 31 | if isValid() { 32 | self.loginActivityIndicator.isHidden = false 33 | self.loginActivityIndicator.startAnimating() 34 | let email = emailTextField.text?.lowercased() 35 | let password = passwordTextField.text 36 | let params: [String: AnyObject] = [ 37 | 38 | Constants.UserDefaultsKey.emailJsonKey: email as AnyObject, 39 | Constants.UserDefaultsKey.passwordJsonKey: password as AnyObject 40 | 41 | ] 42 | 43 | Client.sharedInstance.loginUser(params as [String: AnyObject]) { (success, result, message) in 44 | DispatchQueue.main.async { 45 | self.loginActivityIndicator.stopAnimating() 46 | self.toggleEditing() 47 | if success { 48 | self.view.makeToast(message) 49 | guard let accessToken = result?["access_token"] as? String else { 50 | fatalError("Unable to Fetch AccessToken") 51 | } 52 | UserDefaults.standard.set(accessToken, forKey: Constants.UserDefaultsKey.acessToken) 53 | let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main) 54 | guard let vc: UITabBarController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarController") as? UITabBarController else { 55 | fatalError("Cannot Cast to UITabBarController") 56 | } 57 | vc.selectedIndex = 0 58 | self.present(vc, animated: true, completion: nil) 59 | 60 | } 61 | else { 62 | self.view.makeToast(message) 63 | self.toggleEditing() 64 | } 65 | 66 | } 67 | } 68 | } 69 | else { 70 | self.view.makeToast(Constants.ResponseMessages.checkParameter) 71 | } 72 | 73 | } 74 | 75 | // Keyboard Return Key Hit 76 | func textFieldShouldReturn(_ textField: UITextField) -> Bool { 77 | textField.resignFirstResponder() 78 | return true 79 | } 80 | 81 | @objc func textFieldDidChange(textField: UITextField) { 82 | if textField == emailTextField, let emailID = emailTextField.text { 83 | if !emailID.isValidEmail() { 84 | emailTextField.dividerActiveColor = .red 85 | } else { 86 | emailTextField.dividerActiveColor = .green 87 | } 88 | } else if textField == passwordTextField, let password = passwordTextField.text { 89 | if password.isEmpty || password.count < 5 { 90 | passwordTextField.dividerActiveColor = .red 91 | } else { 92 | passwordTextField.dividerActiveColor = .green 93 | } 94 | } 95 | } 96 | 97 | // force dismiss keyboard if open. 98 | @objc func dismissKeyboard() { 99 | view.endEditing(true) 100 | } 101 | 102 | // Toggle Editing 103 | func toggleEditing() { 104 | emailTextField.isEnabled = !emailTextField.isEnabled 105 | passwordTextField.isEnabled = !passwordTextField.isEnabled 106 | loginButton.isEnabled = !loginButton.isEnabled 107 | } 108 | 109 | // Clear field after login 110 | func clearFields() { 111 | passwordTextField.text = "" 112 | } 113 | 114 | // Validate fields 115 | func isValid() -> Bool { 116 | if let emailID = emailTextField.text, !emailID.isValidEmail() { 117 | return false 118 | } 119 | 120 | if let password = passwordTextField.text, password.isEmpty { 121 | return false 122 | } 123 | 124 | return true 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /FOSSAsia/LoginViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Material 3 | 4 | class LoginViewController: UIViewController, UITextFieldDelegate { 5 | 6 | @IBOutlet weak var emailTextField: TextField! 7 | @IBOutlet weak var passwordTextField: TextField! 8 | @IBOutlet weak var loginButton: RaisedButton! 9 | 10 | @IBOutlet weak var loginActivityIndicator: UIActivityIndicatorView! 11 | 12 | override func viewDidLoad() { 13 | super.viewDidLoad() 14 | addTapGesture() 15 | prepareUserNameField() 16 | preparePasswordField() 17 | prepareLoginButton() 18 | emailTextField.delegate = self 19 | passwordTextField.delegate = self 20 | } 21 | 22 | override func viewDidAppear(_ animated: Bool) { 23 | self.parent?.navigationItem.title = "Login" 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /FOSSAsia/MapViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by SIMRANPREET KAUR on 06/06/18. 6 | // Copyright © 2018 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import MapKit 11 | import CoreLocation 12 | 13 | class MapViewController: UIViewController { 14 | 15 | @IBOutlet weak var mapView: MKMapView! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | let locationCoordinates = CLLocationCoordinate2DMake(Constants.Location.lattitude, Constants.Location.longitude) 20 | let span = MKCoordinateSpanMake(Constants.Location.spanCoordinate, Constants.Location.spanCoordinate) 21 | let region = MKCoordinateRegionMake(locationCoordinates, span) 22 | mapView.setRegion(region, animated: true) 23 | let annotation = MKPointAnnotation() 24 | annotation.coordinate = locationCoordinates 25 | annotation.title = Constants.Location.annotationTitle 26 | mapView.addAnnotation(annotation) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /FOSSAsia/Microlocation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Microlocation.swift 3 | // FOSSAsia 4 | // 5 | // Created by Pratik Todi on 28/02/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Microlocation { 12 | let id: Int 13 | let name: String 14 | let latitude: Double 15 | let longitude: Double 16 | let floor: Int 17 | 18 | static func getNameOfMicrolocationId(_ id: Int, microlocations: [Microlocation]) -> String? { 19 | for microlocation in microlocations { 20 | if microlocation.id == id { 21 | return microlocation.name 22 | } 23 | } 24 | return nil 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FOSSAsia/MoreViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MoreViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 11/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SafariServices 11 | 12 | private struct DefaultURLs { 13 | static let fossasia2018 = "https://2018.fossasia.org/" 14 | static let fossaisaTwitter = "https://twitter.com/fossasia" 15 | static let fossasiaItune = "https://itunes.apple.com/us/app/fossasia/id1089164461?ls=1&mt=8" 16 | static let fossasiaGoogleGroups = "http://groups.google.com/group/fossasia" 17 | } 18 | 19 | class MoreViewController: UITableViewController { 20 | 21 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 22 | guard (indexPath as NSIndexPath).section == 0 else { 23 | return 24 | } 25 | 26 | switch (indexPath as NSIndexPath).row { 27 | case 0: 28 | self.present(self.createSVC(DefaultURLs.fossasia2018), animated: true, completion: nil) 29 | break 30 | case 1: 31 | self.present(self.createSVC(DefaultURLs.fossaisaTwitter), animated: true, completion: nil) 32 | break 33 | case 2: 34 | let alertController = UIAlertController(title: Constants.appStoreAlertTitle, message: Constants.appStoreAlertMessage, preferredStyle: .alert) 35 | let openAction = UIAlertAction(title: Constants.okTitle, style: .default, handler: { (action) -> Void in 36 | let itunesLink = DefaultURLs.fossasiaItune 37 | if let url = URL(string: itunesLink) { 38 | UIApplication.shared.open(url, options: [:], completionHandler: nil) 39 | } 40 | }) 41 | let cancelAction = UIAlertAction(title: Constants.cancelTitle, style: .cancel, handler: { (action) -> Void in 42 | // do nothing 43 | }) 44 | alertController.addAction(openAction) 45 | alertController.addAction(cancelAction) 46 | self.present(alertController, animated: true, completion: { () -> Void in 47 | 48 | }) 49 | 50 | break 51 | case 3: 52 | self.present(self.createSVC(DefaultURLs.fossasiaGoogleGroups), animated: true, completion: nil) 53 | break 54 | 55 | case 5: 56 | let activityViewController : UIActivityViewController = UIActivityViewController(activityItems: [Constants.MoreViewController.message], applicationActivities: nil) 57 | 58 | activityViewController.setValue(Constants.MoreViewController.subject, forKey: Constants.MoreViewController.Title) 59 | // For overcoming the crash in iPad 60 | activityViewController.popoverPresentationController?.sourceView = self.view 61 | 62 | activityViewController.excludedActivityTypes = [ 63 | UIActivityType.airDrop, 64 | UIActivityType.saveToCameraRoll, 65 | UIActivityType.openInIBooks, 66 | UIActivityType.copyToPasteboard ] 67 | self.present(activityViewController, animated: true, completion: nil) 68 | 69 | break 70 | default: 71 | break 72 | } 73 | } 74 | 75 | func createSVC(_ urlString: String) -> SFSafariViewController { 76 | return SFSafariViewController(url: URL(string: urlString)!) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FOSSAsia/Observable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Observable.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class Observable { 12 | typealias Observer = (T) -> Void 13 | var observer: Observer? 14 | 15 | func observe(_ observer: Observer?) { 16 | self.observer = observer 17 | observer?(value) 18 | } 19 | 20 | var value: T { 21 | didSet { 22 | observer?(value) 23 | } 24 | } 25 | 26 | init(_ v: T) { 27 | value = v 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FOSSAsia/ProfileViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class ProfileViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 4 | 5 | @IBOutlet weak var profileImageView: UIImageView! 6 | var imagePicker: UIImagePickerController! 7 | 8 | @IBOutlet weak var userName: UILabel! 9 | 10 | override func viewDidLoad() { 11 | super.viewDidLoad() 12 | setImageView() 13 | addTapGesture() 14 | setUserName() 15 | setBackButton() 16 | 17 | 18 | // Do any additional setup after loading the view. 19 | 20 | } 21 | 22 | func addTapGesture() { 23 | let tap = UITapGestureRecognizer(target: self, action: #selector(tapAvatar)) 24 | profileImageView.addGestureRecognizer(tap) 25 | profileImageView.isUserInteractionEnabled = true 26 | } 27 | 28 | 29 | 30 | @IBAction func logOutPressed(_ sender: Any) { 31 | let alert = UIAlertController(title: Constants.alertMessage.logoutMessageTitle, message: Constants.alertMessage.logoutMessage, preferredStyle: .alert) 32 | 33 | alert.addAction(UIAlertAction(title: Constants.alertMessage.yesTitle, style: .default, handler: { action in 34 | UserDefaults.standard.set(nil, forKey: Constants.UserDefaultsKey.acessToken) 35 | UserDefaults.standard.set(nil, forKey: Constants.UserDefaultsKey.firstName) 36 | UserDefaults.standard.set(nil, forKey: Constants.UserDefaultsKey.lastName) 37 | self.userName.text = "" 38 | let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main) 39 | guard let vc: UITabBarController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarController") as? UITabBarController else { 40 | fatalError("Cannot Cast to UITabBarController") 41 | } 42 | vc.selectedIndex = 0 43 | self.present(vc, animated: true, completion: nil) 44 | })) 45 | 46 | alert.addAction(UIAlertAction(title: Constants.alertMessage.noTitle, style: .cancel, handler: { action in 47 | self.dismiss(animated: true, completion: nil) 48 | })) 49 | 50 | self.present(alert, animated: true) 51 | 52 | } 53 | 54 | 55 | 56 | @objc func tapAvatar() { 57 | let imagePickerController = UIImagePickerController() 58 | 59 | // Only allow photos to be picked, not taken. 60 | imagePickerController.sourceType = .photoLibrary 61 | 62 | // Make sure ViewController is notified when the user picks an image. 63 | imagePickerController.delegate = self 64 | present(imagePickerController, animated: true, completion: nil) 65 | } 66 | 67 | func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 68 | // Dismiss the picker if the user canceled. 69 | dismiss(animated: true, completion: nil) 70 | } 71 | 72 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) { 73 | 74 | // The info dictionary may contain multiple representations of the image. You want to use the original. 75 | guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { 76 | fatalError("Expected a dictionary containing an image, but was provided the following: \(info)") 77 | } 78 | 79 | // Set photoImageView to display the selected image. 80 | profileImageView.image = selectedImage 81 | 82 | // Dismiss the picker. 83 | dismiss(animated: true, completion: nil) 84 | } 85 | 86 | func setUserName() { 87 | if UserDefaults.exists(key: Constants.UserDefaultsKey.firstName) { 88 | userName.text = UserDefaults.standard.string(forKey: Constants.UserDefaultsKey.firstName) 89 | } 90 | } 91 | 92 | func setImageView() { 93 | profileImageView.layer.borderWidth = 1.0 94 | profileImageView.layer.masksToBounds = false 95 | profileImageView.layer.borderColor = UIColor.white.cgColor 96 | profileImageView.layer.cornerRadius = profileImageView.frame.size.width / 2 97 | profileImageView.clipsToBounds = true 98 | } 99 | 100 | func setBackButton() { 101 | let button = UIButton(type: .custom) 102 | button.setImage(UIImage(named: "back"), for: .normal) 103 | button.addTarget(self, action: #selector(AuthTabBarViewController.backAction), for: .touchUpInside) 104 | button.frame = CGRect(x: 0, y: 0, width: 53, height: 31) 105 | button.imageEdgeInsets = UIEdgeInsetsMake(1, -32, 1, 32) 106 | let label = UILabel(frame: CGRect(x: 3, y: 5, width: 50, height: 20)) 107 | label.text = "Back" 108 | label.textAlignment = .center 109 | label.textColor = UIColor.white 110 | label.backgroundColor = UIColor.clear 111 | button.addSubview(label) 112 | let barButton = UIBarButtonItem(customView: button) 113 | self.navigationItem.leftBarButtonItem = barButton 114 | } 115 | 116 | 117 | @objc func backAction() { 118 | 119 | let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main) 120 | guard let vc: UITabBarController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarController") as? UITabBarController else { 121 | fatalError("Cannot Cast to UITabBarController") 122 | } 123 | vc.selectedIndex = 0 124 | self.present(vc, animated: true, completion: nil) 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /FOSSAsia/RangeExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RangeExtension.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 5/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Sequence { 12 | func toArray() -> [Iterator.Element] { 13 | 14 | return Array(self) 15 | } 16 | } 17 | 18 | extension String { 19 | 20 | func isValidEmail() -> Bool { 21 | let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,20}" 22 | let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegEx) 23 | return emailTest.evaluate(with: self) 24 | } 25 | 26 | } 27 | 28 | extension UserDefaults { 29 | 30 | static func exists(key: String) -> Bool { 31 | return UserDefaults.standard.object(forKey: key) != nil 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /FOSSAsia/Schedule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Schedule.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 1/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Schedule { 12 | let date: Date 13 | let events: [Event] 14 | } 15 | -------------------------------------------------------------------------------- /FOSSAsia/ScheduleBrowsingProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScheduleBrowsingProtocol.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 13/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import MGSwipeTableCell 11 | import DZNEmptyDataSet 12 | 13 | typealias SwipeToFavoriteCellPresentable = MGSwipeTableCellDelegate & CellsFavoritable 14 | typealias TableViewRefreshable = ScheduleRefreshable & ScheduleViewModelDelegate 15 | 16 | protocol CellsFavoritable { 17 | func favoriteEvent(_ indexPath: IndexPath) 18 | } 19 | 20 | protocol ScheduleRefreshable { 21 | func refreshData(_ sender: AnyObject) 22 | } 23 | -------------------------------------------------------------------------------- /FOSSAsia/SchedulePagingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SchedulePagingView.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 11/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SchedulePagingView: UIView { 12 | 13 | weak var delegate: SchedulePagingViewDelegate? 14 | 15 | @IBOutlet weak var prevButton: UIButton! 16 | @IBOutlet weak var nextButton: UIButton! 17 | @IBOutlet weak var dateLabel: UILabel! 18 | 19 | @IBAction func prevButtonPressed(_ sender: AnyObject) { 20 | delegate?.prevButtonDidPress(self) 21 | } 22 | 23 | @IBAction func nextButtonPressed(_ sender: AnyObject) { 24 | delegate?.nextButtonDidPress(self) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FOSSAsia/ScheduleViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MGSwipeTableCell 11 | 12 | class ScheduleViewController: EventsBaseViewController, SwipeToFavoriteCellPresentable, TableViewRefreshable { 13 | var refreshControl : UIRefreshControl! 14 | 15 | // Constants for Storyboard/VC 16 | struct StoryboardConstants { 17 | static let storyboardName = "ScheduleVC" 18 | static let viewControllerId = String(describing: ScheduleViewController.self) 19 | } 20 | 21 | lazy var filteredEvents: [EventViewModel] = self.allEvents 22 | var filterString: String? = nil { 23 | didSet { 24 | if filterString == nil || filterString!.isEmpty { 25 | filteredEvents = self.allEvents 26 | } else { 27 | let filterPredicate = NSPredicate(format: "self contains[c] %@", argumentArray: [filterString!]) 28 | filteredEvents = allEvents.filter({filterPredicate.evaluate(with: $0.eventName) }) 29 | } 30 | } 31 | } 32 | 33 | override func viewDidLoad() { 34 | super.viewDidLoad() 35 | 36 | viewModel?.delegate = self 37 | DispatchQueue.main.async { 38 | self.refreshControl = UIRefreshControl() 39 | self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh") 40 | self.refreshControl.addTarget(self, action: #selector(ScheduleViewController.refreshData(_:)), for: .valueChanged) 41 | self.tableView.addSubview(self.refreshControl) 42 | } 43 | } 44 | 45 | class func scheduleViewControllerFor(_ schedule: ScheduleViewModel) -> ScheduleViewController { 46 | let storyboard = UIStoryboard(name: ScheduleViewController.StoryboardConstants.storyboardName, bundle: nil) 47 | 48 | let viewController = storyboard.instantiateViewController(withIdentifier: ScheduleViewController.StoryboardConstants.viewControllerId) as! ScheduleViewController 49 | viewController.viewModel = schedule 50 | 51 | return viewController 52 | } 53 | 54 | @objc func refreshData(_ sender: AnyObject) { 55 | viewModel?.refresh() 56 | } 57 | } 58 | 59 | extension ScheduleViewController: UISearchResultsUpdating { 60 | func updateSearchResults(for searchController: UISearchController) { 61 | guard searchController.isActive else { 62 | return 63 | } 64 | filterString = searchController.searchBar.text 65 | } 66 | } 67 | 68 | extension ScheduleViewController { 69 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 70 | let cell = tableView.dequeueReusableCell(withIdentifier: EventsBaseViewController.kEventCellReuseIdentifier, for: indexPath) as! EventCell 71 | let eventViewModel = allEvents[(indexPath as NSIndexPath).row] 72 | cell.configure(withPresenter: eventViewModel) 73 | cell.delegate = self 74 | 75 | return cell 76 | } 77 | } 78 | 79 | // MARK: - SwipeToFavoriteCellPresentable Conformance 80 | extension ScheduleViewController { 81 | func favoriteEvent(_ indexPath: IndexPath) { 82 | weak var me = self 83 | let eventViewModel = me!.eventViewModelForIndexPath(indexPath) 84 | eventViewModel.favoriteEvent { (eventViewModel, error) -> Void in 85 | if error == nil { 86 | self.tableView.reloadData() 87 | } 88 | } 89 | } 90 | 91 | func swipeTableCell(_ cell: MGSwipeTableCell!, swipeButtonsFor direction: MGSwipeDirection, swipeSettings: MGSwipeSettings!, expansionSettings: MGSwipeExpansionSettings!) -> [AnyObject]! { 92 | swipeSettings.transition = .border 93 | expansionSettings.buttonIndex = 0 94 | 95 | weak var me = self 96 | let eventViewModel = me!.eventViewModelForIndexPath(me!.tableView.indexPath(for: cell)!) 97 | 98 | if direction == .leftToRight { 99 | expansionSettings.fillOnTrigger = false 100 | expansionSettings.threshold = 2 101 | 102 | let faveButton = MGSwipeButton(title: "", icon: (eventViewModel.isFavorite ? UIImage(named: "cell_favorite_selected") : UIImage(named: "cell_favorite")), backgroundColor: Colors.favoriteOrangeColor!) { (sender: MGSwipeTableCell!) -> Bool in 103 | if let sessionCell = sender as? EventCell { 104 | UIView.animate(withDuration: 0.3, animations: { () -> Void in 105 | if (eventViewModel.isFavorite) { 106 | sessionCell.favoriteImage.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) 107 | sessionCell.favoriteImage.alpha = 0.0 108 | } else { 109 | sessionCell.favoriteImage.transform = CGAffineTransform.identity 110 | sessionCell.favoriteImage.alpha = 1.0 111 | } 112 | }, completion: { (done) -> Void in 113 | if done { 114 | self.favoriteEvent(me!.tableView.indexPath(for: cell)!) 115 | } 116 | }) 117 | } 118 | return true 119 | } 120 | 121 | faveButton.setPadding(CGFloat(20)) 122 | cell.leftButtons = [faveButton] 123 | 124 | return [faveButton] 125 | } 126 | return nil 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /FOSSAsia/ScheduleViewControllerDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScheduleViewControllerDelegate.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 27/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ScheduleViewControllerDelegate: class { 12 | func eventDidGetSelected(_ tableView: UITableView, atIndexPath: IndexPath) 13 | } 14 | -------------------------------------------------------------------------------- /FOSSAsia/ScheduleViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScheduleViewModel.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 1/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ScheduleCountPresentable { 12 | var count: Int {get} 13 | } 14 | 15 | struct ScheduleViewModel: ScheduleCountPresentable { 16 | weak var delegate: ScheduleViewModelDelegate? 17 | // MARK: - Properties 18 | let date: Observable 19 | let events: Observable<[EventViewModel]> 20 | 21 | let isFavoritesOnly: Observable 22 | 23 | // MARK: - Errors 24 | let hasError: Observable 25 | let errorMessage: Observable 26 | 27 | // MARK: - Services 28 | fileprivate var eventsService: EventProvider 29 | 30 | init (_ date: Date, favoritesOnly: Bool = false) { 31 | hasError = Observable(false) 32 | errorMessage = Observable(nil) 33 | 34 | self.date = Observable(date) 35 | self.events = Observable([]) 36 | self.isFavoritesOnly = Observable(favoritesOnly) 37 | 38 | // Dependency Injections 39 | eventsService = EventProvider() 40 | self.refresh() 41 | } 42 | 43 | func refresh() { 44 | if let filteredTracks = UserDefaults.standard.object(forKey: Constants.UserDefaultsKey.FilteredTrackIds) as? [Int] { 45 | eventsService.getEvents(date.value, trackIds: filteredTracks) { (events, error) -> Void in 46 | guard let unwrappedEvents = events else { 47 | self.delegate?.scheduleDidLoad(nil, error: error) 48 | return 49 | } 50 | 51 | var eventsArray: [Event] = unwrappedEvents 52 | if self.isFavoritesOnly.value { 53 | eventsArray = eventsArray.filter({ $0.favorite }) 54 | } 55 | 56 | self.update(Schedule(date: self.date.value, events: eventsArray)) 57 | } 58 | } 59 | } 60 | 61 | fileprivate func update(_ schedule: Schedule) { 62 | let tempEvents = schedule.events.map { event in 63 | return EventViewModel(event) 64 | } 65 | events.value = tempEvents 66 | self.delegate?.scheduleDidLoad(schedule, error: nil) 67 | } 68 | 69 | fileprivate func update(_ error: Error) { 70 | hasError.value = true 71 | 72 | switch error.errorCode { 73 | case .urlError: 74 | errorMessage.value = "The events service is not working." 75 | case .networkRequestFailed: 76 | errorMessage.value = "The network appears to be down." 77 | case .jsonSerializationFailed: 78 | errorMessage.value = "We're having trouble processing events data." 79 | case .jsonParsingFailed: 80 | errorMessage.value = "We're having trouble parsing events data." 81 | case .jsonSystemReadingFailed: 82 | errorMessage.value = "There seems to be a problem with reading data from disk." 83 | case .writingOnDiskFailed: 84 | errorMessage.value = "There seems to be a problem with writing data on disk." 85 | } 86 | 87 | self.events.value = [] 88 | } 89 | 90 | } 91 | 92 | // MARK :- ScheduleCountPresentableConformance 93 | extension ScheduleViewModel { 94 | var count: Int { return self.events.value.count } 95 | } 96 | -------------------------------------------------------------------------------- /FOSSAsia/ScheduleViewModelDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScheduleViewModelDelegate.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 5/3/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ScheduleViewModelDelegate: class { 12 | func scheduleDidLoad(_ schedule: Schedule?, error: Error?) 13 | } 14 | 15 | extension ScheduleViewController { 16 | func scheduleDidLoad(_ schedule: Schedule?, error: Error?) { 17 | guard error == nil else { 18 | let alert = UIAlertController(title: "Error", message: "Could not load stock quotes \(error.debugDescription)", preferredStyle: UIAlertControllerStyle.alert) 19 | alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil)) 20 | self.present(alert, animated: true, completion: nil) 21 | return 22 | } 23 | 24 | let now = Date() 25 | let updateString = "Last updated: " + (now as NSDate).formattedDate(withFormat: "dd MMMM yyyy, HH:mm:ss", locale: Locale.autoupdatingCurrent) 26 | self.refreshControl.attributedTitle = NSAttributedString(string: updateString) 27 | if self.refreshControl.isRefreshing { 28 | DispatchQueue.main.async { 29 | self.refreshControl.endRefreshing() 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /FOSSAsia/SettingsManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsManager.swift 3 | // FOSSAsia 4 | // 5 | // Created by Pratik Todi on 27/02/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct SettingsManager { 12 | 13 | static let keyForEvent = Constants.SettingsManager.keyForEvent 14 | static let keyForMicrolocations = Constants.SettingsManager.keyForMicrolocations 15 | 16 | static let favouritesLocalFileName = Constants.SettingsManager.favesJSON 17 | 18 | static func isKeyPresentInUserDefaults(_ key: String) -> Bool { 19 | let defaults = UserDefaults.standard 20 | return defaults.bool(forKey: key) 21 | } 22 | 23 | static func saveKeyInUserDefaults(_ key: String, bool: Bool) { 24 | let defaults = UserDefaults.standard 25 | defaults.set(bool, forKey: key) 26 | } 27 | 28 | static func getLocalFileName(_ eventInfo: EventInfo) -> String { 29 | return eventInfo.rawValue + Constants.jsonFileExtension 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /FOSSAsia/SignupViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Material 3 | class SignUpViewController: UIViewController, UITextFieldDelegate { 4 | 5 | @IBOutlet weak var passwordTextField: TextField! 6 | @IBOutlet weak var confirmPasswordTextField: TextField! 7 | @IBOutlet weak var firstNameTextField: TextField! 8 | 9 | @IBOutlet weak var emailTextField: TextField! 10 | 11 | @IBOutlet weak var lastNameTextField: TextField! 12 | 13 | @IBOutlet weak var signUpButton: RaisedButton! 14 | 15 | 16 | @IBOutlet weak var signupActivityIndicator: UIActivityIndicatorView! 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | addTapGesture() 21 | prepareFields() 22 | prepareSignUpButton() 23 | passwordTextField.delegate = self 24 | confirmPasswordTextField.delegate = self 25 | firstNameTextField.delegate = self 26 | lastNameTextField.delegate = self 27 | emailTextField.delegate = self 28 | } 29 | 30 | override func viewDidAppear(_ animated: Bool) { 31 | self.parent?.navigationItem.title = "Signup" 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /FOSSAsia/Speaker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Speaker.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Speaker { 12 | let name: String 13 | 14 | } 15 | -------------------------------------------------------------------------------- /FOSSAsia/SpeakerViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpeakerViewModel.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 29/1/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct SpeakerViewModel { 12 | let name: Observable 13 | 14 | init(_ speaker: Speaker) { 15 | name = Observable(speaker.name) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /FOSSAsia/SwiftHEXColors.swift: -------------------------------------------------------------------------------- 1 | // SwiftHEXColors.swift 2 | // 3 | // Copyright (c) 2014 Doan Truong Thi 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #if os(iOS) 24 | import UIKit 25 | typealias SWColor = UIColor 26 | #else 27 | import Cocoa 28 | typealias SWColor = NSColor 29 | #endif 30 | 31 | /// An extension of UIColor (on iOS) or NSColor (on OSX) providing HEX color handling. 32 | public extension SWColor { 33 | /** 34 | Create non-autoreleased color with in the given hex string. Alpha will be set as 1 by default. 35 | - parameter hexString: The hex string, with or without the hash character. 36 | - returns: A color with the given hex string. 37 | */ 38 | public convenience init?(hexString: String) { 39 | self.init(hexString: hexString, alpha: 1.0) 40 | } 41 | 42 | /** 43 | Create non-autoreleased color with in the given hex string and alpha. 44 | - parameter hexString: The hex string, with or without the hash character. 45 | - parameter alpha: The alpha value, a floating value between 0 and 1. 46 | - returns: A color with the given hex string and alpha. 47 | */ 48 | public convenience init?(hexString: String, alpha: Float) { 49 | var hex = hexString 50 | 51 | // Check for hash and remove the hash 52 | if hex.hasPrefix("#") { 53 | let hexRange = hex.index(hex.startIndex, offsetBy: 1) 54 | hex = String(hex[hexRange]) 55 | } 56 | 57 | if (hex.range(of: "(^[0-9A-Fa-f]{6}$)|(^[0-9A-Fa-f]{3}$)", options: .regularExpression) != nil) { 58 | 59 | // Deal with 3 character Hex strings - Swift 4 method 60 | if hex.count == 3 { 61 | let redHex = String(hex[...hex.index(hex.startIndex, offsetBy: 1)]) 62 | let greenHex = String(hex[hex.index(hex.startIndex, offsetBy: 1) ..< hex.index(hex.startIndex, offsetBy: 2)]) 63 | let blueHex = String(hex[hex.index(hex.startIndex, offsetBy: 2)...]) 64 | 65 | hex = redHex + redHex + greenHex + greenHex + blueHex + blueHex 66 | } 67 | 68 | let redHex = String(hex[...hex.index(hex.startIndex, offsetBy: 2)]) 69 | let greenHex = String(hex[hex.index(hex.startIndex, offsetBy: 2) ..< hex.index(hex.startIndex, offsetBy: 4)]) 70 | let blueHex = String(hex[hex.index(hex.startIndex, offsetBy: 4) ..< hex.index(hex.startIndex, offsetBy: 6)]) 71 | 72 | var redInt: CUnsignedInt = 0 73 | var greenInt: CUnsignedInt = 0 74 | var blueInt: CUnsignedInt = 0 75 | 76 | Scanner(string: redHex).scanHexInt32(&redInt) 77 | Scanner(string: greenHex).scanHexInt32(&greenInt) 78 | Scanner(string: blueHex).scanHexInt32(&blueInt) 79 | 80 | self.init(red: CGFloat(redInt) / 255.0, green: CGFloat(greenInt) / 255.0, blue: CGFloat(blueInt) / 255.0, alpha: CGFloat(alpha)) 81 | } else { 82 | // Note: 83 | // The swift 1.1 compiler is currently unable to destroy partially initialized classes in all cases, 84 | // so it disallows formation of a situation where it would have to. We consider this a bug to be fixed 85 | // in future releases, not a feature. -- Apple Forum 86 | self.init() 87 | return nil 88 | } 89 | } 90 | 91 | /** 92 | Create non-autoreleased color with in the given hex value. Alpha will be set as 1 by default. 93 | - parameter hex: The hex value. For example: 0xff8942 (no quotation). 94 | - returns: A color with the given hex value 95 | */ 96 | public convenience init?(hex: Int) { 97 | self.init(hex: hex, alpha: 1.0) 98 | } 99 | 100 | /** 101 | Create non-autoreleased color with in the given hex value and alpha 102 | - parameter hex: The hex value. For example: 0xff8942 (no quotation). 103 | - parameter alpha: The alpha value, a floating value between 0 and 1. 104 | - returns: color with the given hex value and alpha 105 | */ 106 | public convenience init?(hex: Int, alpha: Float) { 107 | var hexString = String(format: "%2X", hex) 108 | let leadingZerosString = String(repeating: "0", count: 6 - hexString.count) 109 | hexString = leadingZerosString + hexString 110 | self.init(hexString: hexString as String, alpha: alpha) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /FOSSAsia/TrackViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TrackViewModel.swift 3 | // FOSSAsia 4 | // 5 | // Created by Jurvis Tan on 5/2/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol TrackDetailsPresentable { 12 | var trackId: Int {get} 13 | var trackName: String {get} 14 | } 15 | 16 | protocol TrackStatusPresentable { 17 | var isTrackOn: Bool {get} 18 | func changeFilterPreference(_ status: Bool) 19 | } 20 | 21 | protocol TrackColorPresentable { 22 | var trackColor: UIColor {get} 23 | } 24 | 25 | struct TrackViewModel: TrackDetailsPresentable, TrackStatusPresentable, TrackColorPresentable { 26 | 27 | // MARK: - Properties 28 | let isOn: Observable 29 | let id: Observable 30 | let name: Observable 31 | 32 | init(_ track: Event.Track) { 33 | self.id = Observable(track.rawValue) 34 | self.name = Observable(track.description) 35 | if let filteredTrackIds = UserDefaults.standard.object(forKey: Constants.UserDefaultsKey.FilteredTrackIds) as? [Int] { 36 | self.isOn = Observable(filteredTrackIds.contains(track.rawValue)) 37 | } else { 38 | self.isOn = Observable(true) 39 | } 40 | } 41 | 42 | fileprivate func update(_ status: Bool) { 43 | if var filteredTracksDefaults = UserDefaults.standard.object(forKey: Constants.UserDefaultsKey.FilteredTrackIds) as? [Int] { 44 | if status { 45 | filteredTracksDefaults.append(self.id.value) 46 | } else { 47 | guard filteredTracksDefaults.contains(self.id.value) else { 48 | return 49 | } 50 | filteredTracksDefaults = filteredTracksDefaults.filter({ $0 != self.id.value}) 51 | } 52 | UserDefaults.standard.set(filteredTracksDefaults, forKey: Constants.UserDefaultsKey.FilteredTrackIds) 53 | 54 | } 55 | } 56 | 57 | } 58 | 59 | // MARK: - TrackDetailsPresentable Conformane 60 | extension TrackViewModel { 61 | var trackId: Int { return self.id.value } 62 | var trackName: String { return self.name.value } 63 | } 64 | 65 | // MARK: - TrackStatusPresentable 66 | extension TrackViewModel { 67 | var isTrackOn: Bool { return self.isOn.value } 68 | func changeFilterPreference(_ status: Bool) { 69 | self.update(status) 70 | } 71 | } 72 | 73 | // MARK: - TrackColorPresentable 74 | extension TrackViewModel { 75 | var trackColor: UIColor { 76 | if let dummyEvent = Event.Track(rawValue: self.id.value) { 77 | return dummyEvent.getTrackColor() 78 | } else { 79 | return UIColor.white 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /FOSSAsiaUITests/FOSSAsiaUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FOSSAsiaUITests.swift 3 | // FOSSAsiaUITests 4 | // 5 | // Created by Jurvis Tan on 6/3/16. 6 | // Copyright © 2016 FossAsia. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FOSSAsiaUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | continueAfterFailure = false 17 | let app = XCUIApplication() 18 | setupSnapshot(app) 19 | app.launch() 20 | } 21 | 22 | override func tearDown() { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | super.tearDown() 25 | } 26 | 27 | func testExample() { 28 | // Use recording to get started writing UI tests. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | 31 | let app = XCUIApplication() 32 | 33 | snapshot("0Launch") 34 | snapshot("1Event") 35 | snapshot("2AddToCalendar") 36 | 37 | let tabBarsQuery = app.tabBars 38 | tabBarsQuery.children(matching: .button).element(boundBy: 1).tap() 39 | snapshot("3Favorites") 40 | tabBarsQuery.children(matching: .button).element(boundBy: 2).tap() 41 | snapshot("4More") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /FOSSAsiaUITests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 91 23 | NSPhotoLibraryAddUsageDescription 24 | Add Avatar 25 | 26 | 27 | -------------------------------------------------------------------------------- /FOSSAsiaUITests/SnapshotHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapshotHelper.swift 3 | // Example 4 | // 5 | // Created by Felix Krause on 10/8/15. 6 | // Copyright © 2015 Felix Krause. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | 12 | var deviceLanguage = "" 13 | var locale = "" 14 | 15 | @available(*, deprecated, message: "use setupSnapshot: instead") 16 | func setLanguage(_ app: XCUIApplication) { 17 | setupSnapshot(app) 18 | } 19 | 20 | func setupSnapshot(_ app: XCUIApplication) { 21 | Snapshot.setupSnapshot(app) 22 | } 23 | 24 | func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) { 25 | Snapshot.snapshot(name, waitForLoadingIndicator: waitForLoadingIndicator) 26 | } 27 | 28 | class Snapshot: NSObject { 29 | 30 | class func setupSnapshot(_ app: XCUIApplication) { 31 | setLanguage(app) 32 | setLocale(app) 33 | setLaunchArguments(app) 34 | } 35 | 36 | class func setLanguage(_ app: XCUIApplication) { 37 | guard let prefix = pathPrefix() else { 38 | return 39 | } 40 | 41 | let path = prefix.appendingPathComponent("language.txt") 42 | 43 | do { 44 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines 45 | deviceLanguage = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String 46 | app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"] 47 | } catch { 48 | print("Couldn't detect/set language...") 49 | } 50 | } 51 | 52 | class func setLocale(_ app: XCUIApplication) { 53 | guard let prefix = pathPrefix() else { 54 | return 55 | } 56 | 57 | let path = prefix.appendingPathComponent("locale.txt") 58 | 59 | do { 60 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines 61 | locale = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String 62 | } catch { 63 | print("Couldn't detect/set locale...") 64 | } 65 | if locale.isEmpty { 66 | locale = Locale(identifier: deviceLanguage).identifier 67 | } 68 | app.launchArguments += ["-AppleLocale", "\"\(locale)\""] 69 | } 70 | 71 | class func setLaunchArguments(_ app: XCUIApplication) { 72 | guard let prefix = pathPrefix() else { 73 | return 74 | } 75 | 76 | let path = prefix.appendingPathComponent("snapshot-launch_arguments.txt") 77 | app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"] 78 | 79 | do { 80 | let launchArguments = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String 81 | let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: []) 82 | let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location: 0, length: launchArguments.count)) 83 | let results = matches.map { result -> String in 84 | (launchArguments as NSString).substring(with: result.range) 85 | } 86 | app.launchArguments += results 87 | } catch { 88 | print("Couldn't detect/set launch_arguments...") 89 | } 90 | } 91 | 92 | class func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) { 93 | if waitForLoadingIndicator { 94 | waitForLoadingIndicatorToDisappear() 95 | } 96 | 97 | print("snapshot: \(name)") // more information about this, check out https://github.com/fastlane/snapshot 98 | 99 | sleep(1) // Waiting for the animation to be finished (kind of) 100 | XCUIDevice.shared.orientation = .unknown 101 | } 102 | 103 | class func waitForLoadingIndicatorToDisappear() { 104 | let query = XCUIApplication().statusBars.children(matching: .other).element(boundBy: 1).children(matching: .other) 105 | 106 | while (0.. NSString? { 113 | if let path = ProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? { 114 | return path.appendingPathComponent("Library/Caches/tools.fastlane") as NSString? 115 | } 116 | print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane") 117 | return nil 118 | } 119 | } 120 | 121 | extension XCUIElement { 122 | var isLoadingIndicator: Bool { 123 | return self.frame.size == CGSize(width: 10, height: 20) 124 | } 125 | } 126 | 127 | // Please don't remove the lines below 128 | // They are used to detect outdated configuration files 129 | // SnapshotHelperVersion [1.2] 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 FOSSASIA 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | Status API Training Shop Blog About Pricing 24 | 25 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '8.0' 2 | use_frameworks! 3 | 4 | target 'FOSSAsia' do 5 | 6 | pod 'Material' 7 | pod 'Pages' 8 | pod 'Toast-Swift', '~> 3.0.0' 9 | pod 'SwiftyJSON', :git => 'https://github.com/SwiftyJSON/SwiftyJSON.git' 10 | pod 'Alamofire', '~> 4.7' 11 | pod 'DateTools', :git => 'https://github.com/MatthewYork/DateTools.git' 12 | pod 'MGSwipeTableCell', :git => 'https://github.com/MortimerGoro/MGSwipeTableCell.git' 13 | pod 'DZNEmptyDataSet', :git => 'https://github.com/dzenbot/DZNEmptyDataSet.git' 14 | pod 'SwiftValidators' 15 | pod 'IQKeyboardManagerSwift', '5.0.0' 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (4.9.1) 3 | - DateTools (2.0.0) 4 | - DZNEmptyDataSet (1.8.1) 5 | - IQKeyboardManagerSwift (5.0.0) 6 | - Material (3.1.8): 7 | - Material/Core (= 3.1.8) 8 | - Material/Core (3.1.8): 9 | - Motion (~> 3.1.1) 10 | - MGSwipeTableCell (1.6.11) 11 | - Motion (3.1.3): 12 | - Motion/Core (= 3.1.3) 13 | - Motion/Core (3.1.3) 14 | - Pages (2.0.2) 15 | - SwiftValidators (5.0.0) 16 | - SwiftyJSON (5.0.0) 17 | - Toast-Swift (3.0.1) 18 | 19 | DEPENDENCIES: 20 | - Alamofire (~> 4.7) 21 | - DateTools (from `https://github.com/MatthewYork/DateTools.git`) 22 | - DZNEmptyDataSet (from `https://github.com/dzenbot/DZNEmptyDataSet.git`) 23 | - IQKeyboardManagerSwift (= 5.0.0) 24 | - Material 25 | - MGSwipeTableCell (from `https://github.com/MortimerGoro/MGSwipeTableCell.git`) 26 | - Pages 27 | - SwiftValidators 28 | - SwiftyJSON (from `https://github.com/SwiftyJSON/SwiftyJSON.git`) 29 | - Toast-Swift (~> 3.0.0) 30 | 31 | SPEC REPOS: 32 | trunk: 33 | - Alamofire 34 | - IQKeyboardManagerSwift 35 | - Material 36 | - Motion 37 | - Pages 38 | - SwiftValidators 39 | - Toast-Swift 40 | 41 | EXTERNAL SOURCES: 42 | DateTools: 43 | :git: https://github.com/MatthewYork/DateTools.git 44 | DZNEmptyDataSet: 45 | :git: https://github.com/dzenbot/DZNEmptyDataSet.git 46 | MGSwipeTableCell: 47 | :git: https://github.com/MortimerGoro/MGSwipeTableCell.git 48 | SwiftyJSON: 49 | :git: https://github.com/SwiftyJSON/SwiftyJSON.git 50 | 51 | CHECKOUT OPTIONS: 52 | DateTools: 53 | :commit: 76ba8bafccb0b28d9af74a8f525a74b5276ed693 54 | :git: https://github.com/MatthewYork/DateTools.git 55 | DZNEmptyDataSet: 56 | :commit: 8deb3fe69f75c5022a53a903468b29552dc70e66 57 | :git: https://github.com/dzenbot/DZNEmptyDataSet.git 58 | MGSwipeTableCell: 59 | :commit: 887696bce561d19497f5419123bdb350fd1202ab 60 | :git: https://github.com/MortimerGoro/MGSwipeTableCell.git 61 | SwiftyJSON: 62 | :commit: bad5f2f94a71216a32c030a3586bdcfc1f7e660b 63 | :git: https://github.com/SwiftyJSON/SwiftyJSON.git 64 | 65 | SPEC CHECKSUMS: 66 | Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 67 | DateTools: 933ac9c490f21f92127cf690ccd8c397e0126caf 68 | DZNEmptyDataSet: b94434220f87d9dda46660eb4f07a424778e93b4 69 | IQKeyboardManagerSwift: 3f340202ebe1a7076279b9b9b3c817243ddb3aab 70 | Material: a2a3f400a3b549d53ef89e56c58c4535b29db387 71 | MGSwipeTableCell: b804e4e450dee439c42250be90bd50458bf67fce 72 | Motion: cf1e060e489f6661126374d5c60dbd2ed991605c 73 | Pages: 5564ac6035c48fef7a837049314f57507d263b11 74 | SwiftValidators: 81db772ba2798fd4140ed57bfd7b80ab1ab42e93 75 | SwiftyJSON: f0574c07d8ca1644050db687067209e3033a89a0 76 | Toast-Swift: ba0b01b095aada709d915f9beb1d38184a2721c3 77 | 78 | PODFILE CHECKSUM: 661d447f3ad9e389af5d92f0b5150e7060e8ca05 79 | 80 | COCOAPODS: 1.8.4 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | | **CircleCI** | **Code Quality** | **Chat** | 2 | |--------------|------------------|----------| 3 | | [![CircleCI](https://circleci.com/gh/fossasia/open-event-ios.svg?style=svg)](https://circleci.com/gh/fossasia/open-event-ios) | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/4faa165463a44fffbd23f319d78a26ea)](https://www.codacy.com/app/mb/open-event-ios?utm_source=github.com&utm_medium=referral&utm_content=fossasia/open-event-ios&utm_campaign=badger) | [![Join the chat at gitter](https://badges.gitter.im/fossasia/https://github.com/fossasia/open-event-ios.svg)](https://gitter.im/fossasia/https://github.com/fossasia/open-event-ios?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | 4 | # Open Event iOS 5 | **iOS** app for **Open Event** 6 | ![Open Event](https://storage.googleapis.com/eventyay.com/assets/branding/base_branding.png) 7 | 8 | ## Introduction 9 | > This is an iOS app developed for `FOSSASIA` in mind. The Open Event Project offers event managers a platform to organize all kinds of events including concerts, conferences, summits and regular meetups. 10 | 11 | ## Roadmap 12 | 13 | Make the app functionality and UI/UX similar to the android app for Open Event. 14 | 15 | ## Communication 16 | 17 | **Please join our mailing list to discuss questions regarding the project :-** 18 | 19 | > *https://groups.google.com/forum/#!forum/open-event* 20 | 21 | **Our chat channel is here :-** 22 | 23 | > *https://gitter.im/fossasia/open-event-ios* 24 | 25 | ## Things To Have 26 | 1. **[Xcode](https://developer.apple.com/xcode/)** 27 | 2. **[CocoaPods](http://cocoapods.org/)** 28 | 29 | ### Libraries used and their documentation 30 | 31 | - Material [Docs](https://cocoapods.org/pods/Material) 32 | - Pages [Docs](https://github.com/hyperoslo/Pages) 33 | - Toast-Swift [Docs](https://github.com/scalessec/Toast-Swift) 34 | - SwiftyJSON [Docs](https://github.com/SwiftyJSON/SwiftyJSON) 35 | - Alamofire [Docs](https://github.com/Alamofire/Alamofire) 36 | - DateTools [Docs](https://github.com/MatthewYork/DateTools) 37 | - MGSwipeTableCell [Docs](https://github.com/MortimerGoro/MGSwipeTableCell) 38 | - DZNEmptyDataSet [Docs](https://github.com/dzenbot/DZNEmptyDataSet) 39 | - SwiftValidators [Docs](https://github.com/SwiftValidatorCommunity/SwiftValidator) 40 | - IQkeyboardManagerSwift [Docs](https://github.com/hackiftekhar/IQKeyboardManager) 41 | 42 | 43 | 44 | ## Development Setup 45 | 46 | Before you begin, you should already have the Xcode downloaded and set up correctly. You can find a guide on how to do this here: [Setting up Xcode](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppStoreDistributionTutorial/Setup/Setup.html) 47 | 48 | #####        Steps to install Cocoapods (one time installation) 49 | 50 | - Run `sudo gem install cocoapods` to install the latest version of cocoapods. To install cocoapods from HomeBrew, run `brew install cocoapods`. 51 | 52 | - Next, run `pod setup` for setting up cocoapods master repo. You may include `--verbose` for more descriptive logs. 53 | **NOTE:** This might take a while to setup depending on your network speed. 54 | 55 | ## Setting up the iOS Project 56 | 57 | 1. Download the _open_event_ios_ project source. You can do this either by forking and cloning the repository (recommended if you plan on pushing changes) or by downloading it as a ZIP file and extracting it. 58 | 59 | 2. Navigate to the unzipped folder and run `pod install`. 60 | 61 | 3. Open `FOSSAsia.xcworkspace` from the folder. 62 | 63 | 4. Build the project (⌘+B) and check for any errors. 64 | 65 | 5. Run the app (⌘+R).and test it. 66 | # Contribute! 67 | 68 | > You're now ready to contribute! 69 | 70 | Before writing any code, We will highly recommend to have a look at the [Contribution Guidelines](CONTRIBUTING.md) to avoid any unnecessary conflicts. For contributors new to Git please have a look at the [Git Configuration commands](docs/gitconfiguration.md) . 71 | 72 | ## License 73 | This repository is licensed under the **[MIT License](LICENSE)**. 74 | > To obtain the software under a different license, Please contact **FOSSASIA**. 75 | 76 | -------------------------------------------------------------------------------- /Scripts/before_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | gem install bundler 6 | gem install xcpretty 7 | gem install cocoapods 8 | -------------------------------------------------------------------------------- /Scripts/build_for_testing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | xcodebuild clean build-for-testing \ 4 | -workspace FOSSAsia.xcworkspace \ 5 | -sdk iphonesimulator \ 6 | -destination 'platform=iOS Simulator,name=iPhone 8,OS=11.2' \ 7 | -scheme FOSSAsia | xcpretty -c && exit ${PIPESTATUS[0]} 8 | -------------------------------------------------------------------------------- /Scripts/update_dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Update all external dependencies 6 | curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf 7 | pod install 8 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | xcodebuild test -workspace FOSSAsia.xcworkspace -scheme FOSSAsia -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.0' 2 | -------------------------------------------------------------------------------- /docs/gitconfiguration.md: -------------------------------------------------------------------------------- 1 | ## Git commands 2 | ### Configuring remotes 3 | When a repository is cloned, it has a default remote called `origin` that points to your fork on GitHub, not the original repository it was forked from. To keep track of the original repository, you should add another remote named `upstream`:
4 | 1. Get the path where you have your git repository on your machine. Go to that path in Terminal using cd. Alternatively, Right click on project in Github Desktop and hit ‘Open in Terminal’.
5 | 2. Run `git remote -v` to check the status of current remotes, you should see something like the following:
6 | > origin https://github.com/YOUR_USERNAME/open-event-ios.git(fetch)
7 | > origin https://github.com/YOUR_USERNAME/open-event-ios.git(push)
8 | 3. Set the remote of orignal repository as `upstream`:
9 | `git remote add upstream https://github.com/fossasia/open-event-ios.git`
10 | 4. Run `git remote -v` again to check the status of current remotes, you should see something like the following:
11 | > origin https://github.com/YOUR_USERNAME/open-event-ios.git (fetch)
12 | > origin https://github.com/YOUR_USERNAME/open-event-ios.git (push)
13 | > upstream https://github.com/fossasia/open-event-ios.git (fetch)
14 | > upstream https://github.com/fossasia/open-event-ios.git (push)
15 | 5. To update your local copy with remote changes, run the following:
16 | `git fetch upstream development`
17 | `git rebase upstream/development`
18 | This will give you an exact copy of the current remote, make sure you don't have any local changes.
19 | 6. Project set-up is complete.
20 | ### Developing a feature 21 | 1. Make sure you are in the development branch `git checkout development`.
22 | 2. Sync your copy `git pull --rebase upstream development`.
23 | 3. Create a new branch with a meaningful name `git checkout -b branch_name`.
24 | 4. Develop your feature on Xcode IDE and run it using the simulator or connecting your own iphone.
25 | 5. Add the files you changed `git add file_name` (avoid using `git add .`).
26 | 6. Commit your changes `git commit -m "Message briefly explaining the feature"`.
27 | 7. Keep one commit per feature. If you forgot to add changes, you can edit the previous commit `git commit --amend`.
28 | 8. Push to your repo `git push origin branch-name`.
29 | 9. Go into [the Github repo](https://github.com/fossasia/open-event-ios) and create a pull request explaining your changes.
30 | 10. If you are requested to make changes, edit your commit using `git commit --amend`, push again and the pull request will edit automatically.
31 | 11. If you have more than one commit try squashing them into single commit by following command:
32 | `git rebase -i HEAD~n `(having n number of commits).
33 | 12. Once you've run a git rebase -i command, text editor will open with a file that lists all the commits in current branch, and in front of each commit is the word "pick". For every line except the first, replace the word "pick" with the word "squash".
34 | 13. Save and close the file, and a moment later a new file should pop up in editor, combining all the commit messages of all the commits. Reword this commit message into meaningful one briefly explaining all the features, and then save and close that file as well. This commit message will be the commit message for the one, big commit that you are squashing all of your larger commits into. Once you've saved and closed that file, your commits of current branch have been squashed together.
35 | 14. Force push to update your pull request with command `git push origin branchname --force`.
36 | --------------------------------------------------------------------------------