feat: add warning news type and Firefox performance notice (#3680)

## Description:
Adds a new `warning` news type to the news banner system and uses it to
display a Firefox performance notice.

Changes:
- Added `warning` type with red styling to `NewsBox.ts`
- Added `news_box.warning` key (`"WARNING"`) to `en.json`
- Added Firefox performance notice to `resources/news.json` using the
new `warning` type
- Added `news_box.*` dynamic key pattern to `TranslationSystem.test.ts`
to fix unused key detection

## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## UI change:
<img width="2101" height="1770" alt="CleanShot 2026-04-16 at 15 04
35@2x"
src="https://github.com/user-attachments/assets/7a8b9290-4216-4799-b271-606afd9b8723"
/>



## Please put your Discord username so you can be contacted if a bug or
regression is found:
fghjk_60845
This commit is contained in:
Ivan Batsulin
2026-04-16 16:53:38 -07:00
committed by GitHub
parent 1ebac8e854
commit 76f8441b45
6 changed files with 36 additions and 11 deletions
+16 -6
View File
@@ -1,4 +1,5 @@
import { LitElement, html, nothing } from "lit";
import { resolveMarkdown } from "lit-markdown";
import { customElement, state } from "lit/decorators.js";
import type { NewsItem } from "../../core/ApiSchemas";
import { getNews } from "../Api";
@@ -24,16 +25,18 @@ export function getVisibleNewsItems(items: NewsItem[]): NewsItem[] {
return items.filter((item) => !dismissed.has(item.id));
}
const typeLabelKeys: Record<NewsItem["type"], string> = {
const typeLabelKeys: Record<string, string> = {
tournament: "news_box.tournament",
tutorial: "news_box.tutorial",
announcement: "news_box.news",
warning: "news_box.warning",
};
const typeLabelColors: Record<NewsItem["type"], string> = {
const typeLabelColors: Record<string, string> = {
tournament: "bg-amber-500/20 text-amber-300",
tutorial: "bg-sky-500/20 text-sky-300",
announcement: "bg-emerald-500/20 text-emerald-300",
warning: "bg-red-500/20 text-red-300",
};
@customElement("news-box")
@@ -118,8 +121,10 @@ export class NewsBox extends LitElement {
<span
class="shrink-0 text-[10px] font-bold tracking-wider px-2 py-0.5 rounded ${typeLabelColors[
item.type
]}"
>${translateText(typeLabelKeys[item.type])}</span
] ?? typeLabelColors["announcement"]}"
>${translateText(
typeLabelKeys[item.type] ?? typeLabelKeys["announcement"],
)}</span
>
<div class="flex-1 min-w-0">
${item.url
@@ -133,8 +138,13 @@ export class NewsBox extends LitElement {
: html`<span class="text-sm font-medium text-white truncate block"
>${item.title}</span
>`}
<span class="text-xs text-white/50 truncate block"
>${item.description}</span
<span
class="text-xs text-white/50 block [&_a]:text-blue-300 [&_a:hover]:text-blue-200"
>${resolveMarkdown(
item.descriptionTranslationKey
? translateText(item.descriptionTranslationKey)
: (item.description ?? ""),
)}</span
>
</div>
${this.items.length > 1
+2 -1
View File
@@ -201,7 +201,8 @@ export type RankedLeaderboardResponse = z.infer<
export const NewsItemSchema = z.object({
id: z.string(),
title: z.string(),
description: z.string(),
description: z.string().optional(),
descriptionTranslationKey: z.string().optional(),
url: z.string().nullable().optional(),
type: z.enum(["tournament", "tutorial", "announcement"]).or(z.string()),
});