[chatui] Right-aligned times

This commit is contained in:
Derek 2024-03-17 20:03:16 -04:00
parent 832e49b29b
commit ac63accbed
2 changed files with 111 additions and 67 deletions
packages/frontend/src/ui/chat

View file

@ -1,21 +1,28 @@
<template>
<header class="dehvdgxo">
<MkA v-user-preview="note.user.id" class="name" :to="userPage(note.user)">
<MkUserName :user="note.user"/>
</MkA>
<span v-if="note.user.isBot" class="is-bot">bot</span>
<span class="username"><MkAcct :user="note.user"/></span>
<div class="info">
<MkA class="created-at" :to="notePage(note)">
<MkTime :time="note.createdAt"/>
<header :class="$style.root">
<div :class="$style.left">
<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'" class="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'" class="ti ti-mail"></i>
</span>
<span v-if="note.localOnly" class="localOnly"><i class="ti ti-rocket-off"></i></span>
<span v-if="note.channel" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
<span v-if="note.user.isBot" :class="$style.is-bot">bot</span>
<span :class="$style.username"><MkAcct :user="note.user"/></span>
<div v-if="note.user.badgeRoles" :class="$style.badgeRoles">
<img v-for="(role, i) in note.user.badgeRoles" :key="i" v-tooltip="role.name" :class="$style.badgeRole" :src="role.iconUrl!"/>
</div>
</div>
<div :class="$style.right">
<div :class="$style.info">
<span v-if="note.visibility !== 'public'">
<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'" class="ti ti-mail"></i>
</span>
<span v-if="note.localOnly" :class="$style.localOnly"><i class="ti ti-rocket-off"></i></span>
<span v-if="note.channel" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
<MkA :class="$style.createdAt" :to="notePage(note)">
<MkTime :time="note.createdAt" colored/>
</MkA>
</div>
</div>
</header>
</template>
@ -45,51 +52,69 @@ export default defineComponent({
});
</script>
<style lang="scss" scoped>
.dehvdgxo {
<style lang="scss" module>
.root {
display: flex;
width: 100%;
align-items: baseline;
white-space: nowrap;
font-size: 0.9em;
> .name {
display: block;
margin: 0 .5em 0 0;
padding: 0;
overflow: hidden;
font-size: 1em;
font-weight: bold;
text-decoration: none;
text-overflow: ellipsis;
&:hover {
text-decoration: underline;
}
.left {
display: flex;
margin-right: auto;
}
}
> .is-bot {
flex-shrink: 0;
align-self: center;
margin: 0 .5em 0 0;
padding: 1px 6px;
font-size: 80%;
border: solid 0.5px var(--divider);
border-radius: 3px;
.name {
display: block;
margin: 0 .5em 0 0;
padding: 0;
overflow: hidden;
font-size: 1em;
font-weight: bold;
text-decoration: none;
text-overflow: ellipsis;
&:hover {
text-decoration: underline;
}
}
> .username {
margin: 0 .5em 0 0;
overflow: hidden;
text-overflow: ellipsis;
.isBot {
flex-shrink: 0;
align-self: center;
margin: 0 .5em 0 0;
padding: 1px 6px;
font-size: 80%;
border: solid 0.5px var(--divider);
border-radius: 3px;
}
.username {
margin: 0 .5em 0 0;
overflow: hidden;
text-overflow: ellipsis;
}
.badgeRoles {
margin: 0 .5em 0 0;
}
.badgeRole {
height: 1.3em;
vertical-align: -20%;
& + .badgeRole {
margin-left: 0.2em;
}
}
> .info {
font-size: 0.9em;
opacity: 0.7;
.info {
opacity: 0.7;
> span {
margin-left: 8px;
}
> *:not(:last-child) {
margin-right: 8px;
}
}
</style>

View file

@ -19,6 +19,19 @@
<MkAvatar class="avatar" :user="note.user"/>
<i class="icon ti ti-repeat"></i>
<XSub class="note" :note="appearNote"/>
<div class="info">
<span v-if="note.visibility !== 'public'" class="visibility" :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" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
<span v-if="note.channel" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
<button ref="renoteTime" class="_button time" @click.stop="showRenoteMenu()">
<i class="ti ti-dots dropdownIcon"></i>
<MkTime :time="note.createdAt"/>
</button>
</div>
</div>
<div v-else-if="isRenote" class="header renote-header">
<MkAvatar class="avatar" :user="note.user"/>
@ -31,10 +44,6 @@
</template>
</I18n>
<div class="info">
<button ref="renoteTime" class="_button time" @click="showRenoteMenu()">
<i class="ti ti-dots dropdownIcon"></i>
<MkTime :time="note.createdAt"/>
</button>
<span v-if="note.visibility !== 'public'" class="visibility" :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>
@ -42,6 +51,10 @@
</span>
<span v-if="note.localOnly" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
<span v-if="note.channel" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
<button ref="renoteTime" class="_button time" @click="showRenoteMenu()">
<i class="ti ti-dots dropdownIcon"></i>
<MkTime :time="note.createdAt"/>
</button>
</div>
</div>
<article v-if="!renoteCollapsed" class="article" @contextmenu.stop="onContextmenu">
@ -82,7 +95,7 @@
<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
</div>
<MkReactionsViewer :note="appearNote"/>
<footer class="footer _panel">
<footer class="footer">
<button v-tooltip="i18n.ts.reply" class="button _button" @click="reply()">
<i class="ti ti-arrow-back-up"></i>
<p v-if="appearNote.repliesCount > 0" class="count">{{ appearNote.repliesCount }}</p>
@ -569,6 +582,10 @@ function emitUpdReaction(emoji: string, delta: number) {
&:hover, &.operating {
> .article > .main > .footer {
display: block;
opacity: 1;
}
&::before {
opacity: 0;
}
}
@ -577,17 +594,13 @@ function emitUpdReaction(emoji: string, delta: number) {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
opacity: 0.15;
z-index: -1;
background: var(--channelColor);
opacity: 0.15;
filter: saturate(75%);
transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);
}
&:hover::before {
opacity: 0;
}
&::after {
content: "";
position: absolute;
@ -673,7 +686,6 @@ function emitUpdReaction(emoji: string, delta: number) {
align-items: center;
line-height: 28px;
white-space: pre;
color: var(--renote);
> .avatar {
flex-shrink: 0;
@ -685,7 +697,6 @@ function emitUpdReaction(emoji: string, delta: number) {
}
> i {
color: var(--renote);
margin-right: 0.5em;
}
@ -699,11 +710,16 @@ function emitUpdReaction(emoji: string, delta: number) {
font-weight: bold;
}
}
}
> .renote-header, > .collapsed-renote {
color: var(--renote);
> .info {
margin-left: 8px;
margin-left: auto;
font-size: 0.9em;
opacity: 0.7;
white-space: nowrap;
> .time {
flex-shrink: 0;
@ -714,8 +730,8 @@ function emitUpdReaction(emoji: string, delta: number) {
}
}
> span {
margin-left: 8px;
> *:not(:last-child) {
margin-right: 8px;
}
}
}
@ -842,11 +858,14 @@ function emitUpdReaction(emoji: string, delta: number) {
> .footer {
display: none;
overflow: clip;
position: absolute;
top: 8px;
right: 8px;
padding: 0 6px;
bottom: 0px;
right: 0px;
padding: 2px 8px;
opacity: 0.7;
background: var(--panel);
border-top-left-radius: var(--radius);
&:hover {
opacity: 1;