dkforest

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

commit e0005caaf70b96f43af3bb8b417feb3f57c25ea9
parent ec8ed62be439aabf9d0e6120311d92bb9dc217f5
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Fri, 16 Jun 2023 05:26:49 -0700

Fix read-marker bug when messages are edited

Diffstat:
Mpkg/web/handlers/api/v1/chat.go | 17++++++++++++++---
Mpkg/web/handlers/api/v1/messages.qtpl | 18++++++++++++------
Mpkg/web/handlers/api/v1/messages.qtpl.go | 1124++++++++++++++++++++++++++++++++++++++++---------------------------------------
3 files changed, 602 insertions(+), 557 deletions(-)

diff --git a/pkg/web/handlers/api/v1/chat.go b/pkg/web/handlers/api/v1/chat.go @@ -150,7 +150,7 @@ func ChatStreamMessagesHandler(c echo.Context) error { data.Messages = msgs data.NbButtons = authUser.CountUIButtons() nullUsername := config.NullUsername - send("<div>" + RenderMessages(authUser, data, csrf, nullUsername) + "</div>") + send("<div>" + RenderMessages(authUser, data, csrf, nullUsername, nil, false) + "</div>") c.Response().Flush() // Create a subscriber and topics to listen to @@ -301,7 +301,18 @@ Loop: // Render the new revision of the messages in html data.Messages = msgs data.NbButtons = authUser.CountUIButtons() - send(RenderMessages(authUser, data, csrf, nullUsername)) + data.ReadMarker, _ = db.GetUserReadMarker(authUser.ID, room.ID) + + // Only try to redraw the read-marker if the first message + // that we redraw is older than our read-marker position. + var readMarkerRevRef *int + fstMsgTsRound := msgs[0].CreatedAt.Round(time.Second) + readMarkerTsRound := data.ReadMarker.ReadAt.Round(time.Second) + if !fstMsgTsRound.After(readMarkerTsRound) { + readMarkerRevRef = &readMarkerRev + } + + send(RenderMessages(authUser, data, csrf, nullUsername, readMarkerRevRef, true)) c.Response().Flush() continue @@ -324,7 +335,7 @@ Loop: baseTopBarURL := "/api/v1/chat/top-bar/" + room.Name readMarkerRendered := true isFirstMsg := false - renderedMsg := RenderMessage(1, *msg, authUser, data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, csrf, nullUsername) + renderedMsg := RenderMessage(1, *msg, authUser, data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, csrf, nullUsername, &readMarkerRev, false) // Keep track of unread messages msgsMap.Set(msg.ID) diff --git a/pkg/web/handlers/api/v1/messages.qtpl b/pkg/web/handlers/api/v1/messages.qtpl @@ -1,5 +1,6 @@ {% import "dkforest/pkg/database" %} {% import "dkforest/pkg/managers" %} +{% import "time" %} {% import humanize "github.com/dustin/go-humanize" %} {%- func GenerateStyle(AuthUser *database.User, Data ChatMessagesData) -%} @@ -238,7 +239,7 @@ {%- endif -%} <div id="msgs"> - {%-= RenderMessages(AuthUser, Data, CSRF, NullUsername) -%} + {%-= RenderMessages(AuthUser, Data, CSRF, NullUsername, nil, false) -%} </div> {% if !AuthUser.HideRightColumn %} @@ -303,14 +304,14 @@ </div> {%- endfunc -%} -{%- func RenderMessages(AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) -%} +{%- func RenderMessages(AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) -%} {%- code baseTopBarURL := "/api/v1/chat/top-bar/" + Data.ChatMenuData.RoomName readMarkerRendered := false isFirstMsg := true -%} {%- for idx, e := range Data.Messages -%} - {%-= RenderMessage(idx, e, AuthUser, Data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, CSRF, NullUsername) -%} + {%-= RenderMessage(idx, e, AuthUser, Data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, CSRF, NullUsername, readMarkerRev, isEdit) -%} {% endfor %} {% if len(Data.Messages) == 0 %} <div id="no-msg"><em>No message yet</em></div> @@ -318,12 +319,17 @@ {%- endfunc -%} {%- func RenderMessage(idx int, e database.ChatMessage, AuthUser *database.User, - Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string) -%} + Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) -%} {%- if e.UserCanSee(*AuthUser) -%} - {%- if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !*readMarkerRendered %} + {%- if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !*readMarkerRendered && readMarkerRev == nil && !isEdit%} <div class="read-marker read-marker-0"{% if idx == 0 %} style="display:none;"{% endif %}></div> {%- code *readMarkerRendered = true -%} - {%- endif -%} + {%- elseif AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Round(time.Second).After(Data.ReadMarker.ReadAt.Round(time.Second)) && !*readMarkerRendered && readMarkerRev != nil && isEdit -%} + <style>.read-marker-{%d (*readMarkerRev) %}{display:none !important;}</style> + {%- code *readMarkerRev++ -%} + <div class="read-marker read-marker-{%d *readMarkerRev %}"></div> + {%- code *readMarkerRendered = true -%} + {% endif %} <div id="msgid-{%s e.UUID %}" class="msgidc-{%s e.UUID %}-{%dl e.Rev %} msg {%- if (e.User.IsHellbanned || e.IsHellbanned) && AuthUser.DisplayHellbanned %} hb-row {%- elseif AuthUser.ID == e.User.ID && AuthUser.HighlightOwnMessages %} own-highlight{%- endif -%} diff --git a/pkg/web/handlers/api/v1/messages.qtpl.go b/pkg/web/handlers/api/v1/messages.qtpl.go @@ -11,24 +11,27 @@ import "dkforest/pkg/database" import "dkforest/pkg/managers" //line messages.qtpl:3 +import "time" + +//line messages.qtpl:4 import humanize "github.com/dustin/go-humanize" -//line messages.qtpl:5 +//line messages.qtpl:6 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line messages.qtpl:5 +//line messages.qtpl:6 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer ) -//line messages.qtpl:5 +//line messages.qtpl:6 func StreamGenerateStyle(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData) { -//line messages.qtpl:5 +//line messages.qtpl:6 qw422016.N().S(`<style> /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 @@ -149,20 +152,20 @@ func StreamGenerateStyle(qw422016 *qt422016.Writer, AuthUser *database.User, Dat } #manualrefresh { `) -//line messages.qtpl:125 +//line messages.qtpl:126 if !Data.ForceManualRefresh { -//line messages.qtpl:125 +//line messages.qtpl:126 qw422016.N().S(` top: -200%; animation: timeout_messages `) -//line messages.qtpl:127 +//line messages.qtpl:128 qw422016.N().DL(Data.ManualRefreshTimeout) -//line messages.qtpl:127 +//line messages.qtpl:128 qw422016.N().S(`s forwards; `) -//line messages.qtpl:128 +//line messages.qtpl:129 } -//line messages.qtpl:128 +//line messages.qtpl:129 qw422016.N().S(` color: #bf2718; display: block; @@ -188,9 +191,9 @@ func StreamGenerateStyle(qw422016 *qt422016.Writer, AuthUser *database.User, Dat strong { font-weight: bold; } em { font-style: italic; } pre { border: 1px solid #2b442b; padding: 2px; margin: 2px 0; max-height: `) -//line messages.qtpl:152 +//line messages.qtpl:153 qw422016.N().DL(AuthUser.CodeBlockHeight) -//line messages.qtpl:152 +//line messages.qtpl:153 qw422016.N().S(`px; overflow: auto; background-color: rgba(39,40,34,0.6) !important; font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; } .fullscreen { position: absolute; margin-top: -19px; right: 3px; } @@ -215,28 +218,28 @@ func StreamGenerateStyle(qw422016 *qt422016.Writer, AuthUser *database.User, Dat .f-white-clr, .f-white-clr:hover { color: white; } .line-through { text-decoration: line-through; } .hb-row { background-color: rgba(0, 0, 0, 0.7); opacity: `) -//line messages.qtpl:175 +//line messages.qtpl:176 qw422016.N().F(AuthUser.GetHellbanOpacityF64()) -//line messages.qtpl:175 +//line messages.qtpl:176 qw422016.N().S(`; } .own-highlight { background-color: rgba(255,241,176,0.05); } .read-marker { border-style: outset; border-top: `) -//line messages.qtpl:177 +//line messages.qtpl:178 qw422016.N().DL(AuthUser.ChatReadMarkerSize) -//line messages.qtpl:177 +//line messages.qtpl:178 qw422016.N().S(`px solid `) -//line messages.qtpl:177 +//line messages.qtpl:178 qw422016.E().S(AuthUser.ChatReadMarkerColor) -//line messages.qtpl:177 +//line messages.qtpl:178 qw422016.N().S(`; } #msgs { `) -//line messages.qtpl:178 +//line messages.qtpl:179 if !AuthUser.HideRightColumn { -//line messages.qtpl:178 +//line messages.qtpl:179 qw422016.N().S(`width: calc(100% - 185px); float: left; `) -//line messages.qtpl:178 +//line messages.qtpl:179 } -//line messages.qtpl:178 +//line messages.qtpl:179 qw422016.N().S(`line-height: 1.2; } #no-msg { padding-left: 10px; color: #ddd; } #rgt-pane-w { width: 150px; height: 100%; position: fixed; right: 15px; overflow-y: auto; } @@ -262,86 +265,86 @@ func StreamGenerateStyle(qw422016 *qt422016.Writer, AuthUser *database.User, Dat @keyframes i2 { 0% { background-color: #006400; } 32% { background-color: #006400; } 33% { background-color: #626400; } 99% { background-color: #626400; } 100% { background-color: #8b0000; } } </style> `) -//line messages.qtpl:202 +//line messages.qtpl:203 } -//line messages.qtpl:202 +//line messages.qtpl:203 func WriteGenerateStyle(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData) { -//line messages.qtpl:202 +//line messages.qtpl:203 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:202 +//line messages.qtpl:203 StreamGenerateStyle(qw422016, AuthUser, Data) -//line messages.qtpl:202 +//line messages.qtpl:203 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:202 +//line messages.qtpl:203 } -//line messages.qtpl:202 +//line messages.qtpl:203 func GenerateStyle(AuthUser *database.User, Data ChatMessagesData) string { -//line messages.qtpl:202 +//line messages.qtpl:203 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:202 +//line messages.qtpl:203 WriteGenerateStyle(qb422016, AuthUser, Data) -//line messages.qtpl:202 +//line messages.qtpl:203 qs422016 := string(qb422016.B) -//line messages.qtpl:202 +//line messages.qtpl:203 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:202 +//line messages.qtpl:203 return qs422016 -//line messages.qtpl:202 +//line messages.qtpl:203 } -//line messages.qtpl:204 +//line messages.qtpl:205 func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) { -//line messages.qtpl:204 +//line messages.qtpl:205 qw422016.N().S(`<html lang="en"> <head> <title></title> `) -//line messages.qtpl:208 +//line messages.qtpl:209 if !Data.ChatMenuData.PreventRefresh && !Data.ForceManualRefresh { -//line messages.qtpl:208 +//line messages.qtpl:209 qw422016.N().S(`<meta http-equiv="refresh" content="`) -//line messages.qtpl:208 +//line messages.qtpl:209 qw422016.N().DL(AuthUser.RefreshRate) -//line messages.qtpl:208 +//line messages.qtpl:209 qw422016.N().S(`">`) -//line messages.qtpl:208 - } //line messages.qtpl:209 + } +//line messages.qtpl:210 if AuthUser.CollectMetadata { -//line messages.qtpl:209 +//line messages.qtpl:210 qw422016.N().S(`<link rel="stylesheet" type="text/css" href="/public/css/meta.css?v=`) -//line messages.qtpl:209 +//line messages.qtpl:210 qw422016.E().S(VERSION) -//line messages.qtpl:209 +//line messages.qtpl:210 qw422016.N().S(`" />`) -//line messages.qtpl:209 - } //line messages.qtpl:210 + } +//line messages.qtpl:211 StreamGenerateStyle(qw422016, AuthUser, Data) -//line messages.qtpl:210 +//line messages.qtpl:211 qw422016.N().S(` </head> <body> `) -//line messages.qtpl:214 +//line messages.qtpl:215 if Data.ForceManualRefresh { -//line messages.qtpl:214 +//line messages.qtpl:215 qw422016.N().S(` <div id="manualrefresh"> <h4>Manual refresh required</h4> <form method="get" action="/chat/`) -//line messages.qtpl:217 +//line messages.qtpl:218 qw422016.E().S(Data.ChatMenuData.RoomName) -//line messages.qtpl:217 +//line messages.qtpl:218 qw422016.N().S(`" target="_top"> <input type="submit" value="Reload" /> </form> </div> `) -//line messages.qtpl:221 +//line messages.qtpl:222 } else if !Data.ChatMenuData.PreventRefresh { -//line messages.qtpl:221 +//line messages.qtpl:222 qw422016.N().S(` <div id="manualrefresh"> <h4>Manual refresh required</h4> <form method="get"> @@ -349,1091 +352,1116 @@ func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername strin </form> </div> `) -//line messages.qtpl:228 +//line messages.qtpl:229 } -//line messages.qtpl:228 +//line messages.qtpl:229 qw422016.N().S(` `) -//line messages.qtpl:230 +//line messages.qtpl:231 if Data.Error != "" { -//line messages.qtpl:230 - qw422016.N().S(` <a href="/api/v1/chat/messages/`) //line messages.qtpl:231 + qw422016.N().S(` <a href="/api/v1/chat/messages/`) +//line messages.qtpl:232 qw422016.E().S(Data.ChatMenuData.RoomName) -//line messages.qtpl:231 +//line messages.qtpl:232 qw422016.N().S(`" id="msg-err">× `) -//line messages.qtpl:231 +//line messages.qtpl:232 qw422016.E().S(Data.Error) -//line messages.qtpl:231 +//line messages.qtpl:232 qw422016.N().S(`</a> `) -//line messages.qtpl:232 +//line messages.qtpl:233 } -//line messages.qtpl:232 +//line messages.qtpl:233 qw422016.N().S(` `) -//line messages.qtpl:234 +//line messages.qtpl:235 if Data.PmSound || Data.TaggedSound { -//line messages.qtpl:234 +//line messages.qtpl:235 qw422016.N().S(` <audio src="/public/mp3/sound5.mp3" autoplay></audio> `) -//line messages.qtpl:236 +//line messages.qtpl:237 } else if Data.NewMessageSound { -//line messages.qtpl:236 +//line messages.qtpl:237 qw422016.N().S(` <audio src="/public/mp3/sound6.mp3" autoplay></audio> `) -//line messages.qtpl:238 +//line messages.qtpl:239 } -//line messages.qtpl:238 +//line messages.qtpl:239 qw422016.N().S(` <div id="msgs"> `) -//line messages.qtpl:241 - StreamRenderMessages(qw422016, AuthUser, Data, CSRF, NullUsername) -//line messages.qtpl:241 +//line messages.qtpl:242 + StreamRenderMessages(qw422016, AuthUser, Data, CSRF, NullUsername, nil, false) +//line messages.qtpl:242 qw422016.N().S(` </div> `) -//line messages.qtpl:244 +//line messages.qtpl:245 if !AuthUser.HideRightColumn { -//line messages.qtpl:244 +//line messages.qtpl:245 qw422016.N().S(` <div id="rgt-pane-w"> `) -//line messages.qtpl:246 +//line messages.qtpl:247 StreamRenderRightColumn(qw422016, AuthUser, Data.ChatMenuData) -//line messages.qtpl:246 +//line messages.qtpl:247 qw422016.N().S(` </div> `) -//line messages.qtpl:248 - } //line messages.qtpl:249 + } +//line messages.qtpl:250 if AuthUser.CollectMetadata { -//line messages.qtpl:249 +//line messages.qtpl:250 qw422016.N().S(` <div class="div_1"></div> <div class="div_2"></div> <div class="div_f0">a</div> `) -//line messages.qtpl:253 +//line messages.qtpl:254 } -//line messages.qtpl:253 +//line messages.qtpl:254 qw422016.N().S(` </body> </html> `) -//line messages.qtpl:256 +//line messages.qtpl:257 } -//line messages.qtpl:256 +//line messages.qtpl:257 func WriteMessages(qq422016 qtio422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) { -//line messages.qtpl:256 +//line messages.qtpl:257 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:256 +//line messages.qtpl:257 StreamMessages(qw422016, VERSION, CSRF, NullUsername, AuthUser, Data) -//line messages.qtpl:256 +//line messages.qtpl:257 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:256 +//line messages.qtpl:257 } -//line messages.qtpl:256 +//line messages.qtpl:257 func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) string { -//line messages.qtpl:256 +//line messages.qtpl:257 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:256 +//line messages.qtpl:257 WriteMessages(qb422016, VERSION, CSRF, NullUsername, AuthUser, Data) -//line messages.qtpl:256 +//line messages.qtpl:257 qs422016 := string(qb422016.B) -//line messages.qtpl:256 +//line messages.qtpl:257 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:256 +//line messages.qtpl:257 return qs422016 -//line messages.qtpl:256 +//line messages.qtpl:257 } -//line messages.qtpl:259 +//line messages.qtpl:260 func StreamRenderRightColumn(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMenuData) { -//line messages.qtpl:259 +//line messages.qtpl:260 qw422016.N().S(`<div id="rgt-pane"> <div class="mb-20px"> <div class="rgt-title">Inbox (<a href="/settings/inbox" target="_top"`) -//line messages.qtpl:262 +//line messages.qtpl:263 if Data.InboxCount > 0 { -//line messages.qtpl:262 +//line messages.qtpl:263 qw422016.N().S(`class="notif"`) -//line messages.qtpl:262 +//line messages.qtpl:263 } -//line messages.qtpl:262 +//line messages.qtpl:263 qw422016.N().S(`>`) -//line messages.qtpl:262 +//line messages.qtpl:263 qw422016.N().DL(Data.InboxCount) -//line messages.qtpl:262 +//line messages.qtpl:263 qw422016.N().S(`</a>)</div> </div> <div class="mb-20px"> <div class="rgt-title">Rooms:</div> `) -//line messages.qtpl:266 - for _, e := range Data.OfficialRooms { //line messages.qtpl:267 - if e.Name == "club" { + for _, e := range Data.OfficialRooms { //line messages.qtpl:268 + if e.Name == "club" { +//line messages.qtpl:269 if AuthUser.IsClubMember { -//line messages.qtpl:268 - qw422016.N().S(` <div><a href="/chat/club" target="_top"`) //line messages.qtpl:269 + qw422016.N().S(` <div><a href="/chat/club" target="_top"`) +//line messages.qtpl:270 if e.IsUnread { -//line messages.qtpl:269 +//line messages.qtpl:270 qw422016.N().S(` class="unread_room"`) -//line messages.qtpl:269 +//line messages.qtpl:270 } -//line messages.qtpl:269 +//line messages.qtpl:270 qw422016.N().S(`>#club</a></div> `) -//line messages.qtpl:270 - } //line messages.qtpl:271 - } else if e.Name == "moderators" { + } //line messages.qtpl:272 + } else if e.Name == "moderators" { +//line messages.qtpl:273 if AuthUser.IsModerator() { -//line messages.qtpl:272 - qw422016.N().S(` <div><a href="/chat/moderators" target="_top"`) //line messages.qtpl:273 + qw422016.N().S(` <div><a href="/chat/moderators" target="_top"`) +//line messages.qtpl:274 if e.IsUnread { -//line messages.qtpl:273 +//line messages.qtpl:274 qw422016.N().S(` class="unread_room"`) -//line messages.qtpl:273 +//line messages.qtpl:274 } -//line messages.qtpl:273 +//line messages.qtpl:274 qw422016.N().S(`>#moderators</a></div> `) -//line messages.qtpl:274 - } //line messages.qtpl:275 + } +//line messages.qtpl:276 } else { -//line messages.qtpl:275 - qw422016.N().S(` <div><a href="/chat/`) //line messages.qtpl:276 + qw422016.N().S(` <div><a href="/chat/`) +//line messages.qtpl:277 qw422016.E().S(e.Name) -//line messages.qtpl:276 +//line messages.qtpl:277 qw422016.N().S(`" target="_top"`) -//line messages.qtpl:276 +//line messages.qtpl:277 if e.IsUnread { -//line messages.qtpl:276 +//line messages.qtpl:277 qw422016.N().S(` class="unread_room"`) -//line messages.qtpl:276 +//line messages.qtpl:277 } -//line messages.qtpl:276 +//line messages.qtpl:277 qw422016.N().S(`>#`) -//line messages.qtpl:276 +//line messages.qtpl:277 qw422016.E().S(e.Name) -//line messages.qtpl:276 +//line messages.qtpl:277 qw422016.N().S(`</a></div> `) -//line messages.qtpl:277 - } //line messages.qtpl:278 - } + } //line messages.qtpl:279 + } +//line messages.qtpl:280 if len(Data.SubscribedRooms) > 0 { -//line messages.qtpl:279 +//line messages.qtpl:280 qw422016.N().S(` <div class="mt-10px"></div> `) -//line messages.qtpl:281 +//line messages.qtpl:282 for _, e := range Data.SubscribedRooms { -//line messages.qtpl:281 - qw422016.N().S(` <div><a href="/chat/`) //line messages.qtpl:282 + qw422016.N().S(` <div><a href="/chat/`) +//line messages.qtpl:283 qw422016.E().S(e.Name) -//line messages.qtpl:282 +//line messages.qtpl:283 qw422016.N().S(`" target="_top"`) -//line messages.qtpl:282 +//line messages.qtpl:283 if e.IsUnread { -//line messages.qtpl:282 +//line messages.qtpl:283 qw422016.N().S(` class="unread_room"`) -//line messages.qtpl:282 +//line messages.qtpl:283 } -//line messages.qtpl:282 +//line messages.qtpl:283 qw422016.N().S(`>#`) -//line messages.qtpl:282 +//line messages.qtpl:283 qw422016.E().S(e.Name) -//line messages.qtpl:282 +//line messages.qtpl:283 qw422016.N().S(`</a></div> `) -//line messages.qtpl:283 - } //line messages.qtpl:284 + } +//line messages.qtpl:285 } -//line messages.qtpl:284 +//line messages.qtpl:285 qw422016.N().S(` <div class="mt-5px"><a href="/rooms" target="_top">[...]</a></div> </div> <div class="mb-20px"> <div class="rgt-title">In this room:</div> `) -//line messages.qtpl:289 +//line messages.qtpl:290 for _, e := range Data.Members { -//line messages.qtpl:289 - qw422016.N().S(` `) //line messages.qtpl:290 + qw422016.N().S(` `) +//line messages.qtpl:291 StreamMember(qw422016, AuthUser, Data, e) -//line messages.qtpl:290 +//line messages.qtpl:291 qw422016.N().S(` `) -//line messages.qtpl:291 +//line messages.qtpl:292 } -//line messages.qtpl:291 +//line messages.qtpl:292 qw422016.N().S(` </div> `) -//line messages.qtpl:293 +//line messages.qtpl:294 if Data.VisibleMemberInChat || AuthUser.DisplayHellbanned { -//line messages.qtpl:293 +//line messages.qtpl:294 qw422016.N().S(` <div class="mb-30px"> `) -//line messages.qtpl:295 +//line messages.qtpl:296 if len(Data.MembersInChat) > 0 { -//line messages.qtpl:295 +//line messages.qtpl:296 qw422016.N().S(` <div class="rgt-title">In other rooms:</div> `) -//line messages.qtpl:297 +//line messages.qtpl:298 for _, e := range Data.MembersInChat { -//line messages.qtpl:297 - qw422016.N().S(` `) //line messages.qtpl:298 + qw422016.N().S(` `) +//line messages.qtpl:299 StreamMember(qw422016, AuthUser, Data, e) -//line messages.qtpl:298 +//line messages.qtpl:299 qw422016.N().S(` `) -//line messages.qtpl:299 - } //line messages.qtpl:300 + } +//line messages.qtpl:301 } -//line messages.qtpl:300 +//line messages.qtpl:301 qw422016.N().S(` </div> `) -//line messages.qtpl:302 +//line messages.qtpl:303 } -//line messages.qtpl:302 +//line messages.qtpl:303 qw422016.N().S(`</div> `) -//line messages.qtpl:304 +//line messages.qtpl:305 } -//line messages.qtpl:304 +//line messages.qtpl:305 func WriteRenderRightColumn(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMenuData) { -//line messages.qtpl:304 +//line messages.qtpl:305 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:304 +//line messages.qtpl:305 StreamRenderRightColumn(qw422016, AuthUser, Data) -//line messages.qtpl:304 +//line messages.qtpl:305 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:304 +//line messages.qtpl:305 } -//line messages.qtpl:304 +//line messages.qtpl:305 func RenderRightColumn(AuthUser *database.User, Data ChatMenuData) string { -//line messages.qtpl:304 +//line messages.qtpl:305 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:304 +//line messages.qtpl:305 WriteRenderRightColumn(qb422016, AuthUser, Data) -//line messages.qtpl:304 +//line messages.qtpl:305 qs422016 := string(qb422016.B) -//line messages.qtpl:304 +//line messages.qtpl:305 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:304 +//line messages.qtpl:305 return qs422016 -//line messages.qtpl:304 +//line messages.qtpl:305 } -//line messages.qtpl:306 -func StreamRenderMessages(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) { -//line messages.qtpl:308 +//line messages.qtpl:307 +func StreamRenderMessages(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) { +//line messages.qtpl:309 baseTopBarURL := "/api/v1/chat/top-bar/" + Data.ChatMenuData.RoomName readMarkerRendered := false isFirstMsg := true -//line messages.qtpl:312 - for idx, e := range Data.Messages { -//line messages.qtpl:313 - StreamRenderMessage(qw422016, idx, e, AuthUser, Data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, CSRF, NullUsername) //line messages.qtpl:313 - qw422016.N().S(` `) + for idx, e := range Data.Messages { //line messages.qtpl:314 - } + StreamRenderMessage(qw422016, idx, e, AuthUser, Data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, CSRF, NullUsername, readMarkerRev, isEdit) //line messages.qtpl:314 + qw422016.N().S(` `) +//line messages.qtpl:315 + } +//line messages.qtpl:315 qw422016.N().S(` `) -//line messages.qtpl:315 +//line messages.qtpl:316 if len(Data.Messages) == 0 { -//line messages.qtpl:315 +//line messages.qtpl:316 qw422016.N().S(` <div id="no-msg"><em>No message yet</em></div> `) -//line messages.qtpl:317 +//line messages.qtpl:318 } -//line messages.qtpl:317 +//line messages.qtpl:318 qw422016.N().S(` `) -//line messages.qtpl:318 +//line messages.qtpl:319 } -//line messages.qtpl:318 -func WriteRenderMessages(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) { -//line messages.qtpl:318 +//line messages.qtpl:319 +func WriteRenderMessages(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) { +//line messages.qtpl:319 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:318 - StreamRenderMessages(qw422016, AuthUser, Data, CSRF, NullUsername) -//line messages.qtpl:318 +//line messages.qtpl:319 + StreamRenderMessages(qw422016, AuthUser, Data, CSRF, NullUsername, readMarkerRev, isEdit) +//line messages.qtpl:319 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:318 +//line messages.qtpl:319 } -//line messages.qtpl:318 -func RenderMessages(AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) string { -//line messages.qtpl:318 +//line messages.qtpl:319 +func RenderMessages(AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) string { +//line messages.qtpl:319 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:318 - WriteRenderMessages(qb422016, AuthUser, Data, CSRF, NullUsername) -//line messages.qtpl:318 +//line messages.qtpl:319 + WriteRenderMessages(qb422016, AuthUser, Data, CSRF, NullUsername, readMarkerRev, isEdit) +//line messages.qtpl:319 qs422016 := string(qb422016.B) -//line messages.qtpl:318 +//line messages.qtpl:319 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:318 +//line messages.qtpl:319 return qs422016 -//line messages.qtpl:318 +//line messages.qtpl:319 } -//line messages.qtpl:320 +//line messages.qtpl:321 func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMessage, AuthUser *database.User, - Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string) { -//line messages.qtpl:322 - if e.UserCanSee(*AuthUser) { -//line messages.qtpl:323 - if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !*readMarkerRendered { + Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) { //line messages.qtpl:323 + if e.UserCanSee(*AuthUser) { +//line messages.qtpl:324 + if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !*readMarkerRendered && readMarkerRev == nil && !isEdit { +//line messages.qtpl:324 qw422016.N().S(` <div class="read-marker read-marker-0"`) -//line messages.qtpl:324 +//line messages.qtpl:325 if idx == 0 { -//line messages.qtpl:324 +//line messages.qtpl:325 qw422016.N().S(` style="display:none;"`) -//line messages.qtpl:324 +//line messages.qtpl:325 } -//line messages.qtpl:324 +//line messages.qtpl:325 qw422016.N().S(`></div> `) -//line messages.qtpl:325 +//line messages.qtpl:326 *readMarkerRendered = true -//line messages.qtpl:326 - } -//line messages.qtpl:326 - qw422016.N().S(` <div id="msgid-`) //line messages.qtpl:327 - qw422016.E().S(e.UUID) + } else if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Round(time.Second).After(Data.ReadMarker.ReadAt.Round(time.Second)) && !*readMarkerRendered && readMarkerRev != nil && isEdit { //line messages.qtpl:327 + qw422016.N().S(` <style>.read-marker-`) +//line messages.qtpl:328 + qw422016.N().D((*readMarkerRev)) +//line messages.qtpl:328 + qw422016.N().S(`{display:none !important;}</style> +`) +//line messages.qtpl:329 + *readMarkerRev++ + +//line messages.qtpl:329 + qw422016.N().S(` <div class="read-marker read-marker-`) +//line messages.qtpl:330 + qw422016.N().D(*readMarkerRev) +//line messages.qtpl:330 + qw422016.N().S(`"></div> +`) +//line messages.qtpl:331 + *readMarkerRendered = true + +//line messages.qtpl:331 + qw422016.N().S(` `) +//line messages.qtpl:332 + } +//line messages.qtpl:332 + qw422016.N().S(` + <div id="msgid-`) +//line messages.qtpl:333 + qw422016.E().S(e.UUID) +//line messages.qtpl:333 qw422016.N().S(`" class="msgidc-`) -//line messages.qtpl:327 +//line messages.qtpl:333 qw422016.E().S(e.UUID) -//line messages.qtpl:327 +//line messages.qtpl:333 qw422016.N().S(`-`) -//line messages.qtpl:327 +//line messages.qtpl:333 qw422016.N().DL(e.Rev) -//line messages.qtpl:327 +//line messages.qtpl:333 qw422016.N().S(` msg `) -//line messages.qtpl:328 +//line messages.qtpl:334 if (e.User.IsHellbanned || e.IsHellbanned) && AuthUser.DisplayHellbanned { -//line messages.qtpl:328 +//line messages.qtpl:334 qw422016.N().S(` hb-row `) -//line messages.qtpl:329 +//line messages.qtpl:335 } else if AuthUser.ID == e.User.ID && AuthUser.HighlightOwnMessages { -//line messages.qtpl:329 +//line messages.qtpl:335 qw422016.N().S(` own-highlight`) -//line messages.qtpl:329 +//line messages.qtpl:335 } -//line messages.qtpl:329 +//line messages.qtpl:335 qw422016.N().S(` "> `) -//line messages.qtpl:331 +//line messages.qtpl:337 if e.UserCanDelete(*AuthUser) { -//line messages.qtpl:332 +//line messages.qtpl:338 if AuthUser.DisplayDeleteButton { -//line messages.qtpl:333 +//line messages.qtpl:339 if e.TooOldToDelete() { -//line messages.qtpl:333 +//line messages.qtpl:339 qw422016.N().S(` <form method="post" action="/api/v1/chat/messages/delete/`) -//line messages.qtpl:334 +//line messages.qtpl:340 qw422016.E().S(e.UUID) -//line messages.qtpl:334 +//line messages.qtpl:340 qw422016.N().S(`" class="d-inline"> <input type="hidden" name="csrf" value="`) -//line messages.qtpl:335 +//line messages.qtpl:341 qw422016.E().S(CSRF) -//line messages.qtpl:335 +//line messages.qtpl:341 qw422016.N().S(`" /> <button class="mod-btn delete_msg_btn f-orange-clr" title="delete"></button> </form> `) -//line messages.qtpl:338 +//line messages.qtpl:344 } else { -//line messages.qtpl:338 +//line messages.qtpl:344 qw422016.N().S(` <form method="post" action="/api/v1/chat/messages/delete/`) -//line messages.qtpl:339 +//line messages.qtpl:345 qw422016.E().S(e.UUID) -//line messages.qtpl:339 +//line messages.qtpl:345 qw422016.N().S(`" class="d-inline"> <input type="hidden" name="csrf" value="`) -//line messages.qtpl:340 +//line messages.qtpl:346 qw422016.E().S(CSRF) -//line messages.qtpl:340 +//line messages.qtpl:346 qw422016.N().S(`" /> <button class="mod-btn delete_msg_btn " title="delete" style=" `) -//line messages.qtpl:344 +//line messages.qtpl:350 if string(e.User.Username) != NullUsername { -//line messages.qtpl:345 +//line messages.qtpl:351 if (AuthUser.IsModerator() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || e.IsRoomOwner(*AuthUser) { -//line messages.qtpl:345 +//line messages.qtpl:351 qw422016.N().S(` animation: `) -//line messages.qtpl:346 +//line messages.qtpl:352 qw422016.N().DL(e.DeleteSecondsRemaining()) -//line messages.qtpl:346 +//line messages.qtpl:352 qw422016.N().S(`s 1s forwards orange_btn; `) -//line messages.qtpl:347 +//line messages.qtpl:353 } else { -//line messages.qtpl:347 +//line messages.qtpl:353 qw422016.N().S(` animation: `) -//line messages.qtpl:348 +//line messages.qtpl:354 qw422016.N().DL(e.DeleteSecondsRemaining()) -//line messages.qtpl:348 +//line messages.qtpl:354 qw422016.N().S(`s 1s forwards hide_btn; `) -//line messages.qtpl:349 +//line messages.qtpl:355 } -//line messages.qtpl:350 +//line messages.qtpl:356 } -//line messages.qtpl:350 +//line messages.qtpl:356 qw422016.N().S(` " ></button> </form> `) -//line messages.qtpl:354 +//line messages.qtpl:360 } -//line messages.qtpl:355 +//line messages.qtpl:361 } -//line messages.qtpl:356 +//line messages.qtpl:362 if AuthUser.IsModerator() { -//line messages.qtpl:357 +//line messages.qtpl:363 if !e.OwnMessage(*AuthUser) { -//line messages.qtpl:358 +//line messages.qtpl:364 if AuthUser.DisplayHellbanButton { -//line messages.qtpl:359 +//line messages.qtpl:365 if string(e.User.Username) == NullUsername { -//line messages.qtpl:359 +//line messages.qtpl:365 qw422016.N().S(` <div class="spacer16"></div> `) -//line messages.qtpl:361 +//line messages.qtpl:367 } else { -//line messages.qtpl:362 +//line messages.qtpl:368 if e.User.IsHellbanned { -//line messages.qtpl:362 +//line messages.qtpl:368 qw422016.N().S(` <form method="post" action="/api/v1/users/`) -//line messages.qtpl:363 +//line messages.qtpl:369 qw422016.E().S(e.UserID.String()) -//line messages.qtpl:363 +//line messages.qtpl:369 qw422016.N().S(`/unhellban" class="d-inline"> <input type="hidden" name="csrf" value="`) -//line messages.qtpl:364 +//line messages.qtpl:370 qw422016.E().S(CSRF) -//line messages.qtpl:364 +//line messages.qtpl:370 qw422016.N().S(`" /> <button class="mod-btn hb_btn f-orange-clr line-through" title="unhellban"></button> </form> `) -//line messages.qtpl:367 +//line messages.qtpl:373 } else { -//line messages.qtpl:367 +//line messages.qtpl:373 qw422016.N().S(` <form method="post" action="/api/v1/users/`) -//line messages.qtpl:368 +//line messages.qtpl:374 qw422016.E().S(e.UserID.String()) -//line messages.qtpl:368 +//line messages.qtpl:374 qw422016.N().S(`/hellban" class="d-inline"> <input type="hidden" name="csrf" value="`) -//line messages.qtpl:369 +//line messages.qtpl:375 qw422016.E().S(CSRF) -//line messages.qtpl:369 +//line messages.qtpl:375 qw422016.N().S(`" /> <button class="mod-btn hb_btn f-orange-clr" title="hellban"></button> </form> `) -//line messages.qtpl:372 +//line messages.qtpl:378 } -//line messages.qtpl:373 +//line messages.qtpl:379 } -//line messages.qtpl:374 +//line messages.qtpl:380 } -//line messages.qtpl:375 +//line messages.qtpl:381 if AuthUser.DisplayKickButton { -//line messages.qtpl:375 +//line messages.qtpl:381 qw422016.N().S(` <form method="post" action="/api/v1/users/`) -//line messages.qtpl:376 +//line messages.qtpl:382 qw422016.E().S(e.UserID.String()) -//line messages.qtpl:376 +//line messages.qtpl:382 qw422016.N().S(`/kick" class="d-inline"> <input type="hidden" name="csrf" value="`) -//line messages.qtpl:377 +//line messages.qtpl:383 qw422016.E().S(CSRF) -//line messages.qtpl:377 +//line messages.qtpl:383 qw422016.N().S(`" /> <button class="mod-btn k_btn f-orange-clr" title="kick"></button> </form> `) -//line messages.qtpl:380 +//line messages.qtpl:386 } -//line messages.qtpl:381 +//line messages.qtpl:387 } else { -//line messages.qtpl:382 +//line messages.qtpl:388 if AuthUser.DisplayKickButton && AuthUser.DisplayHellbanButton { -//line messages.qtpl:382 +//line messages.qtpl:388 qw422016.N().S(` <div class="spacer36"></div> `) -//line messages.qtpl:384 +//line messages.qtpl:390 } else if AuthUser.DisplayKickButton || AuthUser.DisplayHellbanButton { -//line messages.qtpl:384 +//line messages.qtpl:390 qw422016.N().S(` <div class="spacer16"></div> `) -//line messages.qtpl:386 +//line messages.qtpl:392 } -//line messages.qtpl:387 +//line messages.qtpl:393 } -//line messages.qtpl:388 +//line messages.qtpl:394 } -//line messages.qtpl:389 +//line messages.qtpl:395 } else { -//line messages.qtpl:390 +//line messages.qtpl:396 if Data.NbButtons == 3 { -//line messages.qtpl:390 +//line messages.qtpl:396 qw422016.N().S(` <div class="spacer56"></div> `) -//line messages.qtpl:392 +//line messages.qtpl:398 } else if Data.NbButtons == 2 { -//line messages.qtpl:392 +//line messages.qtpl:398 qw422016.N().S(` <div class="spacer36"></div> `) -//line messages.qtpl:394 +//line messages.qtpl:400 } else if Data.NbButtons == 1 { -//line messages.qtpl:394 +//line messages.qtpl:400 qw422016.N().S(` <div class="spacer16"></div> `) -//line messages.qtpl:396 +//line messages.qtpl:402 } -//line messages.qtpl:397 +//line messages.qtpl:403 } -//line messages.qtpl:398 +//line messages.qtpl:404 if AuthUser.GetDateFormat() != "" { -//line messages.qtpl:398 +//line messages.qtpl:404 qw422016.N().S(` <a href="`) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.N().S(`?quote=`) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.E().S(e.UUID) -//line messages.qtpl:399 +//line messages.qtpl:405 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.N().S(`" target="iframe1" class="date date-link" title="`) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.E().S(e.CreatedAt.Format("01-02 15:04:05")) -//line messages.qtpl:399 +//line messages.qtpl:405 if *isFirstMsg { -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.N().S(` (`) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.E().S(humanize.Time(e.CreatedAt)) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.N().S(`)`) -//line messages.qtpl:399 +//line messages.qtpl:405 } -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.N().S(`">`) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.E().S(e.CreatedAt.Format(AuthUser.GetDateFormat())) -//line messages.qtpl:399 +//line messages.qtpl:405 qw422016.N().S(`</a> `) -//line messages.qtpl:400 +//line messages.qtpl:406 *isFirstMsg = false -//line messages.qtpl:400 +//line messages.qtpl:406 qw422016.N().S(` `) -//line messages.qtpl:401 +//line messages.qtpl:407 } -//line messages.qtpl:401 +//line messages.qtpl:407 qw422016.N().S(` <a href="/u/`) -//line messages.qtpl:402 +//line messages.qtpl:408 qw422016.E().S(string(e.GetProfile(AuthUser))) -//line messages.qtpl:402 +//line messages.qtpl:408 qw422016.N().S(`" target="_blank" class="f-def-clr">-</a> `) -//line messages.qtpl:403 +//line messages.qtpl:409 if e.System { -//line messages.qtpl:403 +//line messages.qtpl:409 qw422016.N().S(` <span class="sysmsg">`) -//line messages.qtpl:404 +//line messages.qtpl:410 streamunesc(qw422016, e.Message) -//line messages.qtpl:404 +//line messages.qtpl:410 qw422016.N().S(`</span> `) -//line messages.qtpl:405 +//line messages.qtpl:411 } else { -//line messages.qtpl:406 +//line messages.qtpl:412 if e.Moderators { -//line messages.qtpl:406 +//line messages.qtpl:412 qw422016.N().S(`<span class="sysmsg">[<a href="`) -//line messages.qtpl:406 +//line messages.qtpl:412 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:406 +//line messages.qtpl:412 qw422016.N().S(`?m=1`) -//line messages.qtpl:406 +//line messages.qtpl:412 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:406 +//line messages.qtpl:412 qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">M</a>]</span>&nbsp;`) -//line messages.qtpl:406 +//line messages.qtpl:412 } -//line messages.qtpl:407 +//line messages.qtpl:413 if e.GroupID != nil { -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.N().S(`<span class="sysmsg">[<a href="`) -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.N().S(`?g=`) -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.E().S(e.Group.Name) -//line messages.qtpl:407 +//line messages.qtpl:413 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">`) -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.E().S(e.Group.Name) -//line messages.qtpl:407 +//line messages.qtpl:413 qw422016.N().S(`</a>]</span>&nbsp;`) -//line messages.qtpl:407 +//line messages.qtpl:413 } -//line messages.qtpl:408 +//line messages.qtpl:414 if e.ToUserID != nil { -//line messages.qtpl:408 +//line messages.qtpl:414 qw422016.N().S(` [`) -//line messages.qtpl:409 +//line messages.qtpl:415 streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL) -//line messages.qtpl:409 +//line messages.qtpl:415 qw422016.N().S(` → `) -//line messages.qtpl:411 +//line messages.qtpl:417 if e.ToUser.ID == AuthUser.ID { -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`<span `) -//line messages.qtpl:411 +//line messages.qtpl:417 streamunesc(qw422016, e.ToUser.GenerateChatStyle()) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`>`) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.E().S(string(e.ToUser.Username)) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`</span>`) -//line messages.qtpl:411 +//line messages.qtpl:417 } else { -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`<a `) -//line messages.qtpl:411 +//line messages.qtpl:417 streamunesc(qw422016, e.ToUser.GenerateChatStyle()) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(` href="`) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`?pm=`) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.E().S(string(e.ToUser.Username)) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.E().S(Data.TopBarQueryParams) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`" target="iframe1">`) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.E().S(string(e.ToUser.Username)) -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`</a>`) -//line messages.qtpl:411 +//line messages.qtpl:417 } -//line messages.qtpl:411 +//line messages.qtpl:417 qw422016.N().S(`] - `) -//line messages.qtpl:412 +//line messages.qtpl:418 } else { -//line messages.qtpl:413 +//line messages.qtpl:419 streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL) -//line messages.qtpl:414 +//line messages.qtpl:420 if !e.IsMe() { -//line messages.qtpl:415 +//line messages.qtpl:421 if AuthUser.CanSeeHB() && (e.IsHellbanned || e.User.IsHellbanned) && (e.ToUserID == nil) { -//line messages.qtpl:415 +//line messages.qtpl:421 qw422016.N().S(` <a href="`) -//line messages.qtpl:416 +//line messages.qtpl:422 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:416 +//line messages.qtpl:422 qw422016.N().S(`?hbm=1`) -//line messages.qtpl:416 +//line messages.qtpl:422 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:416 +//line messages.qtpl:422 qw422016.N().S(`" target="iframe1" class="f-def-clr">-</a> `) -//line messages.qtpl:417 +//line messages.qtpl:423 } else { -//line messages.qtpl:417 +//line messages.qtpl:423 qw422016.N().S(` - `) -//line messages.qtpl:419 +//line messages.qtpl:425 } -//line messages.qtpl:420 +//line messages.qtpl:426 } -//line messages.qtpl:421 +//line messages.qtpl:427 } -//line messages.qtpl:421 +//line messages.qtpl:427 qw422016.N().S(` <span `) -//line messages.qtpl:422 +//line messages.qtpl:428 streamunesc(qw422016, e.User.GenerateChatStyle()) -//line messages.qtpl:422 +//line messages.qtpl:428 qw422016.N().S(`><span class="o-wrap">`) -//line messages.qtpl:422 +//line messages.qtpl:428 qw422016.N().S(unesc(e.MsgToDisplay(AuthUser))) -//line messages.qtpl:422 +//line messages.qtpl:428 qw422016.N().S(`</span></span> `) -//line messages.qtpl:423 +//line messages.qtpl:429 } -//line messages.qtpl:423 +//line messages.qtpl:429 qw422016.N().S(` </div> `) -//line messages.qtpl:425 +//line messages.qtpl:431 } -//line messages.qtpl:426 +//line messages.qtpl:432 } -//line messages.qtpl:426 +//line messages.qtpl:432 func WriteRenderMessage(qq422016 qtio422016.Writer, idx int, e database.ChatMessage, AuthUser *database.User, - Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string) { -//line messages.qtpl:426 + Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) { +//line messages.qtpl:432 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:426 - StreamRenderMessage(qw422016, idx, e, AuthUser, Data, baseTopBarURL, readMarkerRendered, isFirstMsg, CSRF, NullUsername) -//line messages.qtpl:426 +//line messages.qtpl:432 + StreamRenderMessage(qw422016, idx, e, AuthUser, Data, baseTopBarURL, readMarkerRendered, isFirstMsg, CSRF, NullUsername, readMarkerRev, isEdit) +//line messages.qtpl:432 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:426 +//line messages.qtpl:432 } -//line messages.qtpl:426 +//line messages.qtpl:432 func RenderMessage(idx int, e database.ChatMessage, AuthUser *database.User, - Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string) string { -//line messages.qtpl:426 + Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string, readMarkerRev *int, isEdit bool) string { +//line messages.qtpl:432 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:426 - WriteRenderMessage(qb422016, idx, e, AuthUser, Data, baseTopBarURL, readMarkerRendered, isFirstMsg, CSRF, NullUsername) -//line messages.qtpl:426 +//line messages.qtpl:432 + WriteRenderMessage(qb422016, idx, e, AuthUser, Data, baseTopBarURL, readMarkerRendered, isFirstMsg, CSRF, NullUsername, readMarkerRev, isEdit) +//line messages.qtpl:432 qs422016 := string(qb422016.B) -//line messages.qtpl:426 +//line messages.qtpl:432 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:426 +//line messages.qtpl:432 return qs422016 -//line messages.qtpl:426 +//line messages.qtpl:432 } -//line messages.qtpl:429 +//line messages.qtpl:435 func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMenuData, El managers.UserInfo) { -//line messages.qtpl:429 +//line messages.qtpl:435 qw422016.N().S(` `) -//line messages.qtpl:430 +//line messages.qtpl:436 baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName -//line messages.qtpl:431 +//line messages.qtpl:437 if El.Username == AuthUser.Username { -//line messages.qtpl:431 +//line messages.qtpl:437 qw422016.N().S(` <div> <span style="color: `) -//line messages.qtpl:433 +//line messages.qtpl:439 qw422016.E().S(El.Color) -//line messages.qtpl:433 +//line messages.qtpl:439 qw422016.N().S(`;">`) -//line messages.qtpl:433 +//line messages.qtpl:439 qw422016.E().S(string(El.Username)) -//line messages.qtpl:433 +//line messages.qtpl:439 qw422016.N().S(`</span> `) -//line messages.qtpl:434 +//line messages.qtpl:440 if El.AfkIndicatorEnabled { -//line messages.qtpl:434 +//line messages.qtpl:440 qw422016.N().S(` <small class="afk-indicator">afk</small> `) -//line messages.qtpl:436 +//line messages.qtpl:442 } -//line messages.qtpl:436 +//line messages.qtpl:442 qw422016.N().S(` </div> `) -//line messages.qtpl:438 +//line messages.qtpl:444 } else { -//line messages.qtpl:439 +//line messages.qtpl:445 if !El.IsHellbanned || AuthUser.ID == El.UserID || (El.IsHellbanned && AuthUser.IsHellbanned) || AuthUser.DisplayHellbanned { -//line messages.qtpl:439 +//line messages.qtpl:445 qw422016.N().S(` <div> `) -//line messages.qtpl:441 +//line messages.qtpl:447 tagType := "tag" -//line messages.qtpl:442 +//line messages.qtpl:448 if AuthUser.CanSeeHB() && El.IsHellbanned { -//line messages.qtpl:443 +//line messages.qtpl:449 tagType = "htag" -//line messages.qtpl:444 +//line messages.qtpl:450 } -//line messages.qtpl:445 +//line messages.qtpl:451 qw422016.N().S(`<a href="`) -//line messages.qtpl:446 +//line messages.qtpl:452 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:446 +//line messages.qtpl:452 qw422016.N().S(`?`) -//line messages.qtpl:446 +//line messages.qtpl:452 qw422016.E().S(tagType) -//line messages.qtpl:446 +//line messages.qtpl:452 qw422016.N().S(`=`) -//line messages.qtpl:446 +//line messages.qtpl:452 qw422016.E().S(string(El.Username)) -//line messages.qtpl:446 +//line messages.qtpl:452 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:446 +//line messages.qtpl:452 qw422016.N().S(`"target="iframe1"`) -//line messages.qtpl:448 +//line messages.qtpl:454 if El.IsHellbanned && AuthUser.DisplayHellbanned { -//line messages.qtpl:448 +//line messages.qtpl:454 qw422016.N().S(`class="hb-row"`) -//line messages.qtpl:448 +//line messages.qtpl:454 } -//line messages.qtpl:448 +//line messages.qtpl:454 qw422016.N().S(`style="color:`) -//line messages.qtpl:449 +//line messages.qtpl:455 qw422016.E().S(El.Color) -//line messages.qtpl:449 +//line messages.qtpl:455 qw422016.N().S(`;">`) -//line messages.qtpl:449 +//line messages.qtpl:455 qw422016.E().S(string(El.Username[0])) -//line messages.qtpl:449 +//line messages.qtpl:455 qw422016.N().S(`</a><a href="`) -//line messages.qtpl:450 +//line messages.qtpl:456 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:450 +//line messages.qtpl:456 qw422016.N().S(`?pm=`) -//line messages.qtpl:450 +//line messages.qtpl:456 qw422016.E().S(string(El.Username)) -//line messages.qtpl:450 +//line messages.qtpl:456 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:450 +//line messages.qtpl:456 qw422016.N().S(`"target="iframe1"`) -//line messages.qtpl:452 +//line messages.qtpl:458 if El.IsHellbanned && AuthUser.DisplayHellbanned { -//line messages.qtpl:452 +//line messages.qtpl:458 qw422016.N().S(`class="hb-row"`) -//line messages.qtpl:452 +//line messages.qtpl:458 } -//line messages.qtpl:452 +//line messages.qtpl:458 qw422016.N().S(`style="color:`) -//line messages.qtpl:453 +//line messages.qtpl:459 qw422016.E().S(El.Color) -//line messages.qtpl:453 +//line messages.qtpl:459 qw422016.N().S(`;">`) -//line messages.qtpl:453 +//line messages.qtpl:459 qw422016.E().S(string(El.Username[1 : len(El.Username)-1])) -//line messages.qtpl:453 +//line messages.qtpl:459 qw422016.N().S(`</a><a href="/u/`) -//line messages.qtpl:454 +//line messages.qtpl:460 qw422016.E().S(string(El.Username)) -//line messages.qtpl:454 +//line messages.qtpl:460 qw422016.N().S(`"rel="noopener noreferrer" target="_blank"`) -//line messages.qtpl:456 +//line messages.qtpl:462 if El.IsHellbanned && AuthUser.DisplayHellbanned { -//line messages.qtpl:456 +//line messages.qtpl:462 qw422016.N().S(`class="hb-row"`) -//line messages.qtpl:456 +//line messages.qtpl:462 } -//line messages.qtpl:456 +//line messages.qtpl:462 qw422016.N().S(`style="color:`) -//line messages.qtpl:457 +//line messages.qtpl:463 qw422016.E().S(El.Color) -//line messages.qtpl:457 +//line messages.qtpl:463 qw422016.N().S(`;">`) -//line messages.qtpl:457 +//line messages.qtpl:463 qw422016.E().S(string(El.Username[len(El.Username)-1])) -//line messages.qtpl:457 +//line messages.qtpl:463 qw422016.N().S(`</a>`) -//line messages.qtpl:459 +//line messages.qtpl:465 if El.AfkIndicatorEnabled { -//line messages.qtpl:459 +//line messages.qtpl:465 qw422016.N().S(` <small class="afk-indicator">afk</small> `) -//line messages.qtpl:461 +//line messages.qtpl:467 } -//line messages.qtpl:461 +//line messages.qtpl:467 qw422016.N().S(` </div> `) -//line messages.qtpl:463 +//line messages.qtpl:469 } -//line messages.qtpl:464 +//line messages.qtpl:470 } -//line messages.qtpl:465 +//line messages.qtpl:471 } -//line messages.qtpl:465 +//line messages.qtpl:471 func WriteMember(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMenuData, El managers.UserInfo) { -//line messages.qtpl:465 +//line messages.qtpl:471 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:465 +//line messages.qtpl:471 StreamMember(qw422016, AuthUser, Data, El) -//line messages.qtpl:465 +//line messages.qtpl:471 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:465 +//line messages.qtpl:471 } -//line messages.qtpl:465 +//line messages.qtpl:471 func Member(AuthUser *database.User, Data ChatMenuData, El managers.UserInfo) string { -//line messages.qtpl:465 +//line messages.qtpl:471 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:465 +//line messages.qtpl:471 WriteMember(qb422016, AuthUser, Data, El) -//line messages.qtpl:465 +//line messages.qtpl:471 qs422016 := string(qb422016.B) -//line messages.qtpl:465 +//line messages.qtpl:471 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:465 +//line messages.qtpl:471 return qs422016 -//line messages.qtpl:465 +//line messages.qtpl:471 } -//line messages.qtpl:468 +//line messages.qtpl:474 func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) { -//line messages.qtpl:469 +//line messages.qtpl:475 tagType := "tag" -//line messages.qtpl:470 +//line messages.qtpl:476 if El.ToUserID != nil { -//line messages.qtpl:471 +//line messages.qtpl:477 tagType = "pm" -//line messages.qtpl:472 +//line messages.qtpl:478 } else if AuthUser.CanSeeHB() && (El.IsHellbanned || El.User.IsHellbanned) { -//line messages.qtpl:473 +//line messages.qtpl:479 tagType = "htag" -//line messages.qtpl:474 +//line messages.qtpl:480 } else if AuthUser.IsModerator() && El.Moderators { -//line messages.qtpl:475 +//line messages.qtpl:481 tagType = "mtag" -//line messages.qtpl:476 +//line messages.qtpl:482 } -//line messages.qtpl:477 +//line messages.qtpl:483 if El.User.ID == AuthUser.ID { -//line messages.qtpl:478 +//line messages.qtpl:484 if El.CanBeEdited() { -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`<a `) -//line messages.qtpl:478 +//line messages.qtpl:484 streamunesc(qw422016, El.User.GenerateChatStyle()) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(` href="`) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`?e=`) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.E().S(El.CreatedAt.Format("15:04:05")) -//line messages.qtpl:478 +//line messages.qtpl:484 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`" target="iframe1">`) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.E().S(string(El.User.Username)) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`</a>`) -//line messages.qtpl:478 +//line messages.qtpl:484 } else { -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`<span `) -//line messages.qtpl:478 +//line messages.qtpl:484 streamunesc(qw422016, El.User.GenerateChatStyle()) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`>`) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.E().S(string(El.User.Username)) -//line messages.qtpl:478 +//line messages.qtpl:484 qw422016.N().S(`</span>`) -//line messages.qtpl:478 +//line messages.qtpl:484 } -//line messages.qtpl:479 +//line messages.qtpl:485 } else { -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.N().S(`<a `) -//line messages.qtpl:479 +//line messages.qtpl:485 streamunesc(qw422016, El.User.GenerateChatStyle()) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.N().S(` href="`) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.E().S(baseTopBarURL) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.N().S(`?`) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.E().S(tagType) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.N().S(`=`) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.E().S(string(El.User.Username)) -//line messages.qtpl:479 +//line messages.qtpl:485 streamunesc(qw422016, Data.TopBarQueryParams) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.N().S(`" target="iframe1">`) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.E().S(string(El.User.Username)) -//line messages.qtpl:479 +//line messages.qtpl:485 qw422016.N().S(`</a>`) -//line messages.qtpl:479 +//line messages.qtpl:485 } -//line messages.qtpl:480 +//line messages.qtpl:486 } -//line messages.qtpl:480 +//line messages.qtpl:486 func writefromUsername(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) { -//line messages.qtpl:480 +//line messages.qtpl:486 qw422016 := qt422016.AcquireWriter(qq422016) -//line messages.qtpl:480 +//line messages.qtpl:486 streamfromUsername(qw422016, AuthUser, Data, El, baseTopBarURL) -//line messages.qtpl:480 +//line messages.qtpl:486 qt422016.ReleaseWriter(qw422016) -//line messages.qtpl:480 +//line messages.qtpl:486 } -//line messages.qtpl:480 +//line messages.qtpl:486 func fromUsername(AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) string { -//line messages.qtpl:480 +//line messages.qtpl:486 qb422016 := qt422016.AcquireByteBuffer() -//line messages.qtpl:480 +//line messages.qtpl:486 writefromUsername(qb422016, AuthUser, Data, El, baseTopBarURL) -//line messages.qtpl:480 +//line messages.qtpl:486 qs422016 := string(qb422016.B) -//line messages.qtpl:480 +//line messages.qtpl:486 qt422016.ReleaseByteBuffer(qb422016) -//line messages.qtpl:480 +//line messages.qtpl:486 return qs422016 -//line messages.qtpl:480 +//line messages.qtpl:486 }