Show current user in top bar

This commit is contained in:
DonVoo 2026-07-13 02:04:50 +02:00
parent 8e9fb55710
commit 0bb49019b6
4 changed files with 56 additions and 41 deletions

View file

@ -59,8 +59,8 @@ func renderStartPage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<script src="/static/app.js?v=20260712-20" defer></script></head>
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -94,21 +94,22 @@ func renderStartPage(w http.ResponseWriter, r *http.Request) {
</section>
</main>
<footer class="statusbar"><span>bereit</span></footer>
</body></html>`, renderRibbonEmailBoxMenu("home"), renderRibbonTransferMenu(""), renderRibbonActions(false), html.EscapeString(userDisplayLabel(user)))
</body></html>`, renderRibbonEmailBoxMenu("home"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), html.EscapeString(userDisplayLabel(user)))
}
// renderShell ist das Grundgeruest im Outlook-2013-Look:
//
// [ Ribbon: Email-Box | Mail-Transfer | Einstellungen | Mail-Graveyard ]
// [ Archiv-mbox | Nachrichtenliste | Quelle/Target ]
func renderShell(w http.ResponseWriter, active, readingPane string) {
func renderShell(w http.ResponseWriter, r *http.Request, active, readingPane string) {
user := CurrentUser(r)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -147,7 +148,7 @@ func renderShell(w http.ResponseWriter, active, readingPane string) {
</div>
<footer class="statusbar"><span id="mig-status"
hx-get="/migrate/status" hx-trigger="every 3s" hx-swap="innerHTML">bereit</span></footer>
</body></html>`, renderRibbonEmailBoxMenu("archive"), renderRibbonTransferMenu(""), renderRibbonActions(false), renderInitialReadPane(readingPane))
</body></html>`, renderRibbonEmailBoxMenu("archive"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), renderInitialReadPane(readingPane))
}
func accountsHandler(w http.ResponseWriter, r *http.Request) {
@ -168,7 +169,7 @@ func accountsHandler(w http.ResponseWriter, r *http.Request) {
return
}
}
renderAccountsPage(w, accounts, edit, r.URL.Query().Get("msg"), r.URL.Query().Get("err"))
renderAccountsPage(w, r, accounts, edit, r.URL.Query().Get("msg"), r.URL.Query().Get("err"))
}
func accountSaveHandler(w http.ResponseWriter, r *http.Request) {
@ -252,7 +253,7 @@ func archivesHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
renderArchivesPage(w, archiveMailboxes(accounts), accounts, r.URL.Query().Get("msg"), r.URL.Query().Get("err"))
renderArchivesPage(w, r, archiveMailboxes(accounts), accounts, r.URL.Query().Get("msg"), r.URL.Query().Get("err"))
}
func transferHandler(w http.ResponseWriter, r *http.Request) {
@ -269,7 +270,7 @@ func transferHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
renderTransferPage(w, transferModeBySlug(mode), accounts, archiveMailboxes(accounts))
renderTransferPage(w, r, transferModeBySlug(mode), accounts, archiveMailboxes(accounts))
}
func emailBoxHandler(w http.ResponseWriter, r *http.Request) {
@ -281,9 +282,9 @@ func emailBoxHandler(w http.ResponseWriter, r *http.Request) {
kind := strings.TrimPrefix(r.URL.Path, "/boxes/")
switch kind {
case "source":
renderSourceEmailBoxPage(w, accounts)
renderSourceEmailBoxPage(w, r, accounts)
case "target":
renderTargetEmailBoxPage(w, accounts)
renderTargetEmailBoxPage(w, r, accounts)
default:
http.Redirect(w, r, "/view", http.StatusSeeOther)
}
@ -541,7 +542,8 @@ func userToggleActiveHandler(w http.ResponseWriter, r *http.Request) {
redirectUsers(w, r, username, "Benutzer aktiviert.")
}
func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account, msg, errMsg string) {
func renderAccountsPage(w http.ResponseWriter, r *http.Request, accounts []Account, edit Account, msg, errMsg string) {
user := CurrentUser(r)
if edit.Name == "" {
edit = Account{SrcPort: 993, SrcSecurity: "tls", SrcProto: "imap", DstPort: 993, DstSecurity: "tls", Active: true}
}
@ -550,9 +552,9 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Konten-Verwaltung - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -575,7 +577,7 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
<a class="backstage-item" href="/logout">Logout</a>
</aside>
<button class="backstage-shade" type="button" aria-label="Menue schliessen" data-backstage-close></button>
<main class="accounts-page">`, renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(""), renderRibbonActions(false))
<main class="accounts-page">`, renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(""), renderRibbonActions(false, user))
if msg != "" {
fmt.Fprintf(w, `<div class="notice ok">%s</div>`, html.EscapeString(msg))
}
@ -589,14 +591,15 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
fmt.Fprint(w, `</div></section></main><footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`)
}
func renderArchivesPage(w http.ResponseWriter, archives []string, accounts []Account, msg, errMsg string) {
func renderArchivesPage(w http.ResponseWriter, r *http.Request, archives []string, accounts []Account, msg, errMsg string) {
user := CurrentUser(r)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Archiv-mbox Verwaltung - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -619,7 +622,7 @@ func renderArchivesPage(w http.ResponseWriter, archives []string, accounts []Acc
<a class="backstage-item" href="/logout">Logout</a>
</aside>
<button class="backstage-shade" type="button" aria-label="Menue schliessen" data-backstage-close></button>
<main class="accounts-page archive-page">`, renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(""), renderRibbonActions(false))
<main class="accounts-page archive-page">`, renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(""), renderRibbonActions(false, user))
if msg != "" {
fmt.Fprintf(w, `<div class="notice ok">%s</div>`, html.EscapeString(msg))
}
@ -641,9 +644,9 @@ func renderUsersPage(w http.ResponseWriter, r *http.Request, users []AppUser, ed
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Benutzerverwaltung - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -666,7 +669,7 @@ func renderUsersPage(w http.ResponseWriter, r *http.Request, users []AppUser, ed
<a class="backstage-item" href="/logout">Logout</a>
</aside>
<button class="backstage-shade" type="button" aria-label="Menue schliessen" data-backstage-close></button>
<main class="accounts-page users-page">`, renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(""), renderRibbonActions(true))
<main class="accounts-page users-page">`, renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(""), renderRibbonActions(true, CurrentUser(r)))
if msg != "" {
fmt.Fprintf(w, `<div class="notice ok">%s</div>`, html.EscapeString(msg))
}
@ -705,14 +708,15 @@ func transferModeBySlug(slug string) transferMode {
return modes[0]
}
func renderTransferPage(w http.ResponseWriter, mode transferMode, accounts []Account, archives []string) {
func renderTransferPage(w http.ResponseWriter, r *http.Request, mode transferMode, accounts []Account, archives []string) {
user := CurrentUser(r)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>%s - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -740,19 +744,20 @@ func renderTransferPage(w http.ResponseWriter, mode transferMode, accounts []Acc
</section>
</main>
<footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`,
html.EscapeString(mode.Title), renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(mode.Slug), renderRibbonActions(false), transferMenuItems(mode.Slug),
html.EscapeString(mode.Title), renderRibbonEmailBoxMenu(""), renderRibbonTransferMenu(mode.Slug), renderRibbonActions(false, user), transferMenuItems(mode.Slug),
html.EscapeString(mode.LeftTitle), renderTransferPicker(mode.LeftKind, accounts, archives),
html.EscapeString(mode.RightTitle), renderTransferPicker(mode.RightKind, accounts, archives))
}
func renderSourceEmailBoxPage(w http.ResponseWriter, accounts []Account) {
func renderSourceEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts []Account) {
user := CurrentUser(r)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Quell-Postfach - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -783,17 +788,18 @@ func renderSourceEmailBoxPage(w http.ResponseWriter, accounts []Account) {
<section class="pane pane-read"><div class="ef-empty">Nachricht waehlen.</div></section>
</div>
<footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`,
renderRibbonEmailBoxMenu("source"), renderRibbonTransferMenu(""), renderRibbonActions(false), renderEmailBoxSourcePane(accounts))
renderRibbonEmailBoxMenu("source"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), renderEmailBoxSourcePane(accounts))
}
func renderTargetEmailBoxPage(w http.ResponseWriter, accounts []Account) {
func renderTargetEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts []Account) {
user := CurrentUser(r)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Ziel-Postfach - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-20">
<link rel="stylesheet" href="/static/style.css?v=20260712-21">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-20" defer></script></head>
<script src="/static/app.js?v=20260712-21" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -824,7 +830,7 @@ func renderTargetEmailBoxPage(w http.ResponseWriter, accounts []Account) {
<aside class="pane pane-tree">%s</aside>
</div>
<footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`,
renderRibbonEmailBoxMenu("target"), renderRibbonTransferMenu(""), renderRibbonActions(false), renderEmailBoxTargetPane(accounts))
renderRibbonEmailBoxMenu("target"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), renderEmailBoxTargetPane(accounts))
}
func renderEmailBoxSourcePane(accounts []Account) string {
@ -947,12 +953,13 @@ func renderRibbonEmailBoxMenu(active string) string {
return b.String()
}
func renderRibbonActions(settingsActive bool) string {
func renderRibbonActions(settingsActive bool, user AppUser) string {
settingsClass := "ribbon-icon"
if settingsActive {
settingsClass += " active"
}
return fmt.Sprintf(`<div class="ribbon-spacer"></div><a class="%s" href="/users" title="Einstellungen" aria-label="Einstellungen">&#9881;</a><a class="ribbon-icon" href="/logout" title="Logout" aria-label="Logout">&#x23FB;</a>`, settingsClass)
return fmt.Sprintf(`<div class="ribbon-spacer"></div><span class="ribbon-user" title="%s">%s</span><a class="%s" href="/users" title="Einstellungen" aria-label="Einstellungen">&#9881;</a><a class="ribbon-icon" href="/logout" title="Logout" aria-label="Logout">&#x23FB;</a>`,
html.EscapeString(user.Username), html.EscapeString(userDisplayName(user)), settingsClass)
}
func renderRibbonTransferMenu(active string) string {