Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b286ef2a74 | ||
|
|
121937bcbe | ||
|
|
1274bd98df | ||
|
|
1942ffbdcd | ||
|
|
fdff541a2a | ||
|
|
b8a1c5386f | ||
|
|
3c71b8c8f8 | ||
|
|
27ba1bd931 | ||
|
|
2fad1225b0 | ||
|
|
3c968a2bb2 | ||
|
|
e30555c865 | ||
|
|
322df8d47e | ||
|
|
2c56ff2584 | ||
|
|
6d7254f2d2 | ||
|
|
4953fe79fe | ||
|
|
b15925815e | ||
|
|
51d61895a4 | ||
|
|
7f611bd199 | ||
|
|
1b05730c3d | ||
|
|
bf143681ff | ||
|
|
e9979fdad2 | ||
|
|
f1fa827d42 | ||
|
|
b7be3d762b | ||
|
|
7f21132f0c |
@@ -5,7 +5,7 @@
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"baseBranch": "origin/main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
**/dist
|
||||
**/node_modules
|
||||
**/protos
|
||||
**/proto
|
||||
**/coverage
|
||||
**/storybook-static
|
||||
@@ -20,27 +20,37 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
# https://github.com/changesets/changesets/issues/1055
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9.12.3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: 'yarn'
|
||||
node-version: 20.18.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Changeset
|
||||
# https://github.com/changesets/changesets/issues/1048
|
||||
run: pnpm dlx @changesets/cli status --since origin/main
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --frozen-lockfile
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: yarn build
|
||||
run: pnpm build
|
||||
|
||||
- name: Typecheck
|
||||
run: yarn typecheck
|
||||
run: pnpm typecheck
|
||||
|
||||
- name: Lint
|
||||
run: yarn lint && yarn format --check
|
||||
run: pnpm lint && pnpm format --check
|
||||
|
||||
- name: Test
|
||||
run: yarn test
|
||||
run: pnpm test
|
||||
|
||||
@@ -20,19 +20,22 @@ jobs:
|
||||
needs: ci
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
node-version: 18
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn build
|
||||
version: 9.12.3
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.18.0
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm build
|
||||
- uses: changesets/action@v1
|
||||
id: changesets
|
||||
with:
|
||||
title: Release
|
||||
commit: Release
|
||||
version: yarn changeset version
|
||||
publish: yarn changeset publish
|
||||
version: pnpm changeset version
|
||||
publish: pnpm changeset publish
|
||||
createGithubReleases: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
pnpm lint-staged
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
20.18.0
|
||||
@@ -0,0 +1,2 @@
|
||||
!.npmrc
|
||||
#!pnpm-lock.yaml
|
||||
@@ -0,0 +1,11 @@
|
||||
; https://pnpm.io/cli/run#enable-pre-post-scripts
|
||||
enable-pre-post-scripts=true
|
||||
; https://pnpm.io/npmrc#node-linker
|
||||
; node-linker=hoisted
|
||||
; https://pnpm.io/npmrc#shamefully-hoist
|
||||
;shamefully-hoist=true
|
||||
;auto-install-peers=true
|
||||
; https://pnpm.io/npmrc#node-version
|
||||
node-version=20.18.0
|
||||
; https://pnpm.io/npmrc#engine-strict
|
||||
engine-strict=true
|
||||
@@ -0,0 +1 @@
|
||||
pnpm-lock.yaml
|
||||
@@ -1,7 +1,13 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"npm.packageManager": "yarn",
|
||||
"npm.packageManager": "pnpm",
|
||||
"eslint.useESLintClass": true,
|
||||
"eslint.workingDirectories": [
|
||||
"./packages/colors",
|
||||
"./packages/icons",
|
||||
"./packages/components",
|
||||
"./packages/status-js",
|
||||
"./apps/connector",
|
||||
{
|
||||
"mode": "auto",
|
||||
"#comment": "See https://github.com/microsoft/vscode-eslint/issues/1161 for reason (i.e. multiple .eslintrc config files)"
|
||||
|
||||
@@ -6,13 +6,13 @@ This monorepo contains packages for building web applications in the Status ecos
|
||||
|
||||
## Packages
|
||||
|
||||
| Name | `npm` | Description |
|
||||
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`@status-im/components`](./packages/components) | [](https://www.npmjs.com/package/@status-im/components) | Component library built with Radix UI, React Aria, Tailwind CSS. |
|
||||
| [`@status-im/js`](./packages/status-js) | [](https://www.npmjs.com/package/@status-im/js) | Libary for Waku protocol integration and blockchain interactions. |
|
||||
| [`@status-im/icons`](./packages/icons) | [](https://www.npmjs.com/package/@status-im/icons) | Auto-generated icon library based on our [design system](https://www.figma.com/design/qLLuMLfpGxK9OfpIavwsmK/Iconset?node-id=3239-987&node-type=frame&t=0h8iIiZ3Sf0g4MRV-11). |
|
||||
| [`@status-im/colors`](./packages/colors) | [](https://www.npmjs.com/package/@status-im/colors) | Auto-generated color palette based on our [design system](https://www.figma.com/design/v98g9ZiaSHYUdKWrbFg9eM/Foundations?node-id=619-5995&node-type=canvas&m=dev). |
|
||||
| [`@status-im/eslint-config`](./packages/eslint-config) | | Shared ESLint configuration for consistent code style across projects. |
|
||||
| Name | `npm` | Description |
|
||||
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`@status-im/components`](./packages/components) | [](https://www.npmjs.com/package/@status-im/components) | Component library built with Radix UI, React Aria, Tailwind CSS. |
|
||||
| [`@status-im/js`](./packages/status-js) | [](https://www.npmjs.com/package/@status-im/js) | Libary for Waku protocol integration and blockchain interactions. |
|
||||
| [`@status-im/icons`](./packages/icons) | [](https://www.npmjs.com/package/@status-im/icons) | Auto-generated icon library based on our [design system](https://www.figma.com/design/qLLuMLfpGxK9OfpIavwsmK/Iconset?node-id=3239-987&node-type=frame&t=0h8iIiZ3Sf0g4MRV-11). |
|
||||
| [`@status-im/colors`](./packages/colors) | [](https://www.npmjs.com/package/@status-im/colors) | Auto-generated color palette based on our [design system](https://www.figma.com/design/v98g9ZiaSHYUdKWrbFg9eM/Foundations?node-id=619-5995&node-type=canvas&m=dev). |
|
||||
| [`@status-im/eslint-config`](./packages/eslint-config) | [](https://www.npmjs.com/package/@status-im/eslint-config) | Shared ESLint configuration for consistent code style across projects. |
|
||||
|
||||
## Apps
|
||||
|
||||
@@ -24,8 +24,8 @@ This monorepo contains packages for building web applications in the Status ecos
|
||||
|
||||
Required:
|
||||
|
||||
- **[Node.js](https://nodejs.org/)** v18.x
|
||||
- **[Yarn](https://yarnpkg.com/)** v1.22.x
|
||||
- **[Node.js](https://nodejs.org/)** v20.x
|
||||
- **[pnpm](https://pnpm.io)** v9.12.x
|
||||
|
||||
Recommended:
|
||||
|
||||
@@ -57,24 +57,24 @@ Recommended:
|
||||
2. Install dependencies:
|
||||
|
||||
```
|
||||
yarn install
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Build all packages:
|
||||
|
||||
```
|
||||
yarn build
|
||||
pnpm build
|
||||
```
|
||||
|
||||
4. Run tests:
|
||||
|
||||
```
|
||||
yarn test
|
||||
pnpm test
|
||||
```
|
||||
|
||||
5. Start development mode:
|
||||
```
|
||||
yarn dev
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## Storybook
|
||||
@@ -82,7 +82,7 @@ Recommended:
|
||||
To view and interact with the components, you can run Storybook:
|
||||
|
||||
```
|
||||
yarn storybook
|
||||
pnpm storybook
|
||||
```
|
||||
|
||||
This will start the Storybook server, allowing you to browse and test components in isolation.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
extends: ['@status-im/eslint-config', 'plugin:tailwindcss/recommended'],
|
||||
|
||||
rules: {
|
||||
'no-constant-binary-expression': 'error',
|
||||
'no-restricted-globals': ['error', 'process'],
|
||||
'jsx-a11y/alt-text': [
|
||||
1,
|
||||
{
|
||||
img: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
// parser: 'esprima',
|
||||
files: ['*.mjs'],
|
||||
// env: {
|
||||
// browser: true,
|
||||
// es2021: true,
|
||||
// },
|
||||
// extends: ['eslint:recommended', 'plugin:import/recommended'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.js'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# connector
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c71b8c: update ESLint
|
||||
- Updated dependencies [3c71b8c]
|
||||
- @status-im/colors@1.0.2
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.11'
|
||||
|
||||
def changesDetected = false
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -27,12 +29,26 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Check Changed Files') {
|
||||
when {
|
||||
changeset pattern: "apps/connector/**", comparator: "GLOB"
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
changesDetected = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Install') {
|
||||
when {
|
||||
expression { changesDetected }
|
||||
}
|
||||
steps {
|
||||
dir("${env.WORKSPACE}/apps/connector") {
|
||||
script {
|
||||
nix.shell(
|
||||
'yarn install --frozen-lockfile',
|
||||
'pnpm install --frozen-lockfile',
|
||||
pure: false,
|
||||
entryPoint: "${env.WORKSPACE}/apps/connector/shell.nix"
|
||||
)
|
||||
@@ -42,11 +58,14 @@ pipeline {
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
when {
|
||||
expression { changesDetected }
|
||||
}
|
||||
steps {
|
||||
dir("${env.WORKSPACE}/apps/connector") {
|
||||
dir("${env.WORKSPACE}") {
|
||||
script {
|
||||
nix.shell(
|
||||
'yarn build:chrome',
|
||||
'pnpm turbo run build --filter=connector',
|
||||
pure: false,
|
||||
entryPoint: "${env.WORKSPACE}/apps/connector/shell.nix"
|
||||
)
|
||||
@@ -56,6 +75,9 @@ pipeline {
|
||||
}
|
||||
|
||||
stage('Zip') {
|
||||
when {
|
||||
expression { changesDetected }
|
||||
}
|
||||
steps {
|
||||
dir("${env.WORKSPACE}/apps/connector") {
|
||||
zip(
|
||||
@@ -68,6 +90,9 @@ pipeline {
|
||||
}
|
||||
|
||||
stage('Archive') {
|
||||
when {
|
||||
expression { changesDetected }
|
||||
}
|
||||
steps {
|
||||
dir("${env.WORKSPACE}/apps/connector") {
|
||||
archiveArtifacts(
|
||||
@@ -79,6 +104,9 @@ pipeline {
|
||||
}
|
||||
|
||||
stage('Upload') {
|
||||
when {
|
||||
expression { changesDetected }
|
||||
}
|
||||
steps {
|
||||
dir("${env.WORKSPACE}/apps/connector") {
|
||||
script {
|
||||
@@ -90,8 +118,20 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
success { script { github.notifyPR(true) } }
|
||||
failure { script { github.notifyPR(false) } }
|
||||
success {
|
||||
script {
|
||||
if(changesDetected) {
|
||||
github.notifyPR(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
failure {
|
||||
script {
|
||||
if(changesDetected) {
|
||||
github.notifyPR(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup { cleanWs() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ Status Desktop Wallet extended to decentralized applications in your browser.
|
||||
|
||||
Depends on:
|
||||
|
||||
- Status Desktop https://github.com/status-im/status-desktop/tree/release/2.30.x
|
||||
- **[Status Desktop](https://github.com/status-im/status-desktop/releases)** >=2.32.x
|
||||
|
||||
Tested with these browsers:
|
||||
|
||||
@@ -20,13 +20,13 @@ Tested with these browsers:
|
||||
#### Develop
|
||||
|
||||
```bash
|
||||
yarn dev:chrome
|
||||
pnpm dev:chrome
|
||||
```
|
||||
|
||||
#### Build
|
||||
|
||||
```bash
|
||||
yarn build:chrome
|
||||
pnpm build:chrome
|
||||
```
|
||||
|
||||
#### Load
|
||||
@@ -42,7 +42,7 @@ Google Chrome > Window > Extensions > Load unpacked > select build (build/chrome
|
||||
#### Develop
|
||||
|
||||
```bash
|
||||
yarn dev:safari
|
||||
pnpm dev:safari
|
||||
```
|
||||
|
||||
#### Convert
|
||||
@@ -70,13 +70,13 @@ Safari > Settings... > Extensions > check Status
|
||||
#### Develop
|
||||
|
||||
```bash
|
||||
yarn dev:firefox
|
||||
pnpm dev:firefox
|
||||
```
|
||||
|
||||
#### Build
|
||||
|
||||
```bash
|
||||
yarn build:firefox
|
||||
pnpm build:firefox
|
||||
```
|
||||
|
||||
#### Load
|
||||
@@ -87,6 +87,18 @@ Firefox Developer Edition > Tools > Add-ons and Themes > click on gear icon (Too
|
||||
|
||||
> Note: Does not reload automatically, requires build and load on change.
|
||||
|
||||
### Status Desktop
|
||||
|
||||
#### Run
|
||||
|
||||
##### macOS
|
||||
|
||||
```bash
|
||||
FLAG_CONNECTOR_ENABLED=1 '/Volumes/Status Desktop/Status.app/Contents/MacOS/nim_status_client'
|
||||
```
|
||||
|
||||
> Tip: Point to the installer package location without dropping and replacing current app.
|
||||
|
||||
## Testing
|
||||
|
||||
Download latest build from last merged PR or build from source. To use the extension see the load steps from [Development](#development) section.
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import configs, { tailwindcssConfigs } from '@status-im/eslint-config'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
...configs,
|
||||
...tailwindcssConfigs,
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
rules: {
|
||||
'no-constant-binary-expression': 'error',
|
||||
'no-restricted-globals': ['error', 'process'],
|
||||
'jsx-a11y/alt-text': [
|
||||
1,
|
||||
{
|
||||
img: [],
|
||||
},
|
||||
],
|
||||
'no-empty': 'warn',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.mjs'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.js'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: ['.plasmo'],
|
||||
},
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "connector",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"license": "MPL-2.0",
|
||||
"private": true,
|
||||
"repository": {
|
||||
@@ -9,12 +9,14 @@
|
||||
"directory": "apps/connector"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev:chrome": "plasmo dev --target=chrome-mv3",
|
||||
"dev:safari": "plasmo dev --target=safari-mv3",
|
||||
"dev:firefox": "plasmo dev --target=firefox-mv3",
|
||||
"build": "pnpm build:chrome",
|
||||
"build:chrome": "plasmo build --target=chrome-mv3",
|
||||
"build:firefox": "plasmo build --target=firefox-mv3 --zip",
|
||||
"lint": "eslint ./src",
|
||||
"lint": "eslint src",
|
||||
"format": "prettier --write .",
|
||||
"package": "plasmo package",
|
||||
"clean": "rimraf apps build .plasmo node_modules"
|
||||
@@ -24,7 +26,7 @@
|
||||
"@plasmohq/storage": "^1.11.0",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-switch": "^1.1.0",
|
||||
"@status-im/colors": "^0.4.0",
|
||||
"@status-im/colors": "workspace:*",
|
||||
"cva": "^1.0.0-beta.1",
|
||||
"ethers": "^6.13.0",
|
||||
"plasmo": "0.88.0",
|
||||
@@ -36,7 +38,7 @@
|
||||
"devDependencies": {
|
||||
"@ianvs/prettier-plugin-sort-imports": "4.1.1",
|
||||
"@parcel/bundler-experimental": "^2.7.0",
|
||||
"@status-im/eslint-config": "^0.3.0",
|
||||
"@status-im/eslint-config": "workspace:*",
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"@types/chrome": "0.0.258",
|
||||
"@types/node": "20.11.5",
|
||||
@@ -44,7 +46,6 @@
|
||||
"@types/react-dom": "18.2.18",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.2.0",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "3.2.4",
|
||||
"prettier-plugin-tailwindcss": "^0.6.1",
|
||||
@@ -57,11 +58,14 @@
|
||||
},
|
||||
"manifest": {
|
||||
"manifest_version": 3,
|
||||
"name": "A wallet connector by Status BETA",
|
||||
"description": "THIS EXTENSION IS FOR BETA TESTING. Status Desktop Wallet extended to decentralised applications in your browser.",
|
||||
"name": "A wallet connector by Status",
|
||||
"description": "Status Desktop Wallet extended to decentralised applications in your browser.",
|
||||
"externally_connectable": {
|
||||
"ids": [],
|
||||
"matches": []
|
||||
},
|
||||
"host_permissions": [
|
||||
"https://*/*",
|
||||
"https://chromewebstore.google.com/*"
|
||||
"https://*/*"
|
||||
],
|
||||
"permissions": [
|
||||
"storage"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
source ? builtins.fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/614b4613980a522ba49f0d194531beddbb7220d3.tar.gz";
|
||||
sha256 = "sha256:1kipdjdjcd1brm5a9lzlhffrgyid0byaqwfnpzlmw3q825z7nj6w";
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/df27247e6f3e636c119e2610bf12d38b5e98cc79.tar.gz";
|
||||
sha256 = "sha256:0bbvimk7xb7akrx106mmsiwf9nzxnssisqmqffla03zz51d0kz2n";
|
||||
},
|
||||
pkgs ? import (source) {}
|
||||
}:
|
||||
@@ -11,6 +11,6 @@ pkgs.mkShell {
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_20
|
||||
yarn
|
||||
pnpm
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ const styles = cva({
|
||||
base: 'flex h-6 items-center gap-1 rounded-[20px] border px-2 text-13',
|
||||
variants: {
|
||||
status: {
|
||||
on: 'border-success-/20 bg-success-/10 text-success-60',
|
||||
off: 'border-danger-/20 bg-danger-/10 text-danger-60',
|
||||
on: 'border-success-50/20 bg-success-50/10 text-success-60',
|
||||
off: 'border-danger-50/20 bg-danger-50/10 text-danger-60',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -96,15 +96,11 @@ export class Provider {
|
||||
this.#listeners.get('connect')?.({ chainId: '0x1' })
|
||||
this.#listeners.get('connected')?.({ chainId: '0x1' })
|
||||
this.connected = true
|
||||
|
||||
console.log('connected::')
|
||||
}
|
||||
|
||||
if (method === 'wallet_switchEthereumChain') {
|
||||
this.#listeners.get('chainChanged')?.(message.data)
|
||||
this.#listeners.get('networkChanged')?.(message.data)
|
||||
|
||||
console.log('chainChanged::')
|
||||
}
|
||||
|
||||
resolve(message.data)
|
||||
@@ -112,8 +108,6 @@ export class Provider {
|
||||
return
|
||||
}
|
||||
case 'status:proxy:error': {
|
||||
console.error(message.error)
|
||||
|
||||
// note: for those dApps that make call after having permissions revoked
|
||||
if (
|
||||
message.error.message === 'dApp is not permitted by user' &&
|
||||
@@ -127,7 +121,7 @@ export class Provider {
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// we don't reject here because incoming message is not from the proxy
|
||||
return
|
||||
}
|
||||
@@ -154,21 +148,15 @@ export class Provider {
|
||||
}
|
||||
|
||||
public on(event: Event, handler: (args: unknown) => void): void {
|
||||
console.log('on::', event, handler)
|
||||
|
||||
this.#listeners.set(event, handler)
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
public async close(...args: unknown[]): Promise<void> {
|
||||
console.log('close::', args)
|
||||
|
||||
public async close(): Promise<void> {
|
||||
this.disconnect()
|
||||
}
|
||||
|
||||
public removeListener(event: Event, handler: (args: unknown) => void): void {
|
||||
console.log('removeListener::', event, handler)
|
||||
|
||||
public removeListener(event: Event): void {
|
||||
// note: not all dapps remove these on disconnect
|
||||
if (event === 'close' || event === 'disconnect') {
|
||||
this.disconnect()
|
||||
@@ -177,6 +165,10 @@ export class Provider {
|
||||
this.#listeners.delete(event)
|
||||
}
|
||||
|
||||
public async enable() {
|
||||
return true
|
||||
}
|
||||
|
||||
private async disconnect() {
|
||||
if (!this.connected) {
|
||||
return
|
||||
@@ -184,8 +176,6 @@ export class Provider {
|
||||
|
||||
this.connected = false
|
||||
|
||||
console.log('disconnect::')
|
||||
|
||||
await this.request({
|
||||
method: 'wallet_revokePermissions',
|
||||
params: [
|
||||
|
||||
@@ -39,8 +39,6 @@ const handleMessage = async (event: MessageEvent) => {
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('request::', message.data)
|
||||
|
||||
const response = await desktopClient.send({
|
||||
...message.data,
|
||||
name: window.location.hostname,
|
||||
@@ -48,8 +46,6 @@ const handleMessage = async (event: MessageEvent) => {
|
||||
iconUrl: getFaviconUrl() ?? '',
|
||||
})
|
||||
|
||||
console.log('response::', response)
|
||||
|
||||
event.ports[0].postMessage({
|
||||
type: 'status:proxy:success',
|
||||
data: response,
|
||||
|
||||
@@ -10,8 +10,7 @@ export function useLocalStorage<T>(
|
||||
try {
|
||||
const item = window.localStorage.getItem(key)
|
||||
setStoredValue(item ? JSON.parse(item) : initialValue)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
} catch {
|
||||
setStoredValue(initialValue)
|
||||
}
|
||||
}, [])
|
||||
@@ -40,9 +39,7 @@ export function useLocalStorage<T>(
|
||||
setStoredValue(valueToStore)
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore))
|
||||
window.dispatchEvent(new Event('storage'))
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return [storedValue, setValue]
|
||||
|
||||
@@ -19,7 +19,6 @@ export class DesktopClient {
|
||||
return
|
||||
}
|
||||
|
||||
console.log('stop::')
|
||||
this.#rpcClient?.destroy()
|
||||
this.#rpcClient = null
|
||||
|
||||
@@ -28,7 +27,6 @@ export class DesktopClient {
|
||||
|
||||
public async send(args: DesktopRequestArguments) {
|
||||
if (!this.#rpcClient) {
|
||||
console.log('start::')
|
||||
this.#rpcClient = new WebSocketProvider(
|
||||
config.desktop.rpc.url,
|
||||
'mainnet',
|
||||
@@ -43,11 +41,6 @@ export class DesktopClient {
|
||||
|
||||
await waitUntilOpen(this.#rpcClient.websocket)
|
||||
|
||||
console.log('client::', {
|
||||
method: config.desktop.rpc.method,
|
||||
params: [JSON.stringify(args)],
|
||||
})
|
||||
|
||||
return await this.#rpcClient.send(config.desktop.rpc.method, [
|
||||
JSON.stringify(args),
|
||||
])
|
||||
@@ -78,10 +71,6 @@ async function waitUntilOpen(websocket: WebSocketLike) {
|
||||
reject(new Error('Timed out to connect to the RPC server'))
|
||||
}, 30 * 1000)
|
||||
|
||||
if (websocket.readyState === WebSocket.CONNECTING) {
|
||||
console.info('Waiting for the RPC server to connect')
|
||||
}
|
||||
|
||||
const onopen = websocket.onopen?.bind(websocket)
|
||||
websocket.onopen = event => {
|
||||
onopen?.(event)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
{
|
||||
ignores: [
|
||||
'**/dist',
|
||||
'**/node_modules',
|
||||
'**/protos',
|
||||
'**/proto',
|
||||
'**/coverage',
|
||||
'**/storybook-static',
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -7,21 +7,22 @@
|
||||
"packages/status-js",
|
||||
"packages/colors",
|
||||
"packages/icons",
|
||||
"packages/components"
|
||||
"packages/components",
|
||||
"apps/connector"
|
||||
]
|
||||
},
|
||||
"keywords": [],
|
||||
"scripts": {
|
||||
"postinstall": "patch-package",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"prepare": "husky install",
|
||||
"test": "turbo run test --filter=@status-im/* -- --run",
|
||||
"dev": "turbo run dev --filter=@status-im/* --parallel",
|
||||
"build": "turbo run build --filter=@status-im/*",
|
||||
"lint": "turbo run lint --filter=@status-im/* --filter=web",
|
||||
"build": "turbo run build --filter=@status-im/* --filter=connector",
|
||||
"lint": "turbo run lint --filter=@status-im/* --filter=connector",
|
||||
"typecheck": "turbo run typecheck",
|
||||
"format": "prettier --ignore-path .gitignore --write .",
|
||||
"format": "prettier --write .",
|
||||
"clean": "turbo run clean && rimraf node_modules",
|
||||
"storybook": "yarn workspace @status-im/components storybook"
|
||||
"storybook": "pnpm --filter @status-im/components storybook"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "18.0.33",
|
||||
@@ -29,14 +30,18 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.26.2",
|
||||
"@status-im/eslint-config": "*",
|
||||
"@status-im/eslint-config": "workspace:*",
|
||||
"@tsconfig/strictest": "^2.0.0",
|
||||
"@types/prettier": "^2.7.2",
|
||||
"eslint": "^9.14.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.2.0",
|
||||
"patch-package": "^6.5.1",
|
||||
"lint-staged": "^15.2.10",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||
"@types/react": "^18.0.33",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"rimraf": "^4.4.1",
|
||||
"turbo": "^1.8.8",
|
||||
"typescript": "^5.6.2",
|
||||
@@ -44,10 +49,17 @@
|
||||
"vite-node": "^0.29.8",
|
||||
"vitest": "^0.29.8"
|
||||
},
|
||||
"packageManager": "yarn@1.22.17",
|
||||
"packageManager": "pnpm@9.12.3",
|
||||
"lint-staged": {
|
||||
"*.{md,mdx,yml,yaml,json}": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@achingbrain/ssdp@4.0.1": "patches/@achingbrain__ssdp@4.0.1.patch",
|
||||
"@libp2p/bootstrap@9.0.10": "patches/@libp2p__bootstrap@9.0.10.patch",
|
||||
"it-length-prefixed@9.0.3": "patches/it-length-prefixed@9.0.3.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": ["@status-im/eslint-config"]
|
||||
}
|
||||
@@ -1,5 +1,17 @@
|
||||
# @status-im/colors
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c71b8c: update ESLint
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fad122: use pnpm and update node
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import configs from '@status-im/eslint-config'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [...configs]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@status-im/colors",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"license": "MPL-2.0",
|
||||
"files": [
|
||||
"types",
|
||||
@@ -19,25 +19,29 @@
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"sync": "rimraf src && vite-node scripts/sync.ts",
|
||||
"dev": "vite build --watch --mode development",
|
||||
"build:types": "tsc --noEmit false --emitDeclarationOnly",
|
||||
"build": "vite build",
|
||||
"postbuild": "yarn build:types",
|
||||
"postbuild": "pnpm build:types",
|
||||
"#test": "vitest",
|
||||
"typecheck": "tsc",
|
||||
"lint": "eslint src",
|
||||
"lint:fix": "yarn lint --fix",
|
||||
"lint:fix": "pnpm lint --fix",
|
||||
"format": "prettier --write src",
|
||||
"clean": "rimraf dist node_modules .turbo",
|
||||
"prepack": "yarn build"
|
||||
"prepack": "pnpm build"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"devDependencies": {
|
||||
"@clack/prompts": "^0.6.3",
|
||||
"colorjs.io": "^0.4.3",
|
||||
"@status-im/eslint-config": "*",
|
||||
"@status-im/eslint-config": "workspace:*",
|
||||
"figma-api": "^1.11.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"vite": "^5.4.3",
|
||||
|
||||
@@ -4,7 +4,7 @@ export const networks = {
|
||||
hermez: 'rgba(235 132 98 / 100%)',
|
||||
optimism: 'rgba(231 110 110 / 100%)',
|
||||
polygon: 'rgba(173 113 243 / 100%)',
|
||||
unknow: 'rgba(238 242 245 / 100%)',
|
||||
unknown: 'rgba(238 242 245 / 100%)',
|
||||
'x-dai': 'rgba(63 192 189 / 100%)',
|
||||
'zk-sync': 'rgba(159 160 254 / 100%)',
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": ["plugin:tailwindcss/recommended", "@status-im/eslint-config"],
|
||||
"rules": {
|
||||
"tailwindcss/classnames-order": "off"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,58 @@
|
||||
# @status-im/components
|
||||
|
||||
## 1.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1942ffb]
|
||||
- @status-im/icons@1.0.3
|
||||
|
||||
## 1.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c71b8c: update ESLint
|
||||
- Updated dependencies [3c71b8c]
|
||||
- @status-im/colors@1.0.2
|
||||
- @status-im/icons@1.0.2
|
||||
|
||||
## 1.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fad122: use pnpm and update node
|
||||
- e30555c: fix <DropdownMenu.SubTrigger /> icon; unknown network typo
|
||||
- 3c968a2: add missing directive to `<SegmentedControl />`
|
||||
- Updated dependencies [2fad122]
|
||||
- @status-im/colors@1.0.1
|
||||
- @status-im/icons@1.0.1
|
||||
|
||||
## 1.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2c56ff2: adds segmented control to index file
|
||||
|
||||
## 1.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b159258: fix `<DropdownMenu.Item />` onSelect prop
|
||||
- 4953fe7: adds segmented control component
|
||||
|
||||
## 1.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e9979fd: updates icon color for missing compound variants
|
||||
- bf14368: add `type="account"` to `<ContextTag />`
|
||||
|
||||
## 1.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7f21132: fix `<Shortcut />`icon prop and symbol centering
|
||||
|
||||
## 1.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import configs, { tailwindcssConfigs } from '@status-im/eslint-config'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [...configs, ...tailwindcssConfigs]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@status-im/components",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.12",
|
||||
"license": "MPL-2.0",
|
||||
"sideEffects": [
|
||||
"*.css"
|
||||
@@ -24,10 +24,14 @@
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "vite build --watch --mode development",
|
||||
"build": "vite build",
|
||||
"postbuild": "yarn build:types",
|
||||
"postbuild": "pnpm build:types",
|
||||
"build:types": "tsc --noEmit false --emitDeclarationOnly",
|
||||
"typecheck": "tsc",
|
||||
"lint": "eslint src",
|
||||
@@ -36,7 +40,7 @@
|
||||
"storybook:dev": "storybook dev -p 3001",
|
||||
"storybook:build": "storybook build",
|
||||
"clean": "rimraf node_modules dist .turbo storybook-static",
|
||||
"prepack": "yarn build"
|
||||
"prepack": "pnpm build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0"
|
||||
@@ -50,9 +54,10 @@
|
||||
"@radix-ui/react-switch": "^1.1.0",
|
||||
"@radix-ui/react-tabs": "^1.1.0",
|
||||
"@radix-ui/react-toast": "^1.2.1",
|
||||
"@radix-ui/react-toggle-group": "^1.1.0",
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@status-im/colors": "*",
|
||||
"@status-im/icons": "*",
|
||||
"@status-im/colors": "workspace:*",
|
||||
"@status-im/icons": "workspace:*",
|
||||
"cva": "^1.0.0-beta.1",
|
||||
"date-fns": "^2.30.0",
|
||||
"react-aria-components": "^1.3.3",
|
||||
@@ -61,7 +66,8 @@
|
||||
"zustand": "^4.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@status-im/eslint-config": "*",
|
||||
"@status-im/eslint-config": "workspace:*",
|
||||
"@storybook/addon-actions": "^8.3.0",
|
||||
"@storybook/addon-designs": "^8.0.3",
|
||||
"@storybook/addon-essentials": "^8.3.0",
|
||||
"@storybook/addon-interactions": "^8.3.0",
|
||||
@@ -71,6 +77,8 @@
|
||||
"@storybook/react": "^8.3.0",
|
||||
"@storybook/react-vite": "^8.3.0",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@types/react": "^18.0.33",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@vitejs/plugin-react-swc": "^3.7.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint-plugin-tailwindcss": "^3.17.4",
|
||||
|
||||
|
After Width: | Height: | Size: 127 KiB |
@@ -7,7 +7,7 @@
|
||||
const child_process = require('node:child_process')
|
||||
const process = require('node:process')
|
||||
|
||||
const subprocess = child_process.spawn('yarn', ['storybook:dev', '--no-open'], {
|
||||
const subprocess = child_process.spawn('pnpm', ['storybook:dev', '--no-open'], {
|
||||
detached: true,
|
||||
stdio: 'inherit',
|
||||
})
|
||||
|
||||
@@ -14,6 +14,7 @@ const sizesAvatar = {
|
||||
}
|
||||
|
||||
const renderVariant = (variant: AvatarProps['type']) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const content = (props: any) => {
|
||||
const sizes = sizesAvatar[variant]
|
||||
|
||||
@@ -47,7 +48,7 @@ const meta = {
|
||||
},
|
||||
|
||||
render: props => (
|
||||
<div className="grid gap-4 theme-yellow">
|
||||
<div className="grid gap-4">
|
||||
<h1 className="text-19">User Avatar</h1>
|
||||
{renderVariant('user')({
|
||||
...props,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { Fragment } from 'react'
|
||||
|
||||
import { PlaceholderIcon } from '@status-im/icons/20'
|
||||
|
||||
import { Button } from './button'
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
@@ -51,7 +55,22 @@ const meta: Meta<
|
||||
).map(variant => (
|
||||
<div key={variant} className="flex items-center gap-4">
|
||||
{(['40', '32', '24'] as const).map(size => (
|
||||
<Button key={size} {...args} variant={variant} size={size} />
|
||||
<Fragment key={size}>
|
||||
<Button {...args} variant={variant} size={size} />
|
||||
{/* With icon */}
|
||||
<Button
|
||||
{...args}
|
||||
size={size}
|
||||
variant={variant}
|
||||
iconBefore={<PlaceholderIcon />}
|
||||
/>
|
||||
<Button
|
||||
aria-label="Button with icon only"
|
||||
size={size}
|
||||
variant={variant}
|
||||
icon={<PlaceholderIcon />}
|
||||
/>
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -193,11 +193,41 @@ const iconStyles = cva({
|
||||
placement: 'after',
|
||||
className: '-mr-0.5',
|
||||
},
|
||||
{
|
||||
variant: 'grey',
|
||||
iconOnly: true,
|
||||
className: '!text-neutral-100 dark:!text-white-100',
|
||||
},
|
||||
{
|
||||
variant: 'outline',
|
||||
iconOnly: true,
|
||||
className: '!text-neutral-100 dark:!text-white-100',
|
||||
},
|
||||
{
|
||||
variant: 'darkGrey',
|
||||
iconOnly: true,
|
||||
className: '!text-neutral-100 dark:!text-white-100',
|
||||
},
|
||||
{
|
||||
variant: 'ghost',
|
||||
iconOnly: true,
|
||||
className: '!text-neutral-100 dark:!text-white-100',
|
||||
},
|
||||
{
|
||||
variant: 'primary',
|
||||
iconOnly: true,
|
||||
className: '!text-white-100',
|
||||
},
|
||||
{
|
||||
variant: 'positive',
|
||||
iconOnly: true,
|
||||
className: '!text-white-100',
|
||||
},
|
||||
{
|
||||
variant: 'danger',
|
||||
iconOnly: true,
|
||||
className: '!text-white-100',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ const ContextTagVariant = (props: Props) => {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<ContextTag {...props} type="account" label="Account name" emoji="🐷" />
|
||||
<ContextTag
|
||||
{...props}
|
||||
type="icon"
|
||||
|
||||
@@ -3,6 +3,8 @@ import { cloneElement, forwardRef } from 'react'
|
||||
import { cva, cx } from 'cva'
|
||||
import { match } from 'ts-pattern'
|
||||
|
||||
import { Avatar } from '../avatar'
|
||||
|
||||
import type { IconElement } from '../types'
|
||||
import type { VariantProps } from 'cva'
|
||||
|
||||
@@ -15,10 +17,10 @@ type Props = {
|
||||
| { type: 'community'; label: string; icon: IconElement }
|
||||
| { type: 'token'; label: string; icon: IconElement }
|
||||
| { type: 'network'; label: string; icon: IconElement }
|
||||
| { type: 'account'; label: string; emoji: string }
|
||||
| { type: 'icon'; label: string; icon: IconElement }
|
||||
)
|
||||
// | { type: 'user'; user: { name: string; src: string } }
|
||||
// | { type: 'account'; account: { name: string; emoji: string } }
|
||||
// | {
|
||||
// type: 'group'
|
||||
// group: {
|
||||
@@ -36,7 +38,7 @@ type Props = {
|
||||
|
||||
const baseStyles = cva({
|
||||
base: [
|
||||
'inline-flex w-fit cursor-default items-center rounded-full',
|
||||
'inline-flex w-fit cursor-default items-center',
|
||||
'font-medium text-neutral-100 dark:text-white-100',
|
||||
'bg-neutral-10 blur:bg-neutral-80/5 dark:bg-neutral-90 blur:dark:bg-white-5',
|
||||
],
|
||||
@@ -50,6 +52,13 @@ const baseStyles = cva({
|
||||
selected: {
|
||||
true: 'border border-customisation-50',
|
||||
},
|
||||
rounded: {
|
||||
'8': 'rounded-8',
|
||||
full: 'rounded-full',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
rounded: 'full',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -116,6 +125,23 @@ const ContextTag = (props: Props, ref: React.Ref<HTMLDivElement>) => {
|
||||
</div>
|
||||
)
|
||||
})
|
||||
.with({ type: 'account' }, ({ label, emoji }) => {
|
||||
return (
|
||||
<div {...rest} ref={ref} className={baseStyles({ size, rounded: '8' })}>
|
||||
<span className={iconStyles({ size, rounded: '6', offset: size })}>
|
||||
<Avatar
|
||||
type="account"
|
||||
size={match(size)
|
||||
.with('32', () => '28' as const)
|
||||
.otherwise(() => '20' as const)}
|
||||
name={label}
|
||||
emoji={emoji}
|
||||
/>
|
||||
</span>
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
.with({ type: 'icon' }, ({ icon, label }) => {
|
||||
return (
|
||||
<div {...rest} ref={ref} className={baseStyles({ size })}>
|
||||
|
||||
@@ -2,8 +2,8 @@ import { cloneElement, forwardRef, useId } from 'react'
|
||||
|
||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||
import {
|
||||
ArrowRightIcon,
|
||||
CheckIcon,
|
||||
ChevronRightIcon,
|
||||
ExternalIcon,
|
||||
SearchIcon,
|
||||
} from '@status-im/icons/20'
|
||||
@@ -123,7 +123,6 @@ Search.displayName = 'Search'
|
||||
type ItemProps = DropdownMenu.DropdownMenuItemProps & {
|
||||
icon?: IconElement
|
||||
label: string
|
||||
onSelect: () => void
|
||||
selected?: boolean
|
||||
danger?: boolean
|
||||
external?: boolean
|
||||
@@ -302,7 +301,7 @@ export const SubTrigger = (props: SubTriggerProps) => {
|
||||
<span className={iconStyles({ danger })}>{cloneElement(icon)}</span>
|
||||
)}
|
||||
<span className={labelStyles({ danger })}>{label}</span>
|
||||
<ArrowRightIcon className="text-neutral-50" />
|
||||
<ChevronRightIcon className="text-neutral-50" />
|
||||
</DropdownMenu.SubTrigger>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
const sizes = ['40', '32', '24'] as const
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const renderVariant = (variant: string) => (props: any) => (
|
||||
<div className="flex items-center gap-4">
|
||||
{sizes.map(size => (
|
||||
|
||||
@@ -9,6 +9,7 @@ export { IconButton } from './icon-button'
|
||||
export { Input } from './input'
|
||||
export { Popover } from './popover'
|
||||
export { StatusProvider } from './provider'
|
||||
export { SegmentedControl } from './segmented-control'
|
||||
export { Shortcut } from './shortcut'
|
||||
export { Skeleton } from './skeleton'
|
||||
export { Step } from './step'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * as SegmentedControl from './segmented-control'
|
||||
@@ -0,0 +1,130 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
import { PlaceholderIcon } from '@status-im/icons/20'
|
||||
|
||||
import { SegmentedControl } from './'
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
type RootProps = React.ComponentPropsWithoutRef<typeof SegmentedControl.Root>
|
||||
type ItemProps = React.ComponentPropsWithoutRef<typeof SegmentedControl.Item>
|
||||
|
||||
const SegmentedControlVariant = (
|
||||
props: Omit<ItemProps, 'value'> & {
|
||||
count: number
|
||||
size: RootProps['size']
|
||||
variant: RootProps['variant']
|
||||
},
|
||||
) => {
|
||||
const [value, setValue] = useState('0')
|
||||
|
||||
const { count, variant, size, ...itemProps } = props
|
||||
|
||||
return (
|
||||
<SegmentedControl.Root
|
||||
value={value}
|
||||
onValueChange={setValue}
|
||||
variant={variant}
|
||||
size={size}
|
||||
>
|
||||
{Array(count)
|
||||
.fill(null)
|
||||
.map((_, index) => {
|
||||
return (
|
||||
<SegmentedControl.Item
|
||||
{...(itemProps as ItemProps)}
|
||||
key={index}
|
||||
value={index.toString()}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</SegmentedControl.Root>
|
||||
)
|
||||
}
|
||||
|
||||
const SegmentedControlGroup = (
|
||||
props: Omit<RootProps, 'value' | 'onValueChange'>,
|
||||
) => {
|
||||
const { variant = 'grey' } = props
|
||||
|
||||
return (
|
||||
<div className="inline-flex flex-col gap-12">
|
||||
<div className="flex flex-col gap-6">
|
||||
<SegmentedControlVariant count={5} size="32" variant={variant}>
|
||||
Tab
|
||||
</SegmentedControlVariant>
|
||||
|
||||
<SegmentedControlVariant
|
||||
count={5}
|
||||
size="32"
|
||||
variant={variant}
|
||||
icon={<PlaceholderIcon />}
|
||||
>
|
||||
Tab
|
||||
</SegmentedControlVariant>
|
||||
|
||||
<SegmentedControlVariant count={2} size="32" variant={variant}>
|
||||
Tab
|
||||
</SegmentedControlVariant>
|
||||
<SegmentedControlVariant
|
||||
count={2}
|
||||
size="32"
|
||||
variant={variant}
|
||||
icon={<PlaceholderIcon />}
|
||||
>
|
||||
Tab
|
||||
</SegmentedControlVariant>
|
||||
|
||||
<SegmentedControlVariant
|
||||
count={5}
|
||||
size="32"
|
||||
variant={variant}
|
||||
icon={<PlaceholderIcon />}
|
||||
aria-label="placeholder"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'Components/Segmented Control',
|
||||
render: args => {
|
||||
return (
|
||||
<div className="flex flex-wrap gap-5">
|
||||
<div className="flex flex-wrap gap-5">
|
||||
<div className="rounded-[24px] bg-white-100 p-12 dark:bg-neutral-90">
|
||||
<SegmentedControlGroup {...args} />
|
||||
</div>
|
||||
|
||||
<div className="inline-flex flex-col gap-12 rounded-[24px] bg-neutral-5 p-12 dark:bg-neutral-95">
|
||||
<SegmentedControlGroup {...args} variant="darkGrey" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
data-background="blur"
|
||||
className="relative inline-flex flex-col gap-12 overflow-hidden rounded-[24px] p-12"
|
||||
>
|
||||
<div className="absolute left-0 top-0 z-10 size-full bg-blur-white/70 backdrop-blur-[20px] dark:bg-blur-neutral-80/80" />
|
||||
{/* Background image */}
|
||||
<div className="absolute left-0 top-0 size-full bg-[url(./assets/background-blur.png)] bg-cover bg-center bg-no-repeat" />
|
||||
<div className="relative z-10">
|
||||
<SegmentedControlGroup {...args} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
type Story = StoryObj
|
||||
|
||||
export const Light: Story = {}
|
||||
export const Dark: Story = {
|
||||
parameters: {
|
||||
backgrounds: { default: 'dark' },
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
@@ -0,0 +1,212 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
cloneElement,
|
||||
createContext,
|
||||
forwardRef,
|
||||
useContext,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
|
||||
import * as ToggleGroup from '@radix-ui/react-toggle-group'
|
||||
import { cva } from 'cva'
|
||||
|
||||
import type { IconElement } from '../types'
|
||||
import type { VariantProps } from 'cva'
|
||||
|
||||
type Variants = VariantProps<typeof rootStyles>
|
||||
|
||||
const SegmentedControlContext = createContext<
|
||||
Pick<Variants, 'variant' | 'size'>
|
||||
>({})
|
||||
|
||||
function useSegmentedControlContext() {
|
||||
const context = useContext(SegmentedControlContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
'useSegmentedControlContext must be used within a <SegmentedControl.Root />',
|
||||
)
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
type RootProps = Omit<ToggleGroup.ToggleGroupSingleProps, 'type'> & {
|
||||
value: string
|
||||
onValueChange: (value: string) => void
|
||||
variant?: Variants['variant']
|
||||
size?: Variants['size']
|
||||
}
|
||||
|
||||
const rootStyles = cva({
|
||||
base: 'relative flex flex-1 items-center justify-center gap-0.5 rounded-10 p-0.5',
|
||||
variants: {
|
||||
variant: {
|
||||
grey: 'bg-neutral-10 blur:bg-neutral-80/5 blur:backdrop-blur-[20px] dark:bg-neutral-80 blur:dark:bg-white-5',
|
||||
darkGrey: 'bg-neutral-20 dark:bg-neutral-90',
|
||||
},
|
||||
size: {
|
||||
'24': 'h-6',
|
||||
'32': 'h-8',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const activeSegmentStyles = cva({
|
||||
base: 'pointer-events-none absolute inset-y-0.5 left-0 flex-1 rounded-8 transition-all duration-200 ease-out',
|
||||
variants: {
|
||||
variant: {
|
||||
grey: 'bg-neutral-50 blur:bg-neutral-80/60 dark:bg-neutral-60 blur:dark:bg-white-20',
|
||||
darkGrey: 'bg-neutral-50 dark:bg-neutral-60',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const Root = forwardRef<
|
||||
React.ElementRef<typeof ToggleGroup.Root>,
|
||||
RootProps
|
||||
>((props, ref) => {
|
||||
const {
|
||||
children,
|
||||
variant = 'grey',
|
||||
size = '32',
|
||||
value,
|
||||
onValueChange,
|
||||
...rootProps
|
||||
} = props
|
||||
|
||||
const rootRef = useRef<HTMLDivElement>(null)
|
||||
useImperativeHandle(ref, () => rootRef.current!)
|
||||
|
||||
const [indicatorStyle, setIndicatorStyle] = useState<React.CSSProperties>({})
|
||||
|
||||
useEffect(() => {
|
||||
const activeButton =
|
||||
rootRef.current!.querySelector<HTMLButtonElement>('[data-state="on"]')!
|
||||
|
||||
if (activeButton) {
|
||||
setIndicatorStyle({
|
||||
width: activeButton.offsetWidth,
|
||||
transform: `translateX(${activeButton.offsetLeft}px)`,
|
||||
})
|
||||
}
|
||||
}, [value])
|
||||
|
||||
return (
|
||||
<SegmentedControlContext.Provider
|
||||
value={useMemo(() => ({ size, variant }), [size, variant])}
|
||||
>
|
||||
<ToggleGroup.Root
|
||||
{...rootProps}
|
||||
ref={rootRef}
|
||||
type="single"
|
||||
className={rootStyles({ size, variant })}
|
||||
value={value}
|
||||
onValueChange={value => {
|
||||
// Ensuring there is always a value
|
||||
// @see https://www.radix-ui.com/primitives/docs/components/toggle-group#ensuring-there-is-always-a-value
|
||||
if (value) {
|
||||
onValueChange(value)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={activeSegmentStyles({ variant })}
|
||||
style={indicatorStyle}
|
||||
/>
|
||||
{children}
|
||||
</ToggleGroup.Root>
|
||||
</SegmentedControlContext.Provider>
|
||||
)
|
||||
})
|
||||
|
||||
Root.displayName = 'Root'
|
||||
|
||||
/**
|
||||
* Item
|
||||
*/
|
||||
|
||||
const itemStyles = cva({
|
||||
base: [
|
||||
'group relative z-10 flex flex-1 select-none items-center justify-center gap-1 whitespace-nowrap rounded-8 bg-transparent font-medium transition-all duration-300 ease-out',
|
||||
'text-neutral-100 data-[state="on"]:text-white-100 dark:text-white-100',
|
||||
],
|
||||
|
||||
variants: {
|
||||
variant: {
|
||||
grey: [
|
||||
'data-[state="off"]:hover:bg-neutral-20 data-[state="off"]:blur:hover:bg-neutral-80/5 data-[state="off"]:dark:hover:bg-neutral-70 data-[state="off"]:dark:blur:hover:bg-white-5',
|
||||
],
|
||||
darkGrey: [
|
||||
'data-[state="off"]:hover:bg-neutral-30 data-[state="off"]:dark:hover:bg-neutral-80',
|
||||
],
|
||||
},
|
||||
size: {
|
||||
'24': 'h-6 px-2 text-13',
|
||||
'32': 'h-7 px-3 text-15',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const iconStyles = cva({
|
||||
base: [
|
||||
'size-5 text-neutral-50 group-data-[state="on"]:text-white-100 dark:text-white-40',
|
||||
],
|
||||
variants: {
|
||||
iconOnly: {
|
||||
true: '',
|
||||
false: '-ml-0.5',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
type ItemProps = Omit<
|
||||
React.ComponentPropsWithoutRef<typeof ToggleGroup.Item>,
|
||||
'children'
|
||||
> &
|
||||
(
|
||||
| {
|
||||
icon?: IconElement
|
||||
children: React.ReactNode
|
||||
}
|
||||
| {
|
||||
icon: IconElement
|
||||
children?: never
|
||||
'aria-label': string
|
||||
}
|
||||
)
|
||||
|
||||
export const Item = forwardRef<
|
||||
React.ElementRef<typeof ToggleGroup.Item>,
|
||||
ItemProps
|
||||
>((props, ref) => {
|
||||
const { icon, children, ...itemProps } = props
|
||||
|
||||
const { size, variant } = useSegmentedControlContext()
|
||||
|
||||
const iconOnly = children ? false : true
|
||||
|
||||
return (
|
||||
<ToggleGroup.Item
|
||||
{...itemProps}
|
||||
ref={ref}
|
||||
className={itemStyles({ size, variant })}
|
||||
>
|
||||
{icon && (
|
||||
<>
|
||||
{cloneElement(icon, {
|
||||
className: iconStyles({ iconOnly }),
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
{children}
|
||||
</ToggleGroup.Item>
|
||||
)
|
||||
})
|
||||
|
||||
Item.displayName = 'Item'
|
||||
@@ -6,10 +6,10 @@ import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
const variants = ['primary', 'secondary', 'gray'] as const
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const renderVariant = (variant: (typeof variants)[number]) => (props: any) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<Shortcut {...props} variant={variant} icon={CommandIcon} />
|
||||
<Shortcut {...props} variant={variant} icon={<CommandIcon />} />
|
||||
<Shortcut {...props} variant={variant} symbol="K" />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { forwardRef } from 'react'
|
||||
import { cloneElement, forwardRef } from 'react'
|
||||
|
||||
import { match, P } from 'ts-pattern'
|
||||
|
||||
import { cva } from '../utils/variants'
|
||||
|
||||
import type { IconElement } from '../types'
|
||||
import type { VariantProps } from '../utils/variants'
|
||||
|
||||
const styles = cva({
|
||||
base: 'flex size-4 flex-shrink-0 items-center justify-center rounded-6 border',
|
||||
base: 'grid size-4 flex-shrink-0 place-items-center rounded-6 border',
|
||||
variants: {
|
||||
variant: {
|
||||
primary: [
|
||||
@@ -32,7 +33,7 @@ const styles = cva({
|
||||
type Props = VariantProps<typeof styles> &
|
||||
(
|
||||
| {
|
||||
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>
|
||||
icon: IconElement
|
||||
symbol?: never
|
||||
}
|
||||
| {
|
||||
@@ -42,15 +43,17 @@ type Props = VariantProps<typeof styles> &
|
||||
)
|
||||
|
||||
const Shortcut = (props: Props, ref: React.Ref<HTMLDivElement>) => {
|
||||
const { variant = 'primary', ...rest } = props
|
||||
const { variant = 'primary' } = props
|
||||
|
||||
return (
|
||||
<div className={styles({ variant })} ref={ref} {...rest}>
|
||||
<div className={styles({ variant })} ref={ref}>
|
||||
{match(props)
|
||||
.with({ symbol: P.string }, ({ symbol }) => (
|
||||
<span className="text-11 font-medium">{symbol}</span>
|
||||
))
|
||||
.with({ icon: P._ }, ({ icon: Icon }) => <Icon className="size-3" />)
|
||||
.with({ icon: P._ }, ({ icon }) =>
|
||||
cloneElement(icon, { className: 'size-3' }),
|
||||
)
|
||||
.exhaustive()}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { cva, cx, type VariantProps } from 'cva'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const styles = cva({
|
||||
base: 'animate-skeleton overflow-hidden',
|
||||
|
||||
|
||||
@@ -26,6 +26,16 @@ type RootProps = React.ComponentProps<typeof Tabs.Root> & {
|
||||
|
||||
const TabsContext = createContext<Pick<RootProps, 'size' | 'variant'>>({})
|
||||
|
||||
function useTabsContext() {
|
||||
const context = useContext(TabsContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useTabsContext must be used within a <Tabs.Root />')
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
export const Root = (props: RootProps) => {
|
||||
const { size = '32', variant = 'grey', ...rootProps } = props
|
||||
|
||||
@@ -42,7 +52,7 @@ export const List = forwardRef<
|
||||
React.ElementRef<typeof Tabs.List>,
|
||||
React.ComponentPropsWithoutRef<typeof Tabs.List>
|
||||
>((props, ref) => {
|
||||
const { size } = useContext(TabsContext)!
|
||||
const { size } = useTabsContext()
|
||||
|
||||
return (
|
||||
<Tabs.List
|
||||
@@ -74,7 +84,7 @@ export const Trigger = forwardRef<
|
||||
>((props, ref) => {
|
||||
const { children, ...rest } = props
|
||||
|
||||
const { size, variant } = useContext(TabsContext)!
|
||||
const { size, variant } = useTabsContext()
|
||||
|
||||
return (
|
||||
<Tabs.Trigger {...rest} ref={ref} className={tabStyles({ variant, size })}>
|
||||
|
||||
@@ -27,13 +27,7 @@ function Tag(
|
||||
props: Props & (ButtonProps | DivProps),
|
||||
ref: Ref<HTMLButtonElement | HTMLDivElement>,
|
||||
) {
|
||||
const {
|
||||
size = '32',
|
||||
icon,
|
||||
iconPlacement = 'left',
|
||||
label,
|
||||
...rest
|
||||
} = props
|
||||
const { size = '32', icon, iconPlacement = 'left', label, ...rest } = props
|
||||
|
||||
const iconOnly = Boolean(icon && !label)
|
||||
|
||||
|
||||
@@ -26,7 +26,11 @@ const Actions = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const meta = {
|
||||
/**
|
||||
* > error TS2742: The inferred type of 'meta' cannot be named without a reference to '.pnpm/@storybook+csf@0.1.11/node_modules/@storybook/csf'. This is likely not portable. A type annotation is necessary.
|
||||
* > – @see https://github.com/storybookjs/storybook/issues/24656
|
||||
*/
|
||||
const meta: Meta<typeof Toast> = {
|
||||
component: Toast,
|
||||
title: 'Components/Toast',
|
||||
parameters: {
|
||||
@@ -75,7 +79,7 @@ const meta = {
|
||||
</>
|
||||
),
|
||||
],
|
||||
} satisfies Meta<typeof Toast>
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof Toast>
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@ export type CustomisationColorType = keyof typeof customisation
|
||||
|
||||
export type Prettify<T> = {
|
||||
[K in keyof T]: T[K]
|
||||
} & {} // eslint-disable-line @typescript-eslint/ban-types
|
||||
} & {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://openapi.vercel.sh/vercel.json",
|
||||
"ignoreCommand": "git diff --quiet HEAD^ HEAD ../../{patches,package.json,turbo.json} ../../packages/{colors,icons} ./",
|
||||
"installCommand": "yarn install --cwd ../../ --frozen-lockfile",
|
||||
"buildCommand": "turbo run build --cwd ../../ --filter=components... && yarn storybook:build"
|
||||
"installCommand": "pnpm install --dir ../../ --frozen-lockfile",
|
||||
"buildCommand": "turbo run build --cwd ../../ --filter=components... && pnpm storybook:build"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @status-im/eslint-config
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c71b8c: update ESLint
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fad122: use pnpm and update node
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import js from '@eslint/js'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
{
|
||||
...js.configs.recommended,
|
||||
files: ['**/*.js', '**/*.mjs', '**/*.cjs'],
|
||||
},
|
||||
]
|
||||
@@ -1,103 +1,174 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
// TODO: Enable type-aware linting (https://typescript-eslint.io/docs/linting/type-linting)
|
||||
// "tsconfigRootDir": ".",
|
||||
// "project": ["./packages/*/tsconfig.json"],
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
warnOnUnsupportedTypeScriptVersion: true,
|
||||
// // @ts-check
|
||||
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import {
|
||||
parser as typescriptParser,
|
||||
plugin as typescriptPlugin,
|
||||
configs as typescriptConfigs,
|
||||
} from 'typescript-eslint'
|
||||
import commentsPlugin from 'eslint-plugin-eslint-comments'
|
||||
import * as importPlugin from 'eslint-plugin-import'
|
||||
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y'
|
||||
import reactPlugin from 'eslint-plugin-react'
|
||||
import reactHooksPlugin from 'eslint-plugin-react-hooks'
|
||||
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort'
|
||||
import prettierPlugin from 'eslint-plugin-prettier/recommended'
|
||||
import tailwindcssPlugin from 'eslint-plugin-tailwindcss'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
{
|
||||
name: '@status-im/eslint-config',
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
'import',
|
||||
'simple-import-sort',
|
||||
'react',
|
||||
'jsx-a11y',
|
||||
],
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
// "plugin:@typescript-eslint/recommended-requiring-type-checking",
|
||||
'plugin:eslint-comments/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'prettier',
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
files: ['examples/**/*.tsx'],
|
||||
rules: {
|
||||
'react/jsx-uses-react': 'off',
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
},
|
||||
{
|
||||
plugins: {
|
||||
import: importPlugin,
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
'react/prop-types': 0,
|
||||
// "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
// TODO: turn on this rul
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
// "@typescript-eslint/consistent-type-exports": "error",
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [
|
||||
// Side effect imports.
|
||||
['^\\u0000'],
|
||||
// `react` related packages come first.
|
||||
['^react$', '^react-dom$'],
|
||||
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
|
||||
['^@?\\w'],
|
||||
// Absolute imports and other imports such as Vue-style `@/foo`.
|
||||
// Anything not matched in another group.
|
||||
['^'],
|
||||
// Relative imports.
|
||||
// Anything that starts with a dot.
|
||||
['^\\.'],
|
||||
// type imports last as a separate group
|
||||
['^.+\\u0000$'],
|
||||
],
|
||||
},
|
||||
rules: {
|
||||
...importPlugin.configs.recommended.rules,
|
||||
},
|
||||
files: [
|
||||
'**/*.js',
|
||||
'**/*.cjs',
|
||||
'**/*.mjs',
|
||||
'**/*.jsx',
|
||||
'**/*.ts',
|
||||
'**/*.mts',
|
||||
'**/*.tsx',
|
||||
'**/*.mdx',
|
||||
], // js, ts, mdx
|
||||
},
|
||||
{
|
||||
...js.configs.recommended,
|
||||
files: ['**/*.js', '**/*.mjs', '**/*.cjs', '**/*.ts', '**/*.tsx'], // js
|
||||
},
|
||||
...typescriptConfigs.recommended.map(config => ({
|
||||
...config,
|
||||
files: ['**/*.ts', '**/*.mts', '**/*.tsx'],
|
||||
})),
|
||||
{
|
||||
...jsxA11yPlugin.flatConfigs.recommended,
|
||||
files: ['**/*.js', '**/*.mjs', '**/*.cjs', '**/*.ts', '**/*.tsx'],
|
||||
},
|
||||
{
|
||||
...reactPlugin.configs.flat['jsx-runtime'],
|
||||
files: ['**/*.js', '**/*.mjs', '**/*.cjs', '**/*.ts', '**/*.tsx'],
|
||||
},
|
||||
{
|
||||
...prettierPlugin,
|
||||
files: [
|
||||
'**/*.js',
|
||||
'**/*.mjs',
|
||||
'**/*.cjs',
|
||||
'**/*.ts',
|
||||
'**/*.tsx',
|
||||
'**/*.md',
|
||||
'**/*.mdx',
|
||||
],
|
||||
'simple-import-sort/exports': 'error',
|
||||
'import/first': 'error',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-duplicates': 'error',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
project: [
|
||||
'tsconfig.base.json',
|
||||
'packages/*/tsconfig.json',
|
||||
'apps/*/tsconfig.json',
|
||||
],
|
||||
{
|
||||
files: ['**/*.ts', '**/*.mts', '**/*.tsx'], // ts
|
||||
languageOptions: {
|
||||
parser: typescriptParser,
|
||||
parserOptions: {
|
||||
// TODO: Enable type-aware linting (https://typescript-eslint.io/docs/linting/type-linting)
|
||||
// "tsconfigRootDir": ".",
|
||||
// "project": ["./packages/*/tsconfig.json"],
|
||||
// sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
// warnOnUnsupportedTypeScriptVersion: true,
|
||||
},
|
||||
typescript: {
|
||||
alwaysTryTypes: true,
|
||||
project: [
|
||||
'tsconfig.base.json',
|
||||
'packages/*/tsconfig.json',
|
||||
'apps/*/tsconfig.json',
|
||||
],
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
'@typescript-eslint': typescriptPlugin,
|
||||
'eslint-comments': commentsPlugin,
|
||||
react: reactPlugin,
|
||||
'react-hooks': reactHooksPlugin,
|
||||
'simple-import-sort': simpleImportSortPlugin,
|
||||
},
|
||||
rules: {
|
||||
...importPlugin.configs.typescript.rules,
|
||||
...reactHooksPlugin.configs.recommended.rules,
|
||||
'react/prop-types': 0,
|
||||
// "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
// TODO: turn on this rul
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
// "@typescript-eslint/consistent-type-exports": "error",
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [
|
||||
// Side effect imports.
|
||||
['^\\u0000'],
|
||||
// `react` related packages come first.
|
||||
['^react$', '^react-dom$'],
|
||||
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
|
||||
['^@?\\w'],
|
||||
// Absolute imports and other imports such as Vue-style `@/foo`.
|
||||
// Anything not matched in another group.
|
||||
['^'],
|
||||
// Relative imports.
|
||||
// Anything that starts with a dot.
|
||||
['^\\.'],
|
||||
// type imports last as a separate group
|
||||
['^.+\\u0000$'],
|
||||
],
|
||||
},
|
||||
],
|
||||
'simple-import-sort/exports': 'error',
|
||||
'import/first': 'error',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-duplicates': 'error',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
project: [
|
||||
'tsconfig.base.json',
|
||||
'packages/*/tsconfig.json',
|
||||
'apps/*/tsconfig.json',
|
||||
],
|
||||
},
|
||||
typescript: {
|
||||
alwaysTryTypes: true,
|
||||
project: [
|
||||
'tsconfig.base.json',
|
||||
'packages/*/tsconfig.json',
|
||||
'apps/*/tsconfig.json',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export const tailwindcssConfigs = [
|
||||
{
|
||||
files: ['**/*.ts', '**/*.mts', '**/*.tsx'],
|
||||
},
|
||||
...tailwindcssPlugin.configs['flat/recommended'],
|
||||
{
|
||||
rules: {
|
||||
'tailwindcss/classnames-order': 'off',
|
||||
'tailwindcss/migration-from-tailwind-2': 'off',
|
||||
},
|
||||
settings: {
|
||||
tailwindcss: {
|
||||
callees: ['cx', 'cva'],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@status-im/eslint-config",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"main": "index.js",
|
||||
"license": "MPL-2.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./index.js",
|
||||
@@ -10,24 +11,33 @@
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules"
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"clean": "rimraf node_modules",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^9.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||
"@typescript-eslint/parser": "^5.59.11",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-next": "^13.2.4",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-import-resolver-node": "^0.3.7",
|
||||
"eslint-import-resolver-typescript": "^3.5.5",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.14.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-node": "^0.3.9",
|
||||
"eslint-import-resolver-typescript": "^3.6.3",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-tailwindcss": "^3.12.1"
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-plugin-tailwindcss": "^3.17.5",
|
||||
"globals": "^15.12.0",
|
||||
"typescript-eslint": "^8.13.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": ["@status-im/eslint-config"],
|
||||
"ignorePatterns": ["dist", "index.js", "index.es.js"]
|
||||
}
|
||||
@@ -1,5 +1,23 @@
|
||||
# @status-im/icons
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1942ffb: Sync icons
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c71b8c: update ESLint
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fad122: use pnpm and update node
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import configs from '@status-im/eslint-config'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
...configs,
|
||||
{
|
||||
ignores: ['dist', 'index.js', 'index.es.js'],
|
||||
},
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@status-im/icons",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.3",
|
||||
"license": "MPL-2.0",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -53,20 +53,24 @@
|
||||
"import": "./svg/reactions/*.svg"
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"sync": "vite-node scripts/sync.ts && prettier --parser=html --write 'svg/**/*.svg'",
|
||||
"generate": "rimraf src && svgr svg --out-dir src && yarn lint:fix && yarn format",
|
||||
"generate": "rimraf src && svgr --no-prettier svg --out-dir src && pnpm lint:fix && pnpm format",
|
||||
"dev": "vite build --watch --mode development",
|
||||
"build": "vite build",
|
||||
"postbuild": "yarn build:types",
|
||||
"postbuild": "pnpm build:types",
|
||||
"build:types": "tsc src/**/index.ts --emitDeclarationOnly --declaration --jsx react-jsx --skipLibCheck --declarationDir ./dist",
|
||||
"#test": "vitest",
|
||||
"typecheck": "tsc",
|
||||
"lint": "eslint 'src/**/*.{ts,tsx}'",
|
||||
"lint:fix": "yarn lint --fix",
|
||||
"lint": "eslint src",
|
||||
"lint:fix": "pnpm lint --fix",
|
||||
"format": "prettier --write 'src/**/*.{ts,tsx}'",
|
||||
"clean": "rimraf dist node_modules .turbo",
|
||||
"prepack": "yarn build"
|
||||
"prepack": "pnpm build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.x || ^17.x || ^18.x",
|
||||
@@ -74,10 +78,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clack/prompts": "^0.7.0",
|
||||
"@status-im/eslint-config": "*",
|
||||
"@status-im/eslint-config": "workspace:*",
|
||||
"@svgr/cli": "^8.1.0",
|
||||
"@svgr/core": "^8.1.0",
|
||||
"@svgr/plugin-prettier": "^8.1.0",
|
||||
"@svgr/plugin-svgo": "^8.1.0",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { SVGProps } from 'react'
|
||||
|
||||
const SvgChromeIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
viewBox="0 0 20 20"
|
||||
aria-hidden={true}
|
||||
focusable={false}
|
||||
{...props}
|
||||
>
|
||||
<g fill="currentColor" clipPath="url(#prefix__clip0_8189_64)">
|
||||
<path d="M10 13.572c-.7 0-1.352-.193-1.931-.579a3.64 3.64 0 0 1-1.303-1.472L3.869 6.5C3.266 7.586 3 8.769 3 10c0 1.762.58 3.283 1.714 4.586 1.134 1.304 2.558 2.076 4.248 2.342l2.028-3.525a2.935 2.935 0 0 1-.99.17ZM7.803 7.103C8.455 6.597 9.18 6.38 10 6.38h6.01c-.627-1.062-1.472-1.834-2.534-2.438A6.71 6.71 0 0 0 10 3a6.965 6.965 0 0 0-3.066.7c-.94.459-1.834 1.134-2.462 2.003L6.5 9.034c.193-.772.652-1.424 1.303-1.93Z" />
|
||||
<path d="M16.47 7.369h-4.056c.7.7 1.183 1.617 1.183 2.63 0 .75-.218 1.425-.628 2.053L10.073 17c1.906-.024 3.548-.7 4.9-2.076C16.323 13.548 17 11.907 17 10c0-.893-.145-1.835-.53-2.631Z" />
|
||||
<path d="M10 7.345c1.448 0 2.655 1.207 2.655 2.655 0 1.448-1.207 2.655-2.655 2.655-1.448 0-2.655-1.207-2.655-2.655 0-1.448 1.207-2.655 2.655-2.655Z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="prefix__clip0_8189_64">
|
||||
<path fill="#fff" d="M3 3h14v14H3z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
export default SvgChromeIcon
|
||||
@@ -14,7 +14,7 @@ const SvgExternalIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M11.551 7.6H7V6.4h6.6V13h-1.2V8.449l-6.476 6.475-.848-.848L11.55 7.6Z"
|
||||
d="M11.551 6.6H7V5.4h6.6V12h-1.2V7.449l-6.476 6.475-.848-.848L11.55 6.6Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -56,6 +56,7 @@ export { default as ChevronsLeftIcon } from './chevrons-left-icon'
|
||||
export { default as ChevronsRightIcon } from './chevrons-right-icon'
|
||||
export { default as ChileIcon } from './chile-icon'
|
||||
export { default as ChinaIcon } from './china-icon'
|
||||
export { default as ChromeIcon } from './chrome-icon'
|
||||
export { default as CircleIcon } from './circle-icon'
|
||||
export { default as ClearBigIcon } from './clear-big-icon'
|
||||
export { default as ClearIcon } from './clear-icon'
|
||||
@@ -278,6 +279,7 @@ export { default as ScanBigIcon } from './scan-big-icon'
|
||||
export { default as ScanIcon } from './scan-icon'
|
||||
export { default as SearchIcon } from './search-icon'
|
||||
export { default as SeedIcon } from './seed-icon'
|
||||
export { default as SellIcon } from './sell-icon'
|
||||
export { default as SendAudioIcon } from './send-audio-icon'
|
||||
export { default as SendBlurIcon } from './send-blur-icon'
|
||||
export { default as SendIcon } from './send-icon'
|
||||
|
||||
@@ -14,7 +14,7 @@ const SvgPopupIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M2.6 10c0-1.727.068-3.046.264-4.06.196-1.01.51-1.665.96-2.116.452-.451 1.106-.764 2.116-.96C6.955 2.667 8.273 2.6 10 2.6c1.728 0 3.046.067 4.061.264 1.01.196 1.664.509 2.115.96.451.451.765 1.106.96 2.115.197 1.015.264 2.334.264 4.061 0 1.727-.067 3.046-.264 4.06-.195 1.01-.509 1.665-.96 2.116-.451.45-1.106.764-2.115.96-1.015.197-2.333.264-4.06.264-1.728 0-3.046-.067-4.061-.264-1.01-.196-1.664-.51-2.115-.96-.452-.451-.765-1.106-.96-2.115C2.667 13.046 2.6 11.727 2.6 10ZM10 1.4c-1.739 0-3.154.066-4.289.286-1.14.221-2.053.608-2.735 1.29-.682.682-1.069 1.594-1.29 2.735C1.466 6.846 1.4 8.26 1.4 10c0 1.74.066 3.154.286 4.29.221 1.14.608 2.052 1.29 2.734.682.682 1.594 1.069 2.735 1.29 1.135.22 2.55.286 4.29.286 1.739 0 3.154-.066 4.289-.286 1.14-.221 2.053-.608 2.735-1.29.682-.682 1.068-1.594 1.29-2.735.22-1.135.285-2.55.285-4.289 0-1.74-.066-3.154-.286-4.29-.22-1.14-.607-2.052-1.29-2.734-.681-.682-1.594-1.069-2.735-1.29C13.155 1.466 11.74 1.4 10 1.4ZM9 7.6h2.552l-4.976 4.976.848.848L12.4 8.448V11h1.2V6.4H9v1.2Z"
|
||||
d="M2.6 10c0-1.727.068-3.046.264-4.06.196-1.01.51-1.665.96-2.116.452-.451 1.106-.764 2.116-.96C6.955 2.667 8.273 2.6 10 2.6c1.728 0 3.046.067 4.061.264 1.01.196 1.664.509 2.115.96.451.451.765 1.106.96 2.115.197 1.015.264 2.334.264 4.061 0 1.727-.067 3.046-.264 4.06-.195 1.01-.509 1.665-.96 2.116-.451.45-1.106.764-2.115.96-1.015.197-2.333.264-4.06.264-1.728 0-3.046-.067-4.061-.264-1.01-.196-1.664-.51-2.115-.96-.452-.451-.765-1.106-.96-2.115C2.667 13.046 2.6 11.727 2.6 10ZM10 1.4c-1.739 0-3.154.066-4.289.286-1.14.221-2.053.608-2.735 1.29-.682.682-1.069 1.594-1.29 2.735C1.466 6.846 1.4 8.26 1.4 10c0 1.74.066 3.154.286 4.29.221 1.14.608 2.052 1.29 2.734.682.682 1.594 1.069 2.735 1.29 1.135.22 2.55.286 4.29.286 1.739 0 3.154-.066 4.289-.286 1.14-.221 2.053-.608 2.735-1.29.682-.682 1.068-1.594 1.29-2.735.22-1.135.285-2.55.285-4.289 0-1.74-.066-3.154-.286-4.29-.22-1.14-.607-2.052-1.29-2.734-.681-.682-1.594-1.069-2.735-1.29C13.155 1.466 11.74 1.4 10 1.4ZM9 7.6h2.551l-4.975 4.976.848.848L12.4 8.45V11h1.2V6.4H9v1.2Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { SVGProps } from 'react'
|
||||
|
||||
const SvgSellIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
viewBox="0 0 20 20"
|
||||
aria-hidden={true}
|
||||
focusable={false}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M3.1 10c0-1.619.063-2.852.247-3.8.182-.942.474-1.547.89-1.963.415-.416 1.021-.708 1.963-.89.948-.184 2.18-.247 3.8-.247 1.619 0 2.852.063 3.8.247.942.182 1.547.474 1.963.89.416.416.708 1.021.89 1.963.184.948.247 2.181.247 3.8 0 1.619-.063 2.852-.247 3.8-.182.942-.474 1.547-.89 1.963-.416.416-1.021.708-1.963.89-.948.184-2.181.247-3.8.247-1.62 0-2.852-.063-3.8-.247-.942-.182-1.548-.474-1.963-.89-.416-.416-.708-1.021-.89-1.963-.184-.948-.247-2.181-.247-3.8ZM10 1.9c-1.631 0-2.96.062-4.028.269-1.074.208-1.937.573-2.584 1.22-.647.646-1.011 1.51-1.22 2.583C1.963 7.039 1.9 8.369 1.9 10c0 1.631.062 2.96.269 4.028.208 1.074.572 1.937 1.22 2.584.646.647 1.509 1.011 2.583 1.22 1.067.206 2.397.268 4.028.268 1.63 0 2.96-.062 4.028-.269 1.074-.208 1.937-.572 2.584-1.22.646-.646 1.011-1.51 1.22-2.583.206-1.067.268-2.397.268-4.028 0-1.631-.062-2.96-.269-4.028-.208-1.074-.573-1.937-1.22-2.584-.646-.646-1.51-1.011-2.583-1.22C12.961 1.963 11.631 1.9 10 1.9Zm-3.5 8.7h7V9.4h-7v1.2Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
export default SvgSellIcon
|
||||
@@ -1,3 +1,4 @@
|
||||
export { default as ArbiscanIcon } from './arbiscan-icon'
|
||||
export { default as DiscordIcon } from './discord-icon'
|
||||
export { default as EtherscanIcon } from './etherscan-icon'
|
||||
export { default as FacebookIcon } from './facebook-icon'
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<g fill="currentColor" clip-path="url(#prefix__clip0_8189_64)">
|
||||
<path
|
||||
d="M10 13.572c-.7 0-1.352-.193-1.931-.579a3.64 3.64 0 0 1-1.303-1.472L3.869 6.5C3.266 7.586 3 8.769 3 10c0 1.762.58 3.283 1.714 4.586 1.134 1.304 2.558 2.076 4.248 2.342l2.028-3.525a2.935 2.935 0 0 1-.99.17ZM7.803 7.103C8.455 6.597 9.18 6.38 10 6.38h6.01c-.627-1.062-1.472-1.834-2.534-2.438A6.71 6.71 0 0 0 10 3a6.965 6.965 0 0 0-3.066.7c-.94.459-1.834 1.134-2.462 2.003L6.5 9.034c.193-.772.652-1.424 1.303-1.93Z"
|
||||
/>
|
||||
<path
|
||||
d="M16.47 7.369h-4.056c.7.7 1.183 1.617 1.183 2.63 0 .75-.218 1.425-.628 2.053L10.073 17c1.906-.024 3.548-.7 4.9-2.076C16.323 13.548 17 11.907 17 10c0-.893-.145-1.835-.53-2.631Z"
|
||||
/>
|
||||
<path
|
||||
d="M10 7.345c1.448 0 2.655 1.207 2.655 2.655 0 1.448-1.207 2.655-2.655 2.655-1.448 0-2.655-1.207-2.655-2.655 0-1.448 1.207-2.655 2.655-2.655Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="prefix__clip0_8189_64">
|
||||
<path fill="#fff" d="M3 3h14v14H3z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -8,7 +8,7 @@
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
d="M11.551 7.6H7V6.4h6.6V13h-1.2V8.449l-6.476 6.475-.848-.848L11.55 7.6Z"
|
||||
d="M11.551 6.6H7V5.4h6.6V12h-1.2V7.449l-6.476 6.475-.848-.848L11.55 6.6Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 277 B After Width: | Height: | Size: 277 B |
@@ -8,7 +8,7 @@
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
d="M2.6 10c0-1.727.068-3.046.264-4.06.196-1.01.51-1.665.96-2.116.452-.451 1.106-.764 2.116-.96C6.955 2.667 8.273 2.6 10 2.6c1.728 0 3.046.067 4.061.264 1.01.196 1.664.509 2.115.96.451.451.765 1.106.96 2.115.197 1.015.264 2.334.264 4.061 0 1.727-.067 3.046-.264 4.06-.195 1.01-.509 1.665-.96 2.116-.451.45-1.106.764-2.115.96-1.015.197-2.333.264-4.06.264-1.728 0-3.046-.067-4.061-.264-1.01-.196-1.664-.51-2.115-.96-.452-.451-.765-1.106-.96-2.115C2.667 13.046 2.6 11.727 2.6 10ZM10 1.4c-1.739 0-3.154.066-4.289.286-1.14.221-2.053.608-2.735 1.29-.682.682-1.069 1.594-1.29 2.735C1.466 6.846 1.4 8.26 1.4 10c0 1.74.066 3.154.286 4.29.221 1.14.608 2.052 1.29 2.734.682.682 1.594 1.069 2.735 1.29 1.135.22 2.55.286 4.29.286 1.739 0 3.154-.066 4.289-.286 1.14-.221 2.053-.608 2.735-1.29.682-.682 1.068-1.594 1.29-2.735.22-1.135.285-2.55.285-4.289 0-1.74-.066-3.154-.286-4.29-.22-1.14-.607-2.052-1.29-2.734-.681-.682-1.594-1.069-2.735-1.29C13.155 1.466 11.74 1.4 10 1.4ZM9 7.6h2.552l-4.976 4.976.848.848L12.4 8.448V11h1.2V6.4H9v1.2Z"
|
||||
d="M2.6 10c0-1.727.068-3.046.264-4.06.196-1.01.51-1.665.96-2.116.452-.451 1.106-.764 2.116-.96C6.955 2.667 8.273 2.6 10 2.6c1.728 0 3.046.067 4.061.264 1.01.196 1.664.509 2.115.96.451.451.765 1.106.96 2.115.197 1.015.264 2.334.264 4.061 0 1.727-.067 3.046-.264 4.06-.195 1.01-.509 1.665-.96 2.116-.451.45-1.106.764-2.115.96-1.015.197-2.333.264-4.06.264-1.728 0-3.046-.067-4.061-.264-1.01-.196-1.664-.51-2.115-.96-.452-.451-.765-1.106-.96-2.115C2.667 13.046 2.6 11.727 2.6 10ZM10 1.4c-1.739 0-3.154.066-4.289.286-1.14.221-2.053.608-2.735 1.29-.682.682-1.069 1.594-1.29 2.735C1.466 6.846 1.4 8.26 1.4 10c0 1.74.066 3.154.286 4.29.221 1.14.608 2.052 1.29 2.734.682.682 1.594 1.069 2.735 1.29 1.135.22 2.55.286 4.29.286 1.739 0 3.154-.066 4.289-.286 1.14-.221 2.053-.608 2.735-1.29.682-.682 1.068-1.594 1.29-2.735.22-1.135.285-2.55.285-4.289 0-1.74-.066-3.154-.286-4.29-.22-1.14-.607-2.052-1.29-2.734-.681-.682-1.594-1.069-2.735-1.29C13.155 1.466 11.74 1.4 10 1.4ZM9 7.6h2.551l-4.975 4.976.848.848L12.4 8.45V11h1.2V6.4H9v1.2Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
d="M3.1 10c0-1.619.063-2.852.247-3.8.182-.942.474-1.547.89-1.963.415-.416 1.021-.708 1.963-.89.948-.184 2.18-.247 3.8-.247 1.619 0 2.852.063 3.8.247.942.182 1.547.474 1.963.89.416.416.708 1.021.89 1.963.184.948.247 2.181.247 3.8 0 1.619-.063 2.852-.247 3.8-.182.942-.474 1.547-.89 1.963-.416.416-1.021.708-1.963.89-.948.184-2.181.247-3.8.247-1.62 0-2.852-.063-3.8-.247-.942-.182-1.548-.474-1.963-.89-.416-.416-.708-1.021-.89-1.963-.184-.948-.247-2.181-.247-3.8ZM10 1.9c-1.631 0-2.96.062-4.028.269-1.074.208-1.937.573-2.584 1.22-.647.646-1.011 1.51-1.22 2.583C1.963 7.039 1.9 8.369 1.9 10c0 1.631.062 2.96.269 4.028.208 1.074.572 1.937 1.22 2.584.646.647 1.509 1.011 2.583 1.22 1.067.206 2.397.268 4.028.268 1.63 0 2.96-.062 4.028-.269 1.074-.208 1.937-.572 2.584-1.22.646-.646 1.011-1.51 1.22-2.583.206-1.067.268-2.397.268-4.028 0-1.631-.062-2.96-.269-4.028-.208-1.074-.573-1.937-1.22-2.584-.646-.646-1.51-1.011-2.583-1.22C12.961 1.963 11.631 1.9 10 1.9Zm-3.5 8.7h7V9.4h-7v1.2Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 129 KiB |
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": ["@status-im/eslint-config"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["./src/protos/**/*_pb.ts"],
|
||||
"rules": {
|
||||
"eslint-comments/disable-enable-pair": "off",
|
||||
"eslint-comments/no-unlimited-disable": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,17 @@
|
||||
# @status-im/js
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c71b8c: update ESLint
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fad122: use pnpm and update node
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import configs from '@status-im/eslint-config'
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
...configs,
|
||||
{
|
||||
files: ['./src/protos/**/*_pb.ts'],
|
||||
rules: {
|
||||
'eslint-comments/disable-enable-pair': 'off',
|
||||
'eslint-comments/no-unlimited-disable': 'off',
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@status-im/js",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"license": "MPL-2.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
@@ -33,11 +33,15 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/status-im/status-web/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"test": "vitest",
|
||||
"dev": "vite build --watch --mode development",
|
||||
"build": "vite build",
|
||||
"postbuild": "yarn build:types",
|
||||
"postbuild": "pnpm build:types",
|
||||
"build:types": "tsc --noEmit false --emitDeclarationOnly || true",
|
||||
"lint": "eslint src",
|
||||
"typecheck": "tsc",
|
||||
@@ -60,7 +64,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bufbuild/protoc-gen-es": "1.4.2",
|
||||
"@status-im/eslint-config": "*",
|
||||
"@status-im/eslint-config": "workspace:*",
|
||||
"@waku/interfaces": "^0.0.21",
|
||||
"happy-dom": "^9.1.7"
|
||||
},
|
||||
|
||||
@@ -86,7 +86,7 @@ export class ActivityCenter {
|
||||
|
||||
public addMessageNotification = (
|
||||
newMessage: ChatMessage,
|
||||
referencedMessage?: ChatMessage
|
||||
referencedMessage?: ChatMessage,
|
||||
) => {
|
||||
let isMention: boolean | undefined
|
||||
let isReply: boolean | undefined
|
||||
|
||||
@@ -101,7 +101,7 @@ export class Chat {
|
||||
client: Client,
|
||||
uuid: string,
|
||||
type: MessageType.COMMUNITY_CHAT,
|
||||
description: CommunityChat
|
||||
description: CommunityChat,
|
||||
) => {
|
||||
const id = `${community.publicKey}${uuid}`
|
||||
const contentTopic = idToContentTopic(id)
|
||||
@@ -171,7 +171,7 @@ export class Chat {
|
||||
}
|
||||
|
||||
public onMessage = (
|
||||
callback: (messages: ChatMessage[]) => void
|
||||
callback: (messages: ChatMessage[]) => void,
|
||||
): (() => void) => {
|
||||
this.messageCallbacks.add(callback)
|
||||
// todo?: set from ui, think use case without an ui
|
||||
@@ -227,7 +227,7 @@ export class Chat {
|
||||
pageSize: 50,
|
||||
// most recent page first
|
||||
pageDirection: PageDirection.BACKWARD,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
this.#previousFetchedStartTime = startTime
|
||||
@@ -278,7 +278,7 @@ export class Chat {
|
||||
this.#oldestFetchedMessage = this.getOldestFetchedMessage(
|
||||
this.#oldestFetchedMessage,
|
||||
newMessage.messageId,
|
||||
timestamp
|
||||
timestamp,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ export class Chat {
|
||||
if (!this.#isActive && !isAuthor) {
|
||||
this.client.activityCenter.addMessageNotification(
|
||||
newMessage,
|
||||
this.#messages.get(newMessage.responseTo)
|
||||
this.#messages.get(newMessage.responseTo),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -349,7 +349,7 @@ export class Chat {
|
||||
messageId: string,
|
||||
text: string,
|
||||
clock: bigint,
|
||||
signerPublicKey: string
|
||||
signerPublicKey: string,
|
||||
) => {
|
||||
const message = this.#messages.get(messageId)
|
||||
|
||||
@@ -374,7 +374,7 @@ export class Chat {
|
||||
public handleDeletedMessage = (
|
||||
messageId: string,
|
||||
clock: bigint,
|
||||
signerPublicKey: string
|
||||
signerPublicKey: string,
|
||||
) => {
|
||||
const message = this.#messages.get(messageId)
|
||||
if (message && this.isAuthor(message, signerPublicKey)) {
|
||||
@@ -394,7 +394,7 @@ export class Chat {
|
||||
public handlePinnedMessage = (
|
||||
messageId: string,
|
||||
clock: bigint,
|
||||
pinned?: boolean
|
||||
pinned?: boolean,
|
||||
) => {
|
||||
const message = this.#messages.get(messageId)
|
||||
if (message) {
|
||||
@@ -419,14 +419,14 @@ export class Chat {
|
||||
messageId: string,
|
||||
reaction: EmojiReaction,
|
||||
clock: bigint,
|
||||
signerPublicKey: string
|
||||
signerPublicKey: string,
|
||||
) => {
|
||||
const message = this.#messages.get(messageId)
|
||||
if (message) {
|
||||
const reactions = getReactions(
|
||||
reaction,
|
||||
message.reactions,
|
||||
signerPublicKey
|
||||
signerPublicKey,
|
||||
)
|
||||
message.reactions = reactions
|
||||
|
||||
@@ -447,7 +447,7 @@ export class Chat {
|
||||
SAD: new Set<string>(),
|
||||
ANGRY: new Set<string>(),
|
||||
},
|
||||
signerPublicKey
|
||||
signerPublicKey,
|
||||
)
|
||||
|
||||
this.#reactEvents.set(messageId, { clock, reactions })
|
||||
@@ -455,7 +455,7 @@ export class Chat {
|
||||
const reactions = getReactions(
|
||||
reaction,
|
||||
reactEvent.reactions,
|
||||
signerPublicKey
|
||||
signerPublicKey,
|
||||
)
|
||||
|
||||
this.#reactEvents.set(messageId, { clock, reactions })
|
||||
@@ -489,7 +489,7 @@ export class Chat {
|
||||
ApplicationMetadataMessage_Type.CHAT_MESSAGE,
|
||||
payload,
|
||||
this.contentTopic,
|
||||
this.symmetricKey
|
||||
this.symmetricKey,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ export class Chat {
|
||||
ApplicationMetadataMessage_Type.CHAT_MESSAGE,
|
||||
payload,
|
||||
this.contentTopic,
|
||||
this.symmetricKey
|
||||
this.symmetricKey,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -554,14 +554,14 @@ export class Chat {
|
||||
ApplicationMetadataMessage_Type.EDIT_MESSAGE,
|
||||
payload,
|
||||
this.contentTopic,
|
||||
this.symmetricKey
|
||||
this.symmetricKey,
|
||||
)
|
||||
}
|
||||
|
||||
public deleteMessage = async (messageId: string) => {
|
||||
if (!this.client.account) {
|
||||
throw new Error(
|
||||
'Text message cannot be deleted without a created account'
|
||||
'Text message cannot be deleted without a created account',
|
||||
)
|
||||
}
|
||||
|
||||
@@ -587,13 +587,13 @@ export class Chat {
|
||||
ApplicationMetadataMessage_Type.DELETE_MESSAGE,
|
||||
payload,
|
||||
this.contentTopic,
|
||||
this.symmetricKey
|
||||
this.symmetricKey,
|
||||
)
|
||||
}
|
||||
|
||||
public sendReaction = async (
|
||||
messageId: string,
|
||||
reaction: keyof ChatMessage['reactions']
|
||||
reaction: keyof ChatMessage['reactions'],
|
||||
) => {
|
||||
if (!this.client.account) {
|
||||
throw new Error('Account not initialized')
|
||||
@@ -606,7 +606,7 @@ export class Chat {
|
||||
}
|
||||
|
||||
const retracted = message.reactions[reaction].has(
|
||||
`0x${this.client.account.publicKey}`
|
||||
`0x${this.client.account.publicKey}`,
|
||||
)
|
||||
|
||||
const payload = new EmojiReaction({
|
||||
@@ -623,13 +623,13 @@ export class Chat {
|
||||
ApplicationMetadataMessage_Type.EMOJI_REACTION,
|
||||
payload,
|
||||
this.contentTopic,
|
||||
this.symmetricKey
|
||||
this.symmetricKey,
|
||||
)
|
||||
}
|
||||
|
||||
public isAuthor = (
|
||||
message: ChatMessage,
|
||||
signerPublicKey: string
|
||||
signerPublicKey: string,
|
||||
): boolean => {
|
||||
return message.signer === signerPublicKey
|
||||
}
|
||||
@@ -637,7 +637,7 @@ export class Chat {
|
||||
private getOldestFetchedMessage(
|
||||
oldestMessage: FetchedMessage | undefined,
|
||||
messageId: string,
|
||||
messageTimestamp?: Date
|
||||
messageTimestamp?: Date,
|
||||
): FetchedMessage {
|
||||
let message: FetchedMessage
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ class Client {
|
||||
await waitForRemotePeer(
|
||||
waku,
|
||||
[Protocols.Store, Protocols.Filter, Protocols.LightPush],
|
||||
10 * 1000
|
||||
10 * 1000,
|
||||
)
|
||||
|
||||
// Client
|
||||
@@ -250,7 +250,7 @@ class Client {
|
||||
type: ApplicationMetadataMessage_Type,
|
||||
payload: Uint8Array,
|
||||
contentTopic: string,
|
||||
symKey: Uint8Array
|
||||
symKey: Uint8Array,
|
||||
) => {
|
||||
if (!this.waku) {
|
||||
throw new Error('Waku not started')
|
||||
@@ -278,7 +278,7 @@ class Client {
|
||||
shard: 32,
|
||||
},
|
||||
}),
|
||||
{ payload: message }
|
||||
{ payload: message },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ export class Community {
|
||||
if (this.description) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return this.description
|
||||
@@ -120,12 +120,12 @@ export class Community {
|
||||
shard: 32,
|
||||
}),
|
||||
],
|
||||
this.client.handleWakuMessage
|
||||
this.client.handleWakuMessage,
|
||||
)
|
||||
}
|
||||
|
||||
private observeChatMessages = async (
|
||||
chatDescriptions: CommunityDescription['chats']
|
||||
chatDescriptions: CommunityDescription['chats'],
|
||||
) => {
|
||||
const chatPromises = Object.entries(chatDescriptions).map(
|
||||
async ([chatUuid, chatDescription]: [string, CommunityChat]) => {
|
||||
@@ -134,7 +134,7 @@ export class Community {
|
||||
this.client,
|
||||
chatUuid,
|
||||
MessageType.COMMUNITY_CHAT,
|
||||
chatDescription
|
||||
chatDescription,
|
||||
)
|
||||
|
||||
this.chats.set(chatUuid, chat)
|
||||
@@ -146,18 +146,18 @@ export class Community {
|
||||
shard: 32,
|
||||
}),
|
||||
],
|
||||
this.client.handleWakuMessage
|
||||
this.client.handleWakuMessage,
|
||||
)
|
||||
|
||||
this.#chatUnobserveFns.set(chat.contentTopic, unobserveFn)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
await Promise.all(chatPromises)
|
||||
}
|
||||
|
||||
private unobserveChatMessages = (
|
||||
chatDescription: CommunityDescription['chats']
|
||||
chatDescription: CommunityDescription['chats'],
|
||||
) => {
|
||||
const contentTopics: string[] = []
|
||||
|
||||
@@ -179,7 +179,7 @@ export class Community {
|
||||
}
|
||||
|
||||
contentTopics.forEach(contentTopic =>
|
||||
this.#chatUnobserveFns.get(contentTopic)?.()
|
||||
this.#chatUnobserveFns.get(contentTopic)?.(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ export class Community {
|
||||
// observe
|
||||
const removedChats = getDifferenceByKeys(
|
||||
this.description.chats,
|
||||
description.chats
|
||||
description.chats,
|
||||
)
|
||||
if (Object.keys(removedChats).length) {
|
||||
this.unobserveChatMessages(removedChats)
|
||||
@@ -215,7 +215,7 @@ export class Community {
|
||||
|
||||
const addedChats = getDifferenceByKeys(
|
||||
description.chats,
|
||||
this.description.chats
|
||||
this.description.chats,
|
||||
)
|
||||
if (Object.keys(addedChats).length) {
|
||||
this.observeChatMessages(addedChats)
|
||||
@@ -232,7 +232,7 @@ export class Community {
|
||||
|
||||
const members = getObjectsDifference(
|
||||
this.description.members,
|
||||
description.members
|
||||
description.members,
|
||||
)
|
||||
|
||||
this.addMembers(members.added)
|
||||
@@ -251,7 +251,7 @@ export class Community {
|
||||
// handle
|
||||
Object.entries(this.description.chats).forEach(
|
||||
([chatUuid, chatDescription]) =>
|
||||
this.chats.get(chatUuid)?.handleChange(chatDescription)
|
||||
this.chats.get(chatUuid)?.handleChange(chatDescription),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -275,13 +275,13 @@ export class Community {
|
||||
ApplicationMetadataMessage_Type.COMMUNITY_REQUEST_TO_JOIN,
|
||||
payload,
|
||||
this.contentTopic,
|
||||
this.symmetricKey
|
||||
this.symmetricKey,
|
||||
)
|
||||
}
|
||||
|
||||
public isOwner = (
|
||||
/** Uncompressed. */
|
||||
signerPublicKey: string
|
||||
signerPublicKey: string,
|
||||
): boolean => {
|
||||
return this.publicKey === `0x${compressPublicKey(signerPublicKey)}`
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export type Reactions = {
|
||||
export function getReactions(
|
||||
reaction: EmojiReaction,
|
||||
reactions: Reactions,
|
||||
publicKey: string
|
||||
publicKey: string,
|
||||
): Reactions {
|
||||
const { type, retracted } = reaction
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export function handleWakuMessage(
|
||||
// state
|
||||
client: Client,
|
||||
community: Community,
|
||||
account?: Account
|
||||
account?: Account,
|
||||
): void {
|
||||
// decode (layers)
|
||||
// validate
|
||||
@@ -57,9 +57,8 @@ export function handleWakuMessage(
|
||||
if (decodedProtocol) {
|
||||
messageToDecode = decodedProtocol.publicMessage
|
||||
}
|
||||
} catch {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
} catch {}
|
||||
|
||||
const decodedMetadata = ApplicationMetadataMessage.fromBinary(messageToDecode)
|
||||
if (!decodedMetadata.payload) {
|
||||
@@ -69,12 +68,12 @@ export function handleWakuMessage(
|
||||
|
||||
const signerPublicKeyBytes = recoverPublicKey(
|
||||
decodedMetadata.signature,
|
||||
decodedMetadata.payload
|
||||
decodedMetadata.payload,
|
||||
)
|
||||
|
||||
const messageId = payloadToId(
|
||||
decodedProtocol?.publicMessage ?? wakuMessage.payload,
|
||||
signerPublicKeyBytes
|
||||
signerPublicKeyBytes,
|
||||
)
|
||||
const messageTimestamp = wakuMessage.timestamp
|
||||
const signerPublicKey = `0x${bytesToHex(signerPublicKeyBytes)}`
|
||||
@@ -181,7 +180,7 @@ export function handleWakuMessage(
|
||||
messageId,
|
||||
decodedPayload.text,
|
||||
decodedPayload.clock,
|
||||
signerPublicKey
|
||||
signerPublicKey,
|
||||
)
|
||||
chat.setClock(decodedPayload.clock)
|
||||
|
||||
@@ -220,7 +219,7 @@ export function handleWakuMessage(
|
||||
chat.handleDeletedMessage(
|
||||
messageId,
|
||||
decodedPayload.clock,
|
||||
signerPublicKey
|
||||
signerPublicKey,
|
||||
)
|
||||
chat.setClock(decodedPayload.clock)
|
||||
|
||||
@@ -259,7 +258,7 @@ export function handleWakuMessage(
|
||||
chat.handlePinnedMessage(
|
||||
messageId,
|
||||
decodedPayload.clock,
|
||||
decodedPayload.pinned
|
||||
decodedPayload.pinned,
|
||||
)
|
||||
chat.setClock(decodedPayload.clock)
|
||||
|
||||
@@ -299,7 +298,7 @@ export function handleWakuMessage(
|
||||
messageId,
|
||||
decodedPayload,
|
||||
decodedPayload.clock,
|
||||
signerPublicKey
|
||||
signerPublicKey,
|
||||
)
|
||||
chat.setClock(decodedPayload.clock)
|
||||
|
||||
@@ -320,7 +319,6 @@ export function handleWakuMessage(
|
||||
}
|
||||
} catch {
|
||||
// protons-runtime throws when trying to decode invalid protocol buffers
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -4,10 +4,10 @@ import {
|
||||
} from '../../protos/communities_pb'
|
||||
|
||||
export function isEncrypted(
|
||||
tokenPermissions: CommunityDescription['tokenPermissions']
|
||||
tokenPermissions: CommunityDescription['tokenPermissions'],
|
||||
): boolean {
|
||||
return Object.values(tokenPermissions).some(
|
||||
permission =>
|
||||
permission.type === CommunityTokenPermission_Type.BECOME_MEMBER
|
||||
permission.type === CommunityTokenPermission_Type.BECOME_MEMBER,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function mapChatMessage(
|
||||
signerPublicKey: string
|
||||
community: Community
|
||||
chat: Chat
|
||||
}
|
||||
},
|
||||
): ChatMessage {
|
||||
const { messageId, chatUuid, signerPublicKey, community, chat } = props
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export class LocalStorage implements Storage {
|
||||
try {
|
||||
window.localStorage.setItem(
|
||||
this.#getStorageKey(key),
|
||||
JSON.stringify(value)
|
||||
JSON.stringify(value),
|
||||
)
|
||||
return true
|
||||
} catch {
|
||||
|
||||
@@ -6,14 +6,14 @@ export const pbkdf2: PBKDF2 = async (
|
||||
password: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
iterations: number,
|
||||
keylen: number
|
||||
keylen: number,
|
||||
): Promise<Uint8Array> => {
|
||||
const cryptoKey = await window.crypto.subtle.importKey(
|
||||
'raw',
|
||||
password,
|
||||
{ name: 'PBKDF2' },
|
||||
false,
|
||||
['deriveBits']
|
||||
['deriveBits'],
|
||||
)
|
||||
|
||||
const derivedKey = await window.crypto.subtle.deriveBits(
|
||||
@@ -26,7 +26,7 @@ export const pbkdf2: PBKDF2 = async (
|
||||
},
|
||||
},
|
||||
cryptoKey,
|
||||
keylen << 3
|
||||
keylen << 3,
|
||||
)
|
||||
|
||||
return new Uint8Array(derivedKey)
|
||||
|
||||
@@ -16,7 +16,7 @@ export class EthereumClient {
|
||||
|
||||
async resolvePublicKey(
|
||||
ensName: string,
|
||||
options: { compress: boolean }
|
||||
options: { compress: boolean },
|
||||
): Promise<string | undefined> {
|
||||
try {
|
||||
const resolver = await this.#provider.getResolver(ensName)
|
||||
@@ -51,22 +51,22 @@ export class EthereumClient {
|
||||
|
||||
async resolveOwner(
|
||||
registryContractAddress: string,
|
||||
communityPublicKey: string
|
||||
communityPublicKey: string,
|
||||
): Promise<string | undefined> {
|
||||
try {
|
||||
const registryContract = new ethers.Contract(
|
||||
registryContractAddress,
|
||||
['function getEntry(address _communityAddress) view returns (address)'],
|
||||
this.#provider
|
||||
this.#provider,
|
||||
)
|
||||
const ownerContractAddress = await registryContract.getEntry(
|
||||
publicKeyToETHAddress(communityPublicKey)
|
||||
publicKeyToETHAddress(communityPublicKey),
|
||||
)
|
||||
|
||||
const ownerContract = new ethers.Contract(
|
||||
ownerContractAddress,
|
||||
['function signerPublicKey() view returns (bytes)'],
|
||||
this.#provider
|
||||
this.#provider,
|
||||
)
|
||||
const owner = await ownerContract.signerPublicKey()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export function getDifferenceByKeys<T extends Record<string, unknown>>(
|
||||
a: T,
|
||||
b: T
|
||||
b: T,
|
||||
): T {
|
||||
const initialValue: Record<string, unknown> = {}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ type Input<Value> = Record<string, Value>
|
||||
|
||||
export function getObjectsDifference<Value>(
|
||||
oldObject: Input<Value>,
|
||||
newObject: Input<Value>
|
||||
newObject: Input<Value>,
|
||||
) {
|
||||
const added: Record<string, Value> = {}
|
||||
const removed: string[] = []
|
||||
|
||||
@@ -16,7 +16,7 @@ export type ChannelInfo = {
|
||||
|
||||
export function mapChannel(
|
||||
communityChat: CommunityChat,
|
||||
communityDescription: CommunityDescription
|
||||
communityDescription: CommunityDescription,
|
||||
): ChannelInfo | undefined {
|
||||
const community = mapCommunity(communityDescription)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export type Tag = {
|
||||
}
|
||||
|
||||
export function mapCommunity(
|
||||
communityDescription: CommunityDescription
|
||||
communityDescription: CommunityDescription,
|
||||
): CommunityInfo | undefined {
|
||||
const { identity, tags, members } = communityDescription
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export type UserInfo = {
|
||||
|
||||
export function mapUser(
|
||||
contactCodeAdvertisement: ContactCodeAdvertisement,
|
||||
userPublicKey: string
|
||||
userPublicKey: string,
|
||||
): UserInfo | undefined {
|
||||
const { chatIdentity: identity } = contactCodeAdvertisement
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class RequestClient {
|
||||
contractAddresses?: Record<number, Record<string, string>>
|
||||
started?: boolean
|
||||
environment?: 'development' | 'preview' | 'production'
|
||||
}
|
||||
},
|
||||
) {
|
||||
const { environment = 'development' } = options
|
||||
|
||||
@@ -136,7 +136,7 @@ class RequestClient {
|
||||
await Promise.all([
|
||||
async () => this.waku.stop(),
|
||||
[...this.#ethereumClients.values()].map(async provider =>
|
||||
provider.stop()
|
||||
provider.stop(),
|
||||
),
|
||||
])
|
||||
|
||||
@@ -163,7 +163,7 @@ class RequestClient {
|
||||
|
||||
public fetchCommunity = async (
|
||||
/** Compressed */
|
||||
publicKey: string
|
||||
publicKey: string,
|
||||
): Promise<CommunityInfo | undefined> => {
|
||||
const communityDescription = await this.fetchCommunityDescription(publicKey)
|
||||
|
||||
@@ -177,7 +177,7 @@ class RequestClient {
|
||||
public fetchChannel = async (
|
||||
/** Compressed */
|
||||
publicKey: string,
|
||||
uuid: string
|
||||
uuid: string,
|
||||
): Promise<ChannelInfo | undefined> => {
|
||||
const communityDescription = await this.fetchCommunityDescription(publicKey)
|
||||
|
||||
@@ -192,11 +192,10 @@ class RequestClient {
|
||||
|
||||
public fetchUser = async (
|
||||
/** Uncompressed */
|
||||
publicKey: string
|
||||
publicKey: string,
|
||||
): Promise<UserInfo | undefined> => {
|
||||
const contactCodeAdvertisement = await this.fetchContactCodeAdvertisement(
|
||||
publicKey
|
||||
)
|
||||
const contactCodeAdvertisement =
|
||||
await this.fetchContactCodeAdvertisement(publicKey)
|
||||
|
||||
if (!contactCodeAdvertisement) {
|
||||
return
|
||||
@@ -207,7 +206,7 @@ class RequestClient {
|
||||
|
||||
public fetchCommunityDescription = async (
|
||||
/** Compressed */
|
||||
communityPublicKey: string
|
||||
communityPublicKey: string,
|
||||
): Promise<CommunityDescription | undefined> => {
|
||||
const contentTopic = idToContentTopic(communityPublicKey)
|
||||
const symmetricKey = await generateKeyFromPassword(communityPublicKey)
|
||||
@@ -238,24 +237,25 @@ class RequestClient {
|
||||
|
||||
// decode
|
||||
const decodedCommunityDescription = CommunityDescription.fromBinary(
|
||||
message.payload
|
||||
message.payload,
|
||||
)
|
||||
|
||||
// validate
|
||||
if (
|
||||
!isClockValid(
|
||||
BigInt(decodedCommunityDescription.clock),
|
||||
message.timestamp
|
||||
message.timestamp,
|
||||
)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
const ownerTokenPermission = Object.values(
|
||||
decodedCommunityDescription.tokenPermissions
|
||||
decodedCommunityDescription.tokenPermissions,
|
||||
).find(
|
||||
permission =>
|
||||
permission.type === CommunityTokenPermission_Type.BECOME_TOKEN_OWNER
|
||||
permission.type ===
|
||||
CommunityTokenPermission_Type.BECOME_TOKEN_OWNER,
|
||||
)
|
||||
if (ownerTokenPermission) {
|
||||
const criteria = ownerTokenPermission.tokenCriteria[0]
|
||||
@@ -281,7 +281,7 @@ class RequestClient {
|
||||
const ownerPublicKey = await ethereumClient.resolveOwner(
|
||||
this.#contractAddresses[Number(chainId)]
|
||||
.CommunityOwnerTokenRegistry,
|
||||
communityPublicKey
|
||||
communityPublicKey,
|
||||
)
|
||||
|
||||
if (ownerPublicKey !== message.signerPublicKey) {
|
||||
@@ -301,11 +301,11 @@ class RequestClient {
|
||||
}
|
||||
|
||||
private fetchContactCodeAdvertisement = async (
|
||||
publicKey: string
|
||||
publicKey: string,
|
||||
): Promise<ContactCodeAdvertisement | undefined> => {
|
||||
const contentTopic = idToContentTopic(`${publicKey}-contact-code`)
|
||||
const symmetricKey = await generateKeyFromPassword(
|
||||
`${publicKey}-contact-code`
|
||||
`${publicKey}-contact-code`,
|
||||
)
|
||||
|
||||
const wakuMessageGenerator = this.waku.store.queryGenerator([
|
||||
@@ -336,7 +336,7 @@ class RequestClient {
|
||||
|
||||
// decode
|
||||
const decodedContactCode = ContactCodeAdvertisement.fromBinary(
|
||||
message.payload
|
||||
message.payload,
|
||||
)
|
||||
|
||||
// validate
|
||||
@@ -347,7 +347,7 @@ class RequestClient {
|
||||
if (
|
||||
!isClockValid(
|
||||
BigInt(decodedContactCode.chatIdentity.clock),
|
||||
message.timestamp
|
||||
message.timestamp,
|
||||
)
|
||||
) {
|
||||
continue
|
||||
@@ -364,7 +364,7 @@ class RequestClient {
|
||||
}
|
||||
|
||||
private handleWakuMessage = (
|
||||
wakuMessage: DecodedMessage
|
||||
wakuMessage: DecodedMessage,
|
||||
):
|
||||
| {
|
||||
timestamp: Date
|
||||
@@ -394,17 +394,17 @@ class RequestClient {
|
||||
|
||||
if (decodedSegment) {
|
||||
const unsegmentedMessageHash = bytesToHex(
|
||||
decodedSegment.entireMessageHash
|
||||
decodedSegment.entireMessageHash,
|
||||
)
|
||||
|
||||
const segmentedWakuMessages = this.#segmentedWakuMessages.get(
|
||||
unsegmentedMessageHash
|
||||
unsegmentedMessageHash,
|
||||
)
|
||||
|
||||
if (!segmentedWakuMessages) {
|
||||
this.#segmentedWakuMessages.set(
|
||||
unsegmentedMessageHash,
|
||||
new Map([[decodedSegment.index, decodedSegment]])
|
||||
new Map([[decodedSegment.index, decodedSegment]]),
|
||||
)
|
||||
|
||||
return
|
||||
@@ -430,13 +430,12 @@ class RequestClient {
|
||||
messageToDecode = unsegmentedPayload
|
||||
|
||||
this.#segmentedWakuMessages.delete(unsegmentedMessageHash)
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
} catch {}
|
||||
|
||||
let decodedProtocol
|
||||
try {
|
||||
@@ -447,9 +446,8 @@ class RequestClient {
|
||||
} else if (decodedProtocol) {
|
||||
messageToDecode = decodedProtocol.publicMessage
|
||||
}
|
||||
} catch {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
} catch {}
|
||||
|
||||
let decodedMetadata
|
||||
try {
|
||||
@@ -468,12 +466,12 @@ class RequestClient {
|
||||
|
||||
const signerPublicKeyBytes = recoverPublicKey(
|
||||
decodedMetadata.signature,
|
||||
decodedMetadata.payload
|
||||
decodedMetadata.payload,
|
||||
)
|
||||
|
||||
const messageId = payloadToId(
|
||||
decodedProtocol?.publicMessage ?? wakuMessage.payload,
|
||||
signerPublicKeyBytes
|
||||
signerPublicKeyBytes,
|
||||
)
|
||||
|
||||
// already handled
|
||||
@@ -493,7 +491,7 @@ class RequestClient {
|
||||
}
|
||||
|
||||
export async function createRequestClient(
|
||||
options: RequestClientOptions
|
||||
options: RequestClientOptions,
|
||||
): Promise<RequestClient> {
|
||||
return await RequestClient.start(options)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export function compressPublicKey(publicKey: string): string {
|
||||
try {
|
||||
const pk = publicKey.replace(/^0[xX]/, '') // ensures hexadecimal digits without "base prefix"
|
||||
return secp.Point.fromHex(pk).toHex(true)
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error('Invalid public key')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ describe('Create URLs', () => {
|
||||
} as unknown as CommunityDescription
|
||||
|
||||
expect(createCommunityURLWithChatKey(community.chatKey).toString()).toBe(
|
||||
'https://status.app/c#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11'
|
||||
'https://status.app/c#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11',
|
||||
)
|
||||
expect(
|
||||
(
|
||||
@@ -58,11 +58,11 @@ describe('Create URLs', () => {
|
||||
membersCount: 446_744,
|
||||
tagIndices: [1, 33, 51],
|
||||
},
|
||||
community.chatKey
|
||||
community.chatKey,
|
||||
)
|
||||
).toString()
|
||||
).toString(),
|
||||
).toBe(
|
||||
'https://status.app/c/iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11'
|
||||
'https://status.app/c/iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11',
|
||||
)
|
||||
})
|
||||
|
||||
@@ -95,9 +95,9 @@ describe('Create URLs', () => {
|
||||
} as unknown as CommunityChat
|
||||
|
||||
expect(
|
||||
createChannelURLWithChatKey(chat.uuid, community.chatKey).toString()
|
||||
createChannelURLWithChatKey(chat.uuid, community.chatKey).toString(),
|
||||
).toBe(
|
||||
'https://status.app/cc/003cdcd5-e065-48f9-b166-b1a94ac75a11#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11'
|
||||
'https://status.app/cc/003cdcd5-e065-48f9-b166-b1a94ac75a11#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11',
|
||||
)
|
||||
expect(
|
||||
(
|
||||
@@ -112,11 +112,11 @@ describe('Create URLs', () => {
|
||||
displayName: community.description.identity!.displayName,
|
||||
},
|
||||
} as unknown as PlainMessage<ChannelProto>,
|
||||
community.chatKey
|
||||
community.chatKey,
|
||||
)
|
||||
).toString()
|
||||
).toString(),
|
||||
).toBe(
|
||||
'https://status.app/cc/G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11'
|
||||
'https://status.app/cc/G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11',
|
||||
)
|
||||
})
|
||||
|
||||
@@ -134,10 +134,10 @@ describe('Create URLs', () => {
|
||||
} as unknown as ContactCodeAdvertisement
|
||||
|
||||
expect(createUserURLWithENS(account.ensName).toString()).toBe(
|
||||
'https://status.app/u#testing.stateofus.eth'
|
||||
'https://status.app/u#testing.stateofus.eth',
|
||||
)
|
||||
expect(createUserURLWithChatKey(account.chatKey).toString()).toBe(
|
||||
'https://status.app/u#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj'
|
||||
'https://status.app/u#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj',
|
||||
)
|
||||
expect(
|
||||
(
|
||||
@@ -147,11 +147,11 @@ describe('Create URLs', () => {
|
||||
displayName: account.description.chatIdentity!.displayName,
|
||||
color: account.description.chatIdentity!.color,
|
||||
},
|
||||
account.chatKey
|
||||
account.chatKey,
|
||||
)
|
||||
).toString()
|
||||
).toString(),
|
||||
).toBe(
|
||||
'https://status.app/u/G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj'
|
||||
'https://status.app/u/G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@ export function createCommunityURLWithChatKey(communityChatKey: string): URL {
|
||||
|
||||
export async function createCommunityURLWithData(
|
||||
communityData: PlainMessage<Community>,
|
||||
communityChatKey: string
|
||||
communityChatKey: string,
|
||||
): Promise<URL> {
|
||||
const encodedURLData = encodeCommunityURLData(communityData)
|
||||
|
||||
@@ -24,14 +24,14 @@ export async function createCommunityURLWithData(
|
||||
|
||||
export function createChannelURLWithChatKey(
|
||||
channelUuid: string,
|
||||
communityChatKey: string
|
||||
communityChatKey: string,
|
||||
): URL {
|
||||
return new URL(`${BASE_URL}/cc/${channelUuid}#${communityChatKey}`)
|
||||
}
|
||||
|
||||
export async function createChannelURLWithData(
|
||||
channelData: PlainMessage<Channel>,
|
||||
communityChatKey: string
|
||||
communityChatKey: string,
|
||||
): Promise<URL> {
|
||||
const encodedURLData = encodeChannelURLData(channelData)
|
||||
|
||||
@@ -48,7 +48,7 @@ export function createUserURLWithChatKey(chatKey: string): URL {
|
||||
|
||||
export async function createUserURLWithData(
|
||||
userData: PlainMessage<User>,
|
||||
userChatKey: string
|
||||
userChatKey: string,
|
||||
): Promise<URL> {
|
||||
const encodedURLData = encodeUserURLData(userData)
|
||||
|
||||
|
||||