chat.gohtml (12251B)
1 {{ define "nav-mb" }} mb-1{{ end }} 2 3 {{ define "extra-head" }} 4 <style> 5 {{ if .Data.RedRoom }} 6 html, body { 7 background-color: #3b0000 !important; 8 } 9 {{ else }} 10 html, body { 11 background-color: {{ .AuthUser.ChatBackgroundColor }} !important; 12 } 13 {{ end }} 14 #chat-top-bar { 15 border: 0; 16 height: {{ if .Data.Multiline }}157{{ else }}57{{ end }}px; 17 } 18 #chat-content { 19 border: 0; 20 border-left: 1px solid #aaa; 21 width: 100%; 22 height: calc(100vh - {{ if .Data.Multiline }}278{{ else }}178{{ end }}px); 23 } 24 #chat-controls { 25 border: 0; 26 width: 100%; 27 height: 30px; 28 position: absolute; 29 bottom: 0; 30 } 31 #chat-menu { 32 border: 0; 33 width: 150px; 34 height: calc(100vh - {{ if .Data.Multiline }}278{{ else }}178{{ end }}px); 35 position: fixed; 36 right: 15px; 37 overflow-y: auto; 38 line-height: 1.15; 39 } 40 .btn-xs { 41 margin: 0 !important; 42 padding: 0 4px !important; 43 font-size: 11px !important; 44 } 45 body { 46 {{ if .IsAprilFool2023 }} 47 background-image: url("/public/img/trees_donkey_kong.png"); 48 {{ else if eq .AuthUser.Theme 1 }} 49 background-image: url("/public/img/trees_christmas.png"); 50 {{ else if eq .AuthUser.Theme 2 }} 51 {{ else }} 52 background-image: url("/public/img/trees.gif"); 53 {{ end }} 54 background-repeat: no-repeat; 55 background-attachment: fixed; 56 background-position: right bottom; 57 background-size: auto calc(100vh - 100px); 58 } 59 {{ if .Data.DisplayTutorial }} 60 #tutorial_btn_next { 61 visibility: hidden; 62 animation: {{ .Data.TutoSecs }}s 1s forwards timer_countdown_frames2; 63 } 64 @keyframes timer_countdown_frames2 { 65 99% { visibility: hidden; } 66 100% { visibility: visible; } 67 } 68 #tutorial_secs:before { 69 content: "{{ .Data.TutoSecs }}"; 70 animation: {{ .Data.TutoSecs }}s 1s forwards timer_countdown_frames; 71 } 72 @keyframes timer_countdown_frames { 73 {{ range .Data.TutoFrames -}} 74 {{ . | css }} 75 {{ end -}} 76 } 77 .modal { 78 -moz-backdrop-filter: blur(2px); 79 -webkit-backdrop-filter: blur(2px); 80 backdrop-filter: blur(2px); 81 } 82 @-moz-document url-prefix() { 83 .modal { 84 background-color: rgba(0, 0, 0, .6); 85 } 86 } 87 {{ end }} 88 </style> 89 {{ end }} 90 91 {{ define "title" }}dkf - #{{ .Data.Room.Name }}{{ end }} 92 93 {{ define "content" }} 94 95 {{ if .Data.DisplayTutorial }} 96 {{ if eq .AuthUser.ChatTutorial 0 }} 97 <div class="modal d-block"> 98 <div class="modal-dialog modal-dialog-centered"> 99 <div class="modal-content"> 100 <div class="modal-header"> 101 <h5 class="modal-title">Tutorial (1/3)</h5> 102 </div> 103 <div class="modal-body"> 104 Rules of this chat: 105 <ul> 106 <li>No cp (child abuse content)</li> 107 <li>Be civil</li> 108 </ul> 109 </div> 110 <div class="modal-footer"> 111 <span>Wait for <span id="tutorial_secs"></span> seconds</span> 112 <form method="post"> 113 <input type="hidden" name="formName" value="tutorialP1"> 114 <input type="hidden" name="csrf" value="{{ .CSRF }}"> 115 <button type="submit" class="btn btn-primary" id="tutorial_btn_next">I agree</button> 116 </form> 117 </div> 118 </div> 119 </div> 120 </div> 121 {{ else if eq .AuthUser.ChatTutorial 1 }} 122 <div class="modal d-block"> 123 <div class="modal-dialog modal-dialog-centered"> 124 <div class="modal-content"> 125 <div class="modal-header"> 126 <h5 class="modal-title">Tutorial (2/3)</h5> 127 </div> 128 <div class="modal-body"> 129 If you are looking for <a href="/links" rel="noopener noreferrer" target="_blank">Links</a>,<br /> 130 look at the "<a href="/links" rel="noopener noreferrer" target="_blank">Links</a>" section in the header. 131 </div> 132 <div class="modal-footer"> 133 <span>Wait for <span id="tutorial_secs"></span> seconds</span> 134 <form method="post"> 135 <input type="hidden" name="formName" value="tutorialP2"> 136 <input type="hidden" name="csrf" value="{{ .CSRF }}"> 137 <button type="submit" class="btn btn-primary" id="tutorial_btn_next">I understand</button> 138 </form> 139 </div> 140 </div> 141 </div> 142 </div> 143 {{ else if eq .AuthUser.ChatTutorial 2 }} 144 <div class="modal d-block"> 145 <div class="modal-dialog modal-dialog-centered"> 146 <div class="modal-content"> 147 <div class="modal-header"> 148 <h5 class="modal-title">Tutorial (3/3)</h5> 149 </div> 150 <div class="modal-body"> 151 Trolls will be kicked on sight<br /> 152 Enjoy your stay 153 </div> 154 <div class="modal-footer"> 155 <span>Wait for <span id="tutorial_secs"></span> seconds</span> 156 <form method="post"> 157 <input type="hidden" name="formName" value="tutorialP3"> 158 <input type="hidden" name="csrf" value="{{ .CSRF }}"> 159 <button type="submit" class="btn btn-primary" id="tutorial_btn_next">Complete</button> 160 </form> 161 </div> 162 </div> 163 </div> 164 </div> 165 {{ end }} 166 {{ end }} 167 168 <div style="{{ if not .AuthUser.HideRightColumn }}margin: 0 0 0 15px;{{ else }}margin: 0 15px;{{ end }}"> 169 <div> 170 {{ if .AuthUser.ChatBarAtBottom }} 171 <div> 172 <iframe id="chat-content" name="iframe2" src="/api/v1/chat/messages/{{ .Data.Room.Name }}{{ if .Data.IsStream }}/stream{{ end }}{{ .Data.ChatQueryParams }}"></iframe> 173 {{ if .Data.IsStream }}<iframe id="chat-menu" src="/api/v1/chat/messages/{{ .Data.Room.Name }}/stream/menu{{ .Data.ChatQueryParams }}"></iframe>{{ end }} 174 </div> 175 {{ end }} 176 <div> 177 <span> 178 > {{ t "Room" . }} 179 {{ if .Data.Room.ExternalLink }} 180 <a href="{{ .Data.Room.ExternalLink }}" rel="noopener noreferrer" target="_blank">#{{ .Data.Room.Name }}</a> 181 {{ else }} 182 #{{ .Data.Room.Name }} 183 {{ end }} 184 </span> 185 <div style="padding-left: 30px;" class="d-inline"> 186 <!-- {{ if and .Data.Room.OwnerUserID (eq (derefUserID .Data.Room.OwnerUserID) .AuthUser.ID) }}--> 187 <!-- <a href="/chat/{{ .Data.Room.Name }}/settings" class="btn btn-xs btn-secondary">{{ t "Room settings" . }}</a>--> 188 <!-- {{ end }}--> 189 {{ if .Data.Room.Password }} 190 <form method="post" style="display: inline-block"> 191 <input type="hidden" name="csrf" value="{{ .CSRF }}" /> 192 <input type="hidden" name="formName" value="logout" /> 193 <button type="submit" class="btn btn-xs btn-secondary">{{ t "Logout" . }}</button> 194 </form> 195 {{ end }} 196 {{ if not .Data.IsOfficialRoom }} 197 {{ if .Data.IsSubscribed }} 198 <form method="post" style="display: inline-block" action="/api/v1/rooms/{{ .Data.Room.Name }}/unsubscribe"> 199 <input type="hidden" name="csrf" value="{{ .CSRF }}" /> 200 <button type="submit" class="btn btn-xs btn-secondary">{{ t "Unsubscribe" . }}</button> 201 </form> 202 {{ else }} 203 <form method="post" style="display: inline-block" action="/api/v1/rooms/{{ .Data.Room.Name }}/subscribe"> 204 <input type="hidden" name="csrf" value="{{ .CSRF }}" /> 205 <button type="submit" class="btn btn-xs btn-secondary">{{ t "Subscribe" . }}</button> 206 </form> 207 {{ end }} 208 {{ end }} 209 {{ if and .Data.Room.OwnerUserID (eq (derefUserID .Data.Room.OwnerUserID) .AuthUser.ID) }} 210 <a href="/chat/{{ .Data.Room.Name }}/delete" class="btn btn-xs btn-danger">{{ t "Delete room" . }}</a> 211 {{ end }} 212 </div> 213 </div> 214 <div> 215 {{/* 216 allow-forms: Needed to send messages using the chat input box 217 allow-scripts: Needed for "autofocus" to work `Blocked autofocusing on a <input> element because the element's frame is sandboxed and the 'allow-scripts' permission is not set.` 218 allow-same-origin: Needed so that the iframe can access the cookies such as CSRF 219 allow-top-navigation-by-user-activation: Needed for links such as "Settings" to navigate the top-level page using "_top" 220 221 How does iframe behave in HTML5 without the sandbox attribute? 222 https://stackoverflow.com/questions/13703760/how-does-iframe-behave-in-html5-without-the-sandbox-attribute 223 */}} 224 <iframe id="chat-top-bar" name="iframe1" src="/api/v1/chat/top-bar/{{ .Data.Room.Name }}{{ .Data.ChatQueryParams }}" sandbox="allow-forms allow-scripts allow-same-origin allow-top-navigation-by-user-activation" style="width: 100%;"></iframe> 225 </div> 226 {{ if not .AuthUser.ChatBarAtBottom }} 227 <div> 228 {{/* 229 This iframe cannot be sandboxed, as it would prevent having "form" or "link" with a `target="..."` property. 230 Such form/link would open a new tab instead of sending data from/to the other iframe. 231 */}} 232 {{/* 233 allow-scripts: Needed for html meta refresh `Refused to execute the redirect specified via '<meta http-equiv='refresh' content='...'>'. The document is sandboxed, and the 'allow-scripts' keyword is not set.` 234 allow-forms: Needed for forms within the chat such as battleship 235 allow-same-origin: Needed so that the iframe can access the cookies such as CSRF 236 allow-popups: Needed to open external links in new tab 237 allow-popups-to-escape-sandbox: Allows external websites to not be restricted by the sandbox 238 allow-top-navigation-by-user-activation: Needed for links such as "#suggestions" to navigate the top-level page using "_top" 239 sandbox=" 240 allow-forms 241 allow-scripts 242 allow-same-origin 243 allow-top-navigation-by-user-activation 244 allow-popups 245 allow-popups-to-escape-sandbox" 246 */}} 247 <iframe id="chat-content" name="iframe2" src="/api/v1/chat/messages/{{ .Data.Room.Name }}{{ if .Data.IsStream }}/stream{{ end }}{{ .Data.ChatQueryParams }}"></iframe> 248 {{ if and .Data.IsStream (not .AuthUser.HideRightColumn) }}<iframe id="chat-menu" src="/api/v1/chat/messages/{{ .Data.Room.Name }}/stream/menu{{ .Data.ChatQueryParams }}"></iframe>{{ end }} 249 </div> 250 {{ end }} 251 </div> 252 </div> 253 254 <iframe id="chat-controls" name="iframe3" src="/api/v1/chat/controls/{{ .Data.Room.Name }}/{{ .Data.IsStream }}{{ .Data.ChatQueryParams }}"></iframe> 255 256 {{ end }}