From 0126dba475c2dea706c6157c7baecc154a013772 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 13 Mar 2025 19:30:35 +0900 Subject: [PATCH] enhance(frontend): re-organize settings page --- .../frontend/src/pages/settings/index.vue | 5 - .../frontend/src/pages/settings/other.vue | 21 + .../src/pages/settings/preferences.vue | 972 +++++++++--------- .../frontend/src/pages/settings/roles.vue | 48 - packages/frontend/src/router/definition.ts | 4 - .../utility/autogen/settings-search-index.ts | 115 ++- 6 files changed, 568 insertions(+), 597 deletions(-) delete mode 100644 packages/frontend/src/pages/settings/roles.vue diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue index e8ba03005a..0579b6d14a 100644 --- a/packages/frontend/src/pages/settings/index.vue +++ b/packages/frontend/src/pages/settings/index.vue @@ -140,11 +140,6 @@ const menuDef = computed<SuperMenuDef[]>(() => [{ text: i18n.ts.drive, to: '/settings/drive', active: currentPage.value?.route.name === 'drive', - }, { - icon: 'ti ti-badges', - text: i18n.ts.roles, - to: '/settings/roles', - active: currentPage.value?.route.name === 'roles', }, { icon: 'ti ti-ban', text: i18n.ts.muteAndBlock, diff --git a/packages/frontend/src/pages/settings/other.vue b/packages/frontend/src/pages/settings/other.vue index 835739a6c6..b60db78071 100644 --- a/packages/frontend/src/pages/settings/other.vue +++ b/packages/frontend/src/pages/settings/other.vue @@ -33,10 +33,30 @@ SPDX-License-Identifier: AGPL-3.0-only <template #key>{{ i18n.ts.registeredDate }}</template> <template #value><MkTime :time="$i.createdAt" mode="detail"/></template> </MkKeyValue> + + <MkFolder> + <template #icon><i class="ti ti-badges"></i></template> + <template #label><SearchLabel>{{ i18n.ts._role.policies }}</SearchLabel></template> + + <div class="_gaps_s"> + <div v-for="policy in Object.keys($i.policies)" :key="policy"> + {{ policy }} ... {{ $i.policies[policy] }} + </div> + </div> + </MkFolder> </div> </MkFolder> </SearchMarker> + <SearchMarker :keywords="['roles']"> + <MkFolder> + <template #icon><i class="ti ti-badges"></i></template> + <template #label><SearchLabel>{{ i18n.ts.rolesAssignedToMe }}</SearchLabel></template> + + <MkRolePreview v-for="role in $i.roles" :key="role.id" :role="role" :forModeration="false"/> + </MkFolder> + </SearchMarker> + <SearchMarker :keywords="['account', 'move', 'migration']"> <MkFolder> <template #icon><i class="ti ti-plane"></i></template> @@ -124,6 +144,7 @@ import { definePage } from '@/page.js'; import { reloadAsk } from '@/utility/reload-ask.js'; import FormSection from '@/components/form/section.vue'; import { prefer } from '@/preferences.js'; +import MkRolePreview from '@/components/MkRolePreview.vue'; const $i = signinRequired(); diff --git a/packages/frontend/src/pages/settings/preferences.vue b/packages/frontend/src/pages/settings/preferences.vue index b9a596067c..94d154e9c7 100644 --- a/packages/frontend/src/pages/settings/preferences.vue +++ b/packages/frontend/src/pages/settings/preferences.vue @@ -10,510 +10,512 @@ SPDX-License-Identifier: AGPL-3.0-only <SearchKeyword>{{ i18n.ts._settings.preferencesBanner }}</SearchKeyword> </MkFeatureBanner> - <SearchMarker :keywords="['general']"> - <MkFolder :defaultOpen="true"> - <template #label><SearchLabel>{{ i18n.ts.general }}</SearchLabel></template> + <div class="_gaps_s"> + <SearchMarker :keywords="['general']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.general }}</SearchLabel></template> - <div class="_gaps_m"> - <SearchMarker :keywords="['language']"> - <MkSelect v-model="lang"> - <template #label><SearchLabel>{{ i18n.ts.uiLanguage }}</SearchLabel></template> - <option v-for="x in langs" :key="x[0]" :value="x[0]">{{ x[1] }}</option> - <template #caption> - <I18n :src="i18n.ts.i18nInfo" tag="span"> - <template #link> - <MkLink url="https://crowdin.com/project/misskey">Crowdin</MkLink> - </template> - </I18n> - </template> - </MkSelect> - </SearchMarker> - - <SearchMarker :keywords="['device', 'type', 'kind', 'smartphone', 'tablet', 'desktop']"> - <MkRadios v-model="overridedDeviceKind"> - <template #label><SearchLabel>{{ i18n.ts.overridedDeviceKind }}</SearchLabel></template> - <option :value="null">{{ i18n.ts.auto }}</option> - <option value="smartphone"><i class="ti ti-device-mobile"/> {{ i18n.ts.smartphone }}</option> - <option value="tablet"><i class="ti ti-device-tablet"/> {{ i18n.ts.tablet }}</option> - <option value="desktop"><i class="ti ti-device-desktop"/> {{ i18n.ts.desktop }}</option> - </MkRadios> - </SearchMarker> - - <div class="_gaps_s"> - <SearchMarker :keywords="['blur']"> - <MkPreferenceContainer k="useBlurEffect"> - <MkSwitch v-model="useBlurEffect"> - <template #label><SearchLabel>{{ i18n.ts.useBlurEffect }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['blur', 'modal']"> - <MkPreferenceContainer k="useBlurEffectForModal"> - <MkSwitch v-model="useBlurEffectForModal"> - <template #label><SearchLabel>{{ i18n.ts.useBlurEffectForModal }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['avatar', 'icon', 'decoration', 'show']"> - <MkPreferenceContainer k="showAvatarDecorations"> - <MkSwitch v-model="showAvatarDecorations"> - <template #label><SearchLabel>{{ i18n.ts.showAvatarDecorations }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['follow', 'confirm', 'always']"> - <MkPreferenceContainer k="alwaysConfirmFollow"> - <MkSwitch v-model="alwaysConfirmFollow"> - <template #label><SearchLabel>{{ i18n.ts.alwaysConfirmFollow }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['highlight', 'sensitive', 'nsfw', 'image', 'photo', 'picture', 'media', 'thumbnail']"> - <MkPreferenceContainer k="highlightSensitiveMedia"> - <MkSwitch v-model="highlightSensitiveMedia"> - <template #label><SearchLabel>{{ i18n.ts.highlightSensitiveMedia }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['sensitive', 'nsfw', 'media', 'image', 'photo', 'picture', 'attachment', 'confirm']"> - <MkPreferenceContainer k="confirmWhenRevealingSensitiveMedia"> - <MkSwitch v-model="confirmWhenRevealingSensitiveMedia"> - <template #label><SearchLabel>{{ i18n.ts.confirmWhenRevealingSensitiveMedia }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - </div> - - <SearchMarker :keywords="['emoji', 'style', 'native', 'system', 'fluent', 'twemoji']"> - <MkPreferenceContainer k="emojiStyle"> - <div> - <MkRadios v-model="emojiStyle"> - <template #label><SearchLabel>{{ i18n.ts.emojiStyle }}</SearchLabel></template> - <option value="native">{{ i18n.ts.native }}</option> - <option value="fluentEmoji">Fluent Emoji</option> - <option value="twemoji">Twemoji</option> - </MkRadios> - <div style="margin: 8px 0 0 0; font-size: 1.5em;"><Mfm :key="emojiStyle" text="๐ฎ๐ฆ๐ญ๐ฉ๐ฐ๐ซ๐ฌ๐ฅ๐ช"/></div> - </div> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['pinned', 'list']"> - <MkFolder> - <template #label><SearchLabel>{{ i18n.ts.pinnedList }}</SearchLabel></template> - <!-- ่คๆฐใใณๆญขใ็ฎก็ใงใใใใใซใใใใใฉใใใฉใใฎใงไธๆฆใฒใจใคใฎใฟ --> - <MkButton v-if="prefer.r.pinnedUserLists.value.length === 0" @click="setPinnedList()">{{ i18n.ts.add }}</MkButton> - <MkButton v-else danger @click="removePinnedList()"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton> - </MkFolder> - </SearchMarker> - </div> - </MkFolder> - </SearchMarker> - - <SearchMarker :keywords="['timeline']"> - <MkFolder :defaultOpen="true"> - <template #label><SearchLabel>{{ i18n.ts.timeline }}</SearchLabel></template> - - <div class="_gaps_s"> - <SearchMarker :keywords="['post', 'form', 'timeline']"> - <MkPreferenceContainer k="showFixedPostForm"> - <MkSwitch v-model="showFixedPostForm"> - <template #label><SearchLabel>{{ i18n.ts.showFixedPostForm }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['post', 'form', 'timeline', 'channel']"> - <MkPreferenceContainer k="showFixedPostFormInChannel"> - <MkSwitch v-model="showFixedPostFormInChannel"> - <template #label><SearchLabel>{{ i18n.ts.showFixedPostFormInChannel }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['renote']"> - <MkPreferenceContainer k="collapseRenotes"> - <MkSwitch v-model="collapseRenotes"> - <template #label><SearchLabel>{{ i18n.ts.collapseRenotes }}</SearchLabel></template> - <template #caption><SearchKeyword>{{ i18n.ts.collapseRenotesDescription }}</SearchKeyword></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['note', 'timeline', 'gap']"> - <MkPreferenceContainer k="showGapBetweenNotesInTimeline"> - <MkSwitch v-model="showGapBetweenNotesInTimeline"> - <template #label><SearchLabel>{{ i18n.ts.showGapBetweenNotesInTimeline }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['load', 'auto', 'more']"> - <MkPreferenceContainer k="enableInfiniteScroll"> - <MkSwitch v-model="enableInfiniteScroll"> - <template #label><SearchLabel>{{ i18n.ts.enableInfiniteScroll }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['disable', 'streaming', 'timeline']"> - <MkPreferenceContainer k="disableStreamingTimeline"> - <MkSwitch v-model="disableStreamingTimeline"> - <template #label><SearchLabel>{{ i18n.ts.disableStreamingTimeline }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - </div> - </MkFolder> - </SearchMarker> - - <SearchMarker :keywords="['note']"> - <MkFolder :defaultOpen="true"> - <template #label><SearchLabel>{{ i18n.ts.note }}</SearchLabel></template> - - <div class="_gaps_m"> - <div class="_gaps_s"> - <SearchMarker :keywords="['hover', 'show', 'footer', 'action']"> - <MkPreferenceContainer k="showNoteActionsOnlyHover"> - <MkSwitch v-model="showNoteActionsOnlyHover"> - <template #label><SearchLabel>{{ i18n.ts.showNoteActionsOnlyHover }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['footer', 'action', 'clip', 'show']"> - <MkPreferenceContainer k="showClipButtonInNoteFooter"> - <MkSwitch v-model="showClipButtonInNoteFooter"> - <template #label><SearchLabel>{{ i18n.ts.showClipButtonInNoteFooter }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['mfm', 'enable', 'show', 'advanced']"> - <MkPreferenceContainer k="advancedMfm"> - <MkSwitch v-model="advancedMfm"> - <template #label><SearchLabel>{{ i18n.ts.enableAdvancedMfm }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['reaction', 'count', 'show']"> - <MkPreferenceContainer k="showReactionsCount"> - <MkSwitch v-model="showReactionsCount"> - <template #label><SearchLabel>{{ i18n.ts.showReactionsCount }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['reaction', 'confirm']"> - <MkPreferenceContainer k="confirmOnReact"> - <MkSwitch v-model="confirmOnReact"> - <template #label><SearchLabel>{{ i18n.ts.confirmOnReact }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['image', 'photo', 'picture', 'media', 'thumbnail', 'quality', 'raw', 'attachment']"> - <MkPreferenceContainer k="loadRawImages"> - <MkSwitch v-model="loadRawImages"> - <template #label><SearchLabel>{{ i18n.ts.loadRawImages }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['reaction', 'picker', 'contextmenu', 'open']"> - <MkPreferenceContainer k="useReactionPickerForContextMenu"> - <MkSwitch v-model="useReactionPickerForContextMenu"> - <template #label><SearchLabel>{{ i18n.ts.useReactionPickerForContextMenu }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - </div> - - <SearchMarker :keywords="['reaction', 'size', 'scale', 'display']"> - <MkPreferenceContainer k="reactionsDisplaySize"> - <MkRadios v-model="reactionsDisplaySize"> - <template #label><SearchLabel>{{ i18n.ts.reactionsDisplaySize }}</SearchLabel></template> - <option value="small">{{ i18n.ts.small }}</option> - <option value="medium">{{ i18n.ts.medium }}</option> - <option value="large">{{ i18n.ts.large }}</option> - </MkRadios> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['reaction', 'size', 'scale', 'display', 'width', 'limit']"> - <MkPreferenceContainer k="limitWidthOfReaction"> - <MkSwitch v-model="limitWidthOfReaction"> - <template #label><SearchLabel>{{ i18n.ts.limitWidthOfReaction }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['attachment', 'image', 'photo', 'picture', 'media', 'thumbnail', 'list', 'size', 'height']"> - <MkPreferenceContainer k="mediaListWithOneImageAppearance"> - <MkRadios v-model="mediaListWithOneImageAppearance"> - <template #label><SearchLabel>{{ i18n.ts.mediaListWithOneImageAppearance }}</SearchLabel></template> - <option value="expand">{{ i18n.ts.default }}</option> - <option value="16_9">{{ i18n.tsx.limitTo({ x: '16:9' }) }}</option> - <option value="1_1">{{ i18n.tsx.limitTo({ x: '1:1' }) }}</option> - <option value="2_3">{{ i18n.tsx.limitTo({ x: '2:3' }) }}</option> - </MkRadios> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['ticker', 'information', 'label', 'instance', 'server', 'host', 'federation']"> - <MkPreferenceContainer k="instanceTicker"> - <MkSelect v-if="instance.federation !== 'none'" v-model="instanceTicker"> - <template #label><SearchLabel>{{ i18n.ts.instanceTicker }}</SearchLabel></template> - <option value="none">{{ i18n.ts._instanceTicker.none }}</option> - <option value="remote">{{ i18n.ts._instanceTicker.remote }}</option> - <option value="always">{{ i18n.ts._instanceTicker.always }}</option> + <div class="_gaps_m"> + <SearchMarker :keywords="['language']"> + <MkSelect v-model="lang"> + <template #label><SearchLabel>{{ i18n.ts.uiLanguage }}</SearchLabel></template> + <option v-for="x in langs" :key="x[0]" :value="x[0]">{{ x[1] }}</option> + <template #caption> + <I18n :src="i18n.ts.i18nInfo" tag="span"> + <template #link> + <MkLink url="https://crowdin.com/project/misskey">Crowdin</MkLink> + </template> + </I18n> + </template> </MkSelect> - </MkPreferenceContainer> - </SearchMarker> + </SearchMarker> - <SearchMarker :keywords="['attachment', 'image', 'photo', 'picture', 'media', 'thumbnail', 'nsfw', 'sensitive', 'display', 'show', 'hide', 'visibility']"> - <MkPreferenceContainer k="nsfw"> - <MkSelect v-model="nsfw"> - <template #label><SearchLabel>{{ i18n.ts.displayOfSensitiveMedia }}</SearchLabel></template> - <option value="respect">{{ i18n.ts._displayOfSensitiveMedia.respect }}</option> - <option value="ignore">{{ i18n.ts._displayOfSensitiveMedia.ignore }}</option> - <option value="force">{{ i18n.ts._displayOfSensitiveMedia.force }}</option> - </MkSelect> - </MkPreferenceContainer> - </SearchMarker> - </div> - </MkFolder> - </SearchMarker> + <SearchMarker :keywords="['device', 'type', 'kind', 'smartphone', 'tablet', 'desktop']"> + <MkRadios v-model="overridedDeviceKind"> + <template #label><SearchLabel>{{ i18n.ts.overridedDeviceKind }}</SearchLabel></template> + <option :value="null">{{ i18n.ts.auto }}</option> + <option value="smartphone"><i class="ti ti-device-mobile"/> {{ i18n.ts.smartphone }}</option> + <option value="tablet"><i class="ti ti-device-tablet"/> {{ i18n.ts.tablet }}</option> + <option value="desktop"><i class="ti ti-device-desktop"/> {{ i18n.ts.desktop }}</option> + </MkRadios> + </SearchMarker> - <SearchMarker :keywords="['post', 'form']"> - <MkFolder :defaultOpen="true"> - <template #label><SearchLabel>{{ i18n.ts.postForm }}</SearchLabel></template> + <div class="_gaps_s"> + <SearchMarker :keywords="['blur']"> + <MkPreferenceContainer k="useBlurEffect"> + <MkSwitch v-model="useBlurEffect"> + <template #label><SearchLabel>{{ i18n.ts.useBlurEffect }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> - <div class="_gaps_m"> - <div class="_gaps_s"> - <SearchMarker :keywords="['remember', 'keep', 'note', 'cw']"> - <MkPreferenceContainer k="keepCw"> - <MkSwitch v-model="keepCw"> - <template #label><SearchLabel>{{ i18n.ts.keepCw }}</SearchLabel></template> - </MkSwitch> + <SearchMarker :keywords="['blur', 'modal']"> + <MkPreferenceContainer k="useBlurEffectForModal"> + <MkSwitch v-model="useBlurEffectForModal"> + <template #label><SearchLabel>{{ i18n.ts.useBlurEffectForModal }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['avatar', 'icon', 'decoration', 'show']"> + <MkPreferenceContainer k="showAvatarDecorations"> + <MkSwitch v-model="showAvatarDecorations"> + <template #label><SearchLabel>{{ i18n.ts.showAvatarDecorations }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['follow', 'confirm', 'always']"> + <MkPreferenceContainer k="alwaysConfirmFollow"> + <MkSwitch v-model="alwaysConfirmFollow"> + <template #label><SearchLabel>{{ i18n.ts.alwaysConfirmFollow }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['highlight', 'sensitive', 'nsfw', 'image', 'photo', 'picture', 'media', 'thumbnail']"> + <MkPreferenceContainer k="highlightSensitiveMedia"> + <MkSwitch v-model="highlightSensitiveMedia"> + <template #label><SearchLabel>{{ i18n.ts.highlightSensitiveMedia }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['sensitive', 'nsfw', 'media', 'image', 'photo', 'picture', 'attachment', 'confirm']"> + <MkPreferenceContainer k="confirmWhenRevealingSensitiveMedia"> + <MkSwitch v-model="confirmWhenRevealingSensitiveMedia"> + <template #label><SearchLabel>{{ i18n.ts.confirmWhenRevealingSensitiveMedia }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + </div> + + <SearchMarker :keywords="['emoji', 'style', 'native', 'system', 'fluent', 'twemoji']"> + <MkPreferenceContainer k="emojiStyle"> + <div> + <MkRadios v-model="emojiStyle"> + <template #label><SearchLabel>{{ i18n.ts.emojiStyle }}</SearchLabel></template> + <option value="native">{{ i18n.ts.native }}</option> + <option value="fluentEmoji">Fluent Emoji</option> + <option value="twemoji">Twemoji</option> + </MkRadios> + <div style="margin: 8px 0 0 0; font-size: 1.5em;"><Mfm :key="emojiStyle" text="๐ฎ๐ฆ๐ญ๐ฉ๐ฐ๐ซ๐ฌ๐ฅ๐ช"/></div> + </div> </MkPreferenceContainer> </SearchMarker> - <SearchMarker :keywords="['remember', 'keep', 'note', 'visibility']"> - <MkPreferenceContainer k="rememberNoteVisibility"> - <MkSwitch v-model="rememberNoteVisibility"> - <template #label><SearchLabel>{{ i18n.ts.rememberNoteVisibility }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['mfm', 'enable', 'show', 'advanced', 'picker', 'form', 'function', 'fn']"> - <MkPreferenceContainer k="enableQuickAddMfmFunction"> - <MkSwitch v-model="enableQuickAddMfmFunction"> - <template #label><SearchLabel>{{ i18n.ts.enableQuickAddMfmFunction }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - </div> - - <SearchMarker :keywords="['default', 'note', 'visibility']"> - <MkDisableSection :disabled="rememberNoteVisibility"> + <SearchMarker :keywords="['pinned', 'list']"> <MkFolder> - <template #label><SearchLabel>{{ i18n.ts.defaultNoteVisibility }}</SearchLabel></template> - <template v-if="defaultNoteVisibility === 'public'" #suffix>{{ i18n.ts._visibility.public }}</template> - <template v-else-if="defaultNoteVisibility === 'home'" #suffix>{{ i18n.ts._visibility.home }}</template> - <template v-else-if="defaultNoteVisibility === 'followers'" #suffix>{{ i18n.ts._visibility.followers }}</template> - <template v-else-if="defaultNoteVisibility === 'specified'" #suffix>{{ i18n.ts._visibility.specified }}</template> + <template #label><SearchLabel>{{ i18n.ts.pinnedList }}</SearchLabel></template> + <!-- ่คๆฐใใณๆญขใ็ฎก็ใงใใใใใซใใใใใฉใใใฉใใฎใงไธๆฆใฒใจใคใฎใฟ --> + <MkButton v-if="prefer.r.pinnedUserLists.value.length === 0" @click="setPinnedList()">{{ i18n.ts.add }}</MkButton> + <MkButton v-else danger @click="removePinnedList()"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton> + </MkFolder> + </SearchMarker> + </div> + </MkFolder> + </SearchMarker> - <div class="_gaps_m"> - <MkPreferenceContainer k="defaultNoteVisibility"> - <MkSelect v-model="defaultNoteVisibility"> - <option value="public">{{ i18n.ts._visibility.public }}</option> - <option value="home">{{ i18n.ts._visibility.home }}</option> - <option value="followers">{{ i18n.ts._visibility.followers }}</option> - <option value="specified">{{ i18n.ts._visibility.specified }}</option> - </MkSelect> - </MkPreferenceContainer> + <SearchMarker :keywords="['timeline']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.timeline }}</SearchLabel></template> - <MkPreferenceContainer k="defaultNoteLocalOnly"> - <MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.disableFederation }}</MkSwitch> - </MkPreferenceContainer> + <div class="_gaps_s"> + <SearchMarker :keywords="['post', 'form', 'timeline']"> + <MkPreferenceContainer k="showFixedPostForm"> + <MkSwitch v-model="showFixedPostForm"> + <template #label><SearchLabel>{{ i18n.ts.showFixedPostForm }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['post', 'form', 'timeline', 'channel']"> + <MkPreferenceContainer k="showFixedPostFormInChannel"> + <MkSwitch v-model="showFixedPostFormInChannel"> + <template #label><SearchLabel>{{ i18n.ts.showFixedPostFormInChannel }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['renote']"> + <MkPreferenceContainer k="collapseRenotes"> + <MkSwitch v-model="collapseRenotes"> + <template #label><SearchLabel>{{ i18n.ts.collapseRenotes }}</SearchLabel></template> + <template #caption><SearchKeyword>{{ i18n.ts.collapseRenotesDescription }}</SearchKeyword></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['note', 'timeline', 'gap']"> + <MkPreferenceContainer k="showGapBetweenNotesInTimeline"> + <MkSwitch v-model="showGapBetweenNotesInTimeline"> + <template #label><SearchLabel>{{ i18n.ts.showGapBetweenNotesInTimeline }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['load', 'auto', 'more']"> + <MkPreferenceContainer k="enableInfiniteScroll"> + <MkSwitch v-model="enableInfiniteScroll"> + <template #label><SearchLabel>{{ i18n.ts.enableInfiniteScroll }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['disable', 'streaming', 'timeline']"> + <MkPreferenceContainer k="disableStreamingTimeline"> + <MkSwitch v-model="disableStreamingTimeline"> + <template #label><SearchLabel>{{ i18n.ts.disableStreamingTimeline }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + </div> + </MkFolder> + </SearchMarker> + + <SearchMarker :keywords="['note']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.note }}</SearchLabel></template> + + <div class="_gaps_m"> + <div class="_gaps_s"> + <SearchMarker :keywords="['hover', 'show', 'footer', 'action']"> + <MkPreferenceContainer k="showNoteActionsOnlyHover"> + <MkSwitch v-model="showNoteActionsOnlyHover"> + <template #label><SearchLabel>{{ i18n.ts.showNoteActionsOnlyHover }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['footer', 'action', 'clip', 'show']"> + <MkPreferenceContainer k="showClipButtonInNoteFooter"> + <MkSwitch v-model="showClipButtonInNoteFooter"> + <template #label><SearchLabel>{{ i18n.ts.showClipButtonInNoteFooter }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['mfm', 'enable', 'show', 'advanced']"> + <MkPreferenceContainer k="advancedMfm"> + <MkSwitch v-model="advancedMfm"> + <template #label><SearchLabel>{{ i18n.ts.enableAdvancedMfm }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['reaction', 'count', 'show']"> + <MkPreferenceContainer k="showReactionsCount"> + <MkSwitch v-model="showReactionsCount"> + <template #label><SearchLabel>{{ i18n.ts.showReactionsCount }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['reaction', 'confirm']"> + <MkPreferenceContainer k="confirmOnReact"> + <MkSwitch v-model="confirmOnReact"> + <template #label><SearchLabel>{{ i18n.ts.confirmOnReact }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['image', 'photo', 'picture', 'media', 'thumbnail', 'quality', 'raw', 'attachment']"> + <MkPreferenceContainer k="loadRawImages"> + <MkSwitch v-model="loadRawImages"> + <template #label><SearchLabel>{{ i18n.ts.loadRawImages }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['reaction', 'picker', 'contextmenu', 'open']"> + <MkPreferenceContainer k="useReactionPickerForContextMenu"> + <MkSwitch v-model="useReactionPickerForContextMenu"> + <template #label><SearchLabel>{{ i18n.ts.useReactionPickerForContextMenu }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + </div> + + <SearchMarker :keywords="['reaction', 'size', 'scale', 'display']"> + <MkPreferenceContainer k="reactionsDisplaySize"> + <MkRadios v-model="reactionsDisplaySize"> + <template #label><SearchLabel>{{ i18n.ts.reactionsDisplaySize }}</SearchLabel></template> + <option value="small">{{ i18n.ts.small }}</option> + <option value="medium">{{ i18n.ts.medium }}</option> + <option value="large">{{ i18n.ts.large }}</option> + </MkRadios> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['reaction', 'size', 'scale', 'display', 'width', 'limit']"> + <MkPreferenceContainer k="limitWidthOfReaction"> + <MkSwitch v-model="limitWidthOfReaction"> + <template #label><SearchLabel>{{ i18n.ts.limitWidthOfReaction }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['attachment', 'image', 'photo', 'picture', 'media', 'thumbnail', 'list', 'size', 'height']"> + <MkPreferenceContainer k="mediaListWithOneImageAppearance"> + <MkRadios v-model="mediaListWithOneImageAppearance"> + <template #label><SearchLabel>{{ i18n.ts.mediaListWithOneImageAppearance }}</SearchLabel></template> + <option value="expand">{{ i18n.ts.default }}</option> + <option value="16_9">{{ i18n.tsx.limitTo({ x: '16:9' }) }}</option> + <option value="1_1">{{ i18n.tsx.limitTo({ x: '1:1' }) }}</option> + <option value="2_3">{{ i18n.tsx.limitTo({ x: '2:3' }) }}</option> + </MkRadios> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['ticker', 'information', 'label', 'instance', 'server', 'host', 'federation']"> + <MkPreferenceContainer k="instanceTicker"> + <MkSelect v-if="instance.federation !== 'none'" v-model="instanceTicker"> + <template #label><SearchLabel>{{ i18n.ts.instanceTicker }}</SearchLabel></template> + <option value="none">{{ i18n.ts._instanceTicker.none }}</option> + <option value="remote">{{ i18n.ts._instanceTicker.remote }}</option> + <option value="always">{{ i18n.ts._instanceTicker.always }}</option> + </MkSelect> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['attachment', 'image', 'photo', 'picture', 'media', 'thumbnail', 'nsfw', 'sensitive', 'display', 'show', 'hide', 'visibility']"> + <MkPreferenceContainer k="nsfw"> + <MkSelect v-model="nsfw"> + <template #label><SearchLabel>{{ i18n.ts.displayOfSensitiveMedia }}</SearchLabel></template> + <option value="respect">{{ i18n.ts._displayOfSensitiveMedia.respect }}</option> + <option value="ignore">{{ i18n.ts._displayOfSensitiveMedia.ignore }}</option> + <option value="force">{{ i18n.ts._displayOfSensitiveMedia.force }}</option> + </MkSelect> + </MkPreferenceContainer> + </SearchMarker> + </div> + </MkFolder> + </SearchMarker> + + <SearchMarker :keywords="['post', 'form']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.postForm }}</SearchLabel></template> + + <div class="_gaps_m"> + <div class="_gaps_s"> + <SearchMarker :keywords="['remember', 'keep', 'note', 'cw']"> + <MkPreferenceContainer k="keepCw"> + <MkSwitch v-model="keepCw"> + <template #label><SearchLabel>{{ i18n.ts.keepCw }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['remember', 'keep', 'note', 'visibility']"> + <MkPreferenceContainer k="rememberNoteVisibility"> + <MkSwitch v-model="rememberNoteVisibility"> + <template #label><SearchLabel>{{ i18n.ts.rememberNoteVisibility }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['mfm', 'enable', 'show', 'advanced', 'picker', 'form', 'function', 'fn']"> + <MkPreferenceContainer k="enableQuickAddMfmFunction"> + <MkSwitch v-model="enableQuickAddMfmFunction"> + <template #label><SearchLabel>{{ i18n.ts.enableQuickAddMfmFunction }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + </div> + + <SearchMarker :keywords="['default', 'note', 'visibility']"> + <MkDisableSection :disabled="rememberNoteVisibility"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.defaultNoteVisibility }}</SearchLabel></template> + <template v-if="defaultNoteVisibility === 'public'" #suffix>{{ i18n.ts._visibility.public }}</template> + <template v-else-if="defaultNoteVisibility === 'home'" #suffix>{{ i18n.ts._visibility.home }}</template> + <template v-else-if="defaultNoteVisibility === 'followers'" #suffix>{{ i18n.ts._visibility.followers }}</template> + <template v-else-if="defaultNoteVisibility === 'specified'" #suffix>{{ i18n.ts._visibility.specified }}</template> + + <div class="_gaps_m"> + <MkPreferenceContainer k="defaultNoteVisibility"> + <MkSelect v-model="defaultNoteVisibility"> + <option value="public">{{ i18n.ts._visibility.public }}</option> + <option value="home">{{ i18n.ts._visibility.home }}</option> + <option value="followers">{{ i18n.ts._visibility.followers }}</option> + <option value="specified">{{ i18n.ts._visibility.specified }}</option> + </MkSelect> + </MkPreferenceContainer> + + <MkPreferenceContainer k="defaultNoteLocalOnly"> + <MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.disableFederation }}</MkSwitch> + </MkPreferenceContainer> + </div> + </MkFolder> + </MkDisableSection> + </SearchMarker> + </div> + </MkFolder> + </SearchMarker> + + <SearchMarker :keywords="['notification']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.notifications }}</SearchLabel></template> + + <div class="_gaps_m"> + <SearchMarker :keywords="['group']"> + <MkPreferenceContainer k="useGroupedNotifications"> + <MkSwitch v-model="useGroupedNotifications"> + <template #label><SearchLabel>{{ i18n.ts.useGroupedNotifications }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['position']"> + <MkPreferenceContainer k="notificationPosition"> + <MkRadios v-model="notificationPosition"> + <template #label><SearchLabel>{{ i18n.ts.position }}</SearchLabel></template> + <option value="leftTop"><i class="ti ti-align-box-left-top"></i> {{ i18n.ts.leftTop }}</option> + <option value="rightTop"><i class="ti ti-align-box-right-top"></i> {{ i18n.ts.rightTop }}</option> + <option value="leftBottom"><i class="ti ti-align-box-left-bottom"></i> {{ i18n.ts.leftBottom }}</option> + <option value="rightBottom"><i class="ti ti-align-box-right-bottom"></i> {{ i18n.ts.rightBottom }}</option> + </MkRadios> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['stack', 'axis', 'direction']"> + <MkPreferenceContainer k="notificationStackAxis"> + <MkRadios v-model="notificationStackAxis"> + <template #label><SearchLabel>{{ i18n.ts.stackAxis }}</SearchLabel></template> + <option value="vertical"><i class="ti ti-carousel-vertical"></i> {{ i18n.ts.vertical }}</option> + <option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option> + </MkRadios> + </MkPreferenceContainer> + </SearchMarker> + + <MkButton @click="testNotification">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> + </div> + </MkFolder> + </SearchMarker> + + <SearchMarker :keywords="['other']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.other }}</SearchLabel></template> + + <div class="_gaps_m"> + <div class="_gaps_s"> + <SearchMarker :keywords="['avatar', 'icon', 'square']"> + <MkPreferenceContainer k="squareAvatars"> + <MkSwitch v-model="squareAvatars"> + <template #label><SearchLabel>{{ i18n.ts.squareAvatars }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['effect', 'show']"> + <MkPreferenceContainer k="enableSeasonalScreenEffect"> + <MkSwitch v-model="enableSeasonalScreenEffect"> + <template #label><SearchLabel>{{ i18n.ts.seasonalScreenEffect }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['image', 'photo', 'picture', 'media', 'thumbnail', 'new', 'tab']"> + <MkPreferenceContainer k="imageNewTab"> + <MkSwitch v-model="imageNewTab"> + <template #label><SearchLabel>{{ i18n.ts.openImageInNewTab }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + </div> + + <SearchMarker :keywords="['server', 'disconnect', 'reconnect', 'reload', 'streaming']"> + <MkPreferenceContainer k="serverDisconnectedBehavior"> + <MkSelect v-model="serverDisconnectedBehavior"> + <template #label><SearchLabel>{{ i18n.ts.whenServerDisconnected }}</SearchLabel></template> + <option value="reload">{{ i18n.ts._serverDisconnectedBehavior.reload }}</option> + <option value="dialog">{{ i18n.ts._serverDisconnectedBehavior.dialog }}</option> + <option value="quiet">{{ i18n.ts._serverDisconnectedBehavior.quiet }}</option> + </MkSelect> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['cache', 'page']"> + <MkPreferenceContainer k="numberOfPageCache"> + <MkRange v-model="numberOfPageCache" :min="1" :max="10" :step="1" easing> + <template #label><SearchLabel>{{ i18n.ts.numberOfPageCache }}</SearchLabel></template> + <template #caption>{{ i18n.ts.numberOfPageCacheDescription }}</template> + </MkRange> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['ad', 'show']"> + <MkPreferenceContainer k="forceShowAds"> + <MkSwitch v-model="forceShowAds"> + <template #label><SearchLabel>{{ i18n.ts.forceShowAds }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker> + <MkPreferenceContainer k="hemisphere"> + <MkRadios v-model="hemisphere"> + <template #label><SearchLabel>{{ i18n.ts.hemisphere }}</SearchLabel></template> + <option value="N">{{ i18n.ts._hemisphere.N }}</option> + <option value="S">{{ i18n.ts._hemisphere.S }}</option> + <template #caption>{{ i18n.ts._hemisphere.caption }}</template> + </MkRadios> + </MkPreferenceContainer> + </SearchMarker> + + <SearchMarker :keywords="['emoji', 'dictionary', 'additional', 'extra']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.additionalEmojiDictionary }}</SearchLabel></template> + <div class="_buttons"> + <template v-for="lang in emojiIndexLangs" :key="lang"> + <MkButton v-if="store.r.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }} ({{ getEmojiIndexLangName(lang) }})</MkButton> + <MkButton v-else @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ getEmojiIndexLangName(lang) }}{{ store.r.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton> + </template> </div> </MkFolder> - </MkDisableSection> - </SearchMarker> - </div> - </MkFolder> - </SearchMarker> - - <SearchMarker :keywords="['notification']"> - <MkFolder :defaultOpen="true"> - <template #label><SearchLabel>{{ i18n.ts.notifications }}</SearchLabel></template> - - <div class="_gaps_m"> - <SearchMarker :keywords="['group']"> - <MkPreferenceContainer k="useGroupedNotifications"> - <MkSwitch v-model="useGroupedNotifications"> - <template #label><SearchLabel>{{ i18n.ts.useGroupedNotifications }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['position']"> - <MkPreferenceContainer k="notificationPosition"> - <MkRadios v-model="notificationPosition"> - <template #label><SearchLabel>{{ i18n.ts.position }}</SearchLabel></template> - <option value="leftTop"><i class="ti ti-align-box-left-top"></i> {{ i18n.ts.leftTop }}</option> - <option value="rightTop"><i class="ti ti-align-box-right-top"></i> {{ i18n.ts.rightTop }}</option> - <option value="leftBottom"><i class="ti ti-align-box-left-bottom"></i> {{ i18n.ts.leftBottom }}</option> - <option value="rightBottom"><i class="ti ti-align-box-right-bottom"></i> {{ i18n.ts.rightBottom }}</option> - </MkRadios> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['stack', 'axis', 'direction']"> - <MkPreferenceContainer k="notificationStackAxis"> - <MkRadios v-model="notificationStackAxis"> - <template #label><SearchLabel>{{ i18n.ts.stackAxis }}</SearchLabel></template> - <option value="vertical"><i class="ti ti-carousel-vertical"></i> {{ i18n.ts.vertical }}</option> - <option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option> - </MkRadios> - </MkPreferenceContainer> - </SearchMarker> - - <MkButton @click="testNotification">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> - </div> - </MkFolder> - </SearchMarker> - - <SearchMarker :keywords="['other']"> - <MkFolder :defaultOpen="true"> - <template #label><SearchLabel>{{ i18n.ts.other }}</SearchLabel></template> - - <div class="_gaps_m"> - <div class="_gaps_s"> - <SearchMarker :keywords="['avatar', 'icon', 'square']"> - <MkPreferenceContainer k="squareAvatars"> - <MkSwitch v-model="squareAvatars"> - <template #label><SearchLabel>{{ i18n.ts.squareAvatars }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['effect', 'show']"> - <MkPreferenceContainer k="enableSeasonalScreenEffect"> - <MkSwitch v-model="enableSeasonalScreenEffect"> - <template #label><SearchLabel>{{ i18n.ts.seasonalScreenEffect }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['image', 'photo', 'picture', 'media', 'thumbnail', 'new', 'tab']"> - <MkPreferenceContainer k="imageNewTab"> - <MkSwitch v-model="imageNewTab"> - <template #label><SearchLabel>{{ i18n.ts.openImageInNewTab }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> </SearchMarker> </div> + </MkFolder> + </SearchMarker> - <SearchMarker :keywords="['server', 'disconnect', 'reconnect', 'reload', 'streaming']"> - <MkPreferenceContainer k="serverDisconnectedBehavior"> - <MkSelect v-model="serverDisconnectedBehavior"> - <template #label><SearchLabel>{{ i18n.ts.whenServerDisconnected }}</SearchLabel></template> - <option value="reload">{{ i18n.ts._serverDisconnectedBehavior.reload }}</option> - <option value="dialog">{{ i18n.ts._serverDisconnectedBehavior.dialog }}</option> - <option value="quiet">{{ i18n.ts._serverDisconnectedBehavior.quiet }}</option> - </MkSelect> - </MkPreferenceContainer> - </SearchMarker> + <SearchMarker :keywords="['datasaver']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.dataSaver }}</SearchLabel></template> - <SearchMarker :keywords="['cache', 'page']"> - <MkPreferenceContainer k="numberOfPageCache"> - <MkRange v-model="numberOfPageCache" :min="1" :max="10" :step="1" easing> - <template #label><SearchLabel>{{ i18n.ts.numberOfPageCache }}</SearchLabel></template> - <template #caption>{{ i18n.ts.numberOfPageCacheDescription }}</template> - </MkRange> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['ad', 'show']"> - <MkPreferenceContainer k="forceShowAds"> - <MkSwitch v-model="forceShowAds"> - <template #label><SearchLabel>{{ i18n.ts.forceShowAds }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker> - <MkPreferenceContainer k="hemisphere"> - <MkRadios v-model="hemisphere"> - <template #label><SearchLabel>{{ i18n.ts.hemisphere }}</SearchLabel></template> - <option value="N">{{ i18n.ts._hemisphere.N }}</option> - <option value="S">{{ i18n.ts._hemisphere.S }}</option> - <template #caption>{{ i18n.ts._hemisphere.caption }}</template> - </MkRadios> - </MkPreferenceContainer> - </SearchMarker> - - <SearchMarker :keywords="['emoji', 'dictionary', 'additional', 'extra']"> - <MkFolder> - <template #label><SearchLabel>{{ i18n.ts.additionalEmojiDictionary }}</SearchLabel></template> - <div class="_buttons"> - <template v-for="lang in emojiIndexLangs" :key="lang"> - <MkButton v-if="store.r.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }} ({{ getEmojiIndexLangName(lang) }})</MkButton> - <MkButton v-else @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ getEmojiIndexLangName(lang) }}{{ store.r.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton> - </template> - </div> - </MkFolder> - </SearchMarker> - </div> - </MkFolder> - </SearchMarker> - - <SearchMarker :keywords="['datasaver']"> - <MkFolder> - <template #label><SearchLabel>{{ i18n.ts.dataSaver }}</SearchLabel></template> - - <div class="_gaps_m"> - <MkInfo>{{ i18n.ts.reloadRequiredToApplySettings }}</MkInfo> - - <div class="_buttons"> - <MkButton inline @click="enableAllDataSaver">{{ i18n.ts.enableAll }}</MkButton> - <MkButton inline @click="disableAllDataSaver">{{ i18n.ts.disableAll }}</MkButton> - </div> <div class="_gaps_m"> - <MkSwitch v-model="dataSaver.media"> - {{ i18n.ts._dataSaver._media.title }} - <template #caption>{{ i18n.ts._dataSaver._media.description }}</template> - </MkSwitch> - <MkSwitch v-model="dataSaver.avatar"> - {{ i18n.ts._dataSaver._avatar.title }} - <template #caption>{{ i18n.ts._dataSaver._avatar.description }}</template> - </MkSwitch> - <MkSwitch v-model="dataSaver.urlPreview"> - {{ i18n.ts._dataSaver._urlPreview.title }} - <template #caption>{{ i18n.ts._dataSaver._urlPreview.description }}</template> - </MkSwitch> - <MkSwitch v-model="dataSaver.code"> - {{ i18n.ts._dataSaver._code.title }} - <template #caption>{{ i18n.ts._dataSaver._code.description }}</template> - </MkSwitch> - </div> - </div> - </MkFolder> - </SearchMarker> + <MkInfo>{{ i18n.ts.reloadRequiredToApplySettings }}</MkInfo> - <FormLink to="/settings/navbar">{{ i18n.ts.navbar }}</FormLink> - <FormLink to="/settings/statusbar">{{ i18n.ts.statusbar }}</FormLink> - <FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink> - <FormLink to="/settings/custom-css"><template #icon><i class="ti ti-code"></i></template>{{ i18n.ts.customCss }}</FormLink> + <div class="_buttons"> + <MkButton inline @click="enableAllDataSaver">{{ i18n.ts.enableAll }}</MkButton> + <MkButton inline @click="disableAllDataSaver">{{ i18n.ts.disableAll }}</MkButton> + </div> + <div class="_gaps_m"> + <MkSwitch v-model="dataSaver.media"> + {{ i18n.ts._dataSaver._media.title }} + <template #caption>{{ i18n.ts._dataSaver._media.description }}</template> + </MkSwitch> + <MkSwitch v-model="dataSaver.avatar"> + {{ i18n.ts._dataSaver._avatar.title }} + <template #caption>{{ i18n.ts._dataSaver._avatar.description }}</template> + </MkSwitch> + <MkSwitch v-model="dataSaver.urlPreview"> + {{ i18n.ts._dataSaver._urlPreview.title }} + <template #caption>{{ i18n.ts._dataSaver._urlPreview.description }}</template> + </MkSwitch> + <MkSwitch v-model="dataSaver.code"> + {{ i18n.ts._dataSaver._code.title }} + <template #caption>{{ i18n.ts._dataSaver._code.description }}</template> + </MkSwitch> + </div> + </div> + </MkFolder> + </SearchMarker> + + <FormLink to="/settings/navbar">{{ i18n.ts.navbar }}</FormLink> + <FormLink to="/settings/statusbar">{{ i18n.ts.statusbar }}</FormLink> + <FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink> + <FormLink to="/settings/custom-css"><template #icon><i class="ti ti-code"></i></template>{{ i18n.ts.customCss }}</FormLink> + </div> </div> </SearchMarker> </template> diff --git a/packages/frontend/src/pages/settings/roles.vue b/packages/frontend/src/pages/settings/roles.vue deleted file mode 100644 index c1cabad2c3..0000000000 --- a/packages/frontend/src/pages/settings/roles.vue +++ /dev/null @@ -1,48 +0,0 @@ -<!-- -SPDX-FileCopyrightText: syuilo and misskey-project -SPDX-License-Identifier: AGPL-3.0-only ---> - -<template> -<div class="_gaps_m"> - <FormSection first> - <template #label>{{ i18n.ts.rolesAssignedToMe }}</template> - <div class="_gaps_s"> - <MkRolePreview v-for="role in $i.roles" :key="role.id" :role="role" :forModeration="false"/> - </div> - </FormSection> - <FormSection> - <template #label>{{ i18n.ts._role.policies }}</template> - <div class="_gaps_s"> - <div v-for="policy in Object.keys($i.policies)" :key="policy"> - {{ policy }} ... {{ $i.policies[policy] }} - </div> - </div> - </FormSection> -</div> -</template> - -<script lang="ts" setup> -import { computed } from 'vue'; -import FormSection from '@/components/form/section.vue'; -import * as os from '@/os.js'; -import { i18n } from '@/i18n.js'; -import { signinRequired } from '@/account.js'; -import { definePage } from '@/page.js'; -import MkRolePreview from '@/components/MkRolePreview.vue'; - -const $i = signinRequired(); - -const headerActions = computed(() => []); - -const headerTabs = computed(() => []); - -definePage(() => ({ - title: i18n.ts.roles, - icon: 'ti ti-badges', -})); -</script> - -<style lang="scss" module> - -</style> diff --git a/packages/frontend/src/router/definition.ts b/packages/frontend/src/router/definition.ts index 62b13d22be..73920766d7 100644 --- a/packages/frontend/src/router/definition.ts +++ b/packages/frontend/src/router/definition.ts @@ -57,10 +57,6 @@ const routes: RouteDef[] = [{ path: '/avatar-decoration', name: 'avatarDecoration', component: page(() => import('@/pages/settings/avatar-decoration.vue')), - }, { - path: '/roles', - name: 'roles', - component: page(() => import('@/pages/settings/roles.vue')), }, { path: '/privacy', name: 'privacy', diff --git a/packages/frontend/src/utility/autogen/settings-search-index.ts b/packages/frontend/src/utility/autogen/settings-search-index.ts index 734dc0c99c..e44910e850 100644 --- a/packages/frontend/src/utility/autogen/settings-search-index.ts +++ b/packages/frontend/src/utility/autogen/settings-search-index.ts @@ -271,55 +271,55 @@ export const searchIndexes: SearchIndexItem[] = [ id: '3yCAv0IsZ', children: [ { - id: 'kMJ5laK3n', + id: 'AKvDrxSj5', children: [ { - id: 'EC8J177N8', + id: 'cAszhShB0', label: i18n.ts.uiLanguage, keywords: ['language'], }, { - id: 'CHKy9gnrh', + id: 'apz9AutPm', label: i18n.ts.overridedDeviceKind, keywords: ['device', 'type', 'kind', 'smartphone', 'tablet', 'desktop'], }, { - id: 'snyCQ5oKE', + id: 'nqRVtw1xw', label: i18n.ts.useBlurEffect, keywords: ['blur'], }, { - id: '8j36S4Ev6', + id: 'EO5WHBeG8', label: i18n.ts.useBlurEffectForModal, keywords: ['blur', 'modal'], }, { - id: 'cytWLyF1V', + id: 'CWpyT9vLK', label: i18n.ts.showAvatarDecorations, keywords: ['avatar', 'icon', 'decoration', 'show'], }, { - id: 'odi1d2SWy', + id: '1wwACqQz1', label: i18n.ts.alwaysConfirmFollow, keywords: ['follow', 'confirm', 'always'], }, { - id: 'm43Eu3Ypg', + id: '1x3JNXj8N', label: i18n.ts.highlightSensitiveMedia, keywords: ['highlight', 'sensitive', 'nsfw', 'image', 'photo', 'picture', 'media', 'thumbnail'], }, { - id: 'cjfAtxMzP', + id: 'CfAg0Qekq', label: i18n.ts.confirmWhenRevealingSensitiveMedia, keywords: ['sensitive', 'nsfw', 'media', 'image', 'photo', 'picture', 'attachment', 'confirm'], }, { - id: 'aefexW9fD', + id: '4LxdiOMNh', label: i18n.ts.emojiStyle, keywords: ['emoji', 'style', 'native', 'system', 'fluent', 'twemoji'], }, { - id: 'p7aiLj6A0', + id: '67knC3FWp', label: i18n.ts.pinnedList, keywords: ['pinned', 'list'], }, @@ -328,35 +328,35 @@ export const searchIndexes: SearchIndexItem[] = [ keywords: ['general'], }, { - id: 'khT3n6byY', + id: 'hDdVkBFJP', children: [ { - id: 'DftdlLbNu', + id: 'igFN7RIUa', label: i18n.ts.showFixedPostForm, keywords: ['post', 'form', 'timeline'], }, { - id: 'FbhoeuRAD', + id: '9uxocbLO0', label: i18n.ts.showFixedPostFormInChannel, keywords: ['post', 'form', 'timeline', 'channel'], }, { - id: 'rq69GTeB4', + id: 'eaT1O1Fao', label: i18n.ts.collapseRenotes, keywords: ['renote', i18n.ts.collapseRenotesDescription], }, { - id: 'omxZk3eET', + id: 'jC7LtTnmc', label: i18n.ts.showGapBetweenNotesInTimeline, keywords: ['note', 'timeline', 'gap'], }, { - id: 'epvi2Nv2G', + id: 'p2wlrnwLo', label: i18n.ts.enableInfiniteScroll, keywords: ['load', 'auto', 'more'], }, { - id: 'v26JSj9mH', + id: 'eqMBMY6LU', label: i18n.ts.disableStreamingTimeline, keywords: ['disable', 'streaming', 'timeline'], }, @@ -365,65 +365,65 @@ export const searchIndexes: SearchIndexItem[] = [ keywords: ['timeline'], }, { - id: '7Uf8ksn3q', + id: '2LNjwv1cr', children: [ { - id: 'tLGyaQagB', + id: '6ylW3eIcD', label: i18n.ts.showNoteActionsOnlyHover, keywords: ['hover', 'show', 'footer', 'action'], }, { - id: '7W6g8Dcqz', + id: 'lBbtAg0Hm', label: i18n.ts.showClipButtonInNoteFooter, keywords: ['footer', 'action', 'clip', 'show'], }, { - id: 'uAOoH3LFF', + id: 'E9whefUtX', label: i18n.ts.enableAdvancedMfm, keywords: ['mfm', 'enable', 'show', 'advanced'], }, { - id: 'eCiyZLC8n', + id: 'iQaBbJBva', label: i18n.ts.showReactionsCount, keywords: ['reaction', 'count', 'show'], }, { - id: '68u9uRmFP', + id: 'hgEVGgJa1', label: i18n.ts.confirmOnReact, keywords: ['reaction', 'confirm'], }, { - id: 'rHWm4sXIe', + id: 'yxehrHZ6x', label: i18n.ts.loadRawImages, keywords: ['image', 'photo', 'picture', 'media', 'thumbnail', 'quality', 'raw', 'attachment'], }, { - id: '9L2XGJw7e', + id: 'DdoFLaSG8', label: i18n.ts.useReactionPickerForContextMenu, keywords: ['reaction', 'picker', 'contextmenu', 'open'], }, { - id: 'uIMCIK7kG', + id: 'fyod6U3QX', label: i18n.ts.reactionsDisplaySize, keywords: ['reaction', 'size', 'scale', 'display'], }, { - id: 'uMckjO9bz', + id: 'kmdsnVIQX', label: i18n.ts.limitWidthOfReaction, keywords: ['reaction', 'size', 'scale', 'display', 'width', 'limit'], }, { - id: 'yeghU4qiH', + id: 'hacQ9br20', label: i18n.ts.mediaListWithOneImageAppearance, keywords: ['attachment', 'image', 'photo', 'picture', 'media', 'thumbnail', 'list', 'size', 'height'], }, { - id: 'yYSOPoAKE', + id: 'vE7KeV4U4', label: i18n.ts.instanceTicker, keywords: ['ticker', 'information', 'label', 'instance', 'server', 'host', 'federation'], }, { - id: 'iOHiIu32L', + id: '3reoOxO26', label: i18n.ts.displayOfSensitiveMedia, keywords: ['attachment', 'image', 'photo', 'picture', 'media', 'thumbnail', 'nsfw', 'sensitive', 'display', 'show', 'hide', 'visibility'], }, @@ -432,25 +432,25 @@ export const searchIndexes: SearchIndexItem[] = [ keywords: ['note'], }, { - id: 'zrJicawH9', + id: 'eROFRMtXv', children: [ { - id: 'iuEuPe6pa', + id: 'bezWaWd6M', label: i18n.ts.keepCw, keywords: ['remember', 'keep', 'note', 'cw'], }, { - id: '9WrGgANqN', + id: '90ngq28Nx', label: i18n.ts.rememberNoteVisibility, keywords: ['remember', 'keep', 'note', 'visibility'], }, { - id: 'Cu7ErCM7C', + id: 'ERGQVw6ml', label: i18n.ts.enableQuickAddMfmFunction, keywords: ['mfm', 'enable', 'show', 'advanced', 'picker', 'form', 'function', 'fn'], }, { - id: 'oQl8xwiyI', + id: 'g0otcvWv3', label: i18n.ts.defaultNoteVisibility, keywords: ['default', 'note', 'visibility'], }, @@ -459,20 +459,20 @@ export const searchIndexes: SearchIndexItem[] = [ keywords: ['post', 'form'], }, { - id: 'xFmAg2tDe', + id: 'AWLIP02IT', children: [ { - id: 'mepqKL5Ow', + id: 'rDLJRu99', label: i18n.ts.useGroupedNotifications, keywords: ['group'], }, { - id: 'wUuUOEO1g', + id: '70WDijfPH', label: i18n.ts.position, keywords: ['position'], }, { - id: '27em8eC8R', + id: 'xKUzsSrKy', label: i18n.ts.stackAxis, keywords: ['stack', 'axis', 'direction'], }, @@ -481,45 +481,45 @@ export const searchIndexes: SearchIndexItem[] = [ keywords: ['notification'], }, { - id: 'AzymHsnrp', + id: '2E7vdIUQd', children: [ { - id: 'DFUrEO2DI', + id: 'C2iXtZKb3', label: i18n.ts.squareAvatars, keywords: ['avatar', 'icon', 'square'], }, { - id: 'r9DX60AxL', + id: 'DCfJg0bva', label: i18n.ts.seasonalScreenEffect, keywords: ['effect', 'show'], }, { - id: 'sJ3fqncSD', + id: 'AV0iGW0vg', label: i18n.ts.openImageInNewTab, keywords: ['image', 'photo', 'picture', 'media', 'thumbnail', 'new', 'tab'], }, { - id: 'p7s0hwZ8A', + id: '5h8vhCX1S', label: i18n.ts.whenServerDisconnected, keywords: ['server', 'disconnect', 'reconnect', 'reload', 'streaming'], }, { - id: 'yCleENWNf', + id: 'zZxyXHk3A', label: i18n.ts.numberOfPageCache, keywords: ['cache', 'page'], }, { - id: 'omEy5Q3Ev', + id: '7ix3kvMyU', label: i18n.ts.forceShowAds, keywords: ['ad', 'show'], }, { - id: 'aWitQSBtD', + id: '6RxgjmMLN', label: i18n.ts.hemisphere, keywords: [], }, { - id: 'hUQAXl1H4', + id: '5iMpm5rES', label: i18n.ts.additionalEmojiDictionary, keywords: ['emoji', 'dictionary', 'additional', 'extra'], }, @@ -528,7 +528,7 @@ export const searchIndexes: SearchIndexItem[] = [ keywords: ['other'], }, { - id: 'aSbKFHbOy', + id: 'fnR7PRww5', label: i18n.ts.dataSaver, keywords: ['datasaver'], }, @@ -550,26 +550,31 @@ export const searchIndexes: SearchIndexItem[] = [ children: [ { id: 'msAcN6u3S', - label: i18n.ts.accountInfo, + label: i18n.ts._role.policies, keywords: ['account', 'info'], }, { - id: 'ts8DgdnZV', + id: 'pbTLsgRO7', + label: i18n.ts.rolesAssignedToMe, + keywords: ['roles'], + }, + { + id: 'fQpvZyfLK', label: i18n.ts.accountMigration, keywords: ['account', 'move', 'migration'], }, { - id: '4BG7nBECm', + id: 'xhfur5m2z', label: i18n.ts.closeAccount, keywords: ['account', 'close', 'delete', i18n.ts._accountDelete.requestAccountDelete], }, { - id: '2qI6ruPgi', + id: 'oAXB8zm2U', label: i18n.ts.experimentalFeatures, keywords: ['experimental', 'feature', 'flags'], }, { - id: 'cIeaax47o', + id: '95OjjGSo7', label: i18n.ts.developer, keywords: ['developer', 'mode', 'debug'], },