Skip to content

Commit

Permalink
Merge branch 'serafuku-dev' into serafuku
Browse files Browse the repository at this point in the history
  • Loading branch information
yunochi committed Oct 25, 2024
2 parents 235791b + 303276e commit f32643a
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 81 deletions.
2 changes: 0 additions & 2 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1298,8 +1298,6 @@ _abuseUserReport:
resolveTutorial: "If the report is legitimate in content, select \"Accept\" to mark the case as resolved in the affirmative.\nIf the content of the report is not legitimate, select \"Reject\" to mark the case as resolved in the negative."
noteUpdatedAt: "Edited: {date} {time}"
editHistory: "Edit history"
fold: "Expand"
unfold: "Collapse"

_delivery:
status: "Delivery status"
Expand Down
8 changes: 0 additions & 8 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5301,14 +5301,6 @@ export interface Locale extends ILocale {
* 修正履歴
*/
"editHistory": string;
/**
* 開く
*/
"fold": string;
/**
* 閉じる
*/
"unfold": string;
"_delivery": {
/**
* 配信状態
Expand Down
2 changes: 0 additions & 2 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1322,8 +1322,6 @@ _abuseUserReport:
resolveTutorial: "内容が正当である通報に対応した場合は「是認」を選択し、肯定的にケースが解決されたことをマークします。\n内容が正当でない通報の場合は「否認」を選択し、否定的にケースが解決されたことをマークします。"
noteUpdatedAt: "編集済み: {date} {time}"
editHistory: "修正履歴"
fold: "開く"
unfold: "閉じる"

_delivery:
status: "配信状態"
Expand Down
2 changes: 0 additions & 2 deletions locales/ko-KR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1321,8 +1321,6 @@ _abuseUserReport:
resolveTutorial: "적절한 신고 내용에 대응한 경우, \"인용\"을 선택하여 \"해결됨\"으로 기록합니다.\n적절하지 않은 신고를 받은 경우, \"기각\"을 선택하여 \"기각\"으로 기록합니다."
noteUpdatedAt: "편집됨: {date} {time}"
editHistory: "편집 기록"
fold: "펼치기"
unfold: "접기"

_delivery:
status: "전송 상태"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,29 @@ export class CleanExpiredRemoteFilesProcessorService {
let counter = 0;

for (const uid of userIds) {
await this.db.transaction(async (entityManager) => {
const user = await entityManager.findOneBy(MiUser, { id: uid });
if (!user) return;
const userAvatarFile = user.avatarId != null ? await entityManager.findOneBy(MiDriveFile, { id: user.avatarId }) : null;
const userBannerFile = user.bannerId != null ? await entityManager.findOneBy(MiDriveFile, { id: user.bannerId }) : null;
const update: Partial<MiUser> = {};
if (userAvatarFile?.isLink) {
update.avatarUrl = userAvatarFile.uri != null ? this.getProxiedUrl(userAvatarFile.uri, 'avatar') : null;
}
if (userBannerFile?.isLink) {
update.bannerUrl = userBannerFile.uri != null ? this.getProxiedUrl(userBannerFile.uri, 'static') : null;
}

if (update.avatarUrl != null || update.bannerUrl != null) {
counter++;
this.logger.debug(`Update User ${user.id}'s avatar / banner URL...: ${JSON.stringify(update)}`);
await entityManager.update(MiUser, { id: user.id }, update);
}
});
try {
await this.db.transaction(async (entityManager) => {
const user = await entityManager.findOneBy(MiUser, { id: uid });
if (!user) return;
const userAvatarFile = user.avatarId != null ? await entityManager.findOneBy(MiDriveFile, { id: user.avatarId }) : null;
const userBannerFile = user.bannerId != null ? await entityManager.findOneBy(MiDriveFile, { id: user.bannerId }) : null;
const update: Partial<MiUser> = {};
if (userAvatarFile?.isLink) {
update.avatarUrl = userAvatarFile.uri != null ? this.getProxiedUrl(userAvatarFile.uri, 'avatar') : null;
}
if (userBannerFile?.isLink) {
update.bannerUrl = userBannerFile.uri != null ? this.getProxiedUrl(userBannerFile.uri) : null;
}

if (update.avatarUrl != null || update.bannerUrl != null) {
counter++;
this.logger.debug(`Update User ${user.id}'s avatar / banner URL...: ${JSON.stringify(update)}`);
await entityManager.update(MiUser, { id: user.id }, update);
}
});
} catch (err) {
this.logger.warn(JSON.stringify(err));
}
}

this.logger.info(`Updated ${counter} avatar/banner URL`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import { Inject, Injectable } from '@nestjs/common';
import { IsNull, MoreThan, Not } from 'typeorm';
import { ListObjectsCommandInput } from '@aws-sdk/client-s3';
import { DI } from '@/di-symbols.js';
import type { MiDriveFile, DriveFilesRepository } from '@/models/_.js';
import type { MiDriveFile, DriveFilesRepository, UsersRepository } from '@/models/_.js';
import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import { bindThis } from '@/decorators.js';
import { S3Service } from '@/core/S3Service.js';
import { MetaService } from '@/core/MetaService.js';
import type { MiRemoteUser, MiUser } from '@/models/User.js';
import { appendQuery, query } from '@/misc/prelude/url.js';
import type { Config } from '@/config.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';

Expand All @@ -24,6 +27,12 @@ export class CleanRemoteFilesProcessorService {
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

@Inject(DI.config)
private config: Config,

private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
private s3Service: S3Service,
Expand Down Expand Up @@ -72,7 +81,12 @@ export class CleanRemoteFilesProcessorService {
}

this.logger.succ('All cached remote files has been deleted.');
await this.cleanOrphanedFiles();
await this.fixAvatars();
}

@bindThis
private async cleanOrphanedFiles(): Promise<void> {
this.logger.info('Cleaning orphaned files...');
let object_cursor: string | null = null;
let delete_counter = 0;
Expand Down Expand Up @@ -121,6 +135,87 @@ export class CleanRemoteFilesProcessorService {
break;
}
}
this.logger.info(`${delete_counter} orphaned files deleted.`);
this.logger.succ(`${delete_counter} orphaned files deleted.`);
}

@bindThis
private async fixAvatars(): Promise<void> {
this.logger.info('Start Update remote users avatar URLs...');

let cursor: MiRemoteUser['id'] | null = null;
let count = 0;
while (true) {
const users = await this.usersRepository.find({
where: [{
host: Not(IsNull()),
avatarId: Not(IsNull()),
...(cursor ? { id: MoreThan(cursor) } : {} ),
}, {
host: Not(IsNull()),
bannerId: Not(IsNull()),
...(cursor ? { id: MoreThan(cursor) } : {} ),
}],
take: 8,
order: {
id: 1,
},
});

if (users.length === 0) {
break;
}
cursor = users.at(-1)?.id ?? null;
const results = await Promise.all(users.map(user => this.fixAvatar(user)));
count += results.filter(res => res).length;
}

this.logger.succ(`Updated ${count} User's avatar/banner URL`);
}

/** return true when updated */
@bindThis
private async fixAvatar(user: MiUser | null): Promise<boolean> {
const update: Partial<MiUser> = {};
if (!user) return false;
if (user.avatarId) {
const avatarFile = await this.driveFilesRepository.findOneBy({ id: user.avatarId });
if (avatarFile?.isLink && avatarFile.uri) {
const avatarUrl = this.getProxiedUrl(avatarFile.uri, 'avatar');
if (avatarUrl !== user.avatarUrl) {
update.avatarUrl = avatarUrl;
}
}
}
if (user.bannerId) {
const bannerFile = await this.driveFilesRepository.findOneBy({ id: user.bannerId });
if (bannerFile?.isLink && bannerFile.uri) {
const bannerUrl = this.getProxiedUrl(bannerFile.uri);
if (bannerUrl !== user.bannerUrl) {
update.bannerUrl = bannerUrl;
}
}
}
if (!update.avatarUrl && !update.bannerUrl) return false;

// Update User Avatar / Banner URL
try {
this.logger.debug(`Update user to ${JSON.stringify(update)}`);
await this.usersRepository.update({ id: user.id }, update);
return true;
} catch (err) {
this.logger.warn(JSON.stringify(err));
return false;
}
}

@bindThis
private getProxiedUrl(url: string, mode?: 'static' | 'avatar'): string {
return appendQuery(
`${this.config.mediaProxy}/${mode ?? 'image'}.webp`,
query({
url,
...(mode ? { [mode]: '1' } : {}),
}),
);
}
}
2 changes: 2 additions & 0 deletions packages/backend/src/server/api/SignupApiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ export class SignupApiService {
}

return { pendingApproval: true };
} else {
await this.usersRepository.update({ username: pendingUser.username }, { approved: true });
}

return this.signinService.signin(request, reply, account as MiLocalUser);
Expand Down
3 changes: 1 addition & 2 deletions packages/frontend/src/components/MkNoteDetailed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,8 @@ function loadHistories() {
};
histories.value.push(current_version);
}
if (res.length === 0) {
if (res.length < 5) {
history_list_end.value = true;
return;
}
histories_untilId.value = res[ res.length - 1 ].id;
histories.value = histories.value.concat(res);
Expand Down
48 changes: 4 additions & 44 deletions packages/frontend/src/components/MkNoteHistorySub.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
<div>
<div v-if="newNote.text && !collapsed">
<div v-if="newNote.text">
<Mfm
v-if="!raw"
:text="newNote.text"
Expand All @@ -39,16 +39,8 @@ SPDX-License-Identifier: AGPL-3.0-only
:newString="newNote.text"
/>
</div>
<span v-if="props.newNote.files && props.newNote.files.length > 0 && !collapsed">
<MkMediaList :mediaList="props.newNote.files"/>
</span>
<div :class="$style.showButton">
<button v-if="collapsed" :class="$style.showMore" class="_button" @click="collapsed = false">
<span :class="$style.showMoreLabel">{{ i18n.ts.fold }}</span>
</button>
<button v-else-if="!collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
<span :class="$style.showLessLabel">{{ i18n.ts.unfold }}</span>
</button>
<div v-if="props.newNote.files && props.newNote.files.length > 0 && !raw" style="display: flex; justify-content: center;">
<MkMediaList :mediaList="props.newNote.files" style="width: 70%;"/>
</div>
</div>
</div>
Expand All @@ -62,6 +54,7 @@ import * as Misskey from 'misskey-js';
import { CodeDiff } from 'v-code-diff';
import { userPage } from '@/filters/user.js';
import { i18n } from '@/i18n.js';
import MkMediaList from '@/components/MkMediaList.vue';

const props = defineProps<{
oldNote: Misskey.entities.NoteHistory | null;
Expand All @@ -73,7 +66,6 @@ const props = defineProps<{
// 현재 표시하는 노트의 인덱스
index: number;
}>();
const collapsed = ref(true);

</script>

Expand Down Expand Up @@ -217,38 +209,6 @@ const collapsed = ref(true);
color: var(--renote);
}

.showMore{
width: 100%;
position: sticky;
bottom: calc(var(--stickyBottom, 0px) + 14px);
}

.showMoreLabel {
display: inline-block;
background: var(--popup);
padding: 0.6em 8em;
font-size: 0.8em;
border-radius: 0.8em;
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
}

.showLess {
width: 100%;
margin-top: 14px;
position: sticky;
bottom: calc(var(--stickyBottom, 0px) + 14px);
}

.showLessLabel {
display: inline-block;
background: var(--popup);
padding: 0.6em 8em;
margin-top: 3em;
font-size: 0.8em;
border-radius: 0.8em;
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
}

.name {
flex-shrink: 1;
display: block;
Expand Down

0 comments on commit f32643a

Please sign in to comment.