Skip to content

Commit

Permalink
Minor tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Sep 24, 2020
1 parent 2760425 commit 8267b23
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 23 deletions.
1 change: 0 additions & 1 deletion Gifski/Constants.swift
Expand Up @@ -19,6 +19,5 @@ extension NSColor {

extension Defaults.Keys {
static let outputQuality = Key<Double>("outputQuality", default: 1)
static let successfulConversionsCount = Key<Int>("successfulConversionsCount", default: 0)
static let loopGif = Key<Bool>("loopGif", default: true)
}
6 changes: 2 additions & 4 deletions Gifski/ConversionCompletedViewController.swift
Expand Up @@ -73,9 +73,7 @@ final class ConversionCompletedViewController: NSViewController {
self.tooltip.show(from: self.draggableFile, preferredEdge: .maxY)
}

if Defaults[.successfulConversionsCount] == 5 {
SKStoreReviewController.requestReview()
}
SSApp.requestReviewAfterBeingCalledThisManyTimes([5, 100, 1000])
}

private func setUpUI() {
Expand Down Expand Up @@ -121,7 +119,7 @@ final class ConversionCompletedViewController: NSViewController {
self.copyButton.title = "Copied!"
self.copyButton.isEnabled = false

App.runOnce(identifier: "copyWarning") {
SSApp.runOnce(identifier: "copyWarning") {
NSAlert.showModal(
for: self.copyButton.window,
message: "The GIF was copied to the clipboard.",
Expand Down
4 changes: 1 addition & 3 deletions Gifski/ConversionViewController.swift
Expand Up @@ -84,9 +84,7 @@ final class ConversionViewController: NSViewController {
do {
let gifUrl = try self.generateTemporaryGifUrl(for: conversion.video)
try result.get().write(to: gifUrl, options: .atomic)
try? gifUrl.setMetadata(key: .itemCreator, value: "\(App.name) \(App.version)")
Defaults[.successfulConversionsCount] += 1

try? gifUrl.setMetadata(key: .itemCreator, value: "\(SSApp.name) \(SSApp.version)")
self.didComplete(conversion: conversion, gifUrl: gifUrl)
} catch Gifski.Error.cancelled {
self.cancelConversion()
Expand Down
2 changes: 1 addition & 1 deletion Gifski/MainWindowController.swift
Expand Up @@ -8,7 +8,7 @@ final class MainWindowController: NSWindowController {
}

private func showWelcomeScreenIfNeeded() {
guard App.isFirstLaunch else {
guard SSApp.isFirstLaunch else {
return
}

Expand Down
47 changes: 37 additions & 10 deletions Gifski/Utilities.swift
Expand Up @@ -2,6 +2,7 @@ import Cocoa
import AVFoundation
import class Quartz.QLPreviewPanel
import Defaults
import StoreKit.SKStoreReviewController

/**
Convenience function for initializing an object and modifying its properties
Expand Down Expand Up @@ -335,7 +336,7 @@ extension AVAssetImageGenerator {
)
case .failed:
// TODO: Ideally, we should trim blank frames when initially reading the video in `VideoValidator.swift`, but I don't know a way to detect blank frames. We should still keep this fix even if we find a way to trim as this handles blank frames in the middle of the video.
// TODO: Report the `xcrun` bug to Apple if it's still an issue in macOS 10.16.
// TODO: Report the `xcrun` bug to Apple if it's still an issue in macOS 11.
// We ignore blank frames. A video can sometimes contain blank frames at the start when you record an iOS simulator using `xcrun simctl io booted recordVideo simulator.mp4`.
if
let error = error as? AVError,
Expand Down Expand Up @@ -465,7 +466,6 @@ extension String.StringInterpolation {
}


// TODO: Make this a `BinaryFloatingPoint` extension instead.
extension Double {
/**
Converts the number to a string and strips fractional trailing zeros.
Expand Down Expand Up @@ -1338,7 +1338,7 @@ extension NSPasteboard {
Read more: http://nspasteboard.org
*/
func setSourceApp() {
setString(App.id, forType: .sourceAppBundleIdentifier)
setString(SSApp.id, forType: .sourceAppBundleIdentifier)
}
}

Expand Down Expand Up @@ -1390,7 +1390,7 @@ final class FeedbackMenuItem: NSMenuItem {
super.init(coder: decoder)

onAction = { _ in
App.openSendFeedbackPage()
SSApp.openSendFeedbackPage()
}
}
}
Expand Down Expand Up @@ -1636,7 +1636,7 @@ extension String {
}


enum App {
enum SSApp {
static let id = Bundle.main.bundleIdentifier!
static let name = Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
static let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
Expand All @@ -1657,21 +1657,21 @@ enum App {
static func openSendFeedbackPage() {
let metadata =
"""
\(App.name) \(App.versionWithBuild) - \(App.id)
\(SSApp.name) \(SSApp.versionWithBuild) - \(SSApp.id)
macOS \(Device.osVersion)
\(Device.hardwareModel)
"""

let query: [String: String] = [
"product": App.name,
"product": SSApp.name,
"metadata": metadata
]

URL("https://sindresorhus.com/feedback/").settingQueryItems(from: query).open()
}
}

extension App {
extension SSApp {
static func runOnce(identifier: String, _ execute: () -> Void) {
let key = "SS_App_runOnce__\(identifier)"

Expand Down Expand Up @@ -2321,7 +2321,7 @@ extension NSError {
let errorName = "\(error)".split(separator: "(").first ?? ""

return .init(
domain: "\(App.id) - \(nsError.domain)\(errorName.isEmpty ? "" : ".")\(errorName)",
domain: "\(SSApp.id) - \(nsError.domain)\(errorName.isEmpty ? "" : ".")\(errorName)",
code: nsError.code,
userInfo: userInfo
)
Expand Down Expand Up @@ -2363,7 +2363,7 @@ extension NSError {
}

return .init(
domain: domainPostfix.map { "\(App.id) - \($0)" } ?? App.id,
domain: domainPostfix.map { "\(SSApp.id) - \($0)" } ?? SSApp.id,
code: 1, // This is what Swift errors end up as.
userInfo: userInfo
)
Expand Down Expand Up @@ -3330,3 +3330,30 @@ extension DateComponentsFormatter {
return string(from: timeInterval)
}
}


extension Numeric {
mutating func increment(by value: Self = 1) -> Self {
self += value
return self
}

mutating func decrement(by value: Self = 1) -> Self {
self -= value
return self
}
}


extension SSApp {
private static let key = Defaults.Key("SSApp_requestReview", default: 0)

/// Requests a review only after this method has been called the given amount of times.
static func requestReviewAfterBeingCalledThisManyTimes(_ counts: [Int]) {
guard counts.contains(Defaults[key].increment()) else {
return
}

SKStoreReviewController.requestReview()
}
}
6 changes: 2 additions & 4 deletions Gifski/VideoValidator.swift
Expand Up @@ -26,12 +26,10 @@ struct VideoValidator {
)

guard inputUrl.fileSize > 0 else {
// TODO: Make this not report to Crashlytics at some point.
NSAlert.showModalAndReportToCrashlytics(
NSAlert.showModal(
for: window,
message: "The selected file is empty.",
informativeText: "Try selecting a different file.",
debugInfo: ""
informativeText: "Try selecting a different file."
)

return .failure
Expand Down

0 comments on commit 8267b23

Please sign in to comment.