summaryrefslogtreecommitdiff
path: root/packages/frontend/src/ui/deck.vue
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-04-29 09:43:15 +0900
committersyuilo <4439005+syuilo@users.noreply.github.com>2025-04-29 09:43:15 +0900
commitd6ae4c980ba0e7893af4a2c327cad367cda24e5c (patch)
tree220f5ddf34da3edb6d5f5b674062b9b7905f7739 /packages/frontend/src/ui/deck.vue
parentBump version to 2025.4.1-beta.8 (diff)
downloadmisskey-d6ae4c980ba0e7893af4a2c327cad367cda24e5c.tar.gz
misskey-d6ae4c980ba0e7893af4a2c327cad367cda24e5c.tar.bz2
misskey-d6ae4c980ba0e7893af4a2c327cad367cda24e5c.zip
feat(frontend): タイトルバーを表示できるように
Diffstat (limited to 'packages/frontend/src/ui/deck.vue')
-rw-r--r--packages/frontend/src/ui/deck.vue140
1 files changed, 74 insertions, 66 deletions
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index 7556f513c2..f702e8ef44 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -4,71 +4,75 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
-<div :class="[$style.root, { [$style.withWallpaper]: withWallpaper }]">
- <XSidebar v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'left'"/>
+<div :class="[$style.root]">
+ <XTitlebar v-if="prefer.r.showTitlebar.value" style="flex-shrink: 0;"/>
- <div :class="$style.main">
- <XNavbarH v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'top'"/>
+ <div :class="$style.nonTitlebarArea">
+ <XSidebar v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'left'"/>
- <XAnnouncements v-if="$i"/>
- <XStatusBars/>
- <div :class="$style.columnsWrapper">
- <!-- passive: https://bugs.webkit.org/show_bug.cgi?id=281300 -->
- <div ref="columnsEl" :class="[$style.columns, { [$style.center]: prefer.r['deck.columnAlign'].value === 'center', [$style.snapScroll]: snapScroll }]" @contextmenu.self.prevent="onContextmenu" @wheel.passive.self="onWheel">
- <!-- sectionを利用しているのは、deck.vue側でcolumnに対してfirst-of-typeを効かせるため -->
- <section
- v-for="ids in layout"
- :class="$style.section"
- :style="columns.filter(c => ids.includes(c.id)).some(c => c.flexible) ? { flex: 1, minWidth: '350px' } : { width: Math.max(...columns.filter(c => ids.includes(c.id)).map(c => c.width)) + 'px' }"
- @wheel.passive.self="onWheel"
- >
- <component
- :is="columnComponents[columns.find(c => c.id === id)!.type] ?? XTlColumn"
- v-for="id in ids"
- :ref="id"
- :key="id"
- :class="[$style.column, { '_shadow': withWallpaper }]"
- :column="columns.find(c => c.id === id)!"
- :isStacked="ids.length > 1"
- @headerWheel="onWheel"
- />
- </section>
- <div v-if="layout.length === 0" class="_panel" :class="$style.onboarding">
- <div>{{ i18n.ts._deck.introduction }}</div>
- <div>{{ i18n.ts._deck.introduction2 }}</div>
+ <div :class="[$style.main, { [$style.withWallpaper]: withWallpaper, [$style.withSidebarAndTitlebar]: !isMobile && prefer.r['deck.navbarPosition'].value === 'left' && prefer.r.showTitlebar.value }]" :style="{ backgroundImage: prefer.s['deck.wallpaper'] != null ? `url(${ prefer.s['deck.wallpaper'] })` : null }">
+ <XNavbarH v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'top'"/>
+
+ <XAnnouncements v-if="$i"/>
+ <XStatusBars/>
+ <div :class="$style.columnsWrapper">
+ <!-- passive: https://bugs.webkit.org/show_bug.cgi?id=281300 -->
+ <div ref="columnsEl" :class="[$style.columns, { [$style.center]: prefer.r['deck.columnAlign'].value === 'center', [$style.snapScroll]: snapScroll }]" @contextmenu.self.prevent="onContextmenu" @wheel.passive.self="onWheel">
+ <!-- sectionを利用しているのは、deck.vue側でcolumnに対してfirst-of-typeを効かせるため -->
+ <section
+ v-for="ids in layout"
+ :class="$style.section"
+ :style="columns.filter(c => ids.includes(c.id)).some(c => c.flexible) ? { flex: 1, minWidth: '350px' } : { width: Math.max(...columns.filter(c => ids.includes(c.id)).map(c => c.width)) + 'px' }"
+ @wheel.passive.self="onWheel"
+ >
+ <component
+ :is="columnComponents[columns.find(c => c.id === id)!.type] ?? XTlColumn"
+ v-for="id in ids"
+ :ref="id"
+ :key="id"
+ :class="[$style.column, { '_shadow': withWallpaper }]"
+ :column="columns.find(c => c.id === id)!"
+ :isStacked="ids.length > 1"
+ @headerWheel="onWheel"
+ />
+ </section>
+ <div v-if="layout.length === 0" class="_panel" :class="$style.onboarding">
+ <div>{{ i18n.ts._deck.introduction }}</div>
+ <div>{{ i18n.ts._deck.introduction2 }}</div>
+ </div>
+ </div>
+
+ <div v-if="prefer.r['deck.menuPosition'].value === 'right'" :class="$style.sideMenu">
+ <div :class="$style.sideMenuTop">
+ <button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.sideMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
+ <button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
+ </div>
+ <div :class="$style.sideMenuMiddle">
+ <button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
+ </div>
+ <div :class="$style.sideMenuBottom">
+ <button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
+ </div>
</div>
</div>
- <div v-if="prefer.r['deck.menuPosition'].value === 'right'" :class="$style.sideMenu">
- <div :class="$style.sideMenuTop">
- <button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.sideMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
- <button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
+ <div v-if="prefer.r['deck.menuPosition'].value === 'bottom'" :class="$style.bottomMenu">
+ <div :class="$style.bottomMenuLeft">
+ <button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.bottomMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
+ <button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.bottomMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
</div>
- <div :class="$style.sideMenuMiddle">
- <button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
+ <div :class="$style.bottomMenuMiddle">
+ <button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.bottomMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
</div>
- <div :class="$style.sideMenuBottom">
- <button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
+ <div :class="$style.bottomMenuRight">
+ <button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.bottomMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
</div>
</div>
- </div>
-
- <div v-if="prefer.r['deck.menuPosition'].value === 'bottom'" :class="$style.bottomMenu">
- <div :class="$style.bottomMenuLeft">
- <button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.bottomMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
- <button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.bottomMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
- </div>
- <div :class="$style.bottomMenuMiddle">
- <button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.bottomMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
- </div>
- <div :class="$style.bottomMenuRight">
- <button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.bottomMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
- </div>
- </div>
- <XNavbarH v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'bottom'"/>
+ <XNavbarH v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'bottom'"/>
- <XMobileFooterMenu v-if="isMobile" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
+ <XMobileFooterMenu v-if="isMobile" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
+ </div>
</div>
<XCommon v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
@@ -82,6 +86,7 @@ import XCommon from './_common_/common.vue';
import XSidebar from '@/ui/_common_/navbar.vue';
import XNavbarH from '@/ui/_common_/navbar-h.vue';
import XMobileFooterMenu from '@/ui/_common_/mobile-footer-menu.vue';
+import XTitlebar from '@/ui/_common_/titlebar.vue';
import * as os from '@/os.js';
import { $i } from '@/i.js';
import { i18n } from '@/i18n.js';
@@ -209,30 +214,25 @@ async function deleteProfile() {
window.document.documentElement.style.overflowY = 'hidden';
window.document.documentElement.style.scrollBehavior = 'auto';
-
-if (prefer.s['deck.wallpaper'] != null) {
- window.document.documentElement.style.backgroundImage = `url(${prefer.s['deck.wallpaper']})`;
-}
</script>
<style lang="scss" module>
.root {
- $nav-hide-threshold: 650px; // TODO: どこかに集約したい
-
--MI-margin: var(--MI-marginHalf);
--columnGap: v-bind("gap + 'px'");
display: flex;
+ flex-direction: column;
height: 100dvh;
box-sizing: border-box;
flex: 1;
+ background: var(--MI_THEME-navBg);
+}
- &.withWallpaper {
- .main {
- background: transparent;
- }
- }
+.nonTitlebarArea {
+ display: flex;
+ flex: 1;
}
.main {
@@ -240,7 +240,15 @@ if (prefer.s['deck.wallpaper'] != null) {
min-width: 0;
display: flex;
flex-direction: column;
- background: var(--MI_THEME-deckBg);
+
+ &:not(.withWallpaper) {
+ background: var(--MI_THEME-deckBg);
+ }
+
+ &.withSidebarAndTitlebar {
+ border-radius: 12px 0 0 0;
+ overflow: clip;
+ }
}
.columnsWrapper {