From d47b4b068630c13983759c0c9763dde7b18d129d Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 31 Jul 2026 22:42:23 -0400 Subject: [PATCH] Collapse WhatsApp Web to a Signal-style avatar rail in slim windows (#6473) * Make menu overflow visible with a half-row peek and edge fades Menus used to cut off clean at ten rows, so anything below the fold was undiscoverable. Now the list sizes to what fits within 60% of the screen and always ends mid-row when items overflow, with scroll-position-driven fades at both edges. Keyboard navigation keeps the next hidden row peeking past the cursor so the fold affordance travels with the selection. Co-Authored-By: Claude Fable 5 * Collapse WhatsApp Web to a Signal-style avatar rail in slim windows Add a WhatsApp Slim Chromium extension that injects CSS into web.whatsapp.com, collapsing the chat list to a 90px avatar rail with floating unread badges when the window is narrower than 1100px. Wide windows keep the stock layout. Loaded through the existing --load-extension list in chromium-flags.conf, with a migration to append it for existing users. Co-Authored-By: Claude Fable 5 --------- Co-authored-by: Claude Fable 5 --- config/chromium-flags.conf | 2 +- .../extensions/whatsapp-slim/manifest.json | 12 ++++ .../extensions/whatsapp-slim/whatsapp.css | 64 +++++++++++++++++++ migrations/1785543725.sh | 20 ++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 default/chromium/extensions/whatsapp-slim/manifest.json create mode 100644 default/chromium/extensions/whatsapp-slim/whatsapp.css create mode 100644 migrations/1785543725.sh diff --git a/config/chromium-flags.conf b/config/chromium-flags.conf index 5edf16a7..1fe08716 100644 --- a/config/chromium-flags.conf +++ b/config/chromium-flags.conf @@ -2,4 +2,4 @@ --ozone-platform-hint=wayland --password-store=gnome-libsecret --enable-features=TouchpadOverscrollHistoryNavigation ---load-extension=/usr/share/omarchy/default/chromium/extensions/copy-url,/usr/share/omarchy/default/chromium/extensions/yt-dlp +--load-extension=/usr/share/omarchy/default/chromium/extensions/copy-url,/usr/share/omarchy/default/chromium/extensions/yt-dlp,/usr/share/omarchy/default/chromium/extensions/whatsapp-slim diff --git a/default/chromium/extensions/whatsapp-slim/manifest.json b/default/chromium/extensions/whatsapp-slim/manifest.json new file mode 100644 index 00000000..48471bd5 --- /dev/null +++ b/default/chromium/extensions/whatsapp-slim/manifest.json @@ -0,0 +1,12 @@ +{ + "manifest_version": 3, + "name": "WhatsApp Slim", + "version": "1.0", + "description": "Collapse WhatsApp Web's chat list to an avatar rail in narrow windows, this extension is installed by Omarchy", + "content_scripts": [ + { + "matches": ["https://web.whatsapp.com/*"], + "css": ["whatsapp.css"] + } + ] +} diff --git a/default/chromium/extensions/whatsapp-slim/whatsapp.css b/default/chromium/extensions/whatsapp-slim/whatsapp.css new file mode 100644 index 00000000..db6684e3 --- /dev/null +++ b/default/chromium/extensions/whatsapp-slim/whatsapp.css @@ -0,0 +1,64 @@ +/* Collapse WhatsApp Web's chat list to a Signal-style avatar rail when the + * window is too narrow to show both the full list and the conversation. + * Leans on WhatsApp's stable structural ids (#side, #main, #pane-side) and + * data-testid hooks rather than its obfuscated, frequently-churning class + * names. */ + +@media (max-width: 1100px) { + /* The chat-list column (title header + #side) becomes an avatar rail */ + div:has(> div#side) { + flex: 0 0 90px !important; + min-width: 90px !important; + max-width: 90px !important; + } + + /* Chat-list title bar, search, filter chips, and banner don't fit. + * Scoped to the column wrapper: the left icon nav rail confusingly + * shares the same chatlist-header testid and must survive. */ + div:has(> div#side) > header, + #side > div:first-child, + #side [role="tablist"], + #side span[data-testid="chat-butterbar"] { + display: none !important; + } + + /* The rail doesn't need a visible scrollbar, and horizontal overflow + * from the collapsed rows must not wiggle */ + #pane-side { + overflow-x: hidden !important; + scrollbar-width: none !important; + } + + /* Chat rows: keep the avatar column, collapse the text/preview columns + * without display:none so the unread badge can be resurrected */ + [data-testid="cell-frame-container"] { + position: relative !important; + } + + [data-testid="cell-frame-container"] > div:not(:first-child) { + visibility: hidden !important; + width: 0 !important; + min-width: 0 !important; + overflow: hidden !important; + } + + /* Float the unread badge over the avatar's top-right corner */ + [data-testid="cell-frame-container"] span[aria-label*="unread"] { + visibility: visible !important; + position: absolute !important; + top: 2px !important; + left: 50px !important; + } + + /* The empty drawer overlay keeps the stock chat-list width, which + * strands its divider border in the middle of the conversation */ + [data-testid="drawer-middle"] { + border-left: none !important; + } + + /* Let the app shrink below WhatsApp's default minimum width */ + #app, + #app .two { + min-width: 0 !important; + } +} diff --git a/migrations/1785543725.sh b/migrations/1785543725.sh new file mode 100644 index 00000000..71e1abea --- /dev/null +++ b/migrations/1785543725.sh @@ -0,0 +1,20 @@ +echo "Add WhatsApp Slim extension to Chromium-based browsers" + +WHATSAPP_SLIM_EXT="$OMARCHY_PATH/default/chromium/extensions/whatsapp-slim" + +add_whatsapp_slim_extension() { + local file=$1 + + [[ -f $file ]] || return 0 + grep -q "extensions/whatsapp-slim" "$file" && return 0 + + if grep -q "^--load-extension=" "$file"; then + sed -i --follow-symlinks "s|^--load-extension=\(.*\)$|--load-extension=\1,$WHATSAPP_SLIM_EXT|" "$file" + else + echo "--load-extension=$WHATSAPP_SLIM_EXT" >>"$file" + fi +} + +for conf in chromium chrome google-chrome brave brave-beta brave-nightly brave-origin-beta microsoft-edge-stable; do + add_whatsapp_slim_extension "$HOME/.config/$conf-flags.conf" +done