commit
9ad57324db
8 changed files with 54 additions and 10 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -11,6 +11,18 @@
|
||||||
-
|
-
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## 13.12.1
|
||||||
|
|
||||||
|
### Client
|
||||||
|
- プロフィール画面におけるモデレーションノートの表示を調整
|
||||||
|
- Fix: 一部ダイアログが表示されない問題を修正
|
||||||
|
- Fix: MkUserInfoのフォローボタンが変な位置にある問題を修正
|
||||||
|
|
||||||
|
### Server
|
||||||
|
- Fix: リモートサーバーの情報が更新できない問題を修正
|
||||||
|
- Fix: 13.11を経験しない状態で13.12にアップデートした場合ユーザープロフィール関連の画像が消失する問題を修正
|
||||||
|
|
||||||
## 13.12.0
|
## 13.12.0
|
||||||
|
|
||||||
### NOTE
|
### NOTE
|
||||||
|
|
|
@ -1040,6 +1040,7 @@ initialAccountSetting: "초기 설정"
|
||||||
youFollowing: "팔로잉"
|
youFollowing: "팔로잉"
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "계정 생성이 완료되었습니다!"
|
accountCreated: "계정 생성이 완료되었습니다!"
|
||||||
|
letsStartAccountSetup: "계정의 초기 설정을 진행합니다."
|
||||||
letsFillYourProfile: "우선 나의 프로필을 설정해 보아요."
|
letsFillYourProfile: "우선 나의 프로필을 설정해 보아요."
|
||||||
profileSetting: "프로필 설정"
|
profileSetting: "프로필 설정"
|
||||||
theseSettingsCanEditLater: "이 설정들은 나중에도 변경할 수 있습니다."
|
theseSettingsCanEditLater: "이 설정들은 나중에도 변경할 수 있습니다."
|
||||||
|
@ -1049,6 +1050,7 @@ _initialAccountSetting:
|
||||||
initialAccountSettingCompleted: "초기 설정을 모두 마쳤습니다!"
|
initialAccountSettingCompleted: "초기 설정을 모두 마쳤습니다!"
|
||||||
haveFun: "{name}와 함께 즐거운 시간 보내세요!"
|
haveFun: "{name}와 함께 즐거운 시간 보내세요!"
|
||||||
ifYouNeedLearnMore: "{name}(Misskey)의 사용 방법에 대해 자세히 알아보려면 {link}를 참고해 주세요."
|
ifYouNeedLearnMore: "{name}(Misskey)의 사용 방법에 대해 자세히 알아보려면 {link}를 참고해 주세요."
|
||||||
|
skipAreYouSure: "초기 설정을 넘기시겠습니까?"
|
||||||
_serverRules:
|
_serverRules:
|
||||||
description: "회원 가입 이전에 간단하게 표시할 서버 규칙입니다. 이용 약관의 요약으로 구성하는 것을 추천합니다."
|
description: "회원 가입 이전에 간단하게 표시할 서버 규칙입니다. 이용 약관의 요약으로 구성하는 것을 추천합니다."
|
||||||
_accountMigration:
|
_accountMigration:
|
||||||
|
@ -1597,6 +1599,16 @@ _time:
|
||||||
minute: "분"
|
minute: "분"
|
||||||
hour: "시간"
|
hour: "시간"
|
||||||
day: "일"
|
day: "일"
|
||||||
|
_timelineTutorial:
|
||||||
|
title: "Misskey의 사용 방법"
|
||||||
|
step1_1: "이것은 '타임라인'입니다. {name}에 게시된 '노트'가 시간 순서대로 표시됩니다."
|
||||||
|
step1_2: "타임라인은 몇 가지 종류로 나뉩니다. 그 중에 '홈 타임라인'은 내가 팔로우한 사람의 노트가 표시되며, '로컬 타임라인'에는 {name} 의 모든 노트가 표시됩니다."
|
||||||
|
step2_1: "그럼 시험삼아 노트를 작성해 봅시다. 화면에 있는 연필 버튼을 눌러 보세요."
|
||||||
|
step2_2: "첫 노트이니까 자기소개, 혹은 가볍게 \"안녕 {name}\"라고 올려 보는 건 어떨까요?"
|
||||||
|
step3_1: "노트 작성을 끝내셨나요?"
|
||||||
|
step3_2: "당신의 노트가 타임라인에 표시되어 있다면 성공입니다."
|
||||||
|
step4_1: "노트에는 '리액션'을 붙일 수 있습니다."
|
||||||
|
step4_2: "리액션을 붙이려면, 노트의 \"+\" 버튼을 클릭하고 원하는 이모지를 선택합니다."
|
||||||
_2fa:
|
_2fa:
|
||||||
alreadyRegistered: "이미 설정이 완료되었습니다."
|
alreadyRegistered: "이미 설정이 완료되었습니다."
|
||||||
registerTOTP: "인증 앱 설정 시작"
|
registerTOTP: "인증 앱 설정 시작"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "13.12.0",
|
"version": "13.12.1",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -75,8 +75,6 @@ export class FederatedInstanceService {
|
||||||
return response.raw[0];
|
return response.raw[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
const updated = result.raw[0];
|
this.federatedInstanceCache.set(result.host, result);
|
||||||
|
|
||||||
this.federatedInstanceCache.set(updated.host, updated);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,6 +306,24 @@ export class UserEntityService implements OnModuleInit {
|
||||||
|
|
||||||
const user = typeof src === 'object' ? src : await this.usersRepository.findOneByOrFail({ id: src });
|
const user = typeof src === 'object' ? src : await this.usersRepository.findOneByOrFail({ id: src });
|
||||||
|
|
||||||
|
// migration
|
||||||
|
if (user.avatarId != null && user.avatarUrl === null) {
|
||||||
|
const avatar = await this.driveFilesRepository.findOneByOrFail({ id: user.avatarId });
|
||||||
|
user.avatarUrl = this.driveFileEntityService.getPublicUrl(avatar, 'avatar');
|
||||||
|
this.usersRepository.update(user.id, {
|
||||||
|
avatarUrl: user.avatarUrl,
|
||||||
|
avatarBlurhash: avatar.blurhash,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (user.bannerId != null && user.bannerUrl === null) {
|
||||||
|
const banner = await this.driveFilesRepository.findOneByOrFail({ id: user.bannerId });
|
||||||
|
user.bannerUrl = this.driveFileEntityService.getPublicUrl(banner);
|
||||||
|
this.usersRepository.update(user.id, {
|
||||||
|
bannerUrl: user.bannerUrl,
|
||||||
|
bannerBlurhash: banner.blurhash,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const meId = me ? me.id : null;
|
const meId = me ? me.id : null;
|
||||||
const isMe = meId === user.id;
|
const isMe = meId === user.id;
|
||||||
const iAmModerator = me ? await this.roleService.isModerator(me as User) : false;
|
const iAmModerator = me ? await this.roleService.isModerator(me as User) : false;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<MkModal ref="modal" :prefer-type="'dialog'" @click="onBgClick" @closed="$emit('closed')">
|
<MkModal ref="modal" :prefer-type="'dialog'" @click="onBgClick" @closed="$emit('closed')">
|
||||||
<div ref="rootEl" class="ebkgoccj" :style="{ width: `${width}px`, height: height ? `${height}px` : null }" @keydown="onKeydown">
|
<div ref="rootEl" class="ebkgoccj" :style="{ width: `${width}px`, height: `min(${height}px, 100%)` }" @keydown="onKeydown">
|
||||||
<div ref="headerEl" class="header">
|
<div ref="headerEl" class="header">
|
||||||
<button v-if="withOkButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
|
<button v-if="withOkButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
|
||||||
<span class="title">
|
<span class="title">
|
||||||
|
@ -24,12 +24,12 @@ const props = withDefaults(defineProps<{
|
||||||
withOkButton: boolean;
|
withOkButton: boolean;
|
||||||
okButtonDisabled: boolean;
|
okButtonDisabled: boolean;
|
||||||
width: number;
|
width: number;
|
||||||
height: number | null;
|
height: number;
|
||||||
}>(), {
|
}>(), {
|
||||||
withOkButton: false,
|
withOkButton: false,
|
||||||
okButtonDisabled: false,
|
okButtonDisabled: false,
|
||||||
width: 400,
|
width: 400,
|
||||||
height: null,
|
height: 500,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
@ -84,7 +84,6 @@ defineExpose({
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.ebkgoccj {
|
.ebkgoccj {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-height: 100%;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -131,7 +131,7 @@ defineProps<{
|
||||||
}
|
}
|
||||||
|
|
||||||
.follow {
|
.follow {
|
||||||
position: absolute;
|
position: absolute !important;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,12 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="iAmModerator" class="moderationNote">
|
<div v-if="iAmModerator" class="moderationNote">
|
||||||
<MkTextarea v-model="moderationNote" manual-save>
|
<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manual-save>
|
||||||
<template #label>Moderation note</template>
|
<template #label>Moderation note</template>
|
||||||
</MkTextarea>
|
</MkTextarea>
|
||||||
|
<div v-else>
|
||||||
|
<MkButton small @click="editModerationNote = true">Add moderation note</MkButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}">
|
<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}">
|
||||||
<div class="heading" v-text="i18n.ts.memo"/>
|
<div class="heading" v-text="i18n.ts.memo"/>
|
||||||
|
@ -142,6 +145,7 @@ import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
|
||||||
import MkTextarea from '@/components/MkTextarea.vue';
|
import MkTextarea from '@/components/MkTextarea.vue';
|
||||||
import MkOmit from '@/components/MkOmit.vue';
|
import MkOmit from '@/components/MkOmit.vue';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
import MkInfo from '@/components/MkInfo.vue';
|
||||||
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { getScrollPosition } from '@/scripts/scroll';
|
import { getScrollPosition } from '@/scripts/scroll';
|
||||||
import { getUserMenu } from '@/scripts/get-user-menu';
|
import { getUserMenu } from '@/scripts/get-user-menu';
|
||||||
import number from '@/filters/number';
|
import number from '@/filters/number';
|
||||||
|
@ -176,6 +180,7 @@ let memoTextareaEl = $ref<null | HTMLElement>(null);
|
||||||
let memoDraft = $ref(props.user.memo);
|
let memoDraft = $ref(props.user.memo);
|
||||||
let isEditingMemo = $ref(false);
|
let isEditingMemo = $ref(false);
|
||||||
let moderationNote = $ref(props.user.moderationNote);
|
let moderationNote = $ref(props.user.moderationNote);
|
||||||
|
let editModerationNote = $ref(false);
|
||||||
|
|
||||||
watch($$(moderationNote), async () => {
|
watch($$(moderationNote), async () => {
|
||||||
await os.api('admin/update-user-note', { userId: props.user.id, text: moderationNote });
|
await os.api('admin/update-user-note', { userId: props.user.id, text: moderationNote });
|
||||||
|
|
Loading…
Reference in a new issue