enhance(frontend): データセーバーモードで隠れる画像を増やす等 (#11806)
* enhance datasaver mode * サムネイルがないとき変な角丸にならんようにする * Avoid using wildcard selector * Avoid wildcard * Update MkMediaImage.vue * (fix) ノートの画像プレビューがでない * (fix) recent pages design --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
		
							parent
							
								
									85078601c2
								
							
						
					
					
						commit
						c0838c473f
					
				
					 7 changed files with 87 additions and 43 deletions
				
			
		| 
						 | 
					@ -38,6 +38,7 @@
 | 
				
			||||||
- Enhance: ノート検索にローカルのみ検索可能なオプションの追加
 | 
					- Enhance: ノート検索にローカルのみ検索可能なオプションの追加
 | 
				
			||||||
- Enhance: AiScriptで`LOCALE`として現在の設定言語を取得できるように
 | 
					- Enhance: AiScriptで`LOCALE`として現在の設定言語を取得できるように
 | 
				
			||||||
- Enhance: Renote自体を通報できるように
 | 
					- Enhance: Renote自体を通報できるように
 | 
				
			||||||
 | 
					- Enhance: データセーバーモードの強化
 | 
				
			||||||
- Enhance: Renoteを管理者権限で削除可能に
 | 
					- Enhance: Renoteを管理者権限で削除可能に
 | 
				
			||||||
- `$[rainbow ]`記法が、動きのあるMFMが無効になっていても使用できるようになりました
 | 
					- `$[rainbow ]`記法が、動きのあるMFMが無効になっていても使用できるようになりました
 | 
				
			||||||
- Playの操作を行うAPI TokenをAPIコンソールから発行できるように
 | 
					- Playの操作を行うAPI TokenをAPIコンソールから発行できるように
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,33 +5,40 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div :class="hide ? $style.hidden : $style.visible" :style="darkMode ? '--c: rgb(255 255 255 / 2%);' : '--c: rgb(0 0 0 / 2%);'" @click="onclick">
 | 
					<div :class="hide ? $style.hidden : $style.visible" :style="darkMode ? '--c: rgb(255 255 255 / 2%);' : '--c: rgb(0 0 0 / 2%);'" @click="onclick">
 | 
				
			||||||
	<a
 | 
						<component
 | 
				
			||||||
		:class="$style.imageContainer"
 | 
							:is="disableImageLink ? 'div' : 'a'"
 | 
				
			||||||
		:href="image.url"
 | 
							v-bind="disableImageLink ? {
 | 
				
			||||||
		:title="image.name"
 | 
								title: image.name,
 | 
				
			||||||
 | 
								class: $style.imageContainer,
 | 
				
			||||||
 | 
							} : {
 | 
				
			||||||
 | 
								title: image.name,
 | 
				
			||||||
 | 
								class: $style.imageContainer,
 | 
				
			||||||
 | 
								href: image.url,
 | 
				
			||||||
 | 
								style: 'cursor: zoom-in;'
 | 
				
			||||||
 | 
							}"
 | 
				
			||||||
	>
 | 
						>
 | 
				
			||||||
		<ImgWithBlurhash
 | 
							<ImgWithBlurhash
 | 
				
			||||||
			:hash="image.blurhash"
 | 
								:hash="image.blurhash"
 | 
				
			||||||
			:src="(defaultStore.state.enableDataSaverMode && hide) ? null : url"
 | 
								:src="(defaultStore.state.enableDataSaverMode && hide) ? null : url"
 | 
				
			||||||
			:forceBlurhash="hide"
 | 
								:forceBlurhash="hide"
 | 
				
			||||||
			:cover="hide"
 | 
								:cover="hide || cover"
 | 
				
			||||||
			:alt="image.comment || image.name"
 | 
								:alt="image.comment || image.name"
 | 
				
			||||||
			:title="image.comment || image.name"
 | 
								:title="image.comment || image.name"
 | 
				
			||||||
			:width="image.properties.width"
 | 
								:width="image.properties.width"
 | 
				
			||||||
			:height="image.properties.height"
 | 
								:height="image.properties.height"
 | 
				
			||||||
			:style="hide ? 'filter: brightness(0.5);' : null"
 | 
								:style="hide ? 'filter: brightness(0.5);' : null"
 | 
				
			||||||
		/>
 | 
							/>
 | 
				
			||||||
	</a>
 | 
						</component>
 | 
				
			||||||
	<template v-if="hide">
 | 
						<template v-if="hide">
 | 
				
			||||||
		<div :class="$style.hiddenText">
 | 
							<div :class="$style.hiddenText">
 | 
				
			||||||
			<div :class="$style.hiddenTextWrapper">
 | 
								<div :class="$style.hiddenTextWrapper">
 | 
				
			||||||
				<b v-if="image.isSensitive" style="display: block;"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.enableDataSaverMode ? ` (${i18n.ts.image}${image.size ? ' ' + bytes(image.size) : ''})` : '' }}</b>
 | 
									<b v-if="image.isSensitive" style="display: block;"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.enableDataSaverMode ? ` (${i18n.ts.image}${image.size ? ' ' + bytes(image.size) : ''})` : '' }}</b>
 | 
				
			||||||
				<b v-else style="display: block;"><i class="ti ti-photo"></i> {{ defaultStore.state.enableDataSaverMode && image.size ? bytes(image.size) : i18n.ts.image }}</b>
 | 
									<b v-else style="display: block;"><i class="ti ti-photo"></i> {{ defaultStore.state.enableDataSaverMode && image.size ? bytes(image.size) : i18n.ts.image }}</b>
 | 
				
			||||||
				<span style="display: block;">{{ i18n.ts.clickToShow }}</span>
 | 
									<span v-if="controls" style="display: block;">{{ i18n.ts.clickToShow }}</span>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</template>
 | 
						</template>
 | 
				
			||||||
	<template v-else>
 | 
						<template v-else-if="controls">
 | 
				
			||||||
		<div :class="$style.indicators">
 | 
							<div :class="$style.indicators">
 | 
				
			||||||
			<div v-if="['image/gif', 'image/apng'].includes(image.type)" :class="$style.indicator">GIF</div>
 | 
								<div v-if="['image/gif', 'image/apng'].includes(image.type)" :class="$style.indicator">GIF</div>
 | 
				
			||||||
			<div v-if="image.comment" :class="$style.indicator">ALT</div>
 | 
								<div v-if="image.comment" :class="$style.indicator">ALT</div>
 | 
				
			||||||
| 
						 | 
					@ -54,10 +61,17 @@ import { i18n } from '@/i18n';
 | 
				
			||||||
import * as os from '@/os';
 | 
					import * as os from '@/os';
 | 
				
			||||||
import { iAmModerator } from '@/account';
 | 
					import { iAmModerator } from '@/account';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = withDefaults(defineProps<{
 | 
				
			||||||
	image: Misskey.entities.DriveFile;
 | 
						image: Misskey.entities.DriveFile;
 | 
				
			||||||
	raw?: boolean;
 | 
						raw?: boolean;
 | 
				
			||||||
}>();
 | 
						cover?: boolean;
 | 
				
			||||||
 | 
						disableImageLink?: boolean;
 | 
				
			||||||
 | 
						controls?: boolean;
 | 
				
			||||||
 | 
					}>(), {
 | 
				
			||||||
 | 
						cover: false,
 | 
				
			||||||
 | 
						disableImageLink: false,
 | 
				
			||||||
 | 
						controls: true,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let hide = $ref(true);
 | 
					let hide = $ref(true);
 | 
				
			||||||
let darkMode: boolean = $ref(defaultStore.state.darkMode);
 | 
					let darkMode: boolean = $ref(defaultStore.state.darkMode);
 | 
				
			||||||
| 
						 | 
					@ -70,6 +84,9 @@ const url = $computed(() => (props.raw || defaultStore.state.loadRawImages)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onclick() {
 | 
					function onclick() {
 | 
				
			||||||
 | 
						if (!props.controls) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (hide) {
 | 
						if (hide) {
 | 
				
			||||||
		hide = false;
 | 
							hide = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -117,6 +134,7 @@ function showMenu(ev: MouseEvent) {
 | 
				
			||||||
	display: flex;
 | 
						display: flex;
 | 
				
			||||||
	justify-content: center;
 | 
						justify-content: center;
 | 
				
			||||||
	align-items: center;
 | 
						align-items: center;
 | 
				
			||||||
 | 
						cursor: pointer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hide {
 | 
					.hide {
 | 
				
			||||||
| 
						 | 
					@ -167,7 +185,6 @@ function showMenu(ev: MouseEvent) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.imageContainer {
 | 
					.imageContainer {
 | 
				
			||||||
	display: block;
 | 
						display: block;
 | 
				
			||||||
	cursor: zoom-in;
 | 
					 | 
				
			||||||
	overflow: hidden;
 | 
						overflow: hidden;
 | 
				
			||||||
	width: 100%;
 | 
						width: 100%;
 | 
				
			||||||
	height: 100%;
 | 
						height: 100%;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<MkA :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj" tabindex="-1">
 | 
					<MkA :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj" tabindex="-1">
 | 
				
			||||||
	<div v-if="page.eyeCatchingImage" class="thumbnail" :style="`background-image: url('${page.eyeCatchingImage.thumbnailUrl}')`"></div>
 | 
						<div v-if="page.eyeCatchingImage" class="thumbnail">
 | 
				
			||||||
 | 
							<MediaImage
 | 
				
			||||||
 | 
								:image="page.eyeCatchingImage"
 | 
				
			||||||
 | 
								:disableImageLink="true"
 | 
				
			||||||
 | 
								:controls="false"
 | 
				
			||||||
 | 
								:cover="true"
 | 
				
			||||||
 | 
								:class="$style.eyeCatchingImageRoot"
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
	<article>
 | 
						<article>
 | 
				
			||||||
		<header>
 | 
							<header>
 | 
				
			||||||
			<h1 :title="page.title">{{ page.title }}</h1>
 | 
								<h1 :title="page.title">{{ page.title }}</h1>
 | 
				
			||||||
| 
						 | 
					@ -23,12 +31,22 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
import { } from 'vue';
 | 
					import { } from 'vue';
 | 
				
			||||||
import * as Misskey from 'misskey-js';
 | 
					import * as Misskey from 'misskey-js';
 | 
				
			||||||
import { userName } from '@/filters/user';
 | 
					import { userName } from '@/filters/user';
 | 
				
			||||||
 | 
					import MediaImage from '@/components/MkMediaImage.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = defineProps<{
 | 
				
			||||||
	page: Misskey.entities.Page;
 | 
						page: Misskey.entities.Page;
 | 
				
			||||||
}>();
 | 
					}>();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style module>
 | 
				
			||||||
 | 
					.eyeCatchingImageRoot {
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
						height: 200px;
 | 
				
			||||||
 | 
						border-radius: var(--radius) var(--radius) 0 0;
 | 
				
			||||||
 | 
						overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
.vhpxefrj {
 | 
					.vhpxefrj {
 | 
				
			||||||
	display: block;
 | 
						display: block;
 | 
				
			||||||
| 
						 | 
					@ -39,32 +57,15 @@ const props = defineProps<{
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	> .thumbnail {
 | 
						> .thumbnail {
 | 
				
			||||||
		width: 100%;
 | 
					 | 
				
			||||||
		height: 200px;
 | 
					 | 
				
			||||||
		background-position: center;
 | 
					 | 
				
			||||||
		background-size: cover;
 | 
					 | 
				
			||||||
		display: flex;
 | 
					 | 
				
			||||||
		justify-content: center;
 | 
					 | 
				
			||||||
		align-items: center;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		> button {
 | 
					 | 
				
			||||||
			font-size: 3.5em;
 | 
					 | 
				
			||||||
			opacity: 0.7;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:hover {
 | 
					 | 
				
			||||||
				font-size: 4em;
 | 
					 | 
				
			||||||
				opacity: 0.9;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		& + article {
 | 
							& + article {
 | 
				
			||||||
			left: 100px;
 | 
								border-radius: 0 0 var(--radius) var(--radius);
 | 
				
			||||||
			width: calc(100% - 100px);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	> article {
 | 
						> article {
 | 
				
			||||||
 | 
							background-color: var(--panel);
 | 
				
			||||||
		padding: 16px;
 | 
							padding: 16px;
 | 
				
			||||||
 | 
							border-radius: var(--radius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> header {
 | 
							> header {
 | 
				
			||||||
			margin-bottom: 8px;
 | 
								margin-bottom: 8px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<div v-else>
 | 
					<div v-else>
 | 
				
			||||||
	<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substring(local.length) : url" rel="nofollow noopener" :target="target" :title="url">
 | 
						<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substring(local.length) : url" rel="nofollow noopener" :target="target" :title="url">
 | 
				
			||||||
		<div v-if="thumbnail" :class="$style.thumbnail" :style="`background-image: url('${thumbnail}')`">
 | 
							<div v-if="thumbnail" :class="$style.thumbnail" :style="defaultStore.state.enableDataSaverMode ? '' : `background-image: url('${thumbnail}')`">
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<article :class="$style.body">
 | 
							<article :class="$style.body">
 | 
				
			||||||
			<header :class="$style.header">
 | 
								<header :class="$style.header">
 | 
				
			||||||
| 
						 | 
					@ -260,6 +260,7 @@ onUnmounted(() => {
 | 
				
			||||||
	height: 100%;
 | 
						height: 100%;
 | 
				
			||||||
	background-position: center;
 | 
						background-position: center;
 | 
				
			||||||
	background-size: cover;
 | 
						background-size: cover;
 | 
				
			||||||
 | 
						background-color: var(--bg);
 | 
				
			||||||
	display: flex;
 | 
						display: flex;
 | 
				
			||||||
	justify-content: center;
 | 
						justify-content: center;
 | 
				
			||||||
	align-items: center;
 | 
						align-items: center;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,20 +5,24 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div>
 | 
					<div>
 | 
				
			||||||
	<ImgWithBlurhash v-if="image" style="max-width: 100%;" :hash="image.blurhash" :src="image.url" :alt="image.comment" :title="image.comment" :width="image.properties.width" :height="image.properties.height" :cover="false"/>
 | 
						<MediaImage
 | 
				
			||||||
 | 
							v-if="image"
 | 
				
			||||||
 | 
							:image="image"
 | 
				
			||||||
 | 
							:disableImageLink="true"
 | 
				
			||||||
 | 
						/>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { } from 'vue';
 | 
					import { ref } from 'vue';
 | 
				
			||||||
import * as Misskey from 'misskey-js';
 | 
					import * as Misskey from 'misskey-js';
 | 
				
			||||||
import { ImageBlock } from './block.type';
 | 
					import { ImageBlock } from './block.type';
 | 
				
			||||||
import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
 | 
					import MediaImage from '@/components/MkMediaImage.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = defineProps<{
 | 
				
			||||||
	block: ImageBlock,
 | 
						block: ImageBlock,
 | 
				
			||||||
	page: Misskey.entities.Page,
 | 
						page: Misskey.entities.Page,
 | 
				
			||||||
}>();
 | 
					}>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const image = props.page.attachedFiles.find(x => x.id === props.block.fileId);
 | 
					const image = ref<Misskey.entities.DriveFile>(props.page.attachedFiles.find(x => x.id === props.block.fileId));
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
-->
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div :class="{ [$style.center]: page.alignCenter, [$style.serif]: page.font === 'serif' }">
 | 
					<div :class="{ [$style.center]: page.alignCenter, [$style.serif]: page.font === 'serif' }" class="_gaps_s">
 | 
				
			||||||
	<XBlock v-for="child in page.content" :key="child.id" :page="page" :block="child" :h="2"/>
 | 
						<XBlock v-for="child in page.content" :key="child.id" :page="page" :block="child" :h="2"/>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
				-->
 | 
									-->
 | 
				
			||||||
					<div class="banner">
 | 
										<div class="banner">
 | 
				
			||||||
						<img v-if="page.eyeCatchingImageId" :src="page.eyeCatchingImage.url"/>
 | 
											<MkMediaImage
 | 
				
			||||||
 | 
												v-if="page.eyeCatchingImageId"
 | 
				
			||||||
 | 
												:image="page.eyeCatchingImage"
 | 
				
			||||||
 | 
												:cover="true"
 | 
				
			||||||
 | 
												:disableImageLink="true"
 | 
				
			||||||
 | 
												class="thumbnail"
 | 
				
			||||||
 | 
											/>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div class="content">
 | 
										<div class="content">
 | 
				
			||||||
						<XPage :page="page"/>
 | 
											<XPage :page="page"/>
 | 
				
			||||||
| 
						 | 
					@ -56,8 +62,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
				<MkContainer :max-height="300" :foldable="true" class="other">
 | 
									<MkContainer :max-height="300" :foldable="true" class="other">
 | 
				
			||||||
					<template #icon><i class="ti ti-clock"></i></template>
 | 
										<template #icon><i class="ti ti-clock"></i></template>
 | 
				
			||||||
					<template #header>{{ i18n.ts.recentPosts }}</template>
 | 
										<template #header>{{ i18n.ts.recentPosts }}</template>
 | 
				
			||||||
					<MkPagination v-slot="{items}" :pagination="otherPostsPagination">
 | 
										<MkPagination v-slot="{items}" :pagination="otherPostsPagination" :class="$style.relatedPagesRoot" class="_gaps">
 | 
				
			||||||
						<MkPagePreview v-for="page in items" :key="page.id" :page="page" class="_margin"/>
 | 
											<MkPagePreview v-for="page in items" :key="page.id" :page="page" :class="$style.relatedPagesItem"/>
 | 
				
			||||||
					</MkPagination>
 | 
										</MkPagination>
 | 
				
			||||||
				</MkContainer>
 | 
									</MkContainer>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
| 
						 | 
					@ -74,6 +80,7 @@ import XPage from '@/components/page/page.vue';
 | 
				
			||||||
import MkButton from '@/components/MkButton.vue';
 | 
					import MkButton from '@/components/MkButton.vue';
 | 
				
			||||||
import * as os from '@/os';
 | 
					import * as os from '@/os';
 | 
				
			||||||
import { url } from '@/config';
 | 
					import { url } from '@/config';
 | 
				
			||||||
 | 
					import MkMediaImage from '@/components/MkMediaImage.vue';
 | 
				
			||||||
import MkFollowButton from '@/components/MkFollowButton.vue';
 | 
					import MkFollowButton from '@/components/MkFollowButton.vue';
 | 
				
			||||||
import MkContainer from '@/components/MkContainer.vue';
 | 
					import MkContainer from '@/components/MkContainer.vue';
 | 
				
			||||||
import MkPagination from '@/components/MkPagination.vue';
 | 
					import MkPagination from '@/components/MkPagination.vue';
 | 
				
			||||||
| 
						 | 
					@ -204,11 +211,14 @@ definePageMetadata(computed(() => page ? {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> .banner {
 | 
							> .banner {
 | 
				
			||||||
			> img {
 | 
								> .thumbnail {
 | 
				
			||||||
				// TODO: 良い感じのアスペクト比で表示
 | 
									// TODO: 良い感じのアスペクト比で表示
 | 
				
			||||||
				display: block;
 | 
									display: block;
 | 
				
			||||||
				width: 100%;
 | 
									width: 100%;
 | 
				
			||||||
				height: 150px;
 | 
									height: auto;
 | 
				
			||||||
 | 
									aspect-ratio: 3/1;
 | 
				
			||||||
 | 
									border-radius: var(--radius);
 | 
				
			||||||
 | 
									overflow: hidden;
 | 
				
			||||||
				object-fit: cover;
 | 
									object-fit: cover;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -279,3 +289,13 @@ definePageMetadata(computed(() => page ? {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style module>
 | 
				
			||||||
 | 
					.relatedPagesRoot {
 | 
				
			||||||
 | 
						padding: var(--margin);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.relatedPagesItem > article {
 | 
				
			||||||
 | 
						background-color: var(--panelHighlight) !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue