Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Open issue from notification #2259

Merged
merged 1 commit into from
Oct 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Classes/Systems/AppRouter/AppController+SetupRoutes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ extension AppController {
register(route: BookmarkShortcutRoute.self)
register(route: SwitchAccountShortcutRoute.self)
register(route: SearchShortcutRoute.self)
register(route: IssueNotificationRoute.self)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// AppController+UNUserNotificationCenterDelegate.swift
// Freetime
//
// Created by Ryan Nystrom on 10/9/18.
// Copyright © 2018 Ryan Nystrom. All rights reserved.
//

import UserNotifications

extension AppController: UNUserNotificationCenterDelegate {

func attachNotificationDelegate() {
UNUserNotificationCenter.current().delegate = self
}

// MARK: UNUserNotificationCenterDelegate

func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([.alert, .sound])
}

func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
switch response.actionIdentifier {
case UNNotificationDismissActionIdentifier: break
case UNNotificationDefaultActionIdentifier:
if let (path, params) = response.notification.request.content.routableUserInfo {
handle(path: path, params: params)
}
default: print(response.actionIdentifier)
}
completionHandler()
}

}
12 changes: 8 additions & 4 deletions Classes/Systems/AppRouter/AppController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit
import GitHubSession
import GitHubAPI

final class AppController: LoginSplashViewControllerDelegate, GitHubSessionListener {
final class AppController: NSObject, LoginSplashViewControllerDelegate, GitHubSessionListener {

private var splitViewController: AppSplitViewController!
private let sessionManager = GitHubSessionManager()
Expand All @@ -20,7 +20,9 @@ final class AppController: LoginSplashViewControllerDelegate, GitHubSessionListe
private var watchAppSync: WatchAppUserSessionSync?
private var routes = [String: (Routable & RoutePerformable).Type]()

init() {
override init() {
super.init()
attachNotificationDelegate()
sessionManager.addListener(listener: self)
}

Expand Down Expand Up @@ -67,11 +69,13 @@ final class AppController: LoginSplashViewControllerDelegate, GitHubSessionListe
@discardableResult
func handle(path: String, params: [String: String]) -> Bool {
guard let routeType = routes[path],
let route = routeType.from(params: params)
let route = routeType.from(params: params),
let client = appClient
else { return false }
return route.perform(
sessionManager: sessionManager,
splitViewController: splitViewController
splitViewController: splitViewController,
client: client
)
}

Expand Down
3 changes: 2 additions & 1 deletion Classes/Systems/AppRouter/BookmarkShortcutRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ struct BookmarkShortcutRoute: Routable {
extension BookmarkShortcutRoute: RoutePerformable {
func perform(
sessionManager: GitHubSessionManager,
splitViewController: AppSplitViewController
splitViewController: AppSplitViewController,
client: GithubClient
) -> Bool {
return splitViewController.masterTabBarController?.selectTab(of: BookmarkViewController.self) != nil
}
Expand Down
46 changes: 46 additions & 0 deletions Classes/Systems/AppRouter/IssueNotificationRoute.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// IssueNotificationRoute.swift
// Freetime
//
// Created by Ryan Nystrom on 10/9/18.
// Copyright © 2018 Ryan Nystrom. All rights reserved.
//

import Foundation
import GitHubSession

struct IssueNotificationRoute: Routable {
let owner: String
let repo: String
let number: Int
static func from(params: [String : String]) -> IssueNotificationRoute? {
guard let owner = params["owner"],
let repo = params["repo"],
let number = (params["number"] as NSString?)?.integerValue
else { return nil }
return IssueNotificationRoute(owner: owner, repo: repo, number: number)
}
static var path: String {
return "com.githawk.issue-notifications"
}
var encoded: [String : String] {
return [
"owner": owner,
"repo": repo,
"number": "\(number)"
]
}
}

extension IssueNotificationRoute: RoutePerformable {
func perform(
sessionManager: GitHubSessionManager,
splitViewController: AppSplitViewController,
client: GithubClient
) -> Bool {
let model = IssueDetailsModel(owner: owner, repo: repo, number: number)
let controller = IssuesViewController(client: client, model: model, scrollToBottom: true)
splitViewController.showDetailViewController(controller, sender: nil)
return true
}
}
3 changes: 2 additions & 1 deletion Classes/Systems/AppRouter/RoutePerformable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ protocol RoutePerformable {
@discardableResult
func perform(
sessionManager: GitHubSessionManager,
splitViewController: AppSplitViewController
splitViewController: AppSplitViewController,
client: GithubClient
) -> Bool
}
3 changes: 2 additions & 1 deletion Classes/Systems/AppRouter/SearchShortcutRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ struct SearchShortcutRoute: Routable {
extension SearchShortcutRoute: RoutePerformable {
func perform(
sessionManager: GitHubSessionManager,
splitViewController: AppSplitViewController
splitViewController: AppSplitViewController,
client: GithubClient
) -> Bool {
guard let controller = splitViewController.masterTabBarController?.selectTab(of: SearchViewController.self)
else { return false }
Expand Down
3 changes: 2 additions & 1 deletion Classes/Systems/AppRouter/SwitchAccountShortcutRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ struct SwitchAccountShortcutRoute: Routable {
extension SwitchAccountShortcutRoute: RoutePerformable {
func perform(
sessionManager: GitHubSessionManager,
splitViewController: AppSplitViewController
splitViewController: AppSplitViewController,
client: GithubClient
) -> Bool {
let userSessions = sessionManager.userSessions
guard let needle = userSessions.first(where: { username == $0.username })
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// UNMutableNotificationContent+Routable.swift
// Freetime
//
// Created by Ryan Nystrom on 10/9/18.
// Copyright © 2018 Ryan Nystrom. All rights reserved.
//

import UserNotifications

let UNNotificationContentRoutePathKey = "path"

extension UNMutableNotificationContent {

func set<T: Routable>(route: T) {
userInfo[UNNotificationContentRoutePathKey] = T.path
route.encoded.forEach { userInfo[$0] = $1 }
}

}
26 changes: 26 additions & 0 deletions Classes/Systems/AppRouter/UNNotificationContent+Routable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// UNNotificationContent+Routable.swift
// Freetime
//
// Created by Ryan Nystrom on 10/9/18.
// Copyright © 2018 Ryan Nystrom. All rights reserved.
//

import UserNotifications

extension UNNotificationContent {

var routableUserInfo: (path: String, params: [String: String])? {
guard let path = userInfo[UNNotificationContentRoutePathKey] as? String else { return nil }
var params = [String: String]()
userInfo.forEach {
guard let key = $0 as? String,
let value = $1 as? String,
value != UNNotificationContentRoutePathKey
else { return }
params[key] = value
}
return (path, params)
}

}
10 changes: 10 additions & 0 deletions Classes/Systems/BadgeNotifications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ final class BadgeNotifications {
content.body = $0.subject.title
content.subtitle = "\(type.localizedString) \(identifier.string)"

// currently only handling issues
if let identifier = $0.subject.identifier,
case .number(let n) = identifier {
content.set(route: IssueNotificationRoute(
owner: $0.repository.owner.login,
repo: $0.repository.name,
number: n
))
}

let request = UNNotificationRequest(
identifier: $0.id,
content: content,
Expand Down
18 changes: 17 additions & 1 deletion Freetime.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@
29A08FBD1F12EF7C00C5368E /* IssueReferencedCommitCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A08FBA1F12EF7C00C5368E /* IssueReferencedCommitCell.swift */; };
29A08FBE1F12EF7C00C5368E /* IssueReferencedCommitModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A08FBB1F12EF7C00C5368E /* IssueReferencedCommitModel.swift */; };
29A08FBF1F12EF7C00C5368E /* IssueReferencedCommitSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A08FBC1F12EF7C00C5368E /* IssueReferencedCommitSectionController.swift */; };
29A1053F216D9062004734A0 /* UNNotificationContent+Routable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A1053E216D9062004734A0 /* UNNotificationContent+Routable.swift */; };
29A10541216D912F004734A0 /* IssueNotificationRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A10540216D912F004734A0 /* IssueNotificationRoute.swift */; };
29A10543216D9381004734A0 /* UNMutableNotificationContent+Routable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A10542216D9381004734A0 /* UNMutableNotificationContent+Routable.swift */; };
29A10545216D9515004734A0 /* AppController+UNUserNotificationCenterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A10544216D9515004734A0 /* AppController+UNUserNotificationCenterDelegate.swift */; };
29A195021EC66B8B00C3E289 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A195011EC66B8B00C3E289 /* UIColor+Hex.swift */; };
29A195071EC7601000C3E289 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 29A195061EC7601000C3E289 /* Localizable.stringsdict */; };
29A195081EC7602500C3E289 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 29A195061EC7601000C3E289 /* Localizable.stringsdict */; };
Expand Down Expand Up @@ -837,6 +841,10 @@
29A08FBA1F12EF7C00C5368E /* IssueReferencedCommitCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IssueReferencedCommitCell.swift; sourceTree = "<group>"; };
29A08FBB1F12EF7C00C5368E /* IssueReferencedCommitModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IssueReferencedCommitModel.swift; sourceTree = "<group>"; };
29A08FBC1F12EF7C00C5368E /* IssueReferencedCommitSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IssueReferencedCommitSectionController.swift; sourceTree = "<group>"; };
29A1053E216D9062004734A0 /* UNNotificationContent+Routable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNNotificationContent+Routable.swift"; sourceTree = "<group>"; };
29A10540216D912F004734A0 /* IssueNotificationRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueNotificationRoute.swift; sourceTree = "<group>"; };
29A10542216D9381004734A0 /* UNMutableNotificationContent+Routable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNMutableNotificationContent+Routable.swift"; sourceTree = "<group>"; };
29A10544216D9515004734A0 /* AppController+UNUserNotificationCenterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppController+UNUserNotificationCenterDelegate.swift"; sourceTree = "<group>"; };
29A195011EC66B8B00C3E289 /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = "<group>"; };
29A195061EC7601000C3E289 /* Localizable.stringsdict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = "<group>"; };
29A195091EC78B4800C3E289 /* NotificationType+Icon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NotificationType+Icon.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1096,13 +1104,17 @@
isa = PBXGroup;
children = (
290CA7632169799600DE04F8 /* AppController.swift */,
290CA779216AFC1300DE04F8 /* AppController+SetupRoutes.swift */,
29A10544216D9515004734A0 /* AppController+UNUserNotificationCenterDelegate.swift */,
290CA76521697A7900DE04F8 /* AppSplitViewController.swift */,
290CA773216AE94D00DE04F8 /* BookmarkShortcutRoute.swift */,
29A10540216D912F004734A0 /* IssueNotificationRoute.swift */,
290CA76D216AE8FA00DE04F8 /* Routable.swift */,
290CA779216AFC1300DE04F8 /* AppController+SetupRoutes.swift */,
290CA777216AFAE600DE04F8 /* RoutePerformable.swift */,
290CA769216AC82700DE04F8 /* SearchShortcutRoute.swift */,
290CA771216AE93E00DE04F8 /* SwitchAccountShortcutRoute.swift */,
29A10542216D9381004734A0 /* UNMutableNotificationContent+Routable.swift */,
29A1053E216D9062004734A0 /* UNNotificationContent+Routable.swift */,
);
path = AppRouter;
sourceTree = "<group>";
Expand Down Expand Up @@ -2816,6 +2828,7 @@
2967DC56211751CB00FD3683 /* UIContentSizeCategory+Preferred.swift in Sources */,
7BBFEE5B1F8A8A0400C68E47 /* SearchBarSectionController.swift in Sources */,
292FCAFA1EDFCC510026635E /* IssueCommentDetailsViewModel.swift in Sources */,
29A10541216D912F004734A0 /* IssueNotificationRoute.swift in Sources */,
2949674E1EF9719300B1CF1A /* IssueCommentHrCell.swift in Sources */,
2949674C1EF9716400B1CF1A /* IssueCommentHrModel.swift in Sources */,
294967531EFC1EDB00B1CF1A /* IssueCommentHtmlCell.swift in Sources */,
Expand Down Expand Up @@ -2970,6 +2983,7 @@
29DA1E801F5DF2960050C64B /* LoadMoreSectionController.swift in Sources */,
29416BFB1F113D0A00D03E1A /* LoginSplashViewController.swift in Sources */,
29DA1E8C1F5F8CC40050C64B /* MarkdownAttribute.swift in Sources */,
29A10545216D9515004734A0 /* AppController+UNUserNotificationCenterDelegate.swift in Sources */,
29351E9C2079106300FF8C17 /* String+GitHubEmoji.swift in Sources */,
98647DF31F758CCF00A4DE7A /* NewIssueTableViewController.swift in Sources */,
290EF5761F06BA06006A2160 /* NoNewNotificationsCell.swift in Sources */,
Expand Down Expand Up @@ -3020,6 +3034,7 @@
2924C18820D5B2F200FCFCFF /* PeopleSectionController.swift in Sources */,
292ACE181F5C945B00C9A02C /* RepositoryIssueSummaryModel.swift in Sources */,
DCA5ED1B1FAEF78B0072F074 /* BookmarkSectionController.swift in Sources */,
29A1053F216D9062004734A0 /* UNNotificationContent+Routable.swift in Sources */,
29693EE520FAA05F00336200 /* IssueAutocomplete.swift in Sources */,
986B87341F2CAE9800AAB55C /* RepositoryIssueSummaryType.swift in Sources */,
2905AFAD1F7357C50015AE32 /* RepositoryIssuesViewController.swift in Sources */,
Expand Down Expand Up @@ -3111,6 +3126,7 @@
2977788A20B306F200F2AFC2 /* LabelLayoutManager.swift in Sources */,
29DB264A1FCA10A800C3D0C9 /* GithubHighlighting.swift in Sources */,
2950AB1D2083B1E400C6F19A /* EmptyLoadingView.swift in Sources */,
29A10543216D9381004734A0 /* UNMutableNotificationContent+Routable.swift in Sources */,
29B0EF871F93DF6C00870291 /* RepositoryCodeBlobViewController.swift in Sources */,
98F9F4001F9CCFFE005A0266 /* ImageUploadTableViewController.swift in Sources */,
29C167671ECA005500439D62 /* Constants.swift in Sources */,
Expand Down