0
0
Fork 0

Merge pull request #29 from Oliver-Akins/feature/track-card-v2

Feature/track card v2
This commit is contained in:
Oliver 2020-08-23 01:39:49 -06:00 committed by GitHub
commit 16e0a6b7bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 283 additions and 52 deletions

View file

@ -2,15 +2,15 @@
<div id="icon" :style="div_styles"> <div id="icon" :style="div_styles">
<span v-if="type === 'notes'" :style="span_styles"> <span v-if="type === 'notes'" :style="span_styles">
<svg <svg
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<rect <rect
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
fill="none" fill="none"
rx="0" rx="0"
ry="0" ry="0"
@ -25,15 +25,15 @@
</span> </span>
<span v-else-if="type === 'note_filled'" :style="span_styles"> <span v-else-if="type === 'note_filled'" :style="span_styles">
<svg <svg
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<rect <rect
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
fill="none" fill="none"
rx="0" rx="0"
ry="0" ry="0"
@ -48,12 +48,12 @@
</span> </span>
<span v-else-if="type === 'palette'" :style="span_styles"> <span v-else-if="type === 'palette'" :style="span_styles">
<svg <svg
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
> >
<rect <rect
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
fill="none" fill="none"
rx="0" rx="0"
ry="0" ry="0"
@ -68,15 +68,15 @@
</span> </span>
<span v-else-if="type === 'info'" :style="span_styles"> <span v-else-if="type === 'info'" :style="span_styles">
<svg <svg
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<rect <rect
:width="inner_size" :width="innerSize"
:height="inner_size" :height="innerSize"
fill="none" fill="none"
rx="0" rx="0"
ry="0" ry="0"
@ -88,6 +88,29 @@
/> />
</svg> </svg>
</span> </span>
<span v-if="type === 'share'" :style="span_styles">
<svg
:width="innerSize"
:height="innerSize"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
:width="innerSize"
:height="innerSize"
fill="none"
rx="0"
ry="0"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M17 10C19.2091 10 21 8.20914 21 6C21 3.79086 19.2091 2 17 2C14.7909 2 13 3.79086 13 6C13 6.44376 13.0723 6.87064 13.2057 7.26952L9.90706 9.25245C9.17789 8.48121 8.14514 8 7 8C4.79086 8 3 9.79086 3 12C3 14.2091 4.79086 16 7 16C8.14608 16 9.17958 15.518 9.90885 14.7457L13.2074 16.7252C13.0729 17.1256 13 17.5543 13 18C13 20.2091 14.7909 22 17 22C19.2091 22 21 20.2091 21 18C21 15.7909 19.2091 14 17 14C15.8535 14 14.8197 14.4823 14.0904 15.2551L10.7922 13.2758C10.927 12.8751 11 12.4461 11 12C11 11.5527 10.9266 11.1226 10.7911 10.721L14.0861 8.74027C14.8156 9.51576 15.8513 10 17 10ZM19.8 18C19.8 19.5464 18.5464 20.8 17 20.8C15.4536 20.8 14.2 19.5464 14.2 18C14.2 16.4536 15.4536 15.2 17 15.2C18.5464 15.2 19.8 16.4536 19.8 18ZM19.8 6C19.8 7.5464 18.5464 8.8 17 8.8C15.4536 8.8 14.2 7.5464 14.2 6C14.2 4.4536 15.4536 3.2 17 3.2C18.5464 3.2 19.8 4.4536 19.8 6ZM9.8 12C9.8 13.5464 8.5464 14.8 7 14.8C5.4536 14.8 4.2 13.5464 4.2 12C4.2 10.4536 5.4536 9.2 7 9.2C8.5464 9.2 9.8 10.4536 9.8 12Z"
:fill="primary"
/>
</svg>
</span>
</div> </div>
</template> </template>
@ -114,7 +137,7 @@ export default {
default: 25, default: 25,
required: false, required: false,
}, },
inner_size: { innerSize: {
type: Number, type: Number,
default: null, default: null,
required: false, required: false,
@ -140,10 +163,10 @@ export default {
}}, }},
computed: { computed: {
span_styles() { span_styles() {
if (this.inner_size) { if (this.innerSize) {
return { return {
"width": `${this.inner_size}px`, "width": `${this.innerSize}px`,
"height": `${this.inner_size}px`, "height": `${this.innerSize}px`,
} }
} }
let x = Math.floor(this.size * 0.6); let x = Math.floor(this.size * 0.6);

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="card" @click="show_track_info = true"> <div class="card">
<div class="image"> <div class="image">
<img <img
v-if="item.album.images.length !== 0" v-if="item.album.images.length !== 0"
@ -21,19 +21,47 @@
{{ item.artists.map(x => x.name).join(`, `) }} {{ item.artists.map(x => x.name).join(`, `) }}
</div> </div>
</div> </div>
<div <div class="bottom-bar">
v-tooltip.auto="popularity_tooltip" <button
class="popularity corner" class="popularity"
@click.self.stop="show_pop_modal = true" v-tooltip="popularity_tooltip"
@click="show_pop_modal = true"
> >
{{ item.popularity }} {{ item.popularity }}
</div> </button>
<button
class="share"
name="Share"
v-tooltip="share_tooltip"
@click="show_share_modal = true"
>
<icon
type="share"
:size="22"
:inner-size="22"
:primary="css_var('--card-bottom-row-icon-colour')"
/>
</button>
<button
class="information"
name="Track Information"
v-tooltip="info_tooltip"
@click="show_track_info = true"
>
<icon
type="info"
:size="22"
:inner-size="22"
:primary="css_var('--card-bottom-row-icon-colour')"
/>
</button>
<div <div
v-tooltip.auto="duration_tooltip" class="duration"
class="duration corner" v-tooltip="duration_tooltip"
> >
{{ duration }} {{ duration }}
</div> </div>
</div>
<PopularityModal <PopularityModal
v-if="show_pop_modal" v-if="show_pop_modal"
@close="show_pop_modal = false" @close="show_pop_modal = false"
@ -43,19 +71,28 @@
:track="item" :track="item"
@close="show_track_info = false" @close="show_track_info = false"
/> />
<Sharing
v-if="show_share_modal"
:track="item"
@close="show_share_modal = false"
/>
</div> </div>
</template> </template>
<script> <script>
// Import Components // Import Components
import PopularityModal from "../modals/PopularityInfo.vue"; import Icon from "../Icon";
import DetailedTrackModal from "../modals/DetailedTrack.vue"; import ShareModal from "../modals/ShareTrack";
import PopularityModal from "../modals/PopularityInfo";
import DetailedTrackModal from "../modals/DetailedTrack";
export default { export default {
name: `TrackCard`, name: `TrackCard`,
components: { components: {
PopularityModal: PopularityModal, PopularityModal: PopularityModal,
TrackInfo: DetailedTrackModal, TrackInfo: DetailedTrackModal,
Sharing: ShareModal,
icon: Icon,
}, },
props: { props: {
item: { item: {
@ -66,8 +103,11 @@ export default {
data() { return { data() { return {
duration_tooltip: `Song Duration`, duration_tooltip: `Song Duration`,
popularity_tooltip: `Song Popularity`, popularity_tooltip: `Song Popularity`,
info_tooltip: `Audio Features`,
share_tooltip: `Share`,
show_pop_modal: false, show_pop_modal: false,
show_track_info: false, show_track_info: false,
show_share_modal: false,
}}, }},
computed: { computed: {
duration() { duration() {
@ -100,7 +140,6 @@ export default {
.card { .card {
border-radius: var(--corner-rounding); border-radius: var(--corner-rounding);
background-color: var(--card-colour); background-color: var(--card-colour);
padding: 10px 10px 1.75em;
color: var(--card-text); color: var(--card-text);
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -108,6 +147,7 @@ export default {
position: relative; position: relative;
margin: 5px auto; margin: 5px auto;
display: flex; display: flex;
padding: 10px;
width: 90%; width: 90%;
} }
@ -118,6 +158,14 @@ img {
height: var(--size); height: var(--size);
} }
.track-info {
justify-content: center;
flex-direction: column;
margin-bottom: 25px;
display: flex;
height: 100%;
}
.title { .title {
text-align: center; text-align: center;
font-size: larger; font-size: larger;
@ -128,27 +176,75 @@ img {
font-size: smaller; font-size: smaller;
} }
.corner { .bottom-bar {
background-color: var(--on-card-colour); border-radius: 0 0 var(--corner-rounding) var(--corner-rounding);
color: var(--on-card-text); background-color: var(--card-bottom-row-background);
color: var(--card-bottom-row-text-colour);
justify-content: space-between;
position: absolute; position: absolute;
padding: 1px 6px; display: flex;
width: 100%;
bottom: 0;
}
.bottom-bar > button {
background-color: var(--card-bottom-row-background);
color: var(--card-bottom-row-text-colour);
font-size: initial;
padding: 0;
} }
.popularity {
border-radius: 0 var(--corner-rounding) 0 var(--corner-rounding); .popularity { cursor: pointer; }
bottom: 0; .popularity:hover { background-color: var(--card-bottom-row-hover-background); }
left: 0;
} .information, .share {
.popularity:hover { justify-content: center;
align-items: center;
cursor: pointer; cursor: pointer;
display: flex;
}
.information:hover, .share:hover {
background-color: var(--card-bottom-row-hover-background);
} }
.duration {
border-radius: var(--corner-rounding) 0 var(--corner-rounding) 0; /* Setting the growth and alignments of the bottom bar buttons */
bottom: 0; .bottom-bar > * {
right: 0; border-color: var(--card-bottom-row-divider-colour);
padding-bottom: 2px;
padding-top: 2px;
} }
.bottom-bar > :nth-child(1) {
border-radius: 0 0 0 var(--corner-rounding);
border-right-style: solid;
border-right-width: 2px;
padding-left: 5%;
text-align: left;
flex-grow: 1;
}
.bottom-bar > :nth-child(2) {
border-radius: 0;
border-right-style: solid;
border-right-width: 1px;
text-align: center;
flex-grow: 2;
}
.bottom-bar > :nth-child(3) {
border-radius: 0;
border-left-style: solid;
border-left-width: 1px;
text-align: center;
flex-grow: 2;
}
.bottom-bar > :nth-child(4) {
border-radius: 0 0 var(--corner-rounding) 0;
border-left-style: solid;
border-left-width: 2px;
padding-right: 5%;
text-align: right;
flex-grow: 1;
}
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
.card { .card {

View file

@ -0,0 +1,102 @@
<template>
<transition name="fade" @after-enter="content = true">
<div
v-if="container"
class="modal-container"
@click.self.stop="content = false"
>
<transition name="burst" @after-leave="$emit('close')">
<div v-if="content" class="modal">
<h2 class="center">Track Sharing</h2>
<div class="share-buttons">
<button
@click="copy_link(track.external_urls.spotify)"
>
Copy Track Link
</button>
<button
@click="copy_link(track.album.external_urls.spotify)"
>
Copy Album Link
</button>
<button
v-for="artist in track.artists"
:key="artist.uri"
@click="copy_link(artist.external_urls.spotify)"
>
Copy {{ artist.name }}'s Link
</button>
</div>
</div>
</transition>
</div>
</transition>
</template>
<script>
export default {
name: `ShareTrack`,
props: {
track: {
type: Object,
required: true,
},
},
data() {return {
content: false,
container: false,
}},
computed: {},
mounted() {
this.$nextTick(function() {
this.container = true;
});
}
}
</script>
<style scoped>
.modal-container {
background-color: var(--modal-container-background);
justify-content: center;
align-items: center;
position: fixed;
display: flex;
height: 100vh;
width: 100vw;
z-index: 10;
left: 0;
top: 0;
}
.modal {
background-color: var(--modal-background);
border-radius: var(--corner-rounding);
padding: 0 15px 15px 15px;
text-align: center;
max-height: 85%;
z-index: 11;
width: 90%;
}
.share-buttons {
flex-direction: column;
align-items: center;
display: flex;
}
.share-buttons > button {
margin-bottom: 10px;
width: 90%;
}
@media only screen and (min-width: 768px) {
.modal {
width: 50%;
max-height: 75%;
}
.share-buttons > button {
width: 64%;
}
}
</style>

View file

@ -8,7 +8,10 @@ button {
font-size: larger; font-size: larger;
outline: none; outline: none;
} }
button:hover { cursor: pointer; } button:hover {
background-color: var(--button-hover-background);
cursor: pointer;
}
button[disabled] { button[disabled] {
background-color: var(--button-disabled-background); background-color: var(--button-disabled-background);
color: var(--button-disabled-text); color: var(--button-disabled-text);

View file

@ -23,7 +23,7 @@
--card-text: #ffffff80; --card-text: #ffffff80;
--on-card-colour: #4c4c4c; --on-card-colour: #4c4c4c;
--on-card-text: var(--spotify-green); --on-card-text: var(--accent2);
--modal-container-background: #0e0f10eb; --modal-container-background: #0e0f10eb;
--modal-background: var(--card-colour); --modal-background: var(--card-colour);
@ -38,6 +38,7 @@
--input-text: var(--spotify-green); --input-text: var(--spotify-green);
--input-active-border: var(--accent2); --input-active-border: var(--accent2);
--button-hover-background: var(--accent2);
--button-background: var(--spotify-green); --button-background: var(--spotify-green);
--button-disabled-background: #09682a; --button-disabled-background: #09682a;
--button-text: var(--spotify-black); --button-text: var(--spotify-black);
@ -60,4 +61,10 @@
--scrollbar-background: #0f0f0f; --scrollbar-background: #0f0f0f;
--scrollbar-handle: #4d4d4d; --scrollbar-handle: #4d4d4d;
--scrollbar-handle-hover: #5e5e5e; --scrollbar-handle-hover: #5e5e5e;
--card-bottom-row-text-colour: var(--accent2);
--card-bottom-row-background: var(--on-card-colour);
--card-bottom-row-hover-background: #414141;
--card-bottom-row-divider-colour: #000000;
--card-bottom-row-icon-colour: var(--card-bottom-row-text-colour);
} }