Feature update
-- Added new filtering UI
This commit is contained in:
parent
638d62b6b2
commit
71c712d81e
@ -1,3 +1,4 @@
|
||||
/*jshint esversion: 6 */
|
||||
//Button
|
||||
const smButton = document.createElement('template')
|
||||
smButton.innerHTML = `
|
||||
@ -1707,7 +1708,7 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
this.stripSelect = this.shadowRoot.querySelector('.strip-select')
|
||||
this.slottedOptions
|
||||
this._value
|
||||
this.scrollDistance = 300
|
||||
this.scrollDistance
|
||||
}
|
||||
get value() {
|
||||
return this._value
|
||||
@ -1743,13 +1744,14 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
const navButtonLeft = this.shadowRoot.querySelector('.nav-button--left')
|
||||
const navButtonRight = this.shadowRoot.querySelector('.nav-button--right')
|
||||
slot.addEventListener('slotchange', e => {
|
||||
slot.assignedElements().forEach(elem => {
|
||||
const assignedElements = slot.assignedElements()
|
||||
assignedElements.forEach(elem => {
|
||||
if (elem.hasAttribute('selected')) {
|
||||
elem.setAttribute('active', '')
|
||||
this._value = elem.value
|
||||
}
|
||||
})
|
||||
if (slot.assignedElements().length) {
|
||||
if (assignedElements.length > 0) {
|
||||
firstOptionObserver.observe(slot.assignedElements()[0])
|
||||
lastOptionObserver.observe(slot.assignedElements()[slot.assignedElements().length - 1])
|
||||
}
|
||||
@ -1758,8 +1760,23 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
navButtonRight.classList.add('hide')
|
||||
coverLeft.classList.add('hide')
|
||||
coverRight.classList.add('hide')
|
||||
firstOptionObserver.disconnect()
|
||||
lastOptionObserver.disconnect()
|
||||
}
|
||||
})
|
||||
const resObs = new ResizeObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.contentBoxSize) {
|
||||
// Firefox implements `contentBoxSize` as a single content rect, rather than an array
|
||||
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
|
||||
|
||||
this.scrollDistance = contentBoxSize.inlineSize * 0.6
|
||||
} else {
|
||||
this.scrollDistance = entry.contentRect.width * 0.6
|
||||
}
|
||||
})
|
||||
})
|
||||
resObs.observe(this)
|
||||
this.stripSelect.addEventListener('option-clicked', e => {
|
||||
if (this._value !== e.target.value) {
|
||||
this._value = e.target.value
|
||||
@ -1782,7 +1799,8 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
})
|
||||
},
|
||||
{
|
||||
threshold: 0.9
|
||||
threshold: 0.9,
|
||||
root: this
|
||||
})
|
||||
const lastOptionObserver = new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
@ -1797,7 +1815,8 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
})
|
||||
},
|
||||
{
|
||||
threshold: 0.9
|
||||
threshold: 0.9,
|
||||
root: this
|
||||
})
|
||||
navButtonLeft.addEventListener('click', this.scrollLeft)
|
||||
navButtonRight.addEventListener('click', this.scrollRight)
|
||||
@ -1827,8 +1846,9 @@ stripOption.innerHTML = `
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem 0.8rem;
|
||||
transition: background 0.3s;
|
||||
border-radius: var(--border-radius);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
:host([active]) .strip-option{
|
||||
@ -1868,16 +1888,19 @@ customElements.define('strip-option', class extends HTMLElement{
|
||||
})
|
||||
)
|
||||
}
|
||||
handleKeyDown = (e) => {
|
||||
if (e.key === 'Enter' || e.key === 'Space') {
|
||||
this.fireEvent()
|
||||
}
|
||||
}
|
||||
connectedCallback() {
|
||||
this._value = this.getAttribute('value')
|
||||
this.addEventListener('click', e => {
|
||||
this.fireEvent()
|
||||
})
|
||||
this.addEventListener('keyup', e => {
|
||||
if (e.key === 'Enter' || e.key === 'Space') {
|
||||
this.fireEvent()
|
||||
}
|
||||
})
|
||||
this.addEventListener('click', this.fireEvent)
|
||||
this.addEventListener('keydown', this.handleKeyDown)
|
||||
}
|
||||
disconnectedCallback() {
|
||||
this.removeEventListener('click', this.fireEvent)
|
||||
this.removeEventListener('keydown', this.handleKeyDown)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
81
css/main.css
81
css/main.css
@ -301,6 +301,12 @@ ul {
|
||||
fill: rgba(var(--text-color), 0.9);
|
||||
}
|
||||
|
||||
.button__icon {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.page-layout {
|
||||
position: relative;
|
||||
display: grid;
|
||||
@ -536,6 +542,7 @@ ul {
|
||||
}
|
||||
|
||||
.progress-indicator {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
height: 2.3rem;
|
||||
padding: 0 0.6rem;
|
||||
@ -545,25 +552,37 @@ ul {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
width: 9ch;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.progress-loader {
|
||||
.progress-loader,
|
||||
.placeholder-loader {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
fill: none;
|
||||
padding: 0.1rem;
|
||||
stroke-width: 16;
|
||||
stroke-width: 12;
|
||||
overflow: visible;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.progress-loader {
|
||||
stroke-dasharray: 201;
|
||||
stroke-dashoffset: 201;
|
||||
transform: rotate(-90deg);
|
||||
stroke: var(--accent-color);
|
||||
transition: stroke-dashoffset 0.3s;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.placeholder-loader {
|
||||
position: absolute;
|
||||
stroke: rgba(var(--text-color), 0.1);
|
||||
}
|
||||
|
||||
.torrent-preview {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.torrent-preview__info-section {
|
||||
@ -605,23 +624,24 @@ ul {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 0.3rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
|
||||
#torrent_name {
|
||||
line-height: 1.1;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
#torrent__description {
|
||||
font-size: 0.9rem;
|
||||
#torrent_description {
|
||||
font-size: 1rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
|
||||
#torrent_uploader {
|
||||
font-weight: 500;
|
||||
margin-top: 1rem;
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
width: auto;
|
||||
border-radius: 1.5rem;
|
||||
padding: 0.3rem 0.8rem;
|
||||
@ -649,6 +669,18 @@ ul {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
#torrent_index_tx {
|
||||
padding: 0.4rem;
|
||||
font-size: 0.9rem;
|
||||
border-radius: 0.5rem;
|
||||
align-self: flex-start;
|
||||
border: solid var(--accent-color) thin;
|
||||
}
|
||||
#torrent_index_tx .icon {
|
||||
height: 1.2rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
#advance_search_section {
|
||||
align-items: flex-start;
|
||||
padding: 1rem 0;
|
||||
@ -666,6 +698,36 @@ sm-option {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
#filter_popup {
|
||||
--width: min(32rem, 100%);
|
||||
}
|
||||
|
||||
.option-selector {
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.filter-option {
|
||||
display: inline-flex;
|
||||
margin: 0 0.5rem 0.8rem 0;
|
||||
}
|
||||
.filter-option input[type=radio] {
|
||||
display: none;
|
||||
}
|
||||
.filter-option input[type=radio]:checked ~ .option-text {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
background-color: var(--accent-color);
|
||||
border: solid var(--accent-color) thin;
|
||||
}
|
||||
.filter-option .option-text {
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
border-radius: 0.3rem;
|
||||
padding: 0.5rem 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
border: solid rgba(var(--text-color), 0.2) thin;
|
||||
}
|
||||
|
||||
#page_selector strip-option,
|
||||
#search_page_selector strip-option {
|
||||
--border-radius: 0.3rem;
|
||||
@ -712,7 +774,7 @@ sm-option {
|
||||
}
|
||||
@media only screen and (min-width: 640px) {
|
||||
.popup__header {
|
||||
padding: 1.5rem 1.5rem 0 1.5rem;
|
||||
padding: 1.5rem 1.5rem 0 0.5rem;
|
||||
}
|
||||
|
||||
.auto-grid-2 {
|
||||
@ -735,7 +797,7 @@ sm-option {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
#torrent_popup {
|
||||
#filter_popup {
|
||||
--min-height: 80vh;
|
||||
}
|
||||
|
||||
@ -745,6 +807,7 @@ sm-option {
|
||||
|
||||
#torrent_name {
|
||||
font-size: 4rem;
|
||||
max-width: 16ch;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1280px) {
|
||||
|
||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -244,11 +244,18 @@ ul{
|
||||
.observe-empty-state:not(:empty) ~ .empty-state{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.icon{
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
fill: rgba(var(--text-color), 0.9);
|
||||
}
|
||||
.button__icon{
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.page-layout{
|
||||
position: relative;
|
||||
@ -477,6 +484,7 @@ ul{
|
||||
}
|
||||
}
|
||||
.progress-indicator{
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
height: 2.3rem;
|
||||
padding: 0 0.6rem;
|
||||
@ -485,23 +493,32 @@ ul{
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
width: 9ch;
|
||||
text-align: right;
|
||||
}
|
||||
.progress-loader{
|
||||
.progress-loader,
|
||||
.placeholder-loader{
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
fill: none;
|
||||
padding: 0.1rem;
|
||||
stroke-width: 16;
|
||||
stroke-width: 12;
|
||||
overflow: visible;
|
||||
margin-right: 0.5rem;
|
||||
}.progress-loader{
|
||||
stroke-dasharray: 201;
|
||||
stroke-dashoffset: 201;
|
||||
transform: rotate(-90deg);
|
||||
stroke: var(--accent-color);
|
||||
transition: stroke-dashoffset 0.3s;
|
||||
z-index: 1;
|
||||
}
|
||||
.placeholder-loader{
|
||||
position: absolute;
|
||||
stroke: rgba(var(--text-color), 0.1);
|
||||
}
|
||||
.torrent-preview{
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
.torrent-preview__info-section{
|
||||
display: flex;
|
||||
@ -539,20 +556,21 @@ ul{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 0.3rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
#torrent_name{
|
||||
line-height: 1.1;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
#torrent__description{
|
||||
font-size: 0.9rem;
|
||||
#torrent_description{
|
||||
font-size: 1rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
#torrent_uploader{
|
||||
font-weight: 500;
|
||||
margin-top: 1rem;
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
width: auto;
|
||||
border-radius: 1.5rem;
|
||||
padding: 0.3rem 0.8rem;
|
||||
@ -577,6 +595,17 @@ ul{
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
#torrent_index_tx{
|
||||
padding: 0.4rem;
|
||||
font-size: 0.9rem;
|
||||
border-radius: 0.5rem;
|
||||
align-self: flex-start;
|
||||
border: solid var(--accent-color) thin;
|
||||
.icon{
|
||||
height: 1.2rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
#advance_search_section{
|
||||
align-items: flex-start;
|
||||
padding: 1rem 0;
|
||||
@ -592,6 +621,35 @@ sm-option{
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
#filter_popup{
|
||||
--width: min(32rem, 100%);
|
||||
}
|
||||
|
||||
.option-selector{
|
||||
padding: 1rem 0;
|
||||
}
|
||||
.filter-option{
|
||||
display: inline-flex;
|
||||
margin: 0 0.5rem 0.8rem 0;
|
||||
input[type="radio"]{
|
||||
display: none;
|
||||
}
|
||||
input[type="radio"]:checked ~ .option-text{
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
background-color: var(--accent-color);
|
||||
border: solid var(--accent-color) thin;
|
||||
}
|
||||
.option-text{
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
border-radius: 0.3rem;
|
||||
padding: 0.5rem 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
border: solid rgba(var(--text-color), 0.2) thin;
|
||||
}
|
||||
}
|
||||
|
||||
#page_selector,
|
||||
#search_page_selector{
|
||||
strip-option{
|
||||
@ -636,7 +694,7 @@ sm-option{
|
||||
}
|
||||
@media only screen and (min-width: 640px) {
|
||||
.popup__header{
|
||||
padding: 1.5rem 1.5rem 0 1.5rem;
|
||||
padding: 1.5rem 1.5rem 0 0.5rem;
|
||||
}
|
||||
.auto-grid-2{
|
||||
grid-template-columns: 1fr 1fr;
|
||||
@ -653,7 +711,7 @@ sm-option{
|
||||
.torrent-card{
|
||||
padding: 1.5rem;
|
||||
}
|
||||
#torrent_popup{
|
||||
#filter_popup{
|
||||
--min-height: 80vh;
|
||||
}
|
||||
.torrent-preview{
|
||||
@ -661,6 +719,7 @@ sm-option{
|
||||
}
|
||||
#torrent_name{
|
||||
font-size: 4rem;
|
||||
max-width: 16ch;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1280px) {
|
||||
|
||||
280
index.html
280
index.html
@ -8,7 +8,8 @@
|
||||
<title>FLO Torrent</title>
|
||||
<link rel="shortcut icon" href="flo-torrent.png" type="image/png">
|
||||
<link rel="stylesheet" href="css/main.min.css">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400..900&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
@ -25,13 +26,30 @@
|
||||
<sm-button variant="no-outline" class="submit-btn">OK</button>
|
||||
</div>
|
||||
</sm-popup>
|
||||
<sm-popup id="filter_popup">
|
||||
<header class="popup__header" slot="header">
|
||||
<button class="popup__header__close" onclick="getRef('filter_popup').hide()">
|
||||
<svg class="icon close-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
|
||||
</button>
|
||||
<h3>Filter</h3>
|
||||
</header>
|
||||
<form id="filter_form" onsubmit="return false">
|
||||
<h4>Category</h4>
|
||||
<section id="category_selector" class="option-selector"></section>
|
||||
<div class="flex gap-1">
|
||||
<button class="justify-right" onclick="resetFilter()">Clear</button>
|
||||
<button onclick="addFilter()" class="button button--primary">Fliter</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</sm-popup>
|
||||
<header id="main_header">
|
||||
<div class="flex align-center">
|
||||
<svg id="main_header__logo" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M20.46,21.32C20,19.78,18.6,18.59,15.3,17a12.67,12.67,0,0,1-2.64-1.56,4.27,4.27,0,0,1-.79-1,2.6,2.6,0,0,1,0-1.41c.24-.68.49-1,2.43-2.85a7.18,7.18,0,0,0,2.09-2.92,4.25,4.25,0,0,0,0-1.77,6.52,6.52,0,0,0-2.85-3.11c-.56-.36-.81-.4-.81-.15a2.33,2.33,0,0,1-.18.45L12.4,3l-.53-.36c-.28-.21-.64-.41-.77-.49s-.46-.11-.46,0a6.21,6.21,0,0,1-.37.83s-.08,0-.17-.08c-1.15-.83-1.64-1-1.64-.73A7.33,7.33,0,0,1,7.7,3.65C6.48,5.68,5.24,6.7,4,6.7c-.56,0-.54,0-.37.64s.2.58.68.43a3.37,3.37,0,0,0,1.09-.54.86.86,0,0,1,.3-.17,1.34,1.34,0,0,1,.13.39.79.79,0,0,0,.17.4A3.5,3.5,0,0,0,7.37,7.3L7.8,7l.09.34c.12.45.19.51.62.39a4.25,4.25,0,0,0,2.17-1.54l.38-.45,0,.39A5.92,5.92,0,0,1,8.89,9.54L7.67,10.71c-2,1.93-1.89,3.51.37,5a27.41,27.41,0,0,0,2.89,1.51c.17.07.62.32,1,.54C14,19,15,20.23,15,21.48a2,2,0,0,0,0,.49h0c0,.05,0,.05.56-.1a1.89,1.89,0,0,0,.53-.21,2.41,2.41,0,0,0-.34-1.15,7.05,7.05,0,0,0-1.68-1.77,21.91,21.91,0,0,0-3.2-1.83A9.53,9.53,0,0,1,8.16,15.2a2.18,2.18,0,0,1-.74-1.55C7.42,12.79,7.86,12,9,11c1.77-1.64,2.45-2.45,2.92-3.55a2.28,2.28,0,0,0,.26-1.26A2,2,0,0,0,12,5.06l-.2-.45L12,4.3l.28-.49.09-.18L12.6,4a3.69,3.69,0,0,1,.61,1.76A3.47,3.47,0,0,1,12.94,7l-.09.25s-.21.37-.41.69A17.78,17.78,0,0,1,9.91,10.6c-1.07,1-1.43,1.62-1.47,2.47a2.05,2.05,0,0,0,.7,1.73,10.47,10.47,0,0,0,3.28,2.08c2.28,1.13,3.26,1.81,4,2.73a2.94,2.94,0,0,1,.74,1.75,1.26,1.26,0,0,0,.09.57.48.48,0,0,0,.26,0l.51-.13.29-.08,0-.28c-.13-1-1-2-2.47-3a25.52,25.52,0,0,0-3.26-1.77,8.59,8.59,0,0,1-2.23-1.43,2.09,2.09,0,0,1-.5-2.62c.26-.53.5-.83,2.35-2.6,1.51-1.45,2.15-2.58,2.15-3.79A3.67,3.67,0,0,0,13,3.48a3,3,0,0,1-.4-.42A1.85,1.85,0,0,1,13,2.33a6.74,6.74,0,0,1,1.83,1.73,2.62,2.62,0,0,1,.47,1.68,3,3,0,0,1-.55,1.84c-.45.78-.79,1.14-2.67,2.93a5.56,5.56,0,0,0-1.3,1.64,1.77,1.77,0,0,0-.21,1,1.76,1.76,0,0,0,.19.92,6.28,6.28,0,0,0,2.9,2.34,21.6,21.6,0,0,1,3.66,2c1.35,1,2,2,2,3a1.06,1.06,0,0,0,.05.47,2.83,2.83,0,0,0,1-.24C20.56,21.68,20.56,21.66,20.46,21.32ZM7.29,6.4h0a2.23,2.23,0,0,1-.9.28L6,6.72l.43-.53a15.22,15.22,0,0,0,1.89-3,3.52,3.52,0,0,1,.38-.67c.07-.08.49.2,1,.64l.39.35L9.66,4A6.7,6.7,0,0,1,7.29,6.4Zm3.58-1.11A5.8,5.8,0,0,1,9.25,6.51h0a3.3,3.3,0,0,1-.74.17l-.35,0,.39-.49a15.64,15.64,0,0,0,1.32-2,4.63,4.63,0,0,1,.28-.49c.06-.08.33.26.57.77l.28.57Zm1-1.4a1.63,1.63,0,0,1-.28.4A6.63,6.63,0,0,1,11,3.72l-.53-.56.12-.29c.2-.49.24-.51.64-.19a5.57,5.57,0,0,1,.85.78A2.78,2.78,0,0,1,11.87,3.89Z" />
|
||||
</svg>
|
||||
<a href="" class="header__company-name">RanchiMall</a>
|
||||
<a href="./index.html" class="header__company-name">RanchiMall</a>
|
||||
</div>
|
||||
<label class="theme-switcher" title="Change theme">
|
||||
<input id="theme_switcher" class="theme-switcher__checkbox" type="checkbox">
|
||||
@ -103,13 +121,17 @@
|
||||
<h1 id="torrent_name"></h1>
|
||||
<p id="torrent_description"></p>
|
||||
<h5 id="torrent_uploader"></h5>
|
||||
<a id="torrent_index_tx" target="_blank" class="flex align-center">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6zm11-3v8h-2V6.413l-7.793 7.794-1.414-1.414L17.585 5H13V3h8z"/></svg>
|
||||
See the index entry in blockchain
|
||||
</a>
|
||||
<div id="download_container">
|
||||
<button id="torrent_download_button"
|
||||
onclick="downloadTorrent(currentTorrent.filename, currentTorrent.startTx, currentTorrent.chunks, currentTorrent.id, true)">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M16 2l5 5v14.008a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992C3 2.444 3.445 2 3.993 2H16zm-3 10V8h-2v4H8l4 4 4-4h-3z" />
|
||||
d="M16 2l5 5v14.008a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992C3 2.444 3.445 2 3.993 2H16zm-3 10V8h-2v4H8l4 4 4-4h-3z" />
|
||||
</svg>
|
||||
Get torrent
|
||||
</button>
|
||||
@ -119,46 +141,27 @@
|
||||
</section>
|
||||
</section>
|
||||
<section id="search" class="page hide-completely page-layout">
|
||||
<section id="advance_search_section" class="grid gap-1 auto-grid-2">
|
||||
<div class="grid gap-1">
|
||||
<h1 class="page__title">Search</h1>
|
||||
<section class="search-container">
|
||||
<sm-input id="advance_torrent_search" class="search-torrent" type="search">
|
||||
<svg class="icon" slot="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24"
|
||||
height="24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M18.031 16.617l4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617zm-2.006-.742A6.977 6.977 0 0 0 18 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 0 0 4.875-1.975l.15-.15z" />
|
||||
</svg>
|
||||
</sm-input>
|
||||
<section id="advance_search_suggestions" class="search-suggestions-container"></section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="grid gap-1">
|
||||
<sm-switch id="advance_search_switch">
|
||||
<h4 slot="right">Advanced search</h4>
|
||||
</sm-switch>
|
||||
<section id="advance_search_panel"
|
||||
class="grid flow-column align-center justify-start gap-1-5 hide-completely">
|
||||
<div class="grid flow-column align-center justify-start gap-0-5">
|
||||
<h5>Category</h5>
|
||||
<sm-select id="category_selector">
|
||||
<sm-option value="movie">Movie</sm-option>
|
||||
<sm-option value="tv series">TV series</sm-option>
|
||||
<sm-option value="video">Video</sm-option>
|
||||
<sm-option value="music">Music</sm-option>
|
||||
<sm-option value="software">Software</sm-option>
|
||||
<sm-option value="game">Game</sm-option>
|
||||
<sm-option value="image">Image</sm-option>
|
||||
<sm-option value="audio">Audio</sm-option>
|
||||
<sm-option value="misc">Misc</sm-option>
|
||||
</sm-select>
|
||||
</div>
|
||||
<button onclick="renderSearchResult('', true); pushParams();" class="button button--primary">Fliter</button>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
<div id="result_for"></div>
|
||||
<div class="grid gap-1">
|
||||
<h1 class="page__title">Search</h1>
|
||||
<section class="search-container">
|
||||
<sm-input id="advance_torrent_search" class="search-torrent" type="search">
|
||||
<svg class="icon" slot="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24"
|
||||
height="24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M18.031 16.617l4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617zm-2.006-.742A6.977 6.977 0 0 0 18 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 0 0 4.875-1.975l.15-.15z" />
|
||||
</svg>
|
||||
</sm-input>
|
||||
<section id="advance_search_suggestions" class="search-suggestions-container"></section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="flex align-center space-between">
|
||||
<p id="result_for"></p>
|
||||
<button id="filter_button" onclick="getRef('filter_popup').show()">
|
||||
<svg class="icon button__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M6.17 18a3.001 3.001 0 0 1 5.66 0H22v2H11.83a3.001 3.001 0 0 1-5.66 0H2v-2h4.17zm6-7a3.001 3.001 0 0 1 5.66 0H22v2h-4.17a3.001 3.001 0 0 1-5.66 0H2v-2h10.17zm-6-7a3.001 3.001 0 0 1 5.66 0H22v2H11.83a3.001 3.001 0 0 1-5.66 0H2V4h4.17z"/></svg>
|
||||
Filter
|
||||
</button>
|
||||
</div>
|
||||
<section id="search_result" class="torrent-container"></section>
|
||||
<strip-select id="search_page_selector"></strip-select>
|
||||
</section>
|
||||
@ -224,7 +227,6 @@
|
||||
var DBDeleteRequest = window.indexedDB.deleteDatabase("FLO_Torrent");
|
||||
DBDeleteRequest.onsuccess = function (event) {
|
||||
console.log("Database deleted successfully");
|
||||
alert("Successfully Cleared Local Data!");
|
||||
};
|
||||
}
|
||||
|
||||
@ -549,6 +551,7 @@
|
||||
className: 'progress-indicator flex align-center',
|
||||
innerHTML: `
|
||||
<svg class="progress-loader" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="32"/></svg>
|
||||
<svg class="placeholder-loader" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="32"/></svg>
|
||||
<span class="progress-percent">0% done</span>
|
||||
`
|
||||
})
|
||||
@ -574,7 +577,6 @@
|
||||
}
|
||||
}, 300);
|
||||
}).catch(error => {
|
||||
alert(error);
|
||||
console.error(error);
|
||||
})
|
||||
}
|
||||
@ -865,6 +867,18 @@
|
||||
card.querySelector('.torrent-card__uploader').textContent = `by ${uploader}`
|
||||
card.querySelector('.torrent-card__icon').innerHTML = getIcon(type)
|
||||
return card
|
||||
},
|
||||
filterOption(obj){
|
||||
const {content, groupName, value} = obj
|
||||
const option = create('label', {
|
||||
className: 'filter-option'
|
||||
})
|
||||
|
||||
option.innerHTML = `
|
||||
<input type="radio" name="${groupName}" value="${value}">
|
||||
<div class="option-text">${content}</div>
|
||||
`
|
||||
return option
|
||||
}
|
||||
}
|
||||
function getIcon(type) {
|
||||
@ -917,9 +931,9 @@
|
||||
|
||||
function pushParams() {
|
||||
let params = ''
|
||||
for (let prop in advancedSearch) {
|
||||
if (prop !== 'isActive' && advancedSearch[prop] && advancedSearch[prop] !== '') {
|
||||
params += `${prop}=${advancedSearch[prop]}&`
|
||||
for (let prop in filteredSearch) {
|
||||
if (prop !== 'isActive' && filteredSearch[prop] && filteredSearch[prop] !== '') {
|
||||
params += `${prop}=${filteredSearch[prop]}&`
|
||||
}
|
||||
}
|
||||
if (params.slice(-1) === '&') {
|
||||
@ -928,7 +942,7 @@
|
||||
history.pushState(null, null, `?${params}#search`)
|
||||
}
|
||||
|
||||
let advancedSearch = {
|
||||
let filteredSearch = {
|
||||
active: false,
|
||||
query: '',
|
||||
category: ''
|
||||
@ -937,14 +951,15 @@
|
||||
let lastCategory = ''
|
||||
|
||||
async function renderSearchResult(searchKey, shouldFilter = false) {
|
||||
if (lastQuery !== searchKey || shouldFilter || advancedSearch.category !== lastCategory) {
|
||||
debugger
|
||||
if (lastQuery !== searchKey || shouldFilter || filteredSearch.category !== lastCategory) {
|
||||
if (shouldFilter) {
|
||||
searchKey = getRef('advance_torrent_search').value.trim() !== '' ? getRef('advance_torrent_search').value.trim() : lastQuery
|
||||
}
|
||||
advancedSearch['query'] = searchKey
|
||||
filteredSearch['query'] = searchKey
|
||||
let result
|
||||
if (advancedSearch.isActive) {
|
||||
result = await getFilteredTorrents(['type'], advancedSearch.category)
|
||||
if (filteredSearch.isActive) {
|
||||
result = await getFilteredTorrents(['type'], filteredSearch.category)
|
||||
result = await getFilteredTorrents(['name', 'filename', 'tags'], searchKey, {torrents: result})
|
||||
}
|
||||
else {
|
||||
@ -969,11 +984,28 @@
|
||||
}
|
||||
|
||||
lastQuery = searchKey
|
||||
lastCategory = advancedSearch.category
|
||||
showPage('search')
|
||||
lastCategory = filteredSearch.category
|
||||
}
|
||||
}
|
||||
|
||||
const categories = ['movie', 'tv series', 'video', 'music', 'software', 'game', 'image', 'audio', 'misc']
|
||||
|
||||
function renderOptions(list, options){
|
||||
const {groupName} = options
|
||||
const frag = document.createDocumentFragment()
|
||||
list.forEach(item => {
|
||||
const optionObj = {
|
||||
content: item,
|
||||
groupName,
|
||||
value: item
|
||||
}
|
||||
frag.append(render.filterOption(optionObj))
|
||||
})
|
||||
return frag
|
||||
}
|
||||
|
||||
let currentpage = ''
|
||||
|
||||
async function showPage(target) {
|
||||
let params = getSearchParams()
|
||||
let page = target.includes('#') ? target.split('#')[1] : target
|
||||
@ -981,19 +1013,23 @@
|
||||
case 'loading_page':
|
||||
break;
|
||||
case 'search':
|
||||
if(currentpage !== page){
|
||||
getRef('category_selector').innerHTML = ''
|
||||
getRef('category_selector').append(renderOptions(categories, {groupName: 'category-selector'}))
|
||||
}
|
||||
if (params.query) {
|
||||
if (params.category) {
|
||||
advancedSearch = {
|
||||
filteredSearch = {
|
||||
isActive: true,
|
||||
...params
|
||||
}
|
||||
getRef('advance_search_switch').checked = true
|
||||
getRef('advance_search_panel').classList.remove('hide-completely')
|
||||
const selectedCategory = getRef('category_selector').querySelector(`[value="${filteredSearch.category}"]`)
|
||||
if(selectedCategory){
|
||||
selectedCategory.checked = true
|
||||
}
|
||||
}
|
||||
else{
|
||||
advancedSearch.category = 'movie'
|
||||
getRef('advance_search_switch').checked = false
|
||||
getRef('advance_search_panel').classList.add('hide-completely')
|
||||
resetFilter()
|
||||
}
|
||||
renderSearchResult(params.query)
|
||||
}
|
||||
@ -1006,6 +1042,7 @@
|
||||
getRef('torrent_description').textContent = description
|
||||
getRef('torrent_tags').textContent = tags.split('/').join('•')
|
||||
getRef('torrent_uploader').textContent = `Uploaded by ${uploader}`
|
||||
getRef('torrent_index_tx').href = `https://livenet.flocha.in/tx/${startTx}`
|
||||
break;
|
||||
case 'browse':
|
||||
const category = getRef('browse_category_selector').value
|
||||
@ -1019,8 +1056,11 @@
|
||||
getRef('torrent_container').innerHTML = ``
|
||||
getRef('torrent_container').append(renderTorrents(allTorrents))
|
||||
}
|
||||
document.querySelector('.page:not(.hide-completely)')?.classList.add('hide-completely')
|
||||
getRef(page).classList.remove('hide-completely')
|
||||
if(currentpage !== page){
|
||||
document.querySelector('.page:not(.hide-completely)')?.classList.add('hide-completely')
|
||||
getRef(page).classList.remove('hide-completely')
|
||||
currentpage = page
|
||||
}
|
||||
}
|
||||
|
||||
function alphaIncSort(arr, prop) {
|
||||
@ -1105,6 +1145,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
function handleEnter(e){
|
||||
if (e.target.value.trim() !== '') {
|
||||
switch (e.key) {
|
||||
case 'Enter':
|
||||
const searchKey = e.target.value.trim()
|
||||
renderSearchResult(searchKey)
|
||||
pushParams()
|
||||
showPage('search')
|
||||
e.target.value = ''
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
e.target.nextElementSibling.firstElementChild.focus()
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyboardNav(e){
|
||||
switch (e.key) {
|
||||
case 'ArrowUp':
|
||||
e.preventDefault()
|
||||
if (e.target.previousElementSibling)
|
||||
e.target.previousElementSibling.focus()
|
||||
else
|
||||
e.target.parentNode.previousElementSibling.focusIn()
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
if (e.target.nextElementSibling)
|
||||
e.target.nextElementSibling.focus()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
|
||||
window.addEventListener('load', e => {
|
||||
@ -1133,40 +1208,11 @@
|
||||
downloadTorrent(filename, startTx, chunks, cardId)
|
||||
}
|
||||
})
|
||||
getRef('search_torrent').addEventListener('keydown', async e => {
|
||||
if (e.target.value.trim() !== '') {
|
||||
switch (e.key) {
|
||||
case 'Enter':
|
||||
const searchKey = getRef('search_torrent').value.trim()
|
||||
renderSearchResult(searchKey)
|
||||
pushParams()
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
getRef('search_suggestions').firstElementChild.focus()
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
getRef('search_torrent').addEventListener('keydown', handleEnter)
|
||||
getRef('advance_torrent_search').addEventListener('keydown', handleEnter)
|
||||
getRef('search_suggestions').addEventListener('keydown', handleKeyboardNav)
|
||||
getRef('advance_search_suggestions').addEventListener('keydown', handleKeyboardNav)
|
||||
|
||||
function handleKeyboardNav(e){
|
||||
switch (e.key) {
|
||||
case 'ArrowUp':
|
||||
e.preventDefault()
|
||||
if (e.target.previousElementSibling)
|
||||
e.target.previousElementSibling.focus()
|
||||
else
|
||||
e.target.parentNode.previousElementSibling.focusIn()
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
if (e.target.nextElementSibling)
|
||||
e.target.nextElementSibling.focus()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
getRef('search_torrent').addEventListener('input', async e => {
|
||||
throttle(() => {
|
||||
const searchKey = getRef('search_torrent').value.trim()
|
||||
@ -1179,38 +1225,8 @@
|
||||
renderSearchSuggestions(searchKey, true)
|
||||
}, 100)
|
||||
})
|
||||
getRef('advance_torrent_search').addEventListener('keydown', async e => {
|
||||
if (e.target.value.trim() !== '') {
|
||||
switch (e.key) {
|
||||
case 'Enter':
|
||||
const searchKey = e.target.value.trim()
|
||||
renderSearchResult(searchKey)
|
||||
pushParams()
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
getRef('advance_search_suggestions').firstElementChild.focus()
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
getRef('advance_search_switch').addEventListener('change', e => {
|
||||
if (e.detail.value) {
|
||||
advancedSearch = {
|
||||
isActive: true,
|
||||
category: getRef('category_selector').value
|
||||
}
|
||||
getRef('advance_search_panel').classList.remove('hide-completely')
|
||||
}
|
||||
else {
|
||||
advancedSearch.isActive = false
|
||||
advancedSearch.category = ''
|
||||
getRef('advance_search_panel').classList.add('hide-completely')
|
||||
}
|
||||
advancedSearch['query'] = getRef('advance_torrent_search').value.trim()
|
||||
})
|
||||
getRef('category_selector').addEventListener('change', e => {
|
||||
advancedSearch.category = e.detail.value
|
||||
filteredSearch.category = e.target.value
|
||||
})
|
||||
getRef('browse_category_selector').addEventListener('change', e => {
|
||||
showCategoryTorrents(e.detail.value)
|
||||
@ -1240,6 +1256,18 @@
|
||||
getRef('search_result').append(renderTorrents(result.slice(startIndex, endIndex)))
|
||||
}, 200);
|
||||
})
|
||||
function addFilter(){
|
||||
if(filteredSearch.category){
|
||||
filteredSearch.isActive = true
|
||||
}
|
||||
renderSearchResult('', true);
|
||||
pushParams();
|
||||
}
|
||||
function resetFilter(){
|
||||
filteredSearch.isActive = false
|
||||
filteredSearch.category = undefined
|
||||
getRef('filter_form').reset()
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
3
jshint.jshintrc
Normal file
3
jshint.jshintrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"esversion": 6
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user