mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-23 13:37:42 +00:00
Implement navigation and the page system
This commit is contained in:
parent
30c8d01c9e
commit
e0b1f275dd
@ -13,12 +13,15 @@
|
|||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0",
|
||||||
|
|
||||||
|
"events": "^3.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^4.9.3",
|
"typescript": "^4.9.3",
|
||||||
"@types/react": "^18.0.28",
|
"@types/react": "^18.0.28",
|
||||||
"@types/react-dom": "^18.0.11",
|
"@types/react-dom": "^18.0.11",
|
||||||
|
"@types/events": "^3.0.0",
|
||||||
|
|
||||||
"vite": "^4.2.0",
|
"vite": "^4.2.0",
|
||||||
"vite-plugin-svgr": "^2.4.0",
|
"vite-plugin-svgr": "^2.4.0",
|
||||||
|
92
src/handbook/src/backend/events.ts
Normal file
92
src/handbook/src/backend/events.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { EventEmitter } from "events";
|
||||||
|
import { Page } from "@backend/types";
|
||||||
|
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const navigation = new EventEmitter();
|
||||||
|
|
||||||
|
let navStack: Page[] = [];
|
||||||
|
let currentPage: number | null = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initial setup function for this file.
|
||||||
|
*/
|
||||||
|
export function setup(): void {
|
||||||
|
// Check if the window's href is a page.
|
||||||
|
const page = window.location.href.split("/").pop();
|
||||||
|
if (page == undefined) return;
|
||||||
|
|
||||||
|
// Convert the page to a Page type.
|
||||||
|
const pageName = page.charAt(0).toUpperCase() + page.slice(1);
|
||||||
|
const pageType = pageName as Page;
|
||||||
|
|
||||||
|
// Navigate to the page.
|
||||||
|
navigate(pageType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a navigation listener.
|
||||||
|
*
|
||||||
|
* @param listener The listener to add.
|
||||||
|
*/
|
||||||
|
export function addNavListener(listener: (page: Page) => void) {
|
||||||
|
navigation.on("navigate", listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a navigation listener.
|
||||||
|
*
|
||||||
|
* @param listener The listener to remove.
|
||||||
|
*/
|
||||||
|
export function removeNavListener(listener: (page: Page) => void) {
|
||||||
|
navigation.off("navigate", listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to a page.
|
||||||
|
* Returns the last page.
|
||||||
|
*
|
||||||
|
* @param page The page to navigate to.
|
||||||
|
* @param update Whether to update the state or not.
|
||||||
|
*/
|
||||||
|
export function navigate(page: Page, update: boolean = true): Page | null {
|
||||||
|
// Navigate to the new page.
|
||||||
|
const lastPage = currentPage;
|
||||||
|
navigation.emit("navigate", page);
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
// Set the current page.
|
||||||
|
navStack.push(page);
|
||||||
|
currentPage = navStack.length - 1;
|
||||||
|
// Add the page to the window history.
|
||||||
|
window.history.pushState(page, page, "/" + page.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastPage ? navStack[lastPage] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Goes back or forward in the navigation stack.
|
||||||
|
*
|
||||||
|
* @param forward Whether to go forward or not.
|
||||||
|
*/
|
||||||
|
export function go(forward: boolean): void {
|
||||||
|
if (currentPage == undefined) return;
|
||||||
|
|
||||||
|
// Get the new page.
|
||||||
|
const newPage = forward ? currentPage + 1 : currentPage - 1;
|
||||||
|
if (newPage < 0 || newPage >= navStack.length) return;
|
||||||
|
|
||||||
|
// Navigate to the new page.
|
||||||
|
currentPage = newPage;
|
||||||
|
navigation.emit("navigate", navStack[newPage]);
|
||||||
|
|
||||||
|
// Update the window history.
|
||||||
|
window.history.pushState(navStack[newPage], navStack[newPage], "/" + navStack[newPage].toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the global event system.
|
||||||
|
export default emitter;
|
||||||
|
// @ts-ignore
|
||||||
|
window["emitter"] = emitter;
|
||||||
|
// @ts-ignore
|
||||||
|
window["navigate"] = navigate;
|
1
src/handbook/src/backend/types.ts
Normal file
1
src/handbook/src/backend/types.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export type Page = "Home";
|
147
src/handbook/src/css/pages/HomePage.scss
Normal file
147
src/handbook/src/css/pages/HomePage.scss
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
.HomePage {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
background-color: var(--background-color);
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Top {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 80%;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Title {
|
||||||
|
margin-top: 31px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Buttons {
|
||||||
|
width: 100%;
|
||||||
|
height: 40%;
|
||||||
|
|
||||||
|
max-width: 1376px;
|
||||||
|
max-height: 256px;
|
||||||
|
|
||||||
|
gap: 24px;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Bottom {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
height: 50%;
|
||||||
|
max-height: 125px;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Box {
|
||||||
|
display: flex;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Disclaimer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 630px;
|
||||||
|
max-height: 93px;
|
||||||
|
|
||||||
|
margin: 0 0 0 60px;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 11px;
|
||||||
|
|
||||||
|
:nth-child(1) {
|
||||||
|
font-size: 24px;
|
||||||
|
max-height: 30px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 18px;
|
||||||
|
max-height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Discord {
|
||||||
|
max-height: 40px;
|
||||||
|
max-width: 150px;
|
||||||
|
|
||||||
|
gap: 8px;
|
||||||
|
align-self: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 44px;
|
||||||
|
max-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
|
||||||
|
max-width: 300px;
|
||||||
|
max-height: 80px;
|
||||||
|
|
||||||
|
margin: 13px 60px 0 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Credits {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
max-height: 18px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
|
||||||
|
:nth-child(1) {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(2) {
|
||||||
|
font-size: 10px;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.HomePage_Links {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
@ -1,147 +1,4 @@
|
|||||||
.Content {
|
.Content {
|
||||||
display: flex;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
background-color: var(--background-color);
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Top {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 80%;
|
|
||||||
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
gap: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Title {
|
|
||||||
margin-top: 31px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Buttons {
|
|
||||||
width: 100%;
|
|
||||||
height: 40%;
|
|
||||||
|
|
||||||
max-width: 1376px;
|
|
||||||
max-height: 256px;
|
|
||||||
|
|
||||||
gap: 24px;
|
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Bottom {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
height: 50%;
|
|
||||||
max-height: 125px;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Box {
|
|
||||||
display: flex;
|
|
||||||
background-color: var(--secondary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Disclaimer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
background-color: var(--secondary-color);
|
|
||||||
|
|
||||||
width: 50%;
|
|
||||||
height: 100%;
|
|
||||||
max-width: 630px;
|
|
||||||
max-height: 93px;
|
|
||||||
|
|
||||||
margin: 0 0 0 60px;
|
|
||||||
border-radius: 10px;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 11px;
|
|
||||||
|
|
||||||
:nth-child(1) {
|
|
||||||
font-size: 24px;
|
|
||||||
max-height: 30px;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 18px;
|
|
||||||
max-height: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Discord {
|
|
||||||
max-height: 40px;
|
|
||||||
max-width: 150px;
|
|
||||||
|
|
||||||
gap: 8px;
|
|
||||||
align-self: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
max-width: 44px;
|
|
||||||
max-height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Text {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background-color: var(--secondary-color);
|
|
||||||
|
|
||||||
max-width: 300px;
|
|
||||||
max-height: 80px;
|
|
||||||
|
|
||||||
margin: 13px 60px 0 0;
|
|
||||||
border-radius: 10px;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Credits {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 5px;
|
|
||||||
|
|
||||||
max-height: 18px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
|
|
||||||
:nth-child(1) {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
:nth-child(2) {
|
|
||||||
font-size: 10px;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.Content_Links {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--text-primary-color);
|
|
||||||
text-decoration: none;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
|
|
||||||
|
import * as events from "@backend/events";
|
||||||
|
|
||||||
import App from "@components/App";
|
import App from "@components/App";
|
||||||
|
|
||||||
|
// Call initial setup functions.
|
||||||
|
events.setup();
|
||||||
|
|
||||||
// Render the application.
|
// Render the application.
|
||||||
createRoot(document.getElementById(
|
createRoot(document.getElementById(
|
||||||
"root") as HTMLElement).render(
|
"root") as HTMLElement).render(
|
||||||
|
66
src/handbook/src/ui/pages/HomePage.tsx
Normal file
66
src/handbook/src/ui/pages/HomePage.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import HomeButton from "@app/ui/widgets/HomeButton";
|
||||||
|
|
||||||
|
import { ReactComponent as DiscordLogo } from "@icons/discord.svg";
|
||||||
|
|
||||||
|
import "@css/pages/HomePage.scss";
|
||||||
|
|
||||||
|
class HomePage extends React.Component<any, any> {
|
||||||
|
constructor(props: any) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={"HomePage"}>
|
||||||
|
<div className={"HomePage_Top"}>
|
||||||
|
<h1 className={"HomePage_Title"}>Welcome back, Traveler~</h1>
|
||||||
|
|
||||||
|
<div className={"HomePage_Buttons"}>
|
||||||
|
<HomeButton name={"Commands"} anchor={"commands"} />
|
||||||
|
<HomeButton name={"Characters"} anchor={"avatars"} />
|
||||||
|
<HomeButton name={"Items"} anchor={"items"} />
|
||||||
|
<HomeButton name={"Entities"} anchor={"monsters"} />
|
||||||
|
<HomeButton name={"Scenes"} anchor={"scenes"} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"HomePage_Buttons"}>
|
||||||
|
<HomeButton name={"Quests"} anchor={"quests"} />
|
||||||
|
<HomeButton name={"Achievements"} anchor={"achievements"} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"HomePage_Bottom"}>
|
||||||
|
<div className={"HomePage_Box HomePage_Disclaimer"}>
|
||||||
|
<div>
|
||||||
|
<p>This tool is not affiliated with HoYoverse.</p>
|
||||||
|
<p>Genshin Impact, game HomePage and materials are</p>
|
||||||
|
<p>trademarks and copyrights of HoYoverse.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"HomePage_Discord"}>
|
||||||
|
<DiscordLogo />
|
||||||
|
<p>Join the Community!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"HomePage_Text"}>
|
||||||
|
<div className={"HomePage_Credits"}>
|
||||||
|
<p>Credits</p>
|
||||||
|
<p>(hover to see info)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"HomePage_Links"}>
|
||||||
|
<a href={"https://paimon.moe"}>paimon.moe</a>
|
||||||
|
<a href={"https://gitlab.com/Dimbreath/AnimeGameData"}>Anime Game Data</a>
|
||||||
|
<a href={"https://genshin-impact.fandom.com"}>Genshin Impact Wiki</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HomePage;
|
@ -1,65 +1,52 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import HomeButton from "@app/ui/widgets/HomeButton";
|
import HomePage from "@pages/HomePage";
|
||||||
|
|
||||||
import { ReactComponent as DiscordLogo } from "@icons/discord.svg";
|
import type { Page } from "@backend/types";
|
||||||
|
|
||||||
import "@css/views/Content.scss";
|
import "@css/views/Content.scss";
|
||||||
|
import { addNavListener, removeNavListener } from "@backend/events";
|
||||||
|
|
||||||
class Content extends React.Component<any, any> {
|
interface IProps {
|
||||||
constructor(props: any) {
|
initial?: Page;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
current: Page;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Content extends React.Component<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
current: props.initial ?? "Home"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to the specified page.
|
||||||
|
*
|
||||||
|
* @param page The page to navigate to.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private navigate(page: Page): void {
|
||||||
|
this.setState({ current: page });
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
addNavListener(this.navigate.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
removeNavListener(this.navigate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
switch (this.state.current) {
|
||||||
<div className={"Content"}>
|
default: return undefined;
|
||||||
<div className={"Content_Top"}>
|
case "Home": return <HomePage />;
|
||||||
<h1 className={"Content_Title"}>Welcome back, Traveler~</h1>
|
}
|
||||||
|
|
||||||
<div className={"Content_Buttons"}>
|
|
||||||
<HomeButton name={"Commands"} anchor={"commands"} />
|
|
||||||
<HomeButton name={"Characters"} anchor={"avatars"} />
|
|
||||||
<HomeButton name={"Items"} anchor={"items"} />
|
|
||||||
<HomeButton name={"Entities"} anchor={"monsters"} />
|
|
||||||
<HomeButton name={"Scenes"} anchor={"scenes"} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={"Content_Buttons"}>
|
|
||||||
<HomeButton name={"Quests"} anchor={"quests"} />
|
|
||||||
<HomeButton name={"Achievements"} anchor={"achievements"} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={"Content_Bottom"}>
|
|
||||||
<div className={"Content_Box Content_Disclaimer"}>
|
|
||||||
<div>
|
|
||||||
<p>This tool is not affiliated with HoYoverse.</p>
|
|
||||||
<p>Genshin Impact, game content and materials are</p>
|
|
||||||
<p>trademarks and copyrights of HoYoverse.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={"Content_Discord"}>
|
|
||||||
<DiscordLogo />
|
|
||||||
<p>Join the Community!</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={"Content_Text"}>
|
|
||||||
<div className={"Content_Credits"}>
|
|
||||||
<p>Credits</p>
|
|
||||||
<p>(hover to see info)</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={"Content_Links"}>
|
|
||||||
<a href={"https://paimon.moe"}>paimon.moe</a>
|
|
||||||
<a href={"https://gitlab.com/Dimbreath/AnimeGameData"}>Anime Game Data</a>
|
|
||||||
<a href={"https://genshin-impact.fandom.com"}>Genshin Impact Wiki</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
"@css/*": ["src/css/*"],
|
"@css/*": ["src/css/*"],
|
||||||
"@components/*": ["src/ui/*"],
|
"@components/*": ["src/ui/*"],
|
||||||
"@icons/*": ["src/icons/*"],
|
"@icons/*": ["src/icons/*"],
|
||||||
"@views/*": ["src/ui/views/*"]
|
"@views/*": ["src/ui/views/*"],
|
||||||
|
"@pages/*": ["src/ui/pages/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
|
Loading…
Reference in New Issue
Block a user