commit 409383f7b86312fc65da33e9ff79cd08c7c3ceb5
parent a054f9c241f598bb5f4dc11fefb15dd1a01b34f2
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Tue, 24 Jan 2023 16:09:11 -0800
better archive permalink
Diffstat:
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>
+ <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>
{{- end -}}
{{- if and $.AuthUser.CanSeeHB (or .IsHellbanned .User.IsHellbanned) (not .ToUserID) -}}
-
@@ -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 }}">« {{ t "Prev" . }}</a>
- <a href="?p={{ add .Data.CurrentPage 1 }}" class="btn btn-light{{ if eq .Data.CurrentPage .Data.MaxPage }} disabled{{ end }}">{{ t "Next" . }} »</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 }}">« {{ t "Prev" . }}</a>
+ <a href="?p={{ add .Data.CurrentPage 1 }}" class="btn btn-light{{ if eq .Data.CurrentPage .Data.MaxPage }} disabled{{ end }}">{{ t "Next" . }} »</a>
+ </div>
+ {{ end }}
</div>
{{ end }}
\ No newline at end of file