From e4fc9ea816eabba03933d9845ba0918b1ad365ab Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Sat, 4 Mar 2023 10:50:21 +0900 Subject: [PATCH] enhance(client): improve channel ui --- packages/frontend/src/pages/channel.vue | 161 ++++++++---------------- 1 file changed, 53 insertions(+), 108 deletions(-) diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index 81fc5ec877..d757e5b1a2 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -1,28 +1,23 @@ <template> <MkStickyContainer> <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> - <MkSpacer :content-max="700"> - <div v-if="channel && tab === 'timeline'" class="_gaps"> - <div class="wpgynlbz _panel" :class="{ hide: !showBanner }"> - <XChannelFollowButton :channel="channel" :full="true" class="subscribe"/> - <button class="_button toggle" @click="() => showBanner = !showBanner"> - <template v-if="showBanner"><i class="ti ti-chevron-up"></i></template> - <template v-else><i class="ti ti-chevron-down"></i></template> - </button> - <div v-if="!showBanner" class="hideOverlay"> - </div> - <div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" class="banner"> - <div class="status"> + <MkSpacer :content-max="700" :class="$style.main"> + <div v-if="channel && tab === 'overview'" class="_gaps"> + <div class="_panel" :class="$style.bannerContainer"> + <XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/> + <div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" :class="$style.banner"> + <div :class="$style.bannerStatus"> <div><i class="ti ti-users ti-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div> <div><i class="ti ti-pencil ti-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div> </div> - <div class="fade"></div> + <div :class="$style.bannerFade"></div> </div> - <div v-if="channel.description" class="description"> + <div v-if="channel.description" :class="$style.description"> <Mfm :text="channel.description" :is-note="false" :i="$i"/> </div> </div> - + </div> + <div v-if="channel && tab === 'timeline'" class="_gaps"> <!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる --> <MkPostForm v-if="$i && defaultStore.reactiveState.showFixedPostFormInChannel.value" :channel="channel" class="post-form _panel" fixed :autofocus="deviceKind === 'desktop'"/> @@ -68,7 +63,6 @@ const props = defineProps<{ let tab = $ref('timeline'); let channel = $ref(null); -let showBanner = $ref(true); const featuredPagination = $computed(() => ({ endpoint: 'notes/featured' as const, limit: 10, @@ -113,6 +107,10 @@ const headerActions = $computed(() => channel && channel.userId ? [{ }] : null); const headerTabs = $computed(() => [{ + key: 'overview', + title: i18n.ts.overview, + icon: 'ti ti-info-circle', +}, { key: 'timeline', title: i18n.ts.timeline, icon: 'ti ti-home', @@ -129,109 +127,56 @@ definePageMetadata(computed(() => channel ? { </script> <style lang="scss" module> +.main { + min-height: calc(var(--containerHeight) - (var(--stickyTop, 0px) + var(--stickyBottom, 0px))); +} + .footer { -webkit-backdrop-filter: var(--blur, blur(15px)); backdrop-filter: var(--blur, blur(15px)); border-top: solid 0.5px var(--divider); } -</style> -<style lang="scss" scoped> -.wpgynlbz { +.bannerContainer { position: relative; +} - > .subscribe { - position: absolute; - z-index: 1; - top: 16px; - left: 16px; - } +.subscribe { + position: absolute; + z-index: 1; + top: 16px; + left: 16px; +} - > .toggle { - position: absolute; - z-index: 2; - top: 8px; - right: 8px; - font-size: 1.2em; - width: 48px; - height: 48px; - color: #fff; - background: rgba(0, 0, 0, 0.5); - border-radius: 100%; - - > i { - vertical-align: middle; - } - } - - > .banner { - position: relative; - height: 200px; - background-position: center; - background-size: cover; +.banner { + position: relative; + height: 200px; + background-position: center; + background-size: cover; +} - > .fade { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 64px; - background: linear-gradient(0deg, var(--panel), var(--X15)); - } +.bannerFade { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 64px; + background: linear-gradient(0deg, var(--panel), var(--X15)); +} - > .status { - position: absolute; - z-index: 1; - bottom: 16px; - right: 16px; - padding: 8px 12px; - font-size: 80%; - background: rgba(0, 0, 0, 0.7); - border-radius: 6px; - color: #fff; - } - } +.bannerStatus { + position: absolute; + z-index: 1; + bottom: 16px; + right: 16px; + padding: 8px 12px; + font-size: 80%; + background: rgba(0, 0, 0, 0.7); + border-radius: 6px; + color: #fff; +} - > .description { - padding: 16px; - } - - > .hideOverlay { - position: absolute; - z-index: 1; - top: 0; - left: 0; - width: 100%; - height: 100%; - -webkit-backdrop-filter: var(--blur, blur(16px)); - backdrop-filter: var(--blur, blur(16px)); - background: rgba(0, 0, 0, 0.3); - } - - &.hide { - > .subscribe { - display: none; - } - - > .toggle { - top: 0; - right: 0; - height: 100%; - background: transparent; - } - - > .banner { - height: 42px; - filter: blur(8px); - - > * { - display: none; - } - } - - > .description { - display: none; - } - } +.description { + padding: 16px; } </style>