switch locale component
This commit is contained in:
parent
d47939059b
commit
45f6158e7d
8 changed files with 98 additions and 16 deletions
|
@ -20,7 +20,7 @@ import {
|
||||||
traverseFolder,
|
traverseFolder,
|
||||||
} from './MultiFileDownloader'
|
} from './MultiFileDownloader'
|
||||||
|
|
||||||
import { layouts } from './SwitchLayout'
|
import layouts from './SwitchLayout'
|
||||||
import Loading, { LoadingIcon } from './Loading'
|
import Loading, { LoadingIcon } from './Loading'
|
||||||
import FourOhFour from './FourOhFour'
|
import FourOhFour from './FourOhFour'
|
||||||
import Auth from './Auth'
|
import Auth from './Auth'
|
||||||
|
@ -263,7 +263,7 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
|
||||||
t('Failed to download folder {{path}}: {{status}} {{message}} Skipped it to continue.', {
|
t('Failed to download folder {{path}}: {{status}} {{message}} Skipped it to continue.', {
|
||||||
path: p,
|
path: p,
|
||||||
status: error.status,
|
status: error.status,
|
||||||
message: error.message
|
message: error.message,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
@ -323,7 +323,7 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
|
||||||
<div className="border-b border-gray-200 p-3 text-center font-mono text-sm text-gray-400 dark:border-gray-700">
|
<div className="border-b border-gray-200 p-3 text-center font-mono text-sm text-gray-400 dark:border-gray-700">
|
||||||
{t('- showing {{count}} page(s) ', {
|
{t('- showing {{count}} page(s) ', {
|
||||||
count: size,
|
count: size,
|
||||||
totalFileNum: isLoadingMore ? '...' : folderChildren.length
|
totalFileNum: isLoadingMore ? '...' : folderChildren.length,
|
||||||
}) +
|
}) +
|
||||||
(isLoadingMore
|
(isLoadingMore
|
||||||
? t('of {{count}} file(s) -', { count: folderChildren.length, context: 'loading' })
|
? t('of {{count}} file(s) -', { count: folderChildren.length, context: 'loading' })
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { useTranslation } from 'next-i18next'
|
||||||
|
|
||||||
import siteConfig from '../config/site.config'
|
import siteConfig from '../config/site.config'
|
||||||
import SearchModal from './SearchModal'
|
import SearchModal from './SearchModal'
|
||||||
|
import SwitchLang from './SwitchLang'
|
||||||
import useDeviceOS from '../utils/useDeviceOS'
|
import useDeviceOS from '../utils/useDeviceOS'
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
|
@ -88,6 +89,8 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<SwitchLang />
|
||||||
|
|
||||||
{siteConfig.links.length !== 0 &&
|
{siteConfig.links.length !== 0 &&
|
||||||
siteConfig.links.map((l: { name: string; link: string }) => (
|
siteConfig.links.map((l: { name: string; link: string }) => (
|
||||||
<a
|
<a
|
||||||
|
|
65
components/SwitchLang.tsx
Normal file
65
components/SwitchLang.tsx
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { Menu, Transition } from '@headlessui/react'
|
||||||
|
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
|
// https://headlessui.dev/react/menu#integrating-with-next-js
|
||||||
|
const CustomLink = ({ href, children, as, locale, ...props }): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<Link href={href} as={as} locale={locale}>
|
||||||
|
<a {...props}>{children}</a>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const localeText = (locale: string): string => {
|
||||||
|
switch (locale) {
|
||||||
|
case 'en':
|
||||||
|
return '🇬🇧 English'
|
||||||
|
case 'zh-CN':
|
||||||
|
return '🇨🇳 简体中文'
|
||||||
|
default:
|
||||||
|
return '🇬🇧 English'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const SwitchLang = () => {
|
||||||
|
const { locales, pathname, query, asPath } = useRouter()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<Menu>
|
||||||
|
<Menu.Button className="flex items-center space-x-1.5 hover:opacity-80 dark:text-white">
|
||||||
|
<FontAwesomeIcon className="h-4 w-4" icon="language" />
|
||||||
|
<FontAwesomeIcon className="h-3 w-3" icon="chevron-down" />
|
||||||
|
</Menu.Button>
|
||||||
|
|
||||||
|
<Transition
|
||||||
|
as={Fragment}
|
||||||
|
enter="transition duration-100 ease-out"
|
||||||
|
enterFrom="transform scale-95 opacity-0"
|
||||||
|
enterTo="transform scale-100 opacity-100"
|
||||||
|
leave="transition duration-75 ease-out"
|
||||||
|
leaveFrom="transform scale-100 opacity-100"
|
||||||
|
leaveTo="transform scale-95 opacity-0"
|
||||||
|
>
|
||||||
|
<Menu.Items className="absolute top-0 right-0 z-20 mt-8 w-28 divide-y divide-gray-900 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-900 dark:text-white">
|
||||||
|
{locales!.map(locale => (
|
||||||
|
<Menu.Item key={locale}>
|
||||||
|
<CustomLink key={locale} href={{ pathname, query }} as={asPath} locale={locale}>
|
||||||
|
<div className="m-1 cursor-pointer rounded px-2 py-1 text-left text-sm font-medium hover:bg-blue-50 hover:text-blue-700 dark:hover:bg-blue-600/10 dark:hover:text-blue-400">
|
||||||
|
{localeText(locale)}
|
||||||
|
</div>
|
||||||
|
</CustomLink>
|
||||||
|
</Menu.Item>
|
||||||
|
))}
|
||||||
|
</Menu.Items>
|
||||||
|
</Transition>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SwitchLang
|
|
@ -11,7 +11,7 @@ export const layouts: Array<{ id: number; name: 'Grid' | 'List'; icon: IconProp
|
||||||
{ id: 2, name: 'Grid', icon: 'th' },
|
{ id: 2, name: 'Grid', icon: 'th' },
|
||||||
]
|
]
|
||||||
|
|
||||||
export const SwitchLayout = () => {
|
const SwitchLayout = () => {
|
||||||
const [preferredLayout, setPreferredLayout] = useLocalStorage('preferredLayout', layouts[0])
|
const [preferredLayout, setPreferredLayout] = useLocalStorage('preferredLayout', layouts[0])
|
||||||
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -35,7 +35,15 @@ export const SwitchLayout = () => {
|
||||||
</span>
|
</span>
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
|
|
||||||
<Transition as={Fragment} leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0">
|
<Transition
|
||||||
|
as={Fragment}
|
||||||
|
enter="transition duration-100 ease-out"
|
||||||
|
enterFrom="transform scale-95 opacity-0"
|
||||||
|
enterTo="transform scale-100 opacity-100"
|
||||||
|
leave="transition duration-75 ease-out"
|
||||||
|
leaveFrom="transform scale-100 opacity-100"
|
||||||
|
leaveTo="transform scale-95 opacity-0"
|
||||||
|
>
|
||||||
<Listbox.Options className="absolute right-0 z-20 mt-1 w-32 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-800">
|
<Listbox.Options className="absolute right-0 z-20 mt-1 w-32 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-800">
|
||||||
{layouts.map(layout => (
|
{layouts.map(layout => (
|
||||||
<Listbox.Option
|
<Listbox.Option
|
||||||
|
@ -67,3 +75,5 @@ export const SwitchLayout = () => {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default SwitchLayout
|
||||||
|
|
|
@ -7,7 +7,7 @@ import Navbar from '../components/Navbar'
|
||||||
import FileListing from '../components/FileListing'
|
import FileListing from '../components/FileListing'
|
||||||
import Footer from '../components/Footer'
|
import Footer from '../components/Footer'
|
||||||
import Breadcrumb from '../components/Breadcrumb'
|
import Breadcrumb from '../components/Breadcrumb'
|
||||||
import { SwitchLayout } from '../components/SwitchLayout'
|
import SwitchLayout from '../components/SwitchLayout'
|
||||||
|
|
||||||
export default function Folders() {
|
export default function Folders() {
|
||||||
const { query } = useRouter()
|
const { query } = useRouter()
|
||||||
|
@ -21,7 +21,7 @@ export default function Folders() {
|
||||||
<main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
|
<main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="mx-auto w-full max-w-5xl p-4">
|
<div className="mx-auto w-full max-w-5xl p-4">
|
||||||
<nav className="mb-4 flex items-center justify-between pl-1 space-x-3">
|
<nav className="mb-4 flex items-center justify-between space-x-3 pl-1">
|
||||||
<Breadcrumb query={query} />
|
<Breadcrumb query={query} />
|
||||||
<SwitchLayout />
|
<SwitchLayout />
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -37,7 +37,7 @@ export default function Folders() {
|
||||||
export async function getServerSideProps({ locale }) {
|
export async function getServerSideProps({ locale }) {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
...(await serverSideTranslations(locale, ['common']))
|
...(await serverSideTranslations(locale, ['common'])),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ import {
|
||||||
faThLarge,
|
faThLarge,
|
||||||
faThList,
|
faThList,
|
||||||
faHome,
|
faHome,
|
||||||
|
faLanguage,
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import * as Icons from '@fortawesome/free-brands-svg-icons'
|
import * as Icons from '@fortawesome/free-brands-svg-icons'
|
||||||
|
|
||||||
|
@ -107,6 +108,7 @@ library.add(
|
||||||
faTh,
|
faTh,
|
||||||
faThLarge,
|
faThLarge,
|
||||||
faThList,
|
faThList,
|
||||||
|
faLanguage,
|
||||||
...iconList
|
...iconList
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Navbar from '../components/Navbar'
|
||||||
import FileListing from '../components/FileListing'
|
import FileListing from '../components/FileListing'
|
||||||
import Footer from '../components/Footer'
|
import Footer from '../components/Footer'
|
||||||
import Breadcrumb from '../components/Breadcrumb'
|
import Breadcrumb from '../components/Breadcrumb'
|
||||||
import { SwitchLayout } from '../components/SwitchLayout'
|
import SwitchLayout from '../components/SwitchLayout'
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
|
@ -34,7 +34,7 @@ export default function Home() {
|
||||||
export async function getServerSideProps({ locale }) {
|
export async function getServerSideProps({ locale }) {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
...(await serverSideTranslations(locale, ['common']))
|
...(await serverSideTranslations(locale, ['common'])),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ specifiers:
|
||||||
eslint: 8.8.0
|
eslint: 8.8.0
|
||||||
eslint-config-next: 12.0.10
|
eslint-config-next: 12.0.10
|
||||||
eslint-config-prettier: ^8.3.0
|
eslint-config-prettier: ^8.3.0
|
||||||
i18next-parser: ^5.4.0
|
|
||||||
flv.js: ^1.6.2
|
flv.js: ^1.6.2
|
||||||
|
i18next-parser: ^5.4.0
|
||||||
ioredis: ^4.28.2
|
ioredis: ^4.28.2
|
||||||
jszip: ^3.7.1
|
jszip: ^3.7.1
|
||||||
next: ^12.0.10
|
next: ^12.0.10
|
||||||
|
@ -1134,13 +1134,14 @@ packages:
|
||||||
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/de-indent/1.0.2:
|
|
||||||
resolution: {integrity: sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=}
|
|
||||||
dev: true
|
|
||||||
/dayjs/1.10.7:
|
/dayjs/1.10.7:
|
||||||
resolution: {integrity: sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==}
|
resolution: {integrity: sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/de-indent/1.0.2:
|
||||||
|
resolution: {integrity: sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/debounce-promise/3.1.2:
|
/debounce-promise/3.1.2:
|
||||||
resolution: {integrity: sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==}
|
resolution: {integrity: sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -1757,6 +1758,7 @@ packages:
|
||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
readable-stream: 2.3.7
|
readable-stream: 2.3.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/flv.js/1.6.2:
|
/flv.js/1.6.2:
|
||||||
resolution: {integrity: sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==}
|
resolution: {integrity: sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in a new issue