Improve comment avatars on mobile
continuous-integration/drone/push Build is passing Details

This commit is contained in:
kolaente 2020-11-15 17:17:08 +01:00
parent 1d66218d5b
commit 460c30bd36
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
4 changed files with 107 additions and 32 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="{'is-pulled-up': isEditEnabled}" class="editor"> <div :class="{'is-pulled-up': isEditEnabled}" class="editor">
<div class="tabs is-right" v-if="hasPreview && isEditEnabled"> <div class="tabs is-right" v-if="hasPreview && isEditEnabled && !hasEditBottom">
<ul> <ul>
<li :class="{'is-active': isPreviewActive}" v-if="isEditActive"> <li :class="{'is-active': isPreviewActive}" v-if="isEditActive">
<a @click="showPreview">Preview</a> <a @click="showPreview">Preview</a>
@ -21,6 +21,20 @@
<div class="preview content" v-html="preview" v-if="isPreviewActive"> <div class="preview content" v-html="preview" v-if="isPreviewActive">
</div> </div>
<ul class="actions">
<li v-for="(action, k) in bottomActions" :key="k">
<a @click="action.action">{{ action.title }}</a>
</li>
<template v-if="hasEditBottom">
<li :class="{'is-active': isPreviewActive}" v-if="isEditActive">
<a @click="showPreview">Preview</a>
</li>
<li :class="{'is-active': isEditActive}">
<a @click="() => {isPreviewActive = false; isEditActive = true}">Edit</a>
</li>
</template>
</ul>
</div> </div>
</template> </template>
@ -67,6 +81,13 @@ export default {
isEditEnabled: { isEditEnabled: {
default: true, default: true,
}, },
hasEditBottom: {
type: Boolean,
default: false,
},
bottomActions: {
default: () => [],
},
}, },
data() { data() {
return { return {
@ -435,4 +456,34 @@ pre.CodeMirror-line {
font-family: $vikunja-font; font-family: $vikunja-font;
font-weight: 400; font-weight: 400;
} }
ul.actions {
font-size: .8em;
margin: 0;
li {
display: inline-block;
&:after {
content: '·';
padding: 0 .25rem;
}
&:last-child:after {
content: '';
}
}
&, a {
color: $grey;
}
a:hover {
text-decoration: underline;
}
}
.vue-easymde.content {
margin-bottom: 0 !important;
}
</style> </style>

View File

@ -7,19 +7,21 @@
Comments Comments
</h1> </h1>
<div class="comments"> <div class="comments">
<progress class="progress is-small is-info" max="100" v-if="taskCommentService.loading">Loading <progress class="progress is-small is-info" max="100" v-if="taskCommentService.loading">
comments... Loading comments...
</progress> </progress>
<div :key="c.id" class="media comment" v-for="c in comments"> <div :key="c.id" class="media comment" v-for="c in comments">
<figure class="media-left"> <figure class="media-left is-hidden-mobile">
<img :src="c.author.getAvatarUrl(48)" alt="" class="image is-avatar" height="48" width="48"/> <img :src="c.author.getAvatarUrl(48)" alt="" class="image is-avatar" height="48" width="48"/>
</figure> </figure>
<div class="media-content"> <div class="media-content">
<div :class="{'is-pulled-up': canWrite}" class="comment-info"> <div class="comment-info">
<img :src="c.author.getAvatarUrl(20)" alt="" class="image is-avatar" height="20" width="20"/>
<strong>{{ c.author.username }}</strong>&nbsp; <strong>{{ c.author.username }}</strong>&nbsp;
<small v-tooltip="formatDate(c.created)">{{ formatDateSince(c.created) }}</small> <span v-tooltip="formatDate(c.created)">{{ formatDateSince(c.created) }}</span>
<small v-if="+new Date(c.created) !== +new Date(c.updated)" v-tooltip="formatDate(c.updated)"> · <span v-if="+new Date(c.created) !== +new Date(c.updated)" v-tooltip="formatDate(c.updated)">
edited {{ formatDateSince(c.updated) }}</small> · edited {{ formatDateSince(c.updated) }}
</span>
</div> </div>
<editor <editor
:has-preview="true" :has-preview="true"
@ -28,14 +30,13 @@
:upload-enabled="true" :upload-enabled="true"
@change="() => {toggleEdit(c);editComment()}" @change="() => {toggleEdit(c);editComment()}"
v-model="c.comment" v-model="c.comment"
:has-edit-bottom="true"
:bottom-actions="actions[c.id]"
/> />
<div class="comment-actions" v-if="canWrite">
<a @click="toggleDelete(c.id)">Remove</a>
</div>
</div> </div>
</div> </div>
<div class="media comment" v-if="canWrite"> <div class="media comment" v-if="canWrite">
<figure class="media-left"> <figure class="media-left is-hidden-mobile">
<img :src="userAvatar" alt="" class="image is-avatar" height="48" width="48"/> <img :src="userAvatar" alt="" class="image is-avatar" height="48" width="48"/>
</figure> </figure>
<div class="media-content"> <div class="media-content">
@ -114,6 +115,7 @@ export default {
taskCommentService: TaskCommentService, taskCommentService: TaskCommentService,
newComment: TaskCommentModel, newComment: TaskCommentModel,
editorActive: true, editorActive: true,
actions: {},
} }
}, },
created() { created() {
@ -130,6 +132,9 @@ export default {
taskId() { taskId() {
this.loadComments() this.loadComments()
}, },
canWrite() {
this.makeActions()
},
}, },
computed: { computed: {
userAvatar() { userAvatar() {
@ -141,6 +146,7 @@ export default {
this.taskCommentService.getAll({taskId: this.taskId}) this.taskCommentService.getAll({taskId: this.taskId})
.then(r => { .then(r => {
this.$set(this, 'comments', r) this.$set(this, 'comments', r)
this.makeActions()
}) })
.catch(e => { .catch(e => {
this.error(e, this) this.error(e, this)
@ -212,6 +218,16 @@ export default {
this.showDeleteModal = false this.showDeleteModal = false
}) })
}, },
makeActions() {
if (this.canWrite) {
this.comments.forEach(c => {
this.$set(this.actions, c.id, [{
action: () => this.toggleDelete(c.id),
title: 'Remove',
}])
})
}
}
}, },
} }
</script> </script>

View File

@ -5,29 +5,36 @@
margin: 0 1em; margin: 0 1em;
} }
@media screen and (min-width: $tablet) { .comment-info {
.comment-info.is-pulled-up { display: flex;
margin-bottom: -3rem; align-items: center;
* {
padding-right: .5rem;
}
img {
display: none;
}
@media screen and (max-width: $tablet) {
img {
display: block;
width: 20px;
height: 20px;
padding-right: 0;
margin-right: .5rem;
}
}
span {
font-size: .75rem;
line-height: 1;
} }
} }
.editor .tabs { .editor {
margin-bottom: 0; margin-top: .5rem;
ul {
border-bottom: none;
}
} }
.comment-actions {
font-size: .8em;
&, a {
color: $grey;
}
a:hover {
text-decoration: underline;
}
}
} }

View File

@ -5,6 +5,7 @@ $red: #ff4136;
$blue: #1973ff; $blue: #1973ff;
$primary: $blue; $primary: $blue;
$dark: lighten($black, 8); $dark: lighten($black, 8);
$grey: hsl(0, 0%, 48%);
$info-invert: #fff; $info-invert: #fff;
$family-sans-serif: 'Open Sans', Helvetica, Arial, sans-serif; $family-sans-serif: 'Open Sans', Helvetica, Arial, sans-serif;