Merge branch 'misskey-dev:develop' into develop

This commit is contained in:
老兄 2023-10-25 22:59:52 +08:00 committed by GitHub
commit cd36628900
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 32 additions and 7 deletions

View File

@ -22,6 +22,7 @@
- Feat: プラグイン・テーマを外部サイトから直接インストールできるようになりました - Feat: プラグイン・テーマを外部サイトから直接インストールできるようになりました
- 外部サイトでの実装が必要です。詳細は Misskey Hub をご覧ください - 外部サイトでの実装が必要です。詳細は Misskey Hub をご覧ください
https://misskey-hub.net/docs/advanced/publish-on-your-website.html https://misskey-hub.net/docs/advanced/publish-on-your-website.html
- Feat: AiScript関数`Mk:nyaize()`が追加されました
- Fix: 投稿フォームでのユーザー変更がプレビューに反映されない問題を修正 - Fix: 投稿フォームでのユーザー変更がプレビューに反映されない問題を修正
### Server ### Server
@ -30,6 +31,7 @@
- Fix: ローカルタイムラインに投稿者自身の投稿への返信が含まれない問題を修正 - Fix: ローカルタイムラインに投稿者自身の投稿への返信が含まれない問題を修正
- Fix: 自分のフォローしているユーザーの自分のフォローしていないユーザーの visibility: followers な投稿への返信がストリーミングで流れてくる問題を修正 - Fix: 自分のフォローしているユーザーの自分のフォローしていないユーザーの visibility: followers な投稿への返信がストリーミングで流れてくる問題を修正
- Fix: RedisへのTLキャッシュが有効の場合にHTL/LTL/STLが空になることがある問題を修正 - Fix: RedisへのTLキャッシュが有効の場合にHTL/LTL/STLが空になることがある問題を修正
- Fix: STLでフォローしていないチャンネルが取得される問題を修正
## 2023.10.2 ## 2023.10.2

View File

@ -5,7 +5,7 @@
import { Brackets } from 'typeorm'; import { Brackets } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository, FollowingsRepository, MiNote } from '@/models/_.js'; import type { NotesRepository, FollowingsRepository, MiNote, ChannelFollowingsRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import ActiveUsersChart from '@/core/chart/charts/active-users.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
@ -69,6 +69,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
@Inject(DI.notesRepository) @Inject(DI.notesRepository)
private notesRepository: NotesRepository, private notesRepository: NotesRepository,
@Inject(DI.channelFollowingsRepository)
private channelFollowingsRepository: ChannelFollowingsRepository,
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
private roleService: RoleService, private roleService: RoleService,
private activeUsersChart: ActiveUsersChart, private activeUsersChart: ActiveUsersChart,
@ -208,6 +211,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
withReplies: boolean, withReplies: boolean,
}, me: MiLocalUser) { }, me: MiLocalUser) {
const followees = await this.userFollowingService.getFollowees(me.id); const followees = await this.userFollowingService.getFollowees(me.id);
const followingChannels = await this.channelFollowingsRepository.find({
where: {
followerId: me.id,
},
});
const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId)
.andWhere(new Brackets(qb => { .andWhere(new Brackets(qb => {
@ -226,6 +234,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
.leftJoinAndSelect('reply.user', 'replyUser') .leftJoinAndSelect('reply.user', 'replyUser')
.leftJoinAndSelect('renote.user', 'renoteUser'); .leftJoinAndSelect('renote.user', 'renoteUser');
if (followingChannels.length > 0) {
const followingChannelIds = followingChannels.map(x => x.followeeId);
query.andWhere('note.channelId IN (:...followingChannelIds) OR note.channelId IS NULL', { followingChannelIds });
} else {
query.andWhere('note.channelId IS NULL');
}
if (!ps.withReplies) { if (!ps.withReplies) {
query.andWhere(new Brackets(qb => { query.andWhere(new Brackets(qb => {
qb qb

View File

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<div class="omfetrab" :class="['s' + size, 'w' + width, 'h' + height, { asDrawer, asWindow }]" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : undefined }"> <div class="omfetrab" :class="['s' + size, 'w' + width, 'h' + height, { asDrawer, asWindow }]" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : undefined }">
<input ref="searchEl" :value="q" class="search" data-prevent-emoji-insert :class="{ filled: q != null && q != '' }" :placeholder="i18n.ts.search" type="search" @input="input()" @paste.stop="paste" @keydown.stop.prevent.enter="onEnter"> <input ref="searchEl" :value="q" class="search" data-prevent-emoji-insert :class="{ filled: q != null && q != '' }" :placeholder="i18n.ts.search" type="search" autocapitalize="off" @input="input()" @paste.stop="paste" @keydown.stop.prevent.enter="onEnter">
<!-- FirefoxのTabフォーカスが想定外の挙動となるためtabindex="-1"を追加 https://github.com/misskey-dev/misskey/issues/10744 --> <!-- FirefoxのTabフォーカスが想定外の挙動となるためtabindex="-1"を追加 https://github.com/misskey-dev/misskey/issues/10744 -->
<div ref="emojisEl" class="emojis" tabindex="-1"> <div ref="emojisEl" class="emojis" tabindex="-1">
<section class="result"> <section class="result">

View File

@ -20,6 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:placeholder="placeholder" :placeholder="placeholder"
:pattern="pattern" :pattern="pattern"
:autocomplete="autocomplete" :autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:spellcheck="spellcheck" :spellcheck="spellcheck"
:step="step" :step="step"
:list="id" :list="id"
@ -58,6 +59,7 @@ const props = defineProps<{
placeholder?: string; placeholder?: string;
autofocus?: boolean; autofocus?: boolean;
autocomplete?: string; autocomplete?: string;
autocapitalize?: string;
spellcheck?: boolean; spellcheck?: boolean;
step?: any; step?: any;
datalist?: string[]; datalist?: string[];

View File

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary link to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton> <MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary link to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton>
<div class="query"> <div class="query">
<MkInput v-model="q" class="" :placeholder="i18n.ts.search"> <MkInput v-model="q" class="" :placeholder="i18n.ts.search" autocapitalize="off">
<template #prefix><i class="ti ti-search"></i></template> <template #prefix><i class="ti ti-search"></i></template>
</MkInput> </MkInput>

View File

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :contentMax="900"> <MkSpacer :contentMax="900">
<div class="ogwlenmc"> <div class="ogwlenmc">
<div v-if="tab === 'local'" class="local"> <div v-if="tab === 'local'" class="local">
<MkInput v-model="query" :debounce="true" type="search"> <MkInput v-model="query" :debounce="true" type="search" autocapitalize="off">
<template #prefix><i class="ti ti-search"></i></template> <template #prefix><i class="ti ti-search"></i></template>
<template #label>{{ i18n.ts.search }}</template> <template #label>{{ i18n.ts.search }}</template>
</MkInput> </MkInput>
@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-else-if="tab === 'remote'" class="remote"> <div v-else-if="tab === 'remote'" class="remote">
<FormSplit> <FormSplit>
<MkInput v-model="queryRemote" :debounce="true" type="search"> <MkInput v-model="queryRemote" :debounce="true" type="search" autocapitalize="off">
<template #prefix><i class="ti ti-search"></i></template> <template #prefix><i class="ti ti-search"></i></template>
<template #label>{{ i18n.ts.search }}</template> <template #label>{{ i18n.ts.search }}</template>
</MkInput> </MkInput>

View File

@ -31,13 +31,13 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</div> </div>
<MkButton rounded style="margin: 0 auto;" @click="changeImage">{{ i18n.ts.selectFile }}</MkButton> <MkButton rounded style="margin: 0 auto;" @click="changeImage">{{ i18n.ts.selectFile }}</MkButton>
<MkInput v-model="name" pattern="[a-z0-9_]"> <MkInput v-model="name" pattern="[a-z0-9_]" autocapitalize="off">
<template #label>{{ i18n.ts.name }}</template> <template #label>{{ i18n.ts.name }}</template>
</MkInput> </MkInput>
<MkInput v-model="category" :datalist="customEmojiCategories"> <MkInput v-model="category" :datalist="customEmojiCategories">
<template #label>{{ i18n.ts.category }}</template> <template #label>{{ i18n.ts.category }}</template>
</MkInput> </MkInput>
<MkInput v-model="aliases"> <MkInput v-model="aliases" autocapitalize="off">
<template #label>{{ i18n.ts.tags }}</template> <template #label>{{ i18n.ts.tags }}</template>
<template #caption>{{ i18n.ts.setMultipleBySeparatingWithSpace }}</template> <template #caption>{{ i18n.ts.setMultipleBySeparatingWithSpace }}</template>
</MkInput> </MkInput>

View File

@ -9,6 +9,7 @@ import { $i } from '@/account.js';
import { miLocalStorage } from '@/local-storage.js'; import { miLocalStorage } from '@/local-storage.js';
import { customEmojis } from '@/custom-emojis.js'; import { customEmojis } from '@/custom-emojis.js';
import { url, lang } from '@/config.js'; import { url, lang } from '@/config.js';
import { nyaize } from '@/scripts/nyaize.js';
export function createAiScriptEnv(opts) { export function createAiScriptEnv(opts) {
return { return {
@ -71,5 +72,9 @@ export function createAiScriptEnv(opts) {
'Mk:url': values.FN_NATIVE(() => { 'Mk:url': values.FN_NATIVE(() => {
return values.STR(window.location.href); return values.STR(window.location.href);
}), }),
'Mk:nyaize': values.FN_NATIVE(([text]) => {
utils.assertString(text);
return values.STR(nyaize(text.value));
}),
}; };
} }