Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [0.3.1] - 2026-04-01

### Added
- Owner-controlled channel language for bot replies, with Twitch panel fallback to the channel default when a viewer has no linked or local language preference.
- A non-English translation feedback prompt in the website header and account settings.

### Changed
- Twitch panel and public VIP-token help now share localized VIP automation copy and locale-aware amount formatting.
- More support-event and StreamElements bot replies now respect the channel's configured bot language instead of always replying in English.

### Fixed
- Website language changes now apply immediately again instead of briefly reverting or waiting for the background locale save to finish.

## [0.3.0] - 2026-04-01

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ It runs on TanStack Start, Cloudflare Workers, D1, Durable Objects, Queues, KV,

### Platform And Quality

- Internationalization scaffolding for localized website copy
- Internationalization support for localized website and Twitch panel UI, plus owner-controlled bot reply locales with English as the default
- Durable Object playlist serialization, Queue-based reply delivery, and Cloudflare-backed persistence
- Vitest, Playwright, and GitHub Actions verification

Expand Down
2 changes: 2 additions & 0 deletions drizzle/0023_channel_default_locale.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `channel_settings`
ADD `default_locale` text NOT NULL DEFAULT 'en';
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "request-bot",
"private": true,
"type": "module",
"version": "0.3.0",
"version": "0.3.1",
"engines": {
"node": ">=22"
},
Expand Down
3 changes: 3 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,18 @@ body.overlay-mode {
content slightly left when simple selects open.
*/
html body[data-scroll-locked] {
/* biome-ignore lint/complexity/noImportantStyles: react-remove-scroll injects inline compensation styles we need to neutralize. */
margin-right: 0 !important;
--removed-body-scroll-bar-size: 0px;
}

html body[data-scroll-locked] .width-before-scroll-bar {
/* biome-ignore lint/complexity/noImportantStyles: react-remove-scroll injects inline compensation styles we need to neutralize. */
margin-right: 0 !important;
}

html body[data-scroll-locked] .right-scroll-bar-position {
/* biome-ignore lint/complexity/noImportantStyles: react-remove-scroll injects inline compensation styles we need to neutralize. */
right: 0 !important;
}

Expand Down
58 changes: 58 additions & 0 deletions src/components/translation-help-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useAppLocale, useLocaleTranslation } from "~/lib/i18n/client";
import { cn } from "~/lib/utils";
import { Button } from "./ui/button";
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "./ui/popover";

export function TranslationHelpButton(props: {
className?: string;
align?: "start" | "center" | "end";
}) {
const { locale } = useAppLocale();
const { t } = useLocaleTranslation("common");

if (locale === "en") {
return null;
}

return (
<Popover>
<PopoverTrigger asChild>
<Button
type="button"
variant="secondary"
size="sm"
className={cn("shrink-0", props.className)}
>
{t("translationHelp.button")}
</Button>
</PopoverTrigger>
<PopoverContent
align={props.align ?? "end"}
className="w-80 border-(--border) bg-(--panel) p-4 text-(--text)"
>
<PopoverHeader>
<PopoverTitle className="text-(--text)">
{t("translationHelp.title")}
</PopoverTitle>
<PopoverDescription className="text-sm leading-6 text-(--muted)">
{t("translationHelp.messageLead")}{" "}
<a
href="mailto:support@rocklist.live"
className="font-medium text-(--brand-deep) underline underline-offset-4"
>
support@rocklist.live
</a>
.
</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
);
}
Loading
Loading