1diff --git a/cmd/server/main.go b/cmd/server/main.go
2index b940145af604f507d5625e711765dfb3c27dd86e..c7f901914667d673201e36568756c6201240f863 100644
3--- a/cmd/server/main.go
4+++ b/cmd/server/main.go
5@@ -108,7 +108,7 @@ for _, v := range []view.View{
6 view.NewAuthView(userController),
7 view.NewFileSystemView(*fileSystemController, settingsRepository),
8 view.NewSettingsView(settingsRepository, userRepository),
9- view.NewMediaView(mediaRepository, userRepository),
10+ view.NewMediaView(mediaRepository, userRepository, settingsRepository),
11 } {
12 v.SetMyselfIn(extRouter)
13 }
14diff --git a/pkg/database/repository/settings.go b/pkg/database/repository/settings.go
15index 6ed1eb61e66b2ddbc5f9ddcafc13a568e232e348..c3d8fbb94e4c82a841e151d158dd5b0ea5172e5d 100644
16--- a/pkg/database/repository/settings.go
17+++ b/pkg/database/repository/settings.go
18@@ -4,8 +4,9 @@ import "context"
19
20 type (
21 Settings struct {
22- ShowMode bool
23- ShowOwner bool
24+ ShowMode bool
25+ ShowOwner bool
26+ PreloadVideoMetadata bool
27 }
28
29 SettingsRepository interface {
30diff --git a/pkg/database/sql/settings.go b/pkg/database/sql/settings.go
31index 4e738789296ad2129eb5aa504461c312070f2fca..3f4ad08acee47dfe46a871170f97772cfb10099e 100644
32--- a/pkg/database/sql/settings.go
33+++ b/pkg/database/sql/settings.go
34@@ -11,8 +11,9 @@
35 type (
36 Settings struct {
37 gorm.Model
38- ShowMode bool
39- ShowOwner bool
40+ ShowMode bool
41+ ShowOwner bool
42+ PreloadVideoMetadata bool
43 }
44
45 SettingsRepository struct {
46@@ -51,6 +52,7 @@ }
47
48 s.ShowMode = toSaveSettings.ShowMode
49 s.ShowOwner = toSaveSettings.ShowOwner
50+ s.PreloadVideoMetadata = toSaveSettings.PreloadVideoMetadata
51
52 result := db.Save(s)
53 return result.Error
54@@ -63,7 +65,8 @@ return nil, err
55 }
56
57 return &repository.Settings{
58- ShowMode: s.ShowMode,
59- ShowOwner: s.ShowOwner,
60+ ShowMode: s.ShowMode,
61+ ShowOwner: s.ShowOwner,
62+ PreloadVideoMetadata: s.PreloadVideoMetadata,
63 }, nil
64 }
65diff --git a/pkg/service/auth_test.go b/pkg/service/auth_test.go
66index 7083d0c90ea75569f4e2532f86228a57c49df253..179ded71f0c45eda11fa0008b0e39982b8e1bfea 100644
67--- a/pkg/service/auth_test.go
68+++ b/pkg/service/auth_test.go
69@@ -7,7 +7,6 @@ "context"
70 "testing"
71
72 "git.sr.ht/~gabrielgio/img/pkg/database/repository"
73- "git.sr.ht/~gabrielgio/img/pkg/ext"
74 "git.sr.ht/~gabrielgio/img/pkg/testkit"
75 )
76
77diff --git a/pkg/view/media.go b/pkg/view/media.go
78index e2479405d5a8e49a238872bad1eb74b2c665175b..6e34fd6c4505d418f9a57c57f20d9156866a9b2f 100644
79--- a/pkg/view/media.go
80+++ b/pkg/view/media.go
81@@ -12,8 +12,9 @@ )
82
83 type (
84 MediaView struct {
85- mediaRepository repository.MediaRepository
86- userRepository repository.UserRepository
87+ mediaRepository repository.MediaRepository
88+ userRepository repository.UserRepository
89+ settingsRepository repository.SettingsRepository
90 }
91 )
92
93@@ -50,10 +51,12 @@
94 func NewMediaView(
95 mediaRepository repository.MediaRepository,
96 userRepository repository.UserRepository,
97+ settingsRepository repository.SettingsRepository,
98 ) *MediaView {
99 return &MediaView{
100- mediaRepository: mediaRepository,
101- userRepository: userRepository,
102+ mediaRepository: mediaRepository,
103+ userRepository: userRepository,
104+ settingsRepository: settingsRepository,
105 }
106 }
107
108@@ -72,12 +75,18 @@ if err != nil {
109 return err
110 }
111
112+ settings, err := self.settingsRepository.Load(ctx)
113+ if err != nil {
114+ return err
115+ }
116+
117 page := &templates.MediaPage{
118 Medias: medias,
119 Next: &repository.Pagination{
120 Size: p.Size,
121 Page: p.Page + 1,
122 },
123+ Settings: settings,
124 }
125
126 templates.WritePageTemplate(ctx, page)
127diff --git a/pkg/view/settings.go b/pkg/view/settings.go
128index bee3dc201b1f21d24ceb66ed7ae59df7cb95b491..ffce86b2ab39bfd887d06d37d2f22dfc7b324d13 100644
129--- a/pkg/view/settings.go
130+++ b/pkg/view/settings.go
131@@ -47,13 +47,15 @@ }
132
133 func (self *SettingsView) Save(ctx *fasthttp.RequestCtx) error {
134 var (
135- showMode = string(ctx.FormValue("showMode")) == "on"
136- showOwner = string(ctx.FormValue("showOwner")) == "on"
137+ showMode = string(ctx.FormValue("showMode")) == "on"
138+ showOwner = string(ctx.FormValue("showOwner")) == "on"
139+ preloadVideoMetadata = string(ctx.FormValue("preloadVideoMetadata")) == "on"
140 )
141
142 err := self.settingsRepository.Save(ctx, &repository.Settings{
143- ShowMode: showMode,
144- ShowOwner: showOwner,
145+ ShowMode: showMode,
146+ ShowOwner: showOwner,
147+ PreloadVideoMetadata: preloadVideoMetadata,
148 })
149 if err != nil {
150 return err
151diff --git a/templates/media.qtpl b/templates/media.qtpl
152index 18eac0df9a08dcd92a8ab70ac012eb459c8f43f8..621789945412ff643221945ab5ea59d590722f66 100644
153--- a/templates/media.qtpl
154+++ b/templates/media.qtpl
155@@ -2,8 +2,16 @@ {% import "git.sr.ht/~gabrielgio/img/pkg/database/repository" %}
156
157 {% code
158 type MediaPage struct {
159- Medias []*repository.Media
160- Next *repository.Pagination
161+ Medias []*repository.Media
162+ Next *repository.Pagination
163+ Settings *repository.Settings
164+}
165+
166+func (m *MediaPage) PreloadAttr() string {
167+ if m.Settings.PreloadVideoMetadata {
168+ return "metadata"
169+ }
170+ return "none"
171 }
172 %}
173
174@@ -14,7 +22,7 @@ <div class="columns is-multiline">
175 {% for _, media := range p.Medias %}
176 <div class="card-image">
177 {% if media.IsVideo() %}
178- <video class="image is-fit" controls muted="true" poster="/media/thumbnail?path_hash={%s media.PathHash %}" preload="metadata">
179+ <video class="image is-fit" controls muted="true" poster="/media/thumbnail?path_hash={%s media.PathHash %}" preload="{%s p.PreloadAttr() %}">
180 <source src="/media/image?path_hash={%s media.PathHash %}" type="{%s media.MIMEType %}">
181 </video>
182 {% else %}
183diff --git a/templates/settings.qtpl b/templates/settings.qtpl
184index 509cddd76e1a34dadd953a7d84a2f838cd3ade31..6eee1abd3d87e60ae598ea50651c5c04992932ec 100644
185--- a/templates/settings.qtpl
186+++ b/templates/settings.qtpl
187@@ -30,6 +30,14 @@ </label>
188 </div>
189 </div>
190 <div class="field">
191+ <div class="control">
192+ <label class="checkbox">
193+ <input type="checkbox" id="preloadVideoMetadata" name="preloadVideoMetadata" {% if p.Settings.PreloadVideoMetadata %}checked{% endif %}>
194+ Preload video metadata
195+ </label>
196+ </div>
197+ </div>
198+ <div class="field">
199 <input class="button" value="save" type="submit">
200 </div>
201 </form>