Merge remote-tracking branch 'tedu/master' into docker
This commit is contained in:
commit
17ca2738d1
47
activity.go
47
activity.go
|
@ -27,6 +27,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -506,6 +507,39 @@ func firstofmany(obj junk.Junk, key string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
var re_mast0link = regexp.MustCompile(`https://[[:alnum:].]+/users/[[:alnum:]]+/statuses/[[:digit:]]+`)
|
||||
var re_masto1ink = regexp.MustCompile(`https://[[:alnum:].]+/@[[:alnum:]]+/[[:digit:]]+`)
|
||||
var re_misslink = regexp.MustCompile(`https://[[:alnum:].]+/notes/[[:alnum:]]+`)
|
||||
var re_honklink = regexp.MustCompile(`https://[[:alnum:].]+/u/[[:alnum:]]+/h/[[:alnum:]]+`)
|
||||
var re_romalink = regexp.MustCompile(`https://[[:alnum:].]+/objects/[[:alnum:]-]+`)
|
||||
var re_qtlinks = regexp.MustCompile(`>https://[^\s<]+<`)
|
||||
|
||||
func qutify(user *WhatAbout, content string) string {
|
||||
// well this is gross
|
||||
malcontent := strings.ReplaceAll(content, `</span><span class="ellipsis">`, "")
|
||||
malcontent = strings.ReplaceAll(malcontent, `</span><span class="invisible">`, "")
|
||||
mlinks := re_qtlinks.FindAllString(malcontent, -1)
|
||||
for _, m := range mlinks {
|
||||
m = m[1 : len(m)-1]
|
||||
dlog.Printf("consider qt: %s", m)
|
||||
if re_mast0link.MatchString(m) ||
|
||||
re_masto1ink.MatchString(m) ||
|
||||
re_misslink.MatchString(m) ||
|
||||
re_honklink.MatchString(m) ||
|
||||
re_romalink.MatchString(m) {
|
||||
j, err := GetJunk(user.ID, m)
|
||||
dlog.Printf("fetched %s: %s", m, err)
|
||||
if err == nil {
|
||||
q, ok := j.GetString("content")
|
||||
if ok {
|
||||
content = fmt.Sprintf("%s<blockquote>%s</blockquote>", content, q)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
|
||||
depth := 0
|
||||
maxdepth := 10
|
||||
|
@ -690,9 +724,11 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
|
|||
return nil
|
||||
}
|
||||
if originate(xid) != origin {
|
||||
ilog.Printf("original sin: %s not from %s", xid, origin)
|
||||
item.Write(ilog.Writer())
|
||||
return nil
|
||||
if !develMode && origin != "" {
|
||||
ilog.Printf("original sin: %s not from %s", xid, origin)
|
||||
item.Write(ilog.Writer())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var xonk Honk
|
||||
|
@ -742,6 +778,9 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
|
|||
content += fmt.Sprintf(`<p><a href="%s">%s</a>`, url, url)
|
||||
url = xid
|
||||
}
|
||||
if user.Options.InlineQuotes {
|
||||
content = qutify(user, content)
|
||||
}
|
||||
rid, ok = obj.GetString("inReplyTo")
|
||||
if !ok {
|
||||
if robj, ok := obj.GetMap("inReplyTo"); ok {
|
||||
|
@ -1904,7 +1943,7 @@ func followyou2(user *WhatAbout, j junk.Junk) {
|
|||
|
||||
ilog.Printf("updating honker accept: %s", who)
|
||||
db := opendatabase()
|
||||
row := db.QueryRow("select name, folxid from honkers where userid = ? and xid = ? and flavor in ('presub')",
|
||||
row := db.QueryRow("select name, folxid from honkers where userid = ? and xid = ? and flavor in ('presub', 'sub')",
|
||||
user.ID, who)
|
||||
var name, folxid string
|
||||
err := row.Scan(&name, &folxid)
|
||||
|
|
|
@ -2,6 +2,18 @@ changelog
|
|||
|
||||
=== next
|
||||
|
||||
+ Emu peeker
|
||||
|
||||
+ CSP compliance
|
||||
|
||||
+ Filter to match anything with summary/warning.
|
||||
|
||||
+ Start collecting quties.
|
||||
|
||||
+ Fix http signatures for GET requests.
|
||||
|
||||
+ Fix adjacent mentions.
|
||||
|
||||
+ Fix argv for chpass.
|
||||
|
||||
+ Avoid self mention in reply all.
|
||||
|
|
|
@ -51,6 +51,7 @@ fields as well.
|
|||
.It Ar text
|
||||
Regular expression match against the post
|
||||
.Fa content .
|
||||
The special value of "." will match any post with a summary only.
|
||||
.It Ar is announce
|
||||
Is announced (shared).
|
||||
.It Ar announce of
|
||||
|
|
|
@ -139,6 +139,9 @@ A 24 hour clock is assumed, unless am or pm are specified.
|
|||
The duration is optional and may be specified as XdYhZm for X days, Y hours,
|
||||
and Z minutes (1d12h would be a 36 hour event).
|
||||
.Pp
|
||||
Clicking the pretty circle face will open the emu peeker to add in the
|
||||
selection of emus.
|
||||
.Pp
|
||||
When everything is at last ready to go, press the
|
||||
.Dq it's gonna be honked
|
||||
button.
|
||||
|
|
2
go.mod
2
go.mod
|
@ -9,5 +9,5 @@ require (
|
|||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
|
||||
humungus.tedunangst.com/r/go-sqlite3 v1.1.3
|
||||
humungus.tedunangst.com/r/webs v0.6.59
|
||||
humungus.tedunangst.com/r/webs v0.6.60
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -25,5 +25,5 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
humungus.tedunangst.com/r/go-sqlite3 v1.1.3 h1:G2N4wzDS0NbuvrZtQJhh4F+3X+s7BF8b9ga8k38geUI=
|
||||
humungus.tedunangst.com/r/go-sqlite3 v1.1.3/go.mod h1:FtEEmQM7U2Ey1TuEEOyY1BmphTZnmiEjPsNLEAkpf/M=
|
||||
humungus.tedunangst.com/r/webs v0.6.59 h1:zOlBGZqrRo22QND1CN8HbhEv3JwoiZkspi7TgVuJS0s=
|
||||
humungus.tedunangst.com/r/webs v0.6.59/go.mod h1:03R0N9BcT49HB4TDd1YmarpbiPvPzVDm74Mk4h1hYPc=
|
||||
humungus.tedunangst.com/r/webs v0.6.60 h1:2PjVTVH3js4PXv8lrEw7nxtRmwwt1COl7t7tZMPxBPs=
|
||||
humungus.tedunangst.com/r/webs v0.6.60/go.mod h1:03R0N9BcT49HB4TDd1YmarpbiPvPzVDm74Mk4h1hYPc=
|
||||
|
|
11
hfcs.go
11
hfcs.go
|
@ -107,7 +107,7 @@ func filtcachefiller(userid int64) (afiltermap, bool) {
|
|||
expflush = filt.Expiration
|
||||
}
|
||||
}
|
||||
if t := filt.Text; t != "" {
|
||||
if t := filt.Text; t != "" && t != "." {
|
||||
wordfront := t[0] != '#'
|
||||
wordtail := true
|
||||
t = "(?i:" + t + ")"
|
||||
|
@ -314,7 +314,7 @@ func matchfilterX(h *Honk, f *Filter) string {
|
|||
rv += " announce"
|
||||
}
|
||||
}
|
||||
if match && f.Text != "" {
|
||||
if match && f.Text != "" && f.Text != "." {
|
||||
match = false
|
||||
re := f.re_text
|
||||
m := re.FindString(h.Precis)
|
||||
|
@ -334,6 +334,13 @@ func matchfilterX(h *Honk, f *Filter) string {
|
|||
rv = m
|
||||
}
|
||||
}
|
||||
if match && f.Text == "." {
|
||||
match = false
|
||||
if h.Precis != "" {
|
||||
match = true
|
||||
rv = h.Precis
|
||||
}
|
||||
}
|
||||
if match {
|
||||
return rv
|
||||
}
|
||||
|
|
19
honk.go
19
honk.go
|
@ -51,15 +51,16 @@ type WhatAbout struct {
|
|||
}
|
||||
|
||||
type UserOptions struct {
|
||||
SkinnyCSS bool `json:",omitempty"`
|
||||
OmitImages bool `json:",omitempty"`
|
||||
MentionAll bool `json:",omitempty"`
|
||||
Avatar string `json:",omitempty"`
|
||||
Banner string `json:",omitempty"`
|
||||
MapLink string `json:",omitempty"`
|
||||
Reaction string `json:",omitempty"`
|
||||
MeCount int64
|
||||
ChatCount int64
|
||||
SkinnyCSS bool `json:",omitempty"`
|
||||
OmitImages bool `json:",omitempty"`
|
||||
MentionAll bool `json:",omitempty"`
|
||||
InlineQuotes bool `json:",omitempty"`
|
||||
Avatar string `json:",omitempty"`
|
||||
Banner string `json:",omitempty"`
|
||||
MapLink string `json:",omitempty"`
|
||||
Reaction string `json:",omitempty"`
|
||||
MeCount int64
|
||||
ChatCount int64
|
||||
}
|
||||
|
||||
type KeyInfo struct {
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
<div class="info">
|
||||
{{ .AboutMsg }}
|
||||
<p>
|
||||
<table style="font-size:0.8em">
|
||||
<table class="font08em">
|
||||
<tbody>
|
||||
<tr><td>version:<td style="text-align:right">{{ .HonkVersion }}
|
||||
<tr><td>memory:<td style="text-align:right">{{ printf "%.02f" .Sensors.Memory }}MB
|
||||
<tr><td>uptime:<td style="text-align:right">{{ printf "%.02f" .Sensors.Uptime }}s
|
||||
<tr><td>cputime:<td style="text-align:right">{{ printf "%.02f" .Sensors.CPU }}s
|
||||
<tr><td>version:<td class="textright">{{ .HonkVersion }}
|
||||
<tr><td>memory:<td class="textright">{{ printf "%.02f" .Sensors.Memory }}MB
|
||||
<tr><td>uptime:<td class="textright">{{ printf "%.02f" .Sensors.Uptime }}s
|
||||
<tr><td>cputime:<td class="textright">{{ printf "%.02f" .Sensors.CPU }}s
|
||||
</table>
|
||||
<p>
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
<input tabindex=1 type="checkbox" id="omitimages" name="omitimages" value="omitimages" {{ if .User.Options.OmitImages }}checked{{ end }}><span></span>
|
||||
<p><label class="button" for="mentionall">mention all:</label>
|
||||
<input tabindex=1 type="checkbox" id="mentionall" name="mentionall" value="mentionall" {{ if .User.Options.MentionAll }}checked{{ end }}><span></span>
|
||||
|
||||
<p><label class="button" for="inlineqts">inline quotes:</label>
|
||||
<input tabindex=1 type="checkbox" id="inlineqts" name="inlineqts" value="inlineqts" {{ if .User.Options.InlineQuotes }}checked{{ end }}><span></span>
|
||||
<p><label class="button" for="maps">apple map links:</label>
|
||||
<input tabindex=1 type="checkbox" id="maps" name="maps" value="apple" {{ if eq "apple" .User.Options.MapLink }}checked{{ end }}><span></span>
|
||||
<p><label class="button" for="reaction">reaction:</label>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{{ template "header.html" . }}
|
||||
<script src="/misc.js{{ .MiscJSParam }}" defer></script>
|
||||
<main>
|
||||
<div class="info">
|
||||
<p>
|
||||
|
@ -10,14 +11,8 @@
|
|||
<p><label for=noise>noise:</label><br>
|
||||
<textarea name="noise" id="noise"></textarea>
|
||||
<p><button name="chonk" value="chonk">chonk</button>
|
||||
<label class=button id="donker">attach: <input onchange="updatedonker(this);" type="file" name="donk"><span></span></label>
|
||||
<label class=button id="donker">attach: <input type="file" name="donk"><span></span></label>
|
||||
</form>
|
||||
<script>
|
||||
function updatedonker(el) {
|
||||
el = el.parentElement
|
||||
el.children[1].textContent = el.children[0].value.slice(-20)
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
{{ $chonkcsrf := .ChonkCSRF }}
|
||||
{{ range .Chatter }}
|
||||
|
@ -59,7 +54,7 @@ chatter: {{ .Target }}
|
|||
<p><label for=noise>noise:</label><br>
|
||||
<textarea name="noise" id="noise"></textarea>
|
||||
<p><button name="chonk" value="chonk">chonk</button>
|
||||
<label class=button id="donker">attach: <input onchange="updatedonker(this);" type="file" name="donk"><span></span></label>
|
||||
<label class=button id="donker">attach: <input type="file" name="donk"><span></span></label>
|
||||
</form>
|
||||
</section>
|
||||
{{ end }}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
{{ range .Combos }}
|
||||
<section class="honk">
|
||||
<header>
|
||||
<p style="font-size: 1.8em"><a href="/c/{{ . }}">{{ . }}</a>
|
||||
<p class="font18em"><a href="/c/{{ . }}">{{ . }}</a>
|
||||
</header>
|
||||
</section>
|
||||
{{ end }}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{{ range .Emus }}<img class="emu" alt=":{{.Name}}:" src="{{ .ID }}">{{ end }}
|
|
@ -6,14 +6,11 @@
|
|||
{{ if .LocalStyleParam }}
|
||||
<link href="/local.css{{ .LocalStyleParam }}" rel="stylesheet">
|
||||
{{ end }}
|
||||
<style>
|
||||
{{ .UserStyle }}
|
||||
</style>
|
||||
<link href="/icon.png" rel="icon">
|
||||
<meta name="theme-color" content="#305">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
</head>
|
||||
<body>
|
||||
<body{{ if .UserStyle}} {{ .UserStyle }}{{ end }}>
|
||||
<header>
|
||||
{{ if .UserInfo }}
|
||||
<details id="topmenu">
|
||||
|
@ -22,7 +19,7 @@
|
|||
<li><a id="homelink" href="/">home</a>
|
||||
<li><a id="atmelink" href="/atme">@me<span id=mecount>{{ if .UserInfo.Options.MeCount }}({{ .UserInfo.Options.MeCount }}){{ end }}</span></a>
|
||||
<li><a id="firstlink" href="/first">first</a>
|
||||
<li style="list-style-type:none; margin-left:-1em">
|
||||
<li class="details">
|
||||
<details>
|
||||
<summary>combos</summary>
|
||||
<ul>
|
||||
|
@ -39,7 +36,7 @@
|
|||
<li><a href="/honkers">honkers</a>
|
||||
<li><a href="/hfcs">filters</a>
|
||||
<li><a href="/account">account</a>
|
||||
<li style="list-style-type:none; margin-left:-1em">
|
||||
<li class="details">
|
||||
<details>
|
||||
<summary>more stuff</summary>
|
||||
<ul>
|
||||
|
@ -59,7 +56,7 @@
|
|||
</details>
|
||||
<div id="topspacer">
|
||||
<p>
|
||||
<p class="nophone" onclick="window.scrollTo(0,0)">top
|
||||
<p class="nophone">top
|
||||
</div>
|
||||
{{ else }}
|
||||
<div id="topmenu">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<article class="honk {{ .Honk.Style }}" data-convoy="{{ .Honk.Convoy }}">
|
||||
<article class="honk {{ .Honk.Style }}" data-convoy="{{ .Honk.Convoy }}" data-hname="{{ .Honk.Handles }}" data-xid="{{ .Honk.XID }}" data-id="{{ .Honk.ID }}">
|
||||
{{ $bonkcsrf := .BonkCSRF }}
|
||||
{{ $IsPreview := .IsPreview }}
|
||||
{{ $maplink := .MapLink }}
|
||||
|
@ -30,7 +30,7 @@
|
|||
<span class="clip"><a href="{{ .URL }}" rel=noreferrer>{{ .What }}</a> {{ .Date.Local.Format "02 Jan 2006 15:04 -0700" }}</span>
|
||||
{{ if .Oonker }}
|
||||
<br>
|
||||
<span style="margin-left: 1em;" class="clip">
|
||||
<span class="left1em clip">
|
||||
{{ if $bonkcsrf }}
|
||||
original: <a class="honkerlink" href="/h?xid={{ .Oonker }}" data-xid="{{ .Oonker }}">{{ .Oondle }}</a>
|
||||
{{ else }}
|
||||
|
@ -40,14 +40,14 @@ original: <a href="{{ .Oonker }}" rel=noreferrer>{{ .Oondle }}</a>
|
|||
{{ else }}
|
||||
{{ if .RID }}
|
||||
<br>
|
||||
<span style="margin-left: 1em;" class="clip">
|
||||
<span class="left1em clip">
|
||||
in reply to: <a href="{{ .RID }}" rel=noreferrer>{{ .RID }}</a>
|
||||
</span>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<br>
|
||||
{{ if $bonkcsrf }}
|
||||
<span style="margin-left: 1em;" class="clip">convoy: <a class="convoylink" href="/t?c={{ .Convoy }}">{{ .Convoy }}</a></span>
|
||||
<span class="left1em clip">convoy: <a class="convoylink" href="/t?c={{ .Convoy }}">{{ .Convoy }}</a></span>
|
||||
{{ end }}
|
||||
</header>
|
||||
<p>
|
||||
|
@ -95,7 +95,7 @@ in reply to: <a href="{{ .RID }}" rel=noreferrer>{{ .RID }}</a>
|
|||
{{ .Honk.Guesses }}
|
||||
<p>{{ .Honk.Noise }}
|
||||
{{ else }}
|
||||
<button onclick="return playit(this, '{{ .Honk.Noise }}', '{{ .Honk.Wonkles }}', '{{ .Honk.XID }}')">it's play time!</button>
|
||||
<button class="playit" data-noise="{{ .Honk.Noise }}" data-wonk="{{ .Honk.Wonkles }}">it's play time!</button>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if and $bonkcsrf (not $IsPreview) }}
|
||||
|
@ -106,41 +106,41 @@ in reply to: <a href="{{ .RID }}" rel=noreferrer>{{ .RID }}</a>
|
|||
<p>
|
||||
{{ if .Honk.Public }}
|
||||
{{ if .Honk.IsBonked }}
|
||||
<button onclick="return unbonk(this, '{{ .Honk.XID }}');">unbonk</button>
|
||||
<button class="unbonk">unbonk</button>
|
||||
{{ else }}
|
||||
<button onclick="return bonk(this, '{{ .Honk.XID }}');">bonk</button>
|
||||
<button class="bonk">bonk</button>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<button disabled>nope</button>
|
||||
{{ end }}
|
||||
<button onclick="return showhonkform(this, '{{ .Honk.XID }}', '{{ .Honk.Handles }}');"><a href="/newhonk?rid={{ .Honk.XID }}">honk back</a></button>
|
||||
<button onclick="return muteit(this, '{{ .Honk.Convoy }}');">mute</button>
|
||||
<button onclick="return showelement('evenmore{{ .Honk.ID }}')">even more</button>
|
||||
<button class="honkback"><a href="/newhonk?rid={{ .Honk.XID }}">honk back</a></button>
|
||||
<button class="mute">mute</button>
|
||||
<button class="evenmore">even more</button>
|
||||
</div>
|
||||
<div id="evenmore{{ .Honk.ID }}" style="display:none">
|
||||
<div id="evenmore{{ .Honk.ID }}" class="hide">
|
||||
<p>
|
||||
<button onclick="return zonkit(this, '{{ .Honk.XID }}');">zonk</button>
|
||||
<button class="zonk">zonk</button>
|
||||
{{ if .Honk.IsAcked }}
|
||||
<button onclick="return flogit(this, 'deack', '{{ .Honk.XID }}');">deack</button>
|
||||
<button class="flogit-deack">deack</button>
|
||||
{{ else }}
|
||||
<button onclick="return flogit(this, 'ack', '{{ .Honk.XID }}');">ack</button>
|
||||
<button class="flogit-ack" >ack</button>
|
||||
{{ end }}
|
||||
{{ if .Honk.IsSaved }}
|
||||
<button onclick="return flogit(this, 'unsave', '{{ .Honk.XID }}');">unsave</button>
|
||||
<button class="flogit-unsave">unsave</button>
|
||||
{{ else }}
|
||||
<button onclick="return flogit(this, 'save', '{{ .Honk.XID }}');">save</button>
|
||||
<button class="flogit-save">save</button>
|
||||
{{ end }}
|
||||
{{ if .Honk.IsUntagged }}
|
||||
<button disabled>untagged</button>
|
||||
{{ else }}
|
||||
<button onclick="return flogit(this, 'untag', '{{ .Honk.XID }}');">untag me</button>
|
||||
<button class="flogit-untag">untag me</button>
|
||||
{{ end }}
|
||||
<button><a href="/edit?xid={{ .Honk.XID }}">edit</a></button>
|
||||
{{ if not (eq .Badonk "none") }}
|
||||
{{ if .Honk.IsReacted }}
|
||||
<button disabled>badonked</button>
|
||||
{{ else }}
|
||||
<button onclick="return flogit(this, 'react', '{{ .Honk.XID }}');">{{ .Badonk }}</button>
|
||||
<button class="flogit-react" >{{ .Badonk }}</button>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{{ template "header.html" . }}
|
||||
<script src="/misc.js{{ .MiscJSParam }}" defer></script>
|
||||
<main>
|
||||
<div class="info">
|
||||
<p>
|
||||
|
@ -21,21 +22,13 @@
|
|||
</div>
|
||||
{{ $honkercsrf := .HonkerCSRF }}
|
||||
<div class="info">
|
||||
<script>
|
||||
function expandstuff() {
|
||||
var els = document.querySelectorAll(".honk details")
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].open = true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<p><button onclick="expandstuff()">expand</button>
|
||||
<p><button class="expand">expand</button>
|
||||
</div>
|
||||
{{ range .Honkers }}
|
||||
<section class="honk">
|
||||
<header>
|
||||
<img alt="avatar" src="/a?a={{ .XID }}">
|
||||
<p style="font-size: 1.8em"><a href="/h/{{ .Name }}">{{ .Name }}</a>
|
||||
<p class="font18em"><a href="/h/{{ .Name }}">{{ .Name }}</a>
|
||||
</header>
|
||||
<p>
|
||||
<details>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<p id="honkformhost">
|
||||
<button id="honkingtime" onclick="return showhonkform();" {{ if .IsPreview }}style="display:none"{{ end }}><a href="/newhonk">it's honking time</a></button>
|
||||
<form id="honkform" action="/honk" method="POST" enctype="multipart/form-data" {{ if not .IsPreview }}style="display: none"{{ end }}>
|
||||
<button id="honkingtime" {{ if .IsPreview }}class="hide"{{ end }}><a href="/newhonk">it's honking time</a></button>
|
||||
<form id="honkform" action="/honk" method="POST" enctype="multipart/form-data" {{ if not .IsPreview }}class="hide"{{ end }}>
|
||||
<input type="hidden" name="CSRF" value="{{ .HonkCSRF }}">
|
||||
<input type="hidden" name="updatexid" id="updatexidinput" value = "{{ .UpdateXID }}">
|
||||
<input type="hidden" name="rid" id="ridinput" value="{{ .InReplyTo }}">
|
||||
|
@ -9,12 +9,12 @@
|
|||
<details>
|
||||
<summary>more options</summary>
|
||||
<p>
|
||||
<label class=button id="donker">attach: <input onchange="updatedonker();" type="file" name="donk"><span>{{ .SavedFile }}</span></label>
|
||||
<label class=button id="donker">attach: <input type="file" name="donk"><span>{{ .SavedFile }}</span></label>
|
||||
<input type="hidden" id="saveddonkxid" name="donkxid" value="{{ .SavedFile }}">
|
||||
<p id="donkdescriptor"><label for=donkdesc>description:</label><br>
|
||||
<input type="text" name="donkdesc" value="{{ .DonkDesc }}" autocomplete=off>
|
||||
{{ with .SavedPlace }}
|
||||
<p><button id=checkinbutton type=button onclick="fillcheckin()">checkin</button>
|
||||
<p><button id=checkinbutton type=button>checkin</button>
|
||||
<div id=placedescriptor>
|
||||
<p><label>name:</label><br><input type="text" name="placename" id=placenameinput value="{{ .Name }}">
|
||||
<p><label>url:</label><br><input type="text" name="placeurl" id=placeurlinput value="{{ .Url }}">
|
||||
|
@ -22,26 +22,34 @@
|
|||
<label>lon: </label><input type="text" size=9 name="placelong" id=placelonginput value="{{ .Longitude }}">
|
||||
</div>
|
||||
{{ else }}
|
||||
<p><button id=checkinbutton type=button onclick="fillcheckin()">checkin</button>
|
||||
<div id=placedescriptor style="display: none">
|
||||
<p><button id=checkinbutton type=button>checkin</button>
|
||||
<div id=placedescriptor class="hide">
|
||||
<p><label>name:</label><br><input type="text" name="placename" id=placenameinput value="">
|
||||
<p><label>url:</label><br><input type="text" name="placeurl" id=placeurlinput value="">
|
||||
<p><label>lat: </label><input type="text" size=9 name="placelat" id=placelatinput value="">
|
||||
<label>lon: </label><input type="text" size=9 name="placelong" id=placelonginput value="">
|
||||
</div>
|
||||
{{ end }}
|
||||
<p><button id=addtimebutton type=button onclick="showelement('timedescriptor')">add time</button>
|
||||
<div id=timedescriptor style="{{ or .ShowTime "display: none" }}">
|
||||
<p><button id=addtimebutton type=button>add time</button>
|
||||
<div id=timedescriptor class="{{ or .ShowTime "hide" }}">
|
||||
<p><label for=timestart>start:</label><br>
|
||||
<input type="text" name="timestart" value="{{ .StartTime }}">
|
||||
<p><label for=timeend>duration:</label><br>
|
||||
<input type="text" name="timeend" value="{{ .Duration }}">
|
||||
</div>
|
||||
<svg class="emuload" id="emuload" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-mood-neutral" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<circle cx="12" cy="12" r="9"></circle>
|
||||
<line x1="9" y1="10" x2="9.01" y2="10"></line>
|
||||
<line x1="15" y1="10" x2="15.01" y2="10"></line>
|
||||
</svg>
|
||||
<div id="emupicker">
|
||||
</div>
|
||||
</details>
|
||||
<p>
|
||||
<textarea name="noise" id="honknoise">{{ .Noise }}</textarea>
|
||||
<p class="buttonarray">
|
||||
<button>it's gonna be honked</button>
|
||||
<button name="preview" value="preview">preview</button>
|
||||
<button type=button name="cancel" value="cancel" onclick="cancelhonking()">cancel</button>
|
||||
<button type=button name="cancel" value="cancel">cancel</button>
|
||||
</form>
|
||||
|
|
|
@ -3,42 +3,24 @@
|
|||
<div class="info" id="infobox">
|
||||
<div id="srvmsg">
|
||||
{{ if .Name }}
|
||||
<p>{{ .Name }} <span style="margin-left:1em;"><a href="/u/{{ .Name }}/rss">rss</a></span>
|
||||
<p>{{ .Name }} <span class="left1em"><a href="/u/{{ .Name }}/rss">rss</a></span>
|
||||
<p>{{ .WhatAbout }}
|
||||
{{ end }}
|
||||
<p>{{ .ServerMessage }}
|
||||
</div>
|
||||
{{ if .HonkCSRF }}
|
||||
{{ template "honkform.html" . }}
|
||||
<script>
|
||||
var csrftoken = {{ .HonkCSRF }}
|
||||
var honksforpage = { }
|
||||
var curpagestate = { name: "{{ .PageName }}", arg : "{{ .PageArg }}" }
|
||||
var tophid = { }
|
||||
tophid[curpagestate.name + ":" + curpagestate.arg] = "{{ .TopHID }}"
|
||||
var servermsgs = { }
|
||||
servermsgs[curpagestate.name + ":" + curpagestate.arg] = "{{ .ServerMessage }}"
|
||||
</script>
|
||||
<script src="/honkpage.js{{ .JSParam }}"></script>
|
||||
<script src="/honkpage.js{{ .JSParam }}" defer data-csrf="{{ .HonkCSRF }}" data-pagename="{{ .PageName }}" data-pagearg="{{ .PageArg }}" data-tophid="{{ .TopHID }}" data-srvmsg="{{ .ServerMessage }}"></script>
|
||||
{{ end }}
|
||||
<script>
|
||||
function playit(elem, word, wordlist, xid) {
|
||||
import('/wonk.js').then(module => {
|
||||
makeaguess = module.makeaguess
|
||||
module.addguesscontrols(elem, word, wordlist, xid)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{{ if .LocalJSParam }}
|
||||
<script src="/local.js{{ .LocalJSParam }}"></script>
|
||||
<script src="/local.js{{ .LocalJSParam }}" defer></script>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ if and .HonkCSRF (not .IsPreview) }}
|
||||
<div class="info" id="refreshbox">
|
||||
<p><button onclick="refreshhonks(this)">refresh</button><span></span>
|
||||
<button onclick="oldestnewest(this)">scroll down</button>
|
||||
<p><button class="refresh">refresh</button><span></span>
|
||||
<button class="scrolldown">scroll down</button>
|
||||
</div>
|
||||
{{ if eq .ServerMessage "one honk maybe more" }} <script> hideelement("refreshbox")</script> {{ end }}
|
||||
{{ end }}
|
||||
<div id="honksonpage">
|
||||
<div>
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
var csrftoken = ""
|
||||
var honksforpage = { }
|
||||
var curpagestate = { name: "", arg : "" }
|
||||
var tophid = { }
|
||||
var servermsgs = { }
|
||||
|
||||
function encode(hash) {
|
||||
var s = []
|
||||
for (var key in hash) {
|
||||
var val = hash[key]
|
||||
s.push(encodeURIComponent(key) + "=" + encodeURIComponent(val))
|
||||
}
|
||||
return s.join("&")
|
||||
var s = []
|
||||
for (var key in hash) {
|
||||
var val = hash[key]
|
||||
s.push(encodeURIComponent(key) + "=" + encodeURIComponent(val))
|
||||
}
|
||||
return s.join("&")
|
||||
}
|
||||
function post(url, data) {
|
||||
var x = new XMLHttpRequest()
|
||||
|
@ -268,25 +274,78 @@ function relinklinks() {
|
|||
el.onclick = pageswitcher("honker", xid)
|
||||
el.classList.remove("honkerlink")
|
||||
}
|
||||
|
||||
els = document.querySelectorAll("#honksonpage article button")
|
||||
els.forEach(function(el) {
|
||||
var honk = el.closest("article")
|
||||
var convoy = honk.dataset.convoy
|
||||
var hname = honk.dataset.hname
|
||||
var xid = honk.dataset.xid
|
||||
var id = Number(honk.dataset.id)
|
||||
|
||||
if (!(id > 0)) {
|
||||
console.error("could not determine honk id")
|
||||
return
|
||||
}
|
||||
|
||||
if (el.classList.contains("unbonk")) {
|
||||
el.onclick = function() {
|
||||
unbonk(el, xid);
|
||||
}
|
||||
} else if (el.classList.contains("bonk")) {
|
||||
el.onclick = function() {
|
||||
bonk(el, xid)
|
||||
}
|
||||
} else if (el.classList.contains("honkback")) {
|
||||
el.onclick = function() {
|
||||
return showhonkform(el, xid, hname)
|
||||
}
|
||||
} else if (el.classList.contains("mute")) {
|
||||
el.onclick = function() {
|
||||
muteit(el, convoy);
|
||||
}
|
||||
} else if (el.classList.contains("evenmore")) {
|
||||
var more = document.querySelector("#evenmore"+id);
|
||||
el.onclick = function() {
|
||||
more.classList.toggle("hide");
|
||||
}
|
||||
} else if (el.classList.contains("zonk")) {
|
||||
el.onclick = function() {
|
||||
zonkit(el, xid);
|
||||
}
|
||||
} else if (el.classList.contains("flogit-deack")) {
|
||||
el.onclick = function() {
|
||||
flogit(el, "deack", xid);
|
||||
}
|
||||
} else if (el.classList.contains("flogit-ack")) {
|
||||
el.onclick = function() {
|
||||
flogit(el, "ack", xid);
|
||||
}
|
||||
} else if (el.classList.contains("flogit-unsave")) {
|
||||
el.onclick = function() {
|
||||
flogit(el, "unsave", xid);
|
||||
}
|
||||
} else if (el.classList.contains("flogit-save")) {
|
||||
el.onclick = function() {
|
||||
flogit(el, "save", xid);
|
||||
}
|
||||
} else if (el.classList.contains("flogit-untag")) {
|
||||
el.onclick = function() {
|
||||
flogit(el, "untag", xid);
|
||||
}
|
||||
} else if (el.classList.contains("flogit-react")) {
|
||||
el.onclick = function() {
|
||||
flogit(el, "react", xid);
|
||||
}
|
||||
} else if (el.classList.contains("playit")) {
|
||||
var noise = el.dataset.noise
|
||||
var wonk = el.dataset.wonk
|
||||
el.onclick = function() {
|
||||
playit(el, noise, wonk, xid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
(function() {
|
||||
var el = document.getElementById("homelink")
|
||||
el.onclick = pageswitcher("home", "")
|
||||
el = document.getElementById("atmelink")
|
||||
el.onclick = pageswitcher("atme", "")
|
||||
el = document.getElementById("firstlink")
|
||||
el.onclick = pageswitcher("first", "")
|
||||
el = document.getElementById("savedlink")
|
||||
el.onclick = pageswitcher("saved", "")
|
||||
el = document.getElementById("longagolink")
|
||||
el.onclick = pageswitcher("longago", "")
|
||||
relinklinks()
|
||||
window.onpopstate = statechanger
|
||||
history.replaceState(curpagestate, "some title", "")
|
||||
})();
|
||||
(function() {
|
||||
hideelement("donkdescriptor")
|
||||
})();
|
||||
function showhonkform(elem, rid, hname) {
|
||||
var form = lehonkform
|
||||
form.style = "display: block"
|
||||
|
@ -363,3 +422,98 @@ function fillcheckin() {
|
|||
}, gpsoptions)
|
||||
}
|
||||
}
|
||||
function playit(elem, word, wordlist, xid) {
|
||||
import('/wonk.js').then(module => {
|
||||
makeaguess = module.makeaguess
|
||||
module.addguesscontrols(elem, word, wordlist, xid)
|
||||
})
|
||||
}
|
||||
function addemu(elem) {
|
||||
const data = elem.alt
|
||||
const box = document.getElementById("honknoise");
|
||||
box.value += data;
|
||||
}
|
||||
function loademus() {
|
||||
div = document.getElementById("emupicker")
|
||||
request = new XMLHttpRequest()
|
||||
request.open('GET', '/emus')
|
||||
request.onload = function() {
|
||||
div.innerHTML = request.responseText
|
||||
div.querySelectorAll(".emu").forEach(function(el) {
|
||||
el.onclick = function() {
|
||||
addemu(el)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (div.style.display === "none") {
|
||||
div.style.display = "block";
|
||||
} else {
|
||||
div.style.display = "none";
|
||||
}
|
||||
request.send()
|
||||
}
|
||||
|
||||
// init
|
||||
(function() {
|
||||
var me = document.currentScript;
|
||||
csrftoken = me.dataset.csrf
|
||||
curpagestate.name = me.dataset.pagename
|
||||
curpagestate.arg = me.dataset.pagearg
|
||||
tophid[curpagestate.name + ":" + curpagestate.arg] = me.dataset.tophid
|
||||
servermsgs[curpagestate.name + ":" + curpagestate.arg] = me.dataset.srvmsg
|
||||
|
||||
var el = document.getElementById("homelink")
|
||||
el.onclick = pageswitcher("home", "")
|
||||
el = document.getElementById("atmelink")
|
||||
el.onclick = pageswitcher("atme", "")
|
||||
el = document.getElementById("firstlink")
|
||||
el.onclick = pageswitcher("first", "")
|
||||
el = document.getElementById("savedlink")
|
||||
el.onclick = pageswitcher("saved", "")
|
||||
el = document.getElementById("longagolink")
|
||||
el.onclick = pageswitcher("longago", "")
|
||||
|
||||
var totop = document.querySelector(".nophone")
|
||||
if (totop) {
|
||||
totop.onclick = function() {
|
||||
window.scrollTo(0,0)
|
||||
}
|
||||
}
|
||||
|
||||
var refreshbox = document.getElementById("refreshbox")
|
||||
if (refreshbox) {
|
||||
refreshbox.querySelectorAll("button").forEach(function(el) {
|
||||
if (el.classList.contains("refresh")) {
|
||||
el.onclick = function() {
|
||||
refreshhonks(el)
|
||||
}
|
||||
} else if (el.classList.contains("scrolldown")) {
|
||||
el.onclick = function() {
|
||||
oldestnewest(el)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (me.dataset.srvmsg == "one honk maybe more") {
|
||||
hideelement(refreshbox)
|
||||
}
|
||||
}
|
||||
|
||||
var td = document.getElementById("timedescriptor")
|
||||
document.getElementById("addtimebutton").onclick = function() {
|
||||
td.classList.toggle("hide")
|
||||
}
|
||||
document.getElementById("honkingtime").onclick = function() {
|
||||
return showhonkform()
|
||||
}
|
||||
document.getElementById("checkinbutton").onclick = fillcheckin
|
||||
document.getElementById("emuload").onclick = loademus
|
||||
document.querySelector("#donker input").onchange = updatedonker
|
||||
document.querySelector("button[name=cancel]").onclick = cancelhonking
|
||||
|
||||
relinklinks()
|
||||
window.onpopstate = statechanger
|
||||
history.replaceState(curpagestate, "some title", "")
|
||||
|
||||
hideelement("donkdescriptor")
|
||||
})();
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
function expandstuff() {
|
||||
var els = document.querySelectorAll(".honk details")
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].open = true
|
||||
}
|
||||
}
|
||||
|
||||
function updatedonker(el) {
|
||||
el = el.parentElement
|
||||
el.children[1].textContent = el.children[0].value.slice(-20)
|
||||
}
|
||||
|
||||
(function() {
|
||||
var expand = document.querySelector("button.expand")
|
||||
if (expand) {
|
||||
expand.onclick = expandstuff
|
||||
}
|
||||
|
||||
var donk = document.querySelector("#donker input")
|
||||
if (donk) {
|
||||
donk.onchange = function() {
|
||||
updatedonker(this);
|
||||
}
|
||||
}
|
||||
})()
|
|
@ -10,7 +10,7 @@
|
|||
{{ $letter = (call $firstrune .Name) }}
|
||||
<li><p>
|
||||
{{ end }}
|
||||
<span style="white-space: nowrap;"><a href="/o/{{ .Name }}">#{{ .Name }}</a> ({{ .Count }})</span>
|
||||
<span class="wsnowrap"><a href="/o/{{ .Name }}">#{{ .Name }}</a> ({{ .Count }})</span>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -253,6 +253,11 @@ input[type=file] {
|
|||
.honk details.actions summary {
|
||||
color: var(--fg-subtle);
|
||||
}
|
||||
|
||||
#emupicker{height:300px;overflow-y:scroll;padding:3px;background:var(--bg-dark);border:solid 5px var(--fg-subtle);text-align:center;display:none;}
|
||||
#emupicker img{margin:0;}
|
||||
.emuload{background:var(--bg-page);padding:0.5em;}
|
||||
|
||||
.subtle .noise {
|
||||
color: var(--fg-subtle);
|
||||
font-size: 0.8em;
|
||||
|
@ -340,3 +345,44 @@ img.emu {
|
|||
--fg-limited: #a79;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CSP: style-src: self
|
||||
*/
|
||||
|
||||
li.details {
|
||||
list-style-type: none;
|
||||
margin-left: -1em;
|
||||
}
|
||||
|
||||
.left1em {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.textright {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.font08em {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.font18em {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.wsnowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.skinny main {
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.fontmonospace {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,10 @@ export function addguesscontrols(elem, word, wordlist, xid) {
|
|||
}
|
||||
host.validGuesses = validguesses
|
||||
var div = document.createElement( 'div' );
|
||||
div.innerHTML = "<p><input> <button onclick='return makeaguess(this)'>guess</button>"
|
||||
div.innerHTML = "<p><input> <button>guess</button>"
|
||||
div.querySelector('button').onclick = function() {
|
||||
makeaguess(this)
|
||||
}
|
||||
host.append(div)
|
||||
elem.remove()
|
||||
}
|
||||
|
@ -57,7 +60,7 @@ export function makeaguess(btn) {
|
|||
}
|
||||
|
||||
var div = document.createElement( 'div' );
|
||||
div.innerHTML = "<p style='font-family: monospace'>" + res
|
||||
div.innerHTML = "<p class='fontmonospace'>" + res
|
||||
host.append(div)
|
||||
host.guesses.push(obfu)
|
||||
} else {
|
||||
|
@ -76,7 +79,10 @@ export function makeaguess(btn) {
|
|||
if (typeof(csrftoken) != "undefined")
|
||||
post("/zonkit", encode({"CSRF": csrftoken, "wherefore": "wonk", "guesses": host.guesses.join("<p>"), "what": host.xid}))
|
||||
} else {
|
||||
div.innerHTML = "<p><input> <button onclick='return makeaguess(this)'>guess</button>"
|
||||
div.innerHTML = "<p><input> <button>guess</button>"
|
||||
div.querySelector('button').onclick = function() {
|
||||
makeaguess(this)
|
||||
}
|
||||
}
|
||||
host.append(div)
|
||||
btn.parentElement.remove()
|
||||
|
|
65
web.go
65
web.go
|
@ -50,16 +50,18 @@ var honkSep = "h"
|
|||
|
||||
var develMode = false
|
||||
|
||||
func getuserstyle(u *login.UserInfo) template.CSS {
|
||||
var allemus []Emu
|
||||
|
||||
func getuserstyle(u *login.UserInfo) template.HTMLAttr {
|
||||
if u == nil {
|
||||
return ""
|
||||
}
|
||||
user, _ := butwhatabout(u.Username)
|
||||
css := template.CSS("")
|
||||
class := template.HTMLAttr("")
|
||||
if user.Options.SkinnyCSS {
|
||||
css += "main { max-width: 700px; }\n"
|
||||
class += `class="skinny"`
|
||||
}
|
||||
return css
|
||||
return class
|
||||
}
|
||||
|
||||
func getmaplink(u *login.UserInfo) string {
|
||||
|
@ -80,6 +82,7 @@ func getInfo(r *http.Request) map[string]interface{} {
|
|||
templinfo["LocalStyleParam"] = getassetparam(dataDir + "/views/local.css")
|
||||
templinfo["JSParam"] = getassetparam(viewDir + "/views/honkpage.js")
|
||||
templinfo["LocalJSParam"] = getassetparam(dataDir + "/views/local.js")
|
||||
templinfo["MiscJSParam"] = getassetparam(dataDir + "/views/misc.js")
|
||||
templinfo["ServerName"] = serverName
|
||||
templinfo["IconName"] = iconName
|
||||
templinfo["UserSep"] = userSep
|
||||
|
@ -148,6 +151,15 @@ func homepage(w http.ResponseWriter, r *http.Request) {
|
|||
honkpage(w, u, honks, templinfo)
|
||||
}
|
||||
|
||||
func showemus(w http.ResponseWriter, r *http.Request) {
|
||||
templinfo := getInfo(r)
|
||||
templinfo["Emus"] = allemus
|
||||
err := readviews.Execute(w, "emus.html", templinfo)
|
||||
if err != nil {
|
||||
elog.Print(err)
|
||||
}
|
||||
}
|
||||
|
||||
func showfunzone(w http.ResponseWriter, r *http.Request) {
|
||||
var emunames, memenames []string
|
||||
emuext := make(map[string]string)
|
||||
|
@ -1122,6 +1134,11 @@ func saveuser(w http.ResponseWriter, r *http.Request) {
|
|||
} else {
|
||||
options.MentionAll = false
|
||||
}
|
||||
if r.FormValue("inlineqts") == "inlineqts" {
|
||||
options.InlineQuotes = true
|
||||
} else {
|
||||
options.InlineQuotes = false
|
||||
}
|
||||
if r.FormValue("maps") == "apple" {
|
||||
options.MapLink = "apple"
|
||||
} else {
|
||||
|
@ -1429,7 +1446,7 @@ func edithonkpage(w http.ResponseWriter, r *http.Request) {
|
|||
templinfo["Noise"] = noise
|
||||
templinfo["SavedPlace"] = honk.Place
|
||||
if tm := honk.Time; tm != nil {
|
||||
templinfo["ShowTime"] = ";"
|
||||
templinfo["ShowTime"] = " "
|
||||
templinfo["StartTime"] = tm.StartTime.Format("2006-01-02 15:04")
|
||||
if tm.Duration != 0 {
|
||||
templinfo["Duration"] = tm.Duration
|
||||
|
@ -1751,7 +1768,7 @@ func submithonk(w http.ResponseWriter, r *http.Request) *Honk {
|
|||
templinfo["Noise"] = r.FormValue("noise")
|
||||
templinfo["SavedFile"] = donkxid
|
||||
if tm := honk.Time; tm != nil {
|
||||
templinfo["ShowTime"] = ";"
|
||||
templinfo["ShowTime"] = " "
|
||||
templinfo["StartTime"] = tm.StartTime.Format("2006-01-02 15:04")
|
||||
if tm.Duration != 0 {
|
||||
templinfo["Duration"] = tm.Duration
|
||||
|
@ -2414,6 +2431,37 @@ func bgmonitor() {
|
|||
}
|
||||
}
|
||||
|
||||
func addcspheaders(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'none'; script-src 'self'; connect-src 'self'; style-src 'self'; img-src 'self'; report-uri /csp-violation")
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func emuinit() {
|
||||
var emunames []string
|
||||
dir, err := os.Open(dataDir + "/emus")
|
||||
if err == nil {
|
||||
emunames, _ = dir.Readdirnames(0)
|
||||
dir.Close()
|
||||
}
|
||||
for _, e := range emunames {
|
||||
if len(e) <= 4 {
|
||||
continue
|
||||
}
|
||||
ext := e[len(e)-4:]
|
||||
emu := Emu{
|
||||
ID: fmt.Sprintf("/emu/%s", e),
|
||||
Name: e[:len(e)-4],
|
||||
Type: "image/" + ext[1:],
|
||||
}
|
||||
allemus = append(allemus, emu)
|
||||
}
|
||||
sort.Slice(allemus, func(i, j int) bool {
|
||||
return allemus[i].Name < allemus[j].Name
|
||||
})
|
||||
}
|
||||
|
||||
func serve() {
|
||||
db := opendatabase()
|
||||
login.Init(login.InitArgs{Db: db, Logger: ilog, Insecure: develMode, SameSiteStrict: !develMode})
|
||||
|
@ -2428,6 +2476,7 @@ func serve() {
|
|||
go tracker()
|
||||
go bgmonitor()
|
||||
loadLingo()
|
||||
emuinit()
|
||||
|
||||
readviews = templates.Load(develMode,
|
||||
viewDir+"/views/honkpage.html",
|
||||
|
@ -2446,6 +2495,7 @@ func serve() {
|
|||
viewDir+"/views/msg.html",
|
||||
viewDir+"/views/header.html",
|
||||
viewDir+"/views/onts.html",
|
||||
viewDir+"/views/emus.html",
|
||||
viewDir+"/views/honkpage.js",
|
||||
)
|
||||
if !develMode {
|
||||
|
@ -2466,6 +2516,7 @@ func serve() {
|
|||
}
|
||||
|
||||
mux := mux.NewRouter()
|
||||
mux.Use(addcspheaders)
|
||||
mux.Use(login.Checker)
|
||||
|
||||
mux.Handle("/api", login.TokenRequired(http.HandlerFunc(apihandler)))
|
||||
|
@ -2503,6 +2554,7 @@ func serve() {
|
|||
getters.HandleFunc("/style.css", serveviewasset)
|
||||
getters.HandleFunc("/honkpage.js", serveviewasset)
|
||||
getters.HandleFunc("/wonk.js", serveviewasset)
|
||||
getters.HandleFunc("/misc.js", serveviewasset)
|
||||
getters.HandleFunc("/local.css", servedataasset)
|
||||
getters.HandleFunc("/local.js", servedataasset)
|
||||
getters.HandleFunc("/icon.png", servedataasset)
|
||||
|
@ -2545,6 +2597,7 @@ func serve() {
|
|||
loggedin.HandleFunc("/t", showconvoy)
|
||||
loggedin.HandleFunc("/q", showsearch)
|
||||
loggedin.HandleFunc("/hydra", webhydra)
|
||||
loggedin.HandleFunc("/emus", showemus)
|
||||
loggedin.Handle("/submithonker", login.CSRFWrap("submithonker", http.HandlerFunc(submithonker)))
|
||||
|
||||
err = http.Serve(listener, mux)
|
||||
|
|
Loading…
Reference in New Issue