@@ -12,40 +12,39 @@ import (
1212func (s * Sender ) formatNotificationBody (sub * notifier.Subscription , thread * notifier.Thread , posts []* notifier.Post ) string {
1313 var b strings.Builder
1414
15- b .WriteString ("<!DOCTYPE html>\n <html>\n <head>\n " )
15+ b .WriteString ("<!DOCTYPE html>\n <html lang= \" en \" >\n <head>\n " )
1616 b .WriteString ("<meta charset=\" utf-8\" >\n " )
17+ b .WriteString ("<meta name=\" viewport\" content=\" width=device-width, initial-scale=1\" >\n " )
1718 b .WriteString ("<style>\n " )
1819 b .WriteString ("body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }\n " )
19- b .WriteString (".header { border-bottom: 2px solid #e67e22; padding-bottom: 10px; margin-bottom: 20px; }\n " )
20- b .WriteString (".post { margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid #ecf0f1; }\n " )
21- b .WriteString (".post:last-of-type { border-bottom: none; }\n " )
20+ b .WriteString (".post { margin-bottom: 30px; padding-bottom: 30px; border-bottom: 2px solid #e67e22; }\n " )
21+ b .WriteString (".post:last-of-type { border-bottom: none; padding-bottom: 0; }\n " )
22+ b .WriteString (".post:first-of-type { padding-top: 0; }\n " )
23+ b .WriteString (".meta { margin-bottom: 12px; }\n " )
24+ b .WriteString (".post-number { color: #7f8c8d; font-weight: 500; font-size: 1.1em; text-decoration: none; }\n " )
25+ b .WriteString (".post-number:hover { text-decoration: underline; }\n " )
2226 b .WriteString (".author { color: #e67e22; font-weight: 600; font-size: 1.2em; }\n " )
2327 b .WriteString (".timestamp { color: #7f8c8d; font-size: 0.9em; }\n " )
24- b .WriteString (".content { background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 15px 0; }\n " )
28+ b .WriteString (".content { margin: 15px 0; }\n " )
2529 b .WriteString (".content img { max-width: 100%; height: auto; margin: 10px 0; display: block; }\n " )
26- b .WriteString (".footer { margin-top: 20px; padding-top: 10px; border-top: 2px solid #ecf0f1; color: #7f8c8d; font-size: 0.9em; }\n " )
30+ b .WriteString (".content blockquote { border-left: 3px solid #ddd; padding-left: 15px; margin: 10px 0; color: #666; font-size: 0.95em; }\n " )
31+ b .WriteString (".footer { margin-top: 30px; padding-top: 15px; border-top: 1px solid #ddd; font-size: 0.9em; color: #7f8c8d; }\n " )
32+ b .WriteString (".footer a { color: #7f8c8d; text-decoration: underline; margin: 0 8px; }\n " )
33+ b .WriteString (".footer a:first-child { margin-left: 0; }\n " )
2734 b .WriteString ("a { color: #e67e22; text-decoration: none; }\n " )
2835 b .WriteString ("a:hover { text-decoration: underline; }\n " )
29- b .WriteString (".view-post { display: inline-block; margin-top: 10px; font-size: 0.9em; }\n " )
3036 b .WriteString ("</style>\n </head>\n <body>\n " )
3137
32- b .WriteString ("<div class=\" header\" >\n " )
33- if len (posts ) == 1 {
34- b .WriteString ("<h2>New ADVRider Post</h2>\n " )
35- } else {
36- b .WriteString (fmt .Sprintf ("<h2>%d New ADVRider Posts</h2>\n " , len (posts )))
37- }
38- b .WriteString ("</div>\n " )
39-
40- // Render each post
38+ // Render each post - no redundant header
4139 for _ , post := range posts {
4240 b .WriteString ("<div class=\" post\" >\n " )
4341 b .WriteString ("<div class=\" meta\" >\n " )
44- b .WriteString (fmt .Sprintf ("<span class=\" author\" >%s</span>\n " , escapeHTML (post .Author )))
42+ b .WriteString (fmt .Sprintf ("<a href=\" %s\" class=\" post-number\" >#%s</a>\n " , escapeHTML (post .URL ), escapeHTML (post .ID )))
43+ b .WriteString (fmt .Sprintf ("<span class=\" author\" > • %s</span>\n " , escapeHTML (post .Author )))
4544 if post .Timestamp != "" {
4645 t , err := time .Parse (time .RFC3339 , post .Timestamp )
4746 if err == nil {
48- b .WriteString (fmt .Sprintf ("<span class=\" timestamp\" > • %s</span>\n " , t .Format ("Jan 2, 2006 at 3:04 PM" )))
47+ b .WriteString (fmt .Sprintf ("<span class=\" timestamp\" > • %s UTC </span>\n " , t .Format ("Jan 2, 2006 at 3:04 PM" )))
4948 }
5049 }
5150 b .WriteString ("</div>\n " )
@@ -59,16 +58,14 @@ func (s *Sender) formatNotificationBody(sub *notifier.Subscription, thread *noti
5958 }
6059 b .WriteString ("</div>\n " )
6160
62- b .WriteString (fmt .Sprintf ("<a href=\" %s\" class=\" view-post\" >View this post on ADVRider</a>\n " , escapeHTML (post .URL )))
6361 b .WriteString ("</div>\n " )
6462 }
6563
64+ // Footer with thread link and manage link
6665 b .WriteString ("<div class=\" footer\" >\n " )
67- b .WriteString (fmt .Sprintf ("<a href=\" %s\" >View full thread on ADVRider</a>\n " , escapeHTML (thread .ThreadURL )))
68- b .WriteString (" • \n " )
69- // Use secure token in manage link
66+ b .WriteString (fmt .Sprintf ("<a href=\" %s\" >View thread</a>\n " , escapeHTML (thread .ThreadURL )))
7067 manageURL := fmt .Sprintf ("%s/manage?token=%s" , s .baseURL , url .QueryEscape (sub .Token ))
71- b .WriteString (fmt .Sprintf ("<a href=\" %s\" >Manage Subscriptions </a>\n " , escapeHTML (manageURL )))
68+ b .WriteString (fmt .Sprintf ("<a href=\" %s\" >Manage</a>\n " , escapeHTML (manageURL )))
7269 b .WriteString ("</div>\n " )
7370
7471 b .WriteString ("</body>\n </html>" )
0 commit comments