mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-14 15:16:09 -05:00
lingui initial
This commit is contained in:
14
.babelrc
Normal file
14
.babelrc
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"next/babel",
|
||||
{
|
||||
"preset-env": {},
|
||||
"transform-runtime": {},
|
||||
"styled-jsx": {},
|
||||
"class-properties": {}
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": ["macros"]
|
||||
}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -33,3 +33,7 @@ prisma/.env
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# lingui
|
||||
locale/_build/
|
||||
locale/**/*.js
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
old
|
||||
.next
|
||||
prisma/migrations
|
||||
prisma/migrations
|
||||
locales/**/*.js
|
||||
16
lib/i18n.ts
Normal file
16
lib/i18n.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { i18n } from "@lingui/core";
|
||||
import { en } from "make-plural/plurals";
|
||||
|
||||
i18n.loadLocaleData("en", { plurals: en });
|
||||
//i18n.loadLocaleData("cs", { plurals: cs });
|
||||
|
||||
/**
|
||||
* Load messages for requested locale and activate it.
|
||||
* This function isn't part of the LinguiJS library because there're
|
||||
* many ways how to load messages — from REST API, from file, from cache, etc.
|
||||
*/
|
||||
export async function activate(locale: string) {
|
||||
const { messages } = await import(`locale/${locale}/messages.js`);
|
||||
i18n.load(locale, messages);
|
||||
i18n.activate(locale);
|
||||
}
|
||||
14
lingui.config.js
Normal file
14
lingui.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
locales: ["en"],
|
||||
sourceLocale: "en",
|
||||
catalogs: [
|
||||
{
|
||||
path: "<rootDir>/locale/{locale}/messages",
|
||||
include: [
|
||||
"./pages/",
|
||||
"./components/",
|
||||
"./scenes/"
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
74
locale/en/messages.po
Normal file
74
locale/en/messages.po
Normal file
@@ -0,0 +1,74 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2020-11-04 01:38+0200\n"
|
||||
"Mime-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: en\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:209
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:161
|
||||
msgid "Country"
|
||||
msgstr "Country"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:109
|
||||
msgid "Custom URL"
|
||||
msgstr "Custom URL"
|
||||
|
||||
#: scenes/Profile/index.tsx:17
|
||||
msgid "Edit profile"
|
||||
msgstr "Edit profile"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:102
|
||||
msgid "Editing profile"
|
||||
msgstr "Editing profile"
|
||||
|
||||
#: scenes/Layout/components/TopNav.tsx:19
|
||||
msgid "Log in via Discord"
|
||||
msgstr "Log in via Discord"
|
||||
|
||||
#: scenes/Layout/components/TopNav.tsx:36
|
||||
msgid "Log out"
|
||||
msgstr "Log out"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:194
|
||||
msgid "Motion sensitivity"
|
||||
msgstr "Motion sensitivity"
|
||||
|
||||
#: scenes/Layout/components/TopNav.tsx:32
|
||||
msgid "Profile"
|
||||
msgstr "Profile"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:206
|
||||
msgid "Save"
|
||||
msgstr "Save"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:184
|
||||
msgid "Stick sensitivity"
|
||||
msgstr "Stick sensitivity"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:137
|
||||
msgid "Twitch name"
|
||||
msgstr "Twitch name"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:123
|
||||
msgid "Twitter name"
|
||||
msgstr "Twitter name"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:172
|
||||
msgid "Weapon pool"
|
||||
msgstr "Weapon pool"
|
||||
|
||||
#: scenes/Profile/components/ProfileModal.tsx:151
|
||||
msgid "YouTube channel ID"
|
||||
msgstr "YouTube channel ID"
|
||||
759
package-lock.json
generated
759
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"build": "lingui compile && next build",
|
||||
"start": "next start",
|
||||
"migrate:save": "npx prisma migrate save --name init --experimental",
|
||||
"migrate:up": "npx prisma migrate up --experimental",
|
||||
@@ -13,13 +13,17 @@
|
||||
"gen": "graphql-codegen --config codegen.yml",
|
||||
"seed": "ts-node prisma/seed.ts",
|
||||
"prettier": "prettier --write .",
|
||||
"e2e": "cypress open"
|
||||
"e2e": "cypress open",
|
||||
"add-locale": "lingui add-locale",
|
||||
"extract": "lingui extract",
|
||||
"compile": "lingui compile"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.2.5",
|
||||
"@chakra-ui/core": "^1.0.0-rc.8",
|
||||
"@chakra-ui/theme-tools": "^1.0.0-rc.8",
|
||||
"@hookform/resolvers": "^1.0.0",
|
||||
"@lingui/react": "^3.0.3",
|
||||
"@nexus/schema": "^0.17.0",
|
||||
"@prisma/client": "^2.10.1",
|
||||
"@sendou/react-sketch": "^0.5.2",
|
||||
@@ -47,6 +51,8 @@
|
||||
"@graphql-codegen/typescript": "1.17.11",
|
||||
"@graphql-codegen/typescript-operations": "1.17.8",
|
||||
"@graphql-codegen/typescript-react-apollo": "2.0.7",
|
||||
"@lingui/cli": "^3.0.3",
|
||||
"@lingui/macro": "^3.0.3",
|
||||
"@prisma/cli": "^2.10.1",
|
||||
"@types/next-auth": "^3.1.14",
|
||||
"@types/node": "^14.14.6",
|
||||
@@ -55,5 +61,6 @@
|
||||
"prettier": "^2.1.2",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^4.0.5"
|
||||
}
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { ApolloProvider } from "@apollo/client";
|
||||
import { ChakraProvider, extendTheme } from "@chakra-ui/core";
|
||||
import { mode } from "@chakra-ui/theme-tools";
|
||||
import { i18n } from "@lingui/core";
|
||||
import { I18nProvider } from "@lingui/react";
|
||||
import { useApollo } from "lib/apollo";
|
||||
import { activate } from "lib/i18n";
|
||||
import { Provider as NextAuthProvider } from "next-auth/client";
|
||||
import GoogleFonts from "next-google-fonts";
|
||||
import type { AppProps } from "next/app";
|
||||
import { useEffect } from "react";
|
||||
import Layout from "scenes/Layout";
|
||||
import { theme } from "theme";
|
||||
|
||||
@@ -82,6 +86,10 @@ const extendedTheme = extendTheme({
|
||||
const MyApp = (props: AppProps) => {
|
||||
const apolloClient = useApollo(props.pageProps.initialApolloState);
|
||||
|
||||
useEffect(() => {
|
||||
activate("en");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<GoogleFonts
|
||||
@@ -90,7 +98,9 @@ const MyApp = (props: AppProps) => {
|
||||
<NextAuthProvider session={props.pageProps.session}>
|
||||
<ApolloProvider client={apolloClient}>
|
||||
<ChakraProvider theme={extendedTheme}>
|
||||
<Layout {...props} />
|
||||
<I18nProvider i18n={i18n}>
|
||||
<Layout {...props} />
|
||||
</I18nProvider>
|
||||
</ChakraProvider>
|
||||
</ApolloProvider>
|
||||
</NextAuthProvider>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
MenuList,
|
||||
useColorMode,
|
||||
} from "@chakra-ui/core";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { DiscordIcon } from "assets/icons";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import useUser from "lib/useUser";
|
||||
@@ -37,7 +38,7 @@ const TopNav = () => {
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
>
|
||||
{t("navigation;Log in via Discord")}
|
||||
<Trans>Log in via Discord</Trans>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -60,10 +61,12 @@ const TopNav = () => {
|
||||
<MenuList>
|
||||
<MenuGroup title={`${user.username}#${user.discriminator}`}>
|
||||
<Link href={`/u/${user.discordId}`}>
|
||||
<MenuItem>{t("navigation;Profile")}</MenuItem>
|
||||
<MenuItem>
|
||||
<Trans>Profile</Trans>
|
||||
</MenuItem>
|
||||
</Link>
|
||||
<MenuItem onClick={() => signOut()}>
|
||||
{t("navigation;Log out")}
|
||||
<Trans>Log out</Trans>
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
useToast,
|
||||
} from "@chakra-ui/core";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { countries } from "countries-list";
|
||||
import {
|
||||
GetUserByIdentifierDocument,
|
||||
@@ -158,13 +159,15 @@ const ProfileModal: React.FC<Props> = ({
|
||||
<Modal isOpen onClose={onClose} size="xl" closeOnOverlayClick={false}>
|
||||
<ModalOverlay>
|
||||
<ModalContent>
|
||||
<ModalHeader>{t("users;Editing profile")}</ModalHeader>
|
||||
<ModalHeader>
|
||||
<Trans>Editing profile</Trans>
|
||||
</ModalHeader>
|
||||
<ModalCloseButton borderRadius="50%" />
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<ModalBody pb={6}>
|
||||
<FormControl isInvalid={!!errors.customUrlPath}>
|
||||
<FormLabel htmlFor="customUrlPath">
|
||||
{t("users;Custom URL")}
|
||||
<Trans>Custom URL</Trans>
|
||||
</FormLabel>
|
||||
<InputGroup>
|
||||
<InputLeftAddon children="https://sendou.ink/u/" />
|
||||
@@ -188,7 +191,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
mb={1}
|
||||
color="#1DA1F2"
|
||||
/>{" "}
|
||||
{t("users;Twitter name")}
|
||||
<Trans>Twitter name</Trans>
|
||||
</FormLabel>
|
||||
<InputGroup>
|
||||
<InputLeftAddon children="https://twitter.com/" />
|
||||
@@ -212,7 +215,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
mb={1}
|
||||
color="#6441A4"
|
||||
/>
|
||||
{t("users;Twitch name")}
|
||||
<Trans>Twitch name</Trans>
|
||||
</FormLabel>
|
||||
<InputGroup>
|
||||
<InputLeftAddon children="https://twitch.tv/" />
|
||||
@@ -236,7 +239,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
mb={1}
|
||||
color="#FF0000"
|
||||
/>
|
||||
{t("users;YouTube channel ID")}
|
||||
<Trans>YouTube channel ID</Trans>
|
||||
</FormLabel>
|
||||
<InputGroup>
|
||||
<InputLeftAddon children="https://youtube.com/channel/" />
|
||||
@@ -250,7 +253,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
</FormControl>
|
||||
|
||||
<FormLabel htmlFor="country" mt={4}>
|
||||
{t("users;Country")}
|
||||
<Trans>Country</Trans>
|
||||
</FormLabel>
|
||||
{/* FIXME: placeholders for dropdowns */}
|
||||
<Select ref={register} name="country">
|
||||
@@ -265,7 +268,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
|
||||
<FormControl isInvalid={!!errors.weaponPool}>
|
||||
<FormLabel htmlFor="weaponPool" mt={4}>
|
||||
{t("users;Weapon pool")}
|
||||
<Trans>Weapon pool</Trans>
|
||||
</FormLabel>
|
||||
<Controller
|
||||
name="weaponPool"
|
||||
@@ -288,7 +291,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
|
||||
<FormLabel htmlFor="sensStick" mt={4}>
|
||||
<Box as={FaGamepad} display="inline-block" mr={2} mb={1} />
|
||||
{t("users;Stick sensitivity")}
|
||||
<Trans>Stick sensitivity</Trans>
|
||||
</FormLabel>
|
||||
<Select ref={register} name="sensStick">
|
||||
{sensOptions.map((sens) => (
|
||||
@@ -300,7 +303,7 @@ const ProfileModal: React.FC<Props> = ({
|
||||
|
||||
<FormLabel htmlFor="sensMotion" mt={4}>
|
||||
<Box as={FaGamepad} display="inline-block" mr={2} mb={1} />
|
||||
{t("users;Motion sensitivity")}
|
||||
<Trans>Motion sensitivity</Trans>
|
||||
</FormLabel>
|
||||
<Select ref={register} name="sensMotion">
|
||||
{sensOptions.map((sens) => (
|
||||
@@ -322,10 +325,10 @@ const ProfileModal: React.FC<Props> = ({
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button mr={3} type="submit" isLoading={loading}>
|
||||
Save
|
||||
<Trans>Save</Trans>
|
||||
</Button>
|
||||
<Button onClick={onClose} variant="outline">
|
||||
Cancel
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</form>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Box, Button } from "@chakra-ui/core";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { GetUserByIdentifierQuery } from "generated/graphql";
|
||||
import Markdown from "lib/components/Markdown";
|
||||
import MyHead from "lib/components/MyHead";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import useUser from "lib/useUser";
|
||||
import { useState } from "react";
|
||||
import AvatarWithInfo from "./components/AvatarWithInfo";
|
||||
@@ -14,7 +14,6 @@ interface Props {
|
||||
}
|
||||
|
||||
const Profile: React.FC<Props> = ({ user, identifier }) => {
|
||||
const { t } = useTranslation();
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [loggedInUser] = useUser();
|
||||
return (
|
||||
@@ -23,7 +22,7 @@ const Profile: React.FC<Props> = ({ user, identifier }) => {
|
||||
<AvatarWithInfo user={user} />
|
||||
{loggedInUser?.id === user.id && (
|
||||
<Button onClick={() => setShowModal(true)}>
|
||||
{t("users;Edit profile")}
|
||||
<Trans>Edit profile</Trans>
|
||||
</Button>
|
||||
)}
|
||||
{showModal && (
|
||||
|
||||
Reference in New Issue
Block a user