dkforest

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

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                 &gt; {{ 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 }}