Skip to content

Commit

Permalink
Merge pull request #28 from wflixu/next
Browse files Browse the repository at this point in the history
v1.4.4
  • Loading branch information
wflixu authored Nov 14, 2024
2 parents 5d6bd71 + 9b2450c commit 36ac5e8
Show file tree
Hide file tree
Showing 37 changed files with 1,083 additions and 1,330 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ playground.xcworkspace
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

output/*
output/*
Build/
DerivedData/
2 changes: 1 addition & 1 deletion FinderSyncExt/FinderSyncExt.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.cn.wflixu.RClick</string>
<string>$(TeamIdentifierPrefix)cn.wflixu.RClick</string>
</array>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
Expand Down
233 changes: 117 additions & 116 deletions FinderSyncExt/FinderOpen.swift → FinderSyncExt/FinderSyncExt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,53 @@

import AppKit
import Cocoa
import Darwin
import FinderSync
import os.log

private let logger = Logger(subsystem: subsystem, category: "menu")
// MARK: DELETE

class FinderOpen: FIFinderSync {
import OSLog
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "RClick", category: "FinderOpen")

@MainActor
class FinderSyncExt: FIFinderSync {
// @AppLog(category: "AppState")
// private var logger

var myFolderURL = URL(fileURLWithPath: "/Users/")
var isHostAppOpen = true
let menuStore = MenuItemStore()
let folderStore = FolderItemStore()
let finderChannel = FinderCommChannel()
let messager = Messager.shared
var isHostAppOpen = false
lazy var appState: AppState = { AppState(inExt: true) }()

var bookmarkItems: [BookmarkFolderItem] = []
private var tagRidDict: [Int: String] = [:]

let messager = Messager.shared

var triggerManKind = FIMenuKind.contextualMenuForContainer

override init() {
super.init()

FIFinderSyncController.default().directoryURLs = [myFolderURL]
logger.info("FinderSync() launched from \(Bundle.main.bundlePath as NSString)")

logger.info("end ..... directoryURLS ...")

logger.info("---- finderOpen init")
finderChannel.setup(folderStore, menuStore)

messager.on(name: "quit") { _ in
// self.
logger.info("main app quited 。。。")
self.isHostAppOpen = false
}
messager.on(name: "running") { _ in
messager.on(name: "running") { payload in
self.isHostAppOpen = true
logger.warning("startt running")
// self.
logger.info("main app running\(payload.description)")
if payload.target.count > 0 {
FIFinderSyncController.default().directoryURLs = Set(payload.target.map { URL(fileURLWithPath: $0) })
}
Task {
self.appState.refresh()
}
}
}

Expand All @@ -44,7 +62,7 @@ class FinderOpen: FIFinderSync {
override func beginObservingDirectory(at url: URL) {
// The user is now seeing the container's contents.
// If they see it in more than one view at a time, we're only told once.
NSLog("beginObservingDirectoryAtURL: %@", url.path as NSString)
logger.info("beginObservingDirectoryAtURL: \(url.path as NSString)")
let dirs = FIFinderSyncController.default().directoryURLs!

for dir in dirs {
Expand All @@ -54,7 +72,7 @@ class FinderOpen: FIFinderSync {

override func endObservingDirectory(at url: URL) {
// The user is no longer seeing the container's contents.
NSLog("endObservingDirectoryAtURL: %@", url.path as NSString)
logger.info("endObservingDirectoryAtURL: \(url.path as NSString)")
}

override func requestBadgeIdentifier(for url: URL) {
Expand All @@ -75,119 +93,91 @@ class FinderOpen: FIFinderSync {
return NSImage(named: "toolbar")!
}

@MainActor func initMenuDirs() throws {
do {
let bks = try folderStore.getBookmarkItems()
logger.warning("start init fifindersync ")
if bks.isEmpty {
logger.warning("start init fifindersync empty ")
} else {
logger.warning("start init fifindersync else")
for dir in bks {
logger.warning("Sync directory set to \(dir.path) ")
}
}
} catch {
logger.error("Failed to load URLs: \(error)")
}
}

@MainActor override func menu(for menuKind: FIMenuKind) -> NSMenu {
// Produce a menu for the extension.
logger.info("mak menddd .....")
triggerManKind = menuKind

logger.info("start build menu ....")
let applicationMenu = NSMenu(title: "RClick")
guard isHostAppOpen else {
return applicationMenu
}
switch menuKind {
// finder 中my选中文件或文件夹
case .contextualMenuForContainer:
createMenuForContainer(applicationMenu)

// finder 中 有选中文件或文件夹
case .contextualMenuForItems:
NSLog("contextualMenuForItems")

createMenuForItems(applicationMenu)

case .toolbarItemMenu:

switch menuKind {
// finder 中没有选中文件或文件夹

case .toolbarItemMenu, .contextualMenuForItems, .contextualMenuForContainer:
logger.info("mak menddd .....")
createMenuForToolbar(applicationMenu)

default:
print("Some other character")
logger.warning("not have menuKind ")
}

return applicationMenu
}
@objc func createMenuForContainer(_ applicationMenu: NSMenu) {

@objc func createMenuForToolbar(_ applicationMenu: NSMenu) {
for nsmenu in createAppItems() {
applicationMenu.addItem(nsmenu)
}

if let fileMenuItem = createFileCreateMenuItem() {
applicationMenu.addItem(fileMenuItem)
}
}

@objc func createMenuForItems(_ applicationMenu: NSMenu) {
for nsmenu in createAppItems() {
applicationMenu.addItem(nsmenu)
}

for item in createActionMenuItems() {
applicationMenu.addItem(item)
}
}

@objc func createMenuForToolbar(_ applicationMenu: NSMenu) {
for nsmenu in createAppItems() {
applicationMenu.addItem(nsmenu)
}

if let fileMenuItem = createFileCreateMenuItem() {
applicationMenu.addItem(fileMenuItem)
}
}


@objc func createAppItems() -> [NSMenuItem] {
var appMenuItems: [NSMenuItem] = []
for item in menuStore.appItems {
//
for item in appState.apps {
let menuItem = NSMenuItem()
menuItem.target = self
menuItem.title = String(localized: "Open With \(item.name)")
menuItem.action = #selector(appOpen(_:))
menuItem.toolTip = "\(item.name)"
menuItem.tag = 0
menuItem.tag = getUniqueTag(for: item.id)
menuItem.image = NSWorkspace.shared.icon(forFile: item.url.path)
appMenuItems.append(menuItem)
}
return appMenuItems
}

private func getUniqueTag(for rid: String) -> Int {
var newTag = Int.random(in: 1...Int.max)

// 确保生成的 tag 不在已有的 keys 中
while tagRidDict.keys.contains(newTag) {
newTag = Int.random(in: 1...Int.max)
}
tagRidDict[newTag] = rid
return newTag
}

@objc func createActionMenuItems() -> [NSMenuItem] {
var actionMenuitems: [NSMenuItem] = []

for item in menuStore.actionItems.filter(\.enabled) {
for item in appState.actions.filter(\.enabled) {
let menuItem = NSMenuItem()
menuItem.target = self
menuItem.title = String(localized: String.LocalizationValue(item.key))
menuItem.title = String(localized: String.LocalizationValue(item.name))
menuItem.action = #selector(actioning(_:))
menuItem.toolTip = "\(item.name)"
menuItem.tag = 1
menuItem.image = NSImage(systemSymbolName: item.iconName, accessibilityDescription: item.iconName)!
logger.info("item key\(item.key)")
menuItem.tag = getUniqueTag(for: item.id)
menuItem.image = NSImage(systemSymbolName: item.icon, accessibilityDescription: item.name)!

actionMenuitems.append(menuItem)
}
return actionMenuitems
}


// 创建文件菜单容器
@objc func createFileCreateMenuItem() -> NSMenuItem? {
let enabledFiletypeItems = menuStore.filetypeItems.filter(\.enabled)
let enabledFiletypeItems = appState.newFiles.filter(\.enabled)
if enabledFiletypeItems.isEmpty {
return nil
}
Expand All @@ -201,79 +191,90 @@ class FinderOpen: FIFinderSync {
menuItem.title = item.name
menuItem.action = #selector(createFile(_:))
menuItem.toolTip = "\(item.name)"
menuItem.tag = 2
if let img = NSImage(named: item.iconName) {
menuItem.tag = getUniqueTag(for: item.id)

if let img = NSImage(named: item.icon) {
menuItem.image = img
} else {
logger.info("")
}

submenu.addItem(menuItem)
}
menuItem.submenu = submenu
return menuItem
}

@MainActor @objc func createFile(_ menuItem: NSMenuItem) {
let item = menuStore.getFileCreateItem(name: menuItem.title)
guard let rid = tagRidDict[menuItem.tag] else {
logger.warning("not get rid for \(menuItem.tag)")
return
}
let url = FIFinderSyncController.default().targetedURL()
if let target = url?.path(), let ext = item?.ext {
messager.sendMessage(name: Key.messageFromFinder, data: MessagePayload(action: "Create File", target: [target], ext: ext))

if let target = url?.path() {
messager.sendMessage(name: Key.messageFromFinder, data: MessagePayload(action: "Create File", target: [target], rid: rid))
}
}

@MainActor @objc func actioning(_ menuItem: NSMenuItem) {
guard let item = menuStore.getActionItem(name: menuItem.title) else {
logger.info("not item ad ")
guard let rid = tagRidDict[menuItem.tag] else {
logger.warning("not get rid")
return
}
guard let urls = FIFinderSyncController.default().selectedItemURLs(), !urls.isEmpty else {
logger.info("not urls")
let target = getTargets(triggerManKind)
if target.isEmpty {
logger.warning("not dir when actioning")
return
}

let urlstr = urls.map { $0.path }
messager.sendMessage(name: Key.messageFromFinder, data: MessagePayload(action: item.key, target: urlstr))
messager.sendMessage(name: Key.messageFromFinder, data: MessagePayload(action: "actioning", target: target, rid: rid))
}

@objc func appOpen(_ menuItem: NSMenuItem) {

var target: String
func getTargets(_ kind: FIMenuKind) -> [String] {
var target: [String] = []

switch triggerManKind {
case FIMenuKind.contextualMenuForItems:
let urls = FIFinderSyncController.default().selectedItemURLs()
guard let targetURL = urls?.first
else { return }
target = targetURL.path
case FIMenuKind.toolbarItemMenu:
let selectedURLs = FIFinderSyncController.default().selectedItemURLs()

if let targetURL = selectedURLs?.first {
target = targetURL.path
if let urls = FIFinderSyncController.default().selectedItemURLs() {
for url in urls {
target.append(url.path())
}
} else {
logger.warning("not have selected dirs")
}

if let targetURL2 = FIFinderSyncController.default().targetedURL() {
target = targetURL2.path
} else {
logger.warning("no target URL")
return
case FIMenuKind.toolbarItemMenu:
if let urls = FIFinderSyncController.default().selectedItemURLs() {
for url in urls {
target.append(url.path())
}
}
if target.isEmpty {
if let targetURL = FIFinderSyncController.default().targetedURL() {
target.append(targetURL.path())
}
}

default:
guard let targetURL = FIFinderSyncController.default().targetedURL()
else { return }
target = targetURL.path
if let targetURL = FIFinderSyncController.default().targetedURL() {
target.append(targetURL.path())
}
}


return target
}

@objc func appOpen(_ menuItem: NSMenuItem) {
guard let rid = tagRidDict[menuItem.tag] else {
logger.warning("not get rid")
return
}

let item = menuStore.getAppItem(name: menuItem.title)
if let appUrl = item?.url {
messager.sendMessage(name: Key.messageFromFinder, data: MessagePayload(action: "open", target: [target], app: appUrl.path))
let target: [String] = getTargets(triggerManKind)
if !target.isEmpty {
messager.sendMessage(name: Key.messageFromFinder, data: MessagePayload(action: "open", target: target, rid: rid))
} else {
logger.warning("not get target")
}
}
}
Loading

0 comments on commit 36ac5e8

Please sign in to comment.