Add thumbnails/listing view mode (close #278)

This commit adds an option to change view mode (thumbnails/listing) for
artists and albums views.
This commit is contained in:
An Phan 2016-03-27 13:13:17 +07:00
parent bad47db651
commit f43e72355c
6 changed files with 148 additions and 13 deletions

View file

@ -2,9 +2,10 @@
<section id="albumsWrapper">
<h1 class="heading">
<span>Albums</span>
<view-mode-switch :mode.sync="viewMode" :for="'albums'"></view-mode-switch>
</h1>
<div class="albums main-scroll-wrap" v-el:wrapper @scroll="scrolling">
<div class="albums main-scroll-wrap as-{{ viewMode }}" v-el:wrapper @scroll="scrolling">
<album-item v-for="item in items
| orderBy 'name'
| filterBy q in 'name' 'artist.name'
@ -17,12 +18,13 @@
<script>
import albumItem from '../../shared/album-item.vue';
import viewModeSwitch from '../../shared/view-mode-switch.vue';
import infiniteScroll from '../../../mixins/infinite-scroll';
import albumStore from '../../../stores/album';
export default {
mixins: [infiniteScroll],
components: { albumItem },
components: { albumItem, viewModeSwitch },
data() {
return {
@ -30,6 +32,7 @@
numOfItems: 9,
state: albumStore.state,
q: '',
viewMode: null,
};
},
@ -45,6 +48,8 @@
*/
'koel:ready': function () {
this.displayMore();
return true;
},
'koel:teardown': function () {

View file

@ -2,9 +2,10 @@
<section id="artistsWrapper">
<h1 class="heading">
<span>Artists</span>
<view-mode-switch :mode.sync="viewMode" :for="'artists'"></view-mode-switch>
</h1>
<div class="artists main-scroll-wrap" v-el:wrapper @scroll="scrolling">
<div class="artists main-scroll-wrap as-{{ viewMode }}" v-el:wrapper @scroll="scrolling">
<artist-item v-for="item in items
| filterBy q in 'name'
| limitBy numOfItems" :artist="item"></artist-item>
@ -16,13 +17,14 @@
<script>
import artistItem from '../../shared/artist-item.vue';
import viewModeSwitch from '../../shared/view-mode-switch.vue';
import infiniteScroll from '../../../mixins/infinite-scroll';
import artistStore from '../../../stores/artist';
export default {
mixins: [infiniteScroll],
components: { artistItem },
components: { artistItem, viewModeSwitch },
data() {
return {
@ -30,6 +32,7 @@
numOfItems: 9,
state: artistStore.state,
q: '',
viewMode: null,
};
},
@ -39,12 +42,20 @@
},
},
methods: {
setViewMode(mode) {
this.viewMode = mode;
},
},
events: {
/**
* When the application is ready, load the first batch of items.
*/
'koel:ready': function () {
this.displayMore();
return true;
},
'koel:teardown': function () {

View file

@ -7,6 +7,7 @@
</span>
<footer>
<a class="name" @click.prevent="viewDetails">{{ album.name }}</a>
<span class="sep">by</span>
<a class="artist" @click.prevent="viewArtistDetails">{{ album.artist.name }}</a>
<p class="meta">
{{ album.songs.length }} {{ album.songs.length | pluralize 'song' }}
@ -76,4 +77,13 @@
@import "../../../sass/partials/_mixins.scss";
@include artist-album-card();
.sep {
display: none;
color: $color2ndText;
.as-list & {
display: inline;
}
}
</style>

View file

@ -0,0 +1,81 @@
<template>
<span class="view-modes">
<a :class="{ active: mode === 'thumbnails' }"
title="View as thumbnails"
@click.prevent="setMode('thumbnails')"><i class="fa fa-th-large"></i></a>
<a :class="{ active: mode === 'list' }"
title="View as list"
@click.prevent="setMode('list')"><i class="fa fa-list"></i></a>
</span>
</template>
<script>
import preferenceStore from '../../stores/preference';
import isMobile from 'ismobilejs';
export default {
props: ['mode', 'for'],
computed: {
/**
* The preference key for local storage for persistent mode.
*
* @return {string}
*/
preferenceKey() {
return `${this.for}ViewMode`;
},
},
methods: {
setMode(mode) {
preferenceStore.set(this.preferenceKey, this.mode = mode);
},
},
events: {
'koel:ready': function () {
this.mode = preferenceStore.get(this.preferenceKey);
// If the value is empty, we set a default mode.
// On mobile, the mode should be 'listing'.
// For desktop, 'thumbnails'.
if (!this.mode) {
this.mode = isMobile.phone ? 'list' : 'thumbnails';
}
},
},
};
</script>
<style lang="sass" scoped>
@import "../../../sass/partials/_vars.scss";
@import "../../../sass/partials/_mixins.scss";
.view-modes {
display: flex;
flex: 0 0 64px;
border: 1px solid rgba(255, 255, 255, .2);
height: 28px;
border-radius: 5px;
overflow: hidden;
a {
width: 50%;
text-align: center;
line-height: 26px;
font-size: 14px;
&.active {
background: #fff;
color: #111;
}
}
@media only screen and(max-width: 768px) {
flex: 0;
width: 64px;
margin-top: 8px;
}
}
</style>

View file

@ -15,7 +15,9 @@ export default {
equalizer: {
preamp: 0,
gains: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
}
},
artistsViewMode: null,
albumsViewMode: null,
},
/**

View file

@ -17,6 +17,22 @@
width: 23.5%;
position: relative;
.as-list & {
flex-direction: row;
display: flex;
width: 100% !important;
.cover {
flex: 0 0 80px;
height: 80px;
padding-top: 0;
}
footer {
flex: 1;
}
}
@media only screen and (max-width: 1200px) {
width: 32%;
}
@ -51,24 +67,30 @@
padding-top: 100%;
position: relative;
.control {
$playBtnWidth: 96px;
display: none;
@mixin control($playBtnWidth, $fontSize, $textIndent) {
width: $playBtnWidth;
height: $playBtnWidth;
text-align: center;
line-height: $playBtnWidth;
font-size: 54px;
font-size: $fontSize;
text-indent: $textIndent;
left: calc(50% - #{$playBtnWidth/2});
}
.control {
.as-list & {
@include control(46px, 27px, 2px);
}
@include control(96px, 54px, 5px);
display: none;
text-align: center;
background: #111;
border-radius: 50%;
text-indent: 5px;
opacity: .7;
border: 1px solid transparent;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: calc(50% - #{$playBtnWidth/2});
transition: .3s;
&:hover {
@ -127,6 +149,10 @@
&:hover {
color: $colorHighlight;
}
.as-list & {
display: inline;
}
}
}
}