From 110b0a4ae75f9fce13d5ea80600406e8afd8fd78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6ttger?= Date: Tue, 9 Sep 2025 11:35:44 +0200 Subject: [PATCH] Add alert if share extension disabled --- QuickDrop.xcodeproj/project.pbxproj | 10 + QuickDrop/AppDelegate.swift | 3 +- QuickDrop/Localizable.xcstrings | 394 ++++++++++++++--------- QuickDrop/Util/SendToExtension.swift | 23 ++ QuickDrop/View/TutorialView.swift | 2 +- QuickDrop/View/WelcomeScreen.swift | 6 - ShareExtension/View/SmallSheetView.swift | 2 +- 7 files changed, 286 insertions(+), 154 deletions(-) create mode 100644 QuickDrop/Util/SendToExtension.swift diff --git a/QuickDrop.xcodeproj/project.pbxproj b/QuickDrop.xcodeproj/project.pbxproj index 37961cf..970bf62 100644 --- a/QuickDrop.xcodeproj/project.pbxproj +++ b/QuickDrop.xcodeproj/project.pbxproj @@ -33,6 +33,10 @@ EB1325F42E7025D900FD749C /* ApIsolationTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E92E7025D900FD749C /* ApIsolationTester.swift */; }; EB1325F52E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */; }; EB1325F62E7025D900FD749C /* ApIsolation6Tester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */; }; + EB1325F82E70288300FD749C /* SendToExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325F72E70287C00FD749C /* SendToExtension.swift */; }; + EB1325F92E70288300FD749C /* SendToExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325F72E70287C00FD749C /* SendToExtension.swift */; }; + EB1325FA2E70288300FD749C /* SendToExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325F72E70287C00FD749C /* SendToExtension.swift */; }; + EB1325FB2E70288300FD749C /* SendToExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325F72E70287C00FD749C /* SendToExtension.swift */; }; EB16B6122E58B4B9007D9792 /* IdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16B6112E58B4B9007D9792 /* IdentityManager.swift */; }; EB16B6132E58B4B9007D9792 /* IdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16B6112E58B4B9007D9792 /* IdentityManager.swift */; }; EB16B6142E58B4B9007D9792 /* IdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16B6112E58B4B9007D9792 /* IdentityManager.swift */; }; @@ -318,6 +322,7 @@ EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveNetworkInterface.swift; sourceTree = ""; }; EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolation6Tester.swift; sourceTree = ""; }; EB1325E92E7025D900FD749C /* ApIsolationTester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolationTester.swift; sourceTree = ""; }; + EB1325F72E70287C00FD749C /* SendToExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToExtension.swift; sourceTree = ""; }; EB16B6112E58B4B9007D9792 /* IdentityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityManager.swift; sourceTree = ""; }; EB16B6162E58B4C8007D9792 /* TrustStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustStore.swift; sourceTree = ""; }; EB16B7762E59BA9F007D9792 /* AppGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppGroup.swift; sourceTree = ""; }; @@ -627,6 +632,7 @@ EBC05C6B2E33B57100EECC18 /* Util */ = { isa = PBXGroup; children = ( + EB1325F72E70287C00FD749C /* SendToExtension.swift */, EB5C383E2E38C49D0052EFD7 /* LaunchAtLogin.swift */, EB886E662E4F2F7C0052B7D9 /* License.swift */, EB36435F2D73A29F009CDFF8 /* AudioManager.swift */, @@ -898,6 +904,7 @@ files = ( EB704A832E4B10D4008E608F /* DistributionDetector.swift in Sources */, EB96ED902D7F8114004B3FF1 /* Localized.swift in Sources */, + EB1325F82E70288300FD749C /* SendToExtension.swift in Sources */, EB16B6172E58B4C8007D9792 /* TrustStore.swift in Sources */, EB886E542E4E19390052B7D9 /* HKDF.swift in Sources */, EBC05C862E33B58300EECC18 /* NetworkFilterIssueView.swift in Sources */, @@ -984,6 +991,7 @@ EB16B77A2E59BAA1007D9792 /* AppGroup.swift in Sources */, EBC05C822E33B58300EECC18 /* ApIsolationIssueView.swift in Sources */, EBC05C832E33B58300EECC18 /* FirewallIssueView.swift in Sources */, + EB1325FA2E70288300FD749C /* SendToExtension.swift in Sources */, EB1325F42E7025D900FD749C /* ApIsolationTester.swift in Sources */, EB1325F52E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */, EB1325F62E7025D900FD749C /* ApIsolation6Tester.swift in Sources */, @@ -1020,6 +1028,7 @@ EB5C37FE2E377CE70052EFD7 /* offline_wire_formats.pb.swift in Sources */, EB886E6A2E4F37B90052B7D9 /* ErrorAlertHandler.swift in Sources */, EB886E5E2E4F13EB0052B7D9 /* Zip.swift in Sources */, + EB1325F92E70288300FD749C /* SendToExtension.swift in Sources */, EB5C383D2E38C2D90052EFD7 /* AudioManager.swift in Sources */, EB979F942E50CA23008B8C5C /* Configuration.swift in Sources */, EB979F952E50CA23008B8C5C /* ContentView.swift in Sources */, @@ -1048,6 +1057,7 @@ EB950B572E520591002D68FA /* ErrorAlertHandler.swift in Sources */, EB950B462E520436002D68FA /* OutboundNearbyConnection.swift in Sources */, EB950B472E520436002D68FA /* sharing_enums.pb.swift in Sources */, + EB1325FB2E70288300FD749C /* SendToExtension.swift in Sources */, EB950B482E520436002D68FA /* Localized.swift in Sources */, EB950B492E520436002D68FA /* device_to_device_messages.pb.swift in Sources */, EB1325F12E7025D900FD749C /* ApIsolationTester.swift in Sources */, diff --git a/QuickDrop/AppDelegate.swift b/QuickDrop/AppDelegate.swift index cc6a786..a39d1a2 100644 --- a/QuickDrop/AppDelegate.swift +++ b/QuickDrop/AppDelegate.swift @@ -191,8 +191,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } } else { - let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) - sharingService?.perform(withItems: [clipboardString]) + sendToSharingService(items: [clipboardString]) } } diff --git a/QuickDrop/Localizable.xcstrings b/QuickDrop/Localizable.xcstrings index d00e438..4b38002 100644 --- a/QuickDrop/Localizable.xcstrings +++ b/QuickDrop/Localizable.xcstrings @@ -7271,113 +7271,6 @@ } } }, - "QuickDrop" : { - "localizations" : { - "ar" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "de" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "es" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "fr" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "hu" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "it" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "ja" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "ko" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "nl" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "pt-BR" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "ro" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "ru" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "th" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "uk" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "new", - "value" : "" - } - } - }, - "shouldTranslate" : false - }, "QuickDropAndroidAppAdvertisement" : { "extractionState" : "manual", "localizations" : { @@ -8447,112 +8340,111 @@ } } }, - "Reset UD" : { + "ResetAllSettings" : { "localizations" : { "ar" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "إعادة تعيين جميع الإعدادات" } }, "de" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Alle Einstellungen zurücksetzen" } }, "en" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Reset All Settings" } }, "es" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Restablecer Todos los Ajustes" } }, "fr" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Réinitialiser tous les réglages" } }, "hu" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Összes beállítás visszaállítása" } }, "it" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Ripristina tutte le impostazioni" } }, "ja" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "すべての設定をリセット" } }, "ko" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "모든 설정 초기화" } }, "nl" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Alle instellingen opnieuw instellen" } }, "pt-BR" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Redefinir Todas as Configurações" } }, "pt-PT" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Repor Todas as Definições" } }, "ro" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Resetează toate setările" } }, "ru" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Сбросить все настройки" } }, "th" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "รีเซ็ตการตั้งค่าทั้งหมด" } }, "uk" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "Скинути всі налаштування" } }, "zh-Hans" : { "stringUnit" : { - "state" : "new", - "value" : "" + "state" : "translated", + "value" : "重置所有设置" } } - }, - "shouldTranslate" : false + } }, "SaveFilesLocation" : { "extractionState" : "manual", @@ -9622,6 +9514,220 @@ } } }, + "ShareExtensionDisabledDescription" : { + "extractionState" : "manual", + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "لمشاركة هذا المحتوى مع جهاز آخر، افتح إعدادات النظام في جهاز Mac الخاص بك وانتقل إلى \"عام > عناصر تسجيل الدخول والإضافات\".\n\nقم بالتمرير إلى الأسفل إلى \"المشاركة\" وانقر على زر المعلومات الصحيح. أخيراً، قم بتمكين التبديل لخدمة QuickDrop وحاول مرة أخرى." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Um diesen Inhalt mit einem anderen Gerät zu teilen, öffne die Systemeinstellungen deines Macs und navigiere zu Allgemein > Anmeldeobjekte & Erweiterungen.\n\nScrolle nach unten zu 'Teilen' und klicke auf die rechte Info-Taste. Aktiviere abschließend den Schalter für QuickDrop und versuche es erneut." + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "To share this content with another device, open your Mac’s System Settings and navigate to General > Login Items & Extensions.\n\nScroll down to 'Sharing' and click on the right info button. Finally, enable the toggle for QuickDrop and try again." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para compartir este contenido con otro dispositivo, abre la Configuración del Sistema de tu Mac y navega a General > Elementos de Inicio de Sesión y Extensiones.\n\nDesplázate hacia abajo hasta 'Compartir' y haz clic en el botón de información a la derecha. Finalmente, activa el interruptor de QuickDrop y vuelve a intentarlo." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour partager ce contenu avec un autre appareil, ouvrez les Réglages Système de votre Mac et allez dans Général > Éléments Ouverture & Extensions.\n\nFaites défiler jusqu'à 'Partage' et cliquez sur le bouton d'info à droite. Enfin, activez le commutateur pour QuickDrop et réessayez." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ha meg szeretné osztani ezt a tartalmat egy másik eszközzel, nyissa meg a Mac számítógépén a Rendszerbeállításokat, és navigáljon az Általános > Bejelentkezési elemek és bővítmények menüpontra.\n\nGörgessen le a „Megosztás” részhez, majd kattintson a jobb oldali információs gombra. Végül engedélyezze a QuickDrop kapcsolót, és próbálja újra." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Per condividere questo contenuto con un altro dispositivo, apri le Impostazioni di Sistema del tuo Mac e vai su Generali > Elementi di Login e Estensioni.\n\nScorri fino a 'Condivisione' e clicca sul pulsante info a destra. Infine, abilita l’interruttore per QuickDrop e riprova." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このコンテンツを別のデバイスと共有するには、Macのシステム設定を開き、「一般」>「ログイン項目&拡張機能」に移動します。\n\n「共有」までスクロールして、右側の情報ボタンをクリックします。最後にQuickDropのトグルを有効にしてもう一度お試しください。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "이 콘텐츠를 다른 기기와 공유하려면 Mac의 시스템 설정을 열고 일반 > 로그인 항목 및 확장으로 이동하세요.\n\n'공유'로 스크롤을 내리고 오른쪽 정보 버튼을 클릭하세요. 마지막으로 QuickDrop에 대한 토글을 활성화하고 다시 시도하세요." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Om deze inhoud met een ander apparaat te delen, open de Systeeminstellingen van je Mac en ga naar Algemeen > Inlogitems & Extensies.\n\nScroll naar 'Delen' en klik op de juiste infoknop. Schakel vervolgens de schakelaar voor QuickDrop in en probeer het opnieuw." + } + }, + "pt-BR" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para compartilhar este conteúdo com outro dispositivo, abra as Configurações do Sistema do seu Mac e navegue até Geral > Itens de Login e Extensões.\n\nRole até 'Compartilhamento' e clique no botão de informação à direita. Por fim, ative a opção para QuickDrop e tente novamente." + } + }, + "pt-PT" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para partilhar este conteúdo com outro dispositivo, abra as Definições do Sistema no seu Mac e navegue até Geral > Itens de Início de Sessão e Extensões.\n\nDesça até 'Partilha' e clique no botão de informação à direita. Finalmente, ative a opção para o QuickDrop e tente novamente." + } + }, + "ro" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pentru a partaja acest conținut cu alt dispozitiv, deschide Configurările de sistem ale Mac-ului tău și navighează la General > Elemente de Login & Extensii.\n\nDerulează în jos la 'Partajare' și fă clic pe butonul corespunzător de informații. În final, activează comutatorul pentru QuickDrop și încearcă din nou." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Чтобы поделиться этим содержимым с другим устройством, откройте Системные настройки на вашем Mac и перейдите в раздел Общие > Элементы входа и Расширения.\n\nПрокрутите вниз до раздела 'Обмен' и нажмите на правую информационную кнопку. Наконец, включите переключатель для QuickDrop и попробуйте снова." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "หากต้องการแชร์เนื้อหานี้กับอุปกรณ์อื่น ให้เปิดการตั้งค่าระบบของ Mac แล้วไปที่ทั่วไป > รายการเข้าสู่ระบบ & ส่วนขยาย\n\nเลื่อนลงไปที่ 'การแชร์' และคลิกที่ปุ่มข้อมูลทางขวามือ สุดท้ายให้เปิดสวิตช์สำหรับ QuickDrop และลองอีกครั้ง" + } + }, + "uk" : { + "stringUnit" : { + "state" : "translated", + "value" : "Щоб поділитися цим вмістом з іншим пристроєм, відкрийте Системні налаштування на вашому Mac і перейдіть до Загальне > Елементи входу та розширення.\n\nПрокрутіть вниз до 'Обмін' і натисніть праву кнопку з інформацією. Нарешті, увімкніть перемикач для QuickDrop і спробуйте ще раз." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "要与其他设备共享此内容,请打开 Mac 的系统设置,导航到 通用 > 登录项与扩展。\n\n向下滚动到“共享”并点击右侧的信息按钮。最后,启用 QuickDrop 的切换按钮,然后重试。" + } + } + } + }, + "ShareExtensionDisabledTitle" : { + "extractionState" : "manual", + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم تعطيل امتداد المشاركة" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Teilerweiterung deaktiviert" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Share Extension Disabled" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extensión de Compartir Desactivada" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extension de partage désactivée" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Megosztási bővítmény letiltva" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Estensione di condivisione disattivata" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "共有拡張機能が無効です" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "공유 확장 기능 비활성화됨" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deeluitbreiding uitgeschakeld" + } + }, + "pt-BR" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extensão de Compartilhamento Desativada" + } + }, + "pt-PT" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extensão de Partilha Desativada" + } + }, + "ro" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extensia de partajare dezactivată" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Расширение обмена отключено" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "การแชร์แบบส่วนขยายถูกปิดใช้งาน" + } + }, + "uk" : { + "stringUnit" : { + "state" : "translated", + "value" : "Розширення обміну вимкнено" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "共享扩展已禁用" + } + } + } + }, "SupportQuickDrop" : { "localizations" : { "ar" : { diff --git a/QuickDrop/Util/SendToExtension.swift b/QuickDrop/Util/SendToExtension.swift new file mode 100644 index 0000000..80c6014 --- /dev/null +++ b/QuickDrop/Util/SendToExtension.swift @@ -0,0 +1,23 @@ +// +// SendToExtension.swift +// QuickDrop +// +// Created by Leon Böttger on 09.09.25. +// + +import Foundation +import AppKit + +func sendToSharingService(items: [Any]) { + if let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) { + sharingService.perform(withItems: items) + } + else { + // show alert + let alert = NSAlert() + alert.alertStyle = .critical + alert.messageText = "ShareExtensionDisabledTitle".localized() + alert.informativeText = "ShareExtensionDisabledDescription".localized() + alert.runModal() + } +} diff --git a/QuickDrop/View/TutorialView.swift b/QuickDrop/View/TutorialView.swift index 54a2a2a..aeeb359 100644 --- a/QuickDrop/View/TutorialView.swift +++ b/QuickDrop/View/TutorialView.swift @@ -56,7 +56,7 @@ struct TutorialView: View { Button { Settings.shared.deleteAllUserDefaults() } label: { - Text("Reset UD") + Text("ResetAllSettings") .underline() .font(.footnote) .opacity(0.5) diff --git a/QuickDrop/View/WelcomeScreen.swift b/QuickDrop/View/WelcomeScreen.swift index 6a875fe..f8b26a1 100644 --- a/QuickDrop/View/WelcomeScreen.swift +++ b/QuickDrop/View/WelcomeScreen.swift @@ -138,12 +138,6 @@ struct WelcomeScreen: View { } } } - - func sendToSharingService(items: [Any]) { - if let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) { - sharingService.perform(withItems: items) - } - } } diff --git a/ShareExtension/View/SmallSheetView.swift b/ShareExtension/View/SmallSheetView.swift index 212646e..e3b65f4 100644 --- a/ShareExtension/View/SmallSheetView.swift +++ b/ShareExtension/View/SmallSheetView.swift @@ -36,7 +36,7 @@ struct SmallSheetView: View { .frame(width: imageSize, height: imageSize) if type != .sendToDeviceQrCode { - Text("QuickDrop") + Text(String("QuickDrop")) } } .padding(.leading, 18)