Merge branch 'refactor-14530' of https://github.com/kakkokari-gtyih/misskey into refactor-14530

This commit is contained in:
kakkokari-gtyih 2024-09-10 17:22:28 +09:00
commit a9ec768537
14 changed files with 251 additions and 21 deletions

View File

@ -0,0 +1,203 @@
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Misskey configuration
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# ┌─────┐
#───┘ URL └─────────────────────────────────────────────────────
# Final accessible URL seen by a user.
url: 'http://misskey.local'
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!
# ┌───────────────────────┐
#───┘ Port and TLS settings └───────────────────────────────────
#
# Misskey requires a reverse proxy to support HTTPS connections.
#
# +----- https://example.tld/ ------------+
# +------+ |+-------------+ +----------------+|
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
# +------+ |+-------------+ +----------------+|
# +---------------------------------------+
#
# You need to set up a reverse proxy. (e.g. nginx)
# An encrypted connection with HTTPS is highly recommended
# because tokens may be transferred in GET requests.
# The port that your Misskey server should listen on.
port: 61812
# ┌──────────────────────────┐
#───┘ PostgreSQL configuration └────────────────────────────────
db:
host: db
port: 5432
# Database name
db: misskey
# Auth
user: postgres
pass: postgres
# Whether disable Caching queries
#disableCache: true
# Extra Connection options
#extra:
# ssl: true
dbReplications: false
# You can configure any number of replicas here
#dbSlaves:
# -
# host:
# port:
# db:
# user:
# pass:
# -
# host:
# port:
# db:
# user:
# pass:
# ┌─────────────────────┐
#───┘ Redis configuration └─────────────────────────────────────
redis:
host: redis
port: 6379
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
#pass: example-pass
#prefix: example-prefix
#db: 1
#redisForPubsub:
# host: redis
# port: 6379
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
# #pass: example-pass
# #prefix: example-prefix
# #db: 1
#redisForJobQueue:
# host: redis
# port: 6379
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
# #pass: example-pass
# #prefix: example-prefix
# #db: 1
#redisForTimelines:
# host: redis
# port: 6379
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
# #pass: example-pass
# #prefix: example-prefix
# #db: 1
# ┌───────────────────────────┐
#───┘ MeiliSearch configuration └─────────────────────────────
#meilisearch:
# host: meilisearch
# port: 7700
# apiKey: ''
# ssl: true
# index: ''
# ┌───────────────┐
#───┘ ID generation └───────────────────────────────────────────
# You can select the ID generation method.
# You don't usually need to change this setting, but you can
# change it according to your preferences.
# Available methods:
# aid ... Short, Millisecond accuracy
# aidx ... Millisecond accuracy
# meid ... Similar to ObjectID, Millisecond accuracy
# ulid ... Millisecond accuracy
# objectid ... This is left for backward compatibility
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# ID SETTINGS AFTER THAT!
id: 'aidx'
# ┌────────────────┐
#───┘ Error tracking └──────────────────────────────────────────
# Sentry is available for error tracking.
# See the Sentry documentation for more details on options.
#sentryForBackend:
# enableNodeProfiling: true
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
#sentryForFrontend:
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
# ┌─────────────────────┐
#───┘ Other configuration └─────────────────────────────────────
# Whether disable HSTS
#disableHsts: true
# Number of worker processes
#clusterLimit: 1
# Job concurrency per worker
# deliverJobConcurrency: 128
# inboxJobConcurrency: 16
# Job rate limiter
# deliverJobPerSec: 128
# inboxJobPerSec: 32
# Job attempts
# deliverJobMaxAttempts: 12
# inboxJobMaxAttempts: 8
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Proxy for HTTP/HTTPS
#proxy: http://127.0.0.1:3128
proxyBypassHosts:
- api.deepl.com
- api-free.deepl.com
- www.recaptcha.net
- hcaptcha.com
- challenges.cloudflare.com
# Proxy for SMTP/SMTPS
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
# Media Proxy
#mediaProxy: https://example.com/proxy
# Proxy remote files (default: true)
proxyRemoteFiles: true
# Sign to ActivityPub GET request (default: true)
signToActivityPubGet: true
allowedPrivateNetworks: [
'127.0.0.1/32'
]
# Upload or download file size limits (bytes)
#maxFileSize: 262144000

View File

@ -3,6 +3,8 @@
set -xe set -xe
sudo chown node node_modules sudo chown node node_modules
sudo apt-get update
sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
git config --global --add safe.directory /workspace git config --global --add safe.directory /workspace
git submodule update --init git submodule update --init
corepack install corepack install
@ -12,3 +14,4 @@ pnpm install --frozen-lockfile
cp .devcontainer/devcontainer.yml .config/default.yml cp .devcontainer/devcontainer.yml .config/default.yml
pnpm build pnpm build
pnpm migrate pnpm migrate
pnpm exec cypress install

1
.gitignore vendored
View File

@ -35,6 +35,7 @@ coverage
!/.config/example.yml !/.config/example.yml
!/.config/docker_example.yml !/.config/docker_example.yml
!/.config/docker_example.env !/.config/docker_example.env
!/.config/cypress-devcontainer.yml
docker-compose.yml docker-compose.yml
compose.yml compose.yml
.devcontainer/compose.yml .devcontainer/compose.yml

View File

@ -6,12 +6,12 @@
### Client ### Client
- Feat: ノート単体・ユーザーのノート・クリップのノートの埋め込み機能 - Feat: ノート単体・ユーザーのノート・クリップのノートの埋め込み機能
- 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です - 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です
- サイズ制限を超過するファイルをアップロードしようとした際にエラーを出すように - Enhance: サイズ制限を超過するファイルをアップロードしようとした際にエラーを出すように
- Enhance: アイコンデコレーション管理画面にプレビューを追加 - Enhance: アイコンデコレーション管理画面にプレビューを追加
- Fix: サーバーメトリクスが2つ以上あるとリロード直後の表示がおかしくなる問題を修正 - Fix: サーバーメトリクスが2つ以上あるとリロード直後の表示がおかしくなる問題を修正
### Server ### Server
- ファイルがサイズの制限を超えてアップロードされた際にエラーを返さなかった問題を修正 - Fix: ファイルがサイズの制限を超えてアップロードされた際にエラーを返さなかった問題を修正
## 2024.8.0 ## 2024.8.0

View File

@ -37,6 +37,7 @@
"cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts", "cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts",
"cy:run": "pnpm cypress run", "cy:run": "pnpm cypress run",
"e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run", "e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run",
"e2e-dev-container": "cp ./.config/cypress-devcontainer.yml ./.config/test.yml && pnpm start-server-and-test start:test http://localhost:61812 cy:run",
"jest": "cd packages/backend && pnpm jest", "jest": "cd packages/backend && pnpm jest",
"jest-and-coverage": "cd packages/backend && pnpm jest-and-coverage", "jest-and-coverage": "cd packages/backend && pnpm jest-and-coverage",
"test": "pnpm -r test", "test": "pnpm -r test",

View File

@ -10,23 +10,42 @@ import '@tabler/icons-webfont/dist/tabler-icons.scss';
import '@/style.scss'; import '@/style.scss';
import { createApp, defineAsyncComponent } from 'vue'; import { createApp, defineAsyncComponent } from 'vue';
import lightTheme from '@@/themes/l-light.json5'; import defaultLightTheme from '@@/themes/l-light.json5';
import darkTheme from '@@/themes/d-dark.json5'; import defaultDarkTheme from '@@/themes/d-dark.json5';
import { MediaProxy } from '@@/js/media-proxy.js'; import { MediaProxy } from '@@/js/media-proxy.js';
import { applyTheme } from './theme.js'; import { applyTheme, assertIsTheme } from '@/theme.js';
import { fetchCustomEmojis } from './custom-emojis.js'; import { fetchCustomEmojis } from '@/custom-emojis.js';
import { DI } from './di.js'; import { DI } from '@/di.js';
import { serverMetadata } from './server-metadata.js'; import { serverMetadata } from '@/server-metadata.js';
import { url } from '@@/js/config.js'; import { url } from '@@/js/config.js';
import { parseEmbedParams } from '@@/js/embed-page.js'; import { parseEmbedParams } from '@@/js/embed-page.js';
import { postMessageToParentWindow, setIframeId } from '@/post-message.js'; import { postMessageToParentWindow, setIframeId } from '@/post-message.js';
console.info('Misskey Embed'); import type { Theme } from '@/theme.js';
console.log('Misskey Embed');
const params = new URLSearchParams(location.search); const params = new URLSearchParams(location.search);
const embedParams = parseEmbedParams(params); const embedParams = parseEmbedParams(params);
console.info(embedParams); if (_DEV_) console.log(embedParams);
function parseThemeOrNull(theme: string | null): Theme | null {
if (theme == null) return null;
try {
const parsed = JSON.parse(theme);
if (assertIsTheme(parsed)) {
return parsed;
} else {
return null;
}
} catch (err) {
return null;
}
}
const lightTheme = parseThemeOrNull(serverMetadata.defaultLightTheme) ?? defaultLightTheme;
const darkTheme = parseThemeOrNull(serverMetadata.defaultDarkTheme) ?? defaultDarkTheme;
if (embedParams.colorMode === 'dark') { if (embedParams.colorMode === 'dark') {
applyTheme(darkTheme); applyTheme(darkTheme);

View File

@ -135,7 +135,7 @@ misskeyApi('clips/show', {
.instanceIcon { .instanceIcon {
height: 24px; height: 24px;
border-radius: 4px; border-radius: 3px;
} }
} }
</style> </style>

View File

@ -119,7 +119,7 @@ function top(ev: MouseEvent) {
.instanceIcon { .instanceIcon {
height: 24px; height: 24px;
border-radius: 4px; border-radius: 3px;
} }
} }
</style> </style>

View File

@ -132,7 +132,7 @@ misskeyApi('users/show', {
.instanceIcon { .instanceIcon {
height: 24px; height: 24px;
border-radius: 4px; border-radius: 3px;
} }
} }
</style> </style>

View File

@ -3,13 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import * as Misskey from 'misskey-js';
import { misskeyApi } from '@/misskey-api.js'; import { misskeyApi } from '@/misskey-api.js';
const providedMetaEl = document.getElementById('misskey_meta'); const providedMetaEl = document.getElementById('misskey_meta');
const _serverMetadata = (providedMetaEl && providedMetaEl.textContent) ? JSON.parse(providedMetaEl.textContent) : null; const _serverMetadata: Misskey.entities.MetaDetailed | null = (providedMetaEl && providedMetaEl.textContent) ? JSON.parse(providedMetaEl.textContent) : null;
// NOTE: devモードのときしか _serverMetadata が null になることは無い // NOTE: devモードのときしか _serverMetadata が null になることは無い
export const serverMetadata = _serverMetadata ?? await misskeyApi('meta', { export const serverMetadata: Misskey.entities.MetaDetailed = _serverMetadata ?? await misskeyApi('meta', {
detail: true, detail: true,
}); });

View File

@ -26,6 +26,10 @@ export type Theme = {
let timeout: number | null = null; let timeout: number | null = null;
export function assertIsTheme(theme: Record<string, unknown>): theme is Theme {
return typeof theme === 'object' && theme !== null && 'id' in theme && 'name' in theme && 'author' in theme && 'props' in theme;
}
export function applyTheme(theme: Theme, persist = true) { export function applyTheme(theme: Theme, persist = true) {
if (timeout) window.clearTimeout(timeout); if (timeout) window.clearTimeout(timeout);
@ -35,8 +39,6 @@ export function applyTheme(theme: Theme, persist = true) {
document.documentElement.classList.remove('_themeChanging_'); document.documentElement.classList.remove('_themeChanging_');
}, 1000); }, 1000);
const colorScheme = theme.base === 'dark' ? 'dark' : 'light';
// Deep copy // Deep copy
const _theme = JSON.parse(JSON.stringify(theme)); const _theme = JSON.parse(JSON.stringify(theme));
@ -58,7 +60,7 @@ export function applyTheme(theme: Theme, persist = true) {
document.documentElement.style.setProperty(`--${k}`, v.toString()); document.documentElement.style.setProperty(`--${k}`, v.toString());
} }
document.documentElement.style.setProperty('color-scheme', colorScheme); // iframeを正常に透過させるために、cssのcolor-schemeは `light dark;` 固定にしてある。style.scss参照
} }
function compile(theme: Theme): Record<string, string> { function compile(theme: Theme): Record<string, string> {

View File

@ -40,7 +40,7 @@ import XNotFound from '@/pages/not-found.vue';
const page = location.pathname.split('/')[2]; const page = location.pathname.split('/')[2];
const contentId = location.pathname.split('/')[3]; const contentId = location.pathname.split('/')[3];
console.log(page, contentId); if (_DEV_) console.log(page, contentId);
const embedParams = inject(DI.embedParams, defaultEmbedParams); const embedParams = inject(DI.embedParams, defaultEmbedParams);

View File

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@close="cancel()" @close="cancel()"
@closed="$emit('closed')" @closed="$emit('closed')"
> >
<template #header>{{ i18n.ts._embedCodeGen.title }}</template> <template #header><i class="ti ti-code"></i> {{ i18n.ts._embedCodeGen.title }}</template>
<div :class="$style.embedCodeGenRoot"> <div :class="$style.embedCodeGenRoot">
<Transition <Transition

View File

@ -52,7 +52,7 @@ export const getBuiltinThemes = () => Promise.all(
'd-cherry', 'd-cherry',
'd-ice', 'd-ice',
'd-u0', 'd-u0',
].map(name => import(`@/themes/${name}.json5`).then(({ default: _default }): Theme => _default)), ].map(name => import(`@@/themes/${name}.json5`).then(({ default: _default }): Theme => _default)),
); );
export const getBuiltinThemesRef = () => { export const getBuiltinThemesRef = () => {