Skip to content

Commit

Permalink
Merge remote-branch 'misskey/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
noridev committed Jan 8, 2025
2 parents 20d713e + 13439e0 commit 3c94611
Show file tree
Hide file tree
Showing 24 changed files with 1,496 additions and 109 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
(Cherry-picked from https://github.com/Otaku-Social/maniakey/pull/13)
- Enhance: 照会に失敗した場合、その理由を表示するように
- Enhance: AiScriptのセーブデータを明示的に削除する関数`Mk:remove`を追加
- Enhance: AiScriptの拡張API関数において引数の型チェックをより厳格に
- Fix: 画面サイズが変わった際にナビゲーションバーが自動で折りたたまれない問題を修正
- Fix: サーバー情報メニューに区切り線が不足していたのを修正
- Fix: ノートがログインしているユーザーしか見れない場合にログインダイアログを閉じるとその後の動線がなくなる問題を修正
Expand All @@ -20,13 +21,17 @@
(Cherry-picked from https://github.com/TeamNijimiss/misskey/commit/800359623e41a662551d774de15b0437b6849bb4)
- Fix: ノート作成画面でファイルの添付可能個数を超えてもノートボタンが押せていた問題を修正
- Fix: 「アカウントを管理」画面で、ユーザー情報の取得に失敗したアカウント(削除されたアカウントなど)が表示されない問題を修正
- Fix: 言語データのキャッシュ状況によっては、埋め込みウィジェットが正しく起動しない問題を修正

### Server
- Enhance: pg_bigmが利用できるよう、ノートの検索をILIKE演算子でなくLIKE演算子でLOWER()をかけたテキストに対して行うように
- Fix: ユーザーのプロフィール画面をアドレス入力などで直接表示した際に概要タブの描画に失敗する問題の修正( #15032 )
- Fix: 起動前の疎通チェックが機能しなくなっていた問題を修正
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/737)

- Fix: ロックダウンされた期間指定のノートがStreaming経由でLTLに出現するのを修正 ( #15200 )
- Fix: disableClustering設定時の初期化ロジックを調整( #15223 )
- Fix: ActivityPubリクエストかどうかの判定が正しくない問題を修正
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/869)

## 2024.11.0

Expand Down
20 changes: 13 additions & 7 deletions packages/backend/src/boot/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,22 @@ process.on('warning', warning => {

//#endregion

if (cluster.isPrimary || envOption.disableClustering) {
await masterMain();

if (!envOption.disableClustering) {
if (cluster.isPrimary) {
logger.info(`Start main process... pid: ${process.pid}`);
await masterMain();
ev.mount();
} else if (cluster.isWorker) {
logger.info(`Start worker process... pid: ${process.pid}`);
await workerMain();
} else {
throw new Error('Unknown process type');
}
}

if (cluster.isWorker || envOption.disableClustering) {
await workerMain();
} else {
// 非clusterの場合はMasterのみが起動するため、Workerの処理は行わない(cluster.isWorker === trueの状態でこのブロックに来ることはない)
logger.info(`Start main process... pid: ${process.pid}`);
await masterMain();
ev.mount();
}

readyRef.value = true;
Expand Down
24 changes: 18 additions & 6 deletions packages/backend/src/boot/master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,37 @@ export async function masterMain() {
});
}

if (envOption.disableClustering) {
bootLogger.info(
`mode: [disableClustering: ${envOption.disableClustering}, onlyServer: ${envOption.onlyServer}, onlyQueue: ${envOption.onlyQueue}]`
);

if (!envOption.disableClustering) {
// clusterモジュール有効時

if (envOption.onlyServer) {
await server();
// onlyServer かつ enableCluster な場合、メインプロセスはforkのみに制限する(listenしない)。
// ワーカープロセス側でlistenすると、メインプロセスでポートへの着信を受け入れてワーカープロセスへの分配を行う動作をする。
// そのため、メインプロセスでも直接listenするとポートの競合が発生して起動に失敗してしまう。
// see: https://nodejs.org/api/cluster.html#cluster
} else if (envOption.onlyQueue) {
await jobQueue();
} else {
await server();
await jobQueue();
}

await spawnWorkers(config.clusterLimit);
} else {
// clusterモジュール無効時

if (envOption.onlyServer) {
// nop
await server();
} else if (envOption.onlyQueue) {
// nop
await jobQueue();
} else {
await server();
await jobQueue();
}

await spawnWorkers(config.clusterLimit);
}

if (envOption.onlyQueue) {
Expand Down
9 changes: 7 additions & 2 deletions packages/backend/src/core/entities/NoteEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ export class NoteEntityService implements OnModuleInit {
}

@bindThis
private async hideNote(packedNote: Packed<'Note'>, meId: MiUser['id'] | null): Promise<void> {
// FIXME: このvisibility変更処理が当関数にあるのは若干不自然かもしれない(関数名を treatVisibility とかに変える手もある)
private treatVisibility(packedNote: Packed<'Note'>): Packed<'Note'>['visibility'] {
if (packedNote.visibility === 'public' || packedNote.visibility === 'home') {
const followersOnlyBefore = packedNote.user.makeNotesFollowersOnlyBefore;
if ((followersOnlyBefore != null)
Expand All @@ -118,7 +117,11 @@ export class NoteEntityService implements OnModuleInit {
packedNote.visibility = 'followers';
}
}
return packedNote.visibility;
}

@bindThis
private async hideNote(packedNote: Packed<'Note'>, meId: MiUser['id'] | null): Promise<void> {
if (meId === packedNote.userId) return;

// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
Expand Down Expand Up @@ -479,6 +482,8 @@ export class NoteEntityService implements OnModuleInit {
} : {}),
});

this.treatVisibility(packed);

if (!opts.skipHide) {
await this.hideNote(packed, meId);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/server/ActivityPubServerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,8 @@ export class ActivityPubServerService {
},
deriveConstraint(request: IncomingMessage) {
const accepted = accepts(request).type(['html', ACTIVITY_JSON, LD_JSON]);
const isAp = typeof accepted === 'string' && !accepted.match(/html/);
return isAp ? 'ap' : 'html';
if (accepted === false) return null;
return accepted !== 'html' ? 'ap' : 'html';
},
});

Expand Down
4 changes: 2 additions & 2 deletions packages/cherrypick-js/etc/cherrypick-js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
import { EventEmitter } from 'eventemitter3';
import { Options } from 'reconnecting-websocket';
import type { PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/types';
import _ReconnectingWebsocket from 'reconnecting-websocket';

// Warning: (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts
//
Expand Down Expand Up @@ -3341,7 +3341,7 @@ export class Stream extends EventEmitter<StreamEvents> implements IStream {
constructor(origin: string, user: {
token: string;
} | null, options?: {
WebSocket?: _ReconnectingWebsocket.Options['WebSocket'];
WebSocket?: Options['WebSocket'];
});
// (undocumented)
close(): void;
Expand Down
12 changes: 7 additions & 5 deletions packages/cherrypick-js/src/streaming.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { EventEmitter } from 'eventemitter3';
import _ReconnectingWebsocket from 'reconnecting-websocket';
import _ReconnectingWebSocket, { Options } from 'reconnecting-websocket';
import type { BroadcastEvents, Channels } from './streaming.types.js';

const ReconnectingWebsocket = _ReconnectingWebsocket as unknown as typeof _ReconnectingWebsocket['default'];
// コンストラクタとクラスそのものの定義が上手く解決出来ないため再定義
const ReconnectingWebSocketConstructor = _ReconnectingWebSocket as unknown as typeof _ReconnectingWebSocket.default;
type ReconnectingWebSocket = _ReconnectingWebSocket.default;

export function urlQuery(obj: Record<string, string | number | boolean | undefined>): string {
const params = Object.entries(obj)
Expand Down Expand Up @@ -43,15 +45,15 @@ export interface IStream extends EventEmitter<StreamEvents> {
*/
// eslint-disable-next-line import/no-default-export
export default class Stream extends EventEmitter<StreamEvents> implements IStream {
private stream: _ReconnectingWebsocket.default;
private stream: ReconnectingWebSocket;
public state: 'initializing' | 'reconnecting' | 'connected' = 'initializing';
private sharedConnectionPools: Pool[] = [];
private sharedConnections: SharedConnection[] = [];
private nonSharedConnections: NonSharedConnection[] = [];
private idCounter = 0;

constructor(origin: string, user: { token: string; } | null, options?: {
WebSocket?: _ReconnectingWebsocket.Options['WebSocket'];
WebSocket?: Options['WebSocket'];
}) {
super();

Expand Down Expand Up @@ -80,7 +82,7 @@ export default class Stream extends EventEmitter<StreamEvents> implements IStrea

const wsOrigin = origin.replace('http://', 'ws://').replace('https://', 'wss://');

this.stream = new ReconnectingWebsocket(`${wsOrigin}/streaming?${query}`, '', {
this.stream = new ReconnectingWebSocketConstructor(`${wsOrigin}/streaming?${query}`, '', {
minReconnectionDelay: 1, // https://github.com/pladaria/reconnecting-websocket/issues/91
WebSocket: options.WebSocket,
});
Expand Down
21 changes: 19 additions & 2 deletions packages/frontend-embed/src/boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ 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 } from '@@/js/config.js';
import { url, version, basedMisskeyVersion, 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';
Expand All @@ -22,7 +22,7 @@ import { DI } from '@/di.js';
import { serverMetadata } from '@/server-metadata.js';
import { postMessageToParentWindow, setIframeId } from '@/post-message.js';
import { serverContext } from '@/server-context.js';
import { i18n } from '@/i18n.js';
import { i18n, updateI18n } from '@/i18n.js';

console.log('CherryPick Embed');

Expand Down Expand Up @@ -70,6 +70,23 @@ if (embedParams.colorMode === 'dark') {
}
//#endregion

//#region Detect language & fetch translations
const localeVersion = localStorage.getItem('localeVersion');
const lastBasedMisskeyVersion = localStorage.getItem('lastBasedMisskeyVersion');
const localeOutdated = (localeVersion == null || localeVersion !== version || lastBasedMisskeyVersion !== basedMisskeyVersion || 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';

Expand Down
2 changes: 0 additions & 2 deletions packages/frontend-embed/src/components/EmMfm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,6 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
return [h(EmEmoji, {
key: Math.random(),
emoji: token.props.emoji,
menu: props.enableEmojiMenu,
menuReaction: props.enableEmojiMenuReaction,
})];
}

Expand Down
3 changes: 2 additions & 1 deletion packages/frontend-embed/src/components/EmNotes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ SPDX-License-Identifier: AGPL-3.0-only

<template #default="{ items: notes }">
<div :class="[$style.root]">
<EmNote v-for="note in notes" :key="note._featuredId_ || note._prId_ || note.id" :class="$style.note" :note="note"/>
<EmNote v-for="note in notes" :key="note._featuredId_ || note._prId_ || note.id" :class="$style.note" :note="note as Misskey.entities.Note"/>
</div>
</template>
</EmPagination>
</template>

<script lang="ts" setup>
import { useTemplateRef } from 'vue';
import * as Misskey from 'cherrypick-js';
import EmNote from '@/components/EmNote.vue';
import EmPagination, { Paging } from '@/components/EmPagination.vue';
import { i18n } from '@/i18n.js';
Expand Down
25 changes: 15 additions & 10 deletions packages/frontend-embed/src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,21 @@ function compile(theme: Theme): Record<string, string> {
return getColor(theme.props[val]);
} else if (val[0] === ':') { // func
const parts = val.split('<');
const func = parts.shift().substring(1);
const arg = parseFloat(parts.shift());
const color = getColor(parts.join('<'));

switch (func) {
case 'darken': return color.darken(arg);
case 'lighten': return color.lighten(arg);
case 'alpha': return color.setAlpha(arg);
case 'hue': return color.spin(arg);
case 'saturate': return color.saturate(arg);
const funcTxt = parts.shift();
const argTxt = parts.shift();

if (funcTxt && argTxt) {
const func = funcTxt.substring(1);
const arg = parseFloat(argTxt);
const color = getColor(parts.join('<'));

switch (func) {
case 'darken': return color.darken(arg);
case 'lighten': return color.lighten(arg);
case 'alpha': return color.setAlpha(arg);
case 'hue': return color.spin(arg);
case 'saturate': return color.saturate(arg);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/frontend-embed/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"declaration": false,
"sourceMap": false,
"target": "ES2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"module": "ES2022",
"moduleResolution": "Bundler",
"removeComments": false,
"noLib": false,
"strict": true,
Expand Down
1 change: 1 addition & 0 deletions packages/frontend-shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@typescript-eslint/parser": "7.17.0",
"esbuild": "0.24.0",
"eslint-plugin-vue": "9.31.0",
"nodemon": "3.1.7",
"typescript": "5.6.3",
"vue-eslint-parser": "9.4.3"
},
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/src/pages/welcome.entrance.a.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function getInstanceIcon(instance: Misskey.entities.FederationInstance): string
misskeyApiGet('federation/instances', {
sort: '+pubSub',
limit: 20,
blocked: 'false',
}).then(_instances => {
instances.value = _instances;
});
Expand Down
Loading

0 comments on commit 3c94611

Please sign in to comment.