diff --git a/GitTime/Sources/CompositionRoot.swift b/GitTime/Sources/CompositionRoot.swift index d717f02..0b4d6c6 100644 --- a/GitTime/Sources/CompositionRoot.swift +++ b/GitTime/Sources/CompositionRoot.swift @@ -70,7 +70,9 @@ final class CompositionRoot { let activityController = configureActivityScreen(activityService: activityService, userService: userService, - crawlerService: crawlerService) + crawlerService: crawlerService, + keychainService: keychainService + ) let trendController = configureTrendingScreen(crawlerService: crawlerService, languagesService: languageService, @@ -163,11 +165,14 @@ extension CompositionRoot { static func configureActivityScreen( activityService: ActivityServiceType, userService: UserServiceType, - crawlerService: GitTimeCrawlerServiceType + crawlerService: GitTimeCrawlerServiceType, + keychainService: KeychainServiceType ) -> ActivityViewController { let reactor = ActivityViewReactor(activityService: activityService, userService: userService, - crawlerService: crawlerService) + crawlerService: crawlerService, + keychainService: keychainService + ) let controller = ActivityViewController(reactor: reactor) controller.title = "Activity" controller.tabBarItem.title = "Activity" diff --git a/GitTime/Sources/Models/Event.swift b/GitTime/Sources/Models/Event.swift index 8998093..4a3a3f4 100644 --- a/GitTime/Sources/Models/Event.swift +++ b/GitTime/Sources/Models/Event.swift @@ -73,8 +73,7 @@ struct Event: ModelType { repo = try container.decode(RepositoryInfo.self, forKey: .repo) isPublic = try container.decode(Bool.self, forKey: .isPublic) let dateString = try container.decode(String.self, forKey: .createdAt) - let df = DateFormatter() - df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + let df = ISO8601DateFormatter() createdAt = df.date(from: dateString) ?? Date() switch type { diff --git a/GitTime/Sources/Models/Me.swift b/GitTime/Sources/Models/Me.swift index 5e71f17..f7d4817 100644 --- a/GitTime/Sources/Models/Me.swift +++ b/GitTime/Sources/Models/Me.swift @@ -11,6 +11,7 @@ import Foundation struct Me: ModelType { let id: Int let name: String + let additionalName: String let profileURL: String let url: String let bio: String? @@ -23,6 +24,7 @@ struct Me: ModelType { enum CodingKeys: String, CodingKey { case id case name = "login" + case additionalName = "name" case profileURL = "avatar_url" case url = "html_url" case bio diff --git a/GitTime/Sources/Models/Payload.swift b/GitTime/Sources/Models/Payload.swift index cfecffa..1da74c6 100644 --- a/GitTime/Sources/Models/Payload.swift +++ b/GitTime/Sources/Models/Payload.swift @@ -259,8 +259,7 @@ struct Comment: ModelType { body = try container.decode(String.self, forKey: .body) let dateString = try container.decode(String.self, forKey: .createdAt) - let df = DateFormatter() - df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + let df = ISO8601DateFormatter() createdAt = df.date(from: dateString) ?? Date() } diff --git a/GitTime/Sources/ViewControllers/Activity/ActivityViewReactor.swift b/GitTime/Sources/ViewControllers/Activity/ActivityViewReactor.swift index 247d45a..87cf8bd 100644 --- a/GitTime/Sources/ViewControllers/Activity/ActivityViewReactor.swift +++ b/GitTime/Sources/ViewControllers/Activity/ActivityViewReactor.swift @@ -8,6 +8,7 @@ import UIKit +import GitHubKit import Moya import ReactorKit import RxCocoa @@ -60,17 +61,21 @@ final class ActivityViewReactor: ReactorKit.Reactor { fileprivate let activityService: ActivityServiceType fileprivate let userService: UserServiceType fileprivate let crawlerService: GitTimeCrawlerServiceType + fileprivate let keychainService: KeychainServiceType private let imageDownloder = ImageDownloader(name: "profileImageDownloder") init( activityService: ActivityServiceType, userService: UserServiceType, - crawlerService: GitTimeCrawlerServiceType + crawlerService: GitTimeCrawlerServiceType, + keychainService: KeychainServiceType ) { self.activityService = activityService self.userService = userService self.crawlerService = crawlerService + self.keychainService = keychainService + self.initialState = State(isLoading: false, page: ActivityViewReactor.INITIAL_PAGE, canLoadMore: true, @@ -192,6 +197,27 @@ final class ActivityViewReactor: ReactorKit.Reactor { guard let me = GlobalStates.shared.currentUser.value else { return .empty() } + return self.fetchContributions() + .observe(on: MainScheduler.instance) + .map { userContribution -> ContributionInfo in + return ContributionInfo( + count: userContribution.totalContributions, + contributions: userContribution.contributions.map { + Contribution( + date: $0.date, + contribution: $0.contributionCount, + hexColor: $0.color + ) + }, + userName: me.name, + additionalName: me.additionalName, + profileImageURL: me.profileURL + ) + } + .flatMap { response -> Observable in + return .just(.setContributionInfo(response)) + } + /* return self.crawlerService.fetchContributionsRawdata(userName: me.name) .map { response -> Mutation in let contributionInfo = self.parseContribution(response: response) @@ -203,6 +229,30 @@ final class ActivityViewReactor: ReactorKit.Reactor { .map { contributionInfo -> Mutation in return .setContributionInfo(contributionInfo)} } + */ + } + + private func fetchContributions() -> Observable { + guard let accessToken = keychainService.getAccessToken() else { return .empty() } + guard let me = GlobalStates.shared.currentUser.value else { return .empty() } + + let githubKit = GitHubKit(config: .init(token: accessToken)) + + return Observable.create { observer -> Disposable in + async { + do { + let contribution = try await githubKit.contributions(userName: me.name) + observer.onNext(contribution) + observer.onCompleted() + } catch { + observer.onError(error) + } + } + + return Disposables.create { + + } + } } private func requestTrialContributions() -> Observable { diff --git a/GitTime/Sources/Views/Activity/ActivityItemCell.swift b/GitTime/Sources/Views/Activity/ActivityItemCell.swift index 073bff6..df68f4c 100644 --- a/GitTime/Sources/Views/Activity/ActivityItemCell.swift +++ b/GitTime/Sources/Views/Activity/ActivityItemCell.swift @@ -157,8 +157,8 @@ final class ActivityItemCell: BaseTableViewCell, ReactorKit.View { let actorProfile = state.event.actor.profileURL if let actorProfileURL = URL(string: actorProfile) { let cache = ImageCache.default - cache.memoryStorage.config.expiration = .seconds(2) - authorProfileImageView.kf.setImage(with: actorProfileURL, options: [.memoryCacheExpiration(.seconds(5))]) + cache.memoryStorage.config.expiration = .days(1) + authorProfileImageView.kf.setImage(with: actorProfileURL, options: [.memoryCacheExpiration(.days(1))]) } let actorName = state.event.actor.name diff --git a/GitTime/Supporting Files/Info.plist b/GitTime/Supporting Files/Info.plist index da0a7f9..678e2c2 100644 --- a/GitTime/Supporting Files/Info.plist +++ b/GitTime/Supporting Files/Info.plist @@ -85,7 +85,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.2.1 + 2.2.2 CFBundleURLTypes @@ -100,7 +100,7 @@ CFBundleVersion - 9 + 10 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/project.yml b/project.yml index 5da4d17..30549f4 100644 --- a/project.yml +++ b/project.yml @@ -57,6 +57,9 @@ packages: Toaster: url: https://github.com/devxoul/Toaster.git branch: master + GitHubKit: + url: https://github.com/87kangsw/GitHubKit + from: 1.0.0 fileGroups: - GitTime/Supporting Files targets: @@ -118,6 +121,7 @@ targets: - package: Firebase product: FirebasePerformance - package: Toaster + - package: GitHubKit GitTimeTests: platform: iOS type: bundle.unit-test