├── .gitignore
├── .swiftlint.yml
├── CONTRIBUTING.md
├── Constants
└── L10nEnum.swift
├── Fabric.framework
├── Fabric
├── Headers
│ ├── FABAttributes.h
│ └── Fabric.h
├── Info.plist
├── Modules
│ └── module.modulemap
├── run
└── uploadDSYM
├── LICENSE
├── Podfile
├── Podfile.lock
├── Preview.html
├── README.md
├── SEDaily-IOS.xcodeproj
├── project.pbxproj
├── project.pbxproj.mergesave
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ └── SEDaily-IOS.xcscheme
├── SEDaily-IOS.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── SEDaily-IOS
├── API.swift
├── APIStripeExtension.swift
├── ActionView.swift
├── AnalyticsHelper.swift
├── AnswersTracker.swift
├── AppDelegate.swift
├── AskForReview.swift
├── Asset.swift
├── AssetPlayer.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-57x57@1x.png
│ │ ├── Icon-App-57x57@2x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-72x72@1x.png
│ │ ├── Icon-App-72x72@2x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ ├── Icon-App-83.5x83.5@2x.png
│ │ ├── Icon-Small-50x50@1x.png
│ │ ├── Icon-Small-50x50@2x.png
│ │ └── SEDaily_Logo_Marketing_Icon.png
│ ├── Arrow-Down.imageset
│ │ ├── Arrow-Down.png
│ │ ├── Arrow-Down@2x.png
│ │ ├── Arrow-Down@3x.png
│ │ └── Contents.json
│ ├── Arrow-Up.imageset
│ │ ├── Arrow-Up.png
│ │ ├── Arrow-Up@2x.png
│ │ ├── Arrow-Up@3x.png
│ │ └── Contents.json
│ ├── BigCircle.imageset
│ │ ├── BigCircle.png
│ │ ├── BigCircle@2x.png
│ │ ├── BigCircle@3x.png
│ │ └── Contents.json
│ ├── Contents.json
│ ├── Logo_BarButton.imageset
│ │ ├── Contents.json
│ │ ├── Logo_BarButton.png
│ │ ├── Logo_BarButton@2x.png
│ │ └── Logo_BarButton@3x.png
│ ├── SEDaily_Logo.imageset
│ │ ├── Contents.json
│ │ ├── SEDaily_Logo.png
│ │ ├── SEDaily_Logo@2x.png
│ │ └── SEDaily_Logo@3x.png
│ ├── SmallCircle.imageset
│ │ ├── Contents.json
│ │ ├── SmallCircle.png
│ │ ├── SmallCircle@2x.png
│ │ └── SmallCircle@3x.png
│ ├── Square.imageset
│ │ ├── Contents.json
│ │ ├── Square.png
│ │ ├── Square@2x.png
│ │ └── Square@3x.png
│ ├── Triangle.imageset
│ │ ├── Contents.json
│ │ ├── Triangle.png
│ │ ├── Triangle@2x.png
│ │ └── Triangle@3x.png
│ ├── activity_feed_selected.imageset
│ │ ├── Contents.json
│ │ ├── activity_feed_selected.png
│ │ ├── activity_feed_selected@2x.png
│ │ └── activity_feed_selected@3x.png
│ ├── bookmark.imageset
│ │ ├── Contents.json
│ │ ├── bookmark@1x.png
│ │ ├── bookmark@2x.png
│ │ └── bookmark@3x.png
│ ├── bookmark_outline.imageset
│ │ ├── Contents.json
│ │ ├── bookmark_outline@1x.png
│ │ ├── bookmark_outline@2x.png
│ │ └── bookmark_outline@3x.png
│ ├── comment.imageset
│ │ ├── Contents.json
│ │ ├── comment@1x.png
│ │ ├── comment@2x.png
│ │ └── comment@3x.png
│ ├── download.imageset
│ │ ├── Contents.json
│ │ ├── download@1x.png
│ │ ├── download@2x.png
│ │ └── download@3x.png
│ ├── download_outline.imageset
│ │ ├── Contents.json
│ │ ├── download_outline@1x.png
│ │ ├── download_outline@2x.png
│ │ └── download_outline@3x.png
│ ├── download_panel.imageset
│ │ ├── Contents.json
│ │ ├── download_panel@1x.png
│ │ ├── download_panel@2x.png
│ │ └── download_panel@3x.png
│ ├── download_panel_outline.imageset
│ │ ├── Contents.json
│ │ ├── download_panel_outline@1x.png
│ │ ├── download_panel_outline@2x.png
│ │ └── download_panel_outline@3x.png
│ ├── forward_audio.imageset
│ │ ├── Contents.json
│ │ ├── forward_audio.png
│ │ ├── forward_audio@2x.png
│ │ └── forward_audio@3x.png
│ ├── info.imageset
│ │ ├── Contents.json
│ │ ├── info.png
│ │ ├── info@2x.png
│ │ └── info@3x.png
│ ├── latest.imageset
│ │ ├── Contents.json
│ │ ├── latest@1x.png
│ │ ├── latest@2x.png
│ │ └── latest@3x.png
│ ├── latest_outline.imageset
│ │ ├── Contents.json
│ │ ├── latest_outline@1x.png
│ │ ├── latest_outline@2x.png
│ │ └── latest_outline@3x.png
│ ├── like.imageset
│ │ ├── Contents.json
│ │ ├── Contents.json~4878a9558ba262a552fdc061e5bc104e8c791a06
│ │ ├── Contents.json~HEAD
│ │ ├── like@1x.png
│ │ ├── like@2x.png
│ │ └── like@3x.png
│ ├── like_outline.imageset
│ │ ├── Contents.json
│ │ ├── like_outline@1x.png
│ │ ├── like_outline@2x.png
│ │ └── like_outline@3x.png
│ ├── link.imageset
│ │ ├── Contents.json
│ │ ├── link@1x.png
│ │ ├── link@2x.png
│ │ └── link@3x.png
│ ├── logo_subtitle.imageset
│ │ ├── Contents.json
│ │ ├── logo_subtitle.png
│ │ ├── logo_subtitle@2x.png
│ │ └── logo_subtitle@3x.png
│ ├── menu_hamburger.imageset
│ │ ├── Contents.json
│ │ ├── menu_hamburger.png
│ │ ├── menu_hamburger@2x.png
│ │ └── menu_hamburger@3x.png
│ ├── mic_stand.imageset
│ │ ├── Contents.json
│ │ ├── mic_stand.png
│ │ ├── mic_stand@2x.png
│ │ └── mic_stand@3x.png
│ ├── mic_stand_selected.imageset
│ │ ├── Contents.json
│ │ ├── mic_stand_selected.png
│ │ ├── mic_stand_selected@2x.png
│ │ └── mic_stand_selected@3x.png
│ ├── pause-big.imageset
│ │ ├── Contents.json
│ │ ├── pause-big.png
│ │ ├── pause-big@2x.png
│ │ └── pause-big@3x.png
│ ├── pause.imageset
│ │ ├── Contents.json
│ │ ├── pause.png
│ │ ├── pause@2x.png
│ │ └── pause@3x.png
│ ├── pause_audio.imageset
│ │ ├── Contents.json
│ │ ├── pause_audio.png
│ │ ├── pause_audio@2x.png
│ │ └── pause_audio@3x.png
│ ├── pause_white.imageset
│ │ ├── Contents.json
│ │ ├── pause_white.png
│ │ ├── pause_white@2x.png
│ │ └── pause_white@3x.png
│ ├── person.imageset
│ │ ├── Contents.json
│ │ ├── person@1x.png
│ │ ├── person@2x.png
│ │ └── person@3x.png
│ ├── person_outline.imageset
│ │ ├── Contents.json
│ │ ├── person_outline@1x.png
│ │ ├── person_outline@2x.png
│ │ └── person_outline@3x.png
│ ├── play-big.imageset
│ │ ├── Contents.json
│ │ ├── play-big.png
│ │ ├── play-big@2x.png
│ │ └── play-big@3x.png
│ ├── play.imageset
│ │ ├── Contents.json
│ │ ├── play.png
│ │ ├── play@2x.png
│ │ └── play@3x.png
│ ├── play_audio.imageset
│ │ ├── Contents.json
│ │ ├── play_audio.png
│ │ ├── play_audio@2x.png
│ │ └── play_audio@3x.png
│ ├── play_white.imageset
│ │ ├── Contents.json
│ │ ├── play_white.png
│ │ ├── play_white@2x.png
│ │ └── play_white@3x.png
│ ├── profile-icon-9.imageset
│ │ ├── Contents.json
│ │ └── profile-icon-9.png
│ ├── rewind_audio.imageset
│ │ ├── Contents.json
│ │ ├── rewind_audio@1x.png
│ │ ├── rewind_audio@2x.png
│ │ └── rewind_audio@3x.png
│ ├── sedaily-logo.imageset
│ │ ├── Contents.json
│ │ ├── sedaily-logo.png
│ │ ├── sedaily-logo@2x.png
│ │ └── sedaily-logo@3x.png
│ └── share.imageset
│ │ ├── Contents.json
│ │ ├── share@1x.png
│ │ ├── share@2x.png
│ │ └── share@3x.png
├── AudioOverlayViewController.swift
├── AudioPlayerView.swift
├── AudioView.swift
├── Author.swift
├── AvatarCell.swift
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ ├── Localizable.strings
│ └── Main.storyboard
├── BaseFeedItem.swift
├── Bookmark
│ ├── BookmarkCollectionViewController.swift
│ ├── BookmarkViewModelController.swift
│ └── StateBookmarkView.swift
├── BookmarkService.swift
├── Comment.swift
├── CommentCell.swift
├── CommentReplyTableViewCell.swift
├── CommentTableViewCell.swift
├── CommentsResponse.swift
├── CommentsViewController.swift
├── ContainerViewController.swift
├── CurrentlyPlaying.swift
├── CustomTabViewController.swift
├── Debouncer.swift
├── Debug
│ ├── Debug.storyboard
│ ├── DebugTabViewController.swift
│ ├── TestHook.swift
│ ├── TestHookBool.swift
│ ├── TestHookBoolTableViewCell.swift
│ ├── TestHookEvent.swift
│ ├── TestHookEventTableViewCell.swift
│ └── TestHookManager.swift
├── DescriptionCell.swift
├── DiskKeys.swift
├── DownloadService.swift
├── DownloadsCollectionViewController.swift
├── DownloadsViewModelController.swift
├── EpisodeHeaderCell.swift
├── EpisodeViewController.swift
├── FeedItem.swift
├── FeedItemCell.swift
├── FeedList.storyboard
├── FeedListViewController.swift
├── FilterObject.swift
├── ForumHeaderViewController.swift
├── ForumList.storyboard
├── ForumListViewController.swift
├── ForumThread.swift
├── ForumThreadCell.swift
├── ForumThreadLite.swift
├── GeneralCollectionViewController.swift
├── GoogleService-Info.plist
├── Haptics.swift
├── HeaderView.swift
├── Helpers.swift
├── HtmlHelper.swift
├── Info.plist
├── ItemCollectionViewCell.swift
├── KoalaTeaFlowLayout.swift
├── LabelCell.swift
├── LoginViewController.swift
├── MainFlowCoordinator.swift
├── MainTabBarController.swift
├── NavigationControllerExtension.swift
├── NetworkService.swift
├── NotificationTableViewCell.swift
├── Notifications.swift
├── NotificationsController.swift
├── NotificationsTableViewController.swift
├── OfflineDownloadsManager.swift
├── OpenSans-Light.ttf
├── OpenSans-Regular.ttf
├── OpenSans-Semibold.ttf
├── OverlayViewController.swift
├── PlayProgress.swift
├── PlayProgressModelController.swift
├── PlaybackSpeed.swift
├── PlayerView.swift
├── Podcast.swift
├── PodcastCollectionViewCell.swift
├── PodcastCollectionViewController.swift
├── PodcastDataSource.swift
├── PodcastDescriptionView.swift
├── PodcastDetailViewController.swift
├── PodcastLite.swift
├── PodcastPageViewController.swift
├── PodcastRepository.swift
├── PodcastTableViewCell.swift
├── PodcastViewModel.swift
├── PodcastViewModelController.swift
├── PostsForTopicCollectionViewController.swift
├── ProfileCell.swift
├── ProfileTableViewDataSource.swift
├── ProfileViewController.swift
├── ProgressIndicator.swift
├── PurchaseSubscriptionViewController.swift
├── RelatedLink.swift
├── RelatedLinkWebVC.swift
├── RelatedLinkWebVC.xib
├── RelatedLinks.storyboard
├── RelatedLinksViewController.swift
├── RemoteCommandDataSource.swift
├── RemoteCommandManager.swift
├── Roboto-Bold.ttf
├── Roboto-Light.ttf
├── Roboto-Regular.ttf
├── RootViewController.swift
├── SearchCollectionViewController.swift
├── SeparatorCell.swift
├── SettingsCell.swift
├── SkeletonCollectionView.swift
├── StateController.swift
├── Stylesheet.swift
├── SubscriptionModel.swift
├── SubscriptionStatusViewController.swift
├── SummaryCell.swift
├── SwitchCell.swift
├── TagsCell.swift
├── ThreadHeaderView.swift
├── Topic.swift
├── TopicTableViewController.swift
├── UIButtonExtension.swift
├── UIColor+Extensions.swift
├── URLSchemaHelper.swift
├── UpvoteService.swift
├── User+ProfileViewController.Section.swift
├── UserModel.swift
├── ViewPlayground.playground
│ ├── Contents.swift
│ ├── Sources
│ │ └── KTResponsiveUI
│ │ │ ├── KTResponsiveUI
│ │ │ └── Classes
│ │ │ │ ├── Extensions.swift
│ │ │ │ └── UIViewExtensions.swift
│ │ │ ├── LICENSE
│ │ │ └── README.md
│ └── contents.xcplayground
├── WebViewCell.swift
├── en.lproj
│ └── Localizable.strings
└── fr.lproj
│ ├── LaunchScreen.strings
│ ├── Localizable.strings
│ └── Main.strings
├── SEDaily-IOSTests
├── APITests
│ ├── LoginTests.swift
│ ├── PostsTests.swift
│ ├── RegisterTests.swift
│ └── VotingTests.swift
├── HelpersTests.swift
├── Info.plist
├── Mocks
│ ├── Responses
│ │ ├── login
│ │ │ ├── login_nonexistinguser.json
│ │ │ ├── login_success.json
│ │ │ └── login_wrongpass.json
│ │ ├── posts
│ │ │ ├── getPostsWith_success.json
│ │ │ ├── getPosts_topPosts.json
│ │ │ ├── upvote_failure.json
│ │ │ └── upvote_success.json
│ │ └── register
│ │ │ ├── register_emptyusernamepass.json
│ │ │ ├── register_success.json
│ │ │ └── register_userexists.json
│ └── UserDefaultsMock.swift
├── SEDailyIOSTests.swift
└── UserModelTests.swift
├── fastlane
├── Appfile
├── Deliverfile
├── Fastfile
├── README.md
└── metadata
│ ├── copyright.txt
│ ├── en-US
│ ├── description.txt
│ ├── keywords.txt
│ ├── marketing_url.txt
│ ├── name.txt
│ ├── privacy_url.txt
│ ├── promotional_text.txt
│ ├── release_notes.txt
│ ├── subtitle.txt
│ └── support_url.txt
│ ├── primary_category.txt
│ ├── primary_first_sub_category.txt
│ ├── primary_second_sub_category.txt
│ ├── review_information
│ ├── demo_password.txt
│ ├── demo_user.txt
│ ├── email_address.txt
│ ├── first_name.txt
│ ├── last_name.txt
│ ├── notes.txt
│ └── phone_number.txt
│ ├── secondary_category.txt
│ ├── secondary_first_sub_category.txt
│ ├── secondary_second_sub_category.txt
│ └── trade_representative_contact_information
│ ├── address_line1.txt
│ ├── city_name.txt
│ ├── country.txt
│ ├── is_displayed_on_app_store.txt
│ ├── postal_code.txt
│ ├── state.txt
│ └── trade_name.txt
└── screenshots
└── app_screenshots.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | <<<<<<< HEAD
23 | *.xccheckout
24 | *.xcscmblueprint
25 |
26 | /Pods
27 | .DS_Store
28 | ReadyRosie.xcworkspace/xcuserdata/CraigHolliday.xcuserdatad/UserInterfaceState.xcuserstate
29 | *.xcuserstate
30 |
31 | ## Obj-C/Swift specific
32 | *.hmap
33 | *.ipa
34 | *.dSYM.zip
35 | *.dSYM
36 |
37 | ## Playgrounds
38 | timeline.xctimeline
39 | playground.xcworkspace
40 |
41 | # Swift Package Manager
42 | #
43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
44 | # Packages/
45 | .build/
46 |
47 | # CocoaPods
48 | #
49 | # We recommend against adding the Pods directory to your .gitignore. However
50 | # you should judge for yourself, the pros and cons are mentioned at:
51 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
52 | #
53 | Pods/
54 |
55 | # Carthage
56 | #
57 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
58 | # Carthage/Checkouts
59 |
60 | Carthage/Build
61 |
62 | # fastlane
63 | #
64 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
65 | # screenshots whenever they are needed.
66 | # For more information about the recommended setup visit:
67 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
68 |
69 | fastlane/report.xml
70 | fastlane/Preview.html
71 | fastlane/screenshots
72 | fastlane/test_output
73 |
74 | .DS_Store
75 | GoogleService-Info.plist
76 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | excluded: # paths to ignore during linting. Takes precedence over `included`.
2 | - Pods
3 |
4 | disabled_rules:
5 | - line_length
6 | - identifier_name
7 | - superfluous_disable_command
8 | - todo
9 | - cyclomatic_complexity
10 | - function_body_length
11 | - nesting
12 | - file_length
13 | - type_body_length
14 | - trailing_whitespace
15 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | How to Contribute
2 | -----------------
3 | We'd love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow.
4 |
5 | Getting Started
6 | ---------------
7 | We use [gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) so instead of a single `master` branch, we use two branches to record the history of the project. The `master` branch stores the official release history, and the `develop` branch serves as an integration branch for features. It's also convenient to tag all commits in the master branch with a version number.
8 |
9 | Workflow
10 | --------
11 | If you would like to contribute to this project, please:
12 | - Pick an [issue](https://github.com/SoftwareEngineeringDaily/se-daily-iOS/issues) to work on or create a [proposal](https://github.com/SoftwareEngineeringDaily/se-daily-iOS//blob/master/CONTRIBUTING.md#feature-proposals) for a new feature.
13 | - Fork this project.
14 | - Create your feature branch based off the `develop` branch.
15 | - Create a pull request to get your worked reviewed and merged back into the upstream `develop` branch.
16 |
17 | Please include screenshots of your app changes and write down the test scenarios you followed to verify that your code works.
18 |
19 | Feature proposals
20 | -----------------
21 | Please create an issue, label it as a `feature proposal` and follow the following template:
22 | ```markdown
23 | # Proposal: [your title here]
24 |
25 | ## Summary
26 | {Also include any designs or wireframes here}
27 |
28 | ## Rationale
29 | {First reason for why we should consider this proposal}
30 | {Second reason for why we should consider this proposal}
31 | {etc}
32 |
33 | ## Scope
34 |
35 | ## Important Notes
36 |
37 | ## Open Questions
38 | ```
39 |
40 | How to get unstuck
41 | ------------------
42 | We have an active Slack community that you can reach out to for more information or just to chat with anyone. Check out the [
SED iOS app development](https://softwaredaily.slack.com/app_redirect?channel=sed_app_ios) slack channel.
43 |
44 | Also checkout the [Open Source Guide](https://softwareengineeringdaily.github.io/).
45 |
46 | Code reviews
47 | ------------
48 | All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more information on using pull requests.
49 |
50 | Community Guidelines
51 | --------------------
52 | - Be considerate, kind, constructive, and helpful.
53 | - Do not engage in demeaning, discriminatory, harassing, or hateful speech, and imagery.
54 |
--------------------------------------------------------------------------------
/Fabric.framework/Fabric:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/Fabric.framework/Fabric
--------------------------------------------------------------------------------
/Fabric.framework/Headers/FABAttributes.h:
--------------------------------------------------------------------------------
1 | //
2 | // FABAttributes.h
3 | // Fabric
4 | //
5 | // Copyright (C) 2015 Twitter, Inc.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #pragma once
21 |
22 | #define FAB_UNAVAILABLE(x) __attribute__((unavailable(x)))
23 |
24 | #if !__has_feature(nullability)
25 | #define nonnull
26 | #define nullable
27 | #define _Nullable
28 | #define _Nonnull
29 | #endif
30 |
31 | #ifndef NS_ASSUME_NONNULL_BEGIN
32 | #define NS_ASSUME_NONNULL_BEGIN
33 | #endif
34 |
35 | #ifndef NS_ASSUME_NONNULL_END
36 | #define NS_ASSUME_NONNULL_END
37 | #endif
38 |
39 |
40 | /**
41 | * The following macros are defined here to provide
42 | * backwards compatability. If you are still using
43 | * them you should migrate to the native nullability
44 | * macros.
45 | */
46 | #define fab_nullable nullable
47 | #define fab_nonnull nonnull
48 | #define FAB_NONNULL __fab_nonnull
49 | #define FAB_NULLABLE __fab_nullable
50 | #define FAB_START_NONNULL NS_ASSUME_NONNULL_BEGIN
51 | #define FAB_END_NONNULL NS_ASSUME_NONNULL_END
52 |
--------------------------------------------------------------------------------
/Fabric.framework/Headers/Fabric.h:
--------------------------------------------------------------------------------
1 | //
2 | // Fabric.h
3 | // Fabric
4 | //
5 | // Copyright (C) 2015 Twitter, Inc.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import
21 | #import "FABAttributes.h"
22 |
23 | NS_ASSUME_NONNULL_BEGIN
24 |
25 | #if TARGET_OS_IPHONE
26 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
27 | #error "Fabric's minimum iOS version is 6.0"
28 | #endif
29 | #else
30 | #if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
31 | #error "Fabric's minimum OS X version is 10.7"
32 | #endif
33 | #endif
34 |
35 | /**
36 | * Fabric Base. Coordinates configuration and starts all provided kits.
37 | */
38 | @interface Fabric : NSObject
39 |
40 | /**
41 | * Initialize Fabric and all provided kits. Call this method within your App Delegate's `application:didFinishLaunchingWithOptions:` and provide the kits you wish to use.
42 | *
43 | * For example, in Objective-C:
44 | *
45 | * `[Fabric with:@[[Crashlytics class], [Twitter class], [Digits class], [MoPub class]]];`
46 | *
47 | * Swift:
48 | *
49 | * `Fabric.with([Crashlytics.self(), Twitter.self(), Digits.self(), MoPub.self()])`
50 | *
51 | * Only the first call to this method is honored. Subsequent calls are no-ops.
52 | *
53 | * @param kitClasses An array of kit Class objects
54 | *
55 | * @return Returns the shared Fabric instance. In most cases this can be ignored.
56 | */
57 | + (instancetype)with:(NSArray *)kitClasses;
58 |
59 | /**
60 | * Returns the Fabric singleton object.
61 | */
62 | + (instancetype)sharedSDK;
63 |
64 | /**
65 | * This BOOL enables or disables debug logging, such as kit version information. The default value is NO.
66 | */
67 | @property (nonatomic, assign) BOOL debug;
68 |
69 | /**
70 | * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
71 | */
72 | - (id)init FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
73 |
74 | /**
75 | * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
76 | */
77 | + (instancetype)new FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
78 |
79 | @end
80 |
81 | NS_ASSUME_NONNULL_END
82 |
83 |
--------------------------------------------------------------------------------
/Fabric.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/Fabric.framework/Info.plist
--------------------------------------------------------------------------------
/Fabric.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module Fabric {
2 | umbrella header "Fabric.h"
3 |
4 | export *
5 | module * { export * }
6 | }
--------------------------------------------------------------------------------
/Fabric.framework/run:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # run
4 | #
5 | # Copyright (c) 2015 Crashlytics. All rights reserved.
6 |
7 | # Figure out where we're being called from
8 | DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
9 |
10 | # Quote path in case of spaces or special chars
11 | DIR="\"${DIR}"
12 |
13 | PATH_SEP="/"
14 | VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
15 | UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
16 |
17 | # Ensure params are as expected, run in sync mode to validate
18 | eval $DIR$PATH_SEP$VALIDATE_COMMAND
19 | return_code=$?
20 |
21 | if [[ $return_code != 0 ]]; then
22 | exit $return_code
23 | fi
24 |
25 | # Verification passed, upload dSYM in background to prevent Xcode from waiting
26 | # Note: Validation is performed again before upload.
27 | # Output can still be found in Console.app
28 | eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
29 |
--------------------------------------------------------------------------------
/Fabric.framework/uploadDSYM:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/Fabric.framework/uploadDSYM
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2017 Kunal Kapadia
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | platform :ios, '10.3'
3 |
4 | target 'SEDaily-IOS' do
5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for SEDaily-IOS
9 | pod 'ActiveLabel', :git => 'https://github.com/optonaut/ActiveLabel.swift.git'
10 | p
11 | pod 'Alamofire', '~> 4.5.1'
12 | pod 'Down'
13 | pod 'Disk', '~> 0.3.1'
14 | pod 'Eureka', '~> 4.1.1'
15 | pod 'Firebase/Core'
16 | pod 'Firebase/Analytics'
17 | pod 'Fabric', '~> 1.10.2'
18 | pod 'Crashlytics', '~> 3.13.4'
19 | pod 'IQKeyboardManagerSwift', '~> 5.0.8'
20 | pod 'Kingfisher', '~> 4.2.0'
21 | pod 'KTResponsiveUI', '~> 0.2.4'
22 | pod 'MBProgressHUD', '~> 1.1.0'
23 | pod 'Pageboy', '~> 2.0.2'
24 | pod 'PopupDialog', '~> 0.6.0'
25 | pod 'Reusable', '~> 4.0.0'
26 | pod 'Skeleton', '~> 0.1.0'
27 | pod 'SnapKit', '~> 4.0.0'
28 | pod 'StatefulViewController', '~> 3.0'
29 | pod 'SwiftGen', '~> 5.2.1'
30 | pod 'SwiftMoment'
31 | pod 'SwiftLint', '~> 0.25.1'
32 | pod 'SwiftSoup', '~> 1.5.8'
33 | pod 'SwifterSwift', '~> 4.0.1'
34 | pod 'SwiftyBeaver', '~> 1.4.2'
35 | pod 'SwiftyJSON'
36 | pod 'Tabman', '~> 1.0.5'
37 | pod 'WaitForIt', '~> 2.0.0'
38 | pod 'Tags'
39 |
40 | target 'SEDaily-IOSTests' do
41 | inherit! :search_paths
42 | pod 'Quick'
43 | pod 'Nimble'
44 | pod 'Mockingjay'
45 | end
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Software Engineering Daily iOS App
2 |
3 | [](https://softwareengineeringdaily.com/)
4 |
5 | Native iOS app for [Software Engineering Daily](https://softwareengineeringdaily.com/).
6 |
7 | ## Screenshots
8 |
9 | 
10 |
11 | ## Getting Started
12 |
13 | The app is 100% Swift. User interface is built mostly in code using [SnapKit](https://github.com/SnapKit/SnapKit) DSL. The current architecture is MVVM-C, but moving forward we are open to consider some Redux-like state management implementation.
14 |
15 | ## Setup
16 |
17 | We are using [CocoaPods](http://cocoapods.org) to manage dependencies.
18 | Clone the repo and then run:
19 |
20 | ```
21 | $ sudo gem install cocoapods
22 | $ pod install
23 | ```
24 |
25 | CocoaPods requires that you open the *SEDaily-IOS.xcworkspace*.
26 |
27 | ```
28 | $ open SEDaily-IOS.xcworkspace
29 | ```
30 |
31 | ## Dependencies
32 |
33 | There are +25 various dependencies used in the project. Moving forward some of them may be subject to change/removal.
34 | The most important ones are:
35 |
36 | * [SnapKit](https://github.com/SnapKit/SnapKit) - Build layouts in code.
37 | * [Alamofire](https://github.com/Alamofire/Alamofire) - Industry standard for networking.
38 | * [Kingfisher](https://github.com/onevcat/Kingfisher) - Caching images.
39 | * [SwiftLint](https://github.com/realm/SwiftLint) - Swift language linter.
40 |
41 |
42 |
43 | ## Upcoming features
44 |
45 | Interested in seeing a particular feature implemented in this app? Please open a new [issue](https://github.com/SoftwareEngineeringDaily/se-daily-iOS/issues) with a [feature proposal](https://github.com/SoftwareEngineeringDaily/se-daily-iOS/blob/master/CONTRIBUTING.md#feature-proposals).
46 |
47 | Contributing
48 | ------------
49 | Checkout [CONTRIBUTING.md](https://github.com/SoftwareEngineeringDaily/se-daily-iOS/blob/master/CONTRIBUTING.md) for details.
50 |
51 |
--------------------------------------------------------------------------------
/SEDaily-IOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SEDaily-IOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SEDaily-IOS.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SEDaily-IOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ActionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ActionView.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/1/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class ActionView {
13 | let actionStackView: UIStackView = UIStackView()
14 | let upvoteButton: UIButton = UIButton()
15 | let commentButton: UIButton = UIButton()
16 | let bookmarkButton: UIButton = UIButton()
17 |
18 | var commentShowCallback: ( ()-> Void) = {}
19 |
20 | let upvoteCountLabel: UILabel = UILabel()
21 |
22 | let upvoteStackView: UIStackView = UIStackView()
23 |
24 | func setupComponents(superview: UIView) {
25 | func setupButtons() {
26 | upvoteButton.setImage(UIImage(named: "like_outline"), for: .normal)
27 | upvoteButton.setImage(UIImage(named: "like"), for: .selected)
28 |
29 | bookmarkButton.setImage(UIImage(named: "bookmark_outline"), for: .normal)
30 | bookmarkButton.setImage(UIImage(named: "bookmark"), for: .selected)
31 |
32 | commentButton.setImage(UIImage(named: "comment"), for: .normal)
33 | commentButton.setImage(UIImage(named: "comment"), for: .normal)
34 | }
35 | func setupUpvoteStackView() {
36 | upvoteStackView.alignment = .center
37 | upvoteStackView.axis = .horizontal
38 | upvoteStackView.distribution = .fillEqually
39 |
40 | upvoteStackView.addArrangedSubview(upvoteButton)
41 | upvoteStackView.addArrangedSubview(upvoteCountLabel)
42 | }
43 |
44 | func setupActionStackView() {
45 | actionStackView.alignment = .center
46 | actionStackView.axis = .horizontal
47 | actionStackView.distribution = .fillEqually
48 |
49 | actionStackView.addArrangedSubview(upvoteStackView)
50 | actionStackView.addArrangedSubview(commentButton)
51 | actionStackView.addArrangedSubview(bookmarkButton)
52 | superview.addSubview(actionStackView)
53 | }
54 | setupButtons()
55 | setupUpvoteStackView()
56 | setupActionStackView()
57 |
58 | }
59 |
60 |
61 | func setupContraints() {
62 | upvoteButton.snp.makeConstraints { (make) -> Void in
63 | make.right.equalTo(upvoteCountLabel.snp.left)
64 | make.height.width.equalTo(UIView.getValueScaledByScreenWidthFor(baseValue: 50.0)).priority(999)
65 | }
66 | bookmarkButton.snp.makeConstraints { (make) -> Void in
67 |
68 | make.height.width.equalTo(UIView.getValueScaledByScreenWidthFor(baseValue: 50.0)).priority(999)
69 | }
70 | commentButton.snp.makeConstraints { (make) -> Void in
71 |
72 | make.height.width.equalTo(UIView.getValueScaledByScreenWidthFor(baseValue: 50.0)).priority(999)
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/SEDaily-IOS/AskForReview.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AskForReview.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Eduardo Saenz on 11/9/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import WaitForIt
11 |
12 | struct AskForReview: ScenarioProtocol {
13 | static let completedReviewKey = "completedReview"
14 |
15 | static func config() {
16 | /*
17 | Trigger an event three times minimum before executing
18 | Wait at least one day after the first event to execute
19 | Execute at most three times with a check if the review has been completed
20 | */
21 | minEventsRequired = 3
22 | minSecondsSinceFirstEvent = 86_400 // seconds in one day
23 | minSecondsSinceLastEvent = 86_400 // seconds in one day
24 | maxExecutionsPermitted = 3
25 | customConditions = {
26 | let defaults = UserDefaults.standard
27 | return !(defaults.object(forKey: completedReviewKey) != nil &&
28 | defaults.bool(forKey: completedReviewKey))
29 | }
30 | }
31 |
32 | static func setReviewed() {
33 | let defaults = UserDefaults.standard
34 | defaults.set(true, forKey: AskForReview.completedReviewKey)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Asset.swift:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2016 Apple Inc. All Rights Reserved.
3 | See LICENSE.txt for this sample’s licensing information
4 |
5 | Abstract:
6 | `Asset` is a wrapper struct around an `AVURLAsset` and its asset name.
7 | */
8 |
9 | import Foundation
10 | import AVFoundation
11 |
12 | public class Asset {
13 | // MARK: Types
14 | static let nameKey = "AssetName"
15 |
16 | // MARK: Properties
17 |
18 | /// The name of the asset to present in the application.
19 | public var assetName: String = ""
20 |
21 | // Custom artwork
22 | public var artworkURL: URL? = nil
23 |
24 | /// The `AVURLAsset` corresponding to an asset in either the application bundle or on the Internet.
25 | public var urlAsset: AVURLAsset
26 |
27 | public var savedTime: Float = 0 // This is in seconds
28 |
29 | // @TODO: Idk if CMTime is the right thing to use
30 | public var savedCMTime: CMTime {
31 | get {
32 | return CMTimeMake(Int64(savedTime), 1)
33 | }
34 | }
35 |
36 | public init(assetName: String, url: URL, artworkURL: URL? = nil, savedTime: Float = 0) {
37 | self.assetName = assetName
38 | let avURLAsset = AVURLAsset(url: url)
39 | self.urlAsset = avURLAsset
40 | self.artworkURL = artworkURL
41 | self.savedTime = savedTime
42 | }
43 | }
44 |
45 | extension Asset: Equatable {
46 | public static func == (lhs: Asset, rhs: Asset) -> Bool {
47 | return lhs.assetName == rhs.assetName && lhs.urlAsset == lhs.urlAsset
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/SEDaily_Logo_Marketing_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/AppIcon.appiconset/SEDaily_Logo_Marketing_Icon.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Arrow-Down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Arrow-Down.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Arrow-Down@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Arrow-Down@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Arrow-Down@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Arrow-Down@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Down.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Arrow-Down.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Arrow-Down@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Arrow-Down@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Arrow-Up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Arrow-Up.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Arrow-Up@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Arrow-Up@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Arrow-Up@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Arrow-Up@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Arrow-Up.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Arrow-Up.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Arrow-Up@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Arrow-Up@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/BigCircle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/BigCircle.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/BigCircle@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/BigCircle@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/BigCircle@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/BigCircle@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/BigCircle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "BigCircle.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "BigCircle@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "BigCircle@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Logo_BarButton.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Logo_BarButton@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Logo_BarButton@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Logo_BarButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Logo_BarButton.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Logo_BarButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Logo_BarButton@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Logo_BarButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Logo_BarButton.imageset/Logo_BarButton@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "SEDaily_Logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "SEDaily_Logo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "SEDaily_Logo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/SEDaily_Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/SEDaily_Logo.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/SEDaily_Logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/SEDaily_Logo@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/SEDaily_Logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/SEDaily_Logo.imageset/SEDaily_Logo@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "SmallCircle.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "SmallCircle@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "SmallCircle@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/SmallCircle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/SmallCircle.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/SmallCircle@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/SmallCircle@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/SmallCircle@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/SmallCircle.imageset/SmallCircle@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Square.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Square.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Square@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Square@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Square.imageset/Square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Square.imageset/Square.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Square.imageset/Square@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Square.imageset/Square@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Square.imageset/Square@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Square.imageset/Square@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Triangle.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Triangle@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Triangle@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Triangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Triangle.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Triangle@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Triangle@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Triangle@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/Triangle.imageset/Triangle@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "activity_feed_selected.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "activity_feed_selected@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "activity_feed_selected@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/activity_feed_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/activity_feed_selected.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/activity_feed_selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/activity_feed_selected@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/activity_feed_selected@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/activity_feed_selected.imageset/activity_feed_selected@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bookmark@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "bookmark@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "bookmark@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark.imageset/bookmark@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/bookmark.imageset/bookmark@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark.imageset/bookmark@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/bookmark.imageset/bookmark@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark.imageset/bookmark@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/bookmark.imageset/bookmark@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bookmark_outline@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "bookmark_outline@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "bookmark_outline@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/bookmark_outline@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/bookmark_outline@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/bookmark_outline@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/bookmark_outline@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/bookmark_outline@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/bookmark_outline.imageset/bookmark_outline@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/comment.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "comment@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "comment@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "comment@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/comment.imageset/comment@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/comment.imageset/comment@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/comment.imageset/comment@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/comment.imageset/comment@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/comment.imageset/comment@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/comment.imageset/comment@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "download@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "download@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "download@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download.imageset/download@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download.imageset/download@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download.imageset/download@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download.imageset/download@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download.imageset/download@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download.imageset/download@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_outline.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "download_outline@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "download_outline@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "download_outline@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_outline.imageset/download_outline@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_outline.imageset/download_outline@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_outline.imageset/download_outline@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_outline.imageset/download_outline@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_outline.imageset/download_outline@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_outline.imageset/download_outline@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "download_panel@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "download_panel@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "download_panel@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel.imageset/download_panel@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_panel.imageset/download_panel@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel.imageset/download_panel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_panel.imageset/download_panel@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel.imageset/download_panel@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_panel.imageset/download_panel@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "download_panel_outline@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "download_panel_outline@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "download_panel_outline@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/download_panel_outline@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/download_panel_outline@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/download_panel_outline@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/download_panel_outline@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/download_panel_outline@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/download_panel_outline.imageset/download_panel_outline@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "forward_audio.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "forward_audio@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "forward_audio@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/forward_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/forward_audio.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/forward_audio@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/forward_audio@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/forward_audio@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/forward_audio.imageset/forward_audio@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/info.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "info.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "info@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "info@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/info.imageset/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/info.imageset/info.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/info.imageset/info@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/info.imageset/info@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/info.imageset/info@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/info.imageset/info@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "latest@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "latest@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "latest@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest.imageset/latest@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/latest.imageset/latest@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest.imageset/latest@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/latest.imageset/latest@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest.imageset/latest@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/latest.imageset/latest@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "latest_outline@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "latest_outline@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "latest_outline@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/latest_outline@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/latest_outline@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/latest_outline@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/latest_outline@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/latest_outline@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/latest_outline.imageset/latest_outline@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "like@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "like@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "like@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like.imageset/Contents.json~4878a9558ba262a552fdc061e5bc104e8c791a06:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "like@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "like@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "like@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like.imageset/Contents.json~HEAD:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "like@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "like@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "like@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like.imageset/like@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/like.imageset/like@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like.imageset/like@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/like.imageset/like@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like.imageset/like@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/like.imageset/like@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like_outline.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "like_outline@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "like_outline@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "like_outline@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like_outline.imageset/like_outline@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/like_outline.imageset/like_outline@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like_outline.imageset/like_outline@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/like_outline.imageset/like_outline@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/like_outline.imageset/like_outline@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/like_outline.imageset/like_outline@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/link.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "link@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "link@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "link@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/link.imageset/link@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/link.imageset/link@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/link.imageset/link@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/link.imageset/link@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/link.imageset/link@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/link.imageset/link@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "logo_subtitle.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "logo_subtitle@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "logo_subtitle@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/logo_subtitle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/logo_subtitle.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/logo_subtitle@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/logo_subtitle@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/logo_subtitle@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/logo_subtitle.imageset/logo_subtitle@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "menu_hamburger.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "menu_hamburger@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "menu_hamburger@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/menu_hamburger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/menu_hamburger.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/menu_hamburger@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/menu_hamburger@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/menu_hamburger@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/menu_hamburger.imageset/menu_hamburger@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "mic_stand.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "mic_stand@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "mic_stand@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/mic_stand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/mic_stand.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/mic_stand@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/mic_stand@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/mic_stand@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/mic_stand.imageset/mic_stand@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "mic_stand_selected.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "mic_stand_selected@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "mic_stand_selected@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/mic_stand_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/mic_stand_selected.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/mic_stand_selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/mic_stand_selected@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/mic_stand_selected@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/mic_stand_selected.imageset/mic_stand_selected@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause-big.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "pause-big.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "pause-big@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "pause-big@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause-big.imageset/pause-big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause-big.imageset/pause-big.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause-big.imageset/pause-big@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause-big.imageset/pause-big@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause-big.imageset/pause-big@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause-big.imageset/pause-big@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "pause.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "pause@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "pause@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause.imageset/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause.imageset/pause.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause.imageset/pause@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause.imageset/pause@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause.imageset/pause@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause.imageset/pause@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "pause_audio.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "pause_audio@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "pause_audio@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/pause_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/pause_audio.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/pause_audio@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/pause_audio@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/pause_audio@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause_audio.imageset/pause_audio@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_white.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "pause_white.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "pause_white@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "pause_white@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_white.imageset/pause_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause_white.imageset/pause_white.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_white.imageset/pause_white@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause_white.imageset/pause_white@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/pause_white.imageset/pause_white@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/pause_white.imageset/pause_white@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "person@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "person@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "person@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person.imageset/person@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/person.imageset/person@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person.imageset/person@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/person.imageset/person@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person.imageset/person@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/person.imageset/person@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person_outline.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "person_outline@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "person_outline@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "person_outline@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person_outline.imageset/person_outline@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/person_outline.imageset/person_outline@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person_outline.imageset/person_outline@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/person_outline.imageset/person_outline@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/person_outline.imageset/person_outline@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/person_outline.imageset/person_outline@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play-big.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "play-big.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "play-big@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "play-big@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play-big.imageset/play-big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play-big.imageset/play-big.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play-big.imageset/play-big@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play-big.imageset/play-big@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play-big.imageset/play-big@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play-big.imageset/play-big@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "play.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "play@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "play@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play.imageset/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play.imageset/play.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play.imageset/play@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play.imageset/play@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play.imageset/play@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play.imageset/play@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_audio.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "play_audio.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "play_audio@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "play_audio@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_audio.imageset/play_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play_audio.imageset/play_audio.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_audio.imageset/play_audio@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play_audio.imageset/play_audio@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_audio.imageset/play_audio@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play_audio.imageset/play_audio@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_white.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "play_white.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "play_white@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "play_white@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_white.imageset/play_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play_white.imageset/play_white.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_white.imageset/play_white@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play_white.imageset/play_white@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/play_white.imageset/play_white@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/play_white.imageset/play_white@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/profile-icon-9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "profile-icon-9.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 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/profile-icon-9.imageset/profile-icon-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/profile-icon-9.imageset/profile-icon-9.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "rewind_audio@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "rewind_audio@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "rewind_audio@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/rewind_audio@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/rewind_audio@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/rewind_audio@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/rewind_audio@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/rewind_audio@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/rewind_audio.imageset/rewind_audio@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "sedaily-logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "sedaily-logo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "sedaily-logo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/sedaily-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/sedaily-logo.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/sedaily-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/sedaily-logo@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/sedaily-logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/sedaily-logo.imageset/sedaily-logo@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/share.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "share@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "share@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "share@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/share.imageset/share@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/share.imageset/share@1x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/share.imageset/share@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/share.imageset/share@2x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Assets.xcassets/share.imageset/share@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Assets.xcassets/share.imageset/share@3x.png
--------------------------------------------------------------------------------
/SEDaily-IOS/Author.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Author.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 2/5/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | // TODO: should merge this with User constuct?
11 |
12 | public struct Author: Codable {
13 | let email: String?
14 | let username: String?
15 | let name: String?
16 | let avatarUrl: String?
17 | let _id: String?
18 | }
19 |
20 |
21 | extension Author {
22 | func displayName() -> String {
23 |
24 | if let name = self.name {
25 | return name
26 | }
27 | if let username = self.username {
28 | return username
29 | }
30 |
31 | return L10n.anonymous
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/SEDaily-IOS/AvatarCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AvatarCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/5/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 |
10 | import UIKit
11 | import Reusable
12 |
13 | class AvatarCell: UITableViewCell, Reusable {
14 | private var avatarImageView: UIImageView!
15 |
16 | var avatarURL: URL? = nil {
17 | didSet {
18 | setupLayout()
19 | setupAvatar(imageURL: avatarURL)
20 | }
21 | }
22 | }
23 |
24 | extension AvatarCell {
25 | private func setupLayout() {
26 | self.selectionStyle = .none
27 |
28 | avatarImageView = UIImageView()
29 | contentView.addSubview(avatarImageView)
30 | avatarImageView.contentMode = .scaleAspectFill
31 | avatarImageView.clipsToBounds = true
32 | avatarImageView.cornerRadius = UIView.getValueScaledByScreenWidthFor(baseValue: 50)
33 | avatarImageView.kf.indicatorType = .activity
34 |
35 | avatarImageView.snp.makeConstraints { (make) -> Void in
36 | make.top.equalToSuperview().offset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
37 | make.bottom.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
38 | make.width.equalTo(UIView.getValueScaledByScreenWidthFor(baseValue: 100.0))
39 | make.height.equalTo(UIView.getValueScaledByScreenWidthFor(baseValue: 100.0))
40 | make.centerX.equalToSuperview()
41 | }
42 | }
43 | private func setupAvatar(imageURL: URL?) {
44 | avatarImageView.kf.cancelDownloadTask()
45 | avatarImageView.image = nil
46 | guard let imageURL = imageURL else {
47 | avatarImageView.image = #imageLiteral(resourceName: "SEDaily_Logo")
48 | return
49 | }
50 | avatarImageView.kf.setImage(with: imageURL, options: [.transition(.fade(0.2))])
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/SEDaily-IOS/BaseFeedItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseFeedItem.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 5/18/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol BaseFeedItem: Codable {
12 | var _id: String {get set}
13 | var score: Int {get set}
14 | var downvoted: Bool? {get set}
15 | var upvoted: Bool? {get set}
16 | }
17 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Bookmark/BookmarkViewModelController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BookmarkViewModelController.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/4/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public class BookmarkViewModelController {
12 | typealias Model = Podcast
13 | typealias ViewModel = PodcastViewModel
14 | typealias SuccessCallback = () -> Void
15 | typealias ErrorCallback = (RepositoryError?) -> Void
16 |
17 | private let repository = PodcastRepository()
18 | private var viewModels: [ViewModel?] = []
19 |
20 | var viewModelsCount: Int {
21 | return viewModels.count
22 | }
23 |
24 | func viewModel(at index: Int) -> ViewModel? {
25 | guard index >= 0 && index < viewModelsCount else { return nil }
26 | return viewModels[index]
27 | }
28 |
29 | func update(with podcast: PodcastViewModel) {
30 | let index = self.viewModels.index { (item) -> Bool in
31 | return item?._id == podcast._id
32 | }
33 | guard let modelsIndex = index else { return }
34 | self.viewModels.remove(at: modelsIndex)
35 | if podcast.isBookmarked {
36 | self.viewModels.insert(podcast, at: modelsIndex)
37 | }
38 |
39 | self.repository.updateDataSource(diskKey: .PodcastFolder, item: podcast.baseModelRepresentation)
40 | }
41 |
42 | func retrieveCachedBookmarkData(onSuccess: @escaping SuccessCallback) {
43 | self.repository.retrieveCachedBookmarkData(
44 | onSuccess: { (podcasts) in
45 | self.viewModels.removeAll()
46 | podcasts.forEach({ podcast in
47 | self.viewModels.push(ViewModel(podcast: podcast))
48 | })
49 | onSuccess() },
50 | onFailure: { _ in })
51 | }
52 |
53 | func retrieveNetworkBookmarkData(onSuccess: @escaping SuccessCallback) {
54 | self.repository.retrieveNetworkBookmarkData(
55 | onSuccess: { (podcasts) in
56 | self.viewModels.removeAll()
57 | podcasts.forEach({ podcast in
58 | self.viewModels.push(ViewModel(podcast: podcast))
59 | })
60 | onSuccess() },
61 | onFailure: { _ in })
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Bookmark/StateBookmarkView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StateBookmarkView.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/16/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | protocol StateViewDelegate: class {
13 | func refreshPressed()
14 | }
15 |
16 | /// Generic view for states used in view controllers
17 | class StateView: UIView {
18 | private var stackView: UIStackView!
19 | private var refreshButton: UIButton!
20 | weak var delegate: StateViewDelegate?
21 |
22 | init(
23 | frame: CGRect,
24 | text: String,
25 | showLoadingIndicator: Bool,
26 | showRefreshButton: Bool,
27 | delegate: StateViewDelegate?) {
28 | super.init(frame: frame)
29 |
30 | self.delegate = delegate
31 |
32 | self.stackView = UIStackView()
33 | self.stackView.axis = .vertical
34 | self.addSubview(self.stackView)
35 |
36 | let label = UILabel(text: text)
37 |
38 | let horizontalStackView = UIStackView()
39 | horizontalStackView.spacing = 10
40 | if showLoadingIndicator {
41 | let activityIndicator = UIActivityIndicatorView()
42 | activityIndicator.startAnimating()
43 | activityIndicator.color = UIColor.gray
44 | horizontalStackView.addArrangedSubview(activityIndicator)
45 | }
46 | horizontalStackView.addArrangedSubview(label)
47 |
48 | self.stackView.addArrangedSubview(horizontalStackView)
49 |
50 | if showRefreshButton {
51 | self.refreshButton = UIButton()
52 | self.refreshButton.setTitle(L10n.tapToRefresh, for: .normal)
53 | self.refreshButton.setTitleColor(UIColor.init(hex: 0x007AFF), for: .normal)
54 | self.refreshButton.addTarget(self, action: #selector(self.refreshPressed), for: .touchUpInside)
55 | self.stackView.addArrangedSubview(self.refreshButton)
56 | }
57 |
58 | self.stackView.snp.makeConstraints { (make) in
59 | make.centerX.centerY.equalToSuperview()
60 | }
61 | }
62 |
63 | @objc func refreshPressed() {
64 | self.delegate?.refreshPressed()
65 | }
66 |
67 | required init?(coder aDecoder: NSCoder) {
68 | fatalError("init(coder:) has not been implemented")
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/SEDaily-IOS/BookmarkService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BookmarkService.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 4/24/19.
6 | // Copyright © 2019 Altalogy All rights reserved.
7 | //
8 |
9 | protocol BookmarkServiceUIDelegate: class {
10 | func bookmarkUIDidChange(isBookmarked: Bool)
11 | func bookmarkUIImmediateUpdate()
12 | }
13 |
14 | import Foundation
15 |
16 | class BookmarkService {
17 |
18 | let networkService: API = API()
19 |
20 | var podcastViewModel: PodcastViewModel
21 |
22 |
23 | weak var UIDelegate: BookmarkServiceUIDelegate?
24 |
25 | init(podcastViewModel: PodcastViewModel) {
26 | self.podcastViewModel = podcastViewModel
27 | }
28 |
29 | func setBookmark() {
30 | guard UserManager.sharedInstance.isCurrentUserLoggedIn() == true else {
31 | Helpers.alertWithMessage(title: Helpers.Alerts.error, message: Helpers.Messages.youMustLogin, completionHandler: nil)
32 | return
33 | }
34 | UIDelegate?.bookmarkUIImmediateUpdate()
35 | self.setBookmark(value: true)
36 | }
37 |
38 | private func setBookmark(value: Bool) {
39 | let podcastId = podcastViewModel._id
40 | networkService.setBookmarkPodcast(
41 | value: value,
42 | podcastId: podcastId,
43 | completion: { [weak self] (success, active) in
44 | guard success != nil else {
45 | self?.UIDelegate?.bookmarkUIImmediateUpdate()
46 | return }
47 | if success == true {
48 | guard let active = active else { return }
49 | self?.updateBookmarked(active: active)
50 | } else { self?.UIDelegate?.bookmarkUIImmediateUpdate() }
51 | })
52 | Analytics2.bookmarkButtonPressed(podcastId: podcastViewModel._id)
53 | }
54 |
55 | private func updateBookmarked(active: Bool) {
56 | self.podcastViewModel.isBookmarked = active
57 | let userInfo = ["viewModel": podcastViewModel]
58 | NotificationCenter.default.post(name: .viewModelUpdated, object: nil, userInfo: userInfo)
59 | self.UIDelegate?.bookmarkUIDidChange(isBookmarked: active)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Comment.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Comment.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 2/1/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Down
11 | import SwiftMoment
12 |
13 | public struct Comment: Codable {
14 | let author: Author
15 | let _id: String
16 | let content: String
17 | let dateCreated: String
18 | let deleted: Bool
19 | let rootEntity: String
20 | let replies: [Comment]?
21 | let score: Int
22 | let upvoted: Bool?
23 | let downvoted: Bool?
24 | let parentComment: String?
25 | }
26 |
27 | extension Comment {
28 |
29 | func getDatedCreatedPretty() -> String {
30 | return moment(self.dateCreated)?.fromNow() ?? ""
31 | }
32 |
33 | func commentBody() -> NSAttributedString {
34 | // This should be done on the server
35 | let down = Down(markdownString: self.content)
36 | if let content = try? down.toAttributedString() {
37 | return content
38 | } else {
39 | return NSAttributedString(string: self.content)
40 | }
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/SEDaily-IOS/CommentReplyTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommentReplyTableViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 2/2/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CommentReplyTableViewCell: UITableViewCell {
12 |
13 | @IBOutlet weak var avatarImage: UIImageView!
14 | @IBOutlet weak var contentLabel: UILabel!
15 | @IBOutlet weak var usernameLabel: UILabel!
16 | @IBOutlet weak var dateLabel: UILabel!
17 | var comment: Comment? {
18 | didSet {
19 | contentLabel.attributedText = comment?.commentBody()
20 | let prettyDate = comment?.getDatedCreatedPretty()
21 | dateLabel.text = prettyDate
22 | usernameLabel.text = comment?.author.displayName()
23 |
24 | if let imageString = comment?.author.avatarUrl {
25 | let url = URL(string: imageString)
26 | avatarImage.kf.setImage(with: url)
27 | } else {
28 | avatarImage.image = UIImage(named: "profile-icon-9")
29 | }
30 |
31 | if comment?.deleted == true {
32 | contentLabel.textColor = UIColor.lightGray
33 | } else {
34 | contentLabel.textColor = UIColor.black
35 | }
36 | }
37 | }
38 |
39 | override func awakeFromNib() {
40 | super.awakeFromNib()
41 | setupLayout()
42 |
43 | // Initialization code
44 | }
45 |
46 | override func setSelected(_ selected: Bool, animated: Bool) {
47 | super.setSelected(selected, animated: animated)
48 |
49 | // Configure the view for the selected state
50 | }
51 |
52 | }
53 |
54 | extension CommentReplyTableViewCell {
55 | private func setupLayout() {
56 | func setupAvatarImage() {
57 | avatarImage.contentMode = .scaleAspectFill
58 | avatarImage.cornerRadius = avatarImage.frame.height / 2.0
59 | avatarImage.clipsToBounds = true
60 | }
61 | setupAvatarImage()
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SEDaily-IOS/CommentTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommentTableViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 2/2/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | class CommentTableViewCell: UITableViewCell {
13 | @IBOutlet weak var avatarImage: UIImageView!
14 | @IBOutlet weak var usernameLabel: UILabel!
15 | @IBOutlet weak var contentLabel: UILabel!
16 | @IBOutlet weak var replyButton: UIButton!
17 | @IBOutlet weak var dateLabel: UILabel!
18 | weak var delegate: CommentReplyTableViewCellDelegate?
19 | var hideReplyCell = false {
20 | didSet {
21 | replyButton.isHidden = hideReplyCell
22 | }
23 | }
24 |
25 | var comment: Comment? {
26 | didSet {
27 | let prettyDate = comment?.getDatedCreatedPretty()
28 | dateLabel.text = prettyDate
29 | contentLabel.attributedText = comment?.commentBody()
30 | usernameLabel.text = comment?.author.displayName()
31 |
32 | if let imageString = comment?.author.avatarUrl {
33 | let url = URL(string: imageString)
34 | avatarImage.kf.setImage(with: url)
35 | } else {
36 | avatarImage.image = UIImage(named: "profile-icon-9")
37 | }
38 | if comment?.deleted == true {
39 | contentLabel.textColor = UIColor.lightGray
40 | } else {
41 | contentLabel.textColor = UIColor.black
42 | }
43 | }
44 | }
45 |
46 | override func awakeFromNib() {
47 | super.awakeFromNib()
48 | // Initialization code
49 | }
50 |
51 | @IBAction func replyButtonPressed(_ sender: UIButton) {
52 | if let comment = comment {
53 | delegate?.replyToCommentPressed(comment: comment)
54 | }
55 | }
56 |
57 | override func setSelected(_ selected: Bool, animated: Bool) {
58 | super.setSelected(selected, animated: animated)
59 |
60 | // Configure the view for the selected state
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/SEDaily-IOS/CommentsResponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommentsResponse.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 2/1/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct CommentsResponse: Codable {
12 | let result: [Comment]
13 | }
14 |
--------------------------------------------------------------------------------
/SEDaily-IOS/CurrentlyPlaying.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CurrentlyPlaying.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/6/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | // This is a workaround to keep global playing state
11 | class CurrentlyPlaying {
12 | // static let shared = CurrentlyPlaying()
13 | // private var currentlyPlayingId: String = ""
14 | // func setCurrentlyPlaying(id: String) {
15 | // currentlyPlayingId = id
16 | // }
17 | // func getCurrentlyPlayingId()-> String {
18 | // return currentlyPlayingId
19 | // }
20 | }
21 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debouncer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Debouncer.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 4/24/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class Debouncer: NSObject {
12 | var callback: (() -> ())
13 | var delay: Double
14 | weak var timer: Timer?
15 |
16 | init(delay: Double, callback: @escaping (() -> ())) {
17 | self.delay = delay
18 | self.callback = callback
19 | }
20 |
21 | func call() {
22 | timer?.invalidate()
23 | let nextTimer = Timer.scheduledTimer(timeInterval: delay, target: self, selector: #selector(Debouncer.fireNow), userInfo: nil, repeats: false)
24 | timer = nextTimer
25 | }
26 |
27 | @objc func fireNow() {
28 | self.callback()
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debug/TestHook.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestHook.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 10/7/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class TestHook {
12 | let name: String
13 | let id: TestHookId
14 |
15 | var reuseId: String {
16 | return ""
17 | }
18 | var order = 0
19 |
20 | init(id: TestHookId, name: String) {
21 | self.id = id
22 | self.name = name
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debug/TestHookBool.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestHookBool.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/15/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class TestHookBool: TestHook {
12 | override var reuseId: String {
13 | return "TestHookBoolCellId"
14 | }
15 |
16 | private var _defaultValue = false
17 |
18 | var value: Bool {
19 | get {
20 | return UserDefaults.standard.bool(forKey: self.id.rawValue)
21 | }
22 |
23 | set(newValue) {
24 | UserDefaults.standard.set(newValue, forKey: self.id.rawValue)
25 | }
26 | }
27 |
28 | var defaultValue: Bool {
29 | get {
30 | return self._defaultValue
31 | }
32 | set(newDefaultValue) {
33 | self._defaultValue = newDefaultValue
34 | if UserDefaults.standard.object(forKey: self.id.rawValue) == nil {
35 | UserDefaults.standard.set(newDefaultValue, forKey: self.id.rawValue)
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debug/TestHookBoolTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestHookBoolTableViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/15/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class TestHookBoolTableViewCell: UITableViewCell, TestHookTableViewCell {
13 | @IBOutlet private weak var title: UILabel!
14 | @IBOutlet private weak var boolSwitch: UISwitch!
15 |
16 | private weak var testHookBool: TestHookBool?
17 |
18 | @IBAction func valueChanged(_ sender: Any) {
19 | self.testHookBool?.value = self.boolSwitch.isOn
20 | }
21 |
22 | func configure(testHook: TestHook) {
23 | self.title.text = testHook.name
24 |
25 | if let testHookBool = testHook as? TestHookBool {
26 | self.testHookBool = testHookBool
27 | self.boolSwitch.isOn = testHookBool.value
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debug/TestHookEvent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestHookEvent.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/15/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class TestHookEvent: TestHook {
12 | override var reuseId: String {
13 | return "TestHookEventCellId"
14 | }
15 | var execute: (() -> Void)?
16 | }
17 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debug/TestHookEventTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestHookEventTableViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/15/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class TestHookEventTableViewCell: UITableViewCell, TestHookTableViewCell {
13 | @IBOutlet private weak var title: UILabel!
14 | private var testHookEvent: TestHookEvent?
15 |
16 | func configure(testHook: TestHook) {
17 | self.title.text = testHook.name
18 |
19 | if let testHookEvent = testHook as? TestHookEvent {
20 | self.testHookEvent = testHookEvent
21 | }
22 | }
23 |
24 | @IBAction func buttonTapped(_ sender: Any) {
25 | self.testHookEvent?.execute?()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Debug/TestHookManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestHookManager.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 12/15/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum TestHookId: String {
12 | case useStagingEndpoint
13 | case viewDisk
14 | case getPodcastBookmarks
15 | case clearAlreadyLoadedToday
16 | }
17 |
18 | class TestHookManager {
19 | private(set) static var testHooksMap = [TestHookId: TestHook]()
20 | private(set) static var testHooksArray = [TestHook]()
21 | private static var order = 0
22 |
23 | private init() {
24 | }
25 |
26 | static func add(testHook: TestHook) {
27 | testHook.order = order
28 | order += 1
29 | TestHookManager.testHooksMap[testHook.id] = testHook
30 |
31 | TestHookManager.testHooksArray = Array(TestHookManager.testHooksMap.values)
32 | TestHookManager.testHooksArray.sort { $0.order < $1.order }
33 | }
34 |
35 | static func testHookBool(id: TestHookId) -> TestHookBool? {
36 | return TestHookManager.testHooksMap[id] as? TestHookBool
37 | }
38 |
39 | static func testHookEvent(id: TestHookId) -> TestHookEvent? {
40 | return TestHookManager.testHooksMap[id] as? TestHookEvent
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/SEDaily-IOS/DescriptionCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WebViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/2/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Reusable
11 | import WebKit
12 |
13 | class DescriptionCell: UITableViewCell, Reusable {
14 |
15 | var descriptionLabel: UILabel!
16 | //webView.navigationDelegate = self
17 |
18 | var viewModel: PodcastViewModel = PodcastViewModel() {
19 | willSet {
20 | guard newValue != self.viewModel else { return }
21 | }
22 | didSet {
23 | //updateUI()
24 | var str: String!
25 | // Due to asynchronuous nature of decoding html content, this is a better way to do it
26 | DispatchQueue.global(qos: .background).async { [weak self] in
27 | str = self?.viewModel.podcastDescription
28 | DispatchQueue.main.async {
29 | print(str)
30 | self?.descriptionLabel.text = str
31 | self?.layoutIfNeeded()
32 | }
33 | }
34 | }
35 | }
36 |
37 |
38 | override func awakeFromNib() {
39 | super.awakeFromNib()
40 | // Initialization code
41 | }
42 |
43 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
44 | super.init(style: style, reuseIdentifier: reuseIdentifier)
45 | setupLayout()
46 |
47 | }
48 | required init
49 | (coder aDecoder: NSCoder) {
50 | fatalError("init(coder:)")
51 | }
52 |
53 | override func setSelected(_ selected: Bool, animated: Bool) {
54 | super.setSelected(selected, animated: animated)
55 |
56 | // Configure the view for the selected state
57 | }
58 |
59 | }
60 |
61 | extension DescriptionCell {
62 | private func setupLayout() {
63 | descriptionLabel = UILabel()
64 | descriptionLabel.numberOfLines = 0
65 | descriptionLabel.font = UIFont(name: "OpenSans", size: UIView.getValueScaledByScreenWidthFor(baseValue: 13))
66 | descriptionLabel.textColor = Stylesheet.Colors.dark
67 | self.contentView.addSubview(descriptionLabel)
68 | descriptionLabel.snp.makeConstraints { (make) in
69 | make.left.right.top.equalToSuperview().offset(UIView.getValueScaledByScreenWidthFor(baseValue: 10))
70 | make.bottom.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue: 10))
71 | }
72 | }
73 | }
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/SEDaily-IOS/DiskKeys.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DiskKeys.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 11/16/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum DiskKeys: String {
12 | case PodcastFolder = "Podcasts"
13 | case OfflineDownloads = "Offline-Downloads"
14 |
15 | var folderPath: String {
16 | return self.rawValue + "/" + self.rawValue + ".json"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SEDaily-IOS/DownloadService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DownloadService.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 4/24/19.
6 | // Copyright © 2019 Altalogy All rights reserved.
7 | //
8 |
9 | protocol DownloadServiceUIDelegate: class {
10 | func downloadUIDidChange(progress: Int?, success: Bool?)
11 | }
12 | import Foundation
13 | import UIKit
14 |
15 | class DownloadService {
16 |
17 | weak var UIDelegate: DownloadServiceUIDelegate?
18 |
19 | var podcastViewModel: PodcastViewModel
20 |
21 | private let downloadManager = OfflineDownloadsManager.sharedInstance
22 |
23 | init(podcastViewModel: PodcastViewModel) {
24 | self.podcastViewModel = podcastViewModel
25 | }
26 |
27 | func savePodcast() {
28 |
29 | let podcastId = self.podcastViewModel._id
30 |
31 | self.downloadManager.save(
32 | podcast: self.podcastViewModel,
33 | onProgress: { progress in
34 | // Show progress
35 | let progressAsInt = Int((progress * 100).rounded())
36 | self.UIDelegate?.downloadUIDidChange(progress: progressAsInt, success: nil)
37 | self.podcastViewModel.downloadingProgress = progressAsInt
38 | },
39 | onSuccess: { [weak self] in
40 | // for search bug fix
41 | guard let strongSelf = self else { return }
42 | let userInfo = ["viewModel": strongSelf.podcastViewModel]
43 | NotificationCenter.default.post(name: .viewModelUpdated, object: nil, userInfo: userInfo)
44 | //
45 | strongSelf.UIDelegate?.downloadUIDidChange(progress: nil, success: true)
46 | },
47 | onFailure: { error in
48 | self.UIDelegate?.downloadUIDidChange(progress: nil, success: false)
49 | guard let error = error else { return }
50 | // Alert Error
51 | Helpers.alertWithMessage(title: error.localizedDescription.capitalized, message: "")
52 |
53 | })
54 | }
55 |
56 | func deletePodcast() {
57 |
58 | Helpers.alertWithMessageCustomAction(title: L10n.deletePodcast, message: nil, actionTitle: L10n.deletePodcastButtonTitle) { [weak self] in
59 | guard let strongSelf = self else { return }
60 | strongSelf.downloadManager.deletePodcast(podcast: strongSelf.podcastViewModel) {
61 | strongSelf.UIDelegate?.downloadUIDidChange(progress: nil, success: false)
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/SEDaily-IOS/DownloadsViewModelController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DownloadsViewModelController.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/21/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 |
10 | import Foundation
11 |
12 | public class DownloadsViewModelController {
13 | typealias Model = Podcast
14 | typealias ViewModel = PodcastViewModel
15 | typealias SuccessCallback = () -> Void
16 | typealias ErrorCallback = (RepositoryError?) -> Void
17 |
18 | private let repository = PodcastRepository()
19 | private var viewModels: [ViewModel?] = []
20 |
21 | var viewModelsCount: Int {
22 | return viewModels.count
23 | }
24 |
25 | func viewModel(at index: Int) -> ViewModel? {
26 | guard index >= 0 && index < viewModelsCount else { return nil }
27 | return viewModels[index]
28 | }
29 |
30 | func update(with podcast: PodcastViewModel) {
31 | let index = self.viewModels.index { (item) -> Bool in
32 | return item?._id == podcast._id
33 | }
34 | guard let modelsIndex = index else { return }
35 | self.viewModels.remove(at: modelsIndex)
36 | self.viewModels.insert(podcast, at: modelsIndex)
37 |
38 | // Tell repository to update Datasource
39 | self.repository.updateDataSource(diskKey: .PodcastFolder, item: podcast.baseModelRepresentation)
40 | }
41 |
42 | func retrieveCachedDownloadsData(onSuccess: @escaping SuccessCallback) {
43 | self.repository.retrieveDownloadsData(
44 | onSuccess: { (podcasts) in
45 | self.viewModels.removeAll()
46 | podcasts.forEach({ podcast in
47 | self.viewModels.push(ViewModel(podcast: podcast))
48 | })
49 | onSuccess() },
50 | onFailure: { _ in })
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/SEDaily-IOS/FeedItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedItem.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 5/15/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 |
13 | import Foundation
14 |
15 | public struct FeedItem: Codable {
16 | let _id: String
17 | let randomOrder: Double
18 | var relatedLink: RelatedLink
19 | // let author: Author // Is a string at times..
20 | }
21 |
--------------------------------------------------------------------------------
/SEDaily-IOS/FilterObject.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FilterObject.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 10/21/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct FilterObject: Codable {
12 | let type: String
13 | let tags: [Int]
14 | var tagsAsString: String {
15 | let stringArray = tags.map { String($0) }
16 | return stringArray.joined(separator: " ")
17 | }
18 | let lastDate: String
19 | let categories: [Int]
20 | var categoriesAsString: String {
21 | let stringArray = categories.map { String($0) }
22 | return stringArray.joined(separator: " ")
23 | }
24 |
25 | init(type: String = "",
26 | tags: [Int] = [],
27 | lastDate: String = "",
28 | categories: [Int] = []) {
29 | self.type = type
30 | self.tags = tags
31 | self.lastDate = lastDate
32 | self.categories = categories
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ForumHeaderViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ForumHeaderViewController.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 4/26/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ForumHeaderViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | // Do any additional setup after loading the view.
17 | }
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 |
25 | /*
26 | // MARK: - Navigation
27 |
28 | // In a storyboard-based application, you will often want to do a little preparation before navigation
29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
30 | // Get the new view controller using segue.destinationViewController.
31 | // Pass the selected object to the new view controller.
32 | }
33 | */
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ForumThread.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ForumThread.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 4/24/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftMoment
11 |
12 | public struct ForumThread: BaseFeedItem {
13 | var _id: String
14 | let title: String
15 | let content: String
16 | let author: Author
17 | let commentsCount: Int
18 | let dateCreated: String
19 | let dateLastAcitiy: String // An annoying bug that will require database migrations + miner update
20 | var score: Int = 0
21 | let deleted: Bool
22 | var downvoted: Bool?
23 | var upvoted: Bool?
24 | let podcastEpisode: PodcastLite?
25 | }
26 |
27 | extension ForumThread {
28 | func getPrettyTitle() -> String {
29 | if podcastEpisode == nil {
30 | return self.title
31 | }
32 | // Remove "Discuss: " from threads with posts defined:
33 | return self.title.substring(from: self.title.index(self.title.startIndex, offsetBy: 9))
34 | }
35 | func getCommentsSummary() -> String {
36 | if commentsCount != 1 {
37 | return "\(commentsCount) comments"
38 | } else {
39 | return "\(commentsCount) comment"
40 | }
41 | }
42 |
43 | func getDateLastActivityPretty() -> String {
44 | return moment(self.dateLastAcitiy)?.fromNow() ?? ""
45 | }
46 |
47 | func getDatedCreatedPretty() -> String {
48 | return moment(self.dateCreated)?.fromNow() ?? ""
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ForumThreadLite.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Thread.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 4/24/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct ForumThreadLite: Codable {
12 | let _id: String
13 | // let author: Author // Is a string at times..
14 | }
15 |
--------------------------------------------------------------------------------
/SEDaily-IOS/GoogleService-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CLIENT_ID
6 | 139717358510-83krai1okqvenaus4onn4qlndvs1vk64.apps.googleusercontent.com
7 | REVERSED_CLIENT_ID
8 | com.googleusercontent.apps.139717358510-83krai1okqvenaus4onn4qlndvs1vk64
9 | API_KEY
10 | AIzaSyAdaeUl4tnLv2jfV-3z9h2IwDfvz3qzP3A
11 | GCM_SENDER_ID
12 | 139717358510
13 | PLIST_VERSION
14 | 1
15 | BUNDLE_ID
16 | koala-tea.SEDaily
17 | PROJECT_ID
18 | sedaily-ebb27
19 | STORAGE_BUCKET
20 | sedaily-ebb27.appspot.com
21 | IS_ADS_ENABLED
22 |
23 | IS_ANALYTICS_ENABLED
24 |
25 | IS_APPINVITE_ENABLED
26 |
27 | IS_GCM_ENABLED
28 |
29 | IS_SIGNIN_ENABLED
30 |
31 | GOOGLE_APP_ID
32 | 1:139717358510:ios:a92590b1eee7f0b7
33 | DATABASE_URL
34 | https://sedaily-ebb27.firebaseio.com
35 |
36 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Haptics.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Haptics.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/21/19.
6 | // Copyright © 2019 Altalogy All rights reserved.
7 | //
8 | import UIKit
9 |
10 | enum FeedbackType {
11 | case impact
12 | case notification
13 | case selection
14 | }
15 |
16 | import Foundation
17 |
18 | class Haptics {
19 | static func feedback(_ feedback: FeedbackType) {
20 | switch feedback {
21 | case .impact:
22 | let impact = UIImpactFeedbackGenerator()
23 | impact.impactOccurred()
24 | case .notification:
25 | let notification = UINotificationFeedbackGenerator()
26 | notification.notificationOccurred(.success)
27 | case .selection:
28 | let selection = UISelectionFeedbackGenerator()
29 | selection.selectionChanged()
30 | }
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | SEDaily
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 2.0.1
21 | CFBundleVersion
22 | 5
23 | ITSAppUsesNonExemptEncryption
24 |
25 | LSApplicationCategoryType
26 |
27 | LSRequiresIPhoneOS
28 |
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 |
34 | UIAppFonts
35 |
36 | Roboto-Bold.ttf
37 | OpenSans-Semibold.ttf
38 | OpenSans-Regular.ttf
39 | Roboto-Light.ttf
40 | Roboto-Regular.ttf
41 | OpenSans-Light.ttf
42 |
43 | UIBackgroundModes
44 |
45 | audio
46 | fetch
47 |
48 | UILaunchStoryboardName
49 | LaunchScreen
50 | UIRequiredDeviceCapabilities
51 |
52 | armv7
53 |
54 | UIStatusBarHidden
55 |
56 | UIStatusBarStyle
57 | UIStatusBarStyleDefault
58 | UISupportedInterfaceOrientations
59 |
60 | UIInterfaceOrientationPortrait
61 |
62 | UISupportedInterfaceOrientations~ipad
63 |
64 | UIInterfaceOrientationPortrait
65 | UIInterfaceOrientationPortraitUpsideDown
66 | UIInterfaceOrientationLandscapeLeft
67 | UIInterfaceOrientationLandscapeRight
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/SEDaily-IOS/LabelCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LabelCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/10/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | import Foundation
12 | import Reusable
13 | import UIKit
14 |
15 | class LabelCell: UITableViewCell, Reusable {
16 |
17 | private var label: UILabel = UILabel()
18 |
19 | var viewModel: ViewModel = ViewModel() {
20 | didSet {
21 | label.text = viewModel.text
22 | setupLayout(style: viewModel.style)
23 |
24 | }
25 | }
26 |
27 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
28 | super.init(style: style, reuseIdentifier: reuseIdentifier)
29 | contentView.addSubview(label)
30 | self.selectionStyle = .none
31 | self.isUserInteractionEnabled = true
32 | }
33 |
34 | required init
35 | (coder aDecoder: NSCoder) {
36 | fatalError("init(coder:)")
37 | }
38 | }
39 |
40 |
41 | extension LabelCell {
42 | private func setupLayout(style: ViewModel.Style) {
43 |
44 | label.snp.makeConstraints { (make) in
45 | make.left.right.equalToSuperview().offset(style.marginX)
46 | make.right.equalToSuperview().inset(style.marginX)
47 | make.top.equalToSuperview().offset(style.marginY)
48 | make.bottom.equalToSuperview().inset(style.marginY)
49 | }
50 | label.textAlignment = style.alignment
51 | label.font = style.font
52 | label.textColor = style.color
53 |
54 | self.accessoryType = style.accessory
55 | }
56 | }
57 |
58 | // MARK: - ViewModel
59 | extension LabelCell {
60 | struct ViewModel {
61 | struct Style {
62 | var marginX: CGFloat = 0
63 | var marginY: CGFloat = 0
64 | var font: UIFont = UIFont(name: "Roboto", size: 10.0)! //arbitrary
65 | var color = UIColor.clear
66 | var alignment = NSTextAlignment.left
67 | var accessory: UITableViewCell.AccessoryType = .disclosureIndicator
68 | }
69 | var text = ""
70 | var style = Style()
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/SEDaily-IOS/MainFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainFlowCoordinator.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/26/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | import Foundation
12 | import UIKit
13 |
14 | protocol Coordinator: AnyObject {
15 | func configure(viewController: UIViewController)
16 | }
17 |
18 | protocol MainCoordinated: AnyObject {
19 | var mainCoordinator: MainFlowCoordinator? { get set }
20 | }
21 |
22 | protocol AudioControllable: AnyObject {
23 | var audioControlDelegate: EpisodeViewDelegate? { get set }
24 | }
25 |
26 | protocol Stateful: AnyObject {
27 | var stateController: StateController? { get set }
28 | }
29 |
30 |
31 | class MainFlowCoordinator: NSObject {
32 | let stateController = StateController()
33 | let rootViewController: RootViewController
34 |
35 |
36 | init(mainViewController: RootViewController) {
37 | self.rootViewController = mainViewController
38 | super.init()
39 | configure(viewController: mainViewController)
40 | }
41 |
42 | //Here you will pass viewModel as parameter, "info" String now for the exemplary purpose
43 | func viewController(_ viewController: UINavigationController, with viewModel: PodcastViewModel) {
44 | if let vc = viewController.visibleViewController as? EpisodeViewController { // a mechanism to prevent pushing the same view controllers
45 | if vc.viewModel == viewModel {
46 | return
47 | }
48 | }
49 | let vc = EpisodeViewController()
50 | vc.viewModel = viewModel
51 | configure(viewController: vc)
52 | viewController.pushViewController(vc, animated: true)
53 | }
54 |
55 | func viewController(_ navigationController: UINavigationController, push viewController: UIViewController) {
56 | configure(viewController: viewController)
57 | navigationController.pushViewController(viewController, animated: true)
58 | }
59 |
60 |
61 |
62 | }
63 |
64 | extension MainFlowCoordinator: Coordinator {
65 | func configure(viewController: UIViewController) {
66 | (viewController as? MainCoordinated)?.mainCoordinator = self
67 | (viewController as? Stateful)?.stateController = stateController
68 | (viewController as? AudioControllable)?.audioControlDelegate = rootViewController.overlayController
69 | if let rootController = viewController as? RootViewController {
70 | rootController.childViewControllers.forEach(configure(viewController:))
71 | }
72 | if let tabBarController = viewController as? UITabBarController {
73 | tabBarController.viewControllers?.forEach(configure(viewController:))
74 | }
75 | if let navigationController = viewController as? UINavigationController,
76 | let rootViewController = navigationController.viewControllers.first {
77 | configure(viewController: rootViewController)
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/SEDaily-IOS/NavigationControllerExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationControllerExtension.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 6/27/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UINavigationController {
12 | override open func viewDidLoad() {
13 | super.viewDidLoad()
14 |
15 | // Do any additional setup after loading the view.
16 | Stylesheet.applyOn(self)
17 | }
18 |
19 | override open func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 | override open var preferredStatusBarStyle: UIStatusBarStyle {
25 | return Stylesheet.Contexts.Global.StatusBarStyle
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SEDaily-IOS/NetworkService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkRequest.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Berk Mollamustafaoglu on 13/01/2018.
6 | // Copyright © 2018. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Alamofire
11 |
12 | protocol NetworkService {
13 | func networkRequest(_ urlString: URLConvertible, method: HTTPMethod, parameters: Parameters?, encoding: ParameterEncoding, headers: HTTPHeaders?) -> DataRequest
14 | }
15 |
16 | extension NetworkService {
17 | func networkRequest(_ urlString: URLConvertible, method: HTTPMethod, parameters: Parameters?, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders?) {
18 | return networkRequest(urlString, method: method, parameters: parameters, encoding: encoding, headers: headers)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SEDaily-IOS/NotificationTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationTableViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Keith Holliday on 4/2/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Reusable
11 | import SnapKit
12 | import SwifterSwift
13 | import KTResponsiveUI
14 | import Kingfisher
15 |
16 | class NotificationTableViewCell: UITableViewCell, Reusable {
17 | public var cellLabel: UILabel!
18 | public var cellToggle: UISwitch!
19 | var separator: UIView!
20 |
21 |
22 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
23 | super.init(style: style, reuseIdentifier: reuseIdentifier)
24 |
25 | cellLabel = UILabel()
26 | cellLabel.textColor = .black
27 | cellLabel.baselineAdjustment = .alignCenters
28 | cellLabel.numberOfLines = 0
29 | cellLabel.font = UIFont(name: "OpenSans", size: UIView.getValueScaledByScreenWidthFor(baseValue: 15))
30 | cellLabel.textColor = Stylesheet.Colors.dark
31 | cellToggle = UISwitch()
32 | cellToggle.tintColor = Stylesheet.Colors.light
33 | cellToggle.onTintColor = Stylesheet.Colors.base
34 |
35 |
36 | self.contentView.addSubview(cellLabel)
37 | self.contentView.addSubview(cellToggle)
38 | setupSeparator()
39 |
40 | cellLabel.snp.makeConstraints { (make) in
41 | make.left.equalToSuperview().offset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
42 | make.centerY.equalToSuperview()
43 | make.top.equalToSuperview().offset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
44 | make.bottom.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
45 | }
46 |
47 | cellToggle.snp.makeConstraints { (make) in
48 | make.right.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
49 | make.centerY.equalToSuperview()
50 | }
51 | separator.snp.makeConstraints { (make) -> Void in
52 | make.left.right.bottom.equalToSuperview()
53 | make.height.equalTo(2.0)
54 | }
55 | }
56 |
57 | required init(coder aDecoder: NSCoder) {
58 | fatalError("init(coder:)")
59 | }
60 |
61 | func setupSeparator() {
62 | separator = UIView()
63 | contentView.addSubview(separator)
64 | separator.backgroundColor = Stylesheet.Colors.light
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Notifications.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Notifications.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 7/24/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension Notification.Name {
12 | static let loginChanged = Notification.Name("loginChanged")
13 | static let viewModelUpdated = Notification.Name("viewModelUpdated")
14 | static let episodeViewWillExpand = Notification.Name("episodeViewWillExpand")
15 | static let reloadEpisodeView = Notification.Name("reloadEpisodeView")
16 | }
17 |
--------------------------------------------------------------------------------
/SEDaily-IOS/OpenSans-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/OpenSans-Light.ttf
--------------------------------------------------------------------------------
/SEDaily-IOS/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/SEDaily-IOS/OpenSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/OpenSans-Semibold.ttf
--------------------------------------------------------------------------------
/SEDaily-IOS/PlayProgress.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlayProgress.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 4/11/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct PlayProgress: Codable {
12 | let id: String
13 | var currentTime: Float
14 | var totalLength: Float
15 | var progressFraction: Float {
16 | get {
17 | return currentTime / totalLength
18 | }
19 | }
20 | var timeLeft: Float {
21 | get {
22 | return totalLength - currentTime
23 | }
24 | }
25 |
26 | init(id: String, currentTime: Float, totalLength: Float) {
27 | self.id = id
28 | self.currentTime = currentTime
29 | self.totalLength = totalLength
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SEDaily-IOS/PlayProgressModelController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlayProgressModelController.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 4/12/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | typealias PlayProgressDict = [String: PlayProgress]
12 |
13 | class PlayProgressModelController {
14 |
15 | var episodesPlayProgress: PlayProgressDict = PlayProgressDict()
16 |
17 | static func saveRecentlyListenedEpisodeId(id: String) {
18 | let defaults = UserDefaults.standard
19 | defaults.set(id, forKey: "sedaily-recentlyListened")
20 | }
21 |
22 | static func cleanRecentlyListenedEpisodeId() {
23 | let defaults = UserDefaults.standard
24 | defaults.set("", forKey: "sedaily-recentlyListened")
25 | }
26 |
27 | static func getRecentlyListenedEpisodeId() -> String? {
28 | let defaults = UserDefaults.standard
29 | guard let id = defaults.object(forKey: "sedaily-recentlyListened") as? String else { return nil}
30 | return id
31 | }
32 |
33 | func save() {
34 | var progressToSave: [String: Data] = [String: Data]()
35 | for (key, playProgress) in self.episodesPlayProgress {
36 | guard let playProgressData = encodePlayProgress(from: playProgress) else { return }
37 | progressToSave[key] = playProgressData
38 | }
39 | saveToDefaults(progressToSave: progressToSave)
40 | }
41 |
42 | func retrieve() {
43 | guard let fetched = fetchFromDefaults() else { return }
44 | var result: PlayProgressDict = PlayProgressDict()
45 | for (key, playProgressData) in fetched {
46 | guard let playProgress = decodePlayProgress(from: playProgressData) else { return }
47 | result[key] = playProgress
48 | }
49 | episodesPlayProgress = result
50 | }
51 |
52 | }
53 |
54 | private extension PlayProgressModelController {
55 |
56 | private func saveToDefaults(progressToSave: [String: Data]) {
57 | let defaults = UserDefaults.standard
58 | defaults.set(progressToSave, forKey: "sedaily-playProgress")
59 | }
60 |
61 | private func fetchFromDefaults()-> [String: Data]? {
62 | let defaults = UserDefaults.standard
63 | guard let fetchedData = defaults.object(forKey: "sedaily-playProgress") as? [String: Data] else { return nil}
64 | return fetchedData
65 | }
66 |
67 | private func decodePlayProgress(from data: Data)-> PlayProgress? {
68 | guard let fetchedPlayProgress = try? PropertyListDecoder().decode(PlayProgress.self, from: data)
69 | else { return nil }
70 | return fetchedPlayProgress
71 | }
72 |
73 | private func encodePlayProgress(from playProgress: PlayProgress)-> Data? {
74 | guard let progressData = try? PropertyListEncoder().encode(playProgress) else { return nil }
75 | return progressData
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/SEDaily-IOS/PlaybackSpeed.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaybackSpeed.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 16/07/2019.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum PlaybackSpeed: Float {
12 | case _1x = 1.0
13 | case _1_2x = 1.2
14 | case _1_4x = 1.4
15 | case _1_6x = 1.6
16 | case _1_8x = 1.8
17 | case _2x = 2.0
18 | case _2_5x = 2.5
19 | case _3x = 3.0
20 |
21 | var title: String {
22 | switch self {
23 | case ._1x:
24 | return "1x (Normal Speed)"
25 | case ._1_2x:
26 | return "1.2x"
27 | case ._1_4x:
28 | return "1.4x"
29 | case ._1_6x:
30 | return "1.6x"
31 | case ._1_8x:
32 | return "1.8x"
33 | case ._2x:
34 | return "⏩ 2x ⏩"
35 | case ._2_5x:
36 | return "2.5x"
37 | case ._3x:
38 | return "🔥 3x 🔥"
39 | }
40 | }
41 |
42 | var shortTitle: String {
43 | switch self {
44 | case ._1x:
45 | return "1x"
46 | case ._1_2x:
47 | return "1.2x"
48 | case ._1_4x:
49 | return "1.4x"
50 | case ._1_6x:
51 | return "1.6x"
52 | case ._1_8x:
53 | return "1.8x"
54 | case ._2x:
55 | return "2x"
56 | case ._2_5x:
57 | return "2.5x"
58 | case ._3x:
59 | return "3x"
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/SEDaily-IOS/PlayerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlayerView.swift
3 | // KoalaTeaPlayer
4 | //
5 | // Created by Craig Holliday on 8/4/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 | import UIKit
9 | import AVFoundation
10 |
11 | import UIKit
12 | import AVFoundation
13 |
14 | /// A simple `UIView` subclass that is backed by an `AVPlayerLayer` layer.
15 | public class PlayerView: UIView {
16 | public var player: AVPlayer? {
17 | get {
18 | return playerLayer.player
19 | }
20 |
21 | set {
22 | playerLayer.player = newValue
23 | }
24 | }
25 |
26 | var playerLayer: AVPlayerLayer {
27 | // swiftlint:disable force_cast
28 | return layer as! AVPlayerLayer
29 | // swiftlint:enable force_cast
30 | }
31 |
32 | override public class var layerClass: AnyClass {
33 | return AVPlayerLayer.self
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/SEDaily-IOS/PodcastDescriptionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PodcastDescriptionView.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 10/18/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ActiveLabel
11 | import KTResponsiveUI
12 |
13 | class PodcastDescriptionView: UIView {
14 |
15 | private lazy var label: ActiveLabel = {
16 | return ActiveLabel(leftInset: 15, topInset: 15, width: 375 - 30, height: 600)
17 | }()
18 |
19 | private let bottomMarginForLabel = UIView.getValueScaledByScreenHeightFor(baseValue: 30)
20 |
21 | override func performLayout() {
22 | self.backgroundColor = Stylesheet.Colors.offWhite
23 |
24 | self.addSubview(label)
25 | self.height = label.height
26 |
27 | label.numberOfLines = 0
28 | label.enabledTypes = [.url]
29 | label.textColor = Stylesheet.Colors.offBlack
30 | label.handleURLTap { url in
31 | if #available(iOS 10.0, *) {
32 | UIApplication.shared.open(url, options: [:], completionHandler: nil)
33 | Tracker.logMovedToWebView(url: url.absoluteString)
34 | } else {
35 | UIApplication.shared.openURL(url)
36 | Tracker.logMovedToWebView(url: url.absoluteString)
37 | }
38 | }
39 | }
40 |
41 | func setupView(podcastModel: PodcastViewModel) {
42 | podcastModel.getHTMLDecodedDescription { (returnedString) in
43 | let paragraphStyle = NSMutableParagraphStyle()
44 | paragraphStyle.paragraphSpacing = 10
45 |
46 | self.label.attributedText = NSAttributedString(string: returnedString, attributes: [NSAttributedStringKey.paragraphStyle: paragraphStyle])
47 | self.label.sizeToFit()
48 | self.height = self.label.height + self.bottomMarginForLabel
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/SEDaily-IOS/PodcastLite.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PodcastLite.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 4/27/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct PodcastLite: Codable {
12 | let _id: String
13 | let thread: String?
14 | let title: String
15 | let rendered:String
16 | let featuredImage: String?
17 |
18 | public init(from decoder: Decoder) throws {
19 | let container = try decoder.container(keyedBy: CodingKeys.self)
20 |
21 | let titleHolder = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .title)
22 | rendered = try titleHolder.decode(String.self, forKey: .rendered)
23 |
24 | featuredImage = try container.decode(String.self, forKey: .featuredImage)
25 | _id = try container.decode(String.self, forKey: ._id)
26 | thread = try container.decode(String.self, forKey: .thread)
27 | title = ""
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ProgressIndicator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProgressIndicator.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Justin Lam on 11/23/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import MBProgressHUD
11 |
12 | class ProgressIndicator {
13 | static func showBlockingProgress() {
14 | if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
15 | MBProgressHUD.showAdded(to: window, animated: true)
16 | }
17 | }
18 |
19 | static func hideBlockingProgress() {
20 | if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
21 | MBProgressHUD.hide(for: window, animated: true)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/SEDaily-IOS/RelatedLink.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RelatedLink.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 1/26/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct RelatedLink: BaseFeedItem {
12 | var score: Int = 0
13 |
14 | var _id: String
15 | var downvoted: Bool?
16 |
17 | var upvoted: Bool?
18 |
19 | let title: String
20 | let url: String
21 |
22 | let postId: String?
23 | let post: PodcastLite?
24 | let image: String?
25 | public init(from decoder: Decoder) throws {
26 | let container = try decoder.container(keyedBy: CodingKeys.self)
27 |
28 | _id = try container.decode(String.self, forKey: ._id)
29 |
30 | if let upvotedResult = try? container.decode(Bool.self, forKey: .upvoted) {
31 | upvoted = upvotedResult
32 | } else {
33 | downvoted = false
34 | }
35 | if let downvotedResult = try? container.decode(Bool.self, forKey: .downvoted) {
36 | downvoted = downvotedResult
37 | } else {
38 | downvoted = false
39 | }
40 |
41 | score = try container.decode(Int.self, forKey: .score)
42 | title = try container.decode(String.self, forKey: .title)
43 | url = try container.decode(String.self, forKey: .url)
44 |
45 | if let value = try? container.decode(PodcastLite.self, forKey: .post) {
46 | post = value
47 | postId = post?._id
48 | } else {
49 | postId = try container.decode(String.self, forKey: .post)
50 | post = nil
51 | }
52 | if let _image = try? container.decode(String.self, forKey: .image) {
53 | image = _image
54 | } else {
55 | image = nil
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/SEDaily-IOS/RelatedLinkWebVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RelatedLinkWebVC.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 5/20/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 |
13 |
14 | //
15 | // RelatedLInkWebVC.swift
16 | // SEDaily-IOS
17 | //
18 | // Created by jason on 5/18/18.
19 | // Copyright © 2018 Koala Tea. All rights reserved.
20 | //
21 |
22 | import UIKit
23 | import WebKit
24 |
25 | class RelatedLinkWebVC: UIViewController, WKUIDelegate, WKNavigationDelegate {
26 | var webView: WKWebView!
27 | var url:URL?
28 | @IBOutlet weak var simpleSpinner: UIActivityIndicatorView!
29 |
30 | func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
31 | simpleSpinner.stopAnimating()
32 | webView.isHidden = false
33 | self.view = webView
34 | }
35 |
36 | @IBAction func openInSafariTapped(_ sender: UIButton) {
37 | if let linkUrl = url {
38 | UIApplication.shared.open(linkUrl, options: [:], completionHandler: nil)
39 | Analytics2.relatedLinkSafariOpen(url: linkUrl)
40 | } else {
41 | print("link null")
42 | }
43 | }
44 |
45 | override func viewWillAppear(_ animated: Bool) {
46 | super.viewDidLoad()
47 | simpleSpinner.startAnimating()
48 | if let url = url {
49 | let webConfiguration = WKWebViewConfiguration()
50 | webView = WKWebView(frame: .zero, configuration: webConfiguration)
51 | webView.uiDelegate = self
52 |
53 | webView.navigationDelegate = self
54 | webView.isHidden = true
55 |
56 | let myRequest = URLRequest(url: url)
57 | webView.load(myRequest)
58 | Analytics2.relatedLinkViewed(url: url)
59 | Tracker.logRelatedLinkViewedFromFeed(url: url)
60 | }
61 | // Do any additional setup after loading the view.
62 | }
63 |
64 | override func didReceiveMemoryWarning() {
65 | super.didReceiveMemoryWarning()
66 | // Dispose of any resources that can be recreated.
67 | }
68 |
69 | /*
70 | // MARK: - Navigation
71 |
72 | // In a storyboard-based application, you will often want to do a little preparation before navigation
73 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
74 | // Get the new view controller using segue.destinationViewController.
75 | // Pass the selected object to the new view controller.
76 | }
77 | */
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/SEDaily-IOS/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Roboto-Light.ttf
--------------------------------------------------------------------------------
/SEDaily-IOS/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/SEDaily-IOS/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/SEDaily-IOS/SeparatorCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SeparatorCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/7/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 |
10 | import UIKit
11 | import Reusable
12 |
13 | class SeparatorCell: UITableViewCell, Reusable {
14 | private var separator: UIView = UIView()
15 |
16 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
17 | super.init(style: style, reuseIdentifier: reuseIdentifier)
18 | contentView.addSubview(separator)
19 | setupLayout()
20 | }
21 |
22 | required init(coder aDecoder: NSCoder) {
23 | fatalError("init(coder:)")
24 | }
25 | }
26 |
27 | extension SeparatorCell {
28 | private func setupLayout() {
29 |
30 | separator.backgroundColor = Stylesheet.Colors.light
31 |
32 | separator.snp.makeConstraints { (make) -> Void in
33 | make.left.right.bottom.top.equalToSuperview()
34 | make.height.equalTo(5.0)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/SEDaily-IOS/SettingsCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationTableViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Keith Holliday on 4/2/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Reusable
11 |
12 | class SettingsCell: UITableViewCell, Reusable {
13 | public var cellLabel: UILabel!
14 | var separator: UIView!
15 |
16 |
17 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
18 | super.init(style: style, reuseIdentifier: reuseIdentifier)
19 |
20 | cellLabel = UILabel()
21 | cellLabel.baselineAdjustment = .alignCenters
22 | cellLabel.numberOfLines = 0
23 | cellLabel.font = UIFont(name: "OpenSans", size: UIView.getValueScaledByScreenWidthFor(baseValue: 15))
24 | cellLabel.textColor = Stylesheet.Colors.dark
25 |
26 |
27 | self.contentView.addSubview(cellLabel)
28 | setupSeparator()
29 |
30 | cellLabel.snp.makeConstraints { (make) in
31 | make.left.equalToSuperview().offset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
32 | make.centerY.equalToSuperview()
33 | make.top.equalToSuperview().offset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
34 | make.bottom.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue: 15.0))
35 | }
36 |
37 | separator.snp.makeConstraints { (make) -> Void in
38 | make.left.right.bottom.equalToSuperview()
39 | make.height.equalTo(2.0)
40 | }
41 | }
42 |
43 | required init(coder aDecoder: NSCoder) {
44 | fatalError("init(coder:)")
45 | }
46 |
47 | func setupSeparator() {
48 | separator = UIView()
49 | contentView.addSubview(separator)
50 | separator.backgroundColor = Stylesheet.Colors.light
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/SEDaily-IOS/SkeletonCollectionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SkeletonCollectionView.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 10/10/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private let reuseIdentifier = "Cell"
12 |
13 | class SkeletonCollectionView: UIView, UICollectionViewDataSource {
14 | var collectionView: UICollectionView!
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 | self.collectionView = UICollectionView(frame: frame, collectionViewLayout: UICollectionViewLayout())
19 | self.addSubview(self.collectionView)
20 | self.collectionView.dataSource = self
21 |
22 | self.collectionView!.register(ItemCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
23 |
24 | let layout = KoalaTeaFlowLayout(cellWidth: Helpers.getScreenWidth(),
25 | cellHeight: UIView.getValueScaledByScreenWidthFor(baseValue: 185.0),
26 | topBottomMargin: UIView.getValueScaledByScreenHeightFor(baseValue: 10),
27 | leftRightMargin: UIView.getValueScaledByScreenWidthFor(baseValue: 0),
28 | cellSpacing: UIView.getValueScaledByScreenWidthFor(baseValue: 10))
29 | self.collectionView?.collectionViewLayout = layout
30 | self.collectionView?.backgroundColor = Stylesheet.Colors.light
31 | }
32 |
33 | required init?(coder aDecoder: NSCoder) {
34 | fatalError("init(coder:) has not been implemented")
35 | }
36 |
37 | // MARK: UICollectionViewDataSource
38 |
39 | func numberOfSections(in collectionView: UICollectionView) -> Int {
40 | // #warning Incomplete implementation, return the number of sections
41 | return 1
42 | }
43 |
44 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
45 | // #warning Incomplete implementation, return the number of items
46 | return 6
47 | }
48 |
49 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
50 | guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? ItemCollectionViewCell else {
51 | return UICollectionViewCell()
52 | }
53 |
54 | // Configure the cell
55 | cell.setupSkeletonCell()
56 |
57 | return cell
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SEDaily-IOS/StateController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StateController.swift
3 | // ExpandableOverlay
4 | //
5 | // Created by Dawid Cedrych on 6/18/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class StateController {
12 |
13 | var isFirstLoad = true
14 |
15 | var isOverlayShowing = false
16 |
17 | private var currentlyPlayingId: String = ""
18 |
19 | func setCurrentlyPlaying(id: String) {
20 | currentlyPlayingId = id
21 | }
22 |
23 | func getCurrentlyPlayingId()-> String {
24 | return currentlyPlayingId
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SEDaily-IOS/SubscriptionModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubscriptionModel.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 1/15/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct StripeModel: Codable {
12 | let _id: String
13 | let planFrequency: String
14 | let dateCreated: String
15 | }
16 |
17 | public struct SubscriptionModel: Codable {
18 | let _id: String
19 | let createdAt: String
20 | let username: String
21 | let subscription: StripeModel
22 | }
23 |
24 | extension SubscriptionModel {
25 | func getCreatedAtDate() -> Date? {
26 | let date = Date(iso8601String: self.subscription.dateCreated)
27 | return date
28 | }
29 |
30 | func getPlanFrequency() -> String {
31 | return self.subscription.planFrequency.capitalized
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/SEDaily-IOS/SummaryCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SummaryCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/5/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Reusable
11 | import UIKit
12 |
13 | class SummaryCell: UITableViewCell, Reusable {
14 |
15 | private var label: UILabel = UILabel()
16 |
17 | var viewModel: ViewModel = ViewModel() {
18 | didSet {
19 | label.text = viewModel.text
20 | setupLayout(style: viewModel.style)
21 |
22 | }
23 | }
24 |
25 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
26 | super.init(style: style, reuseIdentifier: reuseIdentifier)
27 | contentView.addSubview(label)
28 | self.isUserInteractionEnabled = true
29 | self.selectionStyle = .none
30 | }
31 |
32 | required init
33 | (coder aDecoder: NSCoder) {
34 | fatalError("init(coder:)")
35 | }
36 | }
37 |
38 |
39 | extension SummaryCell {
40 | private func setupLayout(style: ViewModel.Style) {
41 |
42 | label.snp.updateConstraints { (make) in
43 | make.left.right.equalToSuperview().offset(style.marginX)
44 | make.right.equalToSuperview().inset(style.marginX)
45 | make.top.equalToSuperview().offset(style.marginY)
46 | make.bottom.equalToSuperview().inset(style.marginY)
47 | }
48 | label.textAlignment = style.alignment
49 | label.font = style.font
50 | label.textColor = style.color
51 | label.numberOfLines = 0
52 | }
53 | }
54 |
55 | // MARK: - ViewModel
56 | extension SummaryCell {
57 | struct ViewModel {
58 | struct Style {
59 | var marginX: CGFloat = 0
60 | var marginY: CGFloat = 0
61 | var font: UIFont = UIFont(name: "Roboto", size: 10.0)! //arbitrary
62 | var color = UIColor.clear
63 | var alignment = NSTextAlignment.left
64 | }
65 | var text = ""
66 | var style = Style()
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/SEDaily-IOS/TagsCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TagsCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/14/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Reusable
11 | import Tags
12 |
13 | class TagsCell: UITableViewCell, Reusable, UIScrollViewDelegate {
14 |
15 | let tagsView = TagsView()
16 | let scrollView = UIScrollView()
17 |
18 | var topics:[String] = [] { willSet {
19 | guard newValue != self.topics else { return }
20 | }
21 | didSet {
22 | tagsView.set(contentsOf: topics)
23 | tagsView.lastTag = "+"
24 | print(tagsView.frame.width)
25 | }
26 | }
27 |
28 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
29 | super.init(style: style, reuseIdentifier: reuseIdentifier)
30 | setupLayout()
31 | scrollView.delegate = self
32 |
33 | }
34 | required init
35 | (coder aDecoder: NSCoder) {
36 | fatalError("init(coder:)")
37 | }
38 |
39 | override func layoutSubviews() {
40 | print(self.contentView.height)
41 | }
42 |
43 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
44 | if scrollView.contentOffset.y > 0 || scrollView.contentOffset.y < 0 {
45 | scrollView.contentOffset.y = 0
46 | }
47 | }
48 |
49 | }
50 |
51 | extension TagsCell {
52 | private func setupLayout() {
53 | scrollView.translatesAutoresizingMaskIntoConstraints = false
54 | tagsView.translatesAutoresizingMaskIntoConstraints = false
55 | scrollView.showsHorizontalScrollIndicator = true
56 | scrollView.backgroundColor = .white
57 | scrollView.contentSize = tagsView.frame.size
58 | let label: UILabel = UILabel()
59 | label.text = ""
60 | contentView.addSubview(scrollView)
61 | scrollView.addSubview(tagsView)
62 | scrollView.addSubview(label)
63 | // layer radius
64 | tagsView.tagLayerRadius = 6
65 | // layer width
66 | tagsView.tagLayerWidth = 1
67 | // layer color
68 | tagsView.tagLayerColor = Stylesheet.Colors.base
69 | // text color
70 | tagsView.tagTitleColor = Stylesheet.Colors.base
71 | // background color
72 | tagsView.tagBackgroundColor = .white
73 | // font
74 | tagsView.tagFont = .systemFont(ofSize: 15)
75 | // text longer ...
76 | tagsView.lineBreakMode = .byTruncatingMiddle
77 |
78 | scrollView.snp.makeConstraints { (make) in
79 | make.top.left.right.bottom.equalToSuperview()
80 | }
81 |
82 | tagsView.snp.makeConstraints { (make) in
83 | make.top.left.right.bottom.equalToSuperview()
84 | //make.height.equalTo(30.0)
85 | make.width.equalTo(5000.0) // this is a workaround for scrollView
86 | }
87 |
88 | if #available(iOS 11, *) {
89 | scrollView.contentInsetAdjustmentBehavior = .never
90 | }
91 | scrollView.contentSize.height = 1.0
92 | //scrollView.contentSize = tagsView.frame.size
93 |
94 |
95 | }
96 | }
97 |
98 |
99 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ThreadHeaderView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ThreadHeaderView.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by jason on 4/28/18.
6 | // Copyright © 2018 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Down
11 |
12 | class ThreadHeaderView: UIView {
13 |
14 | @IBOutlet weak var titleLabel: UILabel!
15 | @IBOutlet weak var contentLabel: UILabel!
16 | @IBOutlet weak var authorLabel: UILabel!
17 | @IBOutlet weak var dateLabel: UILabel!
18 | @IBOutlet weak var commentCountLabel: UILabel!
19 |
20 | var thread: ForumThread? {
21 | didSet {
22 | titleLabel.text = thread?.title
23 | if let threadContent = thread?.content {
24 | let content = Down(markdownString: threadContent)
25 | contentLabel.attributedText = try? content.toAttributedString()
26 | }
27 | commentCountLabel.text = thread?.getCommentsSummary()
28 | if let author = thread?.author {
29 | authorLabel.text = (author.name != nil) ? author.name : author.username
30 | }
31 | dateLabel.text = thread?.getDatedCreatedPretty()
32 | if let thread = thread {
33 | Analytics2.forumThreadViewed(forumThread: thread)
34 | Tracker.logForumThreadViewed(forumThread: thread)
35 | }
36 | }
37 | }
38 |
39 | /*
40 | // Only override draw() if you perform custom drawing.
41 | // An empty implementation adversely affects performance during animation.
42 | override func draw(_ rect: CGRect) {
43 | // Drawing code
44 | }
45 | */
46 |
47 | override func layoutSubviews() {
48 | super.layoutSubviews()
49 | titleLabel.preferredMaxLayoutWidth = titleLabel.bounds.width
50 |
51 | contentLabel.preferredMaxLayoutWidth = titleLabel.bounds.width
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/SEDaily-IOS/Topic.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Topic.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/14/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct Topic: Codable {
12 | let _id: String
13 | let name: String
14 | let slug: String
15 | let status: String
16 | let postCount: Int
17 | }
18 |
19 | extension Topic: Equatable {
20 | public static func == (lhs: Topic, rhs: Topic) -> Bool {
21 | return lhs._id == rhs._id &&
22 | lhs.name == rhs.name &&
23 | lhs.slug == rhs.slug &&
24 | lhs.status == rhs.status &&
25 | lhs.postCount == rhs.postCount
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SEDaily-IOS/UIButtonExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIButtonExtension.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Craig Holliday on 6/27/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIButton {
12 | func setBackgroundColor(color: UIColor, forState: UIControlState) {
13 | UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
14 | UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
15 | UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
16 | let colorImage = UIGraphicsGetImageFromCurrentImageContext()
17 | UIGraphicsEndImageContext()
18 | self.setBackgroundImage(colorImage, for: forState)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SEDaily-IOS/UIColor+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Extensions.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/30/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension UIColor {
13 | func brightened(by factor: CGFloat) -> UIColor {
14 | var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
15 | getHue(&h, saturation: &s, brightness: &b, alpha: &a)
16 | return UIColor(hue: h, saturation: s, brightness: b * factor, alpha: a)
17 | }
18 |
19 | func getGradientColors(brightenedBy: CGFloat) -> [Any] {
20 | return [self.cgColor,
21 | self.brightened(by: brightenedBy).cgColor,
22 | self.cgColor]
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/SEDaily-IOS/URLSchemaHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLSchemaHelper.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/14/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class URLSchemaHelper {
12 | class func addSchema(url: String)->String {
13 | var urlString: String = url
14 | let urlPrefix = urlString.prefix(4)
15 | if urlPrefix != "http" {
16 | // Defaulting to http:
17 | if urlPrefix.prefix(3) == "://" {
18 | urlString = "http\(url)"
19 | } else {
20 | urlString = "http://\(url)"
21 | }
22 | }
23 | return urlString
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/SEDaily-IOS/UpvoteService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UpvoteService.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 4/23/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | protocol UpvoteServiceUIDelegate: class {
10 | func upvoteUIDidChange(isUpvoted: Bool, score: Int)
11 | func upvoteUIImmediateUpdate()
12 | }
13 |
14 |
15 | import Foundation
16 |
17 | class UpvoteService {
18 |
19 | private let networkService = API()
20 |
21 | var podcastViewModel: PodcastViewModel {
22 | didSet {
23 | updateViewModel()
24 | updateUI(isUpvoted: self.podcastViewModel.isUpvoted, score: self.podcastViewModel.score)
25 | }
26 | }
27 |
28 | weak var UIDelegate: UpvoteServiceUIDelegate?
29 |
30 | init(podcastViewModel: PodcastViewModel) {
31 | self.podcastViewModel = podcastViewModel
32 | }
33 |
34 | func upvote() {
35 | guard UserManager.sharedInstance.isCurrentUserLoggedIn() == true else {
36 | Helpers.alertWithMessage(title: Helpers.Alerts.error, message: Helpers.Messages.youMustLogin, completionHandler: nil)
37 | return
38 | }
39 | self.UIDelegate?.upvoteUIImmediateUpdate()
40 |
41 | let podcastId = self.podcastViewModel._id
42 | networkService.upvotePodcast(podcastId: podcastId, completion: { [weak self] (success, active) in
43 | guard success != nil else {
44 | self?.UIDelegate?.upvoteUIImmediateUpdate()
45 | return
46 | }
47 | if success == true {
48 | guard let active = active else { return }
49 | self?.addScore(active: active)
50 | self?.setStatus(active: active)
51 | } else { self?.UIDelegate?.upvoteUIImmediateUpdate() }
52 | })
53 | }
54 |
55 | func addScore(active: Bool) {
56 | guard active != false else {
57 | self.setScoreTo(self.podcastViewModel.score - 1)
58 | return
59 | }
60 | self.setScoreTo(self.podcastViewModel.score + 1)
61 | }
62 |
63 | private func updateViewModel() {
64 | let userInfo = ["viewModel": podcastViewModel]
65 | NotificationCenter.default.post(name: .viewModelUpdated, object: nil, userInfo: userInfo)
66 | }
67 | private func updateUI(isUpvoted: Bool, score: Int) {
68 | self.UIDelegate?.upvoteUIDidChange(isUpvoted: isUpvoted, score: self.podcastViewModel.score)
69 | }
70 |
71 | func setScoreTo(_ score: Int) {
72 | guard self.podcastViewModel.score != score else { return }
73 | self.podcastViewModel.score = score
74 | }
75 | private func setStatus(active: Bool) {
76 | self.podcastViewModel.isUpvoted = active
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/SEDaily-IOS/User+ProfileViewController.Section.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User+ProfileViewController.Section.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 6/5/19.
6 | // Copyright © 2019 Altalogy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension User {
13 | subscript(row: ProfileViewController.Section.SummaryRow) -> Any? {
14 | switch row {
15 | case .bio: return bio
16 | case .name: return name ?? username
17 | case .username: return username
18 | case .avatar: return URL(string: avatarUrl ?? "https://sd-profile-pictures.s3.amazonaws.com/5d03934823a39c002ae7dd70")
19 | case .link: return website
20 | case .signInPlaceholder: return nil
21 | }
22 | }
23 | }
24 |
25 | extension UITableView {
26 | func dequeueReusableCell(for indexPath: IndexPath) -> Cell? {
27 | return dequeueReusableCell(withIdentifier: String(describing: Cell.self), for: indexPath) as? Cell
28 | }
29 |
30 | func dequeueReusableCell(with type: Cell.Type, for indexPath: IndexPath) -> Cell? {
31 | return dequeueReusableCell(withIdentifier: String(describing: type), for: indexPath) as? Cell
32 | }
33 | }
34 |
35 |
36 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ViewPlayground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: A UIKit based Playground for presenting user interface
2 |
3 | import UIKit
4 | import PlaygroundSupport
5 | import ViewPlayground_Sources
6 |
7 | class PodcastCell: UICollectionViewCell {
8 | var imageView: UIImageView!
9 | var titleLabel: UILabel!
10 | var timeDayLabel: UILabel!
11 |
12 | override init(frame: CGRect) {
13 | super.init(frame: frame)
14 | self.backgroundColor = .white
15 | let newContentView = UIView(width: 158, height: 250)
16 | self.contentView.frame = newContentView.frame
17 |
18 | imageView = UIImageView(leftInset: 0, topInset: 4, width: 158)
19 | self.contentView.addSubview(imageView)
20 | self.addSubview(imageView)
21 |
22 | titleLabel = UILabel(origin: imageView.bottomLeftPoint(), topInset: 15, width: 158, height: 50)
23 | self.addSubview(titleLabel)
24 |
25 | timeDayLabel = UILabel(origin: titleLabel.bottomLeftPoint(), topInset: 8, width: 158, height: 10)
26 | self.addSubview(timeDayLabel)
27 | }
28 |
29 | required init(coder aDecoder: NSCoder) {
30 | fatalError("init(coder:)")
31 | }
32 |
33 | func setupCell(image: UIImage, title: String, timeLength: Int, date: Date) {
34 | imageView.image = image
35 | titleLabel.text = title
36 | timeDayLabel.text
37 | }
38 | }
39 |
40 | extension PodcastCell {
41 | func setupSkeletonCell() {
42 |
43 | }
44 | }
45 |
46 | // Present the view controller in the Live View window
47 | let frame = CGRect(x: 0, y: 0, width: UIView.getValueScaledByScreenWidthFor(baseValue: 158), height: UIView.getValueScaledByScreenHeightFor(baseValue: 400))
48 | let cell = PodcastCell(frame: frame)
49 | cell.titleLabel.text = "An American Success Story"
50 | PlaygroundPage.current.liveView = cell
51 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ViewPlayground.playground/Sources/KTResponsiveUI/KTResponsiveUI/Classes/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // KTResponsiveUI_Example
4 | //
5 | // Created by Craig Holliday on 8/28/17.
6 | // Copyright © 2017 CocoaPods. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let iphone7Height: CGFloat = 667.0
12 | let iphone7Width: CGFloat = 375.0
13 |
14 | public extension UIView {
15 | public func topRightPoint() -> CGPoint {
16 | return CGPoint(x: self.frame.maxX, y: self.frame.minY)
17 | }
18 |
19 | public func topMidPoint() -> CGPoint {
20 | return CGPoint(x: self.frame.midX, y: self.frame.minY)
21 | }
22 |
23 | public func topLeftPoint() -> CGPoint {
24 | return CGPoint(x: self.frame.minX, y: self.frame.minY)
25 | }
26 |
27 | public func bottomRightPoint() -> CGPoint {
28 | return CGPoint(x: self.frame.maxX, y: self.frame.maxY)
29 | }
30 |
31 | public func bottomMidPoint() -> CGPoint {
32 | return CGPoint(x: self.frame.midX, y: self.frame.maxY)
33 | }
34 |
35 | public func bottomLeftPoint() -> CGPoint {
36 | return CGPoint(x: self.frame.minX, y: self.frame.maxY)
37 | }
38 |
39 | public func leftMidPoint() -> CGPoint {
40 | return CGPoint(x: self.frame.minX, y: self.frame.midY)
41 | }
42 |
43 | public func rightMidPoint() -> CGPoint {
44 | return CGPoint(x: self.frame.maxX, y: self.frame.midY)
45 | }
46 |
47 | public class func getValueScaledByScreenHeightFor(baseValue: CGFloat) -> CGFloat {
48 | let screenHeight = UIScreen.main.bounds.height
49 | let divisor: CGFloat = iphone7Height / baseValue
50 | let calculatedHeight = screenHeight / divisor
51 | return calculatedHeight
52 | }
53 |
54 | public class func getValueScaledByScreenWidthFor(baseValue: CGFloat) -> CGFloat {
55 | let screenWidth = UIScreen.main.bounds.width
56 | let divisor: CGFloat = iphone7Width / baseValue
57 | let calculatedWidth = screenWidth / divisor
58 | return calculatedWidth
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ViewPlayground.playground/Sources/KTResponsiveUI/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 themisterholliday
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ViewPlayground.playground/Sources/KTResponsiveUI/README.md:
--------------------------------------------------------------------------------
1 | # KTResponsiveUI (WIP)
2 |
3 | [](https://travis-ci.org/themisterholliday/KTResponsiveUI)
4 | [](http://cocoapods.org/pods/KTResponsiveUI)
5 | [](http://cocoapods.org/pods/KTResponsiveUI)
6 | [](http://cocoapods.org/pods/KTResponsiveUI)
7 |
8 | ## Example
9 |
10 | To run the example project, clone the repo, and run `pod install` from the Example directory first.
11 |
12 | ## Requirements
13 |
14 | ## Installation
15 |
16 | KTResponsiveUI is available through [CocoaPods](http://cocoapods.org). To install
17 | it, simply add the following line to your Podfile:
18 |
19 | ```ruby
20 | pod 'KTResponsiveUI'
21 | ```
22 |
23 | ## Author
24 |
25 | themisterholliday, themisterholliday@gmail.com
26 |
27 | ## License
28 |
29 | KTResponsiveUI is available under the MIT license. See the LICENSE file for more info.
30 |
--------------------------------------------------------------------------------
/SEDaily-IOS/ViewPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/SEDaily-IOS/WebViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WebViewCell.swift
3 | // SEDaily-IOS
4 | //
5 | // Created by Dawid Cedrych on 5/2/19.
6 | // Copyright © 2019 Koala Tea. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Reusable
11 | import WebKit
12 | import SnapKit
13 |
14 |
15 | class WebViewCell: UITableViewCell, Reusable {
16 |
17 | var webView: WKWebView!
18 |
19 | var webViewHeight: CGFloat = 0.0 {
20 | didSet {
21 | snp.removeConstraints()
22 | webView.snp.remakeConstraints { (make) in
23 | make.left.top.right.bottom.equalToSuperview()
24 | make.height.equalTo(webViewHeight).priority(999)
25 | make.width.equalToSuperview()
26 | }
27 | }
28 | }
29 |
30 | var delegate: WebViewCellDelegate?
31 |
32 |
33 | override func awakeFromNib() {
34 | super.awakeFromNib()
35 | // Initialization code
36 | }
37 |
38 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
39 | super.init(style: style, reuseIdentifier: reuseIdentifier)
40 | webView = WKWebView()
41 | self.contentView.addSubview(webView)
42 | webView.scrollView.snp.makeConstraints { make in
43 | make.left.equalToSuperview().offset(15.0)
44 | make.right.equalToSuperview().offset(-15.0)
45 | }
46 | }
47 |
48 | required init
49 | (coder aDecoder: NSCoder) {
50 | fatalError("init(coder:)")
51 | }
52 |
53 | override func setSelected(_ selected: Bool, animated: Bool) {
54 | super.setSelected(selected, animated: animated)
55 | }
56 | }
57 |
58 |
59 |
60 | extension WebViewCell: WKNavigationDelegate {
61 | func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
62 | webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
63 | if complete != nil {
64 | webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
65 | guard let h:CGFloat = height as? CGFloat else { return }
66 | self.delegate?.updateWebViewHeight(didCalculateHeight: h)
67 | })
68 | }
69 | })
70 | }
71 | func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
72 | if navigationAction.navigationType == .linkActivated {
73 | if let url = navigationAction.request.url,
74 | UIApplication.shared.canOpenURL(url) {
75 | UIApplication.shared.open(url)
76 | decisionHandler(.cancel)
77 | } else {
78 | decisionHandler(.allow)
79 | }
80 | } else {
81 | decisionHandler(.allow)
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/SEDaily-IOS/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | SEDaily-IOS
4 |
5 | Created by Justin Lam on 10/6/17.
6 | Copyright © 2017 Koala Tea. All rights reserved.
7 | */
8 |
--------------------------------------------------------------------------------
/SEDaily-IOS/fr.lproj/LaunchScreen.strings:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/SEDaily-IOS/fr.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | SEDaily-IOS
4 |
5 | Created by Justin Lam on 10/6/17.
6 | Copyright © 2017 Koala Tea. All rights reserved.
7 | */
8 |
9 | /* */
10 | "TabBarTitleLatest" = "Latest*";
11 | "TabBarJustForYou" = "Just For You*";
12 | "TabTitleAll" = "All*";
13 | "TabTitleBusinessAndPhilosophy" = "Business and Philosophy*";
14 | "TabTitleBlockchain" = "Blockchain*";
15 | "TabTitleCloudEngineering" = "Cloud Engineering*";
16 | "TabTitleData" = "Data*";
17 | "TabTitleJavaScript" = "JavaScript*";
18 | "TabTitleMachineLearning" = "Machine Learning*";
19 | "TabTitleOpenSource" = "Open Source*";
20 | "TabTitleSecurity" = "Security*";
21 | "TabTitleHackers" = "Hackers*";
22 | "TabTitleGreatestHits" = "Greatest Hits*";
23 | "LoginTitle" = "Login*";
24 | "LogoutTitle" = "Logout*";
25 | "EmailAddressPlaceholder" = "Email*";
26 | "PasswordPlaceholder" = "Password*";
27 | "ConfirmPasswordPlaceholder" = "Confirm Password*";
28 | "FirstNamePlaceholder" = "First Name*";
29 | "LastNamePlaceholder" = "Last Name*";
30 | "LoginButtonTitle" = "Login*";
31 | "CancelButtonTitle" = "Cancel*";
32 | "SignUpButtonTitle" = "Sign Up*";
33 | "AlertMessageEmailEmpty" = "Email Field Empty*";
34 | "AlertMessagePasswordEmpty" = "Password Field Empty*";
35 | "AlertMessagePasswordConfirmEmpty" = "Confirm Password Field Empty*";
36 | "AlertMessageEmailWrongFormat" = "Invalid Email Format*";
37 | "AlertMessagePasswordNotLongEnough" = "Password must be longer than 6 characters*";
38 | "AlertMessagePasswordsDonotMatch" = "Password do not match*";
39 | "AlertMessageFirstNameEmpty" = "First Name Field Empty*";
40 | "AlertMessageFirstNameNotLongEnough" = "First Name must be longer than 1 characters*";
41 | "AlertMessageLastNameEmpty" = "Last Name Field Empty*";
42 | "AlertMessageLastNameNotLongEnough" = "Last Name must be longer than 1 characters*";
43 | "AlertMessagePleaseLogin" = "Please Login*";
44 | "AlertMessageIssueWithUserToken" = "Issue with User Token*";
45 | "AlertMessageYouMustLogin" = "You must login to use this feature.*";
46 | "AlertMessageLogoutSuccess" = "Successfully Logged Out*";
47 | "GenericSuccess" = "Success*";
48 | "GenericError" = "Error*";
49 | "GenericOkay" = "Okay*";
50 | "GenericOK" = "OK*";
51 | "Play" = "Play*";
52 | "NoBookmarks" = "No Bookmarks*";
53 | "LoginSeeBookmarks" = "Login to see your bookmarks*";
54 | "TapToRefresh" = "Tap to refresh*";
55 |
--------------------------------------------------------------------------------
/SEDaily-IOS/fr.lproj/Main.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "UITabBarItem"; title = "Item 1"; ObjectID = "1oc-bk-EZe"; */
3 | "1oc-bk-EZe.title" = "Item 1";
4 |
5 | /* Class = "UITabBarItem"; title = "Item 2"; ObjectID = "teR-pK-dgQ"; */
6 | "teR-pK-dgQ.title" = "Item 2";
7 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/HelpersTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HelpersTests.swift
3 | // SEDaily-IOSTests
4 | //
5 | // Created by Berk Mollamustafaoglu on 25/11/2017.
6 | //
7 | //
8 |
9 | import XCTest
10 | import Quick
11 | import Nimble
12 | @testable import SEDaily_IOS
13 |
14 | class HelpersTests: QuickSpec {
15 |
16 | override func spec() {
17 | describe("isValidEmailAddress") {
18 | it("accepts regular email address format") {
19 | expect(Helpers.isValidEmailAddress(emailAddressString: "test@example.com")).to(beTrue())
20 | }
21 |
22 | it("accepts dots and underscores") {
23 | expect(Helpers.isValidEmailAddress(emailAddressString: "test.exampl_e@example.com")).to(beTrue())
24 | }
25 |
26 | it("accepts letters and numbers") {
27 | expect(Helpers.isValidEmailAddress(emailAddressString: "test.exampl_e981@example.com")).to(beTrue())
28 | }
29 |
30 | it("accepts emails with multiple dots") {
31 | expect(Helpers.isValidEmailAddress(emailAddressString: "bla@university.ac.uk")).to(beTrue())
32 | }
33 |
34 | it("doesn't accept empty string before the @ sign") {
35 | expect(Helpers.isValidEmailAddress(emailAddressString: "@example.com")).to(beFalse())
36 | }
37 |
38 | it("doesn't accept characters other than dots and underscores in the main part of the address") {
39 | expect(Helpers.isValidEmailAddress(emailAddressString: "test.exam&pl_e981@example.com")).to(beFalse())
40 | }
41 |
42 | it("doesn't accept single characters after the final dot") {
43 | expect(Helpers.isValidEmailAddress(emailAddressString: "test@example.c")).to(beFalse())
44 | }
45 |
46 | it("doesn't accept numbers after the final dot") {
47 | expect(Helpers.isValidEmailAddress(emailAddressString: "test@example.coa3f")).to(beFalse())
48 | }
49 |
50 | it("doesn't accept symbols after the final dot") {
51 | expect(Helpers.isValidEmailAddress(emailAddressString: "test@example.co/f")).to(beFalse())
52 | }
53 |
54 | }
55 |
56 | describe("getStringFrom tests") {
57 | it("displays the value if the value is above 10") {
58 | expect(Helpers.getStringFrom(seconds: 15)).to(equal("15"))
59 | }
60 |
61 | it("displays the value with a leading zero if it's below 10") {
62 | expect(Helpers.getStringFrom(seconds: 9)).to(equal("09"))
63 | }
64 | }
65 |
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/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 | CFBundleVersion
20 | 10
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/login/login_nonexistinguser.json:
--------------------------------------------------------------------------------
1 | {"message":"User not found."}
2 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/login/login_success.json:
--------------------------------------------------------------------------------
1 | {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YTVhOTgyZjdlNGY0MDAwMmEzMDEyZGEiLCJlbWFpbCI6ImJlcmt0ZXN0MTFAdGVzdC5jb20iLCJ1c2VybmFtZSI6ImJtIiwicGFzc3dvcmQiOiIkMmEkMDgkMUpRbnY5OGx2S2k4L0tiT29GVmk5dXM3YU5NME9WWTBHcHYwOFplM2E4YS4yWDlHd2pJdUsiLCJfX3YiOjAsImNyZWF0ZWRBdCI6IjIwMTgtMDEtMTNUMjM6Mzc6MTkuNTc2WiIsInZlcmlmaWVkIjpmYWxzZSwiaWF0IjoxNTE2MTMzNjEzLCJleHAiOjE2NjAxMzM2MTN9.5omwn1EzDPqyzfyMLcVbGdpaSlNAKvzwfQ_4HeEBdws"}
2 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/login/login_wrongpass.json:
--------------------------------------------------------------------------------
1 | {"message":"Password is incorrect."}
2 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/posts/upvote_failure.json:
--------------------------------------------------------------------------------
1 | {
2 | "message": "Not Found",
3 | "stack": {}
4 | }
5 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/posts/upvote_success.json:
--------------------------------------------------------------------------------
1 | {
2 | "_id": "5a63b51866503d002a70f809",
3 | "direction": "upvote",
4 | "userId": "5a5a982f7e4f40002a3012da",
5 | "postId": "59df362f4a8a50462d2b475e",
6 | "entityId": "59df362f4a8a50462d2b475e",
7 | "__v": 0,
8 | "active": true
9 | }
10 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/register/register_emptyusernamepass.json:
--------------------------------------------------------------------------------
1 | {
2 | "message": "\"username\" is not allowed to be empty and \"password\" is not allowed to be empty",
3 | "stack": {}
4 | }
5 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/register/register_success.json:
--------------------------------------------------------------------------------
1 | {
2 | "user": {
3 | "__v": 0,
4 | "username": "testuser@test.com",
5 | "password": "$2a$08$PmyX0n5VMY8zVte7.dDGMOdSIP1oU7FfBWN9uCukjp1.V4ryFqtmW",
6 | "_id": "5a60ff9de29fa3002a639e5a",
7 | "createdAt": "2018-01-18T20:12:13.358Z",
8 | "verified": false
9 | },
10 | "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfX3YiOjAsInVzZXJuYW1lIjoiYmVya3Rlc3QxMTExMUB0ZXN0LmNvbSIsInBhc3N3b3JkIjoiJDJhJDA4JFBteVgwbjVWTVk4elZ0ZTcuZERHTU9kU0lQMW9VN0ZmQldOOXVDdWtqcDEuVjRyeUZxdG1XIiwiX2lkIjoiNWE2MGZmOWRlMjlmYTMwMDJhNjM5ZTVhIiwiY3JlYXRlZEF0IjoiMjAxOC0wMS0xOFQyMDoxMjoxMy4zNThaIiwidmVyaWZpZWQiOmZhbHNlLCJpYXQiOjE1MTYzMDYzMzMsImV4cCI6MTY2MDMwNjMzM30.uk4ixawSQ11vcS2Cvw3MoxlTvwNlCBnu8MUzE9QgqQM"
11 | }
12 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/Responses/register/register_userexists.json:
--------------------------------------------------------------------------------
1 | {
2 | "message": "User already exists.",
3 | "stack": {}
4 | }
5 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/Mocks/UserDefaultsMock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserDefaultsMock.swift
3 | // SEDaily-IOSTests
4 | //
5 | // Created by Berk Mollamustafaoglu on 26/11/2017.
6 | //
7 | //
8 |
9 | import Foundation
10 | @testable import SEDaily_IOS
11 |
12 | class UserDefaultsMock: UserDefaultsProtocol {
13 |
14 | var dict: [String: Any]
15 |
16 | init(dict: [String: Any]) {
17 | self.dict = dict
18 | }
19 |
20 | func set(_ value: Any?, forKey defaultName: String) {
21 | if let validValue = value {
22 | dict[defaultName] = validValue
23 | }
24 | }
25 |
26 | func data(forKey defaultName: String) -> Data? {
27 | let dataObj = dict[defaultName] as? Data
28 | return dataObj
29 | }
30 |
31 | }
32 |
33 |
34 |
--------------------------------------------------------------------------------
/SEDaily-IOSTests/SEDailyIOSTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SEDaily_IOSTests.swift
3 | // SEDaily-IOSTests
4 | //
5 | // Created by Craig Holliday on 6/25/17.
6 | // Copyright © 2017 Koala Tea. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import SEDaily_IOS
11 |
12 | class SEDailyIOSTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | app_identifier "koala-tea.SEDaily" # The bundle identifier of your app
2 | apple_id "hollidaycraig@yahoo.com" # Your Apple email address
3 |
4 | team_id "54L2FT34WS" # Developer Portal Team ID
5 |
6 | itc_team_id "117695750"
7 | # you can even provide different app identifiers, Apple IDs and team names per lane:
8 | # More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md
9 |
--------------------------------------------------------------------------------
/fastlane/Deliverfile:
--------------------------------------------------------------------------------
1 | ###################### More Options ######################
2 | # If you want to have even more control, check out the documentation
3 | # https://github.com/fastlane/fastlane/blob/master/deliver/Deliverfile.md
4 |
5 |
6 | ###################### Automatically generated ######################
7 | # Feel free to remove the following line if you use fastlane (which you should)
8 |
9 | app_identifier "koala-tea.SEDaily" # The bundle identifier of your app
10 | username "hollidaycraig@yahoo.com" # your Apple ID user
11 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | # Customise this file, documentation can be found here:
2 | # https://github.com/fastlane/fastlane/tree/master/fastlane/docs
3 | # All available actions: https://docs.fastlane.tools/actions
4 | # can also be listed using the `fastlane actions` command
5 |
6 | # Change the syntax highlighting to Ruby
7 | # All lines starting with a # are ignored when running `fastlane`
8 |
9 | # If you want to automatically update fastlane if a new version is available:
10 | # update_fastlane
11 |
12 | # This is the minimum version number required.
13 | # Update this, if you use features of a newer version
14 | fastlane_version "2.42.0"
15 |
16 | default_platform :ios
17 |
18 | platform :ios do
19 | before_all do
20 | # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
21 | cocoapods
22 |
23 | end
24 |
25 | desc "Runs all the tests"
26 | lane :test do
27 | scan
28 | end
29 |
30 | desc "Submit a new Beta Build to Apple TestFlight"
31 | desc "This will also make sure the profile is up to date"
32 | lane :beta do
33 | # match(type: "appstore") # more information: https://codesigning.guide
34 | increment_build_number
35 | gym(scheme: "SEDaily-IOS") # Build your app - more options available
36 | pilot
37 |
38 | # sh "your_script.sh"
39 | # You can also use other beta testing services here (run `fastlane actions`)
40 | end
41 |
42 | desc "Deploy a new version to the App Store"
43 | lane :release do
44 | # match(type: "appstore")
45 | # snapshot
46 | gym(scheme: "SEDaily-IOS") # Build your app - more options available
47 | deliver(force: true)
48 | # frameit
49 | end
50 |
51 | # You can define as many lanes as you want
52 |
53 | after_all do |lane|
54 | # This block is called, only if the executed lane was successful
55 |
56 | # slack(
57 | # message: "Successfully deployed new App Update."
58 | # )
59 | end
60 |
61 | error do |lane, exception|
62 | # slack(
63 | # message: exception.message,
64 | # success: false
65 | # )
66 | end
67 |
68 | desc "Create ipa"
69 | lane :build do
70 | increment_build_number
71 | gym(scheme: "SEDaily-IOS")
72 | end
73 |
74 | desc "Upload to App Store"
75 | lane :upload do
76 | deliver(force: true)
77 | end
78 | end
79 |
80 |
81 | # More information about multiple platforms in fastlane: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md
82 | # All available actions: https://docs.fastlane.tools/actions
83 |
84 | # fastlane reports which actions are used. No personal data is recorded.
85 | # Learn more at https://github.com/fastlane/fastlane#metrics
86 |
--------------------------------------------------------------------------------
/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ================
3 | # Installation
4 |
5 | Make sure you have the latest version of the Xcode command line tools installed:
6 |
7 | ```
8 | xcode-select --install
9 | ```
10 |
11 | Install _fastlane_ using
12 | ```
13 | [sudo] gem install fastlane -NV
14 | ```
15 | or alternatively using `brew cask install fastlane`
16 |
17 | # Available Actions
18 | ## iOS
19 | ### ios test
20 | ```
21 | fastlane ios test
22 | ```
23 | Runs all the tests
24 | ### ios beta
25 | ```
26 | fastlane ios beta
27 | ```
28 | Submit a new Beta Build to Apple TestFlight
29 |
30 | This will also make sure the profile is up to date
31 | ### ios release
32 | ```
33 | fastlane ios release
34 | ```
35 | Deploy a new version to the App Store
36 | ### ios build
37 | ```
38 | fastlane ios build
39 | ```
40 | Create ipa
41 | ### ios upload
42 | ```
43 | fastlane ios upload
44 | ```
45 | Upload to App Store
46 |
47 | ----
48 |
49 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
50 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
51 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
52 |
--------------------------------------------------------------------------------
/fastlane/metadata/copyright.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/description.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/keywords.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/marketing_url.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/name.txt:
--------------------------------------------------------------------------------
1 | SEDaily
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/privacy_url.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/promotional_text.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/release_notes.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/subtitle.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/en-US/support_url.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/primary_category.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/primary_first_sub_category.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/primary_second_sub_category.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/demo_password.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/demo_user.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/email_address.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/first_name.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/last_name.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/notes.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/review_information/phone_number.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/secondary_category.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/secondary_first_sub_category.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/secondary_second_sub_category.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/address_line1.txt:
--------------------------------------------------------------------------------
1 | 2711 Parkview Dr
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/city_name.txt:
--------------------------------------------------------------------------------
1 | Corinth
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/country.txt:
--------------------------------------------------------------------------------
1 | United States
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/is_displayed_on_app_store.txt:
--------------------------------------------------------------------------------
1 | false
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/postal_code.txt:
--------------------------------------------------------------------------------
1 | 76210
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/state.txt:
--------------------------------------------------------------------------------
1 | Texas
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/trade_representative_contact_information/trade_name.txt:
--------------------------------------------------------------------------------
1 | Keith Holliday
2 |
--------------------------------------------------------------------------------
/screenshots/app_screenshots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SoftwareEngineeringDaily/se-daily-iOS/a29d0f99d5eb34b683806e6d5292c4fe4addf3af/screenshots/app_screenshots.png
--------------------------------------------------------------------------------