Compare commits
75 Commits
renovate/n
...
refine-piz
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2402754dcc | ||
![]() |
2493592bd0 | ||
![]() |
eec4ab841a | ||
![]() |
7957ee5191 | ||
![]() |
d0b8ffe629 | ||
![]() |
b200743845 | ||
![]() |
cef7575b76 | ||
![]() |
9842eb2eeb | ||
![]() |
05078e9c14 | ||
![]() |
db5c6fa3c2 | ||
![]() |
8a4e2659ed | ||
![]() |
d19c094a9b | ||
![]() |
08f7e7d9b3 | ||
![]() |
a7f7ff33e7 | ||
![]() |
16ad6b3f6c | ||
![]() |
4df9083bf0 | ||
![]() |
6419af2179 | ||
![]() |
d9858b03c9 | ||
![]() |
88efc0a3be | ||
![]() |
ac21fa7194 | ||
![]() |
c76afce9a7 | ||
![]() |
8e3304344f | ||
![]() |
db5c127cdd | ||
![]() |
0402866b43 | ||
![]() |
6cefabc6b6 | ||
![]() |
c9c04d8391 | ||
![]() |
27e8805dcb | ||
![]() |
933abedc90 | ||
![]() |
69eee9f050 | ||
![]() |
2918fb2609 | ||
![]() |
fcd7fa62ba | ||
![]() |
be7e3b9a0c | ||
![]() |
06e7272ca1 | ||
![]() |
f35eb0f6d9 | ||
![]() |
bdb74539d4 | ||
![]() |
abc1e9168d | ||
![]() |
d30ddd4c2e | ||
![]() |
05cdc095c0 | ||
![]() |
7c1dc3d632 | ||
![]() |
c53349c3b4 | ||
![]() |
a710af54ed | ||
![]() |
ac07bb8d92 | ||
![]() |
698505030e | ||
![]() |
e16a14dcef | ||
![]() |
6d93725084 | ||
![]() |
cb9981d4eb | ||
![]() |
bee4db82bb | ||
![]() |
d7706ef1b5 | ||
![]() |
baf3f4a1d1 | ||
![]() |
c7a56c2c2b | ||
![]() |
8dfff79ca2 | ||
![]() |
83c3bb839f | ||
![]() |
a9fe7eff0a | ||
![]() |
d49ecab792 | ||
![]() |
56459bbe68 | ||
![]() |
6c150ef1fb | ||
![]() |
c78f45ea20 | ||
![]() |
82481c01e0 | ||
![]() |
741cbc34e6 | ||
![]() |
5e86550de3 | ||
![]() |
92aef300ee | ||
![]() |
9ce1b68fd7 | ||
![]() |
5be5c8bec4 | ||
![]() |
0214a0001f | ||
![]() |
46067f6e17 | ||
![]() |
2b71bdf114 | ||
![]() |
9d6b521351 | ||
![]() |
ad708d896b | ||
![]() |
22228b6756 | ||
![]() |
f7ea0c6991 | ||
![]() |
60a3513cfc | ||
![]() |
377f002d68 | ||
![]() |
896bde1005 | ||
![]() |
6d0242277d | ||
![]() |
60f90ca649 |
@@ -5,10 +5,10 @@
|
||||
"workspaceFolder": "/workspace",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "22.14.0"
|
||||
"version": "22.11.0"
|
||||
},
|
||||
"ghcr.io/devcontainers-extra/features/corepack:1": {
|
||||
"version": "0.31.0"
|
||||
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
||||
"version": "10.6.1"
|
||||
}
|
||||
},
|
||||
"forwardPorts": [3000],
|
||||
|
@@ -7,8 +7,6 @@ sudo apt-get update
|
||||
sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
||||
git config --global --add safe.directory /workspace
|
||||
git submodule update --init
|
||||
corepack install
|
||||
corepack enable
|
||||
pnpm config set store-dir /home/node/.local/share/pnpm/store
|
||||
pnpm install --frozen-lockfile
|
||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
||||
|
7
.github/workflows/api-misskey-js.yml
vendored
7
.github/workflows/api-misskey-js.yml
vendored
@@ -9,10 +9,6 @@ on:
|
||||
paths:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/api-misskey-js.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
report:
|
||||
|
||||
@@ -22,7 +18,8 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- run: corepack enable
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.2.0
|
||||
|
11
.github/workflows/get-api-diff.yml
vendored
11
.github/workflows/get-api-diff.yml
vendored
@@ -9,10 +9,6 @@ on:
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- .github/workflows/get-api-diff.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
get-from-misskey:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -21,7 +17,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
api-json-name: [api-base.json, api-head.json]
|
||||
include:
|
||||
- api-json-name: api-base.json
|
||||
@@ -34,14 +30,13 @@ jobs:
|
||||
with:
|
||||
ref: ${{ matrix.ref }}
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
|
16
.github/workflows/lint.yml
vendored
16
.github/workflows/lint.yml
vendored
@@ -28,10 +28,6 @@ on:
|
||||
- packages/misskey-reversi/**
|
||||
- packages/shared/eslint.config.js
|
||||
- .github/workflows/lint.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
pnpm_install:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -40,12 +36,12 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
|
||||
lint:
|
||||
@@ -71,12 +67,12 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Restore eslint cache
|
||||
uses: actions/cache@v4.2.2
|
||||
@@ -101,12 +97,12 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- run: pnpm --filter misskey-js run build
|
||||
if: ${{ matrix.workspace == 'backend' || matrix.workspace == 'sw' }}
|
||||
|
8
.github/workflows/locale.yml
vendored
8
.github/workflows/locale.yml
vendored
@@ -9,10 +9,6 @@ on:
|
||||
paths:
|
||||
- locales/**
|
||||
- .github/workflows/locale.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
locale_verify:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -22,11 +18,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- run: cd locales && node verify.js
|
||||
|
10
.github/workflows/on-release-created.yml
vendored
10
.github/workflows/on-release-created.yml
vendored
@@ -6,9 +6,6 @@ on:
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
publish-misskey-js:
|
||||
name: Publish misskey-js
|
||||
@@ -20,14 +17,14 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
@@ -36,7 +33,6 @@ jobs:
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- name: Publish package
|
||||
run: |
|
||||
corepack enable
|
||||
pnpm i --frozen-lockfile
|
||||
pnpm build
|
||||
pnpm --filter misskey-js publish --access public --no-git-checks --provenance
|
||||
|
8
.github/workflows/storybook.yml
vendored
8
.github/workflows/storybook.yml
vendored
@@ -13,9 +13,6 @@ on:
|
||||
# This is a waste of chromatic build quota, so we don't run storybook CI on pull requests targets master.
|
||||
- master
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
||||
@@ -43,14 +40,13 @@ jobs:
|
||||
run: |
|
||||
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
|
||||
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
|
18
.github/workflows/test-backend.yml
vendored
18
.github/workflows/test-backend.yml
vendored
@@ -18,10 +18,6 @@ on:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-backend.yml
|
||||
- .github/misskey/test.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
unit:
|
||||
name: Unit tests (backend)
|
||||
@@ -29,7 +25,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
@@ -48,8 +44,8 @@ jobs:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Install FFmpeg
|
||||
run: |
|
||||
for i in {1..3}; do
|
||||
@@ -70,7 +66,6 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
@@ -92,7 +87,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
@@ -111,14 +106,13 @@ jobs:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
|
10
.github/workflows/test-federation.yml
vendored
10
.github/workflows/test-federation.yml
vendored
@@ -15,22 +15,19 @@ on:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-federation.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Federation test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Install FFmpeg
|
||||
run: |
|
||||
for i in {1..3}; do
|
||||
@@ -53,7 +50,6 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
- name: Build Misskey
|
||||
run: |
|
||||
corepack enable && corepack prepare
|
||||
pnpm i --frozen-lockfile
|
||||
pnpm build
|
||||
- name: Setup
|
||||
|
18
.github/workflows/test-frontend.yml
vendored
18
.github/workflows/test-frontend.yml
vendored
@@ -22,10 +22,6 @@ on:
|
||||
- packages/backend/**
|
||||
- .github/workflows/test-frontend.yml
|
||||
- .github/misskey/test.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
vitest:
|
||||
name: Unit tests (frontend)
|
||||
@@ -33,20 +29,19 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
@@ -69,7 +64,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
browser: [chrome]
|
||||
|
||||
services:
|
||||
@@ -95,14 +90,13 @@ jobs:
|
||||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
#- uses: browser-actions/setup-firefox@latest
|
||||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
|
9
.github/workflows/test-misskey-js.yml
vendored
9
.github/workflows/test-misskey-js.yml
vendored
@@ -14,10 +14,6 @@ on:
|
||||
paths:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-misskey-js.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Unit tests (misskey.js)
|
||||
@@ -26,14 +22,15 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- run: corepack enable
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
|
8
.github/workflows/test-production.yml
vendored
8
.github/workflows/test-production.yml
vendored
@@ -9,7 +9,6 @@ on:
|
||||
|
||||
env:
|
||||
NODE_ENV: production
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
production:
|
||||
@@ -18,20 +17,19 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
|
11
.github/workflows/validate-api-json.yml
vendored
11
.github/workflows/validate-api-json.yml
vendored
@@ -12,24 +12,20 @@ on:
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- .github/workflows/validate-api-json.yml
|
||||
|
||||
env:
|
||||
COREPACK_DEFAULT_TO_LATEST: 0
|
||||
|
||||
jobs:
|
||||
validate-api-json:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.14.0]
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
@@ -37,7 +33,6 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
- name: Install Redocly CLI
|
||||
run: npm i -g @redocly/cli
|
||||
- run: corepack enable
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
|
@@ -1 +1 @@
|
||||
22.14.0
|
||||
22.11.0
|
||||
|
37
CHANGELOG.md
37
CHANGELOG.md
@@ -1,18 +1,53 @@
|
||||
## 2025.3.2
|
||||
|
||||
### General
|
||||
-
|
||||
|
||||
### Client
|
||||
- Feat: 設定の管理が強化されました
|
||||
- 自動でバックアップされるように
|
||||
- Enhance: プラグインの管理が強化されました
|
||||
- Fix: テーマ切り替え時に一部の色が変わらない問題を修正
|
||||
|
||||
### Server
|
||||
- Fix: プロフィール追加情報で無効なURLに入力された場合に照会エラーを出るのを修正
|
||||
|
||||
|
||||
## 2025.3.1
|
||||
|
||||
### General
|
||||
- pnpmをv10に更新
|
||||
- Corepackを削除
|
||||
|
||||
### Client
|
||||
- Feat: 設定の検索を追加(実験的)
|
||||
- Enhance: 設定項目の再配置
|
||||
|
||||
### Server
|
||||
- Fix: DBマイグレーション際にシステムアカウントのユーザーID判定が正しくない問題を修正
|
||||
- Fix: user.featured列が状況によってJSON文字列になっていたのを修正
|
||||
|
||||
|
||||
## 2025.3.0
|
||||
|
||||
### General
|
||||
- Enhance: プロキシアカウントをシステムアカウントとして作成するように
|
||||
- Enhance: OAuthで外部アプリからロゴが提供されている場合、それを表示できるように
|
||||
書式は https://indieauth.spec.indieweb.org/20220212/#example-2 に準じます。
|
||||
- Fix: システムアカウントが削除できる問題を修正
|
||||
|
||||
### Client
|
||||
- Enhance: モデレーターがセンシティブ設定を変更する際に確認ダイアログを出すように
|
||||
- Enhance: 「UIのアニメーションを減らす」で画面上のエフェクトも減らせるように
|
||||
- Fix: 削除して編集の削除タイミングを投稿後になるように `#14498`
|
||||
- Enhance: 投稿フォームにおける、メディアの添付可能個数のカウントを反転しました
|
||||
- これまでの表示は`添付可能残り個数/上限数`でしたが、`添付個数/上限数`としました
|
||||
- Fix: フォローされたときのメッセージがちらつくことがある問題を修正
|
||||
- Fix: 投稿ダイアログがサイズ限界を超えた際にスクロールできない問題を修正
|
||||
|
||||
### Server
|
||||
- Fix: 特定のケースでActivityPubの処理がデッドロックになることがあるのを修正
|
||||
- Fix: S3互換オブジェクトストレージでファイルのアップロードに失敗することがある問題を修正
|
||||
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/895)
|
||||
|
||||
|
||||
## 2025.2.1
|
||||
|
24
Dockerfile
24
Dockerfile
@@ -1,13 +1,11 @@
|
||||
# syntax = docker/dockerfile:1.4
|
||||
|
||||
ARG NODE_VERSION=22.14.0-bookworm
|
||||
ARG NODE_VERSION=22.11.0-bookworm
|
||||
|
||||
# build assets & compile TypeScript
|
||||
|
||||
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION} AS native-builder
|
||||
|
||||
ENV COREPACK_DEFAULT_TO_LATEST=0
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
rm -f /etc/apt/apt.conf.d/docker-clean \
|
||||
@@ -16,8 +14,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
&& apt-get install -yqq --no-install-recommends \
|
||||
build-essential
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
WORKDIR /misskey
|
||||
|
||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
||||
@@ -33,6 +29,8 @@ COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bu
|
||||
|
||||
ARG NODE_ENV=production
|
||||
|
||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
||||
|
||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||
pnpm i --frozen-lockfile --aggregate-output
|
||||
|
||||
@@ -46,14 +44,10 @@ RUN rm -rf .git/
|
||||
|
||||
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION} AS target-builder
|
||||
|
||||
ENV COREPACK_DEFAULT_TO_LATEST=0
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -yqq --no-install-recommends \
|
||||
build-essential
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
WORKDIR /misskey
|
||||
|
||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
||||
@@ -65,6 +59,8 @@ COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bu
|
||||
|
||||
ARG NODE_ENV=production
|
||||
|
||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
||||
|
||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||
pnpm i --frozen-lockfile --aggregate-output
|
||||
|
||||
@@ -72,13 +68,11 @@ FROM --platform=$TARGETPLATFORM node:${NODE_VERSION}-slim AS runner
|
||||
|
||||
ARG UID="991"
|
||||
ARG GID="991"
|
||||
ENV COREPACK_DEFAULT_TO_LATEST=0
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ffmpeg tini curl libjemalloc-dev libjemalloc2 \
|
||||
&& ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so \
|
||||
&& corepack enable \
|
||||
&& groupadd -g "${GID}" misskey \
|
||||
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
|
||||
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
|
||||
@@ -86,13 +80,13 @@ RUN apt-get update \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists
|
||||
|
||||
# add package.json to add pnpm
|
||||
COPY ./package.json ./package.json
|
||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
||||
|
||||
USER misskey
|
||||
WORKDIR /misskey
|
||||
|
||||
# add package.json to add pnpm
|
||||
COPY --chown=misskey:misskey ./package.json ./package.json
|
||||
RUN corepack install
|
||||
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules
|
||||
|
@@ -111,7 +111,7 @@ followRequests: "Peticions de seguiment"
|
||||
unfollow: "Deixar de seguir"
|
||||
followRequestPending: "Sol·licituds de seguiment pendents"
|
||||
enterEmoji: "Introduir un emoji"
|
||||
renote: "Impulsos"
|
||||
renote: "Impulsar"
|
||||
unrenote: "Anul·la l'impuls"
|
||||
renoted: "S'ha impulsat"
|
||||
renotedToX: "Impulsat per {name}."
|
||||
@@ -260,7 +260,7 @@ noCustomEmojis: "No hi ha emojis personalitzats"
|
||||
noJobs: "No hi ha feines"
|
||||
federating: "Federant"
|
||||
blocked: "Bloquejat"
|
||||
suspended: "Suspés"
|
||||
suspended: "Anul·lar subscripció "
|
||||
all: "tot"
|
||||
subscribing: "Subscrit a"
|
||||
publishing: "S'està publicant"
|
||||
@@ -1114,7 +1114,7 @@ forceShowAds: "Mostra els anuncis sempre "
|
||||
addMemo: "Afegir recordatori"
|
||||
editMemo: "Editar recordatori"
|
||||
reactionsList: "Reaccions"
|
||||
renotesList: "Impulsos"
|
||||
renotesList: "Llistat d'impulsos "
|
||||
notificationDisplay: "Notificacions"
|
||||
leftTop: "Dalt a l'esquerra "
|
||||
rightTop: "Dalt a la dreta "
|
||||
@@ -1190,7 +1190,7 @@ pastAnnouncements: "Informes passats"
|
||||
youHaveUnreadAnnouncements: "Tens informes per llegir."
|
||||
useSecurityKey: "Segueix les instruccions del teu navegador O dispositiu per fer servir el teu passkey."
|
||||
replies: "Respostes"
|
||||
renotes: "Impulsos"
|
||||
renotes: "Impulsar"
|
||||
loadReplies: "Mostrar les respostes"
|
||||
loadConversation: "Mostrar la conversació "
|
||||
pinnedList: "Llista fixada"
|
||||
@@ -1311,6 +1311,8 @@ federationSpecified: "Aquest servidor treballa amb una federació de llistes bla
|
||||
federationDisabled: "La unió es troba deshabilitada en aquest servidor. No es pot interactuar amb usuaris d'altres servidors."
|
||||
confirmOnReact: "Confirmar en reaccionar"
|
||||
reactAreYouSure: "Vols reaccionar amb \"{emoji}\"?"
|
||||
markAsSensitiveConfirm: "Vols marcar aquest contingut com a sensible?"
|
||||
unmarkAsSensitiveConfirm: "Vols deixar de marcar com a sensible aquest contingut?"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "És obligatori l'inici de sessió per poder veure el contingut"
|
||||
requireSigninToViewContentsDescription1: "Es requereix l'inici de sessió per poder veure totes les notes i el contingut que has creat. Amb això esperem evitar que els rastrejadors recopilin informació."
|
||||
@@ -1332,7 +1334,7 @@ _abuseUserReport:
|
||||
resolveTutorial: "Si l'informe és legítim selecciona \"Acceptar\" per resoldre'l positivament. Però si l'informe no és legítim selecciona \"Rebutjar\" per resoldre'l negativament."
|
||||
_delivery:
|
||||
status: "Estat d'entrega "
|
||||
stop: "Suspés"
|
||||
stop: "Anul·lar subscripció "
|
||||
resume: "Torna a enviar"
|
||||
_type:
|
||||
none: "S'està publicant"
|
||||
@@ -2450,7 +2452,7 @@ _notification:
|
||||
follow: "Segueix-me"
|
||||
mention: "Menció"
|
||||
reply: "Respostes"
|
||||
renote: "Renotar"
|
||||
renote: "Impulsar"
|
||||
quote: "Citar"
|
||||
reaction: "Reaccions"
|
||||
pollEnded: "Enquesta terminada"
|
||||
@@ -2465,7 +2467,7 @@ _notification:
|
||||
_actions:
|
||||
followBack: "També et segueix"
|
||||
reply: "Respondre"
|
||||
renote: "Renotar"
|
||||
renote: "Impulsos"
|
||||
_deck:
|
||||
alwaysShowMainColumn: "Mostrar sempre la columna principal"
|
||||
columnAlign: "Alinea les columnes"
|
||||
@@ -2594,6 +2596,7 @@ _moderationLogTypes:
|
||||
deletePage: "Esborrar la pàgina"
|
||||
deleteFlash: "Esborrar el guió"
|
||||
deleteGalleryPost: "Esborrar la publicació de la galeria"
|
||||
updateProxyAccountDescription: "Actualitzar descripció del compte proxy"
|
||||
_fileViewer:
|
||||
title: "Detall del fitxer"
|
||||
type: "Tipus de fitxer"
|
||||
|
@@ -5,6 +5,7 @@ introMisskey: "Vítejte! Misskey je otevřený a decentralizovaný microblogový
|
||||
poweredByMisskeyDescription: "{name} je jeden ze serverů využívající open source platformu <b>Misskey<b> (nazývaná \"Misskey instance\")."
|
||||
monthAndDay: "{day}. {month}."
|
||||
search: "Vyhledávání"
|
||||
reset: "Obnovit"
|
||||
notifications: "Oznámení"
|
||||
username: "Uživatelské jméno"
|
||||
password: "Heslo"
|
||||
@@ -365,8 +366,11 @@ hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Aktivovat hCaptchu"
|
||||
hcaptchaSiteKey: "Klíč stránky"
|
||||
hcaptchaSecretKey: "Tajný Klíč (Secret Key)"
|
||||
mcaptcha: "mCaptcha"
|
||||
enableMcaptcha: "Aktivovat mCaptchu"
|
||||
mcaptchaSiteKey: "Klíč stránky"
|
||||
mcaptchaSecretKey: "Tajný Klíč (Secret Key)"
|
||||
mcaptchaInstanceUrl: "URL mCaptcha serveru"
|
||||
recaptcha: "reCAPTCHA"
|
||||
enableRecaptcha: "Zapnout ReCAPTCHu"
|
||||
recaptchaSiteKey: "Klíč stránky"
|
||||
|
@@ -1311,6 +1311,8 @@ federationSpecified: "This server is operated in a whitelist federation. Interac
|
||||
federationDisabled: "Federation is disabled on this server. You cannot interact with users on other servers."
|
||||
confirmOnReact: "Confirm when reacting"
|
||||
reactAreYouSure: "Would you like to add a \"{emoji}\" reaction?"
|
||||
markAsSensitiveConfirm: "Do you want to set this media as sensitive?"
|
||||
unmarkAsSensitiveConfirm: "Do you want to remove the sensitive designation for this media?"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "Require sign-in to view contents"
|
||||
requireSigninToViewContentsDescription1: "Require login to view all notes and other content you have created. This will have the effect of preventing crawlers from collecting your information."
|
||||
@@ -2594,6 +2596,7 @@ _moderationLogTypes:
|
||||
deletePage: "Page deleted"
|
||||
deleteFlash: "Play deleted"
|
||||
deleteGalleryPost: "Gallery post deleted"
|
||||
updateProxyAccountDescription: "Update the description of the proxy account"
|
||||
_fileViewer:
|
||||
title: "File details"
|
||||
type: "File type"
|
||||
@@ -2649,7 +2652,7 @@ _dataSaver:
|
||||
description: "Prevents images/videos from being loaded automatically. Hidden images/videos will be loaded when tapped."
|
||||
_avatar:
|
||||
title: "Avatar image"
|
||||
description: "Stop avatar image animation. Animated images can be larger in file size than normal images, potentially leading to further reductions in data traffic."
|
||||
description: "Stop avatar image animation. Animated images can be larger in file size than normal images, potentially leading to further reductions in data traffic."
|
||||
_urlPreview:
|
||||
title: "URL preview thumbnails"
|
||||
description: "URL preview thumbnail images will no longer be loaded."
|
||||
@@ -2857,4 +2860,8 @@ _bootErrors:
|
||||
_search:
|
||||
searchScopeAll: "All"
|
||||
searchScopeLocal: "Local"
|
||||
searchScopeServer: "Specific server"
|
||||
searchScopeUser: "Specific user"
|
||||
pleaseEnterServerHost: "Enter the server host"
|
||||
pleaseSelectUser: "Select user"
|
||||
serverHostPlaceholder: "Example: misskey.example.com"
|
||||
|
90
locales/index.d.ts
vendored
90
locales/index.d.ts
vendored
@@ -4971,7 +4971,7 @@ export interface Locale extends ILocale {
|
||||
*/
|
||||
"disableStreamingTimeline": string;
|
||||
/**
|
||||
* 通知をグルーピングして表示する
|
||||
* 通知をグルーピング
|
||||
*/
|
||||
"useGroupedNotifications": string;
|
||||
/**
|
||||
@@ -5270,6 +5270,94 @@ export interface Locale extends ILocale {
|
||||
* このメディアのセンシティブ指定を解除しますか?
|
||||
*/
|
||||
"unmarkAsSensitiveConfirm": string;
|
||||
/**
|
||||
* 環境設定
|
||||
*/
|
||||
"preferences": string;
|
||||
/**
|
||||
* アクセシビリティ
|
||||
*/
|
||||
"accessibility": string;
|
||||
/**
|
||||
* 設定のプロファイル
|
||||
*/
|
||||
"preferencesProfile": string;
|
||||
/**
|
||||
* 設定IDをコピー
|
||||
*/
|
||||
"copyPreferenceId": string;
|
||||
/**
|
||||
* 初期値に戻す
|
||||
*/
|
||||
"resetToDefaultValue": string;
|
||||
/**
|
||||
* アカウントで上書き
|
||||
*/
|
||||
"overrideByAccount": string;
|
||||
/**
|
||||
* 無題
|
||||
*/
|
||||
"untitled": string;
|
||||
/**
|
||||
* 名前はありません
|
||||
*/
|
||||
"noName": string;
|
||||
/**
|
||||
* スキップ
|
||||
*/
|
||||
"skip": string;
|
||||
/**
|
||||
* 復元
|
||||
*/
|
||||
"restore": string;
|
||||
"_preferencesProfile": {
|
||||
/**
|
||||
* プロファイル名
|
||||
*/
|
||||
"profileName": string;
|
||||
/**
|
||||
* このデバイスを識別する名前を設定してください。
|
||||
*/
|
||||
"profileNameDescription": string;
|
||||
/**
|
||||
* 例: 「メインPC」、「スマホ」など
|
||||
*/
|
||||
"profileNameDescription2": string;
|
||||
};
|
||||
"_preferencesBackup": {
|
||||
/**
|
||||
* 自動バックアップ
|
||||
*/
|
||||
"autoBackup": string;
|
||||
/**
|
||||
* バックアップから復元
|
||||
*/
|
||||
"restoreFromBackup": string;
|
||||
/**
|
||||
* バックアップが見つかりませんでした
|
||||
*/
|
||||
"noBackupsFoundTitle": string;
|
||||
/**
|
||||
* 自動で作成されたバックアップは見つかりませんでしたが、バックアップファイルを手動で保存している場合、それをインポートして復元することはできます。
|
||||
*/
|
||||
"noBackupsFoundDescription": string;
|
||||
/**
|
||||
* 復元するバックアップを選択してください
|
||||
*/
|
||||
"selectBackupToRestore": string;
|
||||
/**
|
||||
* 自動バックアップを有効にするにはプロファイル名の設定が必要です。
|
||||
*/
|
||||
"youNeedToNameYourProfileToEnableAutoBackup": string;
|
||||
/**
|
||||
* このデバイスで設定の自動バックアップは有効になっていません。
|
||||
*/
|
||||
"autoPreferencesBackupIsNotEnabledForThisDevice": string;
|
||||
/**
|
||||
* 設定のバックアップが見つかりました
|
||||
*/
|
||||
"backupFound": string;
|
||||
};
|
||||
"_accountSettings": {
|
||||
/**
|
||||
* コンテンツの表示にログインを必須にする
|
||||
|
@@ -126,7 +126,7 @@ pinnedNote: "Nota in primo piano"
|
||||
pinned: "Fissa sul profilo"
|
||||
you: "Tu"
|
||||
clickToShow: "Contenuto occultato, cliccare solo se si intende vedere"
|
||||
sensitive: "Allegato esplicito"
|
||||
sensitive: "Esplicito"
|
||||
add: "Aggiungi"
|
||||
reaction: "Reazioni"
|
||||
reactions: "Reazioni"
|
||||
@@ -228,7 +228,7 @@ jobQueue: "Coda di lavoro"
|
||||
cpuAndMemory: "CPU e Memoria"
|
||||
network: "Rete"
|
||||
disk: "Disco"
|
||||
instanceInfo: "Informazioni sull'istanza"
|
||||
instanceInfo: "Informazioni sul server"
|
||||
statistics: "Statistiche"
|
||||
clearQueue: "Svuota coda"
|
||||
clearQueueConfirmTitle: "Vuoi davvero svuotare la coda?"
|
||||
@@ -445,7 +445,7 @@ exploreFediverse: "Esplora il Fediverso"
|
||||
popularTags: "Hashtag popolari"
|
||||
userList: "Liste"
|
||||
about: "Informazioni"
|
||||
aboutMisskey: "Informazioni di Misskey"
|
||||
aboutMisskey: "A proposito di Misskey"
|
||||
administrator: "Amministratore"
|
||||
token: "Token"
|
||||
2fa: "Autenticazione a due fattori"
|
||||
@@ -893,7 +893,7 @@ searchResult: "Risultati della Ricerca"
|
||||
hashtags: "Hashtag"
|
||||
troubleshooting: "Risoluzione problemi"
|
||||
useBlurEffect: "Utilizza effetto sfocatura"
|
||||
learnMore: "Più dettagli"
|
||||
learnMore: "Per saperne di più"
|
||||
misskeyUpdated: "Misskey è stato aggiornato!"
|
||||
whatIsNew: "Informazioni sull'aggiornamento"
|
||||
translate: "Traduci"
|
||||
@@ -901,7 +901,7 @@ translatedFrom: "Traduzione da {x}"
|
||||
accountDeletionInProgress: "È in corso l'eliminazione del profilo"
|
||||
usernameInfo: "Un nome per identificare univocamente il tuo profilo sull'istanza. Puoi utilizzare caratteri alfanumerici maiuscoli, minuscoli e il trattino basso (_). Non potrai cambiare nome utente in seguito."
|
||||
aiChanMode: "Modalità Ai"
|
||||
devMode: "Modalità sviluppatori"
|
||||
devMode: "Modalità sviluppo"
|
||||
keepCw: "Mostra i contenuti espliciti"
|
||||
pubSub: "Publish/Subscribe del profilo"
|
||||
lastCommunication: "La comunicazione più recente"
|
||||
@@ -1049,7 +1049,7 @@ permissionDeniedError: "Errore, attività non autorizzata"
|
||||
permissionDeniedErrorDescription: "Non si dispone dell'autorizzazione per eseguire questa operazione."
|
||||
preset: "Preimpostato"
|
||||
selectFromPresets: "Seleziona preimpostato"
|
||||
achievements: "Obiettivi raggiunti"
|
||||
achievements: "Conquiste"
|
||||
gotInvalidResponseError: "Risposta del server non valida"
|
||||
gotInvalidResponseErrorDescription: "Il server potrebbe essere irraggiungibile o in manutenzione. Riprova più tardi."
|
||||
thisPostMayBeAnnoying: "Questa nota potrebbe essere offensiva"
|
||||
@@ -1311,6 +1311,10 @@ federationSpecified: "Questo server è federato solo con istanze specifiche del
|
||||
federationDisabled: "Questo server ha la federazione disabilitata. Non puoi interagire con profili provenienti da altri server."
|
||||
confirmOnReact: "Confermare le reazioni"
|
||||
reactAreYouSure: "Vuoi davvero reagire con {emoji} ?"
|
||||
markAsSensitiveConfirm: "Vuoi davvero indicare questo contenuto multimediale come esplicito?"
|
||||
unmarkAsSensitiveConfirm: "Vuoi davvero indicare come non esplicito il contenuto multimediale?"
|
||||
preferences: "Preferenze"
|
||||
accessibility: "Accessibilità"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "Per vedere il contenuto, è necessaria l'iscrizione"
|
||||
requireSigninToViewContentsDescription1: "Richiedere l'iscrizione per visualizzare tutte le Note e gli altri contenuti che hai creato. Probabilmente l'effetto è impedire la raccolta di informazioni da parte dei bot crawler."
|
||||
@@ -1447,9 +1451,9 @@ _initialTutorial:
|
||||
description: "Queste sono solamente alcune delle funzionalità principali di Misskey. Per ulteriori informazioni, {link}."
|
||||
_timelineDescription:
|
||||
home: "Nella Timeline Home, la tua cronologia principale, puoi vedere le Note provenienti dai profili che segui (Following)."
|
||||
local: "La Timeline Locale, è una cronologia di Note pubblicate da tutti i profili iscritti su questo server."
|
||||
social: "La Timeline Sociale, unisce in ordine cronologico l'elenco di Note presenti nella Timeline Home e quella Locale."
|
||||
global: "La Timeline Federata ti consente di vedere le Note pubblicate dai profili di tutti gli altri server federati a questo."
|
||||
local: "La Timeline Locale è un flusso di Note pubblicate dai profili iscritti a questo server."
|
||||
social: "La Timeline Sociale elenca, in ordine cronologico, il flusso di Note nella Timeline Home e Locale."
|
||||
global: "Nella Timeline Federata trovi il flusso di Note provenienti da profili iscritti ad altri server, federati a questo."
|
||||
_serverRules:
|
||||
description: "In Europa è necessario mostrare l'informativa sul trattamento dei dati personali, prima della registrazione al servizio."
|
||||
_serverSettings:
|
||||
@@ -1473,8 +1477,8 @@ _serverSettings:
|
||||
_accountMigration:
|
||||
moveFrom: "Migra un altro profilo dentro a questo"
|
||||
moveFromSub: "Crea un alias verso un altro profilo remoto"
|
||||
moveFromLabel: "Profilo da cui migrare #{n}"
|
||||
moveFromDescription: "Se desideri spostare i Follower da un altro profilo a questo, devi prima creare un alias qui. Assicurati averlo creato PRIMA di eseguire l'attività! Inserisci l'indirizzo del profilo mittente in questo modo: @persona@istanza.it"
|
||||
moveFromLabel: "Profilo da cui migrare n. {n}"
|
||||
moveFromDescription: "Se desideri spostare i Follower da un altro profilo a questo, devi prima creare un alias qui. Assicurati averlo creato PRIMA di eseguire l'attività! Inserisci l'indirizzo del profilo mittente in questo modo: @persona@vecchia.istanza.it"
|
||||
moveTo: "Migrare questo profilo verso un un altro"
|
||||
moveToLabel: "Profilo verso cui migrare"
|
||||
moveCannotBeUndone: "La migrazione è irreversibile, non può essere interrotta o annullata."
|
||||
@@ -1550,13 +1554,13 @@ _achievements:
|
||||
title: "Principiante III"
|
||||
description: "Hai totalizzato 15 accessi!"
|
||||
_login30:
|
||||
title: "Misskist I"
|
||||
title: "Missalcolista I"
|
||||
description: "Hai totalizzato 30 accessi!"
|
||||
_login60:
|
||||
title: "Misskeist II"
|
||||
title: "Missalcolista II"
|
||||
description: "Hai totalizzato 60 accessi!"
|
||||
_login100:
|
||||
title: "Misskeist III"
|
||||
title: "Missalcolista III"
|
||||
description: "Hai totalizzato 100 accessi!"
|
||||
flavor: "Violent Misskeist"
|
||||
_login200:
|
||||
@@ -1642,10 +1646,10 @@ _achievements:
|
||||
description: "Hai superato i 1.000 profili Follower"
|
||||
_collectAchievements30:
|
||||
title: "Collezionista di successi"
|
||||
description: "Hai raggiunto 30 obiettivi"
|
||||
description: "Hai raggiunto 30 conquiste"
|
||||
_viewAchievements3min:
|
||||
title: "Mi piacciono i risultati"
|
||||
description: "Guarda la tua collezione di obiettivi per almeno 3 minuti"
|
||||
description: "Ammira la tua collezione di conquiste per almeno 3 minuti"
|
||||
_iLoveMisskey:
|
||||
title: "I LOVE Misskey"
|
||||
description: "Pubblica «I ♥ #Misskey»"
|
||||
@@ -1910,7 +1914,7 @@ _registry:
|
||||
domain: "Dominio"
|
||||
createKey: "Crea chiave"
|
||||
_aboutMisskey:
|
||||
about: "Misskey è un software libero e open source, sviluppato da syuilo dal 2014."
|
||||
about: "Misskey è software libero, open source, sviluppato da Syuilo fin dal lontano 2014."
|
||||
contributors: "Principali sostenitori"
|
||||
allContributors: "Tutti i sostenitori"
|
||||
source: "Codice sorgente"
|
||||
@@ -2237,7 +2241,7 @@ _widgets:
|
||||
userList: "Elenco utenti"
|
||||
_userList:
|
||||
chooseList: "Seleziona una lista"
|
||||
clicker: "Cliccaggio"
|
||||
clicker: "Cliccheria"
|
||||
birthdayFollowings: "Compleanni del giorno"
|
||||
_cw:
|
||||
hide: "Nascondere"
|
||||
@@ -2300,7 +2304,7 @@ _profile:
|
||||
metadataContent: "Contenuto"
|
||||
changeAvatar: "Modifica immagine profilo"
|
||||
changeBanner: "Cambia intestazione"
|
||||
verifiedLinkDescription: "Puoi verificare il tuo profilo mostrando una icona. Devi inserire la URL alla pagina che contiene un link al tuo profilo."
|
||||
verifiedLinkDescription: "Puoi verificare il tuo profilo mostrando una icona. Devi inserire la URL alla pagina che contiene un link al tuo profilo.\nPer verificare il profilo tramite la spunta di conferma, devi inserire la url alla pagina che contiene un link al tuo profilo Misskey. Deve avere attributo rel='me'."
|
||||
avatarDecorationMax: "Puoi aggiungere fino a {max} decorazioni."
|
||||
followedMessage: "Messaggio, quando qualcuno ti segue"
|
||||
followedMessageDescription: "Puoi impostare un breve messaggio da mostrare agli altri profili quando ti seguono."
|
||||
@@ -2594,6 +2598,7 @@ _moderationLogTypes:
|
||||
deletePage: "Pagina eliminata"
|
||||
deleteFlash: "Play eliminato"
|
||||
deleteGalleryPost: "Eliminazione pubblicazione nella Galleria"
|
||||
updateProxyAccountDescription: "Aggiornata la descrizione del profilo proxy"
|
||||
_fileViewer:
|
||||
title: "Dettagli del file"
|
||||
type: "Tipo di file"
|
||||
@@ -2811,8 +2816,8 @@ _selfXssPrevention:
|
||||
description2: "Se non sai esattamente cosa stai facendo, %c smetti subito e chiudi questa finestra."
|
||||
description3: "Per favore, controlla questo collegamento per avere maggiori dettagli. {link}"
|
||||
_followRequest:
|
||||
recieved: "Ricezione richiesta di Follow"
|
||||
sent: "Richiesta di Follow, inviata"
|
||||
recieved: "Richieste in ingresso"
|
||||
sent: "Richieste in uscita"
|
||||
_remoteLookupErrors:
|
||||
_federationNotAllowed:
|
||||
title: "Server irraggiungibile"
|
||||
@@ -2857,4 +2862,8 @@ _bootErrors:
|
||||
_search:
|
||||
searchScopeAll: "Tutte"
|
||||
searchScopeLocal: "Locale"
|
||||
searchScopeServer: "Specifiche del server"
|
||||
searchScopeUser: "Profilo specifico"
|
||||
pleaseEnterServerHost: "Inserire il nome host"
|
||||
pleaseSelectUser: "Per favore, seleziona un profilo"
|
||||
serverHostPlaceholder: "Es: misskey.example.com"
|
||||
|
@@ -1238,7 +1238,7 @@ releaseToRefresh: "離してリロード"
|
||||
refreshing: "リロード中"
|
||||
pullDownToRefresh: "引っ張ってリロード"
|
||||
disableStreamingTimeline: "タイムラインのリアルタイム更新を無効にする"
|
||||
useGroupedNotifications: "通知をグルーピングして表示する"
|
||||
useGroupedNotifications: "通知をグルーピング"
|
||||
signupPendingError: "メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。"
|
||||
cwNotationRequired: "「内容を隠す」がオンの場合は注釈の記述が必要です。"
|
||||
doReaction: "リアクションする"
|
||||
@@ -1313,6 +1313,31 @@ confirmOnReact: "リアクションする際に確認する"
|
||||
reactAreYouSure: "\" {emoji} \" をリアクションしますか?"
|
||||
markAsSensitiveConfirm: "このメディアをセンシティブとして設定しますか?"
|
||||
unmarkAsSensitiveConfirm: "このメディアのセンシティブ指定を解除しますか?"
|
||||
preferences: "環境設定"
|
||||
accessibility: "アクセシビリティ"
|
||||
preferencesProfile: "設定のプロファイル"
|
||||
copyPreferenceId: "設定IDをコピー"
|
||||
resetToDefaultValue: "初期値に戻す"
|
||||
overrideByAccount: "アカウントで上書き"
|
||||
untitled: "無題"
|
||||
noName: "名前はありません"
|
||||
skip: "スキップ"
|
||||
restore: "復元"
|
||||
|
||||
_preferencesProfile:
|
||||
profileName: "プロファイル名"
|
||||
profileNameDescription: "このデバイスを識別する名前を設定してください。"
|
||||
profileNameDescription2: "例: 「メインPC」、「スマホ」など"
|
||||
|
||||
_preferencesBackup:
|
||||
autoBackup: "自動バックアップ"
|
||||
restoreFromBackup: "バックアップから復元"
|
||||
noBackupsFoundTitle: "バックアップが見つかりませんでした"
|
||||
noBackupsFoundDescription: "自動で作成されたバックアップは見つかりませんでしたが、バックアップファイルを手動で保存している場合、それをインポートして復元することはできます。"
|
||||
selectBackupToRestore: "復元するバックアップを選択してください"
|
||||
youNeedToNameYourProfileToEnableAutoBackup: "自動バックアップを有効にするにはプロファイル名の設定が必要です。"
|
||||
autoPreferencesBackupIsNotEnabledForThisDevice: "このデバイスで設定の自動バックアップは有効になっていません。"
|
||||
backupFound: "設定のバックアップが見つかりました"
|
||||
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "コンテンツの表示にログインを必須にする"
|
||||
|
@@ -1311,6 +1311,10 @@ federationSpecified: "此服务器已开启联合白名单。只能与管理员
|
||||
federationDisabled: "此服务器已禁用联合。无法与其它服务器上的用户通信。"
|
||||
confirmOnReact: "发送回应前需要确认"
|
||||
reactAreYouSure: "要用「{emoji}」进行回应吗?"
|
||||
markAsSensitiveConfirm: "要将此媒体标记为敏感吗?"
|
||||
unmarkAsSensitiveConfirm: "要将此媒体解除敏感标记吗?"
|
||||
preferences: "设置"
|
||||
accessibility: "辅助功能"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "需要登录才能显示内容"
|
||||
requireSigninToViewContentsDescription1: "您发布的所有帖子将变成需要登入后才会显示。有望防止爬虫收集各种信息。"
|
||||
@@ -2594,6 +2598,7 @@ _moderationLogTypes:
|
||||
deletePage: "删除了页面"
|
||||
deleteFlash: "删除了 Play"
|
||||
deleteGalleryPost: "删除了图库稿件"
|
||||
updateProxyAccountDescription: "更新代理账户的说明"
|
||||
_fileViewer:
|
||||
title: "文件信息"
|
||||
type: "文件类型"
|
||||
@@ -2857,4 +2862,8 @@ _bootErrors:
|
||||
_search:
|
||||
searchScopeAll: "全部"
|
||||
searchScopeLocal: "本地"
|
||||
searchScopeUser: "用户指定"
|
||||
searchScopeServer: "指定服务器"
|
||||
searchScopeUser: "指定用户"
|
||||
pleaseEnterServerHost: "请填写服务器主机名"
|
||||
pleaseSelectUser: "请选择用户"
|
||||
serverHostPlaceholder: "如:misskey.example.com"
|
||||
|
@@ -1311,6 +1311,10 @@ federationSpecified: "此伺服器以白名單聯邦的方式運作。除了管
|
||||
federationDisabled: "此伺服器未開啟站台聯邦。無法與其他伺服器上的使用者互動。"
|
||||
confirmOnReact: "反應時確認"
|
||||
reactAreYouSure: "用「 {emoji} 」反應嗎?"
|
||||
markAsSensitiveConfirm: "要將這個媒體設定為敏感嗎?"
|
||||
unmarkAsSensitiveConfirm: "要解除這個媒體的敏感設定嗎?"
|
||||
preferences: "環境設定"
|
||||
accessibility: "輔助工具"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "須登入以顯示內容"
|
||||
requireSigninToViewContentsDescription1: "必須登入才會顯示您建立的貼文等內容。可望有效防止資訊被爬蟲蒐集。"
|
||||
@@ -2594,6 +2598,7 @@ _moderationLogTypes:
|
||||
deletePage: "刪除頁面"
|
||||
deleteFlash: "刪除 Play"
|
||||
deleteGalleryPost: "刪除相簿的貼文"
|
||||
updateProxyAccountDescription: "更新代理帳戶的說明"
|
||||
_fileViewer:
|
||||
title: "檔案詳細資訊"
|
||||
type: "檔案類型 "
|
||||
@@ -2857,4 +2862,8 @@ _bootErrors:
|
||||
_search:
|
||||
searchScopeAll: "全部"
|
||||
searchScopeLocal: "本地"
|
||||
searchScopeServer: "指定伺服器"
|
||||
searchScopeUser: "指定使用者"
|
||||
pleaseEnterServerHost: "請輸入伺服器的主機名稱"
|
||||
pleaseSelectUser: "請選擇使用者"
|
||||
serverHostPlaceholder: "例:misskey.example.com"
|
||||
|
37
package.json
37
package.json
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"version": "2025.3.0-beta.0",
|
||||
"version": "2025.3.2-alpha.4",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/misskey-dev/misskey.git"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.4",
|
||||
"packageManager": "pnpm@10.6.1",
|
||||
"workspaces": [
|
||||
"packages/frontend-shared",
|
||||
"packages/frontend",
|
||||
@@ -47,35 +47,44 @@
|
||||
"cleanall": "pnpm clean-all"
|
||||
},
|
||||
"resolutions": {
|
||||
"chokidar": "3.6.0",
|
||||
"chokidar": "4.0.3",
|
||||
"lodash": "4.17.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"cssnano": "7.0.6",
|
||||
"execa": "8.0.1",
|
||||
"execa": "9.5.2",
|
||||
"fast-glob": "3.3.3",
|
||||
"ignore-walk": "6.0.5",
|
||||
"ignore-walk": "7.0.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"postcss": "8.5.2",
|
||||
"tar": "6.2.1",
|
||||
"postcss": "8.5.3",
|
||||
"tar": "7.4.3",
|
||||
"terser": "5.39.0",
|
||||
"typescript": "5.7.3",
|
||||
"typescript": "5.8.2",
|
||||
"esbuild": "0.25.0",
|
||||
"glob": "11.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@misskey-dev/eslint-plugin": "2.1.0",
|
||||
"@types/node": "22.13.4",
|
||||
"@typescript-eslint/eslint-plugin": "8.24.0",
|
||||
"@typescript-eslint/parser": "8.24.0",
|
||||
"@types/node": "22.13.9",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "14.0.3",
|
||||
"eslint": "9.20.1",
|
||||
"globals": "15.15.0",
|
||||
"cypress": "14.1.0",
|
||||
"eslint": "9.21.0",
|
||||
"globals": "16.0.0",
|
||||
"ncp": "2.0.0",
|
||||
"pnpm": "10.6.1",
|
||||
"start-server-and-test": "2.0.10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.22.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"@aiscript-dev/aiscript-languageserver": "-"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"re2": "scripts/dependency-patches/re2.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class SystemAccounts1741279404074 {
|
||||
name = 'SystemAccounts1741279404074'
|
||||
|
||||
async up(queryRunner) {
|
||||
const instanceActor = await queryRunner.query(`SELECT "id" FROM "user" WHERE "username" = 'instance.actor' AND "host" IS NULL AND "id" NOT IN (SELECT "userId" FROM "system_account" WHERE "type" = 'actor')`);
|
||||
if (instanceActor.length > 0) {
|
||||
console.warn('instance.actor was incorrect, updating...');
|
||||
await queryRunner.query(`UPDATE "system_account" SET "id" = '${instanceActor[0].id}', "userId" = '${instanceActor[0].id}' WHERE "type" = 'actor'`);
|
||||
}
|
||||
|
||||
const relayActor = await queryRunner.query(`SELECT "id" FROM "user" WHERE "username" = 'relay.actor' AND "host" IS NULL AND "id" NOT IN (SELECT "userId" FROM "system_account" WHERE "type" = 'relay')`);
|
||||
if (relayActor.length > 0) {
|
||||
console.warn('relay.actor was incorrect, updating...');
|
||||
await queryRunner.query(`UPDATE "system_account" SET "id" = '${relayActor[0].id}', "userId" = '${relayActor[0].id}' WHERE "type" = 'relay'`);
|
||||
}
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
// fixup migration, no down migration
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class UserFeaturedFixup1741424411879 {
|
||||
name = 'UserFeaturedFixup1741424411879'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`CREATE OR REPLACE FUNCTION pg_temp.extract_ap_id(text) RETURNS text AS $$
|
||||
SELECT
|
||||
CASE
|
||||
WHEN $1 ~ '^https?://' THEN $1
|
||||
WHEN $1 LIKE '{%' THEN COALESCE(jsonb_extract_path_text($1::jsonb, 'id'), null)
|
||||
ELSE null
|
||||
END;
|
||||
$$ LANGUAGE sql IMMUTABLE;`);
|
||||
|
||||
// "host" is NOT NULL is not needed but just in case add it to prevent overwriting irreplaceable data
|
||||
await queryRunner.query(`UPDATE "user" SET "featured" = pg_temp.extract_ap_id("featured") WHERE "host" IS NOT NULL`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
// fixup migration, no down migration
|
||||
}
|
||||
}
|
@@ -268,7 +268,6 @@ export class FileInfoService {
|
||||
private async *asyncIterateFrames(cwd: string, command: FFmpeg.FfmpegCommand): AsyncGenerator<string, void> {
|
||||
const watcher = new FSWatcher({
|
||||
cwd,
|
||||
disableGlobbing: true,
|
||||
});
|
||||
let finished = false;
|
||||
command.once('end', () => {
|
||||
|
@@ -46,6 +46,8 @@ export class S3Service {
|
||||
tls: meta.objectStorageUseSSL,
|
||||
forcePathStyle: meta.objectStorageEndpoint ? meta.objectStorageS3ForcePathStyle : false, // AWS with endPoint omitted
|
||||
requestHandler: new NodeHttpHandler(handlerOption),
|
||||
requestChecksumCalculation: 'WHEN_REQUIRED',
|
||||
responseChecksumValidation: 'WHEN_REQUIRED',
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -499,11 +499,28 @@ export class ApRendererService {
|
||||
this.userProfilesRepository.findOneByOrFail({ userId: user.id }),
|
||||
]);
|
||||
|
||||
const tryRewriteUrl = (maybeUrl: string) => {
|
||||
const urlSafeRegex = /^(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/;
|
||||
try {
|
||||
const match = maybeUrl.match(urlSafeRegex);
|
||||
if (!match) {
|
||||
return maybeUrl;
|
||||
}
|
||||
const urlPart = match[0];
|
||||
const urlPartParsed = new URL(urlPart);
|
||||
const restPart = maybeUrl.slice(match[0].length);
|
||||
|
||||
return `<a href="${urlPartParsed.href}" rel="me nofollow noopener" target="_blank">${urlPart}</a>${restPart}`;
|
||||
} catch (e) {
|
||||
return maybeUrl;
|
||||
}
|
||||
};
|
||||
|
||||
const attachment = profile.fields.map(field => ({
|
||||
type: 'PropertyValue',
|
||||
name: field.name,
|
||||
value: (field.value.startsWith('http://') || field.value.startsWith('https://'))
|
||||
? `<a href="${new URL(field.value).href}" rel="me nofollow noopener" target="_blank">${new URL(field.value).href}</a>`
|
||||
? tryRewriteUrl(field.value)
|
||||
: field.value,
|
||||
}));
|
||||
|
||||
|
@@ -560,7 +560,7 @@ export class ApPersonService implements OnModuleInit {
|
||||
inbox: person.inbox,
|
||||
sharedInbox: person.sharedInbox ?? person.endpoints?.sharedInbox ?? null,
|
||||
followersUri: person.followers ? getApId(person.followers) : undefined,
|
||||
featured: person.featured,
|
||||
featured: person.featured ? getApId(person.featured) : undefined,
|
||||
emojis: emojiNames,
|
||||
name: truncate(person.name, nameLength),
|
||||
tags,
|
||||
|
@@ -751,7 +751,7 @@ export class ActivityPubServerService {
|
||||
});
|
||||
|
||||
// follow
|
||||
fastify.get<{ Params: { followRequestId: string ; } }>('/follows/:followRequestId', async (request, reply) => {
|
||||
fastify.get<{ Params: { followRequestId: string; } }>('/follows/:followRequestId', async (request, reply) => {
|
||||
// This may be used before the follow is completed, so we do not
|
||||
// check if the following exists and only check if the follow request exists.
|
||||
|
||||
|
@@ -497,7 +497,7 @@ export class FileServerService {
|
||||
|
||||
@bindThis
|
||||
private async downloadAndDetectTypeFromUrl(url: string): Promise<
|
||||
{ state: 'remote' ; mime: string; ext: string | null; path: string; cleanup: () => void; filename: string; }
|
||||
{ state: 'remote'; mime: string; ext: string | null; path: string; cleanup: () => void; filename: string; }
|
||||
> {
|
||||
const [path, cleanup] = await createTemp();
|
||||
try {
|
||||
|
@@ -95,6 +95,7 @@ interface ClientInformation {
|
||||
id: string;
|
||||
redirectUris: string[];
|
||||
name: string;
|
||||
logo: string | null;
|
||||
}
|
||||
|
||||
// https://indieauth.spec.indieweb.org/#client-information-discovery
|
||||
@@ -124,11 +125,19 @@ async function discoverClientInformation(logger: Logger, httpRequestService: Htt
|
||||
redirectUris.push(...[...fragment.querySelectorAll<HTMLLinkElement>('link[rel=redirect_uri][href]')].map(el => el.href));
|
||||
|
||||
let name = id;
|
||||
let logo: string | null = null;
|
||||
if (text) {
|
||||
const microformats = mf2(text, { baseUrl: res.url });
|
||||
const nameProperty = microformats.items.find(item => item.type?.includes('h-app') && item.properties.url.includes(id))?.properties.name[0];
|
||||
if (typeof nameProperty === 'string') {
|
||||
name = nameProperty;
|
||||
const correspondingProperties = microformats.items.find(item => item.type?.includes('h-app') && item.properties.url.includes(id));
|
||||
if (correspondingProperties) {
|
||||
const nameProperty = correspondingProperties.properties.name?.[0];
|
||||
if (typeof nameProperty === 'string') {
|
||||
name = nameProperty;
|
||||
}
|
||||
const logoProperty = correspondingProperties.properties.logo?.[0];
|
||||
if (typeof logoProperty === 'string') {
|
||||
logo = logoProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +145,7 @@ async function discoverClientInformation(logger: Logger, httpRequestService: Htt
|
||||
id,
|
||||
redirectUris: redirectUris.map(uri => new URL(uri, res.url).toString()),
|
||||
name: typeof name === 'string' ? name : id,
|
||||
logo,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@@ -379,6 +389,7 @@ export class OAuth2ProviderService {
|
||||
return await reply.view('oauth', {
|
||||
transactionId: oauth2.transactionID,
|
||||
clientName: oauth2.client.name,
|
||||
clientLogo: oauth2.client.logo,
|
||||
scope: oauth2.req.scope.join(' '),
|
||||
});
|
||||
});
|
||||
|
@@ -6,4 +6,6 @@ block meta
|
||||
//- XXX: Remove navigation bar in auth page?
|
||||
meta(name='misskey:oauth:transaction-id' content=transactionId)
|
||||
meta(name='misskey:oauth:client-name' content=clientName)
|
||||
if clientLogo
|
||||
meta(name='misskey:oauth:client-logo' content=clientLogo)
|
||||
meta(name='misskey:oauth:scope' content=scope)
|
||||
|
@@ -12,12 +12,11 @@ services:
|
||||
retries: 20
|
||||
|
||||
misskey:
|
||||
image: node:22.14.0
|
||||
image: node:20
|
||||
env_file:
|
||||
- ./.config/docker.env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- COREPACK_DEFAULT_TO_LATEST=0
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ../../../built
|
||||
@@ -75,6 +74,10 @@ services:
|
||||
source: ../../../pnpm-workspace.yaml
|
||||
target: /misskey/pnpm-workspace.yaml
|
||||
read_only: true
|
||||
- type: bind
|
||||
source: ../../../scripts/dependency-patches
|
||||
target: /misskey/scripts/dependency-patches
|
||||
read_only: true
|
||||
- type: bind
|
||||
source: ./certificates/rootCA.crt
|
||||
target: /usr/local/share/ca-certificates/rootCA.crt
|
||||
@@ -82,7 +85,7 @@ services:
|
||||
working_dir: /misskey
|
||||
command: >
|
||||
bash -c "
|
||||
corepack enable && corepack prepare
|
||||
npm install -g pnpm
|
||||
pnpm -F backend migrate
|
||||
pnpm -F backend start
|
||||
"
|
||||
|
@@ -9,14 +9,14 @@ services:
|
||||
service: misskey
|
||||
command: >
|
||||
bash -c "
|
||||
corepack enable && corepack prepare
|
||||
npm install -g pnpm
|
||||
pnpm -F backend i
|
||||
pnpm -F misskey-js i
|
||||
pnpm -F misskey-reversi i
|
||||
"
|
||||
|
||||
tester:
|
||||
image: node:22.14.0
|
||||
image: node:20
|
||||
depends_on:
|
||||
a.test:
|
||||
condition: service_healthy
|
||||
@@ -29,7 +29,6 @@ services:
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/rootCA.crt
|
||||
- COREPACK_DEFAULT_TO_LATEST=0
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ../package.json
|
||||
@@ -71,6 +70,10 @@ services:
|
||||
source: ../../../pnpm-workspace.yaml
|
||||
target: /misskey/pnpm-workspace.yaml
|
||||
read_only: true
|
||||
- type: bind
|
||||
source: ../../../scripts/dependency-patches
|
||||
target: /misskey/scripts/dependency-patches
|
||||
read_only: true
|
||||
- type: bind
|
||||
source: ./certificates/rootCA.crt
|
||||
target: /usr/local/share/ca-certificates/rootCA.crt
|
||||
@@ -78,7 +81,7 @@ services:
|
||||
working_dir: /misskey
|
||||
entrypoint: >
|
||||
bash -c '
|
||||
corepack enable && corepack prepare
|
||||
npm install -g pnpm
|
||||
pnpm -F misskey-js i --frozen-lockfile
|
||||
pnpm -F backend i --frozen-lockfile
|
||||
exec "$0" "$@"
|
||||
@@ -86,12 +89,10 @@ services:
|
||||
command: pnpm -F backend test:fed
|
||||
|
||||
daemon:
|
||||
image: node:22.14.0
|
||||
image: node:20
|
||||
depends_on:
|
||||
redis.test:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- COREPACK_DEFAULT_TO_LATEST=0
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ../package.json
|
||||
@@ -117,10 +118,14 @@ services:
|
||||
source: ../../../pnpm-workspace.yaml
|
||||
target: /misskey/pnpm-workspace.yaml
|
||||
read_only: true
|
||||
- type: bind
|
||||
source: ../../../scripts/dependency-patches
|
||||
target: /misskey/scripts/dependency-patches
|
||||
read_only: true
|
||||
working_dir: /misskey
|
||||
command: >
|
||||
bash -c "
|
||||
corepack enable && corepack prepare
|
||||
npm install -g pnpm
|
||||
pnpm -F backend i --frozen-lockfile
|
||||
pnpm exec tsc -p ./packages/backend/test-federation
|
||||
node ./packages/backend/test-federation/built/daemon.js
|
||||
|
@@ -72,11 +72,12 @@ const clientConfig: ModuleOptions<'client_id'> = {
|
||||
},
|
||||
};
|
||||
|
||||
function getMeta(html: string): { transactionId: string | undefined, clientName: string | undefined } {
|
||||
function getMeta(html: string): { transactionId: string | undefined, clientName: string | undefined, clientLogo: string | undefined } {
|
||||
const fragment = JSDOM.fragment(html);
|
||||
return {
|
||||
transactionId: fragment.querySelector<HTMLMetaElement>('meta[name="misskey:oauth:transaction-id"]')?.content,
|
||||
clientName: fragment.querySelector<HTMLMetaElement>('meta[name="misskey:oauth:client-name"]')?.content,
|
||||
clientLogo: fragment.querySelector<HTMLMetaElement>('meta[name="misskey:oauth:client-logo"]')?.content,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -915,6 +916,59 @@ describe('OAuth', () => {
|
||||
assert.strictEqual(getMeta(await response.text()).clientName, `http://127.0.0.1:${clientPort}/`);
|
||||
});
|
||||
|
||||
test('With Logo', async () => {
|
||||
sender = (reply): void => {
|
||||
reply.header('Link', '</redirect>; rel="redirect_uri"');
|
||||
reply.send(`
|
||||
<!DOCTYPE html>
|
||||
<div class="h-app">
|
||||
<a href="/" class="u-url p-name">Misklient</a>
|
||||
<img src="/logo.png" class="u-logo" />
|
||||
</div>
|
||||
`);
|
||||
reply.send();
|
||||
};
|
||||
|
||||
const client = new AuthorizationCode(clientConfig);
|
||||
|
||||
const response = await fetch(client.authorizeURL({
|
||||
redirect_uri,
|
||||
scope: 'write:notes',
|
||||
state: 'state',
|
||||
code_challenge: 'code',
|
||||
code_challenge_method: 'S256',
|
||||
} as AuthorizationParamsExtended));
|
||||
assert.strictEqual(response.status, 200);
|
||||
const meta = getMeta(await response.text());
|
||||
assert.strictEqual(meta.clientName, 'Misklient');
|
||||
assert.strictEqual(meta.clientLogo, `http://127.0.0.1:${clientPort}/logo.png`);
|
||||
});
|
||||
|
||||
test('Missing Logo', async () => {
|
||||
sender = (reply): void => {
|
||||
reply.header('Link', '</redirect>; rel="redirect_uri"');
|
||||
reply.send(`
|
||||
<!DOCTYPE html>
|
||||
<div class="h-app"><a href="/" class="u-url p-name">Misklient
|
||||
`);
|
||||
reply.send();
|
||||
};
|
||||
|
||||
const client = new AuthorizationCode(clientConfig);
|
||||
|
||||
const response = await fetch(client.authorizeURL({
|
||||
redirect_uri,
|
||||
scope: 'write:notes',
|
||||
state: 'state',
|
||||
code_challenge: 'code',
|
||||
code_challenge_method: 'S256',
|
||||
} as AuthorizationParamsExtended));
|
||||
assert.strictEqual(response.status, 200);
|
||||
const meta = getMeta(await response.text());
|
||||
assert.strictEqual(meta.clientName, 'Misklient');
|
||||
assert.strictEqual(meta.clientLogo, undefined);
|
||||
});
|
||||
|
||||
test('Mismatching URL in h-app', async () => {
|
||||
sender = (reply): void => {
|
||||
reply.header('Link', '</redirect>; rel="redirect_uri"');
|
||||
|
@@ -14,7 +14,7 @@
|
||||
"@rollup/plugin-json": "6.1.0",
|
||||
"@rollup/plugin-replace": "6.0.2",
|
||||
"@rollup/pluginutils": "5.1.4",
|
||||
"@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.30.0-mi.1932+ab127beee.tar.gz",
|
||||
"@tabler/icons-webfont": "3.31.0",
|
||||
"@twemoji/parser": "15.1.1",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vue/compiler-sfc": "3.5.13",
|
||||
@@ -34,7 +34,7 @@
|
||||
"typescript": "5.8.2",
|
||||
"uuid": "11.1.0",
|
||||
"json5": "2.2.3",
|
||||
"vite": "6.2.0",
|
||||
"vite": "6.2.1",
|
||||
"vue": "3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -48,14 +48,14 @@
|
||||
"@types/ws": "8.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"@vitest/coverage-v8": "3.0.7",
|
||||
"@vitest/coverage-v8": "3.0.8",
|
||||
"@vue/runtime-core": "3.5.13",
|
||||
"acorn": "8.14.0",
|
||||
"acorn": "8.14.1",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-vue": "9.33.0",
|
||||
"eslint-plugin-vue": "10.0.0",
|
||||
"fast-glob": "3.3.3",
|
||||
"happy-dom": "17.2.2",
|
||||
"happy-dom": "17.3.0",
|
||||
"intersection-observer": "0.12.2",
|
||||
"micromatch": "4.0.8",
|
||||
"msw": "2.7.3",
|
||||
@@ -64,7 +64,7 @@
|
||||
"start-server-and-test": "2.0.10",
|
||||
"vite-plugin-turbosnap": "1.0.3",
|
||||
"vue-component-type-helpers": "2.2.8",
|
||||
"vue-eslint-parser": "9.4.3",
|
||||
"vue-eslint-parser": "10.1.1",
|
||||
"vue-tsc": "2.2.8"
|
||||
}
|
||||
}
|
||||
|
@@ -25,10 +25,10 @@
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"esbuild": "0.25.0",
|
||||
"eslint-plugin-vue": "9.33.0",
|
||||
"eslint-plugin-vue": "10.0.0",
|
||||
"nodemon": "3.1.9",
|
||||
"typescript": "5.8.2",
|
||||
"vue-eslint-parser": "9.4.3"
|
||||
"vue-eslint-parser": "10.1.1"
|
||||
},
|
||||
"files": [
|
||||
"js-built"
|
||||
|
@@ -39,6 +39,10 @@ const config = {
|
||||
if (~replacePluginForIsChromatic) {
|
||||
config.plugins?.splice(replacePluginForIsChromatic, 1);
|
||||
}
|
||||
|
||||
//pluginsからcreateSearchIndexを削除、複数あるかもしれないので全て削除
|
||||
config.plugins = config.plugins?.filter((plugin: Plugin) => plugin && plugin.name !== 'createSearchIndex') ?? [];
|
||||
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
{
|
||||
|
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<link rel="preload" href="https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/about-icon.png?raw=true" as="image" type="image/png" crossorigin="anonymous">
|
||||
<link rel="preload" href="https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true" as="image" type="image/jpeg" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://unpkg.com/@tabler/icons-webfont@3.3.0/dist/tabler-icons.min.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/@tabler/icons-webfont@3.31.0/dist/tabler-icons.min.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/@fontsource/m-plus-rounded-1c/index.css">
|
||||
<style>
|
||||
html {
|
||||
|
@@ -21,7 +21,7 @@ let moduleInitialized = false;
|
||||
let unobserve = () => {};
|
||||
let misskeyOS = null;
|
||||
|
||||
function loadTheme(applyTheme: typeof import('../src/scripts/theme')['applyTheme']) {
|
||||
function loadTheme(applyTheme: typeof import('../src/theme')['applyTheme']) {
|
||||
unobserve();
|
||||
const theme = themes[document.documentElement.dataset.misskeyTheme];
|
||||
if (theme) {
|
||||
@@ -67,10 +67,10 @@ queueMicrotask(() => {
|
||||
import('../src/components'),
|
||||
import('../src/directives'),
|
||||
import('../src/widgets'),
|
||||
import('../src/scripts/theme'),
|
||||
import('../src/store'),
|
||||
import('../src/theme'),
|
||||
import('../src/preferences'),
|
||||
import('../src/os'),
|
||||
]).then(([{ default: components }, { default: directives }, { default: widgets }, { applyTheme }, { defaultStore }, os]) => {
|
||||
]).then(([{ default: components }, { default: directives }, { default: widgets }, { applyTheme }, { prefer }, os]) => {
|
||||
setup((app) => {
|
||||
moduleInitialized = true;
|
||||
if (app[appInitialized]) {
|
||||
@@ -83,7 +83,7 @@ queueMicrotask(() => {
|
||||
widgets(app);
|
||||
misskeyOS = os;
|
||||
if (isChromatic()) {
|
||||
defaultStore.set('animation', false);
|
||||
prefer.set('animation', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -104,9 +104,9 @@ const preview = {
|
||||
}
|
||||
}).catch(() => {})
|
||||
: Promise.resolve();
|
||||
const resetDefaultStorePromise = import('../src/store').then(({ defaultStore }) => {
|
||||
const resetDefaultStorePromise = import('../src/store').then(({ store }) => {
|
||||
// @ts-expect-error
|
||||
defaultStore.init();
|
||||
store.init();
|
||||
}).catch(() => {});
|
||||
Promise.all([resetIndexedDBPromise, resetDefaultStorePromise]).then(() => {
|
||||
initLocalStorage();
|
||||
|
2
packages/frontend/@types/theme.d.ts
vendored
2
packages/frontend/@types/theme.d.ts
vendored
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
declare module '@@/themes/*.json5' {
|
||||
import { Theme } from '@/scripts/theme.js';
|
||||
import { Theme } from '@/theme.js';
|
||||
|
||||
const theme: Theme;
|
||||
|
||||
|
@@ -58,7 +58,7 @@ describe(normalizeClass.name, () => {
|
||||
|
||||
it('Composition API (standard)', () => {
|
||||
const ast = parse(`
|
||||
import { c as api, d as defaultStore, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
import { c as api, d as store, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
import { M as MkContainer } from './MkContainer-!~{03M}~.js';
|
||||
import { b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode } from './vue-!~{002}~.js';
|
||||
import './photoswipe-!~{003}~.js';
|
||||
@@ -74,7 +74,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
||||
let fetching = ref(true);
|
||||
let images = ref([]);
|
||||
function thumbnail(image) {
|
||||
return defaultStore.state.disableShowingAnimatedImages ? getStaticImageUrl(image.url) : image.thumbnailUrl;
|
||||
return store.s.disableShowingAnimatedImages ? getStaticImageUrl(image.url) : image.thumbnailUrl;
|
||||
}
|
||||
onMounted(() => {
|
||||
const image = [
|
||||
@@ -173,7 +173,7 @@ export { index_photos as default };
|
||||
`.slice(1), { ecmaVersion: 'latest', sourceType: 'module' });
|
||||
unwindCssModuleClassName(ast);
|
||||
expect(generate(ast)).toBe(`
|
||||
import {c as api, d as defaultStore, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc} from './app-!~{001}~.js';
|
||||
import {c as api, d as store, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc} from './app-!~{001}~.js';
|
||||
import {M as MkContainer} from './MkContainer-!~{03M}~.js';
|
||||
import {b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode} from './vue-!~{002}~.js';
|
||||
import './photoswipe-!~{003}~.js';
|
||||
@@ -190,7 +190,7 @@ const index_photos = defineComponent({
|
||||
let fetching = ref(true);
|
||||
let images = ref([]);
|
||||
function thumbnail(image) {
|
||||
return defaultStore.state.disableShowingAnimatedImages ? getStaticImageUrl(image.url) : image.thumbnailUrl;
|
||||
return store.s.disableShowingAnimatedImages ? getStaticImageUrl(image.url) : image.thumbnailUrl;
|
||||
}
|
||||
onMounted(() => {
|
||||
const image = ["image/jpeg", "image/webp", "image/avif", "image/png", "image/gif", "image/apng", "image/vnd.mozilla.apng"];
|
||||
@@ -268,7 +268,7 @@ export {index_photos as default};
|
||||
it('Composition API (with `useCssModule()`)', () => {
|
||||
const ast = parse(`
|
||||
import { a7 as getCurrentInstance, b as defineComponent, G as useCssModule, a1 as h, H as TransitionGroup } from './!~{002}~.js';
|
||||
import { d as defaultStore, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
import { d as store, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
|
||||
function isDebuggerEnabled(id) {
|
||||
try {
|
||||
@@ -393,7 +393,7 @@ const _sfc_main = defineComponent({
|
||||
el.style.left = "";
|
||||
}
|
||||
return () => h(
|
||||
defaultStore.state.animation ? TransitionGroup : "div",
|
||||
prefer.s.animation ? TransitionGroup : "div",
|
||||
{
|
||||
class: {
|
||||
[$style["date-separated-list"]]: true,
|
||||
@@ -402,7 +402,7 @@ const _sfc_main = defineComponent({
|
||||
[$style["direction-down"]]: props.direction === "down",
|
||||
[$style["direction-up"]]: props.direction === "up"
|
||||
},
|
||||
...defaultStore.state.animation ? {
|
||||
...prefer.s.animation ? {
|
||||
name: "list",
|
||||
tag: "div",
|
||||
onBeforeLeave,
|
||||
@@ -441,7 +441,7 @@ export { MkDateSeparatedList as M };
|
||||
unwindCssModuleClassName(ast);
|
||||
expect(generate(ast)).toBe(`
|
||||
import {a7 as getCurrentInstance, b as defineComponent, G as useCssModule, a1 as h, H as TransitionGroup} from './!~{002}~.js';
|
||||
import {d as defaultStore, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc} from './app-!~{001}~.js';
|
||||
import {d as store, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc} from './app-!~{001}~.js';
|
||||
function isDebuggerEnabled(id) {
|
||||
try {
|
||||
return localStorage.getItem(\`DEBUG_\${id}\`) !== null;
|
||||
@@ -555,7 +555,7 @@ const _sfc_main = defineComponent({
|
||||
el.style.top = "";
|
||||
el.style.left = "";
|
||||
}
|
||||
return () => h(defaultStore.state.animation ? TransitionGroup : "div", {
|
||||
return () => h(prefer.s.animation ? TransitionGroup : "div", {
|
||||
class: {
|
||||
[$style["date-separated-list"]]: true,
|
||||
[$style["date-separated-list-nogap"]]: props.noGap,
|
||||
@@ -563,7 +563,7 @@ const _sfc_main = defineComponent({
|
||||
[$style["direction-down"]]: props.direction === "down",
|
||||
[$style["direction-up"]]: props.direction === "up"
|
||||
},
|
||||
...defaultStore.state.animation ? {
|
||||
...prefer.s.animation ? {
|
||||
name: "list",
|
||||
tag: "div",
|
||||
onBeforeLeave,
|
||||
|
1516
packages/frontend/lib/vite-plugin-create-search-index.ts
Normal file
1516
packages/frontend/lib/vite-plugin-create-search-index.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
||||
"@rollup/plugin-replace": "6.0.2",
|
||||
"@rollup/pluginutils": "5.1.4",
|
||||
"@syuilo/aiscript": "0.19.0",
|
||||
"@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.30.0-mi.1932+ab127beee.tar.gz",
|
||||
"@tabler/icons-webfont": "3.31.0",
|
||||
"@twemoji/parser": "15.1.1",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vue/compiler-sfc": "3.5.13",
|
||||
@@ -51,6 +51,7 @@
|
||||
"insert-text-at-cursor": "0.3.0",
|
||||
"is-file-animated": "1.0.2",
|
||||
"json5": "2.2.3",
|
||||
"magic-string": "0.30.17",
|
||||
"matter-js": "0.20.0",
|
||||
"mfm-js": "0.24.0",
|
||||
"misskey-bubble-game": "workspace:*",
|
||||
@@ -72,30 +73,31 @@
|
||||
"typescript": "5.8.2",
|
||||
"uuid": "11.1.0",
|
||||
"v-code-diff": "1.13.1",
|
||||
"vite": "6.2.0",
|
||||
"vite": "6.2.1",
|
||||
"vue": "3.5.13",
|
||||
"vuedraggable": "next"
|
||||
"vuedraggable": "next",
|
||||
"wanakana": "5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@misskey-dev/summaly": "5.2.0",
|
||||
"@storybook/addon-actions": "8.6.3",
|
||||
"@storybook/addon-essentials": "8.6.3",
|
||||
"@storybook/addon-interactions": "8.6.3",
|
||||
"@storybook/addon-links": "8.6.3",
|
||||
"@storybook/addon-mdx-gfm": "8.6.3",
|
||||
"@storybook/addon-storysource": "8.6.3",
|
||||
"@storybook/blocks": "8.6.3",
|
||||
"@storybook/components": "8.6.3",
|
||||
"@storybook/core-events": "8.6.3",
|
||||
"@storybook/manager-api": "8.6.3",
|
||||
"@storybook/preview-api": "8.6.3",
|
||||
"@storybook/react": "8.6.3",
|
||||
"@storybook/react-vite": "8.6.3",
|
||||
"@storybook/test": "8.6.3",
|
||||
"@storybook/theming": "8.6.3",
|
||||
"@storybook/types": "8.6.3",
|
||||
"@storybook/vue3": "8.6.3",
|
||||
"@storybook/vue3-vite": "8.6.3",
|
||||
"@storybook/addon-actions": "8.6.4",
|
||||
"@storybook/addon-essentials": "8.6.4",
|
||||
"@storybook/addon-interactions": "8.6.4",
|
||||
"@storybook/addon-links": "8.6.4",
|
||||
"@storybook/addon-mdx-gfm": "8.6.4",
|
||||
"@storybook/addon-storysource": "8.6.4",
|
||||
"@storybook/blocks": "8.6.4",
|
||||
"@storybook/components": "8.6.4",
|
||||
"@storybook/core-events": "8.6.4",
|
||||
"@storybook/manager-api": "8.6.4",
|
||||
"@storybook/preview-api": "8.6.4",
|
||||
"@storybook/react": "8.6.4",
|
||||
"@storybook/react-vite": "8.6.4",
|
||||
"@storybook/test": "8.6.4",
|
||||
"@storybook/theming": "8.6.4",
|
||||
"@storybook/types": "8.6.4",
|
||||
"@storybook/vue3": "8.6.4",
|
||||
"@storybook/vue3-vite": "8.6.4",
|
||||
"@testing-library/vue": "8.1.0",
|
||||
"@types/canvas-confetti": "1.9.0",
|
||||
"@types/estree": "1.0.6",
|
||||
@@ -110,15 +112,15 @@
|
||||
"@types/ws": "8.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"@vitest/coverage-v8": "3.0.7",
|
||||
"@vitest/coverage-v8": "3.0.8",
|
||||
"@vue/runtime-core": "3.5.13",
|
||||
"acorn": "8.14.0",
|
||||
"acorn": "8.14.1",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "14.1.0",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-vue": "9.33.0",
|
||||
"eslint-plugin-vue": "10.0.0",
|
||||
"fast-glob": "3.3.3",
|
||||
"happy-dom": "17.2.2",
|
||||
"happy-dom": "17.3.0",
|
||||
"intersection-observer": "0.12.2",
|
||||
"micromatch": "4.0.8",
|
||||
"msw": "2.7.3",
|
||||
@@ -129,13 +131,13 @@
|
||||
"react-dom": "19.0.0",
|
||||
"seedrandom": "3.0.5",
|
||||
"start-server-and-test": "2.0.10",
|
||||
"storybook": "8.6.3",
|
||||
"storybook": "8.6.4",
|
||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||
"vite-plugin-turbosnap": "1.0.3",
|
||||
"vitest": "3.0.7",
|
||||
"vitest": "3.0.8",
|
||||
"vitest-fetch-mock": "0.4.5",
|
||||
"vue-component-type-helpers": "2.2.8",
|
||||
"vue-eslint-parser": "9.4.3",
|
||||
"vue-eslint-parser": "10.1.1",
|
||||
"vue-tsc": "2.2.8"
|
||||
}
|
||||
}
|
||||
|
@@ -8,13 +8,13 @@ import * as Misskey from 'misskey-js';
|
||||
import { apiUrl } from '@@/js/config.js';
|
||||
import type { MenuItem, MenuButton } from '@/types/menu.js';
|
||||
import { defaultMemoryStorage } from '@/memory-storage';
|
||||
import { showSuspendedDialog } from '@/scripts/show-suspended-dialog.js';
|
||||
import { showSuspendedDialog } from '@/utility/show-suspended-dialog.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { del, get, set } from '@/scripts/idb-proxy.js';
|
||||
import { del, get, set } from '@/utility/idb-proxy.js';
|
||||
import { waiting, popup, popupMenu, success, alert } from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { unisonReload, reloadChannel } from '@/scripts/unison-reload.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { unisonReload, reloadChannel } from '@/utility/unison-reload.js';
|
||||
|
||||
// TODO: 他のタブと永続化されたstateを同期
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import * as Misskey from 'misskey-js';
|
||||
import { url, lang } from '@@/js/config.js';
|
||||
import { assertStringAndIsIn } from './common.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { customEmojis } from '@/custom-emojis.js';
|
@@ -6,26 +6,29 @@
|
||||
import { computed, watch, version as vueVersion } from 'vue';
|
||||
import { compareVersions } from 'compare-versions';
|
||||
import { version, lang, updateLocale, locale } from '@@/js/config.js';
|
||||
import defaultLightTheme from '@@/themes/l-light.json5';
|
||||
import defaultDarkTheme from '@@/themes/d-green-lime.json5';
|
||||
import type { App } from 'vue';
|
||||
import widgets from '@/widgets/index.js';
|
||||
import directives from '@/directives/index.js';
|
||||
import components from '@/components/index.js';
|
||||
import { applyTheme } from '@/scripts/theme.js';
|
||||
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js';
|
||||
import { applyTheme } from '@/theme.js';
|
||||
import { isDeviceDarkmode } from '@/utility/is-device-darkmode.js';
|
||||
import { updateI18n, i18n } from '@/i18n.js';
|
||||
import { $i, refreshAccount, login } from '@/account.js';
|
||||
import { defaultStore, ColdDeviceStorage } from '@/store.js';
|
||||
import { store } from '@/store.js';
|
||||
import { fetchInstance, instance } from '@/instance.js';
|
||||
import { deviceKind, updateDeviceKind } from '@/scripts/device-kind.js';
|
||||
import { reloadChannel } from '@/scripts/unison-reload.js';
|
||||
import { getUrlWithoutLoginId } from '@/scripts/login-id.js';
|
||||
import { getAccountFromId } from '@/scripts/get-account-from-id.js';
|
||||
import { deviceKind, updateDeviceKind } from '@/utility/device-kind.js';
|
||||
import { reloadChannel } from '@/utility/unison-reload.js';
|
||||
import { getUrlWithoutLoginId } from '@/utility/login-id.js';
|
||||
import { getAccountFromId } from '@/utility/get-account-from-id.js';
|
||||
import { deckStore } from '@/ui/deck/deck-store.js';
|
||||
import { analytics, initAnalytics } from '@/analytics.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { fetchCustomEmojis } from '@/custom-emojis.js';
|
||||
import { setupRouter } from '@/router/main.js';
|
||||
import { createMainRouter } from '@/router/definition.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
export async function common(createVue: () => App<Element>) {
|
||||
console.info(`Misskey v${version}`);
|
||||
@@ -38,7 +41,7 @@ export async function common(createVue: () => App<Element>) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).$i = $i;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).$store = defaultStore;
|
||||
(window as any).$store = store;
|
||||
|
||||
window.addEventListener('error', event => {
|
||||
console.error(event);
|
||||
@@ -123,7 +126,7 @@ export async function common(createVue: () => App<Element>) {
|
||||
html.setAttribute('lang', lang);
|
||||
//#endregion
|
||||
|
||||
await defaultStore.ready;
|
||||
await store.ready;
|
||||
await deckStore.ready;
|
||||
|
||||
const fetchInstanceMetaPromise = fetchInstance();
|
||||
@@ -151,56 +154,63 @@ export async function common(createVue: () => App<Element>) {
|
||||
//#endregion
|
||||
|
||||
// NOTE: この処理は必ずクライアント更新チェック処理より後に来ること(テーマ再構築のため)
|
||||
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
|
||||
applyTheme(darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'));
|
||||
watch(store.r.darkMode, (darkMode) => {
|
||||
applyTheme(darkMode
|
||||
? (prefer.s.darkTheme ?? defaultDarkTheme)
|
||||
: (prefer.s.lightTheme ?? defaultLightTheme),
|
||||
);
|
||||
}, { immediate: miLocalStorage.getItem('theme') == null });
|
||||
|
||||
document.documentElement.dataset.colorScheme = defaultStore.state.darkMode ? 'dark' : 'light';
|
||||
document.documentElement.dataset.colorScheme = store.s.darkMode ? 'dark' : 'light';
|
||||
|
||||
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter('darkTheme'));
|
||||
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter('lightTheme'));
|
||||
const darkTheme = prefer.model('darkTheme');
|
||||
const lightTheme = prefer.model('lightTheme');
|
||||
|
||||
watch(darkTheme, (theme) => {
|
||||
if (defaultStore.state.darkMode) {
|
||||
applyTheme(theme);
|
||||
if (store.s.darkMode) {
|
||||
applyTheme(theme ?? defaultDarkTheme);
|
||||
}
|
||||
});
|
||||
|
||||
watch(lightTheme, (theme) => {
|
||||
if (!defaultStore.state.darkMode) {
|
||||
applyTheme(theme);
|
||||
if (!store.s.darkMode) {
|
||||
applyTheme(theme ?? defaultLightTheme);
|
||||
}
|
||||
});
|
||||
|
||||
//#region Sync dark mode
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
|
||||
defaultStore.set('darkMode', isDeviceDarkmode());
|
||||
if (prefer.s.syncDeviceDarkMode) {
|
||||
store.commit('darkMode', isDeviceDarkmode());
|
||||
}
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (mql) => {
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
|
||||
defaultStore.set('darkMode', mql.matches);
|
||||
if (prefer.s.syncDeviceDarkMode) {
|
||||
store.commit('darkMode', mql.matches);
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
||||
if (prefer.s.darkTheme && store.s.darkMode) {
|
||||
if (miLocalStorage.getItem('themeId') !== prefer.s.darkTheme.id) applyTheme(prefer.s.darkTheme);
|
||||
} else if (prefer.s.lightTheme && !store.s.darkMode) {
|
||||
if (miLocalStorage.getItem('themeId') !== prefer.s.lightTheme.id) applyTheme(prefer.s.lightTheme);
|
||||
}
|
||||
|
||||
fetchInstanceMetaPromise.then(() => {
|
||||
if (defaultStore.state.themeInitial) {
|
||||
if (instance.defaultLightTheme != null) ColdDeviceStorage.set('lightTheme', JSON.parse(instance.defaultLightTheme));
|
||||
if (instance.defaultDarkTheme != null) ColdDeviceStorage.set('darkTheme', JSON.parse(instance.defaultDarkTheme));
|
||||
defaultStore.set('themeInitial', false);
|
||||
}
|
||||
// TODO: instance.defaultLightTheme/instance.defaultDarkThemeが不正な形式だった場合のケア
|
||||
if (prefer.s.lightTheme == null && instance.defaultLightTheme != null) prefer.commit('lightTheme', JSON.parse(instance.defaultLightTheme));
|
||||
if (prefer.s.darkTheme == null && instance.defaultDarkTheme != null) prefer.commit('darkTheme', JSON.parse(instance.defaultDarkTheme));
|
||||
});
|
||||
|
||||
watch(defaultStore.reactiveState.overridedDeviceKind, (kind) => {
|
||||
watch(prefer.r.overridedDeviceKind, (kind) => {
|
||||
updateDeviceKind(kind);
|
||||
}, { immediate: true });
|
||||
|
||||
watch(defaultStore.reactiveState.useBlurEffectForModal, v => {
|
||||
watch(prefer.r.useBlurEffectForModal, v => {
|
||||
document.documentElement.style.setProperty('--MI-modalBgFilter', v ? 'blur(4px)' : 'none');
|
||||
}, { immediate: true });
|
||||
|
||||
watch(defaultStore.reactiveState.useBlurEffect, v => {
|
||||
watch(prefer.r.useBlurEffect, v => {
|
||||
if (v) {
|
||||
document.documentElement.style.removeProperty('--MI-blur');
|
||||
} else {
|
||||
@@ -214,7 +224,7 @@ export async function common(createVue: () => App<Element>) {
|
||||
navigator.wakeLock.request('screen');
|
||||
}
|
||||
});
|
||||
if (defaultStore.state.keepScreenOn && 'wakeLock' in navigator) {
|
||||
if (prefer.s.keepScreenOn && 'wakeLock' in navigator) {
|
||||
navigator.wakeLock.request('screen')
|
||||
.then(onVisibilityChange)
|
||||
.catch(() => {
|
||||
|
@@ -5,26 +5,29 @@
|
||||
|
||||
import { createApp, defineAsyncComponent, markRaw } from 'vue';
|
||||
import { ui } from '@@/js/config.js';
|
||||
import { common } from './common.js';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { common } from './common.js';
|
||||
import type { Component } from 'vue';
|
||||
import type { Keymap } from '@/utility/hotkey.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { alert, confirm, popup, post, toast } from '@/os.js';
|
||||
import { useStream } from '@/stream.js';
|
||||
import * as sound from '@/scripts/sound.js';
|
||||
import * as sound from '@/utility/sound.js';
|
||||
import { $i, signout, updateAccountPartial } from '@/account.js';
|
||||
import { instance } from '@/instance.js';
|
||||
import { ColdDeviceStorage, defaultStore } from '@/store.js';
|
||||
import { reactionPicker } from '@/scripts/reaction-picker.js';
|
||||
import { ColdDeviceStorage, store } from '@/store.js';
|
||||
import { reactionPicker } from '@/utility/reaction-picker.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { claimAchievement, claimedAchievements } from '@/scripts/achievements.js';
|
||||
import { initializeSw } from '@/scripts/initialize-sw.js';
|
||||
import { deckStore } from '@/ui/deck/deck-store.js';
|
||||
import { emojiPicker } from '@/scripts/emoji-picker.js';
|
||||
import { claimAchievement, claimedAchievements } from '@/utility/achievements.js';
|
||||
import { initializeSw } from '@/utility/initialize-sw.js';
|
||||
import { emojiPicker } from '@/utility/emoji-picker.js';
|
||||
import { mainRouter } from '@/router/main.js';
|
||||
import { makeHotkey } from '@/scripts/hotkey.js';
|
||||
import type { Keymap } from '@/scripts/hotkey.js';
|
||||
import { makeHotkey } from '@/utility/hotkey.js';
|
||||
import { addCustomEmoji, removeCustomEmojis, updateCustomEmojis } from '@/custom-emojis.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { deckStore } from '@/ui/deck/deck-store.js';
|
||||
import { launchPlugins } from '@/plugin.js';
|
||||
|
||||
export async function mainBoot() {
|
||||
const { isClientUpdated } = await common(() => {
|
||||
@@ -34,7 +37,7 @@ export async function mainBoot() {
|
||||
if (!$i) uiStyle = 'visitor';
|
||||
|
||||
if (searchParams.has('zen')) uiStyle = 'zen';
|
||||
if (uiStyle === 'deck' && deckStore.state.useSimpleUiForNonRootPages && location.pathname !== '/') uiStyle = 'zen';
|
||||
if (uiStyle === 'deck' && prefer.s['deck.useSimpleUiForNonRootPages'] && location.pathname !== '/') uiStyle = 'zen';
|
||||
|
||||
if (searchParams.has('ui')) uiStyle = searchParams.get('ui');
|
||||
|
||||
@@ -73,9 +76,9 @@ export async function mainBoot() {
|
||||
|
||||
let reloadDialogShowing = false;
|
||||
stream.on('_disconnected_', async () => {
|
||||
if (defaultStore.state.serverDisconnectedBehavior === 'reload') {
|
||||
if (prefer.s.serverDisconnectedBehavior === 'reload') {
|
||||
location.reload();
|
||||
} else if (defaultStore.state.serverDisconnectedBehavior === 'dialog') {
|
||||
} else if (prefer.s.serverDisconnectedBehavior === 'dialog') {
|
||||
if (reloadDialogShowing) return;
|
||||
reloadDialogShowing = true;
|
||||
const { canceled } = await confirm({
|
||||
@@ -102,30 +105,24 @@ export async function mainBoot() {
|
||||
removeCustomEmojis(emojiData.emojis);
|
||||
});
|
||||
|
||||
for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) {
|
||||
import('@/plugin.js').then(async ({ install }) => {
|
||||
// Workaround for https://bugs.webkit.org/show_bug.cgi?id=242740
|
||||
await new Promise(r => setTimeout(r, 0));
|
||||
install(plugin);
|
||||
});
|
||||
}
|
||||
launchPlugins();
|
||||
|
||||
try {
|
||||
if (defaultStore.state.enableSeasonalScreenEffect) {
|
||||
if (prefer.s.enableSeasonalScreenEffect) {
|
||||
const month = new Date().getMonth() + 1;
|
||||
if (defaultStore.state.hemisphere === 'S') {
|
||||
if (prefer.s.hemisphere === 'S') {
|
||||
// ▼南半球
|
||||
if (month === 7 || month === 8) {
|
||||
const SnowfallEffect = (await import('@/scripts/snowfall-effect.js')).SnowfallEffect;
|
||||
const SnowfallEffect = (await import('@/utility/snowfall-effect.js')).SnowfallEffect;
|
||||
new SnowfallEffect({}).render();
|
||||
}
|
||||
} else {
|
||||
// ▼北半球
|
||||
if (month === 12 || month === 1) {
|
||||
const SnowfallEffect = (await import('@/scripts/snowfall-effect.js')).SnowfallEffect;
|
||||
const SnowfallEffect = (await import('@/utility/snowfall-effect.js')).SnowfallEffect;
|
||||
new SnowfallEffect({}).render();
|
||||
} else if (month === 3 || month === 4) {
|
||||
const SakuraEffect = (await import('@/scripts/snowfall-effect.js')).SnowfallEffect;
|
||||
const SakuraEffect = (await import('@/utility/snowfall-effect.js')).SnowfallEffect;
|
||||
new SakuraEffect({
|
||||
sakura: true,
|
||||
}).render();
|
||||
@@ -138,8 +135,101 @@ export async function mainBoot() {
|
||||
}
|
||||
|
||||
if ($i) {
|
||||
defaultStore.loaded.then(() => {
|
||||
if (defaultStore.state.accountSetupWizard !== -1) {
|
||||
store.loaded.then(async () => {
|
||||
// prefereces migration
|
||||
// TODO: そのうち消す
|
||||
if (store.s.menu.length > 0) {
|
||||
const themes = await misskeyApi('i/registry/get', { scope: ['client'], key: 'themes' }).catch(() => []);
|
||||
if (themes.length > 0) {
|
||||
prefer.commit('themes', themes);
|
||||
}
|
||||
const plugins = ColdDeviceStorage.get('plugins');
|
||||
prefer.commit('plugins', plugins.map(p => ({
|
||||
...p,
|
||||
installId: (p as any).id,
|
||||
id: undefined,
|
||||
})));
|
||||
prefer.commit('lightTheme', ColdDeviceStorage.get('lightTheme'));
|
||||
prefer.commit('darkTheme', ColdDeviceStorage.get('darkTheme'));
|
||||
prefer.commit('syncDeviceDarkMode', ColdDeviceStorage.get('syncDeviceDarkMode'));
|
||||
prefer.commit('overridedDeviceKind', store.s.overridedDeviceKind);
|
||||
prefer.commit('widgets', store.s.widgets);
|
||||
prefer.commit('keepCw', store.s.keepCw);
|
||||
prefer.commit('collapseRenotes', store.s.collapseRenotes);
|
||||
prefer.commit('rememberNoteVisibility', store.s.rememberNoteVisibility);
|
||||
prefer.commit('uploadFolder', store.s.uploadFolder);
|
||||
prefer.commit('keepOriginalUploading', store.s.keepOriginalUploading);
|
||||
prefer.commit('menu', store.s.menu);
|
||||
prefer.commit('statusbars', store.s.statusbars);
|
||||
prefer.commit('pinnedUserLists', store.s.pinnedUserLists);
|
||||
prefer.commit('serverDisconnectedBehavior', store.s.serverDisconnectedBehavior);
|
||||
prefer.commit('nsfw', store.s.nsfw);
|
||||
prefer.commit('highlightSensitiveMedia', store.s.highlightSensitiveMedia);
|
||||
prefer.commit('animation', store.s.animation);
|
||||
prefer.commit('animatedMfm', store.s.animatedMfm);
|
||||
prefer.commit('advancedMfm', store.s.advancedMfm);
|
||||
prefer.commit('showReactionsCount', store.s.showReactionsCount);
|
||||
prefer.commit('enableQuickAddMfmFunction', store.s.enableQuickAddMfmFunction);
|
||||
prefer.commit('loadRawImages', store.s.loadRawImages);
|
||||
prefer.commit('imageNewTab', store.s.imageNewTab);
|
||||
prefer.commit('disableShowingAnimatedImages', store.s.disableShowingAnimatedImages);
|
||||
prefer.commit('emojiStyle', store.s.emojiStyle);
|
||||
prefer.commit('menuStyle', store.s.menuStyle);
|
||||
prefer.commit('useBlurEffectForModal', store.s.useBlurEffectForModal);
|
||||
prefer.commit('useBlurEffect', store.s.useBlurEffect);
|
||||
prefer.commit('showFixedPostForm', store.s.showFixedPostForm);
|
||||
prefer.commit('showFixedPostFormInChannel', store.s.showFixedPostFormInChannel);
|
||||
prefer.commit('enableInfiniteScroll', store.s.enableInfiniteScroll);
|
||||
prefer.commit('useReactionPickerForContextMenu', store.s.useReactionPickerForContextMenu);
|
||||
prefer.commit('showGapBetweenNotesInTimeline', store.s.showGapBetweenNotesInTimeline);
|
||||
prefer.commit('instanceTicker', store.s.instanceTicker);
|
||||
prefer.commit('emojiPickerScale', store.s.emojiPickerScale);
|
||||
prefer.commit('emojiPickerWidth', store.s.emojiPickerWidth);
|
||||
prefer.commit('emojiPickerHeight', store.s.emojiPickerHeight);
|
||||
prefer.commit('emojiPickerStyle', store.s.emojiPickerStyle);
|
||||
prefer.commit('reportError', store.s.reportError);
|
||||
prefer.commit('squareAvatars', store.s.squareAvatars);
|
||||
prefer.commit('showAvatarDecorations', store.s.showAvatarDecorations);
|
||||
prefer.commit('numberOfPageCache', store.s.numberOfPageCache);
|
||||
prefer.commit('showNoteActionsOnlyHover', store.s.showNoteActionsOnlyHover);
|
||||
prefer.commit('showClipButtonInNoteFooter', store.s.showClipButtonInNoteFooter);
|
||||
prefer.commit('reactionsDisplaySize', store.s.reactionsDisplaySize);
|
||||
prefer.commit('limitWidthOfReaction', store.s.limitWidthOfReaction);
|
||||
prefer.commit('forceShowAds', store.s.forceShowAds);
|
||||
prefer.commit('aiChanMode', store.s.aiChanMode);
|
||||
prefer.commit('devMode', store.s.devMode);
|
||||
prefer.commit('mediaListWithOneImageAppearance', store.s.mediaListWithOneImageAppearance);
|
||||
prefer.commit('notificationPosition', store.s.notificationPosition);
|
||||
prefer.commit('notificationStackAxis', store.s.notificationStackAxis);
|
||||
prefer.commit('enableCondensedLine', store.s.enableCondensedLine);
|
||||
prefer.commit('keepScreenOn', store.s.keepScreenOn);
|
||||
prefer.commit('disableStreamingTimeline', store.s.disableStreamingTimeline);
|
||||
prefer.commit('useGroupedNotifications', store.s.useGroupedNotifications);
|
||||
prefer.commit('dataSaver', store.s.dataSaver);
|
||||
prefer.commit('enableSeasonalScreenEffect', store.s.enableSeasonalScreenEffect);
|
||||
prefer.commit('enableHorizontalSwipe', store.s.enableHorizontalSwipe);
|
||||
prefer.commit('useNativeUiForVideoAudioPlayer', store.s.useNativeUIForVideoAudioPlayer);
|
||||
prefer.commit('keepOriginalFilename', store.s.keepOriginalFilename);
|
||||
prefer.commit('alwaysConfirmFollow', store.s.alwaysConfirmFollow);
|
||||
prefer.commit('confirmWhenRevealingSensitiveMedia', store.s.confirmWhenRevealingSensitiveMedia);
|
||||
prefer.commit('contextMenu', store.s.contextMenu);
|
||||
prefer.commit('skipNoteRender', store.s.skipNoteRender);
|
||||
prefer.commit('showSoftWordMutedWord', store.s.showSoftWordMutedWord);
|
||||
prefer.commit('confirmOnReact', store.s.confirmOnReact);
|
||||
prefer.commit('sound.masterVolume', store.s.sound_masterVolume);
|
||||
prefer.commit('sound.notUseSound', store.s.sound_notUseSound);
|
||||
prefer.commit('sound.useSoundOnlyWhenActive', store.s.sound_useSoundOnlyWhenActive);
|
||||
prefer.commit('sound.on.note', store.s.sound_note as any);
|
||||
prefer.commit('sound.on.noteMy', store.s.sound_noteMy as any);
|
||||
prefer.commit('sound.on.notification', store.s.sound_notification as any);
|
||||
prefer.commit('sound.on.reaction', store.s.sound_reaction as any);
|
||||
store.commit('deck.profile', deckStore.s.profile);
|
||||
store.commit('deck.columns', deckStore.s.columns);
|
||||
store.commit('deck.layout', deckStore.s.layout);
|
||||
store.commit('menu', []);
|
||||
}
|
||||
|
||||
if (store.s.accountSetupWizard !== -1) {
|
||||
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkUserSetupDialog.vue')), {}, {
|
||||
closed: () => dispose(),
|
||||
});
|
||||
@@ -154,7 +244,7 @@ export async function mainBoot() {
|
||||
});
|
||||
}
|
||||
|
||||
function onAnnouncementCreated (ev: { announcement: Misskey.entities.Announcement }) {
|
||||
function onAnnouncementCreated(ev: { announcement: Misskey.entities.Announcement }) {
|
||||
const announcement = ev.announcement;
|
||||
if (announcement.display === 'dialog') {
|
||||
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), {
|
||||
@@ -412,7 +502,7 @@ export async function mainBoot() {
|
||||
post();
|
||||
},
|
||||
'd': () => {
|
||||
defaultStore.set('darkMode', !defaultStore.state.darkMode);
|
||||
store.commit('darkMode', !store.s.darkMode);
|
||||
},
|
||||
's': () => {
|
||||
mainRouter.push('/search');
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
import { createApp, defineAsyncComponent } from 'vue';
|
||||
import { common } from './common.js';
|
||||
import { emojiPicker } from '@/scripts/emoji-picker.js';
|
||||
import { emojiPicker } from '@/utility/emoji-picker.js';
|
||||
|
||||
export async function subBoot() {
|
||||
const { isClientUpdated } = await common(() => createApp(
|
||||
|
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { Cache } from '@/scripts/cache.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { Cache } from '@/utility/cache.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
||||
export const clipsCache = new Cache<Misskey.entities.Clip[]>(1000 * 60 * 30, () => misskeyApi('clips/list'));
|
||||
export const rolesCache = new Cache(1000 * 60 * 30, () => misskeyApi('admin/roles/list'));
|
||||
|
@@ -90,7 +90,7 @@ import MkFolder from '@/components/MkFolder.vue';
|
||||
import RouterView from '@/components/global/RouterView.vue';
|
||||
import { useRouterFactory } from '@/router/supplier';
|
||||
import MkTextarea from '@/components/MkTextarea.vue';
|
||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
|
||||
const props = defineProps<{
|
||||
report: Misskey.entities.AdminAbuseUserReportsResponse[number];
|
||||
|
@@ -17,7 +17,7 @@ import * as Misskey from 'misskey-js';
|
||||
import MkMention from './MkMention.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { host as localHost } from '@@/js/config.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
||||
const user = ref<Misskey.entities.UserLite>();
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import { HttpResponse, http } from 'msw';
|
||||
import { userDetailed } from '../../.storybook/fakes.js';
|
||||
import { commonHandlers } from '../../.storybook/mocks.js';
|
||||
import MkAchievements from './MkAchievements.vue';
|
||||
import { ACHIEVEMENT_TYPES } from '@/scripts/achievements.js';
|
||||
import { ACHIEVEMENT_TYPES } from '@/utility/achievements.js';
|
||||
export const Empty = {
|
||||
render(args) {
|
||||
return {
|
||||
|
@@ -55,9 +55,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { onMounted, ref, computed } from 'vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { ACHIEVEMENT_TYPES, ACHIEVEMENT_BADGES, claimAchievement } from '@/scripts/achievements.js';
|
||||
import { ACHIEVEMENT_TYPES, ACHIEVEMENT_BADGES, claimAchievement } from '@/utility/achievements.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
user: Misskey.entities.User;
|
||||
|
@@ -82,7 +82,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { computed, onMounted, onBeforeUnmount, ref } from 'vue';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { globalEvents } from '@/events.js';
|
||||
import { defaultIdlingRenderScheduler } from '@/scripts/idle-render.js';
|
||||
import { defaultIdlingRenderScheduler } from '@/utility/idle-render.js';
|
||||
|
||||
// https://stackoverflow.com/questions/1878907/how-can-i-find-the-difference-between-two-angles
|
||||
const angleDiff = (a: number, b: number) => {
|
||||
|
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { onMounted, shallowRef } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import MkModal from '@/components/MkModal.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
@@ -59,10 +59,10 @@ import MkTextarea from '@/components/MkTextarea.vue';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { deepMerge } from '@/scripts/merge.js';
|
||||
import type { DeepPartial } from '@/scripts/merge.js';
|
||||
import { deepMerge } from '@/utility/merge.js';
|
||||
import type { DeepPartial } from '@/utility/merge.js';
|
||||
|
||||
type PartialAllowedAntenna = Omit<Misskey.entities.Antenna, 'id' | 'createdAt' | 'updatedAt'> & {
|
||||
id?: string;
|
||||
|
@@ -71,7 +71,7 @@ import MkInput from '@/components/MkInput.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import MkTextarea from '@/components/MkTextarea.vue';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
import type { AsUiComponent, AsUiRoot, AsUiPostFormButton } from '@/scripts/aiscript/ui.js';
|
||||
import type { AsUiComponent, AsUiRoot, AsUiPostFormButton } from '@/aiscript/ui.js';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkPostForm from '@/components/MkPostForm.vue';
|
||||
|
||||
|
@@ -123,8 +123,8 @@ import MkButton from '@/components/MkButton.vue';
|
||||
import { $i, getAccounts, getAccountWithSigninDialog, getAccountWithSignupDialog } from '@/account.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { getProxiedImageUrl } from '@/utility/media-proxy.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
||||
const props = defineProps<{
|
||||
name?: string;
|
||||
|
@@ -12,7 +12,7 @@ import { userDetailed } from '../../.storybook/fakes.js';
|
||||
import { commonHandlers } from '../../.storybook/mocks.js';
|
||||
import MkAutocomplete from './MkAutocomplete.vue';
|
||||
import MkInput from './MkInput.vue';
|
||||
import { tick } from '@/scripts/test-utils.js';
|
||||
import { tick } from '@/utility/test-utils.js';
|
||||
const common = {
|
||||
render(args) {
|
||||
return {
|
||||
|
@@ -49,22 +49,23 @@ import sanitizeHtml from 'sanitize-html';
|
||||
import { emojilist, getEmojiName } from '@@/js/emojilist.js';
|
||||
import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@@/js/emoji-base.js';
|
||||
import { MFM_TAGS, MFM_PARAMS } from '@@/js/const.js';
|
||||
import type { EmojiDef } from '@/scripts/search-emoji.js';
|
||||
import contains from '@/scripts/contains.js';
|
||||
import type { EmojiDef } from '@/utility/search-emoji.js';
|
||||
import contains from '@/utility/contains.js';
|
||||
import { acct } from '@/filters/user.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { store } from '@/store.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { customEmojis } from '@/custom-emojis.js';
|
||||
import { searchEmoji } from '@/scripts/search-emoji.js';
|
||||
import { searchEmoji } from '@/utility/search-emoji.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const lib = emojilist.filter(x => x.category !== 'flags');
|
||||
|
||||
const emojiDb = computed(() => {
|
||||
//#region Unicode Emoji
|
||||
const char2path = defaultStore.reactiveState.emojiStyle.value === 'twemoji' ? char2twemojiFilePath : char2fluentEmojiFilePath;
|
||||
const char2path = prefer.r.emojiStyle.value === 'twemoji' ? char2twemojiFilePath : char2fluentEmojiFilePath;
|
||||
|
||||
const unicodeEmojiDB: EmojiDef[] = lib.map(x => ({
|
||||
emoji: x.char,
|
||||
@@ -72,7 +73,7 @@ const emojiDb = computed(() => {
|
||||
url: char2path(x.char),
|
||||
}));
|
||||
|
||||
for (const index of Object.values(defaultStore.state.additionalUnicodeEmojiIndexes)) {
|
||||
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
|
||||
for (const [emoji, keywords] of Object.entries(index)) {
|
||||
for (const k of keywords) {
|
||||
unicodeEmojiDB.push({
|
||||
@@ -154,10 +155,10 @@ function complete(type: string, value: any) {
|
||||
emit('done', { type, value });
|
||||
emit('closed');
|
||||
if (type === 'emoji') {
|
||||
let recents = defaultStore.state.recentlyUsedEmojis;
|
||||
let recents = store.s.recentlyUsedEmojis;
|
||||
recents = recents.filter((emoji: any) => emoji !== value);
|
||||
recents.unshift(value);
|
||||
defaultStore.set('recentlyUsedEmojis', recents.splice(0, 32));
|
||||
store.commit('recentlyUsedEmojis', recents.splice(0, 32));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +238,7 @@ function exec() {
|
||||
} else if (props.type === 'emoji') {
|
||||
if (!props.q || props.q === '') {
|
||||
// 最近使った絵文字をサジェスト
|
||||
emojis.value = defaultStore.state.recentlyUsedEmojis.map(emoji => emojiDb.value.find(dbEmoji => dbEmoji.emoji === emoji)).filter(x => x) as EmojiDef[];
|
||||
emojis.value = store.s.recentlyUsedEmojis.map(emoji => emojiDb.value.find(dbEmoji => dbEmoji.emoji === emoji)).filter(x => x) as EmojiDef[];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
userIds: string[];
|
||||
|
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, shallowRef, computed, onMounted, onBeforeUnmount, watch, onUnmounted } from 'vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { store } from '@/store.js';
|
||||
|
||||
// APIs provided by Captcha services
|
||||
// see: https://docs.hcaptcha.com/configuration/#javascript-api
|
||||
@@ -154,7 +154,7 @@ async function requestRender() {
|
||||
|
||||
captchaWidgetId.value = captcha.value.render(elem, {
|
||||
sitekey: props.sitekey,
|
||||
theme: defaultStore.state.darkMode ? 'dark' : 'light',
|
||||
theme: store.s.darkMode ? 'dark' : 'light',
|
||||
callback: callback,
|
||||
'expired-callback': () => callback(undefined),
|
||||
'error-callback': () => callback(undefined),
|
||||
|
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
|
@@ -53,15 +53,15 @@ export type ChartSrc =
|
||||
import { onMounted, ref, shallowRef, watch } from 'vue';
|
||||
import { Chart } from 'chart.js';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { misskeyApiGet } from '@/scripts/misskey-api.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { useChartTooltip } from '@/scripts/use-chart-tooltip.js';
|
||||
import { chartVLine } from '@/scripts/chart-vline.js';
|
||||
import { alpha } from '@/scripts/color.js';
|
||||
import { misskeyApiGet } from '@/utility/misskey-api.js';
|
||||
import { store } from '@/store.js';
|
||||
import { useChartTooltip } from '@/utility/use-chart-tooltip.js';
|
||||
import { chartVLine } from '@/utility/chart-vline.js';
|
||||
import { alpha } from '@/utility/color.js';
|
||||
import date from '@/filters/date.js';
|
||||
import bytes from '@/filters/bytes.js';
|
||||
import { initChart } from '@/scripts/init-chart.js';
|
||||
import { chartLegend } from '@/scripts/chart-legend.js';
|
||||
import { initChart } from '@/utility/init-chart.js';
|
||||
import { chartLegend } from '@/utility/chart-legend.js';
|
||||
import MkChartLegend from '@/components/MkChartLegend.vue';
|
||||
|
||||
initChart();
|
||||
@@ -161,7 +161,7 @@ const render = () => {
|
||||
chartInstance.destroy();
|
||||
}
|
||||
|
||||
const vLineColor = defaultStore.state.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 maxes = chartData.series.map((x, i) => Math.max(...x.data.map(d => d.y)));
|
||||
|
||||
|
@@ -23,9 +23,9 @@ import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import MkPlusOneEffect from '@/components/MkPlusOneEffect.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { useInterval } from '@@/js/use-interval.js';
|
||||
import * as game from '@/scripts/clicker-game.js';
|
||||
import * as game from '@/utility/clicker-game.js';
|
||||
import number from '@/filters/number.js';
|
||||
import { claimAchievement } from '@/scripts/achievements.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
|
||||
const saveData = game.saveData;
|
||||
const cookies = computed(() => saveData.value?.cookies);
|
||||
|
@@ -12,8 +12,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { bundledLanguagesInfo } from 'shiki/langs';
|
||||
import type { BundledLanguage } from 'shiki/langs';
|
||||
import { getHighlighter, getTheme } from '@/scripts/code-highlighter.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { getHighlighter, getTheme } from '@/utility/code-highlighter.js';
|
||||
import { store } from '@/store.js';
|
||||
|
||||
const props = defineProps<{
|
||||
code: string;
|
||||
@@ -22,7 +22,7 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const highlighter = await getHighlighter();
|
||||
const darkMode = defaultStore.reactiveState.darkMode;
|
||||
const darkMode = store.r.darkMode;
|
||||
const codeLang = ref<BundledLanguage | 'aiscript'>('js');
|
||||
|
||||
const [lightThemeName, darkThemeName] = await Promise.all([
|
||||
@@ -74,10 +74,8 @@ watch(() => props.lang, (to) => {
|
||||
<style module lang="scss">
|
||||
.codeBlockRoot :global(.shiki) {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--MI_THEME-divider);
|
||||
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
||||
|
||||
color: var(--shiki-fallback);
|
||||
|
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</button>
|
||||
<Suspense>
|
||||
<template #fallback>
|
||||
<MkLoading />
|
||||
<MkLoading/>
|
||||
</template>
|
||||
<XCode v-if="show && lang" :code="code" :lang="lang"/>
|
||||
<pre v-else-if="show" :class="$style.codeBlockFallbackRoot"><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
|
||||
@@ -28,9 +28,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { defineAsyncComponent, ref } from 'vue';
|
||||
import * as os from '@/os.js';
|
||||
import MkLoading from '@/components/global/MkLoading.vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
code: string;
|
||||
@@ -42,7 +42,7 @@ const props = withDefaults(defineProps<{
|
||||
forceShow: false,
|
||||
});
|
||||
|
||||
const show = ref(props.forceShow === true ? true : !defaultStore.state.dataSaver.code);
|
||||
const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code);
|
||||
|
||||
const XCode = defineAsyncComponent(() => import('@/components/MkCode.core.vue'));
|
||||
|
||||
|
@@ -19,10 +19,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</header>
|
||||
<Transition
|
||||
:enterActiveClass="defaultStore.state.animation ? $style.transition_toggle_enterActive : ''"
|
||||
:leaveActiveClass="defaultStore.state.animation ? $style.transition_toggle_leaveActive : ''"
|
||||
:enterFromClass="defaultStore.state.animation ? $style.transition_toggle_enterFrom : ''"
|
||||
:leaveToClass="defaultStore.state.animation ? $style.transition_toggle_leaveTo : ''"
|
||||
:enterActiveClass="prefer.s.animation ? $style.transition_toggle_enterActive : ''"
|
||||
:leaveActiveClass="prefer.s.animation ? $style.transition_toggle_leaveActive : ''"
|
||||
:enterFromClass="prefer.s.animation ? $style.transition_toggle_enterFrom : ''"
|
||||
:leaveToClass="prefer.s.animation ? $style.transition_toggle_leaveTo : ''"
|
||||
@enter="enter"
|
||||
@afterEnter="afterEnter"
|
||||
@leave="leave"
|
||||
@@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, shallowRef, watch } from 'vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
|
@@ -6,10 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template>
|
||||
<Transition
|
||||
appear
|
||||
:enterActiveClass="defaultStore.state.animation ? $style.transition_fade_enterActive : ''"
|
||||
:leaveActiveClass="defaultStore.state.animation ? $style.transition_fade_leaveActive : ''"
|
||||
:enterFromClass="defaultStore.state.animation ? $style.transition_fade_enterFrom : ''"
|
||||
:leaveToClass="defaultStore.state.animation ? $style.transition_fade_leaveTo : ''"
|
||||
:enterActiveClass="prefer.s.animation ? $style.transition_fade_enterActive : ''"
|
||||
:leaveActiveClass="prefer.s.animation ? $style.transition_fade_leaveActive : ''"
|
||||
:enterFromClass="prefer.s.animation ? $style.transition_fade_enterFrom : ''"
|
||||
:leaveToClass="prefer.s.animation ? $style.transition_fade_leaveTo : ''"
|
||||
>
|
||||
<div ref="rootEl" :class="$style.root" :style="{ zIndex }" @contextmenu.prevent.stop="() => {}">
|
||||
<MkMenu :items="items" :align="'left'" @close="emit('closed')"/>
|
||||
@@ -21,8 +21,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { onMounted, onBeforeUnmount, shallowRef, ref } from 'vue';
|
||||
import MkMenu from './MkMenu.vue';
|
||||
import type { MenuItem } from '@/types/menu.js';
|
||||
import contains from '@/scripts/contains.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import contains from '@/utility/contains.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import * as os from '@/os.js';
|
||||
|
||||
const props = defineProps<{
|
||||
|
@@ -35,13 +35,13 @@ import { onMounted, shallowRef, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import Cropper from 'cropperjs';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { apiUrl } from '@@/js/config.js';
|
||||
import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { apiUrl } from '@@/js/config.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';
|
||||
import { getProxiedImageUrl } from '@/utility/media-proxy.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'ok', cropped: Misskey.entities.DriveFile): void;
|
||||
@@ -81,8 +81,8 @@ const ok = async () => {
|
||||
formData.append('i', $i!.token);
|
||||
if (props.uploadFolder) {
|
||||
formData.append('folderId', props.uploadFolder);
|
||||
} else if (props.uploadFolder !== null && defaultStore.state.uploadFolder) {
|
||||
formData.append('folderId', defaultStore.state.uploadFolder);
|
||||
} else if (props.uploadFolder !== null && prefer.s.uploadFolder) {
|
||||
formData.append('folderId', prefer.s.uploadFolder);
|
||||
}
|
||||
|
||||
window.fetch(apiUrl + '/drive/files/create', {
|
||||
|
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { computed } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import type { PollEditorModelValue } from '@/components/MkPollEditor.vue';
|
||||
import { concat } from '@/scripts/array.js';
|
||||
import { concat } from '@/utility/array.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
|
||||
|
@@ -6,13 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<script lang="ts">
|
||||
import { defineComponent, h, TransitionGroup, useCssModule } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import type { MisskeyEntity } from '@/types/date-separated-list.js';
|
||||
import MkAd from '@/components/global/MkAd.vue';
|
||||
import { isDebuggerEnabled, stackTraceInstances } from '@/debug.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
import { instance } from '@/instance.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import type { MisskeyEntity } from '@/types/date-separated-list.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -150,7 +150,7 @@ export default defineComponent({
|
||||
[$style['direction-up']]: props.direction === 'up',
|
||||
};
|
||||
|
||||
return () => defaultStore.state.animation ? h(TransitionGroup, {
|
||||
return () => prefer.s.animation ? h(TransitionGroup, {
|
||||
class: classes,
|
||||
name: 'list',
|
||||
tag: 'div',
|
||||
|
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { defaultIdlingRenderScheduler } from '@/scripts/idle-render.js';
|
||||
import { defaultIdlingRenderScheduler } from '@/utility/idle-render.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
showS?: boolean;
|
||||
|
@@ -24,7 +24,8 @@ defineProps<{
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.7;
|
||||
opacity: 0.3;
|
||||
filter: saturate(0.5);
|
||||
}
|
||||
|
||||
.cover {
|
||||
@@ -34,7 +35,7 @@ defineProps<{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: not-allowed;
|
||||
--color: color(from var(--MI_THEME-error) srgb r g b / 0.25);
|
||||
--color: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05));
|
||||
background-size: auto auto;
|
||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 10px, var(--color) 4px, var(--color) 14px);
|
||||
}
|
@@ -45,8 +45,8 @@ import bytes from '@/filters/bytes.js';
|
||||
import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { getDriveFileMenu } from '@/scripts/get-drive-file-menu.js';
|
||||
import { deviceKind } from '@/scripts/device-kind.js';
|
||||
import { getDriveFileMenu } from '@/utility/get-drive-file-menu.js';
|
||||
import { deviceKind } from '@/utility/device-kind.js';
|
||||
import { useRouter } from '@/router/supplier.js';
|
||||
|
||||
const router = useRouter();
|
||||
|
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template v-if="!hover"><i :class="$style.icon" class="ti ti-folder ti-fw"></i></template>
|
||||
{{ folder.name }}
|
||||
</p>
|
||||
<p v-if="defaultStore.state.uploadFolder == folder.id" :class="$style.upload">
|
||||
<p v-if="prefer.s.uploadFolder == folder.id" :class="$style.upload">
|
||||
{{ i18n.ts.uploadFolder }}
|
||||
</p>
|
||||
<button v-if="selectMode" class="_button" :class="$style.checkboxWrapper" @click.prevent.stop="checkboxClicked">
|
||||
@@ -38,11 +38,11 @@ import { computed, defineAsyncComponent, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import type { MenuItem } from '@/types/menu.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { claimAchievement } from '@/scripts/achievements.js';
|
||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
folder: Misskey.entities.DriveFolder;
|
||||
@@ -244,8 +244,8 @@ function deleteFolder() {
|
||||
misskeyApi('drive/folders/delete', {
|
||||
folderId: props.folder.id,
|
||||
}).then(() => {
|
||||
if (defaultStore.state.uploadFolder === props.folder.id) {
|
||||
defaultStore.set('uploadFolder', null);
|
||||
if (prefer.s.uploadFolder === props.folder.id) {
|
||||
prefer.commit('uploadFolder', null);
|
||||
}
|
||||
}).catch(err => {
|
||||
switch (err.id) {
|
||||
@@ -266,7 +266,7 @@ function deleteFolder() {
|
||||
}
|
||||
|
||||
function setAsUploadFolder() {
|
||||
defaultStore.set('uploadFolder', props.folder.id);
|
||||
prefer.commit('uploadFolder', props.folder.id);
|
||||
}
|
||||
|
||||
function onContextmenu(ev: MouseEvent) {
|
||||
@@ -295,7 +295,7 @@ function onContextmenu(ev: MouseEvent) {
|
||||
danger: true,
|
||||
action: deleteFolder,
|
||||
}];
|
||||
if (defaultStore.state.devMode) {
|
||||
if (prefer.s.devMode) {
|
||||
menu = menu.concat([{ type: 'divider' }, {
|
||||
icon: 'ti ti-id',
|
||||
text: i18n.ts.copyFolderId,
|
||||
|
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
const props = defineProps<{
|
||||
|
@@ -104,12 +104,12 @@ import XNavFolder from '@/components/MkDrive.navFolder.vue';
|
||||
import XFolder from '@/components/MkDrive.folder.vue';
|
||||
import XFile from '@/components/MkDrive.file.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { useStream } from '@/stream.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { uploadFile, uploads } from '@/scripts/upload.js';
|
||||
import { claimAchievement } from '@/scripts/achievements.js';
|
||||
import { uploadFile, uploads } from '@/utility/upload.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
initialFolder?: Misskey.entities.DriveFolder;
|
||||
@@ -142,7 +142,7 @@ const selectedFiles = ref<Misskey.entities.DriveFile[]>([]);
|
||||
const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]);
|
||||
const uploadings = uploads;
|
||||
const connection = useStream().useChannel('drive');
|
||||
const keepOriginal = ref<boolean>(defaultStore.state.keepOriginalUploading); // 外部渡しが多いので$refは使わないほうがよい
|
||||
const keepOriginal = ref<boolean>(prefer.s.keepOriginalUploading); // 外部渡しが多いので$refは使わないほうがよい
|
||||
|
||||
// ドロップされようとしているか
|
||||
const draghover = ref(false);
|
||||
@@ -716,7 +716,7 @@ function onContextmenu(ev: MouseEvent) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (defaultStore.state.enableInfiniteScroll && loadMoreFiles.value) {
|
||||
if (prefer.s.enableInfiniteScroll && loadMoreFiles.value) {
|
||||
nextTick(() => {
|
||||
ilFilesObserver.observe(loadMoreFiles.value?.$el);
|
||||
});
|
||||
@@ -737,7 +737,7 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
if (defaultStore.state.enableInfiniteScroll) {
|
||||
if (prefer.s.enableInfiniteScroll) {
|
||||
nextTick(() => {
|
||||
ilFilesObserver.observe(loadMoreFiles.value?.$el);
|
||||
});
|
||||
|
@@ -105,8 +105,8 @@ import MkInfo from '@/components/MkInfo.vue';
|
||||
|
||||
import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||
import { normalizeEmbedParams, getEmbedCode } from '@/scripts/get-embed-code.js';
|
||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
import { normalizeEmbedParams, getEmbedCode } from '@/utility/get-embed-code.js';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'ok'): void;
|
||||
|
@@ -131,17 +131,18 @@ import type {
|
||||
import XSection from '@/components/MkEmojiPicker.section.vue';
|
||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { isTouchUsing } from '@/scripts/touch.js';
|
||||
import { deviceKind } from '@/scripts/device-kind.js';
|
||||
import { isTouchUsing } from '@/utility/touch.js';
|
||||
import { deviceKind } from '@/utility/device-kind.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { store } from '@/store.js';
|
||||
import { customEmojiCategories, customEmojis, customEmojisMap } from '@/custom-emojis.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js';
|
||||
import { checkReactionPermissions } from '@/utility/check-reaction-permissions.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
showPinned?: boolean;
|
||||
pinnedEmojis?: string[];
|
||||
pinnedEmojis?: string[];
|
||||
maxHeight?: number;
|
||||
asDrawer?: boolean;
|
||||
asWindow?: boolean;
|
||||
@@ -163,8 +164,9 @@ const {
|
||||
emojiPickerScale,
|
||||
emojiPickerWidth,
|
||||
emojiPickerHeight,
|
||||
recentlyUsedEmojis,
|
||||
} = defaultStore.reactiveState;
|
||||
} = prefer.r;
|
||||
|
||||
const recentlyUsedEmojis = store.r.recentlyUsedEmojis;
|
||||
|
||||
const recentlyUsedEmojisDef = computed(() => {
|
||||
return recentlyUsedEmojis.value.map(getDef);
|
||||
@@ -317,7 +319,7 @@ watch(q, () => {
|
||||
}
|
||||
if (matches.size >= max) return matches;
|
||||
|
||||
for (const index of Object.values(defaultStore.state.additionalUnicodeEmojiIndexes)) {
|
||||
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
|
||||
for (const emoji of emojis) {
|
||||
if (keywords.every(keyword => index[emoji.char].some(k => k.includes(keyword)))) {
|
||||
matches.add(emoji);
|
||||
@@ -334,7 +336,7 @@ watch(q, () => {
|
||||
}
|
||||
if (matches.size >= max) return matches;
|
||||
|
||||
for (const index of Object.values(defaultStore.state.additionalUnicodeEmojiIndexes)) {
|
||||
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
|
||||
for (const emoji of emojis) {
|
||||
if (index[emoji.char].some(k => k.startsWith(newQ))) {
|
||||
matches.add(emoji);
|
||||
@@ -351,7 +353,7 @@ watch(q, () => {
|
||||
}
|
||||
if (matches.size >= max) return matches;
|
||||
|
||||
for (const index of Object.values(defaultStore.state.additionalUnicodeEmojiIndexes)) {
|
||||
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
|
||||
for (const emoji of emojis) {
|
||||
if (index[emoji.char].some(k => k.includes(newQ))) {
|
||||
matches.add(emoji);
|
||||
@@ -413,7 +415,7 @@ function computeButtonTitle(ev: MouseEvent): void {
|
||||
|
||||
function chosen(emoji: string | Misskey.entities.EmojiSimple | UnicodeEmojiDef, ev?: MouseEvent) {
|
||||
const el = ev && (ev.currentTarget ?? ev.target) as HTMLElement | null | undefined;
|
||||
if (el && defaultStore.state.animation) {
|
||||
if (el && prefer.s.animation) {
|
||||
const rect = el.getBoundingClientRect();
|
||||
const x = rect.left + (el.offsetWidth / 2);
|
||||
const y = rect.top + (el.offsetHeight / 2);
|
||||
@@ -427,10 +429,10 @@ function chosen(emoji: string | Misskey.entities.EmojiSimple | UnicodeEmojiDef,
|
||||
|
||||
// 最近使った絵文字更新
|
||||
if (!pinned.value?.includes(key)) {
|
||||
let recents = defaultStore.state.recentlyUsedEmojis;
|
||||
let recents = store.s.recentlyUsedEmojis;
|
||||
recents = recents.filter((emoji) => emoji !== key);
|
||||
recents.unshift(key);
|
||||
defaultStore.set('recentlyUsedEmojis', recents.splice(0, 32));
|
||||
store.commit('recentlyUsedEmojis', recents.splice(0, 32));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
ref="modal"
|
||||
v-slot="{ type, maxHeight }"
|
||||
:zPriority="'middle'"
|
||||
:preferType="defaultStore.state.emojiPickerStyle"
|
||||
:preferType="prefer.s.emojiPickerStyle"
|
||||
:hasInteractionWithOtherFocusTrappedEls="true"
|
||||
:transparentBg="true"
|
||||
:manualShowing="manualShowing"
|
||||
@@ -40,16 +40,16 @@ import * as Misskey from 'misskey-js';
|
||||
import { shallowRef } from 'vue';
|
||||
import MkModal from '@/components/MkModal.vue';
|
||||
import MkEmojiPicker from '@/components/MkEmojiPicker.vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
manualShowing?: boolean | null;
|
||||
src?: HTMLElement;
|
||||
showPinned?: boolean;
|
||||
pinnedEmojis?: string[],
|
||||
pinnedEmojis?: string[],
|
||||
asReactionPicker?: boolean;
|
||||
targetNote?: Misskey.entities.Note;
|
||||
choseAndClose?: boolean;
|
||||
choseAndClose?: boolean;
|
||||
}>(), {
|
||||
manualShowing: null,
|
||||
showPinned: true,
|
||||
|
@@ -14,10 +14,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</button>
|
||||
</header>
|
||||
<Transition
|
||||
:enterActiveClass="defaultStore.state.animation ? $style.folderToggleEnterActive : ''"
|
||||
:leaveActiveClass="defaultStore.state.animation ? $style.folderToggleLeaveActive : ''"
|
||||
:enterFromClass="defaultStore.state.animation ? $style.folderToggleEnterFrom : ''"
|
||||
:leaveToClass="defaultStore.state.animation ? $style.folderToggleLeaveTo : ''"
|
||||
:enterActiveClass="prefer.s.animation ? $style.folderToggleEnterActive : ''"
|
||||
:leaveActiveClass="prefer.s.animation ? $style.folderToggleLeaveActive : ''"
|
||||
:enterFromClass="prefer.s.animation ? $style.folderToggleEnterFrom : ''"
|
||||
:leaveToClass="prefer.s.animation ? $style.folderToggleLeaveTo : ''"
|
||||
@enter="enter"
|
||||
@afterEnter="afterEnter"
|
||||
@leave="leave"
|
||||
@@ -33,8 +33,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, shallowRef, watch } from 'vue';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { getBgColor } from '@/utility/get-bg-color.js';
|
||||
|
||||
const miLocalStoragePrefix = 'ui:folder:' as const;
|
||||
|
||||
|
@@ -27,10 +27,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<div v-if="openedAtLeastOnce" :class="[$style.body, { [$style.bgSame]: bgSame }]" :style="{ maxHeight: maxHeight ? `${maxHeight}px` : undefined, overflow: maxHeight ? `auto` : undefined }" :aria-hidden="!opened">
|
||||
<Transition
|
||||
:enterActiveClass="defaultStore.state.animation ? $style.transition_toggle_enterActive : ''"
|
||||
:leaveActiveClass="defaultStore.state.animation ? $style.transition_toggle_leaveActive : ''"
|
||||
:enterFromClass="defaultStore.state.animation ? $style.transition_toggle_enterFrom : ''"
|
||||
:leaveToClass="defaultStore.state.animation ? $style.transition_toggle_leaveTo : ''"
|
||||
:enterActiveClass="prefer.s.animation ? $style.transition_toggle_enterActive : ''"
|
||||
:leaveActiveClass="prefer.s.animation ? $style.transition_toggle_leaveActive : ''"
|
||||
:enterFromClass="prefer.s.animation ? $style.transition_toggle_enterFrom : ''"
|
||||
:leaveToClass="prefer.s.animation ? $style.transition_toggle_leaveTo : ''"
|
||||
@enter="enter"
|
||||
@afterEnter="afterEnter"
|
||||
@leave="leave"
|
||||
@@ -57,8 +57,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, ref, shallowRef } from 'vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { getBgColor } from '@/utility/get-bg-color.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
defaultOpen?: boolean;
|
||||
|
@@ -39,13 +39,14 @@ import { onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { host } from '@@/js/config.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { useStream } from '@/stream.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { claimAchievement } from '@/scripts/achievements.js';
|
||||
import { pleaseLogin } from '@/scripts/please-login.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
import { pleaseLogin } from '@/utility/please-login.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { store } from '@/store.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
user: Misskey.entities.UserDetailed,
|
||||
@@ -100,7 +101,7 @@ async function onClick() {
|
||||
userId: props.user.id,
|
||||
});
|
||||
} else {
|
||||
if (defaultStore.state.alwaysConfirmFollow) {
|
||||
if (prefer.s.alwaysConfirmFollow) {
|
||||
const { canceled } = await os.confirm({
|
||||
type: 'question',
|
||||
text: i18n.tsx.followConfirm({ name: props.user.name || props.user.username }),
|
||||
@@ -120,11 +121,11 @@ async function onClick() {
|
||||
} else {
|
||||
await misskeyApi('following/create', {
|
||||
userId: props.user.id,
|
||||
withReplies: defaultStore.state.defaultWithReplies,
|
||||
withReplies: store.s.defaultWithReplies,
|
||||
});
|
||||
emit('update:user', {
|
||||
...props.user,
|
||||
withReplies: defaultStore.state.defaultWithReplies,
|
||||
withReplies: store.s.defaultWithReplies,
|
||||
});
|
||||
hasPendingFollowRequestFromYou.value = true;
|
||||
|
||||
|
@@ -15,8 +15,8 @@ import * as Misskey from 'misskey-js';
|
||||
import { computed, ref } from 'vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { selectFile } from '@/scripts/select-file.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { selectFile } from '@/utility/select-file.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
||||
const props = defineProps<{
|
||||
fileId?: string | null;
|
||||
|
@@ -80,7 +80,7 @@ import MkRange from './MkRange.vue';
|
||||
import MkButton from './MkButton.vue';
|
||||
import MkRadios from './MkRadios.vue';
|
||||
import XFile from './MkFormDialog.file.vue';
|
||||
import type { Form } from '@/scripts/form.js';
|
||||
import type { Form } from '@/utility/form.js';
|
||||
import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { infoImageUrl } from '@/instance.js';
|
||||
|
@@ -35,14 +35,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { computed, ref } from 'vue';
|
||||
import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = defineProps<{
|
||||
post: Misskey.entities.GalleryPost;
|
||||
}>();
|
||||
|
||||
const hover = ref(false);
|
||||
const safe = computed(() => defaultStore.state.nsfw === 'ignore' || defaultStore.state.nsfw === 'respect' && !props.post.isSensitive);
|
||||
const safe = computed(() => prefer.s.nsfw === 'ignore' || prefer.s.nsfw === 'respect' && !props.post.isSensitive);
|
||||
const show = computed(() => safe.value || hover.value);
|
||||
|
||||
function enterHover(): void {
|
||||
|
@@ -16,11 +16,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { onMounted, nextTick, watch, shallowRef, ref } from 'vue';
|
||||
import { Chart } from 'chart.js';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { useChartTooltip } from '@/scripts/use-chart-tooltip.js';
|
||||
import { alpha } from '@/scripts/color.js';
|
||||
import { initChart } from '@/scripts/init-chart.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { store } from '@/store.js';
|
||||
import { useChartTooltip } from '@/utility/use-chart-tooltip.js';
|
||||
import { alpha } from '@/utility/color.js';
|
||||
import { initChart } from '@/utility/init-chart.js';
|
||||
|
||||
initChart();
|
||||
|
||||
@@ -106,7 +106,7 @@ async function renderChart() {
|
||||
|
||||
await nextTick();
|
||||
|
||||
const color = defaultStore.state.darkMode ? '#b4e900' : '#86b300';
|
||||
const color = store.s.darkMode ? '#b4e900' : '#86b300';
|
||||
|
||||
// 視覚上の分かりやすさのため上から最も大きい3つの値の平均を最大値とする
|
||||
const max = values.slice().sort((a, b) => b - a).slice(0, 3).reduce((a, b) => a + b, 0) / 3;
|
||||
|
@@ -28,12 +28,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<script lang="ts" setup>
|
||||
import { ref, shallowRef, computed, nextTick, watch } from 'vue';
|
||||
import type { Tab } from '@/components/global/MkPageHeader.tabs.vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { isHorizontalSwipeSwiping as isSwiping } from '@/scripts/touch.js';
|
||||
import { isHorizontalSwipeSwiping as isSwiping } from '@/utility/touch.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const rootEl = shallowRef<HTMLDivElement>();
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const tabModel = defineModel<string>('tab');
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -44,7 +43,7 @@ const emit = defineEmits<{
|
||||
(ev: 'swiped', newKey: string, direction: 'left' | 'right'): void;
|
||||
}>();
|
||||
|
||||
const shouldAnimate = computed(() => defaultStore.reactiveState.enableHorizontalSwipe.value || defaultStore.reactiveState.animation.value);
|
||||
const shouldAnimate = computed(() => prefer.r.enableHorizontalSwipe.value || prefer.r.animation.value);
|
||||
|
||||
// ▼ しきい値 ▼ //
|
||||
|
||||
@@ -72,7 +71,7 @@ const isSwipingForClass = ref(false);
|
||||
let swipeAborted = false;
|
||||
|
||||
function touchStart(event: TouchEvent) {
|
||||
if (!defaultStore.reactiveState.enableHorizontalSwipe.value) return;
|
||||
if (!prefer.r.enableHorizontalSwipe.value) return;
|
||||
|
||||
if (event.touches.length !== 1) return;
|
||||
|
||||
@@ -83,7 +82,7 @@ function touchStart(event: TouchEvent) {
|
||||
}
|
||||
|
||||
function touchMove(event: TouchEvent) {
|
||||
if (!defaultStore.reactiveState.enableHorizontalSwipe.value) return;
|
||||
if (!prefer.r.enableHorizontalSwipe.value) return;
|
||||
|
||||
if (event.touches.length !== 1) return;
|
||||
|
||||
@@ -134,7 +133,7 @@ function touchEnd(event: TouchEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defaultStore.reactiveState.enableHorizontalSwipe.value) return;
|
||||
if (!prefer.r.enableHorizontalSwipe.value) return;
|
||||
|
||||
if (event.touches.length !== 0) return;
|
||||
|
||||
|
@@ -6,13 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template>
|
||||
<div ref="root" :class="['chromatic-ignore', $style.root, { [$style.cover]: cover }]" :title="title ?? ''">
|
||||
<TransitionGroup
|
||||
:duration="defaultStore.state.animation && props.transition?.duration || undefined"
|
||||
:enterActiveClass="defaultStore.state.animation && props.transition?.enterActiveClass || undefined"
|
||||
:leaveActiveClass="defaultStore.state.animation && (props.transition?.leaveActiveClass ?? $style.transition_leaveActive) || undefined"
|
||||
:enterFromClass="defaultStore.state.animation && props.transition?.enterFromClass || undefined"
|
||||
:leaveToClass="defaultStore.state.animation && props.transition?.leaveToClass || undefined"
|
||||
:enterToClass="defaultStore.state.animation && props.transition?.enterToClass || undefined"
|
||||
:leaveFromClass="defaultStore.state.animation && props.transition?.leaveFromClass || undefined"
|
||||
:duration="prefer.s.animation && props.transition?.duration || undefined"
|
||||
:enterActiveClass="prefer.s.animation && props.transition?.enterActiveClass || undefined"
|
||||
:leaveActiveClass="prefer.s.animation && (props.transition?.leaveActiveClass ?? $style.transition_leaveActive) || undefined"
|
||||
:enterFromClass="prefer.s.animation && props.transition?.enterFromClass || undefined"
|
||||
:leaveToClass="prefer.s.animation && props.transition?.leaveToClass || undefined"
|
||||
:enterToClass="prefer.s.animation && props.transition?.enterToClass || undefined"
|
||||
:leaveFromClass="prefer.s.animation && props.transition?.leaveFromClass || undefined"
|
||||
>
|
||||
<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined" tabindex="-1"/>
|
||||
<img v-show="!hide" key="img" ref="img" :height="imgHeight ?? undefined" :width="imgWidth ?? undefined" :class="$style.img" :src="src ?? undefined" :title="title ?? undefined" :alt="alt ?? undefined" loading="eager" decoding="async" tabindex="-1"/>
|
||||
@@ -60,7 +60,7 @@ const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resol
|
||||
import { computed, nextTick, onMounted, onUnmounted, shallowRef, watch, ref } from 'vue';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { render } from 'buraha';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
transition?: {
|
||||
|
@@ -50,8 +50,8 @@ import { debounce } from 'throttle-debounce';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { useInterval } from '@@/js/use-interval.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { Autocomplete } from '@/scripts/autocomplete.js';
|
||||
import type { SuggestionType } from '@/scripts/autocomplete.js';
|
||||
import { Autocomplete } from '@/utility/autocomplete.js';
|
||||
import type { SuggestionType } from '@/utility/autocomplete.js';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string | number | null;
|
||||
|
@@ -18,8 +18,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import MkMiniChart from '@/components/MkMiniChart.vue';
|
||||
import { misskeyApiGet } from '@/scripts/misskey-api.js';
|
||||
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
|
||||
import { misskeyApiGet } from '@/utility/misskey-api.js';
|
||||
import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js';
|
||||
|
||||
const props = defineProps<{
|
||||
instance: Misskey.entities.FederationInstance;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user