Commit Graph

228 Commits

Author SHA1 Message Date
224a8e0e7a fix(release): enforce Apple hardened runtime 2026-07-30 21:27:34 +02:00
efacfab213 fix(release): expose Apple notarization failures 2026-07-30 21:03:30 +02:00
Hammed Abass
0ec7618ce8 Merge pull request #39 from sudosylabs/feat/release-pipeline-fixes
fix(release): repair Apple and Android builds
2026-07-30 20:30:28 +02:00
8b75423b7a fix(release): repair Apple and Android builds 2026-07-30 20:26:27 +02:00
Hammed Abass
7236933b76 Merge pull request #38 from sudosylabs/feat/release-0.2.1
chore(release): prepare 0.2.1
v0.2.1
2026-07-30 19:43:19 +02:00
fc732e1b77 chore(release): prepare 0.2.1 2026-07-30 19:27:57 +02:00
Hammed Abass
d097c82f6a Merge pull request #37 from sudosylabs/feat/microsoft-store-publishing
ci: automate Microsoft Store updates
2026-07-30 19:25:15 +02:00
caaa9a472d ci: automate Microsoft Store updates 2026-07-30 19:12:50 +02:00
Hammed Abass
4ce124da7c Merge pull request #36 from sudosylabs/feat/automated-release-versions
feat(release): automate derived store versions
2026-07-30 17:58:18 +02:00
94a8b3481b feat(release): automate derived store versions 2026-07-30 17:40:00 +02:00
Hammed Abass
6d908d8dc3 Merge pull request #35 from sudosylabs/feat/release-pipeline
ci: add coordinated cross-platform release pipeline
2026-07-28 11:58:18 +02:00
c6655da7db refactor(version): derive Apple build numbers 2026-07-28 11:27:45 +02:00
2d7982bbb9 ci: add coordinated release pipeline 2026-07-28 11:09:53 +02:00
Hammed Abass
52d4102308 Merge pull request #34 from sudosylabs/feat/unified-versioning
feat(release): unify cross-platform versioning
2026-07-28 08:45:02 +02:00
407a0d2d60 feat(release): unify cross-platform versioning 2026-07-28 08:22:58 +02:00
Hammed Abass
fc1d27bf45 Merge pull request #33 from sudosylabs/feat/release-test-flight
feat(apple): stable iOS/macOS release + macOS direct-download channel
2026-07-27 16:25:55 +02:00
4730554c2c refactor(apple): make InvitationError typed and localize NFC prompts
Replace the free-form InvitationError.message(String) case with semantic
cases mapped to L10n keys at the UI boundary (Error.uiText), so user-facing
error text is localized instead of substring-matched from English blobs.
.raw(String) remains only for genuinely dynamic system/core messages.

Localize the CoreNFC alertMessage prompts via existing L10n keys, and add
SwiftLint rules (raw_alert_message, raw_invitation_error) to catch raw
alert strings and literal .raw("…") errors going forward.
2026-07-27 16:07:19 +02:00
cbb535d998 chore(apple): stop tracking RELEASE-MACOS.md
Keep the macOS release notes local-only; remove from the index and ignore
so the working copy stays on disk without being committed.
2026-07-27 16:05:35 +02:00
a0ebd7c71b fix(apple): restore macOS approval modal and sandboxed file sharing
Approval modal: since the Share/QR sheet auto-opens after creating a transfer,
it is always up when a receiver request arrives, and macOS silently drops a sheet
presented while another is still dismissing — so the approval sheet never appeared.
Drive the approval sheet from explicit state (not a constant binding) and, on
macOS, defer its presentation one dismiss-beat after closing the Share/QR sheet so
the hand-off is serialized. Still a non-dismissable sheet; iOS timing unchanged.

Sandboxed file sharing: the macOS picker released its security scope immediately,
so the core's later import failed with EPERM under the App Store sandbox (the
non-sandboxed .dmg was unaffected). Capture a security-scoped bookmark at pick
time and re-acquire access across shareFiles() — during which the core imports the
bytes — mirroring the receive-folder scoped-access pattern.
2026-07-27 15:01:01 +02:00
cc194f6a7b feat(apple): add direct-download macOS channel (notarized DMG + Sparkle + Homebrew)
Add a second macOS shipping channel alongside the App Store build:

- New VniDropDirect target (Release-Direct config) sharing VniDrop's sources via
  an AppBase target template; links Sparkle behind the DIRECT_DISTRIBUTION flag so
  the App Store binary never bundles a self-updater. arm64-only (core is arm64).
- Sparkle updater (SparkleUpdater.swift) + "Check for Updates" menu, compiled only
  under DIRECT_DISTRIBUTION; Info.plist SUFeedURL points at the GitHub Release
  /latest/download/appcast.xml, non-sandboxed entitlements for Developer ID.
- build-dmg.sh (archive → Developer ID export → DMG → sign → notarize → staple),
  generate-appcast.sh, and ExportOptions-DeveloperID.plist.
- apple-release.yml: on tag v*.*.*, build/notarize the DMG, publish the GitHub
  Release with appcast, and push the Homebrew cask to sudosylabs/homebrew-vnidrop.
  apple.yml gains a PR compile-check of the direct target.
- CFBundleVersion is stamped at build time as a UTC YYMMDD.HHMM timestamp for both
  channels, replacing the hand-maintained build number.
- Docs (RELEASE-MACOS.md, README), cask template + tap README, localized
  updates_check string, Makefile targets, gitignore for dist/ artifacts.
2026-07-27 14:31:36 +02:00
8de190a36e chore(apple): update Icon Composer app icon definition 2026-07-27 12:19:13 +02:00
73bc87d3d1 fix(apple): use TAG NFC reader format for iOS 26 SDK
App Store upload with the iOS 26 SDK rejects the NDEF value (error 90778
"NDEF is disallowed") and requires TAG. NFCNDEFReaderSession keeps working
under the TAG entitlement, so no code changes are needed.
2026-07-27 10:27:22 +02:00
2166aa9ce4 build(apple): ship TestFlight build 7 as Release
Set CURRENT_PROJECT_VERSION to 7 for the next TestFlight upload, and pin the
scheme's Archive/Profile actions to the Release configuration so Product →
Archive can't pick up Debug.
2026-07-27 10:21:54 +02:00
22b93ce94e feat(apple): keep iOS transfers alive in the background
iOS suspends the process on backgrounding, freezing the core's network
threads so in-flight transfers stall and never fire notifications. Hold a
UIApplication background-task assertion (BackgroundActivityController) while
transfers/shares are active so iOS grants its grace window — long enough to
finish and notify. Released on foreground, on completion, or on expiration.
No UIBackgroundModes added (keeps App Store validation clean); macOS is a
no-op since it already runs unfocused.

Add a localized iOS-only Settings notice explaining the platform limit so it
doesn't read as a bug.
2026-07-27 10:02:31 +02:00
31ba3f40b2 test(shared): resolve UI copy from resources 2026-07-25 19:46:34 +02:00
f3124371ee fix(apple): resolve App Store validation errors
- Info.plist: drop unused `fetch`/`processing` background modes (no
  BGTaskScheduler implementation exists, which they would require); keep
  remote-notification.
- Info.plist: set ITSAppUsesNonExemptEncryption=false — the app's standard
  end-to-end encryption qualifies for the mass-market export exemption, so no
  compliance code is required.
- project.yml: emit dwarf-with-dsym for Release so archive symbol upload works.

The remaining upload errors (NFC "NDEF is disallowed", Unsupported SDK) are
artifacts of building with a beta Xcode/SDK 27 and clear when archiving with a
release/RC Xcode; NFCNDEFReaderSession legitimately requires the NDEF format
entitlement, so it is kept as-is.
2026-07-25 19:35:59 +02:00
ea2f8b1cc7 feat(apple): adopt Icon Composer app icon
Replace the legacy AppIcon.appiconset with an Icon Composer AppIcon.icon
bundle in the target's resources. ASSETCATALOG_COMPILER_APPICON_NAME already
points at "AppIcon"; the .icon back-deploys to the iOS 18.2 target.
2026-07-25 16:24:04 +02:00
9b8d66f97d chore(packaging): add Apple App Store design source via Git LFS
Track the Affinity design master (AppStore.af) with Git LFS to keep repo
history lean, and ignore the large exported JPG screenshots (regenerated from
the source) plus macOS/editor junk.
2026-07-25 16:06:44 +02:00
a8a168ffde chore(apple): declare non-exempt encryption use
Add ITSAppUsesNonExemptEncryption=YES to Info.plist so the export-compliance
question is answered once (the app uses standard end-to-end encryption via
iroh). Avoids being re-prompted on every TestFlight/App Store upload.
2026-07-25 16:06:44 +02:00
516c4ace84 docs: set Apache license copyright to VniDrop
Fill in the Apache 2.0 copyright placeholder with "Copyright 2026 VniDrop",
matching the App Store copyright field.
2026-07-25 16:06:43 +02:00
Hammed Abass
c7657c4b37 Merge pull request #31 from sudosylabs/feat/apple-typed-resources-and-fixes
Apple: typed resources and UX fixes
2026-07-24 21:16:56 +02:00
b8e8dd8644 test(core): wait for delivery event visibility 2026-07-24 21:05:37 +02:00
83b66c5eb7 Merge remote-tracking branch 'origin/feat/apple-typed-resources-and-fixes' 2026-07-24 20:52:36 +02:00
81e84b14f8 fix(shared): align action icons and storage refresh 2026-07-24 20:24:23 +02:00
c81cb7c8b6 feat(shared): align non-Apple UX with Apple 2026-07-24 19:58:33 +02:00
319af6f2de fix(l10n): align notification/storage descriptions with KMP behavior
The merge kept this branch's reworded notifications_description and
storage_delete_transfers_description over master's, but the merged KMP code is
master's, so its FoundationComposeTest assertions (and the shipped KMP copy) expect
master's wording. Restore both to master's committed text (pulling the storage one
from master's XML, since master's own strings.json was stale for it). Verified the
two failing KMP Compose tests pass locally.
2026-07-24 19:58:29 +02:00
3abd4d0cfd build(apple): flag raw string literals in SwiftUI initializers
The typed-resource rules missed a bare string literal passed as the leading arg of
a view initializer (e.g. Label("send_stop_sharing", …)), which is an implicit
LocalizedStringKey. Add a rule covering Text/Label/Button/Section/Picker/etc.
(empty labels allowed). Fixes the two dynamic-content Text sites it surfaced by
switching them to Text(verbatim:).
2026-07-24 19:42:40 +02:00
b66cb8c1f1 fix(l10n): restore storage_clearing_transfer_cache dropped in merge
Another key master referenced from Kotlin but kept only in the generated Compose
XML, so regeneration dropped it. Verified exhaustively this time: every
Res.string.* reference in shared/src/commonMain/kotlin now resolves against the
regenerated values/strings.xml, so no further keys are missing.
2026-07-24 19:28:52 +02:00
98da43b122 docs: make strings.json the documented source of truth for l10n
Record in AGENTS.md that localization/strings.json is the single source of truth
and the KMP XML + Apple xcstrings/L10n.swift are generated by the loc CLI and must
never be hand-edited — a key present only in a generated file is dropped on the
next regeneration (which is how the transfer-cache strings were lost in the merge).
2026-07-24 19:02:02 +02:00
7d3f1b9862 fix(l10n): add the transfer-cache-clear strings dropped in merge
Master referenced storage_clear_transfer_cache(_description) and
storage_transfer_cache_cleared from Kotlin but never added them to strings.json —
they lived only in the committed Compose XML. Regenerating l10n from the merged
strings.json dropped them, breaking the shared-kmp build. Add them (kmp target,
all 9 languages, text carried over from master) so generation restores them.
2026-07-24 19:02:02 +02:00
83ddf9f059 ci(apple): install SwiftLint for the required lint build phase
The VniDrop target's SwiftLint pre-build phase is required (fails if missing), so
the Apple CI job must have SwiftLint available. Add a brew install step.
2026-07-24 18:52:26 +02:00
f513a6118e feat(apple): notify the sender when a receiver's delivery fails
plannedReceiverNotifications only fired for completed receivers, so a failed
delivery produced no notification. Add a receiverFailed kind wired through the
planner, id, and deliver paths, with localized notifications_receiver_failed_*
strings and a unit test.
2026-07-24 18:45:02 +02:00
35f06a0b6b fix(apple): localize receiver failure reasons
The receiver row showed the core's raw reason code (e.g. destination_exists),
breaking the never-expose-raw-reason-blobs rule. Map the core reason codes to the
existing L10n.Error.* messages via receiverReasonUiText, with a generic fallback so
a raw code is never surfaced.
2026-07-24 18:45:02 +02:00
b65bac021f build(apple): enforce typed resources with SwiftLint
Add a focused .swiftlint.yml (custom rules only, no default style noise) flagging
raw String(localized:) / LocalizedStringKey / systemName|systemImage literals, and
wire it as a required pre-build phase that fails the build if SwiftLint is missing
(brew install swiftlint). The phase prepends the Homebrew bin dirs since Xcode runs
scripts with a minimal PATH. Runs clean on the current tree (0 violations).
2026-07-24 18:32:15 +02:00
d2924f7ce6 fix(apple): focus the running instance on notification tap
Add a UNUserNotificationCenterDelegate didReceive handler so tapping a notification
is handled inside the running app — activating and bringing the existing window
forward — instead of falling through to default launch behavior, which on macOS
can surface a second process. The approval/transfer UI is driven by core state, so
activating the window reveals any pending approval.
2026-07-24 18:32:15 +02:00
3042005226 refactor(apple): type the merged relay/network resources
Convert master's raw-string localization keys and SF Symbols in the new
relay/network code to typed accessors, matching this branch's typed-resources
convention: relay mode labels/descriptions, NetworkSettings strings, the endpoint
id and relay-validation messages (now typed L10n functions), and SF Symbols via
SFSafeSymbols. Retype the model's relayApplyErrorKey from a raw String key to
String.LocalizationValue so no loose key literals remain in the settings layer.
2026-07-24 18:15:36 +02:00
9b15a388d8 fix(apple): polish the merged Network settings
Move the relay-mode picker's Network title into a Section header (the inline
picker label rendered as a stray row on iOS) and hide the picker label. Use a
verbatim prompt for the relay URL placeholder so macOS stops markdown-linkifying
the URL-shaped text into a purple link.
2026-07-24 17:54:59 +02:00
c23f7916bb Merge origin/master into feat/apple-typed-resources-and-fixes
Brings in custom relays, relay connection policies, storage cache clearing, and
receiver-failure reporting. Apple-side conflict resolutions:
- CoreRepository: keep CoreDispatcher, adopt master's relay factory + network
  transition guard, drop the now-unused serial queue.
- TransferDetailsView: keep the toolbar-share layout; adopt master's
  invitationPresentation-based QR panel and the new .failed receiver case (typed).
- SettingsModel/SettingsScreen: typed L10n titleKey with master's .network case;
  relay controls and the Free up space / storage redesign coexist.
- Add the missing transfer_receiver_failed localization key.
- Regenerate l10n from the merged strings.json; keep the Apple catalog untracked.
- Drop the notificationsEnabled test assertion (notifications preference was
  intentionally removed on this branch).
2026-07-24 17:48:10 +02:00
Hammed Abass
0f8f89641a Merge pull request #32 from sudosylabs/feat/custom-relays
feat(network): add custom relay configuration and transfer controls
2026-07-24 17:09:16 +02:00
b724c1540f fix(shared): derive path names in Rust 2026-07-24 16:52:10 +02:00