diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 576486ce7..7450ac4e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,6 +208,9 @@ importers: shaka-player: specifier: 4.12.5 version: 4.12.5(patch_hash=ztcamgtqc3a62la4l6p3d6w4ae) + terser-webpack-plugin: + specifier: 5.3.14 + version: 5.3.14(webpack@5.96.1) typescript: specifier: 5.7.2 version: 5.7.2 @@ -4651,6 +4654,10 @@ packages: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} + schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + screenfull@5.2.0: resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} engines: {node: '>=0.10.0'} @@ -4906,8 +4913,8 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} - terser-webpack-plugin@5.3.10: - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -9721,6 +9728,13 @@ snapshots: ajv-formats: 2.1.1 ajv-keywords: 5.1.0(ajv@8.17.1) + schema-utils@4.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1 + ajv-keywords: 5.1.0(ajv@8.17.1) + screenfull@5.2.0: {} secure-json-parse@2.7.0: {} @@ -10062,11 +10076,11 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - terser-webpack-plugin@5.3.10(webpack@5.96.1): + terser-webpack-plugin@5.3.14(webpack@5.96.1): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 - schema-utils: 3.3.0 + schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.36.0 webpack: 5.96.1(webpack-cli@5.1.4) @@ -10414,7 +10428,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.96.1) + terser-webpack-plugin: 5.3.14(webpack@5.96.1) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: diff --git a/public/images/001.jpeg b/public/images/001.jpeg deleted file mode 100644 index dc813003b..000000000 Binary files a/public/images/001.jpeg and /dev/null differ diff --git a/public/images/001.webp b/public/images/001.webp new file mode 100644 index 000000000..1962bec91 Binary files /dev/null and b/public/images/001.webp differ diff --git a/public/images/002.jpeg b/public/images/002.jpeg deleted file mode 100644 index 1ece17f3e..000000000 Binary files a/public/images/002.jpeg and /dev/null differ diff --git a/public/images/002.webp b/public/images/002.webp new file mode 100644 index 000000000..2d3f3ea1c Binary files /dev/null and b/public/images/002.webp differ diff --git a/public/images/003.jpeg b/public/images/003.jpeg deleted file mode 100644 index ce28dbef0..000000000 Binary files a/public/images/003.jpeg and /dev/null differ diff --git a/public/images/003.webp b/public/images/003.webp new file mode 100644 index 000000000..46c741fc5 Binary files /dev/null and b/public/images/003.webp differ diff --git a/public/images/004.jpeg b/public/images/004.jpeg deleted file mode 100644 index 1ac258743..000000000 Binary files a/public/images/004.jpeg and /dev/null differ diff --git a/public/images/004.webp b/public/images/004.webp new file mode 100644 index 000000000..a7e3a5c3f Binary files /dev/null and b/public/images/004.webp differ diff --git a/public/images/005.jpeg b/public/images/005.jpeg deleted file mode 100644 index 033c8cb54..000000000 Binary files a/public/images/005.jpeg and /dev/null differ diff --git a/public/images/005.webp b/public/images/005.webp new file mode 100644 index 000000000..631639c63 Binary files /dev/null and b/public/images/005.webp differ diff --git a/public/images/006.jpeg b/public/images/006.jpeg deleted file mode 100644 index 254f8611b..000000000 Binary files a/public/images/006.jpeg and /dev/null differ diff --git a/public/images/006.webp b/public/images/006.webp new file mode 100644 index 000000000..e51b12c07 Binary files /dev/null and b/public/images/006.webp differ diff --git a/public/images/007.jpeg b/public/images/007.jpeg deleted file mode 100644 index f47135155..000000000 Binary files a/public/images/007.jpeg and /dev/null differ diff --git a/public/images/007.webp b/public/images/007.webp new file mode 100644 index 000000000..7bc804ae3 Binary files /dev/null and b/public/images/007.webp differ diff --git a/public/images/008.jpeg b/public/images/008.jpeg deleted file mode 100644 index 1b09e2d4e..000000000 Binary files a/public/images/008.jpeg and /dev/null differ diff --git a/public/images/008.webp b/public/images/008.webp new file mode 100644 index 000000000..874cafbb2 Binary files /dev/null and b/public/images/008.webp differ diff --git a/public/images/009.jpeg b/public/images/009.jpeg deleted file mode 100644 index dddf48709..000000000 Binary files a/public/images/009.jpeg and /dev/null differ diff --git a/public/images/009.webp b/public/images/009.webp new file mode 100644 index 000000000..09da9ead0 Binary files /dev/null and b/public/images/009.webp differ diff --git a/public/images/010.jpeg b/public/images/010.jpeg deleted file mode 100644 index cbb93cccd..000000000 Binary files a/public/images/010.jpeg and /dev/null differ diff --git a/public/images/010.webp b/public/images/010.webp new file mode 100644 index 000000000..1097ae526 Binary files /dev/null and b/public/images/010.webp differ diff --git a/public/images/011.jpeg b/public/images/011.jpeg deleted file mode 100644 index a1daeebba..000000000 Binary files a/public/images/011.jpeg and /dev/null differ diff --git a/public/images/011.webp b/public/images/011.webp new file mode 100644 index 000000000..adedd4d57 Binary files /dev/null and b/public/images/011.webp differ diff --git a/public/images/012.jpeg b/public/images/012.jpeg deleted file mode 100644 index c5426d6f9..000000000 Binary files a/public/images/012.jpeg and /dev/null differ diff --git a/public/images/012.webp b/public/images/012.webp new file mode 100644 index 000000000..62b16abe6 Binary files /dev/null and b/public/images/012.webp differ diff --git a/public/images/013.jpeg b/public/images/013.jpeg deleted file mode 100644 index 8ad516a13..000000000 Binary files a/public/images/013.jpeg and /dev/null differ diff --git a/public/images/013.webp b/public/images/013.webp new file mode 100644 index 000000000..9bbd5959f Binary files /dev/null and b/public/images/013.webp differ diff --git a/public/images/014.jpeg b/public/images/014.jpeg deleted file mode 100644 index be184c423..000000000 Binary files a/public/images/014.jpeg and /dev/null differ diff --git a/public/images/014.webp b/public/images/014.webp new file mode 100644 index 000000000..e0a613f80 Binary files /dev/null and b/public/images/014.webp differ diff --git a/public/images/015.jpeg b/public/images/015.jpeg deleted file mode 100644 index 7485bee90..000000000 Binary files a/public/images/015.jpeg and /dev/null differ diff --git a/public/images/015.webp b/public/images/015.webp new file mode 100644 index 000000000..d1b4651e0 Binary files /dev/null and b/public/images/015.webp differ diff --git a/public/images/016.jpeg b/public/images/016.jpeg deleted file mode 100644 index 4cfbb87bd..000000000 Binary files a/public/images/016.jpeg and /dev/null differ diff --git a/public/images/016.webp b/public/images/016.webp new file mode 100644 index 000000000..0be5b766d Binary files /dev/null and b/public/images/016.webp differ diff --git a/public/images/017.jpeg b/public/images/017.jpeg deleted file mode 100644 index 39a2f2408..000000000 Binary files a/public/images/017.jpeg and /dev/null differ diff --git a/public/images/017.webp b/public/images/017.webp new file mode 100644 index 000000000..3d9bbd69d Binary files /dev/null and b/public/images/017.webp differ diff --git a/public/images/018.jpeg b/public/images/018.jpeg deleted file mode 100644 index f6ae9d20f..000000000 Binary files a/public/images/018.jpeg and /dev/null differ diff --git a/public/images/018.webp b/public/images/018.webp new file mode 100644 index 000000000..81c69c828 Binary files /dev/null and b/public/images/018.webp differ diff --git a/public/images/019.jpeg b/public/images/019.jpeg deleted file mode 100644 index 2f36db641..000000000 Binary files a/public/images/019.jpeg and /dev/null differ diff --git a/public/images/019.webp b/public/images/019.webp new file mode 100644 index 000000000..fbbcbc9a0 Binary files /dev/null and b/public/images/019.webp differ diff --git a/public/images/020.jpeg b/public/images/020.jpeg deleted file mode 100644 index b4a566b73..000000000 Binary files a/public/images/020.jpeg and /dev/null differ diff --git a/public/images/020.webp b/public/images/020.webp new file mode 100644 index 000000000..03f49e51d Binary files /dev/null and b/public/images/020.webp differ diff --git a/public/images/021.jpeg b/public/images/021.jpeg deleted file mode 100644 index 6d663e7f9..000000000 Binary files a/public/images/021.jpeg and /dev/null differ diff --git a/public/images/021.webp b/public/images/021.webp new file mode 100644 index 000000000..f314b8fbb Binary files /dev/null and b/public/images/021.webp differ diff --git a/public/images/022.jpeg b/public/images/022.jpeg deleted file mode 100644 index aa5cccf8c..000000000 Binary files a/public/images/022.jpeg and /dev/null differ diff --git a/public/images/022.webp b/public/images/022.webp new file mode 100644 index 000000000..d9cbaeb4f Binary files /dev/null and b/public/images/022.webp differ diff --git a/public/images/023.jpeg b/public/images/023.jpeg deleted file mode 100644 index 1e1e4e7d3..000000000 Binary files a/public/images/023.jpeg and /dev/null differ diff --git a/public/images/023.webp b/public/images/023.webp new file mode 100644 index 000000000..01c945a4b Binary files /dev/null and b/public/images/023.webp differ diff --git a/public/images/024.jpeg b/public/images/024.jpeg deleted file mode 100644 index c5e5f86c8..000000000 Binary files a/public/images/024.jpeg and /dev/null differ diff --git a/public/images/024.webp b/public/images/024.webp new file mode 100644 index 000000000..c90451b99 Binary files /dev/null and b/public/images/024.webp differ diff --git a/public/images/025.jpeg b/public/images/025.jpeg deleted file mode 100644 index e1c9bc113..000000000 Binary files a/public/images/025.jpeg and /dev/null differ diff --git a/public/images/025.webp b/public/images/025.webp new file mode 100644 index 000000000..27e4b28c6 Binary files /dev/null and b/public/images/025.webp differ diff --git a/public/images/026.jpeg b/public/images/026.jpeg deleted file mode 100644 index 9169af8dd..000000000 Binary files a/public/images/026.jpeg and /dev/null differ diff --git a/public/images/026.webp b/public/images/026.webp new file mode 100644 index 000000000..ac4b90942 Binary files /dev/null and b/public/images/026.webp differ diff --git a/public/images/027.jpeg b/public/images/027.jpeg deleted file mode 100644 index 754c29f51..000000000 Binary files a/public/images/027.jpeg and /dev/null differ diff --git a/public/images/027.webp b/public/images/027.webp new file mode 100644 index 000000000..256c76dac Binary files /dev/null and b/public/images/027.webp differ diff --git a/public/images/028.jpeg b/public/images/028.jpeg deleted file mode 100644 index d27b403be..000000000 Binary files a/public/images/028.jpeg and /dev/null differ diff --git a/public/images/028.webp b/public/images/028.webp new file mode 100644 index 000000000..6ceb1c670 Binary files /dev/null and b/public/images/028.webp differ diff --git a/public/images/029.jpeg b/public/images/029.jpeg deleted file mode 100644 index e74fa0ed4..000000000 Binary files a/public/images/029.jpeg and /dev/null differ diff --git a/public/images/029.webp b/public/images/029.webp new file mode 100644 index 000000000..f40bcef6f Binary files /dev/null and b/public/images/029.webp differ diff --git a/public/images/030.jpeg b/public/images/030.jpeg deleted file mode 100644 index 9d7fe74ff..000000000 Binary files a/public/images/030.jpeg and /dev/null differ diff --git a/public/images/030.webp b/public/images/030.webp new file mode 100644 index 000000000..c9cab52b5 Binary files /dev/null and b/public/images/030.webp differ diff --git a/public/images/031.jpeg b/public/images/031.jpeg deleted file mode 100644 index 926a3ee74..000000000 Binary files a/public/images/031.jpeg and /dev/null differ diff --git a/public/images/031.webp b/public/images/031.webp new file mode 100644 index 000000000..164d47d61 Binary files /dev/null and b/public/images/031.webp differ diff --git a/public/images/032.jpeg b/public/images/032.jpeg deleted file mode 100644 index 57d8a4424..000000000 Binary files a/public/images/032.jpeg and /dev/null differ diff --git a/public/images/032.webp b/public/images/032.webp new file mode 100644 index 000000000..5e7783640 Binary files /dev/null and b/public/images/032.webp differ diff --git a/public/images/033.jpeg b/public/images/033.jpeg deleted file mode 100644 index cb8d05eb9..000000000 Binary files a/public/images/033.jpeg and /dev/null differ diff --git a/public/images/033.webp b/public/images/033.webp new file mode 100644 index 000000000..639708252 Binary files /dev/null and b/public/images/033.webp differ diff --git a/public/images/034.jpeg b/public/images/034.jpeg deleted file mode 100644 index d96e76079..000000000 Binary files a/public/images/034.jpeg and /dev/null differ diff --git a/public/images/034.webp b/public/images/034.webp new file mode 100644 index 000000000..7ead87596 Binary files /dev/null and b/public/images/034.webp differ diff --git a/public/images/035.jpeg b/public/images/035.jpeg deleted file mode 100644 index 0d3a506f3..000000000 Binary files a/public/images/035.jpeg and /dev/null differ diff --git a/public/images/035.webp b/public/images/035.webp new file mode 100644 index 000000000..e21d114a4 Binary files /dev/null and b/public/images/035.webp differ diff --git a/public/images/036.jpeg b/public/images/036.jpeg deleted file mode 100644 index 1f349e9ab..000000000 Binary files a/public/images/036.jpeg and /dev/null differ diff --git a/public/images/036.webp b/public/images/036.webp new file mode 100644 index 000000000..9a2c824da Binary files /dev/null and b/public/images/036.webp differ diff --git a/public/images/037.jpeg b/public/images/037.jpeg deleted file mode 100644 index b18bed87b..000000000 Binary files a/public/images/037.jpeg and /dev/null differ diff --git a/public/images/037.webp b/public/images/037.webp new file mode 100644 index 000000000..0cfff284e Binary files /dev/null and b/public/images/037.webp differ diff --git a/workspaces/client/package.json b/workspaces/client/package.json index f6c261693..b2cd50183 100644 --- a/workspaces/client/package.json +++ b/workspaces/client/package.json @@ -76,7 +76,8 @@ "webpack-bundle-analyzer": "4.10.2", "webpack-cli": "5.1.4", "webpack-dev-server": "5.1.0", - "wireit": "0.14.9" + "wireit": "0.14.9", + "terser-webpack-plugin": "5.3.14" }, "wireit": { "build": { diff --git a/workspaces/client/src/app/createRoutes.tsx b/workspaces/client/src/app/createRoutes.tsx index a81e12561..190d280ff 100644 --- a/workspaces/client/src/app/createRoutes.tsx +++ b/workspaces/client/src/app/createRoutes.tsx @@ -13,7 +13,7 @@ export function createRoutes(store: ReturnType): RouteObject async lazy() { const { HomePage, prefetch } = await lazy( import('@wsh-2025/client/src/pages/home/components/HomePage'), - 1000, + 500, ); return { Component: HomePage, @@ -27,7 +27,7 @@ export function createRoutes(store: ReturnType): RouteObject async lazy() { const { EpisodePage, prefetch } = await lazy( import('@wsh-2025/client/src/pages/episode/components/EpisodePage'), - 1000, + 500, ); return { Component: EpisodePage, @@ -42,7 +42,7 @@ export function createRoutes(store: ReturnType): RouteObject async lazy() { const { prefetch, ProgramPage } = await lazy( import('@wsh-2025/client/src/pages/program/components/ProgramPage'), - 1000, + 500, ); return { Component: ProgramPage, @@ -57,7 +57,7 @@ export function createRoutes(store: ReturnType): RouteObject async lazy() { const { prefetch, SeriesPage } = await lazy( import('@wsh-2025/client/src/pages/series/components/SeriesPage'), - 1000, + 500, ); return { Component: SeriesPage, @@ -72,7 +72,7 @@ export function createRoutes(store: ReturnType): RouteObject async lazy() { const { prefetch, TimetablePage } = await lazy( import('@wsh-2025/client/src/pages/timetable/components/TimetablePage'), - 1000, + 500, ); return { Component: TimetablePage, @@ -87,7 +87,7 @@ export function createRoutes(store: ReturnType): RouteObject async lazy() { const { NotFoundPage, prefetch } = await lazy( import('@wsh-2025/client/src/pages/not_found/components/NotFoundPage'), - 1000, + 500, ); return { Component: NotFoundPage, diff --git a/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts b/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts index 2543d978e..f0afc9709 100644 --- a/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts +++ b/workspaces/client/src/features/channel/stores/createChannelStoreSlice.ts @@ -1,6 +1,6 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getChannelByIdResponse, getChannelsResponse } from '@wsh-2025/schema/src/api/schema'; import { produce } from 'immer'; import { channelService } from '@wsh-2025/client/src/features/channel/services/channelService'; @@ -8,14 +8,14 @@ import { channelService } from '@wsh-2025/client/src/features/channel/services/c type ChannelId = string; interface ChannelState { - channels: Record>; + channels: Record>; } interface ChannelActions { fetchChannelById: (params: { channelId: ChannelId; - }) => Promise>; - fetchChannels: () => Promise>; + }) => Promise>; + fetchChannels: () => Promise>; } export const createChannelStoreSlice = () => { diff --git a/workspaces/client/src/features/episode/services/episodeService.ts b/workspaces/client/src/features/episode/services/episodeService.ts index 3a21b8194..54a40355e 100644 --- a/workspaces/client/src/features/episode/services/episodeService.ts +++ b/workspaces/client/src/features/episode/services/episodeService.ts @@ -1,6 +1,6 @@ import { createFetch, createSchema } from '@better-fetch/fetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getEpisodeByIdResponse, getEpisodesResponse, getEpisodesRequestQuery } from '@wsh-2025/schema/src/api/schema'; import * as batshit from '@yornaath/batshit'; import { schedulePlugin } from '@wsh-2025/client/src/features/requests/schedulePlugin'; @@ -10,11 +10,11 @@ const $fetch = createFetch({ plugins: [schedulePlugin], schema: createSchema({ '/episodes': { - output: schema.getEpisodesResponse, - query: schema.getEpisodesRequestQuery, + output: getEpisodesResponse, + query: getEpisodesRequestQuery, }, '/episodes/:episodeId': { - output: schema.getEpisodeByIdResponse, + output: getEpisodeByIdResponse, }, }), throw: true, @@ -45,8 +45,8 @@ const batcher = batshit.create({ interface EpisodeService { fetchEpisodeById: (query: { episodeId: string; - }) => Promise>; - fetchEpisodes: () => Promise>; + }) => Promise>; + fetchEpisodes: () => Promise>; } export const episodeService: EpisodeService = { diff --git a/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts b/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts index d5d8fef8a..df107fe1c 100644 --- a/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts +++ b/workspaces/client/src/features/episode/stores/createEpisodeStoreSlice.ts @@ -1,6 +1,6 @@ import { lens } from '@dhmk/zustand-lens'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getEpisodeByIdResponse, getEpisodesResponse } from '@wsh-2025/schema/src/api/schema'; import { produce } from 'immer'; import { episodeService } from '@wsh-2025/client/src/features/episode/services/episodeService'; @@ -8,14 +8,14 @@ import { episodeService } from '@wsh-2025/client/src/features/episode/services/e type EpisodeId = string; interface EpisodeState { - episodes: Record>; + episodes: Record>; } interface EpisodeActions { fetchEpisodeById: (params: { episodeId: EpisodeId; - }) => Promise>; - fetchEpisodes: () => Promise>; + }) => Promise>; + fetchEpisodes: () => Promise>; } export const createEpisodeStoreSlice = () => { diff --git a/workspaces/client/src/features/layout/components/Layout.tsx b/workspaces/client/src/features/layout/components/Layout.tsx index 99eadef4b..8c27ff383 100644 --- a/workspaces/client/src/features/layout/components/Layout.tsx +++ b/workspaces/client/src/features/layout/components/Layout.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { ReactNode, useEffect, useState } from 'react'; +import { ReactNode, useEffect, useState, useCallback } from 'react'; import { Flipper } from 'react-flip-toolkit'; import { Link, useLocation, useNavigation } from 'react-router'; @@ -46,8 +46,8 @@ export const Layout = ({ children }: Props) => { }; }, []); - useEffect(() => { - setShouldHeaderBeTransparent(scrollTopOffset > 80); + useCallback(() => { + setShouldHeaderBeTransparent(scrollTopOffset > 1000); }, [scrollTopOffset]); const isSignedIn = user != null; diff --git a/workspaces/client/src/features/recommended/components/CarouselSection.tsx b/workspaces/client/src/features/recommended/components/CarouselSection.tsx index e81aa410e..d4d6f964d 100644 --- a/workspaces/client/src/features/recommended/components/CarouselSection.tsx +++ b/workspaces/client/src/features/recommended/components/CarouselSection.tsx @@ -1,16 +1,17 @@ import { ElementScrollRestoration } from '@epic-web/restore-scroll'; import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/api/schema'; +import React from 'react'; import { ArrayValues } from 'type-fest'; import { useMergeRefs } from 'use-callback-ref'; -import { EpisodeItem } from '@wsh-2025/client/src/features/recommended/components/EpisodeItem'; -import { SeriesItem } from '@wsh-2025/client/src/features/recommended/components/SeriesItem'; +import { MemoEpisodeItem } from '@wsh-2025/client/src/features/recommended/components/EpisodeItem'; +import { MemoSeriesItem } from '@wsh-2025/client/src/features/recommended/components/SeriesItem'; import { useCarouselItemWidth } from '@wsh-2025/client/src/features/recommended/hooks/useCarouselItemWidth'; import { useScrollSnap } from '@wsh-2025/client/src/features/recommended/hooks/useScrollSnap'; interface Props { - module: ArrayValues>; + module: ArrayValues>; } export const CarouselSection = ({ module }: Props) => { @@ -30,8 +31,8 @@ export const CarouselSection = ({ module }: Props) => { > {module.items.map((item) => (
- {item.series != null ? : null} - {item.episode != null ? : null} + {item.series != null ? : null} + {item.episode != null ? : null}
))} @@ -41,3 +42,5 @@ export const CarouselSection = ({ module }: Props) => { ); }; + +export const MemoCarouselSection = React.memo(CarouselSection); \ No newline at end of file diff --git a/workspaces/client/src/features/recommended/components/EpisodeItem.tsx b/workspaces/client/src/features/recommended/components/EpisodeItem.tsx index 74b08745c..457fc17a1 100644 --- a/workspaces/client/src/features/recommended/components/EpisodeItem.tsx +++ b/workspaces/client/src/features/recommended/components/EpisodeItem.tsx @@ -1,8 +1,10 @@ +import React from 'react'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; interface Props { episode: { @@ -25,7 +27,7 @@ export const EpisodeItem = ({ episode }: Props) => { <>
- + {episode.premium ? ( @@ -49,3 +51,5 @@ export const EpisodeItem = ({ episode }: Props) => { ); }; + +export const MemoEpisodeItem = React.memo(EpisodeItem); \ No newline at end of file diff --git a/workspaces/client/src/features/recommended/components/JumbotronSection.tsx b/workspaces/client/src/features/recommended/components/JumbotronSection.tsx index 638c9cfd6..2908f5834 100644 --- a/workspaces/client/src/features/recommended/components/JumbotronSection.tsx +++ b/workspaces/client/src/features/recommended/components/JumbotronSection.tsx @@ -1,6 +1,7 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/api/schema'; import { useRef } from 'react'; +import React from 'react'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; @@ -14,7 +15,7 @@ import { PlayerWrapper } from '../../player/interfaces/player_wrapper'; import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; interface Props { - module: ArrayValues>; + module: ArrayValues>; } export const JumbotronSection = ({ module }: Props) => { @@ -60,3 +61,6 @@ export const JumbotronSection = ({ module }: Props) => { ); }; + + +export const MemoJumbotronSection = React.memo(JumbotronSection); \ No newline at end of file diff --git a/workspaces/client/src/features/recommended/components/RecommendedSection.tsx b/workspaces/client/src/features/recommended/components/RecommendedSection.tsx index d3e287ef0..f96c33cbd 100644 --- a/workspaces/client/src/features/recommended/components/RecommendedSection.tsx +++ b/workspaces/client/src/features/recommended/components/RecommendedSection.tsx @@ -1,18 +1,21 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; -import * as schema from '@wsh-2025/schema/src/api/schema'; +import { getRecommendedModulesResponse } from '@wsh-2025/schema/src/api/schema'; +import React from 'react'; import { ArrayValues } from 'type-fest'; -import { CarouselSection } from '@wsh-2025/client/src/features/recommended/components/CarouselSection'; -import { JumbotronSection } from '@wsh-2025/client/src/features/recommended/components/JumbotronSection'; +import { MemoCarouselSection } from '@wsh-2025/client/src/features/recommended/components/CarouselSection'; +import { MemoJumbotronSection } from '@wsh-2025/client/src/features/recommended/components/JumbotronSection'; interface Props { - module: ArrayValues>; + module: ArrayValues>; } export const RecommendedSection = ({ module }: Props) => { if (module.type === 'jumbotron') { - return ; + return ; } else { - return ; + return ; } }; + +export const MemoRecommendedSection = React.memo(RecommendedSection); diff --git a/workspaces/client/src/features/recommended/components/SeriesItem.tsx b/workspaces/client/src/features/recommended/components/SeriesItem.tsx index 2477b7a97..a7fd95f4c 100644 --- a/workspaces/client/src/features/recommended/components/SeriesItem.tsx +++ b/workspaces/client/src/features/recommended/components/SeriesItem.tsx @@ -1,8 +1,10 @@ +import React from 'react'; import Ellipsis from 'react-ellipsis-component'; import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; interface Props { series: { @@ -21,7 +23,7 @@ export const SeriesItem = ({ series }: Props) => { <>
- +
@@ -36,3 +38,5 @@ export const SeriesItem = ({ series }: Props) => { ); }; + +export const MemoSeriesItem = React.memo(SeriesItem); diff --git a/workspaces/client/src/features/series/components/SeriesEposideItem.tsx b/workspaces/client/src/features/series/components/SeriesEposideItem.tsx index 0a0067d95..93542807e 100644 --- a/workspaces/client/src/features/series/components/SeriesEposideItem.tsx +++ b/workspaces/client/src/features/series/components/SeriesEposideItem.tsx @@ -3,6 +3,7 @@ import { Flipped } from 'react-flip-toolkit'; import { NavLink } from 'react-router'; import { Hoverable } from '@wsh-2025/client/src/features/layout/components/Hoverable'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; interface Props { episode: { @@ -28,7 +29,7 @@ export const SeriesEpisodeItem = ({ episode, selected }: Props) => { <>
- + {episode.premium ? ( diff --git a/workspaces/client/src/main.tsx b/workspaces/client/src/main.tsx index 601b7a6a5..061dfd26c 100644 --- a/workspaces/client/src/main.tsx +++ b/workspaces/client/src/main.tsx @@ -25,7 +25,7 @@ function main() { store}> - , + ); } diff --git a/workspaces/client/src/pages/episode/components/EpisodePage.tsx b/workspaces/client/src/pages/episode/components/EpisodePage.tsx index 075eacc48..af175da01 100644 --- a/workspaces/client/src/pages/episode/components/EpisodePage.tsx +++ b/workspaces/client/src/pages/episode/components/EpisodePage.tsx @@ -16,6 +16,7 @@ import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/ import { SeriesEpisodeList } from '@wsh-2025/client/src/features/series/components/SeriesEpisodeList'; import { PlayerController } from '@wsh-2025/client/src/pages/episode/components/PlayerController'; import { usePlayerRef } from '@wsh-2025/client/src/pages/episode/hooks/usePlayerRef'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; export const prefetch = async (store: ReturnType, { episodeId }: Params) => { invariant(episodeId); @@ -51,7 +52,7 @@ export const EpisodePage = () => {
{isSignInRequired ? (
- +

@@ -74,7 +75,8 @@ export const EpisodePage = () => {

diff --git a/workspaces/client/src/pages/home/components/HomePage.tsx b/workspaces/client/src/pages/home/components/HomePage.tsx index 86cb77e6c..8fc0214c8 100644 --- a/workspaces/client/src/pages/home/components/HomePage.tsx +++ b/workspaces/client/src/pages/home/components/HomePage.tsx @@ -1,5 +1,5 @@ import { createStore } from '@wsh-2025/client/src/app/createStore'; -import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; +import { MemoRecommendedSection } from '@wsh-2025/client/src/features/recommended/components/RecommendedSection'; import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; export const prefetch = async (store: ReturnType) => { @@ -11,7 +11,6 @@ export const prefetch = async (store: ReturnType) => { export const HomePage = () => { const modules = useRecommended({ referenceId: 'entrance' }); - return ( <> Home - AremaTV @@ -20,11 +19,11 @@ export const HomePage = () => { {modules.map((module) => { return (
- +
); })}
); -}; +}; \ No newline at end of file diff --git a/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx b/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx index 66c861769..6a32e20a2 100644 --- a/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx +++ b/workspaces/client/src/pages/not_found/components/NotFoundPage.tsx @@ -21,7 +21,7 @@ export const NotFoundPage = () => {

ページが見つかりませんでした

あなたが見ようとしたページは、残念ながら見つけられませんでした。

- +
{module != null ? : null}
diff --git a/workspaces/client/src/pages/program/components/ProgramPage.tsx b/workspaces/client/src/pages/program/components/ProgramPage.tsx index d13dc9426..16e30905d 100644 --- a/workspaces/client/src/pages/program/components/ProgramPage.tsx +++ b/workspaces/client/src/pages/program/components/ProgramPage.tsx @@ -16,6 +16,7 @@ import { SeriesEpisodeList } from '@wsh-2025/client/src/features/series/componen import { useTimetable } from '@wsh-2025/client/src/features/timetable/hooks/useTimetable'; import { PlayerController } from '@wsh-2025/client/src/pages/program/components/PlayerController'; import { usePlayerRef } from '@wsh-2025/client/src/pages/program/hooks/usePlayerRef'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; export const prefetch = async (store: ReturnType, { programId }: Params) => { invariant(programId); @@ -101,7 +102,7 @@ export const ProgramPage = () => {
{isArchivedRef.current ? (
- +

この番組は放送が終了しました

@@ -127,7 +128,7 @@ export const ProgramPage = () => {
) : (
- +

diff --git a/workspaces/client/src/pages/series/components/SeriesPage.tsx b/workspaces/client/src/pages/series/components/SeriesPage.tsx index abf35aee5..44e115968 100644 --- a/workspaces/client/src/pages/series/components/SeriesPage.tsx +++ b/workspaces/client/src/pages/series/components/SeriesPage.tsx @@ -8,6 +8,7 @@ import { RecommendedSection } from '@wsh-2025/client/src/features/recommended/co import { useRecommended } from '@wsh-2025/client/src/features/recommended/hooks/useRecommended'; import { SeriesEpisodeList } from '@wsh-2025/client/src/features/series/components/SeriesEpisodeList'; import { useSeriesById } from '@wsh-2025/client/src/features/series/hooks/useSeriesById'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; export const prefetch = async (store: ReturnType, { seriesId }: Params) => { invariant(seriesId); @@ -37,7 +38,8 @@ export const SeriesPage = () => {

diff --git a/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx b/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx index c2538c886..bcc7d0cc8 100644 --- a/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx +++ b/workspaces/client/src/pages/timetable/components/ChannelTitle.tsx @@ -3,6 +3,7 @@ import invariant from 'tiny-invariant'; import { useChannelById } from '@wsh-2025/client/src/features/channel/hooks/useChannelById'; import { Gutter } from '@wsh-2025/client/src/pages/timetable/components/Gutter'; import { useColumnWidth } from '@wsh-2025/client/src/pages/timetable/hooks/useColumnWidth'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; interface Props { channelId: string; @@ -17,7 +18,7 @@ export const ChannelTitle = ({ channelId }: Props) => { return (
- {channel.name} + {channel.name}
diff --git a/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx b/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx index ce0f9224a..05337ab73 100644 --- a/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx +++ b/workspaces/client/src/pages/timetable/components/NewTimetableFeatureDialog.tsx @@ -1,6 +1,7 @@ import FeatureExplainImageUrl from '@wsh-2025/client/assets/timetable/feature-explain.png'; import { Dialog } from '@wsh-2025/client/src/features/dialog/components/Dialog'; import { useCloseNewFeatureDialog } from '@wsh-2025/client/src/pages/timetable/hooks/useCloseNewFeatureDialog'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; interface Props { isOpen: boolean; @@ -29,7 +30,7 @@ export const NewTimetableFeatureDialog = ({ isOpen }: Props) => { 引き続き皆様に快適にご利用いただけるよう、サービスの改善に努めてまいります。今後ともどうぞよろしくお願いいたします。

- +
diff --git a/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx b/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx index 41e0ec14c..77451d41d 100644 --- a/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx +++ b/workspaces/client/src/pages/timetable/components/ProgramDetailDialog.tsx @@ -7,6 +7,7 @@ import { ArrayValues } from 'type-fest'; import { Dialog } from '@wsh-2025/client/src/features/dialog/components/Dialog'; import { useEpisode } from '@wsh-2025/client/src/pages/timetable/hooks/useEpisode'; import { useSelectedProgramId } from '@wsh-2025/client/src/pages/timetable/hooks/useSelectedProgramId'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; interface Props { isOpen: boolean; @@ -33,7 +34,8 @@ export const ProgramDetailDialog = ({ isOpen, program }: Props): ReactElement => {episode != null ? ( @@ -47,7 +49,8 @@ export const ProgramDetailDialog = ({ isOpen, program }: Props): ReactElement => ) : null} diff --git a/workspaces/client/src/pages/timetable/hooks/useEpisode.ts b/workspaces/client/src/pages/timetable/hooks/useEpisode.ts index f6d7677c9..da4c0c86f 100644 --- a/workspaces/client/src/pages/timetable/hooks/useEpisode.ts +++ b/workspaces/client/src/pages/timetable/hooks/useEpisode.ts @@ -1,6 +1,6 @@ import { StandardSchemaV1 } from '@standard-schema/spec'; import * as schema from '@wsh-2025/schema/src/api/schema'; -import { useEffect, useState } from 'react'; +import { useCallback, useState } from 'react'; import { episodeService } from '@wsh-2025/client/src/features/episode/services/episodeService'; @@ -9,7 +9,7 @@ type Episode = StandardSchemaV1.InferOutput(null); - useEffect(() => { + useCallback(() => { episodeService .fetchEpisodeById({ episodeId }) .then(setEpisode) diff --git a/workspaces/client/src/utility/file.ts b/workspaces/client/src/utility/file.ts new file mode 100644 index 000000000..ee5d2a585 --- /dev/null +++ b/workspaces/client/src/utility/file.ts @@ -0,0 +1,8 @@ +export function alterExterntion(filUrl: string): string{ + const regexp = /.jpeg|.png|.jpg/; + if(regexp.test(filUrl)){ + return filUrl.replace(regexp, '.webp'); + }else{ + return filUrl; + } +} \ No newline at end of file diff --git a/workspaces/client/webpack.config.mjs b/workspaces/client/webpack.config.mjs index 9164a996e..915bac113 100644 --- a/workspaces/client/webpack.config.mjs +++ b/workspaces/client/webpack.config.mjs @@ -1,12 +1,11 @@ import path from 'node:path'; - +import TerserPlugin from 'terser-webpack-plugin'; import webpack from 'webpack'; /** @type {import('webpack').Configuration} */ const config = { - devtool: 'inline-source-map', entry: './src/main.tsx', - mode: 'none', + mode: 'production', module: { rules: [ { @@ -59,7 +58,7 @@ const config = { publicPath: 'auto', }, plugins: [ - new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }), + new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 5 }), new webpack.EnvironmentPlugin({ API_BASE_URL: '/api', NODE_ENV: '' }), ], resolve: { @@ -69,6 +68,25 @@ const config = { }, extensions: ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts', '.tsx', '.jsx'], }, + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + parallel: 2, + // minify: TerserPlugin.swcMinify, + terserOptions: { + compress: { + ecma: 5, + comparisons: false, + inline: 2, + }, + mangle: { + safari10: true, + }, + }, + }), + ], + } }; export default config; diff --git a/workspaces/server/src/index.ts b/workspaces/server/src/index.ts index e02ab7613..93fae28fb 100644 --- a/workspaces/server/src/index.ts +++ b/workspaces/server/src/index.ts @@ -14,7 +14,7 @@ async function main() { const app = fastify(); app.addHook('onSend', async (_req, reply) => { - reply.header('cache-control', 'no-store'); + reply.header('cache-control', 'private'); //TODO:要検討 }); app.register(cors, { origin: true, diff --git a/workspaces/server/src/ssr.tsx b/workspaces/server/src/ssr.tsx index 7603aafdd..423f80d03 100644 --- a/workspaces/server/src/ssr.tsx +++ b/workspaces/server/src/ssr.tsx @@ -6,6 +6,7 @@ import fastifyStatic from '@fastify/static'; import { StoreProvider } from '@wsh-2025/client/src/app/StoreContext'; import { createRoutes } from '@wsh-2025/client/src/app/createRoutes'; import { createStore } from '@wsh-2025/client/src/app/createStore'; +import { alterExterntion } from '@wsh-2025/client/src/utility/file'; import type { FastifyInstance } from 'fastify'; import { createStandardRequest } from 'fastify-standard-request-reply'; import htmlescape from 'htmlescape'; @@ -73,7 +74,7 @@ export function registerSsr(app: FastifyInstance): void { - ${imagePaths.map((imagePath) => ``).join('\n')} + ${imagePaths.map((imagePath) => ``).join('\n')}