chore: upgrade TypeScript to 5.4 with bundler module resolution and reformat repo against tightened ESLint
This commit is contained in:
parent
ed3e5c0640
commit
e230e688de
78 changed files with 881 additions and 567 deletions
|
|
@ -1,2 +1,3 @@
|
||||||
experiment
|
experiment
|
||||||
node_modules
|
node_modules
|
||||||
|
*.css
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,15 @@ module.exports = {
|
||||||
es2021: true,
|
es2021: true,
|
||||||
},
|
},
|
||||||
extends: [
|
extends: [
|
||||||
"eslint:recommended",
|
'eslint:recommended',
|
||||||
"plugin:react/recommended",
|
'plugin:react/recommended',
|
||||||
"plugin:react-hooks/recommended",
|
'plugin:react-hooks/recommended',
|
||||||
"plugin:@typescript-eslint/eslint-recommended",
|
'plugin:@typescript-eslint/eslint-recommended',
|
||||||
"plugin:@typescript-eslint/recommended",
|
'plugin:@typescript-eslint/recommended',
|
||||||
'airbnb',
|
'airbnb',
|
||||||
'prettier',
|
'prettier',
|
||||||
],
|
],
|
||||||
parser: "@typescript-eslint/parser",
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
jsx: true,
|
jsx: true,
|
||||||
|
|
@ -20,53 +20,73 @@ module.exports = {
|
||||||
ecmaVersion: 'latest',
|
ecmaVersion: 'latest',
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
"globals": {
|
globals: {
|
||||||
JSX: "readonly"
|
JSX: 'readonly',
|
||||||
|
__APP_VERSION__: 'readonly',
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: ['react', '@typescript-eslint'],
|
||||||
'react',
|
|
||||||
'@typescript-eslint'
|
|
||||||
],
|
|
||||||
rules: {
|
rules: {
|
||||||
'linebreak-style': 0,
|
'linebreak-style': 0,
|
||||||
'no-underscore-dangle': 0,
|
'no-underscore-dangle': 0,
|
||||||
"no-shadow": "off",
|
'no-shadow': 'off',
|
||||||
|
|
||||||
"import/prefer-default-export": "off",
|
'import/prefer-default-export': 'off',
|
||||||
"import/extensions": "off",
|
'import/extensions': 'off',
|
||||||
"import/no-unresolved": "off",
|
'import/no-unresolved': 'off',
|
||||||
"import/no-extraneous-dependencies": [
|
'import/no-extraneous-dependencies': [
|
||||||
"error",
|
'error',
|
||||||
{
|
{
|
||||||
devDependencies: true,
|
devDependencies: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
'react/no-unstable-nested-components': [
|
'react/no-unstable-nested-components': ['error', { allowAsProps: true }],
|
||||||
|
'react/jsx-filename-extension': [
|
||||||
'error',
|
'error',
|
||||||
{ allowAsProps: true },
|
|
||||||
],
|
|
||||||
"react/jsx-filename-extension": [
|
|
||||||
"error",
|
|
||||||
{
|
{
|
||||||
extensions: [".tsx", ".jsx"],
|
extensions: ['.tsx', '.jsx'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
"react/require-default-props": "off",
|
'react/require-default-props': 'off',
|
||||||
"react/jsx-props-no-spreading": "off",
|
'react/jsx-props-no-spreading': 'off',
|
||||||
"react-hooks/rules-of-hooks": "error",
|
'react-hooks/rules-of-hooks': 'error',
|
||||||
"react-hooks/exhaustive-deps": "error",
|
'react-hooks/exhaustive-deps': 'error',
|
||||||
|
|
||||||
"@typescript-eslint/no-unused-vars": "error",
|
// Disable base rules in favour of their @typescript-eslint counterparts —
|
||||||
"@typescript-eslint/no-shadow": "error"
|
// the base rules can't see TS-specific constructs (interface members, type
|
||||||
|
// imports, etc.) and double-fire alongside the TS versions.
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||||
|
'@typescript-eslint/no-shadow': 'error',
|
||||||
|
|
||||||
|
// Policy: kept as warnings, not errors. The codebase has ~70 long-standing
|
||||||
|
// `any` casts and ~15 non-null assertions in matrix-js-sdk interop code.
|
||||||
|
// Promoting to error would block builds on existing usage; turning off
|
||||||
|
// would lose signal on new code. Warnings are visible without blocking.
|
||||||
|
'@typescript-eslint/no-explicit-any': 'warn',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'warn',
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ['*.ts'],
|
files: ['*.ts', '*.tsx'],
|
||||||
rules: {
|
rules: {
|
||||||
'no-undef': 'off',
|
'no-undef': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Upstream-vendored binary parsing copied verbatim from matrix-react-sdk
|
||||||
|
// (src/util/cryptE2ERoomKeys.js header link). Bitwise ops, post-increment
|
||||||
|
// and string concatenation are correct for the domain — clean-up risks
|
||||||
|
// breaking E2E room-key import/export. Keep the body byte-identical to
|
||||||
|
// upstream and disable only the rules that fire on those idioms.
|
||||||
|
files: ['src/util/cryptE2ERoomKeys.js'],
|
||||||
|
rules: {
|
||||||
|
'no-bitwise': 'off',
|
||||||
|
'no-plusplus': 'off',
|
||||||
|
'prefer-template': 'off',
|
||||||
|
'no-param-reassign': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,40 @@ node_modules
|
||||||
package.json
|
package.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
LICENSE
|
LICENSE
|
||||||
README.md
|
README.md
|
||||||
|
|
||||||
|
# Generated by Capacitor / Gradle / AGP — never format these.
|
||||||
|
android/app/build/
|
||||||
|
android/build/
|
||||||
|
android/capacitor-cordova-android-plugins/build/
|
||||||
|
android/app/src/main/assets/public/
|
||||||
|
android/app/src/main/assets/capacitor.config.json
|
||||||
|
android/app/src/main/assets/capacitor.plugins.json
|
||||||
|
android/app/google-services.json
|
||||||
|
|
||||||
|
# Internal docs — hand-formatted markdown. Prettier reflows tables and
|
||||||
|
# fenced code blocks (e.g. YAML inside fences in server-side.md, tables in
|
||||||
|
# architecture.md) in ways that change document structure, not whitespace.
|
||||||
|
# Most paths under docs/ are gitignored anyway via top-level .gitignore.
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# Upstream Cinny GitHub Actions / templates — leave as-is, format drift here
|
||||||
|
# is unrelated to our work.
|
||||||
|
.github/
|
||||||
|
|
||||||
|
# Minified third-party assets.
|
||||||
|
*.min.js
|
||||||
|
|
||||||
|
# Top-level docs / HTML inherited from upstream Cinny — not part of this
|
||||||
|
# infra cleanup's scope. They have minor pre-existing format drift; touching
|
||||||
|
# them would just add review noise.
|
||||||
|
CLAUDE.md
|
||||||
|
CODE_OF_CONDUCT.md
|
||||||
|
CONTRIBUTING.md
|
||||||
|
index.html
|
||||||
|
|
||||||
|
# Upstream-vendored files copied verbatim from external projects (links in
|
||||||
|
# their headers). Keep byte-identical to upstream to make future re-syncs
|
||||||
|
# trivially diffable. Same intent as the per-file ESLint override.
|
||||||
|
src/util/cryptE2ERoomKeys.js
|
||||||
|
src/util/colorMXID.js
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ npm run typecheck # tsc --noEmit
|
||||||
|
|
||||||
Build: **Vite 5.4** with vanilla-extract, WASM, PWA plugins.
|
Build: **Vite 5.4** with vanilla-extract, WASM, PWA plugins.
|
||||||
|
|
||||||
> **Note:** `.husky/pre-commit` is currently commented out. Absolute `npm run typecheck` and `npm run check:eslint` are **already red** by known tech debt (~835 typecheck + 39 eslint errors, see `docs/known-tech-debt-lint/`). Use `bash docs/known-tech-debt-lint/diff.sh` to verify your changes added no new errors, then `npm run build` for the green build check.
|
> **Note:** `.husky/pre-commit` is currently commented out. `npm run check:eslint` is **green** (0 errors, 116 warnings — kept as warn for `no-explicit-any`/`no-non-null-assertion` policy). `npm run typecheck` still has ~32 known errors (residual project bugs after the TS 5.4 + Bundler migration that cleared ~800 module-resolution errors — see `docs/known-tech-debt-lint/`). Use `bash docs/known-tech-debt-lint/diff.sh` to verify your changes added no new typecheck errors, then `npm run build` for the green build check.
|
||||||
|
|
||||||
## Source Layout
|
## Source Layout
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ i18next + `react-i18next`. Translations in `public/locales/{en,ru}/*.json`, orga
|
||||||
- Current vojo work branch: `vojo/dev`
|
- Current vojo work branch: `vojo/dev`
|
||||||
- Semantic-release on `dev` branch
|
- Semantic-release on `dev` branch
|
||||||
- CI: GitHub Actions (build, deploy, docker, netlify)
|
- CI: GitHub Actions (build, deploy, docker, netlify)
|
||||||
- **Husky pre-commit is currently disabled** — `npm run typecheck` and `npm run check:eslint` do not run automatically. Both are **already red** by known tech debt; use `bash docs/known-tech-debt-lint/diff.sh` to check your changes don't add new errors
|
- **Husky pre-commit is currently disabled** — `npm run typecheck` and `npm run check:eslint` do not run automatically. `check:eslint` is green; `typecheck` still has ~32 known errors. Use `bash docs/known-tech-debt-lint/diff.sh` to check your changes don't add new typecheck errors. Re-enable husky once typecheck residual is cleared.
|
||||||
- **Android `versionCode` is monotonic** (commit 8064760, derived from commit count). Don't squash or rebase across release boundaries — Play store rejects downgrades
|
- **Android `versionCode` is monotonic** (commit 8064760, derived from commit count). Don't squash or rebase across release boundaries — Play store rejects downgrades
|
||||||
- **Commit message style** (vojo memory): one sentence ≤25 words; no body; no Co-Authored-By trailer
|
- **Commit message style** (vojo memory): one sentence ≤25 words; no body; no Co-Authored-By trailer
|
||||||
|
|
||||||
|
|
|
||||||
57
docs/known-tech-debt-lint/README.md
Normal file
57
docs/known-tech-debt-lint/README.md
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Известный техдолг по линтеру
|
||||||
|
|
||||||
|
Эта папка фиксирует **известное состояние** `npm run typecheck` в репозитории. Build при этом зелёный, prod задеплоен — это исторический технический долг, не блокер. Папка нужна чтобы при любых изменениях кода сравнивать **delta** (только то что мы добавили), не путаясь в предсуществующих ошибках.
|
||||||
|
|
||||||
|
После апгрейда TypeScript 4.9 → 5.4 + `moduleResolution: "Bundler"` (см. историю коммита) основная масса (~803 из 835 предыдущих ошибок) исчезла. Осталось ~32 ошибки уже про реальные баги/несоответствия типов в нашем коде, не про модульное резолвинг. `npm run check:eslint` теперь — обычный зелёный чек (0 ошибок, 116 warnings), отдельный snapshot не нужен.
|
||||||
|
|
||||||
|
## Состав
|
||||||
|
|
||||||
|
| Файл | Что |
|
||||||
|
|---|---|
|
||||||
|
| `typecheck.snapshot.txt` | Полный stdout `npm run typecheck`. **~61 строка, ~32 ошибки.** |
|
||||||
|
| `diff.sh` | Скрипт сравнения: запускает текущий typecheck, сравнивает с snapshot-ом, выдаёт **только delta**. |
|
||||||
|
|
||||||
|
## Как пользоваться
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash docs/known-tech-debt-lint/diff.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
На чистой ветке выводит:
|
||||||
|
```
|
||||||
|
=== typecheck diff vs known-tech-debt snapshot ===
|
||||||
|
no new typecheck errors
|
||||||
|
```
|
||||||
|
|
||||||
|
Если что-то сломал — выводит конкретные новые ошибки в формате `file.tsx(_,_): error TS...` (line/col маска чтобы pure-line-shift не давал phantom NEW + fixed). Реальные позиции — `npm run typecheck` напрямую. Если случайно починил предсуществующий долг — отчитается «(incidentally fixed: N)» к сведению.
|
||||||
|
|
||||||
|
Скрипт смотрит **working tree**, не staged-состояние. Для строгого pre-commit gate сначала apply'нуть свой stage в чистый worktree (`git stash --keep-index` + `bash diff.sh` + `git stash pop`).
|
||||||
|
|
||||||
|
`npm run check:eslint` запускайте напрямую — он зелёный.
|
||||||
|
|
||||||
|
## Что в долге (TL;DR)
|
||||||
|
|
||||||
|
**Typecheck (~32 ошибок):** реальные несоответствия типов. Категории:
|
||||||
|
|
||||||
|
- TS2345 keyof literal-union mismatch (~14): `mx.getAccountData(string)` / `mx.getStateEvent(...)` ждёт `keyof AccountDataEvents` (узкие литеральные типы), у нас передаются `AccountDataEvent.PoniesEmoteRooms`, `'m.call.member'`, `'in.cinny.spaces'` и т.п. — валидные Matrix event-types, но не в SDK-юнионе.
|
||||||
|
- TS2345 i18next signature (~3): `t('Room.members_count', { count: millify(...) })` — `count` хочет `number`, а `millify()` возвращает `string`. На рантайме отображается корректно (в локалях нет plural-вариантов).
|
||||||
|
- TS2345 / TS18048 `Room | undefined` / `Room | null` после `.filter((r) => !!r)` (~6): TS не пропускает truthy-фильтр без type predicate. UserChips.tsx, AddExisting.tsx, Invites.tsx, GlobalPacks.tsx. Runtime безопасно.
|
||||||
|
- TS2345 `IContent` → `RoomMessageEventContent` (1): MessageEditor.tsx — typing gap между общим content и room-message variant.
|
||||||
|
- TS7006 implicit `any` (6): event-handler params (`evt`, `event`, `ev`) в Message.tsx, EventReaders.tsx, UrlPreviewCard.tsx, LiveChip.tsx, MemberGlance.tsx, ReactionViewer.tsx.
|
||||||
|
- TS2540 read-only `sandbox` (1): CallEmbed.ts — `iframe.sandbox = "..."`. Современные DOM types сделали его `DOMTokenList` read-only, но браузеры всё ещё принимают строку.
|
||||||
|
- TS2353 unknown property `endpoint` (1): push.ts — лишнее поле в `setPusher.data`. SDK типы неполные, sygnal/UnifiedPush его читает.
|
||||||
|
- TS2322 `(number | undefined)[]` → `number[]` (1): usePowerLevelTags.ts — то же truthy-filter narrowing.
|
||||||
|
|
||||||
|
Build зелёный, ESLint зелёный. Все 32 оставшихся ошибки — type-strictness без runtime-импакта (truthy-filter narrowing, узкие SDK literal-union'ы, под-типированные event-handler params, слишком строгий DOM types). Это **известный долг**, не блокер. Будущая чистка — отдельный план (создать `docs/plans/typecheck_residual_cleanup.md` когда возьмёмся).
|
||||||
|
|
||||||
|
## Когда обновлять snapshot
|
||||||
|
|
||||||
|
Когда долг будет частично разруливаться отдельной задачей — после её мерджа пересоздать snapshot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run typecheck > docs/known-tech-debt-lint/typecheck.snapshot.txt 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
И обновить TL;DR в этом README.
|
||||||
|
|
||||||
|
Когда typecheck станет зелёным — удалить эту папку целиком и включить husky pre-commit hook.
|
||||||
91
docs/known-tech-debt-lint/diff.sh
Executable file
91
docs/known-tech-debt-lint/diff.sh
Executable file
|
|
@ -0,0 +1,91 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Compare current `npm run typecheck` output to the known tech-debt snapshot.
|
||||||
|
# Emits ONLY new errors introduced relative to the snapshot — does not dump
|
||||||
|
# the full output, so agents can read the result without burning context.
|
||||||
|
#
|
||||||
|
# Comparison is line/col-insensitive: each error's `(L,C):` location is masked
|
||||||
|
# to `(_,_):` before sorting + comm, so a pure line shift (e.g. one added/
|
||||||
|
# removed line above the error) doesn't trigger a phantom NEW + fixed pair.
|
||||||
|
# Re-run `npm run typecheck` to see real positions for any errors flagged here.
|
||||||
|
#
|
||||||
|
# Caveat: this checks the working tree, not the staged worktree. If you stage
|
||||||
|
# a fix but leave it unstaged, or vice versa, the diff reports the working-tree
|
||||||
|
# state. For a strict pre-commit gate, run from a clean stash-apply state.
|
||||||
|
#
|
||||||
|
# `npm run check:eslint` is now a normal green check (0 errors); no snapshot
|
||||||
|
# needed there. Run it directly if you want to see warnings.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# bash docs/known-tech-debt-lint/diff.sh
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
|
BASELINE_DIR="$ROOT/docs/known-tech-debt-lint"
|
||||||
|
TC_BASE="$BASELINE_DIR/typecheck.snapshot.txt"
|
||||||
|
|
||||||
|
# Temp files registered for cleanup on any exit path (success, error, ^C).
|
||||||
|
TMP_FILES=()
|
||||||
|
cleanup() { [ "${#TMP_FILES[@]}" -gt 0 ] && rm -f "${TMP_FILES[@]}"; }
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# Tracks whether any new errors were introduced. Set to 1 by run_typecheck_diff
|
||||||
|
# when delta > 0; script exits with this code at end so CI / runbooks can use
|
||||||
|
# the script as a gate (e.g. `bash diff.sh && echo OK`).
|
||||||
|
NEW_ERRORS=0
|
||||||
|
|
||||||
|
run_typecheck_diff() {
|
||||||
|
echo "=== typecheck diff vs known-tech-debt snapshot ==="
|
||||||
|
local now tc_rc
|
||||||
|
now="$(mktemp)"
|
||||||
|
TMP_FILES+=("$now")
|
||||||
|
( cd "$ROOT" && npm run typecheck ) >"$now" 2>&1
|
||||||
|
tc_rc=$?
|
||||||
|
# Sanity-check: distinguish "tsc ran and reported errors" (rc=2, expected on
|
||||||
|
# this baseline) from "tsc/npm/node failed to run at all" (rc=other, broken
|
||||||
|
# toolchain). Without this guard a rc=127 "tsc: not found" or rc=1 npm error
|
||||||
|
# could produce stdout with no "error TS" lines and the diff would falsely
|
||||||
|
# report "no new errors" / "incidentally fixed: 33".
|
||||||
|
if [ "$tc_rc" -ne 0 ] && [ "$tc_rc" -ne 2 ] && ! grep -q "error TS" "$now"; then
|
||||||
|
echo " ERROR: 'npm run typecheck' did not run cleanly (exit=$tc_rc):"
|
||||||
|
sed 's/^/ /' "$now"
|
||||||
|
NEW_ERRORS=2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
# Mask `(line,col):` so a pure line shift doesn't change an error's identity.
|
||||||
|
# We compare on the masked form; for NEW lines we display the masked form (the
|
||||||
|
# real position is reproducible by running `npm run typecheck` directly).
|
||||||
|
# `sort` (NOT `sort -u`): we want to preserve cardinality so that two identical
|
||||||
|
# masked errors in the same file aren't collapsed to one — a regression that
|
||||||
|
# adds a duplicate error would otherwise be hidden by the first occurrence.
|
||||||
|
local mask_re='s/\([0-9]+,[0-9]+\):/(_,_):/'
|
||||||
|
local now_masked base_masked
|
||||||
|
now_masked="$(mktemp)"
|
||||||
|
base_masked="$(mktemp)"
|
||||||
|
TMP_FILES+=("$now_masked" "$base_masked")
|
||||||
|
sed -E "$mask_re" "$now" | grep -E "error TS" | sort > "$now_masked"
|
||||||
|
sed -E "$mask_re" "$TC_BASE" | grep -E "error TS" | sort > "$base_masked"
|
||||||
|
|
||||||
|
local new
|
||||||
|
new="$(comm -23 "$now_masked" "$base_masked")"
|
||||||
|
if [ -z "$new" ]; then
|
||||||
|
echo " no new typecheck errors"
|
||||||
|
else
|
||||||
|
local count
|
||||||
|
count="$(printf '%s\n' "$new" | wc -l)"
|
||||||
|
echo " NEW errors: $count (line/col masked — run \`npm run typecheck\` for real positions)"
|
||||||
|
printf '%s\n' "$new" | sed 's/^/ /'
|
||||||
|
NEW_ERRORS=1
|
||||||
|
fi
|
||||||
|
local fixed
|
||||||
|
fixed="$(comm -13 "$now_masked" "$base_masked")"
|
||||||
|
if [ -n "$fixed" ]; then
|
||||||
|
local fcount
|
||||||
|
fcount="$(printf '%s\n' "$fixed" | wc -l)"
|
||||||
|
echo " (incidentally fixed: $fcount)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_typecheck_diff
|
||||||
|
|
||||||
|
exit "$NEW_ERRORS"
|
||||||
61
docs/known-tech-debt-lint/typecheck.snapshot.txt
Normal file
61
docs/known-tech-debt-lint/typecheck.snapshot.txt
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
> vojo@4.11.1 typecheck
|
||||||
|
> tsc --noEmit
|
||||||
|
|
||||||
|
src/app/components/event-readers/EventReaders.tsx(82,31): error TS7006: Parameter 'event' implicitly has an 'any' type.
|
||||||
|
src/app/components/image-pack-view/RoomImagePack.tsx(47,9): error TS2345: Argument of type 'StateEvent.PoniesRoomEmotes' is not assignable to parameter of type 'keyof StateEvents'.
|
||||||
|
src/app/components/image-pack-view/UserImagePack.tsx(16,31): error TS2345: Argument of type 'AccountDataEvent.PoniesUserEmotes' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/components/room-card/RoomCard.tsx(259,18): error TS2345: Argument of type '["Explore.members_count", { count: string; }]' is not assignable to parameter of type '[key: string | string[], options: TOptionsBase & $Dictionary & { defaultValue: string; }] | [key: string | string[], defaultValue: string, options?: (TOptionsBase & $Dictionary) | undefined] | [key: ...]'.
|
||||||
|
Type '["Explore.members_count", { count: string; }]' is not assignable to type '[key: "Explore.members_count" | "Explore.members_count"[], options?: (TOptionsBase & $Dictionary) | undefined]'.
|
||||||
|
Type at position 1 in source is not compatible with type at position 1 in target.
|
||||||
|
Type '{ count: string; }' is not assignable to type 'TOptionsBase & $Dictionary'.
|
||||||
|
Type '{ count: string; }' is not assignable to type 'TOptionsBase'.
|
||||||
|
Types of property 'count' are incompatible.
|
||||||
|
Type 'string' is not assignable to type 'number'.
|
||||||
|
src/app/components/url-preview/UrlPreviewCard.tsx(57,27): error TS7006: Parameter 'evt' implicitly has an 'any' type.
|
||||||
|
src/app/components/user-profile/UserChips.tsx(267,13): error TS18048: 'room' is possibly 'undefined'.
|
||||||
|
src/app/components/user-profile/UserChips.tsx(268,28): error TS2345: Argument of type 'Room | undefined' is not assignable to parameter of type 'Room'.
|
||||||
|
Type 'undefined' is not assignable to type 'Room'.
|
||||||
|
src/app/components/user-profile/UserChips.tsx(271,30): error TS18048: 'room' is possibly 'undefined'.
|
||||||
|
src/app/components/user-profile/UserChips.tsx(272,29): error TS2345: Argument of type 'Room | undefined' is not assignable to parameter of type 'Room'.
|
||||||
|
Type 'undefined' is not assignable to type 'Room'.
|
||||||
|
src/app/components/user-profile/UserChips.tsx(275,25): error TS2345: Argument of type 'Room | undefined' is not assignable to parameter of type 'Room'.
|
||||||
|
Type 'undefined' is not assignable to type 'Room'.
|
||||||
|
src/app/features/add-existing/AddExisting.tsx(168,18): error TS2345: Argument of type '(Room | undefined)[]' is not assignable to parameter of type 'Room[]'.
|
||||||
|
Type 'Room | undefined' is not assignable to type 'Room'.
|
||||||
|
Type 'undefined' is not assignable to type 'Room'.
|
||||||
|
src/app/features/call-status/LiveChip.tsx(90,35): error TS7006: Parameter 'evt' implicitly has an 'any' type.
|
||||||
|
src/app/features/call-status/MemberGlance.tsx(49,23): error TS7006: Parameter 'evt' implicitly has an 'any' type.
|
||||||
|
src/app/features/common-settings/general/RoomJoinRules.tsx(92,52): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
|
||||||
|
Type 'undefined' is not assignable to type 'string'.
|
||||||
|
src/app/features/room/MembersDrawer.tsx(80,16): error TS2345: Argument of type '["Room.members_count", { count: string; }]' is not assignable to parameter of type '[key: string | string[], options: TOptionsBase & $Dictionary & { defaultValue: string; }] | [key: string | string[], defaultValue: string, options?: (TOptionsBase & $Dictionary) | undefined] | [key: ...]'.
|
||||||
|
Type '["Room.members_count", { count: string; }]' is not assignable to type '[key: "Room.members_count" | "Room.members_count"[], options?: (TOptionsBase & $Dictionary) | undefined]'.
|
||||||
|
Type at position 1 in source is not compatible with type at position 1 in target.
|
||||||
|
Type '{ count: string; }' is not assignable to type 'TOptionsBase & $Dictionary'.
|
||||||
|
Type '{ count: string; }' is not assignable to type 'TOptionsBase'.
|
||||||
|
Types of property 'count' are incompatible.
|
||||||
|
Type 'string' is not assignable to type 'number'.
|
||||||
|
src/app/features/room/message/Message.tsx(963,31): error TS7006: Parameter 'ev' implicitly has an 'any' type.
|
||||||
|
src/app/features/room/message/MessageEditor.tsx(156,39): error TS2345: Argument of type 'IContent' is not assignable to parameter of type 'RoomMessageEventContent'.
|
||||||
|
Type 'IContent' is not assignable to type 'BaseTimelineEvent & Without<(Without<ReplyEvent, NoRelationEvent> & NoRelationEvent) | (Without<NoRelationEvent, ReplyEvent> & ReplyEvent), (Without<...> & RelationEvent) | (Without<...> & ReplacementEvent<...>)> & Without<...> & ReplacementEvent<...> & FileContent'.
|
||||||
|
Property '"body"' is missing in type 'IContent' but required in type 'BaseTimelineEvent'.
|
||||||
|
src/app/features/room/reaction-viewer/ReactionViewer.tsx(135,33): error TS7006: Parameter 'event' implicitly has an 'any' type.
|
||||||
|
src/app/features/settings/developer-tools/DevelopTools.tsx(30,31): error TS2345: Argument of type 'string' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/features/settings/developer-tools/DevelopTools.tsx(39,54): error TS2345: Argument of type 'string' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/features/settings/emojis-stickers/GlobalPacks.tsx(161,44): error TS2345: Argument of type '(PackAddress | undefined)[]' is not assignable to parameter of type 'PackAddress[]'.
|
||||||
|
Type 'PackAddress | undefined' is not assignable to type 'PackAddress'.
|
||||||
|
Type 'undefined' is not assignable to type 'PackAddress'.
|
||||||
|
src/app/features/settings/emojis-stickers/GlobalPacks.tsx(164,39): error TS2345: Argument of type '(PackAddress | undefined)[]' is not assignable to parameter of type 'PackAddress[]'.
|
||||||
|
src/app/features/settings/emojis-stickers/GlobalPacks.tsx(311,27): error TS2345: Argument of type 'AccountDataEvent.PoniesEmoteRooms' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/features/settings/emojis-stickers/GlobalPacks.tsx(328,31): error TS2345: Argument of type 'AccountDataEvent.PoniesEmoteRooms' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/hooks/useAccountData.ts(7,62): error TS2345: Argument of type 'string' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/hooks/usePowerLevelTags.ts(14,9): error TS2322: Type '(number | undefined)[]' is not assignable to type 'number[]'.
|
||||||
|
Type 'number | undefined' is not assignable to type 'number'.
|
||||||
|
Type 'undefined' is not assignable to type 'number'.
|
||||||
|
src/app/pages/client/inbox/Invites.tsx(722,45): error TS2345: Argument of type 'Room | null' is not assignable to parameter of type 'Room'.
|
||||||
|
Type 'null' is not assignable to type 'Room'.
|
||||||
|
src/app/pages/client/sidebar/SpaceTabs.tsx(750,27): error TS2345: Argument of type 'AccountDataEvent.VojoSpaces' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/pages/client/sidebar/SpaceTabs.tsx(797,25): error TS2345: Argument of type 'AccountDataEvent.VojoSpaces' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/plugins/call/CallEmbed.ts(129,12): error TS2540: Cannot assign to 'sandbox' because it is a read-only property.
|
||||||
|
src/app/plugins/recent-emoji.ts(45,21): error TS2345: Argument of type 'AccountDataEvent.ElementRecentEmoji' is not assignable to parameter of type 'keyof AccountDataEvents'.
|
||||||
|
src/app/utils/push.ts(160,9): error TS2353: Object literal may only specify known properties, and 'endpoint' does not exist in type '{ format?: string | undefined; url?: string | undefined; brand?: string | undefined; }'.
|
||||||
446
package-lock.json
generated
446
package-lock.json
generated
|
|
@ -89,12 +89,12 @@
|
||||||
"@types/react-google-recaptcha": "2.1.8",
|
"@types/react-google-recaptcha": "2.1.8",
|
||||||
"@types/sanitize-html": "2.9.0",
|
"@types/sanitize-html": "2.9.0",
|
||||||
"@types/ua-parser-js": "0.7.36",
|
"@types/ua-parser-js": "0.7.36",
|
||||||
"@typescript-eslint/eslint-plugin": "5.46.1",
|
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||||
"@typescript-eslint/parser": "5.46.1",
|
"@typescript-eslint/parser": "7.18.0",
|
||||||
"@vitejs/plugin-react": "4.2.0",
|
"@vitejs/plugin-react": "4.2.0",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
"cz-conventional-changelog": "3.3.0",
|
"cz-conventional-changelog": "3.3.0",
|
||||||
"eslint": "8.29.0",
|
"eslint": "8.57.1",
|
||||||
"eslint-config-airbnb": "19.0.4",
|
"eslint-config-airbnb": "19.0.4",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-plugin-import": "2.29.1",
|
"eslint-plugin-import": "2.29.1",
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"lint-staged": "16.3.2",
|
"lint-staged": "16.3.2",
|
||||||
"prettier": "2.8.1",
|
"prettier": "2.8.1",
|
||||||
"typescript": "4.9.4",
|
"typescript": "5.4.5",
|
||||||
"vite": "5.4.19",
|
"vite": "5.4.19",
|
||||||
"vite-plugin-pwa": "0.20.5",
|
"vite-plugin-pwa": "0.20.5",
|
||||||
"vite-plugin-static-copy": "1.0.4",
|
"vite-plugin-static-copy": "1.0.4",
|
||||||
|
|
@ -2378,15 +2378,45 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "1.4.1",
|
"version": "4.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
|
||||||
"integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
|
"integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-visitor-keys": "^3.4.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint-community/regexpp": {
|
||||||
|
"version": "4.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
|
||||||
|
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.4.0",
|
"espree": "^9.6.0",
|
||||||
"globals": "^13.19.0",
|
"globals": "^13.19.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
|
|
@ -2406,6 +2436,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
||||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"type-fest": "^0.20.2"
|
"type-fest": "^0.20.2"
|
||||||
},
|
},
|
||||||
|
|
@ -2421,6 +2452,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "(MIT OR CC0-1.0)",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
|
|
@ -2428,6 +2460,16 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint/js": {
|
||||||
|
"version": "8.57.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
|
||||||
|
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fontsource-variable/jetbrains-mono": {
|
"node_modules/@fontsource-variable/jetbrains-mono": {
|
||||||
"version": "5.2.5",
|
"version": "5.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource-variable/jetbrains-mono/-/jetbrains-mono-5.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@fontsource-variable/jetbrains-mono/-/jetbrains-mono-5.2.5.tgz",
|
||||||
|
|
@ -2489,13 +2531,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.14",
|
"version": "0.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
|
||||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
"integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
|
||||||
"deprecated": "Use @eslint/config-array instead",
|
"deprecated": "Use @eslint/config-array instead",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@humanwhocodes/object-schema": "^2.0.2",
|
"@humanwhocodes/object-schema": "^2.0.3",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"minimatch": "^3.0.5"
|
"minimatch": "^3.0.5"
|
||||||
},
|
},
|
||||||
|
|
@ -2521,7 +2564,8 @@
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
|
||||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||||
"deprecated": "Use @eslint/object-schema instead",
|
"deprecated": "Use @eslint/object-schema instead",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/@internationalized/date": {
|
"node_modules/@internationalized/date": {
|
||||||
"version": "3.7.0",
|
"version": "3.7.0",
|
||||||
|
|
@ -5153,12 +5197,6 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/json-schema": {
|
|
||||||
"version": "7.0.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
|
||||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/json5": {
|
"node_modules/@types/json5": {
|
||||||
"version": "0.0.29",
|
"version": "0.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
|
|
@ -5238,12 +5276,6 @@
|
||||||
"integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==",
|
"integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
|
||||||
"version": "7.5.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
|
|
||||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/slice-ansi": {
|
"node_modules/@types/slice-ansi": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
||||||
|
|
@ -5263,31 +5295,32 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz",
|
||||||
"integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==",
|
"integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "5.46.1",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/type-utils": "5.46.1",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
"@typescript-eslint/utils": "5.46.1",
|
"@typescript-eslint/type-utils": "7.18.0",
|
||||||
"debug": "^4.3.4",
|
"@typescript-eslint/utils": "7.18.0",
|
||||||
"ignore": "^5.2.0",
|
"@typescript-eslint/visitor-keys": "7.18.0",
|
||||||
"natural-compare-lite": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"regexpp": "^3.2.0",
|
"ignore": "^5.3.1",
|
||||||
"semver": "^7.3.7",
|
"natural-compare": "^1.4.0",
|
||||||
"tsutils": "^3.21.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^7.0.0",
|
||||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"eslint": "^8.56.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
|
|
@ -5296,25 +5329,27 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
|
||||||
"integrity": "sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==",
|
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "5.46.1",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
"@typescript-eslint/types": "5.46.1",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.46.1",
|
"@typescript-eslint/typescript-estree": "7.18.0",
|
||||||
|
"@typescript-eslint/visitor-keys": "7.18.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"eslint": "^8.56.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
|
|
@ -5323,16 +5358,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz",
|
||||||
"integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==",
|
"integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.46.1",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.46.1"
|
"@typescript-eslint/visitor-keys": "7.18.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
@ -5340,25 +5376,26 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz",
|
||||||
"integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==",
|
"integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "5.46.1",
|
"@typescript-eslint/typescript-estree": "7.18.0",
|
||||||
"@typescript-eslint/utils": "5.46.1",
|
"@typescript-eslint/utils": "7.18.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"tsutils": "^3.21.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "*"
|
"eslint": "^8.56.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
|
|
@ -5367,12 +5404,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz",
|
||||||
"integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==",
|
"integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
@ -5380,21 +5418,23 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz",
|
||||||
"integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==",
|
"integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.46.1",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.46.1",
|
"@typescript-eslint/visitor-keys": "7.18.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"globby": "^11.1.0",
|
"globby": "^11.1.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
"semver": "^7.3.7",
|
"minimatch": "^9.0.4",
|
||||||
"tsutils": "^3.21.0"
|
"semver": "^7.6.0",
|
||||||
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
@ -5406,49 +5446,80 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||||
"version": "5.46.1",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
|
||||||
"integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==",
|
"integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/json-schema": "^7.0.9",
|
"balanced-match": "^1.0.0"
|
||||||
"@types/semver": "^7.3.12",
|
}
|
||||||
"@typescript-eslint/scope-manager": "5.46.1",
|
},
|
||||||
"@typescript-eslint/types": "5.46.1",
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||||
"@typescript-eslint/typescript-estree": "5.46.1",
|
"version": "9.0.9",
|
||||||
"eslint-scope": "^5.1.1",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||||
"eslint-utils": "^3.0.0",
|
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||||
"semver": "^7.3.7"
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": ">=16 || 14 >=14.17"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript-eslint/utils": {
|
||||||
|
"version": "7.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz",
|
||||||
|
"integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
|
"@typescript-eslint/types": "7.18.0",
|
||||||
|
"@typescript-eslint/typescript-estree": "7.18.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"eslint": "^8.56.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "5.46.1",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz",
|
||||||
"integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==",
|
"integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.46.1",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"eslint-visitor-keys": "^3.3.0"
|
"eslint-visitor-keys": "^3.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ungap/structured-clone": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/@vanilla-extract/babel-plugin-debug-ids": {
|
"node_modules/@vanilla-extract/babel-plugin-debug-ids": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.2.0.tgz",
|
||||||
|
|
@ -5607,6 +5678,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -5629,10 +5701,11 @@
|
||||||
"integrity": "sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA=="
|
"integrity": "sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA=="
|
||||||
},
|
},
|
||||||
"node_modules/ajv": {
|
"node_modules/ajv": {
|
||||||
"version": "6.12.6",
|
"version": "6.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
|
||||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
"integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
"fast-json-stable-stringify": "^2.0.0",
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
|
|
@ -5806,6 +5879,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
|
@ -7216,6 +7290,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-type": "^4.0.0"
|
"path-type": "^4.0.0"
|
||||||
},
|
},
|
||||||
|
|
@ -7608,50 +7683,50 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.29.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
|
||||||
"integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
|
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
||||||
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/eslintrc": "^1.3.3",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.6",
|
"@eslint-community/regexpp": "^4.6.1",
|
||||||
|
"@eslint/eslintrc": "^2.1.4",
|
||||||
|
"@eslint/js": "8.57.1",
|
||||||
|
"@humanwhocodes/config-array": "^0.13.0",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
"ajv": "^6.10.0",
|
"@ungap/structured-clone": "^1.2.0",
|
||||||
|
"ajv": "^6.12.4",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"cross-spawn": "^7.0.2",
|
"cross-spawn": "^7.0.2",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"doctrine": "^3.0.0",
|
"doctrine": "^3.0.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.1.1",
|
"eslint-scope": "^7.2.2",
|
||||||
"eslint-utils": "^3.0.0",
|
"eslint-visitor-keys": "^3.4.3",
|
||||||
"eslint-visitor-keys": "^3.3.0",
|
"espree": "^9.6.1",
|
||||||
"espree": "^9.4.0",
|
"esquery": "^1.4.2",
|
||||||
"esquery": "^1.4.0",
|
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"file-entry-cache": "^6.0.1",
|
"file-entry-cache": "^6.0.1",
|
||||||
"find-up": "^5.0.0",
|
"find-up": "^5.0.0",
|
||||||
"glob-parent": "^6.0.2",
|
"glob-parent": "^6.0.2",
|
||||||
"globals": "^13.15.0",
|
"globals": "^13.19.0",
|
||||||
"grapheme-splitter": "^1.0.4",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.0.0",
|
|
||||||
"imurmurhash": "^0.1.4",
|
"imurmurhash": "^0.1.4",
|
||||||
"is-glob": "^4.0.0",
|
"is-glob": "^4.0.0",
|
||||||
"is-path-inside": "^3.0.3",
|
"is-path-inside": "^3.0.3",
|
||||||
"js-sdsl": "^4.1.4",
|
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
"levn": "^0.4.1",
|
"levn": "^0.4.1",
|
||||||
"lodash.merge": "^4.6.2",
|
"lodash.merge": "^4.6.2",
|
||||||
"minimatch": "^3.1.2",
|
"minimatch": "^3.1.2",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"optionator": "^0.9.1",
|
"optionator": "^0.9.3",
|
||||||
"regexpp": "^3.2.0",
|
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
"strip-json-comments": "^3.1.0",
|
|
||||||
"text-table": "^0.2.0"
|
"text-table": "^0.2.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -7947,60 +8022,12 @@
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-scope": {
|
|
||||||
"version": "5.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
|
||||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"esrecurse": "^4.3.0",
|
|
||||||
"estraverse": "^4.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-scope/node_modules/estraverse": {
|
|
||||||
"version": "4.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
|
||||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-utils": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"eslint-visitor-keys": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/mysticatea"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"eslint": ">=5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-visitor-keys": {
|
"node_modules/eslint-visitor-keys": {
|
||||||
"version": "3.4.3",
|
"version": "3.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
},
|
},
|
||||||
|
|
@ -8056,6 +8083,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
|
||||||
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
|
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.9.0",
|
"acorn": "^8.9.0",
|
||||||
"acorn-jsx": "^5.3.2",
|
"acorn-jsx": "^5.3.2",
|
||||||
|
|
@ -8783,6 +8811,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||||
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-union": "^2.1.0",
|
"array-union": "^2.1.0",
|
||||||
"dir-glob": "^3.0.1",
|
"dir-glob": "^3.0.1",
|
||||||
|
|
@ -8815,11 +8844,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
||||||
},
|
},
|
||||||
"node_modules/grapheme-splitter": {
|
"node_modules/graphemer": {
|
||||||
"version": "1.0.4",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
||||||
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
|
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/has": {
|
"node_modules/has": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
|
@ -9860,16 +9890,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/js-sdsl": {
|
|
||||||
"version": "4.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz",
|
|
||||||
"integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/js-sdsl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|
@ -9922,7 +9942,8 @@
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/json-stable-stringify-without-jsonify": {
|
"node_modules/json-stable-stringify-without-jsonify": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
|
@ -10949,12 +10970,6 @@
|
||||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/natural-compare-lite": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
|
@ -11430,6 +11445,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
|
@ -12008,18 +12024,6 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regexpp": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/mysticatea"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/regexpu-core": {
|
"node_modules/regexpu-core": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
|
||||||
|
|
@ -12604,6 +12608,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
|
@ -13159,6 +13164,19 @@
|
||||||
"tree-kill": "cli.js"
|
"tree-kill": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-api-utils": {
|
||||||
|
"version": "1.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
|
||||||
|
"integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
||||||
|
|
@ -13188,27 +13206,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
},
|
},
|
||||||
"node_modules/tsutils": {
|
|
||||||
"version": "3.21.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
|
|
||||||
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^1.8.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tsutils/node_modules/tslib": {
|
|
||||||
"version": "1.14.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
|
@ -13308,9 +13305,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.9.4",
|
"version": "5.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
|
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -13318,7 +13315,7 @@
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.2.0"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ua-parser-js": {
|
"node_modules/ua-parser-js": {
|
||||||
|
|
@ -13481,6 +13478,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
package.json
12
package.json
|
|
@ -12,7 +12,7 @@
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "npm run check:eslint && npm run check:prettier",
|
"lint": "npm run check:eslint && npm run check:prettier",
|
||||||
"check:eslint": "eslint src/*",
|
"check:eslint": "eslint src",
|
||||||
"check:prettier": "prettier --check .",
|
"check:prettier": "prettier --check .",
|
||||||
"fix:prettier": "prettier --write .",
|
"fix:prettier": "prettier --write .",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
"commit": "git-cz"
|
"commit": "git-cz"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{ts,tsx,js,jsx}": "eslint",
|
"*.{ts,tsx,js,jsx,mjs,cjs}": "eslint",
|
||||||
"*": "prettier --ignore-unknown --write"
|
"*": "prettier --ignore-unknown --write"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
|
@ -121,12 +121,12 @@
|
||||||
"@types/react-google-recaptcha": "2.1.8",
|
"@types/react-google-recaptcha": "2.1.8",
|
||||||
"@types/sanitize-html": "2.9.0",
|
"@types/sanitize-html": "2.9.0",
|
||||||
"@types/ua-parser-js": "0.7.36",
|
"@types/ua-parser-js": "0.7.36",
|
||||||
"@typescript-eslint/eslint-plugin": "5.46.1",
|
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||||
"@typescript-eslint/parser": "5.46.1",
|
"@typescript-eslint/parser": "7.18.0",
|
||||||
"@vitejs/plugin-react": "4.2.0",
|
"@vitejs/plugin-react": "4.2.0",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
"cz-conventional-changelog": "3.3.0",
|
"cz-conventional-changelog": "3.3.0",
|
||||||
"eslint": "8.29.0",
|
"eslint": "8.57.1",
|
||||||
"eslint-config-airbnb": "19.0.4",
|
"eslint-config-airbnb": "19.0.4",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-plugin-import": "2.29.1",
|
"eslint-plugin-import": "2.29.1",
|
||||||
|
|
@ -136,7 +136,7 @@
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"lint-staged": "16.3.2",
|
"lint-staged": "16.3.2",
|
||||||
"prettier": "2.8.1",
|
"prettier": "2.8.1",
|
||||||
"typescript": "4.9.4",
|
"typescript": "5.4.5",
|
||||||
"vite": "5.4.19",
|
"vite": "5.4.19",
|
||||||
"vite-plugin-pwa": "0.20.5",
|
"vite-plugin-pwa": "0.20.5",
|
||||||
"vite-plugin-static-copy": "1.0.4",
|
"vite-plugin-static-copy": "1.0.4",
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,16 @@ import { fileURLToPath } from 'node:url';
|
||||||
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const ROOT = path.resolve(HERE, '..');
|
const ROOT = path.resolve(HERE, '..');
|
||||||
const LOCALES_DIR = path.join(ROOT, 'public', 'locales');
|
const LOCALES_DIR = path.join(ROOT, 'public', 'locales');
|
||||||
const DEFAULT_OUT = path.join(ROOT, 'android', 'app', 'build', 'generated', 'res', 'push', 'manual');
|
const DEFAULT_OUT = path.join(
|
||||||
|
ROOT,
|
||||||
|
'android',
|
||||||
|
'app',
|
||||||
|
'build',
|
||||||
|
'generated',
|
||||||
|
'res',
|
||||||
|
'push',
|
||||||
|
'manual'
|
||||||
|
);
|
||||||
|
|
||||||
// Keys from the Push namespace that end up in Android resources.
|
// Keys from the Push namespace that end up in Android resources.
|
||||||
// SW-only strings (encrypted_message, incoming_call, open_to_answer) are
|
// SW-only strings (encrypted_message, incoming_call, open_to_answer) are
|
||||||
|
|
@ -140,10 +149,7 @@ function verifyParity(bundles) {
|
||||||
for (const entry of tokenSets.slice(1)) {
|
for (const entry of tokenSets.slice(1)) {
|
||||||
const baselineArr = [...baseline.tokens].sort();
|
const baselineArr = [...baseline.tokens].sort();
|
||||||
const entryArr = [...entry.tokens].sort();
|
const entryArr = [...entry.tokens].sort();
|
||||||
if (
|
if (baselineArr.length !== entryArr.length || baselineArr.some((t, i) => t !== entryArr[i])) {
|
||||||
baselineArr.length !== entryArr.length ||
|
|
||||||
baselineArr.some((t, i) => t !== entryArr[i])
|
|
||||||
) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Placeholder drift on Push.${key}: ` +
|
`Placeholder drift on Push.${key}: ` +
|
||||||
`${baseline.locale}=${JSON.stringify(baselineArr)}, ` +
|
`${baseline.locale}=${JSON.stringify(baselineArr)}, ` +
|
||||||
|
|
@ -168,9 +174,7 @@ function emitResource(locale, bundle, resDir) {
|
||||||
const raw = bundle[key];
|
const raw = bundle[key];
|
||||||
const { text, placeholders } = convertPlaceholders(raw, locale, key);
|
const { text, placeholders } = convertPlaceholders(raw, locale, key);
|
||||||
const formattedAttr = placeholders.size > 0 ? ' formatted="true"' : '';
|
const formattedAttr = placeholders.size > 0 ? ' formatted="true"' : '';
|
||||||
lines.push(
|
lines.push(` <string name="push_${key}"${formattedAttr}>${xmlEscape(text)}</string>`);
|
||||||
` <string name="push_${key}"${formattedAttr}>${xmlEscape(text)}</string>`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
lines.push('</resources>');
|
lines.push('</resources>');
|
||||||
lines.push('');
|
lines.push('');
|
||||||
|
|
|
||||||
|
|
@ -151,10 +151,7 @@ export function AdditionalCreatorInput({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingTile
|
<SettingTile title={t('Create.founders')} description={t('Create.founders_desc')}>
|
||||||
title={t('Create.founders')}
|
|
||||||
description={t('Create.founders_desc')}
|
|
||||||
>
|
|
||||||
<Box shrink="No" direction="Column" gap="100">
|
<Box shrink="No" direction="Column" gap="100">
|
||||||
<Box gap="200" wrap="Wrap">
|
<Box gap="200" wrap="Wrap">
|
||||||
<Chip type="button" variant="Primary" radii="Pill" outlined>
|
<Chip type="button" variant="Primary" radii="Pill" outlined>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
} from '../../plugins/markdown';
|
} from '../../plugins/markdown';
|
||||||
import { findAndReplace } from '../../utils/findAndReplace';
|
import { findAndReplace } from '../../utils/findAndReplace';
|
||||||
import { sanitizeForRegex } from '../../utils/regex';
|
import { sanitizeForRegex } from '../../utils/regex';
|
||||||
import { getCanonicalAliasOrRoomId, isUserId } from '../../utils/matrix';
|
import { isUserId } from '../../utils/matrix';
|
||||||
|
|
||||||
export type OutputOptions = {
|
export type OutputOptions = {
|
||||||
allowTextFormatting?: boolean;
|
allowTextFormatting?: boolean;
|
||||||
|
|
@ -215,7 +215,7 @@ export const getMentions = (mx: MatrixClient, roomId: string, editor: Editor): M
|
||||||
if (node.name === '@room') {
|
if (node.name === '@room') {
|
||||||
mentionData.room = true;
|
mentionData.room = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUserId(node.id) && node.id !== mx.getUserId()) {
|
if (isUserId(node.id) && node.id !== mx.getUserId()) {
|
||||||
mentionData.users.add(node.id);
|
mentionData.users.add(node.id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,11 @@ export function ImageTile({
|
||||||
radii="Pill"
|
radii="Pill"
|
||||||
onClick={() => onDeleteToggle?.(defaultShortcode)}
|
onClick={() => onDeleteToggle?.(defaultShortcode)}
|
||||||
>
|
>
|
||||||
{deleted ? <Text size="B300">{t('RoomSettings.undo')}</Text> : <Icon size="50" src={Icons.Delete} />}
|
{deleted ? (
|
||||||
|
<Text size="B300">{t('RoomSettings.undo')}</Text>
|
||||||
|
) : (
|
||||||
|
<Icon size="50" src={Icons.Delete} />
|
||||||
|
)}
|
||||||
</Chip>
|
</Chip>
|
||||||
{!deleted && (
|
{!deleted && (
|
||||||
<Chip
|
<Chip
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ export const Reaction = as<
|
||||||
{reaction.startsWith('mxc://') ? (
|
{reaction.startsWith('mxc://') ? (
|
||||||
<img
|
<img
|
||||||
className={css.ReactionImg}
|
className={css.ReactionImg}
|
||||||
src={mxcUrlToHttp(mx, reaction, useAuthentication) ?? reaction
|
src={mxcUrlToHttp(mx, reaction, useAuthentication) ?? reaction}
|
||||||
}
|
|
||||||
alt={reaction}
|
alt={reaction}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -136,23 +136,27 @@ export function PageHero({
|
||||||
subTitle,
|
subTitle,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
icon: ReactNode;
|
icon?: ReactNode;
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
subTitle: ReactNode;
|
subTitle?: ReactNode;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Box direction="Column" gap="400">
|
<Box direction="Column" gap="400">
|
||||||
<Box direction="Column" alignItems="Center" gap="200">
|
{icon && (
|
||||||
{icon}
|
<Box direction="Column" alignItems="Center" gap="200">
|
||||||
</Box>
|
{icon}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
<Box as="h2" direction="Column" gap="200" alignItems="Center">
|
<Box as="h2" direction="Column" gap="200" alignItems="Center">
|
||||||
<Text align="Center" size="H2">
|
<Text align="Center" size="H2">
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
<Text align="Center" priority="400">
|
{subTitle && (
|
||||||
{subTitle}
|
<Text align="Center" priority="400">
|
||||||
</Text>
|
{subTitle}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{children}
|
{children}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -152,12 +152,7 @@ export function PushPermissionPrompt() {
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
<Box direction="Row" gap="200" justifyContent="End">
|
<Box direction="Row" gap="200" justifyContent="End">
|
||||||
<Button
|
<Button variant="Secondary" fill="Soft" onClick={handleLater} disabled={busy}>
|
||||||
variant="Secondary"
|
|
||||||
fill="Soft"
|
|
||||||
onClick={handleLater}
|
|
||||||
disabled={busy}
|
|
||||||
>
|
|
||||||
<Text size="B400">{t('Settings.push_prompt_later')}</Text>
|
<Text size="B400">{t('Settings.push_prompt_later')}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,9 @@ export const RoomCard = as<'div', RoomCardProps>(
|
||||||
{typeof joinedMemberCount === 'number' && (
|
{typeof joinedMemberCount === 'number' && (
|
||||||
<Box gap="100">
|
<Box gap="100">
|
||||||
<Icon size="50" src={Icons.User} />
|
<Icon size="50" src={Icons.User} />
|
||||||
<Text size="T200">{t('Explore.members_count', { count: millify(joinedMemberCount) })}</Text>
|
<Text size="T200">
|
||||||
|
{t('Explore.members_count', { count: millify(joinedMemberCount) })}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{typeof joinedRoomId === 'string' && (
|
{typeof joinedRoomId === 'string' && (
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,11 @@ export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) =>
|
||||||
<Text size="T200" priority="300">
|
<Text size="T200" priority="300">
|
||||||
<Trans
|
<Trans
|
||||||
i18nKey="Room.created_by"
|
i18nKey="Room.created_by"
|
||||||
values={{ creator: creatorName, date: timeDayMonthYear(ts), time: timeHourMinute(ts, hour24Clock) }}
|
values={{
|
||||||
|
creator: creatorName,
|
||||||
|
date: timeDayMonthYear(ts),
|
||||||
|
time: timeHourMinute(ts, hour24Clock),
|
||||||
|
}}
|
||||||
components={{ bold: <b /> }}
|
components={{ bold: <b /> }}
|
||||||
/>
|
/>
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,9 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text size="B300">{expandState ? t('RoomSettings.collapse') : t('RoomSettings.expand')}</Text>
|
<Text size="B300">
|
||||||
|
{expandState ? t('RoomSettings.collapse') : t('RoomSettings.expand')}
|
||||||
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -210,7 +212,9 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Box justifyContent="SpaceBetween">
|
<Box justifyContent="SpaceBetween">
|
||||||
<Text size="L400">{t('RoomSettings.events')}</Text>
|
<Text size="L400">{t('RoomSettings.events')}</Text>
|
||||||
<Text size="L400">{t('RoomSettings.total', { count: roomState.size })}</Text>
|
<Text size="L400">
|
||||||
|
{t('RoomSettings.total', { count: roomState.size })}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<CutoutCard>
|
<CutoutCard>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|
@ -300,7 +304,9 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
>
|
>
|
||||||
<Box grow="Yes">
|
<Box grow="Yes">
|
||||||
<Text size="T200" truncate>
|
<Text size="T200" truncate>
|
||||||
{stateKey ? `"${stateKey}"` : t('RoomSettings.default_key')}
|
{stateKey
|
||||||
|
? `"${stateKey}"`
|
||||||
|
: t('RoomSettings.default_key')}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
@ -339,7 +345,11 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text size="B300">{expandAccountData ? t('RoomSettings.collapse') : t('RoomSettings.expand')}</Text>
|
<Text size="B300">
|
||||||
|
{expandAccountData
|
||||||
|
? t('RoomSettings.collapse')
|
||||||
|
: t('RoomSettings.expand')}
|
||||||
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -347,7 +357,9 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Box justifyContent="SpaceBetween">
|
<Box justifyContent="SpaceBetween">
|
||||||
<Text size="L400">{t('RoomSettings.events')}</Text>
|
<Text size="L400">{t('RoomSettings.events')}</Text>
|
||||||
<Text size="L400">{t('RoomSettings.total', { count: accountData.size })}</Text>
|
<Text size="L400">
|
||||||
|
{t('RoomSettings.total', { count: accountData.size })}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<CutoutCard>
|
<CutoutCard>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,11 @@ export function SendRoomEvent({ type, stateKey, requestClose }: SendRoomEventPro
|
||||||
aria-disabled={submitting}
|
aria-disabled={submitting}
|
||||||
>
|
>
|
||||||
<Box shrink="No" direction="Column" gap="100">
|
<Box shrink="No" direction="Column" gap="100">
|
||||||
<Text size="L400">{composeStateEvent ? t('RoomSettings.state_event_type') : t('RoomSettings.message_event_type')}</Text>
|
<Text size="L400">
|
||||||
|
{composeStateEvent
|
||||||
|
? t('RoomSettings.state_event_type')
|
||||||
|
: t('RoomSettings.message_event_type')}
|
||||||
|
</Text>
|
||||||
<Box gap="300">
|
<Box gap="300">
|
||||||
<Box grow="Yes" direction="Column">
|
<Box grow="Yes" direction="Column">
|
||||||
<Input
|
<Input
|
||||||
|
|
|
||||||
|
|
@ -98,10 +98,7 @@ function CreatePackTile({ packs, roomId }: CreatePackTileProps) {
|
||||||
direction="Column"
|
direction="Column"
|
||||||
gap="400"
|
gap="400"
|
||||||
>
|
>
|
||||||
<SettingTile
|
<SettingTile title={t('RoomSettings.new_pack')} description={t('RoomSettings.new_pack_desc')}>
|
||||||
title={t('RoomSettings.new_pack')}
|
|
||||||
description={t('RoomSettings.new_pack_desc')}
|
|
||||||
>
|
|
||||||
<Box
|
<Box
|
||||||
style={{ marginTop: config.space.S200 }}
|
style={{ marginTop: config.space.S200 }}
|
||||||
as="form"
|
as="form"
|
||||||
|
|
|
||||||
|
|
@ -72,9 +72,7 @@ export function RoomPublishedAddresses({ permissions }: RoomPublishedAddressesPr
|
||||||
{publishedAliases.length === 0 ? (
|
{publishedAliases.length === 0 ? (
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Text size="L400">{t('RoomSettings.no_addresses')}</Text>
|
<Text size="L400">{t('RoomSettings.no_addresses')}</Text>
|
||||||
<Text size="T200">
|
<Text size="T200">{t('RoomSettings.no_addresses_hint')}</Text>
|
||||||
{t('RoomSettings.no_addresses_hint')}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Box direction="Column" gap="300">
|
<Box direction="Column" gap="300">
|
||||||
|
|
@ -273,7 +271,9 @@ function LocalAddressesList({
|
||||||
{selectedAliases.length > 0 && (
|
{selectedAliases.length > 0 && (
|
||||||
<Box gap="200">
|
<Box gap="200">
|
||||||
<Box grow="Yes">
|
<Box grow="Yes">
|
||||||
<Text size="L400">{t('RoomSettings.selected_count', { count: selectedAliases.length })}</Text>
|
<Text size="L400">
|
||||||
|
{t('RoomSettings.selected_count', { count: selectedAliases.length })}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box shrink="No" gap="Inherit">
|
<Box shrink="No" gap="Inherit">
|
||||||
{canEditCanonical &&
|
{canEditCanonical &&
|
||||||
|
|
|
||||||
|
|
@ -130,9 +130,7 @@ export function RoomEncryption({ permissions }: RoomEncryptionProps) {
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Header>
|
</Header>
|
||||||
<Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
|
<Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
|
||||||
<Text priority="400">
|
<Text priority="400">{t('RoomSettings.enable_encryption_confirm')}</Text>
|
||||||
{t('RoomSettings.enable_encryption_confirm')}
|
|
||||||
</Text>
|
|
||||||
<Button type="submit" variant="Primary" onClick={handleEnable}>
|
<Button type="submit" variant="Primary" onClick={handleEnable}>
|
||||||
<Text size="B400">{t('RoomSettings.enable_e2e_encryption')}</Text>
|
<Text size="B400">{t('RoomSettings.enable_e2e_encryption')}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,11 @@ function RoomUpgradeDialog({ requestClose }: { requestClose: () => void }) {
|
||||||
size="500"
|
size="500"
|
||||||
>
|
>
|
||||||
<Box grow="Yes">
|
<Box grow="Yes">
|
||||||
<Text size="H4">{room.isSpaceRoom() ? t('RoomSettings.space_upgrade') : t('RoomSettings.room_upgrade')}</Text>
|
<Text size="H4">
|
||||||
|
{room.isSpaceRoom()
|
||||||
|
? t('RoomSettings.space_upgrade')
|
||||||
|
: t('RoomSettings.room_upgrade')}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<IconButton size="300" onClick={requestClose} radii="300">
|
<IconButton size="300" onClick={requestClose} radii="300">
|
||||||
<Icon src={Icons.Cross} />
|
<Icon src={Icons.Cross} />
|
||||||
|
|
@ -150,7 +154,11 @@ function RoomUpgradeDialog({ requestClose }: { requestClose: () => void }) {
|
||||||
disabled={upgrading}
|
disabled={upgrading}
|
||||||
before={upgrading && <Spinner size="200" variant="Secondary" fill="Solid" />}
|
before={upgrading && <Spinner size="200" variant="Secondary" fill="Solid" />}
|
||||||
>
|
>
|
||||||
<Text size="B400">{room.isSpaceRoom() ? t('RoomSettings.upgrade_space') : t('RoomSettings.upgrade_room')}</Text>
|
<Text size="B400">
|
||||||
|
{room.isSpaceRoom()
|
||||||
|
? t('RoomSettings.upgrade_space')
|
||||||
|
: t('RoomSettings.upgrade_room')}
|
||||||
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
@ -216,11 +224,15 @@ export function RoomUpgrade({ permissions, requestClose }: RoomUpgradeProps) {
|
||||||
gap="400"
|
gap="400"
|
||||||
>
|
>
|
||||||
<SettingTile
|
<SettingTile
|
||||||
title={room.isSpaceRoom() ? t('RoomSettings.upgrade_space') : t('RoomSettings.upgrade_room')}
|
title={
|
||||||
|
room.isSpaceRoom() ? t('RoomSettings.upgrade_space') : t('RoomSettings.upgrade_room')
|
||||||
|
}
|
||||||
description={
|
description={
|
||||||
replacementRoom
|
replacementRoom
|
||||||
? tombstoneContent.body ||
|
? tombstoneContent.body ||
|
||||||
(room.isSpaceRoom() ? t('RoomSettings.space_replaced') : t('RoomSettings.room_replaced'))
|
(room.isSpaceRoom()
|
||||||
|
? t('RoomSettings.space_replaced')
|
||||||
|
: t('RoomSettings.room_replaced'))
|
||||||
: t('RoomSettings.current_version', { version: roomVersion })
|
: t('RoomSettings.current_version', { version: roomVersion })
|
||||||
}
|
}
|
||||||
after={
|
after={
|
||||||
|
|
@ -234,7 +246,9 @@ export function RoomUpgrade({ permissions, requestClose }: RoomUpgradeProps) {
|
||||||
radii="300"
|
radii="300"
|
||||||
onClick={handleOpenOldRoom}
|
onClick={handleOpenOldRoom}
|
||||||
>
|
>
|
||||||
<Text size="B300">{room.isSpaceRoom() ? t('RoomSettings.old_space') : t('RoomSettings.old_room')}</Text>
|
<Text size="B300">
|
||||||
|
{room.isSpaceRoom() ? t('RoomSettings.old_space') : t('RoomSettings.old_room')}
|
||||||
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{replacementRoom ? (
|
{replacementRoom ? (
|
||||||
|
|
@ -245,7 +259,11 @@ export function RoomUpgrade({ permissions, requestClose }: RoomUpgradeProps) {
|
||||||
radii="300"
|
radii="300"
|
||||||
onClick={handleOpenRoom}
|
onClick={handleOpenRoom}
|
||||||
>
|
>
|
||||||
<Text size="B300">{room.isSpaceRoom() ? t('RoomSettings.open_new_space') : t('RoomSettings.open_new_room')}</Text>
|
<Text size="B300">
|
||||||
|
{room.isSpaceRoom()
|
||||||
|
? t('RoomSettings.open_new_space')
|
||||||
|
: t('RoomSettings.open_new_room')}
|
||||||
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,9 @@ export function PermissionGroups({
|
||||||
<Text size="B300" truncate>
|
<Text size="B300" truncate>
|
||||||
{tag.name}
|
{tag.name}
|
||||||
</Text>
|
</Text>
|
||||||
{value < maxPower && <Text size="T200">{t('RoomSettings.and_above')}</Text>}
|
{value < maxPower && (
|
||||||
|
<Text size="T200">{t('RoomSettings.and_above')}</Text>
|
||||||
|
)}
|
||||||
</Chip>
|
</Chip>
|
||||||
)}
|
)}
|
||||||
</PowerSwitcher>
|
</PowerSwitcher>
|
||||||
|
|
|
||||||
|
|
@ -474,7 +474,9 @@ export function PowersEditor({ powerLevels, requestClose }: PowersEditorProps) {
|
||||||
<Tooltip style={{ maxWidth: toRem(200) }}>
|
<Tooltip style={{ maxWidth: toRem(200) }}>
|
||||||
{usedPowers.has(power) ? (
|
{usedPowers.has(power) ? (
|
||||||
<Box direction="Column">
|
<Box direction="Column">
|
||||||
<Text size="L400">{t('RoomSettings.used_power_level')}</Text>
|
<Text size="L400">
|
||||||
|
{t('RoomSettings.used_power_level')}
|
||||||
|
</Text>
|
||||||
<Text size="T200">
|
<Text size="T200">
|
||||||
{t('RoomSettings.used_power_level_desc')}
|
{t('RoomSettings.used_power_level_desc')}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,9 @@ export function CreateChat({ defaultUserId }: CreateChatProps) {
|
||||||
<Box shrink="No" style={{ minWidth: toRem(150) }} direction="Column" gap="100">
|
<Box shrink="No" style={{ minWidth: toRem(150) }} direction="Column" gap="100">
|
||||||
<Text size="L400">{t('Direct.server')}</Text>
|
<Text size="L400">{t('Direct.server')}</Text>
|
||||||
<Input
|
<Input
|
||||||
defaultValue={defaultServer && defaultServer !== userServer ? defaultServer : undefined}
|
defaultValue={
|
||||||
|
defaultServer && defaultServer !== userServer ? defaultServer : undefined
|
||||||
|
}
|
||||||
placeholder={userServer}
|
placeholder={userServer}
|
||||||
name="serverInput"
|
name="serverInput"
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,9 @@ function CreateRoomModal({ state }: CreateRoomModalProps) {
|
||||||
>
|
>
|
||||||
<Box grow="Yes">
|
<Box grow="Yes">
|
||||||
<Text size="H4">
|
<Text size="H4">
|
||||||
{type === CreateRoomType.VoiceRoom ? t('Create.new_voice_room') : t('Create.new_chat_room')}
|
{type === CreateRoomType.VoiceRoom
|
||||||
|
? t('Create.new_voice_room')
|
||||||
|
: t('Create.new_chat_room')}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box shrink="No">
|
<Box shrink="No">
|
||||||
|
|
|
||||||
|
|
@ -256,9 +256,11 @@ export function CreateSpaceForm({ defaultAccess, space, onCreate }: CreateSpaceF
|
||||||
<Text size="T300" style={{ color: color.Critical.Main }}>
|
<Text size="T300" style={{ color: color.Critical.Main }}>
|
||||||
<b>
|
<b>
|
||||||
{error instanceof MatrixError && error.name === ErrorCode.M_LIMIT_EXCEEDED
|
{error instanceof MatrixError && error.name === ErrorCode.M_LIMIT_EXCEEDED
|
||||||
? t('Create.rate_limited', { minutes: millisecondsToMinutes(
|
? t('Create.rate_limited', {
|
||||||
(error.data.retry_after_ms as number | undefined) ?? 0
|
minutes: millisecondsToMinutes(
|
||||||
) })
|
(error.data.retry_after_ms as number | undefined) ?? 0
|
||||||
|
),
|
||||||
|
})
|
||||||
: error.message}
|
: error.message}
|
||||||
</b>
|
</b>
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ export function LobbyHero() {
|
||||||
const name = useRoomName(space);
|
const name = useRoomName(space);
|
||||||
const topic = useRoomTopic(space);
|
const topic = useRoomTopic(space);
|
||||||
const avatarMxc = useRoomAvatar(space);
|
const avatarMxc = useRoomAvatar(space);
|
||||||
const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined : undefined;
|
const avatarUrl = avatarMxc
|
||||||
|
? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageHero
|
<PageHero
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,11 @@ function OrderButton({ order, onChange }: OrderButtonProps) {
|
||||||
after={<Icon size="50" src={Icons.Sort} />}
|
after={<Icon size="50" src={Icons.Sort} />}
|
||||||
onClick={handleOpenMenu}
|
onClick={handleOpenMenu}
|
||||||
>
|
>
|
||||||
{rankOrder ? <Text size="T200">{t('Search.relevance')}</Text> : <Text size="T200">{t('Search.recent')}</Text>}
|
{rankOrder ? (
|
||||||
|
<Text size="T200">{t('Search.relevance')}</Text>
|
||||||
|
) : (
|
||||||
|
<Text size="T200">{t('Search.recent')}</Text>
|
||||||
|
)}
|
||||||
</Chip>
|
</Chip>
|
||||||
</PopOut>
|
</PopOut>
|
||||||
);
|
);
|
||||||
|
|
@ -242,7 +246,11 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{!searchResult && <Text size="L400">{t('Search.rooms')}</Text>}
|
{!searchResult && <Text size="L400">{t('Search.rooms')}</Text>}
|
||||||
{searchResult && <Text size="L400">{t('Search.rooms_for_query', { query: searchResult.query })}</Text>}
|
{searchResult && (
|
||||||
|
<Text size="L400">
|
||||||
|
{t('Search.rooms_for_query', { query: searchResult.query })}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
{searchResult && searchResult.items.length === 0 && (
|
{searchResult && searchResult.items.length === 0 && (
|
||||||
<Text style={{ padding: config.space.S400 }} size="T300" align="Center">
|
<Text style={{ padding: config.space.S400 }} size="T300" align="Center">
|
||||||
{t('Search.no_match_found_excl')}
|
{t('Search.no_match_found_excl')}
|
||||||
|
|
@ -295,7 +303,9 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto
|
||||||
<Box shrink="No" direction="Column" gap="100" style={{ padding: config.space.S200 }}>
|
<Box shrink="No" direction="Column" gap="100" style={{ padding: config.space.S200 }}>
|
||||||
<Button size="300" variant="Secondary" radii="300" onClick={handleSave}>
|
<Button size="300" variant="Secondary" radii="300" onClick={handleSave}>
|
||||||
{localSelected && localSelected.length > 0 ? (
|
{localSelected && localSelected.length > 0 ? (
|
||||||
<Text size="B300">{t('Search.save_count', { count: localSelected.length })}</Text>
|
<Text size="B300">
|
||||||
|
{t('Search.save_count', { count: localSelected.length })}
|
||||||
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text size="B300">{t('Search.save')}</Text>
|
<Text size="B300">{t('Search.save')}</Text>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,11 @@ function MemberDrawerHeader({ room }: MemberDrawerHeaderProps) {
|
||||||
<Header className={css.MembersDrawerHeader} variant="Background" size="600">
|
<Header className={css.MembersDrawerHeader} variant="Background" size="600">
|
||||||
<Box grow="Yes" alignItems="Center" gap="200">
|
<Box grow="Yes" alignItems="Center" gap="200">
|
||||||
<Box grow="Yes" alignItems="Center" gap="200">
|
<Box grow="Yes" alignItems="Center" gap="200">
|
||||||
<Text title={t('Room.members_count', { count: room.getJoinedMemberCount() })} size="H5" truncate>
|
<Text
|
||||||
|
title={t('Room.members_count', { count: room.getJoinedMemberCount() })}
|
||||||
|
size="H5"
|
||||||
|
truncate
|
||||||
|
>
|
||||||
{t('Room.members_count', { count: millify(room.getJoinedMemberCount()) })}
|
{t('Room.members_count', { count: millify(room.getJoinedMemberCount()) })}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,22 @@ type SettingsMenuItem = {
|
||||||
const SETTINGS_MENU_ITEMS: SettingsMenuItem[] = [
|
const SETTINGS_MENU_ITEMS: SettingsMenuItem[] = [
|
||||||
{ page: SettingsPages.GeneralPage, nameKey: 'Settings.menu_general', icon: Icons.Setting },
|
{ page: SettingsPages.GeneralPage, nameKey: 'Settings.menu_general', icon: Icons.Setting },
|
||||||
{ page: SettingsPages.AccountPage, nameKey: 'Settings.menu_account', icon: Icons.User },
|
{ page: SettingsPages.AccountPage, nameKey: 'Settings.menu_account', icon: Icons.User },
|
||||||
{ page: SettingsPages.NotificationPage, nameKey: 'Settings.menu_notifications', icon: Icons.Bell },
|
{
|
||||||
|
page: SettingsPages.NotificationPage,
|
||||||
|
nameKey: 'Settings.menu_notifications',
|
||||||
|
icon: Icons.Bell,
|
||||||
|
},
|
||||||
{ page: SettingsPages.DevicesPage, nameKey: 'Settings.menu_devices', icon: Icons.Monitor },
|
{ page: SettingsPages.DevicesPage, nameKey: 'Settings.menu_devices', icon: Icons.Monitor },
|
||||||
{ page: SettingsPages.EmojisStickersPage, nameKey: 'Settings.menu_emojis_stickers', icon: Icons.Smile },
|
{
|
||||||
{ page: SettingsPages.DeveloperToolsPage, nameKey: 'Settings.menu_developer_tools', icon: Icons.Terminal },
|
page: SettingsPages.EmojisStickersPage,
|
||||||
|
nameKey: 'Settings.menu_emojis_stickers',
|
||||||
|
icon: Icons.Smile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
page: SettingsPages.DeveloperToolsPage,
|
||||||
|
nameKey: 'Settings.menu_developer_tools',
|
||||||
|
icon: Icons.Terminal,
|
||||||
|
},
|
||||||
{ page: SettingsPages.AboutPage, nameKey: 'Settings.menu_about', icon: Icons.Info },
|
{ page: SettingsPages.AboutPage, nameKey: 'Settings.menu_about', icon: Icons.Info },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ export function About({ requestClose }: AboutProps) {
|
||||||
</Box>
|
</Box>
|
||||||
<Text>{t('Settings.about_tagline')}</Text>
|
<Text>{t('Settings.about_tagline')}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,10 @@ export function ContactInformation() {
|
||||||
direction="Column"
|
direction="Column"
|
||||||
gap="400"
|
gap="400"
|
||||||
>
|
>
|
||||||
<SettingTile title={t('Settings.email_address')} description={t('Settings.email_address_desc')}>
|
<SettingTile
|
||||||
|
title={t('Settings.email_address')}
|
||||||
|
description={t('Settings.email_address_desc')}
|
||||||
|
>
|
||||||
<Box>
|
<Box>
|
||||||
{emailIds?.map((email) => (
|
{emailIds?.map((email) => (
|
||||||
<Chip key={email.address} as="span" variant="Secondary" radii="Pill">
|
<Chip key={email.address} as="span" variant="Secondary" radii="Pill">
|
||||||
|
|
|
||||||
|
|
@ -145,10 +145,7 @@ export function IgnoredUserList() {
|
||||||
direction="Column"
|
direction="Column"
|
||||||
gap="400"
|
gap="400"
|
||||||
>
|
>
|
||||||
<SettingTile
|
<SettingTile title={t('Settings.select_user')} description={t('Settings.select_user_desc')}>
|
||||||
title={t('Settings.select_user')}
|
|
||||||
description={t('Settings.select_user_desc')}
|
|
||||||
>
|
|
||||||
<Box direction="Column" gap="300">
|
<Box direction="Column" gap="300">
|
||||||
<IgnoreUserInput userList={ignoredUsers} />
|
<IgnoreUserInput userList={ignoredUsers} />
|
||||||
{ignoredUsers.length > 0 && (
|
{ignoredUsers.length > 0 && (
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,14 @@ function DeviceDetails({ device }: { device: IMyDevice }) {
|
||||||
<>
|
<>
|
||||||
{typeof device.device_id === 'string' && (
|
{typeof device.device_id === 'string' && (
|
||||||
<Text className={BreakWord} size="T200" priority="300">
|
<Text className={BreakWord} size="T200" priority="300">
|
||||||
{t('Settings.device_id')}<i>{device.device_id}</i>
|
{t('Settings.device_id')}
|
||||||
|
<i>{device.device_id}</i>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
{typeof device.last_seen_ip === 'string' && (
|
{typeof device.last_seen_ip === 'string' && (
|
||||||
<Text className={BreakWord} size="T200" priority="300">
|
<Text className={BreakWord} size="T200" priority="300">
|
||||||
{t('Settings.ip_address')}<i>{device.last_seen_ip}</i>
|
{t('Settings.ip_address')}
|
||||||
|
<i>{device.last_seen_ip}</i>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
@ -102,7 +104,9 @@ export function DeviceKeyDetails({ crypto }: DeviceKeyDetailsProps) {
|
||||||
return (
|
return (
|
||||||
<Text className={BreakWord} size="T200" priority="300">
|
<Text className={BreakWord} size="T200" priority="300">
|
||||||
{t('Settings.device_key')}
|
{t('Settings.device_key')}
|
||||||
<i>{keysState.status === AsyncStatus.Success ? keysState.data.ed25519 : t('Settings.loading')}</i>
|
<i>
|
||||||
|
{keysState.status === AsyncStatus.Success ? keysState.data.ed25519 : t('Settings.loading')}
|
||||||
|
</i>
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -210,9 +210,7 @@ export function OtherDevices({ devices, refreshDeviceList, showVerification }: O
|
||||||
<ActionUIAFlowsLoader
|
<ActionUIAFlowsLoader
|
||||||
authData={authData}
|
authData={authData}
|
||||||
unsupported={() => (
|
unsupported={() => (
|
||||||
<Text size="T200">
|
<Text size="T200">{t('Settings.delete_devices_unsupported')}</Text>
|
||||||
{t('Settings.delete_devices_unsupported')}
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{(ongoingFlow) => (
|
{(ongoingFlow) => (
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,7 @@ function LearnStartVerificationFromOtherDevice() {
|
||||||
<li>{t('Settings.verify_step_4')}</li>
|
<li>{t('Settings.verify_step_4')}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T200">
|
<Text size="T200">{t('Settings.verify_no_device')}</Text>
|
||||||
{t('Settings.verify_no_device')}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,9 @@ function GlobalPackSelector({
|
||||||
addSelected(roomPackAddresses);
|
addSelected(roomPackAddresses);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text size="B300">{allSelected ? t('Settings.unselect_all') : t('Settings.select_all')}</Text>
|
<Text size="B300">
|
||||||
|
{allSelected ? t('Settings.unselect_all') : t('Settings.select_all')}
|
||||||
|
</Text>
|
||||||
</Chip>
|
</Chip>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import React, {
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import {
|
import {
|
||||||
as,
|
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
config,
|
config,
|
||||||
|
|
@ -107,10 +106,7 @@ function Appearance() {
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Text size="L400">{t('Settings.appearance')}</Text>
|
<Text size="L400">{t('Settings.appearance')}</Text>
|
||||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||||
<SettingTile
|
<SettingTile title={t('Settings.theme')} after={<ThemeSelect />} />
|
||||||
title={t('Settings.theme')}
|
|
||||||
after={<ThemeSelect />}
|
|
||||||
/>
|
|
||||||
</SequenceCard>
|
</SequenceCard>
|
||||||
|
|
||||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||||
|
|
@ -181,7 +177,8 @@ function DateHint({ hasChanges, handleReset }: DateHintProps) {
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
YYYY
|
YYYY
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.four_digit_year')}
|
{': '}
|
||||||
|
{t('Settings.four_digit_year')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -195,25 +192,29 @@ function DateHint({ hasChanges, handleReset }: DateHintProps) {
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
M
|
M
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.the_month')}
|
{': '}
|
||||||
|
{t('Settings.the_month')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
MM
|
MM
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.two_digit_month')}
|
{': '}
|
||||||
|
{t('Settings.two_digit_month')}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
MMM
|
MMM
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.short_month_name')}
|
{': '}
|
||||||
|
{t('Settings.short_month_name')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
MMMM
|
MMMM
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.full_month_name')}
|
{': '}
|
||||||
|
{t('Settings.full_month_name')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -227,13 +228,15 @@ function DateHint({ hasChanges, handleReset }: DateHintProps) {
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
D
|
D
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.day_of_month_val')}
|
{': '}
|
||||||
|
{t('Settings.day_of_month_val')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
DD
|
DD
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.two_digit_day')}
|
{': '}
|
||||||
|
{t('Settings.two_digit_day')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -246,25 +249,29 @@ function DateHint({ hasChanges, handleReset }: DateHintProps) {
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
d
|
d
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.day_of_week_sunday')}
|
{': '}
|
||||||
|
{t('Settings.day_of_week_sunday')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
dd
|
dd
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.two_letter_day')}
|
{': '}
|
||||||
|
{t('Settings.two_letter_day')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
ddd
|
ddd
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.short_day_name')}
|
{': '}
|
||||||
|
{t('Settings.short_day_name')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="T300">
|
<Text size="T300">
|
||||||
dddd
|
dddd
|
||||||
<Text as="span" size="Inherit" priority="300">
|
<Text as="span" size="Inherit" priority="300">
|
||||||
{': '}{t('Settings.full_day_name')}
|
{': '}
|
||||||
|
{t('Settings.full_day_name')}
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -504,7 +511,9 @@ function Editor() {
|
||||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||||
<SettingTile
|
<SettingTile
|
||||||
title={t('Settings.enter_newline')}
|
title={t('Settings.enter_newline')}
|
||||||
description={t('Settings.enter_newline_desc', { key: isMacOS() ? KeySymbol.Command : 'Ctrl' })}
|
description={t('Settings.enter_newline_desc', {
|
||||||
|
key: isMacOS() ? KeySymbol.Command : 'Ctrl',
|
||||||
|
})}
|
||||||
after={<Switch variant="Primary" value={enterForNewline} onChange={setEnterForNewline} />}
|
after={<Switch variant="Primary" value={enterForNewline} onChange={setEnterForNewline} />}
|
||||||
/>
|
/>
|
||||||
</SequenceCard>
|
</SequenceCard>
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,7 @@ export function Notifications({ requestClose }: NotificationsProps) {
|
||||||
direction="Column"
|
direction="Column"
|
||||||
gap="400"
|
gap="400"
|
||||||
>
|
>
|
||||||
<SettingTile
|
<SettingTile description={t('Settings.block_messages_moved')} />
|
||||||
description={t('Settings.block_messages_moved')}
|
|
||||||
/>
|
|
||||||
</SequenceCard>
|
</SequenceCard>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,11 @@ export function SpecialMessagesNotifications() {
|
||||||
gap="400"
|
gap="400"
|
||||||
>
|
>
|
||||||
<SettingTile
|
<SettingTile
|
||||||
title={displayName ? t('Settings.contains_displayname_value', { displayName }) : t('Settings.contains_displayname')}
|
title={
|
||||||
|
displayName
|
||||||
|
? t('Settings.contains_displayname_value', { displayName })
|
||||||
|
: t('Settings.contains_displayname')
|
||||||
|
}
|
||||||
after={
|
after={
|
||||||
<MentionModeSwitcher
|
<MentionModeSwitcher
|
||||||
pushRules={pushRules}
|
pushRules={pushRules}
|
||||||
|
|
|
||||||
|
|
@ -165,11 +165,7 @@ function PushNotification() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingTile
|
<SettingTile title={t('Settings.push_notifications')} description={description} after={after} />
|
||||||
title={t('Settings.push_notifications')}
|
|
||||||
description={description}
|
|
||||||
after={after}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,14 @@ import { addRoomIdToMDirect } from '../utils/matrix';
|
||||||
|
|
||||||
export function useAutoDirectSync(mx: MatrixClient): void {
|
export function useAutoDirectSync(mx: MatrixClient): void {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleMembership = (
|
const handleMembership = (room: Room, _membership: string, prevMembership?: string) => {
|
||||||
room: Room,
|
|
||||||
_membership: string,
|
|
||||||
prevMembership?: string
|
|
||||||
) => {
|
|
||||||
if (prevMembership !== Membership.Invite) return;
|
if (prevMembership !== Membership.Invite) return;
|
||||||
if (room.getMyMembership() !== Membership.Join) return;
|
if (room.getMyMembership() !== Membership.Join) return;
|
||||||
|
|
||||||
const dmInviter = room.getDMInviter();
|
const dmInviter = room.getDMInviter();
|
||||||
if (!dmInviter) return;
|
if (!dmInviter) return;
|
||||||
|
|
||||||
const joinedAndInvited =
|
const joinedAndInvited = room.getJoinedMemberCount() + room.getInvitedMemberCount();
|
||||||
room.getJoinedMemberCount() + room.getInvitedMemberCount();
|
|
||||||
if (joinedAndInvited > 2) return;
|
if (joinedAndInvited > 2) return;
|
||||||
|
|
||||||
const mDirectEvent = getAccountData(mx, AccountDataEvent.Direct);
|
const mDirectEvent = getAccountData(mx, AccountDataEvent.Direct);
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,7 @@ export const createCallEmbed = (
|
||||||
const intent = CallEmbed.getIntent(dm, ongoing, voiceOnly);
|
const intent = CallEmbed.getIntent(dm, ongoing, voiceOnly);
|
||||||
const widget = CallEmbed.getWidget(mx, room, intent, themeKind);
|
const widget = CallEmbed.getWidget(mx, room, intent, themeKind);
|
||||||
const controlState =
|
const controlState =
|
||||||
pref &&
|
pref && new CallControlState(pref.microphone, voiceOnly ? false : pref.video, pref.sound);
|
||||||
new CallControlState(pref.microphone, voiceOnly ? false : pref.video, pref.sound);
|
|
||||||
|
|
||||||
const embed = new CallEmbed(mx, room, widget, container, controlState, voiceOnly);
|
const embed = new CallEmbed(mx, room, widget, container, controlState, voiceOnly);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ import { useState } from 'react';
|
||||||
export function useForceUpdate() {
|
export function useForceUpdate() {
|
||||||
const [data, setData] = useState(null);
|
const [data, setData] = useState(null);
|
||||||
|
|
||||||
return [data, function forceUpdateHook() {
|
return [
|
||||||
setData({});
|
data,
|
||||||
}];
|
function forceUpdateHook() {
|
||||||
|
setData({});
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,7 @@ import {
|
||||||
} from 'matrix-js-sdk';
|
} from 'matrix-js-sdk';
|
||||||
import { IRTCNotificationContent } from 'matrix-js-sdk/lib/matrixrtc/types';
|
import { IRTCNotificationContent } from 'matrix-js-sdk/lib/matrixrtc/types';
|
||||||
import { MatrixRTCSessionManagerEvents } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager';
|
import { MatrixRTCSessionManagerEvents } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager';
|
||||||
import {
|
import { CallMembership, SessionMembershipData } from 'matrix-js-sdk/lib/matrixrtc/CallMembership';
|
||||||
CallMembership,
|
|
||||||
SessionMembershipData,
|
|
||||||
} from 'matrix-js-sdk/lib/matrixrtc/CallMembership';
|
|
||||||
import { MatrixRTCSessionEvent } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSession';
|
import { MatrixRTCSessionEvent } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSession';
|
||||||
import { useMatrixClient } from './useMatrixClient';
|
import { useMatrixClient } from './useMatrixClient';
|
||||||
import { mDirectAtom } from '../state/mDirectList';
|
import { mDirectAtom } from '../state/mDirectList';
|
||||||
|
|
@ -219,10 +216,7 @@ export const useIncomingRtcNotifications = (): void => {
|
||||||
|
|
||||||
const subscribeMemberships = (room: Room): (() => void) => {
|
const subscribeMemberships = (room: Room): (() => void) => {
|
||||||
const session = mx.matrixRTC.getRoomSession(room);
|
const session = mx.matrixRTC.getRoomSession(room);
|
||||||
const handler = (
|
const handler = (_old: CallMembership[], next: CallMembership[]) => {
|
||||||
_old: CallMembership[],
|
|
||||||
next: CallMembership[]
|
|
||||||
) => {
|
|
||||||
if (next.some((m) => m.sender === mx.getUserId())) {
|
if (next.some((m) => m.sender === mx.getUserId())) {
|
||||||
removeByRoom(room.roomId);
|
removeByRoom(room.roomId);
|
||||||
}
|
}
|
||||||
|
|
@ -390,8 +384,7 @@ export const useIncomingRtcNotifications = (): void => {
|
||||||
// with any prior FCM seed for the same eventId — Java merges metadata
|
// with any prior FCM seed for the same eventId — Java merges metadata
|
||||||
// append-only, so we pass only the fields JS has reliable access to.
|
// append-only, so we pass only the fields JS has reliable access to.
|
||||||
const senderMember = room.getMember(sender);
|
const senderMember = room.getMember(sender);
|
||||||
const callerName =
|
const callerName = senderMember?.rawDisplayName || room.name || sender || 'Vojo';
|
||||||
senderMember?.rawDisplayName || room.name || sender || 'Vojo';
|
|
||||||
const lifetime = content.lifetime ?? RTC_NOTIFICATION_DEFAULT_LIFETIME;
|
const lifetime = content.lifetime ?? RTC_NOTIFICATION_DEFAULT_LIFETIME;
|
||||||
callForegroundService
|
callForegroundService
|
||||||
.upsertIncomingRing({
|
.upsertIncomingRing({
|
||||||
|
|
@ -447,8 +440,7 @@ export const useIncomingRtcNotifications = (): void => {
|
||||||
// older top-level field when possible but the content fallback is
|
// older top-level field when possible but the content fallback is
|
||||||
// the safety net.
|
// the safety net.
|
||||||
const redacted =
|
const redacted =
|
||||||
ev.event.redacts ??
|
ev.event.redacts ?? (ev.getContent() as { redacts?: string } | undefined)?.redacts;
|
||||||
(ev.getContent() as { redacts?: string } | undefined)?.redacts;
|
|
||||||
if (!redacted) return;
|
if (!redacted) return;
|
||||||
// Symmetric with RTCDecline: if the redaction arrives before
|
// Symmetric with RTCDecline: if the redaction arrives before
|
||||||
// the notification's processEvent reaches ADD (race via
|
// the notification's processEvent reaches ADD (race via
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ export const usePendingDeclinesFlusher = (): void => {
|
||||||
const { Preferences } = await import('@capacitor/preferences');
|
const { Preferences } = await import('@capacitor/preferences');
|
||||||
const { keys } = await Preferences.keys();
|
const { keys } = await Preferences.keys();
|
||||||
const tombstones = keys.filter((k) => k.startsWith(PENDING_PREFIX));
|
const tombstones = keys.filter((k) => k.startsWith(PENDING_PREFIX));
|
||||||
|
// Sequential drain is intentional — see the race-condition rationale
|
||||||
|
// in the comment above the hook (paralleling sendRtcDecline doubles
|
||||||
|
// timeline noise on the A-side). Don't convert to Promise.all.
|
||||||
|
/* eslint-disable no-restricted-syntax, no-await-in-loop, no-continue */
|
||||||
for (const key of tombstones) {
|
for (const key of tombstones) {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
const notifEventId = key.slice(PENDING_PREFIX.length);
|
const notifEventId = key.slice(PENDING_PREFIX.length);
|
||||||
|
|
@ -66,6 +70,7 @@ export const usePendingDeclinesFlusher = (): void => {
|
||||||
console.warn('[call] pendingDeclines flush failed', notifEventId, err);
|
console.warn('[call] pendingDeclines flush failed', notifEventId, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* eslint-enable no-restricted-syntax, no-await-in-loop, no-continue */
|
||||||
} catch {
|
} catch {
|
||||||
/* preferences import failed — non-fatal */
|
/* preferences import failed — non-fatal */
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,11 @@ const getDefaultTags = (t: TFunction): PowerLevelTags => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const generateFallbackTag = (powerLevelTags: PowerLevelTags, power: number, t: TFunction): MemberPowerTag => {
|
const generateFallbackTag = (
|
||||||
|
powerLevelTags: PowerLevelTags,
|
||||||
|
power: number,
|
||||||
|
t: TFunction
|
||||||
|
): MemberPowerTag => {
|
||||||
const highToLow = sortPowers(getPowers(powerLevelTags));
|
const highToLow = sortPowers(getPowers(powerLevelTags));
|
||||||
|
|
||||||
const tagPower = highToLow.find((p) => p < power);
|
const tagPower = highToLow.find((p) => p < power);
|
||||||
|
|
@ -116,7 +120,10 @@ export const usePowerLevelTags = (room: Room, powerLevels: IPowerLevels): PowerL
|
||||||
return powerLevelTags;
|
return powerLevelTags;
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateFallbackTagSimple = (powerLevelTags: PowerLevelTags, power: number): MemberPowerTag => {
|
const generateFallbackTagSimple = (
|
||||||
|
powerLevelTags: PowerLevelTags,
|
||||||
|
power: number
|
||||||
|
): MemberPowerTag => {
|
||||||
const highToLow = sortPowers(getPowers(powerLevelTags));
|
const highToLow = sortPowers(getPowers(powerLevelTags));
|
||||||
|
|
||||||
const tagPower = highToLow.find((p) => p < power);
|
const tagPower = highToLow.find((p) => p < power);
|
||||||
|
|
|
||||||
|
|
@ -338,60 +338,57 @@ export function usePushNotificationsLifecycle(): void {
|
||||||
pnPromise
|
pnPromise
|
||||||
.then(({ PushNotifications }) => {
|
.then(({ PushNotifications }) => {
|
||||||
if (cancelled) return null;
|
if (cancelled) return null;
|
||||||
return PushNotifications.addListener(
|
return PushNotifications.addListener('pushNotificationActionPerformed', (action) => {
|
||||||
'pushNotificationActionPerformed',
|
const data = action.notification.data as {
|
||||||
(action) => {
|
room_id?: string;
|
||||||
const data = action.notification.data as {
|
call_action?: 'answer' | 'decline';
|
||||||
room_id?: string;
|
notif_event_id?: string;
|
||||||
call_action?: 'answer' | 'decline';
|
};
|
||||||
notif_event_id?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Native CallStyle Answer → open the room and queue a JS-side
|
// Native CallStyle Answer → open the room and queue a JS-side
|
||||||
// switch/start via
|
// switch/start via
|
||||||
// pendingCallActionAtom. The consumer hook picks it up once the
|
// pendingCallActionAtom. The consumer hook picks it up once the
|
||||||
// CallEmbedProvider tree is mounted. DM rooms live in the Direct tab
|
// CallEmbedProvider tree is mounted. DM rooms live in the Direct tab
|
||||||
// route; `getHomeRoomPath` resolves to a Home-tab placeholder for IDs
|
// route; `getHomeRoomPath` resolves to a Home-tab placeholder for IDs
|
||||||
// it doesn't have in its left-rail, hence the DM path here.
|
// it doesn't have in its left-rail, hence the DM path here.
|
||||||
if (data.call_action === 'answer' && data.room_id) {
|
if (data.call_action === 'answer' && data.room_id) {
|
||||||
navigate(getDirectRoomPath(data.room_id), { replace: true });
|
navigate(getDirectRoomPath(data.room_id), { replace: true });
|
||||||
setPendingCallAction({
|
setPendingCallAction({
|
||||||
kind: 'answer',
|
kind: 'answer',
|
||||||
roomId: data.room_id,
|
roomId: data.room_id,
|
||||||
notifEventId: data.notif_event_id,
|
notifEventId: data.notif_event_id,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Decline: queue the action and let the consumer (inside
|
|
||||||
// CallEmbedProvider) fire sendRtcDecline and then minimize the app.
|
|
||||||
// Doing the minimize here would race the setAtom — setAtom schedules
|
|
||||||
// a render-tick, minimize is synchronous, so we'd close the WebView
|
|
||||||
// before the consumer could pick up the atom and send the decline.
|
|
||||||
if (data.call_action === 'decline' && data.room_id && data.notif_event_id) {
|
|
||||||
setPendingCallAction({
|
|
||||||
kind: 'decline',
|
|
||||||
roomId: data.room_id,
|
|
||||||
notifEventId: data.notif_event_id,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FSI launch and body-tap on a call notification hit this path (no
|
|
||||||
// call_action extra, but notif_event_id is present — only call
|
|
||||||
// pushes carry it). DMs are currently the only call surface, so
|
|
||||||
// route to the Direct tab instead of the Home-tab fallback.
|
|
||||||
// Caveat: if group-call push is ever added, those events will also
|
|
||||||
// carry notif_event_id and this branch will route them to the DM
|
|
||||||
// tab incorrectly — revisit together with the group-call pipeline.
|
|
||||||
if (data.room_id && data.notif_event_id) {
|
|
||||||
navigate(getDirectRoomPath(data.room_id), { replace: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.room_id) navigateRoom(data.room_id, undefined, { replace: true });
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
// Decline: queue the action and let the consumer (inside
|
||||||
|
// CallEmbedProvider) fire sendRtcDecline and then minimize the app.
|
||||||
|
// Doing the minimize here would race the setAtom — setAtom schedules
|
||||||
|
// a render-tick, minimize is synchronous, so we'd close the WebView
|
||||||
|
// before the consumer could pick up the atom and send the decline.
|
||||||
|
if (data.call_action === 'decline' && data.room_id && data.notif_event_id) {
|
||||||
|
setPendingCallAction({
|
||||||
|
kind: 'decline',
|
||||||
|
roomId: data.room_id,
|
||||||
|
notifEventId: data.notif_event_id,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FSI launch and body-tap on a call notification hit this path (no
|
||||||
|
// call_action extra, but notif_event_id is present — only call
|
||||||
|
// pushes carry it). DMs are currently the only call surface, so
|
||||||
|
// route to the Direct tab instead of the Home-tab fallback.
|
||||||
|
// Caveat: if group-call push is ever added, those events will also
|
||||||
|
// carry notif_event_id and this branch will route them to the DM
|
||||||
|
// tab incorrectly — revisit together with the group-call pipeline.
|
||||||
|
if (data.room_id && data.notif_event_id) {
|
||||||
|
navigate(getDirectRoomPath(data.room_id), { replace: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.room_id) navigateRoom(data.room_id, undefined, { replace: true });
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.then((h) => {
|
.then((h) => {
|
||||||
if (!h) return;
|
if (!h) return;
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,7 @@ export function CallStatusRenderer() {
|
||||||
|
|
||||||
if (!callEmbed) return null;
|
if (!callEmbed) return null;
|
||||||
|
|
||||||
if (
|
if (screenSize === ScreenSize.Mobile && callEmbed.roomId === selectedRoom && !callEmbed.voiceOnly)
|
||||||
screenSize === ScreenSize.Mobile &&
|
|
||||||
callEmbed.roomId === selectedRoom &&
|
|
||||||
!callEmbed.voiceOnly
|
|
||||||
)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return <CallStatus callEmbed={callEmbed} />;
|
return <CallStatus callEmbed={callEmbed} />;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,11 @@ export function Login() {
|
||||||
{t('Auth.error_client_unsupported', { server })}
|
{t('Auth.error_client_unsupported', { server })}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
<Text align="Center" className={css.AuthBottomLink} style={{ color: 'rgba(232, 228, 223, 0.55)' }}>
|
<Text
|
||||||
|
align="Center"
|
||||||
|
className={css.AuthBottomLink}
|
||||||
|
style={{ color: 'rgba(232, 228, 223, 0.55)' }}
|
||||||
|
>
|
||||||
{t('Auth.new_here')}{' '}
|
{t('Auth.new_here')}{' '}
|
||||||
<Link to={getRegisterPath(server)} style={{ fontWeight: 600 }}>
|
<Link to={getRegisterPath(server)} style={{ fontWeight: 600 }}>
|
||||||
{t('Auth.create_account')}
|
{t('Auth.create_account')}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,5 @@
|
||||||
import React, { FormEventHandler, useCallback } from 'react';
|
import React, { FormEventHandler, useCallback } from 'react';
|
||||||
import {
|
import { Box, Button, Input, Overlay, OverlayBackdrop, OverlayCenter, Spinner, Text } from 'folds';
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
Input,
|
|
||||||
Overlay,
|
|
||||||
OverlayBackdrop,
|
|
||||||
OverlayCenter,
|
|
||||||
Spinner,
|
|
||||||
Text,
|
|
||||||
} from 'folds';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { MatrixError } from 'matrix-js-sdk';
|
import { MatrixError } from 'matrix-js-sdk';
|
||||||
|
|
@ -174,9 +165,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<Text align="Center" size="T200">
|
<Text align="Center" size="T200">
|
||||||
<Link to={getResetPasswordPath(server)}>
|
<Link to={getResetPasswordPath(server)}>{t('Auth.forgot_password')}</Link>
|
||||||
{t('Auth.forgot_password')}
|
|
||||||
</Link>
|
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Button type="submit" variant="Primary" size="500">
|
<Button type="submit" variant="Primary" size="500">
|
||||||
|
|
|
||||||
|
|
@ -299,18 +299,12 @@ export function PasswordRegisterForm({
|
||||||
/>
|
/>
|
||||||
{registerError?.errcode === RegisterError.PasswordWeak && (
|
{registerError?.errcode === RegisterError.PasswordWeak && (
|
||||||
<FieldError
|
<FieldError
|
||||||
message={
|
message={registerError.data.error ?? t('Auth.register_error_password_weak')}
|
||||||
registerError.data.error ??
|
|
||||||
t('Auth.register_error_password_weak')
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{registerError?.errcode === RegisterError.PasswordShort && (
|
{registerError?.errcode === RegisterError.PasswordShort && (
|
||||||
<FieldError
|
<FieldError
|
||||||
message={
|
message={registerError.data.error ?? t('Auth.register_error_password_short')}
|
||||||
registerError.data.error ??
|
|
||||||
t('Auth.register_error_password_short')
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,11 @@ export function Register() {
|
||||||
}
|
}
|
||||||
</SupportedUIAFlowsLoader>
|
</SupportedUIAFlowsLoader>
|
||||||
)}
|
)}
|
||||||
<Text align="Center" className={css.AuthBottomLink} style={{ color: 'rgba(232, 228, 223, 0.55)' }}>
|
<Text
|
||||||
|
align="Center"
|
||||||
|
className={css.AuthBottomLink}
|
||||||
|
style={{ color: 'rgba(232, 228, 223, 0.55)' }}
|
||||||
|
>
|
||||||
{t('Auth.already_have_account')}{' '}
|
{t('Auth.already_have_account')}{' '}
|
||||||
<Link to={getLoginPath(server)} style={{ fontWeight: 600 }}>
|
<Link to={getLoginPath(server)} style={{ fontWeight: 600 }}>
|
||||||
{t('Auth.title_login')}
|
{t('Auth.title_login')}
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,7 @@ function ResetPasswordComplete({ email }: { email?: string }) {
|
||||||
<FocusTrap>
|
<FocusTrap>
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
|
<Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
|
||||||
<Text>
|
<Text>{t('Auth.reset_success_message')}</Text>
|
||||||
{t('Auth.reset_success_message')}
|
|
||||||
</Text>
|
|
||||||
<Button variant="Primary" onClick={handleClick}>
|
<Button variant="Primary" onClick={handleClick}>
|
||||||
<Text size="B400" as="span">
|
<Text size="B400" as="span">
|
||||||
{t('Auth.reset_success_login')}
|
{t('Auth.reset_success_login')}
|
||||||
|
|
@ -170,7 +168,11 @@ export function PasswordResetForm({ defaultEmail }: PasswordResetFormProps) {
|
||||||
return (
|
return (
|
||||||
<Box as="form" onSubmit={handleSubmit} direction="Inherit" gap="400">
|
<Box as="form" onSubmit={handleSubmit} direction="Inherit" gap="400">
|
||||||
<Text size="T300" priority="400">
|
<Text size="T300" priority="400">
|
||||||
<Trans i18nKey="Auth.reset_description" values={{ server }} components={{ strong: <strong /> }} />
|
<Trans
|
||||||
|
i18nKey="Auth.reset_description"
|
||||||
|
values={{ server }}
|
||||||
|
components={{ strong: <strong /> }}
|
||||||
|
/>
|
||||||
</Text>
|
</Text>
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Text as="label" size="L400" priority="300">
|
<Text as="label" size="L400" priority="300">
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,11 @@ export function ResetPassword() {
|
||||||
<PasswordResetForm defaultEmail={resetPasswordSearchParams.email} />
|
<PasswordResetForm defaultEmail={resetPasswordSearchParams.email} />
|
||||||
<span data-spacing-node />
|
<span data-spacing-node />
|
||||||
|
|
||||||
<Text align="Center" className={css.AuthBottomLink} style={{ color: 'rgba(232, 228, 223, 0.55)' }}>
|
<Text
|
||||||
|
align="Center"
|
||||||
|
className={css.AuthBottomLink}
|
||||||
|
style={{ color: 'rgba(232, 228, 223, 0.55)' }}
|
||||||
|
>
|
||||||
{t('Auth.remember_password')}{' '}
|
{t('Auth.remember_password')}{' '}
|
||||||
<Link to={getLoginPath(server)} style={{ fontWeight: 600 }}>
|
<Link to={getLoginPath(server)} style={{ fontWeight: 600 }}>
|
||||||
{t('Auth.title_login')}
|
{t('Auth.title_login')}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,7 @@ import { setFavicon } from '../../utils/dom';
|
||||||
import { useSetting } from '../../state/hooks/settings';
|
import { useSetting } from '../../state/hooks/settings';
|
||||||
import { settingsAtom } from '../../state/settings';
|
import { settingsAtom } from '../../state/settings';
|
||||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||||
import {
|
import { getNotificationType, getUnreadInfo, isNotificationEvent } from '../../utils/room';
|
||||||
getNotificationType,
|
|
||||||
getUnreadInfo,
|
|
||||||
isNotificationEvent,
|
|
||||||
} from '../../utils/room';
|
|
||||||
import { NotificationType, UnreadInfo } from '../../../types/matrix/room';
|
import { NotificationType, UnreadInfo } from '../../../types/matrix/room';
|
||||||
import { useSelectedRoom } from '../../hooks/router/useSelectedRoom';
|
import { useSelectedRoom } from '../../hooks/router/useSelectedRoom';
|
||||||
import { useInboxNotificationsSelected } from '../../hooks/router/useInbox';
|
import { useInboxNotificationsSelected } from '../../hooks/router/useInbox';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ export function SpecVersions({ baseUrl, children }: { baseUrl: string; children:
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<Box direction="Column" gap="400" style={{ padding: config.space.S400 }}>
|
<Box direction="Column" gap="400" style={{ padding: config.space.S400 }}>
|
||||||
<Text>
|
<Text>
|
||||||
Unable to connect to the homeserver. The homeserver or your internet connection may be down.
|
Unable to connect to the homeserver. The homeserver or your internet connection
|
||||||
|
may be down.
|
||||||
</Text>
|
</Text>
|
||||||
<Button variant="Critical" onClick={retry}>
|
<Button variant="Critical" onClick={retry}>
|
||||||
<Text as="span" size="B400">
|
<Text as="span" size="B400">
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,7 @@ export function DirectCreate() {
|
||||||
<PageContentCenter>
|
<PageContentCenter>
|
||||||
<PageHeroSection>
|
<PageHeroSection>
|
||||||
<Box direction="Column" gap="700">
|
<Box direction="Column" gap="700">
|
||||||
<PageHero
|
<PageHero title={t('Direct.create_chat')} />
|
||||||
title={t('Direct.create_chat')}
|
|
||||||
/>
|
|
||||||
<CreateChat defaultUserId={userId} />
|
<CreateChat defaultUserId={userId} />
|
||||||
</Box>
|
</Box>
|
||||||
</PageHeroSection>
|
</PageHeroSection>
|
||||||
|
|
|
||||||
|
|
@ -71,12 +71,7 @@ export function DirectSelfRow() {
|
||||||
style={{ minWidth: 0, overflow: 'hidden' }}
|
style={{ minWidth: 0, overflow: 'hidden' }}
|
||||||
>
|
>
|
||||||
<Box as="span" alignItems="Baseline" gap="100" style={{ minWidth: 0 }}>
|
<Box as="span" alignItems="Baseline" gap="100" style={{ minWidth: 0 }}>
|
||||||
<Text
|
<Text as="span" size="T300" truncate style={{ fontWeight: 600, flexShrink: 1 }}>
|
||||||
as="span"
|
|
||||||
size="T300"
|
|
||||||
truncate
|
|
||||||
style={{ fontWeight: 600, flexShrink: 1 }}
|
|
||||||
>
|
|
||||||
{t('Direct.self_row_label')}
|
{t('Direct.self_row_label')}
|
||||||
</Text>
|
</Text>
|
||||||
<span
|
<span
|
||||||
|
|
@ -95,12 +90,7 @@ export function DirectSelfRow() {
|
||||||
{userId}
|
{userId}
|
||||||
</span>
|
</span>
|
||||||
</Box>
|
</Box>
|
||||||
<Text
|
<Text as="span" size="T200" truncate style={{ opacity: 0.6 }}>
|
||||||
as="span"
|
|
||||||
size="T200"
|
|
||||||
truncate
|
|
||||||
style={{ opacity: 0.6 }}
|
|
||||||
>
|
|
||||||
{t('Direct.self_row_preview')}
|
{t('Direct.self_row_preview')}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,9 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
after={<Icon size="100" src={Icons.ChevronBottom} />}
|
after={<Icon size="100" src={Icons.ChevronBottom} />}
|
||||||
>
|
>
|
||||||
<Text size="T200" truncate>{t('Explore.page_limit', { limit })}</Text>
|
<Text size="T200" truncate>
|
||||||
|
{t('Explore.page_limit', { limit })}
|
||||||
|
</Text>
|
||||||
</Chip>
|
</Chip>
|
||||||
</PopOut>
|
</PopOut>
|
||||||
);
|
);
|
||||||
|
|
@ -539,7 +541,9 @@ export function PublicRooms() {
|
||||||
<Box direction="Column" gap="400">
|
<Box direction="Column" gap="400">
|
||||||
<Box direction="Column" gap="300">
|
<Box direction="Column" gap="300">
|
||||||
{isSearch ? (
|
{isSearch ? (
|
||||||
<Text size="H4">{t('Explore.results_for', { term: serverSearchParams.term })}</Text>
|
<Text size="H4">
|
||||||
|
{t('Explore.results_for', { term: serverSearchParams.term })}
|
||||||
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text size="H4">{t('Explore.popular_communities')}</Text>
|
<Text size="H4">{t('Explore.popular_communities')}</Text>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,7 @@ export function HomeRouteRoomProvider({ children }: { children: ReactNode }) {
|
||||||
// the first paint instead of one frame later. See plan §6.5 / §6.7.
|
// the first paint instead of one frame later. See plan §6.5 / §6.7.
|
||||||
if (
|
if (
|
||||||
room &&
|
room &&
|
||||||
(mDirects.has(room.roomId) ||
|
(mDirects.has(room.roomId) || !!room.getDMInviter() || isDirectInvite(room, mx.getUserId()))
|
||||||
!!room.getDMInviter() ||
|
|
||||||
isDirectInvite(room, mx.getUserId()))
|
|
||||||
) {
|
) {
|
||||||
const alias = getCanonicalAliasOrRoomId(mx, room.roomId);
|
const alias = getCanonicalAliasOrRoomId(mx, room.roomId);
|
||||||
return <Navigate to={getDirectRoomPath(alias, eventId)} replace />;
|
return <Navigate to={getDirectRoomPath(alias, eventId)} replace />;
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,8 @@ function InviteCard({
|
||||||
<Box gap="200" alignItems="Baseline">
|
<Box gap="200" alignItems="Baseline">
|
||||||
<Box grow="Yes">
|
<Box grow="Yes">
|
||||||
<Text size="T200" priority="300">
|
<Text size="T200" priority="300">
|
||||||
{t('Inbox.from')}<b>{invite.senderId}</b>
|
{t('Inbox.from')}
|
||||||
|
<b>{invite.senderId}</b>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
{typeof invite.inviteTs === 'number' && invite.inviteTs !== 0 && (
|
{typeof invite.inviteTs === 'number' && invite.inviteTs !== 0 && (
|
||||||
|
|
@ -337,7 +338,8 @@ function InviteCard({
|
||||||
</Box>
|
</Box>
|
||||||
{invite.reason && (
|
{invite.reason && (
|
||||||
<Text size="T200" priority="300">
|
<Text size="T200" priority="300">
|
||||||
{t('Inbox.reason_label')}{invite.reason}
|
{t('Inbox.reason_label')}
|
||||||
|
{invite.reason}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -756,9 +756,7 @@ export function Notifications() {
|
||||||
gap="200"
|
gap="200"
|
||||||
>
|
>
|
||||||
<Text>{t('Inbox.no_notifications')}</Text>
|
<Text>{t('Inbox.no_notifications')}</Text>
|
||||||
<Text size="T200">
|
<Text size="T200">{t('Inbox.no_notifications_desc')}</Text>
|
||||||
{t('Inbox.no_notifications_desc')}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ function UnverifiedIndicator() {
|
||||||
<>
|
<>
|
||||||
{hasUnverified && (
|
{hasUnverified && (
|
||||||
<SidebarItem active={settings} className={css.UnverifiedTab}>
|
<SidebarItem active={settings} className={css.UnverifiedTab}>
|
||||||
<SidebarItemTooltip tooltip={unverified ? t('Inbox.unverified_device') : t('Inbox.unverified_devices')}>
|
<SidebarItemTooltip
|
||||||
|
tooltip={unverified ? t('Inbox.unverified_device') : t('Inbox.unverified_devices')}
|
||||||
|
>
|
||||||
{(triggerRef) => (
|
{(triggerRef) => (
|
||||||
<SidebarAvatar
|
<SidebarAvatar
|
||||||
className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
|
className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,8 @@ export function getCallCapabilities(
|
||||||
);
|
);
|
||||||
|
|
||||||
capabilities.add(
|
capabilities.add(
|
||||||
WidgetEventCapability.forRoomEvent(
|
WidgetEventCapability.forRoomEvent(EventDirection.Send, 'org.matrix.msc4075.rtc.notification')
|
||||||
EventDirection.Send,
|
.raw
|
||||||
'org.matrix.msc4075.rtc.notification'
|
|
||||||
).raw
|
|
||||||
);
|
);
|
||||||
capabilities.add(
|
capabilities.add(
|
||||||
WidgetEventCapability.forRoomEvent(
|
WidgetEventCapability.forRoomEvent(
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ export type ListAction<T> =
|
||||||
item: T | T[];
|
item: T | T[];
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'REPLACE';
|
type: 'REPLACE';
|
||||||
item: T;
|
item: T;
|
||||||
replacement: T;
|
replacement: T;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'DELETE';
|
type: 'DELETE';
|
||||||
|
|
@ -34,9 +34,12 @@ export const createListAtom = <T>() => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (action.type === 'REPLACE') {
|
if (action.type === 'REPLACE') {
|
||||||
set(baseListAtom, items.map((item) => item === action.item ? action.replacement : item));
|
set(
|
||||||
|
baseListAtom,
|
||||||
|
items.map((item) => (item === action.item ? action.replacement : item))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export type TListAtom<T> = ReturnType<typeof createListAtom<T>>;
|
export type TListAtom<T> = ReturnType<typeof createListAtom<T>>;
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,7 @@ export type TUploadItem = {
|
||||||
|
|
||||||
export type TUploadListAtom = ReturnType<typeof createListAtom<TUploadItem>>;
|
export type TUploadListAtom = ReturnType<typeof createListAtom<TUploadItem>>;
|
||||||
|
|
||||||
export const roomIdToUploadItemsAtomFamily = atomFamily<string, TUploadListAtom>(
|
export const roomIdToUploadItemsAtomFamily = atomFamily<string, TUploadListAtom>(createListAtom);
|
||||||
createListAtom
|
|
||||||
);
|
|
||||||
|
|
||||||
export const roomUploadAtomFamily = createUploadAtomFamily();
|
export const roomUploadAtomFamily = createUploadAtomFamily();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ export const setupExternalLinkHandler = (): (() => void) | undefined => {
|
||||||
if (!isNativePlatform()) return undefined;
|
if (!isNativePlatform()) return undefined;
|
||||||
|
|
||||||
const handler = (e: MouseEvent) => {
|
const handler = (e: MouseEvent) => {
|
||||||
const anchor = (e.target as HTMLElement).closest?.('a[target="_blank"]') as HTMLAnchorElement | null;
|
const anchor = (e.target as HTMLElement).closest?.(
|
||||||
|
'a[target="_blank"]'
|
||||||
|
) as HTMLAnchorElement | null;
|
||||||
if (!anchor?.href) return;
|
if (!anchor?.href) return;
|
||||||
// Mention pills are rendered as matrix.to links with data-mention-id; they
|
// Mention pills are rendered as matrix.to links with data-mention-id; they
|
||||||
// have their own React onClick that opens an in-app profile card. Letting
|
// have their own React onClick that opens an in-app profile card. Letting
|
||||||
|
|
|
||||||
|
|
@ -203,9 +203,7 @@ export const getDMRoomFor = (mx: MatrixClient, userId: string): Room | undefined
|
||||||
// getDMRoomFor(Bob) call and silently route messages to Alice's chat.
|
// getDMRoomFor(Bob) call and silently route messages to Alice's chat.
|
||||||
const active = room
|
const active = room
|
||||||
.getMembers()
|
.getMembers()
|
||||||
.filter(
|
.filter((m) => m.membership === Membership.Join || m.membership === Membership.Invite);
|
||||||
(m) => m.membership === Membership.Join || m.membership === Membership.Invite
|
|
||||||
);
|
|
||||||
if (active.length !== 2) return false;
|
if (active.length !== 2) return false;
|
||||||
const peer = active.find((m) => m.userId !== myUserId);
|
const peer = active.find((m) => m.userId !== myUserId);
|
||||||
return !!peer && peer.userId === userId;
|
return !!peer && peer.userId === userId;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const SESSION_KEY = 'vojo.matrixSession';
|
||||||
export const writeSessionBridge = async (mx: MatrixClient): Promise<void> => {
|
export const writeSessionBridge = async (mx: MatrixClient): Promise<void> => {
|
||||||
if (!isNativePlatform()) return;
|
if (!isNativePlatform()) return;
|
||||||
const accessToken = mx.getAccessToken();
|
const accessToken = mx.getAccessToken();
|
||||||
const baseUrl = mx.baseUrl;
|
const { baseUrl } = mx;
|
||||||
const userId = mx.getUserId();
|
const userId = mx.getUserId();
|
||||||
if (!accessToken || !baseUrl || !userId) return;
|
if (!accessToken || !baseUrl || !userId) return;
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,7 @@ import { createClient, MatrixClient, IndexedDBStore, IndexedDBCryptoStore } from
|
||||||
import { cryptoCallbacks } from './secretStorageKeys';
|
import { cryptoCallbacks } from './secretStorageKeys';
|
||||||
import { clearNavToActivePathStore } from '../app/state/navToActivePath';
|
import { clearNavToActivePathStore } from '../app/state/navToActivePath';
|
||||||
import { pushSessionToSW } from '../sw-session';
|
import { pushSessionToSW } from '../sw-session';
|
||||||
import {
|
import { clearPusherIds, loadPusherIds, setPushEnabled, unregisterPusher } from '../app/utils/push';
|
||||||
clearPusherIds,
|
|
||||||
loadPusherIds,
|
|
||||||
setPushEnabled,
|
|
||||||
unregisterPusher,
|
|
||||||
} from '../app/utils/push';
|
|
||||||
import { isNativePlatform } from '../app/utils/capacitor';
|
import { isNativePlatform } from '../app/utils/capacitor';
|
||||||
import { clearSessionBridge } from '../app/utils/sessionBridge';
|
import { clearSessionBridge } from '../app/utils/sessionBridge';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,7 @@ if ('serviceWorker' in navigator) {
|
||||||
|
|
||||||
if (type === 'notificationClick') {
|
if (type === 'notificationClick') {
|
||||||
const { roomId, isInvite } = ev.data ?? {};
|
const { roomId, isInvite } = ev.data ?? {};
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(new CustomEvent('vojo:pushNavigate', { detail: { roomId, isInvite } }));
|
||||||
new CustomEvent('vojo:pushNavigate', { detail: { roomId, isInvite } })
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
25
src/sw.ts
25
src/sw.ts
|
|
@ -430,9 +430,7 @@ async function pushFallback(): Promise<PushFallback> {
|
||||||
: `${inviter} invited you to a room`;
|
: `${inviter} invited you to a room`;
|
||||||
}
|
}
|
||||||
if (hasRoom) {
|
if (hasRoom) {
|
||||||
return lang === 'ru'
|
return lang === 'ru' ? `Приглашение в ${roomName}` : `Invited you to ${roomName}`;
|
||||||
? `Приглашение в ${roomName}`
|
|
||||||
: `Invited you to ${roomName}`;
|
|
||||||
}
|
}
|
||||||
return safety.inviteGeneric;
|
return safety.inviteGeneric;
|
||||||
},
|
},
|
||||||
|
|
@ -484,10 +482,7 @@ async function tryFetchInvite(
|
||||||
): Promise<{ kind: 'result'; value: InviteLookup } | { kind: 'miss' } | { kind: 'error' }> {
|
): Promise<{ kind: 'result'; value: InviteLookup } | { kind: 'miss' } | { kind: 'error' }> {
|
||||||
let res: Response;
|
let res: Response;
|
||||||
try {
|
try {
|
||||||
res = await fetch(
|
res = await fetch(`${session.baseUrl}/_matrix/client/v3/notifications?limit=30`, { headers });
|
||||||
`${session.baseUrl}/_matrix/client/v3/notifications?limit=30`,
|
|
||||||
{ headers }
|
|
||||||
);
|
|
||||||
} catch {
|
} catch {
|
||||||
return { kind: 'error' };
|
return { kind: 'error' };
|
||||||
}
|
}
|
||||||
|
|
@ -499,9 +494,7 @@ async function tryFetchInvite(
|
||||||
return { kind: 'error' };
|
return { kind: 'error' };
|
||||||
}
|
}
|
||||||
const entries = Array.isArray(json?.notifications) ? json.notifications : [];
|
const entries = Array.isArray(json?.notifications) ? json.notifications : [];
|
||||||
const hit = entries.find(
|
const hit = entries.find((n) => n?.room_id === roomId && n?.event?.event_id === eventId);
|
||||||
(n) => n?.room_id === roomId && n?.event?.event_id === eventId
|
|
||||||
);
|
|
||||||
if (!hit) return { kind: 'miss' };
|
if (!hit) return { kind: 'miss' };
|
||||||
const ev = hit.event;
|
const ev = hit.event;
|
||||||
if (
|
if (
|
||||||
|
|
@ -523,7 +516,8 @@ async function tryFetchInvite(
|
||||||
!!s.content.displayname.trim()
|
!!s.content.displayname.trim()
|
||||||
);
|
);
|
||||||
const nameState = stripped.find(
|
const nameState = stripped.find(
|
||||||
(s) => s?.type === 'm.room.name' && typeof s?.content?.name === 'string' && !!s.content.name.trim()
|
(s) =>
|
||||||
|
s?.type === 'm.room.name' && typeof s?.content?.name === 'string' && !!s.content.name.trim()
|
||||||
);
|
);
|
||||||
const inviter = inviterMember?.content?.displayname ?? mxidLocalPart(ev.sender);
|
const inviter = inviterMember?.content?.displayname ?? mxidLocalPart(ev.sender);
|
||||||
const roomName = nameState?.content?.name;
|
const roomName = nameState?.content?.name;
|
||||||
|
|
@ -572,7 +566,9 @@ async function fetchEventDetails(
|
||||||
// trip; for invitees we fall through to /notifications below.
|
// trip; for invitees we fall through to /notifications below.
|
||||||
const [evRes, nameRes] = await Promise.all([
|
const [evRes, nameRes] = await Promise.all([
|
||||||
fetch(
|
fetch(
|
||||||
`${session.baseUrl}/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/event/${encodeURIComponent(eventId)}`,
|
`${session.baseUrl}/_matrix/client/v3/rooms/${encodeURIComponent(
|
||||||
|
roomId
|
||||||
|
)}/event/${encodeURIComponent(eventId)}`,
|
||||||
{ headers }
|
{ headers }
|
||||||
),
|
),
|
||||||
fetch(
|
fetch(
|
||||||
|
|
@ -608,10 +604,7 @@ async function fetchEventDetails(
|
||||||
isCall = true;
|
isCall = true;
|
||||||
title = fb.incomingCall;
|
title = fb.incomingCall;
|
||||||
body = fb.openToAnswer;
|
body = fb.openToAnswer;
|
||||||
} else if (
|
} else if (event?.type === 'm.room.member' && event?.content?.membership === 'invite') {
|
||||||
event?.type === 'm.room.member' &&
|
|
||||||
event?.content?.membership === 'invite'
|
|
||||||
) {
|
|
||||||
// Invite path for an already-joined user (rare — re-invite after
|
// Invite path for an already-joined user (rare — re-invite after
|
||||||
// leave, or multi-device where another session joined). The 404
|
// leave, or multi-device where another session joined). The 404
|
||||||
// path below handles the pre-join case.
|
// path below handles the pre-join case.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import { MsgType } from 'matrix-js-sdk';
|
||||||
|
|
||||||
export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash';
|
export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash';
|
||||||
export const MATRIX_SPOILER_PROPERTY_NAME = 'page.codeberg.everypizza.msc4193.spoiler';
|
export const MATRIX_SPOILER_PROPERTY_NAME = 'page.codeberg.everypizza.msc4193.spoiler';
|
||||||
export const MATRIX_SPOILER_REASON_PROPERTY_NAME = 'page.codeberg.everypizza.msc4193.spoiler.reason';
|
export const MATRIX_SPOILER_REASON_PROPERTY_NAME =
|
||||||
|
'page.codeberg.everypizza.msc4193.spoiler.reason';
|
||||||
|
|
||||||
export type IImageInfo = {
|
export type IImageInfo = {
|
||||||
w?: number;
|
w?: number;
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"target": "ES2016",
|
"target": "ES2016",
|
||||||
"module": "ES2020",
|
"module": "ESNext",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"moduleResolution": "Node",
|
"moduleResolution": "Bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"lib": ["ES2016", "DOM"]
|
"lib": ["ES2020", "DOM", "DOM.Iterable"]
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "dist"],
|
"exclude": ["node_modules", "dist"],
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue