From c9536b6b498487a4ca1bfb4cd1c593e7650e9d44 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Tue, 16 Oct 2018 18:36:02 +0200 Subject: [PATCH 1/4] Improve gitignore --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cb6b16a8..e3d81491 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,9 @@ fastlane/report.xml fastlane/test_output fastlane/metadata/review_information fastlane/metadata/trade_representative_contact_information -build -dist +build/ +dist/ +ci/BUILD .env.secret* Preview.html Gemfile.lock From e31e4a31df7a3e5ba92e64f1ecf98f5d6b291933 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 17 Oct 2018 15:26:23 +0200 Subject: [PATCH 2/4] Reword issue report --- Passepartout/Resources/en.lproj/Localizable.strings | 2 +- Passepartout/Sources/SwiftGen+Strings.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Passepartout/Resources/en.lproj/Localizable.strings b/Passepartout/Resources/en.lproj/Localizable.strings index ce1bb8ea..65605a9b 100644 --- a/Passepartout/Resources/en.lproj/Localizable.strings +++ b/Passepartout/Resources/en.lproj/Localizable.strings @@ -155,7 +155,7 @@ "vpn.inactive" = "Inactive"; "vpn.disabled" = "Disabled"; -"issue_reporter.title" = "Report issue"; +"issue_reporter.title" = "Report an issue"; "issue_reporter.message" = "Do you want to attach the debug log of your latest connections? The log is crucial to resolve your connectivity issues and is completely anonymous."; "issue_reporter.buttons.with_log" = "Attach debug log"; "issue_reporter.buttons.without_log" = "Omit debug log"; diff --git a/Passepartout/Sources/SwiftGen+Strings.swift b/Passepartout/Sources/SwiftGen+Strings.swift index 66e18426..073b1893 100644 --- a/Passepartout/Sources/SwiftGen+Strings.swift +++ b/Passepartout/Sources/SwiftGen+Strings.swift @@ -275,7 +275,7 @@ internal enum L10n { internal enum IssueReporter { /// Do you want to attach the debug log of your latest connections? The log is crucial to resolve your connectivity issues and is completely anonymous. internal static let message = L10n.tr("Localizable", "issue_reporter.message") - /// Report issue + /// Report an issue internal static let title = L10n.tr("Localizable", "issue_reporter.title") internal enum Alerts { From b6d430f10680608b6bea5a8139d371af164b1f1c Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 17 Oct 2018 23:24:58 +0200 Subject: [PATCH 3/4] Add link to Reddit --- .../Scenes/Organizer/AboutViewController.swift | 18 ++++++++++++++++-- .../Resources/en.lproj/Localizable.strings | 1 + Passepartout/Sources/AppConstants.swift | 2 ++ Passepartout/Sources/SwiftGen+Strings.swift | 5 +++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Passepartout-iOS/Scenes/Organizer/AboutViewController.swift b/Passepartout-iOS/Scenes/Organizer/AboutViewController.swift index cbfa1c75..a2665ae1 100644 --- a/Passepartout-iOS/Scenes/Organizer/AboutViewController.swift +++ b/Passepartout-iOS/Scenes/Organizer/AboutViewController.swift @@ -39,7 +39,7 @@ class AboutViewController: UITableViewController, TableModelHost { model.setHeader(L10n.About.Sections.Feedback.header, for: .feedback) model.set([.version, .credits, .website], in: .info) model.set([.sourcePassepartout, .sourceTunnelKit], in: .source) - model.set([.reportIssue, .writeReview], in: .feedback) + model.set([.discussReddit, .reportIssue, .writeReview], in: .feedback) return model }() @@ -78,6 +78,10 @@ class AboutViewController: UITableViewController, TableModelHost { UIApplication.shared.open(url, options: [:], completionHandler: nil) } + private func discussReddit() { + UIApplication.shared.open(AppConstants.URLs.subreddit, options: [:], completionHandler: nil) + } + private func reportIssue() { IssueReporter.shared.present(in: self) } @@ -114,9 +118,11 @@ extension AboutViewController { case sourceTunnelKit - case writeReview + case discussReddit case reportIssue + + case writeReview } override func numberOfSections(in tableView: UITableView) -> Int { @@ -163,6 +169,11 @@ extension AboutViewController { cell.leftText = GroupConstants.App.tunnelKitName return cell + case .discussReddit: + let cell = Cells.setting.dequeue(from: tableView, for: indexPath) + cell.leftText = L10n.About.Cells.DiscussReddit.caption + return cell + case .reportIssue: let cell = Cells.setting.dequeue(from: tableView, for: indexPath) cell.leftText = L10n.IssueReporter.title @@ -192,6 +203,9 @@ extension AboutViewController { case .sourceTunnelKit: visitRepository(AppConstants.Repos.tunnelKit) + case .discussReddit: + discussReddit() + case .reportIssue: reportIssue() diff --git a/Passepartout/Resources/en.lproj/Localizable.strings b/Passepartout/Resources/en.lproj/Localizable.strings index 65605a9b..5f348034 100644 --- a/Passepartout/Resources/en.lproj/Localizable.strings +++ b/Passepartout/Resources/en.lproj/Localizable.strings @@ -168,6 +168,7 @@ "about.sections.source.header" = "Source code"; "about.sections.feedback.header" = "Feedback"; "about.cells.version.caption" = "Version"; +"about.cells.discuss_reddit.caption" = "Discuss on Reddit"; "about.cells.write_review.caption" = "Write a review"; "about.cells.website.caption" = "Visit website"; diff --git a/Passepartout/Sources/AppConstants.swift b/Passepartout/Sources/AppConstants.swift index 0988eccb..b05c52ab 100644 --- a/Passepartout/Sources/AppConstants.swift +++ b/Passepartout/Sources/AppConstants.swift @@ -110,6 +110,8 @@ class AppConstants { static let changelog = Repos.passepartout.appendingPathComponent("blob/master/CHANGELOG.md") + static let subreddit = URL(string: "https://www.reddit.com/r/passepartout")! + static func review(withId id: String) -> URL { return URL(string: "https://itunes.apple.com/app/id\(id)?action=write-review")! } diff --git a/Passepartout/Sources/SwiftGen+Strings.swift b/Passepartout/Sources/SwiftGen+Strings.swift index 073b1893..4e3eedea 100644 --- a/Passepartout/Sources/SwiftGen+Strings.swift +++ b/Passepartout/Sources/SwiftGen+Strings.swift @@ -14,6 +14,11 @@ internal enum L10n { internal enum Cells { + internal enum DiscussReddit { + /// Discuss on Reddit + internal static let caption = L10n.tr("Localizable", "about.cells.discuss_reddit.caption") + } + internal enum Version { /// Version internal static let caption = L10n.tr("Localizable", "about.cells.version.caption") From 62d1c2d882a9acf224f6dac49af0e09acd094f95 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Thu, 18 Oct 2018 09:52:23 +0200 Subject: [PATCH 4/4] Add promoting alert for subreddit --- Passepartout-iOS/Global/Macros.swift | 7 +++++ .../Organizer/OrganizerViewController.swift | 27 ++++++++++++++++++- .../Resources/en.lproj/Localizable.strings | 5 ++++ .../Sources/Model/TransientStore.swift | 13 +++++++++ Passepartout/Sources/SwiftGen+Strings.swift | 14 ++++++++++ 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Passepartout-iOS/Global/Macros.swift b/Passepartout-iOS/Global/Macros.swift index 4b3cc95f..c28a1e24 100644 --- a/Passepartout-iOS/Global/Macros.swift +++ b/Passepartout-iOS/Global/Macros.swift @@ -58,6 +58,13 @@ extension UIAlertController { } } + func addAction(_ title: String, handler: @escaping () -> Void) { + let action = UIAlertAction(title: title, style: .default) { (action) in + handler() + } + addAction(action) + } + func addDestructiveAction(_ title: String, handler: @escaping () -> Void) { let action = UIAlertAction(title: title, style: .destructive) { (action) in handler() diff --git a/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift b/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift index b6b703a2..2a3cd84c 100644 --- a/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift +++ b/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift @@ -35,7 +35,9 @@ class OrganizerViewController: UITableViewController, TableModelHost { private var hostProfiles: [HostConnectionProfile] = [] private var availableProviderNames: [Infrastructure.Name]? - + + private var didShowSubreddit = false + // MARK: TableModelHost let model: TableModel = { @@ -103,6 +105,25 @@ class OrganizerViewController: UITableViewController, TableModelHost { service.delegate = self } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + if !didShowSubreddit && !TransientStore.shared.didHandleSubreddit { + didShowSubreddit = true + + let alert = Macros.alert(L10n.About.Cells.DiscussReddit.caption, L10n.Reddit.message) + alert.addDefaultAction(L10n.Reddit.Buttons.subscribe) { + TransientStore.shared.didHandleSubreddit = true + self.subscribeSubreddit() + } + alert.addAction(L10n.Reddit.Buttons.never) { + TransientStore.shared.didHandleSubreddit = true + } + alert.addCancelAction(L10n.Reddit.Buttons.remind) + present(alert, animated: true, completion: nil) + } + } + override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if let cell = sender as? UITableViewCell, let indexPath = tableView.indexPath(for: cell) { return model.row(at: indexPath) == .profile @@ -227,6 +248,10 @@ class OrganizerViewController: UITableViewController, TableModelHost { alert.addCancelAction(L10n.Global.cancel) present(alert, animated: true, completion: nil) } + + private func subscribeSubreddit() { + UIApplication.shared.open(AppConstants.URLs.subreddit, options: [:], completionHandler: nil) + } } // MARK: - diff --git a/Passepartout/Resources/en.lproj/Localizable.strings b/Passepartout/Resources/en.lproj/Localizable.strings index 5f348034..b2b1b152 100644 --- a/Passepartout/Resources/en.lproj/Localizable.strings +++ b/Passepartout/Resources/en.lproj/Localizable.strings @@ -27,6 +27,11 @@ "global.cancel" = "Cancel"; "global.next" = "Next"; +"reddit.message" = "Did you know that Passepartout has a subreddit? Subscribe for updates or to discuss issues, features, new platforms or whatever you like.\n\nIt's also a great way to show you care about this project."; +"reddit.buttons.subscribe" = "Subscribe now!"; +"reddit.buttons.remind" = "Remind me later"; +"reddit.buttons.never" = "Don't ask again"; + "organizer.sections.providers.header" = "Networks"; "organizer.sections.providers.footer" = "Here you find a few public infrastructures offering preset configuration profiles."; "organizer.sections.hosts.header" = "Hosts"; diff --git a/Passepartout/Sources/Model/TransientStore.swift b/Passepartout/Sources/Model/TransientStore.swift index 8125e194..58ee4846 100644 --- a/Passepartout/Sources/Model/TransientStore.swift +++ b/Passepartout/Sources/Model/TransientStore.swift @@ -29,12 +29,25 @@ import SwiftyBeaver private let log = SwiftyBeaver.self class TransientStore { + private struct Keys { + static let didHandleSubreddit = "DidHandleSubreddit" + } + static let shared = TransientStore() private let servicePath: URL let service: ConnectionService + var didHandleSubreddit: Bool { + get { + return UserDefaults.standard.bool(forKey: Keys.didHandleSubreddit) + } + set { + UserDefaults.standard.set(newValue, forKey: Keys.didHandleSubreddit) + } + } + private init() { servicePath = FileManager.default.userURL( for: .documentDirectory, diff --git a/Passepartout/Sources/SwiftGen+Strings.swift b/Passepartout/Sources/SwiftGen+Strings.swift index 4e3eedea..4e37c50a 100644 --- a/Passepartout/Sources/SwiftGen+Strings.swift +++ b/Passepartout/Sources/SwiftGen+Strings.swift @@ -395,6 +395,20 @@ internal enum L10n { } } + internal enum Reddit { + /// Did you know that Passepartout has a subreddit? Subscribe for updates or to discuss issues, features, new platforms or whatever you like.\n\nIt's also a great way to show you care about this project. + internal static let message = L10n.tr("Localizable", "reddit.message") + + internal enum Buttons { + /// Don't ask again + internal static let never = L10n.tr("Localizable", "reddit.buttons.never") + /// Remind me later + internal static let remind = L10n.tr("Localizable", "reddit.buttons.remind") + /// Subscribe now! + internal static let subscribe = L10n.tr("Localizable", "reddit.buttons.subscribe") + } + } + internal enum Service { internal enum Alerts {