1 Commits
Author SHA1 Message Date
Leon Böttger b4604a5a51 Add QR code view to fix file sending for Samsung devices 2025-03-17 20:54:01 +01:00
19 changed files with 315 additions and 38 deletions

No files matched your search

+6
View File
@@ -40,6 +40,8 @@
69DCF49C2AB8C58500CBE2CC /* SwiftECC in Frameworks */ = {isa = PBXBuildFile; productRef = 69DCF49B2AB8C58500CBE2CC /* SwiftECC */; };
69DCF49D2AB8C9A500CBE2CC /* libNearbyShare.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DCF4812AB70D0600CBE2CC /* libNearbyShare.dylib */; };
69DCF49E2AB8C9A500CBE2CC /* libNearbyShare.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 69DCF4812AB70D0600CBE2CC /* libNearbyShare.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
EB36CCC02D88999F00835FC5 /* QrCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB36CCBF2D88999F00835FC5 /* QrCodeView.swift */; };
EB36CCC12D889B6400835FC5 /* QrCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB36CCBF2D88999F00835FC5 /* QrCodeView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -208,6 +210,7 @@
E9C8C6D42CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
E9C8C6D52CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
E9C8C6D62CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
EB36CCBF2D88999F00835FC5 /* QrCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -252,6 +255,7 @@
isa = PBXGroup;
children = (
699DEBA52AB0573200115D22 /* ShareViewController.swift */,
EB36CCBF2D88999F00835FC5 /* QrCodeView.swift */,
691F53B92ABB70840089FD92 /* DeviceListCell.swift */,
691F53BA2ABB70840089FD92 /* DeviceListCell.xib */,
699DEBA72AB0573200115D22 /* ShareViewController.xib */,
@@ -503,6 +507,7 @@
files = (
699DEBA62AB0573200115D22 /* ShareViewController.swift in Sources */,
691F53BB2ABB70840089FD92 /* DeviceListCell.swift in Sources */,
EB36CCC02D88999F00835FC5 /* QrCodeView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -512,6 +517,7 @@
files = (
698DFB0329E362140064F247 /* NDNotificationCenterHackery.m in Sources */,
69DA9A1229E0BF5100A442DA /* AppDelegate.swift in Sources */,
EB36CCC12D889B6400835FC5 /* QrCodeView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "QR3.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

@@ -0,0 +1,52 @@
{
"images" : [
{
"filename" : "xmark.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "xmark 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ShareViewController" customModule="ShareExtension" customModuleProvider="target">
<connections>
<outlet property="contentWrap" destination="ACO-U2-AZj" id="PAE-Pw-Vyx"/>
<outlet property="dontSeeDeviceButton" destination="CF4-AV-wG4" id="KWW-f4-IO0"/>
<outlet property="filesIcon" destination="afM-Om-nLQ" id="I58-a3-SBZ"/>
<outlet property="filesLabel" destination="OEz-QK-nem" id="his-3f-6kx"/>
<outlet property="largeProgress" destination="fCj-wF-rEj" id="jEg-Uc-Ur7"/>
@@ -91,64 +92,72 @@ Gw
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="ACO-U2-AZj">
<rect key="frame" x="0.0" y="40" width="404" height="146"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CF4-AV-wG4">
<rect key="frame" x="3" y="3" width="189" height="32"/>
<buttonCell key="cell" type="push" title="Don't see your device?" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="j2l-tf-7in">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="175" id="WQ4-sg-Puk"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="WyJ-wc-nKO"/>
</constraints>
<connections>
<action selector="dontSeeDeviceButton:" target="-2" id="EZu-rX-Ewr"/>
</connections>
</button>
<customView id="ACO-U2-AZj">
<rect key="frame" x="0.0" y="39" width="404" height="146"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
</subviews>
<constraints>
<constraint firstItem="OEz-QK-nem" firstAttribute="top" secondItem="1xF-vr-5sH" secondAttribute="bottom" constant="10" id="852-oh-vM0"/>
<constraint firstItem="OEz-QK-nem" firstAttribute="leading" secondItem="afM-Om-nLQ" secondAttribute="trailing" constant="5" id="CIj-Dk-Md0"/>
<constraint firstAttribute="trailing" secondItem="ACO-U2-AZj" secondAttribute="trailing" id="HIg-sX-IK0"/>
<constraint firstItem="ACO-U2-AZj" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="IGL-2g-wpe"/>
<constraint firstItem="CF4-AV-wG4" firstAttribute="leading" secondItem="afM-Om-nLQ" secondAttribute="leading" id="KfB-g2-nez"/>
<constraint firstItem="afM-Om-nLQ" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="10" id="LK2-cg-qcY"/>
<constraint firstItem="NVE-vN-dkz" firstAttribute="top" secondItem="ACO-U2-AZj" secondAttribute="bottom" constant="10" id="RSD-PX-W0H"/>
<constraint firstAttribute="bottom" secondItem="NVE-vN-dkz" secondAttribute="bottom" constant="10" id="USG-Gg-of3"/>
<constraint firstAttribute="trailing" secondItem="NVE-vN-dkz" secondAttribute="trailing" constant="10" id="Z6U-4n-4tO"/>
<constraint firstItem="CF4-AV-wG4" firstAttribute="baseline" secondItem="NVE-vN-dkz" secondAttribute="baseline" id="duh-UD-VUw"/>
<constraint firstItem="afM-Om-nLQ" firstAttribute="top" secondItem="1" secondAttribute="top" constant="36" id="fUG-kT-wb0"/>
<constraint firstItem="NVE-vN-dkz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="CF4-AV-wG4" secondAttribute="trailing" constant="12" symbolic="YES" id="kWX-0G-L7t"/>
<constraint firstItem="1xF-vr-5sH" firstAttribute="centerX" secondItem="1" secondAttribute="centerX" id="sCA-yf-S9L"/>
<constraint firstItem="1xF-vr-5sH" firstAttribute="top" secondItem="1" secondAttribute="top" constant="10" id="tFn-vk-9Cq"/>
<constraint firstAttribute="trailing" secondItem="OEz-QK-nem" secondAttribute="trailing" constant="10" id="vyd-BI-oDH"/>
<constraint firstItem="ACO-U2-AZj" firstAttribute="top" secondItem="OEz-QK-nem" secondAttribute="bottom" constant="10" id="x5r-wc-s4x"/>
</constraints>
<point key="canvasLocation" x="140" y="-36"/>
</customView>
<stackView wantsLayer="YES" distribution="equalSpacing" orientation="vertical" alignment="centerX" spacing="0.0" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" id="fLZ-IA-bPS">
<rect key="frame" x="0.0" y="0.0" width="521" height="100"/>
<rect key="frame" x="0.0" y="0.0" width="521" height="130"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<progressIndicator wantsLayer="YES" maxValue="100" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fCj-wF-rEj">
<rect key="frame" x="245" y="68" width="32" height="32"/>
<rect key="frame" x="245" y="61" width="32" height="39"/>
</progressIndicator>
<textField wantsLayer="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="27P-yf-gUd">
<rect key="frame" x="189" y="42" width="144" height="16"/>
<rect key="frame" x="189" y="35" width="144" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Looking for devices..." id="NaJ-Wx-Pim">
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField wantsLayer="YES" focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="V5W-Rm-YVM">
<rect key="frame" x="-2" y="0.0" width="525" height="32"/>
<textFieldCell key="cell" alignment="center" title="If you don't see your device, open &quot;Google Files&quot; app and tap &quot;Receive&quot; on the Nearby Share tab." id="vla-gF-eJo">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="27P-yf-gUd" firstAttribute="top" secondItem="fCj-wF-rEj" secondAttribute="bottom" constant="10" id="87W-ec-fMh"/>
<constraint firstItem="V5W-Rm-YVM" firstAttribute="top" secondItem="27P-yf-gUd" secondAttribute="bottom" constant="10" id="OSI-wI-LcY"/>
<constraint firstAttribute="bottom" secondItem="27P-yf-gUd" secondAttribute="bottom" constant="35" id="L3k-0X-y8j"/>
<constraint firstItem="fCj-wF-rEj" firstAttribute="top" secondItem="fLZ-IA-bPS" secondAttribute="top" constant="30" id="Uon-lo-9kV"/>
</constraints>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
<point key="canvasLocation" x="660.5" y="-1.5"/>
</stackView>
@@ -229,22 +238,23 @@ Gw
</customSpacing>
<point key="canvasLocation" x="4" y="-288"/>
</stackView>
<scrollView wantsLayer="YES" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="A4d-Qt-PsT">
<scrollView wantsLayer="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="A4d-Qt-PsT">
<rect key="frame" x="0.0" y="0.0" width="271" height="172"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" id="cCr-8P-Lya">
<rect key="frame" x="1" y="1" width="269" height="170"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" drawsBackground="NO" id="cCr-8P-Lya">
<rect key="frame" x="0.0" y="0.0" width="271" height="172"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<collectionView id="gZI-Zb-Blx">
<rect key="frame" x="0.0" y="0.0" width="269" height="170"/>
<rect key="frame" x="0.0" y="0.0" width="271" height="172"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="ATS-Jd-odC">
<size key="itemSize" width="50" height="50"/>
</collectionViewFlowLayout>
<color key="primaryBackgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="primaryBackgroundColor" red="0.11764705882352941" green="0.11764705882352941" blue="0.11764705882352941" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</collectionView>
</subviews>
<color key="backgroundColor" red="0.11764705882352941" green="0.11764705882352941" blue="0.11764705882352941" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="3j2-z3-G1e">
<rect key="frame" x="-100" y="-100" width="402" height="16"/>
+74
View File
@@ -0,0 +1,74 @@
//
// QrCodeView.swift
// NearDrop
//
// Created by Leon Böttger on 10.03.25.
//
import SwiftUI
let qrCodeViewSize = CGSize(width: 530.0, height: 270.0)
struct QrCodeView: View {
@State private var qrCode: String = ""
let closeView: () -> Void
var body: some View {
VStack {
Button(action: {
closeView()
}, label: {
Image("xmark")
.resizable()
.frame(width: 14, height: 14)
.opacity(0.5)
})
.buttonStyle(PlainButtonStyle())
.frame(maxWidth: .infinity, alignment: .trailing)
.padding(.trailing, 15)
.padding(.top, 15)
HStack {
Spacer()
Image("QR")
.resizable()
.aspectRatio(1, contentMode: .fit)
.frame(height: 190)
Spacer()
Text("QrCodeInstructions".localized())
.padding(.top, 5)
.padding(.horizontal)
.fixedSize(horizontal: false, vertical: true)
.multilineTextAlignment(.center)
Spacer()
}
.padding(.horizontal)
.padding(.bottom)
Spacer()
}
.frame(width: qrCodeViewSize.width, height: qrCodeViewSize.height)
}
}
public extension String {
func localized() -> String {
let localizedString = NSLocalizedString(self, comment: "")
return localizedString
}
}
#Preview {
QrCodeView(closeView: {})
}
+100 -10
View File
@@ -8,6 +8,7 @@
import Foundation
import Cocoa
import NearbyShare
import SwiftUI
class ShareViewController: NSViewController, ShareExtensionDelegate{
@@ -15,6 +16,9 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
private var foundDevices:[RemoteDeviceInfo]=[]
private var chosenDevice:RemoteDeviceInfo?
private var lastError:Error?
private var connectionEstablished = false
private var timeoutDispatchWorkItem: DispatchWorkItem? = nil
@IBOutlet var filesIcon:NSImageView?
@IBOutlet var filesLabel:NSTextField?
@@ -30,6 +34,10 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
@IBOutlet var progressState:NSTextField?
@IBOutlet var progressDeviceIconWrap:NSView?
@IBOutlet var progressDeviceSecondaryIcon:NSImageView?
@IBOutlet var dontSeeDeviceButton: NSButton?
private var qrCodeSheetView: NSPanel? = nil
private var sheetAttachedWindow: NSWindow? = nil
override var nibName: NSNib.Name? {
return NSNib.Name("ShareViewController")
@@ -105,22 +113,73 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
super.viewDidLoad()
NearbyConnectionManager.shared.startDeviceDiscovery()
NearbyConnectionManager.shared.addShareExtensionDelegate(self)
self.scheduleAutomaticQrCodeView()
}
override func viewWillDisappear() {
timeoutDispatchWorkItem?.cancel()
if chosenDevice==nil{
NearbyConnectionManager.shared.stopDeviceDiscovery()
}
NearbyConnectionManager.shared.removeShareExtensionDelegate(self)
}
@IBAction func cancel(_ sender: AnyObject?) {
if let device=chosenDevice{
NearbyConnectionManager.shared.cancelOutgoingTransfer(id: device.id!)
}
let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)
self.extensionContext!.cancelRequest(withError: cancelError)
}
@IBAction func cancel(_ sender: AnyObject?) {
if let device=chosenDevice{
NearbyConnectionManager.shared.cancelOutgoingTransfer(id: device.id!)
}
let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)
self.extensionContext!.cancelRequest(withError: cancelError)
}
@IBAction func dontSeeDeviceButton(_ sender: AnyObject?) {
openQrCodeView()
}
private func openQrCodeView() {
if qrCodeSheetView == nil {
let contentView = QrCodeView {
self.closeQrCodeView()
}
let hostingView = NSHostingView(rootView: contentView)
let panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: qrCodeViewSize.width, height: qrCodeViewSize.height),
styleMask: [.titled, .closable, .utilityWindow],
backing: .buffered,
defer: false)
panel.contentView = hostingView
self.qrCodeSheetView = panel
if let mainWindow = NSApp.mainWindow {
self.sheetAttachedWindow = mainWindow
mainWindow.beginSheet(panel) { _ in }
}
}
}
private func closeQrCodeView() {
if let mainWindow = sheetAttachedWindow, let qrCodeView = self.qrCodeSheetView {
mainWindow.endSheet(qrCodeView)
self.qrCodeSheetView = nil
self.sheetAttachedWindow = nil
}
}
private func scheduleAutomaticQrCodeView() {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
if self.foundDevices.isEmpty {
self.openQrCodeView()
}
}
}
private func urlsReady(){
for url in urls{
@@ -154,6 +213,8 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
}
foundDevices.append(device)
listView?.animator().insertItems(at: [[0, foundDevices.count-1]])
closeQrCodeView()
}
func removeDevice(id: String){
@@ -173,6 +234,9 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
}
func connectionWasEstablished(pinCode: String) {
connectionEstablished = true
progressState?.stringValue=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [pinCode])
progressProgressBar?.isIndeterminate=false
progressProgressBar?.maxValue=1000
@@ -221,15 +285,34 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
}
func selectDevice(device:RemoteDeviceInfo){
NearbyConnectionManager.shared.stopDeviceDiscovery()
NearbyConnectionManager.shared.stopDeviceDiscovery()
listViewWrapper?.animator().isHidden=true
progressView?.animator().isHidden=false
progressDeviceName?.stringValue=device.name
progressDeviceName?.stringValue=getDeviceName(device: device)
progressDeviceIcon?.image=imageForDeviceType(type: device.type)
progressProgressBar?.startAnimation(nil)
progressState?.stringValue=NSLocalizedString("Connecting", value: "Connecting...", comment: "")
chosenDevice=device
NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: urls)
let timeoutAlert = DispatchWorkItem {
if !self.connectionEstablished {
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "TimeoutTitle".localized()
alert.informativeText = "TimeoutDescription".localized()
alert.addButton(withTitle: "TimeoutButton".localized())
alert.beginSheetModal(for: self.view.window!) { _ in }
}
}
self.timeoutDispatchWorkItem = timeoutAlert
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: timeoutAlert)
}
private func dismissDelayed(){
@@ -269,7 +352,7 @@ extension ShareViewController:NSCollectionViewDataSource{
let item=collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DeviceListCell"), for: indexPath)
guard let collectionViewItem = item as? DeviceListCell else {return item}
let device=foundDevices[indexPath[1]]
collectionViewItem.textField?.stringValue=device.name
collectionViewItem.textField?.stringValue=getDeviceName(device: device)
collectionViewItem.imageView?.image=imageForDeviceType(type: device.type)
// TODO maybe there's a better way to handle clicks on collection view items? I'm still new to Apple's way of doing UIs so I may do dumb shit occasionally
collectionViewItem.clickHandler={
@@ -277,4 +360,11 @@ extension ShareViewController:NSCollectionViewDataSource{
}
return collectionViewItem
}
func getDeviceName(device: RemoteDeviceInfo) -> String {
if device.name.count <= 1 {
return "Android"
}
return device.name
}
}
@@ -27,3 +27,15 @@
/* No comment provided by engineer. */
"UnsupportedType" = "نوع المرفق غير مدعوم";
/* No comment provided by engineer. */
"QrCodeInstructions" = " QR ضوئيًا باستخدام جهاز Android الخاص بك لتوصيله بجهاز Mac. تأكد من أن هاتفك متصل بنفس الشبكة.\n\nبدلاً من ذلك، قم بتثبيت وفتح تطبيق 'Files by Google' ثم اضغط على 'استقبال' في الزاوية السفلية اليمنى.";
/* No comment provided by engineer. */
"TimeoutTitle" = "حدث خطأ ما";
/* No comment provided by engineer. */
"TimeoutDescription" = "تعذر على NearDrop الاتصال بهاتفك. يرجى فتح إعدادات جهاز Android والبحث عن 'Quick Share'. قم بتغيير الإعداد 'من يمكنه المشاركة معك' إلى 'الجميع' ثم حاول مرة أخرى.";
/* No comment provided by engineer. */
"TimeoutButton" = "موافق";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -28,3 +28,15 @@
/* No comment provided by engineer. */
"UnsupportedType" = "不支持的文件类型";
/* No comment provided by engineer. */
"QrCodeInstructions" = "使用您的 Android 设备扫描二维码,将其连接到您的 Mac。请确保您的手机连接到同一网络。\n\n或者,安装并打开 'Files by Google' 应用程序,然后点击右下角的 '接收'。";
/* No comment provided by engineer. */
"TimeoutTitle" = "出现问题";
/* No comment provided by engineer. */
"TimeoutDescription" = "NearDrop 无法连接到您的手机。请打开 Android 设备的设置并搜索“快速分享”(Quick Share)。将“谁可以与您分享”更改为“所有人”,然后重试。";
/* No comment provided by engineer. */
"TimeoutButton" = "确定";