Merge upstream (Misskey.io)

This commit is contained in:
무라쿠모 2024-07-19 18:56:30 +09:00
commit 8bd86ce456
No known key found for this signature in database
GPG key ID: 139D6573F92DA9F7
42 changed files with 564 additions and 71 deletions

View file

@ -119,9 +119,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<i class="ti ti-ban"></i>
</button>
<button ref="reactButton" :class="$style.footerButton" class="_button" @click="toggleReact()">
<i v-if="appearNote.reactionAcceptance === 'likeOnly' && appearNote.myReaction != null" class="ti ti-heart-filled" style="color: var(--eventReactionHeart);"></i>
<i v-else-if="appearNote.myReaction != null" class="ti ti-minus" style="color: var(--accent);"></i>
<i v-else-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
<i v-if=" (appearNote.reactionAcceptance === 'likeOnly' || !$i?.policies.canUseReaction) && appearNote.myReaction != null " class="ti ti-heart-filled" style="color: var(--eventReactionHeart);"></i>
<i v-else-if="appearNote.myReaction != null " class="ti ti-minus" style="color: var(--accent);"></i>
<i v-else-if="appearNote.reactionAcceptance === 'likeOnly' || !$i?.policies.canUseReaction" class="ti ti-heart"></i>
<i v-else class="ti ti-plus"></i>
<p v-if="(appearNote.reactionAcceptance === 'likeOnly' || defaultStore.state.showReactionsCount) && appearNote.reactionCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.reactionCount) }}</p>
</button>
@ -160,6 +160,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import MkButton from './MkButton.vue';
import MkNoteSub from '@/components/MkNoteSub.vue';
import MkNoteHeader from '@/components/MkNoteHeader.vue';
import MkNoteSimple from '@/components/MkNoteSimple.vue';
@ -168,7 +169,6 @@ import MkReactionsViewerDetails from '@/components/MkReactionsViewer.details.vue
import MkMediaList from '@/components/MkMediaList.vue';
import MkCwButton from '@/components/MkCwButton.vue';
import MkPoll from '@/components/MkPoll.vue';
import MkButton from './MkButton.vue';
import MkUsersTooltip from '@/components/MkUsersTooltip.vue';
import MkUrlPreview from '@/components/MkUrlPreview.vue';
import MkInstanceTicker from '@/components/MkInstanceTicker.vue';
@ -385,7 +385,7 @@ function reply(viaKeyboard = false): void {
function react(viaKeyboard = false): void {
pleaseLogin();
showMovedDialog();
if (appearNote.value.reactionAcceptance === 'likeOnly') {
if (appearNote.value.reactionAcceptance === 'likeOnly' || !$i?.policies.canUseReaction) {
sound.playMisskeySfx('reaction');
if (props.mock) {

View file

@ -127,9 +127,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<i class="ti ti-ban"></i>
</button>
<button ref="reactButton" :class="$style.noteFooterButton" class="_button" @click="toggleReact()">
<i v-if="appearNote.reactionAcceptance === 'likeOnly' && appearNote.myReaction != null" class="ti ti-heart-filled" style="color: var(--eventReactionHeart);"></i>
<i v-else-if="appearNote.myReaction != null" class="ti ti-minus" style="color: var(--accent);"></i>
<i v-else-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
<i v-if=" (appearNote.reactionAcceptance === 'likeOnly' || !$i?.policies.canUseReaction) && appearNote.myReaction != null " class="ti ti-heart-filled" style="color: var(--eventReactionHeart);"></i>
<i v-else-if="appearNote.myReaction != null " class="ti ti-minus" style="color: var(--accent);"></i>
<i v-else-if="appearNote.reactionAcceptance === 'likeOnly' || !$i?.policies.canUseReaction" class="ti ti-heart"></i>
<i v-else class="ti ti-plus"></i>
<p v-if="(appearNote.reactionAcceptance === 'likeOnly' || defaultStore.state.showReactionsCount) && appearNote.reactionCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.reactionCount) }}</p>
</button>
@ -406,7 +406,7 @@ function reply(viaKeyboard = false): void {
function react(viaKeyboard = false): void {
pleaseLogin();
showMovedDialog();
if (appearNote.value.reactionAcceptance === 'likeOnly') {
if (appearNote.value.reactionAcceptance === 'likeOnly' || !$i?.policies.canUseReaction) {
sound.playMisskeySfx('reaction');
misskeyApi('notes/reactions/create', {

View file

@ -53,7 +53,7 @@ const popularUsers: Paging = {
params: {
state: 'alive',
origin: 'local',
sort: '+follower',
sort: '+pv',
},
};
</script>

View file

@ -25,12 +25,29 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts._profile.description }}</template>
</MkTextarea>
<MkSwitch v-model="useAsBot">
<template #label>{{ i18n.ts.flagAsBot }}</template>
</MkSwitch>
<div v-if="useAsBot" class="_gaps_m">
<div>
<MkInfo>{{ i18n.ts._initialAccountSetting.mustBeSetBotOwner }}</MkInfo>
</div>
<div>
<MkButton @click="selectBotOwner">{{ i18n.ts.selectUser }}</MkButton>
<MkUserCardMini v-if="botOwner" :user="botOwner"></MkUserCardMini>
</div>
</div>
<MkInfo>{{ i18n.ts._initialAccountSetting.youCanEditMoreSettingsInSettingsPageLater }}</MkInfo>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import * as Misskey from 'misskey-js';
import MkSwitch from '@/components/MkSwitch.vue';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import { i18n } from '@/i18n.js';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
@ -45,6 +62,12 @@ const $i = signinRequired();
const name = ref($i.name ?? '');
const description = ref($i.description ?? '');
const useAsBot = ref($i.isBot ?? false);
const botOwner = ref<Misskey.entities.UserDetailed | null>(null);
const emit = defineEmits<{
(ev: 'nextButtonEnabled', value: boolean): void;
}>();
watch(name, () => {
os.apiWithDialog('i/update', {
@ -62,6 +85,12 @@ watch(description, () => {
});
});
watch(useAsBot, () => {
watchBotSettings();
os.apiWithDialog('i/update', { isBot: useAsBot.value });
});
watch(botOwner, watchBotSettings);
function setAvatar(ev) {
chooseFileFromPc(false).then(async (files) => {
const file = files[0];
@ -88,6 +117,25 @@ function setAvatar(ev) {
$i.avatarUrl = i.avatarUrl;
});
}
function selectBotOwner() {
os.selectUser({ includeSelf: false, localOnly: true }).then(_user => {
botOwner.value = _user;
});
}
function watchBotSettings() {
if (useAsBot.value) {
if (botOwner.value != null) {
description.value = (description.value + '\n管理者: @' + botOwner.value.username).trim();
emit('nextButtonEnabled', true);
} else {
emit('nextButtonEnabled', false);
}
} else {
emit('nextButtonEnabled', true);
}
}
</script>
<style lang="scss" module>

View file

@ -9,7 +9,6 @@ SPDX-License-Identifier: AGPL-3.0-only
:width="500"
:height="550"
data-cy-user-setup
@close="close(true)"
@closed="emit('closed')"
>
<template v-if="page === 1" #header><i class="ti ti-user-edit"></i> {{ i18n.ts._initialAccountSetting.profileSetting }}</template>
@ -48,12 +47,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<div style="height: 100cqh; overflow: auto;">
<div :class="$style.pageRoot">
<MkSpacer :marginMin="20" :marginMax="28" :class="$style.pageMain">
<XProfile/>
<XProfile :onNextButtonEnabled="(state) => page1NextButtonDisabled = !state"/>
</MkSpacer>
<div :class="$style.pageFooter">
<div class="_buttonsCenter">
<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
<MkButton primary rounded gradate data-cy-user-setup-continue :disabled="page1NextButtonDisabled" @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
</div>
</div>
</div>
@ -151,6 +150,8 @@ const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
// eslint-disable-next-line vue/no-setup-props-destructure
const page = ref(defaultStore.state.accountSetupWizard);
const page1NextButtonDisabled = ref(false);
watch(page, () => {
defaultStore.set('accountSetupWizard', page.value);
});

View file

@ -92,6 +92,7 @@ export const ROLE_POLICIES = [
'canSearchNotes',
'canUseTranslator',
'canUseDriveFileInSoundSettings',
'canUseReaction',
'canHideAds',
'driveCapacityMb',
'alwaysMarkNsfw',

View file

@ -523,6 +523,26 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseReaction, 'canUseReaction'])">
<template #label>{{ i18n.ts._role._options.canUseReaction }}</template>
<template #suffix>
<span v-if="role.policies.canUseReaction.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
<span v-else>{{ role.policies.canUseReaction.value ? i18n.ts.yes : i18n.ts.no }}</span>
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canUseReaction)"></i></span>
</template>
<div class="_gaps">
<MkSwitch v-model="role.policies.canUseReaction.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
</MkSwitch>
<MkSwitch v-model="role.policies.canUseReaction.value" :disabled="role.policies.canUseReaction.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts.enable }}</template>
</MkSwitch>
<MkRange v-model="role.policies.canUseReaction.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
<template #label>{{ i18n.ts._role.priority }}</template>
</MkRange>
</div>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacity, 'driveCapacityMb'])">
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
<template #suffix>

View file

@ -98,7 +98,7 @@ const pinnedUsers = { endpoint: 'pinned-users', noPaging: true };
const popularUsers = { endpoint: 'users', limit: 10, noPaging: true, params: {
state: 'alive',
origin: 'local',
sort: '+follower',
sort: '+pv',
} };
const recentlyUpdatedUsers = { endpoint: 'users', limit: 10, noPaging: true, params: {
origin: 'local',

View file

@ -1,4 +1,4 @@
<!--
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
@ -65,9 +65,22 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>
</div>
<MkSwitch v-model="keepCw">{{ i18n.ts.keepCw }}</MkSwitch>
</FormSection>
<MkSwitch v-model="keepCw" @update:modelValue="save()">{{ i18n.ts.keepCw }}</MkSwitch>
<FormSection>
<template #label>{{ i18n.ts.hideSensitiveInformation }}</template>
<div class="_gaps_m">
<MkSwitch v-model="hideDirectMessages">
{{ i18n.ts.flagAsCat }}
<template #caption>{{ i18n.ts.flagAsCatDescription }}</template>
</MkSwitch>
</div>
<div class="_gaps_m">
</div>
</FormSection>
</div>
</template>
@ -99,6 +112,7 @@ const defaultNoteVisibility = computed(defaultStore.makeGetterSetter('defaultNot
const defaultNoteLocalOnly = computed(defaultStore.makeGetterSetter('defaultNoteLocalOnly'));
const rememberNoteVisibility = computed(defaultStore.makeGetterSetter('rememberNoteVisibility'));
const keepCw = computed(defaultStore.makeGetterSetter('keepCw'));
const hideDirectMessages = computed(defaultStore.makeGetterSetter('hideDirectMessages'));
function save() {
misskeyApi('i/update', {

View file

@ -80,6 +80,10 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'account',
default: true,
},
hideDirectMessages: {
where: 'deviceAccount',
default: false,
},
showFullAcct: {
where: 'account',
default: false,