1
0
Fork 0
mirror of https://git.sr.ht/~ashkeel/strimertul synced 2024-09-18 01:50:50 +00:00

feat: language selector works!

This commit is contained in:
Ash Keel 2022-12-16 14:51:42 +01:00
parent bf8cd57fff
commit 031f6692bf
No known key found for this signature in database
GPG key ID: BAD8D93E7314ED3E
7 changed files with 94 additions and 31 deletions

View file

@ -58,7 +58,6 @@
"apiguide-1": "You will need to create an application, here's how:",
"apiguide-2": "Go to <1>https://dev.twitch.tv/console/apps/create</1>",
"apiguide-3": "Use the following data for the required fields:",
"oauth-redir-uri": "OAuth Redirect URLs",
"apiguide-4": "Once made, create a <1>New Secret</1>, then copy both fields below and save!",
"app-client-id": "App Client ID",
"app-client-secret": "App Client Secret",
@ -94,7 +93,9 @@
"auth-button": "Authenticate with Twitch",
"auth-message": "Click the following button to authenticate {{APPNAME}} with your Twitch account:",
"current-status": "Current status"
}
},
"app-category": "Category",
"app-oauth-redirect-url": "OAuth Redirect URLs"
},
"botcommands": {
"title": "Bot commands",
@ -171,7 +172,7 @@
"enable": "Enable loyalty system",
"currency-placeholder": "points",
"currency-name": "Currency name",
"currency-name-hint": "This will be appended like this: \"user has X yourcurrency\" so choose a lowercase plural name",
"currency-name-hint": "This will be appended like this: \"user has X yourcurrency\" so choose a lowercase plural name (ex. points)",
"bonus-points": "Bonus points for active users",
"bonus-points-hint": "Extra amount of points awarded to people who have been chatting in the last set interval",
"note": "Note: Unlike platform-native systems (eg. Twitch channel points), this relies on chat activity rather than actual viewing status.",
@ -223,12 +224,12 @@
"reward-desc": "Description",
"reward-cost": "Cost",
"reward-id-hint": "This is what viewers will have to write to claim, ie. \"!redeem reward-id-here\".",
"reward-name-hint": "This is what viewers will see they claimed ie. \"USER has claimed REWARDNAME",
"reward-name-hint": "This is what viewers will see they claimed ie. \"USER has claimed REWARDNAME\"",
"reward-cooldown": "Cooldown",
"reward-details-placeholder": "What extra details to ask the viewer for",
"reward-details": "Require viewer details",
"edit-reward": "Edit reward",
"remove-reward-title": "Remore reward \"{{name}}\"?",
"remove-reward-title": "Remove reward \"{{name}}\"?",
"no-rewards": "There are no loyalty rewards, why not start with an Hydrate or Stretch?",
"no-goals": "There are no goals configured",
"create-goal": "Create goal",

View file

@ -10,7 +10,7 @@ import {
TimerIcon,
} from '@radix-ui/react-icons';
import { EventsOff, EventsOn } from '@wailsapp/runtime/runtime';
import { t } from 'i18next';
import { useTranslation } from 'react-i18next';
import React, { useEffect, useState } from 'react';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
@ -172,6 +172,7 @@ export default function App(): JSX.Element {
const dispatch = useAppDispatch();
const location = useLocation();
const navigate = useNavigate();
const [t, i18n] = useTranslation();
const connectToKV = async () => {
const address = await GetKilovoltBind();
@ -217,12 +218,15 @@ export default function App(): JSX.Element {
}
}, [ready, connected]);
const onboardingDone = uiConfig?.onboardingDone;
// Sync UI changes on key change
useEffect(() => {
if (!onboardingDone) {
if (uiConfig?.language) {
void i18n.changeLanguage(uiConfig?.language ?? 'en');
}
if (!uiConfig?.onboardingDone) {
navigate('/setup');
}
}, [ready, onboardingDone]);
}, [ready, uiConfig]);
if (connected === ConnectionStatus.NotConnected) {
return <Loading message={t('special.loading')} />;

View file

@ -86,7 +86,9 @@ function PageList({
</ToolbarComboBox>
</ToolbarSection>
<ToolbarSection>
<div style={{ padding: '0 0.25rem' }}>{t('pagination.page')}</div>
<div style={{ padding: '0 0.25rem' }}>
{t('pagination.page', { page: current })}
</div>
{current > min ? (
<ToolbarButton
className="button pagination-link"

View file

@ -1,31 +1,76 @@
import React, { ReactElement } from 'react';
import { Root, Item, Indicator } from '@radix-ui/react-radio-group';
import {
Root,
Item,
Indicator,
RadioGroupProps as RootProps,
} from '@radix-ui/react-radio-group';
import { styled } from '~/ui/theme';
export interface RadioGroupProps {
label: string;
selected?: string;
values: {
id: string;
label: string | ReactElement;
}[];
default?: string;
}
export default function RadioGroup(props: RadioGroupProps) {
const RadioRoot = styled(Root, {
display: 'flex',
flexDirection: 'column',
gap: '10px',
margin: '0.5rem 0',
'& label': {
cursor: 'pointer',
},
});
const RadioItem = styled(Item, {
backgroundColor: '$gray12',
borderRadius: '100%',
width: '22px',
height: '22px',
cursor: 'pointer',
padding: 0,
margin: 0,
border: '0',
marginRight: '0.5rem',
'&:hover': {
backgroundColor: '$teal12',
},
'&:focus': {
boxShadow: '0 0 0 2px $gray2',
},
});
const RadioIndicator = styled(Indicator, {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
position: 'relative',
'&::after': {
content: '',
display: 'block',
width: '10px',
height: '10px',
borderRadius: '50%',
backgroundColor: '$teal9',
},
});
export default function RadioGroup(props: RadioGroupProps & RootProps) {
return (
<Root
defaultValue={props.default}
value={props.selected}
aria-label={props.label}
>
<RadioRoot {...props}>
{props.values.map(({ id, label }) => (
<div key={id} style={{ display: 'flex', alignItems: 'center' }}>
<Item value="default" id={`r${id}`}>
<Indicator />
</Item>
<RadioItem value={id} id={`r${id}`}>
<RadioIndicator />
</RadioItem>
<label htmlFor={`r${id}`}>{label}</label>
</div>
))}
</Root>
</RadioRoot>
);
}

View file

@ -230,12 +230,12 @@ function TwitchAPISettings() {
<DefinitionTable
entries={{
'OAuth Redirect URLs': `http://${
[t('pages.twitch-settings.app-oauth-redirect-url')]: `http://${
httpConfig?.bind.indexOf(':') > 0
? httpConfig.bind
: `localhost${httpConfig?.bind ?? ':4337'}`
}/twitch/callback`,
Category: 'Broadcasting Suite',
[t('pages.twitch-settings.app-category')]: 'Broadcasting Suite',
}}
/>
</Step>

View file

@ -12,8 +12,13 @@ import {
PageContainer,
PageHeader,
PageTitle,
styled,
} from '../theme';
const PartialWarning = styled('small', {
color: '$yellow11',
});
export default function UISettingsPage(): React.ReactElement {
const [uiConfig, setUiConfig] = useModule(modules.uiConfig);
const [t, i18n] = useTranslation();
@ -32,20 +37,23 @@ export default function UISettingsPage(): React.ReactElement {
<Field size="fullWidth">
<Label htmlFor="bind">{t('pages.uiconfig.language')}</Label>
<RadioGroup
label={t('pages.uiconfig.language')}
default={i18n.resolvedLanguage}
selected={uiConfig?.language ?? i18n.resolvedLanguage}
aria-label={t('pages.uiconfig.language')}
defaultValue={i18n.resolvedLanguage}
value={uiConfig?.language ?? i18n.resolvedLanguage}
onValueChange={(value) => {
void dispatch(setUiConfig({ ...uiConfig, language: value }));
}}
values={languages.map((lang) => ({
id: lang.code,
label: (
<span>
{lang.name}{' '}
{lang.keys < maxKeys ? (
<small>
<PartialWarning>
{t('pages.uiconfig.partial-translation')} (
{((lang.keys / maxKeys) * 100).toFixed(1)}% - {lang.keys}/
{maxKeys})
</small>
</PartialWarning>
) : null}
</span>
),

View file

@ -25,6 +25,9 @@ export const globalStyles = globalCss({
color: '$teal11',
},
},
p: {
lineHeight: 1.5,
},
});
export const { styled, theme } = createStitches({