Skip to content

Disable composer during slow mode#6499

Open
andremion wants to merge 5 commits into
developfrom
andrerego/and-1177-disable-composer-during-slow-mode
Open

Disable composer during slow mode#6499
andremion wants to merge 5 commits into
developfrom
andrerego/and-1177-disable-composer-during-slow-mode

Conversation

@andremion

@andremion andremion commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Resolves AND-1177.

Goal

When slow mode is active on a channel (coolDownTime > 0), the whole composer should be disabled, not just the send action. This follows the design decision DS-035 ("Slow Mode Locks the Entire Composer"). Before this change, only the send button was replaced by the countdown. The input field and the attachment "+" button stayed interactive and the composer border kept its default colour, which contradicted the spec.

Implementation

While coolDownTime > 0:

  • The input field is disabled (MessageComposerInputCenterContent), and its placeholder shows the remaining seconds ("Slow mode, wait 9s…") via the new stream_ui_message_composer_placeholder_slow_mode string, with translations for all supported locales.
  • The attachment "+" button stays visible but is disabled, including its border (MessageComposerLeadingContent). Its click action is removed from the accessibility tree while disabled.
  • The composer border switches to borderUtilityDisabled and returns to borderCoreDefault once the timer reaches zero (MessageInput). The composer node uses border/utility/disabled here (confirmed with design), so no new colour token was added.
  • The trailing countdown indicator is unchanged.

The composer re-enables automatically when the timer reaches zero, because every slot reads from MessageComposerState.coolDownTime. Factory overrides that only replace the trailing content keep working without changes.

Slow mode activation is also relaxed (MessageComposerController): it now triggers on cooldown > 0 and the absence of the skip-slow-mode capability, instead of also requiring the slow-mode own-capability. The backend only grants slow-mode when cooldown > 0 and the user cannot skip it, so this is equivalent today, but it keeps the client correct if the backend later tightens how that capability is granted, without needing a new client release. It also aligns the activation rule with the iOS and Flutter SDKs.

🎨 UI Changes

Verify the snapshots diff

Testing

Manual steps:

  1. Enable slow mode on a channel (set a cooldown, for example from the dashboard or with channelClient.enableSlowMode(seconds)).
  2. Open the channel and send a message.
  3. Confirm: the input field is greyed and not editable, the "+" button is greyed and not tappable, the composer border uses the lighter disabled colour, the placeholder reads "Slow mode, wait Ns…", and the trailing countdown shows the seconds.
  4. Wait for the countdown to reach zero. The composer re-enables automatically (input editable, "+" tappable, border back to default) with no user action.

Automated:

  • Compose: Robolectric interaction tests in MessageComposerScreenTest (input and "+" disabled during cooldown, slow-mode placeholder, both enabled without cooldown) and Paparazzi snapshots in MessageComposerInputTest and MessageComposerTest.
  • Controller: unit tests in MessageComposerControllerTest assert the cooldown activates without the slow-mode capability and stays off when the user can skip slow mode.
  • E2E: SlowModeTests in the compose sample (cooldown shown after sending, composer locked during cooldown), mirroring the iOS SlowMode_Tests. The e2e suite needs the emulator and the mock-server driver, so it runs in CI.

Summary by CodeRabbit

  • New Features

    • Added slow mode feature with cooldown indicator when message sending is restricted
    • Message composer input and attachments button disabled during cooldown period
    • Cooldown timer displays in placeholder text with countdown
    • Multi-language support for slow mode messaging
  • Tests

    • Added E2E tests for slow mode behavior
    • Added unit tests for composer UI state during cooldown

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

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:improvement Improvement label Jun 12, 2026
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.90 MB 5.90 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.13 MB 11.13 MB 0.00 MB 🟢
stream-chat-android-compose 12.55 MB 12.57 MB 0.02 MB 🟢

@andremion andremion changed the title [AND-1177] Disable composer during slow mode Disable composer during slow mode Jun 12, 2026
@andremion andremion marked this pull request as ready for review June 12, 2026 10:21
@andremion andremion requested a review from a team as a code owner June 12, 2026 10:21
@andremion andremion enabled auto-merge (squash) June 12, 2026 10:21
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR adds slow-mode/cooldown functionality to the message composer. When a channel has cooldown enabled, the input field and attachments button are disabled, the border color changes, and a countdown placeholder is shown. Tests verify the behavior at unit, snapshot, and E2E levels. Localization strings support 9 languages.

Changes

Message Composer Slow Mode Implementation

Layer / File(s) Summary
Composer input and attachments disabled state during cooldown
src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/MessageComposerInputCenterContent.kt, src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/MessageComposerLeadingContent.kt
Input field is disabled when coolDownTime > 0, and placeholder text changes to show slow-mode countdown. Attachments button is disabled via new enabled parameter that reflects cooldown state; disabled state also affects border color and semantics onClick registration.
UI styling and slow-mode visual indication
src/main/java/io/getstream/chat/android/compose/ui/components/composer/CoolDownIndicator.kt, src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt, src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt, api/stream-chat-android-compose.api
Cooldown indicator gains testTag for UI testing. MessageInput border uses disabled color when cooldown is active. New MessageComposerSlowMode preview composable visualizes slow-mode state with coolDownTime = 9. Generated lambda accessor is added to Compose API file.
Unit and snapshot testing
src/test/kotlin/io/getstream/chat/android/compose/ui/messages/MessageComposerTest.kt, src/test/kotlin/io/getstream/chat/android/compose/ui/messages/composer/MessageComposerScreenTest.kt
Snapshot test for slow-mode composer added. Two Compose UI tests verify input and attachments button are disabled during cooldown (coolDownTime > 0) and enabled when cooldown is zero.
E2E test infrastructure and slow-mode tests
stream-chat-android-e2e-test/src/main/kotlin/io/getstream/chat/android/e2e/test/robots/BackendRobot.kt, stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/MessageListPage.kt, stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotMessageListAsserts.kt, stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/SlowModeTests.kt
BackendRobot gains setCooldown(enabled, duration) method to configure backend cooldown. MessageListPage adds cooldownIndicator selector. UserRobot assertions check cooldown visibility and composer disabled state. SlowModeTests class runs two E2E scenarios: cooldown shown when message sent, and composer disabled in slow mode.
Localization strings for multiple languages
src/main/res/values/strings.xml, src/main/res/values-es/strings.xml, src/main/res/values-fr/strings.xml, src/main/res/values-hi/strings.xml, src/main/res/values-in/strings.xml, src/main/res/values-it/strings.xml, src/main/res/values-ja/strings.xml, src/main/res/values-ko/strings.xml
Adds stream_ui_message_composer_placeholder_slow_mode resource with countdown placeholder (%1$ds) in English and 8 localized translations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • GetStream/stream-chat-android#6441: Expands AttachmentPickerButton accessibility/semantics; this PR builds on that work by adding cooldown-driven enabled behavior to the same component.

Suggested reviewers

  • gpunto
  • VelikovPetar

Poem

🐰 The composer rests in gentle slow mode's grace,
Counting down the seconds with a patient face,
Input fields and buttons wait their turn to shine,
While the countdown placeholder marks each passing line.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 title 'Disable composer during slow mode' directly and concisely describes the main objective of the PR: disabling the entire message composer when slow mode is active.
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 pull request description comprehensively covers all required template sections with detailed Goal, Implementation, UI Changes reference, Testing (both manual and automated), and contributor checklist.

✏️ 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 andrerego/and-1177-disable-composer-during-slow-mode

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.

@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

While slow mode is active (coolDownTime > 0) the whole composer is locked:
the input field and attachment button are disabled, the composer and
attachment-button borders switch to the disabled colour, and the input
placeholder shows the remaining seconds. It re-enables automatically when
the timer reaches zero.

Add the stream_ui_message_composer_placeholder_slow_mode string with
translations, plus slow-mode snapshots for the full composer and the input.
Add an instrumented slow-mode suite to the compose sample, mirroring the
iOS SlowMode_Tests. BackendRobot.setCooldown drives the shared mock server
(config/cooldown), and the new UserRobot assertions check the cooldown
indicator, the hidden send button, and the disabled input and attachment
button. CoolDownIndicator gets a testTag so the e2e layer can locate it.
@andremion andremion force-pushed the andrerego/and-1177-disable-composer-during-slow-mode branch from 61f4779 to aad304d Compare June 12, 2026 11:09
The composer gated slow mode on the channel's slow-mode own-capability.
The backend grants that capability only when cooldown > 0 and the user
cannot skip slow mode, so checking those two conditions directly is
equivalent today and keeps the client correct if the backend later
changes how the capability is granted, without needing a client release.
This also aligns the behaviour with the iOS and Flutter SDKs, which do
not require the capability either.
@andremion andremion force-pushed the andrerego/and-1177-disable-composer-during-slow-mode branch from aad304d to 9bfa16e Compare June 12, 2026 12:44
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:improvement Improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant