diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2022-12-27 14:55:11 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-27 14:55:11 +0900 |
| commit | e3f2845cf82c5d9fca3c07541caf5b86a1bbe2c2 (patch) | |
| tree | cd630d33bb69ddaf2c18de683ac71f0b31d96757 /packages/frontend/src/ui | |
| parent | New Crowdin updates (#9416) (diff) | |
| download | misskey-e3f2845cf82c5d9fca3c07541caf5b86a1bbe2c2.tar.gz misskey-e3f2845cf82c5d9fca3c07541caf5b86a1bbe2c2.tar.bz2 misskey-e3f2845cf82c5d9fca3c07541caf5b86a1bbe2c2.zip | |
enhance(client): Sync widgets (#8512)
* feature: sync widgets among devices
* fix
* nanka iroiro
* classic.widgets.vueの機能をuniversal.widgets.vueに統合
* 左右のウィジェット編集状態を同期するように
* 左右やカラム間でウィジェットを行き来できるように
* MkWidgetsをCSS Module化
* set min-height: 100px;
* fix deck widget
* Update packages/client/src/ui/deck/widgets-column.vue
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
* merge
* Update classic.vue
* Delete classic.widgets.vue
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Diffstat (limited to 'packages/frontend/src/ui')
| -rw-r--r-- | packages/frontend/src/ui/classic.vue | 6 | ||||
| -rw-r--r-- | packages/frontend/src/ui/classic.widgets.vue | 84 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/widgets-column.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/ui/universal.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/ui/universal.widgets.vue | 58 |
5 files changed, 54 insertions, 98 deletions
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue index 0e726c11ed..44b017ea96 100644 --- a/packages/frontend/src/ui/classic.vue +++ b/packages/frontend/src/ui/classic.vue @@ -7,7 +7,7 @@ <XSidebar/> </div> <div v-else ref="widgetsLeft" class="widgets left"> - <XWidgets :place="'left'" @mounted="attachSticky(widgetsLeft)"/> + <XWidgets place="left" @mounted="attachSticky(widgetsLeft)"/> </div> <main class="main" :style="{ background: pageMetadata?.value?.bg }" @contextmenu.stop="onContextmenu"> @@ -17,7 +17,7 @@ </main> <div v-if="isDesktop" ref="widgetsRight" class="widgets right"> - <XWidgets :place="null" @mounted="attachSticky(widgetsRight)"/> + <XWidgets :place="showMenuOnTop ? 'right' : null" @mounted="attachSticky(widgetsRight)"/> </div> </div> @@ -52,7 +52,7 @@ import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/script import { defaultStore } from '@/store'; import { i18n } from '@/i18n'; const XHeaderMenu = defineAsyncComponent(() => import('./classic.header.vue')); -const XWidgets = defineAsyncComponent(() => import('./classic.widgets.vue')); +const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue')); const DESKTOP_THRESHOLD = 1100; diff --git a/packages/frontend/src/ui/classic.widgets.vue b/packages/frontend/src/ui/classic.widgets.vue deleted file mode 100644 index 163ec982ce..0000000000 --- a/packages/frontend/src/ui/classic.widgets.vue +++ /dev/null @@ -1,84 +0,0 @@ -<template> -<div class="ddiqwdnk"> - <XWidgets class="widgets" :edit="editMode" :widgets="$store.reactiveState.widgets.value.filter(w => w.place === place)" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="editMode = false"/> - <MkAd class="a" :prefer="['square']"/> - - <button v-if="editMode" class="_textButton edit" style="font-size: 0.9em;" @click="editMode = false"><i class="ti ti-check"></i> {{ $ts.editWidgetsExit }}</button> - <button v-else class="_textButton edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ $ts.editWidgets }}</button> -</div> -</template> - -<script lang="ts"> -import { defineComponent, defineAsyncComponent } from 'vue'; -import XWidgets from '@/components/MkWidgets.vue'; - -export default defineComponent({ - components: { - XWidgets, - }, - - props: { - place: { - type: String, - }, - }, - - emits: ['mounted'], - - data() { - return { - editMode: false, - }; - }, - - mounted() { - this.$emit('mounted', this.$el); - }, - - methods: { - addWidget(widget) { - this.$store.set('widgets', [{ - ...widget, - place: this.place, - }, ...this.$store.state.widgets]); - }, - - removeWidget(widget) { - this.$store.set('widgets', this.$store.state.widgets.filter(w => w.id !== widget.id)); - }, - - updateWidget({ id, data }) { - this.$store.set('widgets', this.$store.state.widgets.map(w => w.id === id ? { - ...w, - data, - } : w)); - }, - - updateWidgets(widgets) { - this.$store.set('widgets', [ - ...this.$store.state.widgets.filter(w => w.place !== this.place), - ...widgets, - ]); - }, - }, -}); -</script> - -<style lang="scss" scoped> -.ddiqwdnk { - position: sticky; - height: min-content; - box-sizing: border-box; - padding-bottom: 8px; - - > .widgets, - > .a { - width: 300px; - } - - > .edit { - display: block; - margin: 16px auto; - } -} -</style> diff --git a/packages/frontend/src/ui/deck/widgets-column.vue b/packages/frontend/src/ui/deck/widgets-column.vue index fc61d18ff6..edc54c1c2b 100644 --- a/packages/frontend/src/ui/deck/widgets-column.vue +++ b/packages/frontend/src/ui/deck/widgets-column.vue @@ -4,7 +4,7 @@ <div class="wtdtxvec"> <div v-if="!(column.widgets && column.widgets.length > 0) && !edit" class="intro">{{ i18n.ts._deck.widgetsIntroduction }}</div> - <XWidgets :edit="edit" :widgets="column.widgets" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="edit = false"/> + <XWidgets :edit="edit" :widgets="column.widgets ?? []" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="edit = false"/> </div> </XColumn> </template> diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue index b91bf476e8..2cb8a9d6a6 100644 --- a/packages/frontend/src/ui/universal.vue +++ b/packages/frontend/src/ui/universal.vue @@ -273,7 +273,7 @@ const wallpaper = localStorage.getItem('wallpaper') != null; right: 0; z-index: 1001; height: 100dvh; - padding: var(--margin); + padding: var(--margin) !important; box-sizing: border-box; overflow: auto; overscroll-behavior: contain; diff --git a/packages/frontend/src/ui/universal.widgets.vue b/packages/frontend/src/ui/universal.widgets.vue index 33fb492836..002aab1090 100644 --- a/packages/frontend/src/ui/universal.widgets.vue +++ b/packages/frontend/src/ui/universal.widgets.vue @@ -1,25 +1,44 @@ <template> -<div class="efzpzdvf"> - <XWidgets :edit="editMode" :widgets="defaultStore.reactiveState.widgets.value" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="editMode = false"/> +<div class="efzpzdvf" :class="{ universal: !classic, classic }"> + <XWidgets :edit="editMode" :widgets="widgets" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="editMode = false"/> <button v-if="editMode" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="ti ti-check"></i> {{ i18n.ts.editWidgetsExit }}</button> <button v-else class="_textButton mk-widget-edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ i18n.ts.editWidgets }}</button> </div> </template> +<script lang="ts"> +let editMode = $ref(false); +</script> <script lang="ts" setup> import { onMounted } from 'vue'; import XWidgets from '@/components/MkWidgets.vue'; import { i18n } from '@/i18n'; import { defaultStore } from '@/store'; +const props = withDefaults(defineProps<{ + // null = 全てのウィジェットを表示 + // left = place: leftだけを表示 + // right = rightとnullを表示 + place?: 'left' | null | 'right'; + classic?: boolean; +}>(), { + place: null, + classic: false, +}); + const emit = defineEmits<{ - (ev: 'mounted', el: Element): void; + (ev: 'mounted', el?: Element): void; }>(); -let editMode = $ref(false); let rootEl = $ref<HTMLDivElement>(); +const widgets = $computed(() => { + if (props.place === null) return defaultStore.reactiveState.widgets.value; + if (props.place === 'left') return defaultStore.reactiveState.widgets.value.filter(w => w.place === 'left'); + return defaultStore.reactiveState.widgets.value.filter(w => w.place !== 'left'); +}); + onMounted(() => { emit('mounted', rootEl); }); @@ -27,7 +46,7 @@ onMounted(() => { function addWidget(widget) { defaultStore.set('widgets', [{ ...widget, - place: null, + place: props.place, }, ...defaultStore.state.widgets]); } @@ -39,11 +58,26 @@ function updateWidget({ id, data }) { defaultStore.set('widgets', defaultStore.state.widgets.map(w => w.id === id ? { ...w, data, + place: props.place, } : w)); } -function updateWidgets(widgets) { - defaultStore.set('widgets', widgets); +function updateWidgets(thisWidgets) { + if (props.place === null) { + defaultStore.set('widgets', thisWidgets); + return; + } + if (props.place === 'left') { + defaultStore.set('widgets', [ + ...thisWidgets.map(w => ({ ...w, place: 'left' })), + ...defaultStore.state.widgets.filter(w => w.place !== 'left' && !thisWidgets.some(t => w.id === t.id)), + ]); + return; + } + defaultStore.set('widgets', [ + ...defaultStore.state.widgets.filter(w => w.place === 'left' && !thisWidgets.some(t => w.id === t.id)), + ...thisWidgets.map(w => ({ ...w, place: 'right' })), + ]); } </script> @@ -52,11 +86,17 @@ function updateWidgets(widgets) { position: sticky; height: min-content; min-height: 100vh; - padding: var(--margin) 0; box-sizing: border-box; + &.universal { + padding: var(--margin) 0; + + > * { + margin: var(--margin) 0; + } + } + > * { - margin: var(--margin) 0; width: 300px; &:first-child { |