Merge branch master into rewrite-watch-video-info

This commit is contained in:
Cadence Ember 2020-06-17 04:11:23 +12:00
commit 8e76badbc7
No known key found for this signature in database
GPG Key ID: 128B99B1B74A6412
10 changed files with 312 additions and 70 deletions

24
package-lock.json generated
View File

@ -17807,8 +17807,7 @@
}, },
"minimist": { "minimist": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true "dev": true
}, },
"schema-utils": { "schema-utils": {
@ -19349,9 +19348,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "3.9.3", "version": "3.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
"integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==", "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==",
"dev": true "dev": true
}, },
"underscore": { "underscore": {
@ -20409,8 +20408,7 @@
}, },
"minimist": { "minimist": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true "dev": true
}, },
"string-width": { "string-width": {
@ -21175,9 +21173,9 @@
} }
}, },
"ytdl-core": { "ytdl-core": {
"version": "3.1.0", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-3.1.0.tgz", "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-3.1.1.tgz",
"integrity": "sha512-3dDIugHLusJ5vXnII4bYrSWLwKPVxPL+nvVl2YS7Jgi0ui6I9RBODKXSu6Xttysvc0HN60QOcDeDFTKmUs92Bg==", "integrity": "sha512-sHw8Vz56Bs7LRKhJARW8j2JREndHFBuEdnYKgjx4RHwh1t75TsdZ5/SRpz9TLkNm2M5S8gVwvWm7AD1blhjb0g==",
"requires": { "requires": {
"html-entities": "^1.3.1", "html-entities": "^1.3.1",
"m3u8stream": "^0.7.1", "m3u8stream": "^0.7.1",
@ -21194,9 +21192,9 @@
} }
}, },
"ytsr": { "ytsr": {
"version": "0.1.14", "version": "0.1.15",
"resolved": "https://registry.npmjs.org/ytsr/-/ytsr-0.1.14.tgz", "resolved": "https://registry.npmjs.org/ytsr/-/ytsr-0.1.15.tgz",
"integrity": "sha512-YlLIDRPVUBOXnBjW6RytxpzC8g5ieqwjzcdrmmgdvTmVD/iisvNBPO5LhqB7R0kbuNHjFW6FBYpCTvCF1gCrHA==", "integrity": "sha512-oOzklBMlRn4SVODMPG/McgX78R5pVBio32TPAoZtP2LBGo/glIbf+QqH8FXbkzIc03Qzp4tsEtQAHOJzg1noFg==",
"requires": { "requires": {
"html-entities": "^1.1.3" "html-entities": "^1.1.3"
} }

View File

@ -39,9 +39,9 @@
"youtube-comments-task": "^1.3.15", "youtube-comments-task": "^1.3.15",
"youtube-suggest": "^1.1.0", "youtube-suggest": "^1.1.0",
"yt-xml2vtt": "^1.0.1", "yt-xml2vtt": "^1.0.1",
"ytdl-core": "^3.1.0", "ytdl-core": "^3.1.1",
"ytpl": "^0.1.21", "ytpl": "^0.1.21",
"ytsr": "^0.1.14" "ytsr": "^0.1.15"
}, },
"description": "A private YouTube client", "description": "A private YouTube client",
"devDependencies": { "devDependencies": {
@ -84,7 +84,7 @@
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"style-loader": "^1.2.1", "style-loader": "^1.2.1",
"tree-kill": "1.2.2", "tree-kill": "1.2.2",
"typescript": "^3.9.3", "typescript": "^3.9.5",
"url-loader": "^4.1.0", "url-loader": "^4.1.0",
"vue-devtools": "^5.1.3", "vue-devtools": "^5.1.3",
"vue-eslint-parser": "^7.1.0", "vue-eslint-parser": "^7.1.0",

View File

@ -0,0 +1,113 @@
.ftIconButton {
display: flex;
flex-flow: row wrap;
justify-content: space-evenly;
position: relative;
}
.iconButton {
width: 1em;
height: 1em;
padding: 10px;
font-size: 20px;
border-radius: 50%;
box-shadow: 0 1px 2px rgba(0,0,0,.5);
cursor: pointer;
-moz-transition: background 0.2s ease-out;
-o-transition: background 0.2s ease-out;
transition: background 0.2s ease-out;
}
.iconButton:hover {
-moz-transition: background 0.2s ease-in;
-o-transition: background 0.2s ease-in;
transition: background 0.2s ease-in;
}
.base {
background-color: var(--card-bg-color);
color: var(--primary-text-color);
}
.base:hover {
background-color: var(--side-nav-hover-color);
}
.base:active {
background-color: var(--side-nav-active-color);
}
.primary {
background-color: var(--primary-color);
color: var(--text-with-main-color);
}
.primary:hover {
background-color: var(--primary-color-hover);
}
.primary:active {
background-color: var(--primary-color-active);
}
.secondary {
background-color: var(--accent-color);
color: var(--text-with-accent-color);
}
.secondary:hover {
background-color: var(--accent-color-hover);
}
.secondary:active {
background-color: var(--accent-color-active);
}
.iconDropdown {
position: absolute;
text-align: center;
list-style-type: none;
z-index: 100;
margin-top: 45px;
font-size: 12px;
box-shadow: 0 1px 2px rgba(0,0,0,.5);
background-color: var(--card-bg-color);
color: var(--secondary-text-color);
}
.iconDropdown p {
padding: 10px;
margin: 0;
white-space: nowrap;
cursor: pointer;
-moz-transition: background 0.2s ease-out;
-o-transition: background 0.2s ease-out;
transition: background 0.2s ease-out;
}
.iconDropdown p:hover {
background-color: var(--side-nav-hover-color);
-moz-transition: background 0.2s ease-in;
-o-transition: background 0.2s ease-in;
transition: background 0.2s ease-in;
}
.iconDropdown p:active {
background-color: var(--side-nav-active-color);
-moz-transition: background 0.1s ease-in;
-o-transition: background 0.1s ease-in;
transition: background 0.1s ease-in;
}
.iconDropdown p a {
text-decoration: none;
color: inherit;
}
.left {
right: 100%;
}
.right {
left: 100%;
}

View File

@ -0,0 +1,54 @@
import Vue from 'vue'
export default Vue.extend({
name: 'FtIconButton',
props: {
title: {
type: String,
default: ''
},
icon: {
type: String,
default: 'ellipsis-v'
},
theme: {
type: String,
default: 'base'
},
dropdownPosition: {
type: String,
default: 'center'
},
dropdownNames: {
type: Array,
default: () => { return [] }
},
dropdownValues: {
type: Array,
default: () => { return [] }
}
},
data: function () {
return {
showDropdown: false
}
},
methods: {
toggleDropdown: function () {
this.showDropdown = !this.showDropdown
},
handleIconClick: function () {
if (this.dropdownNames.length > 0 && this.dropdownValues.length > 0) {
this.toggleDropdown()
} else {
this.$emit('click')
}
},
handleDropdownClick: function (index) {
this.toggleDropdown()
this.$emit('click', this.dropdownValues[index])
}
}
})

View File

@ -0,0 +1,35 @@
<template>
<div class="ftIconButton">
<font-awesome-icon
class="iconButton"
:title="title"
:icon="icon"
:class="{
base: theme === 'base',
primary: theme === 'primary',
secondary: theme === 'secondary'
}"
@click="handleIconClick"
/>
<div
v-if="dropdownNames.length > 0 && showDropdown"
class="iconDropdown"
:class="{
left: dropdownPosition === 'left',
right: dropdownPosition === 'right',
center: dropdownPosition === 'center'
}"
>
<p
v-for="(label, index) in dropdownNames"
:key="index"
@click="handleDropdownClick(index)"
>
{{ label }}
</p>
</div>
</div>
</template>
<script src="./ft-icon-button.js" />
<style scoped src="./ft-icon-button.css" />

View File

@ -3,6 +3,7 @@ import FtCard from '../ft-card/ft-card.vue'
import FtButton from '../ft-button/ft-button.vue' import FtButton from '../ft-button/ft-button.vue'
import FtListDropdown from '../ft-list-dropdown/ft-list-dropdown.vue' import FtListDropdown from '../ft-list-dropdown/ft-list-dropdown.vue'
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
// import { shell } from 'electron' // import { shell } from 'electron'
export default Vue.extend({ export default Vue.extend({
@ -11,7 +12,8 @@ export default Vue.extend({
'ft-card': FtCard, 'ft-card': FtCard,
'ft-button': FtButton, 'ft-button': FtButton,
'ft-list-dropdown': FtListDropdown, 'ft-list-dropdown': FtListDropdown,
'ft-flex-box': FtFlexBox 'ft-flex-box': FtFlexBox,
'ft-icon-button': FtIconButton
}, },
props: { props: {
id: { id: {

View File

@ -41,7 +41,7 @@
grid-template-columns: auto auto grid-template-columns: auto auto
justify-content: space-between justify-content: space-between
margin-left: auto margin-left: auto
max-width: 250px max-width: 210px
@media screen and (max-width: 680px) @media screen and (max-width: 680px)
margin-left: 0 margin-left: 0
@ -53,22 +53,17 @@
grid-column: 1 / 3 grid-column: 1 / 3
margin-bottom: 4px margin-bottom: 4px
.optionsContainer .videoOptions
margin-top: 16px margin-top: 16px
display: flex display: flex
justify-content: flex-end justify-content: flex-end
.option:not(:first-child)
margin-left: 4px
@media screen and (max-width: 680px) @media screen and (max-width: 680px)
justify-content: flex-start justify-content: flex-start
.option @media only screen and (max-width: 1350px)
width: 36px .theatreModeButton
height: 36px display: none
border-radius: 50%
background-color: rgba(255, 255, 255, 0.15)
display: flex
align-items: center
justify-content: center
&:not(:last-child)
margin-right: 4px

View File

@ -40,47 +40,45 @@
<p class="viewCount"> <p class="viewCount">
{{ parsedViewCount }} {{ parsedViewCount }}
</p> </p>
<div <div class="likeBarContainer">
class="likeSection"
>
<div <div
class="likeBar" class="likeSection"
:style="{ background: `linear-gradient(to right, var(--accent-color) ${likePercentageRatio}%, #9E9E9E ${likePercentageRatio}%` }" >
></div> <div
<div class="likeCount">👍 {{ likeCount }}</div> class="likeBar"
<div class="dislikeCount">{{ dislikeCount }} 👎</div> :style="{ background: `linear-gradient(to right, var(--accent-color) ${likePercentageRatio}%, #9E9E9E ${likePercentageRatio}%` }"
</div> ></div>
<!-- <div class="likeCount">👍 {{ likeCount }}</div>
<ft-flex-box class="videoOptions"> <div class="dislikeCount">{{ dislikeCount }} 👎</div>
<ft-button
label="Toggle Theatre Mode"
class="theatreModeButton"
@click="$emit('theatreMode')"
/>
<ft-list-dropdown
:title="formatTypeLabel"
:label-names="formatTypeNames"
:label-values="formatTypeValues"
class="formatTypeDropdown"
@click="handleFormatChange"
/>
<ft-list-dropdown
:title="shareLabel"
:label-names="shareNames"
:label-values="shareValues"
class="shareDropdown"
@click="handleShare"
/>
</ft-flex-box>
-->
<div class="optionsContainer">
<div v-for="i in [`download`, `star`, `bookmark`, `share`]" :key="i" class="option">
<font-awesome-icon
class="refreshIcon"
:icon="i"
/>
</div> </div>
</div> </div>
<div class="videoOptions">
<ft-icon-button
title="Toggle Theatre Mode"
class="theatreModeButton option"
icon="expand-alt"
theme="secondary"
@click="$emit('theatreMode')"
/>
<ft-icon-button
title="Change Video Formats"
class="option"
theme="secondary"
icon="file-video"
:dropdown-names="formatTypeNames"
:dropdown-values="formatTypeValues"
@click="handleFormatChange"
/>
<ft-icon-button
title="Share Video"
class="option"
theme="secondary"
icon="share-alt"
:dropdown-names="shareNames"
:dropdown-values="shareValues"
@click="handleShare"
/>
</div>
</div> </div>
</ft-card> </ft-card>
</template> </template>

View File

@ -200,6 +200,8 @@
.secRed { .secRed {
--accent-color: #f44336; --accent-color: #f44336;
--accent-color-hover: #e53935;
--accent-color-active: #c62828;
--accent-color-light: #ef9a9a; --accent-color-light: #ef9a9a;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(244,67,54,0.04); --accent-color-opacity1: rgba(244,67,54,0.04);
@ -210,6 +212,8 @@
.secPink { .secPink {
--accent-color: #E91E63; --accent-color: #E91E63;
--accent-color-hover: #D81B60;
--accent-color-active: #AD1457;
--accent-color-light: #F48FB1; --accent-color-light: #F48FB1;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(233,30,99,0.04); --accent-color-opacity1: rgba(233,30,99,0.04);
@ -220,6 +224,8 @@
.secPurple { .secPurple {
--accent-color: #9C27B0; --accent-color: #9C27B0;
--accent-color-hover: #8E24AA;
--accent-color-active: #6A1B9A;
--accent-color-light: #CE93D8; --accent-color-light: #CE93D8;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(156,39,176,0.04); --accent-color-opacity1: rgba(156,39,176,0.04);
@ -230,6 +236,8 @@
.secDeepPurple { .secDeepPurple {
--accent-color: #673AB7; --accent-color: #673AB7;
--accent-color-hover: #5E35B1;
--accent-color-active: #4527A0;
--accent-color-light: #B39DDB; --accent-color-light: #B39DDB;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(103,58,183,0.04); --accent-color-opacity1: rgba(103,58,183,0.04);
@ -240,6 +248,8 @@
.secIndigo { .secIndigo {
--accent-color: #3F51B5; --accent-color: #3F51B5;
--accent-color-hover: #3949AB;
--accent-color-active: #283593;
--accent-color-light: #9FA8DA; --accent-color-light: #9FA8DA;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(63,81,181,0.04); --accent-color-opacity1: rgba(63,81,181,0.04);
@ -250,6 +260,8 @@
.secBlue { .secBlue {
--accent-color: #2196F3; --accent-color: #2196F3;
--accent-color-hover: #1E88E5;
--accent-color-active: #1565C0;
--accent-color-light: #90CAF9; --accent-color-light: #90CAF9;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(33,150,243,0.04); --accent-color-opacity1: rgba(33,150,243,0.04);
@ -260,6 +272,8 @@
.secLightBlue { .secLightBlue {
--accent-color: #03A9F4; --accent-color: #03A9F4;
--accent-color-hover: #039BE5;
--accent-color-active: #0277BD;
--accent-color-light: #81D4FA; --accent-color-light: #81D4FA;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(3,169,244,0.04); --accent-color-opacity1: rgba(3,169,244,0.04);
@ -270,6 +284,8 @@
.secCyan { .secCyan {
--accent-color: #00BCD4; --accent-color: #00BCD4;
--accent-color-hover: #00ACC1;
--accent-color-active: #00838F;
--accent-color-light: #80DEEA; --accent-color-light: #80DEEA;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(0,188,212,0.04); --accent-color-opacity1: rgba(0,188,212,0.04);
@ -280,6 +296,8 @@
.secTeal { .secTeal {
--accent-color: #009688; --accent-color: #009688;
--accent-color-hover: #00897B;
--accent-color-active: #00695C;
--accent-color-light: #80CBC4; --accent-color-light: #80CBC4;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(0,150,136,0.04); --accent-color-opacity1: rgba(0,150,136,0.04);
@ -290,6 +308,8 @@
.secGreen { .secGreen {
--accent-color: #4CAF50; --accent-color: #4CAF50;
--accent-color-hover: #43A047;
--accent-color-active: #2E7D32;
--accent-color-light: #A5D6A7; --accent-color-light: #A5D6A7;
--text-with-accent-color: #FFFFFF; --text-with-accent-color: #FFFFFF;
--accent-color-opacity1: rgba(76,175,80,0.04); --accent-color-opacity1: rgba(76,175,80,0.04);
@ -300,6 +320,8 @@
.secLightGreen { .secLightGreen {
--accent-color: #8BC34A; --accent-color: #8BC34A;
--accent-color-hover: #7CB342;
--accent-color-active: #558B2F;
--accent-color-light: #C5E1A5; --accent-color-light: #C5E1A5;
--text-with-accent-color: #000000; --text-with-accent-color: #000000;
--accent-color-opacity1: rgba(139,195,74,0.04); --accent-color-opacity1: rgba(139,195,74,0.04);
@ -310,6 +332,8 @@
.secLime { .secLime {
--accent-color: #CDDC39; --accent-color: #CDDC39;
--accent-color-hover: #C0CA33;
--accent-color-active: #9E9D24;
--accent-color-light: #E6EE9C; --accent-color-light: #E6EE9C;
--text-with-accent-color: #000000; --text-with-accent-color: #000000;
--accent-color-opacity1: rgba(205,220,57,0.04); --accent-color-opacity1: rgba(205,220,57,0.04);
@ -320,6 +344,8 @@
.secYellow { .secYellow {
--accent-color: #FFEB3B; --accent-color: #FFEB3B;
--accent-color-hover: #FDD835;
--accent-color-active: #F9A825;
--accent-color-light: #FFF59D; --accent-color-light: #FFF59D;
--text-with-accent-color: #000000; --text-with-accent-color: #000000;
--accent-color-opacity1: rgba(255,235,59,0.04); --accent-color-opacity1: rgba(255,235,59,0.04);
@ -330,6 +356,8 @@
.secAmber { .secAmber {
--accent-color: #FFC107; --accent-color: #FFC107;
--accent-color-hover: #FFB300;
--accent-color-active: #FF8F00;
--accent-color-light: #FFE082; --accent-color-light: #FFE082;
--text-with-accent-color: #000000; --text-with-accent-color: #000000;
--accent-color-opacity1: rgba(255,193,7,0.04); --accent-color-opacity1: rgba(255,193,7,0.04);
@ -340,6 +368,8 @@
.secOrange { .secOrange {
--accent-color: #FF9800; --accent-color: #FF9800;
--accent-color-hover: #FB8C00;
--accent-color-active: #EF6C00;
--accent-color-light: #FFCC80; --accent-color-light: #FFCC80;
--text-with-accent-color: #000000; --text-with-accent-color: #000000;
--accent-color-opacity1: rgba(255,152,0,0.04); --accent-color-opacity1: rgba(255,152,0,0.04);
@ -350,6 +380,8 @@
.secDeepOrange { .secDeepOrange {
--accent-color: #FF5722; --accent-color: #FF5722;
--accent-color-hover: #F4511E;
--accent-color-active: #D84315;
--accent-color-light: #FFAB91; --accent-color-light: #FFAB91;
--text-with-accent-color: #000000; --text-with-accent-color: #000000;
--accent-color-opacity1: rgba(255,87,34,0.04); --accent-color-opacity1: rgba(255,87,34,0.04);

View File

@ -232,14 +232,29 @@ export default Vue.extend({
if (typeof (format.mimeType) !== 'undefined') { if (typeof (format.mimeType) !== 'undefined') {
return format.mimeType.includes('video/ts') return format.mimeType.includes('video/ts')
} }
return format.itag === 300 || format.itag === 301
}).map((format) => { }).map((format) => {
let qualityLabel
if (format.itag === 300) {
qualityLabel = '720p'
} else if (format.itag === 301) {
qualityLabel = '1080p'
} else {
qualityLabel = format.qualityLabel
}
return { return {
url: format.url, url: format.url,
type: 'application/x-mpegURL', type: 'application/x-mpegURL',
label: 'Dash', label: 'Dash',
qualityLabel: format.qualityLabel qualityLabel: qualityLabel
} }
}).reverse() }).sort((a, b) => {
const qualityA = parseInt(a.qualityLabel.replace('p', ''))
const qualityB = parseInt(b.qualityLabel.replace('p', ''))
return qualityA - qualityB
})
this.activeSourceList = this.videoSourceList this.activeSourceList = this.videoSourceList
} else { } else {