diff --git a/internal/util/cooldowns.go b/internal/util/cooldowns.go index 2a40a1b..401fa52 100644 --- a/internal/util/cooldowns.go +++ b/internal/util/cooldowns.go @@ -15,14 +15,14 @@ var ( ThreadCooldowns = make(map[string]time.Time) ) -var cooldownMutex sync.Mutex +var CooldownMutex sync.Mutex const POST_COOLDOWN = 15 * time.Second const THREAD_COOLDOWN = 2 * time.Minute func IsOnCooldown(ip string, m map[string]time.Time, duration time.Duration) bool { - cooldownMutex.Lock() - defer cooldownMutex.Unlock() + CooldownMutex.Lock() + defer CooldownMutex.Unlock() last, exists := m[ip] if !exists || time.Since(last) >= duration { diff --git a/web/main.go b/web/main.go index 6190a69..ecbbb52 100644 --- a/web/main.go +++ b/web/main.go @@ -264,6 +264,13 @@ func main() { return } + thread, err := database.GetThread(db, threadId) + if err != nil { + http.Error(w, "Failed to get thread", http.StatusBadRequest) + log.Printf("GetThread: %v", err) + return + } + posts, err := database.GetPosts(db, threadId) if err != nil { http.Error(w, "Failed to get posts", http.StatusBadRequest) @@ -278,7 +285,7 @@ func main() { } // dont pass the op post. only replies - views.PostReplies(posts[1:]).Render(r.Context(), w) + views.Posts(posts, thread).Render(r.Context(), w) }) // ----------------- @@ -289,6 +296,8 @@ func main() { go func() { for range time.Tick(10 * time.Minute) { + util.CooldownMutex.Lock() + defer util.CooldownMutex.Unlock() for ip, cooldown := range util.PostCooldowns { if time.Since(cooldown) >= util.POST_COOLDOWN { delete(util.PostCooldowns, ip) diff --git a/web/static/index.css b/web/static/index.css index 823b34d..7972be4 100644 --- a/web/static/index.css +++ b/web/static/index.css @@ -1,5 +1,8 @@ body { background: #EEF2FF; + padding-left: 4px; + padding-right: 4px; + margin: 0 4px; } /* INDEX */ @@ -274,3 +277,28 @@ body { margin: 5px 0; font-size: 12px; } + +.link-button { + background: none; + border: none; + padding: 0; + font-size: .8rem; + color: #34345C; + cursor: pointer; + text-decoration: underline; +} + +.link-button:hover { + color: #ff0000; +} + +hr { + border: none; + border-top-width: medium; + border-top-style: none; + border-top-color: currentcolor; + border-top: + 1px solid #B7C5D9; + height: 0; + clear: left; +} diff --git a/web/views/thread.templ b/web/views/thread.templ index 769a341..febbc7e 100644 --- a/web/views/thread.templ +++ b/web/views/thread.templ @@ -1,105 +1,90 @@ package views import ( - "fmt" - "github.com/dominicf2001/comfychan/internal/database" - "github.com/dominicf2001/comfychan/internal/util" - "github.com/dominicf2001/comfychan/web/views/shared" - "strconv" +"fmt" +"github.com/dominicf2001/comfychan/internal/database" +"github.com/dominicf2001/comfychan/internal/util" +"github.com/dominicf2001/comfychan/web/views/shared" +"strconv" ) templ PostOriginal(post database.Post, thread *database.Thread) { -
-
+
+
+ File: + + { post.MediaPath } + +
+ +
+

{ thread.Subject } -

+ + + { post.CreatedAt.Format("15:04") } + >%d\n'", post.Id) } + class=" post-num"> + No.{ strconv.Itoa(post.Id) } + + +
+

+ @templ.Raw(util.EnrichPost(post.Body)) +

+
+} + +templ PostReply(post database.Post) { +
+
+ + + { post.CreatedAt.Format("15:04") } + >%d\n'", post.Id) } + class=" post-num"> + No.{ strconv.Itoa(post.Id) } + + +
+ if post.MediaPath != "" { +
+
File: { post.MediaPath }
- -
-

{ thread.Subject } -

- - - { post.CreatedAt.Format("15:04") } - >%d\n'", post.Id) } - class=" post-num" - > - No.{ strconv.Itoa(post.Id) } - - -
-

- @templ.Raw(util.EnrichPost(post.Body)) -

-
-} - -templ PostReply(post database.Post) { -
-
- - - { post.CreatedAt.Format("15:04") } - >%d\n'", post.Id) } - class=" post-num" - > - No.{ strconv.Itoa(post.Id) } - - -
- if post.MediaPath != "" { -
-
- File: - - { post.MediaPath } - -
- -
- } -

- @templ.Raw(util.EnrichPost(post.Body)) -

-
-} - -templ PostReplies(posts []database.Post) { - for _, post := range (posts) { - @PostReply(post) -
+ +
} +

+ @templ.Raw(util.EnrichPost(post.Body)) +

+
+} + +templ Posts(posts []database.Post, thread database.Thread) { +@PostOriginal(posts[0], &thread) +
+ for _, post := range (posts[1:]) { + @PostReply(post) +
+ } +
} templ Thread(board database.Board, thread database.Thread, posts []database.Post) { - @shared.Layout() { - - @BoardHeader(board) -
- -
+@BoardHeader(board) +
+ + - - - - - - - - - - - -
comment
File
- - -
-
- @PostOriginal(posts[0], &thread) -
- @PostReplies(posts[1:]) -
-
- } + end"> + + + + + + + + + + + +
comment
File
+ + +
+
+ +
+
+ @Posts(posts, thread) +
+} }