dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit a27d7440fc2d033b526ce7ef62131ae032810f4a
parent df8527df8bbce87d0cc42c070fe49f08ca092bf6
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Tue, 30 May 2023 00:24:40 -0700

put bottom controls in iframe

Diffstat:
Apkg/web/handlers/api/v1/chatControlsHandler.go | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/web/handlers/api/v1/data.go | 8++++++++
Mpkg/web/handlers/chat.go | 51---------------------------------------------------
Mpkg/web/handlers/data.go | 2--
Mpkg/web/middlewares/middlewares.go | 3++-
Apkg/web/public/views/pages/chat-controls.gohtml | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/web/public/views/pages/chat.gohtml | 55+++++++------------------------------------------------
Mpkg/web/web.go | 2++
8 files changed, 178 insertions(+), 102 deletions(-)

diff --git a/pkg/web/handlers/api/v1/chatControlsHandler.go b/pkg/web/handlers/api/v1/chatControlsHandler.go @@ -0,0 +1,88 @@ +package v1 + +import ( + "dkforest/pkg/database" + "dkforest/pkg/utils" + "github.com/labstack/echo" + "net/http" +) + +func ChatControlsHandler(c echo.Context) error { + authUser := c.Get("authUser").(*database.User) + db := c.Get("database").(*database.DkfDB) + + var data chatControlsData + data.RoomName = c.Param("roomName") + data.IsStream = utils.DoParseBool(c.Param("isStream")) + data.TogglePms = utils.DoParseInt64(c.QueryParam("pmonly")) + data.ToggleMentions = utils.DoParseBool(c.QueryParam("mentionsOnly")) + v := c.QueryParams() + if data.TogglePms != 0 { + v.Set("pmonly", utils.FormatInt64(data.TogglePms)) + } + if data.ToggleMentions { + v.Set("mentionsOnly", "1") + } + data.ChatQueryParams = "?" + v.Encode() + + if c.Request().Method == http.MethodPost { + return handlePost(db, c, data, authUser) + } + + return c.Render(http.StatusOK, "chat-controls", data) +} + +func handlePost(db *database.DkfDB, c echo.Context, data chatControlsData, authUser *database.User) error { + formName := c.Request().PostFormValue("formName") + switch formName { + case "toggle-hb": + return handleToggleHBPost(db, c, authUser) + case "toggle-m": + return handleToggleMPost(db, c, authUser) + case "toggle-ignored": + return handleToggleIgnoredPost(db, c, authUser) + case "afk": + return handleAfkPost(db, c, authUser) + case "update-read-marker": + if room, err := db.GetChatRoomByName(data.RoomName); err == nil { + return handleUpdateReadMarkerPost(db, c, room, authUser) + } + } + return c.Redirect(http.StatusFound, c.Request().Referer()) +} + +func handleToggleHBPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { + if authUser.CanSeeHB() { + authUser.DisplayHellbanned = !authUser.DisplayHellbanned + authUser.DoSave(db) + database.MsgPubSub.Pub("refresh_"+string(authUser.Username), database.ChatMessageType{}) + } + return c.Redirect(http.StatusFound, c.Request().Referer()) +} + +func handleToggleMPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { + if authUser.IsModerator() { + authUser.DisplayModerators = !authUser.DisplayModerators + authUser.DoSave(db) + database.MsgPubSub.Pub("refresh_"+string(authUser.Username), database.ChatMessageType{}) + } + return c.Redirect(http.StatusFound, c.Request().Referer()) +} + +func handleToggleIgnoredPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { + authUser.DisplayIgnored = !authUser.DisplayIgnored + authUser.DoSave(db) + database.MsgPubSub.Pub("refresh_"+string(authUser.Username), database.ChatMessageType{}) + return c.Redirect(http.StatusFound, c.Request().Referer()) +} + +func handleAfkPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { + authUser.AFK = !authUser.AFK + authUser.DoSave(db) + return c.Redirect(http.StatusFound, c.Request().Referer()) +} + +func handleUpdateReadMarkerPost(db *database.DkfDB, c echo.Context, room database.ChatRoom, authUser *database.User) error { + db.UpdateChatReadMarker(authUser.ID, room.ID) + return c.Redirect(http.StatusFound, c.Request().Referer()) +} diff --git a/pkg/web/handlers/api/v1/data.go b/pkg/web/handlers/api/v1/data.go @@ -18,6 +18,14 @@ type chatTopBarData struct { CommandsList []string } +type chatControlsData struct { + RoomName string + IsStream bool + ToggleMentions bool + TogglePms int64 + ChatQueryParams string +} + type ChatMenuData struct { InboxCount int64 OfficialRooms []database.ChatRoomAug1 diff --git a/pkg/web/handlers/chat.go b/pkg/web/handlers/chat.go @@ -28,19 +28,11 @@ func chatHandler(c echo.Context, redRoom, stream bool) error { data.PowEnabled = config.PowEnabled.Load() data.RedRoom = redRoom preventRefresh := utils.DoParseBool(c.QueryParam("r")) - data.TogglePms = utils.DoParseInt64(c.QueryParam("pmonly")) - data.ToggleMentions = utils.DoParseBool(c.QueryParam("mentionsOnly")) v := c.QueryParams() if preventRefresh { v.Set("r", "1") } - if data.TogglePms != 0 { - v.Set("pmonly", utils.FormatInt64(data.TogglePms)) - } - if data.ToggleMentions { - v.Set("mentionsOnly", "1") - } if _, found := c.QueryParams()["ml"]; found { v.Set("ml", "1") data.Multiline = true @@ -109,16 +101,6 @@ func handlePost(db *database.DkfDB, c echo.Context, data chatData, authUser *dat switch formName { case "logout": return handleLogoutPost(c, data.Room) - case "toggle-hb": - return handleToggleHBPost(db, c, authUser) - case "toggle-m": - return handleToggleMPost(db, c, authUser) - case "toggle-ignored": - return handleToggleIgnoredPost(db, c, authUser) - case "afk": - return handleAfkPost(db, c, authUser) - case "update-read-marker": - return handleUpdateReadMarkerPost(db, c, data.Room, authUser) case "tutorialP1", "tutorialP2", "tutorialP3": return handleTutorialPost(db, c, data, authUser) case "chat-password": @@ -133,39 +115,6 @@ func handleLogoutPost(c echo.Context, room database.ChatRoom) error { return c.Redirect(http.StatusFound, "/chat") } -func handleToggleHBPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { - if authUser.CanSeeHB() { - authUser.DisplayHellbanned = !authUser.DisplayHellbanned - authUser.DoSave(db) - } - return c.Redirect(http.StatusFound, c.Request().Referer()) -} - -func handleToggleMPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { - if authUser.IsModerator() { - authUser.DisplayModerators = !authUser.DisplayModerators - authUser.DoSave(db) - } - return c.Redirect(http.StatusFound, c.Request().Referer()) -} - -func handleToggleIgnoredPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { - authUser.DisplayIgnored = !authUser.DisplayIgnored - authUser.DoSave(db) - return c.Redirect(http.StatusFound, c.Request().Referer()) -} - -func handleAfkPost(db *database.DkfDB, c echo.Context, authUser *database.User) error { - authUser.AFK = !authUser.AFK - authUser.DoSave(db) - return c.Redirect(http.StatusFound, c.Request().Referer()) -} - -func handleUpdateReadMarkerPost(db *database.DkfDB, c echo.Context, room database.ChatRoom, authUser *database.User) error { - db.UpdateChatReadMarker(authUser.ID, room.ID) - return c.Redirect(http.StatusFound, c.Request().Referer()) -} - func handleTutorialPost(db *database.DkfDB, c echo.Context, data chatData, authUser *database.User) error { if authUser.ChatTutorial < 3 && time.Since(authUser.ChatTutorialTime) >= time.Duration(data.TutoSecs)*time.Second { authUser.ChatTutorial++ diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -373,8 +373,6 @@ type chatData struct { DisplayTutorial bool Multiline bool ChatQueryParams string - ToggleMentions bool - TogglePms int64 RedRoom bool IsSubscribed bool CaptchaID string diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go @@ -274,7 +274,8 @@ func IsAuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc { // Prevent clickjacking by setting the header on every logged in page if !strings.Contains(c.Path(), "/api/v1/chat/messages") && !strings.Contains(c.Path(), "/api/v1/chat/messages/:roomName/stream") && - !strings.Contains(c.Path(), "/api/v1/chat/top-bar") { + !strings.Contains(c.Path(), "/api/v1/chat/top-bar") && + !strings.Contains(c.Path(), "/api/v1/chat/controls") { c.Response().Header().Set("X-Frame-Options", "DENY") } diff --git a/pkg/web/public/views/pages/chat-controls.gohtml b/pkg/web/public/views/pages/chat-controls.gohtml @@ -0,0 +1,70 @@ +{{ define "base" }} +<html lang="en"> + <head> + <title></title> + <link rel="stylesheet" type="text/css" href="/public/css/bootstrap.min.css?v={{ .VERSION }}" /> + <link rel="stylesheet" type="text/css" href="/public/css/style.css?v={{ .VERSION }}" /> + <style> + .btn-xs { + margin: 0 !important; + padding: 0 4px !important; + font-size: 11px !important; + } + form { + padding: 0; + margin: 0; + } + </style> + </head> + <body> + <div style="margin: 0 15px;"> + <a href="/api/v1/chat/messages/{{ .Data.RoomName }}{{ if .Data.IsStream }}/stream{{ end }}{{ .Data.ChatQueryParams }}" target="iframe2" class="btn btn-xs btn-secondary" title="Refresh messages">&#8635;</a> + {{ if .Data.IsStream }}<a href="/api/v1/chat/messages/{{ .Data.RoomName }}/refresh{{ .Data.ChatQueryParams }}" target="_blank" class="btn btn-xs btn-secondary" title="Stop tab loading icon">&#9633;</a>{{ end }} + <a href="/chat/{{ .Data.RoomName }}/archive" target="_top">{{ t "Read all messages" . }}</a> + {{ if .Data.ToggleMentions }} + <a href="/chat/{{ .Data.RoomName }}?mentionsOnly=0" class="btn btn-xs btn-success" title="Only Mentions are displayed" target="_top">Toggle @</a> + {{ else }} + <a href="/chat/{{ .Data.RoomName }}?mentionsOnly=1" class="btn btn-xs btn-secondary" title="All messages displayed" target="_top">Toggle @</a> + {{ end }} + {{ if eq .Data.TogglePms 1 }} + <a href="/chat/{{ .Data.RoomName }}?pmonly=2" class="btn btn-xs btn-success" title="Only PMs are displayed" target="_top">Toggle PM</a> + {{ else if eq .Data.TogglePms 2 }} + <a href="/chat/{{ .Data.RoomName }}?pmonly=0" class="btn btn-xs btn-warning" title="PMs are hidden" target="_top">Toggle PM</a> + {{ else }} + <a href="/chat/{{ .Data.RoomName }}?pmonly=1" class="btn btn-xs btn-secondary" title="All messages displayed" target="_top">Toggle PM</a> + {{ end }} + <form method="post" class="d-inline-block"> + <input type="hidden" name="formName" value="toggle-ignored" /> + <input type="hidden" name="csrf" value="{{ .CSRF }}" /> + <button class="btn btn-xs {{ if .AuthUser.DisplayIgnored }}btn-warning{{ else }}btn-secondary{{ end }}" title="toggle ignored users">Toggle ignored</button> + </form> + {{ if .AuthUser.IsModerator }} + <form method="post" class="d-inline-block"> + <input type="hidden" name="formName" value="toggle-m" /> + <input type="hidden" name="csrf" value="{{ .CSRF }}" /> + <button class="btn btn-xs {{ if .AuthUser.DisplayModerators }}btn-secondary{{ else }}btn-warning{{ end }}" title="toggle moderators messages">Toggle M</button> + </form> + {{ end }} + {{ if .AuthUser.CanSeeHB }} + <form method="post" class="d-inline-block"> + <input type="hidden" name="formName" value="toggle-hb" /> + <input type="hidden" name="csrf" value="{{ .CSRF }}" /> + <button class="btn btn-xs btn-secondary" title="toggle hellban messages">Toggle HB ({{ if .AuthUser.DisplayHellbanned }}on{{ else }}off{{ end }})</button> + </form> + {{ end }} + {{ if .AuthUser.ChatReadMarkerEnabled }} + <form method="post" class="d-inline-block"> + <input type="hidden" name="formName" value="update-read-marker" /> + <input type="hidden" name="csrf" value="{{ .CSRF }}" /> + <button class="btn btn-xs btn-secondary">Update read marker</button> + </form> + {{ end }} + <form method="post" class="d-inline-block"> + <input type="hidden" name="formName" value="afk" /> + <input type="hidden" name="csrf" value="{{ .CSRF }}" /> + <button class="btn btn-xs {{ if .AuthUser.AFK }}btn-danger{{ else }}btn-secondary{{ end }}">afk</button> + </form> + </div> + </body> +</html> +{{ end }} +\ No newline at end of file diff --git a/pkg/web/public/views/pages/chat.gohtml b/pkg/web/public/views/pages/chat.gohtml @@ -15,6 +15,11 @@ width: 100%; height: calc(100vh - {{ if .Data.Multiline }}290{{ else }}190{{ end }}px); } + #chat-controls { + border: 0; + width: 100%; + height: 27px; + } #chat-menu { border: 0; width: 150px; @@ -235,55 +240,9 @@ {{ if and .Data.IsStream (not .AuthUser.HideRightColumn) }}<iframe id="chat-menu" src="/api/v1/chat/messages/{{ .Data.Room.Name }}/stream/menu{{ .Data.ChatQueryParams }}"></iframe>{{ end }} </div> {{ end }} - <div> - <a href="/api/v1/chat/messages/{{ .Data.Room.Name }}{{ if .Data.IsStream }}/stream{{ end }}{{ .Data.ChatQueryParams }}" target="iframe2" class="btn btn-xs btn-secondary" title="Refresh messages">&#8635;</a> - {{ if .Data.IsStream }}<a href="/api/v1/chat/messages/{{ .Data.Room.Name }}/refresh{{ .Data.ChatQueryParams }}" target="_blank" class="btn btn-xs btn-secondary" title="Stop tab loading icon">&#9633;</a>{{ end }} - <a href="/chat/{{ .Data.Room.Name }}/archive">{{ t "Read all messages" . }}</a> - {{ if .Data.ToggleMentions }} - <a href="?mentionsOnly=0" class="btn btn-xs btn-success" title="Only Mentions are displayed">Toggle @</a> - {{ else }} - <a href="?mentionsOnly=1" class="btn btn-xs btn-secondary" title="All messages displayed">Toggle @</a> - {{ end }} - {{ if eq .Data.TogglePms 1 }} - <a href="?pmonly=2" class="btn btn-xs btn-success" title="Only PMs are displayed">Toggle PM</a> - {{ else if eq .Data.TogglePms 2 }} - <a href="?pmonly=0" class="btn btn-xs btn-warning" title="PMs are hidden">Toggle PM</a> - {{ else }} - <a href="?pmonly=1" class="btn btn-xs btn-secondary" title="All messages displayed">Toggle PM</a> - {{ end }} - <form method="post" class="d-inline-block"> - <input type="hidden" name="formName" value="toggle-ignored" /> - <input type="hidden" name="csrf" value="{{ .CSRF }}" /> - <button class="btn btn-xs {{ if .AuthUser.DisplayIgnored }}btn-warning{{ else }}btn-secondary{{ end }}" title="toggle ignored users">Toggle ignored</button> - </form> - {{ if .AuthUser.IsModerator }} - <form method="post" class="d-inline-block"> - <input type="hidden" name="formName" value="toggle-m" /> - <input type="hidden" name="csrf" value="{{ .CSRF }}" /> - <button class="btn btn-xs {{ if .AuthUser.DisplayModerators }}btn-secondary{{ else }}btn-warning{{ end }}" title="toggle moderators messages">Toggle M</button> - </form> - {{ end }} - {{ if .AuthUser.CanSeeHB }} - <form method="post" class="d-inline-block"> - <input type="hidden" name="formName" value="toggle-hb" /> - <input type="hidden" name="csrf" value="{{ .CSRF }}" /> - <button class="btn btn-xs btn-secondary" title="toggle hellban messages">Toggle HB ({{ if .AuthUser.DisplayHellbanned }}on{{ else }}off{{ end }})</button> - </form> - {{ end }} - {{ if .AuthUser.ChatReadMarkerEnabled }} - <form method="post" class="d-inline-block"> - <input type="hidden" name="formName" value="update-read-marker" /> - <input type="hidden" name="csrf" value="{{ .CSRF }}" /> - <button class="btn btn-xs btn-secondary">Update read marker</button> - </form> - {{ end }} - <form method="post" class="d-inline-block"> - <input type="hidden" name="formName" value="afk" /> - <input type="hidden" name="csrf" value="{{ .CSRF }}" /> - <button class="btn btn-xs {{ if .AuthUser.AFK }}btn-danger{{ else }}btn-secondary{{ end }}">afk</button> - </form> - </div> </div> </div> +<iframe id="chat-controls" name="iframe3" src="/api/v1/chat/controls/{{ .Data.Room.Name }}/{{ .Data.IsStream }}{{ .Data.ChatQueryParams }}"></iframe> + {{ end }} \ No newline at end of file diff --git a/pkg/web/web.go b/pkg/web/web.go @@ -143,6 +143,8 @@ func getMainServer(db *database.DkfDB, i18nBundle *i18n.Bundle, renderer *tmp.Te authGroup.POST("/api/v1/chess", v1.ChessHandler) authGroup.POST("/api/v1/werewolf", v1.WerewolfHandler) authGroup.POST("/api/v1/captcha/solver", v1.CaptchaSolverHandler) + authGroup.GET("/api/v1/chat/controls/:roomName/:isStream", v1.ChatControlsHandler) + authGroup.POST("/api/v1/chat/controls/:roomName/:isStream", v1.ChatControlsHandler) authGroup.GET("/api/v1/chat/top-bar/:roomName", v1.ChatTopBarHandler) authGroup.POST("/api/v1/chat/top-bar/:roomName", v1.ChatTopBarHandler, middlewares.AuthRateLimitMiddleware(1*time.Second, 3)) authGroup.GET("/api/v1/chat/messages/:roomName", v1.ChatMessagesHandler)