Add files

This commit is contained in:
jeffvli 2022-12-19 15:59:14 -08:00
commit e87c814068
266 changed files with 63938 additions and 0 deletions

View file

@ -0,0 +1,40 @@
import { useState, useEffect } from 'react';
import isElectron from 'is-electron';
import { Navigate, Outlet, useLocation } from 'react-router-dom';
import { AppRoute } from '/@/renderer/router/routes';
import { useCurrentServer } from '/@/renderer/store';
const localSettings = window.electron.localSettings;
export const AppOutlet = () => {
const location = useLocation();
const currentServer = useCurrentServer();
const [isMpvRequired, setIsMpvRequired] = useState(false);
const isServerRequired = !currentServer;
useEffect(() => {
const getMpvPath = async () => {
if (!isElectron()) return setIsMpvRequired(false);
// const mpvPath = await localSettings.get('mpv_path');
// return setIsMpvRequired(!mpvPath);
};
getMpvPath();
}, []);
const actions = [isServerRequired, isMpvRequired];
const actionRequired = actions.some((c) => c);
if (actionRequired) {
return (
<Navigate
replace
state={{ from: location }}
to={AppRoute.ACTION_REQUIRED}
/>
);
}
return <Outlet />;
};

View file

@ -0,0 +1,89 @@
import { lazy, Suspense } from 'react';
import {
Route,
createRoutesFromElements,
RouterProvider,
createHashRouter,
} from 'react-router-dom';
import { AppRoute } from './routes';
import { RouteErrorBoundary } from '/@/renderer/features/action-required';
import HomeRoute from '/@/renderer/features/home/routes/home-route';
import { DefaultLayout } from '/@/renderer/layouts';
import { AppOutlet } from '/@/renderer/router/app-outlet';
import { TitlebarOutlet } from '/@/renderer/router/titlebar-outlet';
const NowPlayingRoute = lazy(
() => import('/@/renderer/features/now-playing/routes/now-playing-route'),
);
const AlbumListRoute = lazy(() => import('/@/renderer/features/albums/routes/album-list-route'));
const SongListRoute = lazy(() => import('/@/renderer/features/songs/routes/song-list-route'));
const ActionRequiredRoute = lazy(
() => import('/@/renderer/features/action-required/routes/action-required-route'),
);
const InvalidRoute = lazy(
() => import('/@/renderer/features/action-required/routes/invalid-route'),
);
export const AppRouter = () => {
const router = createHashRouter(
createRoutesFromElements(
<>
<Route element={<TitlebarOutlet />}>
<Route
element={<AppOutlet />}
errorElement={<RouteErrorBoundary />}
>
<Route element={<DefaultLayout />}>
<Route
index
element={<HomeRoute />}
/>
<Route
element={<HomeRoute />}
path={AppRoute.HOME}
/>
<Route
element={<NowPlayingRoute />}
path={AppRoute.NOW_PLAYING}
/>
<Route
element={<AlbumListRoute />}
path={AppRoute.LIBRARY_ALBUMS}
/>
<Route
element={<SongListRoute />}
path={AppRoute.LIBRARY_SONGS}
/>
<Route
element={<></>}
path={AppRoute.LIBRARY_ARTISTS}
/>
<Route
element={<InvalidRoute />}
path="*"
/>
</Route>
</Route>
</Route>
<Route element={<TitlebarOutlet />}>
<Route element={<DefaultLayout shell />}>
<Route
element={<ActionRequiredRoute />}
path={AppRoute.ACTION_REQUIRED}
/>
</Route>
</Route>
</>,
),
);
return (
<Suspense fallback={<></>}>
<RouterProvider router={router} />
</Suspense>
);
};

View file

@ -0,0 +1,57 @@
// Referenced from: https://betterprogramming.pub/the-best-way-to-manage-routes-in-a-react-project-with-typescript-c4e8d4422d64
export enum AppRoute {
ACTION_REQUIRED = '/action-required',
EXPLORE = '/explore',
HOME = '/',
LIBRARY_ALBUMARTISTS = '/library/album-artists',
LIBRARY_ALBUMARTISTS_DETAIL = '/library/album-artists/:albumArtistId',
LIBRARY_ALBUMS = '/library/albums',
LIBRARY_ALBUMS_DETAIL = '/library/albums/:albumId',
LIBRARY_ARTISTS = '/library/artists',
LIBRARY_ARTISTS_DETAIL = '/library/artists/:artistId',
LIBRARY_FOLDERS = '/library/folders',
LIBRARY_SONGS = '/library/songs',
NOW_PLAYING = '/now-playing',
PLAYING = '/playing',
PLAYLISTS = '/playlists',
PLAYLISTS_DETAIL = '/playlists/:playlistId',
SEARCH = '/search',
SERVERS = '/servers',
}
type TArgs =
| { path: AppRoute.HOME }
| { path: AppRoute.ACTION_REQUIRED }
| { path: AppRoute.NOW_PLAYING }
| { path: AppRoute.EXPLORE }
| { path: AppRoute.PLAYING }
| { path: AppRoute.SERVERS }
| { path: AppRoute.SEARCH }
| { path: AppRoute.LIBRARY_ARTISTS }
| { path: AppRoute.LIBRARY_ARTISTS_DETAIL }
| { path: AppRoute.LIBRARY_ALBUMARTISTS }
| {
params: { albumArtistId: string };
path: AppRoute.LIBRARY_ALBUMARTISTS_DETAIL;
}
| { path: AppRoute.LIBRARY_ALBUMS }
| { path: AppRoute.LIBRARY_FOLDERS }
| { path: AppRoute.LIBRARY_SONGS }
| {
params: { albumId: string };
path: AppRoute.LIBRARY_ALBUMS_DETAIL;
};
type TArgsWithParams = Extract<TArgs, { params: any; path: any }>;
export const createPath = (args: TArgs) => {
// eslint-disable-next-line no-prototype-builtins
if (args.hasOwnProperty('params') === false) return args.path;
// Create a path by replacing params in the route definition
return Object.entries((args as TArgsWithParams).params).reduce(
(previousValue: string, [param, value]) => previousValue.replace(`:${param}`, `${value}`),
args.path,
);
};

View file

@ -0,0 +1,25 @@
import { Outlet } from 'react-router';
import styled from 'styled-components';
import { Titlebar } from '/@/renderer/features/titlebar/components/titlebar';
const TitlebarContainer = styled.header`
position: absolute;
top: 0;
right: 0;
z-index: 5000;
height: 2.5rem;
background: var(--titlebar-bg);
-webkit-app-region: drag;
opacity: 0.85;
`;
export const TitlebarOutlet = () => {
return (
<>
<TitlebarContainer>
<Titlebar />
</TitlebarContainer>
<Outlet />
</>
);
};