small fixes
This commit is contained in:
parent
936ca1a38c
commit
f4f9b3fa26
9 changed files with 642 additions and 445 deletions
|
@ -6,7 +6,8 @@ const Attachment = {
|
||||||
props: [
|
props: [
|
||||||
'attachment',
|
'attachment',
|
||||||
'nsfw',
|
'nsfw',
|
||||||
'statusId'
|
'statusId',
|
||||||
|
'size'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -29,6 +30,9 @@ const Attachment = {
|
||||||
},
|
},
|
||||||
isEmpty () {
|
isEmpty () {
|
||||||
return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'
|
return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'
|
||||||
|
},
|
||||||
|
isSmall () {
|
||||||
|
return this.size === 'small'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="attachment base03-border" :class="{[type]: true, loading}" v-show="!isEmpty">
|
<div v-if="size==='hide'">
|
||||||
|
<a class="placeholder" v-if="type !== 'html'" :href="attachment.url">[{{nsfw ? "NSFW/" : ""}}{{type.toUpperCase()}}]</a>
|
||||||
|
</div>
|
||||||
|
<div v-else class="attachment base03-border" :class="{[type]: true, loading, 'small-attachment': isSmall}" v-show="!isEmpty">
|
||||||
<a class="image-attachment" v-if="hidden" @click.prevent="toggleHidden()">
|
<a class="image-attachment" v-if="hidden" @click.prevent="toggleHidden()">
|
||||||
<img :key="nsfwImage" :src="nsfwImage"/>
|
<img :key="nsfwImage" :src="nsfwImage"/>
|
||||||
</a>
|
</a>
|
||||||
|
@ -8,10 +11,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a v-if="type === 'image' && !hidden" class="image-attachment" :href="attachment.url" target="_blank">
|
<a v-if="type === 'image' && !hidden" class="image-attachment" :href="attachment.url" target="_blank">
|
||||||
<StillImage class="base03-border" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
|
<StillImage :class="{'small': isSmall}" class="base03-border" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<video class="base03" v-if="type === 'video' && !hidden" :src="attachment.url" controls loop></video>
|
<video :class="{'small': isSmall}" class="base03" v-if="type === 'video' && !hidden" :src="attachment.url" controls loop></video>
|
||||||
|
|
||||||
<audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
|
<audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
|
||||||
|
|
||||||
|
@ -41,6 +44,17 @@
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small-attachment {
|
||||||
|
&.image, &.video {
|
||||||
|
max-width: 35%;
|
||||||
|
}
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.attachment {
|
.attachment {
|
||||||
flex: 1 0 30%;
|
flex: 1 0 30%;
|
||||||
margin: 0.5em 0.7em 0.6em 0.0em;
|
margin: 0.5em 0.7em 0.6em 0.0em;
|
||||||
|
@ -50,7 +64,7 @@
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
}
|
||||||
// fixes small gap below video
|
// fixes small gap below video
|
||||||
&.video {
|
&.video {
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
@ -75,6 +89,9 @@
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
video {
|
video {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -122,7 +139,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.image-attachment {
|
.image-attachment {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
|
@ -131,6 +148,12 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
img {
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -140,5 +163,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="timeline">
|
<div class="timeline">
|
||||||
<status v-for="status in conversation" @goto="setHighlight" :key="status.id" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true' :highlight="highlight" :replies="getReplies(status.id)"></status>
|
<status v-for="status in conversation" @goto="setHighlight" :key="status.id" :inlineExpanded="collapsable" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true' :highlight="highlight" :replies="getReplies(status.id)"></status>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import Status from '../status/status.vue'
|
import Status from '../status/status.vue'
|
||||||
import StillImage from '../still-image/still-image.vue'
|
import StillImage from '../still-image/still-image.vue'
|
||||||
|
import UserCardContent from '../user_card_content/user_card_content.vue'
|
||||||
|
|
||||||
import { sortBy, take, filter } from 'lodash'
|
import { sortBy, take, filter } from 'lodash'
|
||||||
|
|
||||||
const Notifications = {
|
const Notifications = {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
visibleNotificationCount: 10
|
visibleNotificationCount: 10,
|
||||||
|
userExpanded: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -24,15 +26,10 @@ const Notifications = {
|
||||||
},
|
},
|
||||||
unseenCount () {
|
unseenCount () {
|
||||||
return this.unseenNotifications.length
|
return this.unseenNotifications.length
|
||||||
},
|
|
||||||
hiderStyle () {
|
|
||||||
return {
|
|
||||||
background: `linear-gradient(to bottom, rgba(0, 0, 0, 0), ${this.$store.state.config.colors['base00']} 80%)`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Status, StillImage
|
Status, StillImage, UserCardContent
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
unseenCount (count) {
|
unseenCount (count) {
|
||||||
|
@ -46,6 +43,9 @@ const Notifications = {
|
||||||
methods: {
|
methods: {
|
||||||
markAsSeen () {
|
markAsSeen () {
|
||||||
this.$store.commit('markNotificationsAsSeen', this.visibleNotifications)
|
this.$store.commit('markNotificationsAsSeen', this.visibleNotifications)
|
||||||
|
},
|
||||||
|
toggleUserExpanded () {
|
||||||
|
this.userExpanded = !this.userExpanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,22 +30,52 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification {
|
.notification {
|
||||||
// Will have to use pixels here to ensure consistent distance with
|
padding-left: 4px;
|
||||||
// pad alone and pad + border, browsers bad at rounding this with em,
|
box-sizing: border-box;
|
||||||
// they love to give a 1 pixel ghost offset with 0.7em vs 0.3em + 0.4em,
|
|
||||||
// which does not happen with 10px vs 4px + 6px.
|
|
||||||
padding: 0.4em 0 0 10px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
border-bottom-color: inherit;
|
border-bottom-color: inherit;
|
||||||
|
|
||||||
|
.non-mention {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding: 0.6em;
|
||||||
|
.status-el {
|
||||||
|
padding: 0;
|
||||||
|
.status-content.media-body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.text {
|
.status-el {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-right {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-details {
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
line-height:18px;
|
line-height:18px;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5em;
|
||||||
|
flex: 1;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
.timeago {
|
||||||
|
float: right;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-retweet.lit {
|
.icon-retweet.lit {
|
||||||
color: $green;
|
color: $green;
|
||||||
|
@ -79,7 +109,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
padding: 0.3em 0.8em 0.5em;
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
@ -87,29 +116,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
|
||||||
margin-top: 0.3em;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: 0;
|
|
||||||
|
|
||||||
&.animated::before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover .animated.avatar {
|
|
||||||
canvas {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-radius: 0 0 10px 10px;
|
border-radius: 0 0 10px 10px;
|
||||||
|
@ -135,6 +141,35 @@
|
||||||
|
|
||||||
.unseen {
|
.unseen {
|
||||||
border-left: 4px solid rgba(255, 16, 8, 0.75);
|
border-left: 4px solid rgba(255, 16, 8, 0.75);
|
||||||
padding-left: 6px;
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
.avatar-compact {
|
||||||
|
margin-top: 0.3em;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
&.animated::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .animated.avatar {
|
||||||
|
canvas {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-usercard {
|
||||||
|
margin-left: 0.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,46 +8,32 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body base03-border">
|
<div class="panel-body base03-border">
|
||||||
<div v-for="notification in visibleNotifications" :key="notification" class="notification" :class='{"unseen": !notification.seen}'>
|
<div v-for="notification in visibleNotifications" :key="notification" class="notification" :class='{"unseen": !notification.seen}'>
|
||||||
<div>
|
<status v-if="notification.type === 'mention'" :compact="true" :statusoid="notification.status"></status>
|
||||||
<a :href="notification.action.user.statusnet_profile_url" target="_blank">
|
<div class="non-mention" v-else>
|
||||||
<StillImage class='avatar' :src="notification.action.user.profile_image_url_original"/>
|
<a :href="notification.action.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||||
|
<StillImage class='avatar-compact' :src="notification.action.user.profile_image_url_original"/>
|
||||||
</a>
|
</a>
|
||||||
|
<div class='notification-right'>
|
||||||
|
<div class="base03-border usercard" v-if="userExpanded">
|
||||||
|
<user-card-content :user="notification.action.user" :switcher="false"></user-card-content>
|
||||||
</div>
|
</div>
|
||||||
<div class='text' style="width: 100%;">
|
<span class="notification-details">
|
||||||
<div v-if="notification.type === 'favorite'">
|
<span class="username" :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
||||||
<h1>
|
<span v-if="notification.type === 'favorite'">
|
||||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
|
||||||
<i class="fa icon-star lit"></i>
|
<i class="fa icon-star lit"></i>
|
||||||
<small><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
<small>{{$t('notifications.favorited_you')}}</small>
|
||||||
</h1>
|
</span>
|
||||||
<div class="notification-gradient" :style="hiderStyle"></div>
|
<span v-if="notification.type === 'repeat'">
|
||||||
<div class="notification-content" v-html="notification.status.statusnet_html"></div>
|
|
||||||
</div>
|
|
||||||
<div v-if="notification.type === 'repeat'">
|
|
||||||
<h1>
|
|
||||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
|
||||||
<i class="fa icon-retweet lit"></i>
|
<i class="fa icon-retweet lit"></i>
|
||||||
<small><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
<small>{{$t('notifications.repeated_you')}}</small>
|
||||||
</h1>
|
</span>
|
||||||
<div class="notification-gradient" :style="hiderStyle"></div>
|
<span v-if="notification.type === 'follow'">
|
||||||
<div class="notification-content" v-html="notification.status.statusnet_html"></div>
|
|
||||||
</div>
|
|
||||||
<div v-if="notification.type === 'mention'">
|
|
||||||
<h1>
|
|
||||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
|
||||||
<i class="fa icon-reply lit"></i>
|
|
||||||
<small><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
|
||||||
</h1>
|
|
||||||
<status :compact="true" :statusoid="notification.status"></status>
|
|
||||||
</div>
|
|
||||||
<div v-if="notification.type === 'follow'">
|
|
||||||
<h1>
|
|
||||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
|
||||||
<i class="fa icon-user-plus lit"></i>
|
<i class="fa icon-user-plus lit"></i>
|
||||||
</h1>
|
<small>{{$t('notifications.followed_you')}}</small>
|
||||||
<div>
|
</span>
|
||||||
<router-link :to="{ name: 'user-profile', params: { id: notification.action.user.id } }">@{{ notification.action.user.screen_name }}</router-link> {{$t('notifications.followed_you')}}
|
<small class="timeago"><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
||||||
</div>
|
</span>
|
||||||
|
<status class="base04" :compact="true" :statusoid="notification.status" :noHeading="true"></status>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import StillImage from '../still-image/still-image.vue'
|
||||||
import { filter, find } from 'lodash'
|
import { filter, find } from 'lodash'
|
||||||
|
|
||||||
const Status = {
|
const Status = {
|
||||||
|
name: 'Status',
|
||||||
props: [
|
props: [
|
||||||
'statusoid',
|
'statusoid',
|
||||||
'expandable',
|
'expandable',
|
||||||
|
@ -15,7 +16,10 @@ const Status = {
|
||||||
'focused',
|
'focused',
|
||||||
'highlight',
|
'highlight',
|
||||||
'compact',
|
'compact',
|
||||||
'replies'
|
'replies',
|
||||||
|
'noReplyLinks',
|
||||||
|
'noHeading',
|
||||||
|
'inlineExpanded'
|
||||||
],
|
],
|
||||||
data: () => ({
|
data: () => ({
|
||||||
replying: false,
|
replying: false,
|
||||||
|
@ -23,7 +27,8 @@ const Status = {
|
||||||
unmuted: false,
|
unmuted: false,
|
||||||
userExpanded: false,
|
userExpanded: false,
|
||||||
preview: null,
|
preview: null,
|
||||||
showPreview: false
|
showPreview: false,
|
||||||
|
showingTall: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
muteWords () {
|
muteWords () {
|
||||||
|
@ -69,6 +74,35 @@ const Status = {
|
||||||
}
|
}
|
||||||
// use conversation highlight only when in conversation
|
// use conversation highlight only when in conversation
|
||||||
return this.status.id === this.highlight
|
return this.status.id === this.highlight
|
||||||
|
},
|
||||||
|
// This is a bit hacky, but we want to approximate post height before rendering
|
||||||
|
// so we count newlines (masto uses <p> for paragraphs, GS uses <br> between them)
|
||||||
|
// as well as approximate line count by counting characters and approximating ~80
|
||||||
|
// per line.
|
||||||
|
//
|
||||||
|
// Using max-height + overflow: auto for status components resulted in false positives
|
||||||
|
// very often with japanese characters, and it was very annoying.
|
||||||
|
hideTallStatus () {
|
||||||
|
if (this.showingTall) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const lengthScore = this.status.statusnet_html.split(/<p|<br/).length + this.status.text.length / 80
|
||||||
|
return lengthScore > 20
|
||||||
|
},
|
||||||
|
hiderStyle () {
|
||||||
|
const index = this.focused || this.inConversation || this.status.id === this.highlight ? 'base01' : 'base00'
|
||||||
|
return {
|
||||||
|
background: `linear-gradient(to bottom, rgba(0, 0, 0, 0), ${this.$store.state.config.colors[index]} 60%)`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attachmentSize () {
|
||||||
|
if ((this.$store.state.config.hideAttachments && !this.inConversation) ||
|
||||||
|
(this.$store.state.config.hideAttachmentsInConv && this.inConversation)) {
|
||||||
|
return 'hide'
|
||||||
|
} else if (this.compact) {
|
||||||
|
return 'small'
|
||||||
|
}
|
||||||
|
return 'normal'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -107,6 +141,9 @@ const Status = {
|
||||||
toggleUserExpanded () {
|
toggleUserExpanded () {
|
||||||
this.userExpanded = !this.userExpanded
|
this.userExpanded = !this.userExpanded
|
||||||
},
|
},
|
||||||
|
toggleShowTall () {
|
||||||
|
this.showingTall = !this.showingTall
|
||||||
|
},
|
||||||
replyEnter (id, event) {
|
replyEnter (id, event) {
|
||||||
this.showPreview = true
|
this.showPreview = true
|
||||||
const targetId = Number(id)
|
const targetId = Number(id)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<template>
|
<!--<template>
|
||||||
<div class="status-el base00-background" v-if="compact">
|
<div class="status-el base00-background" v-if="compact">
|
||||||
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
|
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
|
||||||
<div v-if="loggedIn">
|
<div v-if="loggedIn">
|
||||||
|
@ -124,44 +124,142 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="status-el base00-background base03-border" :class="[{ 'base01-background': isFocused }, { 'status-conversation': inlineExpanded }]">
|
||||||
|
<template v-if="muted && !noReplyLinks">
|
||||||
|
<div class="media status container muted">
|
||||||
|
<small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small>
|
||||||
|
<small class="muteWords">{{muteWordHits.join(', ')}}</small>
|
||||||
|
<a href="#" class="unmute" @click.prevent="toggleMute"><i class="base09 icon-eye-off"></i></a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div v-if="retweet && !noHeading" class="media container retweet-info">
|
||||||
|
<StillImage v-if="retweet" class='avatar' :src="statusoid.user.profile_image_url_original"/>
|
||||||
|
<div class="media-body base04">
|
||||||
|
<a :href="statusoid.user.statusnet_profile_url" style="font-weight: bold;" :title="'@'+statusoid.user.screen_name">{{retweeter}}</a>
|
||||||
|
<i class='fa icon-retweet retweeted'></i>
|
||||||
|
{{$t('timeline.repeated')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="media status">
|
||||||
|
<div v-if="!noHeading" class="media-left">
|
||||||
|
<a :href="status.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||||
|
<StillImage class='avatar' :class="{'avatar-compact': compact}" :src="status.user.profile_image_url_original"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="status-body">
|
||||||
|
<div class="base03-border usercard media-body" v-if="userExpanded">
|
||||||
|
<user-card-content :user="status.user" :switcher="false"></user-card-content>
|
||||||
|
</div>
|
||||||
|
<div v-if="!noHeading" class="media-body container">
|
||||||
|
<div class="media-heading-left">
|
||||||
|
<div class="name-and-links">
|
||||||
|
<h4 class="user-name">{{status.user.name}}</h4>
|
||||||
|
<span class="links">
|
||||||
|
<router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link>
|
||||||
|
<span v-if="status.in_reply_to_screen_name"> >
|
||||||
|
<router-link :to="{ name: 'user-profile', params: { id: status.in_reply_to_user_id } }">
|
||||||
|
{{status.in_reply_to_screen_name}}
|
||||||
|
</router-link>
|
||||||
|
</span>
|
||||||
|
<a v-if="isReply && !noReplyLinks" href="#" @click.prevent="gotoOriginal(status.in_reply_to_status_id)">
|
||||||
|
<i class="icon-reply base09" @mouseenter="replyEnter(status.in_reply_to_status_id, $event)" @mouseout="replyLeave()"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="replies" v-if="inConversation && !noReplyLinks">
|
||||||
|
<small v-if="replies.length">Replies:</small>
|
||||||
|
<small class="reply-link" v-for="reply in replies">
|
||||||
|
<a href="#" @click.prevent="gotoOriginal(reply.id)" @mouseenter="replyEnter(reply.id, $event)" @mouseout="replyLeave()">{{reply.name}} </a>
|
||||||
|
</small>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="media-heading-right">
|
||||||
|
<router-link class="timeago" :to="{ name: 'conversation', params: { id: status.id } }">
|
||||||
|
<timeago :since="status.created_at" :auto-update="60"></timeago>
|
||||||
|
</router-link>
|
||||||
|
<a :href="status.external_url" target="_blank" v-if="!status.is_local" class="source_url"><i class="base09 icon-binoculars"></i></a>
|
||||||
|
<template v-if="expandable">
|
||||||
|
<a href="#" @click.prevent="toggleExpanded"><i class="base09 icon-plus-squared"></i></a>
|
||||||
|
</template>
|
||||||
|
<a href="#" @click.prevent="toggleMute" v-if="unmuted"><i class="base09 icon-eye-off"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="showPreview" class="status-preview-container">
|
||||||
|
<status class="status-preview" v-if="preview" :noReplyLinks="true" :statusoid="preview" :compact=true></status>
|
||||||
|
<div class="status-preview status-preview-loading base00-background base03-border" v-else>
|
||||||
|
<i class="base09 icon-spin4 animate-spin"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div :class="{'tall-status': hideTallStatus}" class="status-content-wrapper">
|
||||||
|
<a class="tall-status-hider" :style="hiderStyle" v-if="hideTallStatus" href="#" @click.prevent="toggleShowTall">Show more</a>
|
||||||
|
<div @click.prevent="linkClicked" class="status-content media-body" v-html="status.statusnet_html"></div>
|
||||||
|
<a v-if="showingTall" href="#" class="tall-status-unhider" @click.prevent="toggleShowTall">Show less</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if='status.attachments' class='attachments media-body'>
|
||||||
|
<attachment :size="attachmentSize" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments" :key="attachment.id">
|
||||||
|
</attachment>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!noHeading && !noReplyLinks" class='status-actions media-body'>
|
||||||
|
<div v-if="loggedIn">
|
||||||
|
<a href="#" v-on:click.prevent="toggleReplying">
|
||||||
|
<i class="base09 icon-reply" :class="{'icon-reply-active': replying}"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<retweet-button :loggedIn='loggedIn' :status='status'></retweet-button>
|
||||||
|
<favorite-button :loggedIn='loggedIn' :status='status'></favorite-button>
|
||||||
|
<delete-button :status='status'></delete-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container" v-if="replying">
|
||||||
|
<div class="reply-left"/>
|
||||||
|
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script src="./status.js" ></script>
|
<script src="./status.js" ></script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
status-text-container {
|
.status-body {
|
||||||
display: block;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-preview.status-el {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-preview-container {
|
||||||
|
position: relative;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-preview {
|
.status-preview {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
max-width: 34em;
|
max-width: 95%;
|
||||||
padding: 0.5em;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
border-color: inherit;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
|
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
|
.status {
|
||||||
.avatar {
|
flex: 1;
|
||||||
flex-shrink: 0;
|
border: 0;
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
.text {
|
|
||||||
h4 {
|
|
||||||
margin-bottom: 0.4em;
|
|
||||||
small {
|
|
||||||
font-weight: lighter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
padding: 0 0.5em 0.5em 0.5em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +267,10 @@
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
min-width: 8em;
|
min-width: 8em;
|
||||||
|
padding: 0.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-el {
|
.status-el {
|
||||||
|
@ -179,58 +280,64 @@
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
border-left-width: 0px;
|
border-left-width: 0px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
.timeline & {
|
.timeline & {
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notify {
|
|
||||||
.avatar {
|
|
||||||
border-width: 3px;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-body {
|
.media-body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding-left: 0.5em;
|
padding: 0;
|
||||||
|
margin: 0 0 0.25em 0.8em;
|
||||||
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-heading-left {
|
||||||
.user-content {
|
padding: 0;
|
||||||
|
vertical-align: bottom;
|
||||||
min-height: 52px;
|
flex-basis: 100%;
|
||||||
padding-top: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-heading {
|
|
||||||
display: flex;
|
|
||||||
min-height: 1.4em;
|
|
||||||
margin-bottom: 0.3em;
|
|
||||||
|
|
||||||
small {
|
small {
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
}
|
}
|
||||||
h4 {
|
h4 {
|
||||||
margin-right: 0.4em;
|
font-size: 14px;
|
||||||
|
margin-right: 0.25em;
|
||||||
}
|
}
|
||||||
.name-and-links {
|
.name-and-links {
|
||||||
|
padding: 0;
|
||||||
flex: 1 0;
|
flex: 1 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
.links {
|
||||||
|
padding-top: 1px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
.replies {
|
.replies {
|
||||||
flex-basis: 100%;
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
.reply-link {
|
||||||
|
margin-right: 0.2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.source_url {
|
.media-heading-right {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
max-height: 1.5em;
|
||||||
|
margin-left: 0.25em;
|
||||||
|
.timeago {
|
||||||
|
margin-right: 0.2em;
|
||||||
|
font-size: 12px;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
margin-left: 0.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expand {
|
|
||||||
margin-right: -0.3em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -238,12 +345,29 @@
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-content {
|
.tall-status {
|
||||||
margin: 3px 15px 4px 0;
|
position: relative;
|
||||||
max-height: 400px;
|
height: 220px;
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tall-status-hider {
|
||||||
|
position: absolute;
|
||||||
|
height: 70px;
|
||||||
|
margin-top: 150px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tall-status-unhider {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-content {
|
||||||
|
margin-right: 0.5em;
|
||||||
img, video {
|
img, video {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
|
@ -255,33 +379,27 @@
|
||||||
margin: 0.2em 0 0.2em 2em;
|
margin: 0.2em 0 0.2em 2em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: 0.2em;
|
margin-top: 0.2em;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-left {
|
|
||||||
margin: 0.2em 0.3em 0 0;
|
|
||||||
.avatar {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.retweet-info {
|
.retweet-info {
|
||||||
padding: 0.7em 0 0 0.6em;
|
padding: 0.3em 0.6em 0 0.6em;
|
||||||
|
margin: 0 0 -0.3em 0;
|
||||||
.media-left {
|
.avatar {
|
||||||
display: flex;
|
margin-left: 28px;
|
||||||
|
width: 20px;
|
||||||
i {
|
height: 20px;
|
||||||
align-self: center;
|
border-radius: 5px;
|
||||||
text-align: right;
|
|
||||||
flex: 1;
|
|
||||||
padding-right: 0.3em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-body {
|
||||||
|
font-size: 1em;
|
||||||
|
line-height: 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,11 +427,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-actions {
|
.status-actions {
|
||||||
padding-top: 0.15em;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
div, favorite-button {
|
div, favorite-button {
|
||||||
|
padding-top: 0.25em;
|
||||||
max-width: 6em;
|
max-width: 6em;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
@ -327,11 +445,18 @@
|
||||||
color: $blue;
|
color: $blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status .avatar {
|
.status .avatar-compact {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -343,10 +468,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.retweeted {
|
&.retweeted {
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,12 +488,9 @@
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status.compact .avatar {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
padding: 0.4em 0.7em 0.45em 0.7em;
|
display: flex;
|
||||||
|
padding: 0.6em;
|
||||||
border-left: 4px rgba(255, 48, 16, 0.65);
|
border-left: 4px rgba(255, 48, 16, 0.65);
|
||||||
border-left-style: inherit;
|
border-left-style: inherit;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +505,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.muted {
|
.muted {
|
||||||
padding: 0.1em 0.4em 0.1em 0.8em;
|
padding: 0.25em 0.5em;
|
||||||
button {
|
button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
@ -413,8 +531,10 @@
|
||||||
|
|
||||||
@media all and (max-width: 960px) {
|
@media all and (max-width: 960px) {
|
||||||
.status-el {
|
.status-el {
|
||||||
.name-and-links {
|
.retweet-info {
|
||||||
margin-left: -0.25em;
|
.avatar {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.status {
|
.status {
|
||||||
|
@ -424,21 +544,6 @@
|
||||||
.status .avatar {
|
.status .avatar {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
||||||
&.retweeted {
|
|
||||||
width: 34px;
|
|
||||||
height: 34px;
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status .avatar-retweeter {
|
|
||||||
width: 22px;
|
|
||||||
height: 22px;
|
|
||||||
position: absolute;
|
|
||||||
margin-left: 18px;
|
|
||||||
margin-top: 18px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,9 @@ const fi = {
|
||||||
error_fetching: 'Virhe ladatessa viestejä',
|
error_fetching: 'Virhe ladatessa viestejä',
|
||||||
up_to_date: 'Ajantasalla',
|
up_to_date: 'Ajantasalla',
|
||||||
load_older: 'Lataa vanhempia viestejä',
|
load_older: 'Lataa vanhempia viestejä',
|
||||||
conversation: 'Keskustelu'
|
conversation: 'Keskustelu',
|
||||||
|
collapse: 'Sulje',
|
||||||
|
repeated: 'toisti'
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
user_settings: 'Käyttäjän asetukset',
|
user_settings: 'Käyttäjän asetukset',
|
||||||
|
@ -160,7 +162,9 @@ const fi = {
|
||||||
notifications: {
|
notifications: {
|
||||||
notifications: 'Ilmoitukset',
|
notifications: 'Ilmoitukset',
|
||||||
read: 'Lue!',
|
read: 'Lue!',
|
||||||
followed_you: 'seuraa sinua'
|
followed_you: 'seuraa sinua',
|
||||||
|
favorited_you: 'tykkäsi viestistäsi',
|
||||||
|
repeated_you: 'toisti viestisi'
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
login: 'Kirjaudu sisään',
|
login: 'Kirjaudu sisään',
|
||||||
|
@ -220,7 +224,9 @@ const en = {
|
||||||
error_fetching: 'Error fetching updates',
|
error_fetching: 'Error fetching updates',
|
||||||
up_to_date: 'Up-to-date',
|
up_to_date: 'Up-to-date',
|
||||||
load_older: 'Load older statuses',
|
load_older: 'Load older statuses',
|
||||||
conversation: 'Conversation'
|
conversation: 'Conversation',
|
||||||
|
collapse: 'Collapse',
|
||||||
|
repeated: 'repeated'
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
user_settings: 'User Settings',
|
user_settings: 'User Settings',
|
||||||
|
@ -261,7 +267,9 @@ const en = {
|
||||||
notifications: {
|
notifications: {
|
||||||
notifications: 'Notifications',
|
notifications: 'Notifications',
|
||||||
read: 'Read!',
|
read: 'Read!',
|
||||||
followed_you: 'followed you'
|
followed_you: 'followed you',
|
||||||
|
favorited_you: 'favorited your status',
|
||||||
|
repeated_you: 'repeated your status'
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
login: 'Log in',
|
login: 'Log in',
|
||||||
|
|
Loading…
Reference in a new issue