Skip to content

feat: add setAppearance for dark mode and forward custom CSS [ENG-3645] - #93

Open
Dhruwang wants to merge 6 commits into
mainfrom
feat/set-appearance-custom-css
Open

Dhruwang wants to merge 6 commits into
mainfrom
feat/set-appearance-custom-css

Conversation

@Dhruwang

@Dhruwang Dhruwang commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Ref ENG-3645

What & why

Was: Android surveys always rendered light, and the SDK dropped the workspace's compiled custom CSS.
Now: Formbricks.setAppearance(LIGHT | DARK | SYSTEM) switches surveys, live while open. Compiled workspace and survey CSS reach the renderer.

  • Works before setup, or via the config builder. Survives logout, resets on app restart, never sent to the server. Unknown strings log and fall back to light.
  • SYSTEM follows the app's night mode (Activity configuration, so AppCompatDelegate counts), not the phone's.
  • The survey page is built once; live changes use evaluateJavascript with ?., so older servers stay light. The listener is removed in onDestroyView.
  • WebView auto-darkening is switched off (API 33+ isAlgorithmicDarkeningAllowed, 29-32 forceDark) so it cannot invert the survey.
  • customCss forwarded untouched, empty fields omitted, no key when there is none.

Where to look

Coverage

Behaviour Level Evidence
State, unknown value, SYSTEM resolution, listeners, customCss omit/forward, Settings decode with and without it unit (mutation) AppearanceInstrumentedTest and FormbricksViewModelInstrumentedTest (new cases). Rerun: ./gradlew :android:connectedDebugAndroidTest
Live light/dark/system switch keeps the typed answer, custom CSS applies, no-overlay mode manual recording and stills below
Overlay (bottom sheet) mode; instrumented tests manual Not run, see Open gaps
Screen recording and screenshots

Switching light, dark and system while a survey is open

Full-quality recording (mp4)

Dark (opened dark) Light (switched live, answer kept)
Survey in dark mode with custom CSS Survey in light mode with the typed answer
System, app night mode dark System, app night mode light
System appearance with app dark System appearance with app light

Emulator (Pixel, API 36) against a local server on the dark-mode and custom-CSS epic branch; workspace CSS gives pill buttons in light and amber in dark. The demo build temporarily allowed http://localhost; that is not in this PR.

Open gaps

  • Overlay (bottom sheet) presentation not run; only the no-overlay path. The existing instrumented tests were not run.
  • If the host Activity does not handle uiMode in configChanges, a night-mode change recreates it and the survey reloads (answers lost), as on rotation. Documented in the README.
  • A change between the WebView mounting and the survey bundle loading is missed.
  • Needs a server whose renderer has setAppearance; older servers stay light.

Breaking changes

  • None. Purely additive API (FormbricksConfig gains a defaulted appearance field, Settings and Survey a defaulted customCss).

Migrations & env

None. CI fix: JaCoCo and sonar.java.binaries read build/tmp/kotlin-classes/debug, which AGP 9 no longer writes, so coverage was empty on every run (including main). They now read build/intermediates/built_in_kotlinc/debug/compileDebugKotlin/classes.


Agent: claude-sonnet-5-5 (Claude Code), effort unknown.

@CLAassistant

CLAassistant commented Oct 8, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Dhruwang
Dhruwang marked this pull request as ready for review October 8, 2026 07:06
@Dhruwang
Dhruwang requested a review from itsjavi October 8, 2026 07:06
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: a2036e5a-5fd0-474d-8a59-29ad04ebdada
  • 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.

…ut [ENG-3645]

The report read android/build/tmp/kotlin-classes/debug, which AGP 9 no longer writes, so every
coverage run produced an empty report (main shows 0.0% too) and any PR adding coverable lines
failed the new-coverage gate.
Comment thread android/src/main/java/com/formbricks/android/helper/Appearance.kt Outdated
setAppearance called before the renderer existed was a no-op, yet it was
recorded as applied, so the survey stayed light and repeats were dropped.
The page now reports onSurveyRendered and the fragment holds the change
until then; the listener is registered before the first resolve.
…ion [ENG-3645]

Creating the first WebView resets the Activity's configuration to the
phone's, so an app forced dark via AppCompatDelegate got a light survey.
An explicit AppCompat night mode (local, else default) now wins.
@sonarqubecloud

sonarqubecloud Bot commented Oct 8, 2026

Copy link
Copy Markdown

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.

3 participants