Skip to content

Commit

Permalink
Merge pull request #197 from HanaMisskey/merge-upstream-20
Browse files Browse the repository at this point in the history
Merge upstream 20
  • Loading branch information
kanarikanaru authored Jan 12, 2025
2 parents 405932d + c72d784 commit b180c2e
Show file tree
Hide file tree
Showing 29 changed files with 1,544 additions and 172 deletions.
9 changes: 8 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,19 @@
(Cherry-picked from https://github.com/TeamNijimiss/misskey/commit/800359623e41a662551d774de15b0437b6849bb4)
- Fix: ノート作成画面でファイルの添付可能個数を超えてもノートボタンが押せていた問題を修正
- Fix: 「アカウントを管理」画面で、ユーザー情報の取得に失敗したアカウント(削除されたアカウントなど)が表示されない問題を修正
- Fix: 言語データのキャッシュ状況によっては、埋め込みウィジェットが正しく起動しない問題を修正

### Server
- Enhance: pg_bigmが利用できるよう、ノートの検索をILIKE演算子でなくLIKE演算子でLOWER()をかけたテキストに対して行うように
- Enhance: チャート更新時にDBに同時接続しないように
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/830)
- 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
10 changes: 5 additions & 5 deletions packages/backend/src/core/chart/ChartManagementService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ export class ChartManagementService implements OnApplicationShutdown {
@bindThis
public async start() {
// 20分おきにメモリ情報をDBに書き込み
this.saveIntervalId = setInterval(() => {
this.saveIntervalId = setInterval(async () => {
for (const chart of this.charts) {
chart.save();
await chart.save();
}
}, 1000 * 60 * 20);
}
Expand All @@ -69,9 +69,9 @@ export class ChartManagementService implements OnApplicationShutdown {
public async dispose(): Promise<void> {
clearInterval(this.saveIntervalId);
if (process.env.NODE_ENV !== 'test') {
await Promise.all(
this.charts.map(chart => chart.save()),
);
for (const chart of this.charts) {
await chart.save();
}
}
}

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 @@ -102,8 +102,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 @@ -115,7 +114,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 @@ -459,6 +462,8 @@ export class NoteEntityService implements OnModuleInit {
} : {}),
});

this.treatVisibility(packed);

if (!opts.skipHide) {
await this.hideNote(packed, meId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,19 @@ export class CleanChartsProcessorService {
public async process(): Promise<void> {
this.logger.info('Clean charts...');

await Promise.all([
this.federationChart.clean(),
this.notesChart.clean(),
this.usersChart.clean(),
this.activeUsersChart.clean(),
this.instanceChart.clean(),
this.perUserNotesChart.clean(),
this.perUserPvChart.clean(),
this.driveChart.clean(),
this.perUserReactionsChart.clean(),
this.perUserFollowingChart.clean(),
this.perUserDriveChart.clean(),
this.apRequestChart.clean(),
]);
// DBへの同時接続を避けるためにPromise.allを使わずひとつずつ実行する
await this.federationChart.clean();
await this.notesChart.clean();
await this.usersChart.clean();
await this.activeUsersChart.clean();
await this.instanceChart.clean();
await this.perUserNotesChart.clean();
await this.perUserPvChart.clean();
await this.driveChart.clean();
await this.perUserReactionsChart.clean();
await this.perUserFollowingChart.clean();
await this.perUserDriveChart.clean();
await this.apRequestChart.clean();

this.logger.succ('All charts successfully cleaned.');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ export class ResyncChartsProcessorService {
public async process(): Promise<void> {
this.logger.info('Resync charts...');

// DBへの同時接続を避けるためにPromise.allを使わずひとつずつ実行する
// TODO: ユーザーごとのチャートも更新する
// TODO: インスタンスごとのチャートも更新する
await Promise.all([
this.driveChart.resync(),
this.notesChart.resync(),
this.usersChart.resync(),
]);
await this.driveChart.resync();
await this.notesChart.resync();
await this.usersChart.resync();

this.logger.succ('All charts successfully resynced.');
}
Expand Down
27 changes: 13 additions & 14 deletions packages/backend/src/queue/processors/TickChartsProcessorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,19 @@ export class TickChartsProcessorService {
public async process(): Promise<void> {
this.logger.info('Tick charts...');

await Promise.all([
this.federationChart.tick(false),
this.notesChart.tick(false),
this.usersChart.tick(false),
this.activeUsersChart.tick(false),
this.instanceChart.tick(false),
this.perUserNotesChart.tick(false),
this.perUserPvChart.tick(false),
this.driveChart.tick(false),
this.perUserReactionsChart.tick(false),
this.perUserFollowingChart.tick(false),
this.perUserDriveChart.tick(false),
this.apRequestChart.tick(false),
]);
// DBへの同時接続を避けるためにPromise.allを使わずひとつずつ実行する
await this.federationChart.tick(false);
await this.notesChart.tick(false);
await this.usersChart.tick(false);
await this.activeUsersChart.tick(false);
await this.instanceChart.tick(false);
await this.perUserNotesChart.tick(false);
await this.perUserPvChart.tick(false);
await this.driveChart.tick(false);
await this.perUserReactionsChart.tick(false);
await this.perUserFollowingChart.tick(false);
await this.perUserDriveChart.tick(false);
await this.apRequestChart.tick(false);

this.logger.succ('All charts successfully ticked.');
}
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 @@ -519,8 +519,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
20 changes: 18 additions & 2 deletions packages/frontend-embed/src/boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ 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 } from '@@/js/config.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 } from '@/i18n.js';
import { i18n, updateI18n } from '@/i18n.js';

import type { Theme } from '@/theme.js';

Expand Down Expand Up @@ -71,6 +71,22 @@ 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';

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 @@ -425,8 +425,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,7 +13,7 @@ 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>
Expand All @@ -24,6 +24,7 @@ import { useTemplateRef } from 'vue';
import EmNote from '@/components/EmNote.vue';
import EmPagination, { Paging } from '@/components/EmPagination.vue';
import { i18n } from '@/i18n.js';
import * as Misskey from 'misskey-js';

withDefaults(defineProps<{
pagination: Paging;
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 @@ -26,6 +26,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
2 changes: 1 addition & 1 deletion packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@twemoji/parser": "15.1.1",
"@vitejs/plugin-vue": "5.2.0",
"@vue/compiler-sfc": "3.5.12",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.11",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
"astring": "1.9.0",
"broadcast-channel": "7.0.0",
"buraha": "0.0.1",
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 @@ -59,6 +59,7 @@ function getInstanceIcon(instance: Misskey.entities.FederationInstance): string
misskeyApiGet('federation/instances', {
sort: '+pubSub',
limit: 20,
blocked: 'false',
}).then(_instances => {
instances.value = _instances;
});
Expand Down
38 changes: 32 additions & 6 deletions packages/frontend/src/scripts/aiscript/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { utils, values } from '@syuilo/aiscript';
import { errors, utils, values } from '@syuilo/aiscript';
import * as Misskey from 'misskey-js';
import { url, lang } from '@@/js/config.js';
import { assertStringAndIsIn } from './common.js';
import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { $i } from '@/account.js';
import { miLocalStorage } from '@/local-storage.js';
import { customEmojis } from '@/custom-emojis.js';
import { url, lang } from '@@/js/config.js';

const DIALOG_TYPES = [
'error',
'info',
'success',
'warning',
'waiting',
'question',
] as const;

export function aiScriptReadline(q: string): Promise<string> {
return new Promise(ok => {
Expand All @@ -22,15 +32,20 @@ export function aiScriptReadline(q: string): Promise<string> {
});
}

export function createAiScriptEnv(opts) {
export function createAiScriptEnv(opts: { storageKey: string, token?: string }) {
return {
USER_ID: $i ? values.STR($i.id) : values.NULL,
USER_NAME: $i ? values.STR($i.name) : values.NULL,
USER_NAME: $i?.name ? values.STR($i.name) : values.NULL,
USER_USERNAME: $i ? values.STR($i.username) : values.NULL,
CUSTOM_EMOJIS: utils.jsToVal(customEmojis.value),
LOCALE: values.STR(lang),
SERVER_URL: values.STR(url),
'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => {
utils.assertString(title);
utils.assertString(text);
if (type != null) {
assertStringAndIsIn(type, DIALOG_TYPES);
}
await os.alert({
type: type ? type.value : 'info',
title: title.value,
Expand All @@ -39,6 +54,11 @@ export function createAiScriptEnv(opts) {
return values.NULL;
}),
'Mk:confirm': values.FN_NATIVE(async ([title, text, type]) => {
utils.assertString(title);
utils.assertString(text);
if (type != null) {
assertStringAndIsIn(type, DIALOG_TYPES);
}
const confirm = await os.confirm({
type: type ? type.value : 'question',
title: title.value,
Expand All @@ -48,14 +68,20 @@ export function createAiScriptEnv(opts) {
}),
'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => {
utils.assertString(ep);
if (ep.value.includes('://')) throw new Error('invalid endpoint');
if (ep.value.includes('://')) {
throw new errors.AiScriptRuntimeError('invalid endpoint');
}
if (token) {
utils.assertString(token);
// バグがあればundefinedもあり得るため念のため
if (typeof token.value !== 'string') throw new Error('invalid token');
}
const actualToken: string|null = token?.value ?? opts.token ?? null;
return misskeyApi(ep.value, utils.valToJs(param), actualToken).then(res => {
if (param == null) {
throw new errors.AiScriptRuntimeError('expected param');
}
utils.assertObject(param);
return misskeyApi(ep.value, utils.valToJs(param) as object, actualToken).then(res => {
return utils.jsToVal(res);
}, err => {
return values.ERROR('request_failed', utils.jsToVal(err));
Expand Down
Loading

0 comments on commit b180c2e

Please sign in to comment.