Skip to content

Channel pinning: list indicator and sheet header icons#6474

Open
andremion wants to merge 8 commits into
developfrom
feat/channel-pinning-redesign
Open

Channel pinning: list indicator and sheet header icons#6474
andremion wants to merge 8 commits into
developfrom
feat/channel-pinning-redesign

Conversation

@andremion
Copy link
Copy Markdown
Contributor

@andremion andremion commented May 25, 2026

Closes AND-1185

Goal

Implement the channel pinning visual redesign across the Compose SDK: render mute and pin icons on the channel list item and the SelectedChannelMenu header, surface Pin/Unpin Chat as a first-class action in the channel-options sheet, and expose a configurable indicator position so integrators can mix inline and trailing-bottom layouts per the Figma cookbook.

docs https://github.com/GetStream/docs-content/pull/1312

Implementation

Channel-options sheet (ChannelOptions.kt)

  • Moved Pin/Unpin Chat to slot 2 in the DM action list to match the redesign: View Info → Pin/Unpin Chat → Mute/Unmute User → Block/Unblock User → Archive → Delete. Group order already matched; refreshed the stale KDoc.
  • isPinChannelVisible = false default preserved — the feature stays opt-in.
  • Adopted the new Channel.dmCounterpartId helper to remove duplicated member iteration in buildDmChannelActions.

SelectedChannelMenu header icons

  • Added isMuted and isPinned defaulted parameters to SelectedChannelMenu, ChannelMenuParams, and ChannelMenuHeaderContentParams.
  • The default header renders inline mute and pin icons next to the channel name in a fixed name → mute → pin order when either flag is on. Each icon owns its own contentDescription at the leaf (no parent-level semantic override).
  • ChannelsScreen composes isChannelMuted(cid) || isUserMuted(dmCounterpartId) at the call site — same OR the channel-list row uses — so the sheet header mirrors the row state.

Channel list item pin indicator (ChannelItem.kt, ChatUiConfig.kt)

  • New public PinIndicatorPosition enum (InlineTitle, TrailingBottom) and a new pinIndicatorPosition field on ChannelListConfig (default value InlineTitle). Mirrors the existing MuteIndicatorPosition shape so the two attributes are configured independently — integrators can mix positions (mute inline + pin trailing, etc.).
  • Extracted MutedIcon / PinnedIcon private composables to share rendering between the inline and trailing branches and keep TitleRow under detekt's LongMethod threshold.
  • Preview and snapshot test config overrides now use CompositionLocalProvider(LocalChatUiConfig provides …) (matching the MessageComposerInputLink pattern). This also fixes a pre-existing dark-mode rendering bug in muted_channel_trailing_bottom caused by the previous nested-ChatTheme approach defaulting isInDarkMode back to the system value.

Helpers

  • New internal fun Channel.dmCounterpartId(currentUser: User?): String? in ChannelUtils.kt. Used by both buildDmChannelActions and ChannelsScreen. Covered by ChannelUtilsTest (5 cases: DM with counterpart, non-distinct channel, distinct 3-member, distinct 2-member without current user, null current user).

Localization

  • stream_compose_channel_item_pinned added to the eight supported locale files (default + es, fr, hi, in, it, ja, ko).

Compose sample

  • New CustomSettings.isChannelPinningEnabled boolean pref (default false).
  • Surfaced as a FeatureFlag toggle in the Custom Login settings panel, ordered between Adaptive layout and the composer flags to follow the app's screen-surface flow.
  • ChannelsActivity and ChatsActivity read the flag to drive ChannelOptionsVisibility.isPinChannelVisible, and both compose a pinned-first sort QuerySortByField<Channel>().desc("pinned_at").desc("last_updated") as the recipe integrators can mirror.
  • Both activities adopt the private val settings by lazy { customSettings() } field convention (matches CustomLoginActivity, ChannelActivity).

API surface

Additive only — PinIndicatorPosition enum, pinIndicatorPosition field, isMuted/isPinned fields on the two params data classes, and SelectedChannelMenu defaulted params. All new fields are trailing parameters with default values, so existing callers compile unchanged.

🎨 UI Changes

Screen_recording_20260525_155105.webm

Default PinIndicatorPosition.TrailingBottom MuteIndicatorPosition.TrailingBottom
Screen_recording_20260525_155105.webm
Screen_recording_20260525_162627.webm
Screen_recording_20260525_162711.webm

Testing

  1. Run the stream-chat-android-compose-sample app and open Custom Login.
  2. In the settings panel, enable the new Channel pinning flag, then log in with a user that has both one-to-one and group channels.
  3. Sheet header:
    • Long-press a DM. Confirm the header shows the other user's name only (no icons yet).
    • Tap Pin Chat. Long-press the same DM again. Confirm the pin icon appears inline next to the user's name in the header.
    • Tap Mute User. Long-press again. Confirm the mute icon appears too, rendered before the pin icon (order: name → mute → pin).
    • Repeat with a group channel; the group sheet should show View Info → Pin Chat → Leave Group → Delete Group (assuming owner capabilities).
  4. Channel-options actions:
    • Confirm the DM sheet shows actions in the order: View Info → Pin/Unpin Chat → Mute/Unmute User → Block/Unblock User → Delete Chat.
    • Confirm the action label toggles between Pin Chat / Unpin Chat based on the current state.
  5. Channel list item indicator — default inline position:
    • On the channel list, confirm the pin icon appears inline next to the channel name for pinned channels.
    • Confirm pinned channels surface at the top of the list (pinned-first sort recipe).
  6. Trailing-bottom position:
    • Temporarily override ChannelListConfig(pinIndicatorPosition = PinIndicatorPosition.TrailingBottom) in ChannelsActivity. Confirm the pin icon now renders at the trailing end of the message-preview row.
  7. Mixed positions:
    • Configure muteIndicatorPosition = InlineTitle and pinIndicatorPosition = TrailingBottom on the same ChannelListConfig. Confirm the muted icon stays inline with the name while the pin icon moves to the trailing-bottom corner.
  8. Opt-in preserved:
    • Turn off the Channel pinning flag. Confirm Pin/Unpin Chat disappears from the sheet (default opt-in behavior preserved; no breaking change for integrators).

Snapshot baselines for the five new pin variants plus the refreshed muted_channel_trailing_bottom baseline are recorded in stream-chat-android-compose/src/test/snapshots/images/.

Summary by CodeRabbit

Release Notes

  • New Features

    • Channel pinning: pin/unpin important channels for quick access
    • Configurable pin indicator positioning (inline or trailing bottom)
    • Channel muted and pinned state badges displayed in channel headers
    • Feature flag toggle to enable/disable channel pinning
  • Tests

    • Added test coverage for pinned channel UI variants and states

Review Change Stack

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@andremion andremion added the pr:new-feature New feature label May 25, 2026
@andremion
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.83 MB 5.83 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.07 MB 11.07 MB 0.00 MB 🟢
stream-chat-android-compose 12.46 MB 12.46 MB -0.00 MB 🚀

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Walkthrough

This PR adds channel pinning support to Stream Chat Android Compose, enabling users to pin important channels to the top of lists. The implementation spans configuration (new PinIndicatorPosition enum), UI updates (pinned indicators in channel items and menus showing muted/pinned state), action building refactors (deprecating muted parameter), and sample app integration with preference persistence and feature flags.

Changes

Channel Pinning Feature Implementation

Layer / File(s) Summary
Pin indicator configuration and data contracts
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatUiConfig.kt, ChatComponentFactoryParams.kt, stream-chat-android-compose/api/stream-chat-android-compose.api
PinIndicatorPosition enum (InlineTitle, TrailingBottom) controls pin badge placement; ChannelMenuParams and ChannelMenuHeaderContentParams gain isMuted/isPinned boolean flags (defaulting to false) to track menu state.
Menu and dialog header with muted/pinned icons
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt, ChatComponentFactory.kt
SelectedChannelMenu accepts new isMuted/isPinned parameters; DefaultSelectedChannelMenuHeaderContent delegates to new HeaderTitleRow and HeaderStateIcon composables that conditionally render mute and pin icons next to the channel name based on state.
Channel list item pin rendering and icon refactoring
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelItem.kt
Pin state derived from channel; pinned indicators render inline (title row) or trailing-bottom based on pinIndicatorPosition config. Mute and pin icon rendering refactored into shared MutedIcon() and PinnedIcon() helpers; preview configuration uses CompositionLocalProvider to inject ChannelListConfig.
Channel action building refactor and DM utilities
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt, util/ChannelUtils.kt
New Channel.dmCounterpartId(currentUser) helper resolves DM counterpart user ID; buildDefaultChannelActions removes isMuted parameter (old overload deprecated, forwards to new signature). DM action construction updated to resolve counterpart via utility and include explicit pin/unpin actions.
Screen menu state and action building
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/ChannelsScreen.kt
Computes combined muted state (channel muted OR DM counterpart user muted) and derives pin state from channel; passes both to ChannelMenu; calls refactored buildDefaultChannelActions without isMuted argument.
Sample app settings and configuration wiring
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/data/CustomSettings.kt, feature/channel/list/ChannelsActivity.kt, ui/chats/ChatsActivity.kt, ui/login/CustomLoginActivity.kt
CustomSettings adds isChannelPinningEnabled shared preference; activities cache settings instance and use it to configure isPinChannelVisible and channel sort order (prioritize pinned_at, then last_updated); login UI adds feature flag toggle for channel pinning.
Localized string resources
stream-chat-android-compose/src/main/res/values*/strings.xml (9 locales), stream-chat-android-compose-sample/src/main/res/values/strings.xml
Adds stream_compose_channel_item_pinned label across default and localized resource files; sample app adds custom_login_flag_channel_pinning_label and custom_login_flag_channel_pinning_description.
Test coverage and documentation
stream-chat-android-compose/src/test/kotlin/.../ChannelItemTest.kt, SelectedChannelMenuTest.kt, util/ChannelUtilsTest.kt, stream-chat-android-docs/.../SelectedChannelMenu.kt
Snapshot tests added for pinned channel item states (inline, trailing-bottom, muted+pinned variants); SelectedChannelMenuTest refactored to test dialog composables; new ChannelUtilsTest validates dmCounterpartId edge cases (valid DM, invalid/non-DM channels, null current user). Documentation examples remove deprecated isMuted argument from buildDefaultChannelActions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • GetStream/stream-chat-android#6449: Modifies ChannelItem.kt mute-icon rendering; main PR extends that pattern to include pin icons and refactors both into shared composable helpers.

Suggested reviewers

  • gpunto
  • VelikovPetar

Poem

🐰 Whiskers twitch with glee today,
Pins keep channels front and play,
Muted icons dance with pride,
Side by side in config-guide,
Hopping through the sorted heap!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main changes: implementing channel pinning UI with list indicator and sheet header icons.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is comprehensive, well-structured, and addresses all key sections of the template.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/channel-pinning-redesign

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@stream-chat-android-compose/api/stream-chat-android-compose.api`:
- Around line 2909-2920: The new pinIndicatorPosition was inserted in the middle
of the ChannelListConfig primary constructor and generated members
(constructors, copy, componentN), changing the parameter order and breaking
positional/destructuring callers; move pinIndicatorPosition to the end of the
primary constructor and data class property list (so ChannelListConfig keeps
parameters order: MuteIndicatorPosition, Boolean, ChannelOptionsVisibility, then
PinIndicatorPosition as trailing parameter with a default), regenerate/update
the synthetic constructor/copy/componentN ordering accordingly so existing
callers remain source-compatible while exposing the new property.
- Line 890: The public API lost an overload for SelectedChannelMenu when two
Boolean parameters (isMuted, isPinned) were inserted before the headerContent
and centerContent lambdas; add back the old overload (the previous
SelectedChannelMenu signature that accepts Channel, User, List, Function1
headerContent, Function0 ??? — specifically the variant that callers used
positionally for headerContent and centerContent) and implement it as a thin
forwarder to the new SelectedChannelMenu implementation, passing sensible
default values for isMuted and isPinned and forwarding all other args (including
headerContent and centerContent) to preserve binary/Source compatibility; locate
the new implementation named SelectedChannelMenu (mangled in the diff as
SelectedChannelMenu-j30j4ZQ) and create the overload that calls it with default
flags so existing positional callers continue to compile.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatUiConfig.kt`:
- Line 64: The default for pinIndicatorPosition in ChatUiConfig is set to
PinIndicatorPosition.InlineTitle but the redesign intends trailing placement;
update the declaration of pinIndicatorPosition (in ChatUiConfig) to use
PinIndicatorPosition.Trailing as the default so the out-of-the-box behavior
matches the PR objective.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 040c5896-77b9-47a8-bfae-6827572b3352

📥 Commits

Reviewing files that changed from the base of the PR and between 3ae7d8f and 96d7e52.

⛔ Files ignored due to path filters (10)
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_and_pinned_channel.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_and_pinned_channel_mixed_positions.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_and_pinned_channel_trailing_bottom.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_channel_trailing_bottom.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_pinned_channel.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_pinned_channel_trailing_bottom.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_SelectedChannelMenuTest_selected_channel.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_SelectedChannelMenuTest_selected_channel_centered_dialog.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_SelectedChannelMenuTest_selected_channel_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_SelectedChannelMenuTest_selected_channel_muted_and_pinned.png is excluded by !**/*.png
📒 Files selected for processing (26)
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/data/CustomSettings.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/chats/ChatsActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/login/CustomLoginActivity.kt
  • stream-chat-android-compose-sample/src/main/res/values/strings.xml
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/ChannelsScreen.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelItem.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatUiConfig.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/ChannelUtils.kt
  • stream-chat-android-compose/src/main/res/values-es/strings.xml
  • stream-chat-android-compose/src/main/res/values-fr/strings.xml
  • stream-chat-android-compose/src/main/res/values-hi/strings.xml
  • stream-chat-android-compose/src/main/res/values-in/strings.xml
  • stream-chat-android-compose/src/main/res/values-it/strings.xml
  • stream-chat-android-compose/src/main/res/values-ja/strings.xml
  • stream-chat-android-compose/src/main/res/values-ko/strings.xml
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channels/ChannelItemTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channels/SelectedChannelMenuTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/util/ChannelUtilsTest.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/channels/SelectedChannelMenu.kt
💤 Files with no reviewable changes (1)
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/channels/SelectedChannelMenu.kt

Comment thread stream-chat-android-compose/api/stream-chat-android-compose.api Outdated
Comment thread stream-chat-android-compose/api/stream-chat-android-compose.api
@GetStream GetStream deleted a comment from coderabbitai Bot May 26, 2026
@andremion andremion marked this pull request as ready for review May 26, 2026 08:26
@andremion andremion requested a review from a team as a code owner May 26, 2026 08:26
@andremion andremion force-pushed the feat/channel-pinning-redesign branch from 96d7e52 to 0678778 Compare May 27, 2026 13:59
@sonarqubecloud
Copy link
Copy Markdown

@andremion andremion enabled auto-merge (squash) May 27, 2026 14:18
@andremion andremion requested a review from VelikovPetar May 27, 2026 14:31
andremion added 6 commits May 27, 2026 17:19
Aligns the DM action order with the channel-pinning redesign:
View Info -> Pin/Unpin Chat -> Mute/Unmute User -> Block/Unblock User
-> Archive/Unarchive Chat -> Delete Chat. Group order was already correct;
only KDoc refreshed to reflect the actual default flow and the opt-in
nature of Pin and Archive.
The selected-channel menu header now renders inline mute and pin icons
next to the channel name when the respective attribute is active, in a
fixed name -> mute -> pin order matching the redesign.

Adds defaulted isMuted/isPinned fields to ChannelMenuParams and
ChannelMenuHeaderContentParams; ChannelsScreen composes the channel-mute
OR DM-counterpart-user-mute signal inline using existing
isChannelMuted/isUserMuted accessors. Extracts a small internal
Channel.dmCounterpartId helper to remove a duplicate member-iteration
that also appeared in buildDmChannelActions.

Localizes stream_compose_channel_item_pinned across the seven supported
locales. Enables isPinChannelVisible in the compose sample so the
behaviour is reachable from the dogfooding app. The preview-vs-snapshot
duplication for SelectedChannelMenu is removed via three internal
content composables called by both the previews and the Paparazzi tests.
Adds a PinIndicatorPosition enum mirroring MuteIndicatorPosition, plus a
trailing pinIndicatorPosition field on ChannelListConfig so the pin icon
can be placed inline with the channel name or at the trailing bottom of
the preview row, independent of the mute icon position. The render order
in TitleRow is name -> mute -> pin (matching the redesign) and the trailing
branch in MessageRow renders mute before pin. The mute/pin icon rendering
is extracted into MutedIcon/PinnedIcon helpers and the preview/snapshot
config overrides now use CompositionLocalProvider(LocalChatUiConfig) to
keep snapshotWithDarkMode's dark-mode flag intact across nested overrides.

In the sample, channel pinning becomes a CustomSettings feature flag
(isChannelPinningEnabled, default false) toggled from the Custom Login
settings panel and consumed by both ChannelsActivity and ChatsActivity.
Activities adopt the canonical settings field pattern via
private val settings by lazy { customSettings() }.

Snapshot baselines: five new ChannelItem tests (pinned only, pinned
trailing, muted+pinned both inline, muted+pinned both trailing, mixed)
and a refreshed muted_channel_trailing_bottom to fix a pre-existing
dark-mode rendering bug exposed by the same nested-ChatTheme issue.

Also folds in KDoc cleanup on the muted/pinned param docs added in the
previous commit, removing implementation rationale per the engineering
principles.
Composes the existing last_updated sort with a leading desc("pinned_at")
in both ChannelsActivity and ChatsActivity so pinned channels surface at
the top of the channel list while unpinned channels keep their
recent-activity ordering. Acts as the recipe integrators can mirror to
enable pinned-first sorting without a SDK-default change.
…ions

Adds a new public overload of buildDefaultChannelActions without the
isMuted parameter and marks the previous five-arg overload @deprecated
with a ReplaceWith quick-fix. The parameter was received but never read
by either the DM or group action builders. ChannelsScreen, the sample
ChannelsActivity, and the docs example are updated to call the new
overload so the SDK does not dogfood the deprecated API.
Drops the isMuted/isPinned params on ChannelMenuParams,
ChannelMenuHeaderContentParams, and SelectedChannelMenu. The default
header now derives the pinned state from selectedChannel.isPinned() and
the muted state from currentUser.channelMutes (channel-level) and
currentUser.mutes (DM-counterpart) via a private helper. ChannelsScreen
reverts to its pre-PR shape — no OR computation, no flags on the params.

Addresses the review concern that isMuted was ambiguous (channel vs.
user mute) and that both flags duplicate state the menu already has via
selectedChannel + currentUser. Net effect on the public API vs. develop
is zero new fields on the params data classes for icon state.
Aligns ChatsActivity with ChannelsActivity by using the
android_sample_filter predefined filter (which already sorts pinned
channels to the top server-side) instead of an inline filter + client
querySort. Drops the now-unused CHANNEL_ARG_DRAFT, Filters, and
QuerySortByField imports from ChatsActivity.

Also updates the channelsViewModelFactory KDoc in ChannelsActivity to
reflect the actual sort applied by the predefined filter
(QuerySortByField<Channel>().desc("pinned_at").desc("last_updated")).
@andremion andremion force-pushed the feat/channel-pinning-redesign branch from 0678778 to 06a42cd Compare May 28, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:new-feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants