Add sort config for videos widget

This commit is contained in:
Igor Kim
2025-06-28 02:53:37 +05:00
parent c88fd526e5
commit d6de3b3437
2 changed files with 29 additions and 4 deletions

View File

@ -870,6 +870,7 @@ Preview:
| playlists | array | no | | | playlists | array | no | |
| limit | integer | no | 25 | | limit | integer | no | 25 |
| style | string | no | horizontal-cards | | style | string | no | horizontal-cards |
| sort-by | string | no | posted |
| collapse-after | integer | no | 7 | | collapse-after | integer | no | 7 |
| collapse-after-rows | integer | no | 4 | | collapse-after-rows | integer | no | 4 |
| include-shorts | boolean | no | false | | include-shorts | boolean | no | false |
@ -905,6 +906,10 @@ https://www.youtube.com...&list={ID}&...
##### `limit` ##### `limit`
The maximum number of videos to show. The maximum number of videos to show.
##### `sort-by`
Used to specify the order in which the videos should get returned. Possible values are `none`, `updated`, and `posted`.
Default value is `posted`.
##### `collapse-after` ##### `collapse-after`
Specify the number of videos to show when using the `vertical-list` style before the "SHOW MORE" button appears. Specify the number of videos to show when using the `vertical-list` style before the "SHOW MORE" button appears.

View File

@ -31,6 +31,7 @@ type videosWidget struct {
Playlists []string `yaml:"playlists"` Playlists []string `yaml:"playlists"`
Limit int `yaml:"limit"` Limit int `yaml:"limit"`
IncludeShorts bool `yaml:"include-shorts"` IncludeShorts bool `yaml:"include-shorts"`
SortBy string `yaml:"sort-by"`
} }
func (widget *videosWidget) initialize() error { func (widget *videosWidget) initialize() error {
@ -64,7 +65,7 @@ func (widget *videosWidget) initialize() error {
} }
func (widget *videosWidget) update(ctx context.Context) { func (widget *videosWidget) update(ctx context.Context) {
videos, err := fetchYoutubeChannelUploads(widget.Channels, widget.VideoUrlTemplate, widget.IncludeShorts) videos, err := fetchYoutubeChannelUploads(widget.Channels, widget.VideoUrlTemplate, widget.IncludeShorts, widget.SortBy)
if !widget.canContinueUpdateAfterHandlingErr(err) { if !widget.canContinueUpdateAfterHandlingErr(err) {
return return
@ -98,6 +99,7 @@ type youtubeFeedResponseXml struct {
Videos []struct { Videos []struct {
Title string `xml:"title"` Title string `xml:"title"`
Published string `xml:"published"` Published string `xml:"published"`
Updated string `xml:"updated"`
Link struct { Link struct {
Href string `xml:"href,attr"` Href string `xml:"href,attr"`
} `xml:"link"` } `xml:"link"`
@ -126,11 +128,12 @@ type video struct {
Author string Author string
AuthorUrl string AuthorUrl string
TimePosted time.Time TimePosted time.Time
TimeUpdated time.Time
} }
type videoList []video type videoList []video
func (v videoList) sortByNewest() videoList { func (v videoList) sortByPosted() videoList {
sort.Slice(v, func(i, j int) bool { sort.Slice(v, func(i, j int) bool {
return v[i].TimePosted.After(v[j].TimePosted) return v[i].TimePosted.After(v[j].TimePosted)
}) })
@ -138,7 +141,15 @@ func (v videoList) sortByNewest() videoList {
return v return v
} }
func fetchYoutubeChannelUploads(channelOrPlaylistIDs []string, videoUrlTemplate string, includeShorts bool) (videoList, error) { func (v videoList) sortByUpdated() videoList {
sort.Slice(v, func(i, j int) bool {
return v[i].TimeUpdated.After(v[j].TimeUpdated)
})
return v
}
func fetchYoutubeChannelUploads(channelOrPlaylistIDs []string, videoUrlTemplate string, includeShorts bool, sortBy string) (videoList, error) {
requests := make([]*http.Request, 0, len(channelOrPlaylistIDs)) requests := make([]*http.Request, 0, len(channelOrPlaylistIDs))
for i := range channelOrPlaylistIDs { for i := range channelOrPlaylistIDs {
@ -198,6 +209,7 @@ func fetchYoutubeChannelUploads(channelOrPlaylistIDs []string, videoUrlTemplate
Author: response.Channel, Author: response.Channel,
AuthorUrl: response.ChannelLink + "/videos", AuthorUrl: response.ChannelLink + "/videos",
TimePosted: parseYoutubeFeedTime(v.Published), TimePosted: parseYoutubeFeedTime(v.Published),
TimeUpdated: parseYoutubeFeedTime(v.Updated),
}) })
} }
} }
@ -206,7 +218,15 @@ func fetchYoutubeChannelUploads(channelOrPlaylistIDs []string, videoUrlTemplate
return nil, errNoContent return nil, errNoContent
} }
videos.sortByNewest() switch sortBy {
case "none":
case "updated":
videos.sortByUpdated()
case "posted":
videos.sortByPosted()
default: // "posted"
videos.sortByPosted()
}
if failed > 0 { if failed > 0 {
return videos, fmt.Errorf("%w: missing videos from %d channels", errPartialContent, failed) return videos, fmt.Errorf("%w: missing videos from %d channels", errPartialContent, failed)