dkforest

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

commit 5499c6fcc904d647a4206400e29d4917e6d407a7
parent d4eb6eabb7a70576f5630273eabee4575f95d079
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sun, 23 Feb 2025 00:14:46 -0800

get rid of cookie for keeping track of last known messages in non-stream chat version for sound notification

Diffstat:
Acmd/dkf/migrations/165.sql | 20++++++++++++++++++++
Mpkg/actions/actions.go | 1+
Apkg/database/tableUserLastKnownMessages.go | 37+++++++++++++++++++++++++++++++++++++
Mpkg/web/handlers/api/v1/handlers.go | 47+++++++++++++++++++++++------------------------
Mpkg/web/handlers/utils/utils.go | 12------------
5 files changed, 81 insertions(+), 36 deletions(-)

diff --git a/cmd/dkf/migrations/165.sql b/cmd/dkf/migrations/165.sql @@ -0,0 +1,20 @@ +-- +migrate Up +CREATE TABLE IF NOT EXISTS user_last_known_messages ( + user_id INTEGER NOT NULL, + room_id INTEGER NOT NULL, + last_known_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (user_id, room_id), + CONSTRAINT user_last_known_messages_room_id_fk + FOREIGN KEY (room_id) + REFERENCES chat_rooms (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT user_last_known_messages_user_id_fk + FOREIGN KEY (user_id) + REFERENCES users (id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +-- +migrate Down diff --git a/pkg/actions/actions.go b/pkg/actions/actions.go @@ -360,6 +360,7 @@ func cleanupDatabase(db *database.DkfDB) { db.DeleteOldChatInboxMessages() db.DeleteOldDownloads() db.DeleteOldSessionNotifications() + db.DeleteOldUserLastKnownMessages() logrus.Debugf("done cleaning database, took %s", time.Since(start)) } } diff --git a/pkg/database/tableUserLastKnownMessages.go b/pkg/database/tableUserLastKnownMessages.go @@ -0,0 +1,37 @@ +package database + +import ( + "github.com/sirupsen/logrus" + "time" +) + +// UserLastKnownMessage ... +type UserLastKnownMessage struct { + UserID UserID `gorm:"primary_key"` + RoomID RoomID `gorm:"primary_key"` + LastKnownTimestamp time.Time + CreatedAt time.Time +} + +// GetUserLastKnownMessage ... +func (d *DkfDB) GetUserLastKnownMessage(userID UserID, roomID RoomID) (out UserLastKnownMessage, err error) { + err = d.db.First(&out, "user_id = ? AND room_id = ?", userID, roomID).Error + return +} + +// CreateUserLastKnownMessage ... +func (d *DkfDB) CreateUserLastKnownMessage(userID UserID, roomID RoomID, lastKnownTimestamp time.Time) error { + out := UserLastKnownMessage{UserID: userID, RoomID: roomID} + if err := d.db.FirstOrCreate(&out, "user_id = ? AND room_id = ?", userID, roomID).Error; err != nil { + return err + } + out.LastKnownTimestamp = lastKnownTimestamp + return d.db.Save(&out).Error +} + +// DeleteOldUserLastKnownMessages ... +func (d *DkfDB) DeleteOldUserLastKnownMessages() { + if err := d.db.Delete(UserLastKnownMessage{}, "created_at < date('now', '-1 Day')").Error; err != nil { + logrus.Error(err) + } +} diff --git a/pkg/web/handlers/api/v1/handlers.go b/pkg/web/handlers/api/v1/handlers.go @@ -106,14 +106,13 @@ func chatMessages(c echo.Context) (status int, data ChatMessagesData) { data.Messages = msgs data.ReadMarker, _ = db.GetUserReadMarker(authUser.ID, room.ID) data.NbButtons = authUser.CountUIButtons() - if authUser.NotifyNewMessage || authUser.NotifyPmmed || authUser.NotifyTagged { - lastKnownDate := "" - if lastKnownDateCookie, err := hutils.GetLastMsgCookie(c, roomName); err == nil { - lastKnownDate = lastKnownDateCookie.Value + lastKnownDate := time.Now() + if out, err := db.GetUserLastKnownMessage(authUser.ID, room.ID); err == nil { + lastKnownDate = out.LastKnownTimestamp } newMessageSound, pmSound, taggedSound, lastMessageCreatedAt := shouldPlaySound(authUser, lastKnownDate, msgs) - hutils.CreateLastMsgCookie(c, roomName, lastMessageCreatedAt) + utils.LogErr(db.CreateUserLastKnownMessage(authUser.ID, room.ID, lastMessageCreatedAt)) data.NewMessageSound = utils.TernaryOrZero(authUser.NotifyNewMessage, newMessageSound) data.PmSound = utils.TernaryOrZero(authUser.NotifyPmmed, pmSound) data.TaggedSound = utils.TernaryOrZero(authUser.NotifyTagged, taggedSound) @@ -190,38 +189,38 @@ func RoomNotifierHandler(c echo.Context) error { } var data testData - - data.NewMessageSound, data.PmSound, data.TaggedSound, data.LastMessageCreatedAt = shouldPlaySound(authUser, lastKnownDate, msgs) + lastKnownMsgDate, _ := time.Parse(time.RFC3339Nano, lastKnownDate) + var lastMessageCreatedAt time.Time + data.NewMessageSound, data.PmSound, data.TaggedSound, lastMessageCreatedAt = shouldPlaySound(authUser, lastKnownMsgDate, msgs) + data.LastMessageCreatedAt = lastMessageCreatedAt.Format(time.RFC3339Nano) data.InboxCount = db.GetUserInboxMessagesCount(authUser.ID) return c.JSON(http.StatusOK, data) } // Given a "lastKnownDate" and a list of messages, returns what sound notification should be played. -func shouldPlaySound(authUser *database.User, lastKnownDate string, msgs []database.ChatMessage) (newMessageSound, pmSound, taggedSound bool, lastMsgCreatedAt string) { +func shouldPlaySound(authUser *database.User, lastKnownMsgDate time.Time, msgs []database.ChatMessage) (newMessageSound, pmSound, taggedSound bool, lastMsgCreatedAt time.Time) { if len(msgs) > 0 { - if lastKnownMsgDate, err := time.Parse(time.RFC3339Nano, lastKnownDate); err == nil { - for _, msg := range msgs { - lastKnownDateTrunc := lastKnownMsgDate.Truncate(time.Second) - createdAtTrunc := msg.CreatedAt.Truncate(time.Second) - if createdAtTrunc.After(lastKnownDateTrunc) { - if msg.User.ID != authUser.ID { - newMessageSound = true - if strings.Contains(msg.Message, authUser.Username.AtStr()) { - taggedSound = true - } - if msg.IsPmRecipient(authUser.ID) { - pmSound = true - } - break + for _, msg := range msgs { + lastKnownDateTrunc := lastKnownMsgDate.Truncate(time.Second) + createdAtTrunc := msg.CreatedAt.Truncate(time.Second) + if createdAtTrunc.After(lastKnownDateTrunc) { + if msg.User.ID != authUser.ID { + newMessageSound = true + if strings.Contains(msg.Message, authUser.Username.AtStr()) { + taggedSound = true + } + if msg.IsPmRecipient(authUser.ID) { + pmSound = true } - } else if createdAtTrunc.Before(lastKnownMsgDate) { break } + } else if createdAtTrunc.Before(lastKnownMsgDate) { + break } } lastMsg := msgs[0] - lastMsgCreatedAt = lastMsg.CreatedAt.Format(time.RFC3339) + lastMsgCreatedAt = lastMsg.CreatedAt } return newMessageSound, pmSound, taggedSound, lastMsgCreatedAt } diff --git a/pkg/web/handlers/utils/utils.go b/pkg/web/handlers/utils/utils.go @@ -94,10 +94,6 @@ func getGistCookieName(gistUUID string) string { return fmt.Sprintf("gist_%s_auth", gistUUID) } -func getLastMsgCookieName(roomName string) string { - return fmt.Sprintf("last_known_msg_%s", roomName) -} - func getRoomCookieName(roomID int64) string { return fmt.Sprintf("room_%d_auth", roomID) } @@ -136,14 +132,6 @@ func CreateGistCookie(c echo.Context, gistUUID, v string) { c.SetCookie(CreateCookie(getGistCookieName(gistUUID), v, utils.OneDaySecs)) } -func CreateLastMsgCookie(c echo.Context, roomName, v string) { - c.SetCookie(CreateCookie(getLastMsgCookieName(roomName), v, utils.OneDaySecs)) -} - -func GetLastMsgCookie(c echo.Context, roomName string) (*http.Cookie, error) { - return c.Cookie(getLastMsgCookieName(roomName)) -} - func CreatePokerReferralCookie(c echo.Context, v string) { c.SetCookie(CreateCookie(PokerReferralName, v, utils.OneDaySecs)) }