merge batch 3: MacSyncApp menu (reminders+notes+contacts), Info.plist; deploy/entitlements kept apricot
This commit is contained in:
parent
bf3879feba
commit
c420741292
2 changed files with 72 additions and 5 deletions
|
|
@ -4,7 +4,9 @@ import Foundation
|
|||
import ICalSync
|
||||
import IMailSync
|
||||
import IMessageSync
|
||||
import INoteSync
|
||||
import IPhotoSync
|
||||
import IReminderSync
|
||||
import MacSyncShared
|
||||
import Photos
|
||||
|
||||
|
|
@ -27,11 +29,15 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
private let iPhotoSync = IPhotoSync.SyncManager.shared
|
||||
private let iMailSync = IMailSync.SyncManager.shared
|
||||
private let iCalSync = ICalSync.SyncManager.shared
|
||||
private let iReminderSync = IReminderSync.SyncManager.shared
|
||||
private let iNoteSync = INoteSync.SyncManager.shared
|
||||
private let webServer = LocalWebServer()
|
||||
private var syncStatusItem: NSMenuItem?
|
||||
private var iphotoStatusItem: NSMenuItem?
|
||||
private var imailStatusItem: NSMenuItem?
|
||||
private var icalStatusItem: NSMenuItem?
|
||||
private var ireminderStatusItem: NSMenuItem?
|
||||
private var inoteStatusItem: NSMenuItem?
|
||||
private var contactRenderStatusItem: NSMenuItem?
|
||||
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
|
|
@ -62,6 +68,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
iPhotoSync.startSync()
|
||||
iMailSync.startSync()
|
||||
iCalSync.startSync()
|
||||
iReminderSync.startSync()
|
||||
iNoteSync.startSync()
|
||||
ContactRenderPoller.shared.start()
|
||||
} else {
|
||||
let existingDeviceId = try? macSyncSharedKeychain.loadString(key: "deviceId")
|
||||
|
|
@ -96,6 +104,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
self.iPhotoSync.startSync()
|
||||
self.iMailSync.startSync()
|
||||
self.iCalSync.startSync()
|
||||
self.iReminderSync.startSync()
|
||||
self.iNoteSync.startSync()
|
||||
ContactRenderPoller.shared.start()
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -134,6 +144,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
menu.addItem(iCalItem)
|
||||
icalStatusItem = iCalItem
|
||||
|
||||
let iReminderItem = NSMenuItem(title: "Reminders: idle", action: nil, keyEquivalent: "")
|
||||
iReminderItem.isEnabled = false
|
||||
menu.addItem(iReminderItem)
|
||||
ireminderStatusItem = iReminderItem
|
||||
|
||||
let iNoteItem = NSMenuItem(title: "Notes: idle", action: nil, keyEquivalent: "")
|
||||
iNoteItem.isEnabled = false
|
||||
menu.addItem(iNoteItem)
|
||||
inoteStatusItem = iNoteItem
|
||||
|
||||
let contactRenderItem = NSMenuItem(title: "Contacts: idle", action: nil, keyEquivalent: "")
|
||||
contactRenderItem.isEnabled = false
|
||||
menu.addItem(contactRenderItem)
|
||||
|
|
@ -223,6 +243,32 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
icalStatusItem?.title = "iCal: idle"
|
||||
}
|
||||
|
||||
// Reminders
|
||||
if iReminderSync.isSyncing {
|
||||
ireminderStatusItem?.title = "Reminders: \(iReminderSync.currentOperation)"
|
||||
} else if let last = iReminderSync.lastSyncCompletedAt {
|
||||
let total = iReminderSync.stats.reminderCount
|
||||
let suffix = total > 0 ? " (\(total) reminders)" : ""
|
||||
ireminderStatusItem?.title = "Reminders: \(relFormatter.localizedString(for: last, relativeTo: Date()))\(suffix)"
|
||||
} else if iReminderSync.syncError != .none {
|
||||
ireminderStatusItem?.title = "Reminders: \(iReminderSync.syncError.message)"
|
||||
} else {
|
||||
ireminderStatusItem?.title = "Reminders: idle"
|
||||
}
|
||||
|
||||
// Notes
|
||||
if iNoteSync.isSyncing {
|
||||
inoteStatusItem?.title = "Notes: \(iNoteSync.currentOperation)"
|
||||
} else if let last = iNoteSync.lastSyncCompletedAt {
|
||||
let total = iNoteSync.stats.noteCount
|
||||
let suffix = total > 0 ? " (\(total) notes)" : ""
|
||||
inoteStatusItem?.title = "Notes: \(relFormatter.localizedString(for: last, relativeTo: Date()))\(suffix)"
|
||||
} else if iNoteSync.syncError != .none {
|
||||
inoteStatusItem?.title = "Notes: \(iNoteSync.syncError.message)"
|
||||
} else {
|
||||
inoteStatusItem?.title = "Notes: idle"
|
||||
}
|
||||
|
||||
// Contact render
|
||||
let poller = ContactRenderPoller.shared
|
||||
if !poller.lastError.isEmpty {
|
||||
|
|
@ -242,6 +288,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
iPhotoSync.syncNow()
|
||||
iMailSync.syncNow()
|
||||
iCalSync.syncNow()
|
||||
iReminderSync.syncNow()
|
||||
iNoteSync.syncNow()
|
||||
}
|
||||
|
||||
@objc private func openSettings() {
|
||||
|
|
@ -280,7 +328,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
calendars.target = self
|
||||
submenu.addItem(calendars)
|
||||
|
||||
let automation = NSMenuItem(title: "Grant Messages + Mail Automation…", action: #selector(requestAutomation), keyEquivalent: "")
|
||||
let reminders = NSMenuItem(title: "Grant Reminders…", action: #selector(requestReminders), keyEquivalent: "")
|
||||
reminders.target = self
|
||||
submenu.addItem(reminders)
|
||||
|
||||
let automation = NSMenuItem(title: "Grant Messages + Mail + Notes Automation…", action: #selector(requestAutomation), keyEquivalent: "")
|
||||
automation.target = self
|
||||
submenu.addItem(automation)
|
||||
|
||||
|
|
@ -372,13 +424,28 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
@objc private func requestReminders() {
|
||||
NSLog("MacSync: requesting reminders permission")
|
||||
Task {
|
||||
let granted = await iReminderSync.reader.requestAuthorization()
|
||||
if !granted {
|
||||
await MainActor.run {
|
||||
NSWorkspace.shared.open(
|
||||
URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Reminders")!
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func requestAutomation() {
|
||||
NSLog("MacSync: priming Messages + Mail automation TCC")
|
||||
NSLog("MacSync: priming Messages + Mail + Notes automation TCC")
|
||||
// Sending a harmless AppleScript to each app registers MacSync in the Automation
|
||||
// pane and surfaces the first-time "Allow" prompt.
|
||||
let probe = """
|
||||
tell application \"Messages\" to get name
|
||||
tell application \"Mail\" to get name
|
||||
tell application \"Notes\" to get name
|
||||
"""
|
||||
var errorInfo: NSDictionary?
|
||||
_ = NSAppleScript(source: probe)?.executeAndReturnError(&errorInfo)
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
<key>NSContactsUsageDescription</key>
|
||||
<string>MacSync syncs your contacts to your personal server.</string>
|
||||
<key>NSCalendarsUsageDescription</key>
|
||||
<string>MacSync syncs your calendar events to your personal server.</string>
|
||||
<string>MacSync reads and writes calendar events so changes made on the web sync back to Calendar.app.</string>
|
||||
<key>NSRemindersUsageDescription</key>
|
||||
<string>MacSync syncs your reminders to your personal server.</string>
|
||||
<string>MacSync reads and writes Reminders so changes made on the web sync back to Reminders.app.</string>
|
||||
<key>NSAppleEventsUsageDescription</key>
|
||||
<string>MacSync reads your Mail.app messages to sync email to your personal server.</string>
|
||||
<string>MacSync controls Messages.app, Mail.app, and Notes.app via AppleScript to sync messages, email, and notes to and from your personal server.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue