forked from Kieran/zap.stream
Compare commits
1 Commits
main
...
type-error
Author | SHA1 | Date | |
---|---|---|---|
52b3c12a46 |
@ -22,4 +22,4 @@ steps:
|
||||
volumes:
|
||||
- name: cache
|
||||
claim:
|
||||
name: docker-cache
|
||||
name: docker-cache
|
@ -1,19 +1,20 @@
|
||||
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,
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-non-null-assertion": "error",
|
||||
"require-await": "error",
|
||||
"eqeqeq": "error",
|
||||
"object-shorthand": "warn",
|
||||
}
|
||||
};
|
||||
|
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';
|
@ -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" }
|
||||
]
|
@ -120,7 +120,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) as string, e.at(2) as string]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -194,7 +194,10 @@ 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) as string}
|
||||
url={emoji.at(2) as string}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<span className="message-reaction">{e}</span>
|
||||
|
@ -12,7 +12,9 @@ export function LoggedInFollowButton({
|
||||
value: string;
|
||||
}) {
|
||||
const login = useLogin();
|
||||
if (!login) return;
|
||||
if (!login) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { tags, content, timestamp } = login.follows;
|
||||
const follows = tags.filter((t) => t.at(0) === tag);
|
||||
|
@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
.live-chat > .write-message > div:nth-child(1) {
|
||||
height: 40px;
|
||||
height: 32px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@ -325,6 +325,8 @@
|
||||
text-transform: lowercase;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-family: Outfit;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
parseZap,
|
||||
encodeTLV,
|
||||
} from "@snort/system";
|
||||
import { unixNow, unwrap } from "@snort/shared";
|
||||
import { unixNow } from "@snort/shared";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import uniqBy from "lodash.uniqby";
|
||||
|
||||
@ -96,7 +96,7 @@ export function LiveChat({
|
||||
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);
|
||||
|
@ -9,7 +9,6 @@ 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";
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
@ -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) as string).endsWith(`:${d}`));
|
||||
}
|
||||
|
||||
const [dropStyle, dropRef] = useDrop(
|
||||
@ -293,7 +293,9 @@ 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) as string).endsWith(`:${identifier}`)
|
||||
);
|
||||
const userCardsEv = await pub.generic((eb) => {
|
||||
eb.kind(USER_CARDS).content("");
|
||||
for (const tag of newTags) {
|
||||
|
@ -50,10 +50,10 @@ interface TextareaProps {
|
||||
}
|
||||
|
||||
export function Textarea({ emojis, ...props }: TextareaProps) {
|
||||
const userDataProvider = async (token: string) => {
|
||||
const userDataProvider = (token: string) => {
|
||||
const cache = System.ProfileLoader.Cache;
|
||||
if (cache instanceof UserProfileCache) {
|
||||
return await cache.search(token);
|
||||
return cache.search(token);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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.
@ -11,6 +11,7 @@ import { useRequestBuilder } from "@snort/system-react";
|
||||
import { USER_CARDS, CARD } from "const";
|
||||
import { findTag } from "utils";
|
||||
import { System } from "index";
|
||||
import { getAddresses } from "utils";
|
||||
|
||||
export function useUserCards(
|
||||
pubkey: string,
|
||||
@ -29,16 +30,7 @@ export function useUserCards(
|
||||
|
||||
const subRelated = useMemo(() => {
|
||||
if (!pubkey) return null;
|
||||
const splitted = related.map((t) => t[1].split(":"));
|
||||
const authors = splitted
|
||||
.map((s) => s.at(1))
|
||||
.filter((s) => s)
|
||||
.map((s) => s as string);
|
||||
const identifiers = splitted
|
||||
.map((s) => s.at(2))
|
||||
.filter((s) => s)
|
||||
.map((s) => s as string);
|
||||
|
||||
const { authors, identifiers } = getAddresses(related);
|
||||
const rb = new RequestBuilder(`cards:${pubkey}`);
|
||||
rb.withOptions({ leaveOpen })
|
||||
.withFilter()
|
||||
@ -58,7 +50,8 @@ export function useUserCards(
|
||||
const cards = useMemo(() => {
|
||||
return related
|
||||
.map((t) => {
|
||||
const [k, pubkey, identifier] = t[1].split(":");
|
||||
const ref = t.at(1) as string;
|
||||
const [k, pubkey, identifier] = ref.split(":");
|
||||
const kind = Number(k);
|
||||
return (data ?? []).find(
|
||||
(e) =>
|
||||
@ -104,15 +97,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 authors = splitted
|
||||
.map((s) => s.at(1))
|
||||
.filter((s) => s)
|
||||
.map((s) => s as string);
|
||||
const identifiers = splitted
|
||||
.map((s) => s.at(2))
|
||||
.filter((s) => s)
|
||||
.map((s) => s as string);
|
||||
const { authors, identifiers } = getAddresses(related);
|
||||
|
||||
const rb = new RequestBuilder(`cards:${pubkey}`);
|
||||
rb.withOptions({ leaveOpen })
|
||||
@ -134,7 +119,8 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
|
||||
const cards = useMemo(() => {
|
||||
return related
|
||||
.map((t) => {
|
||||
const [k, pubkey, identifier] = t[1].split(":");
|
||||
const ref = t.at(1) as string;
|
||||
const [k, pubkey, identifier] = ref.split(":");
|
||||
const kind = Number(k);
|
||||
return cardEvents.find(
|
||||
(e) =>
|
||||
|
@ -45,7 +45,11 @@ 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))
|
||||
.filter((t) => t)
|
||||
.map((t) => t as string)
|
||||
.map((t) => t.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 as string}:${link.id}`]);
|
||||
return b;
|
||||
}, [link, leaveOpen]);
|
||||
|
||||
|
@ -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";
|
||||
|
||||
@ -131,7 +131,7 @@ export function getPublisher(session: LoginSession) {
|
||||
}
|
||||
case LoginType.PrivateKey: {
|
||||
return new EventPublisher(
|
||||
new PrivateKeySigner(unwrap(session.privateKey)),
|
||||
new PrivateKeySigner(session.privateKey as string),
|
||||
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 as string);
|
||||
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 as string);
|
||||
const placeholder = usePlaceholder(link.id);
|
||||
const profile = useUserProfile(System, link.id);
|
||||
const zapTarget = profile?.lud16 ?? profile?.lud06;
|
||||
|
@ -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 as string);
|
||||
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 { useParams, Navigate } from "react-router-dom";
|
||||
|
||||
import { VideoTile } from "element/video-tile";
|
||||
import { FollowTagButton } from "element/follow-button";
|
||||
@ -9,17 +8,22 @@ import { useStreamsFeed } from "hooks/live-streams";
|
||||
export function TagPage() {
|
||||
const { tag } = useParams();
|
||||
const { live } = useStreamsFeed(tag);
|
||||
return (
|
||||
<div className="tag-page">
|
||||
<div className="tag-page-header">
|
||||
<h1>#{tag}</h1>
|
||||
<FollowTagButton tag={unwrap(tag)} />
|
||||
|
||||
if (typeof tag === "string") {
|
||||
return (
|
||||
<div className="tag-page">
|
||||
<div className="tag-page-header">
|
||||
<h1>#{tag}</h1>
|
||||
<FollowTagButton tag={tag as string} />
|
||||
</div>
|
||||
<div className="video-grid">
|
||||
{live.map((e) => (
|
||||
<VideoTile ev={e} key={e.id} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="video-grid">
|
||||
{live.map((e) => (
|
||||
<VideoTile ev={e} key={e.id} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
return <Navigate to="/" replace={true} />;
|
||||
}
|
||||
|
17
src/utils.ts
17
src/utils.ts
@ -141,3 +141,20 @@ export function getEventFromLocationState(state: unknown | undefined | null) {
|
||||
? (state as NostrEvent)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function getAddresses(tags: Tags) {
|
||||
const splitted = tags
|
||||
.map((t) => t.at(1))
|
||||
.filter((t) => t)
|
||||
.map((t) => t as string)
|
||||
.map((t) => t.split(":"));
|
||||
const authors = splitted
|
||||
.map((s) => s.at(1))
|
||||
.filter((s) => s)
|
||||
.map((s) => s as string);
|
||||
const identifiers = splitted
|
||||
.map((s) => s.at(2))
|
||||
.filter((s) => s)
|
||||
.map((s) => s as string);
|
||||
return { authors, identifiers };
|
||||
}
|
||||
|
@ -68,8 +68,8 @@ const config = {
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
__XXX: process.env["__XXX"] || JSON.stringify(false),
|
||||
__XXX_HOST: JSON.stringify("https://xxzap.com"),
|
||||
}),
|
||||
__XXX_HOST: JSON.stringify("https://xxzap.com")
|
||||
})
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
@ -89,12 +89,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 +106,7 @@ const config = {
|
||||
],
|
||||
},
|
||||
},
|
||||
require.resolve("ts-loader"),
|
||||
require.resolve("ts-loader")
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -151,7 +148,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