Multiple authors in Casper (#448)

This commit is contained in:
Peter Zimon 2018-04-10 20:19:29 +02:00 committed by John O'Nolan
parent 8e865b797b
commit 79e113226c
6 changed files with 430 additions and 35 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -415,8 +415,8 @@ The knock-on effect of this is ugly browser-scroll bars at the bottom, so 80px o
} }
.post-card-content-link { .post-card-content-link {
flex-grow: 1;
position: relative; position: relative;
flex-grow: 1;
display: block; display: block;
padding: 25px 25px 0; padding: 25px 25px 0;
color: var(--darkgrey); color: var(--darkgrey);
@ -453,20 +453,151 @@ The knock-on effect of this is ugly browser-scroll bars at the bottom, so 80px o
} }
.post-card-meta { .post-card-meta {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 25px 25px; padding: 0 25px 25px;
} }
.profile-image-wrapper,
.avatar-wrapper {
position: absolute;
display: inline-block;
width: 28px;
}
.avatar-wrapper {
display: inline-block;
box-sizing: content-box;
margin-right: 3px;
border: 2px solid #fff;
text-align: center;
background-color: color(var(--lightgrey) l(+10%));
border-radius: 100%;
}
.avatar-wrapper svg {
width: 28px;
height: 28px;
}
.author-profile-image { .author-profile-image {
box-sizing: content-box;
margin-right: 5px; margin-right: 5px;
width: 25px; width: 28px;
height: 25px; height: 28px;
border: 2px solid #fff;
border-radius: 100%; border-radius: 100%;
object-fit: cover; object-fit: cover;
} }
.post-card-author { .post-card-meta .profile-image-wrapper,
font-size: 1.3rem; .post-card-meta .avatar-wrapper {
position: relative;
}
.author-list {
display: flex;
margin-bottom: 0;
padding: 0;
max-width: calc(100% - 120px);
list-style-type: none;
}
.author-list-item {
position: relative;
margin: 0;
padding: 0;
width: 25px;
}
.moving-avatar {
transition: all 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99);
transform: translate(0px);
}
.moving-avatar.right {
transform: translateX(10px);
}
.moving-avatar.left {
transform: translateX(-10px);
}
.author-list-item:nth-child( 1 ) {
z-index: 9;
}
.author-list-item:nth-child( 2 ) {
z-index: 8;
}
.author-list-item:nth-child( 3 ) {
z-index: 7;
}
.author-list-item:nth-child( 4 ) {
z-index: 6;
}
.author-list-item:nth-child( 5 ) {
z-index: 5;
}
.author-list-item:nth-child( 6 ) {
z-index: 4;
}
.author-list-item:nth-child( 7 ) {
z-index: 3;
}
.author-list-item:nth-child( 8 ) {
z-index: 2;
}
.author-list-item:nth-child( 9 ) {
z-index: 1;
}
.z-999 {
z-index: 999;
}
.author-name-tooltip {
position: absolute;
bottom: 36px;
z-index: 999;
display: block;
padding: 2px 8px;
color: white;
font-size: 1.2rem;
letter-spacing: 0.2px;
white-space: nowrap;
background: var(--darkgrey);
border-radius: 3px;
box-shadow: rgba(39,44,49,0.08) 0 12px 26px, rgba(39, 44, 49, 0.03) 1px 3px 8px;
opacity: 0;
transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99);
transform: translateY(6px);
pointer-events: none;
}
.author-list-item:hover .author-name-tooltip {
opacity: 1.0;
transform: translateY(0px);
}
@media (max-width: 650px) {
.author-name-tooltip {
display: none;
}
}
.reading-time {
color: var(--midgrey);
font-size: 1.2rem;
font-weight: 500; font-weight: 500;
letter-spacing: 0.5px; letter-spacing: 0.5px;
text-transform: uppercase; text-transform: uppercase;
@ -1163,12 +1294,6 @@ Usage (In Ghost editor):
align-items: center; align-items: center;
} }
.author-card .author-profile-image {
margin-right: 15px;
width: 60px;
height: 60px;
}
.author-card-name { .author-card-name {
margin: 0 0 2px 0; margin: 0 0 2px 0;
padding: 0; padding: 0;
@ -1213,6 +1338,154 @@ Usage (In Ghost editor):
text-decoration: none; text-decoration: none;
} }
.post-full-authors {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
padding-top: 40px;
border-top: color(var(--lightgrey) l(+10%)) 1px solid;
}
.post-full-authors-content {
margin-bottom: 20px;
}
.post-full-authors-content p {
margin-bottom: 0;
color: var(--midgrey);
font-size: 1.4rem;
letter-spacing: 0.2px;
text-align: center;
text-transform: uppercase;
}
.post-full-authors-content a {
display: inline-block;
color: color(var(--darkgrey) l(+20%));
font-size: 1.4rem;
font-weight: 600;
text-transform: uppercase;
}
.post-full-footer .author-list-item {
width: 42px;
}
@media (max-width: 650px) {
.post-full-footer .author-list-item {
width: 54px;
}
}
.post-full-footer .author-list-item > a {
position: absolute;
display: inline-block;
width: 48px;
}
.post-full-footer .author-profile-image,
.post-full-footer .avatar-wrapper {
width: 48px;
height: 48px;
}
.author-card .author-profile-image,
.author-card .avatar-wrapper {
margin-right: 15px;
position: relative;
}
.post-full-footer .avatar-wrapper svg {
width: 46px;
height: 46px;
}
.author-list-item .author-card {
position: absolute;
bottom: 12px;
left: calc(-160px + 28px);
z-index: 999;
display: block;
width: 320px;
font-size: 1.4rem;
letter-spacing: 0.2px;
background: white;
border-radius: 6px;
box-shadow: rgba(39,44,49,0.08) 0 12px 26px, rgba(39, 44, 49, 0.03) 1px 3px 8px;
opacity: 0;
transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99);
transform: scale(0.98) translateY(10px);
pointer-events: none;
}
.author-list-item .author-card:before {
content: "";
position: absolute;
top: 100%;
left: calc(160px - 20px + 6px);
display: block;
width: 0;
height: 0;
border-top: 12px solid #fff;
border-right: 12px solid transparent;
border-left: 12px solid transparent;
}
.author-list-item .author-card.hovered {
opacity: 1.0;
transform: scale(1) translateY(0px);
pointer-events: auto;
}
.author-card .basic-info {
display: flex;
flex-direction: column;
align-items: center;
padding: 30px 20px 20px 20px;
color: #fff;
background: var(--darkgrey);
border-radius: 6px 6px 0 0;
}
.author-card .basic-info h2 {
margin: 1em 0 0.5em;
}
.author-card .bio {
padding: 20px 20px 0;
}
@media (max-width: 650px) {
.author-list-item .author-card {
display: none;
}
}
.basic-info .author-profile-image {
margin: 0;
width: 88px;
height: 88px;
border: none;
}
.basic-info .avatar-wrapper {
position: relative;
margin: 0;
width: 88px;
height: 88px;
border: none;
background: rgba(229, 239, 245, 0.1);
}
.basic-info .avatar-wrapper svg {
margin: 0;
width: 88px;
height: 88px;
opacity: 0.15;
}
/* 7.3. Comments /* 7.3. Comments
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */

View file

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M3.513 18.998C4.749 15.504 8.082 13 12 13s7.251 2.504 8.487 5.998C18.47 21.442 15.417 23 12 23s-6.47-1.558-8.487-4.002zM12 12c2.21 0 4-2.79 4-5s-1.79-4-4-4-4 1.79-4 4 1.79 5 4 5z" fill="#FFF"/></g></svg>

After

Width:  |  Height:  |  Size: 308 B

View file

@ -17,10 +17,26 @@
</section> </section>
</a> </a>
<footer class="post-card-meta"> <footer class="post-card-meta">
{{#if author.profile_image}}
<img class="author-profile-image" src="{{author.profile_image}}" alt="{{author.name}}" /> <ul class="author-list">
{{#foreach authors}}
<li class="author-list-item">
<div class="author-name-tooltip">
{{name}}
</div>
{{#if profile_image}}
<span class="profile-image-wrapper"><img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" /></span>
{{else}}
<span class="avatar-wrapper">{{> "icons/avatar"}}</span>
{{/if}} {{/if}}
<span class="post-card-author">{{author}}</span> </li>
{{/foreach}}
</ul>
<span class="reading-time">{{reading_time}}</span>
</footer> </footer>
</div> </div>
</article> </article>

105
post.hbs
View file

@ -46,12 +46,64 @@ into the {body} of the default.hbs template --}}
{{/if}} {{/if}}
<footer class="post-full-footer"> <footer class="post-full-footer">
{{!-- If there are multiple authors for the post, display all of their avatars in a stack --}}
{{#has author="count:>1"}}
<section class="post-full-authors">
<div class="post-full-authors-content">
<p>This post was a collaboration between</p>
<p>{{authors}}</p>
</div>
<ul class="author-list">
{{#foreach authors}}
<li class="author-list-item">
<div class="author-card">
<div class="basic-info">
{{#if profile_image}}
<img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" />
{{else}}
<span class="avatar-wrapper">{{> "icons/avatar"}}</span>
{{/if}}
<h2>{{name}}</h2>
</div>
<div class="bio">
{{#if bio}}
<p>{{bio}}</p>
<p><a href="{{url}}">More posts</a> by {{name}}.</p>
{{else}}
<p>Read <a href="{{url}}">more posts</a> by this author.</p>
{{/if}}
</div>
</div>
{{#if profile_image}}
<a href="{{url}}" class="moving-avatar"><img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" /></a>
{{else}}
<a href="{{url}}" class="moving-avatar"><span class="avatar-wrapper">{{> "icons/avatar"}}</span></a>
{{/if}}
</li>
{{/foreach}}
</ul>
</section>
{{!-- If there is a single author for the post, display her/his information --}}
{{else}}
{{!-- Everything inside the #author tags pulls data from the author --}} {{!-- Everything inside the #author tags pulls data from the author --}}
{{#author}} {{#author}}
<section class="author-card"> <section class="author-card">
{{#if profile_image}} {{#if profile_image}}
<img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" /> <img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" />
{{else}}
<span class="avatar-wrapper">{{> "icons/avatar"}}</span>
{{/if}} {{/if}}
<section class="author-card-content"> <section class="author-card-content">
<h4 class="author-card-name"><a href="{{url}}">{{name}}</a></h4> <h4 class="author-card-name"><a href="{{url}}">{{name}}</a></h4>
@ -67,6 +119,8 @@ into the {body} of the default.hbs template --}}
</div> </div>
{{/author}} {{/author}}
{{/has}}
</footer> </footer>
{{!-- {{!--
@ -216,6 +270,57 @@ $(document).ready(function () {
window.addEventListener('resize', onResize, false); window.addEventListener('resize', onResize, false);
update(); update();
});
// Adds delay to author card dropups to disappear. This gives enough
// time for the user to interact with the author card while they move
// the mouse from the avatar to the card. Also makes space for the
// interacted avatar.
$(document).ready(function () {
var hoverTimeout;
var direction = 'left';
$('.author-list-item:first-child').addClass('first-child');
function makeSpaceForAvatar(avatar) {
if (avatar.hasClass('first-child')) {
return;
}
$('.author-list-item').each(function(i, obj) {
if ($(this)[0] != avatar[0]) {
if (Number($(this).css('z-index')) > Number(avatar.css('z-index'))) {
$(this).children('.moving-avatar').addClass('left');
} else {
$(this).children('.moving-avatar').addClass('right');
}
}
});
}
$('.author-list-item').hover(function(){
var $this = $(this);
clearTimeout(hoverTimeout);
$('.author-card').removeClass('hovered');
$(this).children('.author-card').addClass('hovered');
makeSpaceForAvatar($this);
}, function() {
var $this = $(this);
$('.author-list-item').children('.moving-avatar').removeClass('left right');
hoverTimeout = setTimeout(function() {
$this.children('.author-card').removeClass('hovered');
}, 800);
});
}); });
</script> </script>
{{/contentFor}} {{/contentFor}}