Merge branch 'v27'

This commit is contained in:
evanpelle
2025-11-21 20:22:40 -08:00
16 changed files with 2274 additions and 493 deletions
+2 -2
View File
@@ -93,7 +93,7 @@ export class GameStartingModal extends LitElement {
}
.copyright {
font-size: 32px;
font-size: 20px;
margin-top: 20px;
margin-bottom: 10px;
opacity: 1;
@@ -118,7 +118,7 @@ export class GameStartingModal extends LitElement {
render() {
return html`
<div class="modal ${this.isVisible ? "visible" : ""}">
<div class="copyright">© OpenFront</div>
<div class="copyright">© OpenFront and Contributors</div>
<a
href="https://github.com/openfrontio/OpenFrontIO/blob/main/CREDITS.md"
target="_blank"
+4
View File
@@ -8,9 +8,11 @@ import bn from "../../resources/lang/bn.json";
import cs from "../../resources/lang/cs.json";
import da from "../../resources/lang/da.json";
import de from "../../resources/lang/de.json";
import el from "../../resources/lang/el.json";
import en from "../../resources/lang/en.json";
import eo from "../../resources/lang/eo.json";
import es from "../../resources/lang/es.json";
import fa from "../../resources/lang/fa.json";
import fi from "../../resources/lang/fi.json";
import fr from "../../resources/lang/fr.json";
import gl from "../../resources/lang/gl.json";
@@ -51,6 +53,7 @@ export class LangSelector extends LitElement {
bg,
bn,
de,
el,
en,
es,
eo,
@@ -71,6 +74,7 @@ export class LangSelector extends LitElement {
cs,
he,
da,
fa,
fi,
"sv-SE": sv_SE,
"zh-CN": zh_CN,
+1 -17
View File
@@ -23,7 +23,7 @@ import { LangSelector } from "./LangSelector";
import { LanguageModal } from "./LanguageModal";
import "./Matchmaking";
import { MatchmakingModal } from "./Matchmaking";
import { NewsModal } from "./NewsModal";
import "./NewsModal";
import "./PublicLobby";
import { PublicLobby } from "./PublicLobby";
import { SinglePlayerModal } from "./SinglePlayerModal";
@@ -39,8 +39,6 @@ import {
incrementGamesPlayed,
isInIframe,
} from "./Utils";
import "./components/NewsButton";
import { NewsButton } from "./components/NewsButton";
import "./components/baseComponents/Button";
import "./components/baseComponents/Modal";
import { getUserMe, isLoggedIn } from "./jwt";
@@ -118,20 +116,6 @@ class Client {
}
gameVersion.innerText = version;
const newsModal = document.querySelector("news-modal") as NewsModal;
if (!newsModal || !(newsModal instanceof NewsModal)) {
console.warn("News modal element not found");
}
const newsButton = document.querySelector("news-button") as NewsButton;
if (!newsButton) {
console.warn("News button element not found");
} else {
console.log("News button element found");
}
// Comment out to show news button.
// newsButton.hidden = true;
const langSelector = document.querySelector(
"lang-selector",
) as LangSelector;
+48
View File
@@ -2,6 +2,8 @@ import { LitElement, css, html } from "lit";
import { resolveMarkdown } from "lit-markdown";
import { customElement, property, query } from "lit/decorators.js";
import changelog from "../../resources/changelog.md";
import megaphone from "../../resources/images/Megaphone.svg";
import version from "../../resources/version.txt";
import { translateText } from "../client/Utils";
import "./components/baseComponents/Button";
import "./components/baseComponents/Modal";
@@ -128,3 +130,49 @@ export class NewsModal extends LitElement {
this.modalEl?.close();
}
}
@customElement("news-button")
export class NewsButton extends LitElement {
@query("news-modal") private newsModal!: NewsModal;
connectedCallback() {
super.connectedCallback();
this.checkForNewVersion();
}
private checkForNewVersion() {
const lastSeenVersion = localStorage.getItem("last-seen-version");
if (lastSeenVersion !== null && lastSeenVersion !== version) {
setTimeout(() => {
this.openNewsModel();
}, 500);
}
}
private openNewsModel() {
localStorage.setItem("last-seen-version", version);
this.newsModal.open();
}
render() {
return html`
<div class="flex relative">
<button
class="border p-[4px] rounded-lg flex cursor-pointer border-black/30 dark:border-gray-300/60 bg-white/70 dark:bg-[rgba(55,65,81,0.7)]"
@click=${this.openNewsModel}
>
<img
class="size-[48px] dark:invert"
src="${megaphone}"
alt=${translateText("news.title")}
/>
</button>
</div>
<news-modal></news-modal>
`;
}
createRenderRoot() {
return this;
}
}
-74
View File
@@ -1,74 +0,0 @@
import { LitElement, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import megaphone from "../../../resources/images/Megaphone.svg";
import version from "../../../resources/version.txt";
import { NewsModal } from "../NewsModal";
import { translateText } from "../Utils";
@customElement("news-button")
export class NewsButton extends LitElement {
@property({ type: Boolean }) hidden = false;
@state() private isActive = false;
connectedCallback() {
super.connectedCallback();
this.checkForNewVersion();
}
private checkForNewVersion() {
try {
const lastSeenVersion = localStorage.getItem("version");
this.isActive = lastSeenVersion !== version;
if (this.isActive) {
setTimeout(() => {
this.openNewsModel();
}, 500);
}
} catch (error) {
// Fallback to NOT showing notification if localStorage fails
this.isActive = false;
}
localStorage.setItem("version", version);
}
private handleClick() {
localStorage.setItem("version", version);
this.isActive = false;
this.openNewsModel();
}
private openNewsModel() {
const newsModal = document.querySelector("news-modal") as NewsModal;
if (newsModal) {
newsModal.open();
} else {
console.log("no newsModal");
}
}
render() {
return html`
<div
class="flex relative ${this.hidden ? "parent-hidden" : ""} ${this
.isActive
? "active"
: ""}"
>
<button
class="border p-[4px] rounded-lg flex cursor-pointer border-black/30 dark:border-gray-300/60 bg-white/70 dark:bg-[rgba(55,65,81,0.7)]"
@click=${this.handleClick}
>
<img
class="size-[48px] dark:invert"
src="${megaphone}"
alt=${translateText("news.title")}
/>
</button>
</div>
`;
}
createRenderRoot() {
return this;
}
}
+22 -21
View File
@@ -317,21 +317,19 @@
</div>
<!-- Footer section -->
<footer class="l-footer">
<div class="l-footer__content">
<div class="l-footer__col t-text-white">
<a
href="https://youtu.be/jvHEvbko3uw?si=znspkP84P76B1w5I"
data-i18n="main.how_to_play"
class="t-link"
target="_blank"
>
How to Play
</a>
<footer
class="flex justify-center px-3 py-3 md:px-6 md:py-3 bg-[var(--boxBackgroundColor)] backdrop-blur-sm"
>
<div
class="flex flex-col md:flex-row flex-nowrap justify-between items-center gap-4 md:gap-0 w-full max-w-[860px] flex-1"
>
<div
class="flex flex-col sm:flex-row gap-4 sm:gap-5 text-white/70 justify-center md:justify-start flex-shrink-0"
>
<a
href="https://openfront.wiki/Main_Page"
data-i18n="main.wiki"
class="t-link"
class="text-white/70 hover:text-white transition-colors duration-300 ease-in-out whitespace-nowrap"
target="_blank"
>
Wiki
@@ -339,25 +337,25 @@
<a
target="_blank"
href="https://www.reddit.com/r/Openfront/"
class="t-link"
class="text-white/70 hover:text-white transition-colors duration-300 ease-in-out whitespace-nowrap"
>
<span data-i18n="main.reddit"> Reddit </span>
</a>
<a
target="_blank"
href="https://discord.gg/jRpxXvG42t"
class="t-link"
class="text-white/70 hover:text-white transition-colors duration-300 ease-in-out whitespace-nowrap"
>
<span data-i18n="main.join_discord"> Join the Discord! </span>
<span data-i18n="main.join_discord"> Discord </span>
</a>
</div>
<div class="l-footer__col t-text-white space-x-4">
<div class="flex justify-center text-white/70 flex-shrink-0">
<a
href="https://github.com/openfrontio/OpenFrontIO"
class="t-link inline-flex items-center space-x-2"
class="text-white/70 hover:text-white transition-colors duration-300 ease-in-out inline-flex items-center gap-2 whitespace-nowrap"
target="_blank"
>
©2025 OpenFront™
© OpenFront™ and Contributors
<img
src="../../resources/icons/github-mark-white.svg"
alt="GitHub"
@@ -366,10 +364,14 @@
class="ml-2"
/>
</a>
</div>
<div
class="flex flex-col sm:flex-row gap-4 sm:gap-4 text-white/70 justify-center md:justify-end flex-shrink-0"
>
<a
href="/privacy-policy.html"
data-i18n="main.privacy_policy"
class="t-link"
class="text-white/70 hover:text-white transition-colors duration-300 ease-in-out whitespace-nowrap"
target="_blank"
>
Privacy Policy
@@ -377,7 +379,7 @@
<a
href="/terms-of-service.html"
data-i18n="main.terms_of_service"
class="t-link"
class="text-white/70 hover:text-white transition-colors duration-300 ease-in-out whitespace-nowrap"
target="_blank"
>
Terms of Service
@@ -410,7 +412,6 @@
<chat-modal></chat-modal>
<user-setting></user-setting>
<multi-tab-modal></multi-tab-modal>
<news-modal></news-modal>
<game-left-sidebar></game-left-sidebar>
<flag-input-modal></flag-input-modal>
<performance-overlay></performance-overlay>
-1
View File
@@ -5,7 +5,6 @@
@import url("./styles/core/variables.css");
@import url("./styles/core/typography.css");
@import url("./styles/layout/header.css");
@import url("./styles/layout/footer.css");
@import url("./styles/layout/container.css");
@import url("./styles/components/button.css");
@import url("./styles/components/modal.css");
-24
View File
@@ -1,24 +0,0 @@
.l-footer {
background: var(--boxBackgroundColor);
backdrop-filter: blur(var(--blur-md));
display: flex;
justify-content: center;
padding: 12px;
@media (min-width: 800px) {
padding: 12px 24px;
}
}
.l-footer__content {
max-width: 860px;
flex-wrap: wrap;
display: flex;
flex: 1;
justify-content: space-between;
}
.l-footer__col {
display: flex;
gap: 20px;
}