Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add non-react qr library. add first Svelte component to Home #10

Merged
merged 2 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions jest.config.ts

This file was deleted.

18 changes: 10 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"dev": "vite --host --mode development",
"build": "tsc && vite build --mode production",
"preview": "vite preview --host",
"test": "jest",
"test": "vitest run",
"predeploy": "yarn build",
"deploy": "gh-pages -d dist"
},
Expand All @@ -20,28 +20,30 @@
"react-router-dom": "^6.8.2",
"react-uuid": "^2.0.0",
"rollup-plugin-node-polyfills": "^0.2.1",
"svelte": "^4.1.1",
"u8-mqtt": "^0.3.2-0",
"vite-plugin-node-polyfills": "^0.7.0"
},
"devDependencies": {
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"@testing-library/jest-dom": "^5.16.5",
"@sveltejs/vite-plugin-svelte": "^2.4.3",
"@testing-library/react": "^14.0.0",
"@testing-library/svelte": "^4.0.3",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.4.0",
"@tsconfig/svelte": "^3.0.0",
"@types/mocha": "^10.0.1",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@vitejs/plugin-react": "^3.1.0",
"babel-jest": "^29.4.3",
"gh-pages": "^5.0.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.4.3",
"jest-environment-jsdom": "^29.4.3",
"ts-jest": "^29.0.5",
"jsdom": "^22.1.0",
"svelte-preprocess": "^5.0.4",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"vite": "^4.1.0"
"vite": "^4.1.0",
"vitest": "^0.33.0"
}
}
13 changes: 6 additions & 7 deletions src/__tests__/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import {render} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {fireEvent} from '@testing-library/svelte'
import Home from '../components/Home';

// Source: https://codingwithmanny.medium.com/quick-jest-setup-with-vitejs-react-typescript-82f325e4323f


test('Renders main page correctly', async () => {
// TODO: improve this with a proper mock
let app_mqtt_client = {
subscribe_topic: () => {
}
}
render(<Home id="123" app_mqtt_client={app_mqtt_client}/>);
const {container} = render(<Home id="123" app_mqtt_client={app_mqtt_client}/>);

// find the svg element and click it
const svg = document.querySelector("svg") as SVGSVGElement;
expect(svg).not.toBeNull();
await userEvent.click(svg);
const div = container.querySelector("div.svelteQrCode>div.qrCodeInner") as HTMLDivElement;
expect(div).not.toBeNull();
await fireEvent.click(div);

// assert that the class "alternative-bg" is added to the div with class "home"
const home = document.querySelector(".home") as HTMLDivElement;
const home = container.querySelector(".home") as HTMLDivElement;
expect(home).not.toBeNull();
expect(home.classList.contains("alternative-bg")).toBeTruthy();
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import {render} from "@testing-library/react";
import React from "react";
import Handheld from "../components/Handheld";

jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useLocation: () => ({
pathname: "localhost:3000/example/path"
})
}));
vi.mock("react-router-dom", () => ({
useLocation: () => ({
pathname: "localhost:3000/example/path"
})
}))

test('Renders Handheld page correctly', async () => {
// TODO: improve this with a proper mock
Expand All @@ -16,4 +15,5 @@ test('Renders Handheld page correctly', async () => {
}
}
render(<Handheld app_mqtt_client={app_mqtt_client}/>);
});
});

1 change: 1 addition & 0 deletions src/assets/qrcode.min.js

Large diffs are not rendered by default.

76 changes: 43 additions & 33 deletions src/components/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {useState} from 'react'
import QRCode from 'react-qr-code';

// @ts-ignore
import React, {MutableRefObject, useLayoutEffect, useRef, useState} from 'react'
// @ts-ignore
import QrContainer from "./QrContainer.svelte";

import Lyrics from './Lyrics';
import {buildHandheldUrl, buildTopic} from "../services/utils";
Expand All @@ -10,6 +11,22 @@ function Home(props: { id: string, app_mqtt_client: any }) {
const [handheldUrl,] = useState(buildHandheldUrl(props.id))
let [topic,] = useState(buildTopic(props.id))

let svelteQrCodeRef: MutableRefObject<any> = useRef()
useLayoutEffect(() => {
// Iterate and remove all previously appended children in the ref
while (svelteQrCodeRef.current?.firstChild) {
svelteQrCodeRef.current?.firstChild?.remove();
}
new QrContainer({
target: svelteQrCodeRef.current,
props: {
alternativeBackground: alternativeBackground,
setAlternativeBackground: setAlternativeBackground,
url: handheldUrl
}
})
}, [alternativeBackground])

// TODO: create a class for the message format
// TODO: is it correct to subscribe here? or should it be in a useEffect?
props.app_mqtt_client.subscribe_topic(
Expand All @@ -21,38 +38,31 @@ function Home(props: { id: string, app_mqtt_client: any }) {
}
})

return (<div className={`home ${alternativeBackground ? "alternative-bg" : ""}`}>
{alternativeBackground && <div className="alternative-bg-background"/>}
<Lyrics
children={
(<div style={{height: "auto", margin: "0 auto", maxWidth: 80, width: "100%"}}>
<QRCode
onClick={() => setAlternativeBackground(!alternativeBackground)}
size={256}
style={{height: "auto", maxWidth: "100%", width: "100%"}}
bgColor={alternativeBackground ? "#000000" : "#FFFFFF"}
fgColor={alternativeBackground ? "#FFFFFF" : "#000000"}
value={handheldUrl}
viewBox={`0 0 ${256} ${256}`}
/>
</div>)}/>
<div className="home__footer">
<div className="can-can-bc">
<a className={`${alternativeBackground ? "alternative-bg" : ""}`}
href="https://www.youtube.com/@pichudequito/videos"
target="_blank">Band:
Can Can
(Ecuador)</a>
</div>
<div className="github-link">
<a className={`${alternativeBackground ? "alternative-bg" : ""}`}
href="https://github.com/linomp/react-qr-mqtt"
target="_blank"><i
className="fab fa-github"></i></a>
return (
<div className={`home ${alternativeBackground ? "alternative-bg" : ""}`}>
{alternativeBackground && <div className="alternative-bg-background"/>}
<Lyrics
children={
(<div style={{width: "100%", display: "flex", flexDirection: "row", justifyContent: "center"}}>
<div className={"svelteQrCode"} ref={svelteQrCodeRef}/>
</div>)}/>
<div className="home__footer">
<div className="can-can-bc">
<a className={`${alternativeBackground ? "alternative-bg" : ""}`}
href="https://www.youtube.com/@pichudequito/videos"
target="_blank">Band:
Can Can
(Ecuador)</a>
</div>
<div className="github-link">
<a className={`${alternativeBackground ? "alternative-bg" : ""}`}
href="https://github.com/linomp/react-qr-mqtt"
target="_blank"><i
className="fab fa-github"></i></a>
</div>
</div>
</div>

</div>);
</div>);
}

export default Home
26 changes: 26 additions & 0 deletions src/components/QrContainer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script lang="ts">
let qrContainer: HTMLElement

export let alternativeBackground: boolean;
export let setAlternativeBackground: (_: boolean) => void;
export let url: string

function initQr() {
// @ts-ignore
let QRCode = window["QRCode"]
new QRCode(qrContainer, {
text: url,
width: 128,
height: 128,
colorDark: alternativeBackground ? "#FFFFFF" : "#000000",
colorLight: alternativeBackground ? "#000000" : "#FFFFFF",
correctLevel : QRCode.CorrectLevel.H
})
}
</script>

<svelte:head>
<script type="text/javascript" src="../src/assets/qrcode.min.js" on:load={() => initQr()} />
</svelte:head>

<div class="qrCodeInner" bind:this={qrContainer} on:click={() => setAlternativeBackground(!alternativeBackground)}/>
15 changes: 15 additions & 0 deletions svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import sveltePreprocess from 'svelte-preprocess'

const preprocess = sveltePreprocess({
// the postcss thing is necessary if the project uses tailwind
// postcss: true,
sveltePreprocess,
typescript: {compilerOptions: {target: 'es2020'}}
})

export default {
compilerOptions: {
accessors: true
},
preprocess
}
41 changes: 24 additions & 17 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src", "i18n"],
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"src/*": ["./src/*"]
},
/* noEmit - vite/esbuild builds (emits) files, not tsc */
"noEmit": true,
"types": ["vite/client", "mocha", "vitest/globals"],
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"useDefineForClassFields": true,
"allowSyntheticDefaultImports": true,
"importsNotUsedAsValues": "error",
"esModuleInterop": true,
"alwaysStrict": true,
"strictNullChecks": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"noImplicitAny": true,
"strictNullChecks": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
"suppressImplicitAnyIndexErrors": true,
"strictPropertyInitialization": true,
"jsx": "react-jsx"
}
}
3 changes: 2 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import {nodePolyfills} from "vite-plugin-node-polyfills";
import {NodeGlobalsPolyfillPlugin} from "@esbuild-plugins/node-globals-polyfill";
import {svelte} from "@sveltejs/vite-plugin-svelte";

// https://vitejs.dev/config/
export default defineConfig({
Expand All @@ -14,7 +15,7 @@ export default defineConfig({
process: true,
buffer: true
}),
],
svelte({hot: !process.env.VITEST})],
build: {
target: 'esnext'
}
Expand Down
16 changes: 16 additions & 0 deletions vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vitest/config'
import {svelte} from "@sveltejs/vite-plugin-svelte";

// TODO: check if this is still necessary once fully migrated to Svelte
export default defineConfig({
plugins: [
react(),
svelte({hot: !process.env.VITEST})
],
test: {
include: ['**/*.test.tsx'],
globals: true,
environment: 'jsdom'
},
})
Loading