Skip to content

Commit ac79bcf

Browse files
Thomas StrombergThomas Stromberg
authored andcommitted
improve delivery reliability
1 parent 7ac5416 commit ac79bcf

File tree

13 files changed

+440
-124
lines changed

13 files changed

+440
-124
lines changed

email/templates.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ func (s *Sender) formatNotificationBody(sub *notifier.Subscription, thread *noti
2121
b.WriteString(".post:last-of-type { border-bottom: none; }\n")
2222
b.WriteString(".author { color: #e67e22; font-weight: 600; }\n")
2323
b.WriteString(".timestamp { color: #7f8c8d; font-size: 0.9em; }\n")
24-
b.WriteString(".content { background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 15px 0; white-space: pre-wrap; }\n")
24+
b.WriteString(".content { background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 15px 0; }\n")
25+
b.WriteString(".content img { max-width: 100%; height: auto; margin: 10px 0; display: block; }\n")
2526
b.WriteString(".footer { margin-top: 20px; padding-top: 10px; border-top: 2px solid #ecf0f1; color: #7f8c8d; font-size: 0.9em; }\n")
2627
b.WriteString("a { color: #e67e22; text-decoration: none; }\n")
2728
b.WriteString("a:hover { text-decoration: underline; }\n")
@@ -50,7 +51,12 @@ func (s *Sender) formatNotificationBody(sub *notifier.Subscription, thread *noti
5051
b.WriteString("</div>\n")
5152

5253
b.WriteString("<div class=\"content\">\n")
53-
b.WriteString(escapeHTML(post.Content))
54+
// Use HTML content if available (includes images), otherwise fall back to plain text
55+
if post.HTMLContent != "" {
56+
b.WriteString(post.HTMLContent)
57+
} else {
58+
b.WriteString(escapeHTML(post.Content))
59+
}
5460
b.WriteString("</div>\n")
5561

5662
b.WriteString(fmt.Sprintf("<a href=\"%s\" class=\"view-post\">View this post on ADVRider</a>\n", escapeHTML(post.URL)))

main.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ func main() {
8787
storageSvc := storage.New(nil, "", localStorage, []byte(salt), logger)
8888
pollSvc := poll.New(scraperSvc, storageSvc, emailSender, logger)
8989

90+
// Run initial polling cycle on startup
91+
logger.Info("Running initial polling cycle on startup")
92+
if err := pollSvc.CheckAll(ctx); err != nil {
93+
logger.Warn("Initial polling cycle failed", "error", err)
94+
} else {
95+
logger.Info("Initial polling cycle completed successfully")
96+
}
97+
9098
// Create and run server
9199
srv := server.New(&server.Config{
92100
Scraper: scraperSvc,
@@ -149,6 +157,14 @@ func main() {
149157
storageSvc := storage.New(storageClient, bucket, "", []byte(salt), logger)
150158
pollSvc := poll.New(scraperSvc, storageSvc, emailSender, logger)
151159

160+
// Run initial polling cycle on startup
161+
logger.Info("Running initial polling cycle on startup")
162+
if err := pollSvc.CheckAll(ctx); err != nil {
163+
logger.Warn("Initial polling cycle failed", "error", err)
164+
} else {
165+
logger.Info("Initial polling cycle completed successfully")
166+
}
167+
152168
// Create server
153169
srv := server.New(&server.Config{
154170
Scraper: scraperSvc,

media/style.css

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,26 @@ strong {
6161
}
6262

6363
a {
64-
display: inline-block;
64+
color: #e67e22;
65+
text-decoration: none;
66+
transition: color 0.2s ease;
67+
}
68+
69+
a:hover {
70+
text-decoration: underline;
71+
}
72+
73+
a:focus {
74+
outline: 2px solid #e67e22;
75+
outline-offset: 2px;
76+
text-decoration: underline;
77+
}
78+
79+
/* Button-styled links for CTAs */
80+
a.button {
81+
display: inline-flex;
82+
align-items: center;
83+
justify-content: center;
6584
background: #e67e22;
6685
color: white;
6786
padding: 14px 28px;
@@ -73,18 +92,16 @@ a {
7392
box-shadow: 0 4px 12px rgba(230, 126, 34, 0.3);
7493
margin-top: 16px;
7594
min-height: 44px;
76-
display: inline-flex;
77-
align-items: center;
78-
justify-content: center;
7995
}
8096

81-
a:hover {
97+
a.button:hover {
8298
background: #d35400;
8399
transform: translateY(-1px);
84100
box-shadow: 0 6px 20px rgba(230, 126, 34, 0.4);
101+
text-decoration: none;
85102
}
86103

87-
a:focus {
104+
a.button:focus {
88105
outline: 3px solid #e67e22;
89106
outline-offset: 2px;
90107
}
@@ -187,35 +204,17 @@ button.secondary:focus {
187204
.thread-url {
188205
font-family: 'SF Mono', 'Monaco', 'Courier New', monospace;
189206
font-size: 14px;
190-
color: #666;
191207
word-break: break-all;
192208
margin-bottom: 8px;
193209
}
194210

195211
.thread-url a {
196-
display: inline;
197-
background: none;
198212
color: #0066cc;
199213
text-decoration: underline;
200-
padding: 2px;
201-
margin: 0;
202-
box-shadow: none;
203-
font-size: inherit;
204-
font-weight: normal;
205-
border-radius: 3px;
206214
}
207215

208216
.thread-url a:hover {
209217
color: #004499;
210-
background: none;
211-
transform: none;
212-
box-shadow: none;
213-
}
214-
215-
.thread-url a:focus {
216-
outline: 2px solid #0066cc;
217-
outline-offset: 2px;
218-
background: rgba(0, 102, 204, 0.1);
219218
}
220219

221220
.thread-meta {
@@ -250,24 +249,7 @@ button.secondary:focus {
250249
margin-bottom: 24px;
251250
}
252251

253-
.empty a {
254-
display: inline-block;
255-
background: #e67e22;
256-
color: white;
257-
padding: 14px 28px;
258-
border-radius: 8px;
259-
text-decoration: none;
260-
font-size: 17px;
261-
font-weight: 600;
262-
box-shadow: 0 4px 12px rgba(230, 126, 34, 0.3);
263-
margin-top: 8px;
264-
}
265-
266-
.empty a:hover {
267-
background: #d35400;
268-
transform: translateY(-1px);
269-
box-shadow: 0 6px 20px rgba(230, 126, 34, 0.4);
270-
}
252+
/* Empty state uses button class for CTA */
271253

272254
.logo {
273255
text-align: center;
@@ -354,32 +336,6 @@ button:active {
354336
color: #767676;
355337
}
356338

357-
.footer a {
358-
display: inline;
359-
background: none;
360-
color: #e67e22;
361-
text-decoration: none;
362-
padding: 2px 4px;
363-
margin: 0 2px;
364-
box-shadow: none;
365-
font-size: inherit;
366-
font-weight: normal;
367-
border-radius: 3px;
368-
}
369-
370-
.footer a:hover {
371-
text-decoration: underline;
372-
background: none;
373-
transform: none;
374-
box-shadow: none;
375-
}
376-
377-
.footer a:focus {
378-
outline: 2px solid #e67e22;
379-
outline-offset: 2px;
380-
text-decoration: underline;
381-
}
382-
383339
@media (max-width: 600px) {
384340
.container {
385341
padding: 32px 24px;

pkg/notifier/notifier.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import "time"
55

66
// Post represents a single post in a thread.
77
type Post struct {
8-
ID string
9-
Author string
10-
Content string
11-
Timestamp string
12-
URL string
8+
ID string
9+
Author string
10+
Content string // Plain text content for fallback
11+
HTMLContent string // HTML content with images and formatting
12+
Timestamp string
13+
URL string
1314
}
1415

1516
// Thread represents a monitored thread with its state.

0 commit comments

Comments
 (0)