[FEAT] add the stack needed

This commit is contained in:
Edouard DUPIN 2025-02-24 09:34:00 +01:00
parent 86fec254aa
commit bd66703a08
27 changed files with 2990 additions and 733 deletions

View File

@ -28,35 +28,33 @@ import org.slf4j.LoggerFactory;
public class Initialization extends MigrationSqlStep {
private static final Logger LOGGER = LoggerFactory.getLogger(Initialization.class);
public static final int KARSO_INITIALISATION_ID = 1;
public static final List<Class<?>> CLASSES_BASE = List.of(Data.class, Media.class, Type.class, Series.class,
Season.class, User.class, UserMediaAdvancement.class);
public static final List<Class<?>> CLASSES_BASE = List.of(Data.class, Media.class, Type.class, Series.class, Season.class, User.class, UserMediaAdvancement.class);
@Override
public String getName() {
return "Initialization";
}
public static void generateObjects() throws Exception {
LOGGER.info("Generate APIs");
final List<Class<?>> listOfResources = List.of(Front.class, HealthCheck.class, SeasonResource.class,
SeriesResource.class, TypeResource.class, UserMediaAdvancementResource.class, UserResource.class,
MediaResource.class, DataResource.class);
final List<Class<?>> listOfResources = List.of(Front.class, HealthCheck.class, SeasonResource.class, SeriesResource.class, TypeResource.class, UserMediaAdvancementResource.class,
UserResource.class, MediaResource.class, DataResource.class);
final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(listOfResources);
api.addModel(JwtToken.class);
TsGenerateApi.generateApi(api, "../front/src/back-api/");
LOGGER.info("Generate APIs (DONE)");
}
@Override
public void generateStep() throws Exception {
for (final Class<?> clazz : CLASSES_BASE) {
addClass(clazz);
}
addAction((final DBAccess da) -> {
final List<Type> data = List.of(//
new Type("Documentary", "Documentary (animals, space, earth...)"), //
@ -89,7 +87,7 @@ public class Initialization extends MigrationSqlStep {
ALTER TABLE `userMediaAdvancement` AUTO_INCREMENT = 1000;
""", "mysql");
}
public static void dropAll(final DBAccess da) {
for (final Class<?> element : CLASSES_BASE) {
try {
@ -100,7 +98,7 @@ public class Initialization extends MigrationSqlStep {
}
}
}
public static void cleanAll(final DBAccess da) {
for (final Class<?> element : CLASSES_BASE) {
try {

View File

@ -91,8 +91,11 @@ public class Migration20250214 extends MigrationSqlStep {
}
}
});
// addAction("""
// ALTER TABLE `media` DROP `dataId`;
// """);
addAction("""
ALTER TABLE `media` DROP `dataId`;
ALTER TABLE `media` CHANGE `dataId` `dataIdOld` binary(16);
""");
addAction("""
ALTER TABLE `media` CHANGE `dataOid` `dataId` binary(12) NOT NULL;

View File

@ -1,6 +1,7 @@
package org.kar.karideo.model;
import java.util.List;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.DataJson;
@ -31,6 +32,9 @@ public class Media extends GenericDataSoftDelete {
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Data.class)
@Column(nullable = false)
public ObjectId dataId;
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Data.class)
@Column(nullable = false)
public UUID dataIdOld;
@Schema(description = "Type of the media")
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Type.class)
public Long typeId;

View File

@ -29,63 +29,64 @@
"*.{ts,tsx,js,jsx,json}": "prettier --write"
},
"dependencies": {
"@locator/babel-jsx": "0.4.4",
"@trivago/prettier-plugin-sort-imports": "5.2.2",
"@chakra-ui/cli": "3.7.0",
"@chakra-ui/react": "3.7.0",
"@chakra-ui/cli": "3.8.1",
"@chakra-ui/react": "3.8.1",
"@emotion/react": "11.14.0",
"allotment": "1.20.2",
"allotment": "1.20.3",
"css-mediaquery": "0.1.2",
"dayjs": "1.11.13",
"history": "5.3.0",
"next-themes": "^0.4.4",
"react": "19.0.0-rc.1",
"react-dom": "19.0.0-rc.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-error-boundary": "5.0.0",
"react-icons": "5.4.0",
"react-router-dom": "7.1.5",
"react-icons": "5.5.0",
"react-router-dom": "7.2.0",
"react-select": "5.10.0",
"react-use": "17.6.0",
"zod": "3.24.1",
"zod": "3.24.2",
"zustand": "5.0.3"
},
"devDependencies": {
"@chakra-ui/styled-system": "^2.12.0",
"@playwright/test": "1.50.1",
"@storybook/addon-actions": "8.5.4",
"@storybook/addon-essentials": "8.5.4",
"@storybook/addon-links": "8.5.4",
"@storybook/addon-mdx-gfm": "8.5.4",
"@storybook/react": "8.5.4",
"@storybook/react-vite": "8.5.4",
"@storybook/theming": "8.5.4",
"@storybook/addon-actions": "8.5.8",
"@storybook/addon-essentials": "8.5.8",
"@storybook/addon-links": "8.5.8",
"@storybook/addon-mdx-gfm": "8.5.8",
"@storybook/react": "8.5.8",
"@storybook/react-vite": "8.5.8",
"@storybook/theming": "8.5.8",
"@testing-library/jest-dom": "6.6.3",
"@testing-library/react": "16.2.0",
"@testing-library/user-event": "14.6.1",
"@trivago/prettier-plugin-sort-imports": "5.2.2",
"@types/jest": "29.5.14",
"@types/node": "22.13.1",
"@types/react": "19.0.8",
"@types/react-dom": "19.0.3",
"@typescript-eslint/eslint-plugin": "8.24.0",
"@typescript-eslint/parser": "8.24.0",
"@types/node": "22.13.4",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
"@typescript-eslint/eslint-plugin": "8.24.1",
"@typescript-eslint/parser": "8.24.1",
"@vitejs/plugin-react": "4.3.4",
"eslint": "9.20.1",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-react": "7.37.4",
"eslint-plugin-react-hooks": "5.1.0",
"eslint-plugin-storybook": "0.11.2",
"eslint-plugin-storybook": "0.11.3",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"knip": "5.44.0",
"knip": "5.44.4",
"lint-staged": "15.4.3",
"npm-check-updates": "^17.1.14",
"prettier": "3.5.0",
"puppeteer": "24.2.0",
"prettier": "3.5.1",
"puppeteer": "24.2.1",
"react-is": "19.0.0",
"storybook": "8.5.4",
"storybook": "8.5.8",
"ts-node": "10.9.2",
"typescript": "5.7.3",
"vite": "6.1.0",
"vitest": "3.0.5"
"vite": "6.1.1",
"vitest": "3.0.6"
}
}

2521
front/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/**
* Interface of the server (auto-generated code)
*/
import { z as zod } from "zod";
import {ZodLong} from "./long";
import {ZodUUIDGenericDataSoftDelete, ZodUUIDGenericDataSoftDeleteWrite } from "./uuid-generic-data-soft-delete";
export const ZodData = ZodUUIDGenericDataSoftDelete.extend({
/**
* Sha512 of the data
*/
sha512: zod.string().max(128),
/**
* Mime -type of the media
*/
mimeType: zod.string().max(128),
/**
* Size in Byte of the data
*/
size: ZodLong,
});
export type Data = zod.infer<typeof ZodData>;
export function isData(data: any): data is Data {
try {
ZodData.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data type='ZodData' error=${e}`);
return false;
}
}
export const ZodDataWrite = ZodUUIDGenericDataSoftDeleteWrite.extend({
/**
* Sha512 of the data
*/
sha512: zod.string().max(128).optional(),
/**
* Mime -type of the media
*/
mimeType: zod.string().max(128).optional(),
/**
* Size in Byte of the data
*/
size: ZodLong.optional(),
});
export type DataWrite = zod.infer<typeof ZodDataWrite>;
export function isDataWrite(data: any): data is DataWrite {
try {
ZodDataWrite.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data type='ZodDataWrite' error=${e}`);
return false;
}
}

View File

@ -0,0 +1,41 @@
/**
* Interface of the server (auto-generated code)
*/
import { z as zod } from "zod";
import {ZodUUIDGenericData, ZodUUIDGenericDataWrite } from "./uuid-generic-data";
export const ZodUUIDGenericDataSoftDelete = ZodUUIDGenericData.extend({
/**
* Deleted state
*/
deleted: zod.boolean().readonly().optional(),
});
export type UUIDGenericDataSoftDelete = zod.infer<typeof ZodUUIDGenericDataSoftDelete>;
export function isUUIDGenericDataSoftDelete(data: any): data is UUIDGenericDataSoftDelete {
try {
ZodUUIDGenericDataSoftDelete.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data type='ZodUUIDGenericDataSoftDelete' error=${e}`);
return false;
}
}
export const ZodUUIDGenericDataSoftDeleteWrite = ZodUUIDGenericDataWrite.extend({
});
export type UUIDGenericDataSoftDeleteWrite = zod.infer<typeof ZodUUIDGenericDataSoftDeleteWrite>;
export function isUUIDGenericDataSoftDeleteWrite(data: any): data is UUIDGenericDataSoftDeleteWrite {
try {
ZodUUIDGenericDataSoftDeleteWrite.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data type='ZodUUIDGenericDataSoftDeleteWrite' error=${e}`);
return false;
}
}

View File

@ -0,0 +1,42 @@
/**
* Interface of the server (auto-generated code)
*/
import { z as zod } from "zod";
import {ZodUUID} from "./uuid";
import {ZodGenericTiming, ZodGenericTimingWrite } from "./generic-timing";
export const ZodUUIDGenericData = ZodGenericTiming.extend({
/**
* Unique UUID of the object
*/
uuid: ZodUUID.readonly(),
});
export type UUIDGenericData = zod.infer<typeof ZodUUIDGenericData>;
export function isUUIDGenericData(data: any): data is UUIDGenericData {
try {
ZodUUIDGenericData.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data type='ZodUUIDGenericData' error=${e}`);
return false;
}
}
export const ZodUUIDGenericDataWrite = ZodGenericTimingWrite.extend({
});
export type UUIDGenericDataWrite = zod.infer<typeof ZodUUIDGenericDataWrite>;
export function isUUIDGenericDataWrite(data: any): data is UUIDGenericDataWrite {
try {
ZodUUIDGenericDataWrite.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data type='ZodUUIDGenericDataWrite' error=${e}`);
return false;
}
}

View File

@ -4,6 +4,7 @@
import { z as zod } from "zod";
import {ZodObjectId} from "./object-id";
import {ZodUUID} from "./uuid";
import {ZodLong} from "./long";
import {ZodInteger} from "./integer";
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
@ -21,6 +22,7 @@ export const ZodMedia = ZodGenericDataSoftDelete.extend({
* Foreign Key Id of the data
*/
dataId: ZodObjectId,
dataIdOld: ZodUUID,
/**
* Type of the media
*/
@ -77,6 +79,7 @@ export const ZodMediaWrite = ZodGenericDataSoftDeleteWrite.extend({
* Foreign Key Id of the data
*/
dataId: ZodObjectId.optional(),
dataIdOld: ZodUUID.optional(),
/**
* Type of the media
*/

View File

@ -0,0 +1,43 @@
import { ReactNode } from 'react';
import { Center, Flex, FlexProps, Text } from '@chakra-ui/react';
import { useColorModeValue } from '@/components/ui/color-mode';
export type VignetteProps = { text?: String; icon: ReactNode } & Pick<
FlexProps,
'onClick'
>;
export const Vignette = ({ icon, text, ...rest }: VignetteProps) => {
return (
<Flex
align="flex-start"
width="200px"
height="190px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
{...rest}
>
<Flex direction="column" width="full" height="full">
<Center height="full">{icon}</Center>
<Center>
<Text
fontSize="25px"
fontWeight="bold"
textTransform="uppercase"
userSelect="none"
>
{text}
</Text>
</Center>
</Flex>
</Flex>
);
};

View File

@ -0,0 +1,61 @@
import { ReactNode } from 'react';
import { Flex, FlexProps } from '@chakra-ui/react';
import { useColorModeValue } from '@/components/ui/color-mode';
export type VignetteProps = { text?: String; icon: ReactNode } & Pick<
FlexProps,
'onClick'
>;
export const VignetteDetail = ({ icon, text, ...rest }: VignetteProps) => {
return (
<Flex
align="flex-start"
width="270px"
height="120px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
key={data.id}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
onClick={() => onSelectItem(data.id)}
>
<DisplayType dataType={data} />
</Flex>
// <Flex
// align="flex-start"
// width="200px"
// height="190px"
// border="1px"
// borderColor="brand.900"
// backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
// padding="5px"
// as="button"
// _hover={{
// boxShadow: 'outline-over',
// bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
// }}
// {...rest}
// >
// <Flex direction="column" width="full" height="full">
// <Center height="full">{icon}</Center>
// <Center>
// <Text
// fontSize="25px"
// fontWeight="bold"
// textTransform="uppercase"
// userSelect="none"
// >
// {text}
// </Text>
// </Center>
// </Flex>
// </Flex>
);
};

View File

@ -25,15 +25,15 @@ export const DisplayMediaFull = ({
const { dataSeries } = useSpecificSeries(media?.seriesId);
return (
<Flex
direction="row"
direction="column"
width="full"
height="full"
data-testid="display-Media-full"
>
<Covers
data={media?.covers}
size="60px"
marginY="auto"
size="100"
height="full"
iconEmpty={MediaActive?.id === media.id ? <LuPlay /> : <LuMusic2 />}
onClick={onClick}
/>
@ -51,21 +51,21 @@ export const DisplayMediaFull = ({
fontSize="20px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
marginX="auto"
overflow="hidden"
// TODO: noOfLines={1}
color={MediaActive?.id === media.id ? 'green.700' : undefined}
>
{media.name} {media.episode && ` [${media.episode}]`}
</Text>
{dataSeason && (
{/* {dataSeason && (
<Text
as="span"
alignContent="left"
fontSize="15px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
marginX="auto"
overflow="hidden"
//noOfLines={1}
marginY="auto"
@ -76,8 +76,8 @@ export const DisplayMediaFull = ({
</Text>{' '}
{dataSeason.name}
</Text>
)}
{dataSeries && (
)} */}
{/* {dataSeries && (
<Text
as="span"
alignContent="left"
@ -95,8 +95,8 @@ export const DisplayMediaFull = ({
</Text>{' '}
{dataSeries && dataSeries.name}
</Text>
)}
{dataType && (
)} */}
{/* {dataType && (
<Text
as="span"
alignContent="left"
@ -114,7 +114,7 @@ export const DisplayMediaFull = ({
</Text>{' '}
{dataType.name}
</Text>
)}
)} */}
</Flex>
<ContextMenu
elements={contextMenu}

View File

@ -0,0 +1,126 @@
import { Flex, Text } from '@chakra-ui/react';
import { LuMusic2, LuPlay } from 'react-icons/lu';
import { Media } from '@/back-api';
import { Covers } from '@/components/Cover';
import { ContextMenu, MenuElement } from '@/components/contextMenu/ContextMenu';
import { useActivePlaylistService } from '@/service/ActivePlaylist';
import { useSpecificSeason } from '@/service/Season';
import { useSpecificSeries } from '@/service/Series';
import { useSpecificType } from '@/service/Type';
export type DisplayMediaProps = {
media: Media;
onClick?: () => void;
contextMenu?: MenuElement[];
};
export const DisplayMediaListFull = ({
media,
onClick,
contextMenu,
}: DisplayMediaProps) => {
const { MediaActive } = useActivePlaylistService();
const { dataSeason } = useSpecificSeason(media?.seasonId);
const { dataType } = useSpecificType(media?.typeId);
const { dataSeries } = useSpecificSeries(media?.seriesId);
return (
<Flex
direction="row"
width="full"
height="full"
data-testid="display-Media-full"
>
<Covers
data={media?.covers}
size="50px"
marginY="auto"
height="full"
iconEmpty={MediaActive?.id === media.id ? <LuPlay /> : <LuMusic2 />}
onClick={onClick}
/>
<Flex
direction="column"
width="full"
height="full"
paddingLeft="5px"
overflowX="hidden"
onClick={onClick}
>
<Text
as="span"
alignContent="left"
fontSize="20px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
overflow="hidden"
// TODO: noOfLines={1}
color={MediaActive?.id === media.id ? 'green.700' : undefined}
>
{media.episode && `[${media.episode}]`} {media.name}
</Text>
{/* {dataSeason && (
<Text
as="span"
alignContent="left"
fontSize="15px"
fontWeight="bold"
userSelect="none"
marginX="auto"
overflow="hidden"
//noOfLines={1}
marginY="auto"
color={MediaActive?.id === media.id ? 'green.700' : undefined}
>
<Text as="span" fontWeight="normal">
Season:
</Text>{' '}
{dataSeason.name}
</Text>
)} */}
{/* {dataSeries && (
<Text
as="span"
alignContent="left"
fontSize="15px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
overflow="hidden"
//noOfLines={1}
marginY="auto"
color={MediaActive?.id === media.id ? 'green.700' : undefined}
>
<Text as="span" fontWeight="normal">
Series(s):
</Text>{' '}
{dataSeries && dataSeries.name}
</Text>
)} */}
{/* {dataType && (
<Text
as="span"
alignContent="left"
fontSize="15px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
overflow="hidden"
//noOfLines={1}
marginY="auto"
color={MediaActive?.id === media.id ? 'green.700' : undefined}
>
<Text as="span" fontWeight="normal">
Type:
</Text>{' '}
{dataType.name}
</Text>
)} */}
</Flex>
<ContextMenu
elements={contextMenu}
data-testid="display-Media-full_context-menu"
/>
</Flex>
);
};

View File

@ -18,7 +18,7 @@ export const DisplaySeries = ({ dataSeries }: DisplaySeriesProps) => {
);
}
return (
<Flex direction="row" width="full" height="full">
<Flex direction="column" width="full" height="full">
<Covers
data={dataSeries?.covers}
size="100"
@ -27,11 +27,11 @@ export const DisplaySeries = ({ dataSeries }: DisplaySeriesProps) => {
/>
<Flex
direction="column"
width="150px"
maxWidth="150px"
width="full"
height="full"
paddingLeft="5px"
overflowX="hidden"
alignContent="center"
>
<Text
as="span"
@ -39,7 +39,7 @@ export const DisplaySeries = ({ dataSeries }: DisplaySeriesProps) => {
fontSize="20px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
marginX="auto"
overflow="hidden"
//TODO: noOfLines={[1, 2]}
>
@ -50,7 +50,7 @@ export const DisplaySeries = ({ dataSeries }: DisplaySeriesProps) => {
alignContent="left"
fontSize="15px"
userSelect="none"
marginRight="auto"
marginX="auto"
overflow="hidden"
//TODO: noOfLines={1}
>

View File

@ -18,10 +18,10 @@ export const DisplayType = ({ dataType }: DisplayTypeProps) => {
);
}
return (
<Flex direction="row" width="full" height="full">
<Flex direction="column" width="full" height="full">
<Covers
data={dataType?.covers}
size="100"
size="50"
height="full"
iconEmpty={<LuDisc3 />}
/>

View File

@ -16,7 +16,7 @@ export interface Environment {
const serverSSOAddress = 'https://atria-soft.org';
const environment_back_prod: Environment = {
production: false,
production: true,
// URL of development API
applName: 'karideo',
defaultServer: 'karideo',
@ -45,42 +45,9 @@ const environment_local: Environment = {
ssoSignUp: `${serverSSOAddress}/karso/signup/karideo-dev/`,
ssoSignOut: `${serverSSOAddress}/karso/signout/karideo-dev/`,
tokenStoredInPermanentStorage: false,
replaceDataToRealServer: true,
replaceDataToRealServer: false,
};
const environment_full_local: Environment = {
production: false,
// URL of development API
applName: 'karideo',
defaultServer: 'karideo',
server: {
karideo: 'http://localhost:18080/karideo/api',
karso: 'http://localhost:15080/karso/api',
},
ssoSite: `${serverSSOAddress}/karso/`,
ssoSignIn: 'http://localhost:4200/signin/karideo-dev/',
ssoSignUp: 'http://localhost:4200/signup/karideo-dev/',
ssoSignOut: 'http://localhost:4200/signout/karideo-dev/',
tokenStoredInPermanentStorage: false,
};
const environment_hybrid: Environment = {
production: false,
// URL of development API
applName: 'karideo',
defaultServer: 'karideo',
server: {
karideo: `${serverSSOAddress}/karideo/api`,
karso: `${serverSSOAddress}/karso/api`,
},
ssoSite: `${serverSSOAddress}/karso/`,
ssoSignIn: 'http://localhost:4200/signin/karideo-dev/',
ssoSignUp: 'http://localhost:4200/signup/karideo-dev/',
ssoSignOut: 'http://localhost:4200/signout/karideo-dev/',
tokenStoredInPermanentStorage: false,
};
/**
* Check if the current environment is for development
* @returns true if development is active.

View File

@ -2,7 +2,6 @@ import { StrictMode } from 'react';
import { ChakraProvider } from '@chakra-ui/react';
import ReactDOM from 'react-dom/client';
import 'regenerator-runtime/runtime';
import App from '@/App';

View File

@ -1,13 +1,13 @@
import { ReactElement } from 'react';
import { Center, Flex, HStack, Text } from '@chakra-ui/react';
import { LuCrown, LuDisc3, LuEar, LuFileAudio } from 'react-icons/lu';
import { MdGroup } from 'react-icons/md';
import { HStack } from '@chakra-ui/react';
import { LuCloudMoon, LuCrown } from 'react-icons/lu';
import { MdVideoFile } from 'react-icons/md';
import { useNavigate } from 'react-router-dom';
import { PageLayout } from '@/components/Layout/PageLayout';
import { TopBar } from '@/components/TopBar/TopBar';
import { useColorModeValue } from '@/components/ui/color-mode';
import { Vignette } from '@/components/Vignette';
type HomeListType = {
id: number;
@ -24,28 +24,16 @@ const homeList: HomeListType[] = [
},
{
id: 2,
name: 'Series',
icon: <MdGroup style={{ width: '100px', height: '100px' }} />,
name: 'Univers',
icon: <LuCloudMoon style={{ width: '100px', height: '100px' }} />,
to: '/Series',
},
{
id: 3,
name: 'Seasons',
icon: <LuDisc3 style={{ width: '100px', height: '100px' }} />,
to: '/Season',
},
{
id: 4,
name: 'Medias',
icon: <LuFileAudio style={{ width: '100px', height: '100px' }} />,
icon: <MdVideoFile style={{ width: '100px', height: '100px' }} />,
to: '/Media',
},
{
id: 5,
name: 'Playlists',
icon: <LuEar style={{ width: '100px', height: '100px' }} />,
to: '/playlists',
},
];
export const HomePage = () => {
@ -65,36 +53,12 @@ export const HomePage = () => {
justify="center"
>
{homeList.map((data) => (
<Flex
align="flex-start"
width="200px"
height="190px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
<Vignette
key={data.id}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
onClick={() => onSelectItem(data)}
>
<Flex direction="column" width="full" height="full">
<Center height="full">{data.icon}</Center>
<Center>
<Text
fontSize="25px"
fontWeight="bold"
textTransform="uppercase"
userSelect="none"
>
{data.name}
</Text>
</Center>
</Flex>
</Flex>
text={data.name}
icon={data.icon}
/>
))}
</HStack>
</PageLayout>

View File

@ -1,4 +1,4 @@
import { Box, Button, Flex, Text } from '@chakra-ui/react';
import { Box, Button, Flex, HStack, Text } from '@chakra-ui/react';
import { LuDisc3 } from 'react-icons/lu';
import { MdEdit } from 'react-icons/md';
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
@ -14,18 +14,22 @@ import { TypeEditPopUp } from '@/components/popup/GenderEditPopUp';
import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
import { DisplaySeries } from '@/components/series/DisplaySeries';
import { useColorModeValue } from '@/components/ui/color-mode';
import { useActivePlaylistService, useSeriesWithType, useSpecificType, useTypeGetVideo } from '@/service';
import {
useActivePlaylistService,
useSeriesWithType,
useSpecificType,
useTypeGetVideo,
} from '@/service';
export const TypeDetailPage = () => {
const { TypeId } = useParams();
const TypeIdInt = TypeId ? parseInt(TypeId, 10) : undefined;
const { typeId } = useParams();
const typeIdInt = typeId ? parseInt(typeId, 10) : undefined;
const { playInList } = useActivePlaylistService();
const { dataType } = useSpecificType(TypeIdInt);
const { videoWithType } = useTypeGetVideo(TypeIdInt);
const { seriesWithType } = useSeriesWithType(TypeIdInt);
const { dataType } = useSpecificType(typeIdInt);
const { videoWithType } = useTypeGetVideo(typeIdInt);
const { seriesWithType } = useSeriesWithType(typeIdInt);
const navigate = useNavigate();
const onSelectItem = (MediaId: number) => {
//navigate(`/Series/${SeriesIdInt}/Type/${TypeId}`);
const onSelectItem = (mediaId: number) => {
let currentPlay = 0;
const listMediaId: number[] = [];
if (!videoWithType) {
@ -34,12 +38,15 @@ export const TypeDetailPage = () => {
}
for (let iii = 0; iii < videoWithType.length; iii++) {
listMediaId.push(videoWithType[iii].id);
if (videoWithType[iii].id === MediaId) {
if (videoWithType[iii].id === mediaId) {
currentPlay = iii;
}
}
playInList(currentPlay, listMediaId);
};
const onSelectSeriesItem = (seriesId: number) => {
navigate(`/type/${typeId}/series/${seriesId}`);
};
console.log(`dataType = ${JSON.stringify(dataType, null, 2)}`);
if (!dataType) {
@ -47,7 +54,7 @@ export const TypeDetailPage = () => {
<>
<TopBar title="Type detail" />
<PageLayoutInfoCenter>
Fail to load Series id: {TypeId}
Fail to load Series id: {typeId}
</PageLayoutInfoCenter>
</>
);
@ -57,9 +64,7 @@ export const TypeDetailPage = () => {
<TopBar title="Type detail">
<Button
{...BUTTON_TOP_BAR_PROPERTY}
onClick={() =>
navigate(`/Type/${TypeId}/edit-Type/${TypeId}`)
}
onClick={() => navigate(`/Type/${typeId}/edit-type/${typeId}`)}
>
<MdEdit />
</Button>
@ -83,36 +88,36 @@ export const TypeDetailPage = () => {
</Flex>
</Flex>
<Flex
direction="column"
<HStack
wrap="wrap"
gap="20px"
marginX="auto"
padding="20px"
width="80%"
justify="center"
>
{seriesWithType?.map((data) => (
<Box
minWidth="100%"
//height="60px"
width="200px"
height="280px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
key={data.id}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
onClick={() => onSelectSeriesItem(data.id)}
>
<DisplaySeries
dataSeries={data}
//onClick={() => onSelectItem(data.id)}
// >onClick={() => onSelectItem(data.id)}
// contextMenu={[
// {
// name: 'Edit',
// onClick: () => {
// navigate(`/Type/${TypeId}/edit-Media/${data.id}`);
// navigate(`/Type/${TypeId}/edit-media/${data.id}`);
// },
// },
// { name: 'Add Playlist', onClick: () => {} },
@ -122,12 +127,11 @@ export const TypeDetailPage = () => {
))}
{videoWithType?.map((data) => (
<Box
minWidth="100%"
//height="60px"
width="200px"
height="280px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
key={data.id}
padding="5px"
as="button"
_hover={{
@ -142,7 +146,7 @@ export const TypeDetailPage = () => {
{
name: 'Edit',
onClick: () => {
navigate(`/Type/${TypeId}/edit-Media/${data.id}`);
navigate(`/Type/${typeId}/edit-media/${data.id}`);
},
},
{ name: 'Add Playlist', onClick: () => {} },
@ -151,10 +155,10 @@ export const TypeDetailPage = () => {
</Box>
))}
<EmptyEnd />
</Flex>
</HStack>
<Routes>
<Route path="edit-Media/:MediaId" element={<MediaEditPopUp />} />
<Route path="edit-Type/:TypeId" element={<TypeEditPopUp />} />
<Route path="edit-media/:MediaId" element={<MediaEditPopUp />} />
<Route path="edit-type/:TypeId" element={<TypeEditPopUp />} />
</Routes>
</PageLayout>
</>

View File

@ -4,11 +4,11 @@ import { Flex, HStack } from '@chakra-ui/react';
import { useNavigate } from 'react-router-dom';
import { EmptyEnd } from '@/components/EmptyEnd';
import { DisplayType } from '@/components/type/DisplayType';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
import { SearchInput } from '@/components/SearchInput';
import { TopBar } from '@/components/TopBar/TopBar';
import { DisplayType } from '@/components/type/DisplayType';
import { useColorModeValue } from '@/components/ui/color-mode';
import { useOrderedTypes } from '@/service/Type';
@ -45,12 +45,11 @@ export const TypesPage = () => {
{dataTypes.map((data) => (
<Flex
align="flex-start"
width="270px"
height="120px"
width="200px"
height="280px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
key={data.id}
padding="5px"
as="button"
_hover={{

View File

@ -1,15 +1,26 @@
import { Navigate, Route, Routes } from 'react-router-dom';
import { Error404 } from '@/errors';
import { TypesSeriesDetailPage } from '@/scene/type/TypesSeriesDetailPage';
import { TypeDetailPage } from './TypesDetailPage';
import { TypesPage } from './TypesPage';
import { TypesSeriesSeasonDetailPage } from './TypesSeriesSeasonDetailPage';
export const TypeRoutes = () => {
return (
<Routes>
<Route path="/" element={<Navigate to="all" replace />} />
<Route path="all" element={<TypesPage />} />
<Route path=":TypeId/*" element={<TypeDetailPage />} />
<Route path=":typeId/*" element={<TypeDetailPage />} />
<Route
path=":typeId/series/:seriesId/*"
element={<TypesSeriesDetailPage />}
/>
<Route
path=":typeId/series/:seriesId/season/:seasonId/*"
element={<TypesSeriesSeasonDetailPage />}
/>
<Route path="*" element={<Error404 />} />
</Routes>
);

View File

@ -0,0 +1,190 @@
import { Box, Button, Flex, HStack, Text } from '@chakra-ui/react';
import { LuDisc3 } from 'react-icons/lu';
import { MdEdit } from 'react-icons/md';
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
import { Covers } from '@/components/Cover';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
//import { useMediasOfAType } from '@/service/Media';
import { DisplayMediaFull } from '@/components/media/DisplayMediaFull';
import { TypeEditPopUp } from '@/components/popup/GenderEditPopUp';
import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
import { DisplaySeason } from '@/components/season/DisplaySeason';
import { useColorModeValue } from '@/components/ui/color-mode';
import {
useActivePlaylistService,
useSeasonWithSeries,
useSpecificSeries,
useSpecificType,
useTypeSeriesGetVideo,
} from '@/service';
export const TypesSeriesDetailPage = () => {
const { typeId, seriesId } = useParams();
const typeIdInt = typeId ? parseInt(typeId, 10) : undefined;
const seriesIdInt = seriesId ? parseInt(seriesId, 10) : undefined;
const { playInList } = useActivePlaylistService();
const { dataType } = useSpecificType(typeIdInt);
const { dataSeries } = useSpecificSeries(seriesIdInt);
const { videoWithType } = useTypeSeriesGetVideo(typeIdInt, seriesIdInt);
const { seasonOfSeriesId } = useSeasonWithSeries(/*typeIdInt,*/ seriesIdInt);
const navigate = useNavigate();
const onSelectSeasonItem = (mediaId: number) => {
navigate(`/type/${typeId}/series/${seriesId}/season/${mediaId}`);
}
const onSelectItem = (mediaId: number) => {
let currentPlay = 0;
const listMediaId: number[] = [];
if (!videoWithType) {
console.log('Fail to get Type...');
return;
}
for (let iii = 0; iii < videoWithType.length; iii++) {
listMediaId.push(videoWithType[iii].id);
if (videoWithType[iii].id === mediaId) {
currentPlay = iii;
}
}
playInList(currentPlay, listMediaId);
};
console.log(`dataType = ${JSON.stringify(dataType, null, 2)}`);
if (!dataType) {
return (
<>
<TopBar title="Type detail" />
<PageLayoutInfoCenter>
Fail to load Series id: {typeId}/{seriesId}
</PageLayoutInfoCenter>
</>
);
}
return (
<>
<TopBar title="Series detail">
<Button
{...BUTTON_TOP_BAR_PROPERTY}
onClick={() =>
navigate(
`/Type/${typeId}/series/${seriesId}/edit-series/${seriesId}`
)
}
>
<MdEdit />
</Button>
</TopBar>
<PageLayout>
<Flex
direction="row"
width="80%"
marginX="auto"
padding="10px"
gap="10px"
>
<Covers data={dataType?.covers} iconEmpty={<LuDisc3 />} slideshow />
<Flex direction="column" width="80%" marginRight="auto">
<Text fontSize="24px" fontWeight="bold">
type: {dataType?.name}
</Text>
<Text fontSize="24px" fontWeight="bold">
series: {dataSeries?.name}
</Text>
{dataSeries?.description && (
<Text>Description: {dataSeries?.description}</Text>
)}
</Flex>
</Flex>
<HStack
wrap="wrap"
gap="20px"
marginX="auto"
padding="20px"
justify="center"
>
{seasonOfSeriesId?.map((data) => (
<Box
key={data.id}
width="full"
maxWidth="calc(min(450px,80%))"
height="150px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
onClick={() => onSelectSeasonItem(data.id)}
>
<DisplaySeason
dataSeason={data}
// contextMenu={[
// {
// name: 'Edit',
// onClick: () => {
// navigate(`/Type/${TypeId}/edit-media/${data.id}`);
// },
// },
// { name: 'Add Playlist', onClick: () => {} },
// ]}
/>
</Box>
))}
</HStack>
<Box width="full" height="10px" background="red"/>
<HStack
wrap="wrap"
gap="20px"
marginX="auto"
padding="20px"
justify="center"
>
{videoWithType?.map((data) => (
<Box
key={data.id}
width="200px"
height="280px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
>
<DisplayMediaFull
media={data}
onClick={() => onSelectItem(data.id)}
contextMenu={[
{
name: 'Edit',
onClick: () => {
navigate(
`/type/${typeId}/series/${seriesId}/edit-media/${data.id}`
);
},
},
{ name: 'Add Playlist', onClick: () => {} },
]}
/>
</Box>
))}
<EmptyEnd />
</HStack>
<Routes>
<Route path="edit-media/:mediaId" element={<MediaEditPopUp />} />
<Route path="edit-type/:typeId" element={<TypeEditPopUp />} />
{/* <Route path="edit-season/:seasonId" element={<TypeSeasonPopUp />} /> */}
</Routes>
</PageLayout>
</>
);
};

View File

@ -0,0 +1,150 @@
import { Box, Button, Flex, HStack, Text } from '@chakra-ui/react';
import { LuDisc3 } from 'react-icons/lu';
import { MdEdit } from 'react-icons/md';
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
import { Covers } from '@/components/Cover';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
import { DisplayMediaFull } from '@/components/media/DisplayMediaFull';
import { TypeEditPopUp } from '@/components/popup/GenderEditPopUp';
import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
import { useColorModeValue } from '@/components/ui/color-mode';
import {
useActivePlaylistService,
useSpecificSeason,
useSpecificSeries,
useSpecificType,
useTypeSeriesSeasonGetVideo,
} from '@/service';
import { DisplayMediaListFull } from '@/components/media/DisplayMediaListFull';
export const TypesSeriesSeasonDetailPage = () => {
const { typeId, seriesId, seasonId } = useParams();
const typeIdInt = typeId ? parseInt(typeId, 10) : undefined;
const seriesIdInt = seriesId ? parseInt(seriesId, 10) : undefined;
const seasonIdInt = seasonId ? parseInt(seasonId, 10) : undefined;
const { playInList } = useActivePlaylistService();
const { dataType } = useSpecificType(typeIdInt);
const { dataSeries } = useSpecificSeries(seriesIdInt);
const { dataSeason } = useSpecificSeason(seasonIdInt);
const { videoWithType: videos } = useTypeSeriesSeasonGetVideo(typeIdInt, seriesIdInt, seasonIdInt);
const navigate = useNavigate();
const onSelectItem = (mediaId: number) => {
let currentPlay = 0;
const listMediaId: number[] = [];
if (!videos) {
console.log('Fail to get Type...');
return;
}
for (let iii = 0; iii < videos.length; iii++) {
listMediaId.push(videos[iii].id);
if (videos[iii].id === mediaId) {
currentPlay = iii;
}
}
playInList(currentPlay, listMediaId);
};
console.log(`dataType = ${JSON.stringify(dataType, null, 2)}`);
if (!dataType) {
return (
<>
<TopBar title="Type detail" />
<PageLayoutInfoCenter>
Fail to load Series id: {typeId}/{seriesId}/{seasonId}
</PageLayoutInfoCenter>
</>
);
}
return (
<>
<TopBar title="season detail">
<Button
{...BUTTON_TOP_BAR_PROPERTY}
onClick={() =>
navigate(
`/Type/${typeId}/series/${seriesId}/season/${seasonId}/edit-season/${seasonId}`
)
}
>
<MdEdit />
</Button>
</TopBar>
<PageLayout>
<Flex
direction="row"
width="80%"
marginX="auto"
padding="10px"
gap="10px"
>
<Covers data={dataType?.covers} iconEmpty={<LuDisc3 />} slideshow />
<Flex direction="column" width="80%" marginRight="auto">
<Text fontSize="24px" fontWeight="bold">
type: {dataType?.name}
</Text>
<Text fontSize="24px" fontWeight="bold">
series: {dataSeries?.name}
</Text>
<Text fontSize="24px" fontWeight="bold">
season: {dataSeason?.name}
</Text>
{dataSeason?.description && (
<Text>Description: {dataSeason?.description}</Text>
)}
</Flex>
</Flex>
<HStack
wrap="wrap"
gap="20px"
marginX="auto"
padding="20px"
justify="center"
>
{videos?.map((data) => (
<Box
key={data.id}
width="calc(max(300px,50%))"
height="60px"
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
>
<DisplayMediaListFull
media={data}
onClick={() => onSelectItem(data.id)}
contextMenu={[
{
name: 'Edit',
onClick: () => {
navigate(
`/type/${typeId}/series/${seriesId}/season/${seasonId}/edit-media/${data.id}`
);
},
},
{ name: 'Add Playlist', onClick: () => {} },
]}
/>
</Box>
))}
<EmptyEnd />
</HStack>
<Routes>
<Route path="edit-media/:mediaId" element={<MediaEditPopUp />} />
<Route path="edit-type/:typeId" element={<TypeEditPopUp />} />
{/* <Route path="edit-season/:seasonId" element={<TypeSeasonPopUp />} /> */}
</Routes>
</PageLayout>
</>
);
};

View File

@ -6,7 +6,9 @@ import { SessionServiceProps } from '@/service/session';
import { DataStoreType, useDataStore } from '@/utils/data-store';
import { DataTools, TypeCheck } from '@/utils/data-tools';
import { isNullOrUndefined } from '@/utils/validator';
import { useMediaService } from './Media';
import { useSeasonService } from './Season';
export type SeriesServiceProps = {
store: DataStoreType<Series>;
@ -67,7 +69,6 @@ export const useSpecificSeries = (id: number | undefined) => {
return { dataSeries };
};
export const useSeriesVideo = (id: number) => {
const { store } = useSeriesService();
const seriesVideo = useMemo(() => {
@ -78,7 +79,8 @@ export const useSeriesVideo = (id: number) => {
check: TypeCheck.EQUAL,
key: 'seriesId',
value: id,
}, {
},
{
check: TypeCheck.EQUAL,
key: 'seasonId',
value: undefined,
@ -96,41 +98,47 @@ export const useSeriesCountVideo = (id?: number) => {
if (id === undefined) {
return 0;
}
return DataTools.count(
store.data,
[
{
check: TypeCheck.EQUAL,
key: 'seriesId',
value: id,
},
]
);
return DataTools.count(store.data, [
{
check: TypeCheck.EQUAL,
key: 'seriesId',
value: id,
},
]);
}, [store.data, id]);
return { isLoading: store.isLoading, seriesCountVideo };
};
export const useSeriesSeasons = (id: number) => {
const { store } = useSeriesService();
const seriesSeason = useMemo(() => {
export const useSeasonWithSeries = (seriesId?: number) => {
const { store } = useSeasonService();
const seasonOfSeriesId = useMemo(() => {
if (seriesId === undefined) {
return [];
}
return DataTools.getsWhere(
store.data,
[
{
check: TypeCheck.EQUAL,
key: 'parentId',
value: id,
value: seriesId,
},
], ['id']
],
['name', 'id']
// TODO: ['>name', 'id'] padding right request ...:
// const maxLength = Math.max(...values.map(v => v.length));
// const paddedA = a.padStart(maxLength, " ");
// const paddedB = b.padStart(maxLength, " ");
// return paddedA.localeCompare(paddedB);
);
}, [store.data, id]);
return { isLoading: store.isLoading, dataTypes: seriesSeason };
}, [store.data, seriesId]);
return { isLoading: store.isLoading, seasonOfSeriesId };
};
export const useSeriesWithType = (typeId?: number) => {
const { store } = useSeriesService();
const seriesWithType = useMemo(() => {
if (typeId === undefined) {
return []
return [];
}
return DataTools.getsWhere(
store.data,
@ -139,10 +147,10 @@ export const useSeriesWithType = (typeId?: number) => {
check: TypeCheck.EQUAL,
key: 'parentId',
value: typeId,
}],
},
],
['name']
);
}, [store.data, typeId]);
return { isLoading: store.isLoading, seriesWithType };
};

View File

@ -6,6 +6,7 @@ import { SessionServiceProps } from '@/service/session';
import { DataStoreType, useDataStore } from '@/utils/data-store';
import { DataTools, TypeCheck } from '@/utils/data-tools';
import { isNullOrUndefined } from '@/utils/validator';
import { useMediaService } from './Media';
export type TypeServiceProps = {
@ -72,15 +73,13 @@ export const useTypeCountVideo = (id?: number) => {
if (id === undefined) {
return 0;
}
return DataTools.count(
store.data,
[
{
check: TypeCheck.EQUAL,
key: 'typeId',
value: id,
}]
);
return DataTools.count(store.data, [
{
check: TypeCheck.EQUAL,
key: 'typeId',
value: id,
},
]);
}, [store.data, id]);
return { isLoading: store.isLoading, countVideoWithType };
};
@ -98,18 +97,101 @@ export const useTypeGetVideo = (id?: number) => {
check: TypeCheck.EQUAL,
key: 'typeId',
value: id,
}, {
},
{
check: TypeCheck.EQUAL,
key: 'seriesId',
value: undefined,
}, {
},
{
check: TypeCheck.EQUAL,
key: 'universeId',
value: undefined,
},
], ['name']
],
['name']
);
}, [store.data, id]);
return { isLoading: store.isLoading, videoWithType };
};
export const useTypeSeriesGetVideo = (idType?: number, idSeries?: number) => {
const { store } = useMediaService();
const videoWithType = useMemo(() => {
if (idType === undefined) {
return [];
}
if (idSeries === undefined) {
return [];
}
return DataTools.getsWhere(
store.data,
[
{
check: TypeCheck.EQUAL,
key: 'typeId',
value: idType,
},
{
check: TypeCheck.EQUAL,
key: 'seriesId',
value: idSeries,
},
{
check: TypeCheck.EQUAL,
key: 'seasonId',
value: undefined,
},
{
check: TypeCheck.EQUAL,
key: 'universeId',
value: undefined,
},
],
['name']
);
}, [store.data, idType]);
return { isLoading: store.isLoading, videoWithType };
};
export const useTypeSeriesSeasonGetVideo = (idType?: number, idSeries?: number, idSeason?: number) => {
const { store } = useMediaService();
const videoWithType = useMemo(() => {
if (idType === undefined) {
return [];
}
if (idSeries === undefined) {
return [];
}
if (idSeason === undefined) {
return [];
}
return DataTools.getsWhere(
store.data,
[
{
check: TypeCheck.EQUAL,
key: 'typeId',
value: idType,
},
{
check: TypeCheck.EQUAL,
key: 'seriesId',
value: idSeries,
},
{
check: TypeCheck.EQUAL,
key: 'seasonId',
value: idSeason,
},
{
check: TypeCheck.EQUAL,
key: 'universeId',
value: undefined,
},
],
['episode', 'name']
);
}, [store.data, idType]);
return { isLoading: store.isLoading, videoWithType };
};

View File

@ -30,7 +30,7 @@ export namespace DataUrlAccess {
});
console.log(`get URL = ${url}`);
if (environment?.replaceDataToRealServer === true) {
return url.replace('http://localhost:19080', 'https://atria-soft.org');
return url.replace('http://localhost:18080', 'https://atria-soft.org');
}
return url;
}
@ -46,7 +46,7 @@ export namespace DataUrlAccess {
},
});
if (environment?.replaceDataToRealServer === true) {
return url.replace('http://localhost:19080', 'https://atria-soft.org');
return url.replace('http://localhost:18080', 'https://atria-soft.org');
}
return url;
};
@ -82,7 +82,7 @@ export namespace DataUrlAccess {
},
});
if (environment?.replaceDataToRealServer === true) {
return url.replace('http://localhost:19080', 'https://atria-soft.org');
return url.replace('http://localhost:18080', 'https://atria-soft.org');
}
return url;
};

View File

@ -4,7 +4,23 @@ import { defineConfig } from 'vite';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [
// other Vite plugins
react({
babel: {
plugins: [
// other Babel plugins
[
"@locator/babel-jsx/dist",
{
env: "development",
},
],
],
},
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),