dkforest

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

commit d2719816d685aee1847c03931211d1514c5d04bf
parent 3b7d9284d4b4a95d86177a14be0d977b54cb91ae
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Tue, 24 Jan 2023 19:40:39 -0800

hide/unhide messages

Diffstat:
Acmd/dkf/migrations/122.sql | 17+++++++++++++++++
Mpkg/database/tableChatMessages.go | 5++++-
Apkg/database/tableIgnoredMessages.go | 23+++++++++++++++++++++++
Mpkg/web/handlers/api/v1/handlers.go | 8++++++--
Mpkg/web/handlers/api/v1/slashInterceptor.go | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/web/handlers/api/v1/topBarHandler.go | 2++
Mpkg/web/public/views/pages/chat-help.gohtml | 10++++++++++
7 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/cmd/dkf/migrations/122.sql b/cmd/dkf/migrations/122.sql @@ -0,0 +1,17 @@ +-- +migrate Up +CREATE TABLE IF NOT EXISTS ignored_messages ( + user_id INTEGER NOT NULL, + message_id INTEGER NOT NULL, + PRIMARY KEY (user_id, message_id), + CONSTRAINT ignored_messages_user_id_fk + FOREIGN KEY (user_id) + REFERENCES users (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT ignored_messages_message_id_fk + FOREIGN KEY (message_id) + REFERENCES chat_messages (id) + ON DELETE CASCADE + ON UPDATE CASCADE); + +-- +migrate Down diff --git a/pkg/database/tableChatMessages.go b/pkg/database/tableChatMessages.go @@ -283,7 +283,7 @@ const ( PmNone ) -func GetChatMessages(roomID RoomID, username string, userID UserID, displayPms PmDisplayMode, mentionsOnly, displayHellbanned, displayIgnored, displayModerators bool) (out ChatMessages, err error) { +func GetChatMessages(roomID RoomID, username string, userID UserID, displayPms PmDisplayMode, mentionsOnly, displayHellbanned, displayIgnored, displayModerators, displayIgnoredMessages bool) (out ChatMessages, err error) { cmp := func(t, t2 ChatMessage) bool { return t.ID > t2.ID } @@ -295,6 +295,9 @@ func GetChatMessages(roomID RoomID, username string, userID UserID, displayPms P Limit(150). Where(`room_id = ? AND group_id IS NULL`, roomID). Order("id DESC") + if !displayIgnoredMessages { + q = q.Where(`id NOT IN (SELECT message_id FROM ignored_messages WHERE user_id = ?)`, userID) + } if !displayIgnored { q = q.Where(`user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`, userID) } diff --git a/pkg/database/tableIgnoredMessages.go b/pkg/database/tableIgnoredMessages.go @@ -0,0 +1,23 @@ +package database + +import ( + "github.com/sirupsen/logrus" +) + +type IgnoredMessage struct { + UserID UserID + MessageID int64 +} + +func IgnoreMessage(userID UserID, messageID int64) { + ignore := IgnoredMessage{UserID: userID, MessageID: messageID} + if err := DB.Create(&ignore).Error; err != nil { + logrus.Error(err) + } +} + +func UnIgnoreMessage(userID UserID, messageID int64) { + if err := DB.Delete(&IgnoredMessage{}, "user_id = ? AND message_id = ?", userID, messageID).Error; err != nil { + logrus.Error(err) + } +} diff --git a/pkg/web/handlers/api/v1/handlers.go b/pkg/web/handlers/api/v1/handlers.go @@ -75,6 +75,8 @@ var groupRmUserRgx = regexp.MustCompile(`^/grmuser (` + groupName + `) ` + optAt var unsubscribeRgx = regexp.MustCompile(`^/unsubscribe (` + roomNameF + `)$`) var bsRgx = regexp.MustCompile(`^/pm ` + optAtGUser + ` /bs\s?([A-J]\d)?$`) var cRgx = regexp.MustCompile(`^/pm ` + optAtGUser + ` /c\s?(move)?$`) +var hideRgx = regexp.MustCompile(`^/hide (\d{2}:\d{2}:\d{2})$`) +var unhideRgx = regexp.MustCompile(`^/unhide (\d{2}:\d{2}:\d{2})$`) // ChatMessagesHandler room messages iframe handler // The chat messages iframe use this endpoint to get the messages for a room. @@ -108,7 +110,8 @@ func ChatMessagesHandler(c echo.Context) error { membersInRoom, membersInChat := managers.ActiveUsers.GetRoomUsers(room, ignoredSet) displayHellbanned := authUser.DisplayHellbanned || authUser.IsHellbanned - msgs, _ := database.GetChatMessages(room.ID, authUser.Username, authUser.ID, pmOnlyQuery, mentionsOnlyQuery, displayHellbanned, authUser.DisplayIgnored, authUser.DisplayModerators) + displayIgnoredMessages := true + msgs, _ := database.GetChatMessages(room.ID, authUser.Username, authUser.ID, pmOnlyQuery, mentionsOnlyQuery, displayHellbanned, authUser.DisplayIgnored, authUser.DisplayModerators, displayIgnoredMessages) if room.IsProtected() { key, err := hutils.GetRoomKeyCookie(c, int64(room.ID)) if err != nil { @@ -193,7 +196,8 @@ func RoomNotifierHandler(c echo.Context) error { managers.ActiveUsers.UpdateUserInRoom(room, managers.NewUserInfo(*authUser, nil)) displayHellbanned := authUser.DisplayHellbanned || authUser.IsHellbanned - msgs, _ := database.GetChatMessages(roomID, authUser.Username, authUser.ID, database.PmNoFilter, false, displayHellbanned, authUser.DisplayIgnored, authUser.DisplayModerators) + displayIgnoredMessages := true + msgs, _ := database.GetChatMessages(roomID, authUser.Username, authUser.ID, database.PmNoFilter, false, displayHellbanned, authUser.DisplayIgnored, authUser.DisplayModerators, displayIgnoredMessages) if room.IsProtected() { key, err := hutils.GetRoomKeyCookie(c, int64(room.ID)) if err != nil { diff --git a/pkg/web/handlers/api/v1/slashInterceptor.go b/pkg/web/handlers/api/v1/slashInterceptor.go @@ -52,6 +52,8 @@ func handleUserCmd(c *Command) (handled bool) { handleToggleAutocomplete(c) || handleTutorialCmd(c) || handleDeleteMsgCmd(c) || + handleHideMsgCmd(c) || + handleUnHideMsgCmd(c) || handleListIgnoredCmd(c) || handleListPmWhitelistCmd(c) || handleSetPmModeWhitelistCmd(c) || @@ -1339,6 +1341,56 @@ func handleDeleteMsgCmd(c *Command) (handled bool) { return } +func handleHideMsgCmd(c *Command) (handled bool) { + if m := hideRgx.FindStringSubmatch(c.message); len(m) == 2 { + date := m[1] + dt, err := utils.ParsePrevDatetimeAt(date, clockwork.NewRealClock()) + if err != nil { + logrus.Error(err) + c.err = err + return true + } + msgs, err := database.GetRoomChatMessagesByDate(c.room.ID, dt.UTC()) + if err != nil { + c.err = err + return true + } + if len(msgs) == 1 { + database.IgnoreMessage(c.authUser.ID, msgs[0].ID) + c.err = ErrRedirect + } else { + c.err = errors.New("more than 1 message") + } + return true + } + return +} + +func handleUnHideMsgCmd(c *Command) (handled bool) { + if m := unhideRgx.FindStringSubmatch(c.message); len(m) == 2 { + date := m[1] + dt, err := utils.ParsePrevDatetimeAt(date, clockwork.NewRealClock()) + if err != nil { + logrus.Error(err) + c.err = err + return true + } + msgs, err := database.GetRoomChatMessagesByDate(c.room.ID, dt.UTC()) + if err != nil { + c.err = err + return true + } + if len(msgs) == 1 { + database.UnIgnoreMessage(c.authUser.ID, msgs[0].ID) + c.err = ErrRedirect + } else { + c.err = errors.New("more than 1 message") + } + return true + } + return +} + func handleIgnoreCmd(c *Command) (handled bool) { if m := ignoreRgx.FindStringSubmatch(c.message); len(m) == 2 { username := m[1] diff --git a/pkg/web/handlers/api/v1/topBarHandler.go b/pkg/web/handlers/api/v1/topBarHandler.go @@ -153,6 +153,8 @@ func buildCommandsList(authUser *database.User, room database.ChatRoom) (command commandsList = append(commandsList, "/inbox ") commandsList = append(commandsList, "/toggle-autocomplete") commandsList = append(commandsList, "/d") + commandsList = append(commandsList, "/hide") + commandsList = append(commandsList, "/unhide") commandsList = append(commandsList, "/pmwhitelist") commandsList = append(commandsList, "/setpmmode whitelist") commandsList = append(commandsList, "/setpmmode standard") diff --git a/pkg/web/public/views/pages/chat-help.gohtml b/pkg/web/public/views/pages/chat-help.gohtml @@ -96,6 +96,16 @@ {{ end }} <div> + <div><code>/hide HH:MM:SS</code></div> + <p>Hide message at specified timestamp</p> + </div> + + <div> + <div><code>/unhide HH:MM:SS</code></div> + <p>Un-hide message at specified timestamp</p> + </div> + + <div> <div><code>/g groupName</code></div> <p>Send message to specified group</p> </div>