wip
This commit is contained in:
parent
d309ca1244
commit
3658e75ff3
|
@ -396,9 +396,8 @@ if (props.mock) {
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
} else {
|
} else {
|
||||||
useNoteCapture({
|
useNoteCapture({
|
||||||
rootEl: rootEl,
|
|
||||||
note: appearNote,
|
note: appearNote,
|
||||||
pureNote: note,
|
parentNote: note,
|
||||||
isDeletedRef: isDeleted,
|
isDeletedRef: isDeleted,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,9 +372,8 @@ const reactionsPagination = computed<Paging>(() => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
useNoteCapture({
|
useNoteCapture({
|
||||||
rootEl: rootEl,
|
|
||||||
note: appearNote,
|
note: appearNote,
|
||||||
pureNote: note,
|
parentNote: note,
|
||||||
isDeletedRef: isDeleted,
|
isDeletedRef: isDeleted,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,13 @@ const CAPTURE_MAX = 30;
|
||||||
const POLLING_INTERVAL = 1000 * 15;
|
const POLLING_INTERVAL = 1000 * 15;
|
||||||
|
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
|
// TODO: IDごとにpriorityを付け、CAPTURE_MAXを超えた場合は優先度の低いものから削除する
|
||||||
|
// priorityは 自分のノート > リノートされているノート > その他のノート > 投稿から3分以上経過しているノート の順で高くするとよさそう
|
||||||
const ids = [...capturedNoteIdMapForPolling.keys()].sort((a, b) => (a > b ? -1 : 1)).slice(0, CAPTURE_MAX); // 新しいものを優先するためにIDで降順ソート
|
const ids = [...capturedNoteIdMapForPolling.keys()].sort((a, b) => (a > b ? -1 : 1)).slice(0, CAPTURE_MAX); // 新しいものを優先するためにIDで降順ソート
|
||||||
if (ids.length === 0) return;
|
if (ids.length === 0) return;
|
||||||
if (window.document.hidden) return;
|
if (window.document.hidden) return;
|
||||||
|
|
||||||
// まとめてリクエストするのではなく、個別にHTTPリクエスト投げてCDNにキャッシュさせた方がサーバーの負荷低減には良いかもしれない
|
// まとめてリクエストするのではなく、個別にHTTPリクエスト投げてCDNにキャッシュさせた方がサーバーの負荷低減には良いかもしれない?
|
||||||
misskeyApi('notes/show-partial-bulk', {
|
misskeyApi('notes/show-partial-bulk', {
|
||||||
noteIds: ids,
|
noteIds: ids,
|
||||||
}).then((items) => {
|
}).then((items) => {
|
||||||
|
@ -46,14 +48,11 @@ window.setInterval(() => {
|
||||||
});
|
});
|
||||||
}, POLLING_INTERVAL);
|
}, POLLING_INTERVAL);
|
||||||
|
|
||||||
function pseudoNoteCapture(props: {
|
function pollingSubscribe(props: {
|
||||||
rootEl: ShallowRef<HTMLElement | undefined>;
|
|
||||||
note: Ref<Misskey.entities.Note>;
|
note: Ref<Misskey.entities.Note>;
|
||||||
pureNote: Ref<Misskey.entities.Note>;
|
|
||||||
isDeletedRef: Ref<boolean>;
|
isDeletedRef: Ref<boolean>;
|
||||||
}) {
|
}) {
|
||||||
const note = props.note;
|
const note = props.note;
|
||||||
const pureNote = props.pureNote;
|
|
||||||
|
|
||||||
function onFetched(data: Pick<Misskey.entities.Note, 'reactions' | 'reactionEmojis'>): void {
|
function onFetched(data: Pick<Misskey.entities.Note, 'reactions' | 'reactionEmojis'>): void {
|
||||||
note.value.reactions = data.reactions;
|
note.value.reactions = data.reactions;
|
||||||
|
@ -79,20 +78,17 @@ function pseudoNoteCapture(props: {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function realtimeNoteCapture(props: {
|
function realtimeSubscribe(props: {
|
||||||
rootEl: ShallowRef<HTMLElement | undefined>;
|
|
||||||
note: Ref<Misskey.entities.Note>;
|
note: Ref<Misskey.entities.Note>;
|
||||||
pureNote: Ref<Misskey.entities.Note>;
|
|
||||||
isDeletedRef: Ref<boolean>;
|
isDeletedRef: Ref<boolean>;
|
||||||
}): void {
|
}): void {
|
||||||
const note = props.note;
|
const note = props.note;
|
||||||
const pureNote = props.pureNote;
|
|
||||||
const connection = useStream();
|
const connection = useStream();
|
||||||
|
|
||||||
function onStreamNoteUpdated(noteData): void {
|
function onStreamNoteUpdated(noteData): void {
|
||||||
const { type, id, body } = noteData;
|
const { type, id, body } = noteData;
|
||||||
|
|
||||||
if ((id !== note.value.id) && (id !== pureNote.value.id)) return;
|
if (id !== note.value.id) return;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'reacted': {
|
case 'reacted': {
|
||||||
|
@ -129,21 +125,12 @@ function realtimeNoteCapture(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
function capture(withHandler = false): void {
|
function capture(withHandler = false): void {
|
||||||
// TODO: このノートがストリーミング経由で流れてきた場合のみ sr する
|
connection.send('sr', { id: note.value.id });
|
||||||
connection.send(window.document.body.contains(props.rootEl.value ?? null as Node | null) ? 'sr' : 's', { id: note.value.id });
|
|
||||||
if (pureNote.value.id !== note.value.id) connection.send('s', { id: pureNote.value.id });
|
|
||||||
if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated);
|
if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
function decapture(withHandler = false): void {
|
function decapture(withHandler = false): void {
|
||||||
connection.send('un', {
|
connection.send('un', { id: note.value.id });
|
||||||
id: note.value.id,
|
|
||||||
});
|
|
||||||
if (pureNote.value.id !== note.value.id) {
|
|
||||||
connection.send('un', {
|
|
||||||
id: pureNote.value.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (withHandler) connection.off('noteUpdated', onStreamNoteUpdated);
|
if (withHandler) connection.off('noteUpdated', onStreamNoteUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +148,13 @@ function realtimeNoteCapture(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useNoteCapture(props: {
|
export function useNoteCapture(props: {
|
||||||
rootEl: ShallowRef<HTMLElement | undefined>;
|
|
||||||
note: Ref<Misskey.entities.Note>;
|
note: Ref<Misskey.entities.Note>;
|
||||||
pureNote: Ref<Misskey.entities.Note>;
|
parentNote: Ref<Misskey.entities.Note> | null;
|
||||||
isDeletedRef: Ref<boolean>;
|
isDeletedRef: Ref<boolean>;
|
||||||
}) {
|
}) {
|
||||||
const note = props.note;
|
const note = props.note;
|
||||||
|
const parentNote = props.parentNote;
|
||||||
|
|
||||||
noteEvents.on(`reacted:${note.value.id}`, onReacted);
|
noteEvents.on(`reacted:${note.value.id}`, onReacted);
|
||||||
noteEvents.on(`unreacted:${note.value.id}`, onUnreacted);
|
noteEvents.on(`unreacted:${note.value.id}`, onUnreacted);
|
||||||
noteEvents.on(`pollVoted:${note.value.id}`, onPollVoted);
|
noteEvents.on(`pollVoted:${note.value.id}`, onPollVoted);
|
||||||
|
@ -240,9 +228,24 @@ export function useNoteCapture(props: {
|
||||||
noteEvents.off(`deleted:${note.value.id}`, onDeleted);
|
noteEvents.off(`deleted:${note.value.id}`, onDeleted);
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($i && store.s.realtimeMode) {
|
// 投稿からある程度経過している(=タイムラインを遡って表示した)ノートは、イベントが発生する可能性が低いためそもそも購読しない
|
||||||
realtimeNoteCapture(props);
|
// ただし「リノートされたばかりの過去のノート」(= parentNoteが存在し、かつparentNoteの投稿日時が最近)はイベント発生が考えられるため購読する
|
||||||
|
// TODO: デバイスとサーバーの時計がズレていると不具合の元になるため、ズレを検知して警告を表示するなどのケアが必要かもしれない
|
||||||
|
if (parentNote == null) {
|
||||||
|
if ((Date.now() - new Date(note.value.createdAt).getTime()) > 1000 * 60 * 5) { // 5min
|
||||||
|
// リノートで表示されているノートでもないし、投稿からある程度経過しているので購読しない
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pseudoNoteCapture(props);
|
if ((Date.now() - new Date(parentNote.value.createdAt).getTime()) > 1000 * 60 * 5) { // 5min
|
||||||
|
// リノートで表示されているノートだが、リノートされてからある程度経過しているので購読しない
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i && store.s.realtimeMode) {
|
||||||
|
realtimeSubscribe(props);
|
||||||
|
} else {
|
||||||
|
pollingSubscribe(props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue