-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added: New `Collection` column type for live channels. This lets you add columns for the `/collection/` directory pages, such as: "Hype Trains Happening Right Now" (`hype-train`), "Speedrunning" (`speedrun-challenge-run`), "It's Indie Game Time" (`indie-game-streams`), "Verified Charity Streams" (`verified-charity`), etc.
- Loading branch information
1 parent
c194ac6
commit 0abcb55
Showing
5 changed files
with
205 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#import "../fragments/stream-info.gql" | ||
#import "../fragments/stream-broadcaster.gql" | ||
|
||
query Deck_LiveCollection($slug: String!, $first: Int, $after: Cursor, $options: BrowsableCollectionStreamsOptions, $previewWidth: Int, $previewHeight: Int) { | ||
collection: browsableCollection(input: {slug: $slug}) { | ||
id | ||
slug | ||
name { | ||
fallbackLocalizedTitle | ||
} | ||
description { | ||
fallbackLocalizedTitle | ||
} | ||
streams(first: $first, after: $after, options: $options) { | ||
pageInfo { | ||
hasNextPage | ||
} | ||
edges { | ||
cursor | ||
node { | ||
...StreamInfo | ||
...StreamBroadcaster | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
const {get, deep_copy} = FrankerFaceZ.utilities.object; | ||
|
||
import { LiveColumnBase } from '../../column-base'; | ||
import { getLoader, cleanViewersCount, cleanTags, checkCosmetics } from '../../data'; | ||
|
||
export default class Collection extends LiveColumnBase { | ||
|
||
getEditComponent() { | ||
return [ | ||
'bd-edit-collection' | ||
]; | ||
} | ||
|
||
showGameLine() { | ||
return true; | ||
} | ||
|
||
useIcon() { | ||
return true; | ||
} | ||
|
||
getTitle() { | ||
if ( ! this.settings.slug ) | ||
return ['addon.deck.unset', '(Unset)']; | ||
|
||
let name = this.settings.slug; | ||
if ( this.cache && this.cache.displayName ) | ||
name = this.cache.displayName; | ||
|
||
return ['addon.deck.live-category', '{name} Streams', {name}]; | ||
} | ||
|
||
canRun() { | ||
return !! this.settings.slug | ||
} | ||
|
||
reset() { | ||
super.reset(); | ||
this.seen = null; | ||
} | ||
|
||
async load(first = 10, cursor = null) { | ||
if ( first > 100 ) | ||
first = 100; | ||
|
||
const data = await getLoader().queryApollo({ | ||
query: require('./collection.gql'), | ||
variables: { | ||
slug: this.settings.slug, | ||
first, | ||
after: cursor, | ||
options: { | ||
requestID: 'twilight-browsable-collections', | ||
recommendationsContext: { | ||
platform: 'web' | ||
}, | ||
broadcasterLanguages: this.languages | ||
} | ||
}, | ||
fetchPolicy: 'network-only' | ||
}); | ||
|
||
this.updateCache({ | ||
displayName: get('data.collection.name.fallbackLocalizedTitle', data), | ||
description: get('data.collection.description.fallbackLocalizedTitle', data) | ||
}); | ||
|
||
const edges = get('data.collection.streams.edges', data), | ||
seen = this.seen = this.seen || new Set, | ||
items = []; | ||
|
||
cursor = null; | ||
|
||
if ( Array.isArray(edges) ) | ||
for(const edge of edges) { | ||
cursor = edge.cursor; | ||
if ( edge.node && edge.node.broadcaster && ! seen.has(edge.node.id) ) { | ||
seen.add(edge.node.id); | ||
const node = deep_copy(edge.node); | ||
cleanViewersCount(node, edge.node); | ||
checkCosmetics(node.broadcaster); | ||
|
||
node.broadcaster.stream = node; | ||
cleanTags(node); | ||
items.push(node.broadcaster); | ||
node.broadcaster = undefined; | ||
} | ||
} | ||
|
||
return { | ||
items, | ||
cursor, | ||
finished: ! get('data.collection.streams.pageInfo.hasNextPage', data) | ||
} | ||
} | ||
} | ||
|
||
Collection.presets = { | ||
live: [ | ||
{ | ||
settings: { | ||
sort: 'VIEWER_COUNT' | ||
}, | ||
list: { | ||
icon: 'ffz-i-tag', | ||
title: 'Collection', | ||
i18n: 'addon.deck.collection', | ||
|
||
desc_i18n: 'addon.deck.collection.live-tip', | ||
desc: 'This column shows live channels from a collection. For example, you can create a column showing all channels with an active Hype Train.' | ||
} | ||
} | ||
] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<template> | ||
<div :class="{'tw-form-required': ! hasSlug}"> | ||
<div class="tw-flex tw-align-items-center tw-mg-y-05"> | ||
<label :for="'slug$' + value.id"> | ||
{{ t('addon.deck.edit.slug', 'Slug:') }} | ||
</label> | ||
<input | ||
:id="'slug$' + value.id" | ||
v-model.trim="value.settings.slug" | ||
class="tw-flex-grow-1 tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 ffz-input" | ||
> | ||
</div> | ||
<section class="tw-c-text-alt-2 bd--half-width-max"> | ||
<t-list | ||
phrase="addon.deck.collection.find-slugs" | ||
default="To find valid slugs, visit Twitch's {homelink} and look for sections that link to pages with {collection} in the URL. As an example, a collection of all live channels with active hype trains has the slug: {hype-train}" | ||
> | ||
<template #homelink> | ||
<react-link | ||
class="ffz-link" | ||
:href="getReactURL('front-page')" | ||
>{{ | ||
t('addon.deck.collection.visit-home', 'home page') | ||
}}</react-link> | ||
</template> | ||
<template #collection> | ||
<code>/collection/</code> | ||
</template> | ||
<template #hype-train> | ||
<code>hype-train</code> | ||
</template> | ||
</t-list> | ||
</section> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
props: ['value', 'type', 'settings', 'inst'], | ||
computed: { | ||
hasSlug() { | ||
return this.value.settings.slug && this.value.settings.slug.length > 0 | ||
} | ||
} | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
{ | ||
"enabled": true, | ||
"requires": [], | ||
"version": "2.7.0", | ||
"version": "2.8.0", | ||
"short_name": "Deck", | ||
"name": "Deck", | ||
"author": "SirStendec", | ||
"description": "Deck provides a TweetDeck-like experience for finding content on Twitch.\n\nYou can define columns for live channels, videos, or clips. Sort each column how you want. Filter by tags. Find the content you want to watch.\n\nThis extension is not super user-friendly for getting started, but I don't have the time to give it the polish it deserves.", | ||
"settings": "add_ons.deck", | ||
"created": "2019-09-12T15:31:59.000Z", | ||
"updated": "2023-12-18T22:15:37.273Z" | ||
"updated": "2024-08-12T17:33:10.178Z" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters