nanka iroiro (#6853)
* wip * Update maps.ts * wip * wip * wip * wip * Update base.vue * wip * wip * wip * wip * Update link.vue * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update privacy.vue * wip * wip * wip * wip * Update range.vue * wip * wip * wip * wip * Update profile.vue * wip * Update a.vue * Update index.vue * wip * Update sidebar.vue * wip * wip * Update account-info.vue * Update a.vue * wip * wip * Update sounds.vue * wip * wip * wip * wip * wip * wip * wip * wip * Update account-info.vue * Update account-info.vue * wip * wip * wip * Update d-persimmon.json5 * wip
This commit is contained in:
@ -94,6 +94,14 @@ export const meta = {
|
||||
}
|
||||
},
|
||||
|
||||
backgroundImageUrl: {
|
||||
validator: $.optional.nullable.str,
|
||||
},
|
||||
|
||||
logoImageUrl: {
|
||||
validator: $.optional.nullable.str,
|
||||
},
|
||||
|
||||
name: {
|
||||
validator: $.optional.nullable.str,
|
||||
desc: {
|
||||
@ -473,6 +481,14 @@ export default define(meta, async (ps, me) => {
|
||||
set.iconUrl = ps.iconUrl;
|
||||
}
|
||||
|
||||
if (ps.backgroundImageUrl !== undefined) {
|
||||
set.backgroundImageUrl = ps.backgroundImageUrl;
|
||||
}
|
||||
|
||||
if (ps.logoImageUrl !== undefined) {
|
||||
set.logoImageUrl = ps.logoImageUrl;
|
||||
}
|
||||
|
||||
if (ps.name !== undefined) {
|
||||
set.name = ps.name;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export default define(meta, async (ps, user) => {
|
||||
const instance = await fetchMeta(true);
|
||||
|
||||
// Calculate drive usage
|
||||
const usage = await DriveFiles.clacDriveUsageOf(user);
|
||||
const usage = await DriveFiles.calcDriveUsageOf(user);
|
||||
|
||||
return {
|
||||
capacity: 1024 * 1024 * instance.localDriveCapacityMb,
|
||||
|
@ -106,6 +106,13 @@ export const meta = {
|
||||
}
|
||||
},
|
||||
|
||||
noCrawle: {
|
||||
validator: $.optional.bool,
|
||||
desc: {
|
||||
'ja-JP': '検索エンジンによるインデックスを拒否するか否か'
|
||||
}
|
||||
},
|
||||
|
||||
isBot: {
|
||||
validator: $.optional.bool,
|
||||
desc: {
|
||||
@ -204,6 +211,7 @@ export default define(meta, async (ps, user, token) => {
|
||||
if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot;
|
||||
if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot;
|
||||
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
|
||||
if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
|
||||
if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat;
|
||||
if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
|
||||
if (typeof ps.alwaysMarkNsfw === 'boolean') profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw;
|
||||
|
@ -129,6 +129,8 @@ export default define(meta, async (ps, me) => {
|
||||
bannerUrl: instance.bannerUrl,
|
||||
errorImageUrl: instance.errorImageUrl,
|
||||
iconUrl: instance.iconUrl,
|
||||
backgroundImageUrl: instance.backgroundImageUrl,
|
||||
logoImageUrl: instance.logoImageUrl,
|
||||
maxNoteTextLength: Math.min(instance.maxNoteTextLength, DB_MAX_NOTE_TEXT_LENGTH),
|
||||
emojis: await Emojis.packMany(emojis),
|
||||
enableEmail: instance.enableEmail,
|
||||
|
144
src/server/api/endpoints/users/stats.ts
Normal file
144
src/server/api/endpoints/users/stats.ts
Normal file
@ -0,0 +1,144 @@
|
||||
import $ from 'cafy';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
import { ID } from '../../../../misc/cafy-id';
|
||||
import { DriveFiles, Followings, NoteFavorites, NoteReactions, Notes, PageLikes, PollVotes, ReversiGames, Users } from '../../../../models';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users'],
|
||||
|
||||
requireCredential: false as const,
|
||||
|
||||
params: {
|
||||
userId: {
|
||||
validator: $.type(ID),
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '9e638e45-3b25-4ef7-8f95-07e8498f1819'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const user = await Users.findOne(ps.userId);
|
||||
if (user == null) {
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
const [
|
||||
notesCount,
|
||||
repliesCount,
|
||||
renotesCount,
|
||||
repliedCount,
|
||||
renotedCount,
|
||||
pollVotesCount,
|
||||
pollVotedCount,
|
||||
localFollowingCount,
|
||||
remoteFollowingCount,
|
||||
localFollowersCount,
|
||||
remoteFollowersCount,
|
||||
sentReactionsCount,
|
||||
receivedReactionsCount,
|
||||
noteFavoritesCount,
|
||||
pageLikesCount,
|
||||
pageLikedCount,
|
||||
driveFilesCount,
|
||||
driveUsage,
|
||||
reversiCount,
|
||||
] = await Promise.all([
|
||||
Notes.createQueryBuilder('note')
|
||||
.where('note.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
Notes.createQueryBuilder('note')
|
||||
.where('note.userId = :userId', { userId: user.id })
|
||||
.andWhere('note.replyId IS NOT NULL')
|
||||
.getCount(),
|
||||
Notes.createQueryBuilder('note')
|
||||
.where('note.userId = :userId', { userId: user.id })
|
||||
.andWhere('note.renoteId IS NOT NULL')
|
||||
.getCount(),
|
||||
Notes.createQueryBuilder('note')
|
||||
.where('note.replyUserId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
Notes.createQueryBuilder('note')
|
||||
.where('note.renoteUserId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
PollVotes.createQueryBuilder('vote')
|
||||
.where('vote.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
PollVotes.createQueryBuilder('vote')
|
||||
.innerJoin('vote.note', 'note')
|
||||
.where('note.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
Followings.createQueryBuilder('following')
|
||||
.where('following.followerId = :userId', { userId: user.id })
|
||||
.andWhere('following.followeeHost IS NULL')
|
||||
.getCount(),
|
||||
Followings.createQueryBuilder('following')
|
||||
.where('following.followerId = :userId', { userId: user.id })
|
||||
.andWhere('following.followeeHost IS NOT NULL')
|
||||
.getCount(),
|
||||
Followings.createQueryBuilder('following')
|
||||
.where('following.followeeId = :userId', { userId: user.id })
|
||||
.andWhere('following.followerHost IS NULL')
|
||||
.getCount(),
|
||||
Followings.createQueryBuilder('following')
|
||||
.where('following.followeeId = :userId', { userId: user.id })
|
||||
.andWhere('following.followerHost IS NOT NULL')
|
||||
.getCount(),
|
||||
NoteReactions.createQueryBuilder('reaction')
|
||||
.where('reaction.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
NoteReactions.createQueryBuilder('reaction')
|
||||
.innerJoin('reaction.note', 'note')
|
||||
.where('note.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
NoteFavorites.createQueryBuilder('favorite')
|
||||
.where('favorite.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
PageLikes.createQueryBuilder('like')
|
||||
.where('like.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
PageLikes.createQueryBuilder('like')
|
||||
.innerJoin('like.page', 'page')
|
||||
.where('page.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
DriveFiles.createQueryBuilder('file')
|
||||
.where('file.userId = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
DriveFiles.calcDriveUsageOf(user),
|
||||
ReversiGames.createQueryBuilder('game')
|
||||
.where('game.user1Id = :userId', { userId: user.id })
|
||||
.orWhere('game.user2Id = :userId', { userId: user.id })
|
||||
.getCount(),
|
||||
]);
|
||||
|
||||
return {
|
||||
notesCount,
|
||||
repliesCount,
|
||||
renotesCount,
|
||||
repliedCount,
|
||||
renotedCount,
|
||||
pollVotesCount,
|
||||
pollVotedCount,
|
||||
localFollowingCount,
|
||||
remoteFollowingCount,
|
||||
localFollowersCount,
|
||||
remoteFollowersCount,
|
||||
followingCount: localFollowingCount + remoteFollowingCount,
|
||||
followersCount: localFollowersCount + remoteFollowersCount,
|
||||
sentReactionsCount,
|
||||
receivedReactionsCount,
|
||||
noteFavoritesCount,
|
||||
pageLikesCount,
|
||||
pageLikedCount,
|
||||
driveFilesCount,
|
||||
driveUsage,
|
||||
reversiCount,
|
||||
};
|
||||
});
|
@ -21,10 +21,11 @@ import apiServer from './api';
|
||||
import { sum } from '../prelude/array';
|
||||
import Logger from '../services/logger';
|
||||
import { program } from '../argv';
|
||||
import { UserProfiles } from '../models';
|
||||
import { UserProfiles, Users } from '../models';
|
||||
import { networkChart } from '../services/chart';
|
||||
import { genAvatar } from '../misc/gen-avatar';
|
||||
import { createTemp } from '../misc/create-temp';
|
||||
import { publishMainStream } from '../services/stream';
|
||||
|
||||
export const serverLogger = new Logger('server', 'gray', false);
|
||||
|
||||
@ -83,10 +84,15 @@ router.get('/verify-email/:code', async ctx => {
|
||||
ctx.body = 'Verify succeeded!';
|
||||
ctx.status = 200;
|
||||
|
||||
UserProfiles.update({ userId: profile.userId }, {
|
||||
await UserProfiles.update({ userId: profile.userId }, {
|
||||
emailVerified: true,
|
||||
emailVerifyCode: null
|
||||
});
|
||||
|
||||
publishMainStream(profile.userId, 'meUpdated', await Users.pack(profile.userId, profile.userId, {
|
||||
detail: true,
|
||||
includeSecrets: true
|
||||
}));
|
||||
} else {
|
||||
ctx.status = 404;
|
||||
}
|
||||
|
@ -242,9 +242,11 @@ router.get('/notes/:note', async ctx => {
|
||||
|
||||
if (note) {
|
||||
const _note = await Notes.pack(note);
|
||||
const profile = await UserProfiles.findOne(note.userId).then(ensure);
|
||||
const meta = await fetchMeta();
|
||||
await ctx.render('note', {
|
||||
note: _note,
|
||||
profile,
|
||||
// TODO: Let locale changeable by instance setting
|
||||
summary: getNoteSummary(_note, locales['ja-JP']),
|
||||
instanceName: meta.name || 'Misskey',
|
||||
@ -280,9 +282,11 @@ router.get('/@:user/pages/:page', async ctx => {
|
||||
|
||||
if (page) {
|
||||
const _page = await Pages.pack(page);
|
||||
const profile = await UserProfiles.findOne(page.userId).then(ensure);
|
||||
const meta = await fetchMeta();
|
||||
await ctx.render('page', {
|
||||
page: _page,
|
||||
profile,
|
||||
instanceName: meta.name || 'Misskey'
|
||||
});
|
||||
|
||||
@ -307,9 +311,11 @@ router.get('/clips/:clip', async ctx => {
|
||||
|
||||
if (clip) {
|
||||
const _clip = await Clips.pack(clip);
|
||||
const profile = await UserProfiles.findOne(clip.userId).then(ensure);
|
||||
const meta = await fetchMeta();
|
||||
await ctx.render('clip', {
|
||||
clip: _clip,
|
||||
profile,
|
||||
instanceName: meta.name || 'Misskey'
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,9 @@ block og
|
||||
meta(property='og:image' content= user.avatarUrl)
|
||||
|
||||
block meta
|
||||
if profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
meta(name='misskey:clip-id' content=clip.id)
|
||||
|
@ -19,6 +19,9 @@ block og
|
||||
meta(property='og:image' content= user.avatarUrl)
|
||||
|
||||
block meta
|
||||
if user.host || profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
meta(name='misskey:note-id' content=note.id)
|
||||
@ -26,9 +29,6 @@ block meta
|
||||
meta(name='twitter:card' content='summary')
|
||||
|
||||
// todo
|
||||
if user.host
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
if user.twitter
|
||||
meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
|
||||
|
||||
|
@ -19,6 +19,9 @@ block og
|
||||
meta(property='og:image' content= page.eyeCatchingImage ? page.eyeCatchingImage.thumbnailUrl : user.avatarUrl)
|
||||
|
||||
block meta
|
||||
if profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
meta(name='misskey:page-id' content=page.id)
|
||||
|
@ -19,14 +19,14 @@ block og
|
||||
meta(property='og:image' content= img)
|
||||
|
||||
block meta
|
||||
if user.host || profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
|
||||
meta(name='twitter:card' content='summary')
|
||||
|
||||
if user.host
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
if profile.twitter
|
||||
meta(name='twitter:creator' content=`@${profile.twitter.screenName}`)
|
||||
|
||||
|
Reference in New Issue
Block a user