Skip to content

Commit

Permalink
🔖 Releasing v0.16.0
Browse files Browse the repository at this point in the history
- Added: Provide command line to upload.
- Added: Support for SM.MS Version 2.
- Added: Weibo host supports custom configuration domain.
- Improved: Optimize browser drag and drop upload.  More formats supported (including GIF).
- Improved: When uploading duplicate pictures on the SM.MS hosts, it will automatically return to the existing picture link.
- Improved: Update icon
  • Loading branch information
gee1k committed Jan 2, 2020
2 parents 8fc68e4 + b4b9950 commit 830e69a
Show file tree
Hide file tree
Showing 108 changed files with 2,884 additions and 355 deletions.
6 changes: 3 additions & 3 deletions Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PODS:
- Alamofire (5.0.0-rc.3)
- CryptoSwift (1.2.0)
- CryptoSwift (1.3.0)
- Kingfisher (5.9.0):
- Kingfisher/Core (= 5.9.0)
- Kingfisher/Core (5.9.0)
Expand Down Expand Up @@ -55,7 +55,7 @@ EXTERNAL SOURCES:

CHECKOUT OPTIONS:
CryptoSwift:
:commit: de6030ce08110b9c6c27310b47b1a4ffc98c4173
:commit: a44caef0550c346e0ab9172f7c9a3852c1833599
:git: https://github.com/krzyzanowskim/CryptoSwift
LoginServiceKit:
:commit: 01b162248760b5fed4c7bffebee37eb92351b41b
Expand All @@ -66,7 +66,7 @@ CHECKOUT OPTIONS:

SPEC CHECKSUMS:
Alamofire: ca8c0de6906873be89d6deec5c8de279e00bf872
CryptoSwift: 40e374e45291d8dceedcb0d6184da94533eaabdf
CryptoSwift: 1283821600233bdbeb96d7b389c3288c3bf77211
Kingfisher: ff98240aebb7302bdc4f1ecd701761030ce18b16
libminipng: c5f4492bf378d3de8dfa3afd4c4372480f52fa9f
LoginServiceKit: 9a8b258c3111fa0d9585615052f778b08be92302
Expand Down
84 changes: 80 additions & 4 deletions uPic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

192 changes: 124 additions & 68 deletions uPic/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import AppKit
import ScriptingBridge
import MASShortcut


@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

/* 状态栏菜单 */
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
var statusItem: NSStatusItem? = nil
let indicator = NSProgressIndicator()

@IBOutlet weak var statusItemMenu: NSMenu!
Expand All @@ -29,92 +30,123 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// 上传成功的url
var resultUrls = [String]()

// MARK: - Cli Support
// 上传来源
var uploadSourceType: UploadSourceType! = .normal

lazy var preferencesWindowController: PreferencesWindowController = {
let storyboard = NSStoryboard(name: "Preferences", bundle: nil)
return storyboard.instantiateInitialController() as? PreferencesWindowController ?? PreferencesWindowController()
}()


func applicationWillFinishLaunching(_ notification: Notification) {
// 添加 url scheme 监听
NSAppleEventManager.shared().setEventHandler(self, andSelector:#selector(handleGetURLEvent(event:withReplyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
let isCommandLineState = Cli.shared.handleCommandLine()
if isCommandLineState {
return
}

}

func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
ConfigManager.shared.firstSetup()
// Register events and status bar menus only in non-command line mode

// Request notification permission
NotificationExt.requestAuthorization()

self.setupStatusBar()
let currentApplication = NSRunningApplication.current

let applications = NSWorkspace.shared.runningApplications.filter{ $0.bundleIdentifier == currentApplication.bundleIdentifier }
if applications.count > 1 {
NotificationExt.shared.postAppIsAlreadyRunningNotice()
currentApplication.terminate()
}

self.bindShortcuts()
// Set status bar icon and progress icon
setupStatusBar()

// 添加 Finder 右键文件上传监听
bindShortcuts()

// Add Finder context menu file upload listener
UploadNotifier.addObserver(observer: self, selector: #selector(uploadFilesFromFinderMenu), notification: .uploadFiles)

// Add URL scheme listening
NSAppleEventManager.shared().setEventHandler(self, andSelector:#selector(handleGetURLEvent(event:withReplyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))


}

func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
ConfigManager.shared.firstSetup()
}

func applicationWillTerminate(_ notification: Notification) {
NSStatusBar.system.removeStatusItem(statusItem)
// 移除 Finder 右键文件上传监听
if let statusItem = statusItem {
NSStatusBar.system.removeStatusItem(statusItem)
}
// Remove Finder context menu file upload listener
UploadNotifier.removeObserver(observer: self, notification: .uploadFiles)
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
return true
}

// Finder 中选中文件右键上传时调用的方法
// Finder context menu file upload listener
@objc func uploadFilesFromFinderMenu(notification: Notification) {

let pathStr = notification.object as? String ?? ""
uploadFilesFromPaths(pathStr)
}

@objc func handleGetURLEvent(event: NSAppleEventDescriptor!, withReplyEvent: NSAppleEventDescriptor!) {
if let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue, let url = NSURL(string: urlString) {

// 解析出参数
var param = urlString
let i = "\(url.scheme!)://".count
param.removeFirst(i)

/// 解析参数类型
let keyValue = param.split(separator: "?")
switch keyValue.first {
case "files":
if (keyValue.count == 2) {
let pathStr = String(keyValue.last ?? "")
self.uploadFilesFromPaths(pathStr.urlDecoded())
}
case "url":
if (keyValue.count == 2) {
let url = String(keyValue.last ?? "")
if let fileUrl = URL(string: url.urlDecoded()), let data = try? Data(contentsOf: fileUrl) {
self.uploadFiles([data])
}
}
default:
debugPrint(keyValue)
}
if let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue{
URLSchemeExt.shared.handleURL(urlString)
}
}
}
// MARK: - Statusbar
extension AppDelegate {

func setupStatusBar() {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
setStatusBarIcon()
setupStatusBarIndicator()

registerStatusBarEvents()
}

private func setupStatusBarIndicator() {
guard let statusItem = statusItem else {
return
}
if let button = statusItem.button {
self.setStatusBarIcon()
button.window?.delegate = self

button.window?.registerForDraggedTypes([NSPasteboard.PasteboardType("NSFilenamesPboardType")])
indicator.frame = NSRect(x: (button.frame.width - 16) / 2,
y: (button.frame.height - 16) / 2,
width: 16,
height: 16)
button.addSubview(indicator)
}
// 初始化任务栏进度图标
indicator.minValue = 0.0
indicator.maxValue = 1.0
indicator.doubleValue = 0.0
indicator.isIndeterminate = false
indicator.controlSize = NSControl.ControlSize.small
indicator.style = NSProgressIndicator.Style.spinning
indicator.isHidden = true
indicator.toolTip = "Right click to cancel the current upload task".localized
}

private func registerStatusBarEvents() {
guard let statusItem = statusItem else {
return
}
statusItem.menu = nil

if let button = statusItem.button {

button.window?.delegate = self

button.window?.registerForDraggedTypes([NSPasteboard.PasteboardType("NSFilenamesPboardType")])
button.action = #selector(statusBarButtonClicked)
button.sendAction(on: [.leftMouseUp, .leftMouseDown,
.rightMouseUp, .rightMouseDown])
Expand All @@ -128,21 +160,12 @@ extension AppDelegate {
}

}

statusItem.menu = nil

// 初始化任务栏进度图标
indicator.minValue = 0.0
indicator.maxValue = 1.0
indicator.doubleValue = 0.0
indicator.isIndeterminate = false
indicator.controlSize = NSControl.ControlSize.small
indicator.style = NSProgressIndicator.Style.spinning
indicator.isHidden = true
indicator.toolTip = "Right click to cancel the current upload task".localized
}

@objc func statusBarButtonClicked(sender: NSStatusBarButton) {
guard let statusItem = statusItem else {
return
}
let event = NSApp.currentEvent!
if event.type == .leftMouseDown || event.type == .leftMouseUp
|| event.modifierFlags.contains(.control)
Expand All @@ -162,10 +185,13 @@ extension AppDelegate {
}

func setStatusBarIcon(isIndicator: Bool = false) {
guard let statusItem = statusItem else {
return
}

if isIndicator {
DispatchQueue.main.async {
self.statusItem.button?.image = nil
statusItem.button?.image = nil
self.indicator.doubleValue = 0.0
self.indicator.isHidden = false
}
Expand All @@ -174,7 +200,7 @@ extension AppDelegate {
let icon = NSImage(named: "statusIcon")
icon!.isTemplate = true
DispatchQueue.main.async {
self.statusItem.button?.image = icon
statusItem.button?.image = icon
self.indicator.isHidden = true
}
}
Expand Down Expand Up @@ -302,7 +328,10 @@ extension AppDelegate {
}

// 上传多个文件
func uploadFiles(_ files: [Any]) {
// MARK: - Cli Support
func uploadFiles(_ files: [Any], _ uploadSourceType: UploadSourceType? = .normal) {
self.uploadSourceType = uploadSourceType

self.needUploadFiles = files
self.resultUrls.removeAll()

Expand All @@ -318,12 +347,7 @@ extension AppDelegate {
func tickFileToUpload() {
if self.needUploadFiles.count == 0 {
// done
self.uploding = false
if self.resultUrls.count > 0 {
let outputStr = self.copyUrls(urls: self.resultUrls)
NotificationExt.shared.postUploadSuccessfulNotice(outputStr)
self.resultUrls.removeAll()
}
uploadDone()
} else {
// next file
let firstFile = self.needUploadFiles.first
Expand All @@ -332,6 +356,12 @@ extension AppDelegate {
BaseUploader.upload(url: firstFile as! URL)
} else if firstFile is Data {
BaseUploader.upload(data: firstFile as! Data)
} else {
// MARK: - Cli Support
if self.uploadSourceType == UploadSourceType.cli {
Cli.shared.uploadError()
}
tickFileToUpload()
}
}
}
Expand All @@ -342,6 +372,12 @@ extension AppDelegate {
func uploadCompleted(url: String) {
self.setStatusBarIcon(isIndicator: false)
self.resultUrls.append(url)

// MARK: - Cli Support
if self.uploadSourceType == UploadSourceType.cli {
Cli.shared.uploadProgress(url)
}

self.tickFileToUpload()
}

Expand All @@ -350,7 +386,13 @@ extension AppDelegate {
///
func uploadFaild(errorMsg: String? = "") {
self.setStatusBarIcon(isIndicator: false)
NotificationExt.shared.postUploadErrorNotice(errorMsg)
// MARK: - Cli Support
if self.uploadSourceType == UploadSourceType.cli {
Cli.shared.uploadError(errorMsg)
} else {
NotificationExt.shared.postUploadErrorNotice(errorMsg)
}

self.tickFileToUpload()
}

Expand All @@ -373,8 +415,22 @@ extension AppDelegate {
self.uploding = false
}

func copyUrls(urls: [String]) -> String {
func uploadDone() {
self.uploding = false
// MARK: - Cli Support
if uploadSourceType == UploadSourceType.cli {
Cli.shared.uploadDone()
} else {
if self.resultUrls.count > 0 {
let outputStr = self.copyUrls(urls: self.resultUrls)
NotificationExt.shared.postUploadSuccessfulNotice(outputStr)
}
}

self.resultUrls.removeAll()
}

func copyUrls(urls: [String]) -> String {
let outputUrls = BaseUploaderUtil.formatOutputUrls(urls)
let outputStr = outputUrls.joined(separator: "\n")
NSPasteboard.general.clearContents()
Expand All @@ -389,7 +445,7 @@ extension AppDelegate {
extension AppDelegate: NSWindowDelegate, NSDraggingDestination {
func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
if sender.isValid {
if let button = statusItem.button {
if let statusItem = statusItem, let button = statusItem.button {
button.image = NSImage(named: "uploadIcon")
}
return .copy
Expand Down Expand Up @@ -428,7 +484,7 @@ extension AppDelegate: NSWindowDelegate, NSDraggingDestination {
}

extension AppDelegate {
// sponsor
// sponsor

func sponsorByPaypal() {
guard let url = URL(string: "https://paypal.me/geee1k") else { return }
Expand Down
Binary file removed uPic/Assets.xcassets/host_icon_1.imageset/smms.png
Binary file not shown.
Binary file removed uPic/Assets.xcassets/host_icon_10.imageset/imgur.png
Binary file not shown.
Binary file not shown.
Binary file removed uPic/Assets.xcassets/host_icon_2.imageset/qiniu.png
Binary file not shown.
Binary file removed uPic/Assets.xcassets/host_icon_3.imageset/upyun.png
Binary file not shown.
Binary file removed uPic/Assets.xcassets/host_icon_4.imageset/aliyun.png
Binary file not shown.
Binary file not shown.
21 changes: 0 additions & 21 deletions uPic/Assets.xcassets/host_icon_6.imageset/Contents.json

This file was deleted.

Binary file removed uPic/Assets.xcassets/host_icon_6.imageset/github.png
Binary file not shown.
Binary file removed uPic/Assets.xcassets/host_icon_7.imageset/gitee.png
Binary file not shown.
Loading

0 comments on commit 830e69a

Please sign in to comment.