forked from Kieran/zap.stream
Compare commits
1 Commits
main
...
markdown-i
Author | SHA1 | Date | |
---|---|---|---|
6781ca3924 |
@ -22,4 +22,4 @@ steps:
|
||||
volumes:
|
||||
- name: cache
|
||||
claim:
|
||||
name: docker-cache
|
||||
name: docker-cache
|
@ -1,19 +1,14 @@
|
||||
module.exports = {
|
||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["@typescript-eslint"],
|
||||
root: true,
|
||||
ignorePatterns: ["build/", "*.test.ts", "*.js"],
|
||||
env: {
|
||||
browser: true,
|
||||
worker: true,
|
||||
commonjs: true,
|
||||
node: false,
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/no-non-null-assertion": "error",
|
||||
"require-await": "error",
|
||||
eqeqeq: "error",
|
||||
"object-shorthand": "warn",
|
||||
},
|
||||
};
|
||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["@typescript-eslint"],
|
||||
root: true,
|
||||
ignorePatterns: ["build/", "*.test.ts", "*.js"],
|
||||
env: {
|
||||
browser: true,
|
||||
worker: true,
|
||||
commonjs: true,
|
||||
node: false,
|
||||
},
|
||||
};
|
||||
|
6
.yarn/sdks/eslint/bin/eslint.js
vendored
6
.yarn/sdks/eslint/bin/eslint.js
vendored
@ -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";
|
||||
|
||||
|
6
.yarn/sdks/eslint/lib/api.js
vendored
6
.yarn/sdks/eslint/lib/api.js
vendored
@ -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";
|
||||
|
||||
|
6
.yarn/sdks/prettier/index.js
vendored
6
.yarn/sdks/prettier/index.js
vendored
@ -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";
|
||||
|
||||
|
6
.yarn/sdks/typescript/lib/tsc.js
vendored
6
.yarn/sdks/typescript/lib/tsc.js
vendored
@ -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";
|
||||
|
||||
|
185
.yarn/sdks/typescript/lib/tsserver.js
vendored
185
.yarn/sdks/typescript/lib/tsserver.js
vendored
@ -1,31 +1,29 @@
|
||||
#!/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";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const moduleWrapper = (tsserver) => {
|
||||
const moduleWrapper = tsserver => {
|
||||
if (!process.versions.pnp) {
|
||||
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 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
|
||||
@ -33,11 +31,7 @@ const moduleWrapper = (tsserver) => {
|
||||
|
||||
function toEditorPath(str) {
|
||||
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
|
||||
if (
|
||||
isAbsolute(str) &&
|
||||
!str.match(/^\^?(zip:|\/zip\/)/) &&
|
||||
(str.match(/\.zip\//) || isVirtual(str))
|
||||
) {
|
||||
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
|
||||
// We also take the opportunity to turn virtual paths into physical ones;
|
||||
// this makes it much easier to work with workspaces that list peer
|
||||
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
|
||||
@ -51,11 +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;
|
||||
}
|
||||
}
|
||||
@ -83,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` ? `` : `/`);
|
||||
@ -143,35 +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 /<pwd>/zipfile:/<pwd>/.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 /<pwd>/zipfile:/<pwd>/.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:///<pwd>/.yarn/...
|
||||
return str.replace(/^zipfile:\/\//, ``);
|
||||
}
|
||||
break;
|
||||
case `neovim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for neovim is in format of zipfile:///<pwd>/.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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,9 +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);
|
||||
};
|
||||
@ -195,13 +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 (
|
||||
@ -212,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) {
|
||||
@ -231,31 +194,21 @@ const moduleWrapper = (tsserver) => {
|
||||
}
|
||||
}
|
||||
|
||||
const processedMessageJSON = JSON.stringify(
|
||||
parsedMessage,
|
||||
(key, value) => {
|
||||
return typeof value === "string" ? fromEditorPath(value) : value;
|
||||
}
|
||||
);
|
||||
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
|
||||
return typeof value === 'string' ? fromEditorPath(value) : value;
|
||||
});
|
||||
|
||||
return originalOnMessage.call(
|
||||
this,
|
||||
isStringMessage
|
||||
? processedMessageJSON
|
||||
: JSON.parse(processedMessageJSON)
|
||||
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;
|
||||
|
185
.yarn/sdks/typescript/lib/tsserverlibrary.js
vendored
185
.yarn/sdks/typescript/lib/tsserverlibrary.js
vendored
@ -1,31 +1,29 @@
|
||||
#!/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";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const moduleWrapper = (tsserver) => {
|
||||
const moduleWrapper = tsserver => {
|
||||
if (!process.versions.pnp) {
|
||||
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 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
|
||||
@ -33,11 +31,7 @@ const moduleWrapper = (tsserver) => {
|
||||
|
||||
function toEditorPath(str) {
|
||||
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
|
||||
if (
|
||||
isAbsolute(str) &&
|
||||
!str.match(/^\^?(zip:|\/zip\/)/) &&
|
||||
(str.match(/\.zip\//) || isVirtual(str))
|
||||
) {
|
||||
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
|
||||
// We also take the opportunity to turn virtual paths into physical ones;
|
||||
// this makes it much easier to work with workspaces that list peer
|
||||
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
|
||||
@ -51,11 +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;
|
||||
}
|
||||
}
|
||||
@ -83,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` ? `` : `/`);
|
||||
@ -143,35 +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 /<pwd>/zipfile:/<pwd>/.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 /<pwd>/zipfile:/<pwd>/.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:///<pwd>/.yarn/...
|
||||
return str.replace(/^zipfile:\/\//, ``);
|
||||
}
|
||||
break;
|
||||
case `neovim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for neovim is in format of zipfile:///<pwd>/.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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,9 +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);
|
||||
};
|
||||
@ -195,13 +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 (
|
||||
@ -212,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) {
|
||||
@ -231,31 +194,21 @@ const moduleWrapper = (tsserver) => {
|
||||
}
|
||||
}
|
||||
|
||||
const processedMessageJSON = JSON.stringify(
|
||||
parsedMessage,
|
||||
(key, value) => {
|
||||
return typeof value === "string" ? fromEditorPath(value) : value;
|
||||
}
|
||||
);
|
||||
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
|
||||
return typeof value === 'string' ? fromEditorPath(value) : value;
|
||||
});
|
||||
|
||||
return originalOnMessage.call(
|
||||
this,
|
||||
isStringMessage
|
||||
? processedMessageJSON
|
||||
: JSON.parse(processedMessageJSON)
|
||||
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;
|
||||
|
6
.yarn/sdks/typescript/lib/typescript.js
vendored
6
.yarn/sdks/typescript/lib/typescript.js
vendored
@ -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";
|
||||
|
||||
|
2
_headers
2
_headers
@ -1,2 +1,2 @@
|
||||
/*
|
||||
Content-Security-Policy: default-src 'self'; manifest-src *; child-src 'none'; worker-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *; img-src * data: blob:; font-src 'self'; media-src * blob:; script-src 'self';
|
||||
Content-Security-Policy: default-src 'self'; manifest-src *; child-src 'none'; worker-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *; img-src * data: blob:; font-src https://fonts.gstatic.com; media-src * blob:; script-src 'self';
|
@ -52,8 +52,7 @@
|
||||
"scripts": {
|
||||
"start": "webpack serve",
|
||||
"build": "webpack --node-env=production",
|
||||
"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"
|
||||
"deploy": "npx wrangler pages publish build"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
@ -85,8 +85,5 @@
|
||||
<symbol id="face-content" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M8 14C8 14 9.5 16 12 16C14.5 16 16 14 16 14M17 9.24C16.605 9.725 16.065 10 15.5 10C14.935 10 14.41 9.725 14 9.24M10 9.24C9.605 9.725 9.065 10 8.5 10C7.935 10 7.41 9.725 7 9.24M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</symbol>
|
||||
<symbol id="user-x" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M16.5 16L21.5 21M21.5 16L16.5 21M15.5 3.29076C16.9659 3.88415 18 5.32131 18 7C18 8.67869 16.9659 10.1159 15.5 10.7092M12 15H8C6.13623 15 5.20435 15 4.46927 15.3045C3.48915 15.7105 2.71046 16.4892 2.30448 17.4693C2 18.2044 2 19.1362 2 21M13.5 7C13.5 9.20914 11.7091 11 9.5 11C7.29086 11 5.5 9.20914 5.5 7C5.5 4.79086 7.29086 3 9.5 3C11.7091 3 13.5 4.79086 13.5 7Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</symbol>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@ -1,17 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Nostr live streaming" />
|
||||
<link rel="apple-touch-icon" href="/logo.png" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<title>zap.stream</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Nostr live streaming" />
|
||||
<link rel="apple-touch-icon" href="/logo.png" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<title>zap.stream</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1 +1,3 @@
|
||||
[{ "id": "nsfw", "text": "NSFW" }]
|
||||
[
|
||||
{ "id": "nsfw", "text": "NSFW" }
|
||||
]
|
4
src/d.ts
4
src/d.ts
@ -1,9 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/// <reference types="@webbtc/webln-types" />
|
||||
|
||||
declare const __XXX: boolean;
|
||||
declare const __XXX_HOST: string;
|
||||
|
||||
declare module "*.jpg" {
|
||||
const value: unknown;
|
||||
export default value;
|
||||
|
@ -13,7 +13,6 @@ import { Icon } from "element/icon";
|
||||
import { Emoji as EmojiComponent } from "element/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";
|
||||
@ -56,7 +55,6 @@ export function ChatMessage({
|
||||
const emojiRef = useRef(null);
|
||||
const isTablet = useMediaQuery("(max-width: 1020px)");
|
||||
const isHovering = useHover(ref);
|
||||
const { mute } = useMute(ev.pubkey);
|
||||
const [showZapDialog, setShowZapDialog] = useState(false);
|
||||
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
||||
const login = useLogin();
|
||||
@ -64,8 +62,6 @@ export function ChatMessage({
|
||||
System,
|
||||
inView?.isIntersecting ? ev.pubkey : undefined
|
||||
);
|
||||
const shouldShowMuteButton =
|
||||
ev.pubkey !== streamer && ev.pubkey !== login?.pubkey;
|
||||
const zapTarget = profile?.lud16 ?? profile?.lud06;
|
||||
const zaps = useMemo(() => {
|
||||
return reactions
|
||||
@ -111,8 +107,8 @@ export function ChatMessage({
|
||||
const pub = login?.publisher();
|
||||
if (emoji.native) {
|
||||
reply = await pub?.react(ev, emoji.native || "+1");
|
||||
} else if (emoji.id) {
|
||||
const e = getEmojiById(emoji.id);
|
||||
} else {
|
||||
const e = getEmojiById(emoji.id!);
|
||||
if (e) {
|
||||
reply = await pub?.generic((eb) => {
|
||||
return eb
|
||||
@ -120,7 +116,7 @@ export function ChatMessage({
|
||||
.content(`:${emoji.id}:`)
|
||||
.tag(["e", ev.id])
|
||||
.tag(["p", ev.pubkey])
|
||||
.tag(["emoji", e[1], e[2]]);
|
||||
.tag(["emoji", e.at(1)!, e.at(2)!]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -136,16 +132,11 @@ export function ChatMessage({
|
||||
const topOffset = ref.current?.getBoundingClientRect().top;
|
||||
const leftOffset = ref.current?.getBoundingClientRect().left;
|
||||
|
||||
function pickEmoji(e: React.MouseEvent) {
|
||||
e.stopPropagation();
|
||||
function pickEmoji(ev: React.MouseEvent) {
|
||||
ev.stopPropagation();
|
||||
setShowEmojiPicker(!showEmojiPicker);
|
||||
}
|
||||
|
||||
function muteUser(e: React.MouseEvent) {
|
||||
e.stopPropagation();
|
||||
mute();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
@ -194,7 +185,7 @@ export function ChatMessage({
|
||||
<div className="message-reaction-container">
|
||||
{isCustomEmojiReaction && emoji ? (
|
||||
<span className="message-reaction">
|
||||
<EmojiComponent name={emoji[1]} url={emoji[2]} />
|
||||
<EmojiComponent name={emoji.at(1)!} url={emoji.at(2)!} />
|
||||
</span>
|
||||
) : (
|
||||
<span className="message-reaction">{e}</span>
|
||||
@ -238,11 +229,6 @@ export function ChatMessage({
|
||||
<button className="message-zap-button" onClick={pickEmoji}>
|
||||
<Icon name="face" className="message-zap-button-icon" />
|
||||
</button>
|
||||
{shouldShowMuteButton && (
|
||||
<button className="message-zap-button" onClick={muteUser}>
|
||||
<Icon name="user-x" className="message-zap-button-icon" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -12,9 +12,7 @@ export function LoggedInFollowButton({
|
||||
value: string;
|
||||
}) {
|
||||
const login = useLogin();
|
||||
if (!login) return;
|
||||
|
||||
const { tags, content, timestamp } = login.follows;
|
||||
const { tags, content, timestamp } = login!.follows;
|
||||
const follows = tags.filter((t) => t.at(0) === tag);
|
||||
const isFollowing = follows.find((t) => t.at(1) === value);
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
.live-chat > .write-message > div:nth-child(1) {
|
||||
height: 40px;
|
||||
height: 32px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@ -111,10 +111,6 @@
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.live-chat .zap-content a {
|
||||
color: var(--text-link);
|
||||
}
|
||||
|
||||
.top-zappers {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -325,6 +321,8 @@
|
||||
text-transform: lowercase;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-family: Outfit;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import {
|
||||
parseZap,
|
||||
encodeTLV,
|
||||
} from "@snort/system";
|
||||
import { unixNow, unwrap } from "@snort/shared";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import uniqBy from "lodash.uniqby";
|
||||
|
||||
@ -29,7 +28,7 @@ import { useLogin } from "hooks/login";
|
||||
import useTopZappers from "hooks/top-zappers";
|
||||
import { useAddress } from "hooks/event";
|
||||
import { formatSats } from "number";
|
||||
import { WEEK, LIVE_STREAM_CHAT } from "const";
|
||||
import { LIVE_STREAM_CHAT } from "const";
|
||||
import { findTag, getTagValues, getHost } from "utils";
|
||||
import { System } from "index";
|
||||
|
||||
@ -92,20 +91,16 @@ export function LiveChat({
|
||||
height?: number;
|
||||
}) {
|
||||
const host = getHost(ev);
|
||||
const { badges, awards } = useBadges(host);
|
||||
const feed = useLiveChatFeed(link, goal ? [goal.id] : undefined);
|
||||
const login = useLogin();
|
||||
useEffect(() => {
|
||||
const pubkeys = [
|
||||
...new Set(feed.zaps.flatMap((a) => [a.pubkey, unwrap(findTag(a, "p"))])),
|
||||
...new Set(feed.zaps.flatMap((a) => [a.pubkey, findTag(a, "p")!])),
|
||||
];
|
||||
System.ProfileLoader.TrackMetadata(pubkeys);
|
||||
return () => System.ProfileLoader.UntrackMetadata(pubkeys);
|
||||
}, [feed.zaps]);
|
||||
const started = useMemo(() => {
|
||||
const starts = findTag(ev, "starts");
|
||||
return starts ? Number(starts) : unixNow() - WEEK;
|
||||
}, [ev]);
|
||||
const { badges, awards } = useBadges(host, started);
|
||||
const mutedPubkeys = useMemo(() => {
|
||||
return new Set(getTagValues(login?.muted.tags ?? [], "p"));
|
||||
}, [login]);
|
||||
|
@ -18,3 +18,7 @@
|
||||
font-weight: 400;
|
||||
line-height: 29px; /* 161.111% */
|
||||
}
|
||||
|
||||
.markdown img:not(.emoji) {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -1,17 +1,13 @@
|
||||
import { useMemo } from "react";
|
||||
import { useLogin } from "hooks/login";
|
||||
import AsyncButton from "element/async-button";
|
||||
import { Login, System } from "index";
|
||||
import { MUTED } from "const";
|
||||
|
||||
export function useMute(pubkey: string) {
|
||||
export function LoggedInMuteButton({ pubkey }: { pubkey: string }) {
|
||||
const login = useLogin();
|
||||
const { tags, content } = login?.muted ?? { tags: [] };
|
||||
const muted = useMemo(() => tags.filter((t) => t.at(0) === "p"), [tags]);
|
||||
const isMuted = useMemo(
|
||||
() => muted.find((t) => t.at(1) === pubkey),
|
||||
[pubkey, muted]
|
||||
);
|
||||
const { tags, content } = login!.muted;
|
||||
const muted = tags.filter((t) => t.at(0) === "p");
|
||||
const isMuted = muted.find((t) => t.at(1) === pubkey);
|
||||
|
||||
async function unmute() {
|
||||
const pub = login?.publisher();
|
||||
@ -47,12 +43,6 @@ export function useMute(pubkey: string) {
|
||||
}
|
||||
}
|
||||
|
||||
return { isMuted, mute, unmute };
|
||||
}
|
||||
|
||||
export function LoggedInMuteButton({ pubkey }: { pubkey: string }) {
|
||||
const { isMuted, mute, unmute } = useMute(pubkey);
|
||||
|
||||
return (
|
||||
<AsyncButton
|
||||
type="button"
|
||||
|
@ -7,9 +7,8 @@ import { StreamProvider, StreamProviders } from "providers";
|
||||
import { useEffect, useState } from "react";
|
||||
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { eventLink, findTag } from "utils";
|
||||
import { eventLink } from "utils";
|
||||
import { NostrProviderDialog } from "./nostr-provider-dialog";
|
||||
import { unwrap } from "@snort/shared";
|
||||
|
||||
function NewStream({ ev, onFinish }: StreamEditorProps) {
|
||||
const providers = useStreamProvider();
|
||||
@ -20,7 +19,7 @@ function NewStream({ ev, onFinish }: StreamEditorProps) {
|
||||
if (!currentProvider) {
|
||||
setCurrentProvider(
|
||||
ev !== undefined
|
||||
? unwrap(providers.find((a) => a.name.toLowerCase() === "manual"))
|
||||
? providers.find((a) => a.name.toLowerCase() === "manual")!
|
||||
: providers.at(0)
|
||||
);
|
||||
}
|
||||
@ -36,17 +35,9 @@ function NewStream({ ev, onFinish }: StreamEditorProps) {
|
||||
onFinish={(ex) => {
|
||||
currentProvider.updateStreamInfo(ex);
|
||||
if (!ev) {
|
||||
if (
|
||||
findTag(ex, "content-warning") &&
|
||||
__XXX_HOST &&
|
||||
__XXX === false
|
||||
) {
|
||||
location.href = `${__XXX_HOST}/${eventLink(ex)}`;
|
||||
} else {
|
||||
navigate(`/${eventLink(ex)}`, {
|
||||
state: ev,
|
||||
});
|
||||
}
|
||||
navigate(`/${eventLink(ex)}`, {
|
||||
state: ev,
|
||||
});
|
||||
} else {
|
||||
onFinish?.(ev);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
.send-zap .amounts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
justify-content: space-evenly;
|
||||
gap: 8px;
|
||||
}
|
||||
|
@ -43,11 +43,10 @@ export function SendZaps({
|
||||
targetName,
|
||||
onFinish,
|
||||
}: SendZapsProps) {
|
||||
const UsdRate = 28_000;
|
||||
const UsdRate = 30_000;
|
||||
|
||||
const satsAmounts = [
|
||||
21, 69, 121, 221, 420, 1_000, 2_100, 5_000, 6_666, 10_000, 21_000, 42_000,
|
||||
69_000, 100_000, 210_000, 500_000, 1_000_000,
|
||||
100, 1_000, 5_000, 10_000, 50_000, 100_000, 500_000, 1_000_000,
|
||||
];
|
||||
const usdAmounts = [0.05, 0.5, 2, 5, 10, 50, 100, 200];
|
||||
const [isFiat, setIsFiat] = useState(false);
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { Menu, MenuItem } from "@szhsin/react-menu";
|
||||
import * as Dialog from "@radix-ui/react-dialog";
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { NostrEvent, NostrPrefix, encodeTLV } from "@snort/system";
|
||||
|
||||
import { Icon } from "./icon";
|
||||
import { useState } from "react";
|
||||
import { Textarea } from "./textarea";
|
||||
import { NostrEvent, NostrPrefix, encodeTLV } from "@snort/system";
|
||||
import { findTag } from "utils";
|
||||
import AsyncButton from "./async-button";
|
||||
import { useLogin } from "hooks/login";
|
||||
@ -20,7 +18,7 @@ export function ShareMenu({ ev }: { ev: NostrEvent }) {
|
||||
|
||||
const naddr = encodeTLV(
|
||||
NostrPrefix.Address,
|
||||
unwrap(findTag(ev, "d")),
|
||||
findTag(ev, "d")!,
|
||||
undefined,
|
||||
ev.kind,
|
||||
ev.pubkey
|
||||
|
@ -100,7 +100,7 @@ function Card({ canEdit, ev, cards }: CardProps) {
|
||||
);
|
||||
|
||||
function findTagByIdentifier(d: string) {
|
||||
return tags.find((t) => t[1].endsWith(`:${d}`));
|
||||
return tags.find((t) => t.at(1)!.endsWith(`:${d}`));
|
||||
}
|
||||
|
||||
const [dropStyle, dropRef] = useDrop(
|
||||
@ -293,7 +293,7 @@ function EditCard({ card, cards }: EditCardProps) {
|
||||
async function onCancel() {
|
||||
const pub = login?.publisher();
|
||||
if (pub) {
|
||||
const newTags = tags.filter((t) => !t[1].endsWith(`:${identifier}`));
|
||||
const newTags = tags.filter((t) => !t.at(1)!.endsWith(`:${identifier}`));
|
||||
const userCardsEv = await pub.generic((eb) => {
|
||||
eb.kind(USER_CARDS).content("");
|
||||
for (const tag of newTags) {
|
||||
@ -408,7 +408,7 @@ export function StreamCardEditor({ pubkey, tags }: StreamCardEditorProps) {
|
||||
<>
|
||||
<div className="stream-cards">
|
||||
{cards.map((ev) => (
|
||||
<Card canEdit={isEditing} cards={cards} key={ev.id} ev={ev} />
|
||||
<Card canEdit={isEditing} cards={cards} key={ev.id} ev={ev!} />
|
||||
))}
|
||||
{isEditing && <AddCard cards={cards} />}
|
||||
</div>
|
||||
@ -433,7 +433,7 @@ export function ReadOnlyStreamCards({ host }: StreamCardsProps) {
|
||||
return (
|
||||
<div className="stream-cards">
|
||||
{cards.map((ev) => (
|
||||
<Card cards={cards} key={ev.id} ev={ev} />
|
||||
<Card cards={cards} key={ev!.id} ev={ev!} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
@ -53,11 +53,11 @@ export function Textarea({ emojis, ...props }: TextareaProps) {
|
||||
const userDataProvider = async (token: string) => {
|
||||
const cache = System.ProfileLoader.Cache;
|
||||
if (cache instanceof UserProfileCache) {
|
||||
return await cache.search(token);
|
||||
return cache.search(token);
|
||||
}
|
||||
};
|
||||
|
||||
const emojiDataProvider = (token: string) => {
|
||||
const emojiDataProvider = async (token: string) => {
|
||||
const results = emojis
|
||||
.map((t) => {
|
||||
return {
|
||||
|
@ -1,84 +0,0 @@
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(outfit_400_latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
|
||||
U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(outfit_400_latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
|
||||
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url(outfit_500_latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
|
||||
U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url(outfit_500_latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
|
||||
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(outfit_600_latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
|
||||
U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(outfit_600_latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
|
||||
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(outfit_700_latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
|
||||
U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(outfit_700_latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
|
||||
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -7,16 +7,18 @@ import {
|
||||
RequestBuilder,
|
||||
} from "@snort/system";
|
||||
import { useRequestBuilder } from "@snort/system-react";
|
||||
import { unixNow } from "@snort/shared";
|
||||
|
||||
import { findTag, toAddress, getTagValues } from "utils";
|
||||
import { WEEK } from "const";
|
||||
import { System } from "index";
|
||||
import type { Badge } from "types";
|
||||
|
||||
export function useBadges(
|
||||
pubkey: string,
|
||||
since: number,
|
||||
leaveOpen = true
|
||||
): { badges: Badge[]; awards: TaggedRawEvent[] } {
|
||||
const since = useMemo(() => unixNow() - WEEK, [pubkey]);
|
||||
const rb = useMemo(() => {
|
||||
const rb = new RequestBuilder(`badges:${pubkey.slice(0, 12)}`);
|
||||
rb.withOptions({ leaveOpen });
|
||||
|
@ -29,7 +29,7 @@ export function useUserCards(
|
||||
|
||||
const subRelated = useMemo(() => {
|
||||
if (!pubkey) return null;
|
||||
const splitted = related.map((t) => t[1].split(":"));
|
||||
const splitted = related.map((t) => t.at(1)!.split(":"));
|
||||
const authors = splitted
|
||||
.map((s) => s.at(1))
|
||||
.filter((s) => s)
|
||||
@ -58,7 +58,7 @@ export function useUserCards(
|
||||
const cards = useMemo(() => {
|
||||
return related
|
||||
.map((t) => {
|
||||
const [k, pubkey, identifier] = t[1].split(":");
|
||||
const [k, pubkey, identifier] = t.at(1)!.split(":");
|
||||
const kind = Number(k);
|
||||
return (data ?? []).find(
|
||||
(e) =>
|
||||
@ -104,7 +104,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
|
||||
|
||||
const subRelated = useMemo(() => {
|
||||
if (!pubkey) return null;
|
||||
const splitted = related.map((t) => t[1].split(":"));
|
||||
const splitted = related.map((t) => t.at(1)!.split(":"));
|
||||
const authors = splitted
|
||||
.map((s) => s.at(1))
|
||||
.filter((s) => s)
|
||||
@ -134,7 +134,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
|
||||
const cards = useMemo(() => {
|
||||
return related
|
||||
.map((t) => {
|
||||
const [k, pubkey, identifier] = t[1].split(":");
|
||||
const [k, pubkey, identifier] = t.at(1)!.split(":");
|
||||
const kind = Number(k);
|
||||
return cardEvents.find(
|
||||
(e) =>
|
||||
|
@ -45,7 +45,7 @@ export function useUserEmojiPacks(pubkey?: string, userEmoji?: Tags) {
|
||||
|
||||
const subRelated = useMemo(() => {
|
||||
if (!pubkey) return null;
|
||||
const splitted = related.map((t) => t[1].split(":"));
|
||||
const splitted = related.map((t) => t.at(1)!.split(":"));
|
||||
const authors = splitted
|
||||
.map((s) => s.at(1))
|
||||
.filter((s) => s)
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
parseZap,
|
||||
} from "@snort/system";
|
||||
import { useRequestBuilder } from "@snort/system-react";
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { GOAL } from "const";
|
||||
import { System } from "index";
|
||||
|
||||
@ -37,15 +36,14 @@ export function useZaps(goal: NostrEvent, leaveOpen = false) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useZapGoal(host: string, link?: NostrLink, leaveOpen = false) {
|
||||
export function useZapGoal(host: string, link: NostrLink, leaveOpen = false) {
|
||||
const sub = useMemo(() => {
|
||||
if (!link) return null;
|
||||
const b = new RequestBuilder(`goals:${host.slice(0, 12)}`);
|
||||
b.withOptions({ leaveOpen });
|
||||
b.withFilter()
|
||||
.kinds([GOAL])
|
||||
.authors([host])
|
||||
.tag("a", [`${link.kind}:${unwrap(link.author)}:${link.id}`]);
|
||||
.tag("a", [`${link.kind}:${link.author!}:${link.id}`]);
|
||||
return b;
|
||||
}, [link, leaveOpen]);
|
||||
|
||||
|
@ -37,32 +37,22 @@ export function useStreamsFeed(tag?: string) {
|
||||
const feed = useRequestBuilder<NoteCollection>(System, NoteCollection, rb);
|
||||
const feedSorted = useMemo(() => {
|
||||
if (feed.data) {
|
||||
if (__XXX) {
|
||||
return [...feed.data].filter(
|
||||
(a) => findTag(a, "content-warning") !== undefined
|
||||
);
|
||||
} else {
|
||||
return [...feed.data].filter(
|
||||
(a) => findTag(a, "content-warning") === undefined
|
||||
);
|
||||
}
|
||||
return [...feed.data];
|
||||
}
|
||||
return [];
|
||||
}, [feed.data]);
|
||||
|
||||
const live = feedSorted
|
||||
.filter((a) => findTag(a, "status") === StreamState.Live)
|
||||
.sort(sortStarts);
|
||||
const planned = feedSorted
|
||||
.filter((a) => findTag(a, "status") === StreamState.Planned)
|
||||
.sort(sortStarts);
|
||||
const ended = feedSorted
|
||||
.filter((a) => {
|
||||
const hasEnded = findTag(a, "status") === StreamState.Ended;
|
||||
const recording = findTag(a, "recording") ?? "";
|
||||
return hasEnded && recording?.length > 0;
|
||||
})
|
||||
.sort(sortCreatedAt);
|
||||
const live = feedSorted.filter(
|
||||
(a) => findTag(a, "status") === StreamState.Live
|
||||
).sort(sortStarts);
|
||||
const planned = feedSorted.filter(
|
||||
(a) => findTag(a, "status") === StreamState.Planned
|
||||
).sort(sortStarts);
|
||||
const ended = feedSorted.filter((a) => {
|
||||
const hasEnded = findTag(a, "status") === StreamState.Ended;
|
||||
const recording = findTag(a, "recording") ?? "";
|
||||
return hasEnded && recording?.length > 0;
|
||||
}).sort(sortCreatedAt);
|
||||
|
||||
return { live, planned, ended };
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import "@szhsin/react-menu/dist/index.css";
|
||||
import "./index.css";
|
||||
import "./fonts/outfit/outfit.css";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
@ -11,7 +10,7 @@ import { RootPage } from "pages/root";
|
||||
import { TagPage } from "pages/tag";
|
||||
import { LayoutPage } from "pages/layout";
|
||||
import { ProfilePage } from "pages/profile-page";
|
||||
import { StreamPageHandler } from "pages/stream-page";
|
||||
import { StreamPage } from "pages/stream-page";
|
||||
import { ChatPopout } from "pages/chat-popout";
|
||||
import { LoginStore } from "login";
|
||||
import { StreamProvidersPage } from "pages/providers";
|
||||
@ -54,7 +53,7 @@ const router = createBrowserRouter([
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
element: <StreamPageHandler />,
|
||||
element: <StreamPage />,
|
||||
},
|
||||
{
|
||||
path: "/providers/:id?",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { bytesToHex } from "@noble/curves/abstract/utils";
|
||||
import { schnorr } from "@noble/curves/secp256k1";
|
||||
import { ExternalStore, unwrap } from "@snort/shared";
|
||||
import { ExternalStore } from "@snort/shared";
|
||||
import { EventPublisher, Nip7Signer, PrivateKeySigner } from "@snort/system";
|
||||
import type { EmojiPack, Tags } from "types";
|
||||
|
||||
@ -10,7 +10,7 @@ export enum LoginType {
|
||||
}
|
||||
|
||||
interface ReplaceableTags {
|
||||
tags: Tags;
|
||||
tags: Array<string[]>;
|
||||
content?: string;
|
||||
timestamp: number;
|
||||
}
|
||||
@ -131,7 +131,7 @@ export function getPublisher(session: LoginSession) {
|
||||
}
|
||||
case LoginType.PrivateKey: {
|
||||
return new EventPublisher(
|
||||
new PrivateKeySigner(unwrap(session.privateKey)),
|
||||
new PrivateKeySigner(session.privateKey!),
|
||||
session.pubkey
|
||||
);
|
||||
}
|
||||
|
@ -2,13 +2,12 @@ import "./chat-popout.css";
|
||||
import { LiveChat } from "element/live-chat";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { NostrPrefix, encodeTLV, parseNostrLink } from "@snort/system";
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { useCurrentStreamFeed } from "hooks/current-stream-feed";
|
||||
import { findTag } from "utils";
|
||||
|
||||
export function ChatPopout() {
|
||||
const params = useParams();
|
||||
const link = parseNostrLink(unwrap(params.id));
|
||||
const link = parseNostrLink(params.id!);
|
||||
const ev = useCurrentStreamFeed(link, true);
|
||||
|
||||
const lnk = parseNostrLink(
|
||||
|
@ -10,7 +10,6 @@ import {
|
||||
encodeTLV,
|
||||
} from "@snort/system";
|
||||
import { useUserProfile } from "@snort/system-react";
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { Profile } from "element/profile";
|
||||
import { Icon } from "element/icon";
|
||||
import { SendZapsDialog } from "element/send-zap";
|
||||
@ -53,7 +52,7 @@ const defaultBanner = "https://void.cat/d/Hn1AdN5UKmceuDkgDW847q.webp";
|
||||
export function ProfilePage() {
|
||||
const navigate = useNavigate();
|
||||
const params = useParams();
|
||||
const link = parseNostrLink(unwrap(params.npub));
|
||||
const link = parseNostrLink(params.npub!);
|
||||
const placeholder = usePlaceholder(link.id);
|
||||
const profile = useUserProfile(System, link.id);
|
||||
const zapTarget = profile?.lud16 ?? profile?.lud06;
|
||||
|
@ -38,12 +38,6 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media (max-width: 1020px) {
|
||||
.divider {
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.divider:after {
|
||||
content: "";
|
||||
flex: 1;
|
||||
|
@ -32,14 +32,11 @@ export function RootPage() {
|
||||
return (
|
||||
<div className="homepage">
|
||||
{hasFollowingLive && (
|
||||
<>
|
||||
<h2 className="divider line one-line">Following</h2>
|
||||
<div className="video-grid">
|
||||
{following.map((e) => (
|
||||
<VideoTile ev={e} key={e.id} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
<div className="video-grid">
|
||||
{following.map((e) => (
|
||||
<VideoTile ev={e} key={e.id} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{!hasFollowingLive && (
|
||||
<div className="video-grid">
|
||||
|
@ -1,6 +1,5 @@
|
||||
import "./stream-page.css";
|
||||
import { NostrLink, NostrPrefix, TaggedRawEvent, tryParseNostrLink } from "@snort/system";
|
||||
import { fetchNip05Pubkey } from "@snort/shared";
|
||||
import { parseNostrLink, TaggedRawEvent } from "@snort/system";
|
||||
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
||||
import { Helmet } from "react-helmet";
|
||||
|
||||
@ -10,7 +9,6 @@ import {
|
||||
findTag,
|
||||
getEventFromLocationState,
|
||||
getHost,
|
||||
hexToBech32,
|
||||
} from "utils";
|
||||
import { Profile, getName } from "element/profile";
|
||||
import { LiveChat } from "element/live-chat";
|
||||
@ -33,7 +31,6 @@ import {
|
||||
isContentWarningAccepted,
|
||||
} from "element/content-warning";
|
||||
import { useCurrentStreamFeed } from "hooks/current-stream-feed";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function ProfileInfo({ ev, goal }: { ev?: NostrEvent; goal?: TaggedRawEvent }) {
|
||||
const login = useLogin();
|
||||
@ -113,41 +110,14 @@ function ProfileInfo({ ev, goal }: { ev?: NostrEvent; goal?: TaggedRawEvent }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function StreamPageHandler() {
|
||||
export function StreamPage() {
|
||||
const params = useParams();
|
||||
const location = useLocation();
|
||||
const evPreload = getEventFromLocationState(location.state);
|
||||
const [link, setLink] = useState<NostrLink>();
|
||||
|
||||
useEffect(() => {
|
||||
if (params.id) {
|
||||
const parsedLink = tryParseNostrLink(params.id);
|
||||
if (parsedLink) {
|
||||
setLink(parsedLink);
|
||||
} else {
|
||||
const [handle, domain] = (params.id.includes("@") ? params.id : `${params.id}@zap.stream`).split("@");
|
||||
fetchNip05Pubkey(handle, domain).then(d => {
|
||||
if (d) {
|
||||
setLink({
|
||||
id: d,
|
||||
type: NostrPrefix.PublicKey,
|
||||
encode: () => hexToBech32(NostrPrefix.PublicKey, d)
|
||||
} as NostrLink);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [params.id]);
|
||||
|
||||
if (link) {
|
||||
return <StreamPage link={link} evPreload={evPreload} />
|
||||
}
|
||||
}
|
||||
|
||||
export function StreamPage({ link, evPreload }: { evPreload?: NostrEvent, link: NostrLink }) {
|
||||
const link = parseNostrLink(params.id!);
|
||||
const ev = useCurrentStreamFeed(link, true, evPreload);
|
||||
const host = getHost(ev);
|
||||
const goal = useZapGoal(host, createNostrLink(ev), true);
|
||||
const goal = useZapGoal(host, link, true);
|
||||
|
||||
const title = findTag(ev, "title");
|
||||
const summary = findTag(ev, "summary");
|
||||
|
@ -1,6 +1,5 @@
|
||||
import "./tag.css";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { unwrap } from "@snort/shared";
|
||||
|
||||
import { VideoTile } from "element/video-tile";
|
||||
import { FollowTagButton } from "element/follow-button";
|
||||
@ -13,7 +12,7 @@ export function TagPage() {
|
||||
<div className="tag-page">
|
||||
<div className="tag-page-header">
|
||||
<h1>#{tag}</h1>
|
||||
<FollowTagButton tag={unwrap(tag)} />
|
||||
<FollowTagButton tag={tag!} />
|
||||
</div>
|
||||
<div className="video-grid">
|
||||
{live.map((e) => (
|
||||
|
@ -58,7 +58,7 @@ export class OwncastProvider implements StreamProvider {
|
||||
body?: unknown
|
||||
): Promise<T> {
|
||||
const rsp = await fetch(`${this.#url}${path}`, {
|
||||
method,
|
||||
method: method,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
|
@ -103,7 +103,7 @@ export class Nip103StreamProvider implements StreamProvider {
|
||||
.tag(["method", method]);
|
||||
});
|
||||
const rsp = await fetch(u, {
|
||||
method,
|
||||
method: method,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
|
@ -109,7 +109,7 @@ export function getHost(ev?: NostrEvent) {
|
||||
);
|
||||
}
|
||||
|
||||
export function openFile(): Promise<File | undefined> {
|
||||
export async function openFile(): Promise<File | undefined> {
|
||||
return new Promise((resolve) => {
|
||||
const elm = document.createElement("input");
|
||||
elm.type = "file";
|
||||
|
@ -503,7 +503,7 @@ export class WISH extends TypedEventTarget {
|
||||
},
|
||||
});
|
||||
const body = await resp.text();
|
||||
if (resp.status !== 201) {
|
||||
if (resp.status != 201) {
|
||||
throw new Error(`Unexpected status code ${resp.status}: ${body}`);
|
||||
}
|
||||
|
||||
@ -611,7 +611,7 @@ export class WISH extends TypedEventTarget {
|
||||
throw new Error(`Unexpected status code ${resp.status}: ${body}`);
|
||||
}
|
||||
|
||||
WithEndpoint(endpoint: string, trickle: boolean) {
|
||||
async WithEndpoint(endpoint: string, trickle: boolean) {
|
||||
if (endpoint === "") {
|
||||
throw new Error("Endpoint cannot be empty");
|
||||
}
|
||||
@ -637,7 +637,7 @@ export class WISH extends TypedEventTarget {
|
||||
method: "DELETE",
|
||||
mode: "cors",
|
||||
});
|
||||
if (resp.status !== 200) {
|
||||
if (resp.status != 200) {
|
||||
const body = await resp.text();
|
||||
throw new Error(`Unexpected status code ${resp.status}: ${body}`);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ const config = {
|
||||
new ESLintPlugin({
|
||||
extensions: ["js", "mjs", "jsx", "ts", "tsx"],
|
||||
eslintPath: require.resolve("eslint"),
|
||||
failOnError: !isProduction,
|
||||
failOnError: true,
|
||||
cache: true,
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
@ -65,11 +65,7 @@ const config = {
|
||||
new webpack.IgnorePlugin({
|
||||
resourceRegExp: /^\.\/locale$/,
|
||||
contextRegExp: /moment$/,
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
__XXX: process.env["__XXX"] || JSON.stringify(false),
|
||||
__XXX_HOST: JSON.stringify("https://xxzap.com"),
|
||||
}),
|
||||
})
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
@ -89,12 +85,9 @@ const config = {
|
||||
babelrc: false,
|
||||
configFile: false,
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: "defaults",
|
||||
},
|
||||
],
|
||||
["@babel/preset-env", {
|
||||
targets: "defaults"
|
||||
}],
|
||||
["@babel/preset-react", { runtime: "automatic" }],
|
||||
"@babel/preset-typescript",
|
||||
],
|
||||
@ -109,7 +102,7 @@ const config = {
|
||||
],
|
||||
},
|
||||
},
|
||||
require.resolve("ts-loader"),
|
||||
require.resolve("ts-loader")
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -151,7 +144,7 @@ const config = {
|
||||
aliasFields: ["browser"],
|
||||
extensions: ["...", ".tsx", ".ts", ".jsx", ".js"],
|
||||
modules: ["...", __dirname, path.resolve(__dirname, "src")],
|
||||
fallback: { crypto: false },
|
||||
fallback: { "crypto": false }
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user