Skip to content

Commit 7b5e8f9

Browse files
authored
Merge pull request #674 from IvanSavoskin/feature/support-android-app-theme-params
feat(bridge): Add formatter for int theme params
2 parents 4513f18 + f2ee866 commit 7b5e8f9

File tree

6 files changed

+129
-7
lines changed

6 files changed

+129
-7
lines changed

.changeset/spicy-owls-jam.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@telegram-apps/bridge": minor
3+
"@telegram-apps/transformers": minor
4+
---
5+
6+
Add formatter for int theme params

packages/bridge/src/events/emitter.test.ts

+47
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,53 @@ describe('on', () => {
184184
});
185185
});
186186
});
187+
188+
it('should format theme_params if it was in int', () => {
189+
const listener = vi.fn();
190+
on('theme_changed', listener);
191+
192+
emitEvent('theme_changed', {
193+
theme_params: {
194+
accent_text_color: -10177041,
195+
bg_color: -14602949,
196+
bottom_bar_bg_color: -15393241,
197+
button_color: -11491093,
198+
button_text_color: -1,
199+
destructive_text_color: -1152913,
200+
header_bg_color: -14406343,
201+
hint_color: -8549479,
202+
link_color: -10572831,
203+
secondary_bg_color: -15393241,
204+
section_bg_color: -14866637,
205+
section_header_text_color: -8796932,
206+
section_separator_color: -15920616,
207+
subtitle_text_color: -8681584,
208+
text_color: -1,
209+
},
210+
// We are just testing an invalid Android client behavior here.
211+
} as any);
212+
213+
expect(listener).toHaveBeenCalledTimes(1);
214+
expect(listener).toHaveBeenCalledWith({
215+
theme_params: {
216+
accent_text_color: '#64b5ef',
217+
bg_color: '#212d3b',
218+
bottom_bar_bg_color: '#151e27',
219+
button_color: '#50a8eb',
220+
button_text_color: '#ffffff',
221+
destructive_text_color: '#ee686f',
222+
header_bg_color: '#242d39',
223+
hint_color: '#7d8b99',
224+
link_color: '#5eabe1',
225+
secondary_bg_color: '#151e27',
226+
section_bg_color: '#1d2733',
227+
section_header_text_color: '#79c4fc',
228+
section_separator_color: '#0d1218',
229+
subtitle_text_color: '#7b8790',
230+
text_color: '#ffffff',
231+
},
232+
});
233+
});
187234
});
188235

189236
describe('off', () => {

packages/bridge/src/events/emitter.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
nullish,
1212
type BaseSchema,
1313
} from 'valibot';
14-
import { jsonParse, MiniAppsMessageSchema } from '@telegram-apps/transformers';
14+
import { jsonParse, MiniAppsMessageSchema, themeParams } from '@telegram-apps/transformers';
1515

1616
import { createEmitter } from '@/events/createEmitter.js';
1717
import type { EventName, EventPayload, Events } from '@/events/types/index.js';
@@ -41,6 +41,9 @@ const transformers = {
4141
is_state_stable: boolean(),
4242
is_expanded: boolean(),
4343
}),
44+
theme_changed: looseObject({
45+
theme_params: themeParams(),
46+
}),
4447
} as const satisfies { [E in EventName]?: BaseSchema<unknown, EventPayload<E>, any> };
4548

4649
function listener(event: MessageEvent): void {
@@ -60,6 +63,7 @@ function listener(event: MessageEvent): void {
6063

6164
const { eventType, eventData } = message;
6265
const schema = transformers[eventType as keyof typeof transformers];
66+
6367
try {
6468
const data = schema ? parse(schema, eventData) : eventData;
6569
emit(eventType as any, data);

packages/bridge/src/events/types/events.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ export interface Events {
546546
*/
547547
theme_changed: {
548548
/**
549-
* Map where the key is a theme stylesheet key and value is the
549+
* Map where the key is a theme stylesheet key and value is the
550550
* corresponding color in
551551
* `#RRGGBB` format.
552552
*/

packages/transformers/src/generators/themeParams.test.ts

+53
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,23 @@ describe('themeParams', () => {
2525
})).toBe(true);
2626
expect(is(themeParams(), { accent_text_color: '#aabbc' })).toBe(false);
2727
expect(is(themeParams(), 'aaa')).toBe(false);
28+
expect(is(themeParams(), {
29+
accent_text_color: -10177041,
30+
bg_color: -14602949,
31+
bottom_bar_bg_color: -15393241,
32+
button_color: -11491093,
33+
button_text_color: -1,
34+
destructive_text_color: -1152913,
35+
header_bg_color: -14406343,
36+
hint_color: -8549479,
37+
link_color: -10572831,
38+
secondary_bg_color: -15393241,
39+
section_bg_color: -14866637,
40+
section_header_text_color: -8796932,
41+
section_separator_color: -15920616,
42+
subtitle_text_color: -8681584,
43+
text_color: -1,
44+
})).toBe(true);
2845
});
2946

3047
it('should camelize keys if true passed', () => {
@@ -67,4 +84,40 @@ describe('themeParams', () => {
6784
expect(parse(themeParams(false), input)).not.toStrictEqual(inputCamelized);
6885
expect(parse(themeParams(true), input)).toStrictEqual(inputCamelized);
6986
});
87+
88+
it('should properly handle numeric values', () => {
89+
expect(parse(themeParams(), {
90+
accent_text_color: -10177041,
91+
bg_color: -14602949,
92+
bottom_bar_bg_color: -15393241,
93+
button_color: -11491093,
94+
button_text_color: -1,
95+
destructive_text_color: -1152913,
96+
header_bg_color: -14406343,
97+
hint_color: -8549479,
98+
link_color: -10572831,
99+
secondary_bg_color: -15393241,
100+
section_bg_color: -14866637,
101+
section_header_text_color: -8796932,
102+
section_separator_color: -15920616,
103+
subtitle_text_color: -8681584,
104+
text_color: -1,
105+
})).toStrictEqual({
106+
accent_text_color: '#64b5ef',
107+
bg_color: '#212d3b',
108+
bottom_bar_bg_color: '#151e27',
109+
button_color: '#50a8eb',
110+
button_text_color: '#ffffff',
111+
destructive_text_color: '#ee686f',
112+
header_bg_color: '#242d39',
113+
hint_color: '#7d8b99',
114+
link_color: '#5eabe1',
115+
secondary_bg_color: '#151e27',
116+
section_bg_color: '#1d2733',
117+
section_header_text_color: '#79c4fc',
118+
section_separator_color: '#0d1218',
119+
subtitle_text_color: '#7b8790',
120+
text_color: '#ffffff',
121+
});
122+
});
70123
});

packages/transformers/src/generators/themeParams.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
check,
33
type CheckAction,
4+
number,
5+
type NumberSchema,
46
pipe,
57
record,
68
type RecordSchema,
@@ -9,19 +11,29 @@ import {
911
type StringSchema,
1012
transform,
1113
type TransformAction,
14+
union,
15+
type UnionSchema,
1216
} from 'valibot';
1317
import type { RGB, KnownThemeParamsKey } from '@telegram-apps/types';
1418

15-
import { isRGB } from '@/validation/rgb.js';
1619
import {
1720
type CamelCaseTransformer,
1821
createCamelCaseGen,
1922
} from '@/camel-casing/createCamelCaseGen.js';
23+
import { isRGB } from '@/validation/rgb.js';
2024

2125
export const themeParams = createCamelCaseGen(
2226
record(
2327
string(),
24-
pipe(string(), check(isRGB), transform(i => i as RGB)),
28+
pipe(
29+
union([string(), number()]),
30+
transform(value => {
31+
return typeof value === 'number'
32+
? `#${(value & 0x00FFFFFF).toString(16).padStart(6, '0')}`
33+
: value;
34+
}),
35+
check(isRGB),
36+
),
2537
),
2638
) as CamelCaseTransformer<
2739
RecordSchema<
@@ -30,9 +42,9 @@ export const themeParams = createCamelCaseGen(
3042
TransformAction<string, KnownThemeParamsKey>,
3143
]>,
3244
SchemaWithPipe<[
33-
StringSchema<undefined>,
34-
CheckAction<string, undefined>,
35-
TransformAction<string, RGB>
45+
UnionSchema<[StringSchema<undefined>, NumberSchema<undefined>], any>,
46+
TransformAction<string | number, string>,
47+
CheckAction<RGB, undefined>
3648
]>,
3749
undefined
3850
>

0 commit comments

Comments
 (0)