From d3a6544bc5fd7b3d2d65494ba1c3155b024a436e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 6 Dec 2022 11:21:12 -0300 Subject: [PATCH] using web-utils in anastasis-webui --- packages/anastasis-webui/build.mjs | 147 +++++++ packages/anastasis-webui/clean_and_build.sh | 72 ---- packages/anastasis-webui/dev.mjs | 91 +---- packages/anastasis-webui/html/stories.html | 72 ---- packages/anastasis-webui/html/ui-dev.html | 65 ---- packages/anastasis-webui/package.json | 12 +- .../src/components/menu/SideBar.tsx | 33 +- .../src/components/picker/DurationPicker.tsx | 12 +- .../src/context/translation.ts | 41 +- packages/anastasis-webui/src/hooks/index.ts | 71 +--- .../src/{main.ts => hooks/useLang.ts} | 33 +- .../src/hooks/useLocalStorage.ts | 80 ++++ packages/anastasis-webui/src/i18n/index.tsx | 211 ---------- .../{html/ui.html => src/index.html} | 32 +- .../src/{main.test.ts => index.test.ts} | 0 packages/anastasis-webui/src/index.ts | 25 +- .../home/AddingProviderScreen/stories.tsx | 1 + .../pages/home/AddingProviderScreen/views.tsx | 4 +- .../home/AttributeEntryScreen.stories.tsx | 1 + .../AuthenticationEditorScreen.stories.tsx | 1 + .../home/BackupFinishedScreen.stories.tsx | 1 + .../home/ChallengeOverviewScreen.stories.tsx | 1 + .../home/ChallengePayingScreen.stories.tsx | 1 + .../home/ContinentSelectionScreen.stories.tsx | 1 + .../pages/home/EditPoliciesScreen.stories.tsx | 1 + .../home/PoliciesPayingScreen.stories.tsx | 1 + .../home/RecoveryFinishedScreen.stories.tsx | 1 + .../home/ReviewPoliciesScreen.stories.tsx | 1 + .../pages/home/SecretEditorScreen.stories.tsx | 1 + .../home/SecretSelectionScreen.stories.tsx | 1 + .../src/pages/home/SolveScreen.stories.tsx | 1 + .../src/pages/home/StartScreen.stories.tsx | 1 + .../pages/home/TruthsPayingScreen.stories.tsx | 1 + .../AuthMethodEmailSetup.stories.tsx | 1 + .../AuthMethodEmailSolve.stories.tsx | 1 + .../home/authMethod/AuthMethodEmailSolve.tsx | 6 +- .../AuthMethodIbanSetup.stories.tsx | 1 + .../AuthMethodIbanSolve.stories.tsx | 1 + .../AuthMethodPostSetup.stories.tsx | 1 + .../AuthMethodPostSolve.stories.tsx | 1 + .../home/authMethod/AuthMethodPostSolve.tsx | 6 +- .../AuthMethodQuestionSetup.stories.tsx | 1 + .../AuthMethodQuestionSolve.stories.tsx | 1 + .../authMethod/AuthMethodSmsSetup.stories.tsx | 1 + .../authMethod/AuthMethodSmsSolve.stories.tsx | 1 + .../home/authMethod/AuthMethodSmsSolve.tsx | 6 +- .../AuthMethodTotpSetup.stories.tsx | 1 + .../AuthMethodTotpSolve.stories.tsx | 1 + .../anastasis-webui/src/scss/_mixins.scss | 2 +- packages/anastasis-webui/src/stories.tsx | 365 +----------------- packages/anastasis-webui/src/test-utils.ts | 12 +- packages/anastasis-webui/src/utils/index.tsx | 16 +- packages/anastasis-webui/watch/reply.sh | 18 - packages/anastasis-webui/watch/send.sh | 12 - packages/anastasis-webui/watch/send2.sh | 14 - packages/anastasis-webui/watch/serve.sh | 7 - .../watch/web_socket_client.request | 6 - .../watch/web_socket_server.reply | 5 - 58 files changed, 430 insertions(+), 1074 deletions(-) create mode 100755 packages/anastasis-webui/build.mjs delete mode 100755 packages/anastasis-webui/clean_and_build.sh delete mode 100644 packages/anastasis-webui/html/stories.html delete mode 100644 packages/anastasis-webui/html/ui-dev.html rename packages/anastasis-webui/src/{main.ts => hooks/useLang.ts} (51%) create mode 100644 packages/anastasis-webui/src/hooks/useLocalStorage.ts delete mode 100644 packages/anastasis-webui/src/i18n/index.tsx rename packages/anastasis-webui/{html/ui.html => src/index.html} (67%) rename packages/anastasis-webui/src/{main.test.ts => index.test.ts} (100%) delete mode 100755 packages/anastasis-webui/watch/reply.sh delete mode 100755 packages/anastasis-webui/watch/send.sh delete mode 100755 packages/anastasis-webui/watch/send2.sh delete mode 100755 packages/anastasis-webui/watch/serve.sh delete mode 100644 packages/anastasis-webui/watch/web_socket_client.request delete mode 100644 packages/anastasis-webui/watch/web_socket_server.reply diff --git a/packages/anastasis-webui/build.mjs b/packages/anastasis-webui/build.mjs new file mode 100755 index 000000000..ebe914541 --- /dev/null +++ b/packages/anastasis-webui/build.mjs @@ -0,0 +1,147 @@ +#!/usr/bin/env node +/* + This file is part of GNU Anastasis + (C) 2021-2022 Anastasis SARL + + GNU Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + GNU Anastasis; see the file COPYING. If not, see + */ +/* eslint-disable no-undef */ +import esbuild from 'esbuild' +import fs from 'fs'; +import path from "path" +import sass from "sass"; + +// eslint-disable-next-line no-undef +const BASE = process.cwd(); + +const preact = path.join( + BASE, + "node_modules", + "preact", + "compat", + "dist", + "compat.module.js", +); + +const preactCompatPlugin = { + name: "preact-compat", + setup(build) { + build.onResolve({ filter: /^(react-dom|react)$/ }, (args) => { + return { + path: preact, + }; + }); + }, +}; + + +let GIT_ROOT = BASE +while (!fs.existsSync(path.join(GIT_ROOT, '.git')) && GIT_ROOT !== '/') { + GIT_ROOT = path.join(GIT_ROOT, '../') +} +if (GIT_ROOT === '/') { + // eslint-disable-next-line no-undef + console.log("not found") + // eslint-disable-next-line no-undef + process.exit(1); +} +const GIT_HASH = GIT_ROOT === '/' ? undefined : git_hash() + + +let _package = JSON.parse(fs.readFileSync(path.join(BASE, 'package.json'))); + +function git_hash() { + const rev = fs.readFileSync(path.join(GIT_ROOT, '.git', 'HEAD')).toString().trim().split(/.*[: ]/).slice(-1)[0]; + if (rev.indexOf('/') === -1) { + return rev; + } else { + return fs.readFileSync(path.join(GIT_ROOT, '.git', rev)).toString().trim(); + } +} + +const DEFAULT_SASS_FILTER = /\.(s[ac]ss|css)$/ + +const buildSassPlugin = { + name: "custom-build-sass", + setup(build) { + + build.onLoad({ filter: DEFAULT_SASS_FILTER }, ({ path: file }) => { + const resolveDir = path.dirname(file) + const { css: contents } = sass.compile(file, { loadPaths: ["./"] }) + + return { + resolveDir, + loader: 'css', + contents + } + }); + + }, +}; + +function copyFilesPlugin(options) { + if (!options.basedir) { + options.basedir = process.cwd() + } + return { + name: "copy-files", + setup(build) { + build.onEnd(() => { + for (const fop of options) { + fs.copyFileSync(path.join(options.basedir, fop.src), path.join(options.basedir, fop.dest)); + } + }); + }, + }; +} + +export const buildConfig = { + entryPoints: ['src/index.ts', 'src/stories.tsx'], + bundle: true, + outdir: 'dist', + minify: false, + loader: { + '.svg': 'dataurl', + '.ttf': 'file', + '.woff': 'file', + '.woff2': 'file', + '.eot': 'file', + }, + target: [ + 'es6' + ], + format: 'esm', + platform: 'browser', + sourcemap: true, + jsxFactory: 'h', + jsxFragment: 'Fragment', + define: { + '__VERSION__': `"${_package.version}"`, + '__GIT_HASH__': `"${GIT_HASH}"`, + }, + plugins: [ + preactCompatPlugin, + copyFilesPlugin([ + { + src: "./src/index.html", + dest: "./dist/index.html", + }, + ]), + buildSassPlugin + ], +} + +await esbuild.build(buildConfig) + + + + diff --git a/packages/anastasis-webui/clean_and_build.sh b/packages/anastasis-webui/clean_and_build.sh deleted file mode 100755 index 9486848fe..000000000 --- a/packages/anastasis-webui/clean_and_build.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash - -echo clean -rm -rf dist -mkdir -p dist/fonts -cp \ - src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf \ - src/scss/fonts/materialdesignicons-webfont-4.9.95.ttf \ - src/scss/fonts/materialdesignicons-webfont-4.9.95.woff \ - src/scss/fonts/materialdesignicons-webfont-4.9.95.woff2 \ - dist/fonts - -VERSION=$(jq -r .version package.json) -GIT_HASH=$(git rev-parse --short HEAD) - -function build_css() { - pnpm exec sass -I . ./src/scss/main.scss dist/main.css -} -function build_js() { - pnpm exec esbuild --log-level=error --define:process.env.__VERSION__=\"${VERSION}\" --define:process.env.__GIT_HASH__=\"${GIT_HASH}\" --bundle $1 --outdir=dist --target=es6 --loader:.svg=dataurl --format=iife --sourcemap --jsx-factory=h --jsx-fragment=Fragment --platform=browser --minify -} - -function build_html() { - cat html/$1.html \ - | sed -e '/ANASTASIS_SCRIPT_CONTENT/ {' -e 'r dist/main.js' -e 'd' -e '}' \ - | sed -e '/ANASTASIS_STYLE_CONTENT/ {' -e 'r dist/main.css' -e 'd' -e '}' \ - >dist/$1.html -} - -function cleanup { - trap - SIGHUP SIGINT SIGTERM SIGQUIT - echo -n "Cleaning up... " - wait - kill -- -$$ - exit 1 -} -trap cleanup SIGHUP SIGINT SIGTERM SIGQUIT - -set -e -echo compile -build_css & -build_js src/main.ts & -build_js src/stories.tsx & -build_js src/main.test.ts & -for file in $(find src/ -name test.ts); do build_js $file; done & -wait -n -wait -n -wait -n -wait -n -wait -n -pnpm run --silent test -- -R dot - -echo html -build_html ui -build_html ui-dev -build_html stories - -if [ "WATCH" == "$1" ]; then - - echo watch mode - echo Writing any file in the src directory will trigger a browser reload. - echo Be sure that the watcher server is running. - echo ./watch/serve.sh - inotifywait -e close_write -r src -q -m | while read line; do - echo $(date) $line - build_js src/main.ts - build_html ui-dev - build_js src/stories.tsx - build_html stories - ./watch/send.sh '{"type":"RELOAD"}' - done; -fi diff --git a/packages/anastasis-webui/dev.mjs b/packages/anastasis-webui/dev.mjs index 3f4915ffc..0446603dc 100755 --- a/packages/anastasis-webui/dev.mjs +++ b/packages/anastasis-webui/dev.mjs @@ -14,87 +14,18 @@ You should have received a copy of the GNU Affero General Public License along with GNU Anastasis; see the file COPYING. If not, see */ -/* eslint-disable no-undef */ -import esbuild from 'esbuild' -import fs from 'fs'; -import WebSocket from "ws"; -import chokidar from "chokidar"; -const devServerBroadcastDelay = 500 -const devServerPort = 8002 -const wss = new WebSocket.Server({ port: devServerPort }); -const toWatch = ["./src"] - -function broadcast(file, event) { - setTimeout(() => { - wss.clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { - console.log(new Date(), file) - client.send(JSON.stringify(event)); - } - }); - }, devServerBroadcastDelay); -} - -const watcher = chokidar - .watch(toWatch, { - persistent: true, - ignoreInitial: true, - awaitWriteFinish: { - stabilityThreshold: 100, - pollInterval: 100, - }, - }) - .on("error", (error) => console.error(error)) - .on("change", async (file) => { - broadcast(file, { type: "RELOAD" }); - }) - .on("add", async (file) => { - broadcast(file, { type: "RELOAD" }); - }) - .on("unlink", async (file) => { - broadcast(file, { type: "RELOAD" }); - }); - -/** - * Just bundling UI Stories. - * FIXME: add linaria CSS after implementing Material so CSS will be bundled - */ -fs.writeFileSync("dist/index.html", fs.readFileSync("html/stories.html")) -fs.writeFileSync("dist/mocha.css", fs.readFileSync("node_modules/mocha/mocha.css")) -fs.writeFileSync("dist/mocha.js", fs.readFileSync("node_modules/mocha/mocha.js")) -fs.writeFileSync("dist/mocha.js.map", fs.readFileSync("node_modules/mocha/mocha.js.map")) - -export const buildConfig = { - entryPoints: ['src/main.ts', 'src/stories.tsx'], - bundle: true, - outdir: 'dist', - minify: false, - loader: { - '.svg': 'dataurl', - }, - target: [ - 'es6' - ], - format: 'iife', - platform: 'browser', - sourcemap: true, - jsxFactory: 'h', - jsxFragment: 'Fragment', -} - -const server = await esbuild - .serve({ servedir: 'dist' }, { - ...buildConfig, outdir: 'dist' - }) - .catch((e) => { - console.log(e) - process.exit(1) - }); - -console.log(`Dev server is ready at http://localhost:${server.port}/. -The server is running a using websocket at ${devServerPort} to notify code change and live reload. -`); +import { serve } from "@gnu-taler/web-util/lib/index.node"; +import esbuild from 'esbuild'; +import { buildConfig } from "./build.mjs"; +buildConfig.inject = ['./node_modules/@gnu-taler/web-util/lib/live-reload.mjs'] +serve({ + folder: './dist', + port: 8080, + source: './src', + development: true, + onUpdate: async () => esbuild.build(buildConfig) +}) diff --git a/packages/anastasis-webui/html/stories.html b/packages/anastasis-webui/html/stories.html deleted file mode 100644 index 9f41fdeaf..000000000 --- a/packages/anastasis-webui/html/stories.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - Stories - - - - - - - - diff --git a/packages/anastasis-webui/html/ui-dev.html b/packages/anastasis-webui/html/ui-dev.html deleted file mode 100644 index 2790d5678..000000000 --- a/packages/anastasis-webui/html/ui-dev.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - -
- - - - diff --git a/packages/anastasis-webui/package.json b/packages/anastasis-webui/package.json index de70d05fc..c01856243 100644 --- a/packages/anastasis-webui/package.json +++ b/packages/anastasis-webui/package.json @@ -15,11 +15,12 @@ "dependencies": { "@gnu-taler/anastasis-core": "workspace:*", "@gnu-taler/taler-util": "workspace:*", + "@gnu-taler/web-util": "workspace:*", "@types/chai": "^4.3.0", "chai": "^4.3.6", "date-fns": "2.29.2", "jed": "1.1.1", - "preact": "^10.5.15", + "preact": "10.11.3", "preact-render-to-string": "^5.1.19", "preact-router": "^3.2.1", "qrcode-generator": "^1.4.4" @@ -41,12 +42,9 @@ "bulma": "^0.9.3", "bulma-checkbox": "^1.1.1", "bulma-radio": "^1.1.1", - "chokidar": "^3.5.3", - "eslint-plugin-header": "^3.1.1", "jssha": "^3.2.0", "mocha": "^9.2.0", - "sass": "1.32.13", - "typescript": "^4.8.4", - "ws": "7.4.5" + "sass": "1.56.1", + "typescript": "^4.8.4" } -} +} \ No newline at end of file diff --git a/packages/anastasis-webui/src/components/menu/SideBar.tsx b/packages/anastasis-webui/src/components/menu/SideBar.tsx index 51e854944..3dac73e04 100644 --- a/packages/anastasis-webui/src/components/menu/SideBar.tsx +++ b/packages/anastasis-webui/src/components/menu/SideBar.tsx @@ -22,7 +22,7 @@ import { BackupStates, RecoveryStates } from "@gnu-taler/anastasis-core"; import { Fragment, h, VNode } from "preact"; import { useAnastasisContext } from "../../context/anastasis.js"; -import { Translate } from "../../i18n/index.js"; +import { useTranslationContext } from "../../context/translation.js"; interface Props { mobile?: boolean; @@ -34,6 +34,7 @@ const VERSION_WITH_HASH = GIT_HASH ? `${VERSION}-${GIT_HASH}` : VERSION; export function Sidebar({ mobile }: Props): VNode { const reducer = useAnastasisContext()!; + const { i18n } = useTranslationContext(); function saveSession(): void { const state = reducer.exportState(); @@ -64,7 +65,7 @@ export function Sidebar({ mobile }: Props): VNode {