Merge branch 'misskey-develop' into merge/2025-03-24
# Conflicts: # .github/workflows/api-misskey-js.yml # .github/workflows/changelog-check.yml # .github/workflows/check-misskey-js-autogen.yml # .github/workflows/get-api-diff.yml # .github/workflows/lint.yml # .github/workflows/locale.yml # .github/workflows/on-release-created.yml # .github/workflows/storybook.yml # .github/workflows/test-backend.yml # .github/workflows/test-federation.yml # .github/workflows/test-frontend.yml # .github/workflows/test-misskey-js.yml # .github/workflows/test-production.yml # .github/workflows/validate-api-json.yml # package.json # packages/backend/package.json # packages/backend/src/server/api/ApiCallService.ts # packages/backend/src/server/api/endpoints/drive/files/create.ts # packages/frontend-shared/js/url.ts # packages/frontend/package.json # packages/frontend/src/components/MkFileCaptionEditWindow.vue # packages/frontend/src/components/MkInfo.vue # packages/frontend/src/components/MkLink.vue # packages/frontend/src/components/MkNote.vue # packages/frontend/src/components/MkNotes.vue # packages/frontend/src/components/MkPageWindow.vue # packages/frontend/src/components/MkReactionsViewer.vue # packages/frontend/src/components/MkTimeline.vue # packages/frontend/src/components/MkUrlPreview.vue # packages/frontend/src/components/MkUserPopup.vue # packages/frontend/src/components/global/MkPageHeader.vue # packages/frontend/src/components/global/MkUrl.vue # packages/frontend/src/components/global/PageWithHeader.vue # packages/frontend/src/pages/about-misskey.vue # packages/frontend/src/pages/announcements.vue # packages/frontend/src/pages/antenna-timeline.vue # packages/frontend/src/pages/channel.vue # packages/frontend/src/pages/instance-info.vue # packages/frontend/src/pages/note.vue # packages/frontend/src/pages/page.vue # packages/frontend/src/pages/role.vue # packages/frontend/src/pages/tag.vue # packages/frontend/src/pages/timeline.vue # packages/frontend/src/pages/user-list-timeline.vue # packages/frontend/src/pages/user/followers.vue # packages/frontend/src/pages/user/following.vue # packages/frontend/src/pages/user/home.vue # packages/frontend/src/pages/user/index.vue # packages/frontend/src/ui/deck.vue # packages/misskey-js/generator/package.json # pnpm-lock.yaml # scripts/changelog-checker/package-lock.json # scripts/changelog-checker/package.json
This commit is contained in:
commit
9c301fa5aa
255 changed files with 4773 additions and 4085 deletions
|
|
@ -421,7 +421,7 @@ function getPointerEvents() {
|
|||
|
||||
#devTicker {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2147483647;
|
||||
color: #ff0;
|
||||
|
|
|
|||
|
|
@ -79,10 +79,9 @@ watch(rootEl, () => {
|
|||
.root {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 12px 12px max(12px, env(safe-area-inset-bottom, 0px)) 12px;
|
||||
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||
grid-gap: 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: var(--MI_THEME-navBg);
|
||||
|
|
@ -91,6 +90,16 @@ watch(rootEl, () => {
|
|||
}
|
||||
|
||||
.item {
|
||||
padding: 12px 0;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
&.post {
|
||||
.itemInner {
|
||||
background: linear-gradient(90deg, var(--MI_THEME-buttonGradateA), var(--MI_THEME-buttonGradateB));
|
||||
|
|
@ -112,7 +121,7 @@ watch(rootEl, () => {
|
|||
padding: 0;
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
max-width: 45px;
|
||||
max-width: 42px;
|
||||
margin: auto;
|
||||
align-content: center;
|
||||
border-radius: 100%;
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ function more() {
|
|||
display: inline-block;
|
||||
width: 38px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.wideInstanceIcon {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div :class="[$style.root, { [$style.iconOnly]: iconOnly }]">
|
||||
<div :class="$style.body">
|
||||
<div :class="$style.top">
|
||||
<div :class="$style.banner" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<button v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<img :src="instance.sidebarLogoUrl && !iconOnly ? instance.sidebarLogoUrl : instance.iconUrl || '/favicon.ico'" alt="" :class="instance.sidebarLogoUrl && !iconOnly ? $style.wideInstanceIcon : $style.instanceIcon" style="viewTransitionName: navbar-serverIcon;"/>
|
||||
</button>
|
||||
|
|
@ -183,12 +182,9 @@ function menuEdit() {
|
|||
}
|
||||
|
||||
.body {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
position: relative;
|
||||
width: var(--nav-icon-only-width);
|
||||
height: 100dvh;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
overflow-x: clip;
|
||||
|
|
@ -303,18 +299,6 @@ function menuEdit() {
|
|||
backdrop-filter: var(--MI-blur, blur(8px));
|
||||
}
|
||||
|
||||
.banner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
-webkit-mask-image: linear-gradient(0deg, rgba(0,0,0,0) 15%, rgba(0,0,0,0.75) 100%);
|
||||
mask-image: linear-gradient(0deg, rgba(0,0,0,0) 15%, rgba(0,0,0,0.75) 100%);
|
||||
}
|
||||
|
||||
.instance {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
|
@ -335,6 +319,7 @@ function menuEdit() {
|
|||
display: inline-block;
|
||||
width: 38px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.wideInstanceIcon {
|
||||
|
|
@ -566,6 +551,7 @@ function menuEdit() {
|
|||
display: inline-block;
|
||||
width: 30px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
|
|
|
|||
87
packages/frontend/src/ui/_common_/titlebar.vue
Normal file
87
packages/frontend/src/ui/_common_/titlebar.vue
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="$style.root">
|
||||
<div :class="$style.title">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/>
|
||||
<span :class="$style.instanceTitle">{{ instance.name ?? host }}</span>
|
||||
</div>
|
||||
<div :class="$style.controls">
|
||||
<span :class="$style.left">
|
||||
<button v-if="canBack" class="_button" :class="$style.button" @click="goBack"><i class="ti ti-arrow-left"></i></button>
|
||||
</span>
|
||||
<span :class="$style.right">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { host } from '@@/js/config.js';
|
||||
import { ref } from 'vue';
|
||||
import { instance } from '@/instance.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const canBack = ref(true);
|
||||
|
||||
function goBack() {
|
||||
window.history.back();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
--height: 36px;
|
||||
|
||||
background: var(--MI_THEME-navBg);
|
||||
height: var(--height);
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
height: var(--height);
|
||||
}
|
||||
|
||||
.controls {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: var(--height);
|
||||
}
|
||||
|
||||
.instanceIcon {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 5px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.instanceTitle {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
height: var(--height);
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -4,76 +4,80 @@ 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"
|
||||
>
|
||||
<Suspense>
|
||||
<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"
|
||||
/>
|
||||
<template #fallback>
|
||||
<MkLoading/>
|
||||
</template>
|
||||
</Suspense>
|
||||
</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"
|
||||
>
|
||||
<Suspense>
|
||||
<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"
|
||||
/>
|
||||
<template #fallback>
|
||||
<MkLoading/>
|
||||
</template>
|
||||
</Suspense>
|
||||
</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>
|
||||
|
||||
<XNavbarH v-if="!isMobile && prefer.r['deck.navbarPosition'].value === 'bottom'"/>
|
||||
|
||||
<XMobileFooterMenu v-if="isMobile" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
|
||||
</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'"/>
|
||||
|
||||
<XMobileFooterMenu v-if="isMobile" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
|
||||
</div>
|
||||
|
||||
<XCommon v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
|
||||
|
|
@ -87,6 +91,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';
|
||||
|
|
@ -216,30 +221,26 @@ 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;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.main {
|
||||
|
|
@ -247,7 +248,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 {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<div
|
||||
class="_forceShrinkSpacer"
|
||||
:class="[$style.root, { [$style.paged]: isMainColumn, [$style.naked]: naked, [$style.active]: active, [$style.draghover]: draghover, [$style.dragging]: dragging, [$style.dropready]: dropready, [$style.withWallpaper]: withWallpaper }]"
|
||||
@dragover.prevent.stop="onDragover"
|
||||
@dragleave="onDragleave"
|
||||
|
|
@ -53,7 +54,6 @@ import { DI } from '@/di.js';
|
|||
|
||||
provide('shouldHeaderThin', true);
|
||||
provide('shouldOmitHeaderTitle', true);
|
||||
provide(DI.forceSpacerMin, true);
|
||||
|
||||
const withWallpaper = prefer.s['deck.wallpaper'] != null;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,22 +4,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
-->
|
||||
|
||||
<template>
|
||||
<div :class="$style.root">
|
||||
<XSidebar v-if="!isMobile" :class="$style.sidebar" :showWidgetButton="!isDesktop" @widgetButtonClick="widgetsShowing = true"/>
|
||||
<div :class="[$style.root, { '_forceShrinkSpacer': deviceKind === 'smartphone' }]">
|
||||
<XTitlebar v-if="prefer.r.showTitlebar.value" style="flex-shrink: 0;"/>
|
||||
|
||||
<div :class="$style.contents" @contextmenu.stop="onContextmenu">
|
||||
<div>
|
||||
<XPreferenceRestore v-if="shouldSuggestRestoreBackup"/>
|
||||
<XAnnouncements v-if="$i"/>
|
||||
<XStatusBars :class="$style.statusbars"/>
|
||||
<div :class="$style.nonTitlebarArea">
|
||||
<XSidebar v-if="!isMobile" :class="$style.sidebar" :showWidgetButton="!isDesktop" @widgetButtonClick="widgetsShowing = true"/>
|
||||
|
||||
<div :class="[$style.contents, !isMobile && prefer.r.showTitlebar.value ? $style.withSidebarAndTitlebar : null]" @contextmenu.stop="onContextmenu">
|
||||
<div>
|
||||
<XPreferenceRestore v-if="shouldSuggestRestoreBackup"/>
|
||||
<XAnnouncements v-if="$i"/>
|
||||
<XStatusBars :class="$style.statusbars"/>
|
||||
</div>
|
||||
<StackingRouterView v-if="prefer.s['experimental.stackingRouterView']" :class="$style.content"/>
|
||||
<RouterView v-else :class="$style.content"/>
|
||||
<XMobileFooterMenu v-if="isMobile" ref="navFooter" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
|
||||
</div>
|
||||
<StackingRouterView v-if="prefer.s['experimental.stackingRouterView']" :class="$style.content"/>
|
||||
<RouterView v-else :class="$style.content"/>
|
||||
<XMobileFooterMenu v-if="isMobile" ref="navFooter" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
|
||||
</div>
|
||||
|
||||
<div v-if="isDesktop && !pageMetadata?.needWideArea" :class="$style.widgets">
|
||||
<XWidgets/>
|
||||
<div v-if="isDesktop && !pageMetadata?.needWideArea" :class="$style.widgets">
|
||||
<XWidgets/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<XCommon v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
|
||||
|
|
@ -34,6 +38,7 @@ import XCommon from './_common_/common.vue';
|
|||
import type { PageMetadata } from '@/page.js';
|
||||
import XMobileFooterMenu from '@/ui/_common_/mobile-footer-menu.vue';
|
||||
import XPreferenceRestore from '@/ui/_common_/PreferenceRestore.vue';
|
||||
import XTitlebar from '@/ui/_common_/titlebar.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { $i } from '@/i.js';
|
||||
|
|
@ -128,8 +133,15 @@ $widgets-hide-threshold: 1090px;
|
|||
height: 100dvh;
|
||||
overflow: clip;
|
||||
contain: strict;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--MI_THEME-navBg);
|
||||
}
|
||||
|
||||
.nonTitlebarArea {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
|
|
@ -142,7 +154,12 @@ $widgets-hide-threshold: 1090px;
|
|||
flex: 1;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
background: var(--MI_THEME-bg);
|
||||
|
||||
&.withSidebarAndTitlebar {
|
||||
background: var(--MI_THEME-navBg);
|
||||
border-radius: 12px 0 0 0;
|
||||
overflow: clip;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue