Skip to content

Commit

Permalink
Cleanup #156
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Nov 10, 2019
1 parent 3771fc0 commit 7167061
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 50 deletions.
6 changes: 6 additions & 0 deletions Gifski.xcodeproj/project.pbxproj
Expand Up @@ -45,6 +45,8 @@
E3D72324229B9A7500989BDF /* CircularProgress+CheckmarkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3D72323229B9A7500989BDF /* CircularProgress+CheckmarkView.swift */; };
E3DF3E88203BD2B900055855 /* EditVideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3DF3E86203BD2B900055855 /* EditVideoViewController.swift */; };
E3DF3E89203BD2B900055855 /* EditVideoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E3DF3E87203BD2B900055855 /* EditVideoViewController.xib */; };
E3FC365C2377FA0000CF7C59 /* Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3FC365B2377FA0000CF7C59 /* Shared.swift */; };
E3FC365E2377FA9F00CF7C59 /* Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3FC365B2377FA0000CF7C59 /* Shared.swift */; };
E3FEF31922C52819003AEFED /* ConversionCompletedViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E3FEF31422C52819003AEFED /* ConversionCompletedViewController.xib */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -147,6 +149,7 @@
E3D72323229B9A7500989BDF /* CircularProgress+CheckmarkView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "CircularProgress+CheckmarkView.swift"; sourceTree = "<group>"; usesTabs = 1; };
E3DF3E86203BD2B900055855 /* EditVideoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = EditVideoViewController.swift; sourceTree = "<group>"; usesTabs = 1; };
E3DF3E87203BD2B900055855 /* EditVideoViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditVideoViewController.xib; sourceTree = "<group>"; };
E3FC365B2377FA0000CF7C59 /* Shared.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Shared.swift; path = Gifski/Shared.swift; sourceTree = SOURCE_ROOT; usesTabs = 1; };
E3FD6190201BCBC30087160A /* Gifski-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "Gifski-Bridging-Header.h"; sourceTree = "<group>"; usesTabs = 1; };
E3FD61A4201BD2DA0087160A /* gifski.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = gifski.h; path = "gifski-api/gifski.h"; sourceTree = "<group>"; };
E3FEF31422C52819003AEFED /* ConversionCompletedViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConversionCompletedViewController.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -255,6 +258,7 @@
children = (
E3AE62861E5CD2F300035A2F /* AppDelegate.swift */,
E3A6BD102245345C00F62256 /* Constants.swift */,
E3FC365B2377FA0000CF7C59 /* Shared.swift */,
C2AFA91B204FFEFD00FC5A7F /* MainWindowController.swift */,
858380E522BFD0E30086BC98 /* VideoDropViewController.swift */,
E3DF3E86203BD2B900055855 /* EditVideoViewController.swift */,
Expand Down Expand Up @@ -468,6 +472,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E3FC365E2377FA9F00CF7C59 /* Shared.swift in Sources */,
0E7925202329BDBE00058B94 /* ShareViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -494,6 +499,7 @@
E3A940122182DCE5006981D5 /* CustomButton.swift in Sources */,
E3DF3E88203BD2B900055855 /* EditVideoViewController.swift in Sources */,
6D86841721FD283B0044F6FE /* ConversionCompletedViewController.swift in Sources */,
E3FC365C2377FA0000CF7C59 /* Shared.swift in Sources */,
B576D25422294F9900A9B75C /* CircularProgress+Util.swift in Sources */,
858380E622BFD0E30086BC98 /* VideoDropViewController.swift in Sources */,
8548806E22B82D1400E97401 /* MenuPopUpButton.swift in Sources */,
Expand Down
46 changes: 28 additions & 18 deletions Gifski/AppDelegate.swift
Expand Up @@ -45,39 +45,49 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}
}

/// Returns `nil` if it should not continue.
func extractSharedVideoUrlIfAny(from url: URL) -> URL? {
guard url.host == "shareExtension" else {
return url
}

guard
let path = url.queryDictionary["path"],
let appGroupShareVideoUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Shared.videoShareGroupIdentifier)?.appendingPathComponent(path)
else {
NSAlert.showModal(
for: mainWindowController.window,
message: "Could not retrieve the shared video."
)
return nil
}

return appGroupShareVideoUrl
}

func application(_ application: NSApplication, open urls: [URL]) {
guard urls.count == 1, let videoUrl = urls.first else {
guard
urls.count == 1,
let videoUrl = urls.first
else {
NSAlert.showModal(
for: mainWindowController.window,
message: "Gifski can only convert a single file at the time."
)
return
}

var sharedVideoUrl = videoUrl

if videoUrl.host == "shareExtension" {
if let path = videoUrl.queryParameters["path"],
let appIdentifierPrefix = Bundle.main.infoDictionary?["AppIdentifierPrefix"] as? String,
let videoUrlString = path.removingPercentEncoding,
let appGroupShareVideoUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "\(appIdentifierPrefix).gifski_video_share_group")?.appendingPathComponent(videoUrlString) {
sharedVideoUrl = appGroupShareVideoUrl
} else {
NSAlert.showModal(
for: mainWindowController.window,
message: "Could not retrieve shared video"
)
return
}
guard let videoUrl2 = extractSharedVideoUrlIfAny(from: videoUrl) else {
return
}

// TODO: Simplify this. Make a function that calls the input when the app finished launching, or right away if it already has.
if hasFinishedLaunching {
mainWindowController.convert(sharedVideoUrl.absoluteURL)
mainWindowController.convert(videoUrl2)
} else {
// This method is called before `applicationDidFinishLaunching`,
// so we buffer it up a video is "Open with" this app
urlToConvertOnLaunch = sharedVideoUrl.absoluteURL
urlToConvertOnLaunch = videoUrl2
}
}

Expand Down
2 changes: 1 addition & 1 deletion Gifski/Gifski.entitlements
Expand Up @@ -6,7 +6,7 @@
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(TeamIdentifierPrefix).gifski_video_share_group</string>
<string>$(TeamIdentifierPrefix)gifski_video_share_group</string>
</array>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
Expand Down
6 changes: 6 additions & 0 deletions Gifski/Shared.swift
@@ -0,0 +1,6 @@
import Foundation

struct Shared {
static let appIdentifierPrefix = Bundle.main.infoDictionary!["AppIdentifierPrefix"] as! String
static let videoShareGroupIdentifier = "\(appIdentifierPrefix)gifski_video_share_group"
}
23 changes: 13 additions & 10 deletions Gifski/util.swift
Expand Up @@ -2358,19 +2358,22 @@ extension URL {
func setMetadata<T>(key: MetadataKey, value: T) throws {
try attributes.set("com.apple.metadata:\(key.attributeKey)", value: value)
}
}

var queryParameters: [String: String] {
guard
let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems
else {
return [:]
}

return queryItems.reduce(into: [String: String]()) { result, item in
extension URLComponents {
var queryDictionary: [String: String] {
queryItems?.reduce(into: [String: String]()) { result, item in
result[item.name] = item.value
}
} ?? [:]
}
}

extension URL {
var components: URLComponents? {
URLComponents(url: self, resolvingAgainstBaseURL: true)
}

var queryDictionary: [String: String] { components?.queryDictionary ?? [:] }
}

extension NSViewController {
Expand Down
12 changes: 6 additions & 6 deletions ShareExtension/Base.lproj/ShareViewController.xib
Expand Up @@ -23,17 +23,16 @@
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="24" id="F0b-Hh-bvT"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" id="j9m-lT-EgP">
<textFieldCell key="cell" alignment="center" id="j9m-lT-EgP">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BTj-qO-jmK">
<rect key="frame" x="305" y="1" width="81" height="32"/>
<rect key="frame" x="286" y="11" width="88" height="32"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="IPb-Z0-hfL"/>
<constraint firstAttribute="width" constant="69" id="v7d-8i-huw"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="76" id="aPk-BM-TQV"/>
</constraints>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="dmg-HE-LAK">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
Expand All @@ -48,9 +47,10 @@ DQ
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="BTj-qO-jmK" secondAttribute="trailing" constant="8" id="2Vn-bU-lwi"/>
<constraint firstAttribute="bottom" secondItem="BTj-qO-jmK" secondAttribute="bottom" constant="8" id="Rap-xl-cH0"/>
<constraint firstItem="BTj-qO-jmK" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" id="1Gj-Ko-d7n"/>
<constraint firstItem="BTj-qO-jmK" firstAttribute="top" secondItem="1wb-Ep-YUq" secondAttribute="bottom" constant="50" id="1bh-kz-JBG"/>
<constraint firstAttribute="trailing" secondItem="1wb-Ep-YUq" secondAttribute="trailing" constant="8" id="WFK-k0-Ol1"/>
<constraint firstAttribute="trailing" secondItem="BTj-qO-jmK" secondAttribute="trailing" constant="20" symbolic="YES" id="jH0-2U-CBr"/>
<constraint firstItem="1wb-Ep-YUq" firstAttribute="centerY" secondItem="1" secondAttribute="centerY" id="qLl-h3-cDV"/>
<constraint firstItem="1wb-Ep-YUq" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="qdU-Bf-Nba"/>
</constraints>
Expand Down
2 changes: 1 addition & 1 deletion ShareExtension/ShareExtension.entitlements
Expand Up @@ -6,7 +6,7 @@
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(TeamIdentifierPrefix).gifski_video_share_group</string>
<string>$(TeamIdentifierPrefix)gifski_video_share_group</string>
</array>
</dict>
</plist>
25 changes: 11 additions & 14 deletions ShareExtension/ShareViewController.swift
Expand Up @@ -17,7 +17,7 @@ final class ShareViewController: NSViewController {
guard
let item = (extensionContext?.inputItems[0] as? NSExtensionItem)?.attachments?.first
else {
presentError(message: "The shared item does not contain an attachment")
presentError(message: "The shared item does not contain an attachment.")
return
}

Expand All @@ -29,7 +29,7 @@ final class ShareViewController: NSViewController {
} else if item.hasItemConformingToTypeIdentifier("com.apple.quicktime-movie") {
typeIdentifier = "com.apple.quicktime-movie"
} else {
presentError(message: "The shared item is not in a valid video format")
presentError(message: "The shared item is not in a supported video format.")
return
}

Expand All @@ -39,19 +39,19 @@ final class ShareViewController: NSViewController {
return
}

let shareUrl = "\(url.lastPathComponent)"
let appIdentifierPrefix = Bundle.main.infoDictionary!["AppIdentifierPrefix"] as! String
let shareUrl = url.lastPathComponent

guard
let appGroupShareVideUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "\(appIdentifierPrefix).gifski_video_share_group")?.appendingPathComponent(shareUrl)
let appGroupShareVideoUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Shared.videoShareGroupIdentifier)?.appendingPathComponent(shareUrl)
else {
self.presentError(message: "Could not share the video with the main app")
self.presentError(message: "Could not share the video with the main app.")
return
}

try? FileManager.default.removeItem(at: appGroupShareVideUrl)
try? FileManager.default.removeItem(at: appGroupShareVideoUrl)

do {
try FileManager.default.copyItem(at: url, to: appGroupShareVideUrl)
try FileManager.default.copyItem(at: url, to: appGroupShareVideoUrl)
} catch {
self.presentError(message: error.localizedDescription)
return
Expand All @@ -60,14 +60,11 @@ final class ShareViewController: NSViewController {
guard
let gifski = self.createMainAppUrl(
queryItems: [
URLQueryItem(
name: "path",
value: shareUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
)
URLQueryItem(name: "path", value: shareUrl)
]
)
else {
self.presentError(message: "Could not share the video with the main app")
self.presentError(message: "Could not share the video with the main app.")
return
}

Expand All @@ -84,7 +81,7 @@ final class ShareViewController: NSViewController {
errorLabel.stringValue = message
}

private func createMainAppUrl(queryItems: [URLQueryItem] = []) -> URL? {
private func createMainAppUrl(queryItems: [URLQueryItem]) -> URL? {
var components = URLComponents()
components.scheme = "gifski"
components.host = "shareExtension"
Expand Down

0 comments on commit 7167061

Please sign in to comment.