dkforest

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

commit d95504f768aa194c4f096f1426a88ec460150afb
parent baa57a927fa27ae1435ed334bf0bd4713b8cba6d
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sat, 20 May 2023 04:36:56 -0700

quicktemplate

Diffstat:
Mgo.mod | 1+
Mgo.sum | 13+++++++++++++
Mpkg/web/handlers/api/v1/handlers.go | 26+++++++++++++++++++++++++-
Apkg/web/handlers/api/v1/messages.qtpl | 431+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/web/handlers/api/v1/messages.qtpl.go | 1421+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 1891 insertions(+), 1 deletion(-)

diff --git a/go.mod b/go.mod @@ -59,6 +59,7 @@ require ( github.com/technoweenie/multipartstreamer v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.1.0 // indirect + github.com/valyala/quicktemplate v1.7.0 // indirect golang.org/x/sys v0.6.0 // indirect gopkg.in/gorp.v1 v1.7.2 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect diff --git a/go.sum b/go.sum @@ -29,6 +29,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -142,6 +144,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -213,6 +216,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -394,9 +399,13 @@ github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= @@ -424,6 +433,7 @@ golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -457,6 +467,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -492,6 +503,8 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/web/handlers/api/v1/handlers.go b/pkg/web/handlers/api/v1/handlers.go @@ -16,7 +16,9 @@ import ( "fmt" "github.com/labstack/echo" "github.com/sirupsen/logrus" + qt "github.com/valyala/quicktemplate" "golang.org/x/net/websocket" + "io" "net/http" "net/url" "regexp" @@ -201,9 +203,28 @@ func chatMessages(c echo.Context) (status int, data chatMessagesData) { return http.StatusOK, data } +func writeunesc(iow io.Writer, s string) { + qw := qt.AcquireWriter(iow) + streamunesc(qw, s) + qt.ReleaseWriter(qw) +} + +func unesc(s string) string { + qb := qt.AcquireByteBuffer() + writeunesc(qb, s) + qs := string(qb.B) + qt.ReleaseByteBuffer(qb) + return qs +} + +func streamunesc(qw *qt.Writer, s string) { + qw.N().S(s) +} + // ChatMessagesHandler room messages iframe handler // The chat messages iframe use this endpoint to get the messages for a room. func ChatMessagesHandler(c echo.Context) error { + authUser := c.Get("authUser").(*database.User) status, data := chatMessages(c) if status != http.StatusOK { return c.NoContent(status) @@ -217,7 +238,10 @@ func ChatMessagesHandler(c echo.Context) error { } return c.JSON(http.StatusOK, data) } - return c.Render(http.StatusOK, "chat-messages", data) + version := config.Global.GetVersion().Original() + csrf, _ := c.Get("csrf").(string) + return c.HTML(http.StatusOK, Messages(version, csrf, config.NullUsername, authUser, data)) + //return c.Render(http.StatusOK, "chat-messages", data) } func ChatMessagesWSHandler(c echo.Context) error { diff --git a/pkg/web/handlers/api/v1/messages.qtpl b/pkg/web/handlers/api/v1/messages.qtpl @@ -0,0 +1,431 @@ +{% import "dkforest/pkg/database" %} +{% import "dkforest/pkg/managers" %} +{% import humanize "github.com/dustin/go-humanize" %} + +{% func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) %} + +<html lang="en"> + <head> + <title></title> + {% if !Data.PreventRefresh && !Data.ForceManualRefresh %}<meta http-equiv="refresh" content="{%dl AuthUser.RefreshRate %}">{% endif %} + {% if AuthUser.CollectMetadata %}<link rel="stylesheet" type="text/css" href="/public/css/meta.css?v={%s VERSION %}" />{% endif %} + + <style> + /* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) + */ + html, body, div, span, applet, object, iframe, + h1, h2, h3, h4, h5, h6, p, blockquote, pre, + a, abbr, acronym, address, big, cite, code, + del, dfn, em, img, ins, kbd, q, s, samp, + small, strike, strong, sub, sup, tt, var, + b, u, i, center, + dl, dt, dd, ol, ul, li, + fieldset, form, label, legend, + table, caption, tbody, tfoot, thead, tr, th, td, + article, aside, canvas, details, embed, + figure, figcaption, footer, header, hgroup, + menu, nav, output, ruby, section, summary, + time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + /* HTML5 display-role reset for older browsers */ + article, aside, details, figcaption, figure, + footer, header, hgroup, menu, nav, section { + display: block; + } + body { + line-height: 1; + } + ol, ul { + list-style: none; + } + blockquote, q { + quotes: none; + } + blockquote:before, blockquote:after, + q:before, q:after { + content: ''; + content: none; + } + table { + border-collapse: collapse; + border-spacing: 0; + } + /* --- end --- */ + + + i { font-style: italic; } + + /* Remove button padding in FF */ + button::-moz-focus-inner { + border:0; + padding:0; + } + + body { font-family: Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; } + a { color: #00bc8c; text-decoration: none; } + a:hover { color: #007053; text-decoration: underline; } + .unread_room { color: #2392da; text-decoration: none; } + .unread_room:hover { color: #004970; text-decoration: underline; } + .emoji { + font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + font-size: 17px; + } + .mod-btn { + width: 16px; height: 16px; + margin: 0; padding: 0; + border: 1px solid gray; + display: inline; + text-align: center; + vertical-align: middle; + user-select: none; + background-color: #444; + color: #ea2a2a; + -webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.25); + -moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.25); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + } + .mod-btn:hover { + background-color: #222; + } + .delete_msg_btn { + font-size: 15px; + line-height: 1; + } + .delete_msg_btn::after { content: "×"; } + .hb_btn { + font-size: 10px; + line-height: 1.4; + } + .hb_btn::after { content: "hb"; } + .k_btn { + font-size: 10px; + line-height: 1.4; + } + .k_btn::after { content: "k"; } + #manualrefresh { + {% if !Data.ForceManualRefresh %} + top: -200%; + animation: timeout_messages {%dl Data.ManualRefreshTimeout %}s forwards; + {% endif %} + color: #bf2718; + display: block; + position: fixed; + text-align: center; + left: calc(50% - 200px); + width: 400px; + z-index: 2; + background-color: #500000; + border: 2px solid #ff0000; + } + @keyframes timeout_messages { + 0% { top: -200%; } + 99% { top: -200%; } + 100% { top: 0; } + } + .date { color: #999; font-family: 'Courier New', Courier, monospace; font-size: 14px; } + .date-link:hover { color: #999; text-decoration: underline; } + .sysmsg { color: #fff; font-family: 'Courier New', Courier, monospace; font-size: 14px; } + small { font-size: 80%; font-weight: 400; } + .msg { padding: 3px 0 3px 8px; border-bottom: 1px solid #444; color: #888; position: relative; } + .msg p:first-of-type { display: inline; } + strong { font-weight: bold; } + em { font-style: italic; } + pre { border: 1px solid #2b442b; padding: 2px; margin: 2px 0; max-height: 300px; overflow: auto; background-color: rgba(39,40,34,0.6) !important; + font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; } + code { border: 1px solid #2b442b; color: #f92672; padding: 0 2px; margin: 0px 0; background-color: rgba(39,40,34,0.6) !important; } + .censored { background-color: black; color: black; padding: 0 3px; } + .censored:hover { background-color: black; color: white; } + ul { list-style-type: disc; margin: 0 0 0 15px; } + * { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + .afk-indicator { color: #ff9a27; } + .spacer16 { display: inline-block; width: 16px; } + .spacer36 { display: inline-block; width: 36px; } + .spacer56 { display: inline-block; width: 56px; } + .d-inline { display: inline; } + .o-wrap { overflow-wrap: break-word; } + .f-def-clr { color: #888; } + .f-orange-clr { color: orange; } + .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: {%f AuthUser.GetHellbanOpacityF64() %}; } + .own-highlight { background-color: rgba(255,241,176,0.05); } + .read-marker { border-top: {%dl AuthUser.ChatReadMarkerSize %}px solid {%s AuthUser.ChatReadMarkerColor %}; } + #msgs { {% if !AuthUser.HideRightColumn %}width: calc(100% - 170px); float: left; {% endif %}line-height: 1.2; } + #no-msg { padding-left: 10px; color: #ddd; } + #rgt-pane { width: 150px; height: 100%; float: left; margin-left: 20px; position: fixed; right: 0; overflow-y: auto; line-height: 1.15; } + .rgt-title { font-weight: bolder; color: #ced4da; } + .mb-20px { margin-bottom: 20px; } + .mb-30px { margin-bottom: 30px; } + .mt-5px { margin-top: 5px; } + .mt-10px { margin-top: 10px; } + .notif, .notif:hover { color: #e74c3c; } + #msg-err { background-color: #8f2d2d; color: #ffffff; padding: 1px 5px 2px 5px; display: block; text-decoration: none; } + </style> + </head> + <body> + + {% if Data.ForceManualRefresh %} + <div id="manualrefresh"> + <h4>Manual refresh required</h4> + <form method="get" action="/chat/{%s Data.RoomName %}" target="_top"> + <input type="submit" value="Reload" /> + </form> + </div> + {% elseif !Data.PreventRefresh %} + <div id="manualrefresh"> + <h4>Manual refresh required</h4> + <form method="get"> + <input type="submit" value="Reload" /> + </form> + </div> + {% endif %} + + {% if Data.Error != "" %} + <a href="/api/v1/chat/messages/{%s Data.RoomName %}" id="msg-err">× {%s Data.Error %}</a> + {% endif %} + + {% if Data.PmSound || Data.TaggedSound %} + <audio src="/public/mp3/sound5.mp3" autoplay></audio> + {% elseif Data.NewMessageSound %} + <audio src="/public/mp3/sound6.mp3" autoplay></audio> + {% endif %} + + <div id="msgs"> + {% code + baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName + readMarkerRendered := false + isFirstMsg := true + %} + {% for idx, e := range Data.Messages %} + {% if e.UserCanSee(*AuthUser) %} + <div id="msgid-{%s e.UUID %}" class="msg + {% if (e.User.IsHellbanned || e.IsHellbanned) && AuthUser.DisplayHellbanned %} hb-row + {% elseif AuthUser.ID == e.User.ID && AuthUser.HighlightOwnMessages %} own-highlight{% endif %} + {% if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !readMarkerRendered %} + {% if idx > 0 %} read-marker{% endif %} + {% code + readMarkerRendered = true + %} + {% endif %} + "> + {% if e.UserCanDelete(*AuthUser) %} + {% if !e.TooOldToDelete() %} + {% if AuthUser.DisplayDeleteButton %} + <form method="post" action="/api/v1/chat/messages/delete/{%s e.UUID %}" class="d-inline"> + <input type="hidden" name="csrf" value="{%s CSRF %}" /> + <button class="mod-btn delete_msg_btn" title="delete"></button> + </form> + {% endif %} + {% elseif (AuthUser.IsModerator() && e.TooOldToDelete() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || (e.Room.OwnerUserID != nil && *e.Room.OwnerUserID == AuthUser.ID) %} + {% if AuthUser.DisplayDeleteButton %} + <form method="post" action="/api/v1/chat/messages/delete/{%s e.UUID %}" class="d-inline"> + <input type="hidden" name="csrf" value="{%s CSRF %}" /> + <button class="mod-btn delete_msg_btn f-orange-clr" title="delete"></button> + </form> + {% endif %} + {% elseif AuthUser.IsModerator() %} + {% if AuthUser.DisplayDeleteButton %} + <div class="spacer16"></div> + {% endif %} + {% else %} + {% if AuthUser.DisplayDeleteButton %} + <div class="spacer16"></div> + {% endif %} + {% endif %} + {% if AuthUser.IsModerator() %} + {% if e.UserID != AuthUser.ID %} + {% if AuthUser.DisplayHellbanButton %} + {% if e.User.Username == NullUsername %} + <div class="spacer16"></div> + {% else %} + {% if e.User.IsHellbanned %} + <form method="post" action="/api/v1/users/{%s e.UserID.String() %}/unhellban" class="d-inline"> + <input type="hidden" name="csrf" value="{%s CSRF %}" /> + <button class="mod-btn hb_btn f-orange-clr line-through" title="unhellban"></button> + </form> + {% else %} + <form method="post" action="/api/v1/users/{%s e.UserID.String() %}/hellban" class="d-inline"> + <input type="hidden" name="csrf" value="{%s CSRF %}" /> + <button class="mod-btn hb_btn f-orange-clr" title="hellban"></button> + </form> + {% endif %} + {% endif %} + {% endif %} + {% if AuthUser.DisplayKickButton %} + <form method="post" action="/api/v1/users/{%s e.UserID.String() %}/kick" class="d-inline"> + <input type="hidden" name="csrf" value="{%s CSRF %}" /> + <button class="mod-btn k_btn f-orange-clr" title="kick"></button> + </form> + {% endif %} + {% else %} + {% if AuthUser.DisplayKickButton && AuthUser.DisplayHellbanButton %} + <div class="spacer36"></div> + {% elseif AuthUser.DisplayKickButton || AuthUser.DisplayHellbanButton %} + <div class="spacer16"></div> + {% endif %} + {% endif %} + {%- endif -%} + {%- else -%} + {%- if Data.NbButtons == 3 -%} + <div class="spacer56"></div> + {%- elseif Data.NbButtons == 2 -%} + <div class="spacer36"></div> + {%- elseif Data.NbButtons == 1 -%} + <div class="spacer16"></div> + {%- endif -%} + {%- endif -%} + {%- if Data.DateFormat != "" -%} + <a href="{%s baseTopBarURL %}?quote={%s e.UUID %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" class="date date-link" title="{%s e.CreatedAt.Format("01-02 15:04:05") %}{% if isFirstMsg %} ({%s humanize.Time(e.CreatedAt) %}){% endif %}">{%s e.CreatedAt.Format(Data.DateFormat) %}</a> + {% code isFirstMsg = false %} + {%- endif -%} + <a href="/u/{%s e.GetProfile(AuthUser) %}" target="_blank" class="f-def-clr">-</a> + {%- if e.System -%} + <span class="sysmsg">{%= unesc(e.Message) %}</span> + {%- else -%} + {%- if e.Moderators -%}<span class="sysmsg">[<a href="{%s baseTopBarURL %}?m=1{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" class="sysmsg f-white-clr">M</a>]</span>&nbsp;{%- endif -%} + {%- if e.GroupID != nil -%}<span class="sysmsg">[<a href="{%s baseTopBarURL %}?g={%s e.Group.Name %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" class="sysmsg f-white-clr">{%s e.Group.Name %}</a>]</span>&nbsp;{%- endif -%} + {%- if e.ToUserID != nil -%} + [{%-= fromUsername(AuthUser, Data, e, baseTopBarURL) -%} + → + {%- if e.ToUser.ID == AuthUser.ID -%}<span {%= unesc(e.ToUser.GenerateChatStyle()) %}>{%s e.ToUser.Username %}</span>{%- else -%}<a {%= unesc(e.ToUser.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?pm={%s e.ToUser.Username %}{%s Data.TopBarQueryParams %}" target="iframe1">{%s e.ToUser.Username %}</a>{%- endif -%}] - + {%- else -%} + {%-= fromUsername(AuthUser, Data, e, baseTopBarURL) -%} + {%- if !e.IsMe() -%} + {%- if AuthUser.CanSeeHB() && (e.IsHellbanned || e.User.IsHellbanned) && (e.ToUserID == nil) -%} + <a href="{%s baseTopBarURL %}?hbm=1{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" class="f-def-clr">-</a> + {%- else -%} + - + {%- endif -%} + {%- endif -%} + {%- endif -%} + <span {%= unesc(e.User.GenerateChatStyle()) %}><span class="o-wrap">{%s= unesc(e.MsgToDisplay()) %}</span></span> + {%- endif -%} + </div> + {%- endif -%} + {% endfor %} + {% if len(Data.Messages) == 0 %} + <div id="no-msg"><em>No message yet</em></div> + {% endif %} + </div> + + {% if !AuthUser.HideRightColumn %} + <div id="rgt-pane"> + <div class="mb-20px"> + <div class="rgt-title">Inbox (<a href="/settings/inbox" target="_top"{% if Data.InboxCount > 0 %}class="notif"{% endif %}>{%dl Data.InboxCount %}</a>)</div> + </div> + <div class="mb-20px"> + <div class="rgt-title">Rooms:</div> + {% for _, e := range Data.OfficialRooms %} + {% if e.Name == "club" %} + {% if AuthUser.IsClubMember %} + <div><a href="/chat/club" target="_top"{% if e.IsUnread %} class="unread_room"{% endif %}>#club</a></div> + {% endif %} + {% elseif e.Name == "moderators" %} + {% if AuthUser.IsModerator() %} + <div><a href="/chat/moderators" target="_top"{% if e.IsUnread %} class="unread_room"{% endif %}>#moderators</a></div> + {% endif %} + {% else %} + <div><a href="/chat/{%s e.Name %}" target="_top"{% if e.IsUnread %} class="unread_room"{% endif %}>#{%s e.Name %}</a></div> + {% endif %} + {% endfor %} + {% if len(Data.SubscribedRooms) > 0 %} + <div class="mt-10px"></div> + {% for _, e := range Data.SubscribedRooms %} + <div><a href="/chat/{%s e.Name %}" target="_top"{% if e.IsUnread %} class="unread_room"{% endif %}>#{%s e.Name %}</a></div> + {% endfor %} + {% endif %} + <div class="mt-5px"><a href="/rooms" target="_top">[...]</a></div> + </div> + <div class="mb-20px"> + <div class="rgt-title">In this room:</div> + {% for _, e := range Data.Members %} + {%= Member(AuthUser, Data, e) %} + {% endfor %} + </div> + {% if Data.VisibleMemberInChat || AuthUser.DisplayHellbanned %} + <div class="mb-30px"> + {% if len(Data.MembersInChat) > 0 %} + <div class="rgt-title">In other rooms:</div> + {% for _, e := range Data.MembersInChat %} + {%= Member(AuthUser, Data, e) %} + {% endfor %} + {% endif %} + </div> + {% endif %} + </div> + {% endif %} + {% if AuthUser.CollectMetadata %} + <div class="div_1"></div> + <div class="div_2"></div> + <div class="div_f0">a</div> + {% endif %} + </body> +</html> +{% endfunc %} + + + +{% func Member(AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) %} + {% code baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName %} + {% if El.Username == AuthUser.Username %} + <div> + <span style="color: {%s El.Color %};">{%s El.Username %}</span> + {% if El.AfkIndicatorEnabled %} + <small class="afk-indicator">afk</small> + {% endif %} + </div> + {% else %} + {% if !El.IsHellbanned || AuthUser.ID == El.UserID || (El.IsHellbanned && AuthUser.IsHellbanned) || AuthUser.DisplayHellbanned %} + <div> + {% code tagType := "tag" %} + {% if AuthUser.CanSeeHB() && El.IsHellbanned %} + {% code tagType = "htag" %} + {% endif %} + {% stripspace %} + <a href="{%s baseTopBarURL %}?{%s tagType %}={%s El.Username %}{%= unesc(Data.TopBarQueryParams) %}" + target="iframe1" + {% if El.IsHellbanned && AuthUser.DisplayHellbanned %}class="hb-row"{% endif %} + style="color: {%s El.Color %};">{%s string(El.Username[0]) %}</a> + <a href="{%s baseTopBarURL %}?pm={%s El.Username %}{%= unesc(Data.TopBarQueryParams) %}" + target="iframe1" + {% if El.IsHellbanned && AuthUser.DisplayHellbanned %}class="hb-row"{% endif %} + style="color: {%s El.Color %};">{%s string(El.Username[1 : len(El.Username)-1]) %}</a> + <a href="/u/{%s El.Username %}" + rel="noopener noreferrer" target="_blank" + {% if El.IsHellbanned && AuthUser.DisplayHellbanned %}class="hb-row"{% endif %} + style="color: {%s El.Color %};">{%s string(El.Username[len(El.Username)-1]) %}</a> + {% endstripspace %} + {% if El.AfkIndicatorEnabled %} + <small class="afk-indicator">afk</small> + {% endif %} + </div> + {% endif %} + {% endif %} +{% endfunc %} + + +{%- func fromUsername(AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) -%} + {%- code tagType := "tag" -%} + {%- if El.ToUserID != nil -%} + {%- code tagType = "pm" -%} + {%- elseif AuthUser.CanSeeHB() && (El.IsHellbanned || El.User.IsHellbanned) -%} + {%- code tagType = "htag" -%} + {%- elseif AuthUser.IsModerator() && El.Moderators -%} + {%- code tagType = "mtag" -%} + {%- endif -%} + {%- if El.User.ID == AuthUser.ID -%} + {%- if El.CanBeEdited() -%}<a {%= unesc(El.User.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?e={%s El.CreatedAt.Format("15:04:05") %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1">{%s El.User.Username %}</a>{%- else -%}<span {%= unesc(El.User.GenerateChatStyle()) %}>{%s El.User.Username %}</span>{%- endif -%} + {%- else -%}<a {%= unesc(El.User.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?{%s tagType %}={%s El.User.Username %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1">{%s El.User.Username %}</a>{%- endif -%} +{%- endfunc -%} diff --git a/pkg/web/handlers/api/v1/messages.qtpl.go b/pkg/web/handlers/api/v1/messages.qtpl.go @@ -0,0 +1,1421 @@ +// Code generated by qtc from "messages.qtpl". DO NOT EDIT. +// See https://github.com/valyala/quicktemplate for details. + +//line messages.qtpl:1 +package v1 + +//line messages.qtpl:1 +import "dkforest/pkg/database" + +//line messages.qtpl:2 +import "dkforest/pkg/managers" + +//line messages.qtpl:3 +import humanize "github.com/dustin/go-humanize" + +//line messages.qtpl:5 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line messages.qtpl:5 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line messages.qtpl:5 +func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) { +//line messages.qtpl:5 + qw422016.N().S(` + +<html lang="en"> + <head> + <title></title> + `) +//line messages.qtpl:10 + if !Data.PreventRefresh && !Data.ForceManualRefresh { +//line messages.qtpl:10 + qw422016.N().S(`<meta http-equiv="refresh" content="`) +//line messages.qtpl:10 + qw422016.N().DL(AuthUser.RefreshRate) +//line messages.qtpl:10 + qw422016.N().S(`">`) +//line messages.qtpl:10 + } +//line messages.qtpl:10 + qw422016.N().S(` + `) +//line messages.qtpl:11 + if AuthUser.CollectMetadata { +//line messages.qtpl:11 + qw422016.N().S(`<link rel="stylesheet" type="text/css" href="/public/css/meta.css?v=`) +//line messages.qtpl:11 + qw422016.E().S(VERSION) +//line messages.qtpl:11 + qw422016.N().S(`" />`) +//line messages.qtpl:11 + } +//line messages.qtpl:11 + qw422016.N().S(` + + <style> + /* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) + */ + html, body, div, span, applet, object, iframe, + h1, h2, h3, h4, h5, h6, p, blockquote, pre, + a, abbr, acronym, address, big, cite, code, + del, dfn, em, img, ins, kbd, q, s, samp, + small, strike, strong, sub, sup, tt, var, + b, u, i, center, + dl, dt, dd, ol, ul, li, + fieldset, form, label, legend, + table, caption, tbody, tfoot, thead, tr, th, td, + article, aside, canvas, details, embed, + figure, figcaption, footer, header, hgroup, + menu, nav, output, ruby, section, summary, + time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + /* HTML5 display-role reset for older browsers */ + article, aside, details, figcaption, figure, + footer, header, hgroup, menu, nav, section { + display: block; + } + body { + line-height: 1; + } + ol, ul { + list-style: none; + } + blockquote, q { + quotes: none; + } + blockquote:before, blockquote:after, + q:before, q:after { + content: ''; + content: none; + } + table { + border-collapse: collapse; + border-spacing: 0; + } + /* --- end --- */ + + + i { font-style: italic; } + + /* Remove button padding in FF */ + button::-moz-focus-inner { + border:0; + padding:0; + } + + body { font-family: Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; } + a { color: #00bc8c; text-decoration: none; } + a:hover { color: #007053; text-decoration: underline; } + .unread_room { color: #2392da; text-decoration: none; } + .unread_room:hover { color: #004970; text-decoration: underline; } + .emoji { + font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + font-size: 17px; + } + .mod-btn { + width: 16px; height: 16px; + margin: 0; padding: 0; + border: 1px solid gray; + display: inline; + text-align: center; + vertical-align: middle; + user-select: none; + background-color: #444; + color: #ea2a2a; + -webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.25); + -moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.25); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + } + .mod-btn:hover { + background-color: #222; + } + .delete_msg_btn { + font-size: 15px; + line-height: 1; + } + .delete_msg_btn::after { content: "×"; } + .hb_btn { + font-size: 10px; + line-height: 1.4; + } + .hb_btn::after { content: "hb"; } + .k_btn { + font-size: 10px; + line-height: 1.4; + } + .k_btn::after { content: "k"; } + #manualrefresh { + `) +//line messages.qtpl:115 + if !Data.ForceManualRefresh { +//line messages.qtpl:115 + qw422016.N().S(` + top: -200%; + animation: timeout_messages `) +//line messages.qtpl:117 + qw422016.N().DL(Data.ManualRefreshTimeout) +//line messages.qtpl:117 + qw422016.N().S(`s forwards; + `) +//line messages.qtpl:118 + } +//line messages.qtpl:118 + qw422016.N().S(` + color: #bf2718; + display: block; + position: fixed; + text-align: center; + left: calc(50% - 200px); + width: 400px; + z-index: 2; + background-color: #500000; + border: 2px solid #ff0000; + } + @keyframes timeout_messages { + 0% { top: -200%; } + 99% { top: -200%; } + 100% { top: 0; } + } + .date { color: #999; font-family: 'Courier New', Courier, monospace; font-size: 14px; } + .date-link:hover { color: #999; text-decoration: underline; } + .sysmsg { color: #fff; font-family: 'Courier New', Courier, monospace; font-size: 14px; } + small { font-size: 80%; font-weight: 400; } + .msg { padding: 3px 0 3px 8px; border-bottom: 1px solid #444; color: #888; position: relative; } + .msg p:first-of-type { display: inline; } + strong { font-weight: bold; } + em { font-style: italic; } + pre { border: 1px solid #2b442b; padding: 2px; margin: 2px 0; max-height: 300px; overflow: auto; background-color: rgba(39,40,34,0.6) !important; + font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; } + code { border: 1px solid #2b442b; color: #f92672; padding: 0 2px; margin: 0px 0; background-color: rgba(39,40,34,0.6) !important; } + .censored { background-color: black; color: black; padding: 0 3px; } + .censored:hover { background-color: black; color: white; } + ul { list-style-type: disc; margin: 0 0 0 15px; } + * { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + .afk-indicator { color: #ff9a27; } + .spacer16 { display: inline-block; width: 16px; } + .spacer36 { display: inline-block; width: 36px; } + .spacer56 { display: inline-block; width: 56px; } + .d-inline { display: inline; } + .o-wrap { overflow-wrap: break-word; } + .f-def-clr { color: #888; } + .f-orange-clr { color: orange; } + .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:162 + qw422016.N().F(AuthUser.GetHellbanOpacityF64()) +//line messages.qtpl:162 + qw422016.N().S(`; } + .own-highlight { background-color: rgba(255,241,176,0.05); } + .read-marker { border-top: `) +//line messages.qtpl:164 + qw422016.N().DL(AuthUser.ChatReadMarkerSize) +//line messages.qtpl:164 + qw422016.N().S(`px solid `) +//line messages.qtpl:164 + qw422016.E().S(AuthUser.ChatReadMarkerColor) +//line messages.qtpl:164 + qw422016.N().S(`; } + #msgs { `) +//line messages.qtpl:165 + if !AuthUser.HideRightColumn { +//line messages.qtpl:165 + qw422016.N().S(`width: calc(100% - 170px); float: left; `) +//line messages.qtpl:165 + } +//line messages.qtpl:165 + qw422016.N().S(`line-height: 1.2; } + #no-msg { padding-left: 10px; color: #ddd; } + #rgt-pane { width: 150px; height: 100%; float: left; margin-left: 20px; position: fixed; right: 0; overflow-y: auto; line-height: 1.15; } + .rgt-title { font-weight: bolder; color: #ced4da; } + .mb-20px { margin-bottom: 20px; } + .mb-30px { margin-bottom: 30px; } + .mt-5px { margin-top: 5px; } + .mt-10px { margin-top: 10px; } + .notif, .notif:hover { color: #e74c3c; } + #msg-err { background-color: #8f2d2d; color: #ffffff; padding: 1px 5px 2px 5px; display: block; text-decoration: none; } + </style> + </head> + <body> + + `) +//line messages.qtpl:179 + if Data.ForceManualRefresh { +//line messages.qtpl:179 + qw422016.N().S(` + <div id="manualrefresh"> + <h4>Manual refresh required</h4> + <form method="get" action="/chat/`) +//line messages.qtpl:182 + qw422016.E().S(Data.RoomName) +//line messages.qtpl:182 + qw422016.N().S(`" target="_top"> + <input type="submit" value="Reload" /> + </form> + </div> + `) +//line messages.qtpl:186 + } else if !Data.PreventRefresh { +//line messages.qtpl:186 + qw422016.N().S(` + <div id="manualrefresh"> + <h4>Manual refresh required</h4> + <form method="get"> + <input type="submit" value="Reload" /> + </form> + </div> + `) +//line messages.qtpl:193 + } +//line messages.qtpl:193 + qw422016.N().S(` + + `) +//line messages.qtpl:195 + if Data.Error != "" { +//line messages.qtpl:195 + qw422016.N().S(` + <a href="/api/v1/chat/messages/`) +//line messages.qtpl:196 + qw422016.E().S(Data.RoomName) +//line messages.qtpl:196 + qw422016.N().S(`" id="msg-err">× `) +//line messages.qtpl:196 + qw422016.E().S(Data.Error) +//line messages.qtpl:196 + qw422016.N().S(`</a> + `) +//line messages.qtpl:197 + } +//line messages.qtpl:197 + qw422016.N().S(` + + `) +//line messages.qtpl:199 + if Data.PmSound || Data.TaggedSound { +//line messages.qtpl:199 + qw422016.N().S(` + <audio src="/public/mp3/sound5.mp3" autoplay></audio> + `) +//line messages.qtpl:201 + } else if Data.NewMessageSound { +//line messages.qtpl:201 + qw422016.N().S(` + <audio src="/public/mp3/sound6.mp3" autoplay></audio> + `) +//line messages.qtpl:203 + } +//line messages.qtpl:203 + qw422016.N().S(` + + <div id="msgs"> + `) +//line messages.qtpl:207 + baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName + readMarkerRendered := false + isFirstMsg := true + +//line messages.qtpl:210 + qw422016.N().S(` + `) +//line messages.qtpl:211 + for idx, e := range Data.Messages { +//line messages.qtpl:211 + qw422016.N().S(` + `) +//line messages.qtpl:212 + if e.UserCanSee(*AuthUser) { +//line messages.qtpl:212 + qw422016.N().S(` + <div id="msgid-`) +//line messages.qtpl:213 + qw422016.E().S(e.UUID) +//line messages.qtpl:213 + qw422016.N().S(`" class="msg + `) +//line messages.qtpl:214 + if (e.User.IsHellbanned || e.IsHellbanned) && AuthUser.DisplayHellbanned { +//line messages.qtpl:214 + qw422016.N().S(` hb-row + `) +//line messages.qtpl:215 + } else if AuthUser.ID == e.User.ID && AuthUser.HighlightOwnMessages { +//line messages.qtpl:215 + qw422016.N().S(` own-highlight`) +//line messages.qtpl:215 + } +//line messages.qtpl:215 + qw422016.N().S(` + `) +//line messages.qtpl:216 + if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !readMarkerRendered { +//line messages.qtpl:216 + qw422016.N().S(` + `) +//line messages.qtpl:217 + if idx > 0 { +//line messages.qtpl:217 + qw422016.N().S(` read-marker`) +//line messages.qtpl:217 + } +//line messages.qtpl:217 + qw422016.N().S(` + `) +//line messages.qtpl:219 + readMarkerRendered = true + +//line messages.qtpl:220 + qw422016.N().S(` + `) +//line messages.qtpl:221 + } +//line messages.qtpl:221 + qw422016.N().S(` + "> + `) +//line messages.qtpl:223 + if e.UserCanDelete(*AuthUser) { +//line messages.qtpl:223 + qw422016.N().S(` + `) +//line messages.qtpl:224 + if !e.TooOldToDelete() { +//line messages.qtpl:224 + qw422016.N().S(` + `) +//line messages.qtpl:225 + if AuthUser.DisplayDeleteButton { +//line messages.qtpl:225 + qw422016.N().S(` + <form method="post" action="/api/v1/chat/messages/delete/`) +//line messages.qtpl:226 + qw422016.E().S(e.UUID) +//line messages.qtpl:226 + qw422016.N().S(`" class="d-inline"> + <input type="hidden" name="csrf" value="`) +//line messages.qtpl:227 + qw422016.E().S(CSRF) +//line messages.qtpl:227 + qw422016.N().S(`" /> + <button class="mod-btn delete_msg_btn" title="delete"></button> + </form> + `) +//line messages.qtpl:230 + } +//line messages.qtpl:230 + qw422016.N().S(` + `) +//line messages.qtpl:231 + } else if (AuthUser.IsModerator() && e.TooOldToDelete() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || (e.Room.OwnerUserID != nil && *e.Room.OwnerUserID == AuthUser.ID) { +//line messages.qtpl:231 + qw422016.N().S(` + `) +//line messages.qtpl:232 + if AuthUser.DisplayDeleteButton { +//line messages.qtpl:232 + qw422016.N().S(` + <form method="post" action="/api/v1/chat/messages/delete/`) +//line messages.qtpl:233 + qw422016.E().S(e.UUID) +//line messages.qtpl:233 + qw422016.N().S(`" class="d-inline"> + <input type="hidden" name="csrf" value="`) +//line messages.qtpl:234 + qw422016.E().S(CSRF) +//line messages.qtpl:234 + qw422016.N().S(`" /> + <button class="mod-btn delete_msg_btn f-orange-clr" title="delete"></button> + </form> + `) +//line messages.qtpl:237 + } +//line messages.qtpl:237 + qw422016.N().S(` + `) +//line messages.qtpl:238 + } else if AuthUser.IsModerator() { +//line messages.qtpl:238 + qw422016.N().S(` + `) +//line messages.qtpl:239 + if AuthUser.DisplayDeleteButton { +//line messages.qtpl:239 + qw422016.N().S(` + <div class="spacer16"></div> + `) +//line messages.qtpl:241 + } +//line messages.qtpl:241 + qw422016.N().S(` + `) +//line messages.qtpl:242 + } else { +//line messages.qtpl:242 + qw422016.N().S(` + `) +//line messages.qtpl:243 + if AuthUser.DisplayDeleteButton { +//line messages.qtpl:243 + qw422016.N().S(` + <div class="spacer16"></div> + `) +//line messages.qtpl:245 + } +//line messages.qtpl:245 + qw422016.N().S(` + `) +//line messages.qtpl:246 + } +//line messages.qtpl:246 + qw422016.N().S(` + `) +//line messages.qtpl:247 + if AuthUser.IsModerator() { +//line messages.qtpl:247 + qw422016.N().S(` + `) +//line messages.qtpl:248 + if e.UserID != AuthUser.ID { +//line messages.qtpl:248 + qw422016.N().S(` + `) +//line messages.qtpl:249 + if AuthUser.DisplayHellbanButton { +//line messages.qtpl:249 + qw422016.N().S(` + `) +//line messages.qtpl:250 + if e.User.Username == NullUsername { +//line messages.qtpl:250 + qw422016.N().S(` + <div class="spacer16"></div> + `) +//line messages.qtpl:252 + } else { +//line messages.qtpl:252 + qw422016.N().S(` + `) +//line messages.qtpl:253 + if e.User.IsHellbanned { +//line messages.qtpl:253 + qw422016.N().S(` + <form method="post" action="/api/v1/users/`) +//line messages.qtpl:254 + qw422016.E().S(e.UserID.String()) +//line messages.qtpl:254 + qw422016.N().S(`/unhellban" class="d-inline"> + <input type="hidden" name="csrf" value="`) +//line messages.qtpl:255 + qw422016.E().S(CSRF) +//line messages.qtpl:255 + qw422016.N().S(`" /> + <button class="mod-btn hb_btn f-orange-clr line-through" title="unhellban"></button> + </form> + `) +//line messages.qtpl:258 + } else { +//line messages.qtpl:258 + qw422016.N().S(` + <form method="post" action="/api/v1/users/`) +//line messages.qtpl:259 + qw422016.E().S(e.UserID.String()) +//line messages.qtpl:259 + qw422016.N().S(`/hellban" class="d-inline"> + <input type="hidden" name="csrf" value="`) +//line messages.qtpl:260 + qw422016.E().S(CSRF) +//line messages.qtpl:260 + qw422016.N().S(`" /> + <button class="mod-btn hb_btn f-orange-clr" title="hellban"></button> + </form> + `) +//line messages.qtpl:263 + } +//line messages.qtpl:263 + qw422016.N().S(` + `) +//line messages.qtpl:264 + } +//line messages.qtpl:264 + qw422016.N().S(` + `) +//line messages.qtpl:265 + } +//line messages.qtpl:265 + qw422016.N().S(` + `) +//line messages.qtpl:266 + if AuthUser.DisplayKickButton { +//line messages.qtpl:266 + qw422016.N().S(` + <form method="post" action="/api/v1/users/`) +//line messages.qtpl:267 + qw422016.E().S(e.UserID.String()) +//line messages.qtpl:267 + qw422016.N().S(`/kick" class="d-inline"> + <input type="hidden" name="csrf" value="`) +//line messages.qtpl:268 + qw422016.E().S(CSRF) +//line messages.qtpl:268 + qw422016.N().S(`" /> + <button class="mod-btn k_btn f-orange-clr" title="kick"></button> + </form> + `) +//line messages.qtpl:271 + } +//line messages.qtpl:271 + qw422016.N().S(` + `) +//line messages.qtpl:272 + } else { +//line messages.qtpl:272 + qw422016.N().S(` + `) +//line messages.qtpl:273 + if AuthUser.DisplayKickButton && AuthUser.DisplayHellbanButton { +//line messages.qtpl:273 + qw422016.N().S(` + <div class="spacer36"></div> + `) +//line messages.qtpl:275 + } else if AuthUser.DisplayKickButton || AuthUser.DisplayHellbanButton { +//line messages.qtpl:275 + qw422016.N().S(` + <div class="spacer16"></div> + `) +//line messages.qtpl:277 + } +//line messages.qtpl:277 + qw422016.N().S(` + `) +//line messages.qtpl:278 + } +//line messages.qtpl:278 + qw422016.N().S(` +`) +//line messages.qtpl:279 + } +//line messages.qtpl:280 + } else { +//line messages.qtpl:281 + if Data.NbButtons == 3 { +//line messages.qtpl:281 + qw422016.N().S(` <div class="spacer56"></div> +`) +//line messages.qtpl:283 + } else if Data.NbButtons == 2 { +//line messages.qtpl:283 + qw422016.N().S(` <div class="spacer36"></div> +`) +//line messages.qtpl:285 + } else if Data.NbButtons == 1 { +//line messages.qtpl:285 + qw422016.N().S(` <div class="spacer16"></div> +`) +//line messages.qtpl:287 + } +//line messages.qtpl:288 + } +//line messages.qtpl:289 + if Data.DateFormat != "" { +//line messages.qtpl:289 + qw422016.N().S(` <a href="`) +//line messages.qtpl:290 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:290 + qw422016.N().S(`?quote=`) +//line messages.qtpl:290 + qw422016.E().S(e.UUID) +//line messages.qtpl:290 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:290 + qw422016.N().S(`" target="iframe1" class="date date-link" title="`) +//line messages.qtpl:290 + qw422016.E().S(e.CreatedAt.Format("01-02 15:04:05")) +//line messages.qtpl:290 + if isFirstMsg { +//line messages.qtpl:290 + qw422016.N().S(` (`) +//line messages.qtpl:290 + qw422016.E().S(humanize.Time(e.CreatedAt)) +//line messages.qtpl:290 + qw422016.N().S(`)`) +//line messages.qtpl:290 + } +//line messages.qtpl:290 + qw422016.N().S(`">`) +//line messages.qtpl:290 + qw422016.E().S(e.CreatedAt.Format(Data.DateFormat)) +//line messages.qtpl:290 + qw422016.N().S(`</a> + `) +//line messages.qtpl:291 + isFirstMsg = false + +//line messages.qtpl:291 + qw422016.N().S(` +`) +//line messages.qtpl:292 + } +//line messages.qtpl:292 + qw422016.N().S(` <a href="/u/`) +//line messages.qtpl:293 + qw422016.E().S(e.GetProfile(AuthUser)) +//line messages.qtpl:293 + qw422016.N().S(`" target="_blank" class="f-def-clr">-</a> +`) +//line messages.qtpl:294 + if e.System { +//line messages.qtpl:294 + qw422016.N().S(` <span class="sysmsg">`) +//line messages.qtpl:295 + streamunesc(qw422016, e.Message) +//line messages.qtpl:295 + qw422016.N().S(`</span> +`) +//line messages.qtpl:296 + } else { +//line messages.qtpl:297 + if e.Moderators { +//line messages.qtpl:297 + qw422016.N().S(`<span class="sysmsg">[<a href="`) +//line messages.qtpl:297 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:297 + qw422016.N().S(`?m=1`) +//line messages.qtpl:297 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:297 + qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">M</a>]</span>&nbsp;`) +//line messages.qtpl:297 + } +//line messages.qtpl:298 + if e.GroupID != nil { +//line messages.qtpl:298 + qw422016.N().S(`<span class="sysmsg">[<a href="`) +//line messages.qtpl:298 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:298 + qw422016.N().S(`?g=`) +//line messages.qtpl:298 + qw422016.E().S(e.Group.Name) +//line messages.qtpl:298 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:298 + qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">`) +//line messages.qtpl:298 + qw422016.E().S(e.Group.Name) +//line messages.qtpl:298 + qw422016.N().S(`</a>]</span>&nbsp;`) +//line messages.qtpl:298 + } +//line messages.qtpl:299 + if e.ToUserID != nil { +//line messages.qtpl:299 + qw422016.N().S(` [`) +//line messages.qtpl:300 + streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL) +//line messages.qtpl:300 + qw422016.N().S(` → +`) +//line messages.qtpl:302 + if e.ToUser.ID == AuthUser.ID { +//line messages.qtpl:302 + qw422016.N().S(`<span `) +//line messages.qtpl:302 + streamunesc(qw422016, e.ToUser.GenerateChatStyle()) +//line messages.qtpl:302 + qw422016.N().S(`>`) +//line messages.qtpl:302 + qw422016.E().S(e.ToUser.Username) +//line messages.qtpl:302 + qw422016.N().S(`</span>`) +//line messages.qtpl:302 + } else { +//line messages.qtpl:302 + qw422016.N().S(`<a `) +//line messages.qtpl:302 + streamunesc(qw422016, e.ToUser.GenerateChatStyle()) +//line messages.qtpl:302 + qw422016.N().S(` href="`) +//line messages.qtpl:302 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:302 + qw422016.N().S(`?pm=`) +//line messages.qtpl:302 + qw422016.E().S(e.ToUser.Username) +//line messages.qtpl:302 + qw422016.E().S(Data.TopBarQueryParams) +//line messages.qtpl:302 + qw422016.N().S(`" target="iframe1">`) +//line messages.qtpl:302 + qw422016.E().S(e.ToUser.Username) +//line messages.qtpl:302 + qw422016.N().S(`</a>`) +//line messages.qtpl:302 + } +//line messages.qtpl:302 + qw422016.N().S(`] - +`) +//line messages.qtpl:303 + } else { +//line messages.qtpl:304 + streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL) +//line messages.qtpl:305 + if !e.IsMe() { +//line messages.qtpl:306 + if AuthUser.CanSeeHB() && (e.IsHellbanned || e.User.IsHellbanned) && (e.ToUserID == nil) { +//line messages.qtpl:306 + qw422016.N().S(` <a href="`) +//line messages.qtpl:307 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:307 + qw422016.N().S(`?hbm=1`) +//line messages.qtpl:307 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:307 + qw422016.N().S(`" target="iframe1" class="f-def-clr">-</a> +`) +//line messages.qtpl:308 + } else { +//line messages.qtpl:308 + qw422016.N().S(` - +`) +//line messages.qtpl:310 + } +//line messages.qtpl:311 + } +//line messages.qtpl:312 + } +//line messages.qtpl:312 + qw422016.N().S(` <span `) +//line messages.qtpl:313 + streamunesc(qw422016, e.User.GenerateChatStyle()) +//line messages.qtpl:313 + qw422016.N().S(`><span class="o-wrap">`) +//line messages.qtpl:313 + qw422016.N().S(unesc(e.MsgToDisplay())) +//line messages.qtpl:313 + qw422016.N().S(`</span></span> +`) +//line messages.qtpl:314 + } +//line messages.qtpl:314 + qw422016.N().S(` </div> +`) +//line messages.qtpl:316 + } +//line messages.qtpl:316 + qw422016.N().S(` `) +//line messages.qtpl:317 + } +//line messages.qtpl:317 + qw422016.N().S(` + `) +//line messages.qtpl:318 + if len(Data.Messages) == 0 { +//line messages.qtpl:318 + qw422016.N().S(` + <div id="no-msg"><em>No message yet</em></div> + `) +//line messages.qtpl:320 + } +//line messages.qtpl:320 + qw422016.N().S(` + </div> + + `) +//line messages.qtpl:323 + if !AuthUser.HideRightColumn { +//line messages.qtpl:323 + 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:326 + if Data.InboxCount > 0 { +//line messages.qtpl:326 + qw422016.N().S(`class="notif"`) +//line messages.qtpl:326 + } +//line messages.qtpl:326 + qw422016.N().S(`>`) +//line messages.qtpl:326 + qw422016.N().DL(Data.InboxCount) +//line messages.qtpl:326 + qw422016.N().S(`</a>)</div> + </div> + <div class="mb-20px"> + <div class="rgt-title">Rooms:</div> + `) +//line messages.qtpl:330 + for _, e := range Data.OfficialRooms { +//line messages.qtpl:330 + qw422016.N().S(` + `) +//line messages.qtpl:331 + if e.Name == "club" { +//line messages.qtpl:331 + qw422016.N().S(` + `) +//line messages.qtpl:332 + if AuthUser.IsClubMember { +//line messages.qtpl:332 + qw422016.N().S(` + <div><a href="/chat/club" target="_top"`) +//line messages.qtpl:333 + if e.IsUnread { +//line messages.qtpl:333 + qw422016.N().S(` class="unread_room"`) +//line messages.qtpl:333 + } +//line messages.qtpl:333 + qw422016.N().S(`>#club</a></div> + `) +//line messages.qtpl:334 + } +//line messages.qtpl:334 + qw422016.N().S(` + `) +//line messages.qtpl:335 + } else if e.Name == "moderators" { +//line messages.qtpl:335 + qw422016.N().S(` + `) +//line messages.qtpl:336 + if AuthUser.IsModerator() { +//line messages.qtpl:336 + qw422016.N().S(` + <div><a href="/chat/moderators" target="_top"`) +//line messages.qtpl:337 + if e.IsUnread { +//line messages.qtpl:337 + qw422016.N().S(` class="unread_room"`) +//line messages.qtpl:337 + } +//line messages.qtpl:337 + qw422016.N().S(`>#moderators</a></div> + `) +//line messages.qtpl:338 + } +//line messages.qtpl:338 + qw422016.N().S(` + `) +//line messages.qtpl:339 + } else { +//line messages.qtpl:339 + qw422016.N().S(` + <div><a href="/chat/`) +//line messages.qtpl:340 + qw422016.E().S(e.Name) +//line messages.qtpl:340 + qw422016.N().S(`" target="_top"`) +//line messages.qtpl:340 + if e.IsUnread { +//line messages.qtpl:340 + qw422016.N().S(` class="unread_room"`) +//line messages.qtpl:340 + } +//line messages.qtpl:340 + qw422016.N().S(`>#`) +//line messages.qtpl:340 + qw422016.E().S(e.Name) +//line messages.qtpl:340 + qw422016.N().S(`</a></div> + `) +//line messages.qtpl:341 + } +//line messages.qtpl:341 + qw422016.N().S(` + `) +//line messages.qtpl:342 + } +//line messages.qtpl:342 + qw422016.N().S(` + `) +//line messages.qtpl:343 + if len(Data.SubscribedRooms) > 0 { +//line messages.qtpl:343 + qw422016.N().S(` + <div class="mt-10px"></div> + `) +//line messages.qtpl:345 + for _, e := range Data.SubscribedRooms { +//line messages.qtpl:345 + qw422016.N().S(` + <div><a href="/chat/`) +//line messages.qtpl:346 + qw422016.E().S(e.Name) +//line messages.qtpl:346 + qw422016.N().S(`" target="_top"`) +//line messages.qtpl:346 + if e.IsUnread { +//line messages.qtpl:346 + qw422016.N().S(` class="unread_room"`) +//line messages.qtpl:346 + } +//line messages.qtpl:346 + qw422016.N().S(`>#`) +//line messages.qtpl:346 + qw422016.E().S(e.Name) +//line messages.qtpl:346 + qw422016.N().S(`</a></div> + `) +//line messages.qtpl:347 + } +//line messages.qtpl:347 + qw422016.N().S(` + `) +//line messages.qtpl:348 + } +//line messages.qtpl:348 + 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:353 + for _, e := range Data.Members { +//line messages.qtpl:353 + qw422016.N().S(` + `) +//line messages.qtpl:354 + StreamMember(qw422016, AuthUser, Data, e) +//line messages.qtpl:354 + qw422016.N().S(` + `) +//line messages.qtpl:355 + } +//line messages.qtpl:355 + qw422016.N().S(` + </div> + `) +//line messages.qtpl:357 + if Data.VisibleMemberInChat || AuthUser.DisplayHellbanned { +//line messages.qtpl:357 + qw422016.N().S(` + <div class="mb-30px"> + `) +//line messages.qtpl:359 + if len(Data.MembersInChat) > 0 { +//line messages.qtpl:359 + qw422016.N().S(` + <div class="rgt-title">In other rooms:</div> + `) +//line messages.qtpl:361 + for _, e := range Data.MembersInChat { +//line messages.qtpl:361 + qw422016.N().S(` + `) +//line messages.qtpl:362 + StreamMember(qw422016, AuthUser, Data, e) +//line messages.qtpl:362 + qw422016.N().S(` + `) +//line messages.qtpl:363 + } +//line messages.qtpl:363 + qw422016.N().S(` + `) +//line messages.qtpl:364 + } +//line messages.qtpl:364 + qw422016.N().S(` + </div> + `) +//line messages.qtpl:366 + } +//line messages.qtpl:366 + qw422016.N().S(` + </div> + `) +//line messages.qtpl:368 + } +//line messages.qtpl:368 + qw422016.N().S(` + `) +//line messages.qtpl:369 + if AuthUser.CollectMetadata { +//line messages.qtpl:369 + qw422016.N().S(` + <div class="div_1"></div> + <div class="div_2"></div> + <div class="div_f0">a</div> + `) +//line messages.qtpl:373 + } +//line messages.qtpl:373 + qw422016.N().S(` + </body> +</html> +`) +//line messages.qtpl:376 +} + +//line messages.qtpl:376 +func WriteMessages(qq422016 qtio422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) { +//line messages.qtpl:376 + qw422016 := qt422016.AcquireWriter(qq422016) +//line messages.qtpl:376 + StreamMessages(qw422016, VERSION, CSRF, NullUsername, AuthUser, Data) +//line messages.qtpl:376 + qt422016.ReleaseWriter(qw422016) +//line messages.qtpl:376 +} + +//line messages.qtpl:376 +func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) string { +//line messages.qtpl:376 + qb422016 := qt422016.AcquireByteBuffer() +//line messages.qtpl:376 + WriteMessages(qb422016, VERSION, CSRF, NullUsername, AuthUser, Data) +//line messages.qtpl:376 + qs422016 := string(qb422016.B) +//line messages.qtpl:376 + qt422016.ReleaseByteBuffer(qb422016) +//line messages.qtpl:376 + return qs422016 +//line messages.qtpl:376 +} + +//line messages.qtpl:380 +func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) { +//line messages.qtpl:380 + qw422016.N().S(` + `) +//line messages.qtpl:381 + baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName + +//line messages.qtpl:381 + qw422016.N().S(` + `) +//line messages.qtpl:382 + if El.Username == AuthUser.Username { +//line messages.qtpl:382 + qw422016.N().S(` + <div> + <span style="color: `) +//line messages.qtpl:384 + qw422016.E().S(El.Color) +//line messages.qtpl:384 + qw422016.N().S(`;">`) +//line messages.qtpl:384 + qw422016.E().S(El.Username) +//line messages.qtpl:384 + qw422016.N().S(`</span> + `) +//line messages.qtpl:385 + if El.AfkIndicatorEnabled { +//line messages.qtpl:385 + qw422016.N().S(` + <small class="afk-indicator">afk</small> + `) +//line messages.qtpl:387 + } +//line messages.qtpl:387 + qw422016.N().S(` + </div> + `) +//line messages.qtpl:389 + } else { +//line messages.qtpl:389 + qw422016.N().S(` + `) +//line messages.qtpl:390 + if !El.IsHellbanned || AuthUser.ID == El.UserID || (El.IsHellbanned && AuthUser.IsHellbanned) || AuthUser.DisplayHellbanned { +//line messages.qtpl:390 + qw422016.N().S(` + <div> + `) +//line messages.qtpl:392 + tagType := "tag" + +//line messages.qtpl:392 + qw422016.N().S(` + `) +//line messages.qtpl:393 + if AuthUser.CanSeeHB() && El.IsHellbanned { +//line messages.qtpl:393 + qw422016.N().S(` + `) +//line messages.qtpl:394 + tagType = "htag" + +//line messages.qtpl:394 + qw422016.N().S(` + `) +//line messages.qtpl:395 + } +//line messages.qtpl:395 + qw422016.N().S(` + `) +//line messages.qtpl:396 + qw422016.N().S(`<a href="`) +//line messages.qtpl:397 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:397 + qw422016.N().S(`?`) +//line messages.qtpl:397 + qw422016.E().S(tagType) +//line messages.qtpl:397 + qw422016.N().S(`=`) +//line messages.qtpl:397 + qw422016.E().S(El.Username) +//line messages.qtpl:397 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:397 + qw422016.N().S(`"target="iframe1"`) +//line messages.qtpl:399 + if El.IsHellbanned && AuthUser.DisplayHellbanned { +//line messages.qtpl:399 + qw422016.N().S(`class="hb-row"`) +//line messages.qtpl:399 + } +//line messages.qtpl:399 + qw422016.N().S(`style="color:`) +//line messages.qtpl:400 + qw422016.E().S(El.Color) +//line messages.qtpl:400 + qw422016.N().S(`;">`) +//line messages.qtpl:400 + qw422016.E().S(string(El.Username[0])) +//line messages.qtpl:400 + qw422016.N().S(`</a><a href="`) +//line messages.qtpl:401 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:401 + qw422016.N().S(`?pm=`) +//line messages.qtpl:401 + qw422016.E().S(El.Username) +//line messages.qtpl:401 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:401 + qw422016.N().S(`"target="iframe1"`) +//line messages.qtpl:403 + if El.IsHellbanned && AuthUser.DisplayHellbanned { +//line messages.qtpl:403 + qw422016.N().S(`class="hb-row"`) +//line messages.qtpl:403 + } +//line messages.qtpl:403 + qw422016.N().S(`style="color:`) +//line messages.qtpl:404 + qw422016.E().S(El.Color) +//line messages.qtpl:404 + qw422016.N().S(`;">`) +//line messages.qtpl:404 + qw422016.E().S(string(El.Username[1 : len(El.Username)-1])) +//line messages.qtpl:404 + qw422016.N().S(`</a><a href="/u/`) +//line messages.qtpl:405 + qw422016.E().S(El.Username) +//line messages.qtpl:405 + qw422016.N().S(`"rel="noopener noreferrer" target="_blank"`) +//line messages.qtpl:407 + if El.IsHellbanned && AuthUser.DisplayHellbanned { +//line messages.qtpl:407 + qw422016.N().S(`class="hb-row"`) +//line messages.qtpl:407 + } +//line messages.qtpl:407 + qw422016.N().S(`style="color:`) +//line messages.qtpl:408 + qw422016.E().S(El.Color) +//line messages.qtpl:408 + qw422016.N().S(`;">`) +//line messages.qtpl:408 + qw422016.E().S(string(El.Username[len(El.Username)-1])) +//line messages.qtpl:408 + qw422016.N().S(`</a>`) +//line messages.qtpl:409 + qw422016.N().S(` + `) +//line messages.qtpl:410 + if El.AfkIndicatorEnabled { +//line messages.qtpl:410 + qw422016.N().S(` + <small class="afk-indicator">afk</small> + `) +//line messages.qtpl:412 + } +//line messages.qtpl:412 + qw422016.N().S(` + </div> + `) +//line messages.qtpl:414 + } +//line messages.qtpl:414 + qw422016.N().S(` + `) +//line messages.qtpl:415 + } +//line messages.qtpl:415 + qw422016.N().S(` +`) +//line messages.qtpl:416 +} + +//line messages.qtpl:416 +func WriteMember(qq422016 qtio422016.Writer, AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) { +//line messages.qtpl:416 + qw422016 := qt422016.AcquireWriter(qq422016) +//line messages.qtpl:416 + StreamMember(qw422016, AuthUser, Data, El) +//line messages.qtpl:416 + qt422016.ReleaseWriter(qw422016) +//line messages.qtpl:416 +} + +//line messages.qtpl:416 +func Member(AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) string { +//line messages.qtpl:416 + qb422016 := qt422016.AcquireByteBuffer() +//line messages.qtpl:416 + WriteMember(qb422016, AuthUser, Data, El) +//line messages.qtpl:416 + qs422016 := string(qb422016.B) +//line messages.qtpl:416 + qt422016.ReleaseByteBuffer(qb422016) +//line messages.qtpl:416 + return qs422016 +//line messages.qtpl:416 +} + +//line messages.qtpl:419 +func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) { +//line messages.qtpl:420 + tagType := "tag" + +//line messages.qtpl:421 + if El.ToUserID != nil { +//line messages.qtpl:422 + tagType = "pm" + +//line messages.qtpl:423 + } else if AuthUser.CanSeeHB() && (El.IsHellbanned || El.User.IsHellbanned) { +//line messages.qtpl:424 + tagType = "htag" + +//line messages.qtpl:425 + } else if AuthUser.IsModerator() && El.Moderators { +//line messages.qtpl:426 + tagType = "mtag" + +//line messages.qtpl:427 + } +//line messages.qtpl:428 + if El.User.ID == AuthUser.ID { +//line messages.qtpl:429 + if El.CanBeEdited() { +//line messages.qtpl:429 + qw422016.N().S(`<a `) +//line messages.qtpl:429 + streamunesc(qw422016, El.User.GenerateChatStyle()) +//line messages.qtpl:429 + qw422016.N().S(` href="`) +//line messages.qtpl:429 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:429 + qw422016.N().S(`?e=`) +//line messages.qtpl:429 + qw422016.E().S(El.CreatedAt.Format("15:04:05")) +//line messages.qtpl:429 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:429 + qw422016.N().S(`" target="iframe1">`) +//line messages.qtpl:429 + qw422016.E().S(El.User.Username) +//line messages.qtpl:429 + qw422016.N().S(`</a>`) +//line messages.qtpl:429 + } else { +//line messages.qtpl:429 + qw422016.N().S(`<span `) +//line messages.qtpl:429 + streamunesc(qw422016, El.User.GenerateChatStyle()) +//line messages.qtpl:429 + qw422016.N().S(`>`) +//line messages.qtpl:429 + qw422016.E().S(El.User.Username) +//line messages.qtpl:429 + qw422016.N().S(`</span>`) +//line messages.qtpl:429 + } +//line messages.qtpl:430 + } else { +//line messages.qtpl:430 + qw422016.N().S(`<a `) +//line messages.qtpl:430 + streamunesc(qw422016, El.User.GenerateChatStyle()) +//line messages.qtpl:430 + qw422016.N().S(` href="`) +//line messages.qtpl:430 + qw422016.E().S(baseTopBarURL) +//line messages.qtpl:430 + qw422016.N().S(`?`) +//line messages.qtpl:430 + qw422016.E().S(tagType) +//line messages.qtpl:430 + qw422016.N().S(`=`) +//line messages.qtpl:430 + qw422016.E().S(El.User.Username) +//line messages.qtpl:430 + streamunesc(qw422016, Data.TopBarQueryParams) +//line messages.qtpl:430 + qw422016.N().S(`" target="iframe1">`) +//line messages.qtpl:430 + qw422016.E().S(El.User.Username) +//line messages.qtpl:430 + qw422016.N().S(`</a>`) +//line messages.qtpl:430 + } +//line messages.qtpl:431 +} + +//line messages.qtpl:431 +func writefromUsername(qq422016 qtio422016.Writer, AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) { +//line messages.qtpl:431 + qw422016 := qt422016.AcquireWriter(qq422016) +//line messages.qtpl:431 + streamfromUsername(qw422016, AuthUser, Data, El, baseTopBarURL) +//line messages.qtpl:431 + qt422016.ReleaseWriter(qw422016) +//line messages.qtpl:431 +} + +//line messages.qtpl:431 +func fromUsername(AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) string { +//line messages.qtpl:431 + qb422016 := qt422016.AcquireByteBuffer() +//line messages.qtpl:431 + writefromUsername(qb422016, AuthUser, Data, El, baseTopBarURL) +//line messages.qtpl:431 + qs422016 := string(qb422016.B) +//line messages.qtpl:431 + qt422016.ReleaseByteBuffer(qb422016) +//line messages.qtpl:431 + return qs422016 +//line messages.qtpl:431 +}