added search page

This commit is contained in:
Mystikfluu 2022-06-07 09:16:17 +02:00
parent 2632d8c133
commit e6617fecc5
11 changed files with 201 additions and 129 deletions

12
css/search.css Normal file
View File

@ -0,0 +1,12 @@
* {
font-family: Arial, Helvetica, sans-serif;
}
body {
background-color: black;
color: black;
}
.form_div {
text-align: center;
}

View File

@ -1,87 +1,12 @@
(function(funcName, baseObj) {
"use strict";
// The public function name defaults to window.docReady
// but you can modify the last line of this function to pass in a different object or method name
// if you want to put them in a different namespace and those will be used instead of
// window.docReady(...)
funcName = funcName || "docReady";
baseObj = baseObj || window;
var readyList = [];
var readyFired = false;
var readyEventHandlersInstalled = false;
// call this when the document is ready
// this function protects itself against being called more than once
function ready() {
if (!readyFired) {
// this must be set to true before we start calling callbacks
readyFired = true;
for (var i = 0; i < readyList.length; i++) {
// if a callback here happens to add new ready handlers,
// the docReady() function will see that it already fired
// and will schedule the callback to run right after
// this event loop finishes so all handlers will still execute
// in order and no new ones will be added to the readyList
// while we are processing the list
readyList[i].fn.call(window, readyList[i].ctx);
}
// allow any closures held by these functions to free
readyList = [];
}
}
function readyStateChange() {
if ( document.readyState === "complete" ) {
ready();
}
}
// This is the one public interface
// docReady(fn, context);
// the context argument is optional - if present, it will be passed
// as an argument to the callback
baseObj[funcName] = function(callback, context) {
if (typeof callback !== "function") {
throw new TypeError("callback for docReady(fn) must be a function");
}
// if ready has already fired, then just schedule the callback
// to fire asynchronously, but right away
if (readyFired) {
setTimeout(function() {callback(context);}, 1);
return;
} else {
// add the function and context to the list
readyList.push({fn: callback, ctx: context});
}
// if document already ready to go, schedule the ready function to run
// IE only safe when readyState is "complete", others safe when readyState is "interactive"
if (document.readyState === "complete" || (!document.attachEvent && document.readyState === "interactive")) {
setTimeout(ready, 1);
} else if (!readyEventHandlersInstalled) {
// otherwise if we don't have event handlers installed, install them
if (document.addEventListener) {
// first choice is DOMContentLoaded event
document.addEventListener("DOMContentLoaded", ready, false);
// backup is window load event
window.addEventListener("load", ready, false);
} else {
// must be IE
document.attachEvent("onreadystatechange", readyStateChange);
window.attachEvent("onload", ready);
}
readyEventHandlersInstalled = true;
}
}
})("docReady", window);
const navbar = `<ul class="navbar">
<li><a href="/">Home</a></li>
<li><a href="/user">Profile</a></li>
<li><a href="/posts">Posts</a></li>
<li><a href="/user" id="hide_user">Profile</a></li>
<li><a href="/posts" id="hide_posts">Posts</a></li>
<li><a href="/search" id="hide_search">Search</a></li>
</ul>`
function addnavbar() {
document.body.innerHTML = navbar + document.body.innerHTML
}
window.docReady(addnavbar)
document.addEventListener("DOMContentLoaded", addnavbar)

View File

@ -13,6 +13,8 @@ const esca = {
const pe = m => esca[m];
const escape = es => replace.call(es, ca, pe);
const htmlesc = es => replace.call(es, ca, pe);
const unes = {
'&amp;': '&',

View File

@ -6,6 +6,6 @@ window.addEventListener("load",async function(){
document.getElementById("NoAccount").style=""
document.getElementById("hide_user").style="display:none;"
document.getElementById("hide_posts").style="display:none;"
document.getElementById("hide_search").style="display:none;"
}
})

46
js/markdown.js Normal file
View File

@ -0,0 +1,46 @@
function urlify(text) {
let textregex = /(([a-z]+:\/\/)(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal|tk|ga|xxx|to))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi
return text.replace(textregex,'<a href="$1" target="_blank" class="insertedlink">$1</a> ')
}
function newlineify(text) {
let textregex = /(\n)/gi
return text.replace(textregex,' <br>')
}
function crossout(text) {
let textregex = /~([^~]*)~/gi
return text.replace(textregex,'<span class="crossout">$1</span>')
}
function italicify(text) {
let textregex = /\*([^\*]*)\*/gi
return text.replace(textregex,'<i>$1</i> ')
}
function boldify(text) {
let textregex = /\*\*([^\*]*)\*\*/gi
return text.replace(textregex,'<b>$1</b> ')
}
function filterMentions(text) {
let textregex = /(@[^\s]*)/gi //if you find an "@" select everything until you find a whitespace (and save as $1)
return text.replace(textregex,`<span><a href="/users/$1" class="mention">$1</a></span> `)
}
function filterReplies(text) {
let textregex = /_@_([^\s]*)/gi
return text.replace(textregex,`<span><a href="/users/$1" class="reply" style="color: pink;">$1</a></span> `)
}
function filterPost(text) {
text = htmlesc(text)
text = newlineify(text)
text = urlify(text)
text = filterReplies(text)
text = filterMentions(text)
text = crossout(text)
text = boldify(text)
text = italicify(text)
return text
}

View File

@ -14,41 +14,9 @@ socket.addEventListener("message", function (event) {
}
}
})
function urlify(text) {
let textregex = /(([a-z]+:\/\/)(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal|tk|ga|xxx|to))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi
return text.replace(textregex,'<a href="$1" target="_blank" class="insertedlink">$1</a> ')
}
function newlineify(text) {
let textregex = /(\n)/gi
return text.replace(textregex,' <br>')
}
function crossout(text) {
let textregex = /~([^~]*)~/gi
return text.replace(textregex,'<span class="crossout">$1</span>')
}
function italicify(text) {
let textregex = /\*([^\*]*)\*/gi
return text.replace(textregex,'<i>$1</i> ')
}
function boldify(text) {
let textregex = /\*\*([^\*]*)\*\*/gi
return text.replace(textregex,'<b>$1</b> ')
}
function filterMentions(text) {
let textregex = /(@[^\s]*)/gi //if you find an "@" select everything until you find a whitespace (and save as $1)
return text.replace(textregex,`<span><a href="/users/$1" class="mention">$1</a></span> `)
}
function filterReplies(text) {
let textregex = /_@_([^\s]*)/gi
return text.replace(textregex,`<span><a href="/users/$1" class="reply" style="color: pink;">$1</a></span> `)
}
document.getElementById("post-btn").addEventListener("click",async function() {
async function postMessage() {
let len = document.getElementById("post-text").value.length
if(len >= 1001) {
alert(`Error, your message cant contain more than 1000 characters! (${len})`)
@ -57,21 +25,10 @@ document.getElementById("post-btn").addEventListener("click",async function() {
let r = await post("/api/post",{"message":document.getElementById("post-text").value})
if(window.location.href.split("?mention=")[1])location.replace('/posts');
document.getElementById("post-text").value=""
})
function filterPost(text) {
text = escape(text)
text = newlineify(text)
text = urlify(text)
text = filterReplies(text)
text = filterMentions(text)
text = crossout(text)
text = boldify(text)
text = italicify(text)
return text
}
document.getElementById("post-btn").addEventListener("click",postMessage)
function spacerTextNode() {
return document.createTextNode(" | ")
}

80
js/search.js Normal file
View File

@ -0,0 +1,80 @@
const valuetoText = {
["user"]:"Username",
["post"]:"Post"
}
function changed() {
document.getElementById("selector").placeholder = valuetoText[document.getElementById("type").value];
}
async function getJSON(url) {
return await(await fetch(url)).json()
}
async function submit() {
const type = document.getElementById("type").value
const selector = document.getElementById("selector").value
document.getElementById("output").innerHTML=""
const res = await getJSON(`/api/search?type=${type}&selector=${selector}`)
//document.getElementById("output").innerHTML = res
console.log(res);
for (let i = 0; i < res.length; i++) {
let obj = res[i]
if(type=="user") {
createPost(obj.User_Name,obj.User_Bio || "wow such empty",0)
} else {
createPost(decodeURIComponent(obj.post_user_name),decodeURIComponent(obj.post_text),obj.post_time,obj.post_special_text,obj.post_id)
}
}
}
function keydown(event) {
if (event.key === "Enter") {
event.preventDefault()
submit()
}
}
function spacerTextNode() {
return document.createTextNode(" | ")
}
function createPost(username,text,time,specialtext,postid) {
if(!specialtext)specialtext=""
const newDiv = document.createElement("div");
const newP = document.createElement("p");
const newA = document.createElement("a");
const newSpan2 = document.createElement("span");
const newSpan3 = document.createElement("span");
const newUsername = document.createTextNode(username);
let timedate = new Date(time)
time = timedate
time = time.toString()
time = time.split(" ")
time = time[0] + " " + time[1] + " " + time[2] + " " + time[3] + " " + time[4]
if(timedate=="Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)")time=""
const newTime = document.createTextNode(time)
const newSpecialText = document.createTextNode(specialtext)
newDiv.classList.add("result");
newSpan3.classList.add("specialtext")
newA.appendChild(newUsername)
newA.href = `/users/${username}`
newSpan2.appendChild(newTime)
newSpan3.appendChild(newSpecialText)
newP.appendChild(newA)
if(time != "")newP.appendChild(spacerTextNode())
newP.appendChild(newSpan2)
if(specialtext != "" && time != "")newP.appendChild(spacerTextNode())
newP.appendChild(newSpan3)
newDiv.appendChild(newP)
newDiv.innerHTML += filterPost(text)
newDiv.id = postid
document.getElementById("output").appendChild(newDiv)
}

View File

@ -9,6 +9,7 @@
}
</script>
<script src="/js/addnavbar.js" charset="utf-8"></script>
<link rel="stylesheet" href="/css/global.css">
</head>
<body>

View File

@ -7,14 +7,15 @@
<link rel="stylesheet" href="/css/global.css">
<script type="text/javascript" src="/js/httppost.js"></script>
<script type="text/javascript" src="/js/htmlescape.js"></script>
<script src="/js/addnavbar.js" charset="utf-8"></script>
<script type="text/javascript" src="/js/addnavbar.js"></script>
<script type="text/javascript" src="/js/markdown.js"></script>
</head>
<body>
<div class="self">
Username: <span class="Username" id="username-self"></span> <br>
<textarea name="name" id="post-text" rows="8" cols="80"></textarea>
<br>
<button type="button" name="button" id="post-btn">Post</button>
<button type="button" name="button" id="post-btn" onclick="postMessage()">Post</button>
</div>
<div class="posts" id="posts"></div>
<script type="text/javascript" src="/js/posts.js"></script>

View File

@ -9,8 +9,8 @@
}
</script>
<script src="/js/addnavbar.js" charset="utf-8"></script>
<link rel="stylesheet" href="/css/global.css">
</head>
<body>
<header>
<h1>Register</h1>

48
views/search.html Normal file
View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search</title>
<link rel="stylesheet" href="/css/search.css">
<script type="text/javascript" src="/js/htmlescape.js"></script>
<link rel="stylesheet" href="/css/global.css">
<script src="/js/httppost.js" charset="utf-8"></script>
<script src="/js/addnavbar.js" charset="utf-8"></script>
<script src="/js/search.js" charset="utf-8"></script>
<script type="text/javascript" src="/js/markdown.js"></script>
<style media="screen">
.result {
background-color: darkgray;
width: 50%;
margin-left: 25%;
margin-right: 25%;
margin-top: 10px;
margin-bottom: 10px;
border-radius: 10px;
overflow-wrap: break-word;
padding-left: 5px;
padding-bottom: 2px;
}
</style>
</head>
<body>
<main>
<div class="form_div form_class">
<select id="type" name="type" onchange="changed()">
<option value="user">Username</option>
<option value="post">Post</option>
</select>
<br>
<br>
<input type="text" name="selector" id="selector" value="" placeholder="UserName" onkeydown="keydown(event)">
</div>
<br>
<div id="output" class="form_class">
</div>
</main>
</body>
</html>