channels.templ
3312 bytes
1package pages
2
3import (
4 "fmt"
5
6 "github.com/TheEdgeOfRage/ytrssil-api/models"
7)
8
9templ unsubscribeModal(channelID string) {
10 <div class="modal fade" id={ fmt.Sprintf("unsubscribe-modal-%s", channelID) } tabindex="-1">
11 <div class="modal-dialog">
12 <div class="modal-content">
13 <div class="modal-header">
14 <h1 class="modal-title fs-5">Confirm Unsubscribe</h1>
15 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
16 </div>
17 <div class="modal-body">
18 <p>Are you sure you want to unsubscribe from this channel?</p>
19 </div>
20 <div class="modal-footer">
21 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
22 <button
23 type="button"
24 class="btn btn-danger"
25 data-bs-dismiss="modal"
26 data-on:click={ fmt.Sprintf("@post('/channels/%s/unsubscribe')", channelID) }
27 >
28 Unsubscribe
29 </button>
30 </div>
31 </div>
32 </div>
33 </div>
34}
35
36templ shortsToggle(channel models.Channel) {
37 <button
38 type="button"
39 class={ fmt.Sprintf("btn btn-sm %s", ifShortsEnabled(channel.EnableShorts)) }
40 data-on:click={ fmt.Sprintf("$enable = %t; @post('/channels/%s/toggle-shorts')", !channel.EnableShorts, channel.ID) }
41 title={ toggleLabel(channel.EnableShorts) }
42 >
43 <svg
44 xmlns="http://www.w3.org/2000/svg"
45 height="24"
46 viewBox="0 0 24 24"
47 width="24"
48 focusable="false"
49 fill="currentColor"
50 ><path d="m13.974 2.052-8 4.7a4 4 0 00.385 7.097l.942.423-1.327.78a4 4 0 004.052 6.897l8-4.7a4.001 4.001 0 00-.384-7.096L16.7 9.73l1.326-.78a4 4 0 10-4.052-6.897ZM10 15V9l5 3-5 3Z"></path></svg>
51 </button>
52}
53
54func ifShortsEnabled(enabled bool) string {
55 if enabled {
56 return "btn-success"
57 }
58 return "btn-outline-secondary"
59}
60
61func toggleLabel(enabled bool) string {
62 if enabled {
63 return "Shorts: ON"
64 }
65 return "Shorts: OFF"
66}
67
68templ ChannelCard(channel models.Channel) {
69 <div id={ fmt.Sprintf("channel-card-%s", channel.ID) } class="channel-card col-md-3 p-2">
70 @unsubscribeModal(channel.ID)
71 <div class="card">
72 <div class="card-body d-flex align-items-center">
73 if channel.ImageURL != "" {
74 <img
75 src={ channel.ImageURL }
76 alt={ channel.Name }
77 class="rounded-circle me-3"
78 style="width: 48px; height: 48px; object-fit: cover;"
79 />
80 }
81 <div class="flex-grow-1">
82 <h5 class="card-title mb-1">
83 <a
84 href={ templ.SafeURL(fmt.Sprintf("https://www.youtube.com/channel/%s", channel.ID)) }
85 target="_blank"
86 rel="noopener"
87 data-open-in-safari
88 class="link-light link-underline-opacity-0"
89 >
90 { channel.Name }
91 </a>
92 </h5>
93 <p class="card-text mb-0 text-muted">
94 { fmt.Sprintf("%d", channel.UnwatchedCount) } unwatched
95 </p>
96 </div>
97 <div class="d-flex gap-2 align-items-center">
98 @shortsToggle(channel)
99 <button
100 class="btn btn-danger ms-2"
101 data-bs-toggle="modal"
102 data-bs-target={ fmt.Sprintf("#unsubscribe-modal-%s", channel.ID) }
103 >
104 <i class="bi bi-bookmark-dash"></i>
105 </button>
106 </div>
107 </div>
108 </div>
109 </div>
110}
111
112templ ChannelsPage(channels []models.Channel) {
113 @BaseLayout("ytrssil - Channels", "channels") {
114 <div id="channels-list" class="row">
115 for _, channel := range channels {
116 @ChannelCard(channel)
117 }
118 </div>
119 }
120}