Skip to content

Commit 84721fb

Browse files
authored
feat: update space skins settings (#497)
* fix: improve skin update code * fix: allow skinParams only for turbo spaces * fix: rename params to skinSettings to follow hub convention * fix: save hex code when saving skin color * refactor: refactor * fix: saved cleaned up domain
1 parent 28e146b commit 84721fb

File tree

4 files changed

+159
-24
lines changed

4 files changed

+159
-24
lines changed

src/helpers/actions.ts

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,81 @@ import snapshot from '@snapshot-labs/snapshot.js';
22
import db from './mysql';
33
import { DEFAULT_NETWORK_ID, jsonParse, NETWORK_ID_WHITELIST } from './utils';
44

5-
export async function addOrUpdateSpace(space: string, settings: any) {
6-
if (!settings?.name) return false;
7-
if (settings.domain) {
8-
settings.domain = settings.domain?.replace(/(^\w+:|^)\/\//, '').replace(/\/$/, '');
5+
function normalizeSettings(settings: any) {
6+
const _settings = snapshot.utils.clone(settings);
7+
8+
if (_settings.domain) {
9+
_settings.domain = _settings.domain?.replace(/(^\w+:|^)\/\//, '').replace(/\/$/, '');
910
}
10-
if (settings.delegationPortal) {
11-
settings.delegationPortal = {
11+
if (_settings.delegationPortal) {
12+
_settings.delegationPortal = {
1213
delegationNetwork: '1',
13-
...settings.delegationPortal
14+
..._settings.delegationPortal
1415
};
1516
}
1617

18+
delete _settings.skinSettings;
19+
20+
return _settings;
21+
}
22+
23+
export async function addOrUpdateSpace(id: string, settings: any) {
24+
if (!settings?.name) return false;
25+
26+
const normalizedSettings = normalizeSettings(settings);
27+
1728
const ts = (Date.now() / 1e3).toFixed();
1829
const query =
1930
'INSERT INTO spaces SET ? ON DUPLICATE KEY UPDATE updated = ?, settings = ?, name = ?, hibernated = 0, domain = ?';
2031

2132
await db.queryAsync(query, [
2233
{
23-
id: space,
34+
id,
2435
name: settings.name,
2536
created: ts,
2637
updated: ts,
27-
settings: JSON.stringify(settings),
28-
domain: settings.domain || null
38+
settings: JSON.stringify(normalizedSettings),
39+
domain: normalizedSettings.domain || null
2940
},
3041
ts,
31-
JSON.stringify(settings),
42+
JSON.stringify(normalizedSettings),
3243
settings.name,
33-
settings.domain || null
44+
normalizedSettings.domain || null
3445
]);
46+
47+
await addOrUpdateSkin(id, settings.skinSettings);
48+
}
49+
50+
export async function addOrUpdateSkin(id: string, skinSettings: Record<string, string>) {
51+
if (!skinSettings) return false;
52+
53+
const COLORS = [
54+
'bg_color',
55+
'link_color',
56+
'text_color',
57+
'content_color',
58+
'border_color',
59+
'heading_color',
60+
'primary_color',
61+
'header_color'
62+
];
63+
64+
await db.queryAsync(
65+
`INSERT INTO skins
66+
SET ?
67+
ON DUPLICATE KEY UPDATE
68+
${COLORS.map(color => `${color} = ?`).join(',')},
69+
theme = COALESCE(VALUES(theme), theme)
70+
`,
71+
[
72+
{
73+
id,
74+
...skinSettings
75+
},
76+
...COLORS.map(color => skinSettings[color]),
77+
skinSettings.theme
78+
]
79+
);
3580
}
3681

3782
export async function getProposal(space, id) {

src/writer/settings.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ export async function verify(body): Promise<any> {
8989
const isAdmin = admins.includes(body.address.toLowerCase());
9090
const newAdmins = (msg.payload.admins || []).map(admin => admin.toLowerCase());
9191

92-
if (msg.payload.domain && !space?.turbo && !space?.domain) {
93-
return Promise.reject('domain is a turbo feature only');
92+
if (!space?.turbo && !space?.domain) {
93+
if (msg.payload.domain) return Promise.reject('domain is a turbo feature only');
94+
if (msg.payload.skinSettings) return Promise.reject('skin is a turbo feature only');
9495
}
9596

9697
const anotherSpaceWithDomain = (

test/integration/helpers/actions.test.ts

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { addOrUpdateSpace, getSpace, sxSpaceExists } from '../../../src/helpers/actions';
1+
import {
2+
addOrUpdateSkin,
3+
addOrUpdateSpace,
4+
getSpace,
5+
sxSpaceExists
6+
} from '../../../src/helpers/actions';
27
import db, { sequencerDB } from '../../../src/helpers/mysql';
38
import { DEFAULT_NETWORK_ID } from '../../../src/helpers/utils';
49
import { spacesSqlFixtures } from '../../fixtures/space';
@@ -166,4 +171,88 @@ describe('helpers/actions', () => {
166171
});
167172
});
168173
});
174+
175+
describe('addOrUpdateSkin', () => {
176+
afterAll(async () => {
177+
await db.queryAsync('DELETE FROM snapshot_sequencer_test.skins');
178+
});
179+
180+
it('adds a new skin when it does not exist', async () => {
181+
const testId = 'test-new-skin-ids';
182+
const skinSettings = {
183+
bg_color: '#000000',
184+
link_color: '#ffffff',
185+
text_color: '#000000',
186+
content_color: '#ffffff',
187+
border_color: '#ffffff',
188+
heading_color: '#ffffff',
189+
primary_color: '#ffffff'
190+
};
191+
await addOrUpdateSkin(testId, skinSettings);
192+
const skin = (await db.queryAsync('SELECT * FROM skins WHERE id = ?', [testId]))[0];
193+
expect(skin).toEqual({
194+
id: testId,
195+
bg_color: '#000000',
196+
link_color: '#ffffff',
197+
text_color: '#000000',
198+
content_color: '#ffffff',
199+
border_color: '#ffffff',
200+
heading_color: '#ffffff',
201+
primary_color: '#ffffff',
202+
header_color: null,
203+
theme: 'light'
204+
});
205+
});
206+
207+
it('updates an existing skin', async () => {
208+
const testId = 'test-update-skin-id';
209+
await db.queryAsync(
210+
'INSERT INTO skins (id, bg_color, link_color, text_color, content_color, border_color, heading_color, primary_color, header_color, theme) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
211+
[
212+
testId,
213+
'#000000',
214+
'#000000',
215+
'#000000',
216+
'#000000',
217+
'#000000',
218+
'#000000',
219+
'#000000',
220+
'#000000',
221+
'light'
222+
]
223+
);
224+
await addOrUpdateSkin(testId, {
225+
bg_color: '#FFFF00',
226+
link_color: '#FFFFFF'
227+
});
228+
const skin = (await db.queryAsync('SELECT * FROM skins WHERE id = ?', [testId]))[0];
229+
expect(skin).toEqual({
230+
id: testId,
231+
bg_color: '#FFFF00',
232+
link_color: '#FFFFFF',
233+
text_color: null,
234+
content_color: null,
235+
border_color: null,
236+
heading_color: null,
237+
primary_color: null,
238+
header_color: null,
239+
theme: 'light'
240+
});
241+
242+
await addOrUpdateSkin(testId, { theme: 'dark' });
243+
const skin2 = (await db.queryAsync('SELECT * FROM skins WHERE id = ?', [testId]))[0];
244+
expect(skin2).toEqual({
245+
id: testId,
246+
bg_color: null,
247+
link_color: null,
248+
text_color: null,
249+
content_color: null,
250+
border_color: null,
251+
heading_color: null,
252+
primary_color: null,
253+
header_color: null,
254+
theme: 'dark'
255+
});
256+
});
257+
});
169258
});

test/schema.sql

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,18 @@ CREATE TABLE leaderboard (
195195

196196
CREATE TABLE skins (
197197
id VARCHAR(100) NOT NULL,
198-
bg_color VARCHAR(6) DEFAULT NULL,
199-
link_color VARCHAR(6) DEFAULT NULL,
200-
text_color VARCHAR(6) DEFAULT NULL,
201-
content_color VARCHAR(6) DEFAULT NULL,
202-
border_color VARCHAR(6) DEFAULT NULL,
203-
heading_color VARCHAR(6) DEFAULT NULL,
204-
primary_color VARCHAR(6) DEFAULT NULL,
205-
header_color VARCHAR(6) DEFAULT NULL,
198+
bg_color VARCHAR(7) DEFAULT NULL,
199+
link_color VARCHAR(7) DEFAULT NULL,
200+
text_color VARCHAR(7) DEFAULT NULL,
201+
content_color VARCHAR(7) DEFAULT NULL,
202+
border_color VARCHAR(7) DEFAULT NULL,
203+
heading_color VARCHAR(7) DEFAULT NULL,
204+
primary_color VARCHAR(7) DEFAULT NULL,
205+
header_color VARCHAR(7) DEFAULT NULL,
206206
theme VARCHAR(5) NOT NULL DEFAULT 'light',
207207
PRIMARY KEY (id)
208208
);
209-
209+
210210
CREATE TABLE options (
211211
name VARCHAR(100) NOT NULL,
212212
value VARCHAR(100) NOT NULL,

0 commit comments

Comments
 (0)