updates
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const SharedCSS = `
|
||||
:root { color-scheme: dark; }
|
||||
@@ -17,8 +22,13 @@ const SharedCSS = `
|
||||
.topbar a { color: #9cdcfe; text-decoration: none; padding: 4px 10px; border-radius: 3px; }
|
||||
.topbar a:hover { background: #2a2d2e; }
|
||||
.topbar a.active { background: #094771; color: #fff; }
|
||||
.beta-pill { margin-left: 4px; padding: 1px 4px; border: 1px solid #555; border-radius: 3px; font-size: 10px; opacity: 0.7; text-transform: uppercase; }
|
||||
.topbar-version { margin-left: auto; font-size: 11px; opacity: 0.45; letter-spacing: 0.4px; }
|
||||
.content { padding: 16px; max-width: 980px; margin: 0 auto; }
|
||||
.beta-tools-footer { max-width: 980px; margin: 24px auto 16px auto; padding: 12px 16px 0; border-top: 1px solid #333; }
|
||||
.beta-tools-footer button { width: 100%; text-align: left; background: #3a3d41; color: #ddd; }
|
||||
.beta-tools-footer button:hover { background: #45494e; }
|
||||
.beta-note { display: block; margin-top: 3px; opacity: 0.65; font-size: 11px; }
|
||||
h2 { margin-top: 0; font-weight: 500; }
|
||||
input[type=text], input[type=date], select, textarea {
|
||||
box-sizing: border-box; padding: 6px 8px;
|
||||
@@ -42,26 +52,79 @@ const SharedCSS = `
|
||||
.hint { font-size: 12px; opacity: 0.7; }
|
||||
`
|
||||
|
||||
type navItem struct{ Path, Label string }
|
||||
type navItem struct {
|
||||
Path string
|
||||
Label string
|
||||
Description string
|
||||
Beta bool
|
||||
}
|
||||
|
||||
var navItems = []navItem{
|
||||
{"/", "Home"},
|
||||
{"/plec", "PLEC Upload"},
|
||||
{"/applovin", "AppLovin Upload"},
|
||||
{"/base64", "Base64 Scanner"},
|
||||
{"/daily", "Daily Update"},
|
||||
{"/mobile", "Send To Mobile"},
|
||||
{Path: "/", Label: "Home"},
|
||||
{Path: "/plec", Label: "PLEC Upload", Description: "Upload HTML to the internal PLEC server"},
|
||||
{Path: "/applovin", Label: "AppLovin Upload", Description: "Upload to p.applov.in (QR preview)"},
|
||||
{Path: "/base64", Label: "Base64 Scanner", Description: "Find non-base64 assets in HTML"},
|
||||
{Path: "/mraid", Label: "MRAID Checker", Description: "Check MRAID requirements and best practices", Beta: true},
|
||||
{Path: "/mobile", Label: "Send To Mobile", Description: "Share HTML to a phone via LAN + QR"},
|
||||
{Path: "/playworks", Label: "Playworks Converter", Description: "Convert Playworks HTML to per-network variants", Beta: true},
|
||||
}
|
||||
|
||||
func visibleNavItems(betaToolsEnabled bool) []navItem {
|
||||
out := make([]navItem, 0, len(navItems))
|
||||
for _, n := range navItems {
|
||||
if n.Beta && !betaToolsEnabled {
|
||||
continue
|
||||
}
|
||||
out = append(out, n)
|
||||
}
|
||||
return sortNavItemsForDisplay(out)
|
||||
}
|
||||
|
||||
func sortNavItemsForDisplay(items []navItem) []navItem {
|
||||
out := append([]navItem(nil), items...)
|
||||
for i := 0; i < len(out); i++ {
|
||||
for j := i + 1; j < len(out); j++ {
|
||||
if out[i].Beta && !out[j].Beta {
|
||||
out[i], out[j] = out[j], out[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func betaToolCount() int {
|
||||
count := 0
|
||||
for _, n := range navItems {
|
||||
if n.Beta {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func Page(activePath, title, body string) string {
|
||||
cfg := LoadConfig()
|
||||
betaToolsEnabled := cfg.BetaToolsEnabled
|
||||
var tabs strings.Builder
|
||||
for _, n := range navItems {
|
||||
for _, n := range visibleNavItems(betaToolsEnabled) {
|
||||
cls := ""
|
||||
if n.Path == activePath {
|
||||
cls = " class=\"active\""
|
||||
}
|
||||
tabs.WriteString(`<a href="` + n.Path + `"` + cls + `>` + n.Label + `</a>`)
|
||||
label := n.Label
|
||||
if n.Beta {
|
||||
label += `<span class="beta-pill">Beta</span>`
|
||||
}
|
||||
tabs.WriteString(`<a href="` + n.Path + `"` + cls + `>` + label + `</a>`)
|
||||
}
|
||||
|
||||
betaButtonLabel := "Enable Beta Tools"
|
||||
betaButtonNote := "Hidden beta tools: " + strconv.Itoa(betaToolCount())
|
||||
if betaToolsEnabled {
|
||||
betaButtonLabel = "Disable Beta Tools"
|
||||
betaButtonNote = "Beta tools are visible in this standalone launcher."
|
||||
}
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta charset="UTF-8" />
|
||||
@@ -70,5 +133,43 @@ func Page(activePath, title, body string) string {
|
||||
</head><body>
|
||||
<div class="topbar">` + tabs.String() + `<span class="topbar-version">v` + AppVersion + `</span></div>
|
||||
<div class="content">` + body + `</div>
|
||||
<div class="beta-tools-footer">
|
||||
<button id="betaToolsToggle" data-enabled="` + boolAttr(betaToolsEnabled) + `">` + betaButtonLabel + `<span class="beta-note">` + betaButtonNote + `</span></button>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById('betaToolsToggle').addEventListener('click', async (event) => {
|
||||
const enabled = event.currentTarget.dataset.enabled === 'true';
|
||||
await fetch('/api/betaTools', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled: !enabled }),
|
||||
});
|
||||
window.location.reload();
|
||||
});
|
||||
</script>
|
||||
</body></html>`
|
||||
}
|
||||
|
||||
func boolAttr(v bool) string {
|
||||
if v {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
}
|
||||
|
||||
func BetaToolsEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
var req struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeJSON(w, map[string]any{"ok": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
cfg := LoadConfig()
|
||||
cfg.BetaToolsEnabled = req.Enabled
|
||||
if err := SaveConfig(cfg); err != nil {
|
||||
writeJSON(w, map[string]any{"ok": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
writeJSON(w, map[string]any{"ok": true})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user