Tag creation for approved users
This commit is contained in:
parent
bccc0ef742
commit
61fd417013
27
core.lua
27
core.lua
@ -65,6 +65,31 @@ local handler = function(req, res)
|
||||
res:statusCode(403)
|
||||
end
|
||||
res:write""
|
||||
elseif req:path():match"^/addtags/?$" then
|
||||
if verified and verified.privs >= DB.USER_PRIVS_APPROVED then
|
||||
local pohst = req:post()
|
||||
|
||||
local returndata = {}
|
||||
|
||||
if pohst.csrf and DB.csrfverify(verified.id, Escapes.urlunescape(pohst.csrf)) then
|
||||
local names = pohst["name[]"]
|
||||
local tcs = pohst["tc[]"]
|
||||
local adults = pohst["adult[]"]
|
||||
|
||||
if #names == #tcs and #names == #adults then
|
||||
for tag = 1, #names do
|
||||
local tagid = DB.tagadd(tostring(names[tag]), (tonumber(tcs[tag]) or 0) + 1, tostring(adults[tag]) == "1")
|
||||
table.insert(returndata, tagid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
res:statusCode(200)
|
||||
res:write(table.concat(returndata, ","))
|
||||
else
|
||||
res:statusCode(403)
|
||||
res:write""
|
||||
end
|
||||
elseif req:path():match"^/verif/?$" then
|
||||
res:addHeader("Set-Cookie", "sesh=" .. (req.querystring.q or "") .. "; SameSite=Lax; Secure; HttpOnly")
|
||||
res:addHeader("Location", "/")
|
||||
@ -183,4 +208,4 @@ local handler = function(req, res)
|
||||
end
|
||||
end
|
||||
|
||||
return handler
|
||||
return handler
|
||||
|
6
db.lua
6
db.lua
@ -416,7 +416,11 @@ local function tagadd(name, category, adultonly)
|
||||
|
||||
pingdb()
|
||||
|
||||
return not not SQLConn:execute("INSERT INTO tags (name, category, adultonly) VALUES ('" .. SQLConn:escape(name) .. "', " .. category .. ", " .. (adultonly and 1 or 0) .. ");")
|
||||
local cur = SQLConn:execute("INSERT INTO tags (name, category, adultonly) VALUES ('" .. SQLConn:escape(name) .. "', " .. category .. ", " .. (adultonly and 1 or 0) .. ");")
|
||||
|
||||
if not cur then return nil end
|
||||
|
||||
return tonumber(SQLConn:getlastautoid())
|
||||
end
|
||||
|
||||
local function regnewobj(ownerid, approved, published)
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% title = BigGlobe.cfg.sitename .. " - generic object database inspired by imageboards" %}
|
||||
|
||||
{% function content() %}
|
||||
<div style="text-align:center;height:50%;margin-top:25%;">
|
||||
<div style="text-align:center;height:50%;margin-top:25vh;">
|
||||
<div style="max-width:15cm;display:inline-block;">
|
||||
<h1>{{ Escapes.htmlescape(BigGlobe.cfg.sitename) }}</h1>
|
||||
<form action="/search" method="GET" id="searchform">
|
||||
@ -81,4 +81,4 @@
|
||||
|
||||
{% end %}
|
||||
|
||||
{# base.inc
|
||||
{# base.inc
|
||||
|
10
obj.html.l
10
obj.html.l
@ -4,6 +4,8 @@
|
||||
obj = DB.getobj(DB.objshowid(request:path():sub(7, 7 + 31)))
|
||||
end
|
||||
|
||||
local filecount = 0
|
||||
|
||||
if obj then
|
||||
local virt = "/objd/" .. DB.objhideid(obj.id) .. "/"
|
||||
local phys = DB.urltophysical(virt)
|
||||
@ -13,6 +15,10 @@
|
||||
if f ~= "." and f ~= ".." then
|
||||
local attribs = LFS.attributes(phys .. f)
|
||||
table.insert(files, {name = f, size = attribs.size, modtime = attribs.modification, phys = phys .. f, virt = virt .. f})
|
||||
|
||||
if f ~= ".thumb.jpg" then
|
||||
filecount = filecount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -41,7 +47,7 @@
|
||||
<div style="display:inline-block;width:40%;vertical-align:top;">
|
||||
<h2 style="margin-bottom:0;">{{ Escapes.htmlescape(obj.name) }}{% if verified and verified.id == obj.owner then %} <a href="/obje/{{ DB.objhideid(obj.id) }}">(edit)</a>{% end %}</h2>
|
||||
<h5 style="margin-top:0;"><sup><a href="/user/{{ obj.owner }}">{{ Escapes.htmlescape(owner.displayname) }}</a> <span class="dt">{{ obj.createtime }}</span></sup></h5>
|
||||
<p>Object has {{#files-1}} files:</p>
|
||||
<p>Object has {{filecount}} files:</p>
|
||||
<ul id="filelist">
|
||||
{% for _,f in pairs(files) do %}
|
||||
{% if f.name ~= ".thumb.jpg" then %}<li><a onmouseenter="hover(this);" download href="{{ Escapes.htmlescape(f.virt) }}">{{ Escapes.htmlescape(f.name) }}</a> ({{ (f.size + 1023) // 1024 }}kB)</li>{% end %}
|
||||
@ -159,4 +165,4 @@
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
{# base.inc
|
||||
{# base.inc
|
||||
|
102
obje.html.l
102
obje.html.l
@ -147,7 +147,7 @@
|
||||
</div>
|
||||
<div style="display:inline-block;vertical-align:top;width:49%;">
|
||||
<h2>Tags</h2>
|
||||
<div style="position:relative;width:80%;" class="tagbox" data-formid="editform" data-formparaminputid="objtagsparam">
|
||||
<div style="position:relative;width:80%;" class="tagbox" data-formid="editform" data-formparaminputid="objtagsparam" data-unknowntags="">
|
||||
<p{% if tagcount > 0 then %} style="visibility:hidden;"{% end %}>Enter tags...</p>
|
||||
{% for _, tag in pairs(tags) do %}
|
||||
<div class="tag tc{{ tag.category }}" data-tagid="{{ tag.id }}">{{ Escapes.htmlescape(tag.name) }}</div>
|
||||
@ -175,15 +175,28 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="newtagsform" class="hidden">
|
||||
<p>There are unknown tags in your submission. Please assign them categories.</p>
|
||||
|
||||
<table>{% --[[
|
||||
<select style="border: 0;"><option value="a">A</option><option value="b">B</option></select>
|
||||
]] %}</table>
|
||||
|
||||
<button>Submit</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{% if BigGlobe.cfg.enable18plus then %}
|
||||
function upd(over18) {
|
||||
document.querySelector(".tagbox").setAttribute("data-over18", +over18 != -1)
|
||||
}
|
||||
var activeo18 = "-1"
|
||||
var activeo18
|
||||
if(window.localStorage.getItem("o18")) {
|
||||
activeo18 = window.localStorage.getItem("o18")
|
||||
}
|
||||
if(!activeo18 || activeo18 == 1) {
|
||||
activeo18 = 0; // Make "Show 18+", not "Only 18+"
|
||||
}
|
||||
upd(activeo18)
|
||||
document.querySelector("ul.over18 input[type=\"radio\"][value=\"" + activeo18 + "\"]").checked = true
|
||||
{% end %}
|
||||
@ -330,13 +343,92 @@
|
||||
xhr.send(formData)
|
||||
}
|
||||
|
||||
function fixnewtags(afterfunc) {
|
||||
var newtagsform = document.querySelector("div#newtagsform")
|
||||
var tbl = newtagsform.querySelector("table")
|
||||
|
||||
var newTags = document.querySelectorAll("div.tagbox div.tag.tcNew")
|
||||
|
||||
for(var i = 0; i < newTags.length; i++) {
|
||||
var row = tbl.insertRow(-1)
|
||||
|
||||
var sel = document.createElement("select")
|
||||
{% for tc = 1, #BigGlobe.cfg.tc do if BigGlobe.cfg.tc[tc].name ~= "" then %}
|
||||
{
|
||||
var opt = document.createElement("option")
|
||||
opt.textContent = "{{ Escapes.htmlescape(BigGlobe.cfg.tc[tc].name) }}"
|
||||
opt.value = {{ tc - 1 }}
|
||||
sel.appendChild(opt)
|
||||
}
|
||||
{% end end %}
|
||||
|
||||
var adult = document.createElement("input")
|
||||
adult.type = "checkbox"
|
||||
adult.checked = false
|
||||
adult.id = "boobietc" + i
|
||||
|
||||
var adultLbl = document.createElement("label")
|
||||
adultLbl.htmlFor = adult.id
|
||||
adultLbl.textContent = "18+"
|
||||
|
||||
row.insertCell(-1).appendChild(sel)
|
||||
row.insertCell(-1).textContent = newTags[i].textContent
|
||||
|
||||
var c = row.insertCell(-1)
|
||||
c.appendChild(adult)
|
||||
c.appendChild(adultLbl)
|
||||
}
|
||||
|
||||
newtagsform.classList.toggle("hidden")
|
||||
|
||||
var btn = newtagsform.querySelector("button")
|
||||
|
||||
btn.onclick = function() {
|
||||
btn.toggleAttribute("disabled")
|
||||
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open("POST", "/addtags", true)
|
||||
|
||||
var formData = new FormData()
|
||||
formData.append("csrf", document.querySelector("[name='csrf']").value)
|
||||
|
||||
for(var i = 0; i < newTags.length; i++) {
|
||||
formData.append("name[]", tbl.rows[i].cells[1].textContent)
|
||||
formData.append("tc[]", tbl.rows[i].cells[0].querySelector("select").value)
|
||||
formData.append("adult[]", tbl.rows[i].cells[2].querySelector("input").checked ? "1" : "0")
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
|
||||
var resp = xhr.responseText.split(",")
|
||||
|
||||
// Set data-tagids so they object may be updated with the new tags
|
||||
for(var i = 0; i < newTags.length; i++) {
|
||||
newTags[i].setAttribute("data-tagid", resp[i])
|
||||
}
|
||||
|
||||
tagbox_updateformdata()
|
||||
|
||||
afterfunc()
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send(formData);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("editform").addEventListener("submit", function(ev) {
|
||||
ev.preventDefault()
|
||||
|
||||
files = Array.from(document.querySelectorAll("input[type='file']"))
|
||||
files.pop() // don't count empty input
|
||||
files.pop() // don't count empty input box
|
||||
|
||||
doremoves()
|
||||
var newTags = document.querySelectorAll("div.tagbox div.tag.tcNew")
|
||||
if(newTags.length != 0) {
|
||||
fixnewtags(doremoves)
|
||||
} else {
|
||||
doremoves()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<script src="/static/tagbox.js"></script>
|
||||
@ -348,4 +440,4 @@
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
{# base.inc
|
||||
{# base.inc
|
||||
|
@ -153,7 +153,15 @@ function Request:parseMultipartFormData(data)
|
||||
}
|
||||
end
|
||||
else
|
||||
output[name] = itemdata
|
||||
if name:sub(#name - 1) == "[]" then
|
||||
if output[name] then
|
||||
table.insert(output[name], itemdata)
|
||||
else
|
||||
output[name] = {itemdata}
|
||||
end
|
||||
else
|
||||
output[name] = itemdata
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -11,6 +11,7 @@ div.tagbox {
|
||||
user-select: contain;
|
||||
padding: 0.4em;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
div.tagbox::after {
|
||||
content: "penis";
|
||||
@ -113,6 +114,7 @@ input[type='text'], input[type='number'] {
|
||||
border: 1px solid gray;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input::placeholder {
|
||||
color: #C0C0C0;
|
||||
@ -125,6 +127,7 @@ ul.over18 {
|
||||
padding: 0 0.4em 0 0.4em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
ul.over18 label {
|
||||
cursor: pointer;
|
||||
@ -210,4 +213,27 @@ footer {
|
||||
margin-top: 2em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
div.tag.tcNew::before {
|
||||
content: "New";
|
||||
}
|
||||
|
||||
div#newtagsform {
|
||||
position: fixed;
|
||||
width: 50vw;
|
||||
height: 50vh;
|
||||
top: 25vh;
|
||||
left: 25vw;
|
||||
background: white;
|
||||
border: 1px solid black;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
div#newtagsform select {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -1,13 +1,28 @@
|
||||
function createtag(name, tc, tagid) {
|
||||
var newtag = document.createElement("div")
|
||||
newtag.classList.toggle("tag")
|
||||
newtag.classList.toggle("tc" + (tc || "New"))
|
||||
if(tagid) {
|
||||
newtag.setAttribute("data-tagid", tagid)
|
||||
}
|
||||
newtag.innerText = name
|
||||
return newtag
|
||||
}
|
||||
|
||||
var acTimer;
|
||||
|
||||
document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formid")).addEventListener("submit", function(ev) {
|
||||
function tagbox_updateformdata() {
|
||||
document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formparaminputid")).value = Array.from(document.querySelectorAll("div.tagbox div.tag")).map(function(a) {return a.getAttribute("data-tagid")}).join(",")
|
||||
})
|
||||
}
|
||||
|
||||
document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formid")).addEventListener("submit", tagbox_updateformdata)
|
||||
|
||||
document.querySelector("div.tagbox").onclick = function(ev) {
|
||||
this.querySelector('span').focus()
|
||||
}
|
||||
|
||||
var UnknownTagsMode = document.querySelector("div.tagbox").getAttribute("data-unknowntags") !== null
|
||||
|
||||
document.querySelector("div.tagbox span").onkeydown = function(ev) {
|
||||
if(ev.keyCode == 13) {
|
||||
ev.preventDefault()
|
||||
@ -15,16 +30,18 @@ document.querySelector("div.tagbox span").onkeydown = function(ev) {
|
||||
if(document.querySelector("div.tagbox span").innerText.length) {
|
||||
var from = document.querySelector("div.autocomplete > div.tag.selected") || document.querySelectorAll("div.autocomplete > div.tag")[0]
|
||||
|
||||
if(!document.querySelector("div.tagbox div.tag[data-tagid='"+from.getAttribute("data-tagid")+"']")) {
|
||||
from.classList.remove("selected")
|
||||
|
||||
document.querySelector("div.tagbox span").innerText = ""
|
||||
document.querySelector("div.tagbox").insertBefore(from, document.querySelector("div.tagbox span"))
|
||||
document.querySelector("div.tagbox").insertBefore(document.createTextNode("\n"), document.querySelector("div.tagbox span"))
|
||||
|
||||
var ac = document.querySelector(".autocomplete")
|
||||
ac.style.visibility = "hidden"
|
||||
if(from) {
|
||||
if(!document.querySelector("div.tagbox div.tag[data-tagid='"+from.getAttribute("data-tagid")+"']")) {
|
||||
from.classList.remove("selected")
|
||||
|
||||
document.querySelector("div.tagbox").insertBefore(from, document.querySelector("div.tagbox span"))
|
||||
document.querySelector("div.tagbox").insertBefore(document.createTextNode("\n"), document.querySelector("div.tagbox span"))
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector("div.tagbox span").innerText = ""
|
||||
var ac = document.querySelector(".autocomplete")
|
||||
ac.style.visibility = "hidden"
|
||||
} else {
|
||||
document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formid")).querySelector("input[type='submit']").click()
|
||||
}
|
||||
@ -75,16 +92,17 @@ document.querySelector("div.tagbox span").oninput = function(ev) {
|
||||
var ac = document.querySelector(".autocomplete")
|
||||
ac.style.visibility = ""
|
||||
while(ac.firstChild) ac.removeChild(ac.firstChild)
|
||||
if(ajax.responseText == "") {
|
||||
if(!UnknownTagsMode && ajax.responseText == "") {
|
||||
ac.innerText = "No such tags found"
|
||||
} else ajax.responseText.split("\n").slice(0, -1).forEach(function(line) {
|
||||
var newtag = document.createElement("div")
|
||||
newtag.classList.toggle("tag")
|
||||
newtag.classList.toggle("tc" + line.split(",")[2])
|
||||
newtag.setAttribute("data-tagid", line.split(",")[0])
|
||||
newtag.innerText = line.split(",")[1]
|
||||
ac.insertBefore(newtag, null)
|
||||
})
|
||||
} else {
|
||||
ajax.responseText.split("\n").slice(0, -1).forEach(function(line) {
|
||||
ac.insertBefore(createtag(line.split(",")[1], line.split(",")[2], line.split(",")[0]), null)
|
||||
})
|
||||
|
||||
if(UnknownTagsMode) {
|
||||
ac.insertBefore(createtag(document.querySelector("div.tagbox span").innerText, null, null), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ajax.send()
|
||||
@ -97,4 +115,4 @@ document.querySelector("div.tagbox span").oninput = function(ev) {
|
||||
clearTimeout(acTimer)
|
||||
acTimer = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user