fix(cdn-caching): 自分のリアクションが表示されない問題を修正 (MisskeyIO#851)

This commit is contained in:
あわわわとーにゅ 2024-12-25 14:13:45 +09:00 committed by kakkokari-gtyih
parent 6139ad3c61
commit b7d80edcbb
13 changed files with 103 additions and 70 deletions

View File

@ -16,7 +16,7 @@ class AntennaChannel extends Channel {
public static requireCredential = true as const;
public static kind = 'read:account';
private antennaId: string;
private idOnly: boolean;
private minimize: boolean;
constructor(
private noteEntityService: NoteEntityService,
@ -32,7 +32,7 @@ class AntennaChannel extends Channel {
public async init(params: any) {
if (typeof params.antennaId !== 'string') return;
this.antennaId = params.antennaId as string;
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
// Subscribe stream
this.subscriber.on(`antennaStream:${this.antennaId}`, this.onEvent);
@ -45,9 +45,13 @@ class AntennaChannel extends Channel {
if (this.isNoteMutedOrBlocked(note)) return;
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -16,7 +16,7 @@ class ChannelChannel extends Channel {
public static shouldShare = false;
public static requireCredential = false as const;
private channelId: string;
private idOnly: boolean;
private minimize: boolean;
constructor(
private noteEntityService: NoteEntityService,
@ -32,7 +32,7 @@ class ChannelChannel extends Channel {
public async init(params: any) {
if (typeof params.channelId !== 'string') return;
this.channelId = params.channelId as string;
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
// Subscribe stream
this.subscriber.on('notesStream', this.onNote);
@ -51,9 +51,13 @@ class ChannelChannel extends Channel {
}
}
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -19,7 +19,7 @@ class GlobalTimelineChannel extends Channel {
public static requireCredential = false as const;
private withRenotes: boolean;
private withFiles: boolean;
private idOnly: boolean;
private minimize: boolean;
constructor(
private metaService: MetaService,
@ -40,7 +40,7 @@ class GlobalTimelineChannel extends Channel {
this.withRenotes = !!(params.withRenotes ?? true);
this.withFiles = !!(params.withFiles ?? false);
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
// Subscribe events
this.subscriber.on('notesStream', this.onNote);
@ -64,9 +64,13 @@ class GlobalTimelineChannel extends Channel {
}
}
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -18,7 +18,7 @@ class HomeTimelineChannel extends Channel {
public static kind = 'read:account';
private withRenotes: boolean;
private withFiles: boolean;
private idOnly: boolean;
private minimize: boolean;
constructor(
private noteEntityService: NoteEntityService,
@ -34,7 +34,7 @@ class HomeTimelineChannel extends Channel {
public async init(params: JsonObject) {
this.withRenotes = !!(params.withRenotes ?? true);
this.withFiles = !!(params.withFiles ?? false);
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
this.subscriber.on('notesStream', this.onNote);
}
@ -88,9 +88,13 @@ class HomeTimelineChannel extends Channel {
}
}
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -21,7 +21,7 @@ class HybridTimelineChannel extends Channel {
private withRenotes: boolean;
private withReplies: boolean;
private withFiles: boolean;
private idOnly: boolean;
private minimize: boolean;
constructor(
private metaService: MetaService,
@ -43,7 +43,7 @@ class HybridTimelineChannel extends Channel {
this.withRenotes = !!(params.withRenotes ?? true);
this.withReplies = !!(params.withReplies ?? false);
this.withFiles = !!(params.withFiles ?? false);
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
// Subscribe events
this.subscriber.on('notesStream', this.onNote);
@ -103,9 +103,13 @@ class HybridTimelineChannel extends Channel {
}
}
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -20,7 +20,7 @@ class LocalTimelineChannel extends Channel {
private withRenotes: boolean;
private withReplies: boolean;
private withFiles: boolean;
private idOnly: boolean;
private minimize: boolean;
constructor(
private metaService: MetaService,
@ -42,7 +42,7 @@ class LocalTimelineChannel extends Channel {
this.withRenotes = !!(params.withRenotes ?? true);
this.withReplies = !!(params.withReplies ?? false);
this.withFiles = !!(params.withFiles ?? false);
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
// Subscribe events
this.subscriber.on('notesStream', this.onNote);
@ -74,9 +74,13 @@ class LocalTimelineChannel extends Channel {
}
}
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -16,7 +16,7 @@ class RoleTimelineChannel extends Channel {
public static shouldShare = false;
public static requireCredential = false as const;
private roleId: string;
private idOnly: boolean;
private minimize: boolean;
constructor(
private noteEntityService: NoteEntityService,
@ -33,7 +33,7 @@ class RoleTimelineChannel extends Channel {
public async init(params: JsonObject) {
if (typeof params.roleId !== 'string') return;
this.roleId = params.roleId;
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
this.subscriber.on(`roleTimelineStream:${this.roleId}`, this.onEvent);
}
@ -50,9 +50,13 @@ class RoleTimelineChannel extends Channel {
if (this.isNoteMutedOrBlocked(note)) return;
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.send('note', note);
}

View File

@ -22,7 +22,7 @@ class UserListChannel extends Channel {
private listUsersClock: NodeJS.Timeout;
private withFiles: boolean;
private withRenotes: boolean;
private idOnly: boolean;
private minimize: boolean;
constructor(
private userListsRepository: UserListsRepository,
@ -43,7 +43,7 @@ class UserListChannel extends Channel {
this.listId = params.listId;
this.withFiles = !!(params.withFiles ?? false);
this.withRenotes = !!(params.withRenotes ?? true);
this.idOnly = !!(params.idOnly ?? false);
this.minimize = !!(params.minimize ?? false);
// Check existence and owner
const listExist = await this.userListsRepository.exists({
@ -120,9 +120,13 @@ class UserListChannel extends Channel {
}
}
if (this.idOnly && ['public', 'home'].includes(note.visibility)) {
const idOnlyNote = { id: note.id };
this.send('note', idOnlyNote);
if (this.minimize && ['public', 'home'].includes(note.visibility)) {
this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll ? { choices: note.poll.choices } : undefined,
reply: note.reply ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote ? { myReaction: note.renote.myReaction } : undefined,
});
} else {
this.connection.cacheNote(note);
this.send('note', note);

View File

@ -415,7 +415,7 @@ export const waitFire = async <C extends keyof misskey.Channels>(user: UserToken
if (timer) clearTimeout(timer);
res(true);
}
}, { ...params, idOnly: false });
}, { ...params, minimize: false });
} catch (e) {
rej(e);
}

View File

@ -17,13 +17,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed, watch, onUnmounted, provide, ref, shallowRef } from 'vue';
import { computed, watch, onUnmounted, provide, shallowRef } from 'vue';
import * as Misskey from 'misskey-js';
import type { BasicTimelineType } from '@/timelines.js';
import MkNotes from '@/components/MkNotes.vue';
import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { deepMerge } from '@/scripts/merge.js';
import { $i, iAmModerator } from '@/account.js';
import { instance } from '@/instance.js';
import { defaultStore } from '@/store.js';
@ -79,7 +80,7 @@ async function prepend(data) {
let note = data;
//
// idOnlyid
// minimizeid
if (!data.visibility) {
const initiateTime = Date.now();
const res = await window.fetch(`/notes/${data.id}.json`, {
@ -100,7 +101,7 @@ async function prepend(data) {
return res;
});
if (!res.ok) return;
note = await res.json();
note = deepMerge(data, await res.json());
}
tlNotesCount++;
@ -121,7 +122,7 @@ async function prepend(data) {
let connection: Misskey.ChannelConnection | null = null;
let connection2: Misskey.ChannelConnection | null = null;
let paginationQuery: Paging | null = null;
const idOnly = !iAmModerator;
const minimize = !iAmModerator;
const stream = useStream();
@ -130,13 +131,13 @@ function connectChannel() {
if (props.antenna == null) return;
connection = stream.useChannel('antenna', {
antennaId: props.antenna,
idOnly: idOnly,
minimize: minimize,
});
} else if (props.src === 'home') {
connection = stream.useChannel('homeTimeline', {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined,
idOnly: idOnly,
minimize: minimize,
});
connection2 = stream.useChannel('main');
} else if (props.src === 'local') {
@ -144,20 +145,20 @@ function connectChannel() {
withRenotes: props.withRenotes,
withReplies: props.withReplies,
withFiles: props.onlyFiles ? true : undefined,
idOnly: idOnly,
minimize: minimize,
});
} else if (props.src === 'social') {
connection = stream.useChannel('hybridTimeline', {
withRenotes: props.withRenotes,
withReplies: props.withReplies,
withFiles: props.onlyFiles ? true : undefined,
idOnly: idOnly,
minimize: minimize,
});
} else if (props.src === 'global') {
connection = stream.useChannel('globalTimeline', {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined,
idOnly: idOnly,
minimize: minimize,
});
} else if (props.src === 'mentions') {
connection = stream.useChannel('main');
@ -176,19 +177,19 @@ function connectChannel() {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined,
listId: props.list,
idOnly: idOnly,
minimize: minimize,
});
} else if (props.src === 'channel') {
if (props.channel == null) return;
connection = stream.useChannel('channel', {
channelId: props.channel,
idOnly: idOnly,
minimize: minimize,
});
} else if (props.src === 'role') {
if (props.role == null) return;
connection = stream.useChannel('roleTimeline', {
roleId: props.role,
idOnly: idOnly,
minimize: minimize,
});
}
if (props.src !== 'directs' && props.src !== 'mentions') connection?.on('note', prepend);

View File

@ -22,7 +22,7 @@ export function deepMerge<X extends Record<string | number | symbol, unknown>>(v
if (isPureObject(value) && isPureObject(def)) {
const result = deepClone(value as Cloneable) as X;
for (const [k, v] of Object.entries(def) as [keyof X, X[keyof X]][]) {
if (!Object.prototype.hasOwnProperty.call(value, k) || value[k] === undefined) {
if (!Object.hasOwn(value, k) || value[k] === undefined) {
result[k] = v;
} else if (isPureObject(v) && isPureObject(result[k])) {
const child = deepClone(result[k] as Cloneable) as DeepPartial<X[keyof X] & Record<string | number | symbol, unknown>>;

View File

@ -632,7 +632,7 @@ export type Channels = {
params: {
withRenotes?: boolean;
withFiles?: boolean;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -644,7 +644,7 @@ export type Channels = {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -656,7 +656,7 @@ export type Channels = {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -667,7 +667,7 @@ export type Channels = {
params: {
withRenotes?: boolean;
withFiles?: boolean;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -679,7 +679,7 @@ export type Channels = {
listId: string;
withFiles?: boolean;
withRenotes?: boolean;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -698,7 +698,7 @@ export type Channels = {
roleTimeline: {
params: {
roleId: string;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -708,7 +708,7 @@ export type Channels = {
antenna: {
params: {
antennaId: string;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;
@ -718,7 +718,7 @@ export type Channels = {
channel: {
params: {
channelId: string;
idOnly?: boolean;
minimize?: boolean;
};
events: {
note: (payload: Note) => void;

View File

@ -73,7 +73,7 @@ export type Channels = {
params: {
withRenotes?: boolean;
withFiles?: boolean;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -85,7 +85,7 @@ export type Channels = {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -97,7 +97,7 @@ export type Channels = {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -108,7 +108,7 @@ export type Channels = {
params: {
withRenotes?: boolean;
withFiles?: boolean;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -120,7 +120,7 @@ export type Channels = {
listId: string;
withFiles?: boolean;
withRenotes?: boolean;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -139,7 +139,7 @@ export type Channels = {
roleTimeline: {
params: {
roleId: string;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -149,7 +149,7 @@ export type Channels = {
antenna: {
params: {
antennaId: string;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;
@ -159,7 +159,7 @@ export type Channels = {
channel: {
params: {
channelId: string;
idOnly?: boolean,
minimize?: boolean,
};
events: {
note: (payload: Note) => void;