feat(taildrop): fix DirectFileMode, void callbacks, and empty WaitingFiles

- Add SetStagedFileOps to Extension: sets fileOps without enabling
  DirectFileMode, so WASM clients use staged retrieval (WaitingFiles,
  OpenFile, DeleteFile) instead of direct-write mode.
- Add directFileOps bool field: SetFileOps (Android SAF) sets it true;
  SetStagedFileOps (WASM JS) leaves it false. onChangeProfile now uses
  `fops != nil && e.directFileOps` to determine DirectFileMode.
- Add jsCallVoid to jsFileOps: void ops (openWriter, write, closeWriter,
  remove) now use cb(err?: string) instead of cb(null, err: string).
- Fix waitingFiles() returning JSON null when no files are waiting:
  normalise nil slice to empty slice before marshalling.
- Update wireTaildropFileOps to call SetStagedFileOps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 22:48:11 +00:00
parent b04b4f7751
commit 9f96b7434c
6 changed files with 436 additions and 4 deletions
+12 -1
View File
@@ -18,10 +18,21 @@ func (e *Extension) SetDirectFileRoot(root string) {
e.directFileRoot = root
}
// SetFileOps sets the platform specific file operations. This is used
// SetFileOps sets the platform-specific file operations. This is used
// to call Android's Storage Access Framework APIs.
// It implies DirectFileMode, so received files are delivered directly to the
// caller rather than staged for retrieval via WaitingFiles/OpenFile.
func (e *Extension) SetFileOps(fileOps FileOps) {
e.fileOps = fileOps
e.directFileOps = true
}
// SetStagedFileOps sets the platform-specific file operations without enabling
// DirectFileMode. Received files are staged for explicit retrieval via
// WaitingFiles, OpenFile, and DeleteFile. Used by the WASM JS bridge.
func (e *Extension) SetStagedFileOps(fileOps FileOps) {
e.fileOps = fileOps
e.directFileOps = false
}
func (e *Extension) setPlatformDefaultDirectFileRoot() {