Compare commits

...

2 Commits

Author SHA1 Message Date
codinget e32520659d fix(taildrop): restore incoming file progress notifications
The io.Copy in PutFile was writing directly to wc, bypassing the
incomingFile wrapper whose Write method increments f.copied and fires
a throttled sendFileNotify on progress. As a result, notifyIncomingFiles
on the JS side only ever fired once (on completion) with received=0,
making progress UI impossible. The original inFile wrapping was lost
during the Android SAF refactor.

Also surface the PartialFile.Done flag through jsIncomingFile so JS can
distinguish the final "transfer complete" notification from in-progress
updates.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-16 19:04:02 +00:00
codinget e8eb9d71c2 fix(tsconnect): guard nil n.Prefs in notify callback
n.Prefs is *PrefsView (a pointer), so calling n.Prefs.Valid() on a
Notify where Prefs is nil auto-dereferenced nil and panicked. The
callback's defer recover() swallowed the panic, which meant every
Notify without Prefs (Health-only, FilesWaiting, IncomingFiles,
OutgoingFiles, etc.) never reached the file-related JS calls.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-16 18:43:58 +00:00
2 changed files with 6 additions and 3 deletions
+3 -1
View File
@@ -388,7 +388,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
log.Printf("Could not generate JSON netmap: %v", err)
}
}
if n.Prefs.Valid() {
if n.Prefs != nil && n.Prefs.Valid() {
jsCallbacks.Call("notifyExitNode", string(n.Prefs.ExitNodeID()))
}
if n.BrowseToURL != nil {
@@ -405,6 +405,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
Started: f.Started.UnixMilli(),
DeclaredSize: f.DeclaredSize,
Received: f.Received,
Done: f.Done,
}
}
if b, err := json.Marshal(files); err == nil {
@@ -967,6 +968,7 @@ type jsIncomingFile struct {
Started int64 `json:"started"` // Unix milliseconds; use new Date(started) in JS
DeclaredSize int64 `json:"declaredSize"` // -1 if unknown
Received int64 `json:"received"` // bytes received so far
Done bool `json:"done"` // true once the file has been fully received
}
// jsOutgoingFile is the JSON representation of an outgoing file transfer
+3 -2
View File
@@ -134,8 +134,9 @@ func (m *manager) PutFile(id clientID, baseName string, r io.Reader, offset, len
}
}
// Copy the contents of the file to the writer.
copyLength, err := io.Copy(wc, r)
// Copy via inFile (which wraps wc) so [incomingFile.Write] can track
// progress and fire periodic sendFileNotify callbacks.
copyLength, err := io.Copy(inFile, r)
if err != nil {
return 0, m.redactAndLogError("Copy", err)
}