Dependencies updated & small enhancements (#27)
* Dependencies updated and imports shortened * Head tags refactored * Final tweaks
This commit is contained in:
@@ -23,7 +23,8 @@ branches:
|
|||||||
|
|
||||||
script:
|
script:
|
||||||
- yarn test --ci
|
- yarn test --ci
|
||||||
- yarn dev & wait-on http://localhost:3000
|
- yarn build
|
||||||
|
- yarn start & wait-on http://localhost:3000
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ];
|
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ];
|
||||||
then
|
then
|
||||||
yarn cy:run --record --key $CY_KEY;
|
yarn cy:run --record --key $CY_KEY;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Lingva Translate
|
# Lingva Translate
|
||||||
|
|
||||||
<img src="public/favicon.svg" width="128" align="right">
|
<img src="public/logo.svg" width="128" align="right">
|
||||||
|
|
||||||
[](https://travis-ci.com/TheDavidDelta/lingva-translate)
|
[](https://travis-ci.com/TheDavidDelta/lingva-translate)
|
||||||
[](https://lingva.ml/)
|
[](https://lingva.ml/)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { Stack, HStack, Heading, Text, Icon, useColorModeValue } from "@chakra-ui/react";
|
import { Stack, HStack, Heading, Text, Icon, useColorModeValue } from "@chakra-ui/react";
|
||||||
import { FaSadTear } from "react-icons/fa";
|
import { FaSadTear } from "react-icons/fa";
|
||||||
import Layout from "./Layout";
|
import { CustomHead } from ".";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
statusCode: number,
|
statusCode: number,
|
||||||
@@ -9,7 +9,9 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const CustomError: FC<Props> = ({ statusCode, statusText }) => (
|
const CustomError: FC<Props> = ({ statusCode, statusText }) => (
|
||||||
<Layout customTitle={`${statusCode} - ${statusText}`}>
|
<>
|
||||||
|
<CustomHead customTitle={`${statusCode} - ${statusText}`} />
|
||||||
|
|
||||||
<Stack
|
<Stack
|
||||||
color={useColorModeValue("lingva.900", "lingva.100")}
|
color={useColorModeValue("lingva.900", "lingva.100")}
|
||||||
direction={["column", null, "row"]}
|
direction={["column", null, "row"]}
|
||||||
@@ -28,7 +30,7 @@ const CustomError: FC<Props> = ({ statusCode, statusText }) => (
|
|||||||
{statusText}
|
{statusText}
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Layout>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default CustomError;
|
export default CustomError;
|
||||||
|
|||||||
56
components/CustomHead.tsx
Normal file
56
components/CustomHead.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { useColorModeValue } from "@chakra-ui/react";
|
||||||
|
import theme from "@theme";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
customTitle?: string,
|
||||||
|
home?: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const title = "Lingva Translate";
|
||||||
|
const description = "Alternative front-end for Google Translate, serving as a Free and Open Source translator with over a hundred languages available";
|
||||||
|
|
||||||
|
const siteDomain = process.env["NEXT_PUBLIC_SITE_DOMAIN"];
|
||||||
|
const url = siteDomain && (siteDomain.includes("localhost") ? "http://" : "https://") + siteDomain;
|
||||||
|
|
||||||
|
const CustomHead: FC<Props> = ({ customTitle, home }) => {
|
||||||
|
const fullTitle = customTitle
|
||||||
|
? `${customTitle} | ${title}`
|
||||||
|
: title;
|
||||||
|
|
||||||
|
const themeColor = useColorModeValue(theme.colors.lingva["100"], theme.colors.lingva["900"]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Head>
|
||||||
|
<title>{fullTitle}</title>
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
<meta name="robots" content={home ? "index,follow" : "noindex,nofollow"} />
|
||||||
|
{home && <link rel="canonical" href={url} />}
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||||
|
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<meta name="theme-color" content={themeColor} />
|
||||||
|
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:title" content={fullTitle} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:url" content={url} />
|
||||||
|
<meta property="og:locale" content="en" />
|
||||||
|
|
||||||
|
<meta property="og:image" content={`${url}/favicon-512x512.png`} />
|
||||||
|
<meta property="og:image:type" content="image/png" />
|
||||||
|
<meta property="og:image:width" content="512" />
|
||||||
|
<meta property="og:image:height" content="512" />
|
||||||
|
<meta property="og:image:alt" content={title} />
|
||||||
|
|
||||||
|
<meta property="twitter:card" content="summary" />
|
||||||
|
<meta property="twitter:creator" content="@thedaviddelta" />
|
||||||
|
</Head>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CustomHead;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { Center, Text, useColorModeValue } from "@chakra-ui/react";
|
import { Center, Text } from "@chakra-ui/react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
@@ -11,8 +11,6 @@ const Footer: FC<Props> = (props) => (
|
|||||||
w="full"
|
w="full"
|
||||||
p={3}
|
p={3}
|
||||||
fontSize={["sm", null, "md"]}
|
fontSize={["sm", null, "md"]}
|
||||||
bgColor={useColorModeValue("lingva.100", "lingva.900")}
|
|
||||||
color={useColorModeValue("lingva.900", "lingva.100")}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<Text as="span">© 2021 TheDavidDelta</Text>
|
<Text as="span">© 2021 TheDavidDelta</Text>
|
||||||
|
|||||||
@@ -1,50 +1,57 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
|
import Head from "next/head";
|
||||||
import NextLink from "next/link";
|
import NextLink from "next/link";
|
||||||
import { Flex, HStack, IconButton, Link, useColorModeValue } from "@chakra-ui/react";
|
import { Flex, HStack, IconButton, Link, useColorModeValue } from "@chakra-ui/react";
|
||||||
import { FaGithub } from "react-icons/fa";
|
import { FaGithub } from "react-icons/fa";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import ColorModeToggler from "./ColorModeToggler";
|
import { ColorModeToggler } from ".";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
};
|
};
|
||||||
|
|
||||||
const Header: FC<Props> = (props) => (
|
const Header: FC<Props> = (props) => (
|
||||||
<Flex
|
<>
|
||||||
as="header"
|
<Head>
|
||||||
px={1}
|
<link rel="prefetch" href="/banner_light.svg" />
|
||||||
py={3}
|
<link rel="prefetch" href="/banner_dark.svg" />
|
||||||
justify="space-around"
|
</Head>
|
||||||
align="center"
|
|
||||||
bgColor={useColorModeValue("lingva.100", "lingva.900")}
|
<Flex
|
||||||
w="full"
|
as="header"
|
||||||
{...props}
|
px={1}
|
||||||
>
|
py={3}
|
||||||
<NextLink href="/" passHref={true}>
|
justify="space-around"
|
||||||
<Link display="flex">
|
align="center"
|
||||||
<Image
|
w="full"
|
||||||
src={useColorModeValue("/banner_light.svg", "/banner_dark.svg")}
|
{...props}
|
||||||
alt="Logo"
|
>
|
||||||
width={110}
|
<NextLink href="/" passHref={true}>
|
||||||
height={64}
|
<Link display="flex">
|
||||||
|
<Image
|
||||||
|
src={useColorModeValue("/banner_light.svg", "/banner_dark.svg")}
|
||||||
|
alt="Logo"
|
||||||
|
width={110}
|
||||||
|
height={64}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</NextLink>
|
||||||
|
<HStack spacing={3}>
|
||||||
|
<ColorModeToggler
|
||||||
|
variant={useColorModeValue("outline", "solid")}
|
||||||
/>
|
/>
|
||||||
</Link>
|
<IconButton
|
||||||
</NextLink>
|
as={Link}
|
||||||
<HStack spacing={3}>
|
href="https://github.com/TheDavidDelta/lingva-translate"
|
||||||
<ColorModeToggler
|
isExternal={true}
|
||||||
variant={useColorModeValue("outline", "solid")}
|
aria-label="GitHub"
|
||||||
/>
|
icon={<FaGithub />}
|
||||||
<IconButton
|
colorScheme="lingva"
|
||||||
as={Link}
|
variant={useColorModeValue("outline", "solid")}
|
||||||
href="https://github.com/TheDavidDelta/lingva-translate"
|
/>
|
||||||
isExternal={true}
|
</HStack>
|
||||||
aria-label="GitHub"
|
</Flex>
|
||||||
icon={<FaGithub />}
|
</>
|
||||||
colorScheme="lingva"
|
|
||||||
variant={useColorModeValue("outline", "solid")}
|
|
||||||
/>
|
|
||||||
</HStack>
|
|
||||||
</Flex>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
||||||
|
|||||||
@@ -1,48 +1,13 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { Flex, VStack, Button, Link, useColorModeValue } from "@chakra-ui/react";
|
import { Flex, VStack, Button, Link, useColorModeValue } from "@chakra-ui/react";
|
||||||
import Head from "next/head";
|
import { Header, Footer } from ".";
|
||||||
import Header from "./Header";
|
|
||||||
import Footer from "./Footer";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
customTitle?: string,
|
|
||||||
home?: true
|
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
};
|
};
|
||||||
|
|
||||||
const title = "Lingva Translate";
|
const Layout: FC<Props> = ({ children, ...props }) => (
|
||||||
const description = "Alternative front-end for Google Translate, serving as a Free and Open Source translator with over a hundred languages available";
|
|
||||||
const siteDomain = process.env["NEXT_PUBLIC_SITE_DOMAIN"];
|
|
||||||
const url = siteDomain && (siteDomain.includes("localhost") ? "http://" : "https://") + siteDomain;
|
|
||||||
|
|
||||||
const Layout: FC<Props> = ({ customTitle, children, home, ...props }) => (
|
|
||||||
<>
|
<>
|
||||||
<Head>
|
|
||||||
<title>
|
|
||||||
{customTitle ?? title}
|
|
||||||
</title>
|
|
||||||
<meta name="description" content={description} />
|
|
||||||
<meta name="robots" content={home ? "index,follow" : "noindex,nofollow"} />
|
|
||||||
{home && <link rel="canonical" href={url} />}
|
|
||||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
|
||||||
<link rel="manifest" href="/manifest.json" />
|
|
||||||
<meta name="theme-color" content={useColorModeValue("#bde3cb", "#005525")} />
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta property="og:title" content={title} />
|
|
||||||
<meta property="og:description" content={description} />
|
|
||||||
<meta property="og:url" content={url} />
|
|
||||||
<meta property="og:locale" content="en" />
|
|
||||||
<meta property="og:image" content={`${url}/favicon-512x512.png`} />
|
|
||||||
<meta property="og:image:type" content="image/png" />
|
|
||||||
<meta property="og:image:width" content="512" />
|
|
||||||
<meta property="og:image:height" content="512" />
|
|
||||||
<meta property="og:image:alt" content={title} />
|
|
||||||
<meta property="twitter:card" content="summary" />
|
|
||||||
<meta property="twitter:creator" content="@thedaviddelta" />
|
|
||||||
</Head>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
as={Link}
|
as={Link}
|
||||||
href="#main"
|
href="#main"
|
||||||
@@ -58,7 +23,10 @@ const Layout: FC<Props> = ({ customTitle, children, home, ...props }) => (
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<VStack minH="100vh" spacing={8}>
|
<VStack minH="100vh" spacing={8}>
|
||||||
<Header />
|
<Header
|
||||||
|
bgColor={useColorModeValue("lingva.100", "lingva.900")}
|
||||||
|
/>
|
||||||
|
|
||||||
<Flex
|
<Flex
|
||||||
as="main"
|
as="main"
|
||||||
id="main"
|
id="main"
|
||||||
@@ -68,7 +36,11 @@ const Layout: FC<Props> = ({ customTitle, children, home, ...props }) => (
|
|||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Footer />
|
|
||||||
|
<Footer
|
||||||
|
bgColor={useColorModeValue("lingva.100", "lingva.900")}
|
||||||
|
color={useColorModeValue("lingva.900", "lingva.100")}
|
||||||
|
/>
|
||||||
</VStack>
|
</VStack>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FC, ChangeEvent } from "react";
|
import { FC, ChangeEvent } from "react";
|
||||||
import { Box, HStack, Textarea, IconButton, Tooltip, Spinner, useBreakpointValue, useColorModeValue, useClipboard } from "@chakra-ui/react";
|
import { Box, HStack, Textarea, IconButton, Tooltip, Spinner, useBreakpointValue, useColorModeValue, useClipboard } from "@chakra-ui/react";
|
||||||
import { FaCopy, FaCheck, FaPlay, FaStop } from "react-icons/fa";
|
import { FaCopy, FaCheck, FaPlay, FaStop } from "react-icons/fa";
|
||||||
import { useAudioFromBuffer } from "../hooks";
|
import { useAudioFromBuffer } from "@hooks";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
value: string,
|
value: string,
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
export { default as CustomError } from "./CustomError";
|
export { default as CustomError } from "./CustomError";
|
||||||
|
export { default as CustomHead } from "./CustomHead";
|
||||||
export { default as Layout } from "./Layout";
|
export { default as Layout } from "./Layout";
|
||||||
|
export { default as Header } from "./Header";
|
||||||
|
export { default as Footer } from "./Footer";
|
||||||
|
export { default as ColorModeToggler } from "./ColorModeToggler";
|
||||||
export { default as LangSelect } from "./LangSelect";
|
export { default as LangSelect } from "./LangSelect";
|
||||||
export { default as TranslationArea } from "./TranslationArea";
|
export { default as TranslationArea } from "./TranslationArea";
|
||||||
|
|||||||
@@ -16,5 +16,9 @@ module.exports = {
|
|||||||
setupFilesAfterEnv: [
|
setupFilesAfterEnv: [
|
||||||
"<rootDir>/tests/setupTests.ts"
|
"<rootDir>/tests/setupTests.ts"
|
||||||
],
|
],
|
||||||
moduleFileExtensions: ["ts", "tsx", "js", "jsx"]
|
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
|
||||||
|
moduleNameMapper: {
|
||||||
|
"^@(components|hooks|pages|public|tests|utils|theme)(.*)$": "<rootDir>/$1$2"
|
||||||
|
},
|
||||||
|
testEnvironment: "jsdom"
|
||||||
}
|
}
|
||||||
|
|||||||
50
package.json
50
package.json
@@ -12,41 +12,41 @@
|
|||||||
"cy:run": "cypress run"
|
"cy:run": "cypress run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^1.0.6",
|
"@chakra-ui/icons": "^1.0.12",
|
||||||
"@chakra-ui/react": "^1.6.0",
|
"@chakra-ui/react": "^1.6.0",
|
||||||
"@emotion/react": "^11.1.5",
|
"@emotion/react": "^11",
|
||||||
"@emotion/styled": "^11.1.5",
|
"@emotion/styled": "^11",
|
||||||
"apollo-server-micro": "^2.22.1",
|
"apollo-server-micro": "^2.25.1",
|
||||||
"cheerio": "^1.0.0-rc.5",
|
"cheerio": "^1.0.0-rc.10",
|
||||||
"framer-motion": "^3.10.3",
|
"framer-motion": "^4",
|
||||||
"graphql": "^15.5.0",
|
"graphql": "^15.5.0",
|
||||||
"next": "10.2.0",
|
"next": "10.2.3",
|
||||||
"next-pwa": "^5.2.16",
|
"next-pwa": "^5.2.21",
|
||||||
"nextjs-cors": "^1.0.4",
|
"nextjs-cors": "^1.0.5",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-hotkeys-hook": "^3.3.0",
|
"react-hotkeys-hook": "^3.3.1",
|
||||||
"react-icons": "^4.2.0",
|
"react-icons": "^4.2.0",
|
||||||
"user-agents": "^1.0.597"
|
"user-agents": "^1.0.680"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@testing-library/cypress": "^7.0.4",
|
"@testing-library/cypress": "^7.0.6",
|
||||||
"@testing-library/jest-dom": "^5.11.9",
|
"@testing-library/jest-dom": "^5.13.0",
|
||||||
"@testing-library/react": "^11.2.5",
|
"@testing-library/react": "^11.2.7",
|
||||||
"@testing-library/user-event": "^13.1.8",
|
"@testing-library/user-event": "^13.1.9",
|
||||||
"@types/faker": "^5.1.7",
|
"@types/faker": "^5.5.6",
|
||||||
"@types/jest": "^26.0.20",
|
"@types/jest": "^26.0.23",
|
||||||
"@types/node": "^14.14.33",
|
"@types/node": "^15.0.1",
|
||||||
"@types/react": "^17.0.3",
|
"@types/react": "^17.0.4",
|
||||||
"@types/user-agents": "^1.0.0",
|
"@types/user-agents": "^1.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
||||||
"@typescript-eslint/parser": "^4.0.0",
|
"@typescript-eslint/parser": "^4.0.0",
|
||||||
"apollo-server-testing": "^2.22.1",
|
"apollo-server-testing": "^2.25.1",
|
||||||
"babel-eslint": "^10.0.0",
|
"babel-eslint": "^10.0.0",
|
||||||
"cypress": "^7.2.0",
|
"cypress": "^7.5.0",
|
||||||
"eslint": "^7.5.0",
|
"eslint": "^7.5.0",
|
||||||
"eslint-config-react-app": "^6.0.0",
|
"eslint-config-react-app": "^6.0.0",
|
||||||
"eslint-plugin-cypress": "^2.11.2",
|
"eslint-plugin-cypress": "^2.11.3",
|
||||||
"eslint-plugin-flowtype": "^5.2.0",
|
"eslint-plugin-flowtype": "^5.2.0",
|
||||||
"eslint-plugin-import": "^2.22.0",
|
"eslint-plugin-import": "^2.22.0",
|
||||||
"eslint-plugin-jest": "^24.0.0",
|
"eslint-plugin-jest": "^24.0.0",
|
||||||
@@ -54,11 +54,11 @@
|
|||||||
"eslint-plugin-react": "^7.20.3",
|
"eslint-plugin-react": "^7.20.3",
|
||||||
"eslint-plugin-react-hooks": "^4.0.8",
|
"eslint-plugin-react-hooks": "^4.0.8",
|
||||||
"eslint-plugin-testing-library": "^3.9.0",
|
"eslint-plugin-testing-library": "^3.9.0",
|
||||||
"faker": "^5.4.0",
|
"faker": "^5.5.3",
|
||||||
"jest": "^26.6.3",
|
"jest": "^27.0.4",
|
||||||
"jest-fetch-mock": "^3.0.3",
|
"jest-fetch-mock": "^3.0.3",
|
||||||
"node-mocks-http": "^1.10.1",
|
"node-mocks-http": "^1.10.1",
|
||||||
"typescript": "^4.2.3",
|
"typescript": "^4.2.4",
|
||||||
"wait-on": "^5.3.0"
|
"wait-on": "^5.3.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { CustomError } from "../components";
|
import { CustomError } from "@components";
|
||||||
|
|
||||||
const My404: FC = () => (
|
const My404: FC = () => (
|
||||||
<CustomError statusCode={404} statusText={"This page could not be found"} />
|
<CustomError statusCode={404} statusText="This page could not be found" />
|
||||||
);
|
);
|
||||||
|
|
||||||
export default My404;
|
export default My404;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { CustomError } from "../components";
|
import { CustomError } from "@components";
|
||||||
|
|
||||||
const My500: FC = () => (
|
const My500: FC = () => (
|
||||||
<CustomError statusCode={500} statusText={"Internal Server Error"} />
|
<CustomError statusCode={500} statusText="Internal Server Error" />
|
||||||
);
|
);
|
||||||
|
|
||||||
export default My500;
|
export default My500;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import Router from "next/router";
|
|||||||
import { Stack, VStack, HStack, IconButton } from "@chakra-ui/react";
|
import { Stack, VStack, HStack, IconButton } from "@chakra-ui/react";
|
||||||
import { FaExchangeAlt } from "react-icons/fa";
|
import { FaExchangeAlt } from "react-icons/fa";
|
||||||
import { useHotkeys } from "react-hotkeys-hook";
|
import { useHotkeys } from "react-hotkeys-hook";
|
||||||
import { Layout, LangSelect, TranslationArea } from "../components";
|
import { CustomHead, LangSelect, TranslationArea } from "@components";
|
||||||
import { useToastOnLoad } from "../hooks";
|
import { useToastOnLoad } from "@hooks";
|
||||||
import { googleScrape, extractSlug, textToSpeechScrape } from "../utils/translate";
|
import { googleScrape, extractSlug, textToSpeechScrape } from "@utils/translate";
|
||||||
import { retrieveFiltered, replaceBoth } from "../utils/language";
|
import { retrieveFiltered, replaceBoth } from "@utils/language";
|
||||||
import langReducer, { Actions, initialState } from "../utils/reducer";
|
import langReducer, { Actions, initialState } from "@utils/reducer";
|
||||||
|
|
||||||
const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ home, translationRes, audio, errorMsg, initial }) => {
|
const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ home, translationRes, audio, errorMsg, initial }) => {
|
||||||
const [{ source, target, query, delayedQuery, translation, isLoading }, dispatch] = useReducer(langReducer, initialState);
|
const [{ source, target, query, delayedQuery, translation, isLoading }, dispatch] = useReducer(langReducer, initialState);
|
||||||
@@ -79,7 +79,9 @@ const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ home, transl
|
|||||||
), [canSwitch]);
|
), [canSwitch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout home={home}>
|
<>
|
||||||
|
<CustomHead home={home} />
|
||||||
|
|
||||||
<VStack px={[8, null, 24, 40]} w="full">
|
<VStack px={[8, null, 24, 40]} w="full">
|
||||||
<HStack px={[1, null, 3, 4]} w="full">
|
<HStack px={[1, null, 3, 4]} w="full">
|
||||||
<LangSelect
|
<LangSelect
|
||||||
@@ -128,9 +130,9 @@ const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ home, transl
|
|||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</VStack>
|
</VStack>
|
||||||
</Layout>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
|
|
||||||
@@ -186,4 +188,4 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
|
|||||||
? 2 * 30 * 24 * 60 * 60 // 2 months
|
? 2 * 30 * 24 * 60 * 60 // 2 months
|
||||||
: 1
|
: 1
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { AppProps } from "next/app";
|
import { AppProps } from "next/app";
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { ChakraProvider } from "@chakra-ui/react";
|
import { ChakraProvider } from "@chakra-ui/react";
|
||||||
import theme from "../theme";
|
import theme from "@theme";
|
||||||
|
import { Layout } from "@components";
|
||||||
|
|
||||||
const App: FC<AppProps> = ({ Component, pageProps }) => (
|
const App: FC<AppProps> = ({ Component, pageProps }) => (
|
||||||
<ChakraProvider theme={theme}>
|
<ChakraProvider theme={theme}>
|
||||||
<Component {...pageProps} />
|
<Layout>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</Layout>
|
||||||
</ChakraProvider>
|
</ChakraProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ColorModeScript } from "@chakra-ui/color-mode";
|
import { ColorModeScript } from "@chakra-ui/color-mode";
|
||||||
import Document, { Html, Head, Main, NextScript } from "next/document";
|
import Document, { Html, Head, Main, NextScript } from "next/document";
|
||||||
import theme from "../theme";
|
import theme from "@theme";
|
||||||
|
|
||||||
export default class MyDocument extends Document {
|
export default class MyDocument extends Document {
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ApolloServer, gql, IResolvers } from "apollo-server-micro";
|
import { ApolloServer, gql, IResolvers } from "apollo-server-micro";
|
||||||
import { NextApiHandler } from "next";
|
import { NextApiHandler } from "next";
|
||||||
import NextCors from "nextjs-cors";
|
import NextCors from "nextjs-cors";
|
||||||
import { googleScrape, textToSpeechScrape } from "../../utils/translate";
|
import { googleScrape, textToSpeechScrape } from "@utils/translate";
|
||||||
|
|
||||||
export const typeDefs = gql`
|
export const typeDefs = gql`
|
||||||
type Query {
|
type Query {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { NextApiHandler } from "next";
|
import { NextApiHandler } from "next";
|
||||||
import NextCors from "nextjs-cors";
|
import NextCors from "nextjs-cors";
|
||||||
import { googleScrape, textToSpeechScrape } from "../../../utils/translate";
|
import { googleScrape, textToSpeechScrape } from "@utils/translate";
|
||||||
|
|
||||||
type Data = {
|
type Data = {
|
||||||
translation?: string,
|
translation?: string,
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
@@ -1,6 +1,6 @@
|
|||||||
import { render, screen } from "../reactUtils";
|
import { render, screen } from "@tests/reactUtils";
|
||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
import CustomError from "../../components/CustomError";
|
import CustomError from "@components/CustomError";
|
||||||
|
|
||||||
const code = faker.datatype.number({ min: 400, max: 599 });
|
const code = faker.datatype.number({ min: 400, max: 599 });
|
||||||
const text = faker.random.words();
|
const text = faker.random.words();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { render, screen, waitFor } from "../reactUtils";
|
import { render, screen, waitFor } from "@tests/reactUtils";
|
||||||
import { htmlRes, resolveFetchWith } from "../commonUtils";
|
import { htmlRes, resolveFetchWith } from "@tests/commonUtils";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent from "@testing-library/user-event";
|
||||||
import Router from "next/router";
|
import Router from "next/router";
|
||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
import Page, { getStaticProps } from "../../pages/[[...slug]]";
|
import Page, { getStaticProps } from "@pages/[[...slug]]";
|
||||||
|
|
||||||
const mockPush = jest.spyOn(Router, "push").mockImplementation(async () => true);
|
const mockPush = jest.spyOn(Router, "push").mockImplementation(async () => true);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { createTestClient } from "apollo-server-testing";
|
import { createTestClient } from "apollo-server-testing";
|
||||||
import { ApolloServer } from "apollo-server-micro";
|
import { ApolloServer } from "apollo-server-micro";
|
||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
import { htmlRes, resolveFetchWith } from "../../commonUtils";
|
import { htmlRes, resolveFetchWith } from "@tests/commonUtils";
|
||||||
import { typeDefs, resolvers } from "../../../pages/api/graphql";
|
import { typeDefs, resolvers } from "@pages/api/graphql";
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fetchMock.resetMocks();
|
fetchMock.resetMocks();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import httpMocks from "node-mocks-http";
|
import httpMocks from "node-mocks-http";
|
||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
import { htmlRes, resolveFetchWith } from "../../../commonUtils";
|
import { htmlRes, resolveFetchWith } from "@tests/commonUtils";
|
||||||
import handler from "../../../../pages/api/v1/[[...slug]]";
|
import handler from "@pages/api/v1/[[...slug]]";
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fetchMock.resetMocks();
|
fetchMock.resetMocks();
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { FC, ReactElement } from "react";
|
import { FC, ReactElement } from "react";
|
||||||
import { render, RenderOptions } from "@testing-library/react";
|
import { render, RenderOptions } from "@testing-library/react";
|
||||||
import { ChakraProvider } from "@chakra-ui/react";
|
import { ChakraProvider } from "@chakra-ui/react";
|
||||||
import theme from "../theme";
|
import theme from "@theme";
|
||||||
|
import { Layout } from "@components";
|
||||||
|
|
||||||
// Jest JSDOM bug
|
// Jest JSDOM bug
|
||||||
Object.defineProperty(window, 'matchMedia', {
|
Object.defineProperty(window, 'matchMedia', {
|
||||||
@@ -20,7 +21,9 @@ Object.defineProperty(window, 'matchMedia', {
|
|||||||
|
|
||||||
const Providers: FC = ({ children }) => (
|
const Providers: FC = ({ children }) => (
|
||||||
<ChakraProvider theme={theme}>
|
<ChakraProvider theme={theme}>
|
||||||
{children}
|
<Layout>
|
||||||
|
{children}
|
||||||
|
</Layout>
|
||||||
</ChakraProvider>
|
</ChakraProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { replaceBoth, retrieveFiltered, CheckType, LangType } from "../../utils/language";
|
import { replaceBoth, retrieveFiltered, CheckType, LangType } from "@utils/language";
|
||||||
import { languages, exceptions, mappings } from "../../utils/languages.json";
|
import { languages, exceptions, mappings } from "@utils/languages.json";
|
||||||
|
|
||||||
describe("replaceBoth", () => {
|
describe("replaceBoth", () => {
|
||||||
const testReplacer = (
|
const testReplacer = (
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
import langReducer, { Actions, initialState } from "../../utils/reducer";
|
import langReducer, { Actions, initialState } from "@utils/reducer";
|
||||||
|
|
||||||
it("changes a field value", () => {
|
it("changes a field value", () => {
|
||||||
const query = faker.random.words();
|
const query = faker.random.words();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { htmlRes, resolveFetchWith } from "../commonUtils";
|
import { htmlRes, resolveFetchWith } from "@tests/commonUtils";
|
||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
import { googleScrape, extractSlug, textToSpeechScrape } from "../../utils/translate";
|
import { googleScrape, extractSlug, textToSpeechScrape } from "@utils/translate";
|
||||||
|
|
||||||
const source = faker.random.locale();
|
const source = faker.random.locale();
|
||||||
const target = faker.random.locale();
|
const target = faker.random.locale();
|
||||||
|
|||||||
@@ -16,7 +16,11 @@
|
|||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve"
|
"jsx": "preserve",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"@*": ["*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
|
|||||||
Reference in New Issue
Block a user