feat(apple): send files to a remembered device

Adds the Send files action to the device detail, routing the picked
selection through sendToContact.

Rather than a second picker path, sharePickedFiles now takes a
ShareDestination, so the macOS security-scoped access handling covers both
routes. A contact destination carries no access policy, matching the core's
rule that an offer share is never public.
This commit is contained in:
2026-08-06 18:21:44 +02:00
parent dc23e87c56
commit 268fbf161d
11 changed files with 218 additions and 17 deletions

View File

@@ -166,8 +166,20 @@ final class FakeFileSystemService: FileSystemService {
func defaultReceiveFolder() -> ReceiveFolder { folder }
func validateReceiveFolder(_ folder: ReceiveFolder) async -> FolderAccessStatus { .writable }
func canRevealReceiveFolder(_ folder: ReceiveFolder) -> Bool { false }
func sharePickedFiles(repository: CoreGateway, files: [PickedShareFile], transferName: String, senderName: String, accessPolicy: ShareAccessPolicy) async -> Result<Share, Error> {
await repository.shareSources([], transferName: transferName, senderName: senderName, accessPolicy: accessPolicy)
private(set) var shareDestinations: [ShareDestination] = []
func sharePickedFiles(repository: CoreGateway, files: [PickedShareFile], transferName: String, senderName: String, destination: ShareDestination) async -> Result<Share, Error> {
shareDestinations.append(destination)
switch destination {
case .invitation(let accessPolicy):
return await repository.shareSources(
[], transferName: transferName, senderName: senderName, accessPolicy: accessPolicy
)
case .contact(let endpointId):
return await repository.sendToContact(
endpointId: endpointId, sources: [], transferName: transferName, senderName: senderName
)
}
}
}