Rewrite list items :)
This commit is contained in:
parent
dd2bfc6970
commit
7afbe836d3
|
@ -7,6 +7,13 @@
|
||||||
"type": "npm",
|
"type": "npm",
|
||||||
"script": "dev",
|
"script": "dev",
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "dev-runner",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"label": "npm: dev-runner",
|
||||||
|
"detail": "node _scripts/dev-runner.js"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
name: 'FtAutoGrid',
|
||||||
|
props: {
|
||||||
|
grid: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,10 @@
|
||||||
|
.ft-auto-grid
|
||||||
|
&.grid
|
||||||
|
display: grid
|
||||||
|
grid-template-columns: repeat(auto-fill, 240px)
|
||||||
|
justify-content: space-evenly
|
||||||
|
grid-gap: 5px
|
||||||
|
|
||||||
|
&.list
|
||||||
|
display: grid
|
||||||
|
grid-gap: 16px
|
|
@ -0,0 +1,14 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="ft-auto-grid"
|
||||||
|
:class="{
|
||||||
|
grid: grid,
|
||||||
|
list: !grid
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./ft-auto-grid.js" />
|
||||||
|
<style scoped lang="sass" src="./ft-auto-grid.sass" />
|
|
@ -1,6 +1,6 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
||||||
import FtGrid from '../ft-grid/ft-grid.vue'
|
import FtAutoGrid from '../ft-auto-grid/ft-auto-grid.vue'
|
||||||
import FtListVideo from '../ft-list-video/ft-list-video.vue'
|
import FtListVideo from '../ft-list-video/ft-list-video.vue'
|
||||||
import FtListChannel from '../ft-list-channel/ft-list-channel.vue'
|
import FtListChannel from '../ft-list-channel/ft-list-channel.vue'
|
||||||
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
|
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
|
||||||
|
@ -9,7 +9,7 @@ export default Vue.extend({
|
||||||
name: 'FtElementList',
|
name: 'FtElementList',
|
||||||
components: {
|
components: {
|
||||||
'ft-flex-box': FtFlexBox,
|
'ft-flex-box': FtFlexBox,
|
||||||
'ft-grid': FtGrid,
|
'ft-auto-grid': FtAutoGrid,
|
||||||
'ft-list-video': FtListVideo,
|
'ft-list-video': FtListVideo,
|
||||||
'ft-list-channel': FtListChannel,
|
'ft-list-channel': FtListChannel,
|
||||||
'ft-list-playlist': FtListPlaylist
|
'ft-list-playlist': FtListPlaylist
|
||||||
|
|
|
@ -1,49 +1,29 @@
|
||||||
<template>
|
<template>
|
||||||
<span>
|
<ft-auto-grid
|
||||||
<ft-flex-box
|
:grid="listType !== 'list'"
|
||||||
v-if="listType === 'list'"
|
|
||||||
>
|
>
|
||||||
<span
|
<template
|
||||||
v-for="(result, index) in data"
|
v-for="(result, index) in data"
|
||||||
:key="index"
|
|
||||||
class="maxWidth"
|
|
||||||
>
|
>
|
||||||
<ft-list-channel
|
<ft-list-channel
|
||||||
v-if="result.type === 'channel'"
|
v-if="result.type === 'channel'"
|
||||||
:data="result"
|
:data="result"
|
||||||
/>
|
|
||||||
<ft-list-video
|
|
||||||
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
|
||||||
:data="result"
|
|
||||||
/>
|
|
||||||
<ft-list-playlist
|
|
||||||
v-if="result.type === 'playlist'"
|
|
||||||
:data="result"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</ft-flex-box>
|
|
||||||
<ft-grid
|
|
||||||
v-else
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
v-for="(result, index) in data"
|
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
|
||||||
<ft-list-channel
|
|
||||||
v-if="result.type === 'channel'"
|
|
||||||
:data="result"
|
|
||||||
/>
|
/>
|
||||||
<ft-list-video
|
<ft-list-video
|
||||||
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
||||||
|
appearance="result"
|
||||||
:data="result"
|
:data="result"
|
||||||
|
:key="index"
|
||||||
/>
|
/>
|
||||||
<ft-list-playlist
|
<ft-list-playlist
|
||||||
v-if="result.type === 'playlist'"
|
v-if="result.type === 'playlist'"
|
||||||
|
appearance="result"
|
||||||
:data="result"
|
:data="result"
|
||||||
|
:key="index"
|
||||||
/>
|
/>
|
||||||
</span>
|
</template>
|
||||||
</ft-grid>
|
</ft-auto-grid>
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./ft-element-list.js" />
|
<script src="./ft-element-list.js" />
|
||||||
|
|
|
@ -19,6 +19,14 @@ export default Vue.extend({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
padding: {
|
||||||
|
type: Number,
|
||||||
|
default: 10
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: 20
|
||||||
|
},
|
||||||
forceDropdown: {
|
forceDropdown: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
flex-flow: row wrap
|
flex-flow: row wrap
|
||||||
justify-content: space-evenly
|
justify-content: space-evenly
|
||||||
position: relative
|
position: relative
|
||||||
|
user-select: none
|
||||||
|
|
||||||
.iconButton
|
.iconButton
|
||||||
width: 1em
|
width: 1em
|
||||||
height: 1em
|
height: 1em
|
||||||
padding: 10px
|
|
||||||
font-size: 20px
|
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
transition: background 0.15s ease-out
|
transition: background 0.15s ease-out
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
secondary: theme === 'secondary',
|
secondary: theme === 'secondary',
|
||||||
shadow: useShadow
|
shadow: useShadow
|
||||||
}"
|
}"
|
||||||
|
:style="{
|
||||||
|
padding: padding + 'px',
|
||||||
|
fontSize: size + 'px'
|
||||||
|
}"
|
||||||
@click="handleIconClick"
|
@click="handleIconClick"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
.videoThumbnail {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoCountContainer {
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
right: 0px;
|
|
||||||
width: 120px;
|
|
||||||
background-color: rgba(0,0,0,0.6);
|
|
||||||
color: #FFFFFF;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoCountContainer span {
|
|
||||||
position: absolute;
|
|
||||||
top: 40px;
|
|
||||||
left: 45px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistTitle {
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--title-color);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.channelName {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
width: 240px;
|
|
||||||
height: 250px;
|
|
||||||
padding: 2px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoThumbnail {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
margin-bottom: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoThumbnail img {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoCountContainer {
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .playlistTitle {
|
|
||||||
max-height: 75px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .channelName {
|
|
||||||
width: 275px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
height: 140px;
|
|
||||||
width: 100%;
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-top: 15px;
|
|
||||||
border-bottom: 1px solid var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoThumbnail {
|
|
||||||
float: left;
|
|
||||||
width: 240px;
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoThumbnail img {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoCountContainer {
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .playlistTitle {
|
|
||||||
margin-left: 250px;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .channelName {
|
|
||||||
margin-left: 250px;
|
|
||||||
width: 275px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .description {
|
|
||||||
margin-left: 285px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
height: 35px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
|
@ -6,6 +6,10 @@ export default Vue.extend({
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
appearance: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
|
@ -58,14 +62,6 @@ export default Vue.extend({
|
||||||
this.channelLink = this.data.author.ref
|
this.channelLink = this.data.author.ref
|
||||||
this.playlistLink = this.data.link
|
this.playlistLink = this.data.link
|
||||||
this.videoCount = parseInt(this.data.length.split(' ')[0])
|
this.videoCount = parseInt(this.data.length.split(' ')[0])
|
||||||
},
|
|
||||||
|
|
||||||
goToPlaylist: function (id) {
|
|
||||||
this.$router.push({ path: `/playlist/${id}` })
|
|
||||||
},
|
|
||||||
|
|
||||||
goToChannel: function (id) {
|
|
||||||
console.log(id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
@use "../../sass-partials/_ft-list-item"
|
|
@ -1,38 +1,45 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="ft-list-video"
|
class="ft-list-video"
|
||||||
|
:appearance="appearance"
|
||||||
:class="{ list: listType === 'list', grid: listType === 'grid' }"
|
:class="{ list: listType === 'list', grid: listType === 'grid' }"
|
||||||
>
|
>
|
||||||
<div class="videoThumbnail">
|
<router-link
|
||||||
|
class="videoThumbnail"
|
||||||
|
:to="`/playlist/${playlistId}`"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
:src="thumbnail"
|
:src="thumbnail"
|
||||||
@click="goToPlaylist(playlistId)"
|
class="thumbnailImage"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="videoCountContainer"
|
class="videoCountContainer"
|
||||||
@click="goToPlaylist(playlistId)"
|
|
||||||
>
|
>
|
||||||
<span>
|
<div class="background" />
|
||||||
{{ videoCount }}
|
<div class="inner">
|
||||||
<br>
|
<div>{{ videoCount }}</div>
|
||||||
<font-awesome-icon icon="list" />
|
<div><font-awesome-icon icon="list" /></div>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p
|
</router-link>
|
||||||
class="playlistTitle"
|
<div class="videoInfo">
|
||||||
@click="goToPlaylist(playlistId)"
|
<router-link
|
||||||
|
class="title"
|
||||||
|
:to="`/playlist/${playlistId}`"
|
||||||
>
|
>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</p>
|
</router-link>
|
||||||
<p
|
<div class="infoLine">
|
||||||
|
<router-link
|
||||||
class="channelName"
|
class="channelName"
|
||||||
@click="goToChannel(channelId)"
|
:to="`/channel/${channelId}`"
|
||||||
>
|
>
|
||||||
{{ channelName }}
|
{{ channelName }}
|
||||||
</p>
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./ft-list-playlist.js" />
|
<script src="./ft-list-playlist.js" />
|
||||||
<style scoped src="./ft-list-playlist.css" />
|
<style scoped lang="sass" src="./ft-list-playlist.sass" />
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
.videoThumbnail {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoThumbnail:hover .videoWatched {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.favoritesIcon {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 15px;
|
|
||||||
top: 0px;
|
|
||||||
right: 0px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #000000;
|
|
||||||
opacity: 0.7;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.favorited {
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoDuration {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 13px;
|
|
||||||
bottom: -7px;
|
|
||||||
right: 0px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
padding: 2px;
|
|
||||||
background-color: #000000;
|
|
||||||
opacity: 0.7;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoWatched {
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
width: 100%;
|
|
||||||
background-color: rgba(0,0,0,0.4);
|
|
||||||
color: #FFFFFF;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.watchedProgressBar {
|
|
||||||
background-color: var(--red-500);
|
|
||||||
opacity: 0.8;
|
|
||||||
height: 3px;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoTitle {
|
|
||||||
color: var(--title-color);
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.channelName {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewCount {
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uploadedTime {
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.liveText {
|
|
||||||
color: var(--red-500);
|
|
||||||
font-size: 13px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .iconButton {
|
|
||||||
font-size: 15px;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .iconDropdown {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
width: 240px;
|
|
||||||
height: 250px;
|
|
||||||
padding: 2px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoThumbnail {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
margin-bottom: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoThumbnail img {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoWatched {
|
|
||||||
height: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .optionsButton {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 210px;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .videoTitle {
|
|
||||||
max-height: 55px;
|
|
||||||
width: 210px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
margin-bottom: -15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .channelName {
|
|
||||||
width: 220px;
|
|
||||||
height: 17px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .liveText {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
height: 140px;
|
|
||||||
width: 100%;
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoThumbnail {
|
|
||||||
float: left;
|
|
||||||
width: 240px;
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoThumbnail img {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoWatched {
|
|
||||||
height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .optionsButton {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .videoTitle {
|
|
||||||
margin-left: 250px;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .channelName {
|
|
||||||
margin-left: 250px;
|
|
||||||
max-width: 275px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .viewCount {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .liveText {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list .description {
|
|
||||||
margin-left: 250px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
height: 35px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoRecommendation.list {
|
|
||||||
height: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoRecommendation.list .videoThumbnail {
|
|
||||||
width: 180px;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoRecommendation.list .videoThumbnail img {
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoRecommendation.list .videoTitle {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 185px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoRecommendation.list .channelName {
|
|
||||||
margin-left: 185px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoRecommendation.list .viewCount {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistItem .list {
|
|
||||||
height: 60px;
|
|
||||||
width: calc(100% - 30px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistItem .list .videoThumbnail {
|
|
||||||
width: 100px;
|
|
||||||
height: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistItem .list .videoThumbnail img {
|
|
||||||
height: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistItem .list .videoTitle {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 105px;
|
|
||||||
margin-right: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistItem .list .channelName {
|
|
||||||
margin-left: 105px;
|
|
||||||
margin-right: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistItem .list .viewCount {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
|
@ -1,10 +1,12 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
|
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
|
||||||
|
import FtCard from "../ft-card/ft-card.vue"
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'FtListVideo',
|
name: 'FtListVideo',
|
||||||
components: {
|
components: {
|
||||||
'ft-icon-button': FtIconButton
|
'ft-icon-button': FtIconButton,
|
||||||
|
'ft-card': FtCard
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
|
@ -18,6 +20,10 @@ export default Vue.extend({
|
||||||
forceListType: {
|
forceListType: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
appearance: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
|
@ -120,31 +126,6 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
|
||||||
const playlistInfo = {
|
|
||||||
playlistId: this.playlistId
|
|
||||||
}
|
|
||||||
console.log('playlist info')
|
|
||||||
console.log(playlistInfo)
|
|
||||||
|
|
||||||
if (this.playlistId !== null) {
|
|
||||||
console.log('Sending playlist info')
|
|
||||||
this.$router.push(
|
|
||||||
{
|
|
||||||
path: `/watch/${this.id}`,
|
|
||||||
query: playlistInfo
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
console.log('no playlist found')
|
|
||||||
this.$router.push({ path: `/watch/${this.id}` })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
goToChannel: function () {
|
|
||||||
this.$router.push({ path: `/channel/${this.channelId}` })
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleSave: function () {
|
toggleSave: function () {
|
||||||
console.log('TODO: ft-list-video method toggleSave')
|
console.log('TODO: ft-list-video method toggleSave')
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
@use "../../sass-partials/_ft-list-item"
|
|
@ -3,25 +3,37 @@
|
||||||
class="ft-list-video"
|
class="ft-list-video"
|
||||||
:class="{
|
:class="{
|
||||||
list: (listType === 'list' || forceListType === 'list') && forceListType !== 'grid',
|
list: (listType === 'list' || forceListType === 'list') && forceListType !== 'grid',
|
||||||
grid: (listType === 'grid' || forceListType === 'list') && forceListType !== 'list'
|
grid: (listType === 'grid' || forceListType === 'list') && forceListType !== 'list',
|
||||||
|
[appearance]: true
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="videoThumbnail"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
class="thumbnailLink"
|
||||||
|
:to="{
|
||||||
|
path: `/watch/${id}`,
|
||||||
|
query: playlistId ? {playlistId} : {}
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="videoThumbnail">
|
|
||||||
<img
|
<img
|
||||||
:src="thumbnail"
|
:src="thumbnail"
|
||||||
@click="play(id)"
|
class="thumbnailImage"
|
||||||
>
|
>
|
||||||
<p
|
</router-link>
|
||||||
v-if="!isLive"
|
<div
|
||||||
class="videoDuration"
|
class="videoDuration"
|
||||||
@click="play(id)"
|
:class="{ live: isLive }"
|
||||||
>
|
>
|
||||||
{{ duration }}
|
{{ isLive ? "Live" : duration }}
|
||||||
</p>
|
</div>
|
||||||
<font-awesome-icon
|
<ft-icon-button
|
||||||
v-if="!isLive"
|
v-if="!isLive"
|
||||||
icon="star"
|
icon="star"
|
||||||
class="favoritesIcon"
|
class="favoritesIcon"
|
||||||
|
:padding="6"
|
||||||
|
:size="18"
|
||||||
:class="{ favorited: isFavorited }"
|
:class="{ favorited: isFavorited }"
|
||||||
@click="toggleSave(id)"
|
@click="toggleSave(id)"
|
||||||
/>
|
/>
|
||||||
|
@ -29,7 +41,7 @@
|
||||||
v-if="watched"
|
v-if="watched"
|
||||||
class="videoWatched"
|
class="videoWatched"
|
||||||
>
|
>
|
||||||
WATCHED
|
Watched
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="watched"
|
v-if="watched"
|
||||||
|
@ -37,65 +49,42 @@
|
||||||
:style="{width: progressPercentage + '%'}"
|
:style="{width: progressPercentage + '%'}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="videoInfo">
|
||||||
<ft-icon-button
|
<ft-icon-button
|
||||||
class="optionsButton"
|
class="optionsButton"
|
||||||
title="More Options"
|
title="More Options"
|
||||||
theme="base"
|
theme="base"
|
||||||
|
:size="16"
|
||||||
:use-shadow="false"
|
:use-shadow="false"
|
||||||
dropdown-position-x="left"
|
dropdown-position-x="left"
|
||||||
:dropdown-names="optionsNames"
|
:dropdown-names="optionsNames"
|
||||||
:dropdown-values="optionsValues"
|
:dropdown-values="optionsValues"
|
||||||
@click="handleOptionsClick"
|
@click="handleOptionsClick"
|
||||||
/>
|
/>
|
||||||
<p
|
<router-link
|
||||||
class="videoTitle"
|
class="title"
|
||||||
@click="play(id)"
|
:to="{
|
||||||
|
path: `/watch/${id}`,
|
||||||
|
query: playlistId ? {playlistId} : {}
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</p>
|
</router-link>
|
||||||
|
<div class="infoLine">
|
||||||
|
<router-link class="channelName" :to="`/channel/${channelId}`">{{ channelName }}</router-link>
|
||||||
|
<span v-if="!isLive && !hideViews" class="viewCount">• {{ viewCount }} views</span>
|
||||||
|
<span v-if="uploadedTime !== '' && !isLive" class="uploadedTime">• {{ uploadedTime }}</span>
|
||||||
|
<span v-if="isLive" class="viewCount">• {{ viewCount }} watching</span>
|
||||||
|
</div>
|
||||||
<p
|
<p
|
||||||
class="channelName"
|
v-if="listType !== 'grid' && appearance === 'result'"
|
||||||
@click="goToChannel"
|
|
||||||
>
|
|
||||||
{{ channelName }}
|
|
||||||
</p>
|
|
||||||
<span
|
|
||||||
v-if="!isLive && !hideViews"
|
|
||||||
class="viewCount"
|
|
||||||
@click="play(id)"
|
|
||||||
>
|
|
||||||
{{ viewCount }} views
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="uploadedTime !== '' && !isLive"
|
|
||||||
class="uploadedTime"
|
|
||||||
@click="play(id)"
|
|
||||||
>
|
|
||||||
- {{ uploadedTime }}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="isLive"
|
|
||||||
class="viewCount"
|
|
||||||
@click="play(id)"
|
|
||||||
>
|
|
||||||
{{ viewCount }} watching
|
|
||||||
</span>
|
|
||||||
<p
|
|
||||||
v-if="listType !== 'grid'"
|
|
||||||
class="description"
|
class="description"
|
||||||
@click="play(id)"
|
|
||||||
>
|
>
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</p>
|
</p>
|
||||||
<span
|
</div>
|
||||||
v-if="isLive"
|
|
||||||
class="liveText"
|
|
||||||
@click="play(id)"
|
|
||||||
>
|
|
||||||
LIVE NOW
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./ft-list-video.js" />
|
<script src="./ft-list-video.js" />
|
||||||
<style scoped src="./ft-list-video.css" />
|
<style scoped src="./ft-list-video.sass" lang="sass" />
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
/>
|
/>
|
||||||
<ft-list-video
|
<ft-list-video
|
||||||
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
||||||
|
appearance="result"
|
||||||
:data="result"
|
:data="result"
|
||||||
/>
|
/>
|
||||||
<ft-list-playlist
|
<ft-list-playlist
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
/>
|
/>
|
||||||
<ft-list-video
|
<ft-list-video
|
||||||
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
||||||
|
appearance="result"
|
||||||
:data="result"
|
:data="result"
|
||||||
/>
|
/>
|
||||||
<ft-list-playlist
|
<ft-list-playlist
|
||||||
|
|
|
@ -37,36 +37,34 @@
|
||||||
.playlistItems {
|
.playlistItems {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: 395px;
|
height: 395px;
|
||||||
margin-top: -15px;
|
|
||||||
margin-left: -16px;
|
|
||||||
margin-right: -16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlistItem {
|
.playlistItem {
|
||||||
height: 75px;
|
display: grid;
|
||||||
width: 100%;
|
grid-template-columns: 30px 1fr;
|
||||||
|
align-items: center;
|
||||||
transition: background 0.2s ease-out;
|
transition: background 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.playlistItem:not(:last-child) {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.playlistItem:hover {
|
.playlistItem:hover {
|
||||||
background-color: var(--side-nav-hover-color);
|
background-color: var(--side-nav-hover-color);
|
||||||
transition: background 0.2s ease-in;
|
transition: background 0.2s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.videoIndexContainer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.videoIndex {
|
.videoIndex {
|
||||||
float: left;
|
|
||||||
position: relative;
|
|
||||||
top: 15px;
|
|
||||||
left: 10px;
|
|
||||||
color: var(--tertiary-text-color);
|
color: var(--tertiary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.videoIndexIcon {
|
.videoIndexIcon {
|
||||||
float: left;
|
|
||||||
position: relative;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
top: 32px;
|
|
||||||
left: 10px;
|
|
||||||
color: var(--tertiary-text-color);
|
color: var(--tertiary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
:key="index"
|
:key="index"
|
||||||
class="playlistItem"
|
class="playlistItem"
|
||||||
>
|
>
|
||||||
|
<div class="videoIndexContainer">
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
v-if="item.videoId === videoId"
|
v-if="item.videoId === videoId"
|
||||||
class="videoIndexIcon"
|
class="videoIndexIcon"
|
||||||
|
@ -67,11 +68,12 @@
|
||||||
>
|
>
|
||||||
{{ index + 1 }}
|
{{ index + 1 }}
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
<ft-list-video
|
<ft-list-video
|
||||||
:data="item"
|
:data="item"
|
||||||
:playlist-id="playlistId"
|
:playlist-id="playlistId"
|
||||||
|
appearance="watchPlaylistItem"
|
||||||
force-list-type="list"
|
force-list-type="list"
|
||||||
class="videoInfo"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ft-flex-box>
|
</ft-flex-box>
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
.relative {
|
.watchVideoRecommendations {
|
||||||
position: relative;
|
display: grid;
|
||||||
}
|
grid-gap: 8px;
|
||||||
|
|
||||||
.videoRecommendation {
|
|
||||||
margin-bottom: -15px;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<ft-card class="relative">
|
<ft-card class="relative watchVideoRecommendations">
|
||||||
<h3>
|
<h3>
|
||||||
Up Next
|
Up Next
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -7,8 +7,8 @@
|
||||||
v-for="(video, index) in data"
|
v-for="(video, index) in data"
|
||||||
:key="index"
|
:key="index"
|
||||||
:data="video"
|
:data="video"
|
||||||
|
appearance="recommendation"
|
||||||
force-list-type="list"
|
force-list-type="list"
|
||||||
class="videoRecommendation"
|
|
||||||
/>
|
/>
|
||||||
</ft-card>
|
</ft-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
$thumbnail-overlay-opacity: 0.85
|
||||||
|
|
||||||
|
@mixin is-result
|
||||||
|
@at-root
|
||||||
|
.result#{&}
|
||||||
|
@content
|
||||||
|
|
||||||
|
@mixin is-watch-playlist-item
|
||||||
|
@at-root
|
||||||
|
.watchPlaylistItem#{&}
|
||||||
|
@content
|
||||||
|
|
||||||
|
@mixin is-recommendation
|
||||||
|
@at-root
|
||||||
|
.recommendation#{&}
|
||||||
|
@content
|
||||||
|
|
||||||
|
@mixin is-sidebar-item
|
||||||
|
@at-root
|
||||||
|
.watchPlaylistItem#{&}, .recommendation#{&}
|
||||||
|
@content
|
||||||
|
|
||||||
|
.ft-list-video
|
||||||
|
.videoThumbnail
|
||||||
|
display: flex
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
.thumbnailLink
|
||||||
|
display: flex
|
||||||
|
|
||||||
|
.thumbnailImage
|
||||||
|
height: 130px
|
||||||
|
|
||||||
|
@include is-sidebar-item
|
||||||
|
height: 75px
|
||||||
|
|
||||||
|
@include is-recommendation
|
||||||
|
width: 163px
|
||||||
|
height: auto
|
||||||
|
|
||||||
|
.videoDuration
|
||||||
|
position: absolute
|
||||||
|
bottom: 4px
|
||||||
|
right: 4px
|
||||||
|
padding: 3px 4px
|
||||||
|
line-height: 1.2
|
||||||
|
font-size: 15px
|
||||||
|
border-radius: 5px
|
||||||
|
margin: 0
|
||||||
|
opacity: $thumbnail-overlay-opacity
|
||||||
|
color: var(--primary-text-color)
|
||||||
|
background-color: var(--card-bg-color)
|
||||||
|
|
||||||
|
&.live
|
||||||
|
background-color: #f22
|
||||||
|
color: #fff
|
||||||
|
|
||||||
|
.favoritesIcon
|
||||||
|
position: absolute
|
||||||
|
top: 3px
|
||||||
|
right: 3px
|
||||||
|
font-size: 17px
|
||||||
|
opacity: $thumbnail-overlay-opacity
|
||||||
|
|
||||||
|
.videoCountContainer
|
||||||
|
position: absolute
|
||||||
|
right: 0
|
||||||
|
top: 0
|
||||||
|
bottom: 0
|
||||||
|
width: 60px
|
||||||
|
font-size: 20px
|
||||||
|
|
||||||
|
.background, .inner
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
bottom: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
|
||||||
|
.background
|
||||||
|
background-color: var(--bg-color)
|
||||||
|
opacity: 0.9
|
||||||
|
|
||||||
|
.inner
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
justify-content: center
|
||||||
|
align-items: center
|
||||||
|
color: var(--primary-text-color)
|
||||||
|
|
||||||
|
.videoInfo
|
||||||
|
flex: 1
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
.optionsButton
|
||||||
|
float: right // ohhhh man, float was finally the right choice for something
|
||||||
|
|
||||||
|
.title
|
||||||
|
font-size: 20px
|
||||||
|
color: var(--primary-text-color)
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
@include is-sidebar-item
|
||||||
|
font-size: 15px
|
||||||
|
|
||||||
|
.infoLine
|
||||||
|
margin-top: 5px
|
||||||
|
font-size: 14px
|
||||||
|
|
||||||
|
@include is-sidebar-item
|
||||||
|
font-size: 12px
|
||||||
|
|
||||||
|
&, .channelName
|
||||||
|
color: var(--secondary-text-color)
|
||||||
|
|
||||||
|
.description
|
||||||
|
font-size: 14px
|
||||||
|
color: var(--secondary-text-color)
|
||||||
|
|
||||||
|
&.list
|
||||||
|
display: flex
|
||||||
|
align-items: flex-start
|
||||||
|
|
||||||
|
.videoThumbnail
|
||||||
|
margin-right: 20px
|
||||||
|
|
||||||
|
@include is-sidebar-item
|
||||||
|
margin-right: 10px
|
||||||
|
|
||||||
|
&.grid
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
min-height: 230px
|
||||||
|
padding-bottom: 20px
|
||||||
|
|
||||||
|
.videoThumbnail
|
||||||
|
margin-bottom: 12px
|
||||||
|
|
||||||
|
.thumbnailImage
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.title
|
||||||
|
font-size: 18px
|
||||||
|
|
||||||
|
.infoLine
|
||||||
|
margin-top: 8px
|
||||||
|
font-size: 13px
|
||||||
|
|
||||||
|
|
||||||
|
.videoWatched, .live
|
||||||
|
text-transform: uppercase
|
|
@ -12,4 +12,7 @@
|
||||||
.playlistItems {
|
.playlistItems {
|
||||||
float: right;
|
float: right;
|
||||||
width: 60%;
|
width: 60%;
|
||||||
|
padding: 10px;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,14 @@
|
||||||
v-if="!isLoading"
|
v-if="!isLoading"
|
||||||
class="playlistItems"
|
class="playlistItems"
|
||||||
>
|
>
|
||||||
<ft-flex-box>
|
|
||||||
<ft-list-video
|
<ft-list-video
|
||||||
v-for="(item, index) in playlistItems"
|
v-for="(item, index) in playlistItems"
|
||||||
:key="index"
|
:key="index"
|
||||||
:data="item"
|
:data="item"
|
||||||
:playlist-id="playlistId"
|
:playlist-id="playlistId"
|
||||||
|
appearance="result"
|
||||||
force-list-type="list"
|
force-list-type="list"
|
||||||
class="playlistItem"
|
|
||||||
/>
|
/>
|
||||||
</ft-flex-box>
|
|
||||||
</ft-card>
|
</ft-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -50,8 +50,10 @@
|
||||||
min-width: 380px
|
min-width: 380px
|
||||||
|
|
||||||
.watchVideoPlaylist, .watchVideoSidebar, .theatrePlaylist
|
.watchVideoPlaylist, .watchVideoSidebar, .theatrePlaylist
|
||||||
height: 500px
|
|
||||||
margin: 0 8px 16px
|
margin: 0 8px 16px
|
||||||
|
|
||||||
|
.watchVideoSidebar, .theatrePlaylist
|
||||||
|
height: 500px
|
||||||
|
|
||||||
.watchVideoRecommendations, .theatreRecommendations
|
.watchVideoRecommendations, .theatreRecommendations
|
||||||
margin: 0 8px 16px
|
margin: 0 8px 16px
|
||||||
|
|
Loading…
Reference in New Issue