commit 273d9e84f2c1722994fc843caca44f0bf215af43
parent 0b74330697d0cf8256da5ff4a50a4e2753a0b218
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Sun, 21 May 2023 22:16:42 -0700
chat stream experiment
Diffstat:
8 files changed, 1277 insertions(+), 1035 deletions(-)
diff --git a/pkg/database/tableChatMessages.go b/pkg/database/tableChatMessages.go
@@ -4,6 +4,7 @@ import (
"crypto/cipher"
"crypto/rand"
"dkforest/pkg/config"
+ "dkforest/pkg/pubsub"
"dkforest/pkg/utils"
"encoding/json"
"errors"
@@ -528,9 +529,12 @@ func (d *DkfDB) CreateOrEditMessage(
}
}
editMsg.DoSave(d)
+ MsgPubSub.Pub("room_"+utils.FormatInt64(int64(roomID)), editMsg)
return editMsg.ID, nil
}
+var MsgPubSub = pubsub.NewPubSub[*ChatMessage]()
+
func encryptMessages(html, origMessage, roomKey string) (string, string, error) {
var err error
// Encrypt html message (for displaying)
diff --git a/pkg/web/handlers/api/v1/data.go b/pkg/web/handlers/api/v1/data.go
@@ -18,8 +18,7 @@ type chatTopBarData struct {
CommandsList []string
}
-type chatMessagesData struct {
- IsModerator bool
+type ChatMessagesData struct {
NbButtons int64
Messages []database.ChatMessage
Members []managers.UserInfo
@@ -27,7 +26,6 @@ type chatMessagesData struct {
VisibleMemberInChat bool // either or not at least 1 user is "visibile" (not hellbanned)
PreventRefresh bool
TopBarQueryParams string
- DateFormat string
RoomName string
InboxCount int64
ManualRefreshTimeout int64
@@ -42,7 +40,7 @@ type chatMessagesData struct {
ErrorTs int64
}
-func (c chatMessagesData) MarshalJSON() ([]byte, error) {
+func (c ChatMessagesData) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Members []managers.UserInfo
Messages []database.ChatMessage
diff --git a/pkg/web/handlers/api/v1/handlers.go b/pkg/web/handlers/api/v1/handlers.go
@@ -86,7 +86,7 @@ var memeRenameRgx = regexp.MustCompile(`^/meme ([a-zA-Z0-9_-]{3,50}) ([a-zA-Z0-9
var memeRemoveRgx = regexp.MustCompile(`^/memerm ([a-zA-Z0-9_-]{3,50})$`)
var memesRgx = regexp.MustCompile(`^/memes$`)
-func chatMessages(c echo.Context) (status int, data chatMessagesData) {
+func chatMessages(c echo.Context) (status int, data ChatMessagesData) {
authCookie, _ := c.Cookie(hutils.AuthCookieName)
authUser := c.Get("authUser").(*database.User)
db := c.Get("database").(*database.DkfDB)
@@ -149,8 +149,6 @@ func chatMessages(c echo.Context) (status int, data chatMessagesData) {
}
data.ManualRefreshTimeout = authUser.RefreshRate + 25
- data.DateFormat = authUser.GetDateFormat()
- data.IsModerator = authUser.IsModerator()
data.Messages = msgs
data.Members = membersInRoom
data.MembersInChat = membersInChat
diff --git a/pkg/web/handlers/api/v1/messages.qtpl b/pkg/web/handlers/api/v1/messages.qtpl
@@ -2,7 +2,123 @@
{% import "dkforest/pkg/managers" %}
{% import humanize "github.com/dustin/go-humanize" %}
-{% func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) -%}
+{%- func GenerateStyle(AuthUser *database.User, Data ChatMessagesData) -%}
+<style>
+ 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>
+{%- endfunc -%}
+
+{% func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) -%}
<html lang="en">
<head>
<title></title>
@@ -58,120 +174,8 @@
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>
+ {%-= GenerateStyle(AuthUser, Data) -%}
</head>
<body>
@@ -202,119 +206,7 @@
{%- 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> {%- 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> {%- 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 %}
+ {%-= RenderMessages(AuthUser, Data, CSRF, NullUsername) -%}
</div>
{% if !AuthUser.HideRightColumn %}
@@ -373,8 +265,129 @@
{% endfunc %}
+{%- func RenderMessages(AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) -%}
+ {%- code
+ baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName
+ readMarkerRendered := false
+ isFirstMsg := true
+ -%}
+ {%- for idx, e := range Data.Messages -%}
+ {%-= RenderMessage(idx, e, AuthUser, Data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, CSRF, NullUsername) -%}
+ {% endfor %}
+ {% if len(Data.Messages) == 0 %}
+ <div id="no-msg"><em>No message yet</em></div>
+ {% endif %}
+{%- endfunc -%}
+
+{%- func RenderMessage(idx int, e database.ChatMessage, AuthUser *database.User,
+ Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string) -%}
+ {%- 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 AuthUser.GetDateFormat() != "" -%}
+ <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(AuthUser.GetDateFormat()) %}</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> {%- 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> {%- 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 -%}
+{%- endfunc -%}
+
-{% func Member(AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) %}
+{% 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>
@@ -413,7 +426,7 @@
{% endfunc %}
-{%- func fromUsername(AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) -%}
+{%- func fromUsername(AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) -%}
{%- code tagType := "tag" -%}
{%- if El.ToUserID != nil -%}
{%- code tagType = "pm" -%}
diff --git a/pkg/web/handlers/api/v1/messages.qtpl.go b/pkg/web/handlers/api/v1/messages.qtpl.go
@@ -27,33 +27,211 @@ var (
)
//line messages.qtpl:5
-func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) {
+func StreamGenerateStyle(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData) {
//line messages.qtpl:5
+ qw422016.N().S(`<style>
+ 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:58
+ if !Data.ForceManualRefresh {
+//line messages.qtpl:58
+ qw422016.N().S(`
+ top: -200%;
+ animation: timeout_messages `)
+//line messages.qtpl:60
+ qw422016.N().DL(Data.ManualRefreshTimeout)
+//line messages.qtpl:60
+ qw422016.N().S(`s forwards;
+ `)
+//line messages.qtpl:61
+ }
+//line messages.qtpl:61
+ 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:105
+ qw422016.N().F(AuthUser.GetHellbanOpacityF64())
+//line messages.qtpl:105
+ qw422016.N().S(`; }
+ .own-highlight { background-color: rgba(255,241,176,0.05); }
+ .read-marker { border-top: `)
+//line messages.qtpl:107
+ qw422016.N().DL(AuthUser.ChatReadMarkerSize)
+//line messages.qtpl:107
+ qw422016.N().S(`px solid `)
+//line messages.qtpl:107
+ qw422016.E().S(AuthUser.ChatReadMarkerColor)
+//line messages.qtpl:107
+ qw422016.N().S(`; }
+ #msgs { `)
+//line messages.qtpl:108
+ if !AuthUser.HideRightColumn {
+//line messages.qtpl:108
+ qw422016.N().S(`width: calc(100% - 170px); float: left; `)
+//line messages.qtpl:108
+ }
+//line messages.qtpl:108
+ 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>
+`)
+//line messages.qtpl:119
+}
+
+//line messages.qtpl:119
+func WriteGenerateStyle(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData) {
+//line messages.qtpl:119
+ qw422016 := qt422016.AcquireWriter(qq422016)
+//line messages.qtpl:119
+ StreamGenerateStyle(qw422016, AuthUser, Data)
+//line messages.qtpl:119
+ qt422016.ReleaseWriter(qw422016)
+//line messages.qtpl:119
+}
+
+//line messages.qtpl:119
+func GenerateStyle(AuthUser *database.User, Data ChatMessagesData) string {
+//line messages.qtpl:119
+ qb422016 := qt422016.AcquireByteBuffer()
+//line messages.qtpl:119
+ WriteGenerateStyle(qb422016, AuthUser, Data)
+//line messages.qtpl:119
+ qs422016 := string(qb422016.B)
+//line messages.qtpl:119
+ qt422016.ReleaseByteBuffer(qb422016)
+//line messages.qtpl:119
+ return qs422016
+//line messages.qtpl:119
+}
+
+//line messages.qtpl:121
+func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) {
+//line messages.qtpl:121
qw422016.N().S(`<html lang="en">
<head>
<title></title>
`)
-//line messages.qtpl:9
+//line messages.qtpl:125
if !Data.PreventRefresh && !Data.ForceManualRefresh {
-//line messages.qtpl:9
+//line messages.qtpl:125
qw422016.N().S(`<meta http-equiv="refresh" content="`)
-//line messages.qtpl:9
+//line messages.qtpl:125
qw422016.N().DL(AuthUser.RefreshRate)
-//line messages.qtpl:9
+//line messages.qtpl:125
qw422016.N().S(`">`)
-//line messages.qtpl:9
+//line messages.qtpl:125
}
-//line messages.qtpl:10
+//line messages.qtpl:126
if AuthUser.CollectMetadata {
-//line messages.qtpl:10
+//line messages.qtpl:126
qw422016.N().S(`<link rel="stylesheet" type="text/css" href="/public/css/meta.css?v=`)
-//line messages.qtpl:10
+//line messages.qtpl:126
qw422016.E().S(VERSION)
-//line messages.qtpl:10
+//line messages.qtpl:126
qw422016.N().S(`" />`)
-//line messages.qtpl:10
+//line messages.qtpl:126
}
-//line messages.qtpl:10
+//line messages.qtpl:126
qw422016.N().S(`
<style>
/* http://meyerweb.com/eric/tools/css/reset/
@@ -104,173 +282,32 @@ func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername strin
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:114
- if !Data.ForceManualRefresh {
-//line messages.qtpl:114
- qw422016.N().S(`
- top: -200%;
- animation: timeout_messages `)
-//line messages.qtpl:116
- qw422016.N().DL(Data.ManualRefreshTimeout)
-//line messages.qtpl:116
- qw422016.N().S(`s forwards;
- `)
-//line messages.qtpl:117
- }
-//line messages.qtpl:117
- 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:161
- qw422016.N().F(AuthUser.GetHellbanOpacityF64())
-//line messages.qtpl:161
- qw422016.N().S(`; }
- .own-highlight { background-color: rgba(255,241,176,0.05); }
- .read-marker { border-top: `)
-//line messages.qtpl:163
- qw422016.N().DL(AuthUser.ChatReadMarkerSize)
-//line messages.qtpl:163
- qw422016.N().S(`px solid `)
-//line messages.qtpl:163
- qw422016.E().S(AuthUser.ChatReadMarkerColor)
-//line messages.qtpl:163
- qw422016.N().S(`; }
- #msgs { `)
-//line messages.qtpl:164
- if !AuthUser.HideRightColumn {
-//line messages.qtpl:164
- qw422016.N().S(`width: calc(100% - 170px); float: left; `)
-//line messages.qtpl:164
- }
-//line messages.qtpl:164
- 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>
+`)
+//line messages.qtpl:178
+ StreamGenerateStyle(qw422016, AuthUser, Data)
+//line messages.qtpl:178
+ qw422016.N().S(` </head>
<body>
`)
-//line messages.qtpl:178
+//line messages.qtpl:182
if Data.ForceManualRefresh {
-//line messages.qtpl:178
+//line messages.qtpl:182
qw422016.N().S(` <div id="manualrefresh">
<h4>Manual refresh required</h4>
<form method="get" action="/chat/`)
-//line messages.qtpl:181
+//line messages.qtpl:185
qw422016.E().S(Data.RoomName)
-//line messages.qtpl:181
+//line messages.qtpl:185
qw422016.N().S(`" target="_top">
<input type="submit" value="Reload" />
</form>
</div>
`)
-//line messages.qtpl:185
+//line messages.qtpl:189
} else if !Data.PreventRefresh {
-//line messages.qtpl:185
+//line messages.qtpl:189
qw422016.N().S(` <div id="manualrefresh">
<h4>Manual refresh required</h4>
<form method="get">
@@ -278,962 +315,1033 @@ func StreamMessages(qw422016 *qt422016.Writer, VERSION, CSRF, NullUsername strin
</form>
</div>
`)
-//line messages.qtpl:192
+//line messages.qtpl:196
}
-//line messages.qtpl:192
+//line messages.qtpl:196
qw422016.N().S(`
`)
-//line messages.qtpl:194
+//line messages.qtpl:198
if Data.Error != "" {
-//line messages.qtpl:194
+//line messages.qtpl:198
qw422016.N().S(` <a href="/api/v1/chat/messages/`)
-//line messages.qtpl:195
+//line messages.qtpl:199
qw422016.E().S(Data.RoomName)
-//line messages.qtpl:195
+//line messages.qtpl:199
qw422016.N().S(`" id="msg-err">× `)
-//line messages.qtpl:195
+//line messages.qtpl:199
qw422016.E().S(Data.Error)
-//line messages.qtpl:195
+//line messages.qtpl:199
qw422016.N().S(`</a>
`)
-//line messages.qtpl:196
+//line messages.qtpl:200
}
-//line messages.qtpl:196
+//line messages.qtpl:200
qw422016.N().S(`
`)
-//line messages.qtpl:198
+//line messages.qtpl:202
if Data.PmSound || Data.TaggedSound {
-//line messages.qtpl:198
+//line messages.qtpl:202
qw422016.N().S(` <audio src="/public/mp3/sound5.mp3" autoplay></audio>
`)
-//line messages.qtpl:200
+//line messages.qtpl:204
} else if Data.NewMessageSound {
-//line messages.qtpl:200
+//line messages.qtpl:204
qw422016.N().S(` <audio src="/public/mp3/sound6.mp3" autoplay></audio>
`)
-//line messages.qtpl:202
+//line messages.qtpl:206
}
-//line messages.qtpl:202
+//line messages.qtpl:206
qw422016.N().S(`
<div id="msgs">
`)
-//line messages.qtpl:206
- baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName
- readMarkerRendered := false
- isFirstMsg := true
+//line messages.qtpl:209
+ StreamRenderMessages(qw422016, AuthUser, Data, CSRF, NullUsername)
+//line messages.qtpl:209
+ qw422016.N().S(` </div>
-//line messages.qtpl:210
- for idx, e := range Data.Messages {
-//line messages.qtpl:211
- if e.UserCanSee(*AuthUser) {
-//line messages.qtpl:211
- qw422016.N().S(` <div id="msgid-`)
+ `)
//line messages.qtpl:212
- qw422016.E().S(e.UUID)
+ if !AuthUser.HideRightColumn {
//line messages.qtpl:212
- qw422016.N().S(`" class="msg
-`)
-//line messages.qtpl:213
- if (e.User.IsHellbanned || e.IsHellbanned) && AuthUser.DisplayHellbanned {
-//line messages.qtpl:213
- qw422016.N().S(` hb-row
-`)
-//line messages.qtpl:214
- } else if AuthUser.ID == e.User.ID && AuthUser.HighlightOwnMessages {
-//line messages.qtpl:214
- qw422016.N().S(` own-highlight`)
-//line messages.qtpl:214
- }
+ 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:215
- if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !readMarkerRendered {
+ if Data.InboxCount > 0 {
//line messages.qtpl:215
- qw422016.N().S(`
-`)
-//line messages.qtpl:216
- if idx > 0 {
-//line messages.qtpl:216
- qw422016.N().S(`read-marker`)
-//line messages.qtpl:216
- }
-//line messages.qtpl:217
- readMarkerRendered = true
-
-//line messages.qtpl:218
- }
-//line messages.qtpl:218
- qw422016.N().S(` ">
+ qw422016.N().S(`class="notif"`)
+//line messages.qtpl:215
+ }
+//line messages.qtpl:215
+ qw422016.N().S(`>`)
+//line messages.qtpl:215
+ qw422016.N().DL(Data.InboxCount)
+//line messages.qtpl:215
+ qw422016.N().S(`</a>)</div>
+ </div>
+ <div class="mb-20px">
+ <div class="rgt-title">Rooms:</div>
`)
+//line messages.qtpl:219
+ for _, e := range Data.OfficialRooms {
//line messages.qtpl:220
- if e.UserCanDelete(*AuthUser) {
+ if e.Name == "club" {
//line messages.qtpl:221
- if !e.TooOldToDelete() {
+ if AuthUser.IsClubMember {
+//line messages.qtpl:221
+ qw422016.N().S(` <div><a href="/chat/club" target="_top"`)
+//line messages.qtpl:222
+ if e.IsUnread {
//line messages.qtpl:222
- if AuthUser.DisplayDeleteButton {
+ qw422016.N().S(` class="unread_room"`)
//line messages.qtpl:222
- qw422016.N().S(` <form method="post" action="/api/v1/chat/messages/delete/`)
-//line messages.qtpl:223
- qw422016.E().S(e.UUID)
+ }
+//line messages.qtpl:222
+ qw422016.N().S(`>#club</a></div>
+`)
//line messages.qtpl:223
- qw422016.N().S(`" class="d-inline">
- <input type="hidden" name="csrf" value="`)
-//line messages.qtpl:224
- qw422016.E().S(CSRF)
+ }
//line messages.qtpl:224
- qw422016.N().S(`" />
- <button class="mod-btn delete_msg_btn" title="delete"></button>
- </form>
+ } else if e.Name == "moderators" {
+//line messages.qtpl:225
+ if AuthUser.IsModerator() {
+//line messages.qtpl:225
+ qw422016.N().S(` <div><a href="/chat/moderators" target="_top"`)
+//line messages.qtpl:226
+ if e.IsUnread {
+//line messages.qtpl:226
+ qw422016.N().S(` class="unread_room"`)
+//line messages.qtpl:226
+ }
+//line messages.qtpl:226
+ qw422016.N().S(`>#moderators</a></div>
`)
//line messages.qtpl:227
- }
+ }
+//line messages.qtpl:228
+ } else {
//line messages.qtpl:228
- } else if (AuthUser.IsModerator() && e.TooOldToDelete() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || (e.Room.OwnerUserID != nil && *e.Room.OwnerUserID == AuthUser.ID) {
+ qw422016.N().S(` <div><a href="/chat/`)
//line messages.qtpl:229
- if AuthUser.DisplayDeleteButton {
+ qw422016.E().S(e.Name)
//line messages.qtpl:229
- qw422016.N().S(` <form method="post" action="/api/v1/chat/messages/delete/`)
-//line messages.qtpl:230
- qw422016.E().S(e.UUID)
+ qw422016.N().S(`" target="_top"`)
+//line messages.qtpl:229
+ if e.IsUnread {
+//line messages.qtpl:229
+ qw422016.N().S(` class="unread_room"`)
+//line messages.qtpl:229
+ }
+//line messages.qtpl:229
+ qw422016.N().S(`>#`)
+//line messages.qtpl:229
+ qw422016.E().S(e.Name)
+//line messages.qtpl:229
+ qw422016.N().S(`</a></div>
+`)
//line messages.qtpl:230
- qw422016.N().S(`" class="d-inline">
- <input type="hidden" name="csrf" value="`)
-//line messages.qtpl:231
- qw422016.E().S(CSRF)
+ }
//line messages.qtpl:231
- qw422016.N().S(`" />
- <button class="mod-btn delete_msg_btn f-orange-clr" title="delete"></button>
- </form>
+ }
+//line messages.qtpl:232
+ if len(Data.SubscribedRooms) > 0 {
+//line messages.qtpl:232
+ qw422016.N().S(` <div class="mt-10px"></div>
`)
//line messages.qtpl:234
- }
+ for _, e := range Data.SubscribedRooms {
+//line messages.qtpl:234
+ qw422016.N().S(` <div><a href="/chat/`)
//line messages.qtpl:235
- } else if AuthUser.IsModerator() {
-//line messages.qtpl:236
- if AuthUser.DisplayDeleteButton {
-//line messages.qtpl:236
- qw422016.N().S(` <div class="spacer16"></div>
+ qw422016.E().S(e.Name)
+//line messages.qtpl:235
+ qw422016.N().S(`" target="_top"`)
+//line messages.qtpl:235
+ if e.IsUnread {
+//line messages.qtpl:235
+ qw422016.N().S(` class="unread_room"`)
+//line messages.qtpl:235
+ }
+//line messages.qtpl:235
+ qw422016.N().S(`>#`)
+//line messages.qtpl:235
+ qw422016.E().S(e.Name)
+//line messages.qtpl:235
+ qw422016.N().S(`</a></div>
`)
-//line messages.qtpl:238
- }
-//line messages.qtpl:239
- } else {
-//line messages.qtpl:240
- if AuthUser.DisplayDeleteButton {
-//line messages.qtpl:240
- qw422016.N().S(` <div class="spacer16"></div>
+//line messages.qtpl:236
+ }
+//line messages.qtpl:237
+ }
+//line messages.qtpl:237
+ 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:242
- }
+ for _, e := range Data.Members {
+//line messages.qtpl:242
+ qw422016.N().S(` `)
//line messages.qtpl:243
- }
+ StreamMember(qw422016, AuthUser, Data, e)
+//line messages.qtpl:243
+ qw422016.N().S(`
+`)
//line messages.qtpl:244
- if AuthUser.IsModerator() {
-//line messages.qtpl:245
- if e.UserID != AuthUser.ID {
+ }
+//line messages.qtpl:244
+ qw422016.N().S(` </div>
+`)
+//line messages.qtpl:246
+ if Data.VisibleMemberInChat || AuthUser.DisplayHellbanned {
//line messages.qtpl:246
- if AuthUser.DisplayHellbanButton {
-//line messages.qtpl:247
- if e.User.Username == NullUsername {
-//line messages.qtpl:247
- qw422016.N().S(` <div class="spacer16"></div>
+ qw422016.N().S(` <div class="mb-30px">
+`)
+//line messages.qtpl:248
+ if len(Data.MembersInChat) > 0 {
+//line messages.qtpl:248
+ qw422016.N().S(` <div class="rgt-title">In other rooms:</div>
`)
-//line messages.qtpl:249
- } else {
//line messages.qtpl:250
- if e.User.IsHellbanned {
+ for _, e := range Data.MembersInChat {
//line messages.qtpl:250
- qw422016.N().S(` <form method="post" action="/api/v1/users/`)
+ qw422016.N().S(` `)
//line messages.qtpl:251
- qw422016.E().S(e.UserID.String())
+ StreamMember(qw422016, AuthUser, Data, e)
//line messages.qtpl:251
- qw422016.N().S(`/unhellban" class="d-inline">
- <input type="hidden" name="csrf" value="`)
-//line messages.qtpl:252
- qw422016.E().S(CSRF)
+ qw422016.N().S(`
+`)
//line messages.qtpl:252
- qw422016.N().S(`" />
- <button class="mod-btn hb_btn f-orange-clr line-through" title="unhellban"></button>
- </form>
+ }
+//line messages.qtpl:253
+ }
+//line messages.qtpl:253
+ qw422016.N().S(` </div>
`)
//line messages.qtpl:255
- } else {
+ }
//line messages.qtpl:255
- qw422016.N().S(` <form method="post" action="/api/v1/users/`)
-//line messages.qtpl:256
- qw422016.E().S(e.UserID.String())
-//line messages.qtpl:256
- qw422016.N().S(`/hellban" class="d-inline">
- <input type="hidden" name="csrf" value="`)
-//line messages.qtpl:257
- qw422016.E().S(CSRF)
+ qw422016.N().S(` </div>
+`)
//line messages.qtpl:257
- qw422016.N().S(`" />
- <button class="mod-btn hb_btn f-orange-clr" title="hellban"></button>
- </form>
+ }
+//line messages.qtpl:258
+ if AuthUser.CollectMetadata {
+//line messages.qtpl:258
+ qw422016.N().S(` <div class="div_1"></div>
+ <div class="div_2"></div>
+ <div class="div_f0">a</div>
`)
-//line messages.qtpl:260
- }
-//line messages.qtpl:261
- }
//line messages.qtpl:262
- }
-//line messages.qtpl:263
- if AuthUser.DisplayKickButton {
-//line messages.qtpl:263
- qw422016.N().S(` <form method="post" action="/api/v1/users/`)
-//line messages.qtpl:264
- qw422016.E().S(e.UserID.String())
-//line messages.qtpl:264
- qw422016.N().S(`/kick" class="d-inline">
- <input type="hidden" name="csrf" value="`)
-//line messages.qtpl:265
- qw422016.E().S(CSRF)
-//line messages.qtpl:265
- qw422016.N().S(`" />
- <button class="mod-btn k_btn f-orange-clr" title="kick"></button>
- </form>
-`)
+ }
+//line messages.qtpl:262
+ qw422016.N().S(` </body>
+</html>
+`)
+//line messages.qtpl:265
+}
+
+//line messages.qtpl:265
+func WriteMessages(qq422016 qtio422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) {
+//line messages.qtpl:265
+ qw422016 := qt422016.AcquireWriter(qq422016)
+//line messages.qtpl:265
+ StreamMessages(qw422016, VERSION, CSRF, NullUsername, AuthUser, Data)
+//line messages.qtpl:265
+ qt422016.ReleaseWriter(qw422016)
+//line messages.qtpl:265
+}
+
+//line messages.qtpl:265
+func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data ChatMessagesData) string {
+//line messages.qtpl:265
+ qb422016 := qt422016.AcquireByteBuffer()
+//line messages.qtpl:265
+ WriteMessages(qb422016, VERSION, CSRF, NullUsername, AuthUser, Data)
+//line messages.qtpl:265
+ qs422016 := string(qb422016.B)
+//line messages.qtpl:265
+ qt422016.ReleaseByteBuffer(qb422016)
+//line messages.qtpl:265
+ return qs422016
+//line messages.qtpl:265
+}
+
//line messages.qtpl:268
- }
-//line messages.qtpl:269
- } else {
+func StreamRenderMessages(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) {
//line messages.qtpl:270
- if AuthUser.DisplayKickButton && AuthUser.DisplayHellbanButton {
-//line messages.qtpl:270
- qw422016.N().S(` <div class="spacer36"></div>
-`)
-//line messages.qtpl:272
- } else if AuthUser.DisplayKickButton || AuthUser.DisplayHellbanButton {
-//line messages.qtpl:272
- qw422016.N().S(` <div class="spacer16"></div>
-`)
+ baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName
+ readMarkerRendered := false
+ isFirstMsg := true
+
//line messages.qtpl:274
- }
+ for idx, e := range Data.Messages {
//line messages.qtpl:275
- }
+ StreamRenderMessage(qw422016, idx, e, AuthUser, Data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, CSRF, NullUsername)
+//line messages.qtpl:275
+ qw422016.N().S(` `)
//line messages.qtpl:276
- }
+ }
+//line messages.qtpl:276
+ qw422016.N().S(`
+ `)
//line messages.qtpl:277
- } else {
-//line messages.qtpl:278
- if Data.NbButtons == 3 {
-//line messages.qtpl:278
- qw422016.N().S(` <div class="spacer56"></div>
+ if len(Data.Messages) == 0 {
+//line messages.qtpl:277
+ qw422016.N().S(`
+ <div id="no-msg"><em>No message yet</em></div>
+ `)
+//line messages.qtpl:279
+ }
+//line messages.qtpl:279
+ qw422016.N().S(`
`)
//line messages.qtpl:280
- } else if Data.NbButtons == 2 {
+}
+
//line messages.qtpl:280
- qw422016.N().S(` <div class="spacer36"></div>
-`)
-//line messages.qtpl:282
- } else if Data.NbButtons == 1 {
+func WriteRenderMessages(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) {
+//line messages.qtpl:280
+ qw422016 := qt422016.AcquireWriter(qq422016)
+//line messages.qtpl:280
+ StreamRenderMessages(qw422016, AuthUser, Data, CSRF, NullUsername)
+//line messages.qtpl:280
+ qt422016.ReleaseWriter(qw422016)
+//line messages.qtpl:280
+}
+
+//line messages.qtpl:280
+func RenderMessages(AuthUser *database.User, Data ChatMessagesData, CSRF, NullUsername string) string {
+//line messages.qtpl:280
+ qb422016 := qt422016.AcquireByteBuffer()
+//line messages.qtpl:280
+ WriteRenderMessages(qb422016, AuthUser, Data, CSRF, NullUsername)
+//line messages.qtpl:280
+ qs422016 := string(qb422016.B)
+//line messages.qtpl:280
+ qt422016.ReleaseByteBuffer(qb422016)
+//line messages.qtpl:280
+ return qs422016
+//line messages.qtpl:280
+}
+
//line messages.qtpl:282
- qw422016.N().S(` <div class="spacer16"></div>
-`)
+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:284
- }
+ if e.UserCanSee(*AuthUser) {
+//line messages.qtpl:284
+ qw422016.N().S(` <div id="msgid-`)
//line messages.qtpl:285
- }
+ qw422016.E().S(e.UUID)
+//line messages.qtpl:285
+ qw422016.N().S(`" class="msg
+`)
//line messages.qtpl:286
- if Data.DateFormat != "" {
+ if (e.User.IsHellbanned || e.IsHellbanned) && AuthUser.DisplayHellbanned {
//line messages.qtpl:286
- qw422016.N().S(` <a href="`)
-//line messages.qtpl:287
- qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:287
- qw422016.N().S(`?quote=`)
-//line messages.qtpl:287
- qw422016.E().S(e.UUID)
-//line messages.qtpl:287
- streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:287
- qw422016.N().S(`" target="iframe1" class="date date-link" title="`)
-//line messages.qtpl:287
- qw422016.E().S(e.CreatedAt.Format("01-02 15:04:05"))
-//line messages.qtpl:287
- if isFirstMsg {
-//line messages.qtpl:287
- qw422016.N().S(` (`)
-//line messages.qtpl:287
- qw422016.E().S(humanize.Time(e.CreatedAt))
-//line messages.qtpl:287
- qw422016.N().S(`)`)
-//line messages.qtpl:287
- }
+ qw422016.N().S(` hb-row
+`)
//line messages.qtpl:287
- qw422016.N().S(`">`)
+ } else if AuthUser.ID == e.User.ID && AuthUser.HighlightOwnMessages {
//line messages.qtpl:287
- qw422016.E().S(e.CreatedAt.Format(Data.DateFormat))
+ qw422016.N().S(` own-highlight`)
//line messages.qtpl:287
- qw422016.N().S(`</a>
- `)
+ }
//line messages.qtpl:288
- isFirstMsg = false
-
+ if AuthUser.ChatReadMarkerEnabled && e.CreatedAt.Before(Data.ReadMarker.ReadAt) && !*readMarkerRendered {
//line messages.qtpl:288
- qw422016.N().S(`
+ qw422016.N().S(`
`)
//line messages.qtpl:289
- }
+ if idx > 0 {
//line messages.qtpl:289
- qw422016.N().S(` <a href="/u/`)
-//line messages.qtpl:290
- qw422016.E().S(e.GetProfile(AuthUser))
+ qw422016.N().S(`read-marker`)
+//line messages.qtpl:289
+ }
//line messages.qtpl:290
- qw422016.N().S(`" target="_blank" class="f-def-clr">-</a>
-`)
+ *readMarkerRendered = true
+
//line messages.qtpl:291
- if e.System {
+ }
//line messages.qtpl:291
- qw422016.N().S(` <span class="sysmsg">`)
-//line messages.qtpl:292
- streamunesc(qw422016, e.Message)
-//line messages.qtpl:292
- qw422016.N().S(`</span>
+ qw422016.N().S(` ">
`)
//line messages.qtpl:293
- } else {
-//line messages.qtpl:294
- if e.Moderators {
-//line messages.qtpl:294
- qw422016.N().S(`<span class="sysmsg">[<a href="`)
-//line messages.qtpl:294
- qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:294
- qw422016.N().S(`?m=1`)
-//line messages.qtpl:294
- streamunesc(qw422016, Data.TopBarQueryParams)
+ if e.UserCanDelete(*AuthUser) {
//line messages.qtpl:294
- qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">M</a>]</span> `)
-//line messages.qtpl:294
- }
-//line messages.qtpl:295
- if e.GroupID != nil {
-//line messages.qtpl:295
- qw422016.N().S(`<span class="sysmsg">[<a href="`)
-//line messages.qtpl:295
- qw422016.E().S(baseTopBarURL)
+ if !e.TooOldToDelete() {
//line messages.qtpl:295
- qw422016.N().S(`?g=`)
+ if AuthUser.DisplayDeleteButton {
//line messages.qtpl:295
- qw422016.E().S(e.Group.Name)
-//line messages.qtpl:295
- streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:295
- qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">`)
-//line messages.qtpl:295
- qw422016.E().S(e.Group.Name)
-//line messages.qtpl:295
- qw422016.N().S(`</a>]</span> `)
-//line messages.qtpl:295
- }
+ qw422016.N().S(` <form method="post" action="/api/v1/chat/messages/delete/`)
//line messages.qtpl:296
- if e.ToUserID != nil {
+ qw422016.E().S(e.UUID)
//line messages.qtpl:296
- qw422016.N().S(` [`)
+ qw422016.N().S(`" class="d-inline">
+ <input type="hidden" name="csrf" value="`)
//line messages.qtpl:297
- streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL)
+ qw422016.E().S(CSRF)
//line messages.qtpl:297
- qw422016.N().S(` →
-`)
-//line messages.qtpl:299
- if e.ToUser.ID == AuthUser.ID {
-//line messages.qtpl:299
- qw422016.N().S(`<span `)
-//line messages.qtpl:299
- streamunesc(qw422016, e.ToUser.GenerateChatStyle())
-//line messages.qtpl:299
- qw422016.N().S(`>`)
-//line messages.qtpl:299
- qw422016.E().S(e.ToUser.Username)
-//line messages.qtpl:299
- qw422016.N().S(`</span>`)
-//line messages.qtpl:299
- } else {
-//line messages.qtpl:299
- qw422016.N().S(`<a `)
-//line messages.qtpl:299
- streamunesc(qw422016, e.ToUser.GenerateChatStyle())
-//line messages.qtpl:299
- qw422016.N().S(` href="`)
-//line messages.qtpl:299
- qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:299
- qw422016.N().S(`?pm=`)
-//line messages.qtpl:299
- qw422016.E().S(e.ToUser.Username)
-//line messages.qtpl:299
- qw422016.E().S(Data.TopBarQueryParams)
-//line messages.qtpl:299
- qw422016.N().S(`" target="iframe1">`)
-//line messages.qtpl:299
- qw422016.E().S(e.ToUser.Username)
-//line messages.qtpl:299
- qw422016.N().S(`</a>`)
-//line messages.qtpl:299
- }
-//line messages.qtpl:299
- qw422016.N().S(`] -
+ qw422016.N().S(`" />
+ <button class="mod-btn delete_msg_btn" title="delete"></button>
+ </form>
`)
//line messages.qtpl:300
- } else {
+ }
//line messages.qtpl:301
- streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL)
+ } else if (AuthUser.IsModerator() && e.TooOldToDelete() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || (e.Room.OwnerUserID != nil && *e.Room.OwnerUserID == AuthUser.ID) {
+//line messages.qtpl:302
+ if AuthUser.DisplayDeleteButton {
//line messages.qtpl:302
- if !e.IsMe() {
+ qw422016.N().S(` <form method="post" action="/api/v1/chat/messages/delete/`)
//line messages.qtpl:303
- if AuthUser.CanSeeHB() && (e.IsHellbanned || e.User.IsHellbanned) && (e.ToUserID == nil) {
+ qw422016.E().S(e.UUID)
//line messages.qtpl:303
- qw422016.N().S(` <a href="`)
+ qw422016.N().S(`" class="d-inline">
+ <input type="hidden" name="csrf" value="`)
//line messages.qtpl:304
- qw422016.E().S(baseTopBarURL)
+ qw422016.E().S(CSRF)
//line messages.qtpl:304
- qw422016.N().S(`?hbm=1`)
-//line messages.qtpl:304
- streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:304
- qw422016.N().S(`" target="iframe1" class="f-def-clr">-</a>
-`)
-//line messages.qtpl:305
- } else {
-//line messages.qtpl:305
- qw422016.N().S(` -
+ qw422016.N().S(`" />
+ <button class="mod-btn delete_msg_btn f-orange-clr" title="delete"></button>
+ </form>
`)
//line messages.qtpl:307
- }
+ }
//line messages.qtpl:308
- }
+ } else if AuthUser.IsModerator() {
//line messages.qtpl:309
- }
+ if AuthUser.DisplayDeleteButton {
//line messages.qtpl:309
- qw422016.N().S(` <span `)
-//line messages.qtpl:310
- streamunesc(qw422016, e.User.GenerateChatStyle())
-//line messages.qtpl:310
- qw422016.N().S(`><span class="o-wrap">`)
-//line messages.qtpl:310
- qw422016.N().S(unesc(e.MsgToDisplay()))
-//line messages.qtpl:310
- qw422016.N().S(`</span></span>
+ qw422016.N().S(` <div class="spacer16"></div>
`)
//line messages.qtpl:311
- }
-//line messages.qtpl:311
- qw422016.N().S(` </div>
-`)
+ }
+//line messages.qtpl:312
+ } else {
//line messages.qtpl:313
- }
+ if AuthUser.DisplayDeleteButton {
//line messages.qtpl:313
- qw422016.N().S(` `)
-//line messages.qtpl:314
- }
-//line messages.qtpl:314
- qw422016.N().S(`
- `)
-//line messages.qtpl:315
- if len(Data.Messages) == 0 {
+ qw422016.N().S(` <div class="spacer16"></div>
+`)
//line messages.qtpl:315
- qw422016.N().S(`
- <div id="no-msg"><em>No message yet</em></div>
- `)
-//line messages.qtpl:317
- }
+ }
+//line messages.qtpl:316
+ }
//line messages.qtpl:317
- qw422016.N().S(`
- </div>
-
- `)
+ if AuthUser.IsModerator() {
+//line messages.qtpl:318
+ if e.UserID != AuthUser.ID {
+//line messages.qtpl:319
+ if AuthUser.DisplayHellbanButton {
//line messages.qtpl:320
- if !AuthUser.HideRightColumn {
+ if e.User.Username == NullUsername {
//line messages.qtpl:320
- 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:323
- if Data.InboxCount > 0 {
-//line messages.qtpl:323
- qw422016.N().S(`class="notif"`)
-//line messages.qtpl:323
- }
-//line messages.qtpl:323
- qw422016.N().S(`>`)
+ qw422016.N().S(` <div class="spacer16"></div>
+`)
+//line messages.qtpl:322
+ } else {
//line messages.qtpl:323
- qw422016.N().DL(Data.InboxCount)
+ if e.User.IsHellbanned {
//line messages.qtpl:323
- qw422016.N().S(`</a>)</div>
- </div>
- <div class="mb-20px">
- <div class="rgt-title">Rooms:</div>
+ qw422016.N().S(` <form method="post" action="/api/v1/users/`)
+//line messages.qtpl:324
+ qw422016.E().S(e.UserID.String())
+//line messages.qtpl:324
+ qw422016.N().S(`/unhellban" class="d-inline">
+ <input type="hidden" name="csrf" value="`)
+//line messages.qtpl:325
+ qw422016.E().S(CSRF)
+//line messages.qtpl:325
+ qw422016.N().S(`" />
+ <button class="mod-btn hb_btn f-orange-clr line-through" title="unhellban"></button>
+ </form>
`)
-//line messages.qtpl:327
- for _, e := range Data.OfficialRooms {
//line messages.qtpl:328
- if e.Name == "club" {
+ } else {
+//line messages.qtpl:328
+ qw422016.N().S(` <form method="post" action="/api/v1/users/`)
//line messages.qtpl:329
- if AuthUser.IsClubMember {
+ qw422016.E().S(e.UserID.String())
//line messages.qtpl:329
- qw422016.N().S(` <div><a href="/chat/club" target="_top"`)
-//line messages.qtpl:330
- if e.IsUnread {
+ qw422016.N().S(`/hellban" class="d-inline">
+ <input type="hidden" name="csrf" value="`)
//line messages.qtpl:330
- qw422016.N().S(` class="unread_room"`)
+ qw422016.E().S(CSRF)
//line messages.qtpl:330
- }
-//line messages.qtpl:330
- qw422016.N().S(`>#club</a></div>
+ qw422016.N().S(`" />
+ <button class="mod-btn hb_btn f-orange-clr" title="hellban"></button>
+ </form>
`)
-//line messages.qtpl:331
- }
-//line messages.qtpl:332
- } else if e.Name == "moderators" {
//line messages.qtpl:333
- if AuthUser.IsModerator() {
-//line messages.qtpl:333
- qw422016.N().S(` <div><a href="/chat/moderators" target="_top"`)
-//line messages.qtpl:334
- if e.IsUnread {
-//line messages.qtpl:334
- qw422016.N().S(` class="unread_room"`)
-//line messages.qtpl:334
- }
+ }
//line messages.qtpl:334
- qw422016.N().S(`>#moderators</a></div>
-`)
+ }
//line messages.qtpl:335
- }
+ }
//line messages.qtpl:336
- } else {
+ if AuthUser.DisplayKickButton {
//line messages.qtpl:336
- qw422016.N().S(` <div><a href="/chat/`)
-//line messages.qtpl:337
- qw422016.E().S(e.Name)
-//line messages.qtpl:337
- qw422016.N().S(`" target="_top"`)
-//line messages.qtpl:337
- if e.IsUnread {
-//line messages.qtpl:337
- qw422016.N().S(` class="unread_room"`)
-//line messages.qtpl:337
- }
+ qw422016.N().S(` <form method="post" action="/api/v1/users/`)
//line messages.qtpl:337
- qw422016.N().S(`>#`)
-//line messages.qtpl:337
- qw422016.E().S(e.Name)
+ qw422016.E().S(e.UserID.String())
//line messages.qtpl:337
- qw422016.N().S(`</a></div>
-`)
+ qw422016.N().S(`/kick" class="d-inline">
+ <input type="hidden" name="csrf" value="`)
//line messages.qtpl:338
- }
-//line messages.qtpl:339
- }
-//line messages.qtpl:340
- if len(Data.SubscribedRooms) > 0 {
-//line messages.qtpl:340
- qw422016.N().S(` <div class="mt-10px"></div>
+ qw422016.E().S(CSRF)
+//line messages.qtpl:338
+ qw422016.N().S(`" />
+ <button class="mod-btn k_btn f-orange-clr" title="kick"></button>
+ </form>
`)
+//line messages.qtpl:341
+ }
//line messages.qtpl:342
- for _, e := range Data.SubscribedRooms {
-//line messages.qtpl:342
- qw422016.N().S(` <div><a href="/chat/`)
-//line messages.qtpl:343
- qw422016.E().S(e.Name)
-//line messages.qtpl:343
- qw422016.N().S(`" target="_top"`)
-//line messages.qtpl:343
- if e.IsUnread {
-//line messages.qtpl:343
- qw422016.N().S(` class="unread_room"`)
-//line messages.qtpl:343
- }
-//line messages.qtpl:343
- qw422016.N().S(`>#`)
+ } else {
//line messages.qtpl:343
- qw422016.E().S(e.Name)
+ if AuthUser.DisplayKickButton && AuthUser.DisplayHellbanButton {
//line messages.qtpl:343
- qw422016.N().S(`</a></div>
+ qw422016.N().S(` <div class="spacer36"></div>
`)
-//line messages.qtpl:344
- }
//line messages.qtpl:345
- }
+ } else if AuthUser.DisplayKickButton || AuthUser.DisplayHellbanButton {
//line messages.qtpl:345
- 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>
+ qw422016.N().S(` <div class="spacer16"></div>
`)
+//line messages.qtpl:347
+ }
+//line messages.qtpl:348
+ }
+//line messages.qtpl:349
+ }
//line messages.qtpl:350
- for _, e := range Data.Members {
-//line messages.qtpl:350
- qw422016.N().S(` `)
+ } else {
//line messages.qtpl:351
- StreamMember(qw422016, AuthUser, Data, e)
+ if Data.NbButtons == 3 {
//line messages.qtpl:351
- qw422016.N().S(`
-`)
-//line messages.qtpl:352
- }
-//line messages.qtpl:352
- qw422016.N().S(` </div>
+ qw422016.N().S(` <div class="spacer56"></div>
`)
-//line messages.qtpl:354
- if Data.VisibleMemberInChat || AuthUser.DisplayHellbanned {
-//line messages.qtpl:354
- qw422016.N().S(` <div class="mb-30px">
+//line messages.qtpl:353
+ } else if Data.NbButtons == 2 {
+//line messages.qtpl:353
+ qw422016.N().S(` <div class="spacer36"></div>
`)
-//line messages.qtpl:356
- if len(Data.MembersInChat) > 0 {
-//line messages.qtpl:356
- qw422016.N().S(` <div class="rgt-title">In other rooms:</div>
+//line messages.qtpl:355
+ } else if Data.NbButtons == 1 {
+//line messages.qtpl:355
+ qw422016.N().S(` <div class="spacer16"></div>
`)
+//line messages.qtpl:357
+ }
//line messages.qtpl:358
- for _, e := range Data.MembersInChat {
-//line messages.qtpl:358
- qw422016.N().S(` `)
+ }
//line messages.qtpl:359
- StreamMember(qw422016, AuthUser, Data, e)
+ if AuthUser.GetDateFormat() != "" {
//line messages.qtpl:359
- qw422016.N().S(`
-`)
+ qw422016.N().S(` <a href="`)
+//line messages.qtpl:360
+ qw422016.E().S(baseTopBarURL)
+//line messages.qtpl:360
+ qw422016.N().S(`?quote=`)
+//line messages.qtpl:360
+ qw422016.E().S(e.UUID)
+//line messages.qtpl:360
+ streamunesc(qw422016, Data.TopBarQueryParams)
+//line messages.qtpl:360
+ qw422016.N().S(`" target="iframe1" class="date date-link" title="`)
+//line messages.qtpl:360
+ qw422016.E().S(e.CreatedAt.Format("01-02 15:04:05"))
+//line messages.qtpl:360
+ if *isFirstMsg {
+//line messages.qtpl:360
+ qw422016.N().S(` (`)
+//line messages.qtpl:360
+ qw422016.E().S(humanize.Time(e.CreatedAt))
+//line messages.qtpl:360
+ qw422016.N().S(`)`)
//line messages.qtpl:360
- }
-//line messages.qtpl:361
}
+//line messages.qtpl:360
+ qw422016.N().S(`">`)
+//line messages.qtpl:360
+ qw422016.E().S(e.CreatedAt.Format(AuthUser.GetDateFormat()))
+//line messages.qtpl:360
+ qw422016.N().S(`</a>
+ `)
//line messages.qtpl:361
- qw422016.N().S(` </div>
+ *isFirstMsg = false
+
+//line messages.qtpl:361
+ qw422016.N().S(`
`)
-//line messages.qtpl:363
+//line messages.qtpl:362
}
+//line messages.qtpl:362
+ qw422016.N().S(` <a href="/u/`)
//line messages.qtpl:363
- qw422016.N().S(` </div>
+ qw422016.E().S(e.GetProfile(AuthUser))
+//line messages.qtpl:363
+ qw422016.N().S(`" target="_blank" class="f-def-clr">-</a>
`)
+//line messages.qtpl:364
+ if e.System {
+//line messages.qtpl:364
+ qw422016.N().S(` <span class="sysmsg">`)
//line messages.qtpl:365
- }
-//line messages.qtpl:366
- if AuthUser.CollectMetadata {
-//line messages.qtpl:366
- qw422016.N().S(` <div class="div_1"></div>
- <div class="div_2"></div>
- <div class="div_f0">a</div>
+ streamunesc(qw422016, e.Message)
+//line messages.qtpl:365
+ qw422016.N().S(`</span>
`)
+//line messages.qtpl:366
+ } else {
+//line messages.qtpl:367
+ if e.Moderators {
+//line messages.qtpl:367
+ qw422016.N().S(`<span class="sysmsg">[<a href="`)
+//line messages.qtpl:367
+ qw422016.E().S(baseTopBarURL)
+//line messages.qtpl:367
+ qw422016.N().S(`?m=1`)
+//line messages.qtpl:367
+ streamunesc(qw422016, Data.TopBarQueryParams)
+//line messages.qtpl:367
+ qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">M</a>]</span> `)
+//line messages.qtpl:367
+ }
+//line messages.qtpl:368
+ if e.GroupID != nil {
+//line messages.qtpl:368
+ qw422016.N().S(`<span class="sysmsg">[<a href="`)
+//line messages.qtpl:368
+ qw422016.E().S(baseTopBarURL)
+//line messages.qtpl:368
+ qw422016.N().S(`?g=`)
+//line messages.qtpl:368
+ qw422016.E().S(e.Group.Name)
+//line messages.qtpl:368
+ streamunesc(qw422016, Data.TopBarQueryParams)
+//line messages.qtpl:368
+ qw422016.N().S(`" target="iframe1" class="sysmsg f-white-clr">`)
+//line messages.qtpl:368
+ qw422016.E().S(e.Group.Name)
+//line messages.qtpl:368
+ qw422016.N().S(`</a>]</span> `)
+//line messages.qtpl:368
+ }
+//line messages.qtpl:369
+ if e.ToUserID != nil {
+//line messages.qtpl:369
+ qw422016.N().S(` [`)
//line messages.qtpl:370
- }
+ streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL)
//line messages.qtpl:370
- qw422016.N().S(` </body>
-</html>
+ qw422016.N().S(` →
+`)
+//line messages.qtpl:372
+ if e.ToUser.ID == AuthUser.ID {
+//line messages.qtpl:372
+ qw422016.N().S(`<span `)
+//line messages.qtpl:372
+ streamunesc(qw422016, e.ToUser.GenerateChatStyle())
+//line messages.qtpl:372
+ qw422016.N().S(`>`)
+//line messages.qtpl:372
+ qw422016.E().S(e.ToUser.Username)
+//line messages.qtpl:372
+ qw422016.N().S(`</span>`)
+//line messages.qtpl:372
+ } else {
+//line messages.qtpl:372
+ qw422016.N().S(`<a `)
+//line messages.qtpl:372
+ streamunesc(qw422016, e.ToUser.GenerateChatStyle())
+//line messages.qtpl:372
+ qw422016.N().S(` href="`)
+//line messages.qtpl:372
+ qw422016.E().S(baseTopBarURL)
+//line messages.qtpl:372
+ qw422016.N().S(`?pm=`)
+//line messages.qtpl:372
+ qw422016.E().S(e.ToUser.Username)
+//line messages.qtpl:372
+ qw422016.E().S(Data.TopBarQueryParams)
+//line messages.qtpl:372
+ qw422016.N().S(`" target="iframe1">`)
+//line messages.qtpl:372
+ qw422016.E().S(e.ToUser.Username)
+//line messages.qtpl:372
+ qw422016.N().S(`</a>`)
+//line messages.qtpl:372
+ }
+//line messages.qtpl:372
+ qw422016.N().S(`] -
`)
//line messages.qtpl:373
+ } else {
+//line messages.qtpl:374
+ streamfromUsername(qw422016, AuthUser, Data, e, baseTopBarURL)
+//line messages.qtpl:375
+ if !e.IsMe() {
+//line messages.qtpl:376
+ if AuthUser.CanSeeHB() && (e.IsHellbanned || e.User.IsHellbanned) && (e.ToUserID == nil) {
+//line messages.qtpl:376
+ qw422016.N().S(` <a href="`)
+//line messages.qtpl:377
+ qw422016.E().S(baseTopBarURL)
+//line messages.qtpl:377
+ qw422016.N().S(`?hbm=1`)
+//line messages.qtpl:377
+ streamunesc(qw422016, Data.TopBarQueryParams)
+//line messages.qtpl:377
+ qw422016.N().S(`" target="iframe1" class="f-def-clr">-</a>
+`)
+//line messages.qtpl:378
+ } else {
+//line messages.qtpl:378
+ qw422016.N().S(` -
+`)
+//line messages.qtpl:380
+ }
+//line messages.qtpl:381
+ }
+//line messages.qtpl:382
+ }
+//line messages.qtpl:382
+ qw422016.N().S(` <span `)
+//line messages.qtpl:383
+ streamunesc(qw422016, e.User.GenerateChatStyle())
+//line messages.qtpl:383
+ qw422016.N().S(`><span class="o-wrap">`)
+//line messages.qtpl:383
+ qw422016.N().S(unesc(e.MsgToDisplay()))
+//line messages.qtpl:383
+ qw422016.N().S(`</span></span>
+`)
+//line messages.qtpl:384
+ }
+//line messages.qtpl:384
+ qw422016.N().S(` </div>
+`)
+//line messages.qtpl:386
+ }
+//line messages.qtpl:387
}
-//line messages.qtpl:373
-func WriteMessages(qq422016 qtio422016.Writer, VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) {
-//line messages.qtpl:373
+//line messages.qtpl:387
+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:387
qw422016 := qt422016.AcquireWriter(qq422016)
-//line messages.qtpl:373
- StreamMessages(qw422016, VERSION, CSRF, NullUsername, AuthUser, Data)
-//line messages.qtpl:373
+//line messages.qtpl:387
+ StreamRenderMessage(qw422016, idx, e, AuthUser, Data, baseTopBarURL, readMarkerRendered, isFirstMsg, CSRF, NullUsername)
+//line messages.qtpl:387
qt422016.ReleaseWriter(qw422016)
-//line messages.qtpl:373
+//line messages.qtpl:387
}
-//line messages.qtpl:373
-func Messages(VERSION, CSRF, NullUsername string, AuthUser *database.User, Data chatMessagesData) string {
-//line messages.qtpl:373
+//line messages.qtpl:387
+func RenderMessage(idx int, e database.ChatMessage, AuthUser *database.User,
+ Data ChatMessagesData, baseTopBarURL string, readMarkerRendered, isFirstMsg *bool, CSRF, NullUsername string) string {
+//line messages.qtpl:387
qb422016 := qt422016.AcquireByteBuffer()
-//line messages.qtpl:373
- WriteMessages(qb422016, VERSION, CSRF, NullUsername, AuthUser, Data)
-//line messages.qtpl:373
+//line messages.qtpl:387
+ WriteRenderMessage(qb422016, idx, e, AuthUser, Data, baseTopBarURL, readMarkerRendered, isFirstMsg, CSRF, NullUsername)
+//line messages.qtpl:387
qs422016 := string(qb422016.B)
-//line messages.qtpl:373
+//line messages.qtpl:387
qt422016.ReleaseByteBuffer(qb422016)
-//line messages.qtpl:373
+//line messages.qtpl:387
return qs422016
-//line messages.qtpl:373
+//line messages.qtpl:387
}
-//line messages.qtpl:377
-func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) {
-//line messages.qtpl:377
+//line messages.qtpl:390
+func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData, El managers.UserInfo) {
+//line messages.qtpl:390
qw422016.N().S(`
`)
-//line messages.qtpl:378
+//line messages.qtpl:391
baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName
-//line messages.qtpl:379
+//line messages.qtpl:392
if El.Username == AuthUser.Username {
-//line messages.qtpl:379
+//line messages.qtpl:392
qw422016.N().S(` <div>
<span style="color: `)
-//line messages.qtpl:381
+//line messages.qtpl:394
qw422016.E().S(El.Color)
-//line messages.qtpl:381
+//line messages.qtpl:394
qw422016.N().S(`;">`)
-//line messages.qtpl:381
+//line messages.qtpl:394
qw422016.E().S(El.Username)
-//line messages.qtpl:381
+//line messages.qtpl:394
qw422016.N().S(`</span>
`)
-//line messages.qtpl:382
+//line messages.qtpl:395
if El.AfkIndicatorEnabled {
-//line messages.qtpl:382
+//line messages.qtpl:395
qw422016.N().S(` <small class="afk-indicator">afk</small>
`)
-//line messages.qtpl:384
+//line messages.qtpl:397
}
-//line messages.qtpl:384
+//line messages.qtpl:397
qw422016.N().S(` </div>
`)
-//line messages.qtpl:386
+//line messages.qtpl:399
} else {
-//line messages.qtpl:387
+//line messages.qtpl:400
if !El.IsHellbanned || AuthUser.ID == El.UserID || (El.IsHellbanned && AuthUser.IsHellbanned) || AuthUser.DisplayHellbanned {
-//line messages.qtpl:387
+//line messages.qtpl:400
qw422016.N().S(` <div>
`)
-//line messages.qtpl:389
+//line messages.qtpl:402
tagType := "tag"
-//line messages.qtpl:390
+//line messages.qtpl:403
if AuthUser.CanSeeHB() && El.IsHellbanned {
-//line messages.qtpl:391
+//line messages.qtpl:404
tagType = "htag"
-//line messages.qtpl:392
+//line messages.qtpl:405
}
-//line messages.qtpl:393
+//line messages.qtpl:406
qw422016.N().S(`<a href="`)
-//line messages.qtpl:394
+//line messages.qtpl:407
qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:394
+//line messages.qtpl:407
qw422016.N().S(`?`)
-//line messages.qtpl:394
+//line messages.qtpl:407
qw422016.E().S(tagType)
-//line messages.qtpl:394
+//line messages.qtpl:407
qw422016.N().S(`=`)
-//line messages.qtpl:394
+//line messages.qtpl:407
qw422016.E().S(El.Username)
-//line messages.qtpl:394
+//line messages.qtpl:407
streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:394
+//line messages.qtpl:407
qw422016.N().S(`"target="iframe1"`)
-//line messages.qtpl:396
+//line messages.qtpl:409
if El.IsHellbanned && AuthUser.DisplayHellbanned {
-//line messages.qtpl:396
+//line messages.qtpl:409
qw422016.N().S(`class="hb-row"`)
-//line messages.qtpl:396
+//line messages.qtpl:409
}
-//line messages.qtpl:396
+//line messages.qtpl:409
qw422016.N().S(`style="color:`)
-//line messages.qtpl:397
+//line messages.qtpl:410
qw422016.E().S(El.Color)
-//line messages.qtpl:397
+//line messages.qtpl:410
qw422016.N().S(`;">`)
-//line messages.qtpl:397
+//line messages.qtpl:410
qw422016.E().S(string(El.Username[0]))
-//line messages.qtpl:397
+//line messages.qtpl:410
qw422016.N().S(`</a><a href="`)
-//line messages.qtpl:398
+//line messages.qtpl:411
qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:398
+//line messages.qtpl:411
qw422016.N().S(`?pm=`)
-//line messages.qtpl:398
+//line messages.qtpl:411
qw422016.E().S(El.Username)
-//line messages.qtpl:398
+//line messages.qtpl:411
streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:398
+//line messages.qtpl:411
qw422016.N().S(`"target="iframe1"`)
-//line messages.qtpl:400
+//line messages.qtpl:413
if El.IsHellbanned && AuthUser.DisplayHellbanned {
-//line messages.qtpl:400
+//line messages.qtpl:413
qw422016.N().S(`class="hb-row"`)
-//line messages.qtpl:400
+//line messages.qtpl:413
}
-//line messages.qtpl:400
+//line messages.qtpl:413
qw422016.N().S(`style="color:`)
-//line messages.qtpl:401
+//line messages.qtpl:414
qw422016.E().S(El.Color)
-//line messages.qtpl:401
+//line messages.qtpl:414
qw422016.N().S(`;">`)
-//line messages.qtpl:401
+//line messages.qtpl:414
qw422016.E().S(string(El.Username[1 : len(El.Username)-1]))
-//line messages.qtpl:401
+//line messages.qtpl:414
qw422016.N().S(`</a><a href="/u/`)
-//line messages.qtpl:402
+//line messages.qtpl:415
qw422016.E().S(El.Username)
-//line messages.qtpl:402
+//line messages.qtpl:415
qw422016.N().S(`"rel="noopener noreferrer" target="_blank"`)
-//line messages.qtpl:404
+//line messages.qtpl:417
if El.IsHellbanned && AuthUser.DisplayHellbanned {
-//line messages.qtpl:404
+//line messages.qtpl:417
qw422016.N().S(`class="hb-row"`)
-//line messages.qtpl:404
+//line messages.qtpl:417
}
-//line messages.qtpl:404
+//line messages.qtpl:417
qw422016.N().S(`style="color:`)
-//line messages.qtpl:405
+//line messages.qtpl:418
qw422016.E().S(El.Color)
-//line messages.qtpl:405
+//line messages.qtpl:418
qw422016.N().S(`;">`)
-//line messages.qtpl:405
+//line messages.qtpl:418
qw422016.E().S(string(El.Username[len(El.Username)-1]))
-//line messages.qtpl:405
+//line messages.qtpl:418
qw422016.N().S(`</a>`)
-//line messages.qtpl:407
+//line messages.qtpl:420
if El.AfkIndicatorEnabled {
-//line messages.qtpl:407
+//line messages.qtpl:420
qw422016.N().S(` <small class="afk-indicator">afk</small>
`)
-//line messages.qtpl:409
+//line messages.qtpl:422
}
-//line messages.qtpl:409
+//line messages.qtpl:422
qw422016.N().S(` </div>
`)
-//line messages.qtpl:411
+//line messages.qtpl:424
}
-//line messages.qtpl:412
+//line messages.qtpl:425
}
-//line messages.qtpl:413
+//line messages.qtpl:426
}
-//line messages.qtpl:413
-func WriteMember(qq422016 qtio422016.Writer, AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) {
-//line messages.qtpl:413
+//line messages.qtpl:426
+func WriteMember(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData, El managers.UserInfo) {
+//line messages.qtpl:426
qw422016 := qt422016.AcquireWriter(qq422016)
-//line messages.qtpl:413
+//line messages.qtpl:426
StreamMember(qw422016, AuthUser, Data, El)
-//line messages.qtpl:413
+//line messages.qtpl:426
qt422016.ReleaseWriter(qw422016)
-//line messages.qtpl:413
+//line messages.qtpl:426
}
-//line messages.qtpl:413
-func Member(AuthUser *database.User, Data chatMessagesData, El managers.UserInfo) string {
-//line messages.qtpl:413
+//line messages.qtpl:426
+func Member(AuthUser *database.User, Data ChatMessagesData, El managers.UserInfo) string {
+//line messages.qtpl:426
qb422016 := qt422016.AcquireByteBuffer()
-//line messages.qtpl:413
+//line messages.qtpl:426
WriteMember(qb422016, AuthUser, Data, El)
-//line messages.qtpl:413
+//line messages.qtpl:426
qs422016 := string(qb422016.B)
-//line messages.qtpl:413
+//line messages.qtpl:426
qt422016.ReleaseByteBuffer(qb422016)
-//line messages.qtpl:413
+//line messages.qtpl:426
return qs422016
-//line messages.qtpl:413
+//line messages.qtpl:426
}
-//line messages.qtpl:416
-func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) {
-//line messages.qtpl:417
+//line messages.qtpl:429
+func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) {
+//line messages.qtpl:430
tagType := "tag"
-//line messages.qtpl:418
+//line messages.qtpl:431
if El.ToUserID != nil {
-//line messages.qtpl:419
+//line messages.qtpl:432
tagType = "pm"
-//line messages.qtpl:420
+//line messages.qtpl:433
} else if AuthUser.CanSeeHB() && (El.IsHellbanned || El.User.IsHellbanned) {
-//line messages.qtpl:421
+//line messages.qtpl:434
tagType = "htag"
-//line messages.qtpl:422
+//line messages.qtpl:435
} else if AuthUser.IsModerator() && El.Moderators {
-//line messages.qtpl:423
+//line messages.qtpl:436
tagType = "mtag"
-//line messages.qtpl:424
+//line messages.qtpl:437
}
-//line messages.qtpl:425
+//line messages.qtpl:438
if El.User.ID == AuthUser.ID {
-//line messages.qtpl:426
+//line messages.qtpl:439
if El.CanBeEdited() {
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`<a `)
-//line messages.qtpl:426
+//line messages.qtpl:439
streamunesc(qw422016, El.User.GenerateChatStyle())
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(` href="`)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`?e=`)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.E().S(El.CreatedAt.Format("15:04:05"))
-//line messages.qtpl:426
+//line messages.qtpl:439
streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`" target="iframe1">`)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.E().S(El.User.Username)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`</a>`)
-//line messages.qtpl:426
+//line messages.qtpl:439
} else {
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`<span `)
-//line messages.qtpl:426
+//line messages.qtpl:439
streamunesc(qw422016, El.User.GenerateChatStyle())
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`>`)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.E().S(El.User.Username)
-//line messages.qtpl:426
+//line messages.qtpl:439
qw422016.N().S(`</span>`)
-//line messages.qtpl:426
+//line messages.qtpl:439
}
-//line messages.qtpl:427
+//line messages.qtpl:440
} else {
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.N().S(`<a `)
-//line messages.qtpl:427
+//line messages.qtpl:440
streamunesc(qw422016, El.User.GenerateChatStyle())
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.N().S(` href="`)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.E().S(baseTopBarURL)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.N().S(`?`)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.E().S(tagType)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.N().S(`=`)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.E().S(El.User.Username)
-//line messages.qtpl:427
+//line messages.qtpl:440
streamunesc(qw422016, Data.TopBarQueryParams)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.N().S(`" target="iframe1">`)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.E().S(El.User.Username)
-//line messages.qtpl:427
+//line messages.qtpl:440
qw422016.N().S(`</a>`)
-//line messages.qtpl:427
+//line messages.qtpl:440
}
-//line messages.qtpl:428
+//line messages.qtpl:441
}
-//line messages.qtpl:428
-func writefromUsername(qq422016 qtio422016.Writer, AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) {
-//line messages.qtpl:428
+//line messages.qtpl:441
+func writefromUsername(qq422016 qtio422016.Writer, AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) {
+//line messages.qtpl:441
qw422016 := qt422016.AcquireWriter(qq422016)
-//line messages.qtpl:428
+//line messages.qtpl:441
streamfromUsername(qw422016, AuthUser, Data, El, baseTopBarURL)
-//line messages.qtpl:428
+//line messages.qtpl:441
qt422016.ReleaseWriter(qw422016)
-//line messages.qtpl:428
+//line messages.qtpl:441
}
-//line messages.qtpl:428
-func fromUsername(AuthUser *database.User, Data chatMessagesData, El database.ChatMessage, baseTopBarURL string) string {
-//line messages.qtpl:428
+//line messages.qtpl:441
+func fromUsername(AuthUser *database.User, Data ChatMessagesData, El database.ChatMessage, baseTopBarURL string) string {
+//line messages.qtpl:441
qb422016 := qt422016.AcquireByteBuffer()
-//line messages.qtpl:428
+//line messages.qtpl:441
writefromUsername(qb422016, AuthUser, Data, El, baseTopBarURL)
-//line messages.qtpl:428
+//line messages.qtpl:441
qs422016 := string(qb422016.B)
-//line messages.qtpl:428
+//line messages.qtpl:441
qt422016.ReleaseByteBuffer(qb422016)
-//line messages.qtpl:428
+//line messages.qtpl:441
return qs422016
-//line messages.qtpl:428
+//line messages.qtpl:441
}
diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go
@@ -4874,3 +4874,122 @@ Loop:
}
return nil
}
+
+func ChatStreamHandler(c echo.Context) error {
+ db := c.Get("database").(*database.DkfDB)
+ authUser := c.Get("authUser").(*database.User)
+
+ roomName := c.Param("roomName")
+ room, err := db.GetChatRoomByName(roomName)
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+
+ quit := make(chan bool)
+ quit1 := make(chan bool)
+
+ // Listen to the closing of HTTP connection via CloseNotifier
+ notify := c.Request().Context().Done()
+ utils.SGo(func() {
+ select {
+ case <-notify:
+ case <-quit1:
+ }
+ close(quit)
+ })
+
+ notify1 := make(chan os.Signal)
+ signal.Notify(notify1, os.Interrupt)
+ utils.SGo(func() {
+ select {
+ case <-notify1:
+ case <-quit:
+ }
+ close(quit1)
+ })
+
+ c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
+ c.Response().WriteHeader(http.StatusOK)
+ c.Response().Header().Set("Transfer-Encoding", "chunked")
+ c.Response().Header().Set("Connection", "keep-alive")
+
+ chatQueryParams := ""
+ _, _ = c.Response().Write([]byte(fmt.Sprintf(`
+<style>
+#chat-top-bar {
+ border: 0;
+ height: 57px;
+ width: 800px;
+}
+.container-fluid {
+ width: 800px;
+}
+</style>
+<div class="container-fluid">
+ <iframe id="chat-top-bar" name="iframe1" src="/api/v1/chat/top-bar/` + room.Name + chatQueryParams + `" sandbox="allow-forms allow-scripts allow-same-origin allow-top-navigation-by-user-activation"></iframe>
+</div>
+`)))
+
+ _, _ = c.Response().Write([]byte(cssReset))
+ data := v1.ChatMessagesData{}
+ data.RoomName = room.Name
+ _, _ = c.Response().Write([]byte(v1.GenerateStyle(authUser, data)))
+ _, _ = c.Response().Write([]byte(fmt.Sprintf(`<div style="display:flex;flex-direction:column-reverse;">`)))
+ c.Response().Flush()
+
+ csrf, _ := c.Get("csrf").(string)
+ pmOnlyQuery := dutils.DoParsePmDisplayMode(c.QueryParam("pmonly"))
+ mentionsOnlyQuery := utils.DoParseBool(c.QueryParam("mentionsOnly"))
+ displayHellbanned := authUser.DisplayHellbanned || authUser.IsHellbanned
+ displayIgnoredMessages := false
+ msgs, _ := db.GetChatMessages(room.ID, authUser.Username, authUser.ID, pmOnlyQuery, mentionsOnlyQuery, displayHellbanned, authUser.DisplayIgnored, authUser.DisplayModerators, displayIgnoredMessages)
+ data.Messages = msgs
+ _, _ = c.Response().Write([]byte("<div>" + v1.RenderMessages(authUser, data, csrf, config.NullUsername) + "</div>"))
+ c.Response().Flush()
+
+ authorizedChannels := make([]string, 0)
+ authorizedChannels = append(authorizedChannels, "room_"+utils.FormatInt64(int64(room.ID)))
+ sub := database.MsgPubSub.Subscribe(authorizedChannels)
+ defer sub.Close()
+
+ i := 0
+Loop:
+ for {
+ select {
+ case <-quit:
+ break Loop
+ case <-quit1:
+ break Loop
+ default:
+ }
+
+ _, msg, err := sub.ReceiveTimeout(1 * time.Second)
+ if err != nil {
+ continue
+ }
+
+ i++
+
+ user, _ := db.GetUserByID(msg.UserID)
+ msg.User = user
+ if msg.ToUserID != nil {
+ toUser, _ := db.GetUserByID(*msg.ToUserID)
+ msg.ToUser = &toUser
+ if user.ID != authUser.ID && toUser.ID != authUser.ID {
+ continue
+ }
+ }
+ baseTopBarURL := ""
+ readMarkerRendered := true
+ isFirstMsg := false
+ s := v1.RenderMessage(1, *msg, authUser, data, baseTopBarURL, &readMarkerRendered, &isFirstMsg, csrf, config.NullUsername)
+ _, _ = c.Response().Write([]byte(fmt.Sprintf(`%s`, s)))
+ c.Response().Flush()
+
+ // Refresh the page to prevent having it growing infinitely bigger
+ if i == 5000 {
+ _, _ = c.Response().Write([]byte(fmt.Sprintf(`<meta http-equiv="refresh" content="0">`)))
+ }
+ }
+ return nil
+}
diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go
@@ -31,6 +31,7 @@ var GzipMiddleware = middleware.GzipWithConfig(
c.Path() == "/vip/downloads/:filename" ||
c.Path() == "/vip/challenges/re-1/:filename" ||
c.Path() == "/chess/:key" ||
+ c.Path() == "/chat/:roomName/stream" ||
c.Path() == "/uploads/:filename" ||
c.Path() == "/" {
return true
diff --git a/pkg/web/web.go b/pkg/web/web.go
@@ -211,6 +211,7 @@ func getMainServer(db *database.DkfDB, i18nBundle *i18n.Bundle, renderer *tmp.Te
authGroup.GET("/chat/help", handlers.ChatHelpHandler)
authGroup.GET("/chat/create-room", handlers.ChatCreateRoomHandler, middlewares.AuthRateLimitMiddleware(1*time.Second, 2))
authGroup.POST("/chat/create-room", handlers.ChatCreateRoomHandler, middlewares.AuthRateLimitMiddleware(1*time.Second, 2))
+ authGroup.GET("/chat/:roomName/stream", handlers.ChatStreamHandler)
authGroup.GET("/chat/:roomName/archive", handlers.ChatArchiveHandler)
authGroup.GET("/chat/:roomName/delete", handlers.ChatDeleteHandler)
authGroup.POST("/chat/:roomName/delete", handlers.ChatDeleteHandler)