Merge pull request #37 from cloudrac3r/rewrite-list-items
Rewrite list items
This commit is contained in:
commit
6221f80a52
|
@ -7,6 +7,13 @@
|
|||
"type": "npm",
|
||||
"script": "dev",
|
||||
"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 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 FtListChannel from '../ft-list-channel/ft-list-channel.vue'
|
||||
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
|
||||
|
@ -9,7 +9,7 @@ export default Vue.extend({
|
|||
name: 'FtElementList',
|
||||
components: {
|
||||
'ft-flex-box': FtFlexBox,
|
||||
'ft-grid': FtGrid,
|
||||
'ft-auto-grid': FtAutoGrid,
|
||||
'ft-list-video': FtListVideo,
|
||||
'ft-list-channel': FtListChannel,
|
||||
'ft-list-playlist': FtListPlaylist
|
||||
|
|
|
@ -1,49 +1,30 @@
|
|||
<template>
|
||||
<span>
|
||||
<ft-flex-box
|
||||
v-if="listType === 'list'"
|
||||
<ft-auto-grid
|
||||
:grid="listType !== 'list'"
|
||||
>
|
||||
<template
|
||||
v-for="(result, index) in data"
|
||||
>
|
||||
<span
|
||||
v-for="(result, index) in data"
|
||||
<ft-list-channel
|
||||
v-if="result.type === 'channel'"
|
||||
:key="index"
|
||||
class="maxWidth"
|
||||
>
|
||||
<ft-list-channel
|
||||
v-if="result.type === 'channel'"
|
||||
: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"
|
||||
appearance="result"
|
||||
:data="result"
|
||||
/>
|
||||
<ft-list-video
|
||||
v-if="result.type === 'video' || result.type === 'shortVideo'"
|
||||
:key="index"
|
||||
>
|
||||
<ft-list-channel
|
||||
v-if="result.type === 'channel'"
|
||||
: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-grid>
|
||||
</span>
|
||||
appearance="result"
|
||||
:data="result"
|
||||
/>
|
||||
<ft-list-playlist
|
||||
v-if="result.type === 'playlist'"
|
||||
:key="index"
|
||||
appearance="result"
|
||||
:data="result"
|
||||
/>
|
||||
</template>
|
||||
</ft-auto-grid>
|
||||
</template>
|
||||
|
||||
<script src="./ft-element-list.js" />
|
||||
|
|
|
@ -19,6 +19,14 @@ export default Vue.extend({
|
|||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
padding: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
forceDropdown: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
flex-flow: row wrap
|
||||
justify-content: space-evenly
|
||||
position: relative
|
||||
user-select: none
|
||||
|
||||
.iconButton
|
||||
width: 1em
|
||||
height: 1em
|
||||
padding: 10px
|
||||
font-size: 20px
|
||||
border-radius: 50%
|
||||
cursor: pointer
|
||||
transition: background 0.15s ease-out
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
secondary: theme === 'secondary',
|
||||
shadow: useShadow
|
||||
}"
|
||||
:style="{
|
||||
padding: padding + 'px',
|
||||
fontSize: size + 'px'
|
||||
}"
|
||||
@click="handleIconClick"
|
||||
/>
|
||||
<div
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
.channelThumbnail {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.channelThumbnail img {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
border-radius: 200px 200px 200px 200px;
|
||||
-webkit-border-radius: 200px 200px 200px 200px;
|
||||
}
|
||||
|
||||
.channelName {
|
||||
font-weight: bold;
|
||||
color: var(--title-color);
|
||||
cursor: pointer;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.subscriberCount {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.videoCount {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.grid {
|
||||
width: 240px;
|
||||
height: 250px;
|
||||
padding: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.grid .channelThumbnail {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.grid .channelThumbnail img {
|
||||
position: relative;
|
||||
left: 50px;
|
||||
}
|
||||
|
||||
.grid .channelName {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.list {
|
||||
height: 140px;
|
||||
width: 100%;
|
||||
margin-left: 5px;
|
||||
margin-top: 15px;
|
||||
border-bottom: 1px solid var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.list .channelThumbnail {
|
||||
float: left;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.list .channelThumbnail img {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
.list .channelName {
|
||||
margin-left: 250px;
|
||||
width: 275px;
|
||||
}
|
||||
|
||||
.list .subscriberCount {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.list .videoCount {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.list .description {
|
||||
margin-left: 250px;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
height: 35px;
|
||||
overflow: hidden;
|
||||
}
|
|
@ -6,6 +6,10 @@ export default Vue.extend({
|
|||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
appearance: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -32,10 +36,6 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
goToChannel: function () {
|
||||
this.$router.push({ path: `/channel/${this.id}` })
|
||||
},
|
||||
|
||||
parseLocalData: function () {
|
||||
this.thumbnail = this.data.avatar
|
||||
this.channelName = this.data.name
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
@use "../../sass-partials/_ft-list-item"
|
|
@ -1,40 +1,50 @@
|
|||
<template>
|
||||
<div
|
||||
class="ft-list-channel"
|
||||
:class="{ list: listType === 'list', grid: listType === 'grid' }"
|
||||
class="ft-list-channel ft-list-item"
|
||||
:class="{
|
||||
list: listType === 'list',
|
||||
grid: listType === 'grid',
|
||||
[appearance]: true
|
||||
}"
|
||||
>
|
||||
<div class="channelThumbnail">
|
||||
<img
|
||||
:src="thumbnail"
|
||||
@click="goToChannel(id)"
|
||||
<router-link
|
||||
:to="`/channel/${id}`"
|
||||
>
|
||||
<img
|
||||
:src="thumbnail"
|
||||
class="channelImage"
|
||||
>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="info">
|
||||
<router-link
|
||||
class="title"
|
||||
:to="`/channel/${id}`"
|
||||
>
|
||||
{{ channelName }}
|
||||
</router-link>
|
||||
<div class="infoLine">
|
||||
<span
|
||||
class="subscriberCount"
|
||||
>
|
||||
{{ subscriberCount }} subscribers
|
||||
</span>
|
||||
<span
|
||||
class="videoCount"
|
||||
>
|
||||
- {{ videoCount }} videos
|
||||
</span>
|
||||
</div>
|
||||
<p
|
||||
v-if="listType !== 'grid'"
|
||||
class="description"
|
||||
>
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<p
|
||||
class="channelName"
|
||||
@click="goToChannel(id)"
|
||||
>
|
||||
{{ channelName }}
|
||||
</p>
|
||||
<span
|
||||
class="subscriberCount"
|
||||
@click="goToChannel(id)"
|
||||
>
|
||||
{{ subscriberCount }} subscribers
|
||||
</span>
|
||||
<span
|
||||
class="videoCount"
|
||||
@click="goToChannel(id)"
|
||||
>
|
||||
- {{ videoCount }} videos
|
||||
</span>
|
||||
<p
|
||||
v-if="listType !== 'grid'"
|
||||
class="description"
|
||||
>
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./ft-list-channel.js" />
|
||||
<style scoped src="./ft-list-channel.css" />
|
||||
<style scoped lang="sass" src="./ft-list-channel.sass" />
|
||||
|
|
|
@ -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: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
appearance: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -58,14 +62,6 @@ export default Vue.extend({
|
|||
this.channelLink = this.data.author.ref
|
||||
this.playlistLink = this.data.link
|
||||
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>
|
||||
<div
|
||||
class="ft-list-video"
|
||||
class="ft-list-video ft-list-item"
|
||||
:appearance="appearance"
|
||||
:class="{ list: listType === 'list', grid: listType === 'grid' }"
|
||||
>
|
||||
<div class="videoThumbnail">
|
||||
<router-link
|
||||
class="videoThumbnail"
|
||||
:to="`/playlist/${playlistId}`"
|
||||
>
|
||||
<img
|
||||
:src="thumbnail"
|
||||
@click="goToPlaylist(playlistId)"
|
||||
class="thumbnailImage"
|
||||
>
|
||||
<div
|
||||
class="videoCountContainer"
|
||||
@click="goToPlaylist(playlistId)"
|
||||
>
|
||||
<span>
|
||||
{{ videoCount }}
|
||||
<br>
|
||||
<font-awesome-icon icon="list" />
|
||||
</span>
|
||||
<div class="background" />
|
||||
<div class="inner">
|
||||
<div>{{ videoCount }}</div>
|
||||
<div><font-awesome-icon icon="list" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
<div class="info">
|
||||
<router-link
|
||||
class="title"
|
||||
:to="`/playlist/${playlistId}`"
|
||||
>
|
||||
{{ title }}
|
||||
</router-link>
|
||||
<div class="infoLine">
|
||||
<router-link
|
||||
class="channelName"
|
||||
:to="`/channel/${channelId}`"
|
||||
>
|
||||
{{ channelName }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
class="playlistTitle"
|
||||
@click="goToPlaylist(playlistId)"
|
||||
>
|
||||
{{ title }}
|
||||
</p>
|
||||
<p
|
||||
class="channelName"
|
||||
@click="goToChannel(channelId)"
|
||||
>
|
||||
{{ channelName }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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;
|
||||
}
|
|
@ -18,6 +18,10 @@ export default Vue.extend({
|
|||
forceListType: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
appearance: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -121,31 +125,6 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
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 () {
|
||||
console.log('TODO: ft-list-video method toggleSave')
|
||||
},
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
@use "../../sass-partials/_ft-list-item"
|
|
@ -1,27 +1,39 @@
|
|||
<template>
|
||||
<div
|
||||
class="ft-list-video"
|
||||
class="ft-list-video ft-list-item"
|
||||
:class="{
|
||||
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">
|
||||
<img
|
||||
:src="thumbnail"
|
||||
@click="play(id)"
|
||||
<div
|
||||
class="videoThumbnail"
|
||||
>
|
||||
<router-link
|
||||
class="thumbnailLink"
|
||||
:to="{
|
||||
path: `/watch/${id}`,
|
||||
query: playlistId ? {playlistId} : {}
|
||||
}"
|
||||
>
|
||||
<p
|
||||
v-if="!isLive"
|
||||
<img
|
||||
:src="thumbnail"
|
||||
class="thumbnailImage"
|
||||
>
|
||||
</router-link>
|
||||
<div
|
||||
class="videoDuration"
|
||||
@click="play(id)"
|
||||
:class="{ live: isLive }"
|
||||
>
|
||||
{{ duration }}
|
||||
</p>
|
||||
<font-awesome-icon
|
||||
{{ isLive ? "Live" : duration }}
|
||||
</div>
|
||||
<ft-icon-button
|
||||
v-if="!isLive"
|
||||
icon="star"
|
||||
class="favoritesIcon"
|
||||
:padding="appearance === `watchPlaylistItem` ? 5 : 6"
|
||||
:size="appearance === `watchPlaylistItem` ? 14 : 18"
|
||||
:class="{ favorited: isFavorited }"
|
||||
@click="toggleSave(id)"
|
||||
/>
|
||||
|
@ -29,7 +41,7 @@
|
|||
v-if="watched"
|
||||
class="videoWatched"
|
||||
>
|
||||
WATCHED
|
||||
Watched
|
||||
</div>
|
||||
<div
|
||||
v-if="watched"
|
||||
|
@ -37,65 +49,56 @@
|
|||
:style="{width: progressPercentage + '%'}"
|
||||
/>
|
||||
</div>
|
||||
<ft-icon-button
|
||||
class="optionsButton"
|
||||
title="More Options"
|
||||
theme="base"
|
||||
:use-shadow="false"
|
||||
dropdown-position-x="left"
|
||||
:dropdown-names="optionsNames"
|
||||
:dropdown-values="optionsValues"
|
||||
@click="handleOptionsClick"
|
||||
/>
|
||||
<p
|
||||
class="videoTitle"
|
||||
@click="play(id)"
|
||||
>
|
||||
{{ title }}
|
||||
</p>
|
||||
<p
|
||||
class="channelName"
|
||||
@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"
|
||||
@click="play(id)"
|
||||
>
|
||||
{{ description }}
|
||||
</p>
|
||||
<span
|
||||
v-if="isLive"
|
||||
class="liveText"
|
||||
@click="play(id)"
|
||||
>
|
||||
LIVE NOW
|
||||
</span>
|
||||
<div class="info">
|
||||
<ft-icon-button
|
||||
class="optionsButton"
|
||||
title="More Options"
|
||||
theme="base"
|
||||
:size="16"
|
||||
:use-shadow="false"
|
||||
dropdown-position-x="left"
|
||||
:dropdown-names="optionsNames"
|
||||
:dropdown-values="optionsValues"
|
||||
@click="handleOptionsClick"
|
||||
/>
|
||||
<router-link
|
||||
class="title"
|
||||
:to="{
|
||||
path: `/watch/${id}`,
|
||||
query: playlistId ? {playlistId} : {}
|
||||
}"
|
||||
>
|
||||
{{ title }}
|
||||
</router-link>
|
||||
<div class="infoLine">
|
||||
<router-link
|
||||
class="channelName"
|
||||
:to="`/channel/${channelId}`"
|
||||
>
|
||||
<span>{{ channelName }}</span>
|
||||
</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
|
||||
v-if="listType !== 'grid' && appearance === 'result'"
|
||||
class="description"
|
||||
>
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./ft-list-video.js" />
|
||||
<style scoped src="./ft-list-video.css" />
|
||||
<style scoped src="./ft-list-video.sass" lang="sass" />
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
.maxWidth {
|
||||
width: 100%;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import Vue from 'vue'
|
||||
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
||||
import FtGrid from '../ft-grid/ft-grid.vue'
|
||||
import FtListVideo from '../ft-list-video/ft-list-video.vue'
|
||||
import FtListChannel from '../ft-list-channel/ft-list-channel.vue'
|
||||
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'WatchPlaylist',
|
||||
components: {
|
||||
'ft-flex-box': FtFlexBox,
|
||||
'ft-grid': FtGrid,
|
||||
'ft-list-video': FtListVideo,
|
||||
'ft-list-channel': FtListChannel,
|
||||
'ft-list-playlist': FtListPlaylist
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
test: 'hello'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
listType: function () {
|
||||
return this.$store.getters.getListType
|
||||
}
|
||||
}
|
||||
})
|
|
@ -1,50 +0,0 @@
|
|||
<template>
|
||||
<span>
|
||||
<ft-flex-box
|
||||
v-if="listType === 'list'"
|
||||
>
|
||||
<span
|
||||
v-for="(result, index) in data"
|
||||
:key="index"
|
||||
class="maxWidth"
|
||||
>
|
||||
<ft-list-channel
|
||||
v-if="result.type === 'channel'"
|
||||
: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"
|
||||
>
|
||||
<ft-list-channel
|
||||
v-if="result.type === 'channel'"
|
||||
: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-grid>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script src="./watch-playlist.js" />
|
||||
<style scoped src="./watch-playlist.css" />
|
|
@ -37,36 +37,34 @@
|
|||
.playlistItems {
|
||||
overflow-y: auto;
|
||||
height: 395px;
|
||||
margin-top: -15px;
|
||||
margin-left: -16px;
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
.playlistItem {
|
||||
height: 75px;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 30px 1fr;
|
||||
align-items: center;
|
||||
transition: background 0.2s ease-out;
|
||||
}
|
||||
|
||||
.playlistItem:not(:last-child) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.playlistItem:hover {
|
||||
background-color: var(--side-nav-hover-color);
|
||||
transition: background 0.2s ease-in;
|
||||
}
|
||||
|
||||
.videoIndexContainer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.videoIndex {
|
||||
float: left;
|
||||
position: relative;
|
||||
top: 15px;
|
||||
left: 10px;
|
||||
color: var(--tertiary-text-color);
|
||||
}
|
||||
|
||||
.videoIndexIcon {
|
||||
float: left;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
top: 32px;
|
||||
left: 10px;
|
||||
color: var(--tertiary-text-color);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
@click="playNextVideo"
|
||||
/>
|
||||
</p>
|
||||
<ft-flex-box
|
||||
<div
|
||||
v-if="!isLoading"
|
||||
class="playlistItems"
|
||||
>
|
||||
|
@ -56,25 +56,27 @@
|
|||
:key="index"
|
||||
class="playlistItem"
|
||||
>
|
||||
<font-awesome-icon
|
||||
v-if="item.videoId === videoId"
|
||||
class="videoIndexIcon"
|
||||
icon="play"
|
||||
/>
|
||||
<p
|
||||
v-else
|
||||
class="videoIndex"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</p>
|
||||
<div class="videoIndexContainer">
|
||||
<font-awesome-icon
|
||||
v-if="item.videoId === videoId"
|
||||
class="videoIndexIcon"
|
||||
icon="play"
|
||||
/>
|
||||
<p
|
||||
v-else
|
||||
class="videoIndex"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</p>
|
||||
</div>
|
||||
<ft-list-video
|
||||
:data="item"
|
||||
:playlist-id="playlistId"
|
||||
appearance="watchPlaylistItem"
|
||||
force-list-type="list"
|
||||
class="videoInfo"
|
||||
/>
|
||||
</div>
|
||||
</ft-flex-box>
|
||||
</div>
|
||||
</div>
|
||||
</ft-card>
|
||||
</template>
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.videoRecommendation {
|
||||
margin-bottom: -15px;
|
||||
.watchVideoRecommendations {
|
||||
display: grid;
|
||||
grid-gap: 8px;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ft-card class="relative">
|
||||
<ft-card class="relative watchVideoRecommendations">
|
||||
<h3>
|
||||
Up Next
|
||||
</h3>
|
||||
|
@ -7,8 +7,8 @@
|
|||
v-for="(video, index) in data"
|
||||
:key="index"
|
||||
:data="video"
|
||||
appearance="recommendation"
|
||||
force-list-type="list"
|
||||
class="videoRecommendation"
|
||||
/>
|
||||
</ft-card>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
$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-item
|
||||
.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)
|
||||
pointer-events: none
|
||||
|
||||
&.live
|
||||
background-color: #f22
|
||||
color: #fff
|
||||
|
||||
@include is-watch-playlist-item
|
||||
font-size: 12px
|
||||
|
||||
.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)
|
||||
|
||||
.channelThumbnail
|
||||
display: flex
|
||||
justify-content: center
|
||||
|
||||
.channelImage
|
||||
height: 130px
|
||||
border-radius: 50%
|
||||
|
||||
.info
|
||||
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, .channelThumbnail
|
||||
margin-right: 20px
|
||||
|
||||
.channelThumbnail
|
||||
width: 231px
|
||||
|
||||
@include is-sidebar-item
|
||||
.videoThumbnail
|
||||
margin-right: 10px
|
||||
|
||||
&.grid
|
||||
display: flex
|
||||
flex-direction: column
|
||||
min-height: 230px
|
||||
padding-bottom: 20px
|
||||
|
||||
.videoThumbnail, .channelThumbnail
|
||||
margin-bottom: 12px
|
||||
|
||||
.thumbnailImage
|
||||
width: 100%
|
||||
|
||||
.title
|
||||
font-size: 18px
|
||||
|
||||
.infoLine
|
||||
margin-top: 8px
|
||||
font-size: 13px
|
||||
|
||||
.videoWatched, .live
|
||||
text-transform: uppercase
|
|
@ -123,4 +123,5 @@
|
|||
line-height: 45px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
|
|
@ -12,4 +12,7 @@
|
|||
.playlistItems {
|
||||
float: right;
|
||||
width: 60%;
|
||||
padding: 10px;
|
||||
display: grid;
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
|
|
@ -13,16 +13,14 @@
|
|||
v-if="!isLoading"
|
||||
class="playlistItems"
|
||||
>
|
||||
<ft-flex-box>
|
||||
<ft-list-video
|
||||
v-for="(item, index) in playlistItems"
|
||||
:key="index"
|
||||
:data="item"
|
||||
:playlist-id="playlistId"
|
||||
force-list-type="list"
|
||||
class="playlistItem"
|
||||
/>
|
||||
</ft-flex-box>
|
||||
<ft-list-video
|
||||
v-for="(item, index) in playlistItems"
|
||||
:key="index"
|
||||
:data="item"
|
||||
:playlist-id="playlistId"
|
||||
appearance="result"
|
||||
force-list-type="list"
|
||||
/>
|
||||
</ft-card>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
line-height: 45px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
|
|
|
@ -50,8 +50,10 @@
|
|||
min-width: 380px
|
||||
|
||||
.watchVideoPlaylist, .watchVideoSidebar, .theatrePlaylist
|
||||
height: 500px
|
||||
margin: 0 8px 16px
|
||||
|
||||
.watchVideoSidebar, .theatrePlaylist
|
||||
height: 500px
|
||||
|
||||
.watchVideoRecommendations, .theatreRecommendations
|
||||
margin: 0 8px 16px
|
||||
|
|
Loading…
Reference in New Issue