Skip to content

Brand Refresh#3130

Closed
michalkopanski wants to merge 6 commits into
superset-sh:mainfrom
michalkopanski:brand-refresh
Closed

Brand Refresh#3130
michalkopanski wants to merge 6 commits into
superset-sh:mainfrom
michalkopanski:brand-refresh

Conversation

@michalkopanski
Copy link
Copy Markdown
Contributor

@michalkopanski michalkopanski commented Apr 3, 2026

image

Summary

  • Refreshed all desktop app icons (icon.png/icns/ico, icon-canary, icon-dev) with updated logo treatment
  • Updated macOS tray icon (iconTemplate.png) with new design
  • Added custom DMG installer background (background.tiff) for macOS
  • Added per-build dock icon resolution: dev → icon-dev.png, canary → icon-canary.png, stable → icon.png
  • Updated marketing site wordmark (title.svg) and favicon-192.png with new logo design
  • Updated in-app empty state wordmark (superset-empty-state-wordmark.svg) with new logo and dimensions

Design Updates

image image

How It Works

Build-type detection uses semver prerelease tags — dev builds pick icon-dev, canary picks icon-canary, stable falls back to icon.png. The dock icon setter was simplified to set the image as-is (removed workspace-name border overlay and image processing).

Test plan

  • Dev build shows icon-dev.png in the dock
  • Canary build shows icon-canary.png in the dock
  • Stable build shows icon.png in the dock
  • DMG installer displays the custom background
  • Tray icon renders correctly in the macOS menu bar
  • Marketing site shows updated logo in browser tab (favicon + title.svg)
  • App empty state shows updated wordmark

Testing

  • bun run typecheck
  • bun run lint
  • Manual: validated icon assets render at expected sizes

Summary by CodeRabbit

  • New Features
    • Added a custom background image for the macOS installer.
    • Enhanced the macOS dock icon display with build-type-specific icon variants for development and canary builds.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

Adds conditional DMG background image support to Electron Builder and replaces workspace-name-based dock icon bitmap customization with build-type-based icon selection (dev/canary/fallback), removing OKLCH/color-hash and per-pixel border drawing.

Changes

Cohort / File(s) Summary
Electron Builder Configuration
apps/desktop/electron-builder.ts
Adds dmgBackgroundPath and a conditional dmg block that sets background to build/installer/background.tiff if the file exists.
Dock Icon Selection
apps/desktop/src/main/lib/dock-icon.ts
Removes workspace-name hashing, OKLCH parsing, bitmap analysis, and per-pixel border drawing. Adds canary detection via semver.prerelease(app.getVersion()); resolves and sets icon-dev.png or icon-canary.png (falling back to icon.png) and logs the chosen path; macOS-only gating retained.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibble code and tap my paw,

DMG skies appear—no flaw.
Icons pick their canary hat,
Borders gone, just simple chat.
Hoppity, tidy—let’s ship that! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Brand Refresh' is vague and generic, using a broad term that doesn't convey the specific technical changes (icon updates, dock icon resolution, DMG background) that form the core of the changeset. Consider a more specific title such as 'Add per-build macOS dock icons and update brand assets' to better reflect the primary technical changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request includes a comprehensive description with summary, design updates with images, implementation details, and a complete test plan covering all major changes.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 3, 2026

Greptile Summary

This PR introduces a brand refresh for the Superset desktop app, replacing the previous runtime pixel-manipulation approach (workspace-coloured borders drawn on the base icon) with pre-designed, per-build-type PNG assets (icon-dev.png, icon-canary.png, icon.png) and a custom DMG installer background.

Key changes:

  • dock-icon.ts is dramatically simplified — ~180 lines of custom color-space conversion, SDF border rendering, and bitmap manipulation are removed in favour of a straightforward path-resolution strategy that selects the right PNG based on NODE_ENV and semver.prerelease().
  • electron-builder.ts gains a dmg.background field, guarded with existsSync to match the existing pattern for other platform icons.
  • New binary assets: icon-dev.{png,icns,ico}, icon-canary.{png,icns,ico}, updated stable icon.*, and background.tiff.
  • Note: isCanaryBuild() returns true for any semver prerelease tag, not only "canary" — this is broader than the JSDoc implies and could misclassify future alpha/beta/rc builds.
  • The exported function setWorkspaceDockIcon retains its old workspace-centric name even though workspace logic was fully removed.

Confidence Score: 4/5

  • Safe to merge; the two remaining issues are non-blocking P2s that don't affect the primary happy-path behaviour.
  • The implementation is a significant net simplification and the core logic (existsSync-guarded path resolution, semver.prerelease for canary detection, existing nativeImage.isEmpty() guard) is sound. The isCanaryBuild broadness is a latent bug for future channels but poses no risk today, and the stale function name is cosmetic.
  • apps/desktop/src/main/lib/dock-icon.ts — isCanaryBuild predicate and stale exported function name.

Important Files Changed

Filename Overview
apps/desktop/src/main/lib/dock-icon.ts Major simplification: removes complex pixel-level border rendering in favour of per-build-type PNG resolution; two minor issues — isCanaryBuild is broader than documented, and the exported function name is stale.
apps/desktop/electron-builder.ts Adds conditional DMG background via existsSync guard, consistent with the existing pattern used for mac, linux, and win icon paths.
apps/desktop/src/resources/build/icons/icon-canary.png New canary dock icon PNG asset; no code concerns.
apps/desktop/src/resources/build/icons/icon-dev.png New dev dock icon PNG asset; no code concerns.
apps/desktop/src/resources/build/installer/background.tiff New DMG installer background image; referenced conditionally in electron-builder.ts.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A([setWorkspaceDockIcon called]) --> B{platform === darwin?}
    B -- No --> Z([no-op])
    B -- Yes --> C[getIconPath]
    C --> D[getIconsDir]
    D --> E{app.isPackaged?}
    E -- Yes --> F[process.resourcesPath/app.asar/resources/build/icons]
    E -- No --> G{NODE_ENV === development?}
    G -- Yes --> H[app.getAppPath/src/resources/build/icons]
    G -- No --> I[__dirname/../resources/build/icons]
    F & H & I --> J{NODE_ENV === development?}
    J -- Yes --> K{existsSync icon-dev.png?}
    K -- Yes --> L[return icon-dev.png]
    K -- No --> M[return icon.png]
    J -- No --> N{isCanaryBuild?}
    N -- Yes --> O{existsSync icon-canary.png?}
    O -- Yes --> P[return icon-canary.png]
    O -- No --> M
    N -- No --> M
    L & P & M --> Q[nativeImage.createFromPath]
    Q --> R{icon.isEmpty?}
    R -- Yes --> S([warn and return])
    R -- No --> T[app.dock.setIcon]
Loading

Reviews (1): Last reviewed commit: "feat(desktop): custom DMG installer back..." | Re-trigger Greptile

Comment on lines +10 to 13
function isCanaryBuild(): boolean {
const components = prerelease(app.getVersion());
return components !== null && components.length > 0;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 isCanaryBuild matches all prerelease channels

semver.prerelease() returns a truthy array for any prerelease tag (e.g. alpha, beta, rc, not just canary). If the project ever ships an alpha or rc build using a version string like 0.0.53-beta.1, this function will return true and the canary dock icon will be shown for those builds too.

A tighter check that matches the intent documented in the JSDoc:

Suggested change
function isCanaryBuild(): boolean {
const components = prerelease(app.getVersion());
return components !== null && components.length > 0;
}
function isCanaryBuild(): boolean {
const components = prerelease(app.getVersion());
return components !== null && components.some((c) => String(c).toLowerCase() === "canary");
}

* Sets the macOS dock icon based on the current build type and macOS version.
* No-op on non-macOS platforms.
*/
export function setWorkspaceDockIcon(): void {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Stale exported function name

The function was previously responsible for setting a workspace-coloured border on the dock icon, but that concept has been fully removed. The new behaviour is simply "set the appropriate dock icon for this build type." The exported name setWorkspaceDockIcon will confuse future callers (and any documentation) — consider renaming it to setDockIcon or setBuildTypeDockIcon.

Suggested change
export function setWorkspaceDockIcon(): void {
export function setDockIcon(): void {

Copy link
Copy Markdown
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/desktop/src/main/lib/dock-icon.ts`:
- Around line 15-26: getIconsDir currently falls back to a path built from
__dirname which fails in non-packaged, non-development runs because build/icons
isn’t copied into dist; update getIconsDir to use app.getAppPath() for the
fallback (instead of join(__dirname, "../resources/build/icons")) so the path
resolves the same in preview/dev/packaged modes (reference function getIconsDir,
app.isPackaged, env.NODE_ENV, and __dirname), or alternatively ensure
copyResourcesPlugin copies src/resources/build/icons into dist so the existing
__dirname-based fallback remains valid.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d38f6353-d126-44f2-8834-805659ab670d

📥 Commits

Reviewing files that changed from the base of the PR and between fffa8db and ad8a027.

⛔ Files ignored due to path filters (7)
  • apps/desktop/src/resources/build/icons/icon-canary.ico is excluded by !**/*.ico
  • apps/desktop/src/resources/build/icons/icon-canary.png is excluded by !**/*.png
  • apps/desktop/src/resources/build/icons/icon-dev.ico is excluded by !**/*.ico
  • apps/desktop/src/resources/build/icons/icon-dev.png is excluded by !**/*.png
  • apps/desktop/src/resources/build/icons/icon.ico is excluded by !**/*.ico
  • apps/desktop/src/resources/build/icons/icon.png is excluded by !**/*.png
  • apps/desktop/src/resources/build/installer/background.tiff is excluded by !**/*.tiff
📒 Files selected for processing (5)
  • apps/desktop/electron-builder.ts
  • apps/desktop/src/main/lib/dock-icon.ts
  • apps/desktop/src/resources/build/icons/icon-canary.icns
  • apps/desktop/src/resources/build/icons/icon-dev.icns
  • apps/desktop/src/resources/build/icons/icon.icns

Comment on lines 15 to 26
/**
* Gets the path to the app icon PNG.
* Returns the icons directory path.
*/
function getIconPath(): string {
function getIconsDir(): string {
if (app.isPackaged) {
return join(
process.resourcesPath,
"app.asar/resources/build/icons/icon.png",
);
return join(process.resourcesPath, "app.asar/resources/build/icons");
}

if (env.NODE_ENV === "development") {
return join(app.getAppPath(), "src/resources/build/icons/icon.png");
return join(app.getAppPath(), "src/resources/build/icons");
}

return join(__dirname, "../resources/build/icons/icon.png");
return join(__dirname, "../resources/build/icons");
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify the directory structure to ensure the fallback path is valid.
# Expected: The dist folder should have a structure where resources/build/icons
# is accessible via ../resources/build/icons from the lib folder.

# Check the typical dist structure for Electron main process files
fd -t f "dock-icon" --extension ts --extension js -x dirname {} \;

# Check if resources structure exists in expected locations
tree -L 4 -d apps/desktop/src/resources 2>/dev/null || echo "src/resources not found"
tree -L 4 -d apps/desktop/dist/resources 2>/dev/null || echo "dist/resources not found (may not be built)"

Repository: superset-sh/superset

Length of output: 336


🏁 Script executed:

#!/bin/bash
# Check build configuration files in apps/desktop
find apps/desktop -maxdepth 2 -type f \( -name "package.json" -o -name "tsconfig*.json" -o -name "vite.config.*" -o -name "webpack.config.*" -o -name "*.config.js" \)

Repository: superset-sh/superset

Length of output: 116


🏁 Script executed:

#!/bin/bash
# Check the package.json build scripts
cat apps/desktop/package.json | head -50

Repository: superset-sh/superset

Length of output: 2336


🏁 Script executed:

#!/bin/bash
# Check tsconfig.json for output directory
cat apps/desktop/tsconfig.json

Repository: superset-sh/superset

Length of output: 471


🏁 Script executed:

#!/bin/bash
# Check electron-vite configuration
find apps/desktop -name "electron.vite.config.*" -o -name "vite.config.*" | head -5

Repository: superset-sh/superset

Length of output: 100


🏁 Script executed:

#!/bin/bash
# Look at electron-vite config if it exists
cat apps/desktop/electron.vite.config.ts 2>/dev/null | head -100

Repository: superset-sh/superset

Length of output: 3434


🏁 Script executed:

#!/bin/bash
# Check if there's a script that copies resources to dist
grep -r "resources" apps/desktop/scripts --include="*.ts" --include="*.js" 2>/dev/null | head -20

Repository: superset-sh/superset

Length of output: 173


🏁 Script executed:

#!/bin/bash
# Check the vite helpers to see what copyResourcesPlugin does
cat apps/desktop/vite/helpers.ts 2>/dev/null || cat apps/desktop/vite/helpers.js 2>/dev/null || find apps/desktop/vite -name "*.ts" -o -name "*.js" | xargs ls -la

Repository: superset-sh/superset

Length of output: 2607


🏁 Script executed:

#!/bin/bash
# Also check what the resources variable is used for
cat apps/desktop/vite/helpers/copyResourcesPlugin.ts 2>/dev/null || find apps/desktop -name "*copyResources*"

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

#!/bin/bash
# Verify that build/icons is indeed not in the copy list by checking the entire flow
cat apps/desktop/vite/helpers.ts | grep -A 50 "RESOURCES_TO_COPY"

Repository: superset-sh/superset

Length of output: 1943


🏁 Script executed:

#!/bin/bash
# Check if there's any other mechanism that copies build/ or icons
grep -r "build/icons" apps/desktop --include="*.ts" --include="*.js" --exclude-dir=node_modules | head -20

Repository: superset-sh/superset

Length of output: 1012


🏁 Script executed:

#!/bin/bash
# Check the electron-builder config to see if icons are handled separately
find apps/desktop -name "electron-builder*" -type f | head -5

Repository: superset-sh/superset

Length of output: 136


🏁 Script executed:

#!/bin/bash
# Check the electron-builder config to see how resources are handled
cat apps/desktop/electron-builder.ts 2>/dev/null | head -150

Repository: superset-sh/superset

Length of output: 4622


🏁 Script executed:

#!/bin/bash
# Check specifically how pkg.resources is used
cat apps/desktop/electron-builder.ts | grep -B 5 -A 5 "pkg.resources"

Repository: superset-sh/superset

Length of output: 1474


The fallback path will fail in non-packaged, non-development scenarios.

The third condition (line 25) is triggered when the app is not packaged and not in development mode—such as when running the built output in preview mode. In this case, __dirname resolves to dist/main/lib, and the path ../resources/build/icons becomes dist/resources/build/icons.

However, the build configuration only copies specific resources to dist via copyResourcesPlugin (sounds, tray, browser-extension, migrations, host-migrations, templates), not the build/icons directory. The icons directory only exists in src/resources and is copied to the package by electron-builder during the final packaging step. This means the fallback path will fail when trying to access icons.

Consider using app.getAppPath() for the fallback, which should work consistently across packaging modes, or add build/icons to the resources copied in copyResourcesPlugin.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/main/lib/dock-icon.ts` around lines 15 - 26, getIconsDir
currently falls back to a path built from __dirname which fails in non-packaged,
non-development runs because build/icons isn’t copied into dist; update
getIconsDir to use app.getAppPath() for the fallback (instead of join(__dirname,
"../resources/build/icons")) so the path resolves the same in
preview/dev/packaged modes (reference function getIconsDir, app.isPackaged,
env.NODE_ENV, and __dirname), or alternatively ensure copyResourcesPlugin copies
src/resources/build/icons into dist so the existing __dirname-based fallback
remains valid.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 12 files

…ution

Replaces the workspace-name-colored border overlay with explicit icon
files per build type. Resolution order: icon-dev.png → icon.png (dev),
icon-canary.png → icon.png (canary), icon.png (stable).
Adds support for a custom background.tiff in the DMG installer window.
Falls back to electron-builder's default if the file is absent.
Copy link
Copy Markdown
Contributor

@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.

♻️ Duplicate comments (1)
apps/desktop/src/main/lib/dock-icon.ts (1)

18-25: ⚠️ Potential issue | 🟠 Major

Preview-mode fallback won't find the dock icons.

Line 25 resolves non-packaged, non-development runs relative to __dirname. In preview/non-packaged production runs that path points at the built main output, but src/resources/build/icons is not copied there, so nativeImage.createFromPath() gets a missing file and the branded dock icon never loads. Please either make this branch resolve from a path that exists in preview too, or copy build/icons into the preview resource set.

Expected result: the fallback branch points at resources/build/icons, but the preview/dist resource-copy config does not include build/icons.

#!/bin/bash
set -euo pipefail

echo "[dock-icon fallback branch]"
sed -n '18,26p' apps/desktop/src/main/lib/dock-icon.ts

echo
echo "[desktop build-resource wiring]"
rg -n -C3 'RESOURCES_TO_COPY|copyResourcesPlugin|build/icons|src/resources' apps/desktop --glob '*.ts' --glob 'package.json'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/main/lib/dock-icon.ts` around lines 18 - 25, The fallback
branch in getIconsDir currently returns a path based on __dirname which doesn't
contain src/resources in preview runs; update the final return to point at the
runtime resources folder instead (e.g. return join(process.resourcesPath,
"resources/build/icons")) so nativeImage.createFromPath can find icons in
preview/non-dev runs; modify getIconsDir (and keep existing
app.isPackaged/app.getAppPath branches) to use process.resourcesPath for the
non-packaged non-development fallback.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@apps/desktop/src/main/lib/dock-icon.ts`:
- Around line 18-25: The fallback branch in getIconsDir currently returns a path
based on __dirname which doesn't contain src/resources in preview runs; update
the final return to point at the runtime resources folder instead (e.g. return
join(process.resourcesPath, "resources/build/icons")) so
nativeImage.createFromPath can find icons in preview/non-dev runs; modify
getIconsDir (and keep existing app.isPackaged/app.getAppPath branches) to use
process.resourcesPath for the non-packaged non-development fallback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c7fcd31f-f9fe-4b75-bc4e-20525db09444

📥 Commits

Reviewing files that changed from the base of the PR and between ad8a027 and c4fc5e5.

⛔ Files ignored due to path filters (11)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/assets/superset-empty-state-wordmark.svg is excluded by !**/*.svg
  • apps/desktop/src/resources/build/icons/icon-canary.ico is excluded by !**/*.ico
  • apps/desktop/src/resources/build/icons/icon-canary.png is excluded by !**/*.png
  • apps/desktop/src/resources/build/icons/icon-dev.ico is excluded by !**/*.ico
  • apps/desktop/src/resources/build/icons/icon-dev.png is excluded by !**/*.png
  • apps/desktop/src/resources/build/icons/icon.ico is excluded by !**/*.ico
  • apps/desktop/src/resources/build/icons/icon.png is excluded by !**/*.png
  • apps/desktop/src/resources/build/installer/background.tiff is excluded by !**/*.tiff
  • apps/desktop/src/resources/tray/iconTemplate.png is excluded by !**/*.png
  • apps/marketing/public/favicon-192.png is excluded by !**/*.png
  • apps/marketing/public/title.svg is excluded by !**/*.svg
📒 Files selected for processing (5)
  • apps/desktop/electron-builder.ts
  • apps/desktop/src/main/lib/dock-icon.ts
  • apps/desktop/src/resources/build/icons/icon-canary.icns
  • apps/desktop/src/resources/build/icons/icon-dev.icns
  • apps/desktop/src/resources/build/icons/icon.icns

@Kitenite
Copy link
Copy Markdown
Collaborator

Closing in favor of #3367 — couldn't push to this branch, reopened the work there.

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.

2 participants