add shuffled note timeline
Some checks failed
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/lint-foundkey-js Pipeline was successful
ci/woodpecker/push/lint-sw Pipeline failed
ci/woodpecker/push/lint-client Pipeline failed
ci/woodpecker/push/lint-backend Pipeline failed
ci/woodpecker/push/test Pipeline failed
Some checks failed
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/lint-foundkey-js Pipeline was successful
ci/woodpecker/push/lint-sw Pipeline failed
ci/woodpecker/push/lint-client Pipeline failed
ci/woodpecker/push/lint-backend Pipeline failed
ci/woodpecker/push/test Pipeline failed
Changelog: Added
This commit is contained in:
parent
0bdc24b34e
commit
0bcbb38ecc
5 changed files with 96 additions and 1 deletions
|
@ -1247,6 +1247,7 @@ _timelines:
|
|||
local: "Local"
|
||||
social: "Social"
|
||||
global: "Global"
|
||||
shuffled: "Shuffled"
|
||||
_pages:
|
||||
newPage: "Create a new Page"
|
||||
editPage: "Edit this Page"
|
||||
|
|
|
@ -229,6 +229,7 @@ import * as ep___notes_replies from './endpoints/notes/replies.js';
|
|||
import * as ep___notes_searchByTag from './endpoints/notes/search-by-tag.js';
|
||||
import * as ep___notes_search from './endpoints/notes/search.js';
|
||||
import * as ep___notes_show from './endpoints/notes/show.js';
|
||||
import * as ep___notes_shuffled from './endpoints/notes/shuffled.js';
|
||||
import * as ep___notes_state from './endpoints/notes/state.js';
|
||||
import * as ep___notes_threadMuting_create from './endpoints/notes/thread-muting/create.js';
|
||||
import * as ep___notes_threadMuting_delete from './endpoints/notes/thread-muting/delete.js';
|
||||
|
@ -523,6 +524,7 @@ const eps = [
|
|||
['notes/search-by-tag', ep___notes_searchByTag],
|
||||
['notes/search', ep___notes_search],
|
||||
['notes/show', ep___notes_show],
|
||||
['notes/shuffled', ep___notes_shuffled],
|
||||
['notes/state', ep___notes_state],
|
||||
['notes/thread-muting/create', ep___notes_threadMuting_create],
|
||||
['notes/thread-muting/delete', ep___notes_threadMuting_delete],
|
||||
|
|
80
packages/backend/src/server/api/endpoints/notes/shuffled.ts
Normal file
80
packages/backend/src/server/api/endpoints/notes/shuffled.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { Notes } from '@/models/index.js';
|
||||
import { activeUsersChart } from '@/services/chart/index.js';
|
||||
import define from '@/server/api/define.js';
|
||||
import { makePaginationQuery } from '@/server/api/common/make-pagination-query.js';
|
||||
import { visibilityQuery } from '@/server/api/common/generate-visibility-query.js';
|
||||
import { generateMutedUserQuery } from '@/server/api/common/generate-muted-user-query.js';
|
||||
import { generateRepliesQuery } from '@/server/api/common/generate-replies-query.js';
|
||||
import { generateMutedNoteQuery } from '@/server/api/common/generate-muted-note-query.js';
|
||||
import { generateChannelQuery } from '@/server/api/common/generate-channel-query.js';
|
||||
import { generateBlockedUserQuery } from '@/server/api/common/generate-block-query.js';
|
||||
import { generateMutedRenotesQuery } from '@/server/api/common/generated-muted-renote-query.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['notes'],
|
||||
|
||||
description: 'Returns a shuffled list of the current users notes.',
|
||||
|
||||
requireCredential: true,
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
ref: 'Note',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
seed: {
|
||||
description: 'A seed for the shuffling. If the same seed is provided, the same shuffling will be used. Required for pagination to work.',
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
//#region Construct query
|
||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'),
|
||||
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||
.addSelect('md5(note.id || ' + ps.seed + ')', 'shuffleorder')
|
||||
.andWhere('note.userId = :meId', { meId: user.id })
|
||||
.innerJoinAndSelect('note.user', 'user')
|
||||
.leftJoinAndSelect('user.avatar', 'avatar')
|
||||
.leftJoinAndSelect('user.banner', 'banner')
|
||||
.leftJoinAndSelect('note.reply', 'reply')
|
||||
.leftJoinAndSelect('note.renote', 'renote')
|
||||
.leftJoinAndSelect('reply.user', 'replyUser')
|
||||
.leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar')
|
||||
.leftJoinAndSelect('replyUser.banner', 'replyUserBanner')
|
||||
.leftJoinAndSelect('renote.user', 'renoteUser')
|
||||
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
|
||||
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner')
|
||||
.orderBy('shuffleorder');
|
||||
|
||||
generateChannelQuery(query, user);
|
||||
generateRepliesQuery(query, user);
|
||||
generateMutedUserQuery(query, user);
|
||||
generateMutedNoteQuery(query, user);
|
||||
generateBlockedUserQuery(query, user);
|
||||
generateMutedRenotesQuery(query, user);
|
||||
//#endregion
|
||||
|
||||
const timeline = await visibilityQuery(query, user).take(ps.limit).getMany();
|
||||
|
||||
process.nextTick(() => {
|
||||
activeUsersChart.read(user);
|
||||
});
|
||||
|
||||
return await Notes.packMany(timeline, user);
|
||||
});
|
|
@ -10,7 +10,7 @@ import * as sound from '@/scripts/sound';
|
|||
import { $i } from '@/account';
|
||||
|
||||
const props = defineProps<{
|
||||
src: 'antenna' | 'home' | 'local' | 'social' | 'global' | 'mentions' | 'directs' | 'list' | 'channel' | 'file';
|
||||
src: 'antenna' | 'home' | 'local' | 'social' | 'global' | 'mentions' | 'directs' | 'list' | 'channel' | 'file' | 'shuffled';
|
||||
list?: string;
|
||||
antenna?: string;
|
||||
channel?: string;
|
||||
|
@ -51,6 +51,7 @@ const onChangeFollowing = () => {
|
|||
}
|
||||
};
|
||||
|
||||
let randomSeed = Math.random();
|
||||
let endpoint;
|
||||
let query;
|
||||
let connection;
|
||||
|
@ -136,6 +137,12 @@ switch (props.src) {
|
|||
fileId: props.fileId,
|
||||
};
|
||||
break;
|
||||
case 'shuffled':
|
||||
endpoint = 'notes/shuffled';
|
||||
query = {
|
||||
seed: randomSeed,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
const pagination = {
|
||||
|
|
|
@ -144,6 +144,11 @@ const headerTabs = $computed(() => [{
|
|||
title: i18n.ts.channel,
|
||||
iconOnly: true,
|
||||
onClick: chooseChannel,
|
||||
}, {
|
||||
key: 'shuffled',
|
||||
icon: 'fas fa-shuffle',
|
||||
title: i18n.ts._timelines.shuffled,
|
||||
iconOnly: true,
|
||||
}]);
|
||||
|
||||
definePageMetadata(computed(() => ({
|
||||
|
|
Loading…
Reference in a new issue