1
0
Fork 0
mirror of https://github.com/paricafe/misskey.git synced 2025-03-23 11:39:25 -05:00

enhance(frontend): improve preferences

This commit is contained in:
syuilo 2025-03-13 19:44:23 +09:00
parent 0126dba475
commit 44073736de
9 changed files with 164 additions and 165 deletions

View file

@ -191,6 +191,7 @@ export async function mainBoot() {
prefer.commit('skipNoteRender', store.s.skipNoteRender);
prefer.commit('showSoftWordMutedWord', store.s.showSoftWordMutedWord);
prefer.commit('confirmOnReact', store.s.confirmOnReact);
prefer.commit('defaultFollowWithReplies', store.s.defaultWithReplies);
prefer.commit('sound.masterVolume', store.s.sound_masterVolume);
prefer.commit('sound.notUseSound', store.s.sound_notUseSound);
prefer.commit('sound.useSoundOnlyWhenActive', store.s.sound_useSoundOnlyWhenActive);

View file

@ -45,7 +45,6 @@ import { i18n } from '@/i18n.js';
import { claimAchievement } from '@/utility/achievements.js';
import { pleaseLogin } from '@/utility/please-login.js';
import { $i } from '@/account.js';
import { store } from '@/store.js';
import { prefer } from '@/preferences.js';
const props = withDefaults(defineProps<{
@ -121,11 +120,11 @@ async function onClick() {
} else {
await misskeyApi('following/create', {
userId: props.user.id,
withReplies: store.s.defaultWithReplies,
withReplies: prefer.s.defaultFollowWithReplies,
});
emit('update:user', {
...props.user,
withReplies: store.s.defaultWithReplies,
withReplies: prefer.s.defaultFollowWithReplies,
});
hasPendingFollowRequestFromYou.value = true;

View file

@ -168,12 +168,12 @@ import { selectFile } from '@/utility/select-file.js';
import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js';
import { $i } from '@/account.js';
import { store } from '@/store.js';
import MkFeatureBanner from '@/components/MkFeatureBanner.vue';
import { prefer } from '@/preferences.js';
const excludeMutingUsers = ref(false);
const excludeInactiveUsers = ref(false);
const withReplies = ref(store.s.defaultWithReplies);
const withReplies = ref(prefer.s.defaultFollowWithReplies);
const onExportSuccess = () => {
os.alert({

View file

@ -16,112 +16,102 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="reportError">{{ i18n.ts.sendErrorReports }}<template #caption>{{ i18n.ts.sendErrorReportsDescription }}</template></MkSwitch>
-->
<FormSection first>
<div class="_gaps_s">
<SearchMarker :keywords="['account', 'info']">
<MkFolder>
<template #icon><i class="ti ti-info-circle"></i></template>
<template #label><SearchLabel>{{ i18n.ts.accountInfo }}</SearchLabel></template>
<div class="_gaps_s">
<SearchMarker :keywords="['account', 'info']">
<MkFolder>
<template #icon><i class="ti ti-info-circle"></i></template>
<template #label><SearchLabel>{{ i18n.ts.accountInfo }}</SearchLabel></template>
<div class="_gaps_m">
<MkKeyValue>
<template #key>ID</template>
<template #value><span class="_monospace">{{ $i.id }}</span></template>
</MkKeyValue>
<div class="_gaps_m">
<MkKeyValue>
<template #key>ID</template>
<template #value><span class="_monospace">{{ $i.id }}</span></template>
</MkKeyValue>
<MkKeyValue>
<template #key>{{ i18n.ts.registeredDate }}</template>
<template #value><MkTime :time="$i.createdAt" mode="detail"/></template>
</MkKeyValue>
<MkKeyValue>
<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>
<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 class="_gaps_s">
<div v-for="policy in Object.keys($i.policies)" :key="policy">
{{ policy }} ... {{ $i.policies[policy] }}
</div>
</MkFolder>
</div>
</MkFolder>
</SearchMarker>
</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>
<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>
<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>
<template #label><SearchLabel>{{ i18n.ts.accountMigration }}</SearchLabel></template>
<SearchMarker :keywords="['account', 'move', 'migration']">
<MkFolder>
<template #icon><i class="ti ti-plane"></i></template>
<template #label><SearchLabel>{{ i18n.ts.accountMigration }}</SearchLabel></template>
<XMigration/>
</MkFolder>
</SearchMarker>
<XMigration/>
</MkFolder>
</SearchMarker>
<SearchMarker :keywords="['account', 'close', 'delete']">
<MkFolder>
<template #icon><i class="ti ti-alert-triangle"></i></template>
<template #label><SearchLabel>{{ i18n.ts.closeAccount }}</SearchLabel></template>
<SearchMarker :keywords="['account', 'close', 'delete']">
<MkFolder>
<template #icon><i class="ti ti-alert-triangle"></i></template>
<template #label><SearchLabel>{{ i18n.ts.closeAccount }}</SearchLabel></template>
<div class="_gaps_m">
<FormInfo warn>{{ i18n.ts._accountDelete.mayTakeTime }}</FormInfo>
<FormInfo>{{ i18n.ts._accountDelete.sendEmail }}</FormInfo>
<MkButton v-if="!$i.isDeleted" danger @click="deleteAccount"><SearchKeyword>{{ i18n.ts._accountDelete.requestAccountDelete }}</SearchKeyword></MkButton>
<MkButton v-else disabled>{{ i18n.ts._accountDelete.inProgress }}</MkButton>
</div>
</MkFolder>
</SearchMarker>
<div class="_gaps_m">
<FormInfo warn>{{ i18n.ts._accountDelete.mayTakeTime }}</FormInfo>
<FormInfo>{{ i18n.ts._accountDelete.sendEmail }}</FormInfo>
<MkButton v-if="!$i.isDeleted" danger @click="deleteAccount"><SearchKeyword>{{ i18n.ts._accountDelete.requestAccountDelete }}</SearchKeyword></MkButton>
<MkButton v-else disabled>{{ i18n.ts._accountDelete.inProgress }}</MkButton>
</div>
</MkFolder>
</SearchMarker>
<SearchMarker :keywords="['experimental', 'feature', 'flags']">
<MkFolder>
<template #icon><i class="ti ti-flask"></i></template>
<template #label><SearchLabel>{{ i18n.ts.experimentalFeatures }}</SearchLabel></template>
<SearchMarker :keywords="['experimental', 'feature', 'flags']">
<MkFolder>
<template #icon><i class="ti ti-flask"></i></template>
<template #label><SearchLabel>{{ i18n.ts.experimentalFeatures }}</SearchLabel></template>
<div class="_gaps_m">
<MkSwitch v-model="enableCondensedLine">
<template #label>Enable condensed line</template>
</MkSwitch>
<MkSwitch v-model="skipNoteRender">
<template #label>Enable note render skipping</template>
</MkSwitch>
</div>
</MkFolder>
</SearchMarker>
<div class="_gaps_m">
<MkSwitch v-model="enableCondensedLine">
<template #label>Enable condensed line</template>
</MkSwitch>
<MkSwitch v-model="skipNoteRender">
<template #label>Enable note render skipping</template>
</MkSwitch>
</div>
</MkFolder>
</SearchMarker>
<SearchMarker :keywords="['developer', 'mode', 'debug']">
<MkFolder>
<template #icon><i class="ti ti-code"></i></template>
<template #label><SearchLabel>{{ i18n.ts.developer }}</SearchLabel></template>
<SearchMarker :keywords="['developer', 'mode', 'debug']">
<MkFolder>
<template #icon><i class="ti ti-code"></i></template>
<template #label><SearchLabel>{{ i18n.ts.developer }}</SearchLabel></template>
<div class="_gaps_m">
<MkSwitch v-model="devMode">
<template #label>{{ i18n.ts.devMode }}</template>
</MkSwitch>
</div>
</MkFolder>
</SearchMarker>
</div>
</FormSection>
<div class="_gaps_m">
<MkSwitch v-model="devMode">
<template #label>{{ i18n.ts.devMode }}</template>
</MkSwitch>
</div>
</MkFolder>
</SearchMarker>
</div>
<FormSection>
<FormLink to="/registry"><template #icon><i class="ti ti-adjustments"></i></template>{{ i18n.ts.registry }}</FormLink>
</FormSection>
<hr>
<FormSection>
<div class="_gaps_s">
<MkSwitch v-model="defaultWithReplies">{{ i18n.ts.withRepliesByDefaultForNewlyFollowed }}</MkSwitch>
<MkButton danger @click="updateRepliesAll(true)"><i class="ti ti-messages"></i> {{ i18n.ts.showRepliesToOthersInTimelineAll }}</MkButton>
<MkButton danger @click="updateRepliesAll(false)"><i class="ti ti-messages-off"></i> {{ i18n.ts.hideRepliesToOthersInTimelineAll }}</MkButton>
</div>
</FormSection>
<FormLink to="/registry"><template #icon><i class="ti ti-adjustments"></i></template>{{ i18n.ts.registry }}</FormLink>
</div>
</SearchMarker>
</template>
@ -137,7 +127,6 @@ import MkKeyValue from '@/components/MkKeyValue.vue';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { store } from '@/store.js';
import { signout, signinRequired } from '@/account.js';
import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js';
@ -152,7 +141,6 @@ const reportError = prefer.model('reportError');
const enableCondensedLine = prefer.model('enableCondensedLine');
const skipNoteRender = prefer.model('skipNoteRender');
const devMode = prefer.model('devMode');
const defaultWithReplies = computed(store.makeGetterSetter('defaultWithReplies'));
watch(skipNoteRender, async () => {
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
@ -182,16 +170,6 @@ async function deleteAccount() {
await signout();
}
async function updateRepliesAll(withReplies: boolean) {
const { canceled } = await os.confirm({
type: 'warning',
text: withReplies ? i18n.ts.confirmShowRepliesAll : i18n.ts.confirmHideRepliesAll,
});
if (canceled) return;
misskeyApi('following/update-all', { withReplies });
}
const headerActions = computed(() => []);
const headerTabs = computed(() => []);

View file

@ -393,6 +393,39 @@ SPDX-License-Identifier: AGPL-3.0-only
</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>
<SearchMarker :keywords="['other']">
<MkFolder>
<template #label><SearchLabel>{{ i18n.ts.other }}</SearchLabel></template>
@ -422,6 +455,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
<SearchMarker :keywords="['follow', 'replies']">
<MkPreferenceContainer k="defaultFollowWithReplies">
<MkSwitch v-model="defaultFollowWithReplies">
<template #label><SearchLabel>{{ i18n.ts.withRepliesByDefaultForNewlyFollowed }}</SearchLabel></template>
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
</div>
<SearchMarker :keywords="['server', 'disconnect', 'reconnect', 'reload', 'streaming']">
@ -477,43 +518,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>
</SearchMarker>
</div>
<SearchMarker :keywords="['datasaver']">
<MkFolder>
<template #label><SearchLabel>{{ i18n.ts.dataSaver }}</SearchLabel></template>
<hr>
<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>
<FormLink to="/settings/navbar">{{ i18n.ts.navbar }}</FormLink>
<FormLink to="/settings/statusbar">{{ i18n.ts.statusbar }}</FormLink>
<FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink>
<div class="_gaps_s">
<FormLink to="/settings/navbar"><template #icon><i class="ti ti-list"></i></template>{{ i18n.ts.navbar }}</FormLink>
<FormLink to="/settings/statusbar"><template #icon><i class="ti ti-list"></i></template>{{ i18n.ts.statusbar }}</FormLink>
<FormLink to="/settings/deck"><template #icon><i class="ti ti-columns"></i></template>{{ i18n.ts.deck }}</FormLink>
<FormLink to="/settings/custom-css"><template #icon><i class="ti ti-code"></i></template>{{ i18n.ts.customCss }}</FormLink>
</div>
</div>
@ -592,6 +604,7 @@ const nsfw = prefer.model('nsfw');
const emojiStyle = prefer.model('emojiStyle');
const useBlurEffectForModal = prefer.model('useBlurEffectForModal');
const useBlurEffect = prefer.model('useBlurEffect');
const defaultFollowWithReplies = prefer.model('defaultFollowWithReplies');
watch(lang, () => {
miLocalStorage.setItem('lang', lang.value as string);

View file

@ -306,6 +306,9 @@ export const PREF_DEF = {
confirmOnReact: {
default: false,
},
defaultFollowWithReplies: {
default: false,
},
plugins: {
default: [] as Plugin[],
},

View file

@ -100,10 +100,6 @@ export const store = markRaw(new Storage('base', {
where: 'device',
default: {} as Record<string, Record<string, string[]>>,
},
defaultWithReplies: {
where: 'account',
default: false,
},
pluginTokens: {
where: 'deviceAccount',
default: {} as Record<string, string>, // plugin id, token
@ -119,6 +115,10 @@ export const store = markRaw(new Storage('base', {
},
//#region TODO: そのうち消す (preferに移行済み)
defaultWithReplies: {
where: 'account',
default: false,
},
reactions: {
where: 'account',
default: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'],

View file

@ -128,7 +128,7 @@ optgroup, option {
}
hr {
margin: var(--MI-margin) 0 var(--MI-margin) 0;
margin: 0;
border: none;
height: 1px;
background: var(--MI_THEME-divider);

View file

@ -482,44 +482,54 @@ export const searchIndexes: SearchIndexItem[] = [
},
{
id: '2E7vdIUQd',
label: i18n.ts.dataSaver,
keywords: ['datasaver'],
},
{
id: '6ZbRRIhA6',
children: [
{
id: 'C2iXtZKb3',
id: 'soNZaKfiW',
label: i18n.ts.squareAvatars,
keywords: ['avatar', 'icon', 'square'],
},
{
id: 'DCfJg0bva',
id: 'nhwHJJ2tl',
label: i18n.ts.seasonalScreenEffect,
keywords: ['effect', 'show'],
},
{
id: 'AV0iGW0vg',
id: 'oMAVUuxTm',
label: i18n.ts.openImageInNewTab,
keywords: ['image', 'photo', 'picture', 'media', 'thumbnail', 'new', 'tab'],
},
{
id: '5h8vhCX1S',
id: 'hSqX5JKM7',
label: i18n.ts.withRepliesByDefaultForNewlyFollowed,
keywords: ['follow', 'replies'],
},
{
id: 'fm98eqzke',
label: i18n.ts.whenServerDisconnected,
keywords: ['server', 'disconnect', 'reconnect', 'reload', 'streaming'],
},
{
id: 'zZxyXHk3A',
id: '1rWDVig8Y',
label: i18n.ts.numberOfPageCache,
keywords: ['cache', 'page'],
},
{
id: '7ix3kvMyU',
id: 'vXLtihtCp',
label: i18n.ts.forceShowAds,
keywords: ['ad', 'show'],
},
{
id: '6RxgjmMLN',
id: '77YljFpiH',
label: i18n.ts.hemisphere,
keywords: [],
},
{
id: '5iMpm5rES',
id: 'CZgDNPP1h',
label: i18n.ts.additionalEmojiDictionary,
keywords: ['emoji', 'dictionary', 'additional', 'extra'],
},
@ -527,11 +537,6 @@ export const searchIndexes: SearchIndexItem[] = [
label: i18n.ts.other,
keywords: ['other'],
},
{
id: 'fnR7PRww5',
label: i18n.ts.dataSaver,
keywords: ['datasaver'],
},
],
label: i18n.ts.preferences,
keywords: ['general', 'preferences', i18n.ts._settings.preferencesBanner],
@ -549,32 +554,32 @@ export const searchIndexes: SearchIndexItem[] = [
id: 'F1uK9ssiY',
children: [
{
id: 'msAcN6u3S',
id: 'E0ndmaP6Q',
label: i18n.ts._role.policies,
keywords: ['account', 'info'],
},
{
id: 'pbTLsgRO7',
id: 'r5SjfwZJc',
label: i18n.ts.rolesAssignedToMe,
keywords: ['roles'],
},
{
id: 'fQpvZyfLK',
id: 'cm7LrjgaW',
label: i18n.ts.accountMigration,
keywords: ['account', 'move', 'migration'],
},
{
id: 'xhfur5m2z',
id: 'ozfqNviP3',
label: i18n.ts.closeAccount,
keywords: ['account', 'close', 'delete', i18n.ts._accountDelete.requestAccountDelete],
},
{
id: 'oAXB8zm2U',
id: 'tpywgkpxy',
label: i18n.ts.experimentalFeatures,
keywords: ['experimental', 'feature', 'flags'],
},
{
id: '95OjjGSo7',
id: '54wETGawJ',
label: i18n.ts.developer,
keywords: ['developer', 'mode', 'debug'],
},