Compare commits
1 Commits
renovate/g
...
feat/bundl
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f066247988 |
2
.github/workflows/api-misskey-js.yml
vendored
2
.github/workflows/api-misskey-js.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/changelog-check.yml
vendored
2
.github/workflows/changelog-check.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
- name: Checkout head
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
|
||||
|
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
- name: setup node
|
||||
id: setup-node
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: pnpm
|
||||
|
2
.github/workflows/get-api-diff.yml
vendored
2
.github/workflows/get-api-diff.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
8
.github/workflows/lint.yml
vendored
8
.github/workflows/lint.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.3.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -69,13 +69,13 @@ jobs:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.3.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Restore eslint cache
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v4.2.2
|
||||
with:
|
||||
path: ${{ env.eslint-cache-path }}
|
||||
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.3.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/locale.yml
vendored
2
.github/workflows/locale.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.3.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/on-release-created.yml
vendored
2
.github/workflows/on-release-created.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/storybook.yml
vendored
2
.github/workflows/storybook.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
4
.github/workflows/test-backend.yml
vendored
4
.github/workflows/test-backend.yml
vendored
@@ -62,7 +62,7 @@ jobs:
|
||||
fi
|
||||
done
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/test-federation.yml
vendored
2
.github/workflows/test-federation.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
fi
|
||||
done
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
4
.github/workflows/test-frontend.yml
vendored
4
.github/workflows/test-frontend.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/test-misskey-js.yml
vendored
2
.github/workflows/test-misskey-js.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/test-production.yml
vendored
2
.github/workflows/test-production.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
2
.github/workflows/validate-api-json.yml
vendored
2
.github/workflows/validate-api-json.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.3.0
|
||||
uses: actions/setup-node@v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"version": "2025.3.2-beta.8",
|
||||
"version": "2025.3.2-beta.6",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -37,17 +37,17 @@
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-android-arm64": "1.3.11",
|
||||
"@swc/core-darwin-arm64": "1.11.11",
|
||||
"@swc/core-darwin-x64": "1.11.11",
|
||||
"@swc/core-darwin-arm64": "1.10.16",
|
||||
"@swc/core-darwin-x64": "1.10.16",
|
||||
"@swc/core-freebsd-x64": "1.3.11",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.11.11",
|
||||
"@swc/core-linux-arm64-gnu": "1.11.11",
|
||||
"@swc/core-linux-arm64-musl": "1.11.11",
|
||||
"@swc/core-linux-x64-gnu": "1.11.11",
|
||||
"@swc/core-linux-x64-musl": "1.11.11",
|
||||
"@swc/core-win32-arm64-msvc": "1.11.11",
|
||||
"@swc/core-win32-ia32-msvc": "1.11.11",
|
||||
"@swc/core-win32-x64-msvc": "1.11.11",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.10.16",
|
||||
"@swc/core-linux-arm64-gnu": "1.10.16",
|
||||
"@swc/core-linux-arm64-musl": "1.10.16",
|
||||
"@swc/core-linux-x64-gnu": "1.10.16",
|
||||
"@swc/core-linux-x64-musl": "1.10.16",
|
||||
"@swc/core-win32-arm64-msvc": "1.10.16",
|
||||
"@swc/core-win32-ia32-msvc": "1.10.16",
|
||||
"@swc/core-win32-x64-msvc": "1.10.16",
|
||||
"@tensorflow/tfjs": "4.22.0",
|
||||
"@tensorflow/tfjs-node": "4.22.0",
|
||||
"bufferutil": "4.0.9",
|
||||
@@ -67,23 +67,23 @@
|
||||
"utf-8-validate": "6.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.772.0",
|
||||
"@aws-sdk/lib-storage": "3.772.0",
|
||||
"@aws-sdk/client-s3": "3.749.0",
|
||||
"@aws-sdk/lib-storage": "3.749.0",
|
||||
"@discordapp/twemoji": "15.1.0",
|
||||
"@fastify/accepts": "5.0.2",
|
||||
"@fastify/cookie": "11.0.2",
|
||||
"@fastify/cors": "10.1.0",
|
||||
"@fastify/cors": "10.0.2",
|
||||
"@fastify/express": "4.0.2",
|
||||
"@fastify/http-proxy": "10.0.2",
|
||||
"@fastify/multipart": "9.0.3",
|
||||
"@fastify/static": "8.1.1",
|
||||
"@fastify/static": "8.1.0",
|
||||
"@fastify/view": "10.0.2",
|
||||
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
||||
"@misskey-dev/summaly": "5.2.0",
|
||||
"@napi-rs/canvas": "0.1.68",
|
||||
"@nestjs/common": "11.0.12",
|
||||
"@nestjs/core": "11.0.12",
|
||||
"@nestjs/testing": "11.0.12",
|
||||
"@napi-rs/canvas": "0.1.67",
|
||||
"@nestjs/common": "11.0.9",
|
||||
"@nestjs/core": "11.0.9",
|
||||
"@nestjs/testing": "11.0.9",
|
||||
"@peertube/http-signature": "1.7.0",
|
||||
"@sentry/node": "8.55.0",
|
||||
"@sentry/profiling-node": "8.55.0",
|
||||
@@ -91,7 +91,7 @@
|
||||
"@sinonjs/fake-timers": "11.3.1",
|
||||
"@smithy/node-http-handler": "2.5.0",
|
||||
"@swc/cli": "0.6.0",
|
||||
"@swc/core": "1.11.11",
|
||||
"@swc/core": "1.10.16",
|
||||
"@twemoji/parser": "15.1.1",
|
||||
"accepts": "1.3.8",
|
||||
"ajv": "8.17.1",
|
||||
@@ -100,7 +100,7 @@
|
||||
"bcryptjs": "2.4.3",
|
||||
"blurhash": "2.0.5",
|
||||
"body-parser": "1.20.3",
|
||||
"bullmq": "5.44.1",
|
||||
"bullmq": "5.41.1",
|
||||
"cacheable-lookup": "7.0.0",
|
||||
"cbor": "9.0.2",
|
||||
"chalk": "5.4.1",
|
||||
@@ -122,7 +122,7 @@
|
||||
"hpagent": "1.2.0",
|
||||
"htmlescape": "1.1.1",
|
||||
"http-link-header": "1.1.3",
|
||||
"ioredis": "5.6.0",
|
||||
"ioredis": "5.5.0",
|
||||
"ip-cidr": "4.0.2",
|
||||
"ipaddr.js": "2.2.0",
|
||||
"is-svg": "5.1.0",
|
||||
@@ -131,26 +131,26 @@
|
||||
"json5": "2.2.3",
|
||||
"jsonld": "8.3.3",
|
||||
"jsrsasign": "11.1.0",
|
||||
"juice": "11.0.1",
|
||||
"meilisearch": "0.49.0",
|
||||
"juice": "11.0.0",
|
||||
"meilisearch": "0.48.2",
|
||||
"mfm-js": "0.24.0",
|
||||
"microformats-parser": "2.0.2",
|
||||
"mime-types": "2.1.35",
|
||||
"misskey-js": "workspace:*",
|
||||
"misskey-reversi": "workspace:*",
|
||||
"ms": "3.0.0-canary.1",
|
||||
"nanoid": "5.1.5",
|
||||
"nanoid": "5.1.0",
|
||||
"nested-property": "4.0.0",
|
||||
"node-fetch": "3.3.2",
|
||||
"nodemailer": "6.10.0",
|
||||
"nsfwjs": "4.2.0",
|
||||
"oauth": "0.10.2",
|
||||
"oauth": "0.10.0",
|
||||
"oauth2orize": "1.12.0",
|
||||
"oauth2orize-pkce": "0.1.2",
|
||||
"os-utils": "0.0.14",
|
||||
"otpauth": "9.3.6",
|
||||
"parse5": "7.2.1",
|
||||
"pg": "8.14.1",
|
||||
"pg": "8.13.3",
|
||||
"pkce-challenge": "4.1.0",
|
||||
"probe-image-size": "7.2.3",
|
||||
"promise-limit": "2.7.0",
|
||||
@@ -163,8 +163,8 @@
|
||||
"reflect-metadata": "0.2.2",
|
||||
"rename": "1.0.4",
|
||||
"rss-parser": "3.13.0",
|
||||
"rxjs": "7.8.2",
|
||||
"sanitize-html": "2.15.0",
|
||||
"rxjs": "7.8.1",
|
||||
"sanitize-html": "2.14.0",
|
||||
"secure-json-parse": "3.0.2",
|
||||
"sharp": "0.33.5",
|
||||
"slacc": "0.0.10",
|
||||
@@ -173,14 +173,14 @@
|
||||
"systeminformation": "5.25.11",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tmp": "0.2.3",
|
||||
"tsc-alias": "1.8.11",
|
||||
"tsc-alias": "1.8.10",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"typeorm": "0.3.21",
|
||||
"typescript": "5.8.2",
|
||||
"ulid": "2.4.0",
|
||||
"typeorm": "0.3.20",
|
||||
"typescript": "5.7.3",
|
||||
"ulid": "2.3.0",
|
||||
"vary": "1.1.2",
|
||||
"web-push": "3.6.7",
|
||||
"ws": "8.18.1",
|
||||
"ws": "8.18.0",
|
||||
"xev": "3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -204,7 +204,7 @@
|
||||
"@types/jsrsasign": "10.5.15",
|
||||
"@types/mime-types": "2.1.4",
|
||||
"@types/ms": "0.7.34",
|
||||
"@types/node": "22.13.10",
|
||||
"@types/node": "22.13.4",
|
||||
"@types/nodemailer": "6.4.17",
|
||||
"@types/oauth": "0.9.6",
|
||||
"@types/oauth2orize": "1.11.5",
|
||||
@@ -223,9 +223,9 @@
|
||||
"@types/tmp": "0.2.6",
|
||||
"@types/vary": "1.1.3",
|
||||
"@types/web-push": "3.6.4",
|
||||
"@types/ws": "8.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||
"@typescript-eslint/parser": "8.27.0",
|
||||
"@types/ws": "8.5.14",
|
||||
"@typescript-eslint/eslint-plugin": "8.24.0",
|
||||
"@typescript-eslint/parser": "8.24.0",
|
||||
"aws-sdk-client-mock": "4.1.0",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
@@ -235,6 +235,7 @@
|
||||
"jest-mock": "29.7.0",
|
||||
"nodemon": "3.1.9",
|
||||
"pid-port": "1.0.2",
|
||||
"simple-oauth2": "5.1.0"
|
||||
"simple-oauth2": "5.1.0",
|
||||
"vite": "6.2.1"
|
||||
}
|
||||
}
|
||||
|
@@ -5,10 +5,13 @@
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { dirname, join, resolve } from 'node:path';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import locale from '../../../locales/index.js';
|
||||
import type { RedisOptions } from 'ioredis';
|
||||
import type { Manifest, ManifestChunk } from 'vite';
|
||||
import type { ILocale } from '../../../locales/index.js';
|
||||
|
||||
type RedisOptionsSource = Partial<RedisOptions> & {
|
||||
host: string;
|
||||
@@ -185,9 +188,12 @@ export type Config = {
|
||||
authUrl: string;
|
||||
driveUrl: string;
|
||||
userAgent: string;
|
||||
frontendEntry: string;
|
||||
localeEntries: Record<string, string>;
|
||||
errorLocaleMessages: Record<string, ILocale>;
|
||||
configEntry: ManifestChunk;
|
||||
frontendEntry: ManifestChunk;
|
||||
frontendManifestExists: boolean;
|
||||
frontendEmbedEntry: string;
|
||||
frontendEmbedEntry: ManifestChunk;
|
||||
frontendEmbedManifestExists: boolean;
|
||||
mediaProxy: string;
|
||||
externalMediaProxyEnabled: boolean;
|
||||
@@ -229,12 +235,23 @@ export function loadConfig(): Config {
|
||||
|
||||
const frontendManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_vite_/manifest.json');
|
||||
const frontendEmbedManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_embed_vite_/manifest.json');
|
||||
const frontendManifest = frontendManifestExists ?
|
||||
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_vite_/manifest.json`, 'utf-8'))
|
||||
: { 'src/_boot_.ts': { file: 'src/_boot_.ts' } };
|
||||
const frontendEmbedManifest = frontendEmbedManifestExists ?
|
||||
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
||||
: { 'src/boot.ts': { file: 'src/boot.ts' } };
|
||||
const frontendManifest: Manifest = frontendManifestExists
|
||||
? JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_vite_/manifest.json`, 'utf-8'))
|
||||
: Object.entries(locale).reduce<Record<string, ManifestChunk>>((a, [k]) => {
|
||||
a[`locale:${k}`] = { file: `locale:${k}` };
|
||||
return a;
|
||||
}, {
|
||||
'src/_boot_.ts': { file: 'src/_boot_.ts' },
|
||||
'../frontend-shared/js/config.ts': { file: join('@fs', _dirname.slice(1), '../../frontend-shared/js/config.ts') },
|
||||
});
|
||||
const frontendEmbedManifest: Manifest = frontendEmbedManifestExists
|
||||
? JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
||||
: Object.entries(locale).reduce<Record<string, ManifestChunk>>((a, [k]) => {
|
||||
a[`locale:${k}`] = { file: `locale:${k}` };
|
||||
return a;
|
||||
}, {
|
||||
'src/boot.ts': { file: 'src/boot.ts' },
|
||||
});
|
||||
|
||||
const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source;
|
||||
|
||||
@@ -310,6 +327,20 @@ export function loadConfig(): Config {
|
||||
config.videoThumbnailGenerator.endsWith('/') ? config.videoThumbnailGenerator.substring(0, config.videoThumbnailGenerator.length - 1) : config.videoThumbnailGenerator
|
||||
: null,
|
||||
userAgent: `Misskey/${version} (${config.url})`,
|
||||
localeEntries: Object.entries<ManifestChunk>(frontendManifest).reduce<Record<string, string>>((a, [k, v]) => {
|
||||
if (k.startsWith('locale:')) {
|
||||
a[k.slice('locale:'.length)] = v.file;
|
||||
}
|
||||
return a;
|
||||
}, {}),
|
||||
errorLocaleMessages: Object.entries(locale).reduce<Record<string, ILocale>>((a, [k, v]) => {
|
||||
a[k] = {
|
||||
_bootErrors: v._bootErrors,
|
||||
reload: v.reload,
|
||||
};
|
||||
return a;
|
||||
}, {}),
|
||||
configEntry: frontendManifest['../frontend-shared/js/config.ts'],
|
||||
frontendEntry: frontendManifest['src/_boot_.ts'],
|
||||
frontendManifestExists: frontendManifestExists,
|
||||
frontendEmbedEntry: frontendEmbedManifest['src/boot.ts'],
|
||||
|
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
import * as fs from 'node:fs/promises';
|
||||
import { WritableStream } from 'node:stream/web';
|
||||
import type { PathLike } from 'node:fs';
|
||||
|
||||
/**
|
||||
|
@@ -32,56 +32,24 @@
|
||||
}
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
if (!localStorage.hasOwnProperty('locale')) {
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
const metaRes = await window.fetch('/api/meta', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
credentials: 'omit',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
if (metaRes.status !== 200) {
|
||||
renderError('META_FETCH');
|
||||
return;
|
||||
}
|
||||
const meta = await metaRes.json();
|
||||
const v = meta.version;
|
||||
if (v == null) {
|
||||
renderError('META_FETCH_V');
|
||||
return;
|
||||
}
|
||||
|
||||
// for https://github.com/misskey-dev/misskey/issues/10202
|
||||
if (lang == null || lang.toString == null || lang.toString() === 'null') {
|
||||
console.error('invalid lang value detected!!!', typeof lang, lang);
|
||||
lang = 'en-US';
|
||||
}
|
||||
|
||||
const localRes = await window.fetch(`/assets/locales/${lang}.${v}.json`);
|
||||
if (localRes.status === 200) {
|
||||
localStorage.setItem('lang', lang);
|
||||
localStorage.setItem('locale', await localRes.text());
|
||||
localStorage.setItem('localeVersion', v);
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (!supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
renderError('LOCALE_FETCH');
|
||||
return;
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
await import(`/vite/${LOCALES[lang]}`)
|
||||
.catch(async e => {
|
||||
console.error(e);
|
||||
renderError('LOCALE_FETCH', e);
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Script
|
||||
@@ -115,10 +83,21 @@
|
||||
await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve));
|
||||
}
|
||||
|
||||
const locale = JSON.parse(localStorage.getItem('locale') || '{}');
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (!supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
const title = locale?._bootErrors?.title || 'Failed to initialize Misskey';
|
||||
const reload = locale?.reload || 'Reload';
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
const { locale } = await import(`/vite/${CONFIG_ENTRY}`).catch(() => ({ locale: {} }));
|
||||
const title = locale._bootErrors.title;
|
||||
const reload = locale.reload;
|
||||
|
||||
document.body.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /><path d="M12 9v4" /><path d="M12 16v.01" /></svg>
|
||||
<div class="message">${title}</div>
|
||||
|
@@ -23,56 +23,24 @@
|
||||
}
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
if (!localStorage.hasOwnProperty('locale')) {
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
const metaRes = await window.fetch('/api/meta', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
credentials: 'omit',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
if (metaRes.status !== 200) {
|
||||
renderError('META_FETCH');
|
||||
return;
|
||||
}
|
||||
const meta = await metaRes.json();
|
||||
const v = meta.version;
|
||||
if (v == null) {
|
||||
renderError('META_FETCH_V');
|
||||
return;
|
||||
}
|
||||
|
||||
// for https://github.com/misskey-dev/misskey/issues/10202
|
||||
if (lang == null || lang.toString == null || lang.toString() === 'null') {
|
||||
console.error('invalid lang value detected!!!', typeof lang, lang);
|
||||
lang = 'en-US';
|
||||
}
|
||||
|
||||
const localRes = await window.fetch(`/assets/locales/${lang}.${v}.json`);
|
||||
if (localRes.status === 200) {
|
||||
localStorage.setItem('lang', lang);
|
||||
localStorage.setItem('locale', await localRes.text());
|
||||
localStorage.setItem('localeVersion', v);
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (!supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
renderError('LOCALE_FETCH');
|
||||
return;
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
await import(`/vite/${LOCALES[lang]}`)
|
||||
.catch(async e => {
|
||||
console.error(e);
|
||||
renderError('LOCALE_FETCH', e);
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Script
|
||||
@@ -151,21 +119,25 @@
|
||||
await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve));
|
||||
}
|
||||
|
||||
const locale = JSON.parse(localStorage.getItem('locale') || '{}');
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (!supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
const messages = Object.assign({
|
||||
title: 'Failed to initialize Misskey',
|
||||
solution: 'The following actions may solve the problem.',
|
||||
solution1: 'Update your os and browser',
|
||||
solution2: 'Disable an adblocker',
|
||||
solution3: 'Clear the browser cache',
|
||||
solution4: '(Tor Browser) Set dom.webaudio.enabled to true',
|
||||
otherOption: 'Other options',
|
||||
otherOption1: 'Clear preferences and cache',
|
||||
otherOption2: 'Start the simple client',
|
||||
otherOption3: 'Start the repair tool',
|
||||
}, locale?._bootErrors || {});
|
||||
const reload = locale?.reload || 'Reload';
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
const { locale } = await import(`/vite/${CONFIG_ENTRY}`).catch(() => ({
|
||||
locale: {
|
||||
_bootErrors: {},
|
||||
},
|
||||
}));
|
||||
const messages = locale._bootErrors;
|
||||
const reload = locale.reload;
|
||||
|
||||
let errorsElement = document.getElementById('errors');
|
||||
|
||||
|
@@ -6,23 +6,22 @@
|
||||
'use strict';
|
||||
|
||||
(() => {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const locale = JSON.parse(localStorage.getItem('locale') || '{}');
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const supportedLangs = LANGS;
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (!supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
const messages = Object.assign({
|
||||
title: 'Failed to initialize Misskey',
|
||||
serverError: 'If reloading after a period of time does not resolve the problem, contact the server administrator with the following ERROR ID.',
|
||||
solution: 'The following actions may solve the problem.',
|
||||
solution1: 'Update your os and browser',
|
||||
solution2: 'Disable an adblocker',
|
||||
solution3: 'Clear the browser cache',
|
||||
solution4: '(Tor Browser) Set dom.webaudio.enabled to true',
|
||||
otherOption: 'Other options',
|
||||
otherOption1: 'Clear preferences and cache',
|
||||
otherOption2: 'Start the simple client',
|
||||
otherOption3: 'Start the repair tool',
|
||||
}, locale?._bootErrors || {});
|
||||
const reload = locale?.reload || 'Reload';
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
const locale = ERROR_MESSAGES[lang];
|
||||
const messages = locale._bootErrors;
|
||||
const reload = locale.reload;
|
||||
|
||||
const reloadEls = document.querySelectorAll('[data-i18n-reload]');
|
||||
for (const el of reloadEls) {
|
||||
|
@@ -41,6 +41,8 @@ html(class='embed')
|
||||
script.
|
||||
var VERSION = "#{version}";
|
||||
var CLIENT_ENTRY = "#{entry.file}";
|
||||
var CONFIG_ENTRY = "#{config.configEntry.file}";
|
||||
var LOCALES = JSON.parse(`!{JSON.stringify(config.localeEntries)}`);
|
||||
|
||||
script(type='application/json' id='misskey_meta' data-generated-at=now)
|
||||
!= metaJson
|
||||
|
@@ -70,6 +70,8 @@ html
|
||||
script.
|
||||
var VERSION = "#{version}";
|
||||
var CLIENT_ENTRY = "#{entry.file}";
|
||||
var CONFIG_ENTRY = "#{config.configEntry.file}";
|
||||
var LOCALES = JSON.parse(`!{JSON.stringify(config.localeEntries)}`);
|
||||
|
||||
script(type='application/json' id='misskey_meta' data-generated-at=now)
|
||||
!= metaJson
|
||||
|
@@ -27,6 +27,9 @@ html
|
||||
style
|
||||
include ../error.css
|
||||
|
||||
script.
|
||||
var ERROR_MESSAGES = JSON.parse(`!{JSON.stringify(config.errorLocaleMessages)}`);
|
||||
|
||||
script
|
||||
include ../error.js
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
"@rollup/pluginutils": "5.1.4",
|
||||
"@tabler/icons-webfont": "3.31.0",
|
||||
"@twemoji/parser": "15.1.1",
|
||||
"@vitejs/plugin-vue": "5.2.3",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vue/compiler-sfc": "3.5.13",
|
||||
"astring": "1.9.0",
|
||||
"buraha": "0.0.1",
|
||||
@@ -25,16 +25,16 @@
|
||||
"misskey-js": "workspace:*",
|
||||
"frontend-shared": "workspace:*",
|
||||
"punycode.js": "2.3.1",
|
||||
"rollup": "4.36.0",
|
||||
"sass": "1.86.0",
|
||||
"shiki": "3.2.1",
|
||||
"rollup": "4.34.9",
|
||||
"sass": "1.85.1",
|
||||
"shiki": "3.1.0",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tsc-alias": "1.8.11",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"typescript": "5.8.2",
|
||||
"uuid": "11.1.0",
|
||||
"json5": "2.2.3",
|
||||
"vite": "6.2.2",
|
||||
"vite": "6.2.1",
|
||||
"vue": "3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -42,26 +42,26 @@
|
||||
"@testing-library/vue": "8.1.0",
|
||||
"@types/estree": "1.0.6",
|
||||
"@types/micromatch": "4.0.9",
|
||||
"@types/node": "22.13.11",
|
||||
"@types/node": "22.13.9",
|
||||
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"@types/ws": "8.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||
"@typescript-eslint/parser": "8.27.0",
|
||||
"@vitest/coverage-v8": "3.0.9",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"@vitest/coverage-v8": "3.0.8",
|
||||
"@vue/runtime-core": "3.5.13",
|
||||
"acorn": "8.14.1",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-vue": "10.0.0",
|
||||
"fast-glob": "3.3.3",
|
||||
"happy-dom": "17.4.4",
|
||||
"happy-dom": "17.3.0",
|
||||
"intersection-observer": "0.12.2",
|
||||
"micromatch": "4.0.8",
|
||||
"msw": "2.7.3",
|
||||
"nodemon": "3.1.9",
|
||||
"prettier": "3.5.3",
|
||||
"start-server-and-test": "2.0.11",
|
||||
"start-server-and-test": "2.0.10",
|
||||
"vite-plugin-turbosnap": "1.0.3",
|
||||
"vue-component-type-helpers": "2.2.8",
|
||||
"vue-eslint-parser": "10.1.1",
|
||||
|
@@ -13,18 +13,17 @@ import { createApp, defineAsyncComponent } from 'vue';
|
||||
import defaultLightTheme from '@@/themes/l-light.json5';
|
||||
import defaultDarkTheme from '@@/themes/d-dark.json5';
|
||||
import { MediaProxy } from '@@/js/media-proxy.js';
|
||||
import { url, version, locale, lang, updateLocale } from '@@/js/config.js';
|
||||
import { parseEmbedParams } from '@@/js/embed-page.js';
|
||||
import type { Theme } from '@/theme.js';
|
||||
import { applyTheme, assertIsTheme } from '@/theme.js';
|
||||
import { fetchCustomEmojis } from '@/custom-emojis.js';
|
||||
import { DI } from '@/di.js';
|
||||
import { serverMetadata } from '@/server-metadata.js';
|
||||
import { url, version, locale, lang, updateLocale } from '@@/js/config.js';
|
||||
import { parseEmbedParams } from '@@/js/embed-page.js';
|
||||
import { postMessageToParentWindow, setIframeId } from '@/post-message.js';
|
||||
import { serverContext } from '@/server-context.js';
|
||||
import { i18n, updateI18n } from '@/i18n.js';
|
||||
|
||||
import type { Theme } from '@/theme.js';
|
||||
|
||||
console.log('Misskey Embed');
|
||||
|
||||
//#region Embedパラメータの取得・パース
|
||||
@@ -71,22 +70,6 @@ if (embedParams.colorMode === 'dark') {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
const localeVersion = localStorage.getItem('localeVersion');
|
||||
const localeOutdated = (localeVersion == null || localeVersion !== version || locale == null);
|
||||
if (localeOutdated) {
|
||||
const res = await window.fetch(`/assets/locales/${lang}.${version}.json`);
|
||||
if (res.status === 200) {
|
||||
const newLocale = await res.text();
|
||||
const parsedNewLocale = JSON.parse(newLocale);
|
||||
localStorage.setItem('locale', newLocale);
|
||||
localStorage.setItem('localeVersion', version);
|
||||
updateLocale(parsedNewLocale);
|
||||
updateI18n(parsedNewLocale);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// サイズの制限
|
||||
document.documentElement.style.maxWidth = '500px';
|
||||
|
||||
|
@@ -17,8 +17,7 @@ export const apiUrl = location.origin + '/api';
|
||||
export const wsOrigin = location.origin;
|
||||
export const lang = localStorage.getItem('lang') ?? 'en-US';
|
||||
export const langs = _LANGS_;
|
||||
const preParseLocale = localStorage.getItem('locale');
|
||||
export let locale: Locale = preParseLocale ? JSON.parse(preParseLocale) : null;
|
||||
export let locale: Locale;
|
||||
export const version = _VERSION_;
|
||||
export const instanceName = (siteName === 'Misskey' || siteName == null) ? host : siteName;
|
||||
export const ui = localStorage.getItem('ui');
|
||||
|
@@ -21,10 +21,10 @@
|
||||
"lint": "pnpm typecheck && pnpm eslint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "22.13.11",
|
||||
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||
"@typescript-eslint/parser": "8.27.0",
|
||||
"esbuild": "0.25.1",
|
||||
"@types/node": "22.13.9",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"esbuild": "0.25.0",
|
||||
"eslint-plugin-vue": "10.0.0",
|
||||
"nodemon": "3.1.9",
|
||||
"typescript": "5.8.2",
|
||||
|
@@ -55,7 +55,6 @@ function initLocalStorage() {
|
||||
...userDetailed(),
|
||||
policies: {},
|
||||
}));
|
||||
localStorage.setItem('locale', JSON.stringify(locale));
|
||||
}
|
||||
|
||||
initialize({
|
||||
@@ -70,13 +69,17 @@ queueMicrotask(() => {
|
||||
import('../src/theme.js'),
|
||||
import('../src/preferences.js'),
|
||||
import('../src/os.js'),
|
||||
]).then(([{ default: components }, { default: directives }, { default: widgets }, { applyTheme }, { prefer }, os]) => {
|
||||
import('../src/i18n.js'),
|
||||
import('../../frontend-shared/js/config.js'),
|
||||
]).then(([{ default: components }, { default: directives }, { default: widgets }, { applyTheme }, { prefer }, os, { updateI18n }, { updateLocale }]) => {
|
||||
setup((app) => {
|
||||
moduleInitialized = true;
|
||||
if (app[appInitialized]) {
|
||||
return;
|
||||
}
|
||||
app[appInitialized] = true;
|
||||
updateLocale(locale);
|
||||
updateI18n(locale);
|
||||
loadTheme(applyTheme);
|
||||
components(app);
|
||||
directives(app);
|
||||
|
@@ -28,7 +28,7 @@
|
||||
"@syuilo/aiscript": "0.19.0",
|
||||
"@tabler/icons-webfont": "3.31.0",
|
||||
"@twemoji/parser": "15.1.1",
|
||||
"@vitejs/plugin-vue": "5.2.3",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vue/compiler-sfc": "3.5.13",
|
||||
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
|
||||
"analytics": "0.8.16",
|
||||
@@ -38,7 +38,7 @@
|
||||
"canvas-confetti": "1.9.3",
|
||||
"chart.js": "4.4.8",
|
||||
"chartjs-adapter-date-fns": "3.0.0",
|
||||
"chartjs-chart-matrix": "2.1.1",
|
||||
"chartjs-chart-matrix": "2.0.1",
|
||||
"chartjs-plugin-gradient": "0.6.1",
|
||||
"chartjs-plugin-zoom": "2.2.0",
|
||||
"chromatic": "11.27.0",
|
||||
@@ -60,10 +60,10 @@
|
||||
"misskey-reversi": "workspace:*",
|
||||
"photoswipe": "5.4.4",
|
||||
"punycode.js": "2.3.1",
|
||||
"rollup": "4.36.0",
|
||||
"sanitize-html": "2.15.0",
|
||||
"sass": "1.86.0",
|
||||
"shiki": "3.2.1",
|
||||
"rollup": "4.34.9",
|
||||
"sanitize-html": "2.14.0",
|
||||
"sass": "1.85.1",
|
||||
"shiki": "3.1.0",
|
||||
"strict-event-emitter-types": "2.0.0",
|
||||
"textarea-caret": "3.1.0",
|
||||
"three": "0.174.0",
|
||||
@@ -74,54 +74,54 @@
|
||||
"typescript": "5.8.2",
|
||||
"uuid": "11.1.0",
|
||||
"v-code-diff": "1.13.1",
|
||||
"vite": "6.2.2",
|
||||
"vite": "6.2.1",
|
||||
"vue": "3.5.13",
|
||||
"vuedraggable": "next",
|
||||
"wanakana": "5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@misskey-dev/summaly": "5.2.0",
|
||||
"@storybook/addon-actions": "8.6.7",
|
||||
"@storybook/addon-essentials": "8.6.7",
|
||||
"@storybook/addon-interactions": "8.6.7",
|
||||
"@storybook/addon-links": "8.6.7",
|
||||
"@storybook/addon-mdx-gfm": "8.6.7",
|
||||
"@storybook/addon-storysource": "8.6.7",
|
||||
"@storybook/blocks": "8.6.7",
|
||||
"@storybook/components": "8.6.7",
|
||||
"@storybook/core-events": "8.6.7",
|
||||
"@storybook/manager-api": "8.6.7",
|
||||
"@storybook/preview-api": "8.6.7",
|
||||
"@storybook/react": "8.6.7",
|
||||
"@storybook/react-vite": "8.6.7",
|
||||
"@storybook/test": "8.6.7",
|
||||
"@storybook/theming": "8.6.7",
|
||||
"@storybook/types": "8.6.7",
|
||||
"@storybook/vue3": "8.6.7",
|
||||
"@storybook/vue3-vite": "8.6.7",
|
||||
"@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",
|
||||
"@types/matter-js": "0.19.8",
|
||||
"@types/micromatch": "4.0.9",
|
||||
"@types/node": "22.13.11",
|
||||
"@types/node": "22.13.9",
|
||||
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
||||
"@types/sanitize-html": "2.13.0",
|
||||
"@types/seedrandom": "3.0.8",
|
||||
"@types/throttle-debounce": "5.0.2",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"@types/ws": "8.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||
"@typescript-eslint/parser": "8.27.0",
|
||||
"@vitest/coverage-v8": "3.0.9",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"@vitest/coverage-v8": "3.0.8",
|
||||
"@vue/runtime-core": "3.5.13",
|
||||
"acorn": "8.14.1",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "14.2.0",
|
||||
"cypress": "14.1.0",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-vue": "10.0.0",
|
||||
"fast-glob": "3.3.3",
|
||||
"happy-dom": "17.4.4",
|
||||
"happy-dom": "17.3.0",
|
||||
"intersection-observer": "0.12.2",
|
||||
"micromatch": "4.0.8",
|
||||
"msw": "2.7.3",
|
||||
@@ -131,12 +131,12 @@
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"seedrandom": "3.0.5",
|
||||
"start-server-and-test": "2.0.11",
|
||||
"storybook": "8.6.7",
|
||||
"start-server-and-test": "2.0.10",
|
||||
"storybook": "8.6.4",
|
||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||
"vite-node": "3.0.9",
|
||||
"vite-node": "3.0.8",
|
||||
"vite-plugin-turbosnap": "1.0.3",
|
||||
"vitest": "3.0.9",
|
||||
"vitest": "3.0.8",
|
||||
"vitest-fetch-mock": "0.4.5",
|
||||
"vue-component-type-helpers": "2.2.8",
|
||||
"vue-eslint-parser": "10.1.1",
|
||||
|
@@ -78,22 +78,6 @@ export async function common(createVue: () => App<Element>) {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
const localeVersion = miLocalStorage.getItem('localeVersion');
|
||||
const localeOutdated = (localeVersion == null || localeVersion !== version || locale == null);
|
||||
if (localeOutdated) {
|
||||
const res = await window.fetch(`/assets/locales/${lang}.${version}.json`);
|
||||
if (res.status === 200) {
|
||||
const newLocale = await res.text();
|
||||
const parsedNewLocale = JSON.parse(newLocale);
|
||||
miLocalStorage.setItem('locale', newLocale);
|
||||
miLocalStorage.setItem('localeVersion', version);
|
||||
updateLocale(parsedNewLocale);
|
||||
updateI18n(parsedNewLocale);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// タッチデバイスでCSSの:hoverを機能させる
|
||||
window.document.addEventListener('touchend', () => {}, { passive: true });
|
||||
|
||||
|
@@ -19,9 +19,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
:leaveToClass="transitionName === 'swipeAnimationLeft' ? $style.swipeAnimationLeft_leaveTo : $style.swipeAnimationRight_leaveTo"
|
||||
:style="`--swipe: ${pullDistance}px;`"
|
||||
>
|
||||
<div :key="tabModel">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<!-- 【注意】slot内の最上位要素に動的にkeyを設定すること -->
|
||||
<!-- 各最上位要素にユニークなkeyの指定がないとTransitionがうまく動きません -->
|
||||
<slot></slot>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,32 +0,0 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<MkStickyContainer class="_pageScrollable">
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="actions" :tabs="tabs"/></template>
|
||||
<slot></slot>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { PageHeaderItem } from '@/types/page-header.js';
|
||||
import type { Tab } from './MkPageHeader.tabs.vue';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
tabs?: Tab[];
|
||||
actions?: PageHeaderItem[] | null;
|
||||
thin?: boolean;
|
||||
hideTitle?: boolean;
|
||||
displayMyAvatar?: boolean;
|
||||
}>(), {
|
||||
tabs: () => ([] as Tab[]),
|
||||
});
|
||||
|
||||
const tab = defineModel<string>('tab');
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
||||
</style>
|
@@ -25,8 +25,6 @@ import MkPageHeader from './global/MkPageHeader.vue';
|
||||
import MkSpacer from './global/MkSpacer.vue';
|
||||
import MkStickyContainer from './global/MkStickyContainer.vue';
|
||||
import MkLazy from './global/MkLazy.vue';
|
||||
import PageWithHeader from './global/PageWithHeader.vue';
|
||||
import PageWithAnimBg from './global/PageWithAnimBg.vue';
|
||||
import SearchMarker from './global/SearchMarker.vue';
|
||||
import SearchLabel from './global/SearchLabel.vue';
|
||||
import SearchKeyword from './global/SearchKeyword.vue';
|
||||
@@ -62,8 +60,6 @@ export const components = {
|
||||
MkSpacer: MkSpacer,
|
||||
MkStickyContainer: MkStickyContainer,
|
||||
MkLazy: MkLazy,
|
||||
PageWithHeader: PageWithHeader,
|
||||
PageWithAnimBg: PageWithAnimBg,
|
||||
SearchMarker: SearchMarker,
|
||||
SearchLabel: SearchLabel,
|
||||
SearchKeyword: SearchKeyword,
|
||||
@@ -93,8 +89,6 @@ declare module '@vue/runtime-core' {
|
||||
MkSpacer: typeof MkSpacer;
|
||||
MkStickyContainer: typeof MkStickyContainer;
|
||||
MkLazy: typeof MkLazy;
|
||||
PageWithHeader: typeof PageWithHeader;
|
||||
PageWithAnimBg: typeof PageWithAnimBg;
|
||||
SearchMarker: typeof SearchMarker;
|
||||
SearchLabel: typeof SearchLabel;
|
||||
SearchKeyword: typeof SearchKeyword;
|
||||
|
@@ -23,8 +23,8 @@ export type Keys = (
|
||||
'fontSize' |
|
||||
'ui' |
|
||||
'ui_temp' |
|
||||
'locale' |
|
||||
'localeVersion' |
|
||||
'locale' | // DEPRECATED
|
||||
'localeVersion' | // DEPRECATED
|
||||
'theme' |
|
||||
'themeId' |
|
||||
'customCss' |
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<div style="overflow: clip;">
|
||||
<MkSpacer :contentMax="600" :marginMin="20">
|
||||
<div class="_gaps_m znqjceqz">
|
||||
@@ -129,7 +130,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<MkSpacer v-if="tab === 'overview'" :contentMax="600" :marginMin="20">
|
||||
<XOverview/>
|
||||
@@ -19,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkInstanceStats/>
|
||||
</MkSpacer>
|
||||
</MkHorizontalSwipe>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,11 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer :contentMax="1200">
|
||||
<MkAchievements :user="$i"/>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer v-if="file" :contentMax="600" :marginMin="16" :marginMax="32">
|
||||
<div v-if="tab === 'overview'" class="cxqhhsmd _gaps_m">
|
||||
<a class="thumbnail" :href="file.url" target="_blank">
|
||||
@@ -66,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkObjectView>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="600" :marginMin="16" :marginMax="32">
|
||||
<FormSuspense :p="init">
|
||||
<div v-if="tab === 'overview'" class="_gaps_m">
|
||||
@@ -207,7 +208,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800" :marginMin="16" :marginMax="32">
|
||||
<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
|
||||
<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
|
||||
@@ -13,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkKeyValue>
|
||||
</FormSuspense>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,13 +4,15 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
|
||||
<MkSpacer :contentMax="500">
|
||||
<div class="_gaps">
|
||||
<MkAd v-for="ad in instance.ads" :key="ad.id" :specify="ad"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<Transition
|
||||
:enterActiveClass="prefer.s.animation ? $style.fadeEnterActive : ''"
|
||||
@@ -43,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkLoading v-else/>
|
||||
</Transition>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div class="_gaps">
|
||||
<div :key="tab" class="_gaps">
|
||||
<MkInfo v-if="$i && $i.hasUnreadAnnouncement && tab === 'current'" warn>{{ i18n.ts.youHaveUnreadAnnouncements }}</MkInfo>
|
||||
<MkPagination ref="paginationEl" :key="tab" v-slot="{items}" :pagination="tab === 'current' ? paginationCurrent : paginationPast" class="_gaps">
|
||||
<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
|
||||
@@ -42,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<div ref="rootEl">
|
||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||
@@ -19,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<div class="_gaps_m">
|
||||
<div class="_gaps_m">
|
||||
@@ -29,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="500">
|
||||
<div v-if="state == 'fetch-session-error'">
|
||||
<p>{{ i18n.ts.somethingHappened }}</p>
|
||||
@@ -37,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkSignin @login="onLogin"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="900">
|
||||
<div class="_gaps">
|
||||
<div :class="$style.decorations">
|
||||
@@ -21,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<div v-if="channelId == null || channel != null" class="_gaps_m">
|
||||
<MkInput v-model="name">
|
||||
@@ -64,7 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700" :class="$style.main">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="channel && tab === 'overview'" class="_gaps">
|
||||
<div v-if="channel && tab === 'overview'" key="overview" class="_gaps">
|
||||
<div class="_panel" :class="$style.bannerContainer">
|
||||
<XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/>
|
||||
<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ti ti-star"></i></MkButton>
|
||||
@@ -32,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFoldableSection>
|
||||
</div>
|
||||
<div v-if="channel && tab === 'timeline'" class="_gaps">
|
||||
<div v-if="channel && tab === 'timeline'" key="timeline" class="_gaps">
|
||||
<MkInfo v-if="channel.isArchived" warn>{{ i18n.ts.thisChannelArchived }}</MkInfo>
|
||||
|
||||
<!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる -->
|
||||
@@ -40,10 +41,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after" @note="miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.id}`, Date.now())"/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'featured'">
|
||||
<div v-else-if="tab === 'featured'" key="featured">
|
||||
<MkNotes :pagination="featuredPagination"/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'search'">
|
||||
<div v-else-if="tab === 'search'" key="search">
|
||||
<div v-if="notesSearchAvailable" class="_gaps">
|
||||
<div>
|
||||
<MkInput v-model="searchQuery" @enter="search()">
|
||||
@@ -68,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</template>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="1200">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'search'" :class="$style.searchRoot">
|
||||
<div v-if="tab === 'search'" key="search" :class="$style.searchRoot">
|
||||
<div class="_gaps">
|
||||
<MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search" @enter="search">
|
||||
<template #prefix><i class="ti ti-search"></i></template>
|
||||
@@ -24,28 +25,28 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkChannelList :key="key" :pagination="channelPagination"/>
|
||||
</MkFoldableSection>
|
||||
</div>
|
||||
<div v-if="tab === 'featured'">
|
||||
<div v-if="tab === 'featured'" key="featured">
|
||||
<MkPagination v-slot="{items}" :pagination="featuredPagination">
|
||||
<div :class="$style.root">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
||||
</div>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'favorites'">
|
||||
<div v-else-if="tab === 'favorites'" key="favorites">
|
||||
<MkPagination v-slot="{items}" :pagination="favoritesPagination">
|
||||
<div :class="$style.root">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
||||
</div>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'following'">
|
||||
<div v-else-if="tab === 'following'" key="following">
|
||||
<MkPagination v-slot="{items}" :pagination="followingPagination">
|
||||
<div :class="$style.root">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>
|
||||
</div>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'owned'">
|
||||
<div v-else-if="tab === 'owned'" key="owned">
|
||||
<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
|
||||
<MkPagination v-slot="{items}" :pagination="ownedPagination">
|
||||
<div :class="$style.root">
|
||||
@@ -55,7 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,11 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkClickerGame/>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<div v-if="clip" class="_gaps">
|
||||
<div class="_panel">
|
||||
@@ -26,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkNotes :pagination="pagination" :detail="true"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer :contentMax="600" :marginMin="20">
|
||||
<div class="_gaps_m">
|
||||
<MkKeyValue :copy="instance.maintainerName">
|
||||
@@ -30,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="900">
|
||||
<div class="ogwlenmc">
|
||||
<div v-if="tab === 'local'" class="local">
|
||||
@@ -67,7 +68,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -10,11 +10,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</template>
|
||||
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<MkSpacer v-if="tab === 'info'" :contentMax="800">
|
||||
<MkSpacer v-if="tab === 'info'" key="info" :contentMax="800">
|
||||
<XFileInfo :fileId="fileId"/>
|
||||
</MkSpacer>
|
||||
|
||||
<MkSpacer v-else-if="tab === 'notes'" :contentMax="800">
|
||||
<MkSpacer v-else-if="tab === 'notes'" key="notes" :contentMax="800">
|
||||
<XNotes :fileId="fileId"/>
|
||||
</MkSpacer>
|
||||
</MkHorizontalSwipe>
|
||||
|
@@ -4,19 +4,20 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'featured'">
|
||||
<div v-if="tab === 'featured'" key="featured">
|
||||
<XFeatured/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'users'">
|
||||
<div v-else-if="tab === 'users'" key="users">
|
||||
<XUsers/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'roles'">
|
||||
<div v-else-if="tab === 'roles'" key="roles">
|
||||
<XRoles/>
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkPagination :pagination="pagination">
|
||||
<template #empty>
|
||||
@@ -21,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</template>
|
||||
</MkPagination>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<div class="_gaps">
|
||||
<MkInput v-model="title">
|
||||
@@ -36,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</template>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'featured'">
|
||||
<div v-if="tab === 'featured'" key="featured">
|
||||
<MkPagination v-slot="{items}" :pagination="featuredFlashsPagination">
|
||||
<div class="_gaps_s">
|
||||
<MkFlashPreview v-for="flash in items" :key="flash.id" :flash="flash"/>
|
||||
@@ -15,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkPagination>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'my'">
|
||||
<div v-else-if="tab === 'my'" key="my">
|
||||
<div class="_gaps">
|
||||
<MkButton gradate rounded style="margin: 0 auto;" @click="create()"><i class="ti ti-plus"></i></MkButton>
|
||||
<MkPagination v-slot="{items}" :pagination="myFlashsPagination">
|
||||
@@ -26,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'liked'">
|
||||
<div v-else-if="tab === 'liked'" key="liked">
|
||||
<MkPagination v-slot="{items}" :pagination="likedFlashsPagination">
|
||||
<div class="_gaps_s">
|
||||
<MkFlashPreview v-for="like in items" :key="like.flash.id" :flash="like.flash"/>
|
||||
@@ -35,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<Transition :name="prefer.s.animation ? 'fade' : ''" mode="out-in">
|
||||
<div v-if="flash" :key="flash.id">
|
||||
@@ -57,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkLoading v-else/>
|
||||
</Transition>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,40 +4,43 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<MkPagination ref="paginationComponent" :pagination="pagination">
|
||||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img :src="infoImageUrl" draggable="false"/>
|
||||
<div>{{ i18n.ts.noFollowRequests }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="{items}">
|
||||
<div class="mk-follow-requests _gaps">
|
||||
<div v-for="req in items" :key="req.id" class="user _panel">
|
||||
<MkAvatar class="avatar" :user="displayUser(req)" indicator link preview/>
|
||||
<div class="body">
|
||||
<div class="name">
|
||||
<MkA v-user-preview="displayUser(req).id" class="name" :to="userPage(displayUser(req))"><MkUserName :user="displayUser(req)"/></MkA>
|
||||
<p class="acct">@{{ acct(displayUser(req)) }}</p>
|
||||
</div>
|
||||
<div v-if="tab === 'list'" class="commands">
|
||||
<MkButton class="command" rounded primary @click="accept(displayUser(req))"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
|
||||
<MkButton class="command" rounded danger @click="reject(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
|
||||
</div>
|
||||
<div v-else class="commands">
|
||||
<MkButton class="command" rounded danger @click="cancel(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.cancel }}</MkButton>
|
||||
<div :key="tab" class="_gaps">
|
||||
<MkPagination ref="paginationComponent" :pagination="pagination">
|
||||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img :src="infoImageUrl" draggable="false"/>
|
||||
<div>{{ i18n.ts.noFollowRequests }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="{items}">
|
||||
<div class="mk-follow-requests _gaps">
|
||||
<div v-for="req in items" :key="req.id" class="user _panel">
|
||||
<MkAvatar class="avatar" :user="displayUser(req)" indicator link preview/>
|
||||
<div class="body">
|
||||
<div class="name">
|
||||
<MkA v-user-preview="displayUser(req).id" class="name" :to="userPage(displayUser(req))"><MkUserName :user="displayUser(req)"/></MkA>
|
||||
<p class="acct">@{{ acct(displayUser(req)) }}</p>
|
||||
</div>
|
||||
<div v-if="tab === 'list'" class="commands">
|
||||
<MkButton class="command" rounded primary @click="accept(displayUser(req))"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
|
||||
<MkButton class="command" rounded danger @click="reject(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
|
||||
</div>
|
||||
<div v-else class="commands">
|
||||
<MkButton class="command" rounded danger @click="cancel(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.cancel }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</MkPagination>
|
||||
</template>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800" :marginMin="16" :marginMax="32">
|
||||
<FormSuspense :p="init" class="_gaps">
|
||||
<MkInput v-model="title">
|
||||
@@ -33,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="1400">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'explore'">
|
||||
<div v-if="tab === 'explore'" key="explore">
|
||||
<MkFoldableSection class="_margin">
|
||||
<template #header><i class="ti ti-clock"></i>{{ i18n.ts.recentPosts }}</template>
|
||||
<MkPagination v-slot="{items}" :pagination="recentPostsPagination" :disableAutoLoad="true">
|
||||
@@ -25,14 +26,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkPagination>
|
||||
</MkFoldableSection>
|
||||
</div>
|
||||
<div v-else-if="tab === 'liked'">
|
||||
<div v-else-if="tab === 'liked'" key="liked">
|
||||
<MkPagination v-slot="{items}" :pagination="likedPostsPagination">
|
||||
<div :class="$style.items">
|
||||
<MkGalleryPostPreview v-for="like in items" :key="like.id" :post="like.post" class="post"/>
|
||||
</div>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'my'">
|
||||
<div v-else-if="tab === 'my'" key="my">
|
||||
<MkA to="/gallery/new" class="_link" style="margin: 16px;"><i class="ti ti-plus"></i> {{ i18n.ts.postToGallery }}</MkA>
|
||||
<MkPagination v-slot="{items}" :pagination="myPostsPagination">
|
||||
<div :class="$style.items">
|
||||
@@ -42,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="1000" :marginMin="16" :marginMax="32">
|
||||
<div class="_root">
|
||||
<Transition :name="prefer.s.animation ? 'fade' : ''" mode="out-in">
|
||||
@@ -58,7 +59,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</Transition>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<div class="_gaps">
|
||||
<div class="_panel" :class="$style.link">
|
||||
@@ -19,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithAnimBg>
|
||||
<MkPageWithAnimBg>
|
||||
<MkSpacer :contentMax="550" :marginMax="50">
|
||||
<MkLoading v-if="uiPhase === 'fetching'"/>
|
||||
<MkExtensionInstaller v-else-if="uiPhase === 'confirm' && data" :extension="data" @confirm="install()" @cancel="close_()">
|
||||
@@ -37,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithAnimBg>
|
||||
</MkPageWithAnimBg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -57,6 +57,7 @@ import { parseThemeCode, installTheme } from '@/theme.js';
|
||||
import { unisonReload } from '@/utility/unison-reload.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import MkPageWithAnimBg from '@/components/MkPageWithAnimBg.vue';
|
||||
|
||||
const uiPhase = ref<'fetching' | 'confirm' | 'error'>('fetching');
|
||||
const errorKV = ref<{
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer v-if="instance" :contentMax="600" :marginMin="16" :marginMax="32">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'overview'" class="_gaps_m">
|
||||
<div v-if="tab === 'overview'" key="overview" class="_gaps_m">
|
||||
<div class="fnfelxur">
|
||||
<img :src="faviconUrl" alt="" class="icon"/>
|
||||
<span class="name">{{ instance.name || `(${i18n.ts.unknown})` }}</span>
|
||||
@@ -90,7 +91,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<FormLink :to="`https://${host}/manifest.json`" external style="margin-bottom: 8px;">manifest.json</FormLink>
|
||||
</FormSection>
|
||||
</div>
|
||||
<div v-else-if="tab === 'chart'" class="_gaps_m">
|
||||
<div v-else-if="tab === 'chart'" key="chart" class="_gaps_m">
|
||||
<div class="cmhjzshl">
|
||||
<div class="selects">
|
||||
<MkSelect v-model="chartSrc" style="margin: 0 10px 0 0; flex: 1;">
|
||||
@@ -115,28 +116,27 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="tab === 'users'" class="_gaps_m">
|
||||
<div v-else-if="tab === 'users'" key="users" class="_gaps_m">
|
||||
<MkPagination v-slot="{items}" :pagination="usersPagination" style="display: grid; grid-template-columns: repeat(auto-fill,minmax(270px,1fr)); grid-gap: 12px;">
|
||||
<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" class="user" :to="`/admin/user/${user.id}`">
|
||||
<MkUserCardMini :user="user"/>
|
||||
</MkA>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'raw'" class="_gaps_m">
|
||||
<div v-else-if="tab === 'raw'" key="raw" class="_gaps_m">
|
||||
<MkObjectView tall :value="instance">
|
||||
</MkObjectView>
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import type { ChartSrc } from '@/components/MkChart.vue';
|
||||
import type { Paging } from '@/components/MkPagination.vue';
|
||||
import MkChart from '@/components/MkChart.vue';
|
||||
import type { ChartSrc } from '@/components/MkChart.vue';
|
||||
import MkObjectView from '@/components/MkObjectView.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
@@ -153,6 +153,7 @@ import { definePage } from '@/page.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkUserCardMini from '@/components/MkUserCardMini.vue';
|
||||
import MkPagination from '@/components/MkPagination.vue';
|
||||
import type { Paging } from '@/components/MkPagination.vue';
|
||||
import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue';
|
||||
import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js';
|
||||
import { dateString } from '@/filters/date.js';
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer v-if="!instance.disableRegistration || !($i && ($i.isAdmin || $i.policies.canInvite))" :contentMax="1200">
|
||||
<div :class="$style.root">
|
||||
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
|
||||
@@ -29,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkPagination>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer v-if="error != null" :contentMax="1200">
|
||||
<div :class="$style.root">
|
||||
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
|
||||
@@ -29,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkButton v-if="!list.isLiked" v-tooltip="i18n.ts.like" inline :class="$style.button" asLike @click="like()"><i class="ti ti-heart"></i><span v-if="1 > 0" class="count">{{ list.likedCount }}</span></MkButton>
|
||||
<MkButton inline @click="create()"><i class="ti ti-download" :class="$style.import"></i>{{ i18n.ts.import }}</MkButton>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<div v-if="state === 'done'" class="_buttonsCenter">
|
||||
<MkButton @click="close">{{ i18n.ts.close }}</MkButton>
|
||||
@@ -14,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkLoading/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithAnimBg>
|
||||
<MkPageWithAnimBg>
|
||||
<div :class="$style.formContainer">
|
||||
<div :class="$style.form">
|
||||
<MkAuthConfirm
|
||||
@@ -24,12 +24,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkAuthConfirm>
|
||||
</div>
|
||||
</div>
|
||||
</PageWithAnimBg>
|
||||
</MkPageWithAnimBg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, useTemplateRef } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import MkPageWithAnimBg from '@/components/MkPageWithAnimBg.vue';
|
||||
import MkAuthConfirm from '@/components/MkAuthConfirm.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
@@ -4,9 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
|
||||
<MkAntennaEditor @created="onAntennaCreated"/>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,9 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
|
||||
<MkAntennaEditor v-if="antenna" :antenna="antenna" @updated="onAntennaUpdated"/>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<div>
|
||||
<div v-if="antennas.length === 0" class="empty">
|
||||
@@ -23,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,22 +4,23 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'my'" class="_gaps">
|
||||
<div v-if="tab === 'my'" key="my" class="_gaps">
|
||||
<MkButton primary rounded class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
|
||||
|
||||
<MkPagination v-slot="{ items }" ref="pagingComponent" :pagination="pagination" class="_gaps">
|
||||
<MkClipPreview v-for="item in items" :key="item.id" :clip="item" :noUserInfo="true"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'favorites'" class="_gaps">
|
||||
<div v-else-if="tab === 'favorites'" key="favorites" class="_gaps">
|
||||
<MkClipPreview v-for="item in favorites" :key="item.id" :clip="item"/>
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<div class="_gaps">
|
||||
<div v-if="items.length === 0" class="empty">
|
||||
@@ -24,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700" :class="$style.main">
|
||||
<div v-if="list" class="_gaps">
|
||||
<MkFolder>
|
||||
@@ -48,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkFolder>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<div>
|
||||
<Transition :name="prefer.s.animation ? 'fade' : ''" mode="out-in">
|
||||
@@ -43,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</Transition>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,32 +4,33 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'all'">
|
||||
<div v-if="tab === 'all'" key="all">
|
||||
<XNotifications :class="$style.notifications" :excludeTypes="excludeTypes"/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'mentions'">
|
||||
<div v-else-if="tab === 'mentions'" key="mention">
|
||||
<MkNotes :pagination="mentionsPagination"/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'directNotes'">
|
||||
<div v-else-if="tab === 'directNotes'" key="directNotes">
|
||||
<MkNotes :pagination="directNotesPagination"/>
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { notificationTypes } from '@@/js/const.js';
|
||||
import XNotifications from '@/components/MkNotifications.vue';
|
||||
import MkNotes from '@/components/MkNotes.vue';
|
||||
import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { notificationTypes } from '@@/js/const.js';
|
||||
|
||||
const tab = ref('all');
|
||||
const includeTypes = ref<string[] | null>(null);
|
||||
|
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithAnimBg>
|
||||
<MkPageWithAnimBg>
|
||||
<div :class="$style.formContainer">
|
||||
<div :class="$style.form">
|
||||
<MkAuthConfirm
|
||||
@@ -18,11 +18,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</PageWithAnimBg>
|
||||
</MkPageWithAnimBg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import * as Misskey from 'misskey-js';
|
||||
import MkPageWithAnimBg from '@/components/MkPageWithAnimBg.vue';
|
||||
import { definePage } from '@/page.js';
|
||||
import MkAuthConfirm from '@/components/MkAuthConfirm.vue';
|
||||
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<div class="jqqmcavi">
|
||||
<MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ i18n.ts._pages.viewPage }}</MkButton>
|
||||
@@ -56,19 +57,19 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, provide, watch, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { url } from '@@/js/config.js';
|
||||
import XBlocks from './page-editor.blocks.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import { url } from '@@/js/config.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { selectFile } from '@/utility/select-file.js';
|
||||
@@ -265,8 +266,8 @@ const headerTabs = computed(() => [{
|
||||
|
||||
definePage(() => ({
|
||||
title: props.initPageId ? i18n.ts._pages.editPage
|
||||
: props.initPageName && props.initUser ? i18n.ts._pages.readPage
|
||||
: i18n.ts._pages.newPage,
|
||||
: props.initPageName && props.initUser ? i18n.ts._pages.readPage
|
||||
: i18n.ts._pages.newPage,
|
||||
icon: 'ti ti-pencil',
|
||||
}));
|
||||
</script>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<Transition
|
||||
:enterActiveClass="prefer.s.animation ? $style.fadeEnterActive : ''"
|
||||
@@ -93,7 +94,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkLoading v-else/>
|
||||
</Transition>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="700">
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<div v-if="tab === 'featured'">
|
||||
<div v-if="tab === 'featured'" key="featured">
|
||||
<MkPagination v-slot="{items}" :pagination="featuredPagesPagination">
|
||||
<div class="_gaps">
|
||||
<MkPagePreview v-for="page in items" :key="page.id" :page="page"/>
|
||||
@@ -15,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkPagination>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'my'" class="_gaps">
|
||||
<div v-else-if="tab === 'my'" key="my" class="_gaps">
|
||||
<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
|
||||
<MkPagination v-slot="{items}" :pagination="myPagesPagination">
|
||||
<div class="_gaps">
|
||||
@@ -24,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkPagination>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'liked'">
|
||||
<div v-else-if="tab === 'liked'" key="liked">
|
||||
<MkPagination v-slot="{items}" :pagination="likedPagesPagination">
|
||||
<div class="_gaps">
|
||||
<MkPagePreview v-for="like in items" :key="like.page.id" :page="like.page"/>
|
||||
@@ -33,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="600" :marginMin="16">
|
||||
<div class="_gaps_m">
|
||||
<FormSplit>
|
||||
@@ -28,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</FormSection>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="600" :marginMin="16">
|
||||
<div class="_gaps_m">
|
||||
<FormInfo warn>{{ i18n.ts.editTheseSettingsMayBreakAccount }}</FormInfo>
|
||||
@@ -40,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</template>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="600" :marginMin="16">
|
||||
<MkButton primary @click="createKey">{{ i18n.ts._registry.createKey }}</MkButton>
|
||||
|
||||
@@ -17,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</FormSection>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer v-if="token" :contentMax="700" :marginMin="16" :marginMax="32">
|
||||
<div class="_gaps_m">
|
||||
<MkInput v-model="password" type="password">
|
||||
@@ -15,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkButton primary @click="save">{{ i18n.ts.save }}</MkButton>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :tabs="headerTabs"/></template>
|
||||
<MkSpacer v-if="error != null" :contentMax="1200">
|
||||
<div :class="$style.root">
|
||||
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
|
||||
@@ -31,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<div>{{ i18n.ts.nothing }}</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
|
||||
<MkSpacer :contentMax="800">
|
||||
<div :class="$style.root">
|
||||
<div class="_gaps_s">
|
||||
@@ -51,15 +53,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onDeactivated, onUnmounted, ref, watch, computed } from 'vue';
|
||||
import { Interpreter, Parser, utils } from '@syuilo/aiscript';
|
||||
import type { Ref } from 'vue';
|
||||
import type { AsUiComponent } from '@/aiscript/ui.js';
|
||||
import type { AsUiRoot } from '@/aiscript/ui.js';
|
||||
import { Interpreter, Parser, utils } from '@syuilo/aiscript';
|
||||
import MkContainer from '@/components/MkContainer.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkTextarea from '@/components/MkTextarea.vue';
|
||||
@@ -70,10 +70,13 @@ import { $i } from '@/i.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { registerAsUiLib } from '@/aiscript/ui.js';
|
||||
import type { AsUiComponent } from '@/aiscript/ui.js';
|
||||
import MkAsUi from '@/components/MkAsUi.vue';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
|
||||
import type { AsUiRoot } from '@/aiscript/ui.js';
|
||||
|
||||
const parser = new Parser();
|
||||
let aiscript: Interpreter;
|
||||
const code = ref('');
|
||||
@@ -100,7 +103,7 @@ function stringifyUiProps(uiProps) {
|
||||
return JSON.stringify(
|
||||
{ ...uiProps, type: undefined, id: undefined },
|
||||
(k, v) => typeof v === 'function' ? '<function>' : v,
|
||||
2,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -4,9 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
|
||||
<MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
|
||||
<MkSpacer v-if="tab === 'note'" :contentMax="800">
|
||||
<MkSpacer v-if="tab === 'note'" key="note" :contentMax="800">
|
||||
<div v-if="notesSearchAvailable || ignoreNotesSearchAvailable">
|
||||
<XNote v-bind="props"/>
|
||||
</div>
|
||||
@@ -15,11 +17,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkSpacer>
|
||||
|
||||
<MkSpacer v-else-if="tab === 'user'" :contentMax="800">
|
||||
<MkSpacer v-else-if="tab === 'user'" key="user" :contentMax="800">
|
||||
<XUser v-bind="props"/>
|
||||
</MkSpacer>
|
||||
</MkHorizontalSwipe>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :tabs="headerTabs" :actions="headerActions">
|
||||
<MkStickyContainer class="_pageScrollable">
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="900" :marginMin="20" :marginMax="32">
|
||||
<div ref="el" class="vvcocwet" :class="{ wide: !narrow }">
|
||||
<div class="body">
|
||||
@@ -26,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</mkstickycontainer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@@ -606,8 +606,6 @@ const defaultFollowWithReplies = prefer.model('defaultFollowWithReplies');
|
||||
|
||||
watch(lang, () => {
|
||||
miLocalStorage.setItem('lang', lang.value as string);
|
||||
miLocalStorage.removeItem('locale');
|
||||
miLocalStorage.removeItem('localeVersion');
|
||||
});
|
||||
|
||||
watch([
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkPostForm
|
||||
v-if="state === 'writing'"
|
||||
@@ -25,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkButton @click="goToMisskey">{{ i18n.ts.goToMisskey }}</MkButton>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithAnimBg>
|
||||
<MkPageWithAnimBg>
|
||||
<div :class="$style.formContainer">
|
||||
<form :class="$style.form" class="_panel" @submit.prevent="submit()">
|
||||
<div :class="$style.banner">
|
||||
@@ -20,12 +20,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</PageWithAnimBg>
|
||||
</MkPageWithAnimBg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkPageWithAnimBg from '@/components/MkPageWithAnimBg.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkNotes ref="notes" class="" :pagination="pagination"/>
|
||||
</MkSpacer>
|
||||
@@ -15,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</template>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -62,7 +63,7 @@ const headerActions = computed(() => [{
|
||||
genEmbedCode('tags', props.tag);
|
||||
},
|
||||
}], ev.currentTarget ?? ev.target);
|
||||
},
|
||||
}
|
||||
}]);
|
||||
|
||||
const headerTabs = computed(() => []);
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800" :marginMin="16" :marginMax="32">
|
||||
<div class="cwepdizn _gaps_m">
|
||||
<MkFolder :defaultOpen="true">
|
||||
@@ -68,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkFolder>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,10 +4,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader v-model:tab="src" :actions="headerActions" :tabs="$i ? headerTabs : headerTabsWhenNotLogin" :displayMyAvatar="true">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="src" :actions="headerActions" :tabs="$i ? headerTabs : headerTabsWhenNotLogin" :displayMyAvatar="true"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkHorizontalSwipe v-model:tab="src" :tabs="$i ? headerTabs : headerTabsWhenNotLogin">
|
||||
<div ref="rootEl">
|
||||
<div :key="src" ref="rootEl">
|
||||
<MkInfo v-if="isBasicTimeline(src) && !store.r.timelineTutorials.value[src]" style="margin-bottom: var(--MI-margin);" closable @close="closeTutorial()">
|
||||
{{ i18n.ts._timelineDescription[src] }}
|
||||
</MkInfo>
|
||||
@@ -30,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkHorizontalSwipe>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<div ref="rootEl">
|
||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||
@@ -19,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</PageWithHeader>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user