mirror of
https://github.com/carey314/mio-plugin-airdrop.git
synced 2026-06-11 03:54:33 +00:00
Quick-access AirDrop from the notch panel. Tap the card body, pick files via NSOpenPanel, hand off to NSSharingService(.sendViaAirDrop). No private APIs, no entitlements, no network — just a thin wrapper around the same AirDrop API Finder uses. Design constraint: drag-and-drop is intentionally not implemented. MioIsland's notch panel auto-collapses on click-outside, which breaks the Cmd-Tab-to-Finder / grab / drag-back workflow before the drop target reaches. Tap-to-choose is rock solid by comparison. Requires MioIsland host v2.2.0+ (panel size clamp floor was lowered to 120pt in that release).
47 lines
1.5 KiB
Swift
47 lines
1.5 KiB
Swift
//
|
|
// HostVersionCheck.swift
|
|
// MioIsland AirDrop Plugin
|
|
//
|
|
// Gates the plugin against a minimum host version. Plugin relies on
|
|
// the v2.2.0 panel-sizing rules (min height 120, floating back chip,
|
|
// no chrome header), so older hosts would render this plugin wrong.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
enum HostVersionCheck {
|
|
static let minHost = "2.2.0"
|
|
|
|
/// Bundle.main inside a plugin dylib points to the *host* app, so
|
|
/// we can read its CFBundleShortVersionString to gate features.
|
|
static func isOK() -> Bool {
|
|
let host = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0"
|
|
return compare(host, ">=", minHost)
|
|
}
|
|
|
|
static func hostVersion() -> String {
|
|
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "?"
|
|
}
|
|
|
|
// MARK: - Pure semver compare
|
|
|
|
private static func compare(_ a: String, _ op: String, _ b: String) -> Bool {
|
|
let aParts = parts(a)
|
|
let bParts = parts(b)
|
|
let maxLen = max(aParts.count, bParts.count)
|
|
let ap = aParts + Array(repeating: 0, count: maxLen - aParts.count)
|
|
let bp = bParts + Array(repeating: 0, count: maxLen - bParts.count)
|
|
|
|
switch op {
|
|
case ">=": return !ap.lexicographicallyPrecedes(bp)
|
|
case "<": return ap.lexicographicallyPrecedes(bp)
|
|
case "==": return ap == bp
|
|
default: return false
|
|
}
|
|
}
|
|
|
|
private static func parts(_ s: String) -> [Int] {
|
|
s.split(separator: ".").compactMap { Int($0) }
|
|
}
|
|
}
|