enhance(client): ノートのデザインを改善
This commit is contained in:
parent
32c31da489
commit
63afde0b10
|
@ -34,6 +34,7 @@
|
|||
- 토스트 알림의 배경이 불투명하게 표시되도록
|
||||
- 헤더의 배경이 불투명하게 표시되도록
|
||||
- MFM 도움말에 검색 섹션 추가
|
||||
- 노트 디자인 개선
|
||||
- Fix: (Friendly) 플로팅 메뉴를 길게 눌렀을 때 프로필 이미지를 드래그 할 수 있는 문제
|
||||
- Fix: (Friendly) 타임라인이 변경되었을 때 네비게이션 바의 인디케이터가 사라지지 않는 문제
|
||||
- Fix: 네트워크 트래픽이 10MB/s를 초과하면 네트워크 통계 위젯의 그래프가 잘못 출력되는 문제
|
||||
|
|
|
@ -41,49 +41,53 @@
|
|||
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :class="$style.collapsedRenoteTargetText" @click="renoteCollapsed = false"/>
|
||||
</div>
|
||||
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
||||
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
||||
<MkAvatar :class="[$style.avatar, { [$style.showEl]: showEl && mainRouter.currentRoute.value.name === 'index', [$style.showElTab]: showEl && mainRouter.currentRoute.value.name !== 'index' }]" :user="appearNote.user" link preview/>
|
||||
<div :class="$style.main">
|
||||
<MkNoteHeader :note="appearNote" :mini="true"/>
|
||||
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
||||
<div style="container-type: inline-size;">
|
||||
<p v-if="appearNote.cw != null" :class="$style.cw">
|
||||
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :i="$i"/>
|
||||
<MkCwButton v-model="showContent" :note="appearNote"/>
|
||||
</p>
|
||||
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
|
||||
<div :class="$style.text">
|
||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||
<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
<div v-if="translating || translation" :class="$style.translation">
|
||||
<MkLoading v-if="translating" mini/>
|
||||
<div v-else>
|
||||
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}:</b><hr style="margin: 10px 0;">
|
||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
<div v-if="translation.translator == 'ctav3'" style="margin-top: 10px; padding: 0 0 15px;">
|
||||
<img v-if="!defaultStore.state.darkMode" src="/client-assets/color-short.svg" alt="" style="float: right;">
|
||||
<img v-else src="/client-assets/white-short.svg" alt="" style="float: right;"/>
|
||||
<div style="display: flex; padding-bottom: 10px;">
|
||||
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
||||
<MkAvatar :class="[$style.avatar, { [$style.showEl]: showEl && mainRouter.currentRoute.value.name === 'index', [$style.showElTab]: showEl && mainRouter.currentRoute.value.name !== 'index' }]" :user="appearNote.user" link preview/>
|
||||
<div :class="$style.main">
|
||||
<MkNoteHeader :note="appearNote" :mini="true"/>
|
||||
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
||||
<div style="container-type: inline-size;">
|
||||
<p v-if="appearNote.cw != null" :class="$style.cw">
|
||||
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :i="$i"/>
|
||||
<MkCwButton v-model="showContent" :note="appearNote"/>
|
||||
</p>
|
||||
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
|
||||
<div :class="$style.text">
|
||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||
<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
<div v-if="translating || translation" :class="$style.translation">
|
||||
<MkLoading v-if="translating" mini/>
|
||||
<div v-else>
|
||||
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}:</b><hr style="margin: 10px 0;">
|
||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
<div v-if="translation.translator == 'ctav3'" style="margin-top: 10px; padding: 0 0 15px;">
|
||||
<img v-if="!defaultStore.state.darkMode" src="/client-assets/color-short.svg" alt="" style="float: right;">
|
||||
<img v-else src="/client-assets/white-short.svg" alt="" style="float: right;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appearNote.files.length > 0">
|
||||
<MkMediaList v-if="appearNote.disableRightClick" :mediaList="appearNote.files" @contextmenu.prevent/>
|
||||
<MkMediaList v-else :mediaList="appearNote.files"/>
|
||||
</div>
|
||||
<MkPoll v-if="appearNote.poll" :note="appearNote" :class="$style.poll"/>
|
||||
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
|
||||
<button v-if="(isLong || isMFM) && collapsed" :class="$style.collapsed" class="_button" @click="collapsed = false">
|
||||
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
<button v-else-if="(isLong || isMFM) && !collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
|
||||
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="appearNote.files.length > 0">
|
||||
<MkMediaList v-if="appearNote.disableRightClick" :mediaList="appearNote.files" @contextmenu.prevent/>
|
||||
<MkMediaList v-else :mediaList="appearNote.files"/>
|
||||
</div>
|
||||
<MkPoll v-if="appearNote.poll" :note="appearNote" :class="$style.poll"/>
|
||||
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
|
||||
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
|
||||
<button v-if="(isLong || isMFM) && collapsed" :class="$style.collapsed" class="_button" @click="collapsed = false">
|
||||
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
<button v-else-if="(isLong || isMFM) && !collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
|
||||
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
|
||||
</button>
|
||||
<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
|
||||
</div>
|
||||
<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
|
||||
<div style="padding-left: 10px">
|
||||
<MkReactionsViewer :note="appearNote" :maxNumber="16">
|
||||
<template #more>
|
||||
<button class="_button" :class="$style.reactionDetailsButton" @click="showReactions">
|
||||
|
@ -558,7 +562,7 @@ function showReactions(): void {
|
|||
.tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 32px 8px 32px;
|
||||
padding: 24px 38px 16px;
|
||||
line-height: 24px;
|
||||
font-size: 90%;
|
||||
white-space: pre;
|
||||
|
@ -578,7 +582,7 @@ function showReactions(): void {
|
|||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 32px 8px 32px;
|
||||
padding: 24px 38px 16px;
|
||||
line-height: 28px;
|
||||
white-space: pre;
|
||||
color: var(--renote);
|
||||
|
@ -636,7 +640,7 @@ function showReactions(): void {
|
|||
align-items: center;
|
||||
line-height: 28px;
|
||||
white-space: pre;
|
||||
padding: 0 32px 18px;
|
||||
padding: 8px 38px 24px;
|
||||
}
|
||||
|
||||
.collapsedRenoteTargetAvatar {
|
||||
|
@ -663,7 +667,6 @@ function showReactions(): void {
|
|||
|
||||
.article {
|
||||
position: relative;
|
||||
display: flex;
|
||||
padding: 28px 32px;
|
||||
}
|
||||
|
||||
|
@ -681,8 +684,8 @@ function showReactions(): void {
|
|||
flex-shrink: 0;
|
||||
display: block !important;
|
||||
margin: 0 14px 0 0;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: sticky !important;
|
||||
top: calc(22px + var(--stickyTop, 0px));
|
||||
left: 0;
|
||||
|
@ -776,8 +779,8 @@ function showReactions(): void {
|
|||
}
|
||||
|
||||
.quoteNote {
|
||||
padding: 16px;
|
||||
border: dashed 1px var(--renote);
|
||||
padding: 24px;
|
||||
border: solid 1px var(--renote);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
@ -816,17 +819,16 @@ function showReactions(): void {
|
|||
}
|
||||
|
||||
.renote {
|
||||
padding: 12px 26px 0 26px;
|
||||
padding: 24px 28px 16px;
|
||||
}
|
||||
|
||||
.collapsedRenoteTarget {
|
||||
padding: 8px 28px 24px;
|
||||
}
|
||||
|
||||
.article {
|
||||
padding: 24px 26px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 500px) {
|
||||
|
@ -834,12 +836,8 @@ function showReactions(): void {
|
|||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.renote {
|
||||
padding: 10px 22px 0 22px;
|
||||
}
|
||||
|
||||
.article {
|
||||
padding: 20px 22px;
|
||||
padding: 23px 25px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
|
@ -849,20 +847,20 @@ function showReactions(): void {
|
|||
|
||||
@container (max-width: 480px) {
|
||||
.renote {
|
||||
padding: 8px 16px 0 16px;
|
||||
padding: 20px 24px 8px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 8px 16px 0 16px;
|
||||
padding: 20px 24px 8px;
|
||||
}
|
||||
|
||||
.collapsedRenoteTarget {
|
||||
padding: 0 16px 9px;
|
||||
padding: 8px 24px 20px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.article {
|
||||
padding: 14px 16px;
|
||||
padding: 22px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
</div>
|
||||
<footer>
|
||||
<div :class="$style.noteFooterInfo">
|
||||
<MkA :to="notePage(appearNote)">
|
||||
<MkA :class="$style.time" :to="notePage(appearNote)">
|
||||
<MkTime :time="appearNote.createdAt" mode="detail"/>
|
||||
</MkA>
|
||||
</div>
|
||||
|
@ -607,8 +607,8 @@ if (appearNote.replyId) {
|
|||
}
|
||||
|
||||
.quoteNote {
|
||||
padding: 16px;
|
||||
border: dashed 1px var(--renote);
|
||||
padding: 24px;
|
||||
border: solid 1px var(--renote);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
@ -651,19 +651,27 @@ if (appearNote.replyId) {
|
|||
border-top: solid 0.5px var(--divider);
|
||||
}
|
||||
|
||||
.time {
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 500px) {
|
||||
.root {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 450px) {
|
||||
@container (max-width: 480px) {
|
||||
.renote {
|
||||
padding: 8px 16px 0 16px;
|
||||
}
|
||||
|
||||
.note {
|
||||
padding: 16px;
|
||||
padding: 22px 24px;
|
||||
}
|
||||
|
||||
.noteHeaderAvatar {
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
<template>
|
||||
<header :class="$style.root">
|
||||
<MkA v-user-preview="note.user.id" :class="$style.name" :to="userPage(note.user)">
|
||||
<MkUserName :user="note.user"/>
|
||||
</MkA>
|
||||
<div v-if="note.user.isBot" :class="$style.isBot">bot</div>
|
||||
<div :class="$style.username"><MkAcct :user="note.user"/></div>
|
||||
<div v-if="note.user.badgeRoles" :class="$style.badgeRoles">
|
||||
<img v-for="role in note.user.badgeRoles" :key="role.id" v-tooltip="role.name" :class="$style.badgeRole" :src="role.iconUrl"/>
|
||||
</div>
|
||||
<div :class="$style.info">
|
||||
<MkA :to="notePage(note)">
|
||||
<MkTime :time="note.createdAt"/>
|
||||
<div style="display: flex; align-items: baseline; white-space: nowrap;">
|
||||
<MkA v-user-preview="note.user.id" :class="$style.name" :to="userPage(note.user)">
|
||||
<MkUserName :user="note.user"/>
|
||||
</MkA>
|
||||
<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
|
||||
<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
|
||||
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
||||
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
||||
</span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
|
||||
<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
|
||||
<div v-if="note.user.isBot" :class="$style.isBot">bot</div>
|
||||
<div v-if="note.user.badgeRoles" :class="$style.badgeRoles">
|
||||
<img v-for="role in note.user.badgeRoles" :key="role.id" v-tooltip="role.name" :class="$style.badgeRole" :src="role.iconUrl"/>
|
||||
</div>
|
||||
<div :class="$style.info">
|
||||
<MkA :class="$style.time" :to="notePage(note)">
|
||||
<MkTime :time="note.createdAt"/>
|
||||
</MkA>
|
||||
<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
|
||||
<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
|
||||
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
||||
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
||||
</span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
|
||||
<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="$style.username"><MkAcct :user="note.user"/></div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
|
@ -38,9 +40,7 @@ defineProps<{
|
|||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
white-space: nowrap;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.name {
|
||||
|
@ -75,6 +75,7 @@ defineProps<{
|
|||
margin: 0 .5em 0 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: .95em;
|
||||
}
|
||||
|
||||
.info {
|
||||
|
@ -83,6 +84,14 @@ defineProps<{
|
|||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.time {
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.badgeRoles {
|
||||
margin: 0 .5em 0 0;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ if (props.detail) {
|
|||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
padding: 16px 32px;
|
||||
padding: 28px 32px;
|
||||
font-size: 0.9em;
|
||||
position: relative;
|
||||
|
||||
|
@ -88,9 +88,9 @@ if (props.detail) {
|
|||
.avatar {
|
||||
flex-shrink: 0;
|
||||
display: block;
|
||||
margin: 0 8px 0 0;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
margin: 0 14px 0 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
@ -125,13 +125,30 @@ if (props.detail) {
|
|||
padding: 10px 0 0 16px;
|
||||
}
|
||||
|
||||
@container (max-width: 450px) {
|
||||
@container (max-width: 580px) {
|
||||
.root {
|
||||
padding: 14px 16px;
|
||||
padding: 28px 26px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 500px) {
|
||||
.root {
|
||||
padding: 23px 25px;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 480px) {
|
||||
.root {
|
||||
padding: 22px 24px;
|
||||
|
||||
&.children {
|
||||
padding: 10px 0 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -80,7 +80,7 @@ watch([() => props.note.reactions, () => props.maxNumber], ([newSource, maxNumbe
|
|||
}
|
||||
|
||||
.root {
|
||||
margin: 10px -2px 0 -2px;
|
||||
margin: 10px -2px 10px -2px;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
Loading…
Reference in a new issue