diff --git a/package.json b/package.json index 430d7237..c1ebce97 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "dependencies": { "@firebolt-js/sdk": "^1.5.0", "@lightningjs/l3-ui-theme-base": "^0.3.3", - "@lightningjs/renderer": "3.0.0-beta7", "@lightningtv/core": "3.0.0-2", "@lightningtv/l3-ui-theme-base": "^1.0.0", "@lightningtv/solid": "3.0.0-2", @@ -57,8 +56,7 @@ "pnpm": { "overrides": { "@lightningtv/core": "$@lightningtv/core", - "@lightningtv/solid": "$@lightningtv/solid", - "@lightningjs/renderer": "$@lightningjs/renderer" + "@lightningtv/solid": "$@lightningtv/solid" } }, "lint-staged": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36c6f30d..7a5a9284 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,6 @@ settings: overrides: '@lightningtv/core': 3.0.0-2 '@lightningtv/solid': 3.0.0-2 - '@lightningjs/renderer': 3.0.0-beta7 importers: @@ -19,9 +18,6 @@ importers: '@lightningjs/l3-ui-theme-base': specifier: ^0.3.3 version: 0.3.3 - '@lightningjs/renderer': - specifier: 3.0.0-beta7 - version: 3.0.0-beta7 '@lightningtv/core': specifier: 3.0.0-2 version: 3.0.0-2(@lightningjs/renderer@3.0.0-beta7) @@ -959,7 +955,7 @@ packages: '@lightningtv/core@3.0.0-2': resolution: {integrity: sha512-aDIQlCp1+oK6rQL9ZSn4y/yTK7cIaiW1fOoKPinXKUJKiuU+fIOIyu2kAeNW/AMTl/YjTdMqXuwtW1Tcy5F65g==} peerDependencies: - '@lightningjs/renderer': 3.0.0-beta7 + '@lightningjs/renderer': ^3.0.0-beta4 '@lightningtv/l3-ui-theme-base@1.0.0': resolution: {integrity: sha512-yxjhkNfcN4cDwsrD5Nd1jRqxM/ZetqVG9EppCIEbqaECflw11RI0GvhS7+Wpi4R++4lqsQEYqTN+UVRs56iTMQ==} @@ -967,7 +963,7 @@ packages: '@lightningtv/solid@3.0.0-2': resolution: {integrity: sha512-S4Z08Hu9BO4G3UX6QoYxvZIJEj8YmkWCNLta48d7qepytWq4t5/dVwIZqrc1GGJh3aNFygDFJC0+B2aYbvxnmg==} peerDependencies: - '@lightningjs/renderer': 3.0.0-beta7 + '@lightningjs/renderer': ^3.0.0-beta3 '@solidjs/router': ^0.15.1 solid-js: '*' diff --git a/src/api/index.ts b/src/api/index.ts index cca60d30..baf8d6fc 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -33,7 +33,11 @@ function _get(path: string, params: RequestInit = {}) { function loadConfig() { return _get("/configuration").then((data) => { tmdbConfig = data; - baseImageUrl = data.images?.secure_base_url; + if (__LIGHTNING_DOM_RENDERING__ && import.meta.env.DEV) { + baseImageUrl = '/image_tmdb/' + } else { + baseImageUrl = data.images?.secure_base_url; + } return data; }); } diff --git a/src/index.tsx b/src/index.tsx index 14c1a525..8d92acc5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,60 +5,13 @@ import {elementInterface} from "@lightningtv/solid/devtools"; setElementInterface(elementInterface) -import { createRenderer, Config, loadFonts } from "@lightningtv/solid"; -import { - WebGlCoreRenderer, - SdfTextRenderer -} from "@lightningjs/renderer/webgl"; -import { - CanvasCoreRenderer, - CanvasTextRenderer -} from "@lightningjs/renderer/canvas"; - -import { Inspector } from "@lightningjs/renderer/inspector"; -import { HashRouter, FocusStackProvider } from "@lightningtv/solid/primitives"; -import { Route } from "@solidjs/router"; -import { lazy } from "solid-js"; -import App from "./pages/App"; -import Browse from "./pages/Browse"; -import TMDB from "./pages/TMDB"; -import DestroyPage from "./pages/Destroy"; -import { tmdbData, destroyData } from "./api/tmdbData"; -import NotFound from "./pages/NotFound"; +import * as s from "solid-js"; +import * as router from "@solidjs/router"; +import * as lng from "@lightningtv/solid"; +import * as lngp from "@lightningtv/solid/primitives"; + import fonts from "./fonts"; -import { browsePreload } from "./api/browsePreload"; -import { entityPreload } from "./api/entityPreload"; -import Player from "./pages/Player"; -import LeftNavWrapper from "./pages/LeftNavWrapper"; -const Grid = lazy(() => import("./pages/Grid")); -const Loops = lazy(() => import("./pages/Loops")); -const Infinite = lazy(() => import("./pages/Infinite")); -const TMDBGrid = lazy(() => import("./pages/TMDBGrid")); -const Portal = lazy(() => import("./pages/Portal")); -const TextPage = lazy(() => import("./pages/Text")); -const TextPosterPage = lazy(() => import("./pages/TextPoster")); -const CreatePage = lazy(() => import("./pages/Create")); -const ViewportPage = lazy(() => import("./pages/Viewport")); -const PositioningPage = lazy(() => import("./pages/Positioning")); -const LayoutPage = lazy(() => import("./pages/Layout")); -const FocusBasicsPage = lazy(() => import("./pages/FocusBasics")); -const KeyHandlingPage = lazy(() => import("./pages/KeyHandling")); -const TransitionsPage = lazy(() => import("./pages/Transitions")); -const ComponentsPage = lazy(() => import("./pages/Components")); -const FocusHandlingPage = lazy(() => import("./pages/FocusHandling")); -const GradientsPage = lazy(() => import("./pages/Gradients")); -const FlexPage = lazy(() => import("./pages/Flex")); -const FlexGrowPage = lazy(() => import("./pages/FlexGrow")); -const FlexMenuPage = lazy(() => import("./pages/FlexMenu")); -const FlexSizePage = lazy(() => import("./pages/FlexSize")); -const FlexColumnSizePage = lazy(() => import("./pages/FlexColumnSize")); -const FlexColumnPage = lazy(() => import("./pages/FlexColumn")); -const ButtonsMaterialPage = lazy(() => import("./pages/ButtonsMaterial")); -const SuperFlexPage = lazy(() => import("./pages/SuperFlex")); -const Entity = lazy(() => import("./pages/Entity")); -const People = lazy(() => import("./pages/People")); -const FireboltPage = lazy(() => import("./pages/Firebolt")); let numImageWorkers = 3; const urlParams = new URLSearchParams(window.location.search); @@ -79,17 +32,16 @@ const deviceLogicalPixelRatio = { }[screenSize]; const logFps = true; -Config.debug = false; +lng.Config.debug = false; // Config.keyDebug = true; -Config.animationsEnabled = animationsEnabled === "true"; -Config.fontSettings.fontFamily = "Roboto"; -Config.fontSettings.color = "#f6f6f6"; -Config.fontSettings.fontSize = 32; +lng.Config.animationsEnabled = animationsEnabled === "true"; +lng.Config.fontSettings.fontFamily = "Roboto"; +lng.Config.fontSettings.color = "#f6f6f6"; +lng.Config.fontSettings.fontSize = 32; // Config.focusDebug = true; -Config.rendererOptions = { +lng.Config.rendererOptions = { fpsUpdateInterval: logFps ? 1000 : 0, - inspector: import.meta.env.DEV ? Inspector : undefined, // textureMemory: { // criticalThreshold: 80e6, // }, @@ -103,36 +55,70 @@ Config.rendererOptions = { // Ideally you'd do two separate builds for canvas and webgl to reduce bundle size. if (rendererMode === "canvas") { - Config.rendererOptions.fontEngines = [CanvasTextRenderer]; - Config.rendererOptions.renderEngine = CanvasCoreRenderer; + lng.useCanvasFontEngine() + lng.useCanvasRenderEngine() } else { - Config.rendererOptions.fontEngines = [SdfTextRenderer]; - Config.rendererOptions.renderEngine = WebGlCoreRenderer; + lng.useSdfFontEngine() + lng.useWebglRenderEngine() +} + +if (import.meta.env.DEV) { + lng.useInspector() } -const { renderer, render } = createRenderer(); -loadFonts(fonts); -// Prepare for RC3 of Renderer -import { - Rounded, - RoundedWithBorder, - RoundedWithShadow, - RoundedWithBorderAndShadow, - RadialGradient, - LinearGradient, - HolePunch, -} from '@lightningjs/renderer/webgl/shaders'; -const shManager = renderer.stage.shManager; -shManager.registerShaderType('rounded', Rounded) -shManager.registerShaderType('roundedWithBorder', RoundedWithBorder) -shManager.registerShaderType('roundedWithShadow', RoundedWithShadow) -shManager.registerShaderType('roundedWithBorderWithShadow', RoundedWithBorderAndShadow) -shManager.registerShaderType('radialGradient', RadialGradient) -shManager.registerShaderType('linearGradient', LinearGradient) -shManager.registerShaderType('holePunch', HolePunch) +const { renderer, render } = lng.createRenderer(); + +lng.loadFonts(fonts); + +lng.registerDefaultShaders(renderer.stage.shManager); + + +const Route = router.Route; +const lazy = s.lazy; + +import App from "./pages/App"; +import Browse from "./pages/Browse"; +import TMDB from "./pages/TMDB"; +import DestroyPage from "./pages/Destroy"; +import { tmdbData, destroyData } from "./api/tmdbData"; +import NotFound from "./pages/NotFound"; +import { browsePreload } from "./api/browsePreload"; +import { entityPreload } from "./api/entityPreload"; +import Player from "./pages/Player"; +import LeftNavWrapper from "./pages/LeftNavWrapper"; + +const Grid = lazy(() => import("./pages/Grid")); +const Loops = lazy(() => import("./pages/Loops")); +const Infinite = lazy(() => import("./pages/Infinite")); +const TMDBGrid = lazy(() => import("./pages/TMDBGrid")); +const Portal = lazy(() => import("./pages/Portal")); +const TextPage = lazy(() => import("./pages/Text")); +const TextPosterPage = lazy(() => import("./pages/TextPoster")); +const CreatePage = lazy(() => import("./pages/Create")); +const ViewportPage = lazy(() => import("./pages/Viewport")); +const PositioningPage = lazy(() => import("./pages/Positioning")); +const LayoutPage = lazy(() => import("./pages/Layout")); +const FocusBasicsPage = lazy(() => import("./pages/FocusBasics")); +const KeyHandlingPage = lazy(() => import("./pages/KeyHandling")); +const TransitionsPage = lazy(() => import("./pages/Transitions")); +const ComponentsPage = lazy(() => import("./pages/Components")); +const FocusHandlingPage = lazy(() => import("./pages/FocusHandling")); +const GradientsPage = lazy(() => import("./pages/Gradients")); +const FlexPage = lazy(() => import("./pages/Flex")); +const FlexGrowPage = lazy(() => import("./pages/FlexGrow")); +const FlexMenuPage = lazy(() => import("./pages/FlexMenu")); +const FlexSizePage = lazy(() => import("./pages/FlexSize")); +const FlexColumnSizePage = lazy(() => import("./pages/FlexColumnSize")); +const FlexColumnPage = lazy(() => import("./pages/FlexColumn")); +const ButtonsMaterialPage = lazy(() => import("./pages/ButtonsMaterial")); +const SuperFlexPage = lazy(() => import("./pages/SuperFlex")); +const Entity = lazy(() => import("./pages/Entity")); +const People = lazy(() => import("./pages/People")); +const FireboltPage = lazy(() => import("./pages/Firebolt")); + render(() => ( - - }> + + }> @@ -175,6 +161,6 @@ render(() => ( - - + + )); diff --git a/vite.config.js b/vite.config.js index ee81e623..caae9b1d 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,12 +1,51 @@ -import { defineConfig } from "vite"; +import * as vite from "vite"; import solidPlugin from "vite-plugin-solid"; import legacy from "@vitejs/plugin-legacy"; import devtools from "solid-devtools/vite"; import hexColorTransform from "@lightningtv/vite-hex-transform"; import { configDefaults } from "vitest/config"; -export default defineConfig({ - plugins: [ +/** +* @param {string | undefined} v +* @returns {boolean} +*/ +function envTruthy(v) { + switch (String(v).trim().toLowerCase()) { + case 'true': + case '1': + case 'yes': + case 'y': + return true; + default: + return false; + } +} + +export default vite.defineConfig(env => { + + const isDev = env.mode !== 'production'; + const isV3 = envTruthy(process.env.LIGHTNING_RENDERER_V3); + const domRendering = envTruthy(process.env.LIGHTNING_DOM_RENDERING); + const disableShaders = envTruthy(process.env.LIGHTNING_DISABLE_SHADERS); + + /** @type {Record} */ + const definedVars = { + __DEV__: isDev, + __LIGHTNING_DOM_RENDERING__: domRendering, + __LIGHTNING_DISABLE_SHADERS__: disableShaders, + __LIGHTNING_RENDERER_V3__: isV3, + }; + + let definedVarsMaxLength = 0; + for (const key in definedVars) { + definedVarsMaxLength = Math.max(definedVarsMaxLength, key.length); + } + for (const key in definedVars) { + console.log(`${key.padEnd(definedVarsMaxLength)} = ${definedVars[key]}`); + } + + /** @type {vite.PluginOption[]} */ + const plugins = [ hexColorTransform({ include: ["src/**/*.{ts,tsx,js,jsx}"] }), @@ -35,44 +74,91 @@ export default defineConfig({ // Safari 11 has modules, but throws > ReferenceError: Can't find variable: globalThis "es.global-this" ] + }), + ]; + + if (domRendering) { + // Hack to prevent cors errors when fetching images by dom renderer + // "Failed to load resource: net::ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep" + plugins.push({ + name: 'tmdb proxy', + configureServer(server) { + server.middlewares.use(async (req, res, next) => { + if (req.url != null && req.url.startsWith('/image_tmdb')) { + const target = 'https://image.tmdb.org/t/p/' + const path = req.url.slice('/image_tmdb/'.length) + const proxyUrl = target + path + + try { + let response = await fetch(proxyUrl) + let buffer = await response.arrayBuffer() + res.setHeader('Content-Type', response.headers.get('Content-Type')) + res.end(Buffer.from(buffer)) + } catch (err) { + res.statusCode = 500 + res.end('Proxy error: ' + err.message) + } + return + } + next() + }) + }, + }); + + // Add font links to html for dom renderer + plugins.push({ + name: 'add-font-tags', + transformIndexHtml(html) { + return html.replace( + '', + ` + + +`, + ); + }, }) - ], - build: { - targets: ["chrome>=69"], - minify: false, - sourcemap: false - }, - resolve: { - alias: { - theme: "@lightningjs/l3-ui-theme-base" + } + + return { + define: definedVars, + plugins: plugins, + build: { + targets: ["chrome>=69"], + minify: false, + sourcemap: false + }, + resolve: { + alias: { + theme: "@lightningjs/l3-ui-theme-base" + }, + dedupe: [ + "solid-js", + "solid-js/universal", + "@solidjs/router", + "@lightningtv/core", + "@lightningtv/solid", + "@lightningtv/solid/primitives", + ], + }, + optimizeDeps: { + exclude: [ + "@lightningtv/solid", + "@lightningtv/core", + "@lightningjs/renderer" + ] + }, + server: { + port: 5174, + hmr: true, + headers: { + "Cross-Origin-Opener-Policy": "same-origin", + "Cross-Origin-Embedder-Policy": "require-corp" + } + }, + test: { + exclude: [...configDefaults.exclude, "packages/template/*"], + globals: true }, - dedupe: [ - "solid-js", - "solid-js/universal", - "@solidjs/router", - "@lightningjs/renderer", - "@lightningtv/core", - "@lightningtv/solid", - "@lightningtv/solid/primitives" - ] - }, - optimizeDeps: { - exclude: [ - "@lightningtv/solid", - "@lightningtv/core", - "@lightningjs/renderer" - ] - }, - server: { - port: 5174, - hmr: true, - headers: { - "Cross-Origin-Opener-Policy": "same-origin", - "Cross-Origin-Embedder-Policy": "require-corp" - } - }, - test: { - exclude: [...configDefaults.exclude, "packages/template/*"], - globals: true } });