feat(apple): storage screen, About content, and fixes

- Settings: add Storage screen (size breakdown + delete-all-transfers) and
  expand About (what it is/isn't, privacy & security, license/source)
- Move Report a bug to a toolbar sheet (cancel-only unless empty)
- Send progress: derive the list-row bar from receiver delivery status so it
  clears once every receiver completes
- Fixes: iPad orientations, onChange(of:) iOS 17 API, weak-self captures,
  invalid SF Symbol, macOS bug-report form labels; bump core build target to
  match the app (18.2/15.0)
This commit is contained in:
2026-07-19 13:58:20 +02:00
parent ceccfcda71
commit bfa489def1
13 changed files with 685 additions and 132 deletions

View File

@@ -37,6 +37,196 @@
}
}
},
"about_description" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "VniDrop moves files and folders straight from one device to another over the network, without uploading them to any file-hosting service. Theres no account to create, and no copy of your transfer is left in the cloud once youre done."
}
}
}
},
"about_is_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "What VniDrop is"
}
}
}
},
"about_is_direct" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "A direct device-to-device transfer — your files go straight to the receiver."
}
}
}
},
"about_is_no_account" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Account-free — theres nothing to sign up for."
}
}
}
},
"about_is_in_control" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "You decide who receives: approve each request, or open a transfer to anyone holding the invitation."
}
}
}
},
"about_is_encrypted" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Connections are authenticated and end-to-end encrypted (via Iroh), and incoming files are verified by their content hash."
}
}
}
},
"about_is_open" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open source, released under the Apache 2.0 license."
}
}
}
},
"about_isnt_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "What VniDrop isnt"
}
}
}
},
"about_isnt_cloud" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not cloud storage — no server holds your files, and nothing waits in the cloud after a transfer."
}
}
}
},
"about_isnt_sync" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not a sync or backup service."
}
}
}
},
"about_isnt_public" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not public broadcasting — an invitation is a private access link, not an announcement to everyone nearby."
}
}
}
},
"about_privacy_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Privacy & security"
}
}
}
},
"about_privacy_capability" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Invitations are capabilities. Treat a QR code, NFC tag, or .vnd file like a private access link and share it only with the people you intend — especially with “Anyone with this transfer.”"
}
}
}
},
"about_privacy_deny" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deny by default — VniDrop serves only the content of an active share and rejects unknown requests."
}
}
}
},
"about_privacy_relay" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "If two devices cant connect directly, the encrypted connection may be relayed. Relays forward encrypted packets only; they never store your files."
}
}
}
},
"about_privacy_local" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Received files are saved on your device and never silently overwrite an existing file."
}
}
}
},
"about_license_label" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "License"
}
}
}
},
"about_source_label" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Source code"
}
}
}
},
"about_tagline" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Send files directly. Stay in control of who receives them."
}
}
}
},
"about_privacy" : {
"extractionState" : "stale",
"localizations" : {
@@ -170,6 +360,16 @@
}
}
},
"bug_report_contact_hint" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "name@example.com"
}
}
}
},
"bug_report_contact_label" : {
"localizations" : {
"en" : {
@@ -180,6 +380,36 @@
}
}
},
"bug_report_expected_hint" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Describe what you expected to happen"
}
}
}
},
"bug_report_steps_hint" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "List the steps to reproduce the issue"
}
}
}
},
"bug_report_what_hint" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Describe what happened"
}
}
}
},
"bug_report_description" : {
"extractionState" : "stale",
"localizations" : {
@@ -1729,6 +1959,116 @@
}
}
},
"storage_calculating" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Calculating…"
}
}
}
},
"storage_delete_transfers" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Delete all transfers"
}
}
}
},
"storage_delete_transfers_description" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "This clears all sent and received transfer records from your history. Your received files are not deleted. Note: the transfer engine keeps its stored content, so Transfer data may not decrease. This cant be undone."
}
}
}
},
"storage_deleting" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deleting…"
}
}
}
},
"storage_footer" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transfer data is managed by the transfer engine — your history plus the content of files youve shared. The button below clears your transfer records; the engine keeps its stored content, so this value may not drop. Received files are your downloaded files and are never deleted here."
}
}
}
},
"storage_received_files" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Received files"
}
}
}
},
"storage_temporary" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Temporary files"
}
}
}
},
"storage_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Storage"
}
}
}
},
"storage_total" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Total"
}
}
}
},
"storage_transfer_data" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transfer data"
}
}
}
},
"storage_transfers_deleted" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "All transfers deleted"
}
}
}
},
"status_available" : {
"localizations" : {
"en" : {