user/admin blah
blah
This commit is contained in:
parent
675608c3fd
commit
4ef66e173f
@ -1,41 +1,3 @@
|
|||||||
let flashActive = false;
|
|
||||||
const flashTypes = [ "error", "success", "warn" ];
|
|
||||||
|
|
||||||
const flash = ({ type, msg }) => {
|
|
||||||
let flashContainer;
|
|
||||||
if(tmp = document.querySelector("div#flash"))
|
|
||||||
flashContainer = tmp;
|
|
||||||
else {
|
|
||||||
flashContainer = document.createElement("div");
|
|
||||||
flashContainer.id = "flash";
|
|
||||||
document.body.insertAdjacentElement("afterbegin", flashContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
flashContainer.innerHTML = msg;
|
|
||||||
if(flashTypes.includes(type)) {
|
|
||||||
flashContainer.className = "";
|
|
||||||
flashContainer.classList.add(type);
|
|
||||||
}
|
|
||||||
if(flashActive)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
flashActive = true;
|
|
||||||
flashContainer.animate(
|
|
||||||
[ { bottom: "-28px" }, { bottom: 0 } ], {
|
|
||||||
duration: 500,
|
|
||||||
fill: "both"
|
|
||||||
}
|
|
||||||
).onfinish = () => setTimeout(() => {
|
|
||||||
flashContainer.animate(
|
|
||||||
[ { bottom: 0 }, { bottom: "-28px" } ], {
|
|
||||||
duration: 500,
|
|
||||||
fill: "both"
|
|
||||||
}
|
|
||||||
).onfinish = () => flashActive = false;
|
|
||||||
}, 4 * 1e3);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
if(_addtag = document.querySelector("a#a_addtag")) {
|
if(_addtag = document.querySelector("a#a_addtag")) {
|
||||||
const postid = +document.querySelector("a.id-link").innerText;
|
const postid = +document.querySelector("a.id-link").innerText;
|
||||||
@ -140,10 +102,8 @@ const flash = ({ type, msg }) => {
|
|||||||
tagname: tmptag
|
tagname: tmptag
|
||||||
});
|
});
|
||||||
if(!res.success) {
|
if(!res.success) {
|
||||||
return flash({
|
alert(res.msg);
|
||||||
type: "error",
|
return false;
|
||||||
msg: res.msg
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
tags = res.tags.map(t => t.tag);
|
tags = res.tags.map(t => t.tag);
|
||||||
renderTags(res.tags);
|
renderTags(res.tags);
|
||||||
@ -202,12 +162,6 @@ const flash = ({ type, msg }) => {
|
|||||||
})).json();
|
})).json();
|
||||||
|
|
||||||
renderTags(res.tags);
|
renderTags(res.tags);
|
||||||
tags = res.tags.map(t => t.tag);
|
|
||||||
|
|
||||||
flash({
|
|
||||||
type: "success",
|
|
||||||
msg: tags.join()
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteButtonEvent = async e => {
|
const deleteButtonEvent = async e => {
|
||||||
@ -218,17 +172,8 @@ const flash = ({ type, msg }) => {
|
|||||||
const res = await post("/api/v2/admin/deletepost", {
|
const res = await post("/api/v2/admin/deletepost", {
|
||||||
postid: postid
|
postid: postid
|
||||||
});
|
});
|
||||||
if(res.success) {
|
if(!res.success) {
|
||||||
flash({
|
alert(res.msg);
|
||||||
type: "success",
|
|
||||||
msg: "post was successfully deleted"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
flash({
|
|
||||||
type: "error",
|
|
||||||
msg: res.msg
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
229
public/s/js/user.js
Normal file
229
public/s/js/user.js
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
(async () => {
|
||||||
|
if(_addtag = document.querySelector("a#a_addtag")) {
|
||||||
|
const postid = +document.querySelector("a.id-link").innerText;
|
||||||
|
const poster = document.querySelector("a#a_username").innerText;
|
||||||
|
let tags = [...document.querySelectorAll("#tags > .badge")].map(t => t.innerText.slice(0, -2));
|
||||||
|
|
||||||
|
const queryapi = async (url, data, method = 'GET') => {
|
||||||
|
let req;
|
||||||
|
if(method == 'POST') {
|
||||||
|
req = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let s = [];
|
||||||
|
for(const [ key, val ] of Object.entries(data))
|
||||||
|
s.push(encodeURIComponent(key) + "=" + encodeURIComponent(val));
|
||||||
|
req = await fetch(url + '?' + s.join('&'));
|
||||||
|
}
|
||||||
|
return await req.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
const get = async (url, data) => queryapi(url, data, 'GET');
|
||||||
|
const post = async (url, data) => queryapi(url, data, 'POST');
|
||||||
|
|
||||||
|
const renderTags = _tags => {
|
||||||
|
[...document.querySelectorAll("#tags > .badge")].forEach(tag => tag.parentElement.removeChild(tag));
|
||||||
|
_tags.reverse().forEach(tag => {
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.href = `/tag/${tag.normalized}`;
|
||||||
|
a.style = "color: inherit !important";
|
||||||
|
a.innerHTML = tag.tag;
|
||||||
|
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.classList.add("badge", "mr-2");
|
||||||
|
span.setAttribute('tooltip', tag.user);
|
||||||
|
|
||||||
|
tag.badge.split(" ").forEach(b => span.classList.add(b));
|
||||||
|
|
||||||
|
span.insertAdjacentElement("beforeend", a);
|
||||||
|
|
||||||
|
document.querySelector("#tags").insertAdjacentElement("afterbegin", span);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const addtagClick = (ae = false) => {
|
||||||
|
if(ae)
|
||||||
|
ae.preventDefault();
|
||||||
|
|
||||||
|
const insert = document.querySelector("a#a_addtag");
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.classList.add("badge", "badge-light", "mr-2");
|
||||||
|
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.size = "10";
|
||||||
|
input.value = "";
|
||||||
|
input.setAttribute("list", "testlist");
|
||||||
|
input.setAttribute("autoComplete", "off");
|
||||||
|
|
||||||
|
span.insertAdjacentElement("afterbegin", input);
|
||||||
|
insert.insertAdjacentElement("beforebegin", span);
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
|
||||||
|
let tt = null;
|
||||||
|
let lastInput = '';
|
||||||
|
const testList = document.querySelector('#testlist');
|
||||||
|
|
||||||
|
input.addEventListener("keyup", async e => {
|
||||||
|
if(e.key === "Enter") {
|
||||||
|
const tmptag = input.value?.trim();
|
||||||
|
if(tags.includes(tmptag))
|
||||||
|
return alert("tag already exists");
|
||||||
|
const res = await post("/api/v2/admin/" + postid + "/tags", {
|
||||||
|
tagname: tmptag
|
||||||
|
});
|
||||||
|
if(!res.success) {
|
||||||
|
alert(res.msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tags = res.tags.map(t => t.tag);
|
||||||
|
renderTags(res.tags);
|
||||||
|
addtagClick();
|
||||||
|
testList.innerText = "";
|
||||||
|
}
|
||||||
|
else if(e.key === "Escape") {
|
||||||
|
span.parentElement.removeChild(span);
|
||||||
|
testList.innerText = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(tt != null)
|
||||||
|
clearTimeout(tt);
|
||||||
|
|
||||||
|
tt = setTimeout(async () => {
|
||||||
|
tt = null;
|
||||||
|
|
||||||
|
const tmptag = input.value?.trim();
|
||||||
|
|
||||||
|
if(tmptag == lastInput || tmptag.length <= 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
testList.innerText = "";
|
||||||
|
lastInput = tmptag;
|
||||||
|
|
||||||
|
const res = await get('/api/v2/admin/tags/suggest', {
|
||||||
|
q: tmptag
|
||||||
|
});
|
||||||
|
|
||||||
|
for(const entry of res.suggestions) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = entry.tag;
|
||||||
|
|
||||||
|
if(!/fox/.test(navigator.userAgent))
|
||||||
|
option.innerText = `tagged ${entry.tagged} times (score: ${entry.score.toFixed(2)})`;
|
||||||
|
|
||||||
|
testList.insertAdjacentElement('beforeEnd', option);
|
||||||
|
};
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener("focusout", ie => {
|
||||||
|
if(input.value.length === 0)
|
||||||
|
input.parentElement.parentElement.removeChild(input.parentElement);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleEvent = async (e = false) => {
|
||||||
|
if(e)
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const res = await (await fetch('/api/v2/admin/' + encodeURIComponent(postid) + '/tags/toggle', {
|
||||||
|
method: 'PUT'
|
||||||
|
})).json();
|
||||||
|
|
||||||
|
renderTags(res.tags);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleFavEvent = async e => {
|
||||||
|
const res = await post('/api/v2/admin/togglefav', {
|
||||||
|
postid: postid
|
||||||
|
});
|
||||||
|
if(res.success) {
|
||||||
|
const fav = document.querySelector("svg#a_favo > use").href;
|
||||||
|
fav.baseVal = '/s/img/iconset.svg#heart_' + (fav.baseVal.match(/heart_(regular|solid)$/)[1] == "solid" ? "regular" : "solid");
|
||||||
|
|
||||||
|
// span#favs
|
||||||
|
const favcontainer = document.querySelector('span#favs');
|
||||||
|
favcontainer.innerHTML = "";
|
||||||
|
|
||||||
|
favcontainer.hidden = !(favcontainer.hidden || res.favs.length > 0);
|
||||||
|
|
||||||
|
res.favs.forEach(f => {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = `/user/${f.user}/favs`;
|
||||||
|
a.setAttribute('tooltip', f.user);
|
||||||
|
a.setAttribute('flow', 'up');
|
||||||
|
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = `/t/${f.avatar}.webp`;
|
||||||
|
img.style.height = "32px";
|
||||||
|
img.style.width = "32px";
|
||||||
|
|
||||||
|
a.insertAdjacentElement('beforeend', img);
|
||||||
|
favcontainer.insertAdjacentElement('beforeend', a);
|
||||||
|
favcontainer.innerHTML += " ";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// lul
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_addtag.addEventListener("click", addtagClick);
|
||||||
|
document.querySelector("a#a_toggle").addEventListener("click", toggleEvent);
|
||||||
|
document.querySelector("svg#a_favo").addEventListener("click", toggleFavEvent);
|
||||||
|
|
||||||
|
document.addEventListener("keyup", e => {
|
||||||
|
if(e.target.tagName === "INPUT")
|
||||||
|
return;
|
||||||
|
if(e.key === "p")
|
||||||
|
toggleEvent();
|
||||||
|
else if(e.key === "i")
|
||||||
|
addtagClick();
|
||||||
|
else if(e.key === "x")
|
||||||
|
deleteButtonEvent();
|
||||||
|
else if(e.key === "f")
|
||||||
|
toggleFavEvent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(document.location.pathname === '/settings') {
|
||||||
|
const saveAvatar = async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const avatar = +document.querySelector('input[name="i_avatar"]').value;
|
||||||
|
let res = await fetch('/api/v2/settings/setAvatar', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ avatar })
|
||||||
|
});
|
||||||
|
const code = res.status;
|
||||||
|
res = await res.json();
|
||||||
|
|
||||||
|
switch(code) {
|
||||||
|
case 200:
|
||||||
|
document.querySelector('#img_avatar').src = `/t/${avatar}.webp`;
|
||||||
|
document.querySelector('img.avatar').src = `/t/${avatar}.webp`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log(res);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.querySelector('input#s_avatar').addEventListener('click', saveAvatar);
|
||||||
|
document.querySelector('input[name="i_avatar"]').addEventListener('keyup', async e => {
|
||||||
|
if(e.key === 'Enter')
|
||||||
|
await saveAvatar(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
@ -1,7 +1,11 @@
|
|||||||
@if(session)<!--<div style="position: fixed; bottom: 0; z-index: 998; background-color: var(--bg); width: 100%; height: 29px; border-top: 1px solid var(--accent)">{{ JSON.stringify(session) }}</div>-->@endif
|
@if(session)<div style="position: fixed; bottom: 0; z-index: 998; background-color: var(--bg); width: 100%; height: 29px; border-top: 1px solid var(--accent)">{{ JSON.stringify(session) }}</div>@endif
|
||||||
<script async src="/s/js/theme.js?v=@mtime(/public/s/js/theme.js)"></script>
|
<script async src="/s/js/theme.js?v=@mtime(/public/s/js/theme.js)"></script>
|
||||||
<script src="/s/js/v0ck.js?v=@mtime(/public/s/js/v0ck.js)"></script>
|
<script src="/s/js/v0ck.js?v=@mtime(/public/s/js/v0ck.js)"></script>
|
||||||
<script src="/s/js/f0ck.js?v=@mtime(/public/s/js/f0ck.js)"></script>
|
<script src="/s/js/f0ck.js?v=@mtime(/public/s/js/f0ck.js)"></script>
|
||||||
@if(session)<script src="/s/js/admin.js?v=@mtime(/public/s/js/admin.js)"></script>@endif
|
@if(session && session.admin)
|
||||||
|
<script src="/s/js/admin.js?v=@mtime(/public/s/js/admin.js)"></script>
|
||||||
|
@elseif(session && !session.admin)
|
||||||
|
<script src="/s/js/user.js?v=@mtime(/public/s/js/user.js)"></script>
|
||||||
|
@endif
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user