Skip to content

Commit

Permalink
added search input component
Browse files Browse the repository at this point in the history
needs improvement + functionalities
  • Loading branch information
ShadowLp174 committed Nov 21, 2023
1 parent 32ec60a commit 0b7448f
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 13 deletions.
12 changes: 0 additions & 12 deletions dashboard/static/css/Player.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
scroll-behavior: smooth;
}


.suggestion-li {
cursor: pointer;
}
.slider {
-webkit-appearance: none;
appearance: none;
Expand Down Expand Up @@ -80,14 +76,6 @@
flex-grow: 2;
text-align: left;
}
.queue-container.minimised {
display: none;
}
.queue:empty:after {
content: "Empty";
/*color: rgb(19, 25, 39);*/
font-size: 70%;
}
/*.queue > * {
transition: 1s all;
}*/
Expand Down
51 changes: 51 additions & 0 deletions dashboard/static/css/SearchInput.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@200;300;400;500;600;700;800;900;1000&display=swap');

* {
font-family: 'Cairo', sans-serif;
}

input {
margin: 10px 0 0;
padding: 5px;
padding-left: 7px;
padding-right: 7px;
align-self: center;
border: none;
border-radius: 5px;
font-size: 16px;
width: 100%;
max-width: 400px;
background-color: rgb(19, 25, 39);
border-color: #bbb;

color: white;
/*transition: all 0.2s ease-in-out;*/
}

input::placeholder {
/*color: white;*/
}

ul {
background-color: rgb(19, 25, 39);
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.4);
border-radius: 5px;
/*0 0 5px 5px;*/
position: absolute;
display: none;
top: 0;
left: 50%;
transform: translateX(-50%);
algin-self: center;
width: 100%;
max-width: 400px;
padding: 5px;
margin: 0;
list-style-type: none;
margin: none;
text-align: left;
}

li {
cursor: pointer;
}
4 changes: 4 additions & 0 deletions dashboard/static/js/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,16 @@ class Player extends HTMLElement {
slContainer.append(vI);

const search = document.createElement("search-input");
search.addEventListener("result", console.log)
// TODO: implement full window search
cCon.append(search);

const queue = document.createElement("remix-queue");
queue.style = "grid-row: 2; grid-column-start: 1; grid-column-end: 4";
this.queue = queue;
c.append(queue);

// TODO: maximising/minimising player (together with lazy loading)
}
attributeChangedCallback(name, oldVal, newVal) {
if (name !== "disabled") return;
Expand Down
117 changes: 116 additions & 1 deletion dashboard/static/js/SearchInput.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,125 @@
class SearchInput extends HTMLElement {
completionsElem = null;
inputElem = null;

runningRequest = false;

constructor() {
super();
}
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = "TODO: search input component"

const styles = document.createElement("link");
styles.rel = "stylesheet";
styles.href = "/css/SearchInput.css";
shadow.append(styles);

const c = document.createElement("div"); // container
c.style = "position: relative; display: flex; flex-direction: column";
c.classList.add("search-container");
shadow.append(c);

const input = document.createElement("input");
input.type = "text";
input.name = "search";
input.placeholder = "Search or paste a link";
input.autocomplete = "off";
input.addEventListener("keyup", (e) => { this.#keyUp(e) });
this.inputElem = input;
c.append(input);

const completionCon = document.createElement("div");
completionCon.style = "position: relative; align-self: center; width: 100%";
c.append(completionCon);

const completions = document.createElement("ul");
this.completionsElem = completions;
completionCon.appendChild(completions);

// TODO: register clicks outside of input --> blurring

window.addEventListener("click", (e) => {
//if (!e.target.matches(".search-container > *")) return this.#reset();
// TODO: fix this
});
}

#isValidUrl(str) {
var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name

Check failure

Code scanning / CodeQL

Inefficient regular expression High

This part of the regular expression may cause exponential backtracking on strings starting with '0' and containing many repetitions of '0'.
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
return !!pattern.test(str);
}

#dispatchSearch(string) {
const data = {
raw: string,
url: this.#isValidUrl(string)
}

const event = new CustomEvent("result", {
detail: data,
composed: true
});
this.dispatchEvent(event);
}
#reset() {
this.completionsElem.style.display = "none";
this.inputElem.blur();
// TODO: consider the following:
//this.inputElem.value = "";
}

#getSuggestions(query) {
return new Promise(res => {
const script = document.createElement("script");
script.async = true;
const cname = "suggestion" + (Math.random() + "").replaceAll(".", "");
window[cname] = (data) => {
res(data[1]);
script.remove();
delete window[cname];
}
script.src = "https://suggestqueries.google.com/complete/search?client=firefox&ds=yt&q=" + encodeURIComponent(query) + "&callback=" + cname; // "hl" parameter for locale
this.shadowRoot.appendChild(script);
});
}

#createSuggestionItem(content) {
// TODO: match width to input width
const li = document.createElement("li");
li.innerText = content;
li.setAttribute("suggestion", content);
li.classList.add("suggestion-li");
li.addEventListener("click", () => {
// TODO: dispatch result
});
return li;
}

async #keyUp(e) {
if (e.code === "Enter") {
e.preventDefault();
this.#dispatchSearch(e.target.value);
this.#reset();
return;
}
const i = this.inputElem;
if (i.value === "") this.#reset();
if (this.runningRequest) return;
this.runningRequest = true;

const data = await this.#getSuggestions(i.value);
this.completionsElem.innerHTML = "";
this.completionsElem.style.display = "block";
data.forEach(suggestion => {
this.completionsElem.append(this.#createSuggestionItem(suggestion));
});
this.runningRequest = false;
}
}

Expand Down

0 comments on commit 0b7448f

Please sign in to comment.