mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-07 19:55:46 -05:00
@@ -0,0 +1,62 @@
|
||||
.banner {
|
||||
/* needed for firefox to have a valid output */
|
||||
--l: 50%;
|
||||
|
||||
position: relative;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
var(--color-bg),
|
||||
var(--l),
|
||||
var(--color-bg-higher)
|
||||
);
|
||||
border: var(--border-style-high);
|
||||
border-radius: var(--radius-box);
|
||||
padding: var(--s-4);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bannerContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--s-2);
|
||||
padding-inline-end: min(130px, 30%);
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.bannerTitle {
|
||||
font-size: var(--font-lg);
|
||||
font-weight: var(--weight-bold);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.homeScreenIcon {
|
||||
position: absolute;
|
||||
right: var(--s-6);
|
||||
top: 50%;
|
||||
translate: 0 -50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--s-1);
|
||||
}
|
||||
|
||||
.homeScreenIconImg {
|
||||
width: 56px;
|
||||
border-radius: 22.5%;
|
||||
box-shadow: 0 2px 6px rgb(0 0 0 / 25%);
|
||||
}
|
||||
|
||||
.homeScreenIconLabel {
|
||||
font-size: var(--font-2xs);
|
||||
font-weight: var(--weight-semi);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.instructionsList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--s-2);
|
||||
margin: 0;
|
||||
padding-inline-start: var(--s-6);
|
||||
}
|
||||
188
app/features/front-page/components/PWAInstallBanner.tsx
Normal file
188
app/features/front-page/components/PWAInstallBanner.tsx
Normal file
@@ -0,0 +1,188 @@
|
||||
import { Download } from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SendouButton } from "~/components/elements/Button";
|
||||
import { SendouDialog } from "~/components/elements/Dialog";
|
||||
import styles from "./PWAInstallBanner.module.css";
|
||||
|
||||
interface BeforeInstallPromptEvent extends Event {
|
||||
prompt: () => Promise<{ outcome: "accepted" | "dismissed" }>;
|
||||
}
|
||||
|
||||
type InstallState = "hidden" | "native" | "ios" | "safari";
|
||||
|
||||
const SAFARI_MIN_INSTALL_VERSION = 17;
|
||||
const BANNER_DISMISSED_KEY = "pwa-install-banner-dismissed";
|
||||
|
||||
let deferredInstallPrompt: BeforeInstallPromptEvent | null = null;
|
||||
let bannerDismissed = false;
|
||||
const installStateListeners = new Set<() => void>();
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
try {
|
||||
bannerDismissed = localStorage.getItem(BANNER_DISMISSED_KEY) === "true";
|
||||
} catch {
|
||||
// localStorage may be unavailable
|
||||
}
|
||||
|
||||
window.addEventListener("beforeinstallprompt", (event) => {
|
||||
event.preventDefault();
|
||||
deferredInstallPrompt = event as BeforeInstallPromptEvent;
|
||||
notifyInstallStateChanged();
|
||||
});
|
||||
window.addEventListener("appinstalled", () => {
|
||||
deferredInstallPrompt = null;
|
||||
notifyInstallStateChanged();
|
||||
});
|
||||
}
|
||||
|
||||
export function PWAInstallBanner() {
|
||||
const { t } = useTranslation(["front", "common"]);
|
||||
const installState = useInstallState();
|
||||
|
||||
if (installState === "hidden") return null;
|
||||
|
||||
return (
|
||||
<div className={styles.banner}>
|
||||
<div className={styles.bannerContent}>
|
||||
<h2 className={styles.bannerTitle}>
|
||||
{t("front:install.banner.title")}
|
||||
</h2>
|
||||
<p className="text-xs text-lighter">
|
||||
{t("front:install.banner.description")}
|
||||
</p>
|
||||
<div className="stack horizontal md items-center mt-4">
|
||||
<InstallAction installState={installState} />
|
||||
<SendouButton
|
||||
variant="minimal-destructive"
|
||||
size="small"
|
||||
onPress={dismissBanner}
|
||||
>
|
||||
{t("common:actions.dismiss")}
|
||||
</SendouButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.homeScreenIcon}>
|
||||
<img
|
||||
src="/static-assets/img/app-icon.png"
|
||||
alt=""
|
||||
className={styles.homeScreenIconImg}
|
||||
draggable="false"
|
||||
/>
|
||||
<span className={styles.homeScreenIconLabel}>sendou.ink</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function InstallAction({
|
||||
installState,
|
||||
}: {
|
||||
installState: Exclude<InstallState, "hidden">;
|
||||
}) {
|
||||
const { t } = useTranslation(["front"]);
|
||||
|
||||
const installButton = (
|
||||
<SendouButton
|
||||
size="small"
|
||||
icon={<Download />}
|
||||
onPress={
|
||||
installState === "native"
|
||||
? () => deferredInstallPrompt?.prompt()
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{t("front:install.button")}
|
||||
</SendouButton>
|
||||
);
|
||||
|
||||
if (installState === "native") {
|
||||
return installButton;
|
||||
}
|
||||
|
||||
return (
|
||||
<SendouDialog
|
||||
heading={t("front:install.header")}
|
||||
trigger={installButton}
|
||||
isDismissable
|
||||
showCloseButton
|
||||
>
|
||||
<ol className={styles.instructionsList}>
|
||||
<li>{t(`front:install.${installState}.step1`)}</li>
|
||||
<li>{t(`front:install.${installState}.step2`)}</li>
|
||||
<li>{t(`front:install.${installState}.step3`)}</li>
|
||||
</ol>
|
||||
</SendouDialog>
|
||||
);
|
||||
}
|
||||
|
||||
function useInstallState() {
|
||||
return React.useSyncExternalStore(
|
||||
subscribeToInstallState,
|
||||
getInstallStateSnapshot,
|
||||
getServerInstallStateSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
function subscribeToInstallState(callback: () => void) {
|
||||
installStateListeners.add(callback);
|
||||
return () => installStateListeners.delete(callback);
|
||||
}
|
||||
|
||||
function dismissBanner() {
|
||||
bannerDismissed = true;
|
||||
try {
|
||||
localStorage.setItem(BANNER_DISMISSED_KEY, "true");
|
||||
} catch {
|
||||
// localStorage may be unavailable
|
||||
}
|
||||
notifyInstallStateChanged();
|
||||
}
|
||||
|
||||
function getInstallStateSnapshot(): InstallState {
|
||||
if (bannerDismissed) return "hidden";
|
||||
if (isStandalone()) return "hidden";
|
||||
if (deferredInstallPrompt) return "native";
|
||||
if (isIos()) return "ios";
|
||||
if (isInstallCapableSafariDesktop()) return "safari";
|
||||
return "hidden";
|
||||
}
|
||||
|
||||
function getServerInstallStateSnapshot(): InstallState {
|
||||
return "hidden";
|
||||
}
|
||||
|
||||
function notifyInstallStateChanged() {
|
||||
for (const listener of installStateListeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
|
||||
function isStandalone() {
|
||||
return (
|
||||
window.matchMedia("(display-mode: standalone)").matches ||
|
||||
window.matchMedia("(display-mode: tabbed)").matches ||
|
||||
(navigator as { standalone?: boolean }).standalone === true
|
||||
);
|
||||
}
|
||||
|
||||
function isIos() {
|
||||
return (
|
||||
/iPad|iPhone|iPod/.test(navigator.userAgent) ||
|
||||
(navigator.userAgent.includes("Mac") && navigator.maxTouchPoints > 1)
|
||||
);
|
||||
}
|
||||
|
||||
function isInstallCapableSafariDesktop() {
|
||||
const userAgent = navigator.userAgent;
|
||||
const isSafari =
|
||||
userAgent.includes("Safari") &&
|
||||
!userAgent.includes("Chrome") &&
|
||||
!userAgent.includes("Chromium");
|
||||
if (!isSafari || !userAgent.includes("Mac")) return false;
|
||||
|
||||
const versionMatch = userAgent.match(/Version\/(\d+)/);
|
||||
if (!versionMatch) return false;
|
||||
|
||||
return Number(versionMatch[1]) >= SAFARI_MIN_INSTALL_VERSION;
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import { LocaleTimeRange } from "~/components/LocaleTimeRange";
|
||||
import { navItems } from "~/components/layout/nav-items";
|
||||
import { Main } from "~/components/Main";
|
||||
import { TournamentCard } from "~/features/calendar/components/TournamentCard";
|
||||
import { PWAInstallBanner } from "~/features/front-page/components/PWAInstallBanner";
|
||||
import { SplatoonRotations } from "~/features/front-page/components/SplatoonRotations";
|
||||
import type * as Changelog from "~/features/front-page/core/Changelog.server";
|
||||
import * as Seasons from "~/features/mmr/core/Seasons";
|
||||
@@ -309,6 +310,7 @@ function DiscoverFeatures() {
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
<PWAInstallBanner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Skab",
|
||||
"actions.close": "Luk",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Annuller",
|
||||
"actions.loading": "Indlæser...",
|
||||
"actions.clear": "Ryd",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "Discord-Zeitstempel kopieren",
|
||||
"actions.create": "Erstellen",
|
||||
"actions.close": "Schließen",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Abbrechen",
|
||||
"actions.loading": "Lädt...",
|
||||
"actions.clear": "Leeren",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "Copy Discord timestamp",
|
||||
"actions.create": "Create",
|
||||
"actions.close": "Close",
|
||||
"actions.dismiss": "Dismiss",
|
||||
"actions.cancel": "Cancel",
|
||||
"actions.loading": "Loading...",
|
||||
"actions.clear": "Clear",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "Next",
|
||||
"rotations.credit": "Data from splatoon3.ink",
|
||||
"rotations.filter.all": "All",
|
||||
"discover.header": "Discover all the features"
|
||||
"discover.header": "Discover all the features",
|
||||
"install.button": "Install app",
|
||||
"install.header": "Install sendou.ink",
|
||||
"install.banner.title": "Get the sendou.ink app",
|
||||
"install.banner.description": "Add sendou.ink to your home screen for quick access",
|
||||
"install.ios.step1": "Tap the share button in your browser",
|
||||
"install.ios.step2": "Select \"Add to Home Screen\"",
|
||||
"install.ios.step3": "Tap \"Add\"",
|
||||
"install.safari.step1": "Click the share button in Safari's toolbar",
|
||||
"install.safari.step2": "Select \"Add to Dock\"",
|
||||
"install.safari.step3": "Click \"Add\""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "Copiar timestamp para Discord",
|
||||
"actions.create": "Crear",
|
||||
"actions.close": "Cerrar",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Cancelar",
|
||||
"actions.loading": "Cargando...",
|
||||
"actions.clear": "Limpiar",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Crear",
|
||||
"actions.close": "Cerrar",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Cancelar",
|
||||
"actions.loading": "Cargando...",
|
||||
"actions.clear": "Aclarar",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Créer",
|
||||
"actions.close": "Fermer",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Annuler",
|
||||
"actions.loading": "Chargement...",
|
||||
"actions.clear": "Effacer",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Créer",
|
||||
"actions.close": "Fermer",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Annuler le match",
|
||||
"actions.loading": "Chargement...",
|
||||
"actions.clear": "Effacer",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "יצירה",
|
||||
"actions.close": "סגירה",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "ביטול",
|
||||
"actions.loading": "טוען...",
|
||||
"actions.clear": "ניקוי",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Crea",
|
||||
"actions.close": "Chiudi",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Cancella",
|
||||
"actions.loading": "Caricamento in corso...",
|
||||
"actions.clear": "Svuota",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "作成",
|
||||
"actions.close": "閉じる",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "キャンセル",
|
||||
"actions.loading": "Loading...",
|
||||
"actions.clear": "クリア",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "생성",
|
||||
"actions.close": "닫기",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "취소",
|
||||
"actions.loading": "로딩 중...",
|
||||
"actions.clear": "비우기",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "",
|
||||
"actions.close": "",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "",
|
||||
"actions.loading": "",
|
||||
"actions.clear": "",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Stwórz",
|
||||
"actions.close": "Zamknij",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Anuluj",
|
||||
"actions.loading": "Ładowanie...",
|
||||
"actions.clear": "Wyczyść",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Criar",
|
||||
"actions.close": "Fechar",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Cancelar",
|
||||
"actions.loading": "Carregando...",
|
||||
"actions.clear": "Limpar",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "Создать",
|
||||
"actions.close": "Закрыть",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "Отменить",
|
||||
"actions.loading": "Загрузка...",
|
||||
"actions.clear": "Очистить",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"actions.copyTimestampForDiscord": "",
|
||||
"actions.create": "创建",
|
||||
"actions.close": "关闭",
|
||||
"actions.dismiss": "",
|
||||
"actions.cancel": "取消",
|
||||
"actions.loading": "加载中...",
|
||||
"actions.clear": "清除",
|
||||
|
||||
@@ -40,5 +40,15 @@
|
||||
"rotations.nextLabel": "",
|
||||
"rotations.credit": "",
|
||||
"rotations.filter.all": "",
|
||||
"discover.header": ""
|
||||
"discover.header": "",
|
||||
"install.button": "",
|
||||
"install.header": "",
|
||||
"install.banner.title": "",
|
||||
"install.banner.description": "",
|
||||
"install.ios.step1": "",
|
||||
"install.ios.step2": "",
|
||||
"install.ios.step3": "",
|
||||
"install.safari.step1": "",
|
||||
"install.safari.step2": "",
|
||||
"install.safari.step3": ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user