KotlinGeekDev
4c14554263
Merge branch 'vitorpamplona:main' into kmp-completeness
2026-03-24 13:27:40 +01:00
nrobi144
efa294ea72
feat(highlights): add article highlights and note-taking system
...
Phase 1: HighlightData model + DesktopHighlightStore (Preferences-based)
Phase 2: Text selection highlight via Cmd+H/Cmd+Shift+H, inline bold/italic
rendering, HighlightAnnotationDialog, SelectionContainer wrapping
Phase 3: MyHighlightsScreen with grouped view, HighlightPublishAction for
NIP-84 (kind 9802), deck/sidebar/menu wiring
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-03-24 12:16:54 +02:00
David Kaspar
22142d17f9
Merge pull request #1924 from davotoula/larger-stop-area-for-voice-recording
...
Larger stop area for voice recording
2026-03-24 10:59:41 +01:00
nrobi144
c75176891f
feat(reads): integrate long-form into deck layout with zoom and reactions
...
- Wire Article, Editor, Drafts into DeckColumnType + DeckColumnContainer
- Add Drafts to sidebar nav, Add Column dialog, and Window menu
- Add article navigation (onNavigateToArticle) in SinglePaneLayout
- Add NoteActionsRow to ReadsScreen LongFormCards (zaps, reactions, replies)
- Add Cmd+/Cmd- zoom in ArticleReaderScreen via fontScale on RenderMarkdown
- Add kind 30023 to ProfileSubscription for long-form in user profiles
- Add fontScale param to RenderMarkdown using scaled LocalDensity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-03-24 11:18:37 +02:00
nrobi144
328fcf86d7
refactor(reads): address all review findings — security, performance, simplicity
...
P1 Critical:
- Add 300ms debounce on editor preview to prevent AST re-parse per keystroke
- Hoist Regex constants in ReadingTimeCalculator and TableOfContents
- Add URI scheme allowlist to editor onLinkClick (was missing vs reader)
- Add MAX_CONTENT_BYTES (100KB) validation before publish
P2 Important:
- Delete MarkdownSpikeScreen (278 LOC spike artifact)
- Delete HighlightCreator (95 LOC, zero callers — YAGNI)
- Delete DraftLongTextNoteEvent (162 LOC, no consumers — YAGNI)
- Replace ArticleMediaRenderer interface with onLinkClick lambda
- Extract inline subscription to FilterBuilders.longFormByAddress()
- Replace SimpleDateFormat with thread-safe DateTimeFormatter
- Remove dead placeholders (bookmark button, reactions row, unused param)
- Cache draft index in memory to avoid redundant disk reads
- Add TODO for publish-before-relay-ack issue
P3 Nice-to-have:
- Remove timestamp from subscription subId for stability
- Remove redundant slug ".." removal (regex handles it)
- Add metadata field length limits (title 256, summary 1024)
- Fix identical isMacOS branches in editor
- Validate image URLs (http/https only) in ArticleHeader
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-03-24 11:03:29 +02:00
nrobi144
4fcbffdb3b
feat(reads): Phase 2 — editor, drafts, publish, highlights
...
- Create DraftLongTextNoteEvent (kind 30024) in quartz with EventFactory registration
- Create LongFormPublishAction for signing + publishing kind 30023 events
- Create split-pane ArticleEditorScreen with live markdown preview
- Create MarkdownToolbar (bold, italic, heading, link, image, code, quote)
- Create MetadataPanel (title, summary, banner, tags, slug)
- Create DesktopDraftStore with JSON index + .md files, atomic writes, slug sanitization
- Create DraftsScreen with draft list, delete, new draft button
- Create HighlightCreator dialog for kind 9802 highlight creation
- Add Drafts nav rail entry and Editor/Drafts screen routing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-03-24 10:59:52 +02:00
nrobi144
5ef36363cd
feat(reads): Phase 1 — article reader with markdown, ToC, reading time
...
- Add richtext-commonmark deps to commons for shared markdown rendering
- Create RenderMarkdown composable with URL scheme allowlist (security)
- Create ArticleMediaRenderer interface for platform-specific media
- Create ArticleHeader with banner, title, author, reading time metadata
- Create TableOfContents with heading extraction and scroll-spy
- Create ReadingTimeCalculator (238 WPM prose, 80 WPM code, image decay)
- Create ArticleReaderScreen with Medium-style typography (680dp, 1.58x)
- Add DesktopScreen.Article navigation with address tag routing
- Update ReadsScreen to navigate via address tags instead of event IDs
- Responsive ToC sidebar (shown when window > 1100dp)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-03-24 10:59:52 +02:00
davotoula
e976bf9e2e
code review:
...
- Removed redundant equality guards in SideEffect — MutableState already suppresses no-op writes for value types
- Changed mutableStateOf({}) to mutableStateOf(null) with explicit nullable type — clearer intent, no accidental no-op invocation
- stopRecording() now early-returns with ?: return when not recording, so the Toast only shows for genuinely failed recordings (too short)
2026-03-24 09:25:07 +01:00
davotoula
4e43b14b09
entire solid recording indicator bar stops recording when tapped, not just the small stop icon.
2026-03-24 09:25:07 +01:00
David Kaspar
6f3308e45c
Merge pull request #1923 from vitorpamplona/l10n_crowdin_translations
...
New Crowdin Translations
2026-03-24 09:00:06 +01:00
Crowdin Bot
1dbe552821
New Crowdin translations by GitHub Action
2026-03-24 07:35:59 +00:00
davotoula
6436668808
update skill
2026-03-24 08:32:56 +01:00
davotoula
346a7ecac2
update translations: CZ, DE, PT, SE
2026-03-24 08:27:32 +01:00
Claude
c67d66981c
feat: hide video controls on playback start
...
Video controls are now hidden by default when playback begins.
Users can tap to reveal them. Previously, controls were shown for
2 seconds before auto-hiding (TwoSecondController) or shown by
default (VideoViewInner).
https://claude.ai/code/session_01WpAqbodB5w8oDJpN6MLBs6
2026-03-24 06:15:11 +00:00
Claude
cba65344b9
fix: clean up temp files after upload completes
...
MetadataStripper, MediaCompressor, and EncryptFiles create intermediate
temp files in cacheDir during the upload pipeline, but these were never
deleted after the upload finished. Over time this causes unbounded disk
growth. Wrap upload calls in try/finally to ensure all intermediate temp
files (compressed, stripped, encrypted) are deleted regardless of
success or failure.
https://claude.ai/code/session_01YS3dbZ1k84N2EHS3AruYRV
2026-03-24 04:37:41 +00:00
Claude
6e0e8cf00f
feat: add drag-to-seek support on video progress indicator
...
The progress scrubber can now be dragged to seek through the video,
in addition to the existing tap-to-seek. During drag, the scrubber
enlarges for visual feedback and tracks the finger position in
real-time. Seeking is applied on drag end.
https://claude.ai/code/session_01QvYAvNdC35zGgkdpnujFn2
2026-03-24 04:01:27 +00:00
Claude
8525f2b930
feat: add poll type selector for single and multiple choice polls
...
The poll creation UI now shows filter chips to choose between
single choice and multiple choice poll types. Previously it was
hardcoded to single choice only.
https://claude.ai/code/session_01PEsEyGiNvNcNPSjREN4WzW
2026-03-24 02:50:46 +00:00
Claude
425fc24bc2
perf: optimize ChaCha20 and XChaCha20-Poly1305 for speed
...
ChaCha20Core.chaCha20Xor:
- Parse key/nonce once into initial state, reuse across blocks
- XOR at word level (4 bytes at a time) instead of byte-by-byte
- Reuse working IntArray across blocks instead of allocating per block
XChaCha20Poly1305:
- Add hChaCha20FromNonce24 to avoid nonce copyOfRange(0,16) allocation
- Add chaCha20PolyKey to generate only 32 bytes instead of full 64-byte block
- Use single result array instead of ciphertext + tag concatenation
Benchmark (98-byte padded message, JVM):
Before: encrypt 2286 ns/op, decrypt 2062 ns/op
After: encrypt 1544 ns/op, decrypt 341 ns/op
https://claude.ai/code/session_01YHBwqnb3Z7Q7PX31tJ2G3i
2026-03-24 02:35:30 +00:00
Vitor Pamplona
7874893938
v1.06.1
2026-03-23 18:19:42 -04:00
Vitor Pamplona
51fa28f22a
no message
2026-03-23 18:16:24 -04:00
Vitor Pamplona
ec4f949782
Leaves some space to click when their is no space or new lines on the poll.
2026-03-23 18:15:36 -04:00
Vitor Pamplona
4c9f2de6f7
- Improves rendering of the completed polls
...
- Doesn't render quoted polls
2026-03-23 18:01:41 -04:00
Vitor Pamplona
e5aeb49a4b
Solves some of the crashes of concurrent modification exception
2026-03-23 17:59:14 -04:00
Vitor Pamplona
da84848df7
Merge pull request #1911 from vitorpamplona/l10n_crowdin_translations
...
New Crowdin Translations
2026-03-23 17:46:06 -04:00
Crowdin Bot
3d488165c3
New Crowdin translations by GitHub Action
2026-03-23 21:40:20 +00:00
Vitor Pamplona
f99543dc3b
Merge pull request #1913 from greenart7c3/claude/add-url-crash-tests-J8Omf
...
Claude/add url crash tests j8 omf
2026-03-23 17:38:51 -04:00
Claude
7ea5557828
test: fix UrlTest to use 今北産業 as the crash input (PR #1907 )
...
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 21:02:41 +00:00
Claude
3a93c4b075
test: add UrlTest for getPart() boundary conditions fixed in PR #1907
...
Tests the StringIndexOutOfBoundsException fix in Url.getPart() by directly
constructing Url objects with UrlMarker indices that exceed the trimmed
originalUrl length — the exact scenario that occurs when readEnd() strips
a trailing character (e.g. ':') while the PORT/QUERY marker still points
to the original buffer position.
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 20:57:49 +00:00
Claude
9ebc4a1e67
style: remove trailing blank line in UrlMarkerTest
...
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 20:56:58 +00:00
Claude
9202b60dcf
test: add regression tests for 今北産業 URL crash (PR #1907 )
...
Verifies that the Japanese phrase "今北産業" does not cause a
StringIndexOutOfBoundsException in Url.getPart() and is not
detected as a URL.
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 20:46:59 +00:00
Claude
e31e3829a6
test: add regression tests for PR #1907 URL crash fix
...
Tests cover the StringIndexOutOfBoundsException in Url.getPart() that
occurred when readEnd() trimmed trailing characters (e.g. ':') from a
detected URL but urlMarker indices remained pointing past the trimmed
string's end.
- UrlMarkerTest: three cases testing PORT/QUERY index at or beyond
string length (the boundary conditions fixed by minOf clamping and
the startIndex >= length guard)
- UrlsDetectorTest: regression for "今北産業" (no crash, 0 URLs) and
for a bare "example.com:" host
- UrlParserTest: end-to-end regression for "今北産業" and "example.com:"
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 20:31:28 +00:00
Vitor Pamplona
f553489ddf
Improves the wording of the Last Seen
2026-03-23 15:51:35 -04:00
Vitor Pamplona
2b920fc47a
Merge pull request #1907 from greenart7c3/claude/fix-android-runtime-exception-auFbS
...
Fix URL parsing bounds checking in Url.kt
2026-03-23 15:51:07 -04:00
KotlinGeekDev
ac38a73b5e
spotless apply.
2026-03-23 20:27:04 +01:00
KotlinGeekDev
4672e6b587
Merge remote-tracking branch 'origin/kmp-completeness' into kmp-completeness
2026-03-23 19:55:49 +01:00
KotlinGeekDev
bddff36e6b
androidLibrary {} -> android {}
2026-03-23 19:55:35 +01:00
KotlinGeekDev
03c00b9fba
Merge branch 'vitorpamplona:main' into kmp-completeness
2026-03-23 19:52:22 +01:00
KotlinGeekDev
b495f3f409
NIP19 tests for iOS.
2026-03-23 19:50:26 +01:00
KotlinGeekDev
cfecfe2130
Move uri-reference-kmp to version catalog. Remove swift bridge(was a nice run).
2026-03-23 19:49:24 +01:00
KotlinGeekDev
f2bdb24ee5
Removal of references to APIs using the Swift bridge.
2026-03-23 19:38:10 +01:00
KotlinGeekDev
a9c41e1d55
Introduce uri-reference-kmp and replace uriBridge usages with it.
2026-03-23 19:31:58 +01:00
Claude
2e1bcf3e52
style: apply spotless formatting to ChaCha20/Poly1305 sources
...
https://claude.ai/code/session_01YHBwqnb3Z7Q7PX31tJ2G3i
2026-03-23 17:57:31 +00:00
Vitor Pamplona
306d76f793
Tries to fix
...
IllegalArgumentException: 1.06.0-PLAY
| Prop | Value |
|------|-------|
| Manuf |Google |
| Model |Pixel 8a |
| Prod |akita |
| Android |16 |
| SDK Int |36 |
| Brand |google |
| Hardware |akita |
| Device | akita |
| Host | r-0123456789abcdef-0123 |
| User | android-user |
```
java.lang.IllegalArgumentException: Cannot disable reuse from root if it was caused by other groups
androidx.compose.runtime.PreconditionsKt.throwIllegalArgumentException(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:3)
androidx.compose.runtime.ComposerImpl.endReuseFromRoot(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:19)
androidx.compose.runtime.PausedCompositionImpl.resume(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:369)
androidx.compose.ui.layout.LayoutNodeSubcompositionsState$precomposePaused$2.resume(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:50)
androidx.compose.foundation.lazy.layout.PrefetchHandleProvider$HandleAndRequestImpl.performPausableComposition(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:49)
androidx.compose.foundation.lazy.layout.PrefetchHandleProvider$HandleAndRequestImpl.executeRequest(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:128)
androidx.compose.foundation.lazy.layout.PrefetchHandleProvider$HandleAndRequestImpl.execute(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:33)
androidx.compose.foundation.lazy.layout.AndroidPrefetchScheduler.runRequest(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:36)
androidx.compose.foundation.lazy.layout.AndroidPrefetchScheduler.run(r8-map-id-eb237b6d0af50dd04fa25285a72672c5149c195876ad0d708b61d757d31f3d90:113)
android.os.Handler.handleCallback(Handler.java:1070)
android.os.Handler.dispatchMessage(Handler.java:125)
android.os.Looper.dispatchMessage(Looper.java:333)
android.os.Looper.loopOnce(Looper.java:263)
android.os.Looper.loop(Looper.java:367)
android.app.ActivityThread.main(ActivityThread.java:9331)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:837)
```
2026-03-23 13:47:00 -04:00
Claude
d586a0dc25
feat: replace libsodium with pure Kotlin ChaCha20/Poly1305 implementation
...
Remove LazySodium/JNA/libsodium native dependencies and replace with
pure Kotlin implementations of ChaCha20, HChaCha20, XChaCha20,
Poly1305 MAC, and XChaCha20-Poly1305 AEAD. This eliminates platform-
specific native binaries while maintaining full NIP-44 compatibility.
- Add ChaCha20Core with RFC 8439 block function, IETF stream XOR,
HChaCha20, and XChaCha20
- Add Poly1305 MAC (RFC 8439 §2.5)
- Add XChaCha20Poly1305 AEAD encrypt/decrypt
- Convert LibSodiumInstance from expect/actual to commonMain object
- Delete platform-specific LibSodiumInstance actuals (android/jvm/ios)
- Remove iOS native interop (cinterop, linker opts, .a libraries)
- Remove lazysodium-java, lazysodium-android, JNA from build deps
- Clean up ProGuard rules (remove JNA/LazySodium keep rules)
- Add RFC 8439 + libsodium test vectors for ChaCha20 and XChaCha20
- Update benchmark to use simplified ChaCha20 API
https://claude.ai/code/session_01YHBwqnb3Z7Q7PX31tJ2G3i
2026-03-23 17:40:29 +00:00
Vitor Pamplona
eeca86e542
Fixes comparator to avoid Comparison method violates its general contract!
2026-03-23 13:16:32 -04:00
Claude
951610d9ca
fix: prevent StringIndexOutOfBoundsException in Url.getPart()
...
When UrlDetector.readEnd() trims the last character from URLs ending
with characters like '.', ',', etc., the urlMarker indices remain
based on the original buffer length. This caused getPart() to call
substring() with an end index beyond the trimmed URL's length.
Fix by clamping the end index to originalUrl.length and guarding
against an out-of-bounds start index.
https://claude.ai/code/session_014Q2SvTE5vKgUm1w8dPVjYo
2026-03-23 17:10:56 +00:00
Vitor Pamplona
590bd21f62
UriParser might crash, wraps in a try catch
2026-03-23 13:03:43 -04:00
Vitor Pamplona
81380a32ae
Fixes POCO phone's removal of the + sign in NWC
2026-03-23 13:03:18 -04:00
Vitor Pamplona
943f1256a7
Improves zap-store settings
2026-03-23 12:41:30 -04:00
Vitor Pamplona
7af1be7363
v1.06.0
2026-03-23 11:23:44 -04:00