Skip to content

Commit aba56f0

Browse files
authored
chore: light dark mode for banners (podman-desktop#8343)
1 parent 72c1f79 commit aba56f0

File tree

6 files changed

+90
-36
lines changed

6 files changed

+90
-36
lines changed

packages/main/src/plugin/recommendations/recommendations-api.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export interface ExtensionBanner {
2626
thumbnail: string;
2727
publishDate?: string;
2828
background?: {
29-
image?: string;
29+
// Light and dark colors for the backgrounds in base64. Ex: "data:image/png;base64,<data-here>"
30+
light?: string;
31+
dark?: string;
3032
gradient?: {
3133
start: string;
3234
end: string;

packages/renderer/src/lib/recommendation/ExtensionBanner.spec.ts

+28-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
***********************************************************************/
1818

1919
import { render, screen } from '@testing-library/svelte';
20+
import { tick } from 'svelte';
2021
import { beforeEach, describe, expect, test, vi } from 'vitest';
2122

2223
import ExtensionBanner from '/@/lib/recommendation/ExtensionBanner.svelte';
@@ -54,7 +55,8 @@ const gradientBackground: IExtensionBanner = {
5455
const imageBackground: IExtensionBanner = {
5556
...baseBanner,
5657
background: {
57-
image: 'data:image/png;base64-image',
58+
light: 'data:image/png;base64-image-light',
59+
dark: 'data:image/png;base64-image-dark',
5860
},
5961
};
6062

@@ -65,6 +67,7 @@ beforeEach(() => {
6567
test('banner icon should be visible', () => {
6668
render(ExtensionBanner, {
6769
banner: baseBanner,
70+
isDark: true,
6871
});
6972

7073
const img = screen.getByAltText('banner icon');
@@ -75,6 +78,7 @@ test('banner icon should be visible', () => {
7578
test('thumbnail should be visible', () => {
7679
render(ExtensionBanner, {
7780
banner: baseBanner,
81+
isDark: true,
7882
});
7983

8084
const img = screen.getByAltText('banner thumbnail');
@@ -86,6 +90,7 @@ describe('backgrounds', () => {
8690
test('expect default gradient background', () => {
8791
render(ExtensionBanner, {
8892
banner: baseBanner,
93+
isDark: true,
8994
});
9095

9196
const card = screen.getByLabelText('Recommended extension');
@@ -97,20 +102,40 @@ describe('backgrounds', () => {
97102
test('expect linear gradient background', () => {
98103
render(ExtensionBanner, {
99104
banner: gradientBackground,
105+
isDark: true,
100106
});
107+
tick();
101108

102109
const card = screen.getByLabelText('Recommended extension');
103110
expect(card).toBeDefined();
104111
expect(card.attributes.getNamedItem('style')?.value).toBe('background: linear-gradient(#fff, #000);');
105112
});
106113

107-
test('expect image background', () => {
114+
test('expect image background for dark theme', () => {
108115
render(ExtensionBanner, {
109116
banner: imageBackground,
117+
isDark: true,
110118
});
119+
tick();
111120

112121
const card = screen.getByLabelText('Recommended extension');
113122
expect(card).toBeDefined();
114-
expect(card.attributes.getNamedItem('style')?.value).toBe('background-image: url("data:image/png;base64-image");');
123+
expect(card.attributes.getNamedItem('style')?.value).toBe(
124+
'background-image: url("data:image/png;base64-image-dark");',
125+
);
126+
});
127+
128+
test('expect image background for light theme', () => {
129+
render(ExtensionBanner, {
130+
banner: imageBackground,
131+
isDark: false,
132+
});
133+
tick();
134+
135+
const card = screen.getByLabelText('Recommended extension');
136+
expect(card).toBeDefined();
137+
expect(card.attributes.getNamedItem('style')?.value).toBe(
138+
'background-image: url("data:image/png;base64-image-light");',
139+
);
115140
});
116141
});

packages/renderer/src/lib/recommendation/ExtensionBanner.svelte

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@ import FeaturedExtension from '/@/lib/featured/FeaturedExtension.svelte';
66
import type { ExtensionBanner } from '../../../../main/src/plugin/recommendations/recommendations-api';
77
88
export let banner: ExtensionBanner;
9+
// Pass in the theme appearance colour of PD to the banner, we do it here so we don't have to do multiple isDarkMode() checks when rendering multiple banners.
10+
export let isDark: boolean;
911
1012
let style: string | undefined = undefined;
11-
let hasBackground: boolean = !!banner.background && (!!banner.background.image || !!banner.background.gradient);
13+
let hasBackground: boolean =
14+
!!banner.background && ((!!banner.background.dark && !!banner.background.light) || !!banner.background.gradient);
1215
1316
onMount(() => {
1417
if (banner.background?.gradient) {
1518
style = `background: linear-gradient(${banner.background.gradient.start}, ${banner.background.gradient.end});`;
16-
} else if (banner.background?.image) {
17-
style = `background-image: url("${banner.background.image}");`;
19+
} else if (isDark && banner.background?.dark) {
20+
style = `background-image: url("${banner.background.dark}");`;
21+
} else if (!isDark && banner.background?.light) {
22+
style = `background-image: url("${banner.background.light}");`;
1823
} else {
1924
style = undefined;
2025
}

packages/renderer/src/lib/recommendation/ExtensionBanners.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ import type { ExtensionBanner } from '../../../../main/src/plugin/recommendation
2828

2929
const getExtensionBannersMock = vi.fn();
3030

31+
// mock window.getConfigurationValue
32+
const getConfigurationValueMock = vi.fn();
33+
3134
// fake the window.events object
3235
beforeEach(() => {
36+
vi.resetAllMocks();
37+
(window as any).getConfigurationValue = getConfigurationValueMock;
3338
(window as any).getExtensionBanners = getExtensionBannersMock;
3439
(window.events as unknown) = {
3540
receive: (_channel: string, func: any) => {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
<script lang="ts">
2+
import { onMount } from 'svelte';
3+
24
import ExtensionBanner from '/@/lib/recommendation/ExtensionBanner.svelte';
35
import { extensionBannerInfos } from '/@/stores/extensionBanners';
6+
7+
import { AppearanceUtil } from '../appearance/appearance-util';
8+
9+
let isDark: boolean;
10+
11+
onMount(async () => {
12+
// Retrieve the current theme appearance colour of PD for the banners we will be showing
13+
const appearanceUtil = new AppearanceUtil();
14+
isDark = await appearanceUtil.isDarkMode();
15+
});
416
</script>
517

618
{#each $extensionBannerInfos as banner (banner.extensionId)}
7-
<ExtensionBanner banner={banner} />
19+
<ExtensionBanner banner={banner} isDark={isDark} />
820
{/each}

0 commit comments

Comments
 (0)