forked from platypush/platypush
[Media UI] Extend YouTube video events to all media views.
These events should be available for all YouTube videos, regardless of where they are rendered: - `add-to-playlist` - `remove-from-playlist` - `download`
This commit is contained in:
parent
c416d0ea1f
commit
e180c9c76f
5 changed files with 83 additions and 30 deletions
|
@ -17,6 +17,10 @@
|
||||||
v-if="item.type !== 'torrent'" />
|
v-if="item.type !== 'torrent'" />
|
||||||
<DropdownItem icon-class="fa fa-download" text="Download" @click="$emit('download')"
|
<DropdownItem icon-class="fa fa-download" text="Download" @click="$emit('download')"
|
||||||
v-if="(item.type === 'torrent' || item.type === 'youtube') && item.item_type !== 'channel' && item.item_type !== 'playlist'" />
|
v-if="(item.type === 'torrent' || item.type === 'youtube') && item.item_type !== 'channel' && item.item_type !== 'playlist'" />
|
||||||
|
<DropdownItem icon-class="fa fa-list" text="Add to playlist" @click="$emit('add-to-playlist')"
|
||||||
|
v-if="item.type === 'youtube'" />
|
||||||
|
<DropdownItem icon-class="fa fa-trash" text="Remove from playlist" @click="$emit('remove-from-playlist')"
|
||||||
|
v-if="item.type === 'youtube' && playlist?.length" />
|
||||||
<DropdownItem icon-class="fa fa-window-maximize" text="View in browser" @click="$emit('view')"
|
<DropdownItem icon-class="fa fa-window-maximize" text="View in browser" @click="$emit('view')"
|
||||||
v-if="item.type === 'file'" />
|
v-if="item.type === 'file'" />
|
||||||
<DropdownItem icon-class="fa fa-info-circle" text="Info" @click="$emit('select')" />
|
<DropdownItem icon-class="fa fa-info-circle" text="Info" @click="$emit('select')" />
|
||||||
|
@ -48,7 +52,15 @@ import Utils from "@/Utils";
|
||||||
export default {
|
export default {
|
||||||
components: {Dropdown, DropdownItem, MediaImage},
|
components: {Dropdown, DropdownItem, MediaImage},
|
||||||
mixins: [Utils],
|
mixins: [Utils],
|
||||||
emits: ['play', 'select', 'view', 'download'],
|
emits: [
|
||||||
|
'add-to-playlist',
|
||||||
|
'download',
|
||||||
|
'play',
|
||||||
|
'remove-from-playlist',
|
||||||
|
'select',
|
||||||
|
'view',
|
||||||
|
],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
item: {
|
item: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -64,6 +76,10 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
playlist: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
<Subscriptions :filter="filter"
|
<Subscriptions :filter="filter"
|
||||||
:selected-channel="selectedChannel_"
|
:selected-channel="selectedChannel_"
|
||||||
|
@add-to-playlist="$emit('add-to-playlist', $event)"
|
||||||
|
@download="$emit('download', $event)"
|
||||||
@play="$emit('play', $event)"
|
@play="$emit('play', $event)"
|
||||||
@select="onChannelSelected"
|
@select="onChannelSelected"
|
||||||
v-else-if="selectedView === 'subscriptions'"
|
v-else-if="selectedView === 'subscriptions'"
|
||||||
|
@ -196,6 +198,7 @@ export default {
|
||||||
.body {
|
.body {
|
||||||
height: calc(100% - $media-nav-height - 2px);
|
height: calc(100% - $media-nav-height - 2px);
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -43,8 +43,10 @@
|
||||||
|
|
||||||
<Results :results="channel.items"
|
<Results :results="channel.items"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
:result-index-step="null"
|
||||||
:selected-result="selectedResult"
|
:selected-result="selectedResult"
|
||||||
ref="results"
|
ref="results"
|
||||||
|
@add-to-playlist="$emit('add-to-playlist', $event)"
|
||||||
@download="$emit('download', $event)"
|
@download="$emit('download', $event)"
|
||||||
@play="$emit('play', $event)"
|
@play="$emit('play', $event)"
|
||||||
@scroll-end="loadNextPage"
|
@scroll-end="loadNextPage"
|
||||||
|
@ -60,8 +62,13 @@ import Results from "@/components/panels/Media/Results";
|
||||||
import Utils from "@/Utils";
|
import Utils from "@/Utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['download', 'play'],
|
|
||||||
mixins: [Utils],
|
mixins: [Utils],
|
||||||
|
emits: [
|
||||||
|
'add-to-playlist',
|
||||||
|
'download',
|
||||||
|
'play',
|
||||||
|
],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Loading,
|
Loading,
|
||||||
Results,
|
Results,
|
||||||
|
@ -102,26 +109,47 @@ export default {
|
||||||
async loadChannel() {
|
async loadChannel() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
this.channel = await this.request('youtube.get_channel', {id: this.id})
|
await this.updateChannel(true)
|
||||||
this.subscribed = await this.request('youtube.is_subscribed', {channel_id: this.id})
|
this.subscribed = await this.request('youtube.is_subscribed', {channel_id: this.id})
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadNextPage() {
|
async updateChannel(init) {
|
||||||
if (!this.channel?.next_page_token || this.loadingNextPage)
|
const channel = await this.request(
|
||||||
return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const nextPage = await this.request(
|
|
||||||
'youtube.get_channel',
|
'youtube.get_channel',
|
||||||
{id: this.id, next_page_token: this.channel.next_page_token}
|
{id: this.id, next_page_token: this.channel?.next_page_token}
|
||||||
)
|
)
|
||||||
|
|
||||||
this.channel.items.push(...nextPage.items.filter(item => !this.itemsByUrl[item.url]))
|
const itemsByUrl = this.itemsByUrl || {}
|
||||||
this.channel.next_page_token = nextPage.next_page_token
|
let items = channel.items
|
||||||
this.$refs.results.maxResultIndex += this.$refs.results.resultIndexStep
|
.filter(item => !itemsByUrl[item.url])
|
||||||
|
.map(item => {
|
||||||
|
return {
|
||||||
|
type: 'youtube',
|
||||||
|
...item,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!init) {
|
||||||
|
items = this.channel.items.concat(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.channel = channel
|
||||||
|
this.channel.items = items
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadNextPage() {
|
||||||
|
if (!this.channel?.next_page_token || this.loadingNextPage) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadingNextPage = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.timeout(500)
|
||||||
|
await this.updateChannel()
|
||||||
} finally {
|
} finally {
|
||||||
this.loadingNextPage = false
|
this.loadingNextPage = false
|
||||||
}
|
}
|
||||||
|
@ -132,18 +160,6 @@ export default {
|
||||||
await this.request(`youtube.${action}`, {channel_id: this.id})
|
await this.request(`youtube.${action}`, {channel_id: this.id})
|
||||||
this.subscribed = !this.subscribed
|
this.subscribed = !this.subscribed
|
||||||
},
|
},
|
||||||
|
|
||||||
onScroll(e) {
|
|
||||||
const el = e.target
|
|
||||||
if (!el)
|
|
||||||
return
|
|
||||||
|
|
||||||
const bottom = (el.scrollHeight - el.scrollTop) <= el.clientHeight + 100
|
|
||||||
if (!bottom)
|
|
||||||
return
|
|
||||||
|
|
||||||
this.loadNextPage()
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -20,7 +20,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="subscription-body" v-else>
|
<div class="subscription-body" v-else>
|
||||||
<Channel :id="selectedChannel.id" :filter="filter" @play="$emit('play', $event)" />
|
<Channel
|
||||||
|
:id="selectedChannel.id"
|
||||||
|
:filter="filter"
|
||||||
|
@add-to-playlist="$emit('add-to-playlist', $event)"
|
||||||
|
@download="$emit('download', $event)"
|
||||||
|
@play="$emit('play', $event)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,8 +38,14 @@ import Loading from "@/components/Loading";
|
||||||
import Utils from "@/Utils";
|
import Utils from "@/Utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['play', 'select'],
|
|
||||||
mixins: [Utils],
|
mixins: [Utils],
|
||||||
|
emits: [
|
||||||
|
'add-to-playlist',
|
||||||
|
'download',
|
||||||
|
'play',
|
||||||
|
'select',
|
||||||
|
],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Channel,
|
Channel,
|
||||||
Loading,
|
Loading,
|
||||||
|
|
|
@ -90,14 +90,18 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
visibleResults() {
|
visibleResults() {
|
||||||
return this.results
|
let results = this.results
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
if (!this.filter)
|
if (!this.filter?.length)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
return item.title.toLowerCase().includes(this.filter.toLowerCase())
|
return item.title.toLowerCase().includes(this.filter.toLowerCase())
|
||||||
})
|
})
|
||||||
.slice(0, this.maxResultIndex)
|
|
||||||
|
if (this.maxResultIndex != null)
|
||||||
|
results = results.slice(0, this.maxResultIndex)
|
||||||
|
|
||||||
|
return results
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -112,6 +116,8 @@ export default {
|
||||||
return
|
return
|
||||||
|
|
||||||
this.$emit('scroll-end')
|
this.$emit('scroll-end')
|
||||||
|
|
||||||
|
if (this.resultIndexStep != null)
|
||||||
this.maxResultIndex += this.resultIndexStep
|
this.maxResultIndex += this.resultIndexStep
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue