From c8318c323a19874a69c3ea3de31fe4e5d34b55de Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 1 Sep 2026 08:53:38 -0400 Subject: [PATCH] =?UTF-8?q?android:=20Share=20=E2=86=92=20ThoughtSync,=20a?= =?UTF-8?q?nd=20a=20"New=20note"=20entry=20in=20the=20selection=20toolbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Capture without opening the app first — the input half of #1899. Two ways in: the share sheet from anywhere, and the text-selection toolbar in any app's text field. ## The note is created, not pre-filled The obvious build is "open the editor on a draft holding the shared text". That silently loses it. `NoteEditorScreen`'s flush is guarded by `bodyText != note.body`, so a draft handed the text already has nothing to save — share a link, press back without typing, and it is gone. Which is exactly the shape of a share: the common case is walking away. So `captureShared` makes the row first and opens the editor on the real note. A share has already said "keep this"; creating it is what honours that, and back then leaves a saved note rather than a decision. ## launchMode="singleTop" The reminder notification adds FLAG_ACTIVITY_SINGLE_TOP to its own intent, which is why `onNewIntent` already worked there. A share intent is built by the OTHER app and nothing here can add a flag to it, so the activity has to declare it. Without that, every share while the app was running would stack a second MainActivity — a second view model, a second board, and a back press landing on a stale copy of the same app. ## Subject and text, both A browser sends EXTRA_SUBJECT as the page title and EXTRA_TEXT as the URL. Keeping both makes the note read as its title, because the core names a note by its first line — the difference between a board you can scan and a column of identical links. `distinct` because plenty of senders put the same string in both. The extras are removed on read, like the reminder's note id and for the same reason: the activity keeps its launch intent, so without consuming them a rotation would replay the share and mint the note again. ## Not included: images `image/*` is deliberately absent from the filter. Nothing in this app can create an attachment — the core has `delete_attachment` and no counterpart, and the FFI exposes neither. Declaring the mime type would put ThoughtSync in front of people in the share sheet for a job it cannot do, and fail after they had already chosen it. Adding it needs an attachment-creation path through the core, the FFI and sync, which is its own piece of work. The desktop half of #1899 — a global hotkey — is not in this commit. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01K3MMqUtzX1TJgA1oypvm1c --- android/app/src/main/AndroidManifest.xml | 38 ++++++++++ .../fabledsword/thoughtsync/MainActivity.kt | 73 ++++++++++++++++++- .../thoughtsync/ui/BoardViewModel.kt | 26 +++++++ android/app/src/main/res/values/strings.xml | 5 ++ 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 5c53b18..5b05bb2 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -99,15 +99,53 @@ android:supportsRtl="true" android:theme="@style/Theme.ThoughtSync" android:usesCleartextTraffic="true"> + + + + + + + + + + + + + + + + New note + Manage tags