mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Install poppins as a font
This commit is contained in:
parent
a501c8e571
commit
1e182e0d75
@ -26,7 +26,15 @@ import { QueryClientProvider } from "@tanstack/react-query";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Stack } from "expo-router";
|
import { Stack } from "expo-router";
|
||||||
import { getLocales } from "expo-localization";
|
import { getLocales } from "expo-localization";
|
||||||
import { useState } from "react";
|
import * as SplashScreen from "expo-splash-screen";
|
||||||
|
import {
|
||||||
|
useFonts,
|
||||||
|
Poppins_300Light,
|
||||||
|
Poppins_400Regular,
|
||||||
|
Poppins_900Black,
|
||||||
|
} from "@expo-google-fonts/poppins";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { useColorScheme } from "react-native";
|
||||||
import { initReactI18next, useTranslation } from "react-i18next";
|
import { initReactI18next, useTranslation } from "react-i18next";
|
||||||
import { useTheme } from "yoshiki/native";
|
import { useTheme } from "yoshiki/native";
|
||||||
import "intl-pluralrules";
|
import "intl-pluralrules";
|
||||||
@ -47,34 +55,50 @@ i18next.use(initReactI18next).init({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const ThemedStack = () => {
|
const ThemedStack = ({ onLayout }: { onLayout?: () => void }) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerTitle: () => <NavbarTitle />,
|
headerTitle: () => <NavbarTitle onLayout={onLayout} />,
|
||||||
headerRight: () => <NavbarRight />,
|
headerRight: () => <NavbarRight />,
|
||||||
headerStyle: {
|
headerStyle: {
|
||||||
backgroundColor: theme.appbar,
|
backgroundColor: theme.appbar,
|
||||||
},
|
},
|
||||||
headerTintColor: theme.colors.white,
|
headerTintColor: theme.colors.white,
|
||||||
headerTitleStyle: {
|
|
||||||
fontWeight: "bold",
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SplashScreen.preventAutoHideAsync();
|
||||||
|
|
||||||
export default function Root() {
|
export default function Root() {
|
||||||
const [queryClient] = useState(() => createQueryClient());
|
const [queryClient] = useState(() => createQueryClient());
|
||||||
|
const theme = useColorScheme();
|
||||||
|
const [fontsLoaded] = useFonts({ Poppins_300Light, Poppins_400Regular, Poppins_900Black });
|
||||||
|
|
||||||
|
const onLayout = useCallback(async () => {
|
||||||
|
if (fontsLoaded) {
|
||||||
|
await SplashScreen.hideAsync();
|
||||||
|
}
|
||||||
|
}, [fontsLoaded]);
|
||||||
|
|
||||||
|
if (!fontsLoaded) return null;
|
||||||
return (
|
return (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<ThemeSelector>
|
<ThemeSelector
|
||||||
|
theme={theme ?? "light"}
|
||||||
|
font={{
|
||||||
|
normal: "Poppins_400Regular",
|
||||||
|
"300": "Poppins_300Light",
|
||||||
|
"400": "Poppins_400Regular",
|
||||||
|
"900": "Poppins_900Black",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<PortalProvider>
|
<PortalProvider>
|
||||||
<ThemedStack />
|
<ThemedStack onLayout={onLayout} />
|
||||||
</PortalProvider>
|
</PortalProvider>
|
||||||
</ThemeSelector>
|
</ThemeSelector>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"build:dev": "eas build --profile development --platform android"
|
"build:dev": "eas build --profile development --platform android"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@expo-google-fonts/poppins": "^0.2.2",
|
||||||
"@gorhom/portal": "^1.0.14",
|
"@gorhom/portal": "^1.0.14",
|
||||||
"@kyoo/ui": "workspace:^",
|
"@kyoo/ui": "workspace:^",
|
||||||
"@material-symbols/svg-400": "^0.4.2",
|
"@material-symbols/svg-400": "^0.4.2",
|
||||||
@ -21,6 +22,7 @@
|
|||||||
"expo-build-properties": "~0.4.1",
|
"expo-build-properties": "~0.4.1",
|
||||||
"expo-constants": "~14.0.2",
|
"expo-constants": "~14.0.2",
|
||||||
"expo-dev-client": "~2.0.1",
|
"expo-dev-client": "~2.0.1",
|
||||||
|
"expo-font": "~11.0.1",
|
||||||
"expo-linear-gradient": "~12.0.1",
|
"expo-linear-gradient": "~12.0.1",
|
||||||
"expo-linking": "~3.3.0",
|
"expo-linking": "~3.3.0",
|
||||||
"expo-localization": "~14.0.0",
|
"expo-localization": "~14.0.0",
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const CopyPlugin = require("copy-webpack-plugin");
|
const CopyPlugin = require("copy-webpack-plugin");
|
||||||
const DefinePlugin = require("webpack").DefinePlugin;
|
const DefinePlugin = require("webpack").DefinePlugin;
|
||||||
const withFont = require("next-fonts");
|
|
||||||
|
|
||||||
const suboctopus = path.dirname(require.resolve("libass-wasm"));
|
const suboctopus = path.dirname(require.resolve("libass-wasm"));
|
||||||
|
|
||||||
@ -131,4 +130,4 @@ if (process.env.NODE_ENV !== "production") {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = withFont(nextConfig);
|
module.exports = nextConfig;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"@kyoo/primitives": "workspace:^",
|
"@kyoo/primitives": "workspace:^",
|
||||||
"@kyoo/ui": "workspace:^",
|
"@kyoo/ui": "workspace:^",
|
||||||
"@material-symbols/svg-400": "^0.4.2",
|
"@material-symbols/svg-400": "^0.4.2",
|
||||||
|
"@next/font": "13.0.5",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.1",
|
"@radix-ui/react-dropdown-menu": "^2.0.1",
|
||||||
"@tanstack/react-query": "^4.19.1",
|
"@tanstack/react-query": "^4.19.1",
|
||||||
"expo-linear-gradient": "^12.0.1",
|
"expo-linear-gradient": "^12.0.1",
|
||||||
@ -24,7 +25,6 @@
|
|||||||
"libass-wasm": "^4.1.0",
|
"libass-wasm": "^4.1.0",
|
||||||
"moti": "^0.21.0",
|
"moti": "^0.21.0",
|
||||||
"next": "13.0.5",
|
"next": "13.0.5",
|
||||||
"next-fonts": "^1.5.1",
|
|
||||||
"next-translate": "^1.6.0",
|
"next-translate": "^1.6.0",
|
||||||
"raf": "^3.4.1",
|
"raf": "^3.4.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
@ -21,29 +21,20 @@
|
|||||||
import "../polyfill";
|
import "../polyfill";
|
||||||
|
|
||||||
import { Hydrate, QueryClientProvider } from "@tanstack/react-query";
|
import { Hydrate, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { ReactNode, useState } from "react";
|
import { HiddenIfNoJs, SkeletonCss, ThemeSelector, WebTooltip } from "@kyoo/primitives";
|
||||||
import NextApp, { AppContext, type AppProps } from "next/app";
|
|
||||||
import {
|
|
||||||
HiddenIfNoJs,
|
|
||||||
SkeletonCss,
|
|
||||||
ThemeSelector as KThemeSelector,
|
|
||||||
WebTooltip,
|
|
||||||
} from "@kyoo/primitives";
|
|
||||||
import { createQueryClient, fetchQuery, QueryIdentifier, QueryPage } from "@kyoo/models";
|
import { createQueryClient, fetchQuery, QueryIdentifier, QueryPage } from "@kyoo/models";
|
||||||
|
import { useState } from "react";
|
||||||
|
import NextApp, { AppContext, type AppProps } from "next/app";
|
||||||
|
import { Poppins } from "@next/font/google";
|
||||||
import { useTheme, useMobileHover } from "yoshiki/web";
|
import { useTheme, useMobileHover } from "yoshiki/web";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { withTranslations } from "../i18n";
|
import { withTranslations } from "../i18n";
|
||||||
|
|
||||||
const ThemeSelector = ({ children }: { children?: ReactNode | ReactNode[] }) => {
|
const font = Poppins({ weight: ["300", "400", "900"], subsets: ["latin"], display: "swap" });
|
||||||
// TODO: Handle user selected mode (light, dark, auto)
|
|
||||||
// TODO: Hande theme change.
|
|
||||||
return <KThemeSelector>{children}</KThemeSelector>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const GlobalCssTheme = () => {
|
const GlobalCssTheme = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<style jsx global>{`
|
<style jsx global>{`
|
||||||
@ -51,6 +42,7 @@ const GlobalCssTheme = () => {
|
|||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
background-color: ${theme.background};
|
background-color: ${theme.background};
|
||||||
|
font-family: ${font.style.fontFamily};
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
@ -104,7 +96,8 @@ const App = ({ Component, pageProps }: AppProps) => {
|
|||||||
</Head>
|
</Head>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<Hydrate state={queryState}>
|
<Hydrate state={queryState}>
|
||||||
<ThemeSelector>
|
{/* TODO: Add theme support */}
|
||||||
|
<ThemeSelector theme="light" font={{ normal: "inherit" }}>
|
||||||
<GlobalCssTheme />
|
<GlobalCssTheme />
|
||||||
<Layout page={<Component {...props} />} {...layoutProps} />
|
<Layout page={<Component {...props} />} {...layoutProps} />
|
||||||
</ThemeSelector>
|
</ThemeSelector>
|
||||||
|
@ -45,8 +45,7 @@ export const A = ({
|
|||||||
href={href}
|
href={href}
|
||||||
textProps={css(
|
textProps={css(
|
||||||
{
|
{
|
||||||
// TODO: use a real font here.
|
fontFamily: theme.font.normal,
|
||||||
// fontFamily: theme.fonts.paragraph,
|
|
||||||
color: theme.link,
|
color: theme.link,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -47,10 +47,19 @@ const styleText = (
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
marginVertical: rem(0.5),
|
marginVertical: rem(0.5),
|
||||||
// fontFamily: type === "header" ? theme.fonts.heading : theme.fonts.paragraph,
|
|
||||||
color: type === "header" ? theme.heading : theme.paragraph,
|
color: type === "header" ? theme.heading : theme.paragraph,
|
||||||
|
fontSize: rem(1),
|
||||||
|
fontFamily: theme.font.normal,
|
||||||
|
},
|
||||||
|
type === "sub" && {
|
||||||
|
fontFamily: theme.font["300"] ?? theme.font.normal,
|
||||||
|
fontWeight: "300",
|
||||||
|
opacity: 0.8,
|
||||||
|
fontSize: rem(0.8),
|
||||||
|
},
|
||||||
|
custom?.fontWeight && {
|
||||||
|
fontFamily: theme.font[custom.fontWeight] ?? theme.font.normal,
|
||||||
},
|
},
|
||||||
type === "sub" && { fontWeight: "300", opacity: 0.8, fontSize: rem(0.8) },
|
|
||||||
custom,
|
custom,
|
||||||
],
|
],
|
||||||
props as TextProps,
|
props as TextProps,
|
||||||
@ -61,7 +70,7 @@ const styleText = (
|
|||||||
return Text;
|
return Text;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const H1 = styleText(EH1, "header", { fontSize: rem(3) });
|
export const H1 = styleText(EH1, "header", { fontSize: rem(3), fontWeight: "900" });
|
||||||
export const H2 = styleText(EH2, "header", { fontSize: rem(2) });
|
export const H2 = styleText(EH2, "header", { fontSize: rem(2) });
|
||||||
export const H3 = styleText(EH3, "header");
|
export const H3 = styleText(EH3, "header");
|
||||||
export const H4 = styleText(EH4, "header");
|
export const H4 = styleText(EH4, "header");
|
||||||
|
@ -22,10 +22,6 @@ import { ThemeBuilder } from "./theme";
|
|||||||
|
|
||||||
// Ref: https://github.com/catppuccin/catppuccin
|
// Ref: https://github.com/catppuccin/catppuccin
|
||||||
export const catppuccin: ThemeBuilder = {
|
export const catppuccin: ThemeBuilder = {
|
||||||
fonts: {
|
|
||||||
heading: "Pacifico",
|
|
||||||
paragraph: "Poppins",
|
|
||||||
},
|
|
||||||
light: {
|
light: {
|
||||||
// Catppuccin latte
|
// Catppuccin latte
|
||||||
appbar: "#e64553",
|
appbar: "#e64553",
|
||||||
|
@ -26,12 +26,12 @@ import "yoshiki";
|
|||||||
import "yoshiki/native";
|
import "yoshiki/native";
|
||||||
import { catppuccin } from "./catppuccin";
|
import { catppuccin } from "./catppuccin";
|
||||||
|
|
||||||
type ThemeSettings = {
|
type FontList = Partial<
|
||||||
fonts: {
|
Record<
|
||||||
heading: string;
|
"normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900",
|
||||||
paragraph: string;
|
string
|
||||||
};
|
>
|
||||||
};
|
>;
|
||||||
|
|
||||||
type Mode = {
|
type Mode = {
|
||||||
appbar: Property.Color;
|
appbar: Property.Color;
|
||||||
@ -59,29 +59,31 @@ type Variant = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
declare module "yoshiki" {
|
declare module "yoshiki" {
|
||||||
export interface Theme extends ThemeSettings, Mode, Variant {
|
export interface Theme extends Mode, Variant {
|
||||||
light: Mode & Variant;
|
light: Mode & Variant;
|
||||||
dark: Mode & Variant;
|
dark: Mode & Variant;
|
||||||
user: Mode & Variant;
|
user: Mode & Variant;
|
||||||
alternate: Mode & Variant;
|
alternate: Mode & Variant;
|
||||||
|
font: FontList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module "yoshiki/native" {
|
declare module "yoshiki/native" {
|
||||||
export interface Theme extends ThemeSettings, Mode, Variant {
|
export interface Theme extends Mode, Variant {
|
||||||
light: Mode & Variant;
|
light: Mode & Variant;
|
||||||
dark: Mode & Variant;
|
dark: Mode & Variant;
|
||||||
user: Mode & Variant;
|
user: Mode & Variant;
|
||||||
alternate: Mode & Variant;
|
alternate: Mode & Variant;
|
||||||
|
font: FontList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { Theme } from "yoshiki";
|
export type { Theme } from "yoshiki";
|
||||||
export type ThemeBuilder = ThemeSettings & {
|
export type ThemeBuilder = {
|
||||||
light: Mode & { default: Variant };
|
light: Mode & { default: Variant };
|
||||||
dark: Mode & { default: Variant };
|
dark: Mode & { default: Variant };
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectMode = (theme: ThemeBuilder, mode: "light" | "dark"): Theme => {
|
const selectMode = (theme: ThemeBuilder & { font: FontList }, mode: "light" | "dark"): Theme => {
|
||||||
const { light: lightBuilder, dark: darkBuilder, ...options } = theme;
|
const { light: lightBuilder, dark: darkBuilder, ...options } = theme;
|
||||||
const light = { ...lightBuilder, ...lightBuilder.default };
|
const light = { ...lightBuilder, ...lightBuilder.default };
|
||||||
const dark = { ...darkBuilder, ...darkBuilder.default };
|
const dark = { ...darkBuilder, ...darkBuilder.default };
|
||||||
@ -112,8 +114,18 @@ const switchVariant = (theme: Theme) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ThemeSelector = ({ children }: { children: ReactNode }) => {
|
export const ThemeSelector = ({
|
||||||
return <ThemeProvider theme={selectMode(catppuccin, "light")}>{children}</ThemeProvider>;
|
children,
|
||||||
|
theme,
|
||||||
|
font,
|
||||||
|
}: {
|
||||||
|
children: ReactNode;
|
||||||
|
theme: "light" | "dark";
|
||||||
|
font: FontList;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<ThemeProvider theme={selectMode({ ...catppuccin, font }, theme)}>{children}</ThemeProvider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
type YoshikiFunc<T> = (props: ReturnType<typeof useYoshiki>) => T;
|
type YoshikiFunc<T> = (props: ReturnType<typeof useYoshiki>) => T;
|
||||||
|
@ -59,7 +59,6 @@ export const WebTooltip = ({ theme }: { theme: Theme }) => {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: ${theme.colors.white};
|
color: ${theme.colors.white};
|
||||||
background-color: ${background};
|
background-color: ${background};
|
||||||
font-family: ${theme.fonts.paragraph};
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -30,18 +30,18 @@ import {
|
|||||||
ts,
|
ts,
|
||||||
Link,
|
Link,
|
||||||
} from "@kyoo/primitives";
|
} from "@kyoo/primitives";
|
||||||
import { Platform, TextInput, View } from "react-native";
|
import { Platform, TextInput, View, ViewProps } from "react-native";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { createParam } from "solito";
|
import { createParam } from "solito";
|
||||||
import { useRouter } from "solito/router";
|
import { useRouter } from "solito/router";
|
||||||
import { rem, Stylable, useTheme, useYoshiki } from "yoshiki/native";
|
import { rem, Stylable, useYoshiki } from "yoshiki/native";
|
||||||
import Menu from "@material-symbols/svg-400/rounded/menu-fill.svg";
|
import Menu from "@material-symbols/svg-400/rounded/menu-fill.svg";
|
||||||
import Search from "@material-symbols/svg-400/rounded/search-fill.svg";
|
import Search from "@material-symbols/svg-400/rounded/search-fill.svg";
|
||||||
import { Fetch } from "../fetch";
|
import { Fetch } from "../fetch";
|
||||||
import { KyooLongLogo } from "./icon";
|
import { KyooLongLogo } from "./icon";
|
||||||
import { forwardRef, useRef, useState } from "react";
|
import { forwardRef, useRef, useState } from "react";
|
||||||
|
|
||||||
export const NavbarTitle = (props: Stylable) => {
|
export const NavbarTitle = (props: Stylable & { onLayout?: ViewProps["onLayout"] }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
602
front/yarn.lock
602
front/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user