Merge pull request #31 from Oliver-Akins/dev
Update the track card to be more in line with Spotify's developer ToS
This commit is contained in:
commit
f351cb80fb
14 changed files with 298 additions and 58 deletions
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"clipboard-polyfill": "^3.0.1",
|
||||
"core-js": "^3.6.5",
|
||||
"v-tooltip": "^2.0.3",
|
||||
"vue": "^2.6.11",
|
||||
|
|
|
|||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
|
|
@ -1,5 +1,6 @@
|
|||
dependencies:
|
||||
axios: 0.19.2
|
||||
clipboard-polyfill: 3.0.1
|
||||
core-js: 3.6.5
|
||||
v-tooltip: 2.0.3_vue@2.6.11
|
||||
vue: 2.6.11
|
||||
|
|
@ -2475,6 +2476,10 @@ packages:
|
|||
node: '>= 10'
|
||||
resolution:
|
||||
integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
/clipboard-polyfill/3.0.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-R/uxBa8apxLJArzpFpuTLqavUcnEX8bezZKSuqkwz7Kny2BmxyKDslYGdrKiasKuD+mU1noF7Lkt/p5pyDqFoQ==
|
||||
/clipboardy/2.3.0:
|
||||
dependencies:
|
||||
arch: 2.1.2
|
||||
|
|
@ -8827,6 +8832,7 @@ specifiers:
|
|||
'@vue/cli-service': ~4.4.0
|
||||
axios: ^0.19.2
|
||||
babel-eslint: ^10.1.0
|
||||
clipboard-polyfill: ^3.0.1
|
||||
core-js: ^3.6.5
|
||||
eslint: ^6.7.2
|
||||
eslint-plugin-vue: ^6.2.2
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
<div id="icon" :style="div_styles">
|
||||
<span v-if="type === 'notes'" :style="span_styles">
|
||||
<svg
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
fill="none"
|
||||
rx="0"
|
||||
ry="0"
|
||||
|
|
@ -25,15 +25,15 @@
|
|||
</span>
|
||||
<span v-else-if="type === 'note_filled'" :style="span_styles">
|
||||
<svg
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
fill="none"
|
||||
rx="0"
|
||||
ry="0"
|
||||
|
|
@ -48,12 +48,12 @@
|
|||
</span>
|
||||
<span v-else-if="type === 'palette'" :style="span_styles">
|
||||
<svg
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
>
|
||||
<rect
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
fill="none"
|
||||
rx="0"
|
||||
ry="0"
|
||||
|
|
@ -68,15 +68,15 @@
|
|||
</span>
|
||||
<span v-else-if="type === 'info'" :style="span_styles">
|
||||
<svg
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
:width="inner_size"
|
||||
:height="inner_size"
|
||||
:width="innerSize"
|
||||
:height="innerSize"
|
||||
fill="none"
|
||||
rx="0"
|
||||
ry="0"
|
||||
|
|
@ -88,6 +88,29 @@
|
|||
/>
|
||||
</svg>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
|
@ -114,7 +137,7 @@ export default {
|
|||
default: 25,
|
||||
required: false,
|
||||
},
|
||||
inner_size: {
|
||||
innerSize: {
|
||||
type: Number,
|
||||
default: null,
|
||||
required: false,
|
||||
|
|
@ -140,10 +163,10 @@ export default {
|
|||
}},
|
||||
computed: {
|
||||
span_styles() {
|
||||
if (this.inner_size) {
|
||||
if (this.innerSize) {
|
||||
return {
|
||||
"width": `${this.inner_size}px`,
|
||||
"height": `${this.inner_size}px`,
|
||||
"width": `${this.innerSize}px`,
|
||||
"height": `${this.innerSize}px`,
|
||||
}
|
||||
}
|
||||
let x = Math.floor(this.size * 0.6);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="card" @click.stop="show_track_info = true">
|
||||
<div class="card">
|
||||
<div class="image">
|
||||
<img
|
||||
v-if="item.album.images.length !== 0"
|
||||
|
|
@ -21,19 +21,47 @@
|
|||
{{ item.artists.map(x => x.name).join(`, `) }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-tooltip.auto="popularity_tooltip"
|
||||
class="popularity corner"
|
||||
@click.self="show_pop_modal = true"
|
||||
<div class="bottom-bar">
|
||||
<button
|
||||
class="popularity"
|
||||
v-tooltip="popularity_tooltip"
|
||||
@click="show_pop_modal = true"
|
||||
>
|
||||
{{ 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
|
||||
v-tooltip.auto="duration_tooltip"
|
||||
class="duration corner"
|
||||
class="duration"
|
||||
v-tooltip="duration_tooltip"
|
||||
>
|
||||
{{ duration }}
|
||||
</div>
|
||||
</div>
|
||||
<PopularityModal
|
||||
v-if="show_pop_modal"
|
||||
@close="show_pop_modal = false"
|
||||
|
|
@ -43,19 +71,28 @@
|
|||
:track="item"
|
||||
@close="show_track_info = false"
|
||||
/>
|
||||
<Sharing
|
||||
v-if="show_share_modal"
|
||||
:track="item"
|
||||
@close="show_share_modal = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Import Components
|
||||
import PopularityModal from "../modals/PopularityInfo.vue";
|
||||
import DetailedTrackModal from "../modals/DetailedTrack.vue";
|
||||
import Icon from "../Icon";
|
||||
import ShareModal from "../modals/ShareTrack";
|
||||
import PopularityModal from "../modals/PopularityInfo";
|
||||
import DetailedTrackModal from "../modals/DetailedTrack";
|
||||
|
||||
export default {
|
||||
name: `TrackCard`,
|
||||
components: {
|
||||
PopularityModal: PopularityModal,
|
||||
TrackInfo: DetailedTrackModal,
|
||||
Sharing: ShareModal,
|
||||
icon: Icon,
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
|
|
@ -66,8 +103,11 @@ export default {
|
|||
data() { return {
|
||||
duration_tooltip: `Song Duration`,
|
||||
popularity_tooltip: `Song Popularity`,
|
||||
info_tooltip: `Audio Features`,
|
||||
share_tooltip: `Share`,
|
||||
show_pop_modal: false,
|
||||
show_track_info: false,
|
||||
show_share_modal: false,
|
||||
}},
|
||||
computed: {
|
||||
duration() {
|
||||
|
|
@ -100,7 +140,6 @@ export default {
|
|||
.card {
|
||||
border-radius: var(--corner-rounding);
|
||||
background-color: var(--card-colour);
|
||||
padding: 10px 10px 1.75em;
|
||||
color: var(--card-text);
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -108,6 +147,7 @@ export default {
|
|||
position: relative;
|
||||
margin: 5px auto;
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +158,14 @@ img {
|
|||
height: var(--size);
|
||||
}
|
||||
|
||||
.track-info {
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin-bottom: 25px;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: larger;
|
||||
|
|
@ -128,27 +176,75 @@ img {
|
|||
font-size: smaller;
|
||||
}
|
||||
|
||||
.corner {
|
||||
background-color: var(--on-card-colour);
|
||||
color: var(--on-card-text);
|
||||
.bottom-bar {
|
||||
border-radius: 0 0 var(--corner-rounding) var(--corner-rounding);
|
||||
background-color: var(--card-bottom-row-background);
|
||||
color: var(--card-bottom-row-text-colour);
|
||||
justify-content: space-between;
|
||||
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);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.popularity:hover {
|
||||
|
||||
.popularity { cursor: pointer; }
|
||||
.popularity:hover { background-color: var(--card-bottom-row-hover-background); }
|
||||
|
||||
.information, .share {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
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;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
/* Setting the growth and alignments of the bottom bar buttons */
|
||||
.bottom-bar > * {
|
||||
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) {
|
||||
.card {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div
|
||||
v-if="container"
|
||||
class="modal-container"
|
||||
@click.self="content = false"
|
||||
@click.self.stop="content = false"
|
||||
>
|
||||
<transition name="burst" @after-leave="$emit('close')">
|
||||
<div v-if="content" class="modal">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div
|
||||
v-if="container"
|
||||
class="modal-container"
|
||||
@click.self="content = false"
|
||||
@click.self.stop="content = false"
|
||||
>
|
||||
<transition name="burst" @after-leave="$emit('close')">
|
||||
<div v-if="content" class="modal">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div
|
||||
v-if="container"
|
||||
class="modal-container"
|
||||
@click.self="content = false"
|
||||
@click.self.stop="content = false"
|
||||
>
|
||||
<transition name="burst" @after-leave="$emit('close')">
|
||||
<div v-if="content" class="modal">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div
|
||||
v-if="container"
|
||||
class="modal-container"
|
||||
@click.self="content = false"
|
||||
@click.self.stop="content = false"
|
||||
>
|
||||
<transition name="burst" @after-leave="$emit('close')">
|
||||
<div v-if="content" class="modal">
|
||||
|
|
|
|||
102
src/components/modals/ShareTrack.vue
Normal file
102
src/components/modals/ShareTrack.vue
Normal 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_text(track.external_urls.spotify)"
|
||||
>
|
||||
Copy Track Link
|
||||
</button>
|
||||
<button
|
||||
@click="copy_text(track.album.external_urls.spotify)"
|
||||
>
|
||||
Copy Album Link
|
||||
</button>
|
||||
<button
|
||||
v-for="artist in track.artists"
|
||||
:key="artist.uri"
|
||||
@click="copy_text(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>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<div
|
||||
v-if="container"
|
||||
class="modal-container"
|
||||
@click.self="content = false"
|
||||
@click.self.stop="content = false"
|
||||
>
|
||||
<transition name="burst" @after-leave="$emit('close')">
|
||||
<div v-if="content" class="modal">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div
|
||||
v-if="container"
|
||||
class="modal-container"
|
||||
@click.self="content = false"
|
||||
@click.self.stop="content = false"
|
||||
>
|
||||
<transition name="burst" @after-leave="$emit('close')">
|
||||
<div v-if="content" class="modal">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ button {
|
|||
font-size: larger;
|
||||
outline: none;
|
||||
}
|
||||
button:hover { cursor: pointer; }
|
||||
button:hover {
|
||||
background-color: var(--button-hover-background);
|
||||
cursor: pointer;
|
||||
}
|
||||
button[disabled] {
|
||||
background-color: var(--button-disabled-background);
|
||||
color: var(--button-disabled-text);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
--card-text: #ffffff80;
|
||||
|
||||
--on-card-colour: #4c4c4c;
|
||||
--on-card-text: var(--spotify-green);
|
||||
--on-card-text: var(--accent2);
|
||||
|
||||
--modal-container-background: #0e0f10eb;
|
||||
--modal-background: var(--card-colour);
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
--input-text: var(--spotify-green);
|
||||
--input-active-border: var(--accent2);
|
||||
|
||||
--button-hover-background: var(--accent2);
|
||||
--button-background: var(--spotify-green);
|
||||
--button-disabled-background: #09682a;
|
||||
--button-text: var(--spotify-black);
|
||||
|
|
@ -60,4 +61,10 @@
|
|||
--scrollbar-background: #0f0f0f;
|
||||
--scrollbar-handle: #4d4d4d;
|
||||
--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);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import VTooltip from 'v-tooltip';
|
||||
import * as clipboard from 'clipboard-polyfill/text';
|
||||
import TextareaAutosize from 'vue-textarea-autosize';
|
||||
import VueEllipseProgress from 'vue-ellipse-progress';
|
||||
import App from './App.vue';
|
||||
|
|
@ -44,6 +45,7 @@ Vue.mixin({
|
|||
window.location.href = this.home_page;
|
||||
};
|
||||
},
|
||||
copy_text: clipboard.writeText,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue