dkforest

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

commit 409383f7b86312fc65da33e9ff79cd08c7c3ceb5
parent a054f9c241f598bb5f4dc11fefb15dd1a01b34f2
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Tue, 24 Jan 2023 16:09:11 -0800

better archive permalink

Diffstat:
Mpkg/database/tableUsers.go | 5+++++
Mpkg/web/handlers/data.go | 1+
Mpkg/web/handlers/handlers.go | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mpkg/web/public/views/pages/chat-archive.gohtml | 12+++++++-----
4 files changed, 96 insertions(+), 19 deletions(-)

diff --git a/pkg/database/tableUsers.go b/pkg/database/tableUsers.go @@ -301,6 +301,11 @@ func GetVerifiedUserByUsername(username string) (out User, err error) { return } +func GetUsersByID(ids []UserID) (out []User, err error) { + err = DB.Find(&out, "id IN (?)", ids).Error + return +} + func GetUsersByUsername(usernames []string) (out []User, err error) { err = DB.Find(&out, "username IN (?)", usernames).Error return diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -376,6 +376,7 @@ type chatArchiveData struct { Room database.ChatRoom Messages database.ChatMessages DateFormat string + UUID string MessagesCount int64 CurrentPage int64 MaxPage int64 diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -3,6 +3,7 @@ package handlers import ( "bytes" dutils "dkforest/pkg/database/utils" + "dkforest/pkg/hashset" pubsub2 "dkforest/pkg/pubsub" v1 "dkforest/pkg/web/handlers/api/v1" "encoding/base64" @@ -3120,22 +3121,90 @@ func ChatArchiveHandler(c echo.Context) error { return c.Redirect(http.StatusFound, "/chat") } + data.UUID = c.QueryParam("uuid") data.Room = room - if err := database.DB.Table("chat_messages"). - Where("room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)", room.ID, authUser.ID, authUser.ID). - Scopes(func(query *gorm.DB) *gorm.DB { - if !authUser.DisplayIgnored { - query = query.Where(`user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`, authUser.ID) + + if data.UUID != "" { + msg, err := database.GetRoomChatMessageByUUID(room.ID, data.UUID) + if err != nil { + return c.Redirect(http.StatusFound, "/") + } + nbMsg := 150 + args := []any{room.ID, authUser.ID, authUser.ID} + whereClause := `room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)` + if !authUser.DisplayIgnored { + args = append(args, authUser.ID) + whereClause += ` AND user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)` + } + raw := ` + SELECT * FROM ( + SELECT * + FROM chat_messages + WHERE ` + whereClause + ` + AND id >= ? + ORDER BY id ASC + LIMIT ? + ) + UNION + SELECT * FROM ( + SELECT * + FROM chat_messages + WHERE ` + whereClause + ` + AND id < ? + ORDER BY id DESC + LIMIT ? + ) ORDER BY id DESC` + args = append(args, msg.ID, nbMsg) + args = append(args, args...) + database.DB.Raw(raw, args...).Scan(&data.Messages) + + // Manually do Preload("Room") + for _, m := range data.Messages { + m.Room = data.Room + } + + //--- < Manually do a Preload("User") Preload("ToUser") > --- + usersIDs := hashset.New[database.UserID]() + for _, m := range data.Messages { + usersIDs.Insert(m.UserID) + if m.ToUserID != nil { + usersIDs.Insert(*m.ToUserID) } - data.CurrentPage, data.MaxPage, data.MessagesCount, query = NewPaginator().SetResultPerPage(300).Paginate(c, query) - return query - }). - Order("id DESC"). - Preload("Room"). - Preload("User"). - Preload("ToUser"). - Find(&data.Messages).Error; err != nil { - logrus.Error(err) + } + users, _ := database.GetUsersByID(usersIDs.ToArray()) + usersMap := make(map[database.UserID]database.User) + for _, u := range users { + usersMap[u.ID] = u + } + for i, m := range data.Messages { + if u, ok := usersMap[m.UserID]; ok { + data.Messages[i].User = u + } + if m.ToUserID != nil { + if u, ok := usersMap[*m.ToUserID]; ok { + data.Messages[i].ToUser = &u + } + } + } + //--- </ Manually do a Preload("User") Preload("ToUser") > --- + + } else { + if err := database.DB.Debug().Table("chat_messages"). + Where("room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)", room.ID, authUser.ID, authUser.ID). + Scopes(func(query *gorm.DB) *gorm.DB { + if !authUser.DisplayIgnored { + query = query.Where(`user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`, authUser.ID) + } + data.CurrentPage, data.MaxPage, data.MessagesCount, query = NewPaginator().SetResultPerPage(300).Paginate(c, query) + return query + }). + Order("id DESC"). + Preload("Room"). + Preload("User"). + Preload("ToUser"). + Find(&data.Messages).Error; err != nil { + logrus.Error(err) + } } if room.IsProtected() { diff --git a/pkg/web/public/views/pages/chat-archive.gohtml b/pkg/web/public/views/pages/chat-archive.gohtml @@ -114,7 +114,7 @@ {{ end }} {{ end }} {{- if ne $.Data.DateFormat "" -}} - <a style="color: #999; font-family: 'Courier New', Courier, monospace; font-size: 14px;" href="#{{ .UUID }}" title="{{ .CreatedAt.Format "01-02 15:04:05" }}">{{ .CreatedAt.Format $.Data.DateFormat }}</a>&nbsp; + <a style="color: #999; font-family: 'Courier New', Courier, monospace; font-size: 14px;" href="?uuid={{ .UUID }}#{{ .UUID }}" title="{{ .CreatedAt.Format "01-02 15:04:05" }}">{{ .CreatedAt.Format $.Data.DateFormat }}</a>&nbsp; {{- end -}} {{- if and $.AuthUser.CanSeeHB (or .IsHellbanned .User.IsHellbanned) (not .ToUserID) -}} -&nbsp; @@ -148,10 +148,12 @@ {{ end }} </div> - <div class="mb-5"> - <a href="?p={{ add .Data.CurrentPage -1 }}" class="btn btn-light{{ if le .Data.CurrentPage 1 }} disabled{{ end }}">&laquo; {{ t "Prev" . }}</a> - <a href="?p={{ add .Data.CurrentPage 1 }}" class="btn btn-light{{ if eq .Data.CurrentPage .Data.MaxPage }} disabled{{ end }}">{{ t "Next" . }} &raquo;</a> - </div> + {{ if not .Data.UUID }} + <div class="mb-5"> + <a href="?p={{ add .Data.CurrentPage -1 }}" class="btn btn-light{{ if le .Data.CurrentPage 1 }} disabled{{ end }}">&laquo; {{ t "Prev" . }}</a> + <a href="?p={{ add .Data.CurrentPage 1 }}" class="btn btn-light{{ if eq .Data.CurrentPage .Data.MaxPage }} disabled{{ end }}">{{ t "Next" . }} &raquo;</a> + </div> + {{ end }} </div> {{ end }} \ No newline at end of file