wip
This commit is contained in:
parent
05d41f2a7a
commit
a37a945f95
|
@ -0,0 +1,38 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="[$style.root, { [$style.highlighted]: highlighted }]">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, shallowRef } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
markerId: string;
|
||||
}>();
|
||||
|
||||
const highlighted = window.location.hash.slice(1) === props.markerId;
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
}
|
||||
|
||||
.highlighted {
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 0 2px color(from var(--MI_THEME-accent) srgb r g b / 0.3);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 0 2px transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -5,26 +5,40 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<div class="rrevdjwu" :class="{ grid }">
|
||||
<div v-for="group in def" class="group">
|
||||
<div v-if="group.title" class="title">{{ group.title }}</div>
|
||||
<MkInput v-model="search" :placeholder="i18n.ts.search" type="search" style="margin-bottom: 16px;" @keydown.enter="searchSubmit">
|
||||
<template #prefix><i class="ti ti-search"></i></template>
|
||||
</MkInput>
|
||||
|
||||
<div class="items">
|
||||
<template v-for="(item, i) in group.items">
|
||||
<a v-if="item.type === 'a'" :href="item.href" :target="item.target" class="_button item" :class="{ danger: item.danger, active: item.active }">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.text }}</span>
|
||||
</a>
|
||||
<button v-else-if="item.type === 'button'" class="_button item" :class="{ danger: item.danger, active: item.active }" :disabled="item.active" @click="ev => item.action(ev)">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.text }}</span>
|
||||
</button>
|
||||
<MkA v-else :to="item.to" class="_button item" :class="{ danger: item.danger, active: item.active }">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.text }}</span>
|
||||
</MkA>
|
||||
</template>
|
||||
<template v-if="search == ''">
|
||||
<div v-for="group in def" class="group">
|
||||
<div v-if="group.title" class="title">{{ group.title }}</div>
|
||||
|
||||
<div class="items">
|
||||
<template v-for="(item, i) in group.items">
|
||||
<a v-if="item.type === 'a'" :href="item.href" :target="item.target" class="_button item" :class="{ danger: item.danger, active: item.active }">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.text }}</span>
|
||||
</a>
|
||||
<button v-else-if="item.type === 'button'" class="_button item" :class="{ danger: item.danger, active: item.active }" :disabled="item.active" @click="ev => item.action(ev)">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.text }}</span>
|
||||
</button>
|
||||
<MkA v-else :to="item.to" class="_button item" :class="{ danger: item.danger, active: item.active }">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.text }}</span>
|
||||
</MkA>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-for="item in searchResult">
|
||||
<MkA :to="item.path + '#' + item.id" class="_button searchResultItem">
|
||||
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
|
||||
<span class="text">{{ item.locationLabel.join(' > ') }}</span>
|
||||
</MkA>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -58,10 +72,52 @@ export type SuperMenuDef = {
|
|||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
defineProps<{
|
||||
def: SuperMenuDef[];
|
||||
grid?: boolean;
|
||||
}>();
|
||||
|
||||
const search = ref('');
|
||||
const searchResult = ref<any[]>([]);
|
||||
|
||||
const INDEX = [{
|
||||
id: '727cc9e8-ad67-474a-9241-b5a9a6475e47',
|
||||
locationLabel: [i18n.ts.profile, i18n.ts._profile.name],
|
||||
icon: 'ti ti-user',
|
||||
keywords: ['name'],
|
||||
path: '/settings/profile',
|
||||
}, {
|
||||
id: '1a06c7f9-e85e-46cb-bf5f-b3efa8e71b93',
|
||||
locationLabel: [i18n.ts.profile, i18n.ts._profile.description],
|
||||
icon: 'ti ti-user',
|
||||
keywords: ['bio'],
|
||||
path: '/settings/profile',
|
||||
}, {
|
||||
id: 'acbfe8cb-c3c9-4d90-8c62-713025814b2e',
|
||||
locationLabel: [i18n.ts.privacy, i18n.ts.makeFollowManuallyApprove],
|
||||
icon: 'ti ti-lock-open',
|
||||
keywords: ['follow', 'lock', i18n.ts.lockedAccountInfo],
|
||||
path: '/settings/privacy',
|
||||
}];
|
||||
|
||||
watch(search, (value) => {
|
||||
if (value === '') {
|
||||
searchResult.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
searchResult.value = INDEX.filter((item) => {
|
||||
// TODO: 日本語でひらがなカタカナの区別をしない
|
||||
return item.locationLabel.some((x) => x.toLowerCase().includes(value.toLowerCase())) || item.keywords.some((x) => x.toLowerCase().includes(value.toLowerCase()));
|
||||
});
|
||||
});
|
||||
|
||||
function searchSubmit() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -184,5 +240,47 @@ defineProps<{
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.searchResultItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 9px 16px 9px 8px;
|
||||
border-radius: 9px;
|
||||
font-size: 0.9em;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
background: var(--MI_THEME-panelHighlight);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--MI_THEME-accent);
|
||||
background: var(--MI_THEME-accentedBg);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
color: var(--MI_THEME-error);
|
||||
}
|
||||
|
||||
> .icon {
|
||||
width: 32px;
|
||||
margin-right: 2px;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
> .text {
|
||||
white-space: normal;
|
||||
padding-right: 12px;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,7 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<div class="_gaps_m">
|
||||
<MkSwitch v-model="isLocked" @update:modelValue="save()">{{ i18n.ts.makeFollowManuallyApprove }}<template #caption>{{ i18n.ts.lockedAccountInfo }}</template></MkSwitch>
|
||||
<MkSearchMarker markerId="acbfe8cb-c3c9-4d90-8c62-713025814b2e">
|
||||
<MkSwitch v-model="isLocked" @update:modelValue="save()">{{ i18n.ts.makeFollowManuallyApprove }}<template #caption>{{ i18n.ts.lockedAccountInfo }}</template></MkSwitch>
|
||||
</MkSearchMarker>
|
||||
|
||||
<MkSwitch v-if="isLocked" v-model="autoAcceptFollowed" @update:modelValue="save()">{{ i18n.ts.autoAcceptFollowed }}</MkSwitch>
|
||||
|
||||
<MkSwitch v-model="publicReactions" @update:modelValue="save()">
|
||||
|
@ -174,6 +177,7 @@ import FormSlot from '@/components/form/slot.vue';
|
|||
import { formatDateTimeString } from '@/scripts/format-time-string.js';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import * as os from '@/os.js';
|
||||
import MkSearchMarker from '@/components/MkSearchMarker.vue';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
|
|
|
@ -18,14 +18,18 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<MkInput v-model="profile.name" :max="30" manualSave :mfmAutocomplete="['emoji']">
|
||||
<template #label>{{ i18n.ts._profile.name }}</template>
|
||||
</MkInput>
|
||||
<MkSearchMarker markerId="727cc9e8-ad67-474a-9241-b5a9a6475e47">
|
||||
<MkInput v-model="profile.name" :max="30" manualSave :mfmAutocomplete="['emoji']">
|
||||
<template #label>{{ i18n.ts._profile.name }}</template>
|
||||
</MkInput>
|
||||
</MkSearchMarker>
|
||||
|
||||
<MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true">
|
||||
<template #label>{{ i18n.ts._profile.description }}</template>
|
||||
<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
|
||||
</MkTextarea>
|
||||
<MkSearchMarker markerId="1a06c7f9-e85e-46cb-bf5f-b3efa8e71b93">
|
||||
<MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true">
|
||||
<template #label>{{ i18n.ts._profile.description }}</template>
|
||||
<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
|
||||
</MkTextarea>
|
||||
</MkSearchMarker>
|
||||
|
||||
<MkInput v-model="profile.location" manualSave>
|
||||
<template #label>{{ i18n.ts.location }}</template>
|
||||
|
@ -121,6 +125,7 @@ import MkButton from '@/components/MkButton.vue';
|
|||
import MkInput from '@/components/MkInput.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
import MkSearchMarker from '@/components/MkSearchMarker.vue';
|
||||
import FormSplit from '@/components/form/split.vue';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import FormSlot from '@/components/form/slot.vue';
|
||||
|
|
Loading…
Reference in New Issue