]> code.octet-stream.net Git - broadcaster/commitdiff
More UI improvements v1.0.0
authorThomas Karpiniec <tom.karpiniec@outlook.com>
Wed, 30 Oct 2024 09:31:38 +0000 (20:31 +1100)
committerThomas Karpiniec <tom.karpiniec@outlook.com>
Wed, 30 Oct 2024 09:31:38 +0000 (20:31 +1100)
server/main.go
server/templates/files.html
server/templates/header.html
server/templates/playlist.html
server/templates/playlists.html
server/templates/radios.html
server/templates/radios.partial.html
server/templates/users.html

index 9f6927e9e63850ef8550e02e6b5fb29082c5dec6..d1d47d329afe6029632e073b35d5f1af0fcc800d 100644 (file)
@@ -77,7 +77,7 @@ func main() {
        // Public routes
 
        http.HandleFunc("/login", logInPage)
-       http.Handle("/file-downloads/", http.StripPrefix("/file-downloads/", http.FileServer(http.Dir(config.AudioFilesPath))))
+       http.Handle("/file-downloads/", applyDisposition(http.StripPrefix("/file-downloads/", http.FileServer(http.Dir(config.AudioFilesPath)))))
 
        // Authenticated routes
 
@@ -106,6 +106,24 @@ func main() {
        }
 }
 
+type DispositionMiddleware struct {
+       handler http.Handler
+}
+
+func (m DispositionMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+       log.Println("path", r.URL.Path)
+       if r.URL.Path != "/file-downloads/" {
+               w.Header().Add("Content-Disposition", "attachment")
+       }
+       m.handler.ServeHTTP(w, r)
+}
+
+func applyDisposition(handler http.Handler) DispositionMiddleware {
+       return DispositionMiddleware{
+               handler: handler,
+       }
+}
+
 type authenticatedHandler func(http.ResponseWriter, *http.Request, User)
 
 type AuthMiddleware struct {
@@ -139,6 +157,7 @@ func requireAdmin(handler authenticatedHandler) AuthMiddleware {
 type HeaderData struct {
        SelectedMenu string
        User         User
+       Version      string
 }
 
 func renderHeader(w http.ResponseWriter, selectedMenu string, user User) {
@@ -146,6 +165,7 @@ func renderHeader(w http.ResponseWriter, selectedMenu string, user User) {
        data := HeaderData{
                SelectedMenu: selectedMenu,
                User:         user,
+               Version:      version,
        }
        err := tmpl.Execute(w, data)
        if err != nil {
@@ -456,6 +476,9 @@ func playlistsPage(w http.ResponseWriter, _ *http.Request, user User) {
        data := PlaylistsPageData{
                Playlists: db.GetPlaylists(),
        }
+       for i := range data.Playlists {
+               data.Playlists[i].StartTime = strings.Replace(data.Playlists[i].StartTime, "T", " ", -1)
+       }
        tmpl := template.Must(template.ParseFS(content, "templates/playlists.html"))
        err := tmpl.Execute(w, data)
        if err != nil {
@@ -506,7 +529,7 @@ func editPlaylistPage(w http.ResponseWriter, r *http.Request, id int, user User)
                data.Playlist = playlist
                data.Entries = db.GetEntriesForPlaylist(id)
        }
-       renderHeader(w, "radios", user)
+       renderHeader(w, "playlists", user)
        tmpl := template.Must(template.ParseFS(content, "templates/playlist.html"))
        tmpl.Execute(w, data)
        renderFooter(w)
index e2054720fc7fee44b98bf653d3938e067af7fa9e..a07ce2cf8a5221cb6af57d173a2b707871b97d1f 100644 (file)
@@ -1,10 +1,11 @@
 
       <h1>Audio File Management</h1>
       <p>All files can be downloaded from the <a href="/file-downloads/">public file listing</a>.</p>
-      <table>
+      <table class="listing" border="1">
+      <tr><th>Name</th><th></th></tr>
       {{range .Files}}
-        <tr>
-        <td><b>{{.Name}}</b></td>
+      <tr>
+        <td>{{.Name}}</td>
         <td><form action="/files/delete" method="POST"><input type="hidden" name="filename" value="{{.Name}}"><input type="submit" value="Delete"></form></td>
         </tr>
       {{end}}
index 3d4af191f656149eadeee99a50e62f8baf1ca93c..64b3b4eddc83af3d2b7b3c0f75d00c170d5dbb3d 100644 (file)
@@ -8,13 +8,39 @@
       table.radio-status, td.outer {
         border: 1px solid;
       }
+      table.listing td, table.listing th {
+        padding: 0.35em;
+      }
+      td.enabled {
+        text-align: center;
+      }
+      td.token {
+        font-family: monospace;
+        font-size: 80%;
+      }
       table.inner {
         border-collapse: collapse;
       }
-      td.clear {
+      td.channel-state {
         text-align: center;
+        width: 5em;
+        height: 5em;
+      }
+      td.clear {
         background-color: #eeeeee;
       }
+      td.cos {
+        background-color: #aaeeaa;
+      }
+      td.ptt {
+        background-color: #eeaaaa;
+      }
+      th {
+        text-align: left;
+      }
+      input.seconds {
+        width: 3em;
+      }
       .time-table {
         font-size: 90%;
       }
             {{if .User.Username}}
             <div class="logged-in">Logged in as:<br><i>{{.User.Username}}</i></div>
             {{end}}
-            <div class="menu-tail"><small><i>broadcaster-server vTODO</i></small></div>
+            <div class="menu-tail"><small><i>broadcaster-server {{.Version}}</i></small></div>
         </div>
     {{end}}
     <div class="content">
index d778250ac609e5ba1e1b8147c34ca79ad4c5520f..4493c60b0c9fe6521bdf3db00e2eefc2dfca5b93 100644 (file)
         {{range .Entries}}
         <p>
         Wait until
-        <input type="text" name="delaySeconds" value="{{.DelaySeconds}}">
-        seconds from
+        <input type="text" name="delaySeconds" value="{{.DelaySeconds}}" class="seconds">
+        seconds
         <select name="isRelative">
-          <option value="1">previous item</option>
-          <option value="0" {{if not .IsRelative}} selected="selected" {{end}}>start of transmission</option>
+          <option value="1">from previous</option>
+          <option value="0" {{if not .IsRelative}} selected="selected" {{end}}>from start</option>
         </select>
         then play
         <select name="filename">{{$f := .Filename}}
@@ -52,7 +52,7 @@
           <option value="{{.}}" {{if eq . $f }} selected="selected" {{end}}>{{.}}</option>
           {{end}}
         </select>
-        <a href="#" onclick="deleteItem(this)">(Delete Item)</a>
+        <a href="#" onclick="deleteItem(this)">(Delete)</a>
         </p>
         {{end}}
         <p>
       {{end}}
       <template id="item-template">
         Wait until
-        <input type="text" name="delaySeconds" value="0">
-        seconds from
+        <input type="text" name="delaySeconds" value="0" class="seconds">
+        seconds
         <select name="isRelative">
-          <option value="1">previous item</option>
-          <option value="0">start of transmission</option>
+          <option value="1">from previous</option>
+          <option value="0">from start</option>
         </select>
         then play
         <select name="filename">
@@ -86,5 +86,5 @@
           <option value="{{.}}">{{.}}</option>
           {{end}}
         </select>
-        <a href="#" onclick="deleteItem(this)">(Delete Item)</a>
+        <a href="#" onclick="deleteItem(this)">(Delete)</a>
       </template>
index e6b6a5a37c560a6037a1938df888eb5423483fc8..ceb1ad73aeb971d2b550e9a457a8771a226002d2 100644 (file)
@@ -1,9 +1,9 @@
 
       <h1>Playlist Management</h1>
-      <table>
-      <tr><th>Name</th><th>Enabled?</th><th>Start Time</th><th></th></tr>
+      <table class="listing" border="1">
+      <tr><th>Name</th><th>Start Time</th><th>Enabled?</th><th></th></tr>
       {{range .Playlists}}
-      <tr><td>{{.Name}}</td><td>{{if .Enabled}}✅{{else}}❌{{end}}</td><td>{{.StartTime}}</td><td><a href="/playlists/{{.Id}}">(Edit)</a></td></tr>
+      <tr><td>{{.Name}}</td><td>{{.StartTime}}</td><td class="enabled">{{if .Enabled}}✅{{else}}❌{{end}}</td><td><a href="/playlists/{{.Id}}">(Edit)</a></td></tr>
       {{end}}
       </table>
       <p><a href="/playlists/new">Add New Playlist</a></p>
index 0c1288fe99c26f00802c1d2130bddee3b388777f..a840c0040173f26ff35bd49ff792c3ca5a4543c1 100644 (file)
@@ -1,8 +1,9 @@
 
       <h1>Radios</h1>
-      <ul>
+      <table class="listing" border="1">
+      <tr><th>Name</th><th>Token</th><th></th></tr>
       {{range .Radios}}
-        <li><b>{{.Name}}</b> {{.Token}} <a href="/radios/{{.Id}}">(Edit)</a></li>
+      <tr><td>{{.Name}}</td><td class="token">{{.Token}}</td><td><a href="/radios/{{.Id}}">(Edit)</a></td></tr>
       {{end}}
-      </ul>
+      </table>
       <p><a href="/radios/new">Register New Radio</a></p>
index 010fe0a5f293c18fcbbcad363d30162e58b3cae0..77afca6f87f25abff40d432f1fdff0356ec5a0b7 100644 (file)
@@ -37,7 +37,7 @@
     </td>
 </tr>
 <tr>
-    <td class="outer {{.ChannelClass}}">
+    <td class="outer {{.ChannelClass}} channel-state">
     {{.ChannelState}}
     </td>
     <td class="outer" colspan="2">
index b95b3547626c32327209483600b7039f6f12a6e7..d8d0508d5205a625de5f87cf3fbf225d069b0e2c 100644 (file)
@@ -1,8 +1,9 @@
 
       <h1>User Management</h1>
-      <ul>
+      <table class="listing" border="1">
+      <tr><th>Username</th><th>Is Admin?</th><th></th></tr>
       {{range .Users}}
-        <li><b>{{.Username}}</b> <a href="/users/{{.Id}}">(Edit)</a></li>
+      <tr><td>{{.Username}}</td><td class="enabled">{{if .IsAdmin}}✅{{else}}❌{{end}}</td><td><a href="/users/{{.Id}}">(Edit)</a></td></tr>
       {{end}}
-      </ul>
+      </table>
       <p><a href="/users/new">Add New User</a></p>