Compare commits
26 Commits
2025.3.2-b
...
renovate/g
Author | SHA1 | Date | |
---|---|---|---|
![]() |
850538bff4 | ||
![]() |
50724b6ab8 | ||
![]() |
e61263cff0 | ||
![]() |
d073fe6b02 | ||
![]() |
ce858a676b | ||
![]() |
733a391d86 | ||
![]() |
0e25a0fb81 | ||
![]() |
1fd87bd2e4 | ||
![]() |
ebc54b1f82 | ||
![]() |
6015254e59 | ||
![]() |
c02f0b3b33 | ||
![]() |
abddd40c09 | ||
![]() |
a865a949b5 | ||
![]() |
0007723405 | ||
![]() |
71188b3463 | ||
![]() |
7f534a41a6 | ||
![]() |
f25963e2c2 | ||
![]() |
dfab6b1b8d | ||
![]() |
fac59d75e2 | ||
![]() |
fd3e28812e | ||
![]() |
6a90b7e04b | ||
![]() |
8d8414687a | ||
![]() |
0c682dd027 | ||
![]() |
3399c786a8 | ||
![]() |
64cf101fe7 | ||
![]() |
8b6d90b7a4 |
2
.github/workflows/api-misskey-js.yml
vendored
2
.github/workflows/api-misskey-js.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/changelog-check.yml
vendored
2
.github/workflows/changelog-check.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
- name: Checkout head
|
- name: Checkout head
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
- name: setup node
|
- name: setup node
|
||||||
id: setup-node
|
id: setup-node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
2
.github/workflows/get-api-diff.yml
vendored
2
.github/workflows/get-api-diff.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
8
.github/workflows/lint.yml
vendored
8
.github/workflows/lint.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- uses: actions/setup-node@v4.2.0
|
- uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -69,13 +69,13 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- uses: actions/setup-node@v4.2.0
|
- uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Restore eslint cache
|
- name: Restore eslint cache
|
||||||
uses: actions/cache@v4.2.2
|
uses: actions/cache@v4.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.eslint-cache-path }}
|
path: ${{ env.eslint-cache-path }}
|
||||||
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
||||||
@@ -99,7 +99,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- uses: actions/setup-node@v4.2.0
|
- uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/locale.yml
vendored
2
.github/workflows/locale.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- uses: actions/setup-node@v4.2.0
|
- uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/on-release-created.yml
vendored
2
.github/workflows/on-release-created.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/storybook.yml
vendored
2
.github/workflows/storybook.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js 20.x
|
- name: Use Node.js 20.x
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
4
.github/workflows/test-backend.yml
vendored
4
.github/workflows/test-backend.yml
vendored
@@ -62,7 +62,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -109,7 +109,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/test-federation.yml
vendored
2
.github/workflows/test-federation.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
4
.github/workflows/test-frontend.yml
vendored
4
.github/workflows/test-frontend.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -93,7 +93,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/test-misskey-js.yml
vendored
2
.github/workflows/test-misskey-js.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
|
|
||||||
- name: Setup Node.js ${{ matrix.node-version }}
|
- name: Setup Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/test-production.yml
vendored
2
.github/workflows/test-production.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
2
.github/workflows/validate-api-json.yml
vendored
2
.github/workflows/validate-api-json.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.1.0
|
uses: pnpm/action-setup@v4.1.0
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "2025.3.2-beta.6",
|
"version": "2025.3.2-beta.8",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@@ -37,17 +37,17 @@
|
|||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@swc/core-android-arm64": "1.3.11",
|
"@swc/core-android-arm64": "1.3.11",
|
||||||
"@swc/core-darwin-arm64": "1.10.16",
|
"@swc/core-darwin-arm64": "1.11.11",
|
||||||
"@swc/core-darwin-x64": "1.10.16",
|
"@swc/core-darwin-x64": "1.11.11",
|
||||||
"@swc/core-freebsd-x64": "1.3.11",
|
"@swc/core-freebsd-x64": "1.3.11",
|
||||||
"@swc/core-linux-arm-gnueabihf": "1.10.16",
|
"@swc/core-linux-arm-gnueabihf": "1.11.11",
|
||||||
"@swc/core-linux-arm64-gnu": "1.10.16",
|
"@swc/core-linux-arm64-gnu": "1.11.11",
|
||||||
"@swc/core-linux-arm64-musl": "1.10.16",
|
"@swc/core-linux-arm64-musl": "1.11.11",
|
||||||
"@swc/core-linux-x64-gnu": "1.10.16",
|
"@swc/core-linux-x64-gnu": "1.11.11",
|
||||||
"@swc/core-linux-x64-musl": "1.10.16",
|
"@swc/core-linux-x64-musl": "1.11.11",
|
||||||
"@swc/core-win32-arm64-msvc": "1.10.16",
|
"@swc/core-win32-arm64-msvc": "1.11.11",
|
||||||
"@swc/core-win32-ia32-msvc": "1.10.16",
|
"@swc/core-win32-ia32-msvc": "1.11.11",
|
||||||
"@swc/core-win32-x64-msvc": "1.10.16",
|
"@swc/core-win32-x64-msvc": "1.11.11",
|
||||||
"@tensorflow/tfjs": "4.22.0",
|
"@tensorflow/tfjs": "4.22.0",
|
||||||
"@tensorflow/tfjs-node": "4.22.0",
|
"@tensorflow/tfjs-node": "4.22.0",
|
||||||
"bufferutil": "4.0.9",
|
"bufferutil": "4.0.9",
|
||||||
@@ -67,23 +67,23 @@
|
|||||||
"utf-8-validate": "6.0.5"
|
"utf-8-validate": "6.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "3.749.0",
|
"@aws-sdk/client-s3": "3.772.0",
|
||||||
"@aws-sdk/lib-storage": "3.749.0",
|
"@aws-sdk/lib-storage": "3.772.0",
|
||||||
"@discordapp/twemoji": "15.1.0",
|
"@discordapp/twemoji": "15.1.0",
|
||||||
"@fastify/accepts": "5.0.2",
|
"@fastify/accepts": "5.0.2",
|
||||||
"@fastify/cookie": "11.0.2",
|
"@fastify/cookie": "11.0.2",
|
||||||
"@fastify/cors": "10.0.2",
|
"@fastify/cors": "10.1.0",
|
||||||
"@fastify/express": "4.0.2",
|
"@fastify/express": "4.0.2",
|
||||||
"@fastify/http-proxy": "10.0.2",
|
"@fastify/http-proxy": "10.0.2",
|
||||||
"@fastify/multipart": "9.0.3",
|
"@fastify/multipart": "9.0.3",
|
||||||
"@fastify/static": "8.1.0",
|
"@fastify/static": "8.1.1",
|
||||||
"@fastify/view": "10.0.2",
|
"@fastify/view": "10.0.2",
|
||||||
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
||||||
"@misskey-dev/summaly": "5.2.0",
|
"@misskey-dev/summaly": "5.2.0",
|
||||||
"@napi-rs/canvas": "0.1.67",
|
"@napi-rs/canvas": "0.1.68",
|
||||||
"@nestjs/common": "11.0.9",
|
"@nestjs/common": "11.0.12",
|
||||||
"@nestjs/core": "11.0.9",
|
"@nestjs/core": "11.0.12",
|
||||||
"@nestjs/testing": "11.0.9",
|
"@nestjs/testing": "11.0.12",
|
||||||
"@peertube/http-signature": "1.7.0",
|
"@peertube/http-signature": "1.7.0",
|
||||||
"@sentry/node": "8.55.0",
|
"@sentry/node": "8.55.0",
|
||||||
"@sentry/profiling-node": "8.55.0",
|
"@sentry/profiling-node": "8.55.0",
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
"@sinonjs/fake-timers": "11.3.1",
|
"@sinonjs/fake-timers": "11.3.1",
|
||||||
"@smithy/node-http-handler": "2.5.0",
|
"@smithy/node-http-handler": "2.5.0",
|
||||||
"@swc/cli": "0.6.0",
|
"@swc/cli": "0.6.0",
|
||||||
"@swc/core": "1.10.16",
|
"@swc/core": "1.11.11",
|
||||||
"@twemoji/parser": "15.1.1",
|
"@twemoji/parser": "15.1.1",
|
||||||
"accepts": "1.3.8",
|
"accepts": "1.3.8",
|
||||||
"ajv": "8.17.1",
|
"ajv": "8.17.1",
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "2.0.5",
|
"blurhash": "2.0.5",
|
||||||
"body-parser": "1.20.3",
|
"body-parser": "1.20.3",
|
||||||
"bullmq": "5.41.1",
|
"bullmq": "5.44.1",
|
||||||
"cacheable-lookup": "7.0.0",
|
"cacheable-lookup": "7.0.0",
|
||||||
"cbor": "9.0.2",
|
"cbor": "9.0.2",
|
||||||
"chalk": "5.4.1",
|
"chalk": "5.4.1",
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
"hpagent": "1.2.0",
|
"hpagent": "1.2.0",
|
||||||
"htmlescape": "1.1.1",
|
"htmlescape": "1.1.1",
|
||||||
"http-link-header": "1.1.3",
|
"http-link-header": "1.1.3",
|
||||||
"ioredis": "5.5.0",
|
"ioredis": "5.6.0",
|
||||||
"ip-cidr": "4.0.2",
|
"ip-cidr": "4.0.2",
|
||||||
"ipaddr.js": "2.2.0",
|
"ipaddr.js": "2.2.0",
|
||||||
"is-svg": "5.1.0",
|
"is-svg": "5.1.0",
|
||||||
@@ -131,26 +131,26 @@
|
|||||||
"json5": "2.2.3",
|
"json5": "2.2.3",
|
||||||
"jsonld": "8.3.3",
|
"jsonld": "8.3.3",
|
||||||
"jsrsasign": "11.1.0",
|
"jsrsasign": "11.1.0",
|
||||||
"juice": "11.0.0",
|
"juice": "11.0.1",
|
||||||
"meilisearch": "0.48.2",
|
"meilisearch": "0.49.0",
|
||||||
"mfm-js": "0.24.0",
|
"mfm-js": "0.24.0",
|
||||||
"microformats-parser": "2.0.2",
|
"microformats-parser": "2.0.2",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"misskey-js": "workspace:*",
|
"misskey-js": "workspace:*",
|
||||||
"misskey-reversi": "workspace:*",
|
"misskey-reversi": "workspace:*",
|
||||||
"ms": "3.0.0-canary.1",
|
"ms": "3.0.0-canary.1",
|
||||||
"nanoid": "5.1.0",
|
"nanoid": "5.1.5",
|
||||||
"nested-property": "4.0.0",
|
"nested-property": "4.0.0",
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
"nodemailer": "6.10.0",
|
"nodemailer": "6.10.0",
|
||||||
"nsfwjs": "4.2.0",
|
"nsfwjs": "4.2.0",
|
||||||
"oauth": "0.10.0",
|
"oauth": "0.10.2",
|
||||||
"oauth2orize": "1.12.0",
|
"oauth2orize": "1.12.0",
|
||||||
"oauth2orize-pkce": "0.1.2",
|
"oauth2orize-pkce": "0.1.2",
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
"otpauth": "9.3.6",
|
"otpauth": "9.3.6",
|
||||||
"parse5": "7.2.1",
|
"parse5": "7.2.1",
|
||||||
"pg": "8.13.3",
|
"pg": "8.14.1",
|
||||||
"pkce-challenge": "4.1.0",
|
"pkce-challenge": "4.1.0",
|
||||||
"probe-image-size": "7.2.3",
|
"probe-image-size": "7.2.3",
|
||||||
"promise-limit": "2.7.0",
|
"promise-limit": "2.7.0",
|
||||||
@@ -163,8 +163,8 @@
|
|||||||
"reflect-metadata": "0.2.2",
|
"reflect-metadata": "0.2.2",
|
||||||
"rename": "1.0.4",
|
"rename": "1.0.4",
|
||||||
"rss-parser": "3.13.0",
|
"rss-parser": "3.13.0",
|
||||||
"rxjs": "7.8.1",
|
"rxjs": "7.8.2",
|
||||||
"sanitize-html": "2.14.0",
|
"sanitize-html": "2.15.0",
|
||||||
"secure-json-parse": "3.0.2",
|
"secure-json-parse": "3.0.2",
|
||||||
"sharp": "0.33.5",
|
"sharp": "0.33.5",
|
||||||
"slacc": "0.0.10",
|
"slacc": "0.0.10",
|
||||||
@@ -173,14 +173,14 @@
|
|||||||
"systeminformation": "5.25.11",
|
"systeminformation": "5.25.11",
|
||||||
"tinycolor2": "1.6.0",
|
"tinycolor2": "1.6.0",
|
||||||
"tmp": "0.2.3",
|
"tmp": "0.2.3",
|
||||||
"tsc-alias": "1.8.10",
|
"tsc-alias": "1.8.11",
|
||||||
"tsconfig-paths": "4.2.0",
|
"tsconfig-paths": "4.2.0",
|
||||||
"typeorm": "0.3.20",
|
"typeorm": "0.3.21",
|
||||||
"typescript": "5.7.3",
|
"typescript": "5.8.2",
|
||||||
"ulid": "2.3.0",
|
"ulid": "2.4.0",
|
||||||
"vary": "1.1.2",
|
"vary": "1.1.2",
|
||||||
"web-push": "3.6.7",
|
"web-push": "3.6.7",
|
||||||
"ws": "8.18.0",
|
"ws": "8.18.1",
|
||||||
"xev": "3.0.2"
|
"xev": "3.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
"@types/jsrsasign": "10.5.15",
|
"@types/jsrsasign": "10.5.15",
|
||||||
"@types/mime-types": "2.1.4",
|
"@types/mime-types": "2.1.4",
|
||||||
"@types/ms": "0.7.34",
|
"@types/ms": "0.7.34",
|
||||||
"@types/node": "22.13.4",
|
"@types/node": "22.13.10",
|
||||||
"@types/nodemailer": "6.4.17",
|
"@types/nodemailer": "6.4.17",
|
||||||
"@types/oauth": "0.9.6",
|
"@types/oauth": "0.9.6",
|
||||||
"@types/oauth2orize": "1.11.5",
|
"@types/oauth2orize": "1.11.5",
|
||||||
@@ -223,9 +223,9 @@
|
|||||||
"@types/tmp": "0.2.6",
|
"@types/tmp": "0.2.6",
|
||||||
"@types/vary": "1.1.3",
|
"@types/vary": "1.1.3",
|
||||||
"@types/web-push": "3.6.4",
|
"@types/web-push": "3.6.4",
|
||||||
"@types/ws": "8.5.14",
|
"@types/ws": "8.18.0",
|
||||||
"@typescript-eslint/eslint-plugin": "8.24.0",
|
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||||
"@typescript-eslint/parser": "8.24.0",
|
"@typescript-eslint/parser": "8.27.0",
|
||||||
"aws-sdk-client-mock": "4.1.0",
|
"aws-sdk-client-mock": "4.1.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from 'node:fs/promises';
|
import * as fs from 'node:fs/promises';
|
||||||
|
import { WritableStream } from 'node:stream/web';
|
||||||
import type { PathLike } from 'node:fs';
|
import type { PathLike } from 'node:fs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
"@rollup/pluginutils": "5.1.4",
|
"@rollup/pluginutils": "5.1.4",
|
||||||
"@tabler/icons-webfont": "3.31.0",
|
"@tabler/icons-webfont": "3.31.0",
|
||||||
"@twemoji/parser": "15.1.1",
|
"@twemoji/parser": "15.1.1",
|
||||||
"@vitejs/plugin-vue": "5.2.1",
|
"@vitejs/plugin-vue": "5.2.3",
|
||||||
"@vue/compiler-sfc": "3.5.13",
|
"@vue/compiler-sfc": "3.5.13",
|
||||||
"astring": "1.9.0",
|
"astring": "1.9.0",
|
||||||
"buraha": "0.0.1",
|
"buraha": "0.0.1",
|
||||||
@@ -25,16 +25,16 @@
|
|||||||
"misskey-js": "workspace:*",
|
"misskey-js": "workspace:*",
|
||||||
"frontend-shared": "workspace:*",
|
"frontend-shared": "workspace:*",
|
||||||
"punycode.js": "2.3.1",
|
"punycode.js": "2.3.1",
|
||||||
"rollup": "4.34.9",
|
"rollup": "4.36.0",
|
||||||
"sass": "1.85.1",
|
"sass": "1.86.0",
|
||||||
"shiki": "3.1.0",
|
"shiki": "3.2.1",
|
||||||
"tinycolor2": "1.6.0",
|
"tinycolor2": "1.6.0",
|
||||||
"tsc-alias": "1.8.11",
|
"tsc-alias": "1.8.11",
|
||||||
"tsconfig-paths": "4.2.0",
|
"tsconfig-paths": "4.2.0",
|
||||||
"typescript": "5.8.2",
|
"typescript": "5.8.2",
|
||||||
"uuid": "11.1.0",
|
"uuid": "11.1.0",
|
||||||
"json5": "2.2.3",
|
"json5": "2.2.3",
|
||||||
"vite": "6.2.1",
|
"vite": "6.2.2",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -42,26 +42,26 @@
|
|||||||
"@testing-library/vue": "8.1.0",
|
"@testing-library/vue": "8.1.0",
|
||||||
"@types/estree": "1.0.6",
|
"@types/estree": "1.0.6",
|
||||||
"@types/micromatch": "4.0.9",
|
"@types/micromatch": "4.0.9",
|
||||||
"@types/node": "22.13.9",
|
"@types/node": "22.13.11",
|
||||||
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
||||||
"@types/tinycolor2": "1.4.6",
|
"@types/tinycolor2": "1.4.6",
|
||||||
"@types/ws": "8.18.0",
|
"@types/ws": "8.18.0",
|
||||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||||
"@typescript-eslint/parser": "8.26.0",
|
"@typescript-eslint/parser": "8.27.0",
|
||||||
"@vitest/coverage-v8": "3.0.8",
|
"@vitest/coverage-v8": "3.0.9",
|
||||||
"@vue/runtime-core": "3.5.13",
|
"@vue/runtime-core": "3.5.13",
|
||||||
"acorn": "8.14.1",
|
"acorn": "8.14.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"eslint-plugin-vue": "10.0.0",
|
"eslint-plugin-vue": "10.0.0",
|
||||||
"fast-glob": "3.3.3",
|
"fast-glob": "3.3.3",
|
||||||
"happy-dom": "17.3.0",
|
"happy-dom": "17.4.4",
|
||||||
"intersection-observer": "0.12.2",
|
"intersection-observer": "0.12.2",
|
||||||
"micromatch": "4.0.8",
|
"micromatch": "4.0.8",
|
||||||
"msw": "2.7.3",
|
"msw": "2.7.3",
|
||||||
"nodemon": "3.1.9",
|
"nodemon": "3.1.9",
|
||||||
"prettier": "3.5.3",
|
"prettier": "3.5.3",
|
||||||
"start-server-and-test": "2.0.10",
|
"start-server-and-test": "2.0.11",
|
||||||
"vite-plugin-turbosnap": "1.0.3",
|
"vite-plugin-turbosnap": "1.0.3",
|
||||||
"vue-component-type-helpers": "2.2.8",
|
"vue-component-type-helpers": "2.2.8",
|
||||||
"vue-eslint-parser": "10.1.1",
|
"vue-eslint-parser": "10.1.1",
|
||||||
|
@@ -33,13 +33,11 @@ const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resol
|
|||||||
Math.min(navigator.hardwareConcurrency - 1, 4),
|
Math.min(navigator.hardwareConcurrency - 1, 4),
|
||||||
);
|
);
|
||||||
resolve(workers);
|
resolve(workers);
|
||||||
if (_DEV_) console.log('WebGL2 in worker is supported!');
|
|
||||||
} else {
|
} else {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = 64;
|
canvas.width = 64;
|
||||||
canvas.height = 64;
|
canvas.height = 64;
|
||||||
resolve(canvas);
|
resolve(canvas);
|
||||||
if (_DEV_) console.log('WebGL2 in worker is not supported...');
|
|
||||||
}
|
}
|
||||||
testWorker.terminate();
|
testWorker.terminate();
|
||||||
});
|
});
|
||||||
|
@@ -21,10 +21,10 @@
|
|||||||
"lint": "pnpm typecheck && pnpm eslint"
|
"lint": "pnpm typecheck && pnpm eslint"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "22.13.9",
|
"@types/node": "22.13.11",
|
||||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||||
"@typescript-eslint/parser": "8.26.0",
|
"@typescript-eslint/parser": "8.27.0",
|
||||||
"esbuild": "0.25.0",
|
"esbuild": "0.25.1",
|
||||||
"eslint-plugin-vue": "10.0.0",
|
"eslint-plugin-vue": "10.0.0",
|
||||||
"nodemon": "3.1.9",
|
"nodemon": "3.1.9",
|
||||||
"typescript": "5.8.2",
|
"typescript": "5.8.2",
|
||||||
|
@@ -131,7 +131,7 @@ export function imageDataUrl(options?: {
|
|||||||
alpha?: number,
|
alpha?: number,
|
||||||
}
|
}
|
||||||
}, seed?: string): string {
|
}, seed?: string): string {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = window.document.createElement('canvas');
|
||||||
canvas.width = options?.size?.width ?? 100;
|
canvas.width = options?.size?.width ?? 100;
|
||||||
canvas.height = options?.size?.height ?? 100;
|
canvas.height = options?.size?.height ?? 100;
|
||||||
|
|
||||||
|
@@ -23,9 +23,9 @@ let misskeyOS = null;
|
|||||||
|
|
||||||
function loadTheme(applyTheme: typeof import('../src/theme')['applyTheme']) {
|
function loadTheme(applyTheme: typeof import('../src/theme')['applyTheme']) {
|
||||||
unobserve();
|
unobserve();
|
||||||
const theme = themes[document.documentElement.dataset.misskeyTheme];
|
const theme = themes[window.document.documentElement.dataset.misskeyTheme];
|
||||||
if (theme) {
|
if (theme) {
|
||||||
applyTheme(themes[document.documentElement.dataset.misskeyTheme]);
|
applyTheme(themes[window.document.documentElement.dataset.misskeyTheme]);
|
||||||
} else {
|
} else {
|
||||||
applyTheme(themes['l-light']);
|
applyTheme(themes['l-light']);
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ function loadTheme(applyTheme: typeof import('../src/theme')['applyTheme']) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
observer.observe(document.documentElement, {
|
observer.observe(window.document.documentElement, {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
attributeFilter: ['data-misskey-theme'],
|
attributeFilter: ['data-misskey-theme'],
|
||||||
});
|
});
|
||||||
|
@@ -50,13 +50,46 @@ export default [
|
|||||||
// defineExposeが誤検知されてしまう
|
// defineExposeが誤検知されてしまう
|
||||||
'@typescript-eslint/no-unused-expressions': 'off',
|
'@typescript-eslint/no-unused-expressions': 'off',
|
||||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
||||||
// window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため
|
// window ... グローバルスコープと衝突し、予期せぬ結果を招くため
|
||||||
// e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため
|
// e ... error や event など、複数のキーワードの頭文字であり分かりにくいため
|
||||||
// close ... window.closeと衝突 or 紛らわしい
|
// close ... window.closeと衝突 or 紛らわしい
|
||||||
// open ... window.openと衝突 or 紛らわしい
|
// open ... window.openと衝突 or 紛らわしい
|
||||||
// fetch ... window.fetchと衝突 or 紛らわしい
|
// fetch ... window.fetchと衝突 or 紛らわしい
|
||||||
// location ... window.locationと衝突 or 紛らわしい
|
// location ... window.locationと衝突 or 紛らわしい
|
||||||
'id-denylist': ['error', 'window', 'e', 'close', 'open', 'fetch', 'location'],
|
// document ... window.documentと衝突 or 紛らわしい
|
||||||
|
// history ... window.historyと衝突 or 紛らわしい
|
||||||
|
'id-denylist': ['warn', 'window', 'e', 'close', 'open', 'fetch', 'location', 'document', 'history'],
|
||||||
|
'no-restricted-globals': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'name': 'open',
|
||||||
|
'message': 'Use `window.open`.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'close',
|
||||||
|
'message': 'Use `window.close`.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'fetch',
|
||||||
|
'message': 'Use `window.fetch`.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'location',
|
||||||
|
'message': 'Use `window.location`.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'document',
|
||||||
|
'message': 'Use `window.document`.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'history',
|
||||||
|
'message': 'Use `window.history`.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'name',
|
||||||
|
'message': 'Use `window.name`. もしくは name という変数名を定義し忘れている',
|
||||||
|
},
|
||||||
|
],
|
||||||
'no-shadow': ['warn'],
|
'no-shadow': ['warn'],
|
||||||
'vue/attributes-order': ['error', {
|
'vue/attributes-order': ['error', {
|
||||||
alphabetical: false,
|
alphabetical: false,
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
"@syuilo/aiscript": "0.19.0",
|
"@syuilo/aiscript": "0.19.0",
|
||||||
"@tabler/icons-webfont": "3.31.0",
|
"@tabler/icons-webfont": "3.31.0",
|
||||||
"@twemoji/parser": "15.1.1",
|
"@twemoji/parser": "15.1.1",
|
||||||
"@vitejs/plugin-vue": "5.2.1",
|
"@vitejs/plugin-vue": "5.2.3",
|
||||||
"@vue/compiler-sfc": "3.5.13",
|
"@vue/compiler-sfc": "3.5.13",
|
||||||
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
|
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
|
||||||
"analytics": "0.8.16",
|
"analytics": "0.8.16",
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
"canvas-confetti": "1.9.3",
|
"canvas-confetti": "1.9.3",
|
||||||
"chart.js": "4.4.8",
|
"chart.js": "4.4.8",
|
||||||
"chartjs-adapter-date-fns": "3.0.0",
|
"chartjs-adapter-date-fns": "3.0.0",
|
||||||
"chartjs-chart-matrix": "2.0.1",
|
"chartjs-chart-matrix": "2.1.1",
|
||||||
"chartjs-plugin-gradient": "0.6.1",
|
"chartjs-plugin-gradient": "0.6.1",
|
||||||
"chartjs-plugin-zoom": "2.2.0",
|
"chartjs-plugin-zoom": "2.2.0",
|
||||||
"chromatic": "11.27.0",
|
"chromatic": "11.27.0",
|
||||||
@@ -60,10 +60,10 @@
|
|||||||
"misskey-reversi": "workspace:*",
|
"misskey-reversi": "workspace:*",
|
||||||
"photoswipe": "5.4.4",
|
"photoswipe": "5.4.4",
|
||||||
"punycode.js": "2.3.1",
|
"punycode.js": "2.3.1",
|
||||||
"rollup": "4.34.9",
|
"rollup": "4.36.0",
|
||||||
"sanitize-html": "2.14.0",
|
"sanitize-html": "2.15.0",
|
||||||
"sass": "1.85.1",
|
"sass": "1.86.0",
|
||||||
"shiki": "3.1.0",
|
"shiki": "3.2.1",
|
||||||
"strict-event-emitter-types": "2.0.0",
|
"strict-event-emitter-types": "2.0.0",
|
||||||
"textarea-caret": "3.1.0",
|
"textarea-caret": "3.1.0",
|
||||||
"three": "0.174.0",
|
"three": "0.174.0",
|
||||||
@@ -74,54 +74,54 @@
|
|||||||
"typescript": "5.8.2",
|
"typescript": "5.8.2",
|
||||||
"uuid": "11.1.0",
|
"uuid": "11.1.0",
|
||||||
"v-code-diff": "1.13.1",
|
"v-code-diff": "1.13.1",
|
||||||
"vite": "6.2.1",
|
"vite": "6.2.2",
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.13",
|
||||||
"vuedraggable": "next",
|
"vuedraggable": "next",
|
||||||
"wanakana": "5.3.1"
|
"wanakana": "5.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@misskey-dev/summaly": "5.2.0",
|
"@misskey-dev/summaly": "5.2.0",
|
||||||
"@storybook/addon-actions": "8.6.4",
|
"@storybook/addon-actions": "8.6.7",
|
||||||
"@storybook/addon-essentials": "8.6.4",
|
"@storybook/addon-essentials": "8.6.7",
|
||||||
"@storybook/addon-interactions": "8.6.4",
|
"@storybook/addon-interactions": "8.6.7",
|
||||||
"@storybook/addon-links": "8.6.4",
|
"@storybook/addon-links": "8.6.7",
|
||||||
"@storybook/addon-mdx-gfm": "8.6.4",
|
"@storybook/addon-mdx-gfm": "8.6.7",
|
||||||
"@storybook/addon-storysource": "8.6.4",
|
"@storybook/addon-storysource": "8.6.7",
|
||||||
"@storybook/blocks": "8.6.4",
|
"@storybook/blocks": "8.6.7",
|
||||||
"@storybook/components": "8.6.4",
|
"@storybook/components": "8.6.7",
|
||||||
"@storybook/core-events": "8.6.4",
|
"@storybook/core-events": "8.6.7",
|
||||||
"@storybook/manager-api": "8.6.4",
|
"@storybook/manager-api": "8.6.7",
|
||||||
"@storybook/preview-api": "8.6.4",
|
"@storybook/preview-api": "8.6.7",
|
||||||
"@storybook/react": "8.6.4",
|
"@storybook/react": "8.6.7",
|
||||||
"@storybook/react-vite": "8.6.4",
|
"@storybook/react-vite": "8.6.7",
|
||||||
"@storybook/test": "8.6.4",
|
"@storybook/test": "8.6.7",
|
||||||
"@storybook/theming": "8.6.4",
|
"@storybook/theming": "8.6.7",
|
||||||
"@storybook/types": "8.6.4",
|
"@storybook/types": "8.6.7",
|
||||||
"@storybook/vue3": "8.6.4",
|
"@storybook/vue3": "8.6.7",
|
||||||
"@storybook/vue3-vite": "8.6.4",
|
"@storybook/vue3-vite": "8.6.7",
|
||||||
"@testing-library/vue": "8.1.0",
|
"@testing-library/vue": "8.1.0",
|
||||||
"@types/canvas-confetti": "1.9.0",
|
"@types/canvas-confetti": "1.9.0",
|
||||||
"@types/estree": "1.0.6",
|
"@types/estree": "1.0.6",
|
||||||
"@types/matter-js": "0.19.8",
|
"@types/matter-js": "0.19.8",
|
||||||
"@types/micromatch": "4.0.9",
|
"@types/micromatch": "4.0.9",
|
||||||
"@types/node": "22.13.9",
|
"@types/node": "22.13.11",
|
||||||
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
||||||
"@types/sanitize-html": "2.13.0",
|
"@types/sanitize-html": "2.13.0",
|
||||||
"@types/seedrandom": "3.0.8",
|
"@types/seedrandom": "3.0.8",
|
||||||
"@types/throttle-debounce": "5.0.2",
|
"@types/throttle-debounce": "5.0.2",
|
||||||
"@types/tinycolor2": "1.4.6",
|
"@types/tinycolor2": "1.4.6",
|
||||||
"@types/ws": "8.18.0",
|
"@types/ws": "8.18.0",
|
||||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||||
"@typescript-eslint/parser": "8.26.0",
|
"@typescript-eslint/parser": "8.27.0",
|
||||||
"@vitest/coverage-v8": "3.0.8",
|
"@vitest/coverage-v8": "3.0.9",
|
||||||
"@vue/runtime-core": "3.5.13",
|
"@vue/runtime-core": "3.5.13",
|
||||||
"acorn": "8.14.1",
|
"acorn": "8.14.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "14.1.0",
|
"cypress": "14.2.0",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"eslint-plugin-vue": "10.0.0",
|
"eslint-plugin-vue": "10.0.0",
|
||||||
"fast-glob": "3.3.3",
|
"fast-glob": "3.3.3",
|
||||||
"happy-dom": "17.3.0",
|
"happy-dom": "17.4.4",
|
||||||
"intersection-observer": "0.12.2",
|
"intersection-observer": "0.12.2",
|
||||||
"micromatch": "4.0.8",
|
"micromatch": "4.0.8",
|
||||||
"msw": "2.7.3",
|
"msw": "2.7.3",
|
||||||
@@ -131,12 +131,12 @@
|
|||||||
"react": "19.0.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"seedrandom": "3.0.5",
|
"seedrandom": "3.0.5",
|
||||||
"start-server-and-test": "2.0.10",
|
"start-server-and-test": "2.0.11",
|
||||||
"storybook": "8.6.4",
|
"storybook": "8.6.7",
|
||||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||||
"vite-node": "3.0.8",
|
"vite-node": "3.0.9",
|
||||||
"vite-plugin-turbosnap": "1.0.3",
|
"vite-plugin-turbosnap": "1.0.3",
|
||||||
"vitest": "3.0.8",
|
"vitest": "3.0.9",
|
||||||
"vitest-fetch-mock": "0.4.5",
|
"vitest-fetch-mock": "0.4.5",
|
||||||
"vue-component-type-helpers": "2.2.8",
|
"vue-component-type-helpers": "2.2.8",
|
||||||
"vue-eslint-parser": "10.1.1",
|
"vue-eslint-parser": "10.1.1",
|
||||||
|
@@ -14,7 +14,7 @@ import { subBoot } from '@/boot/sub-boot.js';
|
|||||||
|
|
||||||
const subBootPaths = ['/share', '/auth', '/miauth', '/oauth', '/signup-complete', '/install-extensions'];
|
const subBootPaths = ['/share', '/auth', '/miauth', '/oauth', '/signup-complete', '/install-extensions'];
|
||||||
|
|
||||||
if (subBootPaths.some(i => location.pathname === i || location.pathname.startsWith(i + '/'))) {
|
if (subBootPaths.some(i => window.location.pathname === i || window.location.pathname.startsWith(i + '/'))) {
|
||||||
subBoot();
|
subBoot();
|
||||||
} else {
|
} else {
|
||||||
mainBoot();
|
mainBoot();
|
||||||
|
@@ -191,7 +191,7 @@ export async function login(token: AccountWithToken['token'], redirect?: string)
|
|||||||
// 他のタブは再読み込みするだけ
|
// 他のタブは再読み込みするだけ
|
||||||
reloadChannel.postMessage(null);
|
reloadChannel.postMessage(null);
|
||||||
// このページはredirectで指定された先に移動
|
// このページはredirectで指定された先に移動
|
||||||
location.href = redirect;
|
window.location.href = redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -95,28 +95,28 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
// タッチデバイスでCSSの:hoverを機能させる
|
// タッチデバイスでCSSの:hoverを機能させる
|
||||||
document.addEventListener('touchend', () => {}, { passive: true });
|
window.document.addEventListener('touchend', () => {}, { passive: true });
|
||||||
|
|
||||||
// URLに#pswpを含む場合は取り除く
|
// URLに#pswpを含む場合は取り除く
|
||||||
if (location.hash === '#pswp') {
|
if (window.location.hash === '#pswp') {
|
||||||
history.replaceState(null, '', location.href.replace('#pswp', ''));
|
window.history.replaceState(null, '', window.location.href.replace('#pswp', ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 一斉リロード
|
// 一斉リロード
|
||||||
reloadChannel.addEventListener('message', path => {
|
reloadChannel.addEventListener('message', path => {
|
||||||
if (path !== null) location.href = path;
|
if (path !== null) window.location.href = path;
|
||||||
else location.reload();
|
else window.location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
// If mobile, insert the viewport meta tag
|
// If mobile, insert the viewport meta tag
|
||||||
if (['smartphone', 'tablet'].includes(deviceKind)) {
|
if (['smartphone', 'tablet'].includes(deviceKind)) {
|
||||||
const viewport = document.getElementsByName('viewport').item(0);
|
const viewport = window.document.getElementsByName('viewport').item(0);
|
||||||
viewport.setAttribute('content',
|
viewport.setAttribute('content',
|
||||||
`${viewport.getAttribute('content')}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`);
|
`${viewport.getAttribute('content')}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region Set lang attr
|
//#region Set lang attr
|
||||||
const html = document.documentElement;
|
const html = window.document.documentElement;
|
||||||
html.setAttribute('lang', lang);
|
html.setAttribute('lang', lang);
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@@ -130,11 +130,11 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//#region loginId
|
//#region loginId
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const loginId = params.get('loginId');
|
const loginId = params.get('loginId');
|
||||||
|
|
||||||
if (loginId) {
|
if (loginId) {
|
||||||
const target = getUrlWithoutLoginId(location.href);
|
const target = getUrlWithoutLoginId(window.location.href);
|
||||||
|
|
||||||
if (!$i || $i.id !== loginId) {
|
if (!$i || $i.id !== loginId) {
|
||||||
const account = await getAccountFromId(loginId);
|
const account = await getAccountFromId(loginId);
|
||||||
@@ -143,7 +143,7 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
history.replaceState({ misskey: 'loginId' }, '', target);
|
window.history.replaceState({ misskey: 'loginId' }, '', target);
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
);
|
);
|
||||||
}, { immediate: miLocalStorage.getItem('theme') == null });
|
}, { immediate: miLocalStorage.getItem('theme') == null });
|
||||||
|
|
||||||
document.documentElement.dataset.colorScheme = store.s.darkMode ? 'dark' : 'light';
|
window.document.documentElement.dataset.colorScheme = store.s.darkMode ? 'dark' : 'light';
|
||||||
|
|
||||||
const darkTheme = prefer.model('darkTheme');
|
const darkTheme = prefer.model('darkTheme');
|
||||||
const lightTheme = prefer.model('lightTheme');
|
const lightTheme = prefer.model('lightTheme');
|
||||||
@@ -201,20 +201,20 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
watch(prefer.r.useBlurEffectForModal, v => {
|
watch(prefer.r.useBlurEffectForModal, v => {
|
||||||
document.documentElement.style.setProperty('--MI-modalBgFilter', v ? 'blur(4px)' : 'none');
|
window.document.documentElement.style.setProperty('--MI-modalBgFilter', v ? 'blur(4px)' : 'none');
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
watch(prefer.r.useBlurEffect, v => {
|
watch(prefer.r.useBlurEffect, v => {
|
||||||
if (v) {
|
if (v) {
|
||||||
document.documentElement.style.removeProperty('--MI-blur');
|
window.document.documentElement.style.removeProperty('--MI-blur');
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.style.setProperty('--MI-blur', 'none');
|
window.document.documentElement.style.setProperty('--MI-blur', 'none');
|
||||||
}
|
}
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
// Keep screen on
|
// Keep screen on
|
||||||
const onVisibilityChange = () => document.addEventListener('visibilitychange', () => {
|
const onVisibilityChange = () => window.document.addEventListener('visibilitychange', () => {
|
||||||
if (document.visibilityState === 'visible') {
|
if (window.document.visibilityState === 'visible') {
|
||||||
navigator.wakeLock.request('screen');
|
navigator.wakeLock.request('screen');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -224,7 +224,7 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
.catch(() => {
|
.catch(() => {
|
||||||
// On WebKit-based browsers, user activation is required to send wake lock request
|
// On WebKit-based browsers, user activation is required to send wake lock request
|
||||||
// https://webkit.org/blog/13862/the-user-activation-api/
|
// https://webkit.org/blog/13862/the-user-activation-api/
|
||||||
document.addEventListener(
|
window.document.addEventListener(
|
||||||
'click',
|
'click',
|
||||||
() => navigator.wakeLock.request('screen').then(onVisibilityChange),
|
() => navigator.wakeLock.request('screen').then(onVisibilityChange),
|
||||||
{ once: true },
|
{ once: true },
|
||||||
@@ -233,7 +233,7 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prefer.s.makeEveryTextElementsSelectable) {
|
if (prefer.s.makeEveryTextElementsSelectable) {
|
||||||
document.documentElement.classList.add('forceSelectableAll');
|
window.document.documentElement.classList.add('forceSelectableAll');
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region Fetch user
|
//#region Fetch user
|
||||||
@@ -278,16 +278,16 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
const rootEl = ((): HTMLElement => {
|
const rootEl = ((): HTMLElement => {
|
||||||
const MISSKEY_MOUNT_DIV_ID = 'misskey_app';
|
const MISSKEY_MOUNT_DIV_ID = 'misskey_app';
|
||||||
|
|
||||||
const currentRoot = document.getElementById(MISSKEY_MOUNT_DIV_ID);
|
const currentRoot = window.document.getElementById(MISSKEY_MOUNT_DIV_ID);
|
||||||
|
|
||||||
if (currentRoot) {
|
if (currentRoot) {
|
||||||
console.warn('multiple import detected');
|
console.warn('multiple import detected');
|
||||||
return currentRoot;
|
return currentRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
const root = document.createElement('div');
|
const root = window.document.createElement('div');
|
||||||
root.id = MISSKEY_MOUNT_DIV_ID;
|
root.id = MISSKEY_MOUNT_DIV_ID;
|
||||||
document.body.appendChild(root);
|
window.document.body.appendChild(root);
|
||||||
return root;
|
return root;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@@ -300,24 +300,26 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
removeSplash();
|
removeSplash();
|
||||||
|
|
||||||
//#region Self-XSS 対策メッセージ
|
//#region Self-XSS 対策メッセージ
|
||||||
console.log(
|
if (!_DEV_) {
|
||||||
`%c${i18n.ts._selfXssPrevention.warning}`,
|
console.log(
|
||||||
'color: #f00; background-color: #ff0; font-size: 36px; padding: 4px;',
|
`%c${i18n.ts._selfXssPrevention.warning}`,
|
||||||
);
|
'color: #f00; background-color: #ff0; font-size: 36px; padding: 4px;',
|
||||||
console.log(
|
);
|
||||||
`%c${i18n.ts._selfXssPrevention.title}`,
|
console.log(
|
||||||
'color: #f00; font-weight: 900; font-family: "Hiragino Sans W9", "Hiragino Kaku Gothic ProN", sans-serif; font-size: 24px;',
|
`%c${i18n.ts._selfXssPrevention.title}`,
|
||||||
);
|
'color: #f00; font-weight: 900; font-family: "Hiragino Sans W9", "Hiragino Kaku Gothic ProN", sans-serif; font-size: 24px;',
|
||||||
console.log(
|
);
|
||||||
`%c${i18n.ts._selfXssPrevention.description1}`,
|
console.log(
|
||||||
'font-size: 16px; font-weight: 700;',
|
`%c${i18n.ts._selfXssPrevention.description1}`,
|
||||||
);
|
'font-size: 16px; font-weight: 700;',
|
||||||
console.log(
|
);
|
||||||
`%c${i18n.ts._selfXssPrevention.description2}`,
|
console.log(
|
||||||
'font-size: 16px;',
|
`%c${i18n.ts._selfXssPrevention.description2}`,
|
||||||
'font-size: 20px; font-weight: 700; color: #f00;',
|
'font-size: 16px;',
|
||||||
);
|
'font-size: 20px; font-weight: 700; color: #f00;',
|
||||||
console.log(i18n.tsx._selfXssPrevention.description3({ link: 'https://misskey-hub.net/docs/for-users/resources/self-xss/' }));
|
);
|
||||||
|
console.log(i18n.tsx._selfXssPrevention.description3({ link: 'https://misskey-hub.net/docs/for-users/resources/self-xss/' }));
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -328,7 +330,7 @@ export async function common(createVue: () => App<Element>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function removeSplash() {
|
function removeSplash() {
|
||||||
const splash = document.getElementById('splash');
|
const splash = window.document.getElementById('splash');
|
||||||
if (splash) {
|
if (splash) {
|
||||||
splash.style.opacity = '0';
|
splash.style.opacity = '0';
|
||||||
splash.style.pointerEvents = 'none';
|
splash.style.pointerEvents = 'none';
|
||||||
|
@@ -43,7 +43,7 @@ export async function mainBoot() {
|
|||||||
if (!$i) uiStyle = 'visitor';
|
if (!$i) uiStyle = 'visitor';
|
||||||
|
|
||||||
if (searchParams.has('zen')) uiStyle = 'zen';
|
if (searchParams.has('zen')) uiStyle = 'zen';
|
||||||
if (uiStyle === 'deck' && prefer.s['deck.useSimpleUiForNonRootPages'] && location.pathname !== '/') uiStyle = 'zen';
|
if (uiStyle === 'deck' && prefer.s['deck.useSimpleUiForNonRootPages'] && window.location.pathname !== '/') uiStyle = 'zen';
|
||||||
|
|
||||||
if (searchParams.has('ui')) uiStyle = searchParams.get('ui');
|
if (searchParams.has('ui')) uiStyle = searchParams.get('ui');
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ export async function mainBoot() {
|
|||||||
let reloadDialogShowing = false;
|
let reloadDialogShowing = false;
|
||||||
stream.on('_disconnected_', async () => {
|
stream.on('_disconnected_', async () => {
|
||||||
if (prefer.s.serverDisconnectedBehavior === 'reload') {
|
if (prefer.s.serverDisconnectedBehavior === 'reload') {
|
||||||
location.reload();
|
window.location.reload();
|
||||||
} else if (prefer.s.serverDisconnectedBehavior === 'dialog') {
|
} else if (prefer.s.serverDisconnectedBehavior === 'dialog') {
|
||||||
if (reloadDialogShowing) return;
|
if (reloadDialogShowing) return;
|
||||||
reloadDialogShowing = true;
|
reloadDialogShowing = true;
|
||||||
@@ -227,7 +227,7 @@ export async function mainBoot() {
|
|||||||
});
|
});
|
||||||
reloadDialogShowing = false;
|
reloadDialogShowing = false;
|
||||||
if (!canceled) {
|
if (!canceled) {
|
||||||
location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -398,7 +398,7 @@ export async function mainBoot() {
|
|||||||
let lastVisibilityChangedAt = Date.now();
|
let lastVisibilityChangedAt = Date.now();
|
||||||
|
|
||||||
function claimPlainLucky() {
|
function claimPlainLucky() {
|
||||||
if (document.visibilityState !== 'visible') {
|
if (window.document.visibilityState !== 'visible') {
|
||||||
if (justPlainLuckyTimer != null) window.clearTimeout(justPlainLuckyTimer);
|
if (justPlainLuckyTimer != null) window.clearTimeout(justPlainLuckyTimer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -413,7 +413,7 @@ export async function mainBoot() {
|
|||||||
window.addEventListener('visibilitychange', () => {
|
window.addEventListener('visibilitychange', () => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
if (document.visibilityState === 'visible') {
|
if (window.document.visibilityState === 'visible') {
|
||||||
// タブを高速で切り替えたら取得処理が何度も走るのを防ぐ
|
// タブを高速で切り替えたら取得処理が何度も走るのを防ぐ
|
||||||
if ((now - lastVisibilityChangedAt) < 1000 * 10) {
|
if ((now - lastVisibilityChangedAt) < 1000 * 10) {
|
||||||
justPlainLuckyTimer = window.setTimeout(claimPlainLucky, 1000 * 10);
|
justPlainLuckyTimer = window.setTimeout(claimPlainLucky, 1000 * 10);
|
||||||
@@ -458,7 +458,7 @@ export async function mainBoot() {
|
|||||||
|
|
||||||
const latestDonationInfoShownAt = miLocalStorage.getItem('latestDonationInfoShownAt');
|
const latestDonationInfoShownAt = miLocalStorage.getItem('latestDonationInfoShownAt');
|
||||||
const neverShowDonationInfo = miLocalStorage.getItem('neverShowDonationInfo');
|
const neverShowDonationInfo = miLocalStorage.getItem('neverShowDonationInfo');
|
||||||
if (neverShowDonationInfo !== 'true' && (createdAt.getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !location.pathname.startsWith('/miauth')) {
|
if (neverShowDonationInfo !== 'true' && (createdAt.getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !window.location.pathname.startsWith('/miauth')) {
|
||||||
if (latestDonationInfoShownAt == null || (new Date(latestDonationInfoShownAt).getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 30)))) {
|
if (latestDonationInfoShownAt == null || (new Date(latestDonationInfoShownAt).getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 30)))) {
|
||||||
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDonation.vue')), {}, {
|
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDonation.vue')), {}, {
|
||||||
closed: () => dispose(),
|
closed: () => dispose(),
|
||||||
@@ -554,7 +554,7 @@ export async function mainBoot() {
|
|||||||
mainRouter.push('/search');
|
mainRouter.push('/search');
|
||||||
},
|
},
|
||||||
} as const satisfies Keymap;
|
} as const satisfies Keymap;
|
||||||
document.addEventListener('keydown', makeHotkey(keymap), { passive: false });
|
window.document.addEventListener('keydown', makeHotkey(keymap), { passive: false });
|
||||||
|
|
||||||
initializeSw();
|
initializeSw();
|
||||||
}
|
}
|
||||||
|
@@ -192,7 +192,7 @@ function tick() {
|
|||||||
tick();
|
tick();
|
||||||
|
|
||||||
function calcColors() {
|
function calcColors() {
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||||
const dark = tinycolor(computedStyle.getPropertyValue('--MI_THEME-bg')).isDark();
|
const dark = tinycolor(computedStyle.getPropertyValue('--MI_THEME-bg')).isDark();
|
||||||
const accent = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString();
|
const accent = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString();
|
||||||
majorGraduationColor.value = dark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)';
|
majorGraduationColor.value = dark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)';
|
||||||
|
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<canvas ref="canvasEl" style="width: 100%; height: 100%; pointer-events: none;"></canvas>
|
<canvas ref="canvasEl" style="display: block; width: 100%; height: 100%; pointer-events: none;"></canvas>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -359,7 +359,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
props.textarea.addEventListener('keydown', onKeydown);
|
props.textarea.addEventListener('keydown', onKeydown);
|
||||||
|
|
||||||
document.body.addEventListener('mousedown', onMousedown);
|
window.document.body.addEventListener('mousedown', onMousedown);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
exec();
|
exec();
|
||||||
@@ -375,7 +375,7 @@ onMounted(() => {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
props.textarea.removeEventListener('keydown', onKeydown);
|
props.textarea.removeEventListener('keydown', onKeydown);
|
||||||
|
|
||||||
document.body.removeEventListener('mousedown', onMousedown);
|
window.document.body.removeEventListener('mousedown', onMousedown);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -92,7 +92,7 @@ function onMousedown(evt: MouseEvent): void {
|
|||||||
const target = evt.target! as HTMLElement;
|
const target = evt.target! as HTMLElement;
|
||||||
const rect = target.getBoundingClientRect();
|
const rect = target.getBoundingClientRect();
|
||||||
|
|
||||||
const ripple = document.createElement('div');
|
const ripple = window.document.createElement('div');
|
||||||
ripple.classList.add(ripples.value!.dataset.childrenClass!);
|
ripple.classList.add(ripples.value!.dataset.childrenClass!);
|
||||||
ripple.style.top = (evt.clientY - rect.top - 1).toString() + 'px';
|
ripple.style.top = (evt.clientY - rect.top - 1).toString() + 'px';
|
||||||
ripple.style.left = (evt.clientX - rect.left - 1).toString() + 'px';
|
ripple.style.left = (evt.clientX - rect.left - 1).toString() + 'px';
|
||||||
|
@@ -112,7 +112,7 @@ watch(() => [props.instanceUrl, props.sitekey, props.secretKey], async () => {
|
|||||||
if (loaded || props.provider === 'mcaptcha' || props.provider === 'testcaptcha') {
|
if (loaded || props.provider === 'mcaptcha' || props.provider === 'testcaptcha') {
|
||||||
available.value = true;
|
available.value = true;
|
||||||
} else if (src.value !== null) {
|
} else if (src.value !== null) {
|
||||||
(document.getElementById(scriptId.value) ?? document.head.appendChild(Object.assign(document.createElement('script'), {
|
(window.document.getElementById(scriptId.value) ?? window.document.head.appendChild(Object.assign(window.document.createElement('script'), {
|
||||||
async: true,
|
async: true,
|
||||||
id: scriptId.value,
|
id: scriptId.value,
|
||||||
src: src.value,
|
src: src.value,
|
||||||
@@ -149,7 +149,7 @@ async function requestRender() {
|
|||||||
if (captcha.value.render && captchaEl.value instanceof Element && props.sitekey) {
|
if (captcha.value.render && captchaEl.value instanceof Element && props.sitekey) {
|
||||||
// reCAPTCHAのレンダリング重複判定を回避するため、captchaEl配下に仮のdivを用意する.
|
// reCAPTCHAのレンダリング重複判定を回避するため、captchaEl配下に仮のdivを用意する.
|
||||||
// (同じdivに対して複数回renderを呼び出すとreCAPTCHAはエラーを返すので)
|
// (同じdivに対して複数回renderを呼び出すとreCAPTCHAはエラーを返すので)
|
||||||
const elem = document.createElement('div');
|
const elem = window.document.createElement('div');
|
||||||
captchaEl.value.appendChild(elem);
|
captchaEl.value.appendChild(elem);
|
||||||
|
|
||||||
captchaWidgetId.value = captcha.value.render(elem, {
|
captchaWidgetId.value = captcha.value.render(elem, {
|
||||||
@@ -174,7 +174,7 @@ async function requestRender() {
|
|||||||
|
|
||||||
function clearWidget() {
|
function clearWidget() {
|
||||||
if (props.provider === 'mcaptcha') {
|
if (props.provider === 'mcaptcha') {
|
||||||
const container = document.getElementById('mcaptcha__widget-container');
|
const container = window.document.getElementById('mcaptcha__widget-container');
|
||||||
if (container) {
|
if (container) {
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
@@ -68,11 +68,11 @@ onMounted(() => {
|
|||||||
rootEl.value.style.left = `${left}px`;
|
rootEl.value.style.left = `${left}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.addEventListener('mousedown', onMousedown);
|
window.document.body.addEventListener('mousedown', onMousedown);
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.body.removeEventListener('mousedown', onMousedown);
|
window.document.body.removeEventListener('mousedown', onMousedown);
|
||||||
});
|
});
|
||||||
|
|
||||||
function onMousedown(evt: Event) {
|
function onMousedown(evt: Event) {
|
||||||
|
@@ -3,14 +3,12 @@
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
||||||
/* eslint-disable import/no-default-export */
|
|
||||||
import type { StoryObj } from '@storybook/vue3';
|
|
||||||
import { HttpResponse, http } from 'msw';
|
import { HttpResponse, http } from 'msw';
|
||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
import { file } from '../../.storybook/fakes.js';
|
import { file } from '../../.storybook/fakes.js';
|
||||||
import { commonHandlers } from '../../.storybook/mocks.js';
|
import { commonHandlers } from '../../.storybook/mocks.js';
|
||||||
import MkCropperDialog from './MkCropperDialog.vue';
|
import MkCropperDialog from './MkCropperDialog.vue';
|
||||||
|
import type { StoryObj } from '@storybook/vue3';
|
||||||
export const Default = {
|
export const Default = {
|
||||||
render(args) {
|
render(args) {
|
||||||
return {
|
return {
|
||||||
@@ -55,7 +53,7 @@ export const Default = {
|
|||||||
http.get('/proxy/image.webp', async ({ request }) => {
|
http.get('/proxy/image.webp', async ({ request }) => {
|
||||||
const url = new URL(request.url).searchParams.get('url');
|
const url = new URL(request.url).searchParams.get('url');
|
||||||
if (url === 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true') {
|
if (url === 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true') {
|
||||||
const image = await (await fetch('client-assets/fedi.jpg')).blob();
|
const image = await (await window.fetch('client-assets/fedi.jpg')).blob();
|
||||||
return new HttpResponse(image, {
|
return new HttpResponse(image, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'image/jpeg',
|
'Content-Type': 'image/jpeg',
|
||||||
|
@@ -122,7 +122,7 @@ onMounted(() => {
|
|||||||
cropper = new Cropper(imgEl.value!, {
|
cropper = new Cropper(imgEl.value!, {
|
||||||
});
|
});
|
||||||
|
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||||
|
|
||||||
const selection = cropper.getCropperSelection()!;
|
const selection = cropper.getCropperSelection()!;
|
||||||
selection.themeColor = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString();
|
selection.themeColor = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString();
|
||||||
|
@@ -180,7 +180,7 @@ function applyToPreview() {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (currentPreviewUrl === embedPreviewUrl.value) {
|
if (currentPreviewUrl === embedPreviewUrl.value) {
|
||||||
// URLが変わらなくてもリロード
|
// URLが変わらなくてもリロード
|
||||||
iframeEl.value?.contentWindow?.location.reload();
|
iframeEl.value?.contentWindow?.window.location.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -116,7 +116,7 @@ function toggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||||
const parentBg = getBgColor(rootEl.value?.parentElement) ?? 'transparent';
|
const parentBg = getBgColor(rootEl.value?.parentElement) ?? 'transparent';
|
||||||
const myBg = computedStyle.getPropertyValue('--MI_THEME-panel');
|
const myBg = computedStyle.getPropertyValue('--MI_THEME-panel');
|
||||||
bgSame.value = parentBg === myBg;
|
bgSame.value = parentBg === myBg;
|
||||||
|
@@ -19,9 +19,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
:leaveToClass="transitionName === 'swipeAnimationLeft' ? $style.swipeAnimationLeft_leaveTo : $style.swipeAnimationRight_leaveTo"
|
:leaveToClass="transitionName === 'swipeAnimationLeft' ? $style.swipeAnimationLeft_leaveTo : $style.swipeAnimationRight_leaveTo"
|
||||||
:style="`--swipe: ${pullDistance}px;`"
|
:style="`--swipe: ${pullDistance}px;`"
|
||||||
>
|
>
|
||||||
<!-- 【注意】slot内の最上位要素に動的にkeyを設定すること -->
|
<div :key="tabModel">
|
||||||
<!-- 各最上位要素にユニークなkeyの指定がないとTransitionがうまく動きません -->
|
<slot></slot>
|
||||||
<slot></slot>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -55,7 +55,7 @@ import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurha
|
|||||||
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
||||||
// テスト環境で Web Worker インスタンスは作成できない
|
// テスト環境で Web Worker インスタンスは作成できない
|
||||||
if (import.meta.env.MODE === 'test') {
|
if (import.meta.env.MODE === 'test') {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = window.document.createElement('canvas');
|
||||||
canvas.width = 64;
|
canvas.width = 64;
|
||||||
canvas.height = 64;
|
canvas.height = 64;
|
||||||
resolve(canvas);
|
resolve(canvas);
|
||||||
@@ -69,13 +69,11 @@ const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resol
|
|||||||
Math.min(navigator.hardwareConcurrency - 1, 4),
|
Math.min(navigator.hardwareConcurrency - 1, 4),
|
||||||
);
|
);
|
||||||
resolve(workers);
|
resolve(workers);
|
||||||
if (_DEV_) console.log('WebGL2 in worker is supported!');
|
|
||||||
} else {
|
} else {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = window.document.createElement('canvas');
|
||||||
canvas.width = 64;
|
canvas.width = 64;
|
||||||
canvas.height = 64;
|
canvas.height = 64;
|
||||||
resolve(canvas);
|
resolve(canvas);
|
||||||
if (_DEV_) console.log('WebGL2 in worker is not supported...');
|
|
||||||
}
|
}
|
||||||
testWorker.terminate();
|
testWorker.terminate();
|
||||||
});
|
});
|
||||||
|
@@ -3,13 +3,12 @@
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
||||||
import type { StoryObj } from '@storybook/vue3';
|
|
||||||
import { HttpResponse, http } from 'msw';
|
import { HttpResponse, http } from 'msw';
|
||||||
import { federationInstance } from '../../.storybook/fakes.js';
|
import { federationInstance } from '../../.storybook/fakes.js';
|
||||||
import { commonHandlers } from '../../.storybook/mocks.js';
|
import { commonHandlers } from '../../.storybook/mocks.js';
|
||||||
import { getChartResolver } from '../../.storybook/charts.js';
|
import { getChartResolver } from '../../.storybook/charts.js';
|
||||||
import MkInstanceCardMini from './MkInstanceCardMini.vue';
|
import MkInstanceCardMini from './MkInstanceCardMini.vue';
|
||||||
|
import type { StoryObj } from '@storybook/vue3';
|
||||||
|
|
||||||
export const Default = {
|
export const Default = {
|
||||||
render(args) {
|
render(args) {
|
||||||
@@ -48,7 +47,7 @@ export const Default = {
|
|||||||
const url = new URL(urlStr);
|
const url = new URL(urlStr);
|
||||||
|
|
||||||
if (url.href.startsWith('https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/')) {
|
if (url.href.startsWith('https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/')) {
|
||||||
const image = await (await fetch(`client-assets/${url.pathname.split('/').pop()}`)).blob();
|
const image = await (await window.fetch(`client-assets/${url.pathname.split('/').pop()}`)).blob();
|
||||||
return new HttpResponse(image, {
|
return new HttpResponse(image, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'image/jpeg',
|
'Content-Type': 'image/jpeg',
|
||||||
|
@@ -126,7 +126,7 @@ function createDoughnut(chartEl, tooltip, data) {
|
|||||||
labels: data.map(x => x.name),
|
labels: data.map(x => x.name),
|
||||||
datasets: [{
|
datasets: [{
|
||||||
backgroundColor: data.map(x => x.color),
|
backgroundColor: data.map(x => x.color),
|
||||||
borderColor: getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel'),
|
borderColor: getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'),
|
||||||
borderWidth: 2,
|
borderWidth: 2,
|
||||||
hoverOffset: 0,
|
hoverOffset: 0,
|
||||||
data: data.map(x => x.value),
|
data: data.map(x => x.value),
|
||||||
|
@@ -148,7 +148,7 @@ const keymap = {
|
|||||||
// PlayerElもしくはその子要素にフォーカスがあるかどうか
|
// PlayerElもしくはその子要素にフォーカスがあるかどうか
|
||||||
function hasFocus() {
|
function hasFocus() {
|
||||||
if (!playerEl.value) return false;
|
if (!playerEl.value) return false;
|
||||||
return playerEl.value === document.activeElement || playerEl.value.contains(document.activeElement);
|
return playerEl.value === window.document.activeElement || playerEl.value.contains(window.document.activeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
const playerEl = useTemplateRef('playerEl');
|
const playerEl = useTemplateRef('playerEl');
|
||||||
|
@@ -48,7 +48,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const gallery = useTemplateRef('gallery');
|
const gallery = useTemplateRef('gallery');
|
||||||
const pswpZIndex = os.claimZIndex('middle');
|
const pswpZIndex = os.claimZIndex('middle');
|
||||||
document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString());
|
window.document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString());
|
||||||
const count = computed(() => props.mediaList.filter(media => previewable(media)).length);
|
const count = computed(() => props.mediaList.filter(media => previewable(media)).length);
|
||||||
let lightbox: PhotoSwipeLightbox | null = null;
|
let lightbox: PhotoSwipeLightbox | null = null;
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ onMounted(() => {
|
|||||||
className: 'pswp__alt-text-container',
|
className: 'pswp__alt-text-container',
|
||||||
appendTo: 'wrapper',
|
appendTo: 'wrapper',
|
||||||
onInit: (el, pswp) => {
|
onInit: (el, pswp) => {
|
||||||
const textBox = document.createElement('p');
|
const textBox = window.document.createElement('p');
|
||||||
textBox.className = 'pswp__alt-text _acrylic';
|
textBox.className = 'pswp__alt-text _acrylic';
|
||||||
el.appendChild(textBox);
|
el.appendChild(textBox);
|
||||||
|
|
||||||
@@ -178,19 +178,19 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
lightbox.on('afterInit', () => {
|
lightbox.on('afterInit', () => {
|
||||||
activeEl = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
activeEl = window.document.activeElement instanceof HTMLElement ? window.document.activeElement : null;
|
||||||
focusParent(activeEl, true, true);
|
focusParent(activeEl, true, true);
|
||||||
lightbox?.pswp?.element?.focus({
|
lightbox?.pswp?.element?.focus({
|
||||||
preventScroll: true,
|
preventScroll: true,
|
||||||
});
|
});
|
||||||
history.pushState(null, '', '#pswp');
|
window.history.pushState(null, '', '#pswp');
|
||||||
});
|
});
|
||||||
|
|
||||||
lightbox.on('destroy', () => {
|
lightbox.on('destroy', () => {
|
||||||
focusParent(activeEl, true, false);
|
focusParent(activeEl, true, false);
|
||||||
activeEl = null;
|
activeEl = null;
|
||||||
if (window.location.hash === '#pswp') {
|
if (window.location.hash === '#pswp') {
|
||||||
history.back();
|
window.history.back();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -171,7 +171,7 @@ const keymap = {
|
|||||||
// PlayerElもしくはその子要素にフォーカスがあるかどうか
|
// PlayerElもしくはその子要素にフォーカスがあるかどうか
|
||||||
function hasFocus() {
|
function hasFocus() {
|
||||||
if (!playerEl.value) return false;
|
if (!playerEl.value) return false;
|
||||||
return playerEl.value === document.activeElement || playerEl.value.contains(document.activeElement);
|
return playerEl.value === window.document.activeElement || playerEl.value.contains(window.document.activeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
|
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
|
||||||
@@ -216,7 +216,7 @@ function showMenu(ev: MouseEvent) {
|
|||||||
'2.0x': 2,
|
'2.0x': 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...(document.pictureInPictureEnabled ? [{
|
...(window.document.pictureInPictureEnabled ? [{
|
||||||
text: i18n.ts._mediaControls.pip,
|
text: i18n.ts._mediaControls.pip,
|
||||||
icon: 'ti ti-picture-in-picture',
|
icon: 'ti ti-picture-in-picture',
|
||||||
action: togglePictureInPicture,
|
action: togglePictureInPicture,
|
||||||
@@ -384,8 +384,8 @@ function toggleFullscreen() {
|
|||||||
|
|
||||||
function togglePictureInPicture() {
|
function togglePictureInPicture() {
|
||||||
if (videoEl.value) {
|
if (videoEl.value) {
|
||||||
if (document.pictureInPictureElement) {
|
if (window.document.pictureInPictureElement) {
|
||||||
document.exitPictureInPicture();
|
window.document.exitPictureInPicture();
|
||||||
} else {
|
} else {
|
||||||
videoEl.value.requestPictureInPicture();
|
videoEl.value.requestPictureInPicture();
|
||||||
}
|
}
|
||||||
|
@@ -358,10 +358,10 @@ function switchItem(item: MenuSwitch & { ref: any }) {
|
|||||||
|
|
||||||
function focusUp() {
|
function focusUp() {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
if (!itemsEl.value?.contains(document.activeElement)) return;
|
if (!itemsEl.value?.contains(window.document.activeElement)) return;
|
||||||
|
|
||||||
const focusableElements = Array.from(itemsEl.value.children).filter(isFocusable);
|
const focusableElements = Array.from(itemsEl.value.children).filter(isFocusable);
|
||||||
const activeIndex = focusableElements.findIndex(el => el === document.activeElement);
|
const activeIndex = focusableElements.findIndex(el => el === window.document.activeElement);
|
||||||
const targetIndex = (activeIndex !== -1 && activeIndex !== 0) ? (activeIndex - 1) : (focusableElements.length - 1);
|
const targetIndex = (activeIndex !== -1 && activeIndex !== 0) ? (activeIndex - 1) : (focusableElements.length - 1);
|
||||||
const targetElement = focusableElements.at(targetIndex) ?? itemsEl.value;
|
const targetElement = focusableElements.at(targetIndex) ?? itemsEl.value;
|
||||||
|
|
||||||
@@ -370,10 +370,10 @@ function focusUp() {
|
|||||||
|
|
||||||
function focusDown() {
|
function focusDown() {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
if (!itemsEl.value?.contains(document.activeElement)) return;
|
if (!itemsEl.value?.contains(window.document.activeElement)) return;
|
||||||
|
|
||||||
const focusableElements = Array.from(itemsEl.value.children).filter(isFocusable);
|
const focusableElements = Array.from(itemsEl.value.children).filter(isFocusable);
|
||||||
const activeIndex = focusableElements.findIndex(el => el === document.activeElement);
|
const activeIndex = focusableElements.findIndex(el => el === window.document.activeElement);
|
||||||
const targetIndex = (activeIndex !== -1 && activeIndex !== (focusableElements.length - 1)) ? (activeIndex + 1) : 0;
|
const targetIndex = (activeIndex !== -1 && activeIndex !== (focusableElements.length - 1)) ? (activeIndex + 1) : 0;
|
||||||
const targetElement = focusableElements.at(targetIndex) ?? itemsEl.value;
|
const targetElement = focusableElements.at(targetIndex) ?? itemsEl.value;
|
||||||
|
|
||||||
@@ -400,9 +400,9 @@ const onGlobalMousedown = (ev: MouseEvent) => {
|
|||||||
|
|
||||||
const setupHandlers = () => {
|
const setupHandlers = () => {
|
||||||
if (!isNestingMenu) {
|
if (!isNestingMenu) {
|
||||||
document.addEventListener('focusin', onGlobalFocusin, { passive: true });
|
window.document.addEventListener('focusin', onGlobalFocusin, { passive: true });
|
||||||
}
|
}
|
||||||
document.addEventListener('mousedown', onGlobalMousedown, { passive: true });
|
window.document.addEventListener('mousedown', onGlobalMousedown, { passive: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
let disposed = false;
|
let disposed = false;
|
||||||
@@ -410,9 +410,9 @@ let disposed = false;
|
|||||||
const disposeHandlers = () => {
|
const disposeHandlers = () => {
|
||||||
disposed = true;
|
disposed = true;
|
||||||
if (!isNestingMenu) {
|
if (!isNestingMenu) {
|
||||||
document.removeEventListener('focusin', onGlobalFocusin);
|
window.document.removeEventListener('focusin', onGlobalFocusin);
|
||||||
}
|
}
|
||||||
document.removeEventListener('mousedown', onGlobalMousedown);
|
window.document.removeEventListener('mousedown', onGlobalMousedown);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@@ -48,7 +48,7 @@ const polygonPoints = ref('');
|
|||||||
const headX = ref<number | null>(null);
|
const headX = ref<number | null>(null);
|
||||||
const headY = ref<number | null>(null);
|
const headY = ref<number | null>(null);
|
||||||
const clock = ref<number | null>(null);
|
const clock = ref<number | null>(null);
|
||||||
const accent = tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-accent'));
|
const accent = tinycolor(getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-accent'));
|
||||||
const color = accent.toRgbString();
|
const color = accent.toRgbString();
|
||||||
|
|
||||||
function draw(): void {
|
function draw(): void {
|
||||||
|
@@ -59,7 +59,7 @@ const pagination = computed(() => prefer.r.useGroupedNotifications.value ? {
|
|||||||
|
|
||||||
function onNotification(notification) {
|
function onNotification(notification) {
|
||||||
const isMuted = props.excludeTypes ? props.excludeTypes.includes(notification.type) : false;
|
const isMuted = props.excludeTypes ? props.excludeTypes.includes(notification.type) : false;
|
||||||
if (isMuted || document.visibilityState === 'visible') {
|
if (isMuted || window.document.visibilityState === 'visible') {
|
||||||
useStream().send('readNotification');
|
useStream().send('readNotification');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -142,7 +142,7 @@ const {
|
|||||||
} = prefer.r;
|
} = prefer.r;
|
||||||
|
|
||||||
const contentEl = computed(() => props.pagination.pageEl ?? rootEl.value);
|
const contentEl = computed(() => props.pagination.pageEl ?? rootEl.value);
|
||||||
const scrollableElement = computed(() => contentEl.value ? getScrollContainer(contentEl.value) : document.body);
|
const scrollableElement = computed(() => contentEl.value ? getScrollContainer(contentEl.value) : window.document.body);
|
||||||
|
|
||||||
const visibility = useDocumentVisibility();
|
const visibility = useDocumentVisibility();
|
||||||
|
|
||||||
|
@@ -151,9 +151,9 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
|
|||||||
closed: () => dispose(),
|
closed: () => dispose(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const style = document.createElement('style');
|
const style = window.document.createElement('style');
|
||||||
style.appendChild(document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }'));
|
style.appendChild(window.document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }'));
|
||||||
document.head.appendChild(style);
|
window.document.head.appendChild(style);
|
||||||
|
|
||||||
const thumbWidth = getThumbWidth();
|
const thumbWidth = getThumbWidth();
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
|
|||||||
let beforeValue = finalValue.value;
|
let beforeValue = finalValue.value;
|
||||||
|
|
||||||
const onMouseup = () => {
|
const onMouseup = () => {
|
||||||
document.head.removeChild(style);
|
window.document.head.removeChild(style);
|
||||||
tooltipForDragShowing.value = false;
|
tooltipForDragShowing.value = false;
|
||||||
window.removeEventListener('mousemove', onDrag);
|
window.removeEventListener('mousemove', onDrag);
|
||||||
window.removeEventListener('touchmove', onDrag);
|
window.removeEventListener('touchmove', onDrag);
|
||||||
|
@@ -136,7 +136,7 @@ async function menu(ev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function anime() {
|
function anime() {
|
||||||
if (document.hidden || !prefer.s.animation || buttonEl.value == null) return;
|
if (window.document.hidden || !prefer.s.animation || buttonEl.value == null) return;
|
||||||
|
|
||||||
const rect = buttonEl.value.getBoundingClientRect();
|
const rect = buttonEl.value.getBoundingClientRect();
|
||||||
const x = rect.left + 16;
|
const x = rect.left + 16;
|
||||||
|
@@ -44,7 +44,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
|
const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
|
||||||
|
|
||||||
const accent = tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-accent'));
|
const accent = tinycolor(getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-accent'));
|
||||||
const color = accent.toHex();
|
const color = accent.toHex();
|
||||||
|
|
||||||
if (chartEl.value == null) return;
|
if (chartEl.value == null) return;
|
||||||
|
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
:width="400"
|
:width="400"
|
||||||
:height="500"
|
:height="500"
|
||||||
@close="onCloseModalWindow"
|
@close="onCloseModalWindow"
|
||||||
@closed="console.log('MkRoleSelectDialog: closed') ; $emit('dispose')"
|
@closed="emit('closed')"
|
||||||
>
|
>
|
||||||
<template #header>{{ title }}</template>
|
<template #header>{{ title }}</template>
|
||||||
<MkSpacer :marginMin="20" :marginMax="28">
|
<MkSpacer :marginMin="20" :marginMax="28">
|
||||||
@@ -58,7 +58,7 @@ import MkLoading from '@/components/global/MkLoading.vue';
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: 'done', value: Misskey.entities.Role[]),
|
(ev: 'done', value: Misskey.entities.Role[]),
|
||||||
(ev: 'close'),
|
(ev: 'close'),
|
||||||
(ev: 'dispose'),
|
(ev: 'closed'),
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
|
@@ -267,7 +267,7 @@ async function onSubmit(): Promise<void> {
|
|||||||
'testcaptcha-response': testcaptchaResponse.value,
|
'testcaptcha-response': testcaptchaResponse.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await fetch(`${config.apiUrl}/signup`, {
|
const res = await window.fetch(`${config.apiUrl}/signup`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
@@ -20,7 +20,7 @@ import tinycolor from 'tinycolor2';
|
|||||||
|
|
||||||
const loaded = !!window.TagCanvas;
|
const loaded = !!window.TagCanvas;
|
||||||
const SAFE_FOR_HTML_ID = 'abcdefghijklmnopqrstuvwxyz';
|
const SAFE_FOR_HTML_ID = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||||
const idForCanvas = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
|
const idForCanvas = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
|
||||||
const idForTags = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
|
const idForTags = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
|
||||||
const available = ref(false);
|
const available = ref(false);
|
||||||
@@ -57,7 +57,7 @@ onMounted(() => {
|
|||||||
if (loaded) {
|
if (loaded) {
|
||||||
available.value = true;
|
available.value = true;
|
||||||
} else {
|
} else {
|
||||||
document.head.appendChild(Object.assign(document.createElement('script'), {
|
window.document.head.appendChild(Object.assign(window.document.createElement('script'), {
|
||||||
async: true,
|
async: true,
|
||||||
src: '/client-assets/tagcanvas.min.js',
|
src: '/client-assets/tagcanvas.min.js',
|
||||||
})).addEventListener('load', () => available.value = true);
|
})).addEventListener('load', () => available.value = true);
|
||||||
|
@@ -61,7 +61,7 @@ async function renderChart() {
|
|||||||
|
|
||||||
const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
|
const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
|
||||||
|
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||||
const accent = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString();
|
const accent = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString();
|
||||||
|
|
||||||
const colorRead = accent;
|
const colorRead = accent;
|
||||||
|
@@ -240,7 +240,7 @@ function onHeaderMousedown(evt: MouseEvent | TouchEvent) {
|
|||||||
const main = rootEl.value;
|
const main = rootEl.value;
|
||||||
if (main == null) return;
|
if (main == null) return;
|
||||||
|
|
||||||
if (!contains(main, document.activeElement)) main.focus();
|
if (!contains(main, window.document.activeElement)) main.focus();
|
||||||
|
|
||||||
const position = main.getBoundingClientRect();
|
const position = main.getBoundingClientRect();
|
||||||
|
|
||||||
|
@@ -87,7 +87,7 @@ function openWindow() {
|
|||||||
|
|
||||||
function nav(ev: MouseEvent) {
|
function nav(ev: MouseEvent) {
|
||||||
if (behavior === 'browser') {
|
if (behavior === 'browser') {
|
||||||
location.href = props.to;
|
window.location.href = props.to;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -170,7 +170,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
if (props.rootEl) {
|
if (props.rootEl) {
|
||||||
ro2 = new ResizeObserver((entries, observer) => {
|
ro2 = new ResizeObserver((entries, observer) => {
|
||||||
if (document.body.contains(el.value as HTMLElement)) {
|
if (window.document.body.contains(el.value as HTMLElement)) {
|
||||||
nextTick(() => renderTab());
|
nextTick(() => renderTab());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -69,6 +69,8 @@ const emit = defineEmits<{
|
|||||||
(ev: 'update:tab', key: string);
|
(ev: 'update:tab', key: string);
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const viewId = inject(DI.viewId);
|
||||||
|
const viewTransitionName = computed(() => `${viewId}---pageHeader`);
|
||||||
const injectedPageMetadata = inject(DI.pageMetadata);
|
const injectedPageMetadata = inject(DI.pageMetadata);
|
||||||
const pageMetadata = computed(() => props.overridePageMetadata ?? injectedPageMetadata.value);
|
const pageMetadata = computed(() => props.overridePageMetadata ?? injectedPageMetadata.value);
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@ function onTabClick(): void {
|
|||||||
|
|
||||||
const calcBg = () => {
|
const calcBg = () => {
|
||||||
const rawBg = 'var(--MI_THEME-bg)';
|
const rawBg = 'var(--MI_THEME-bg)';
|
||||||
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(window.document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
||||||
tinyBg.setAlpha(0.85);
|
tinyBg.setAlpha(0.85);
|
||||||
bg.value = tinyBg.toRgbString();
|
bg.value = tinyBg.toRgbString();
|
||||||
};
|
};
|
||||||
@@ -120,7 +122,7 @@ onMounted(() => {
|
|||||||
if (el.value && el.value.parentElement) {
|
if (el.value && el.value.parentElement) {
|
||||||
narrow.value = el.value.parentElement.offsetWidth < 500;
|
narrow.value = el.value.parentElement.offsetWidth < 500;
|
||||||
ro = new ResizeObserver((entries, observer) => {
|
ro = new ResizeObserver((entries, observer) => {
|
||||||
if (el.value && el.value.parentElement && document.body.contains(el.value as HTMLElement)) {
|
if (el.value && el.value.parentElement && window.document.body.contains(el.value as HTMLElement)) {
|
||||||
narrow.value = el.value.parentElement.offsetWidth < 500;
|
narrow.value = el.value.parentElement.offsetWidth < 500;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -140,6 +142,7 @@ onUnmounted(() => {
|
|||||||
backdrop-filter: var(--MI-blur, blur(15px));
|
backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
border-bottom: solid 0.5px var(--MI_THEME-divider);
|
border-bottom: solid 0.5px var(--MI_THEME-divider);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
view-transition-name: v-bind(viewTransitionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upper,
|
.upper,
|
||||||
|
21
packages/frontend/src/components/global/PageWithAnimBg.vue
Normal file
21
packages/frontend/src/components/global/PageWithAnimBg.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<MkAnimBg style="position: absolute;"/>
|
||||||
|
<div class="_pageScrollable" style="position: absolute; top: 0; width: 100%; height: 100%;">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import MkAnimBg from '@/components/MkAnimBg.vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
|
||||||
|
</style>
|
32
packages/frontend/src/components/global/PageWithHeader.vue
Normal file
32
packages/frontend/src/components/global/PageWithHeader.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MkStickyContainer class="_pageScrollable">
|
||||||
|
<template #header><MkPageHeader v-model:tab="tab" :actions="actions" :tabs="tabs"/></template>
|
||||||
|
<slot></slot>
|
||||||
|
</MkStickyContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { PageHeaderItem } from '@/types/page-header.js';
|
||||||
|
import type { Tab } from './MkPageHeader.tabs.vue';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
tabs?: Tab[];
|
||||||
|
actions?: PageHeaderItem[] | null;
|
||||||
|
thin?: boolean;
|
||||||
|
hideTitle?: boolean;
|
||||||
|
displayMyAvatar?: boolean;
|
||||||
|
}>(), {
|
||||||
|
tabs: () => ([] as Tab[]),
|
||||||
|
});
|
||||||
|
|
||||||
|
const tab = defineModel<string>('tab');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
|
||||||
|
</style>
|
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="_pageContainer" style="height: 100%;">
|
<div ref="rootEl" class="_pageContainer" :class="$style.root">
|
||||||
<KeepAlive :max="prefer.s.numberOfPageCache">
|
<KeepAlive :max="prefer.s.numberOfPageCache">
|
||||||
<Suspense :timeout="0">
|
<Suspense :timeout="0">
|
||||||
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
|
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
|
||||||
@@ -18,11 +18,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { inject, provide, ref, shallowRef } from 'vue';
|
import { inject, nextTick, onMounted, provide, ref, shallowRef, useTemplateRef } from 'vue';
|
||||||
import type { Router } from '@/router.js';
|
import type { Router } from '@/router.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import MkLoadingPage from '@/pages/_loading_.vue';
|
import MkLoadingPage from '@/pages/_loading_.vue';
|
||||||
import { DI } from '@/di.js';
|
import { DI } from '@/di.js';
|
||||||
|
import { randomId } from '@/utility/random-id.js';
|
||||||
|
import { deepEqual } from '@/utility/deep-equal.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
router?: Router;
|
router?: Router;
|
||||||
@@ -34,18 +36,76 @@ if (router == null) {
|
|||||||
throw new Error('no router provided');
|
throw new Error('no router provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const viewId = randomId();
|
||||||
|
provide(DI.viewId, viewId);
|
||||||
|
|
||||||
const currentDepth = inject(DI.routerCurrentDepth, 0);
|
const currentDepth = inject(DI.routerCurrentDepth, 0);
|
||||||
provide(DI.routerCurrentDepth, currentDepth + 1);
|
provide(DI.routerCurrentDepth, currentDepth + 1);
|
||||||
|
|
||||||
|
const rootEl = useTemplateRef('rootEl');
|
||||||
|
onMounted(() => {
|
||||||
|
rootEl.value.style.viewTransitionName = viewId; // view-transition-nameにcss varが使えないっぽいため直接代入
|
||||||
|
});
|
||||||
|
|
||||||
|
// view-transition-newなどの<pt-name-selector>にはcss varが使えず、v-bindできないため直接スタイルを生成
|
||||||
|
const viewTransitionStylesTag = window.document.createElement('style');
|
||||||
|
viewTransitionStylesTag.textContent = `
|
||||||
|
@keyframes ${viewId}-old {
|
||||||
|
to { transform: scale(0.95); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ${viewId}-new {
|
||||||
|
from { transform: scale(0.95); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-old(${viewId}) {
|
||||||
|
animation-duration: 0.2s;
|
||||||
|
animation-name: ${viewId}-old;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-new(${viewId}) {
|
||||||
|
animation-duration: 0.2s;
|
||||||
|
animation-name: ${viewId}-new;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
window.document.head.appendChild(viewTransitionStylesTag);
|
||||||
|
|
||||||
const current = router.current!;
|
const current = router.current!;
|
||||||
const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage);
|
const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage);
|
||||||
const currentPageProps = ref(current.props);
|
const currentPageProps = ref(current.props);
|
||||||
|
let currentRoutePath = current.route.path;
|
||||||
const key = ref(router.getCurrentFullPath());
|
const key = ref(router.getCurrentFullPath());
|
||||||
|
|
||||||
router.useListener('change', ({ resolved }) => {
|
router.useListener('change', ({ resolved }) => {
|
||||||
if (resolved == null || 'redirect' in resolved.route) return;
|
if (resolved == null || 'redirect' in resolved.route) return;
|
||||||
currentPageComponent.value = resolved.route.component;
|
if (resolved.route.path === currentRoutePath && deepEqual(resolved.props, currentPageProps.value)) return;
|
||||||
currentPageProps.value = resolved.props;
|
|
||||||
key.value = router.getCurrentFullPath();
|
function _() {
|
||||||
|
currentPageComponent.value = resolved.route.component;
|
||||||
|
currentPageProps.value = resolved.props;
|
||||||
|
key.value = router.getCurrentFullPath();
|
||||||
|
currentRoutePath = resolved.route.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
if (prefer.s.animation && window.document.startViewTransition) {
|
||||||
|
window.document.startViewTransition(() => new Promise((res) => {
|
||||||
|
_();
|
||||||
|
nextTick(() => {
|
||||||
|
res();
|
||||||
|
//setTimeout(res, 100);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
_();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.root {
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--MI_THEME-bg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@@ -42,7 +42,7 @@ const highlighted = ref(props.markerId === searchMarkerId.value);
|
|||||||
|
|
||||||
function checkChildren() {
|
function checkChildren() {
|
||||||
if (props.children?.includes(searchMarkerId.value)) {
|
if (props.children?.includes(searchMarkerId.value)) {
|
||||||
const el = document.querySelector(`[data-in-app-search-marker-id="${searchMarkerId.value}"]`);
|
const el = window.document.querySelector(`[data-in-app-search-marker-id="${searchMarkerId.value}"]`);
|
||||||
highlighted.value = el == null;
|
highlighted.value = el == null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@ import MkPageHeader from './global/MkPageHeader.vue';
|
|||||||
import MkSpacer from './global/MkSpacer.vue';
|
import MkSpacer from './global/MkSpacer.vue';
|
||||||
import MkStickyContainer from './global/MkStickyContainer.vue';
|
import MkStickyContainer from './global/MkStickyContainer.vue';
|
||||||
import MkLazy from './global/MkLazy.vue';
|
import MkLazy from './global/MkLazy.vue';
|
||||||
|
import PageWithHeader from './global/PageWithHeader.vue';
|
||||||
|
import PageWithAnimBg from './global/PageWithAnimBg.vue';
|
||||||
import SearchMarker from './global/SearchMarker.vue';
|
import SearchMarker from './global/SearchMarker.vue';
|
||||||
import SearchLabel from './global/SearchLabel.vue';
|
import SearchLabel from './global/SearchLabel.vue';
|
||||||
import SearchKeyword from './global/SearchKeyword.vue';
|
import SearchKeyword from './global/SearchKeyword.vue';
|
||||||
@@ -60,6 +62,8 @@ export const components = {
|
|||||||
MkSpacer: MkSpacer,
|
MkSpacer: MkSpacer,
|
||||||
MkStickyContainer: MkStickyContainer,
|
MkStickyContainer: MkStickyContainer,
|
||||||
MkLazy: MkLazy,
|
MkLazy: MkLazy,
|
||||||
|
PageWithHeader: PageWithHeader,
|
||||||
|
PageWithAnimBg: PageWithAnimBg,
|
||||||
SearchMarker: SearchMarker,
|
SearchMarker: SearchMarker,
|
||||||
SearchLabel: SearchLabel,
|
SearchLabel: SearchLabel,
|
||||||
SearchKeyword: SearchKeyword,
|
SearchKeyword: SearchKeyword,
|
||||||
@@ -89,6 +93,8 @@ declare module '@vue/runtime-core' {
|
|||||||
MkSpacer: typeof MkSpacer;
|
MkSpacer: typeof MkSpacer;
|
||||||
MkStickyContainer: typeof MkStickyContainer;
|
MkStickyContainer: typeof MkStickyContainer;
|
||||||
MkLazy: typeof MkLazy;
|
MkLazy: typeof MkLazy;
|
||||||
|
PageWithHeader: typeof PageWithHeader;
|
||||||
|
PageWithAnimBg: typeof PageWithAnimBg;
|
||||||
SearchMarker: typeof SearchMarker;
|
SearchMarker: typeof SearchMarker;
|
||||||
SearchLabel: typeof SearchLabel;
|
SearchLabel: typeof SearchLabel;
|
||||||
SearchKeyword: typeof SearchKeyword;
|
SearchKeyword: typeof SearchKeyword;
|
||||||
|
@@ -11,4 +11,5 @@ export const DI = {
|
|||||||
router: Symbol() as InjectionKey<Router>,
|
router: Symbol() as InjectionKey<Router>,
|
||||||
mock: Symbol() as InjectionKey<boolean>,
|
mock: Symbol() as InjectionKey<boolean>,
|
||||||
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any>>>,
|
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any>>>,
|
||||||
|
viewId: Symbol() as InjectionKey<string>,
|
||||||
};
|
};
|
||||||
|
@@ -13,7 +13,7 @@ export default {
|
|||||||
el._keyHandler = makeHotkey(binding.value);
|
el._keyHandler = makeHotkey(binding.value);
|
||||||
|
|
||||||
if (el._hotkey_global) {
|
if (el._hotkey_global) {
|
||||||
document.addEventListener('keydown', el._keyHandler, { passive: false });
|
window.document.addEventListener('keydown', el._keyHandler, { passive: false });
|
||||||
} else {
|
} else {
|
||||||
el.addEventListener('keydown', el._keyHandler, { passive: false });
|
el.addEventListener('keydown', el._keyHandler, { passive: false });
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ export default {
|
|||||||
|
|
||||||
unmounted(el) {
|
unmounted(el) {
|
||||||
if (el._hotkey_global) {
|
if (el._hotkey_global) {
|
||||||
document.removeEventListener('keydown', el._keyHandler);
|
window.document.removeEventListener('keydown', el._keyHandler);
|
||||||
} else {
|
} else {
|
||||||
el.removeEventListener('keydown', el._keyHandler);
|
el.removeEventListener('keydown', el._keyHandler);
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ export default {
|
|||||||
mounted(src, binding, vn) {
|
mounted(src, binding, vn) {
|
||||||
const parentBg = getBgColor(src.parentElement) ?? 'transparent';
|
const parentBg = getBgColor(src.parentElement) ?? 'transparent';
|
||||||
|
|
||||||
const myBg = getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel');
|
const myBg = getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel');
|
||||||
|
|
||||||
if (parentBg === myBg) {
|
if (parentBg === myBg) {
|
||||||
src.style.backgroundColor = 'var(--MI_THEME-bg)';
|
src.style.backgroundColor = 'var(--MI_THEME-bg)';
|
||||||
|
@@ -47,7 +47,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.show = () => {
|
self.show = () => {
|
||||||
if (!document.body.contains(el)) return;
|
if (!window.document.body.contains(el)) return;
|
||||||
if (self._close) return;
|
if (self._close) return;
|
||||||
if (self.text == null) return;
|
if (self.text == null) return;
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ export class UserPreview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private show() {
|
private show() {
|
||||||
if (!document.body.contains(this.el)) return;
|
if (!window.document.body.contains(this.el)) return;
|
||||||
if (this.promise) return;
|
if (this.promise) return;
|
||||||
|
|
||||||
const showing = ref(true);
|
const showing = ref(true);
|
||||||
@@ -58,7 +58,7 @@ export class UserPreview {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.checkTimer = window.setInterval(() => {
|
this.checkTimer = window.setInterval(() => {
|
||||||
if (!document.body.contains(this.el)) {
|
if (!window.document.body.contains(this.el)) {
|
||||||
window.clearTimeout(this.showTimer);
|
window.clearTimeout(this.showTimer);
|
||||||
window.clearTimeout(this.hideTimer);
|
window.clearTimeout(this.hideTimer);
|
||||||
this.close();
|
this.close();
|
||||||
|
@@ -12,7 +12,7 @@ import { DEFAULT_INFO_IMAGE_URL, DEFAULT_NOT_FOUND_IMAGE_URL, DEFAULT_SERVER_ERR
|
|||||||
// TODO: 他のタブと永続化されたstateを同期
|
// TODO: 他のタブと永続化されたstateを同期
|
||||||
|
|
||||||
//#region loader
|
//#region loader
|
||||||
const providedMetaEl = document.getElementById('misskey_meta');
|
const providedMetaEl = window.document.getElementById('misskey_meta');
|
||||||
|
|
||||||
let cachedMeta = miLocalStorage.getItem('instance') ? JSON.parse(miLocalStorage.getItem('instance')!) : null;
|
let cachedMeta = miLocalStorage.getItem('instance') ? JSON.parse(miLocalStorage.getItem('instance')!) : null;
|
||||||
let cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0;
|
let cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0;
|
||||||
|
@@ -320,7 +320,7 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvents> {
|
|||||||
}
|
}
|
||||||
const res = this.navigate(fullPath);
|
const res = this.navigate(fullPath);
|
||||||
if (res.route.path === '/:(*)') {
|
if (res.route.path === '/:(*)') {
|
||||||
location.href = fullPath;
|
window.location.href = fullPath;
|
||||||
} else {
|
} else {
|
||||||
this.emit('push', {
|
this.emit('push', {
|
||||||
beforeFullPath,
|
beforeFullPath,
|
||||||
|
@@ -167,7 +167,7 @@ export const navbarItemDef = reactive({
|
|||||||
title: i18n.ts.reload,
|
title: i18n.ts.reload,
|
||||||
icon: 'ti ti-refresh',
|
icon: 'ti ti-refresh',
|
||||||
action: (ev) => {
|
action: (ev) => {
|
||||||
location.reload();
|
window.location.reload();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
|
@@ -21,10 +21,10 @@ import MkWaitingDialog from '@/components/MkWaitingDialog.vue';
|
|||||||
import MkPageWindow from '@/components/MkPageWindow.vue';
|
import MkPageWindow from '@/components/MkPageWindow.vue';
|
||||||
import MkToast from '@/components/MkToast.vue';
|
import MkToast from '@/components/MkToast.vue';
|
||||||
import MkDialog from '@/components/MkDialog.vue';
|
import MkDialog from '@/components/MkDialog.vue';
|
||||||
import MkPasswordDialog from '@/components/MkPasswordDialog.vue';
|
|
||||||
import MkEmojiPickerDialog from '@/components/MkEmojiPickerDialog.vue';
|
|
||||||
import MkPopupMenu from '@/components/MkPopupMenu.vue';
|
import MkPopupMenu from '@/components/MkPopupMenu.vue';
|
||||||
import MkContextMenu from '@/components/MkContextMenu.vue';
|
import MkContextMenu from '@/components/MkContextMenu.vue';
|
||||||
|
import type MkRoleSelectDialog_TypeReferenceOnly from '@/components/MkRoleSelectDialog.vue';
|
||||||
|
import type MkEmojiPickerDialog_TypeReferenceOnly from '@/components/MkEmojiPickerDialog.vue';
|
||||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||||
import { pleaseLogin } from '@/utility/please-login.js';
|
import { pleaseLogin } from '@/utility/please-login.js';
|
||||||
import { showMovedDialog } from '@/utility/show-moved-dialog.js';
|
import { showMovedDialog } from '@/utility/show-moved-dialog.js';
|
||||||
@@ -181,7 +181,7 @@ type EmitsExtractor<T> = {
|
|||||||
export function popup<T extends Component>(
|
export function popup<T extends Component>(
|
||||||
component: T,
|
component: T,
|
||||||
props: ComponentProps<T>,
|
props: ComponentProps<T>,
|
||||||
events: ComponentEmit<T> = {} as ComponentEmit<T>,
|
events: Partial<ComponentEmit<T>> = {},
|
||||||
): { dispose: () => void } {
|
): { dispose: () => void } {
|
||||||
markRaw(component);
|
markRaw(component);
|
||||||
|
|
||||||
@@ -460,7 +460,7 @@ export function authenticateDialog(): Promise<{
|
|||||||
canceled: false; result: { password: string; token: string | null; };
|
canceled: false; result: { password: string; token: string | null; };
|
||||||
}> {
|
}> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const { dispose } = popup(MkPasswordDialog, {}, {
|
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkPasswordDialog.vue')), {}, {
|
||||||
done: result => {
|
done: result => {
|
||||||
resolve(result ? { canceled: false, result } : { canceled: true, result: undefined });
|
resolve(result ? { canceled: false, result } : { canceled: true, result: undefined });
|
||||||
},
|
},
|
||||||
@@ -617,30 +617,26 @@ export async function selectDriveFolder(multiple: boolean): Promise<Misskey.enti
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function selectRole(params: {
|
export async function selectRole(params: ComponentProps<typeof MkRoleSelectDialog_TypeReferenceOnly>): Promise<
|
||||||
initialRoleIds?: string[],
|
|
||||||
title?: string,
|
|
||||||
infoMessage?: string,
|
|
||||||
publicOnly?: boolean,
|
|
||||||
}): Promise<
|
|
||||||
{ canceled: true; result: undefined; } |
|
{ canceled: true; result: undefined; } |
|
||||||
{ canceled: false; result: Misskey.entities.Role[] }
|
{ canceled: false; result: Misskey.entities.Role[] }
|
||||||
> {
|
> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
popup(defineAsyncComponent(() => import('@/components/MkRoleSelectDialog.vue')), params, {
|
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkRoleSelectDialog.vue')), params, {
|
||||||
done: roles => {
|
done: roles => {
|
||||||
resolve({ canceled: false, result: roles });
|
resolve({ canceled: false, result: roles });
|
||||||
},
|
},
|
||||||
close: () => {
|
close: () => {
|
||||||
resolve({ canceled: true, result: undefined });
|
resolve({ canceled: true, result: undefined });
|
||||||
},
|
},
|
||||||
}, 'dispose');
|
closed: () => dispose(),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function pickEmoji(src: HTMLElement, opts: ComponentProps<typeof MkEmojiPickerDialog>): Promise<string> {
|
export async function pickEmoji(src: HTMLElement, opts: ComponentProps<typeof MkEmojiPickerDialog_TypeReferenceOnly>): Promise<string> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const { dispose } = popup(MkEmojiPickerDialog, {
|
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkEmojiPickerDialog.vue')), {
|
||||||
src,
|
src,
|
||||||
...opts,
|
...opts,
|
||||||
}, {
|
}, {
|
||||||
@@ -675,7 +671,11 @@ export function popupMenu(items: MenuItem[], src?: HTMLElement | EventTarget | n
|
|||||||
width?: number;
|
width?: number;
|
||||||
onClosing?: () => void;
|
onClosing?: () => void;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
let returnFocusTo = getHTMLElementOrNull(src) ?? getHTMLElementOrNull(document.activeElement);
|
if (!(src instanceof HTMLElement)) {
|
||||||
|
src = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let returnFocusTo = getHTMLElementOrNull(src) ?? getHTMLElementOrNull(window.document.activeElement);
|
||||||
return new Promise(resolve => nextTick(() => {
|
return new Promise(resolve => nextTick(() => {
|
||||||
const { dispose } = popup(MkPopupMenu, {
|
const { dispose } = popup(MkPopupMenu, {
|
||||||
items,
|
items,
|
||||||
@@ -704,7 +704,7 @@ export function contextMenu(items: MenuItem[], ev: MouseEvent): Promise<void> {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
let returnFocusTo = getHTMLElementOrNull(ev.currentTarget ?? ev.target) ?? getHTMLElementOrNull(document.activeElement);
|
let returnFocusTo = getHTMLElementOrNull(ev.currentTarget ?? ev.target) ?? getHTMLElementOrNull(window.document.activeElement);
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
return new Promise(resolve => nextTick(() => {
|
return new Promise(resolve => nextTick(() => {
|
||||||
const { dispose } = popup(MkContextMenu, {
|
const { dispose } = popup(MkContextMenu, {
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<div style="overflow: clip;">
|
<div style="overflow: clip;">
|
||||||
<MkSpacer :contentMax="600" :marginMin="20">
|
<MkSpacer :contentMax="600" :marginMin="20">
|
||||||
<div class="_gaps_m znqjceqz">
|
<div class="_gaps_m znqjceqz">
|
||||||
@@ -130,7 +129,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</div>
|
</div>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<MkSpacer v-if="tab === 'overview'" :contentMax="600" :marginMin="20">
|
<MkSpacer v-if="tab === 'overview'" :contentMax="600" :marginMin="20">
|
||||||
<XOverview/>
|
<XOverview/>
|
||||||
@@ -20,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkInstanceStats/>
|
<MkInstanceStats/>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkHorizontalSwipe>
|
</MkHorizontalSwipe>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,12 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader>
|
||||||
<template #header><MkPageHeader/></template>
|
|
||||||
<MkSpacer :contentMax="1200">
|
<MkSpacer :contentMax="1200">
|
||||||
<MkAchievements :user="$i"/>
|
<MkAchievements :user="$i"/>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer v-if="file" :contentMax="600" :marginMin="16" :marginMax="32">
|
<MkSpacer v-if="file" :contentMax="600" :marginMin="16" :marginMax="32">
|
||||||
<div v-if="tab === 'overview'" class="cxqhhsmd _gaps_m">
|
<div v-if="tab === 'overview'" class="cxqhhsmd _gaps_m">
|
||||||
<a class="thumbnail" :href="file.url" target="_blank">
|
<a class="thumbnail" :href="file.url" target="_blank">
|
||||||
@@ -67,7 +66,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</MkObjectView>
|
</MkObjectView>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="600" :marginMin="16" :marginMax="32">
|
<MkSpacer :contentMax="600" :marginMin="16" :marginMax="32">
|
||||||
<FormSuspense :p="init">
|
<FormSuspense :p="init">
|
||||||
<div v-if="tab === 'overview'" class="_gaps_m">
|
<div v-if="tab === 'overview'" class="_gaps_m">
|
||||||
@@ -208,7 +207,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -120,7 +120,7 @@ function onTabClick(tab: Tab, ev: MouseEvent): void {
|
|||||||
|
|
||||||
const calcBg = () => {
|
const calcBg = () => {
|
||||||
const rawBg = pageMetadata.value.bg ?? 'var(--MI_THEME-bg)';
|
const rawBg = pageMetadata.value.bg ?? 'var(--MI_THEME-bg)';
|
||||||
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(window.document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
||||||
tinyBg.setAlpha(0.85);
|
tinyBg.setAlpha(0.85);
|
||||||
bg.value = tinyBg.toRgbString();
|
bg.value = tinyBg.toRgbString();
|
||||||
};
|
};
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="800" :marginMin="16" :marginMax="32">
|
<MkSpacer :contentMax="800" :marginMin="16" :marginMax="32">
|
||||||
<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
|
<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
|
||||||
<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
|
<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
|
||||||
@@ -14,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -41,7 +41,7 @@ onMounted(() => {
|
|||||||
labels: props.data.map(x => x.name),
|
labels: props.data.map(x => x.name),
|
||||||
datasets: [{
|
datasets: [{
|
||||||
backgroundColor: props.data.map(x => x.color),
|
backgroundColor: props.data.map(x => x.color),
|
||||||
borderColor: getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel'),
|
borderColor: getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'),
|
||||||
borderWidth: 2,
|
borderWidth: 2,
|
||||||
hoverOffset: 0,
|
hoverOffset: 0,
|
||||||
data: props.data.map(x => x.value),
|
data: props.data.map(x => x.value),
|
||||||
|
@@ -4,15 +4,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader>
|
||||||
<template #header><MkPageHeader/></template>
|
|
||||||
|
|
||||||
<MkSpacer :contentMax="500">
|
<MkSpacer :contentMax="500">
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<MkAd v-for="ad in instance.ads" :key="ad.id" :specify="ad"/>
|
<MkAd v-for="ad in instance.ads" :key="ad.id" :specify="ad"/>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<Transition
|
<Transition
|
||||||
:enterActiveClass="prefer.s.animation ? $style.fadeEnterActive : ''"
|
:enterActiveClass="prefer.s.animation ? $style.fadeEnterActive : ''"
|
||||||
@@ -44,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkLoading v-else/>
|
<MkLoading v-else/>
|
||||||
</Transition>
|
</Transition>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,11 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<div :key="tab" class="_gaps">
|
<div class="_gaps">
|
||||||
<MkInfo v-if="$i && $i.hasUnreadAnnouncement && tab === 'current'" warn>{{ i18n.ts.youHaveUnreadAnnouncements }}</MkInfo>
|
<MkInfo v-if="$i && $i.hasUnreadAnnouncement && tab === 'current'" warn>{{ i18n.ts.youHaveUnreadAnnouncements }}</MkInfo>
|
||||||
<MkPagination ref="paginationEl" :key="tab" v-slot="{items}" :pagination="tab === 'current' ? paginationCurrent : paginationPast" class="_gaps">
|
<MkPagination ref="paginationEl" :key="tab" v-slot="{items}" :pagination="tab === 'current' ? paginationCurrent : paginationPast" class="_gaps">
|
||||||
<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
|
<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
|
||||||
@@ -43,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</MkHorizontalSwipe>
|
</MkHorizontalSwipe>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<div ref="rootEl">
|
<div ref="rootEl">
|
||||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||||
@@ -20,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="700">
|
<MkSpacer :contentMax="700">
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
@@ -30,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -38,7 +38,7 @@ const emit = defineEmits<{
|
|||||||
const app = computed(() => props.session.app);
|
const app = computed(() => props.session.app);
|
||||||
|
|
||||||
const name = computed(() => {
|
const name = computed(() => {
|
||||||
const el = document.createElement('div');
|
const el = window.document.createElement('div');
|
||||||
el.textContent = app.value.name;
|
el.textContent = app.value.name;
|
||||||
return el.innerHTML;
|
return el.innerHTML;
|
||||||
});
|
});
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="500">
|
<MkSpacer :contentMax="500">
|
||||||
<div v-if="state == 'fetch-session-error'">
|
<div v-if="state == 'fetch-session-error'">
|
||||||
<p>{{ i18n.ts.somethingHappened }}</p>
|
<p>{{ i18n.ts.somethingHappened }}</p>
|
||||||
@@ -38,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkSignin @login="onLogin"/>
|
<MkSignin @login="onLogin"/>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -64,7 +63,7 @@ function accepted() {
|
|||||||
if (session.value && session.value.app.callbackUrl) {
|
if (session.value && session.value.app.callbackUrl) {
|
||||||
const url = new URL(session.value.app.callbackUrl);
|
const url = new URL(session.value.app.callbackUrl);
|
||||||
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:', 'vbscript:'].includes(url.protocol)) throw new Error('invalid url');
|
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:', 'vbscript:'].includes(url.protocol)) throw new Error('invalid url');
|
||||||
location.href = `${session.value.app.callbackUrl}?token=${session.value.token}`;
|
window.location.href = `${session.value.app.callbackUrl}?token=${session.value.token}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="900">
|
<MkSpacer :contentMax="900">
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<div :class="$style.decorations">
|
<div :class="$style.decorations">
|
||||||
@@ -22,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="700">
|
<MkSpacer :contentMax="700">
|
||||||
<div v-if="channelId == null || channel != null" class="_gaps_m">
|
<div v-if="channelId == null || channel != null" class="_gaps_m">
|
||||||
<MkInput v-model="name">
|
<MkInput v-model="name">
|
||||||
@@ -65,7 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,11 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="700" :class="$style.main">
|
<MkSpacer :contentMax="700" :class="$style.main">
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<div v-if="channel && tab === 'overview'" key="overview" class="_gaps">
|
<div v-if="channel && tab === 'overview'" class="_gaps">
|
||||||
<div class="_panel" :class="$style.bannerContainer">
|
<div class="_panel" :class="$style.bannerContainer">
|
||||||
<XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/>
|
<XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/>
|
||||||
<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ti ti-star"></i></MkButton>
|
<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ti ti-star"></i></MkButton>
|
||||||
@@ -33,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</MkFoldableSection>
|
</MkFoldableSection>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="channel && tab === 'timeline'" key="timeline" class="_gaps">
|
<div v-if="channel && tab === 'timeline'" class="_gaps">
|
||||||
<MkInfo v-if="channel.isArchived" warn>{{ i18n.ts.thisChannelArchived }}</MkInfo>
|
<MkInfo v-if="channel.isArchived" warn>{{ i18n.ts.thisChannelArchived }}</MkInfo>
|
||||||
|
|
||||||
<!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる -->
|
<!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる -->
|
||||||
@@ -41,10 +40,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
|
|
||||||
<MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after" @note="miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.id}`, Date.now())"/>
|
<MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after" @note="miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.id}`, Date.now())"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'featured'" key="featured">
|
<div v-else-if="tab === 'featured'">
|
||||||
<MkNotes :pagination="featuredPagination"/>
|
<MkNotes :pagination="featuredPagination"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'search'" key="search">
|
<div v-else-if="tab === 'search'">
|
||||||
<div v-if="notesSearchAvailable" class="_gaps">
|
<div v-if="notesSearchAvailable" class="_gaps">
|
||||||
<div>
|
<div>
|
||||||
<MkInput v-model="searchQuery" @enter="search()">
|
<MkInput v-model="searchQuery" @enter="search()">
|
||||||
@@ -69,7 +68,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,11 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="1200">
|
<MkSpacer :contentMax="1200">
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<div v-if="tab === 'search'" key="search" :class="$style.searchRoot">
|
<div v-if="tab === 'search'" :class="$style.searchRoot">
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search" @enter="search">
|
<MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search" @enter="search">
|
||||||
<template #prefix><i class="ti ti-search"></i></template>
|
<template #prefix><i class="ti ti-search"></i></template>
|
||||||
@@ -25,28 +24,28 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkChannelList :key="key" :pagination="channelPagination"/>
|
<MkChannelList :key="key" :pagination="channelPagination"/>
|
||||||
</MkFoldableSection>
|
</MkFoldableSection>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="tab === 'featured'" key="featured">
|
<div v-if="tab === 'featured'">
|
||||||
<MkPagination v-slot="{items}" :pagination="featuredPagination">
|
<MkPagination v-slot="{items}" :pagination="featuredPagination">
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
||||||
</div>
|
</div>
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'favorites'" key="favorites">
|
<div v-else-if="tab === 'favorites'">
|
||||||
<MkPagination v-slot="{items}" :pagination="favoritesPagination">
|
<MkPagination v-slot="{items}" :pagination="favoritesPagination">
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
||||||
</div>
|
</div>
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'following'" key="following">
|
<div v-else-if="tab === 'following'">
|
||||||
<MkPagination v-slot="{items}" :pagination="followingPagination">
|
<MkPagination v-slot="{items}" :pagination="followingPagination">
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
||||||
</div>
|
</div>
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'owned'" key="owned">
|
<div v-else-if="tab === 'owned'">
|
||||||
<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
|
<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
|
||||||
<MkPagination v-slot="{items}" :pagination="ownedPagination">
|
<MkPagination v-slot="{items}" :pagination="ownedPagination">
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
@@ -56,7 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</MkHorizontalSwipe>
|
</MkHorizontalSwipe>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,12 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader>
|
||||||
<template #header><MkPageHeader/></template>
|
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<MkClickerGame/>
|
<MkClickerGame/>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader :actions="headerActions">
|
||||||
<template #header><MkPageHeader :actions="headerActions"/></template>
|
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<div v-if="clip" class="_gaps">
|
<div v-if="clip" class="_gaps">
|
||||||
<div class="_panel">
|
<div class="_panel">
|
||||||
@@ -27,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkNotes :pagination="pagination" :detail="true"/>
|
<MkNotes :pagination="pagination" :detail="true"/>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader>
|
||||||
<template #header><MkPageHeader/></template>
|
|
||||||
<MkSpacer :contentMax="600" :marginMin="20">
|
<MkSpacer :contentMax="600" :marginMin="20">
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkKeyValue :copy="instance.maintainerName">
|
<MkKeyValue :copy="instance.maintainerName">
|
||||||
@@ -31,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkSpacer :contentMax="900">
|
<MkSpacer :contentMax="900">
|
||||||
<div class="ogwlenmc">
|
<div class="ogwlenmc">
|
||||||
<div v-if="tab === 'local'" class="local">
|
<div v-if="tab === 'local'" class="local">
|
||||||
@@ -68,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@@ -10,11 +10,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<MkSpacer v-if="tab === 'info'" key="info" :contentMax="800">
|
<MkSpacer v-if="tab === 'info'" :contentMax="800">
|
||||||
<XFileInfo :fileId="fileId"/>
|
<XFileInfo :fileId="fileId"/>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
|
|
||||||
<MkSpacer v-else-if="tab === 'notes'" key="notes" :contentMax="800">
|
<MkSpacer v-else-if="tab === 'notes'" :contentMax="800">
|
||||||
<XNotes :fileId="fileId"/>
|
<XNotes :fileId="fileId"/>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkHorizontalSwipe>
|
</MkHorizontalSwipe>
|
||||||
|
@@ -632,7 +632,7 @@ function loadMonoTextures() {
|
|||||||
src = URL.createObjectURL(monoTextures[mono.img]);
|
src = URL.createObjectURL(monoTextures[mono.img]);
|
||||||
monoTextureUrls[mono.img] = src;
|
monoTextureUrls[mono.img] = src;
|
||||||
} else {
|
} else {
|
||||||
const res = await fetch(mono.img);
|
const res = await window.fetch(mono.img);
|
||||||
const blob = await res.blob();
|
const blob = await res.blob();
|
||||||
monoTextures[mono.img] = blob;
|
monoTextures[mono.img] = blob;
|
||||||
src = URL.createObjectURL(blob);
|
src = URL.createObjectURL(blob);
|
||||||
@@ -875,7 +875,7 @@ function loadImage(url: string) {
|
|||||||
|
|
||||||
function getGameImageDriveFile() {
|
function getGameImageDriveFile() {
|
||||||
return new Promise<Misskey.entities.DriveFile | null>(res => {
|
return new Promise<Misskey.entities.DriveFile | null>(res => {
|
||||||
const dcanvas = document.createElement('canvas');
|
const dcanvas = window.document.createElement('canvas');
|
||||||
dcanvas.width = game.GAME_WIDTH;
|
dcanvas.width = game.GAME_WIDTH;
|
||||||
dcanvas.height = game.GAME_HEIGHT;
|
dcanvas.height = game.GAME_HEIGHT;
|
||||||
const ctx = dcanvas.getContext('2d');
|
const ctx = dcanvas.getContext('2d');
|
||||||
|
@@ -4,20 +4,19 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<div v-if="tab === 'featured'" key="featured">
|
<div v-if="tab === 'featured'">
|
||||||
<XFeatured/>
|
<XFeatured/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'users'" key="users">
|
<div v-else-if="tab === 'users'">
|
||||||
<XUsers/>
|
<XUsers/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'roles'" key="roles">
|
<div v-else-if="tab === 'roles'">
|
||||||
<XRoles/>
|
<XRoles/>
|
||||||
</div>
|
</div>
|
||||||
</MkHorizontalSwipe>
|
</MkHorizontalSwipe>
|
||||||
</MkStickyContainer>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user