diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index 2871e2aae5..bc3bdc82fd 100644 Binary files a/app/soapbox/actions/soapbox.js and b/app/soapbox/actions/soapbox.js differ diff --git a/app/soapbox/features/crypto_donate/components/site_wallet.tsx b/app/soapbox/features/crypto_donate/components/site_wallet.tsx index af59647967..f0b6accd7d 100644 --- a/app/soapbox/features/crypto_donate/components/site_wallet.tsx +++ b/app/soapbox/features/crypto_donate/components/site_wallet.tsx @@ -24,7 +24,7 @@ interface ISiteWallet { const SiteWallet: React.FC = ({ limit }): JSX.Element => { const addresses: ImmutableList
= - useSoapboxConfig().get('cryptoAddresses').map(normalizeAddress); + useSoapboxConfig().cryptoAddresses.map(normalizeAddress); const coinList = typeof limit === 'number' ? addresses.take(limit) : addresses; diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index 84d80eea35..16cff42f3c 100644 Binary files a/app/soapbox/features/soapbox_config/index.js and b/app/soapbox/features/soapbox_config/index.js differ diff --git a/app/soapbox/hooks/useSoapboxConfig.ts b/app/soapbox/hooks/useSoapboxConfig.ts index 2e51e59233..92a1ddc212 100644 --- a/app/soapbox/hooks/useSoapboxConfig.ts +++ b/app/soapbox/hooks/useSoapboxConfig.ts @@ -1,9 +1,9 @@ import { getSoapboxConfig } from 'soapbox/actions/soapbox'; import { useAppSelector } from 'soapbox/hooks'; -import type { Map as ImmutableMap } from 'immutable'; +import type { SoapboxConfig } from 'soapbox/types/soapbox'; /** Get the Soapbox config from the store */ -export const useSoapboxConfig = (): ImmutableMap => { +export const useSoapboxConfig = (): SoapboxConfig => { return useAppSelector((state) => getSoapboxConfig(state)); }; diff --git a/app/soapbox/normalizers/index.ts b/app/soapbox/normalizers/index.ts index c4a34d66c2..613de53313 100644 --- a/app/soapbox/normalizers/index.ts +++ b/app/soapbox/normalizers/index.ts @@ -7,3 +7,5 @@ export { MentionRecord, normalizeMention } from './mention'; export { NotificationRecord, normalizeNotification } from './notification'; export { PollRecord, PollOptionRecord, normalizePoll } from './poll'; export { StatusRecord, normalizeStatus } from './status'; + +export { SoapboxConfigRecord, normalizeSoapboxConfig } from './soapbox/soapbox_config'; diff --git a/app/soapbox/normalizers/soapbox/__tests__/soapbox_config-test.js b/app/soapbox/normalizers/soapbox/__tests__/soapbox_config-test.js new file mode 100644 index 0000000000..f564fd17dd Binary files /dev/null and b/app/soapbox/normalizers/soapbox/__tests__/soapbox_config-test.js differ diff --git a/app/soapbox/normalizers/soapbox/soapbox_config.ts b/app/soapbox/normalizers/soapbox/soapbox_config.ts new file mode 100644 index 0000000000..0696eb314c --- /dev/null +++ b/app/soapbox/normalizers/soapbox/soapbox_config.ts @@ -0,0 +1,103 @@ +import { + Map as ImmutableMap, + List as ImmutableList, + Record as ImmutableRecord, + fromJS, +} from 'immutable'; + +const DEFAULT_COLORS = ImmutableMap({ + gray: ImmutableMap({ + 50: '#f9fafb', + 100: '#f3f4f6', + 200: '#e5e7eb', + 300: '#d1d5db', + 400: '#9ca3af', + 500: '#6b7280', + 600: '#4b5563', + 700: '#374151', + 800: '#1f2937', + 900: '#111827', + }), + success: ImmutableMap({ + 50: '#f0fdf4', + 100: '#dcfce7', + 200: '#bbf7d0', + 300: '#86efac', + 400: '#4ade80', + 500: '#22c55e', + 600: '#16a34a', + 700: '#15803d', + 800: '#166534', + 900: '#14532d', + }), + danger: ImmutableMap({ + 50: '#fef2f2', + 100: '#fee2e2', + 200: '#fecaca', + 300: '#fca5a5', + 400: '#f87171', + 500: '#ef4444', + 600: '#dc2626', + 700: '#b91c1c', + 800: '#991b1b', + 900: '#7f1d1d', + }), + 'gradient-purple': '#b8a3f9', + 'gradient-blue': '#9bd5ff', + 'sea-blue': '#2feecc', +}); + +export const SoapboxConfigRecord = ImmutableRecord({ + logo: '', + banner: '', + brandColor: '', // Empty + accentColor: '', + colors: ImmutableMap(), + copyright: `♥${new Date().getFullYear()}. Copying is an act of love. Please copy and share.`, + customCss: ImmutableList(), + defaultSettings: ImmutableMap(), + extensions: ImmutableMap(), + greentext: false, + promoPanel: ImmutableMap({ + items: ImmutableList(), + }), + navlinks: ImmutableMap({ + homeFooter: ImmutableList(), + }), + allowedEmoji: ImmutableList([ + '👍', + '❤️', + '😆', + '😮', + '😢', + '😩', + ]), + verifiedIcon: '', + verifiedCanEditName: false, + displayFqn: true, + cryptoAddresses: ImmutableList>(), + cryptoDonatePanel: ImmutableMap({ + limit: 1, + }), + aboutPages: ImmutableMap(), + betaPages: ImmutableMap(), + mobilePages: ImmutableMap(), + authenticatedProfile: true, + singleUserMode: false, + singleUserModeProfile: '', +}, 'SoapboxConfig'); + +type SoapboxConfigMap = ImmutableMap; + +const normalizeColors = (soapboxConfig: SoapboxConfigMap): SoapboxConfigMap => { + const colors = DEFAULT_COLORS.mergeDeep(soapboxConfig.get('colors')); + return soapboxConfig.set('colors', colors); +}; + +export const normalizeSoapboxConfig = (soapboxConfig: Record) => { + return SoapboxConfigRecord( + ImmutableMap(fromJS(soapboxConfig)).withMutations(soapboxConfig => { + normalizeColors(soapboxConfig); + }), + ); +}; diff --git a/app/soapbox/types/soapbox.ts b/app/soapbox/types/soapbox.ts new file mode 100644 index 0000000000..865a6567c9 --- /dev/null +++ b/app/soapbox/types/soapbox.ts @@ -0,0 +1,5 @@ +import { SoapboxConfigRecord } from 'soapbox/normalizers'; + +type SoapboxConfig = ReturnType; + +export { SoapboxConfig };