Compare commits
1 Commits
renovate/b
...
renovate/r
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cd8c285992 |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -6,24 +6,9 @@
|
|||||||
|
|
||||||
### Client
|
### Client
|
||||||
- Feat: 設定の管理が強化されました
|
- Feat: 設定の管理が強化されました
|
||||||
- 内部処理が一新され、安定性とパフォーマンスが向上しました
|
- 自動でバックアップされるように
|
||||||
- 全てのクライアント設定がエクスポート(バックアップ)/インポート対象に含まれるようになりました
|
|
||||||
- プラグイン、テーマ、クライアントに追加されたすべてのアカウント情報も含まれるようになりました
|
|
||||||
- 自動で設定データをサーバーにバックアップできるように
|
|
||||||
- 設定→設定のプロファイル→自動バックアップ で有効にできます
|
|
||||||
- 新しいデバイスからログインしたり、ブラウザから設定データが消えてしまったときに自動で復元されます(復元をスキップすることも可能)
|
|
||||||
- 任意の設定項目をデバイス間で同期できるように
|
- 任意の設定項目をデバイス間で同期できるように
|
||||||
- 設定項目の「...」メニュー→「デバイス間で同期」
|
|
||||||
- 同期をオンにした際にサーバーに保存された値とローカルの値が競合する場合はどちらを優先するか選択できます
|
|
||||||
- 任意の設定項目を初期値にリセットできるように
|
|
||||||
- 設定項目の「...」メニュー→「初期値にリセット」
|
|
||||||
- アカウントごとに設定値が分離される設定とそうでないクライアント設定が混在していた(かつ分離するかどうかを設定不可だった)のを、基本的に一律でクライアント全体に適用されるようにし、個別でアカウントごとに異なる設定を行えるように
|
|
||||||
- 設定項目の「...」メニュー→「アカウントで上書き」をオンにすることで、設定値をそのアカウントでだけ適用するようにできます
|
|
||||||
- ログアウトすると設定データもブラウザから消去されるようになりプライバシーが向上しました
|
|
||||||
- 再度ログインすればサーバーのバックアップから設定データを復元可能です
|
|
||||||
- エクスポートした設定データを他のサーバーでインポートして適用すること(設定の持ち運び)が可能になりました
|
|
||||||
- Feat: 画面を重ねて表示するオプションを実装(実験的)
|
- Feat: 画面を重ねて表示するオプションを実装(実験的)
|
||||||
- 設定 → その他 → 実験的機能 → Enable stacking router view
|
|
||||||
- Enhance: プラグインの管理が強化されました
|
- Enhance: プラグインの管理が強化されました
|
||||||
- インストール/アンインストール/設定の変更時にリロード不要になりました
|
- インストール/アンインストール/設定の変更時にリロード不要になりました
|
||||||
- Enhance: ログアウト時、ブラウザに保存されたWebクライアントのデータを全て消去するように
|
- Enhance: ログアウト時、ブラウザに保存されたWebクライアントのデータを全て消去するように
|
||||||
|
18
package.json
18
package.json
@@ -6,7 +6,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/misskey-dev/misskey.git"
|
"url": "https://github.com/misskey-dev/misskey.git"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.6.1",
|
"packageManager": "pnpm@10.6.5",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/frontend-shared",
|
"packages/frontend-shared",
|
||||||
"packages/frontend",
|
"packages/frontend",
|
||||||
@@ -61,21 +61,21 @@
|
|||||||
"tar": "7.4.3",
|
"tar": "7.4.3",
|
||||||
"terser": "5.39.0",
|
"terser": "5.39.0",
|
||||||
"typescript": "5.8.2",
|
"typescript": "5.8.2",
|
||||||
"esbuild": "0.25.0",
|
"esbuild": "0.25.1",
|
||||||
"glob": "11.0.1"
|
"glob": "11.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@misskey-dev/eslint-plugin": "2.1.0",
|
"@misskey-dev/eslint-plugin": "2.1.0",
|
||||||
"@types/node": "22.13.10",
|
"@types/node": "22.13.11",
|
||||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||||
"@typescript-eslint/parser": "8.26.0",
|
"@typescript-eslint/parser": "8.27.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "14.1.0",
|
"cypress": "14.2.0",
|
||||||
"eslint": "9.22.0",
|
"eslint": "9.23.0",
|
||||||
"globals": "16.0.0",
|
"globals": "16.0.0",
|
||||||
"ncp": "2.0.0",
|
"ncp": "2.0.0",
|
||||||
"pnpm": "10.6.1",
|
"pnpm": "10.6.5",
|
||||||
"start-server-and-test": "2.0.10"
|
"start-server-and-test": "2.0.11"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@tensorflow/tfjs-core": "4.22.0"
|
"@tensorflow/tfjs-core": "4.22.0"
|
||||||
|
@@ -37,17 +37,17 @@
|
|||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@swc/core-android-arm64": "1.3.11",
|
"@swc/core-android-arm64": "1.3.11",
|
||||||
"@swc/core-darwin-arm64": "1.11.12",
|
"@swc/core-darwin-arm64": "1.11.11",
|
||||||
"@swc/core-darwin-x64": "1.11.12",
|
"@swc/core-darwin-x64": "1.11.11",
|
||||||
"@swc/core-freebsd-x64": "1.3.11",
|
"@swc/core-freebsd-x64": "1.3.11",
|
||||||
"@swc/core-linux-arm-gnueabihf": "1.11.12",
|
"@swc/core-linux-arm-gnueabihf": "1.11.11",
|
||||||
"@swc/core-linux-arm64-gnu": "1.11.12",
|
"@swc/core-linux-arm64-gnu": "1.11.11",
|
||||||
"@swc/core-linux-arm64-musl": "1.11.12",
|
"@swc/core-linux-arm64-musl": "1.11.11",
|
||||||
"@swc/core-linux-x64-gnu": "1.11.12",
|
"@swc/core-linux-x64-gnu": "1.11.11",
|
||||||
"@swc/core-linux-x64-musl": "1.11.12",
|
"@swc/core-linux-x64-musl": "1.11.11",
|
||||||
"@swc/core-win32-arm64-msvc": "1.11.12",
|
"@swc/core-win32-arm64-msvc": "1.11.11",
|
||||||
"@swc/core-win32-ia32-msvc": "1.11.12",
|
"@swc/core-win32-ia32-msvc": "1.11.11",
|
||||||
"@swc/core-win32-x64-msvc": "1.11.12",
|
"@swc/core-win32-x64-msvc": "1.11.11",
|
||||||
"@tensorflow/tfjs": "4.22.0",
|
"@tensorflow/tfjs": "4.22.0",
|
||||||
"@tensorflow/tfjs-node": "4.22.0",
|
"@tensorflow/tfjs-node": "4.22.0",
|
||||||
"bufferutil": "4.0.9",
|
"bufferutil": "4.0.9",
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
"@sinonjs/fake-timers": "11.3.1",
|
"@sinonjs/fake-timers": "11.3.1",
|
||||||
"@smithy/node-http-handler": "2.5.0",
|
"@smithy/node-http-handler": "2.5.0",
|
||||||
"@swc/cli": "0.6.0",
|
"@swc/cli": "0.6.0",
|
||||||
"@swc/core": "1.11.12",
|
"@swc/core": "1.11.11",
|
||||||
"@twemoji/parser": "15.1.1",
|
"@twemoji/parser": "15.1.1",
|
||||||
"accepts": "1.3.8",
|
"accepts": "1.3.8",
|
||||||
"ajv": "8.17.1",
|
"ajv": "8.17.1",
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "2.0.5",
|
"blurhash": "2.0.5",
|
||||||
"body-parser": "1.20.3",
|
"body-parser": "1.20.3",
|
||||||
"bullmq": "5.44.3",
|
"bullmq": "5.44.1",
|
||||||
"cacheable-lookup": "7.0.0",
|
"cacheable-lookup": "7.0.0",
|
||||||
"cbor": "9.0.2",
|
"cbor": "9.0.2",
|
||||||
"chalk": "5.4.1",
|
"chalk": "5.4.1",
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
"@types/jsrsasign": "10.5.15",
|
"@types/jsrsasign": "10.5.15",
|
||||||
"@types/mime-types": "2.1.4",
|
"@types/mime-types": "2.1.4",
|
||||||
"@types/ms": "0.7.34",
|
"@types/ms": "0.7.34",
|
||||||
"@types/node": "22.13.11",
|
"@types/node": "22.13.10",
|
||||||
"@types/nodemailer": "6.4.17",
|
"@types/nodemailer": "6.4.17",
|
||||||
"@types/oauth": "0.9.6",
|
"@types/oauth": "0.9.6",
|
||||||
"@types/oauth2orize": "1.11.5",
|
"@types/oauth2orize": "1.11.5",
|
||||||
|
@@ -391,10 +391,10 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requiredRolePolicy != null && (this.meta.rootUserId !== user!.id)) {
|
if (ep.meta.requireRolePolicy != null && (this.meta.rootUserId !== user!.id)) {
|
||||||
const myRoles = await this.roleService.getUserRoles(user!.id);
|
const myRoles = await this.roleService.getUserRoles(user!.id);
|
||||||
const policies = await this.roleService.getUserPolicies(user!.id);
|
const policies = await this.roleService.getUserPolicies(user!.id);
|
||||||
if (!policies[ep.meta.requiredRolePolicy] && !myRoles.some(r => r.isAdministrator)) {
|
if (!policies[ep.meta.requireRolePolicy] && !myRoles.some(r => r.isAdministrator)) {
|
||||||
throw new ApiError({
|
throw new ApiError({
|
||||||
message: 'You are not assigned to a required role.',
|
message: 'You are not assigned to a required role.',
|
||||||
code: 'ROLE_PERMISSION_DENIED',
|
code: 'ROLE_PERMISSION_DENIED',
|
||||||
|
@@ -39,7 +39,7 @@ interface IEndpointMetaBase {
|
|||||||
*/
|
*/
|
||||||
readonly requireAdmin?: boolean;
|
readonly requireAdmin?: boolean;
|
||||||
|
|
||||||
readonly requiredRolePolicy?: KeyOf<'RolePolicies'>;
|
readonly requireRolePolicy?: KeyOf<'RolePolicies'>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引っ越し済みのユーザーによるリクエストを禁止するか
|
* 引っ越し済みのユーザーによるリクエストを禁止するか
|
||||||
|
@@ -12,7 +12,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
requireRolePolicy: 'canManageAvatarDecorations',
|
||||||
kind: 'write:admin:avatar-decorations',
|
kind: 'write:admin:avatar-decorations',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -13,7 +13,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
requireRolePolicy: 'canManageAvatarDecorations',
|
||||||
kind: 'write:admin:avatar-decorations',
|
kind: 'write:admin:avatar-decorations',
|
||||||
errors: {
|
errors: {
|
||||||
},
|
},
|
||||||
|
@@ -13,7 +13,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
requireRolePolicy: 'canManageAvatarDecorations',
|
||||||
kind: 'read:admin:avatar-decorations',
|
kind: 'read:admin:avatar-decorations',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -13,7 +13,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
requireRolePolicy: 'canManageAvatarDecorations',
|
||||||
kind: 'write:admin:avatar-decorations',
|
kind: 'write:admin:avatar-decorations',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -17,7 +17,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -10,7 +10,7 @@ import { QueueService } from '@/core/QueueService.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@@ -16,7 +16,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'read:admin:emoji',
|
kind: 'read:admin:emoji',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -16,7 +16,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'read:admin:emoji',
|
kind: 'read:admin:emoji',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'write:admin:emoji',
|
kind: 'write:admin:emoji',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -16,7 +16,7 @@ import { ApiError } from '../../error.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canImportAntennas',
|
requireRolePolicy: 'canImportAntennas',
|
||||||
prohibitMoved: true,
|
prohibitMoved: true,
|
||||||
|
|
||||||
limit: {
|
limit: {
|
||||||
|
@@ -15,7 +15,7 @@ import { ApiError } from '../../error.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canImportBlocking',
|
requireRolePolicy: 'canImportBlocking',
|
||||||
prohibitMoved: true,
|
prohibitMoved: true,
|
||||||
|
|
||||||
limit: {
|
limit: {
|
||||||
|
@@ -15,7 +15,7 @@ import { ApiError } from '../../error.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canImportFollowing',
|
requireRolePolicy: 'canImportFollowing',
|
||||||
prohibitMoved: true,
|
prohibitMoved: true,
|
||||||
limit: {
|
limit: {
|
||||||
duration: ms('1hour'),
|
duration: ms('1hour'),
|
||||||
|
@@ -15,7 +15,7 @@ import { ApiError } from '../../error.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canImportMuting',
|
requireRolePolicy: 'canImportMuting',
|
||||||
prohibitMoved: true,
|
prohibitMoved: true,
|
||||||
|
|
||||||
limit: {
|
limit: {
|
||||||
|
@@ -15,7 +15,7 @@ import { ApiError } from '../../error.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canImportUserLists',
|
requireRolePolicy: 'canImportUserLists',
|
||||||
prohibitMoved: true,
|
prohibitMoved: true,
|
||||||
limit: {
|
limit: {
|
||||||
duration: ms('1hour'),
|
duration: ms('1hour'),
|
||||||
|
@@ -18,7 +18,7 @@ export const meta = {
|
|||||||
tags: ['meta'],
|
tags: ['meta'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canInvite',
|
requireRolePolicy: 'canInvite',
|
||||||
kind: 'write:invite-codes',
|
kind: 'write:invite-codes',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -14,7 +14,7 @@ export const meta = {
|
|||||||
tags: ['meta'],
|
tags: ['meta'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canInvite',
|
requireRolePolicy: 'canInvite',
|
||||||
kind: 'write:invite-codes',
|
kind: 'write:invite-codes',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
@@ -15,7 +15,7 @@ export const meta = {
|
|||||||
tags: ['meta'],
|
tags: ['meta'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canInvite',
|
requireRolePolicy: 'canInvite',
|
||||||
kind: 'read:invite-codes',
|
kind: 'read:invite-codes',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -14,7 +14,7 @@ export const meta = {
|
|||||||
tags: ['meta'],
|
tags: ['meta'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canInvite',
|
requireRolePolicy: 'canInvite',
|
||||||
kind: 'read:invite-codes',
|
kind: 'read:invite-codes',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -12,7 +12,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requiredRolePolicy: 'canManageCustomEmojis',
|
requireRolePolicy: 'canManageCustomEmojis',
|
||||||
kind: 'read:admin:emoji',
|
kind: 'read:admin:emoji',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
|
@@ -109,6 +109,12 @@ export const ROLE_POLICIES = [
|
|||||||
'canImportUserLists',
|
'canImportUserLists',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
// なんか動かない
|
||||||
|
//export const CURRENT_STICKY_TOP = Symbol('CURRENT_STICKY_TOP');
|
||||||
|
//export const CURRENT_STICKY_BOTTOM = Symbol('CURRENT_STICKY_BOTTOM');
|
||||||
|
export const CURRENT_STICKY_TOP = 'CURRENT_STICKY_TOP';
|
||||||
|
export const CURRENT_STICKY_BOTTOM = 'CURRENT_STICKY_BOTTOM';
|
||||||
|
|
||||||
export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://xn--931a.moe/assets/error.jpg';
|
export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://xn--931a.moe/assets/error.jpg';
|
||||||
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://xn--931a.moe/assets/not-found.jpg';
|
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://xn--931a.moe/assets/not-found.jpg';
|
||||||
export const DEFAULT_INFO_IMAGE_URL = 'https://xn--931a.moe/assets/info.jpg';
|
export const DEFAULT_INFO_IMAGE_URL = 'https://xn--931a.moe/assets/info.jpg';
|
||||||
|
@@ -23,7 +23,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, provide, inject, ref, watch, useTemplateRef } from 'vue';
|
import { onMounted, onUnmounted, provide, inject, ref, watch, useTemplateRef } from 'vue';
|
||||||
import { DI } from '@/di.js';
|
import { CURRENT_STICKY_BOTTOM, CURRENT_STICKY_TOP } from '@@/js/const.js';
|
||||||
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
const rootEl = useTemplateRef('rootEl');
|
const rootEl = useTemplateRef('rootEl');
|
||||||
const headerEl = useTemplateRef('headerEl');
|
const headerEl = useTemplateRef('headerEl');
|
||||||
@@ -31,13 +32,13 @@ const footerEl = useTemplateRef('footerEl');
|
|||||||
|
|
||||||
const headerHeight = ref<string | undefined>();
|
const headerHeight = ref<string | undefined>();
|
||||||
const childStickyTop = ref(0);
|
const childStickyTop = ref(0);
|
||||||
const parentStickyTop = inject(DI.currentStickyTop, ref(0));
|
const parentStickyTop = inject<Ref<number>>(CURRENT_STICKY_TOP, ref(0));
|
||||||
provide(DI.currentStickyTop, childStickyTop);
|
provide(CURRENT_STICKY_TOP, childStickyTop);
|
||||||
|
|
||||||
const footerHeight = ref<string | undefined>();
|
const footerHeight = ref<string | undefined>();
|
||||||
const childStickyBottom = ref(0);
|
const childStickyBottom = ref(0);
|
||||||
const parentStickyBottom = inject(DI.currentStickyBottom, ref(0));
|
const parentStickyBottom = inject<Ref<number>>(CURRENT_STICKY_BOTTOM, ref(0));
|
||||||
provide(DI.currentStickyBottom, childStickyBottom);
|
provide(CURRENT_STICKY_BOTTOM, childStickyBottom);
|
||||||
|
|
||||||
const calc = () => {
|
const calc = () => {
|
||||||
// コンポーネントが表示されてないけどKeepAliveで残ってる場合などは null になる
|
// コンポーネントが表示されてないけどKeepAliveで残ってる場合などは null になる
|
||||||
|
@@ -4,15 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="[$style.root, reversed ? '_pageScrollableReversed' : '_pageScrollable']">
|
<MkStickyContainer class="_pageScrollable">
|
||||||
<MkStickyContainer>
|
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="actions" :tabs="tabs"/></template>
|
<template #header><MkPageHeader v-model:tab="tab" :actions="actions" :tabs="tabs"/></template>
|
||||||
<div :class="$style.body">
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
|
||||||
<template #footer><slot name="footer"></slot></template>
|
<template #footer><slot name="footer"></slot></template>
|
||||||
</MkStickyContainer>
|
</MkStickyContainer>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -25,7 +21,6 @@ const props = withDefaults(defineProps<{
|
|||||||
thin?: boolean;
|
thin?: boolean;
|
||||||
hideTitle?: boolean;
|
hideTitle?: boolean;
|
||||||
displayMyAvatar?: boolean;
|
displayMyAvatar?: boolean;
|
||||||
reversed?: boolean;
|
|
||||||
}>(), {
|
}>(), {
|
||||||
tabs: () => ([] as Tab[]),
|
tabs: () => ([] as Tab[]),
|
||||||
});
|
});
|
||||||
@@ -34,11 +29,5 @@ const tab = defineModel<string>('tab');
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
.root {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
min-height: calc(100cqh - (var(--MI-stickyTop, 0px) + var(--MI-stickyBottom, 0px)));
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -12,6 +12,4 @@ export const DI = {
|
|||||||
mock: Symbol() as InjectionKey<boolean>,
|
mock: Symbol() as InjectionKey<boolean>,
|
||||||
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any>>>,
|
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any>>>,
|
||||||
viewId: Symbol() as InjectionKey<string>,
|
viewId: Symbol() as InjectionKey<string>,
|
||||||
currentStickyTop: Symbol() as InjectionKey<Ref<number>>,
|
|
||||||
currentStickyBottom: Symbol() as InjectionKey<Ref<number>>,
|
|
||||||
};
|
};
|
||||||
|
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<MkSpacer :contentMax="700">
|
<MkSpacer :contentMax="700" :class="$style.main">
|
||||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||||
<div v-if="channel && tab === 'overview'" class="_gaps">
|
<div v-if="channel && tab === 'overview'" class="_gaps">
|
||||||
<div class="_panel" :class="$style.bannerContainer">
|
<div class="_panel" :class="$style.bannerContainer">
|
||||||
@@ -270,6 +270,10 @@ definePage(() => ({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
.main {
|
||||||
|
min-height: calc(100cqh - (var(--MI-stickyTop, 0px) + var(--MI-stickyBottom, 0px)));
|
||||||
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
backdrop-filter: var(--MI-blur, blur(15px));
|
backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
|
@@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
<MkSpacer v-else-if="list" :contentMax="700">
|
<MkSpacer v-else-if="list" :contentMax="700" :class="$style.main">
|
||||||
<div v-if="list" class="members _margin">
|
<div v-if="list" class="members _margin">
|
||||||
<div :class="$style.member_text">{{ i18n.ts.members }}</div>
|
<div :class="$style.member_text">{{ i18n.ts.members }}</div>
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
@@ -106,6 +106,10 @@ definePage(() => ({
|
|||||||
}));
|
}));
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
.main {
|
||||||
|
min-height: calc(100cqh - (var(--MI-stickyTop, 0px) + var(--MI-stickyBottom, 0px)));
|
||||||
|
}
|
||||||
|
|
||||||
.userItem {
|
.userItem {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||||
<MkSpacer :contentMax="700">
|
<MkSpacer :contentMax="700" :class="$style.main">
|
||||||
<div v-if="list" class="_gaps">
|
<div v-if="list" class="_gaps">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts.settings }}</template>
|
<template #label>{{ i18n.ts.settings }}</template>
|
||||||
@@ -197,6 +197,10 @@ definePage(() => ({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
.main {
|
||||||
|
min-height: calc(100cqh - (var(--MI-stickyTop, 0px) + var(--MI-stickyBottom, 0px)));
|
||||||
|
}
|
||||||
|
|
||||||
.userItem {
|
.userItem {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@@ -179,20 +179,11 @@ rt {
|
|||||||
|
|
||||||
._pageScrollable {
|
._pageScrollable {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: clip;
|
overflow: auto;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
._pageScrollableReversed {
|
|
||||||
height: 100%;
|
|
||||||
overflow: clip;
|
|
||||||
overflow-y: scroll;
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
._indicatorCircle {
|
._indicatorCircle {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
|
@@ -97,6 +97,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, provide, onMounted, computed, ref, watch, useTemplateRef } from 'vue';
|
import { defineAsyncComponent, provide, onMounted, computed, ref, watch, useTemplateRef } from 'vue';
|
||||||
import { instanceName } from '@@/js/config.js';
|
import { instanceName } from '@@/js/config.js';
|
||||||
|
import { CURRENT_STICKY_BOTTOM } from '@@/js/const.js';
|
||||||
import { isLink } from '@@/js/is-link.js';
|
import { isLink } from '@@/js/is-link.js';
|
||||||
import XCommon from './_common_/common.vue';
|
import XCommon from './_common_/common.vue';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
@@ -199,13 +200,16 @@ const onContextmenu = (ev) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const navFooterHeight = ref(0);
|
const navFooterHeight = ref(0);
|
||||||
|
provide<Ref<number>>(CURRENT_STICKY_BOTTOM, navFooterHeight);
|
||||||
|
|
||||||
watch(navFooter, () => {
|
watch(navFooter, () => {
|
||||||
if (navFooter.value) {
|
if (navFooter.value) {
|
||||||
navFooterHeight.value = navFooter.value.offsetHeight;
|
navFooterHeight.value = navFooter.value.offsetHeight;
|
||||||
|
window.document.body.style.setProperty('--MI-stickyBottom', `${navFooterHeight.value}px`);
|
||||||
window.document.body.style.setProperty('--MI-minBottomSpacing', 'var(--MI-minBottomSpacingMobile)');
|
window.document.body.style.setProperty('--MI-minBottomSpacing', 'var(--MI-minBottomSpacingMobile)');
|
||||||
} else {
|
} else {
|
||||||
navFooterHeight.value = 0;
|
navFooterHeight.value = 0;
|
||||||
|
window.document.body.style.setProperty('--MI-stickyBottom', '0px');
|
||||||
window.document.body.style.setProperty('--MI-minBottomSpacing', '0px');
|
window.document.body.style.setProperty('--MI-minBottomSpacing', '0px');
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
574
pnpm-lock.yaml
generated
574
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user