Skip to content

Commit

Permalink
Apply frontend changes for updated logo config
Browse files Browse the repository at this point in the history
This will now change the logo based on current language,
if applicable logos exist.
  • Loading branch information
owi92 committed Dec 10, 2024
1 parent c4c06f9 commit 38ca261
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 55 deletions.
14 changes: 5 additions & 9 deletions frontend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type Config = {
opencast: OpencastConfig;
footerLinks: FooterLink[];
metadataLabels: Record<string, Record<string, MetadataLabel>>;
logo: LogoConfig;
logos: LogoConfig;
plyr: PlyrConfig;
upload: UploadConfig;
paellaPluginConfig: object;
Expand Down Expand Up @@ -63,16 +63,12 @@ type AuthConfig = {
};

type LogoConfig = {
large: SingleLogoConfig;
small: SingleLogoConfig | null;
largeDark: SingleLogoConfig | null;
smallDark: SingleLogoConfig | null;
};

type SingleLogoConfig = {
size: "wide" | "narrow" | "*";
mode: "light" | "dark" | "*";
lang: string;
path: string;
resolution: number[];
};
}[];

type PlyrConfig = {
blankVideo: string;
Expand Down
73 changes: 28 additions & 45 deletions frontend/src/layout/header/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { useTranslation } from "react-i18next";
import { screenWidthAbove, screenWidthAtMost, useColorScheme } from "@opencast/appkit";
import { screenWidthAbove, screenWidthAtMost } from "@opencast/appkit";

import CONFIG from "../../config";
import { BREAKPOINT_SMALL } from "../../GlobalStyle";
import { Link } from "../../router";
import { focusStyle } from "../../ui";
import { translatedConfig } from "../../util";
import { translatedConfig, useLogoConfig } from "../../util";
import { HEADER_BASE_PADDING } from "./ui";
import { COLORS } from "../../color";


export const Logo: React.FC = () => {
const { t, i18n } = useTranslation();
const isDark = useColorScheme().scheme === "dark";
const logos = useLogoConfig();
const alt = t("general.logo-alt", { title: translatedConfig(CONFIG.siteTitle, i18n) });

// This is a bit tricky: we want to specify the `width` and `height`
// attributes on the `img` elements in order to avoid layout shift. That
Expand All @@ -32,24 +33,6 @@ export const Logo: React.FC = () => {
// The solution is to calculate the correct `flex-basis` for the `<a>`
// element manually.

const large = CONFIG.logo.large;
const small = CONFIG.logo.small ?? CONFIG.logo.large;
const largeDark = CONFIG.logo.largeDark ?? CONFIG.logo.large;
const smallDark = CONFIG.logo.smallDark
?? CONFIG.logo.largeDark
?? CONFIG.logo.small
?? CONFIG.logo.large;

// If the dark logos are not specified, we default to the white ones but
// inverting them.
const invertLargeDark = CONFIG.logo.largeDark === null;
const invertSmallDark = CONFIG.logo.smallDark === null && CONFIG.logo.largeDark === null;

const alt = t("general.logo-alt", { title: translatedConfig(CONFIG.siteTitle, i18n) });
const invertCss = {
filter: "invert(100%) hue-rotate(180deg)",
};

return (
<Link to="/" css={{
height: `calc(100% + ${HEADER_BASE_PADDING * 2}px)`,
Expand All @@ -65,30 +48,30 @@ export const Logo: React.FC = () => {
maxWidth: "100%",
},
}}>
<img
width={(isDark ? largeDark : large).resolution[0]}
height={(isDark ? largeDark : large).resolution[1]}
src={(isDark ? largeDark : large).path}
alt={alt}
css={{
...isDark && invertLargeDark && invertCss,
[screenWidthAtMost(BREAKPOINT_SMALL)]: {
display: "none",
},
}}
/>
<img
width={(isDark ? smallDark : small).resolution[0]}
height={(isDark ? smallDark : small).resolution[1]}
src={(isDark ? smallDark : small).path}
alt={alt}
css={{
...isDark && invertSmallDark && invertCss,
[screenWidthAbove(BREAKPOINT_SMALL)]: {
display: "none",
},
}}
/>
{logos.narrow && logos.wide && <>
<img
width={logos.wide.resolution[0]}
height={logos.wide.resolution[1]}
src={logos.wide.path}
alt={alt}
css={{
[screenWidthAtMost(BREAKPOINT_SMALL)]: {
display: "none",
},
}}
/>
<img
width={logos.narrow.resolution[0]}
height={logos.narrow.resolution[1]}
src={logos.narrow.path}
alt={alt}
css={{
[screenWidthAbove(BREAKPOINT_SMALL)]: {
display: "none",
},
}}
/>
</>}
</Link>
);
};
36 changes: 35 additions & 1 deletion frontend/src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { i18n } from "i18next";
import { MutableRefObject, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { bug, match } from "@opencast/appkit";
import { bug, match, useColorScheme } from "@opencast/appkit";

import CONFIG, { TranslatedString } from "../config";
import { TimeUnit } from "../ui/Input";
Expand Down Expand Up @@ -260,3 +260,37 @@ export const getCredentials = (kind: IdKind, id: string): Credentials => {

export const credentialsStorageKey = (kind: IdKind, id: string) =>
CREDENTIALS_STORAGE_KEY + kind + "-" + id;

export const useLogoConfig = () => {
const { i18n } = useTranslation();
const mode = useColorScheme().scheme;
const lang = i18n.resolvedLanguage;
const logos = CONFIG.logos;

const patterns = [
[lang, mode],
[lang, "*"],
["*", mode],
["*", "*"],
];

const findLogo = (size: "wide" | "narrow") => {
for (const [lang, mode] of patterns) {
let match = logos.find(l => l.size === size && l.mode === mode && l.lang === lang);
if (match) {
return { path: match.path, resolution: match.resolution };
}

match = logos.find(l => l.size === "*" && l.mode === mode && l.lang === lang);
if (match) {
return { path: match.path, resolution: match.resolution };
}
}
return null;
};

return {
wide: findLogo("wide"),
narrow: findLogo("narrow"),
};
};

0 comments on commit 38ca261

Please sign in to comment.