refactor(directory): rewrite stylesheet with scss
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
'eslint:recommended',
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
}
|
||||
15
.eslintrc.json
Normal file
15
.eslintrc.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
1.0.17
|
||||
1.0.18
|
||||
@@ -2,40 +2,20 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import {
|
||||
createBrowserRouter,
|
||||
createRoutesFromElements,
|
||||
RouterProvider,
|
||||
Route
|
||||
} from "react-router-dom";
|
||||
import Root from "@/routes/root";
|
||||
import ErrorPage from "@/routes/error-page";
|
||||
import Root from "@/routes/Root";
|
||||
import Error from "@/routes/Error";
|
||||
import routes from "@/routes";
|
||||
import '@/App.css';
|
||||
import '@/App.scss';
|
||||
import 'reset-css';
|
||||
|
||||
const router = createBrowserRouter(
|
||||
createRoutesFromElements(
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<Root
|
||||
title={import.meta.env.VITE_APP_TITLE}
|
||||
/>
|
||||
}
|
||||
errorElement={<ErrorPage />}
|
||||
>
|
||||
{routes.map((route) => {
|
||||
return (
|
||||
<Route key={route.name}
|
||||
index={route.index}
|
||||
path={route.path}
|
||||
element={route.element}
|
||||
loader={route.loader}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</Route>
|
||||
)
|
||||
);
|
||||
const router = createBrowserRouter([{
|
||||
path: "/",
|
||||
element: <Root />,
|
||||
errorElement: <Error />,
|
||||
children: routes.filter((item) => item.routeable),
|
||||
},]);
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
@import 'https://fonts.cdnfonts.com/css/geometos';
|
||||
|
||||
:root {
|
||||
--text-color: rgba(255 255 255 87%);
|
||||
--text-color: rgba(255, 255, 255, 87%);
|
||||
--text-color-full: #fff;
|
||||
--secondary-text-color: #686a72;
|
||||
--date-color: rgba(255 255 255 20%);
|
||||
--date-color: rgba(255, 255, 255, 20%);
|
||||
--border-color: #707070;
|
||||
--link-highlight-color: #33b5e5;
|
||||
--drawer-background-color: rgba(0 0 0 88%);
|
||||
--drawer-background-color: rgba(0, 0, 0, 88%);
|
||||
--root-background-color: #131313;
|
||||
--home-item-hover-background-color: rgba(67 67 67 30%);
|
||||
--home-item-background-linear-gradient-color: rgba(255 255 255 10%);
|
||||
--home-item-outline-color: rgba(214 214 214 30%);
|
||||
--home-item-hover-background-color: rgba(67, 67, 67, 30%);
|
||||
--home-item-background-linear-gradient-color: rgba(255, 255, 255, 10%);
|
||||
--home-item-outline-color: rgba(214, 214, 214, 30%);
|
||||
--button-color: #666;
|
||||
|
||||
font-family: Geometos, "Noto Sans SC", sans-serif;
|
||||
@@ -1,14 +1,14 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classes from './main_border.module.scss';
|
||||
import classes from './scss/border.module.scss';
|
||||
|
||||
export default function MainBorder(props) {
|
||||
export default function Border(props) {
|
||||
return (
|
||||
<section className={classes.border}>
|
||||
{props.children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
MainBorder.propTypes = {
|
||||
Border.propTypes = {
|
||||
children: PropTypes.node,
|
||||
};
|
||||
@@ -2,7 +2,7 @@ import React, {
|
||||
useState
|
||||
} from 'react'
|
||||
import PropTypes from 'prop-types';
|
||||
import classes from './dropdown.module.scss'
|
||||
import classes from './scss/dropdown.module.scss'
|
||||
|
||||
export default function Dropdown(props) {
|
||||
const [hidden, setHidden] = useState(true)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, {
|
||||
useState,
|
||||
} from 'react'
|
||||
import classes from './popup.module.scss';
|
||||
import classes from './scss/popup.module.scss';
|
||||
import ReturnButton from '@/component/return_button';
|
||||
import MainBorder from '@/component/main_border';
|
||||
import Border from '@/component/border';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default function Popup(props) {
|
||||
@@ -20,7 +20,7 @@ export default function Popup(props) {
|
||||
<section className={classes.text}>{props.title}</section>
|
||||
<ReturnButton onClick={toggle} className={classes["return-button"]} />
|
||||
</section>
|
||||
<MainBorder />
|
||||
<Border />
|
||||
<section className={classes.content}>
|
||||
{props.children}
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classes from './return_button.module.scss'
|
||||
import classes from './scss/return_button.module.scss'
|
||||
|
||||
export default function ReturnButton(props) {
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
&.active {
|
||||
.text {
|
||||
color: currentColor;
|
||||
}
|
||||
@@ -41,6 +41,13 @@
|
||||
align-items: center;
|
||||
text-transform: uppercase;
|
||||
font-family: "Geometos", "Noto Sans SC", sans-serif;
|
||||
.return-button {
|
||||
color: var(--button-color);
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
&:hover {
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
.text {
|
||||
flex-grow: 1;
|
||||
@@ -66,13 +73,6 @@
|
||||
opacity: 0.5;
|
||||
visibility: visible;
|
||||
}
|
||||
.return-button {
|
||||
color: var(--button-color);
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
&:hover {
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
opacity: 1;
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classes from './switch.module.scss';
|
||||
import classes from './scss/switch.module.scss';
|
||||
import {
|
||||
useI18n
|
||||
} from '@/state/language'
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
useNavigate,
|
||||
useRouteError
|
||||
} from "react-router-dom";
|
||||
import './error-page.css'
|
||||
import header from '@/scss/root/header.module.scss'
|
||||
import classes from '@/scss/error/Error.module.scss'
|
||||
import { useAtom } from 'jotai'
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import Switch from '@/component/switch';
|
||||
@@ -27,7 +28,8 @@ const obj = config.files[Math.floor((Math.random() * config.files.length))]
|
||||
const filename = obj.key.replace("#", "%23")
|
||||
const padding = obj.paddings
|
||||
|
||||
export default function ErrorPage() {
|
||||
export default function Error() {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const _trackEvt = useUmami('/error')
|
||||
const error = useRouteError();
|
||||
const navigate = useNavigate();
|
||||
@@ -52,8 +54,8 @@ export default function ErrorPage() {
|
||||
useEffect(() => {
|
||||
console.log(error)
|
||||
fetch(`/${import.meta.env.VITE_DIRECTORY_FOLDER}/${filename}.json`).then(res => res.json()).then(data => {
|
||||
setSpineData(data)
|
||||
})
|
||||
setSpineData(data)
|
||||
})
|
||||
}, [error])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -130,10 +132,9 @@ export default function ErrorPage() {
|
||||
}, [playVoice, spineData]);
|
||||
|
||||
return (
|
||||
<section className='error-page'>
|
||||
<header className='header'>
|
||||
<section className={classes.error}>
|
||||
<header className={`${header.header} ${classes.header}`}>
|
||||
<ReturnButton
|
||||
className='return-button'
|
||||
onClick={() => navigate(-1, { replace: true })}
|
||||
/>
|
||||
<Switch
|
||||
@@ -143,11 +144,11 @@ export default function ErrorPage() {
|
||||
handleOnClick={() => setVoiceOn(!voiceOn)}
|
||||
/>
|
||||
</header>
|
||||
<main className='main'>
|
||||
<main className={classes.main}>
|
||||
{
|
||||
content.map((item, index) => {
|
||||
return (
|
||||
<section key={index} className='content'>
|
||||
<section key={index} className={classes.content}>
|
||||
<Typewriter
|
||||
words={[item]}
|
||||
cursor
|
||||
@@ -159,7 +160,7 @@ export default function ErrorPage() {
|
||||
})
|
||||
}
|
||||
<section
|
||||
className={`spine ${spineDone ? 'active' : ''}`}
|
||||
className={`${classes.spine} ${spineDone ? classes.active : ''}`}
|
||||
ref={spineRef}
|
||||
/>
|
||||
</main>
|
||||
@@ -10,9 +10,12 @@ import {
|
||||
Link,
|
||||
NavLink,
|
||||
useNavigate,
|
||||
ScrollRestoration,
|
||||
ScrollRestoration
|
||||
} from "react-router-dom";
|
||||
import './root.css'
|
||||
import classes from '@/scss/root/Root.module.scss'
|
||||
import header from '@/scss/root/header.module.scss'
|
||||
import footer from '@/scss/root/footer.module.scss'
|
||||
import drawer from '@/scss/root/drawer.module.scss'
|
||||
import routes from '@/routes'
|
||||
import { useConfig } from '@/state/config';
|
||||
import { useHeader } from '@/state/header';
|
||||
@@ -25,7 +28,7 @@ import { useBackgrounds } from '@/state/background';
|
||||
import Dropdown from '@/component/dropdown';
|
||||
import Popup from '@/component/popup';
|
||||
import ReturnButton from '@/component/return_button';
|
||||
import MainBorder from '@/component/main_border';
|
||||
import Border from '@/component/border';
|
||||
import CharIcon from '@/component/char_icon';
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
@@ -77,39 +80,39 @@ export default function Root() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className='header'>
|
||||
<header className={header.header}>
|
||||
<section
|
||||
className={`navButton ${drawerHidden ? '' : 'active'}`}
|
||||
className={`${header.navButton} ${drawerHidden ? '' : header.active}`}
|
||||
onClick={() => toggleDrawer()}
|
||||
>
|
||||
<section className='bar'></section>
|
||||
<section className='bar'></section>
|
||||
<section className='bar'></section>
|
||||
<section className={header.bar} />
|
||||
<section className={header.bar} />
|
||||
<section className={header.bar} />
|
||||
</section>
|
||||
<section className='spacer' />
|
||||
<section className='extra-area'>
|
||||
<section className={header.spacer} />
|
||||
<section className={header['extra-area']}>
|
||||
{extraArea}
|
||||
<LanguageDropdown />
|
||||
</section>
|
||||
</header>
|
||||
<nav className={`drawer ${drawerHidden ? '' : 'active'}`}>
|
||||
<nav className={`${drawer.drawer} ${drawerHidden ? '' : drawer.active}`}>
|
||||
<section
|
||||
className='links'
|
||||
className={drawer.links}
|
||||
>
|
||||
<DrawerDestinations
|
||||
toggleDrawer={toggleDrawer}
|
||||
/>
|
||||
</section>
|
||||
<section
|
||||
className={`overlay ${drawerHidden ? '' : 'active'}`}
|
||||
className={`${drawer.overlay} ${drawerHidden ? '' : drawer.active}`}
|
||||
onClick={() => toggleDrawer()}
|
||||
/>
|
||||
</nav>
|
||||
<main className='main'>
|
||||
<section className='main-header'>
|
||||
<section className='main-title'>
|
||||
<main className={classes.main}>
|
||||
<section className={classes.header}>
|
||||
<section className={classes.title}>
|
||||
{headerIcon && (
|
||||
<section className='main-icon'>
|
||||
<section className={classes.icon}>
|
||||
<CharIcon
|
||||
type={headerIcon}
|
||||
viewBox={
|
||||
@@ -120,7 +123,7 @@ export default function Root() {
|
||||
)}
|
||||
{title}
|
||||
</section>
|
||||
<section className='main-tab'>
|
||||
<section className={classes.tab}>
|
||||
{headerTabs}
|
||||
</section>
|
||||
</section>
|
||||
@@ -140,32 +143,32 @@ function FooterElement() {
|
||||
|
||||
return useMemo(() => {
|
||||
return (
|
||||
<footer className='footer'>
|
||||
<section className='links section'>
|
||||
<section className="item">
|
||||
<footer className={footer.footer}>
|
||||
<section className={`${footer.links} ${footer.section}`}>
|
||||
<section className={footer.item}>
|
||||
<Popup
|
||||
className='link'
|
||||
className={footer.link}
|
||||
title={i18n('disclaimer')}
|
||||
>
|
||||
{i18n('disclaimer_content')}
|
||||
</Popup>
|
||||
</section>
|
||||
<section className="item">
|
||||
<Link reloadDocument to="https://privacy.halyul.dev" target="_blank" className='link'>{i18n('privacy_policy')}</Link>
|
||||
<section className={footer.item}>
|
||||
<Link reloadDocument to="https://privacy.halyul.dev" target="_blank" className={footer.link}>{i18n('privacy_policy')}</Link>
|
||||
</section>
|
||||
<section className="item">
|
||||
<Link reloadDocument to="https://github.com/Halyul/aklive2d" target="_blank" className='link'>GitHub</Link>
|
||||
<section className={footer.item}>
|
||||
<Link reloadDocument to="https://github.com/Halyul/aklive2d" target="_blank" className={footer.link}>GitHub</Link>
|
||||
</section>
|
||||
<section className="item">
|
||||
<section className={footer.item}>
|
||||
<Popup
|
||||
className='link'
|
||||
className={footer.link}
|
||||
title={i18n('contact_us')}
|
||||
>
|
||||
ak#halyul.dev
|
||||
</Popup>
|
||||
</section>
|
||||
</section>
|
||||
<section className='copyright section' onDoubleClick={() => {
|
||||
<section className={`${footer.copyright} ${footer.section}`} onDoubleClick={() => {
|
||||
navigate('/error')
|
||||
}}>
|
||||
<span>Spine Runtimes © 2013 - 2019 Esoteric Software LLC</span>
|
||||
@@ -191,7 +194,7 @@ function DrawerDestinations({ toggleDrawer }) {
|
||||
key={item.name}
|
||||
to={item.path}
|
||||
target="_blank"
|
||||
className="link"
|
||||
className={drawer.link}
|
||||
onClick={() => toggleDrawer(false)}
|
||||
>
|
||||
<section>
|
||||
@@ -207,7 +210,9 @@ function DrawerDestinations({ toggleDrawer }) {
|
||||
<NavLink
|
||||
to={item.path}
|
||||
key={item.name}
|
||||
className="link"
|
||||
className={({ isActive, }) =>
|
||||
`${drawer.link} ${isActive ? drawer.active : ''}`
|
||||
}
|
||||
onClick={() => toggleDrawer(false)}
|
||||
>
|
||||
<section>
|
||||
@@ -253,15 +258,15 @@ function HeaderTabsElement({ item }) {
|
||||
|
||||
return (
|
||||
<section
|
||||
className={`main-tab-item ${currentTab === item.key ? 'active' : ''}`}
|
||||
className={`${classes.item} ${currentTab === item.key ? classes.active : ''}`}
|
||||
onClick={(e) => {
|
||||
setCurrentTab(item.key)
|
||||
item.onClick && item.onClick(e, currentTab)
|
||||
}}
|
||||
style={item.style}
|
||||
>
|
||||
<section className='main-tab-text-wrapper'>
|
||||
<span className='text'>{i18n(item.key)}</span>
|
||||
<section className={classes['text-wrapper']}>
|
||||
<span>{i18n(item.key)}</span>
|
||||
</section>
|
||||
</section>
|
||||
)
|
||||
@@ -275,12 +280,12 @@ function HeaderReturnButton() {
|
||||
|
||||
return useMemo(() => {
|
||||
return (
|
||||
<MainBorder>
|
||||
<Border>
|
||||
<ReturnButton
|
||||
className='return-button'
|
||||
className={classes['return-button']}
|
||||
onClick={() => navigate("/")}
|
||||
/>
|
||||
</MainBorder>
|
||||
</Border>
|
||||
)
|
||||
}, [navigate])
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
.error-page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 16px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.error-page .header {
|
||||
padding: 1rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.error-page .main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding-top: 10rem;
|
||||
font-size: 3rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.error-page .spine {
|
||||
max-width: 600px;
|
||||
flex: 1;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.error-page .spine.active {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.error-page .main {
|
||||
padding-top: 6rem;
|
||||
}
|
||||
.error-page .content {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.error-page .main {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
.error-page .content {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import Home from "@/routes/path/home";
|
||||
import Operator from "@/routes/path/operator";
|
||||
import Changelogs from "@/routes/path/changelogs";
|
||||
import Home from "@/routes/path/Home";
|
||||
import Operator from "@/routes/path/Operator";
|
||||
import Changelogs from "@/routes/path/Changelogs";
|
||||
|
||||
export default [
|
||||
{
|
||||
@@ -9,24 +9,28 @@ export default [
|
||||
index: true,
|
||||
name: "home",
|
||||
element: <Home />,
|
||||
inDrawer: true
|
||||
inDrawer: true,
|
||||
routeable: true
|
||||
}, {
|
||||
path: "changelogs",
|
||||
index: false,
|
||||
name: "changelogs",
|
||||
element: <Changelogs />,
|
||||
inDrawer: true
|
||||
inDrawer: true,
|
||||
routeable: true
|
||||
}, {
|
||||
path: "https://ak.hypergryph.com/archive/dynamicCompile/",
|
||||
index: false,
|
||||
name: "offical_page",
|
||||
element: <a/>,
|
||||
inDrawer: true
|
||||
inDrawer: true,
|
||||
routeable: false
|
||||
}, {
|
||||
path: ":key",
|
||||
index: false,
|
||||
name: "operator",
|
||||
element: <Operator />,
|
||||
inDrawer: false
|
||||
inDrawer: false,
|
||||
routeable: true
|
||||
},
|
||||
]
|
||||
@@ -3,11 +3,11 @@ import React, {
|
||||
useEffect,
|
||||
useMemo
|
||||
} from 'react'
|
||||
import classes from './changelogs.module.scss'
|
||||
import classes from '@/scss/changelogs/Changelogs.module.scss'
|
||||
import { useHeader } from '@/state/header';
|
||||
import { useAppbar } from '@/state/appbar';
|
||||
import useUmami from '@parcellab/react-use-umami'
|
||||
import MainBorder from '@/component/main_border';
|
||||
import Border from '@/component/border';
|
||||
|
||||
export default function Changelogs() {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
@@ -59,7 +59,7 @@ export default function Changelogs() {
|
||||
</section>
|
||||
<section className={classes.date}>{item.date}</section>
|
||||
</section>
|
||||
<MainBorder />
|
||||
<Border />
|
||||
</section>
|
||||
)
|
||||
})
|
||||
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
|
||||
import {
|
||||
NavLink,
|
||||
} from "react-router-dom";
|
||||
import classes from './home.module.scss'
|
||||
import classes from '@/scss/home/Home.module.scss'
|
||||
import { useConfig } from '@/state/config';
|
||||
import {
|
||||
useLanguage
|
||||
@@ -19,7 +19,7 @@ import useAudio from '@/libs/voice';
|
||||
import { useAtom } from 'jotai'
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import CharIcon from '@/component/char_icon';
|
||||
import MainBorder from '@/component/main_border';
|
||||
import Border from '@/component/border';
|
||||
import useUmami from '@parcellab/react-use-umami';
|
||||
import Switch from '@/component/switch';
|
||||
|
||||
@@ -76,7 +76,7 @@ export default function Home() {
|
||||
})}
|
||||
<section className={classes.date}>{v[0].date}</section>
|
||||
</section>
|
||||
<MainBorder />
|
||||
<Border />
|
||||
</section>
|
||||
)
|
||||
})
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
useNavigate,
|
||||
Link
|
||||
} from "react-router-dom";
|
||||
import './operator.css'
|
||||
import classes from '@/scss/operator/Operator.module.scss'
|
||||
import { useConfig } from '@/state/config';
|
||||
import {
|
||||
useLanguage,
|
||||
@@ -22,7 +22,7 @@ import useAudio from '@/libs/voice';
|
||||
import useUmami from '@parcellab/react-use-umami'
|
||||
import spine from '!/libs/spine-player'
|
||||
import '!/libs/spine-player.css'
|
||||
import MainBorder from '@/component/main_border';
|
||||
import Border from '@/component/border';
|
||||
import { useI18n } from '@/state/language';
|
||||
|
||||
const getVoiceFoler = (lang) => {
|
||||
@@ -341,9 +341,9 @@ export default function Operator() {
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="operator">
|
||||
<section className="spine-player-wrapper">
|
||||
<section className="spine-settings" style={{
|
||||
<section className={classes.operator}>
|
||||
<section className={classes.main}>
|
||||
<section className={classes.settings} style={{
|
||||
color: config?.color
|
||||
}}>
|
||||
{
|
||||
@@ -351,17 +351,17 @@ export default function Operator() {
|
||||
if (item.options.length === 0) return null
|
||||
return (
|
||||
<section key={item.name}>
|
||||
<section className='settings-title-wrapper'>
|
||||
<section className='text'>{i18n(item.name)}</section>
|
||||
<section className={classes.title}>
|
||||
<section className={classes.text}>{i18n(item.name)}</section>
|
||||
</section>
|
||||
<section className='settings-content-wrapper styled-selection'>
|
||||
<section className={classes['styled-selection']}>
|
||||
{item.options.map((option) => {
|
||||
return (
|
||||
<section className={`content ${option.activeRule && option.activeRule() ? 'active' : ''}`} onClick={(e) => option.onClick(e)} key={option.name}>
|
||||
<section className='content-text'>
|
||||
<section className="outline" />
|
||||
<section className='text'>{i18n(option.name)}</section>
|
||||
<section className='tick-icon' />
|
||||
<section className={`${classes.content} ${option.activeRule && option.activeRule() ? classes.active : ''}`} onClick={(e) => option.onClick(e)} key={option.name}>
|
||||
<section className={classes.option}>
|
||||
<section className={classes.outline} />
|
||||
<section className={classes.text}>{i18n(option.name)}</section>
|
||||
<section className={classes['tick-icon']} />
|
||||
</section>
|
||||
</section>
|
||||
)
|
||||
@@ -372,23 +372,22 @@ export default function Operator() {
|
||||
})
|
||||
}
|
||||
<section>
|
||||
<section className='settings-title-wrapper'>
|
||||
<section className='text'>{i18n('external_links')}</section>
|
||||
<section className={classes.title}>
|
||||
<section className={classes.text}>{i18n('external_links')}</section>
|
||||
</section>
|
||||
<section className='settings-content-wrapper styled-selection'>
|
||||
<section className={classes['styled-selection']}>
|
||||
<Link
|
||||
reloadDocument
|
||||
to={`./index.html?settings`}
|
||||
target='_blank'
|
||||
className='extra-links-item'
|
||||
style={{
|
||||
color: config?.color
|
||||
}}
|
||||
>
|
||||
<section className='content'>
|
||||
<section className='content-text'>
|
||||
<section className="outline" />
|
||||
<section className='text'>
|
||||
<section className={classes.content}>
|
||||
<section className={classes.option}>
|
||||
<section className={classes.outline} />
|
||||
<section className={classes.text}>
|
||||
{i18n('web_version')}
|
||||
</section>
|
||||
</section>
|
||||
@@ -400,14 +399,13 @@ export default function Operator() {
|
||||
reloadDocument
|
||||
to={`https://steamcommunity.com/sharedfiles/filedetails/?id=${config.workshopId}`}
|
||||
target='_blank'
|
||||
className='extra-links-item'
|
||||
style={{
|
||||
color: config?.color
|
||||
}}>
|
||||
<section className='content'>
|
||||
<section className='content-text'>
|
||||
<section className="outline" />
|
||||
<section className='text'>
|
||||
<section className={classes.content}>
|
||||
<section className={classes.option}>
|
||||
<section className={classes.outline} />
|
||||
<section className={classes.text}>
|
||||
{i18n('steam_workshop')}
|
||||
</section>
|
||||
</section>
|
||||
@@ -418,27 +416,27 @@ export default function Operator() {
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section className="spine-container" style={currentBackground && {
|
||||
<section className={classes.container} style={currentBackground && {
|
||||
backgroundImage: `url(/${key}/assets/${import.meta.env.VITE_BACKGROUND_FOLDER}/${currentBackground})`
|
||||
}} >
|
||||
{
|
||||
config && (
|
||||
<img src={`/${config.link}/assets/${config.logo}.png`} alt={config?.codename[language]} className='operator-logo' />
|
||||
<img src={`/${config.link}/assets/${config.logo}.png`} alt={config?.codename[language]} className={classes.logo} />
|
||||
)
|
||||
}
|
||||
<section ref={spineRef} />
|
||||
<section ref={spineRef} className={classes.wrapper} />
|
||||
{currentVoiceId && subtitleObj && (
|
||||
<section className={`voice-wrapper${hideSubtitle ? '' : ' active'}`}>
|
||||
<section className='voice-title'>{subtitleObj[currentVoiceId]?.title}</section>
|
||||
<section className='voice-subtitle'>
|
||||
<section className={`${classes.voice} ${hideSubtitle ? '' : classes.active }`}>
|
||||
<section className={classes.type}>{subtitleObj[currentVoiceId]?.title}</section>
|
||||
<section className={classes.subtitle}>
|
||||
<span>{subtitleObj[currentVoiceId]?.text}</span>
|
||||
<span className='voice-triangle' />
|
||||
<span className={classes.triangle} />
|
||||
</section>
|
||||
</section>)
|
||||
}
|
||||
</section>
|
||||
</section>
|
||||
<MainBorder />
|
||||
<Border />
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
@use 'tab_base';
|
||||
@@ -1,241 +0,0 @@
|
||||
.operator .spine-player-wrapper {
|
||||
padding: 3rem 0 2rem 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.operator .spine-container {
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.operator .spine-container:before {
|
||||
content: "";
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
.operator .spine-container .spine-player {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.operator .spine-settings {
|
||||
margin-right: 1.5rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.operator .text {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.operator .spine-settings .settings-title-wrapper {
|
||||
font-size: 1.25rem;
|
||||
border-left: 3px solid currentColor;
|
||||
padding-left: 0.75rem;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
|
||||
.operator .styled-selection {
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content {
|
||||
padding: 0.8rem 0;
|
||||
cursor: pointer;
|
||||
transition: transform cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text {
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
transform: translate3d(0, 0, 1px);
|
||||
font-size: 1rem;
|
||||
padding: 0.44rem 2.25rem 0.44rem 0.63rem;
|
||||
background-color: var(--home-item-hover-background-color);
|
||||
background-image: repeating-linear-gradient(
|
||||
90deg,
|
||||
var(--home-item-background-linear-gradient-color) 0,
|
||||
var(--home-item-background-linear-gradient-color) 1px,
|
||||
transparent 1px,
|
||||
transparent 4px
|
||||
);
|
||||
transition: transform cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content:hover,
|
||||
.operator .styled-selection .content.active {
|
||||
transform: translate3d(6px, 0, 1px);
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text .outline {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: -6px;
|
||||
top: -6px;
|
||||
border: var(--home-item-outline-color) 1px dashed;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text::before,
|
||||
.operator .styled-selection .content .content-text .outline {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s,
|
||||
visibility cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text .outline::before,
|
||||
.operator .styled-selection .content .content-text .outline::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
border-left: var(--text-color) solid 2px;
|
||||
border-right: var(--text-color) solid 2px;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text .outline::before {
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text .outline::after {
|
||||
bottom: -2px;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text::before {
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(90deg, transparent, currentColor);
|
||||
}
|
||||
|
||||
.operator .styled-selection .content:hover .content-text::before,
|
||||
.operator .styled-selection .content.active .content-text::before,
|
||||
.operator .styled-selection .content:hover .content-text .outline,
|
||||
.operator .styled-selection .content.active .content-text .outline,
|
||||
.operator .styled-selection .content.active .content-text .tick-icon {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.operator .styled-selection .content .content-text .tick-icon {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
right: 0.31rem;
|
||||
top: 50%;
|
||||
width: 0.5rem;
|
||||
height: 1rem;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s,
|
||||
visibility cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
border-right: var(--text-color) solid 0.25rem;
|
||||
border-bottom: var(--text-color) solid 0.25rem;
|
||||
transform: translate(-50%, -70%) rotate(45deg);
|
||||
}
|
||||
|
||||
.operator .voice-wrapper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 30%;
|
||||
z-index: 1;
|
||||
max-width: 480px;
|
||||
width: 85%;
|
||||
opacity: 0;
|
||||
margin: 16px;
|
||||
transition: all 0.5s cubic-bezier(0.65, 0.05, 0.36, 1);
|
||||
visibility: hidden;
|
||||
font-family: 'Noto Sans', sans-serif;
|
||||
}
|
||||
|
||||
.operator .voice-wrapper.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.operator .voice-wrapper .voice-title {
|
||||
background-color: #9e9e9e;
|
||||
color: #000;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -8px;
|
||||
padding: 2px 8px;
|
||||
font-size: 14px;
|
||||
max-width: 180px;
|
||||
width: 65%;
|
||||
box-shadow: 0 3px 6px #00000080;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.operator .voice-wrapper .voice-subtitle {
|
||||
background-color: #000000a6;
|
||||
color: #fff;
|
||||
padding: 16px;
|
||||
font-size: 18px;
|
||||
box-shadow: 0 6px 12px #00000080;
|
||||
position: relative;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.operator .voice-wrapper .voice-triangle {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
right: 8px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 8px 8px 8px 8px;
|
||||
border-color: white transparent transparent transparent;
|
||||
}
|
||||
|
||||
.operator .operator-logo {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 30%;
|
||||
height: auto;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.operator .spine-container {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.operator .spine-container:before {
|
||||
content: "";
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
.operator .spine-container .spine-player {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
.operator .spine-player-wrapper {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.operator .voice-wrapper {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,294 +0,0 @@
|
||||
.main {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
padding-bottom: 3rem;
|
||||
margin: 0 auto;
|
||||
width: 70%;
|
||||
max-width: 100rem;
|
||||
padding-top: 5rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
width: auto;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 1rem;
|
||||
z-index: 3;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.header .spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.header .dropdown {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.navButton {
|
||||
padding: 0.5rem;
|
||||
font-size: 2rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.navButton .bar {
|
||||
width: 2rem;
|
||||
height: 0.2rem;
|
||||
background-color: var(--text-color);
|
||||
transition: transform cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
.navButton .bar:nth-child(1) {
|
||||
transform: translate(0, -200%);
|
||||
}
|
||||
|
||||
.navButton .bar:nth-child(3) {
|
||||
transform: translate(0, 200%);
|
||||
}
|
||||
|
||||
.navButton.active .bar:nth-child(1) {
|
||||
transform: translate(0, 100%) rotateZ(45deg) scaleX(0.5) translate(-50%);
|
||||
}
|
||||
|
||||
.navButton.active .bar:nth-child(2) {
|
||||
transform: rotateZ(-45deg);
|
||||
}
|
||||
|
||||
.navButton.active .bar:nth-child(3) {
|
||||
transform: translate(0, -100%) rotateZ(45deg) scaleX(0.5) translate(50%);
|
||||
}
|
||||
|
||||
.extra-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.navButton,
|
||||
.extra-area {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.drawer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -15rem;
|
||||
width: 15rem;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
transition: left cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.drawer .links {
|
||||
padding: 8rem 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--drawer-background-color);
|
||||
height: 100%;
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
.drawer .overlay {
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.drawer.active {
|
||||
pointer-events: all;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.drawer .link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.2rem;
|
||||
color: var(--text-color);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.drawer .link:hover {
|
||||
color: var(--link-highlight-color);
|
||||
}
|
||||
|
||||
.drawer .link.active {
|
||||
color: var(--link-highlight-color);
|
||||
}
|
||||
|
||||
.main .main-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.main .main-header .main-title {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.main .main-header .main-title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.main .main-header .main-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.main .main-header .main-tab {
|
||||
flex: auto;
|
||||
white-space: pre;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.main .main-header .main-tab .main-tab-item {
|
||||
font-size: 1.25rem;
|
||||
line-height: 3em;
|
||||
font-weight: 700;
|
||||
padding: 0 1rem;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border-bottom: 0.3rem solid transparent;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.main .main-header .main-tab .main-tab-item .main-tab-text-wrapper {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.main .main-header .main-tab .main-tab-item.active .main-tab-text-wrapper,
|
||||
.main .main-header .main-tab .main-tab-item:hover .main-tab-text-wrapper,
|
||||
.main .main-header .main-tab .main-tab-item.active .text,
|
||||
.main .main-header .main-tab .main-tab-item:hover .text {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.main .main-header .main-tab .main-tab-item.active {
|
||||
border-bottom-color: currentColor;
|
||||
}
|
||||
|
||||
.main .main-header .main-tab .main-tab-item.active,
|
||||
.main .main-header .main-tab .main-tab-item:hover {
|
||||
color: var(--link-highlight-color);
|
||||
}
|
||||
|
||||
.main .main-header .main-tab .main-tab-item .main-tab-text-wrapper {
|
||||
color: var(--text-color);
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
.main .main-icon {
|
||||
width: 3.88rem;
|
||||
margin-right: 1.88rem;
|
||||
fill: var(--text-color);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.main .return-button {
|
||||
position: absolute;
|
||||
right: -4rem;
|
||||
bottom: -24px;
|
||||
color: var(--button-color);
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.main .return-button {
|
||||
right: -3.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.main .return-button:hover {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.footer {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.footer .section {
|
||||
border-top: 1px solid var(--border-color);
|
||||
padding: 1rem 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
font-family: "Noto Sans SC", sans-serif;
|
||||
}
|
||||
|
||||
.footer .links {
|
||||
flex-direction: row;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.footer .links .item {
|
||||
padding: 0 1rem;
|
||||
border-left: 2px solid var(--border-color);
|
||||
height: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.footer .links .item:first-of-type {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.footer .copyright {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
font-size: 12px;
|
||||
}
|
||||
13
directory/src/scss/_main_share.scss
Normal file
13
directory/src/scss/_main_share.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.main {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
padding-bottom: 3rem;
|
||||
margin: 0 auto;
|
||||
width: 70%;
|
||||
max-width: 100rem;
|
||||
padding-top: 5rem;
|
||||
min-height: calc(100vh - 5rem - 3rem);
|
||||
}
|
||||
@@ -1,3 +1,14 @@
|
||||
%outline-share {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: -3px;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
border-left: var(--text-color) solid 3px;
|
||||
border-right: var(--text-color) solid 3px;
|
||||
}
|
||||
|
||||
.group {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
@@ -50,24 +61,13 @@
|
||||
border: var(--home-item-outline-color) 1px dashed;
|
||||
padding: 6px;
|
||||
|
||||
%share {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: -3px;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
border-left: var(--text-color) solid 3px;
|
||||
border-right: var(--text-color) solid 3px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
@extend %share;
|
||||
&:before {
|
||||
@extend %outline-share;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
@extend %share;
|
||||
&:after {
|
||||
@extend %outline-share;
|
||||
bottom: -3px;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
@use 'tab_base';
|
||||
@use '@/scss/_page_base.scss';
|
||||
|
||||
.group {
|
||||
flex-direction: column;
|
||||
54
directory/src/scss/error/Error.module.scss
Normal file
54
directory/src/scss/error/Error.module.scss
Normal file
@@ -0,0 +1,54 @@
|
||||
@use '@/scss/_main_share.scss';
|
||||
|
||||
.error {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 16px;
|
||||
user-select: none;
|
||||
|
||||
.header {
|
||||
padding: 1rem;
|
||||
justify-content: space-between;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding-top: 10rem;
|
||||
font-size: 3rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.spine {
|
||||
max-width: 600px;
|
||||
flex: 1;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
||||
&.active {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.main {
|
||||
padding-top: 6rem;
|
||||
}
|
||||
.content {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.main {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
.content {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
directory/src/scss/home/Home.module.scss
Normal file
1
directory/src/scss/home/Home.module.scss
Normal file
@@ -0,0 +1 @@
|
||||
@use '@/scss/_page_base.scss';
|
||||
95
directory/src/scss/root/Root.module.scss
Normal file
95
directory/src/scss/root/Root.module.scss
Normal file
@@ -0,0 +1,95 @@
|
||||
@use '@/scss/_main_share.scss';
|
||||
|
||||
.main {
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
padding-right: 2rem;
|
||||
.title {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.2em;
|
||||
|
||||
.icon {
|
||||
width: 3.88rem;
|
||||
margin-right: 1.88rem;
|
||||
fill: var(--text-color);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: auto;
|
||||
white-space: pre;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
.item {
|
||||
font-size: 1.25rem;
|
||||
line-height: 3em;
|
||||
font-weight: 700;
|
||||
padding: 0 1rem;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border-bottom: 0.3rem solid transparent;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.text-wrapper {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--text-color);
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
color: var(--link-highlight-color);
|
||||
.text-wrapper,
|
||||
.text {
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
border-bottom-color: currentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.return-button {
|
||||
position: absolute;
|
||||
right: -4rem;
|
||||
bottom: -24px;
|
||||
color: var(--button-color);
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
right: -3.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
54
directory/src/scss/root/drawer.module.scss
Normal file
54
directory/src/scss/root/drawer.module.scss
Normal file
@@ -0,0 +1,54 @@
|
||||
.drawer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -15rem;
|
||||
width: 15rem;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
transition: left cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
user-select: none;
|
||||
|
||||
.links {
|
||||
padding: 8rem 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--drawer-background-color);
|
||||
height: 100%;
|
||||
width: 15rem;
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.2rem;
|
||||
color: var(--text-color);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
text-transform: uppercase;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
color: var(--link-highlight-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
z-index: 2;
|
||||
}
|
||||
&.active {
|
||||
pointer-events: all;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
35
directory/src/scss/root/footer.module.scss
Normal file
35
directory/src/scss/root/footer.module.scss
Normal file
@@ -0,0 +1,35 @@
|
||||
.footer {
|
||||
user-select: none;
|
||||
.section {
|
||||
border-top: 1px solid var(--border-color);
|
||||
padding: 1rem 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
font-family: "Noto Sans SC", sans-serif;
|
||||
}
|
||||
.links {
|
||||
flex-direction: row;
|
||||
height: 2rem;
|
||||
|
||||
.item {
|
||||
padding: 0 1rem;
|
||||
border-left: 2px solid var(--border-color);
|
||||
height: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
&:first-of-type {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
74
directory/src/scss/root/header.module.scss
Normal file
74
directory/src/scss/root/header.module.scss
Normal file
@@ -0,0 +1,74 @@
|
||||
.header {
|
||||
width: auto;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 1rem;
|
||||
z-index: 3;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
pointer-events: none;
|
||||
|
||||
.spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.extra-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.navButton {
|
||||
padding: 0.5rem;
|
||||
font-size: 2rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
z-index: 2;
|
||||
pointer-events: auto;
|
||||
|
||||
.bar {
|
||||
width: 2rem;
|
||||
height: 0.2rem;
|
||||
background-color: var(--text-color);
|
||||
transition: transform cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
|
||||
|
||||
&:nth-child(1) {
|
||||
transform: translate(0, -200%);
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
transform: translate(0, 200%);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
.bar {
|
||||
&:nth-child(1) {
|
||||
transform: translate(0, 100%) rotateZ(45deg) scaleX(0.5) translate(-50%);
|
||||
}
|
||||
&:nth-child(2) {
|
||||
transform: rotateZ(-45deg);
|
||||
}
|
||||
&:nth-child(3) {
|
||||
transform: translate(0, -100%) rotateZ(45deg) scaleX(0.5) translate(50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "**/node_modules", "dist", "operator", "release"]
|
||||
}
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "**/node_modules", "dist", "operator", "release"]
|
||||
}
|
||||
|
||||
@@ -54,6 +54,32 @@ export default function ({ backgrounds, charwordTable }) {
|
||||
})
|
||||
})
|
||||
|
||||
writeSync((new EnvGenerator()).generate([
|
||||
{
|
||||
key: "app_title",
|
||||
value: __config.directory.title
|
||||
}, {
|
||||
key: "app_voice_url",
|
||||
value: __config.directory.voice
|
||||
}, {
|
||||
key: "voice_folders",
|
||||
value: JSON.stringify(__config.folder.voice)
|
||||
}, {
|
||||
key: "directory_folder",
|
||||
value: JSON.stringify(__config.folder.directory)
|
||||
}
|
||||
, {
|
||||
key: "background_folder",
|
||||
value: JSON.stringify(__config.folder.background)
|
||||
}, {
|
||||
key: "available_operators",
|
||||
value: JSON.stringify(Object.keys(__config.operators))
|
||||
}, {
|
||||
key: "error_files",
|
||||
value: JSON.stringify(__config.directory.error).replace('#', '%23')
|
||||
}
|
||||
]), path.join(__projetRoot, 'directory', '.env'))
|
||||
|
||||
writeSync(JSON.stringify(directoryJson, null), path.join(targetFolder, "directory.json"))
|
||||
writeSync(JSON.stringify(versionJson, null), path.join(targetFolder, "version.json"))
|
||||
writeSync(JSON.stringify(changelogsArray, null), path.join(targetFolder, "changelogs.json"))
|
||||
|
||||
@@ -148,31 +148,6 @@ class ViteRunner {
|
||||
global.__config = this.#globalConfig
|
||||
}
|
||||
const directoryDir = path.resolve(__projetRoot, 'directory')
|
||||
writeSync((new EnvGenerator()).generate([
|
||||
{
|
||||
key: "app_title",
|
||||
value: this.#globalConfig.directory.title
|
||||
}, {
|
||||
key: "app_voice_url",
|
||||
value: this.#globalConfig.directory.voice
|
||||
}, {
|
||||
key: "voice_folders",
|
||||
value: JSON.stringify(this.#globalConfig.folder.voice)
|
||||
}, {
|
||||
key: "directory_folder",
|
||||
value: JSON.stringify(this.#globalConfig.folder.directory)
|
||||
}
|
||||
, {
|
||||
key: "background_folder",
|
||||
value: JSON.stringify(this.#globalConfig.folder.background)
|
||||
}, {
|
||||
key: "available_operators",
|
||||
value: JSON.stringify(Object.keys(this.#globalConfig.operators))
|
||||
}, {
|
||||
key: "error_files",
|
||||
value: JSON.stringify(this.#globalConfig.directory.error).replace('#', '%23')
|
||||
}
|
||||
]), path.join(directoryDir, '.env'))
|
||||
this.#mode = process.argv[3]
|
||||
const publicDir = path.resolve(__projetRoot, this.#globalConfig.folder.release)
|
||||
const assetsDir = '_directory'
|
||||
|
||||
Reference in New Issue
Block a user