twitch-grid-cards

This commit is contained in:
Atlas 2024-10-06 18:36:37 +03:00
parent d90d39933a
commit b8eeb636e0
7 changed files with 106 additions and 5 deletions

View File

@ -1588,6 +1588,9 @@ Preview:
| ---- | ---- | -------- | ------- |
| channels | array | yes | |
| collapse-after | integer | no | 5 |
| collapse-after-rows | integer | no | 4 |
| style | string | no | |
| show-offline | boolean | no | false |
| sort-by | string | no | viewers |
##### `channels`
@ -1596,6 +1599,15 @@ A list of channels to display.
##### `collapse-after`
How many channels are visible before the "SHOW MORE" button appears. Set to `-1` to never collapse.
##### `collapse-after-rows`
Specify the number of rows to show when using the `grid-cards` style before the "SHOW MORE" button appears.
##### `style`
Used to change the appearance of the widget. Possible values are `grid-cards`.
##### `show-offline`
##### `sort-by`
Can be used to specify the order in which the channels are displayed. Possible values are `viewers` and `live`.

View File

@ -695,6 +695,7 @@ details[open] .summary::after {
@container widget (max-width: 850px) { .cards-grid { --cards-per-row: 3; } }
@container widget (max-width: 750px) { .cards-grid { --cards-per-row: 3; } }
@container widget (max-width: 650px) { .cards-grid { --cards-per-row: 2; } }
@container widget (max-width: 300px) { .cards-grid { --cards-per-row: 1; } }
.widget-small-content-bounds {
max-width: 350px;

View File

@ -34,6 +34,7 @@ var (
MonitorTemplate = compileTemplate("monitor.html", "widget-base.html")
TwitchGamesListTemplate = compileTemplate("twitch-games-list.html", "widget-base.html")
TwitchChannelsTemplate = compileTemplate("twitch-channels.html", "widget-base.html")
TwitchChannelsGridTemplate = compileTemplate("twitch-channels-grid.html", "widget-base.html", "twitch-channels-card-contents.html")
RepositoryTemplate = compileTemplate("repository.html", "widget-base.html")
SearchTemplate = compileTemplate("search.html", "widget-base.html")
ExtensionTemplate = compileTemplate("extension.html", "widget-base.html")

View File

@ -0,0 +1,32 @@
{{ define "twitch-channels-card-contents" }}
{{ if .IsLive }}
<img class="video-thumbnail thumbnail" loading="lazy" src="https://static-cdn.jtvnw.net/previews-ttv/live_user_{{ .Login }}-440x248.jpg" alt="" />
{{ end }}
<div class="flex flex-column grow padding-widget">
<div class="{{ if .IsLive }}twitch-channel-live {{ end }}flex gap-10 items-start thumbnail-parent">
<div class="twitch-channel-avatar-container">
<a href="https://twitch.tv/{{ .Login }}" class="twitch-channel-avatar-link" target="_blank" rel="noreferrer" >
<img class="twitch-channel-avatar thumbnail" src="{{ .AvatarUrl }}" alt="{{ .Login }}" loading="lazy"/>
</a>
</div>
<div class="min-width-0">
<a href="https://twitch.tv/{{ .Login }}" class="size-h3{{ if .IsLive }} color-highlight{{ end }} block text-truncate" target="_blank" rel="noreferrer">{{ .Name }}</a>
{{ if .Exists }}
{{ if .IsLive }}
{{ if .Category }}
<a class="text-truncate block" href="https://www.twitch.tv/directory/category/{{ .CategorySlug }}" target="_blank" rel="noreferrer">{{ .Category }}</a>
{{ end }}
<ul class="list-horizontal-text">
<li {{ dynamicRelativeTimeAttrs .LiveSince }}></li>
<li>{{ .ViewersCount | formatViewerCount }} viewers</li>
</ul>
{{ else }}
<div>Offline</div>
{{ end }}
{{ else }}
<div class="color-negative">Not found</div>
{{ end }}
</div>
</div>
</div>
{{ end }}

View File

@ -0,0 +1,29 @@
{{ template "widget-base.html" . }}
{{ define "widget-content-classes" }}widget-content-frameless{{ end }}
{{ define "widget-content" }}
<div class="flex flex-column">
<div>
<div class="cards-grid collapsible-container" data-collapse-after-rows="{{ .CollapseAfterRows }}">
{{ range .Groups.Online }}
<div class="card widget-content-frame thumbnail-parent">
{{ template "twitch-channels-card-contents" . }}
</div>
{{ end }}
</div>
</div>
{{ if .ShowOffline }}
<div class="margin-top-25">
<div class="widget-header">
<div class="uppercase">Offline Channels</div>
</div>
<div class="cards-grid collapsible-container" data-collapse-after-rows="1">
{{ range .Groups.Offline }}
<div class="card widget-content-frame thumbnail-parent">
{{ template "twitch-channels-card-contents" . }}
</div>
{{ end }}
</div>
</div>
{{ end }}
</div>
{{ end }}

View File

@ -38,6 +38,16 @@ type TwitchChannel struct {
type TwitchChannels []TwitchChannel
func (channels TwitchChannels) GroupByLive() map[string][]TwitchChannel {
grouped := make(map[string][]TwitchChannel)
statusMap := map[bool]string{true: "Online", false: "Offline"}
for _, channel := range channels {
IsLive := statusMap[channel.IsLive]
grouped[IsLive] = append(grouped[IsLive], channel)
}
return grouped
}
func (channels TwitchChannels) SortByViewers() {
sort.Slice(channels, func(i, j int) bool {
return channels[i].ViewersCount > channels[j].ViewersCount

View File

@ -10,11 +10,15 @@ import (
)
type TwitchChannels struct {
widgetBase `yaml:",inline"`
ChannelsRequest []string `yaml:"channels"`
Channels []feed.TwitchChannel `yaml:"-"`
CollapseAfter int `yaml:"collapse-after"`
SortBy string `yaml:"sort-by"`
widgetBase `yaml:",inline"`
ChannelsRequest []string `yaml:"channels"`
Channels []feed.TwitchChannel `yaml:"-"`
Groups map[string][]feed.TwitchChannel `yaml:"-"`
CollapseAfter int `yaml:"collapse-after"`
CollapseAfterRows int `yaml:"collapse-after-rows"`
Style string `yaml:"style"`
SortBy string `yaml:"sort-by"`
ShowOffline bool `yaml:"show-offline"`
}
func (widget *TwitchChannels) Initialize() error {
@ -27,6 +31,10 @@ func (widget *TwitchChannels) Initialize() error {
widget.CollapseAfter = 5
}
if widget.CollapseAfterRows == 0 || widget.CollapseAfterRows < -1 {
widget.CollapseAfterRows = 4
}
if widget.SortBy != "viewers" && widget.SortBy != "live" {
widget.SortBy = "viewers"
}
@ -46,10 +54,18 @@ func (widget *TwitchChannels) Update(ctx context.Context) {
} else if widget.SortBy == "live" {
channels.SortByLive()
}
if widget.Style == "grid-cards" {
groupedChannels := channels.GroupByLive()
widget.Groups = groupedChannels
}
widget.Channels = channels
}
func (widget *TwitchChannels) Render() template.HTML {
if widget.Style == "grid-cards" {
return widget.render(widget, assets.TwitchChannelsGridTemplate)
}
return widget.render(widget, assets.TwitchChannelsTemplate)
}