mirror of
https://github.com/kokonect-link/cherrypick
synced 2024-11-23 22:56:53 +09:00
feat: Improved navigation bar editing experience
This commit is contained in:
parent
1d5434d5f8
commit
9570090daf
@ -29,6 +29,7 @@
|
|||||||
- 클라이언트: 모바일 환경에서 로그인 페이지 디자인 개선
|
- 클라이언트: 모바일 환경에서 로그인 페이지 디자인 개선
|
||||||
- 클라이언트: 타임라인 전환시 맨 위로 이동하도록 변경
|
- 클라이언트: 타임라인 전환시 맨 위로 이동하도록 변경
|
||||||
- 클라이언트: 위젯 위치 변경 방식 개선
|
- 클라이언트: 위젯 위치 변경 방식 개선
|
||||||
|
- 클라이언트: 네비게이션 바 편집 환경 개선
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
- 클라이언트: 채팅방에서 메시지를 입력하고 있을 때 움직이지 않는 온점(.)이 표시되는 문제
|
- 클라이언트: 채팅방에서 메시지를 입력하고 있을 때 움직이지 않는 온점(.)이 표시되는 문제
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="_formRoot">
|
<div class="_formRoot">
|
||||||
<FormTextarea v-model="items" tall manual-save class="_formBlock">
|
|
||||||
<template #label>{{ i18n.ts.navbar }}</template>
|
|
||||||
<template #caption><button class="_textButton" @click="addItem">{{ i18n.ts.addItem }}</button></template>
|
|
||||||
</FormTextarea>
|
|
||||||
|
|
||||||
<FormRadios v-model="menuDisplay" class="_formBlock">
|
<FormRadios v-model="menuDisplay" class="_formBlock">
|
||||||
<template #label>{{ i18n.ts.display }}</template>
|
<template #label>{{ i18n.ts.display }}</template>
|
||||||
<option value="sideFull">{{ i18n.ts._menuDisplay.sideFull }}</option>
|
<option value="sideFull">{{ i18n.ts._menuDisplay.sideFull }}</option>
|
||||||
@ -13,12 +8,30 @@
|
|||||||
<!-- <MkRadio v-model="menuDisplay" value="hide" disabled>{{ i18n.ts._menuDisplay.hide }}</MkRadio>--> <!-- TODO: サイドバーを完全に隠せるようにすると、別途ハンバーガーボタンのようなものをUIに表示する必要があり面倒 -->
|
<!-- <MkRadio v-model="menuDisplay" value="hide" disabled>{{ i18n.ts._menuDisplay.hide }}</MkRadio>--> <!-- TODO: サイドバーを完全に隠せるようにすると、別途ハンバーガーボタンのようなものをUIに表示する必要があり面倒 -->
|
||||||
</FormRadios>
|
</FormRadios>
|
||||||
|
|
||||||
|
<div class="asdiokco _formItem _formPanel">
|
||||||
|
<XDraggable class="draggable" v-model="items" :item-key="item => item" animation="150" delay="100" delay-on-touch-only="true">
|
||||||
|
<template #item="{element: item}">
|
||||||
|
<div class="item">
|
||||||
|
<i v-if="!item.startsWith('-:')" :class="navbarItemDef[item].icon" />
|
||||||
|
<template v-if="item.startsWith('-:')">
|
||||||
|
<i class="fas fa-minus" />
|
||||||
|
<span v-text="$ts.divider"/>
|
||||||
|
</template>
|
||||||
|
<span v-else v-text="$t(navbarItemDef[item] ? navbarItemDef[item].title : item)"/>
|
||||||
|
<div class="del" @click="del(item)"><i class="fas fa-times" /></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</XDraggable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormButton class="_formBlock" @click="addItem"><i class="fas fa-plus"></i> {{ i18n.ts.addItem }}</FormButton>
|
||||||
|
<FormButton v-if="isChanged" class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
|
||||||
<FormButton danger class="_formBlock" @click="reset()"><i class="fas fa-redo"></i> {{ i18n.ts.default }}</FormButton>
|
<FormButton danger class="_formBlock" @click="reset()"><i class="fas fa-redo"></i> {{ i18n.ts.default }}</FormButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, defineAsyncComponent, ref, watch } from 'vue';
|
||||||
import FormTextarea from '@/components/form/textarea.vue';
|
import FormTextarea from '@/components/form/textarea.vue';
|
||||||
import FormRadios from '@/components/form/radios.vue';
|
import FormRadios from '@/components/form/radios.vue';
|
||||||
import FormButton from '@/components/MkButton.vue';
|
import FormButton from '@/components/MkButton.vue';
|
||||||
@ -28,12 +41,19 @@ import { defaultStore } from '@/store';
|
|||||||
import { unisonReload } from '@/scripts/unison-reload';
|
import { unisonReload } from '@/scripts/unison-reload';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
const items = ref(defaultStore.state.menu.join('\n'));
|
const XDraggable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
|
||||||
|
|
||||||
const split = computed(() => items.value.trim().split('\n').filter(x => x.trim() !== ''));
|
// const items = ref(defaultStore.state.menu.join('\n'));
|
||||||
|
const items = ref([]);
|
||||||
|
items.value = defaultStore.state.menu.map(it => it === '-' ? '-:' + uuid() : it);
|
||||||
|
|
||||||
|
// const split = computed(() => items.value.trim().split('\n').filter(x => x.trim() !== ''));
|
||||||
const menuDisplay = computed(defaultStore.makeGetterSetter('menuDisplay'));
|
const menuDisplay = computed(defaultStore.makeGetterSetter('menuDisplay'));
|
||||||
|
|
||||||
|
let isChanged = false;
|
||||||
|
|
||||||
async function reloadAsk() {
|
async function reloadAsk() {
|
||||||
const { canceled } = await os.confirm({
|
const { canceled } = await os.confirm({
|
||||||
type: 'info',
|
type: 'info',
|
||||||
@ -51,25 +71,33 @@ async function addItem() {
|
|||||||
items: [...menu.map(k => ({
|
items: [...menu.map(k => ({
|
||||||
value: k, text: i18n.ts[navbarItemDef[k].title],
|
value: k, text: i18n.ts[navbarItemDef[k].title],
|
||||||
})), {
|
})), {
|
||||||
value: '-', text: i18n.ts.divider,
|
value: '-:' + uuid(), text: i18n.ts.divider,
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
items.value = [...split.value, item].join('\n');
|
items.value = [...items.value, item];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function del(item) {
|
||||||
|
items.value = items.value.filter(it => it !== item);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
defaultStore.set('menu', split.value);
|
// defaultStore.set('menu', split.value);
|
||||||
|
defaultStore.set('menu', items.value.map(it => it.startsWith('-:') ? '-' : it));
|
||||||
await reloadAsk();
|
await reloadAsk();
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
defaultStore.reset('menu');
|
defaultStore.reset('menu');
|
||||||
items.value = defaultStore.state.menu.join('\n');
|
// items.value = defaultStore.state.menu.join('\n');
|
||||||
|
items.value = defaultStore.state.menu.map(it => it === '-' ? '-:' + uuid() : it);
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(items, async () => {
|
watch(items, async () => {
|
||||||
await save();
|
isChanged = true;
|
||||||
|
}, {
|
||||||
|
deep: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(menuDisplay, async () => {
|
watch(menuDisplay, async () => {
|
||||||
@ -85,3 +113,41 @@ definePageMetadata({
|
|||||||
icon: 'fas fa-list-ul',
|
icon: 'fas fa-list-ul',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.asdiokco {
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
> .draggable {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item, .otherItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: solid 1px var(--divider);
|
||||||
|
border-bottom: none;
|
||||||
|
cursor: move;
|
||||||
|
|
||||||
|
> i {
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .del {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--error);
|
||||||
|
justify-content: center;
|
||||||
|
margin-left: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: solid 1px var(--divider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user