Merge branch 'develop' into feat-media-silence
This commit is contained in:
commit
40e4af0b3e
|
@ -24,9 +24,7 @@ jobs:
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||||
|
|
||||||
- name: setup pnpm
|
- name: setup pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
|
|
||||||
- name: setup node
|
- name: setup node
|
||||||
id: setup-node
|
id: setup-node
|
||||||
|
|
|
@ -32,10 +32,7 @@ jobs:
|
||||||
ref: ${{ matrix.ref }}
|
ref: ${{ matrix.ref }}
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -27,10 +27,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: pnpm/action-setup@v3
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- uses: actions/setup-node@v4.0.2
|
- uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
|
@ -54,10 +51,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: pnpm/action-setup@v3
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- uses: actions/setup-node@v4.0.2
|
- uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
|
@ -80,10 +74,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: pnpm/action-setup@v3
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- uses: actions/setup-node@v4.0.2
|
- uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
|
|
|
@ -24,10 +24,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -34,10 +34,7 @@ jobs:
|
||||||
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
|
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
|
||||||
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
|
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js 20.x
|
- name: Use Node.js 20.x
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -41,10 +41,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Install FFmpeg
|
- name: Install FFmpeg
|
||||||
uses: FedericoCarboni/setup-ffmpeg@v3
|
uses: FedericoCarboni/setup-ffmpeg@v3
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
@ -93,10 +90,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -33,10 +33,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
@ -91,10 +88,7 @@ jobs:
|
||||||
#- uses: browser-actions/setup-firefox@latest
|
#- uses: browser-actions/setup-firefox@latest
|
||||||
# if: ${{ matrix.browser == 'firefox' }}
|
# if: ${{ matrix.browser == 'firefox' }}
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -23,10 +23,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -24,10 +24,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
run_install: false
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4.0.2
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
- 「アカウントを見つけやすくする」が有効なユーザーか
|
- 「アカウントを見つけやすくする」が有効なユーザーか
|
||||||
- Fix: Play作成時に設定した公開範囲が機能していない問題を修正
|
- Fix: Play作成時に設定した公開範囲が機能していない問題を修正
|
||||||
- Fix: 正規化されていない状態のhashtagが連合されてきたhtmlに含まれているとhashtagが正しくhashtagに復元されない問題を修正
|
- Fix: 正規化されていない状態のhashtagが連合されてきたhtmlに含まれているとhashtagが正しくhashtagに復元されない問題を修正
|
||||||
|
- Fix: みつけるのアンケート欄にてチャンネルのアンケートが含まれてしまう問題を修正
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
- Feat: アップロードするファイルの名前をランダム文字列にできるように
|
- Feat: アップロードするファイルの名前をランダム文字列にできるように
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
- Fix: リノートをミュートしたユーザの投稿のリノートがミュートされる問題を修正
|
- Fix: リノートをミュートしたユーザの投稿のリノートがミュートされる問題を修正
|
||||||
- Fix: AP Link等は添付ファイル扱いしないようになど (#13754)
|
- Fix: AP Link等は添付ファイル扱いしないようになど (#13754)
|
||||||
- Fix: FTTが有効かつsinceIdのみを指定した場合に帰って来るレスポンスが逆順である問題を修正
|
- Fix: FTTが有効かつsinceIdのみを指定した場合に帰って来るレスポンスが逆順である問題を修正
|
||||||
|
- Fix: `/i/notifications`に `includeTypes`か`excludeTypes`を指定しているとき、通知が存在するのに空配列を返すことがある問題を修正
|
||||||
|
|
||||||
## 2024.3.1
|
## 2024.3.1
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class ChannelIdDenormalizedForMiPoll1716129964060 {
|
||||||
|
name = 'ChannelIdDenormalizedForMiPoll1716129964060'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" ADD "channelId" character varying(32)`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "poll"."channelId" IS '[Denormalized]'`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_c1240fcc9675946ea5d6c2860e" ON "poll" ("channelId") `);
|
||||||
|
await queryRunner.query(`UPDATE "poll" SET "channelId" = "note"."channelId" FROM "note" WHERE "poll"."noteId" = "note"."id"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_c1240fcc9675946ea5d6c2860e"`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "poll"."channelId" IS '[Denormalized]'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" DROP COLUMN "channelId"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -473,6 +473,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
noteVisibility: insert.visibility,
|
noteVisibility: insert.visibility,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
userHost: user.host,
|
userHost: user.host,
|
||||||
|
channelId: insert.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await transactionalEntityManager.insert(MiPoll, poll);
|
await transactionalEntityManager.insert(MiPoll, poll);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { noteVisibilities } from '@/types.js';
|
||||||
import { id } from './util/id.js';
|
import { id } from './util/id.js';
|
||||||
import { MiNote } from './Note.js';
|
import { MiNote } from './Note.js';
|
||||||
import type { MiUser } from './User.js';
|
import type { MiUser } from './User.js';
|
||||||
|
import type { MiChannel } from "@/models/Channel.js";
|
||||||
|
|
||||||
@Entity('poll')
|
@Entity('poll')
|
||||||
export class MiPoll {
|
export class MiPoll {
|
||||||
|
@ -58,6 +59,14 @@ export class MiPoll {
|
||||||
comment: '[Denormalized]',
|
comment: '[Denormalized]',
|
||||||
})
|
})
|
||||||
public userHost: string | null;
|
public userHost: string | null;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({
|
||||||
|
...id(),
|
||||||
|
nullable: true,
|
||||||
|
comment: '[Denormalized]',
|
||||||
|
})
|
||||||
|
public channelId: MiChannel['id'] | null;
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
constructor(data: Partial<MiPoll>) {
|
constructor(data: Partial<MiPoll>) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { In } from 'typeorm';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { NotesRepository } from '@/models/_.js';
|
import type { NotesRepository } from '@/models/_.js';
|
||||||
import { obsoleteNotificationTypes, notificationTypes, FilterUnionByProperty } from '@/types.js';
|
import { FilterUnionByProperty, notificationTypes, obsoleteNotificationTypes } from '@/types.js';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { NoteReadService } from '@/core/NoteReadService.js';
|
import { NoteReadService } from '@/core/NoteReadService.js';
|
||||||
import { NotificationEntityService } from '@/core/entities/NotificationEntityService.js';
|
import { NotificationEntityService } from '@/core/entities/NotificationEntityService.js';
|
||||||
|
@ -84,18 +84,33 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
|
const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
|
||||||
const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
|
const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
|
||||||
|
|
||||||
const limit = ps.limit + (ps.untilId ? 1 : 0) + (ps.sinceId ? 1 : 0); // untilIdに指定したものも含まれるため+1
|
let sinceTime = ps.sinceId ? this.idService.parse(ps.sinceId).date.getTime().toString() : null;
|
||||||
const notificationsRes = await this.redisClient.xrevrange(
|
let untilTime = ps.untilId ? this.idService.parse(ps.untilId).date.getTime().toString() : null;
|
||||||
|
|
||||||
|
let notifications: MiNotification[];
|
||||||
|
for (;;) {
|
||||||
|
let notificationsRes: [id: string, fields: string[]][];
|
||||||
|
|
||||||
|
// sinceidのみの場合は古い順、そうでない場合は新しい順。 QueryService.makePaginationQueryも参照
|
||||||
|
if (sinceTime && !untilTime) {
|
||||||
|
notificationsRes = await this.redisClient.xrange(
|
||||||
`notificationTimeline:${me.id}`,
|
`notificationTimeline:${me.id}`,
|
||||||
ps.untilId ? this.idService.parse(ps.untilId).date.getTime() : '+',
|
'(' + sinceTime,
|
||||||
ps.sinceId ? this.idService.parse(ps.sinceId).date.getTime() : '-',
|
'+',
|
||||||
'COUNT', limit);
|
'COUNT', ps.limit);
|
||||||
|
} else {
|
||||||
|
notificationsRes = await this.redisClient.xrevrange(
|
||||||
|
`notificationTimeline:${me.id}`,
|
||||||
|
untilTime ? '(' + untilTime : '+',
|
||||||
|
sinceTime ? '(' + sinceTime : '-',
|
||||||
|
'COUNT', ps.limit);
|
||||||
|
}
|
||||||
|
|
||||||
if (notificationsRes.length === 0) {
|
if (notificationsRes.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let notifications = notificationsRes.map(x => JSON.parse(x[1][1])).filter(x => x.id !== ps.untilId && x !== ps.sinceId) as MiNotification[];
|
notifications = notificationsRes.map(x => JSON.parse(x[1][1])) as MiNotification[];
|
||||||
|
|
||||||
if (includeTypes && includeTypes.length > 0) {
|
if (includeTypes && includeTypes.length > 0) {
|
||||||
notifications = notifications.filter(notification => includeTypes.includes(notification.type));
|
notifications = notifications.filter(notification => includeTypes.includes(notification.type));
|
||||||
|
@ -103,8 +118,17 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
notifications = notifications.filter(notification => !excludeTypes.includes(notification.type));
|
notifications = notifications.filter(notification => !excludeTypes.includes(notification.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notifications.length === 0) {
|
if (notifications.length !== 0) {
|
||||||
return [];
|
// 通知が1件以上ある場合は返す
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// フィルタしたことで通知が0件になった場合、次のページを取得する
|
||||||
|
if (ps.sinceId && !ps.untilId) {
|
||||||
|
sinceTime = notificationsRes[notificationsRes.length - 1][0];
|
||||||
|
} else {
|
||||||
|
untilTime = notificationsRes[notificationsRes.length - 1][0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark all as read
|
// Mark all as read
|
||||||
|
|
|
@ -32,6 +32,7 @@ export const paramDef = {
|
||||||
properties: {
|
properties: {
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
offset: { type: 'integer', default: 0 },
|
offset: { type: 'integer', default: 0 },
|
||||||
|
excludeChannels: { type: 'boolean', default: false },
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -86,6 +87,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
query.setParameters(mutingQuery.getParameters());
|
query.setParameters(mutingQuery.getParameters());
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
//#region exclude channels
|
||||||
|
if (ps.excludeChannels) {
|
||||||
|
query.andWhere('poll.channelId IS NULL');
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
const polls = await query
|
const polls = await query
|
||||||
.orderBy('poll.noteId', 'DESC')
|
.orderBy('poll.noteId', 'DESC')
|
||||||
.limit(ps.limit)
|
.limit(ps.limit)
|
||||||
|
|
|
@ -29,6 +29,9 @@ const paginationForPolls = {
|
||||||
endpoint: 'notes/polls/recommendation' as const,
|
endpoint: 'notes/polls/recommendation' as const,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
offsetMode: true,
|
offsetMode: true,
|
||||||
|
params: {
|
||||||
|
excludeChannels: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const tab = ref('notes');
|
const tab = ref('notes');
|
||||||
|
|
|
@ -21022,6 +21022,8 @@ export type operations = {
|
||||||
limit?: number;
|
limit?: number;
|
||||||
/** @default 0 */
|
/** @default 0 */
|
||||||
offset?: number;
|
offset?: number;
|
||||||
|
/** @default false */
|
||||||
|
excludeChannels?: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue