Skip to content

Release 1.8.0 - #170

Merged
malkoG merged 5 commits into
hackers-pub:mainfrom
malkoG:release/1.8.0
Oct 4, 2026
Merged

malkoG merged 5 commits into
hackers-pub:mainfrom
malkoG:release/1.8.0

Conversation

@malkoG

@malkoG malkoG commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

1.8.0 adds account switching, selectable post text and sharing of selected text. It also fixes extra spacing in bullet lists.

Account switcher (5264ccc)

  • Switching and adding: a switcher button on the Settings profile row opens a dropdown of your other signed-in accounts plus Add Account, which signs in to another account.
  • Storage: SessionManager stores every signed-in account. The old single-account keys still hold whichever account is active, so code that reads them is unchanged. An existing login joins the list automatically on update.
  • Switching side effects: AccountSessionCoordinator moves FCM registration to the new account and clears notification state and the Apollo cache, so the previous account's data doesn't leak.
  • Signing out: with other accounts saved, signing out switches to the next one.
  • Navigation: every account change also clears the saved bottom-tab back stacks. Without this, tapping a tab could bring back the previous account's screen through restoreState.

Bullet list spacing (acb8e0b)

  • The bug: in PostCard previews, each list item had a blank line under it, which PostDetail didn't show. Compose already starts a new line at every ParagraphStyle boundary, so the separator \n the parser added between items became an empty paragraph.
  • The fix: the parser no longer adds that separator. HtmlListLayoutTest checks real line counts with native graphics, because the parsed text alone can't show this bug.

Selectable text (ca49a97)

  • Coverage: post and article text is selectable in PostCard, PostDetail and ArticleCard, including quoted posts, reply previews, translated text and titles.
  • Taps: a long-press starts a selection and no longer also counts as a tap. Plain taps still follow links and open posts.

Sharing (41c66ae)

  • Share button: shares the link directly. Articles share 『title』 and the URL; notes share the bare URL.
  • Selection menu → Share: shares the selected text in quotes, under the article title, followed by the URL.
  • Length: shares are sized to fit one post on X, with a weighted limit of 280 where a URL counts as 23 and CJK/Hangul/emoji count as 2. A long quote keeps its first and last words around (...), cutting by characters when the text has no spaces.
  • Capturing the selection: the Share item runs the selection's own Copy action with a capturing LocalClipboard in place. The system clipboard is never touched.
  • Cleanup: the share-sheet code that was copy-pasted across 8 screens is now a single helper, sharePlainText.
  • Replies: reply cards in PostDetail now show the Share button.

Version (f97bac6)

  • versionCode 14, versionName 1.8.0

Test plan

  • ./gradlew :app:testDebugUnitTest: 260 tests pass
  • ./gradlew :app:lintDebug: 0 errors
  • On a device, add a second account, switch back and forth, and check that each switch lands on that account's timeline with the right notifications.
  • On a device, sign out of one account while another is saved, and check that the app switches to the remaining account.
  • On a device, check that bullet lists in timeline cards have no blank lines between items.
  • On a device, long-press post text and check that the selection and its Copy menu work. Robolectric can't observe selection.
  • On a device, select text in a note and in an article, tap Share in the selection menu, and check the shared text. Then check that the clipboard still holds what it had before.
  • On a device, tap the Share button on a note and on an article, and check that each shares only the link.

🤖 Generated with Claude Code

malkoG and others added 5 commits October 4, 2026 22:34
SessionManager now keeps every signed-in account as a JSON list in
DataStore, while the existing single-account keys mirror the active one
so current readers (auth interceptor, notification worker, FCM) are
unchanged. Sessions from before this change are folded into the list.

AccountSessionCoordinator owns sign-in, switching, and sign-out: it
moves FCM registration between accounts, clears notification state,
and wipes the Apollo cache so viewer-specific data doesn't leak.
Signing out with other accounts stored promotes the next one.

Settings gets a switcher button at the right of the profile header
that opens a dropdown of the other accounts plus "Add Account".
Account changes reset navigation and also clear saved bottom-tab back
stacks, which restoreState would otherwise bring back with the
previous account's data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
List items are rendered as ParagraphStyle ranges, and Compose already
breaks lines at every paragraph boundary. The "\n" the parser wrote
between items was laid out as its own empty paragraph, so each item got
a blank line under it. This showed up in PostCard, whose default
preview uses this flat rendering path, and not in PostDetail, which
renders lists as separate blocks.

Drop the one separator newline at each paragraph end. Items are now
contiguous, nested lists no longer gain a gap, and a list keeps one
blank line before and after the surrounding paragraphs.

HtmlListLayoutTest measures real line counts with native graphics,
since the parsed text alone can't show this kind of bug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wrap HtmlContent in a SelectionContainer so post bodies are selectable
everywhere they render: PostCard (including reply and quote previews),
PostDetail, and article bodies, lists, headings, and code blocks. The
text rendered outside HtmlContent gets the same treatment: translated
text, post titles in PostCard and PostDetail, and the title and summary
in ArticleCard.

HtmlClickableText now claims long presses with a no-op handler. Without
it, releasing a long press to select text also counted as a tap and
opened the post or followed a link.

HtmlContentSelectionTest covers the tap side: a long press doesn't open
the post, while taps still open it, follow links, and reach the card
behind a selectable title. Robolectric can't observe the selection
itself, so that needs checking on a device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The selection menu in notes and articles gets a "Share" item that
shares the selected text, quoted, under the article's title in 『』
and followed by the post URL. Shares are sized to fit a single post on
X (weighted 280, URLs as 23, CJK/Hangul/emoji as 2): a quote too long
for that keeps its first and last words around "(...)", cutting by
characters when the text has no spaces.

Compose doesn't expose the selected text to menu items, so Share runs
SelectionContainer's own Copy item with a capturing LocalClipboard in
place. The selection reaches the share sheet without touching the
system clipboard.

The share button now shares the link directly: 『title』 and the URL
for articles, the bare URL for notes. Reply cards in PostDetail get
the button as well.

The share-sheet intent that was copy-pasted across eight screens is
now the single sharePlainText helper, and the HTML-to-text step of
the two translate paths is the shared htmlToPlainText.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 4, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 57f43e54-e106-4334-93cc-b18bf62e2f5d
📥 Commits

Reviewing files that changed from the base of the PR and between 7b2a7c3 and f97bac6.

📒 Files selected for processing (33)
  • app/build.gradle.kts
  • app/src/main/java/pub/hackers/android/data/auth/AccountSessionCoordinator.kt
  • app/src/main/java/pub/hackers/android/data/local/SessionManager.kt
  • app/src/main/java/pub/hackers/android/ui/HackersPubApp.kt
  • app/src/main/java/pub/hackers/android/ui/components/ArticleCard.kt
  • app/src/main/java/pub/hackers/android/ui/components/HtmlContent.kt
  • app/src/main/java/pub/hackers/android/ui/components/PostCard.kt
  • app/src/main/java/pub/hackers/android/ui/screens/auth/SignInViewModel.kt
  • app/src/main/java/pub/hackers/android/ui/screens/bookmarks/BookmarksScreen.kt
  • app/src/main/java/pub/hackers/android/ui/screens/explore/ExploreScreen.kt
  • app/src/main/java/pub/hackers/android/ui/screens/postdetail/PostDetailScreen.kt
  • app/src/main/java/pub/hackers/android/ui/screens/profile/ProfileScreen.kt
  • app/src/main/java/pub/hackers/android/ui/screens/search/SearchScreen.kt
  • app/src/main/java/pub/hackers/android/ui/screens/settings/SettingsScreen.kt
  • app/src/main/java/pub/hackers/android/ui/screens/settings/SettingsViewModel.kt
  • app/src/main/java/pub/hackers/android/ui/screens/timeline/TimelineScreen.kt
  • app/src/main/java/pub/hackers/android/ui/share/PostShareButton.kt
  • app/src/main/java/pub/hackers/android/ui/share/PostShareSelection.kt
  • app/src/main/java/pub/hackers/android/ui/share/PostShareText.kt
  • app/src/main/java/pub/hackers/android/ui/share/ShareIntents.kt
  • app/src/main/res/values/strings.xml
  • app/src/test/java/pub/hackers/android/data/auth/AccountSessionCoordinatorTest.kt
  • app/src/test/java/pub/hackers/android/data/local/SessionManagerTest.kt
  • app/src/test/java/pub/hackers/android/ui/components/HtmlContentKtTest.kt
  • app/src/test/java/pub/hackers/android/ui/components/HtmlContentSelectionTest.kt
  • app/src/test/java/pub/hackers/android/ui/components/HtmlListLayoutTest.kt
  • app/src/test/java/pub/hackers/android/ui/screens/auth/SignInViewModelTest.kt
  • app/src/test/java/pub/hackers/android/ui/screens/postdetail/PostDetailContentTest.kt
  • app/src/test/java/pub/hackers/android/ui/screens/settings/SettingsScreenTest.kt
  • app/src/test/java/pub/hackers/android/ui/screens/settings/SettingsViewModelTest.kt
  • app/src/test/java/pub/hackers/android/ui/share/PostShareButtonTest.kt
  • app/src/test/java/pub/hackers/android/ui/share/PostShareTextTest.kt
  • app/src/test/java/pub/hackers/android/ui/share/SelectionCapturingClipboardTest.kt
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@malkoG
malkoG merged commit 2bd51e1 into hackers-pub:main Oct 4, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant