From e2714c4274e0dc551f697f9e2461e51a0e5de489 Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 4 Dec 2023 11:01:56 +0000 Subject: [PATCH] refactor: upgrade --- .eslintrc.cjs | 16 +- .gitignore | 4 +- .prettierignore | 4 +- .vscode/extensions.json | 6 +- .yarn/sdks/eslint/bin/eslint.js | 6 +- .yarn/sdks/eslint/lib/api.js | 6 +- .yarn/sdks/eslint/lib/unsupported-api.js | 20 + .yarn/sdks/eslint/package.json | 10 +- .yarn/sdks/prettier/bin-prettier.js | 20 + .yarn/sdks/prettier/index.js | 6 +- .yarn/sdks/prettier/package.json | 3 +- .yarn/sdks/typescript/lib/tsc.js | 6 +- .yarn/sdks/typescript/lib/tsserver.js | 157 +- .yarn/sdks/typescript/lib/tsserverlibrary.js | 157 +- .yarn/sdks/typescript/lib/typescript.js | 12 +- .yarn/sdks/typescript/package.json | 6 +- public/index.html => index.html | 1 + package.json | 40 +- public/favicon.ico | Bin 4314 -> 0 bytes public/robots.txt | 3 - public/tag_suggestions.json | 1 - src/element/Event.tsx | 16 +- src/element/async-button.tsx | 2 +- src/element/badge.tsx | 2 +- src/element/chat-message.tsx | 27 +- src/element/collapsible.tsx | 16 +- src/element/content-warning.tsx | 8 +- src/element/copy.tsx | 2 +- src/element/emoji-pack.tsx | 22 +- src/element/emoji-picker.tsx | 2 +- src/element/emoji.tsx | 2 +- src/element/external-link.tsx | 2 +- src/element/file-uploader.tsx | 6 +- src/element/follow-button.tsx | 14 +- src/element/goal.tsx | 18 +- src/element/hypertext.tsx | 4 +- src/element/live-chat.tsx | 45 +- src/element/live-video-player.tsx | 2 +- src/element/login-signup.tsx | 63 +- src/element/markdown.tsx | 2 +- src/element/mute-button.tsx | 15 +- src/element/new-goal.tsx | 24 +- src/element/new-stream.tsx | 18 +- src/element/nostr-provider-dialog.tsx | 34 +- src/element/note.tsx | 8 +- src/element/profile.tsx | 6 +- src/element/send-zap.tsx | 24 +- src/element/share-menu.tsx | 18 +- src/element/state-pill.tsx | 2 +- src/element/stream-cards.tsx | 55 +- src/element/stream-editor.tsx | 51 +- src/element/stream-time.tsx | 2 +- src/element/tags.tsx | 9 +- src/element/textarea.tsx | 8 +- src/element/toggle.tsx | 2 +- src/element/top-zappers.tsx | 4 +- src/element/video-tile.tsx | 21 +- src/element/write-message.tsx | 22 +- src/hooks/badges.ts | 6 +- src/hooks/cards.ts | 6 +- src/hooks/current-stream-feed.ts | 3 +- src/hooks/emoji.tsx | 8 +- src/hooks/event-feed.ts | 2 +- src/hooks/event.ts | 2 +- src/hooks/goals.ts | 4 +- src/hooks/lists.ts | 6 +- src/hooks/live-chat.tsx | 4 +- src/hooks/live-streams.ts | 8 +- src/hooks/login.ts | 12 +- src/hooks/profile.ts | 4 +- src/hooks/stream-link.ts | 4 +- src/hooks/stream-provider.tsx | 2 +- src/hooks/zaps.ts | 2 +- src/index.tsx | 34 +- src/intl.tsx | 53 +- src/lang.json | 30 +- src/pages/alerts.tsx | 5 +- src/pages/chat-popout.tsx | 9 +- src/pages/layout.css | 4 +- src/pages/layout.tsx | 26 +- src/pages/profile-page.tsx | 48 +- src/pages/providers/index.tsx | 8 +- src/pages/providers/nostr.tsx | 16 +- src/pages/providers/owncast.tsx | 11 +- src/pages/root.tsx | 16 +- src/pages/settings-page.tsx | 16 +- src/pages/stream-page.tsx | 46 +- src/pages/summary.tsx | 18 +- src/pages/tag.tsx | 6 +- src/pages/widgets.tsx | 38 +- src/pages/widgets/music.tsx | 7 +- src/pages/widgets/top-zappers.tsx | 9 +- src/pages/widgets/views.tsx | 9 +- src/pages/widgets/zaps.tsx | 19 +- src/providers/index.ts | 2 +- src/providers/manual.ts | 2 +- src/providers/owncast.ts | 4 +- src/providers/zsz.ts | 6 +- src/utils.ts | 4 +- src/wish/index.ts | 2 +- tsconfig.json | 30 +- tsconfig.node.json | 10 + vite.config.ts | 39 + webpack.config.js | 161 - yarn.lock | 4769 ++++-------------- 105 files changed, 1894 insertions(+), 4698 deletions(-) create mode 100644 .yarn/sdks/eslint/lib/unsupported-api.js create mode 100755 .yarn/sdks/prettier/bin-prettier.js mode change 100755 => 100644 .yarn/sdks/prettier/index.js rename public/index.html => index.html (89%) delete mode 100644 public/favicon.ico delete mode 100644 public/robots.txt delete mode 100644 public/tag_suggestions.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts delete mode 100644 webpack.config.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7c35369..a938fea 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,7 +1,15 @@ module.exports = { extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint"], + plugins: ["@typescript-eslint", "formatjs"], + rules: { + "formatjs/enforce-id": [ + "error", + { + idInterpolationPattern: "[sha512:contenthash:base64:6]", + }, + ], + }, root: true, ignorePatterns: ["build/", "*.test.ts", "*.js"], env: { @@ -10,10 +18,4 @@ module.exports = { commonjs: true, node: false, }, - rules: { - "@typescript-eslint/no-non-null-assertion": "error", - "require-await": "error", - eqeqeq: "error", - "object-shorthand": "warn", - }, }; diff --git a/.gitignore b/.gitignore index 80c3a89..b251c5f 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,6 @@ yarn-error.log* !.yarn/plugins !.yarn/releases !.yarn/sdks -!.yarn/versions \ No newline at end of file +!.yarn/versions + +dev-dist/ \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 9978033..21a1e19 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,6 @@ .yarn/ .vscode/ node_modules/ -build/ \ No newline at end of file +build/ +dist/ +dev-dist/ \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index da487ff..daaa5ee 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,7 @@ { - "recommendations": ["arcanis.vscode-zipfs", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] + "recommendations": [ + "arcanis.vscode-zipfs", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode" + ] } diff --git a/.yarn/sdks/eslint/bin/eslint.js b/.yarn/sdks/eslint/bin/eslint.js index d24e1b5..9ef98e4 100755 --- a/.yarn/sdks/eslint/bin/eslint.js +++ b/.yarn/sdks/eslint/bin/eslint.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../../.pnp.cjs"; diff --git a/.yarn/sdks/eslint/lib/api.js b/.yarn/sdks/eslint/lib/api.js index d42c7d3..653b22b 100644 --- a/.yarn/sdks/eslint/lib/api.js +++ b/.yarn/sdks/eslint/lib/api.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../../.pnp.cjs"; diff --git a/.yarn/sdks/eslint/lib/unsupported-api.js b/.yarn/sdks/eslint/lib/unsupported-api.js new file mode 100644 index 0000000..30fdf15 --- /dev/null +++ b/.yarn/sdks/eslint/lib/unsupported-api.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require eslint/use-at-your-own-risk + require(absPnpApiPath).setup(); + } +} + +// Defer to the real eslint/use-at-your-own-risk your application uses +module.exports = absRequire(`eslint/use-at-your-own-risk`); diff --git a/.yarn/sdks/eslint/package.json b/.yarn/sdks/eslint/package.json index ff446fd..08e34b2 100644 --- a/.yarn/sdks/eslint/package.json +++ b/.yarn/sdks/eslint/package.json @@ -2,5 +2,13 @@ "name": "eslint", "version": "8.48.0-sdk", "main": "./lib/api.js", - "type": "commonjs" + "type": "commonjs", + "bin": { + "eslint": "./bin/eslint.js" + }, + "exports": { + "./package.json": "./package.json", + ".": "./lib/api.js", + "./use-at-your-own-risk": "./lib/unsupported-api.js" + } } diff --git a/.yarn/sdks/prettier/bin-prettier.js b/.yarn/sdks/prettier/bin-prettier.js new file mode 100755 index 0000000..73f04ca --- /dev/null +++ b/.yarn/sdks/prettier/bin-prettier.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require prettier/bin-prettier.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real prettier/bin-prettier.js your application uses +module.exports = absRequire(`prettier/bin-prettier.js`); diff --git a/.yarn/sdks/prettier/index.js b/.yarn/sdks/prettier/index.js old mode 100755 new mode 100644 index 25c9785..8758e36 --- a/.yarn/sdks/prettier/index.js +++ b/.yarn/sdks/prettier/index.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../.pnp.cjs"; diff --git a/.yarn/sdks/prettier/package.json b/.yarn/sdks/prettier/package.json index 40e3c2e..0afcaf2 100644 --- a/.yarn/sdks/prettier/package.json +++ b/.yarn/sdks/prettier/package.json @@ -2,5 +2,6 @@ "name": "prettier", "version": "2.8.8-sdk", "main": "./index.js", - "type": "commonjs" + "type": "commonjs", + "bin": "./bin-prettier.js" } diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js index cd7b233..2f62fc9 100644 --- a/.yarn/sdks/typescript/lib/tsc.js +++ b/.yarn/sdks/typescript/lib/tsc.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../../.pnp.cjs"; diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js index 5dcd6d9..bbb1e46 100644 --- a/.yarn/sdks/typescript/lib/tsserver.js +++ b/.yarn/sdks/typescript/lib/tsserver.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../../.pnp.cjs"; @@ -14,18 +14,16 @@ const moduleWrapper = tsserver => { return tsserver; } - const { isAbsolute } = require(`path`); + const {isAbsolute} = require(`path`); const pnpApi = require(`pnpapi`); const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); const isPortal = str => str.startsWith("portal:/"); const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); - const dependencyTreeRoots = new Set( - pnpApi.getDependencyTreeRoots().map(locator => { - return `${locator.name}@${locator.reference}`; - }) - ); + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); // VSCode sends the zip paths to TS using the "zip://" prefix, that TS // doesn't understand. This layer makes sure to remove the protocol @@ -47,10 +45,7 @@ const moduleWrapper = tsserver => { const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; if (resolved) { const locator = pnpApi.findPackageLocator(resolved); - if ( - locator && - (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference)) - ) { + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { str = resolved; } } @@ -78,55 +73,41 @@ const moduleWrapper = tsserver => { // Before | ^/zip/c:/foo/bar.zip/package.json // After | ^/zip//c:/foo/bar.zip/package.json // - case `vscode <1.61`: - { - str = `^zip:${str}`; - } - break; + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; - case `vscode <1.66`: - { - str = `^/zip/${str}`; - } - break; + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; - case `vscode <1.68`: - { - str = `^/zip${str}`; - } - break; + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; - case `vscode`: - { - str = `^/zip/${str}`; - } - break; + case `vscode`: { + str = `^/zip/${str}`; + } break; // To make "go to definition" work, // We have to resolve the actual file system path from virtual path // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) - case `coc-nvim`: - { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = resolve(`zipfile:${str}`); - } - break; + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) // We have to resolve the actual file system path from virtual path, // everything else is up to neovim - case `neovim`: - { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = `zipfile://${str}`; - } - break; + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; - default: - { - str = `zip:${str}`; - } - break; + default: { + str = `zip:${str}`; + } break; } } else { str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); @@ -138,30 +119,26 @@ const moduleWrapper = tsserver => { function fromEditorPath(str) { switch (hostInfo) { - case `coc-nvim`: - { - str = str.replace(/\.zip::/, `.zip/`); - // The path for coc-nvim is in format of //zipfile://.yarn/... - // So in order to convert it back, we use .* to match all the thing - // before `zipfile:` - return process.platform === `win32` ? str.replace(/^.*zipfile:\//, ``) : str.replace(/^.*zipfile:/, ``); - } - break; + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; - case `neovim`: - { - str = str.replace(/\.zip::/, `.zip/`); - // The path for neovim is in format of zipfile:////.yarn/... - return str.replace(/^zipfile:\/\//, ``); - } - break; + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; case `vscode`: - default: - { - return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`); - } - break; + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; } } @@ -173,8 +150,8 @@ const moduleWrapper = tsserver => { // TypeScript already does local loads and if this code is running the user trusts the workspace // https://github.com/microsoft/vscode/issues/45856 const ConfiguredProject = tsserver.server.ConfiguredProject; - const { enablePluginsWithOptions: originalEnablePluginsWithOptions } = ConfiguredProject.prototype; - ConfiguredProject.prototype.enablePluginsWithOptions = function () { + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { this.projectService.allowLocalPluginLoads = true; return originalEnablePluginsWithOptions.apply(this, arguments); }; @@ -184,12 +161,12 @@ const moduleWrapper = tsserver => { // like an absolute path of ours and normalize it. const Session = tsserver.server.Session; - const { onMessage: originalOnMessage, send: originalSend } = Session.prototype; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; let hostInfo = `unknown`; Object.assign(Session.prototype, { onMessage(/** @type {string | object} */ message) { - const isStringMessage = typeof message === "string"; + const isStringMessage = typeof message === 'string'; const parsedMessage = isStringMessage ? JSON.parse(message) : message; if ( @@ -200,12 +177,10 @@ const moduleWrapper = tsserver => { ) { hostInfo = parsedMessage.arguments.hostInfo; if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { - const [, major, minor] = ( - process.env.VSCODE_IPC_HOOK.match( - // The RegExp from https://semver.org/ but without the caret at the start - /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ - ) ?? [] - ).map(Number); + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) if (major === 1) { if (minor < 61) { @@ -220,22 +195,20 @@ const moduleWrapper = tsserver => { } const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { - return typeof value === "string" ? fromEditorPath(value) : value; + return typeof value === 'string' ? fromEditorPath(value) : value; }); - return originalOnMessage.call(this, isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)); + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); }, send(/** @type {any} */ msg) { - return originalSend.call( - this, - JSON.parse( - JSON.stringify(msg, (key, value) => { - return typeof value === `string` ? toEditorPath(value) : value; - }) - ) - ); - }, + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } }); return tsserver; diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js index d8dae69..a68f028 100644 --- a/.yarn/sdks/typescript/lib/tsserverlibrary.js +++ b/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../../.pnp.cjs"; @@ -14,18 +14,16 @@ const moduleWrapper = tsserver => { return tsserver; } - const { isAbsolute } = require(`path`); + const {isAbsolute} = require(`path`); const pnpApi = require(`pnpapi`); const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); const isPortal = str => str.startsWith("portal:/"); const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); - const dependencyTreeRoots = new Set( - pnpApi.getDependencyTreeRoots().map(locator => { - return `${locator.name}@${locator.reference}`; - }) - ); + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); // VSCode sends the zip paths to TS using the "zip://" prefix, that TS // doesn't understand. This layer makes sure to remove the protocol @@ -47,10 +45,7 @@ const moduleWrapper = tsserver => { const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; if (resolved) { const locator = pnpApi.findPackageLocator(resolved); - if ( - locator && - (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference)) - ) { + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { str = resolved; } } @@ -78,55 +73,41 @@ const moduleWrapper = tsserver => { // Before | ^/zip/c:/foo/bar.zip/package.json // After | ^/zip//c:/foo/bar.zip/package.json // - case `vscode <1.61`: - { - str = `^zip:${str}`; - } - break; + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; - case `vscode <1.66`: - { - str = `^/zip/${str}`; - } - break; + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; - case `vscode <1.68`: - { - str = `^/zip${str}`; - } - break; + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; - case `vscode`: - { - str = `^/zip/${str}`; - } - break; + case `vscode`: { + str = `^/zip/${str}`; + } break; // To make "go to definition" work, // We have to resolve the actual file system path from virtual path // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) - case `coc-nvim`: - { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = resolve(`zipfile:${str}`); - } - break; + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) // We have to resolve the actual file system path from virtual path, // everything else is up to neovim - case `neovim`: - { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = `zipfile://${str}`; - } - break; + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; - default: - { - str = `zip:${str}`; - } - break; + default: { + str = `zip:${str}`; + } break; } } else { str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); @@ -138,30 +119,26 @@ const moduleWrapper = tsserver => { function fromEditorPath(str) { switch (hostInfo) { - case `coc-nvim`: - { - str = str.replace(/\.zip::/, `.zip/`); - // The path for coc-nvim is in format of //zipfile://.yarn/... - // So in order to convert it back, we use .* to match all the thing - // before `zipfile:` - return process.platform === `win32` ? str.replace(/^.*zipfile:\//, ``) : str.replace(/^.*zipfile:/, ``); - } - break; + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; - case `neovim`: - { - str = str.replace(/\.zip::/, `.zip/`); - // The path for neovim is in format of zipfile:////.yarn/... - return str.replace(/^zipfile:\/\//, ``); - } - break; + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; case `vscode`: - default: - { - return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`); - } - break; + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; } } @@ -173,8 +150,8 @@ const moduleWrapper = tsserver => { // TypeScript already does local loads and if this code is running the user trusts the workspace // https://github.com/microsoft/vscode/issues/45856 const ConfiguredProject = tsserver.server.ConfiguredProject; - const { enablePluginsWithOptions: originalEnablePluginsWithOptions } = ConfiguredProject.prototype; - ConfiguredProject.prototype.enablePluginsWithOptions = function () { + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { this.projectService.allowLocalPluginLoads = true; return originalEnablePluginsWithOptions.apply(this, arguments); }; @@ -184,12 +161,12 @@ const moduleWrapper = tsserver => { // like an absolute path of ours and normalize it. const Session = tsserver.server.Session; - const { onMessage: originalOnMessage, send: originalSend } = Session.prototype; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; let hostInfo = `unknown`; Object.assign(Session.prototype, { onMessage(/** @type {string | object} */ message) { - const isStringMessage = typeof message === "string"; + const isStringMessage = typeof message === 'string'; const parsedMessage = isStringMessage ? JSON.parse(message) : message; if ( @@ -200,12 +177,10 @@ const moduleWrapper = tsserver => { ) { hostInfo = parsedMessage.arguments.hostInfo; if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { - const [, major, minor] = ( - process.env.VSCODE_IPC_HOOK.match( - // The RegExp from https://semver.org/ but without the caret at the start - /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ - ) ?? [] - ).map(Number); + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) if (major === 1) { if (minor < 61) { @@ -220,22 +195,20 @@ const moduleWrapper = tsserver => { } const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { - return typeof value === "string" ? fromEditorPath(value) : value; + return typeof value === 'string' ? fromEditorPath(value) : value; }); - return originalOnMessage.call(this, isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)); + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); }, send(/** @type {any} */ msg) { - return originalSend.call( - this, - JSON.parse( - JSON.stringify(msg, (key, value) => { - return typeof value === `string` ? toEditorPath(value) : value; - }) - ) - ); - }, + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } }); return tsserver; diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js index 4ffbed0..b5f4db2 100644 --- a/.yarn/sdks/typescript/lib/typescript.js +++ b/.yarn/sdks/typescript/lib/typescript.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const { existsSync } = require(`fs`); -const { createRequire } = require(`module`); -const { resolve } = require(`path`); +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); const relPnpApiPath = "../../../../.pnp.cjs"; @@ -11,10 +11,10 @@ const absRequire = createRequire(absPnpApiPath); if (existsSync(absPnpApiPath)) { if (!process.versions.pnp) { - // Setup the environment to be able to require typescript/lib/typescript.js + // Setup the environment to be able to require typescript require(absPnpApiPath).setup(); } } -// Defer to the real typescript/lib/typescript.js your application uses -module.exports = absRequire(`typescript/lib/typescript.js`); +// Defer to the real typescript your application uses +module.exports = absRequire(`typescript`); diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json index 0bfa4eb..d32f391 100644 --- a/.yarn/sdks/typescript/package.json +++ b/.yarn/sdks/typescript/package.json @@ -2,5 +2,9 @@ "name": "typescript", "version": "5.2.2-sdk", "main": "./lib/typescript.js", - "type": "commonjs" + "type": "commonjs", + "bin": { + "tsc": "./bin/tsc", + "tsserver": "./bin/tsserver" + } } diff --git a/public/index.html b/index.html similarity index 89% rename from public/index.html rename to index.html index b2d287d..fc2e45b 100644 --- a/public/index.html +++ b/index.html @@ -13,5 +13,6 @@
+ diff --git a/package.json b/package.json index c6c446a..a16ba40 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,12 @@ "@radix-ui/react-toggle": "^1.0.3", "@react-hook/resize-observer": "^1.2.6", "@scure/base": "^1.1.1", - "@snort/shared": "^1.0.9", - "@snort/system": "^1.1.4", - "@snort/system-react": "^1.1.4", + "@snort/shared": "^1.0.10", + "@snort/system": "^1.1.5", + "@snort/system-react": "^1.1.5", + "@snort/system-wasm": "^1.0.1", "@snort/system-web": "^1.0.2", "@szhsin/react-menu": "^4.0.2", - "@testing-library/jest-dom": "^5.14.1", - "@testing-library/react": "^13.0.0", - "@testing-library/user-event": "^13.2.1", "@types/webscopeio__react-textarea-autocomplete": "^4.7.2", "@void-cat/api": "^1.0.7", "@webscopeio/react-textarea-autocomplete": "^4.9.2", @@ -32,7 +30,6 @@ "lodash": "^4.17.21", "lodash.uniqby": "^4.7.0", "marked": "^9.1.2", - "moment": "^2.29.4", "qr-code-styling": "^1.6.0-rc.1", "react": "^18.2.0", "react-confetti": "^6.1.0", @@ -55,8 +52,8 @@ "workbox-strategies": "^7.0.0" }, "scripts": { - "start": "webpack serve --node-env=development --mode=development", - "build": "webpack --node-env=production --mode=production", + "start": "vite", + "build": "vite build", "deploy": "__XXX='false' && yarn build && npx wrangler pages publish --project-name nostr-live build", "deploy:xxzap": "__XXX='true' && yarn build && npx wrangler pages publish --project-name xxzap build", "intl-extract": "formatjs extract 'src/**/*.ts*' --ignore='**/*.d.ts' --out-file src/lang.json --flatten true", @@ -83,40 +80,27 @@ ] }, "devDependencies": { - "@babel/core": "^7.22.11", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/preset-env": "^7.21.5", - "@babel/preset-react": "^7.18.6", "@formatjs/cli": "^6.1.3", "@formatjs/ts-transformer": "^3.13.3", "@testing-library/dom": "^9.3.1", "@types/lodash": "^4.14.195", "@types/lodash.uniqby": "^4.7.7", + "@types/node": "^20.10.3", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "@types/react-helmet": "^6.1.6", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", + "@vitejs/plugin-react": "^4.2.0", "@webbtc/webln-types": "^1.0.12", - "babel-loader": "^9.1.3", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.0", "eslint": "^8.48.0", - "eslint-webpack-plugin": "^4.0.1", - "html-webpack-plugin": "^5.5.1", - "mini-css-extract-plugin": "^2.7.5", + "eslint-plugin-formatjs": "^4.11.3", "prettier": "^2.8.8", "prop-types": "^15.8.1", - "source-map-loader": "^4.0.1", - "terser-webpack-plugin": "^5.3.9", - "ts-loader": "^9.4.4", "typescript": "^5.2.2", - "webpack": "^5.88.2", - "webpack-bundle-analyzer": "^4.8.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.1", - "workbox-webpack-plugin": "^7.0.0" + "vite": "^5.0.5", + "vite-plugin-pwa": "^0.17.2", + "vite-plugin-version-mark": "^0.0.10" }, "packageManager": "yarn@3.6.3", "prettier": { diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 641a338268b796ac02215fe982810a8f0e53d66d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4314 zcmd5?eGfyLq>lM;#!L1Z1GLsw6AC=pM3t)qoVQJpL3 z5V(iHIusQIvO(AE4{jnIG-CGsq!;^r&+=2hcK6A1c<;^3Z=5&dn~@|P`?R%5_?C{$ zlJrfIBpaJ-OZv_x_KSm^l^c4!UYeYo9Nyd8i$6X-riiG(X0@XL9sB$H@#*R5Vd(yB z^!4@ioS&a3ss$@2cX@gF!|8N7O4%?mG2woFef?EVN3G|;0M?&2Fq?YVezsQKYUP0i zU&9963G>U5T3N05*gYQso5jV5TAlfPo(hEmfj&P!Q#PBWOeUjNT;OAIKEh&iQ#klw zLLp+;Cd}R4T{)wQ z)f@JU3RW4*+}xai-`Lnl>`rBTDi#%EbDe{OgMtkm9UYWTr#Xve^y=!0{C+>V-EJBm zAE%9t4Z6R-Cx^o!*wEkKUyM<$z;||bsG*@j!0~#$bb5M9R;yJwo0^)^1U{8Yk-=aP z^z-=h`FxZ}B#7m)z_Yx(T(b=e3k!l?j?HNx5TLECt&)7PSga-+Mn^|W>gCv+uCK3C zI2;yujYcC~Utd>k!|d#=pfeZ@($LUQabKs?z0-q(1Dcr-Q5-69Hs6^BtmOzYl3Z@kG=7l{TE$aTu@U}lYoWX zL;NexJRT3--rmA|%|@wstgEY|;V&ir+xIMf{FAwcG90)Iu+n)*t*wA+I?$r!JSPqId%~Y9Ow&5}M292yZRo4*tii zudk=Y#YNR>Q2U_-Dc;NjuneIn*reXZauy+rMc8W^>3X^yYkMa>Uv4D { disabled?: boolean; diff --git a/src/element/badge.tsx b/src/element/badge.tsx index d65cad1..a6ded51 100644 --- a/src/element/badge.tsx +++ b/src/element/badge.tsx @@ -1,6 +1,6 @@ import "./badge.css"; import type { NostrEvent } from "@snort/system"; -import { findTag } from "utils"; +import { findTag } from "@/utils"; export function Badge({ ev }: { ev: NostrEvent }) { const name = findTag(ev, "name") || findTag(ev, "d"); diff --git a/src/element/chat-message.tsx b/src/element/chat-message.tsx index b994069..74737c1 100644 --- a/src/element/chat-message.tsx +++ b/src/element/chat-message.tsx @@ -1,20 +1,21 @@ -import { useUserProfile, SnortContext, useEventReactions } from "@snort/system-react"; +import { SnortContext, useEventReactions, useUserProfile } from "@snort/system-react"; import { EventKind, NostrLink, TaggedNostrEvent } from "@snort/system"; -import React, { useRef, useState, useMemo, useContext } from "react"; -import { useMediaQuery, useHover, useOnClickOutside, useIntersectionObserver } from "usehooks-ts"; +import React, { useContext, useMemo, useRef, useState } from "react"; +import { useHover, useIntersectionObserver, useMediaQuery, useOnClickOutside } from "usehooks-ts"; import { dedupe } from "@snort/shared"; -import { EmojiPicker } from "element/emoji-picker"; -import { Icon } from "element/icon"; -import { Emoji as EmojiComponent } from "element/emoji"; +import { EmojiPicker } from "./emoji-picker"; +import { Icon } from "./icon"; +import { Emoji as EmojiComponent } from "./emoji"; import { Profile } from "./profile"; -import { Text } from "element/text"; -import { useMute } from "element/mute-button"; -import { SendZapsDialog } from "element/send-zap"; -import { CollapsibleEvent } from "element/collapsible"; -import { useLogin } from "hooks/login"; -import { formatSats } from "number"; -import type { Badge, Emoji, EmojiPack } from "types"; +import { Text } from "./text"; +import { useMute } from "./mute-button"; +import { SendZapsDialog } from "./send-zap"; +import { CollapsibleEvent } from "./collapsible"; + +import { useLogin } from "@/hooks/login"; +import { formatSats } from "@/number"; +import type { Badge, Emoji, EmojiPack } from "@/types"; function emojifyReaction(reaction: string) { if (reaction === "+") { diff --git a/src/element/collapsible.tsx b/src/element/collapsible.tsx index eb5e535..ab8b077 100644 --- a/src/element/collapsible.tsx +++ b/src/element/collapsible.tsx @@ -8,10 +8,10 @@ import * as Collapsible from "@radix-ui/react-collapsible"; import type { NostrLink } from "@snort/system"; -import { Mention } from "element/mention"; -import { NostrEvent, EventIcon } from "element/Event"; -import { ExternalLink } from "element/external-link"; -import { useEvent } from "hooks/event"; +import { Mention } from "./mention"; +import { EventIcon, NostrEvent } from "./Event"; +import { ExternalLink } from "./external-link"; +import { useEvent } from "@/hooks/event"; interface MediaURLProps { url: URL; @@ -32,7 +32,7 @@ export function MediaURL({ url, children }: MediaURLProps) { @@ -55,7 +55,11 @@ export function CollapsibleEvent({ link }: { link: NostrLink }) { diff --git a/src/element/content-warning.tsx b/src/element/content-warning.tsx index 498ec27..b3f99c6 100644 --- a/src/element/content-warning.tsx +++ b/src/element/content-warning.tsx @@ -19,17 +19,17 @@ export function ContentWarningOverlay() { return (

- +

- +

diff --git a/src/element/copy.tsx b/src/element/copy.tsx index 92e30f5..4679797 100644 --- a/src/element/copy.tsx +++ b/src/element/copy.tsx @@ -1,5 +1,5 @@ import "./copy.css"; -import { useCopy } from "hooks/copy"; +import { useCopy } from "@/hooks/copy"; import { Icon } from "./icon"; export interface CopyProps { diff --git a/src/element/emoji-pack.tsx b/src/element/emoji-pack.tsx index 58e5af5..b4dd050 100644 --- a/src/element/emoji-pack.tsx +++ b/src/element/emoji-pack.tsx @@ -1,17 +1,17 @@ import "./emoji-pack.css"; import { type NostrEvent } from "@snort/system"; - -import { useLogin } from "hooks/login"; -import { toEmojiPack } from "hooks/emoji"; -import AsyncButton from "element/async-button"; -import { findTag } from "utils"; -import { USER_EMOJIS } from "const"; -import { Login } from "index"; -import type { EmojiPack as EmojiPackType } from "types"; import { FormattedMessage } from "react-intl"; import { useContext } from "react"; import { SnortContext } from "@snort/system-react"; +import { useLogin } from "@/hooks/login"; +import { toEmojiPack } from "@/hooks/emoji"; +import AsyncButton from "./async-button"; +import { findTag } from "@/utils"; +import { USER_EMOJIS } from "@/const"; +import { Login } from "@/index"; +import type { EmojiPack as EmojiPackType } from "@/types"; + export function EmojiPack({ ev }: { ev: NostrEvent }) { const system = useContext(SnortContext); const login = useLogin(); @@ -49,7 +49,11 @@ export function EmojiPack({ ev }: { ev: NostrEvent }) { - {isUsed ? : } + {isUsed ? ( + + ) : ( + + )} )} diff --git a/src/element/emoji-picker.tsx b/src/element/emoji-picker.tsx index 212b638..cd365d3 100644 --- a/src/element/emoji-picker.tsx +++ b/src/element/emoji-picker.tsx @@ -1,7 +1,7 @@ import data, { Emoji } from "@emoji-mart/data"; import Picker from "@emoji-mart/react"; import { RefObject } from "react"; -import { EmojiPack } from "types"; +import { EmojiPack } from "@/types"; interface EmojiPickerProps { topOffset: number; diff --git a/src/element/emoji.tsx b/src/element/emoji.tsx index e303f87..bd3f999 100644 --- a/src/element/emoji.tsx +++ b/src/element/emoji.tsx @@ -1,6 +1,6 @@ import "./emoji.css"; import { useMemo } from "react"; -import { EmojiTag } from "types"; +import { EmojiTag } from "@/types"; export type EmojiProps = { name: string; diff --git a/src/element/external-link.tsx b/src/element/external-link.tsx index c8f9b20..5e71dec 100644 --- a/src/element/external-link.tsx +++ b/src/element/external-link.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from "react"; -import { Icon } from "element/icon"; +import { Icon } from "./icon"; interface ExternalLinkProps { href: string; diff --git a/src/element/file-uploader.tsx b/src/element/file-uploader.tsx index d6c372c..4f609b5 100644 --- a/src/element/file-uploader.tsx +++ b/src/element/file-uploader.tsx @@ -79,15 +79,15 @@ export function FileUploader({ defaultImage, onClear, onFileUpload }: FileUpload
{img?.length > 0 && ( )} {img && } diff --git a/src/element/follow-button.tsx b/src/element/follow-button.tsx index 6df9892..255bce5 100644 --- a/src/element/follow-button.tsx +++ b/src/element/follow-button.tsx @@ -1,12 +1,12 @@ import { EventKind } from "@snort/system"; - -import { useLogin } from "hooks/login"; -import AsyncButton from "element/async-button"; -import { Login } from "index"; import { FormattedMessage } from "react-intl"; import { useContext } from "react"; import { SnortContext } from "@snort/system-react"; +import { useLogin } from "@/hooks/login"; +import AsyncButton from "./async-button"; +import { Login } from "@/index"; + export function LoggedInFollowButton({ tag, value }: { tag: "p" | "t"; value: string }) { const system = useContext(SnortContext); const login = useLogin(); @@ -56,7 +56,11 @@ export function LoggedInFollowButton({ tag, value }: { tag: "p" | "t"; value: st type="button" className="btn btn-primary" onClick={isFollowing ? unfollow : follow}> - {isFollowing ? : } + {isFollowing ? ( + + ) : ( + + )} ); } diff --git a/src/element/goal.tsx b/src/element/goal.tsx index b523ee8..d966b14 100644 --- a/src/element/goal.tsx +++ b/src/element/goal.tsx @@ -2,18 +2,18 @@ import "./goal.css"; import { useMemo } from "react"; import * as Progress from "@radix-ui/react-progress"; import Confetti from "react-confetti"; +import { FormattedMessage } from "react-intl"; -import { NostrLink, type NostrEvent } from "@snort/system"; +import { type NostrEvent, NostrLink } from "@snort/system"; import { useUserProfile } from "@snort/system-react"; -import { findTag } from "utils"; -import { formatSats } from "number"; -import usePreviousValue from "hooks/usePreviousValue"; -import { SendZapsDialog } from "element/send-zap"; -import { getName } from "element/profile"; +import { findTag } from "@/utils"; +import { formatSats } from "@/number"; +import usePreviousValue from "@/hooks/usePreviousValue"; +import { SendZapsDialog } from "./send-zap"; +import { getName } from "./profile"; import { Icon } from "./icon"; -import { FormattedMessage } from "react-intl"; -import { useZaps } from "hooks/zaps"; +import { useZaps } from "@/hooks/zaps"; export function Goal({ ev }: { ev: NostrEvent }) { const profile = useUserProfile(ev.pubkey); @@ -48,7 +48,7 @@ export function Goal({ ev }: { ev: NostrEvent }) { {!isFinished && {formatSats(soFar)}} - +
diff --git a/src/element/hypertext.tsx b/src/element/hypertext.tsx index 6462ce2..a6662e8 100644 --- a/src/element/hypertext.tsx +++ b/src/element/hypertext.tsx @@ -1,6 +1,6 @@ import type { ReactNode } from "react"; -import { NostrLink } from "element/nostr-link"; -import { MediaURL } from "element/collapsible"; +import { NostrLink } from "./nostr-link"; +import { MediaURL } from "./collapsible"; const FileExtensionRegex = /\.([\w]+)$/i; diff --git a/src/element/live-chat.tsx b/src/element/live-chat.tsx index bd0a2e0..61968fd 100644 --- a/src/element/live-chat.tsx +++ b/src/element/live-chat.tsx @@ -1,29 +1,29 @@ import "./live-chat.css"; import { FormattedMessage } from "react-intl"; -import { EventKind, NostrLink, ParsedZap, NostrEvent } from "@snort/system"; +import { EventKind, NostrEvent, NostrLink, ParsedZap } from "@snort/system"; import { useEventReactions } from "@snort/system-react"; import { unixNow } from "@snort/shared"; import { useMemo } from "react"; import uniqBy from "lodash.uniqby"; -import { Icon } from "element/icon"; -import Spinner from "element/spinner"; -import { Text } from "element/text"; -import { Profile } from "element/profile"; -import { ChatMessage } from "element/chat-message"; -import { Goal } from "element/goal"; -import { Badge } from "element/badge"; -import { WriteMessage } from "element/write-message"; -import useEmoji, { packId } from "hooks/emoji"; -import { useLiveChatFeed } from "hooks/live-chat"; -import { useMutedPubkeys } from "hooks/lists"; -import { useBadges } from "hooks/badges"; -import { useLogin } from "hooks/login"; -import { useAddress } from "hooks/event"; -import { formatSats } from "number"; -import { WEEK, LIVE_STREAM_CHAT } from "const"; -import { findTag, getTagValues, getHost } from "utils"; -import { TopZappers } from "element/top-zappers"; +import { Icon } from "./icon"; +import Spinner from "./spinner"; +import { Text } from "./text"; +import { Profile } from "./profile"; +import { ChatMessage } from "./chat-message"; +import { Goal } from "./goal"; +import { Badge } from "./badge"; +import { WriteMessage } from "./write-message"; +import useEmoji, { packId } from "@/hooks/emoji"; +import { useLiveChatFeed } from "@/hooks/live-chat"; +import { useMutedPubkeys } from "@/hooks/lists"; +import { useBadges } from "@/hooks/badges"; +import { useLogin } from "@/hooks/login"; +import { useAddress } from "@/hooks/event"; +import { formatSats } from "@/number"; +import { LIVE_STREAM_CHAT, WEEK } from "@/const"; +import { findTag, getHost, getTagValues } from "@/utils"; +import { TopZappers } from "./top-zappers"; export interface LiveChatOptions { canWrite?: boolean; @@ -95,7 +95,7 @@ export function LiveChat({ {(options?.showHeader ?? true) && (

- +

0 && (

- +

@@ -151,7 +151,7 @@ export function LiveChat({ ) : (

- +

)}
@@ -174,6 +174,7 @@ function ChatZap({ zap }: { zap: ParsedZap }) { void }) { throw new Error( formatMessage({ defaultMessage: "Hmm, your lightning address looks wrong", + id: "4l69eO", }) ); } @@ -157,29 +158,29 @@ export function LoginSignup({ close }: { close: () => void }) {

- +

- +


- +
{hasNostrExtension && ( <> - + )} {error && {error}}
@@ -192,15 +193,16 @@ export function LoginSignup({ close }: { close: () => void }) {

- +

- + ), }} @@ -211,7 +213,7 @@ export function LoginSignup({ close }: { close: () => void }) { type="text" value={key} onChange={e => setNewKey(e.target.value)} - placeholder={formatMessage({ defaultMessage: "eg. nsec1xyz" })} + placeholder={formatMessage({ defaultMessage: "eg. nsec1xyz", id: "yzKwBQ" })} />

@@ -224,10 +226,10 @@ export function LoginSignup({ close }: { close: () => void }) { setNewKey(""); setStage(Stage.Login); }}> - + - +
@@ -242,7 +244,7 @@ export function LoginSignup({ close }: { close: () => void }) {

- +

void }) { />
- +
- +
@@ -282,15 +284,19 @@ export function LoginSignup({ close }: { close: () => void }) {

- +

- +

{providerInfo?.balance && (

, }} @@ -301,18 +307,18 @@ export function LoginSignup({ close }: { close: () => void }) {

setLnAddress(e.target.value)} />
- +
{error && {error}} - +
@@ -324,16 +330,19 @@ export function LoginSignup({ close }: { close: () => void }) {

- +

- +

diff --git a/src/element/markdown.tsx b/src/element/markdown.tsx index 6eacb5d..a84d930 100644 --- a/src/element/markdown.tsx +++ b/src/element/markdown.tsx @@ -1,7 +1,7 @@ import "./markdown.css"; import { ReactNode, forwardRef, useMemo } from "react"; -import { marked, Token } from "marked"; +import { Token, marked } from "marked"; import { HyperText } from "./hypertext"; import { Text } from "./text"; diff --git a/src/element/mute-button.tsx b/src/element/mute-button.tsx index f7b5e2f..c0d3700 100644 --- a/src/element/mute-button.tsx +++ b/src/element/mute-button.tsx @@ -1,11 +1,12 @@ import { useContext, useMemo } from "react"; -import { useLogin } from "hooks/login"; -import AsyncButton from "element/async-button"; -import { Login } from "index"; -import { MUTED } from "const"; import { FormattedMessage } from "react-intl"; import { SnortContext } from "@snort/system-react"; +import { useLogin } from "@/hooks/login"; +import AsyncButton from "./async-button"; +import { Login } from "@/index"; +import { MUTED } from "@/const"; + export function useMute(pubkey: string) { const system = useContext(SnortContext); const login = useLogin(); @@ -55,7 +56,11 @@ export function LoggedInMuteButton({ pubkey }: { pubkey: string }) { return ( (isMuted ? unmute() : mute())}> - {isMuted ? : } + {isMuted ? ( + + ) : ( + + )} ); } diff --git a/src/element/new-goal.tsx b/src/element/new-goal.tsx index 756495d..1f283f2 100644 --- a/src/element/new-goal.tsx +++ b/src/element/new-goal.tsx @@ -1,14 +1,14 @@ import "./new-goal.css"; import * as Dialog from "@radix-ui/react-dialog"; +import { FormattedMessage } from "react-intl"; +import { useContext, useState } from "react"; +import { SnortContext } from "@snort/system-react"; import AsyncButton from "./async-button"; -import { Icon } from "element/icon"; -import { useContext, useState } from "react"; -import { GOAL } from "const"; -import { useLogin } from "hooks/login"; -import { FormattedMessage } from "react-intl"; -import { defaultRelays } from "const"; -import { SnortContext } from "@snort/system-react"; +import { Icon } from "./icon"; +import { GOAL } from "@/const"; +import { useLogin } from "@/hooks/login"; +import { defaultRelays } from "@/const"; export function NewGoalDialog() { const system = useContext(SnortContext); @@ -44,7 +44,7 @@ export function NewGoalDialog() { - + @@ -56,12 +56,12 @@ export function NewGoalDialog() {

- +

- +

- +

- +
diff --git a/src/element/new-stream.tsx b/src/element/new-stream.tsx index c255a99..18690d7 100644 --- a/src/element/new-stream.tsx +++ b/src/element/new-stream.tsx @@ -1,18 +1,18 @@ import "./new-stream.css"; import * as Dialog from "@radix-ui/react-dialog"; - -import { Icon } from "element/icon"; -import { useStreamProvider } from "hooks/stream-provider"; -import { StreamProvider, StreamProviders } from "providers"; import { useContext, useEffect, useState } from "react"; -import { StreamEditor, StreamEditorProps } from "./stream-editor"; import { useNavigate } from "react-router-dom"; -import { eventLink, findTag } from "utils"; -import { NostrProviderDialog } from "./nostr-provider-dialog"; import { unwrap } from "@snort/shared"; import { FormattedMessage } from "react-intl"; import { SnortContext } from "@snort/system-react"; +import { Icon } from "./icon"; +import { useStreamProvider } from "@/hooks/stream-provider"; +import { StreamProvider, StreamProviders } from "@/providers"; +import { StreamEditor, StreamEditorProps } from "./stream-editor"; +import { eventLink, findTag } from "@/utils"; +import { NostrProviderDialog } from "./nostr-provider-dialog"; + function NewStream({ ev, onFinish }: StreamEditorProps) { const system = useContext(SnortContext); const providers = useStreamProvider(); @@ -65,7 +65,7 @@ function NewStream({ ev, onFinish }: StreamEditorProps) { return ( <>

- +

{providers.map(v => ( @@ -94,7 +94,7 @@ export function NewStreamDialog(props: NewStreamDialogProps & StreamEditorProps) {!props.text && ( <> - + diff --git a/src/element/nostr-provider-dialog.tsx b/src/element/nostr-provider-dialog.tsx index 525f935..c3b5ea5 100644 --- a/src/element/nostr-provider-dialog.tsx +++ b/src/element/nostr-provider-dialog.tsx @@ -1,12 +1,13 @@ import { NostrEvent } from "@snort/system"; -import { StreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "providers"; import { useContext, useEffect, useState } from "react"; +import { FormattedMessage } from "react-intl"; +import { SnortContext } from "@snort/system-react"; + +import { StreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "@/providers"; import { SendZaps } from "./send-zap"; import { StreamEditor, StreamEditorProps } from "./stream-editor"; import Spinner from "./spinner"; import AsyncButton from "./async-button"; -import { FormattedMessage } from "react-intl"; -import { SnortContext } from "@snort/system-react"; export function NostrProviderDialog({ provider, ...others }: { provider: StreamProvider } & StreamEditorProps) { const system = useContext(SnortContext); @@ -92,13 +93,14 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP

window.open(info.tosLink, "popup", "width=400,height=800")}> - + ), }} @@ -108,7 +110,7 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP

- +
@@ -120,7 +122,7 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP {info.endpoints.length > 1 && (

- +

{sortEndpoints(info.endpoints).map(a => ( @@ -133,7 +135,7 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP )}

- +

@@ -141,36 +143,40 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP

- +

- +

- +
- +

- +

{ep?.capabilities?.map(a => ( diff --git a/src/element/note.tsx b/src/element/note.tsx index d0fe311..fa0332f 100644 --- a/src/element/note.tsx +++ b/src/element/note.tsx @@ -1,11 +1,11 @@ import "./note.css"; import { type NostrEvent, NostrPrefix } from "@snort/system"; - -import { Markdown } from "element/markdown"; -import { ExternalIconLink } from "element/external-link"; -import { Profile } from "element/profile"; import { hexToBech32 } from "@snort/shared"; +import { Markdown } from "./markdown"; +import { ExternalIconLink } from "./external-link"; +import { Profile } from "./profile"; + export function Note({ ev }: { ev: NostrEvent }) { return (
diff --git a/src/element/profile.tsx b/src/element/profile.tsx index 2d0a891..2a808c3 100644 --- a/src/element/profile.tsx +++ b/src/element/profile.tsx @@ -4,11 +4,11 @@ import { Link } from "react-router-dom"; import { useUserProfile } from "@snort/system-react"; import { UserMetadata } from "@snort/system"; import { hexToBech32 } from "@snort/shared"; - -import { Icon } from "element/icon"; -import usePlaceholder from "hooks/placeholders"; import { useInView } from "react-intersection-observer"; +import { Icon } from "./icon"; +import usePlaceholder from "@/hooks/placeholders"; + export interface ProfileOptions { showName?: boolean; showAvatar?: boolean; diff --git a/src/element/send-zap.tsx b/src/element/send-zap.tsx index 157c4e5..cf5c22d 100644 --- a/src/element/send-zap.tsx +++ b/src/element/send-zap.tsx @@ -1,20 +1,20 @@ import "./send-zap.css"; import * as Dialog from "@radix-ui/react-dialog"; -import { useEffect, useState, type ReactNode } from "react"; +import { type ReactNode, useEffect, useState } from "react"; import { LNURL } from "@snort/shared"; -import { NostrEvent, EventPublisher } from "@snort/system"; +import { EventPublisher, NostrEvent } from "@snort/system"; import { secp256k1 } from "@noble/curves/secp256k1"; import { bytesToHex } from "@noble/curves/abstract/utils"; +import { FormattedMessage, FormattedNumber } from "react-intl"; import { formatSats } from "../number"; import { Icon } from "./icon"; import AsyncButton from "./async-button"; import QrCode from "./qr-code"; -import { useLogin } from "hooks/login"; +import { useLogin } from "@/hooks/login"; import Copy from "./copy"; -import { defaultRelays } from "const"; -import { FormattedMessage, FormattedNumber } from "react-intl"; -import { useRates } from "hooks/rates"; +import { defaultRelays } from "@/const"; +import { useRates } from "@/hooks/rates"; export interface LNURLLike { get name(): string; @@ -131,6 +131,7 @@ export function SendZaps({ lnurl, pubkey, aTag, eTag, targetName, onFinish }: Se {isFiat && ( @@ -138,6 +139,7 @@ export function SendZaps({ lnurl, pubkey, aTag, eTag, targetName, onFinish }: Se   , @@ -157,7 +159,7 @@ export function SendZaps({ lnurl, pubkey, aTag, eTag, targetName, onFinish }: Se {svc && (svc.maxCommentLength > 0 || svc.canZap) && (
- +