mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 08:20:50 +00:00
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:
@@ -1068,7 +1068,9 @@
|
||||
"tournament": "TOURNAMENT",
|
||||
"tutorial": "TUTORIAL",
|
||||
"news": "NEWS",
|
||||
"warning": "WARNING",
|
||||
"dismiss": "Dismiss",
|
||||
"go_to_item": "Go to item {num}"
|
||||
"go_to_item": "Go to item {num}",
|
||||
"firefox_warning": "OpenFront.io doesn't perform well with [Firefox-based browsers](https://simple.wikipedia.org/wiki/Web_browsers_based_on_Firefox). We recommend you to use a [Chromium-based browser](https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium) for best performance."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
[
|
||||
{
|
||||
"id": "firefox-performance-issues-2026",
|
||||
"title": "Firefox Performance Issues",
|
||||
"descriptionTranslationKey": "news_box.firefox_warning",
|
||||
"url": null,
|
||||
"type": "warning"
|
||||
},
|
||||
{
|
||||
"id": "clan-tournament-spring-2026",
|
||||
"title": "Upcoming: Spring Clan Tournament",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()),
|
||||
});
|
||||
|
||||
@@ -26,6 +26,7 @@ const DYNAMIC_KEY_PATTERNS: RegExp[] = [
|
||||
/^territory_patterns\.color_palette\.[^.]+$/,
|
||||
/^build_menu\.desc\.[^.]+$/,
|
||||
/^unit_type\.[^.]+$/,
|
||||
/^news_box\.(tournament|tutorial|news|warning|firefox_warning)$/,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,10 +67,14 @@ describe("NewsBox", () => {
|
||||
expect(typeof item.id).toBe("string");
|
||||
expect(item.title).toBeDefined();
|
||||
expect(typeof item.title).toBe("string");
|
||||
expect(item.description).toBeDefined();
|
||||
expect(typeof item.description).toBe("string");
|
||||
const hasDescription =
|
||||
item.description !== undefined ||
|
||||
item.descriptionTranslationKey !== undefined;
|
||||
expect(hasDescription).toBe(true);
|
||||
expect(item.type).toBeDefined();
|
||||
expect(["tournament", "tutorial", "announcement"]).toContain(item.type);
|
||||
expect(["tournament", "tutorial", "announcement", "warning"]).toContain(
|
||||
item.type,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user