UI update
added browse by category
This commit is contained in:
parent
b28d1e27ba
commit
5c8fc0570c
176
components.js
176
components.js
@ -1601,9 +1601,7 @@ stripSelect.innerHTML = `
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
:host{
|
:host{
|
||||||
--background-color: inherit;
|
--gap: 0.5rem;
|
||||||
--active-option-color: inherit;
|
|
||||||
--active-option-backgroud-color: rgba(var(--text-color), .2);
|
|
||||||
}
|
}
|
||||||
.hide{
|
.hide{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@ -1618,32 +1616,24 @@ stripSelect.innerHTML = `
|
|||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
.strip-select{
|
.strip-select{
|
||||||
display: flex;
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
gap: var(--gap);
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
overflow: auto hidden;
|
overflow: auto hidden;
|
||||||
}
|
}
|
||||||
.strip-option{
|
|
||||||
display: flex;
|
|
||||||
flex-strink: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
white-space: nowrap;
|
|
||||||
border-radius: 2rem;
|
|
||||||
padding: 0.5rem 0.8rem;
|
|
||||||
}
|
|
||||||
.strip-option[active]{
|
|
||||||
color: var(--active-option-color);
|
|
||||||
background-color: var(--active-option-backgroud-color);
|
|
||||||
}
|
|
||||||
.nav-button{
|
.nav-button{
|
||||||
position: absolute;
|
display: flex;
|
||||||
|
top: 50%;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
border: none;
|
border: none;
|
||||||
top: 50%;
|
|
||||||
padding: 0.3rem;
|
padding: 0.3rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: none;
|
position: absolute;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--background-color);
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
.nav-button--right{
|
.nav-button--right{
|
||||||
@ -1657,11 +1647,11 @@ stripSelect.innerHTML = `
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.cover--left{
|
.cover--left{
|
||||||
background: linear-gradient(90deg, var(--background-color) 60%, transparent);
|
background: linear-gradient(90deg, var(--background-color), transparent);
|
||||||
}
|
}
|
||||||
.cover--right{
|
.cover--right{
|
||||||
right: 0;
|
right: 0;
|
||||||
background: linear-gradient(90deg, transparent 0%, var(--background-color) 40%);
|
background: linear-gradient(90deg, transparent, var(--background-color));
|
||||||
}
|
}
|
||||||
.nav-button--right::before{
|
.nav-button--right::before{
|
||||||
background-color: red;
|
background-color: red;
|
||||||
@ -1685,6 +1675,9 @@ stripSelect.innerHTML = `
|
|||||||
.strip-select{
|
.strip-select{
|
||||||
overflow: auto hidden;
|
overflow: auto hidden;
|
||||||
}
|
}
|
||||||
|
.cover{
|
||||||
|
width: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media (hover: hover){
|
@media (hover: hover){
|
||||||
.strip-select{
|
.strip-select{
|
||||||
@ -1716,18 +1709,11 @@ customElements.define('strip-select', class extends HTMLElement{
|
|||||||
this.stripSelect = this.shadowRoot.querySelector('.strip-select')
|
this.stripSelect = this.shadowRoot.querySelector('.strip-select')
|
||||||
this.slottedOptions
|
this.slottedOptions
|
||||||
this._value
|
this._value
|
||||||
this.scrollDistance = 200
|
this.scrollDistance = 300
|
||||||
}
|
}
|
||||||
get value() {
|
get value() {
|
||||||
return this._value
|
return this._value
|
||||||
}
|
}
|
||||||
randString = (length) => {
|
|
||||||
let result = '';
|
|
||||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
||||||
for (let i = 0; i < length; i++)
|
|
||||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
fireEvent = () => {
|
fireEvent = () => {
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent("change", {
|
new CustomEvent("change", {
|
||||||
@ -1754,51 +1740,37 @@ customElements.define('strip-select', class extends HTMLElement{
|
|||||||
}
|
}
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
const slot = this.shadowRoot.querySelector('slot')
|
const slot = this.shadowRoot.querySelector('slot')
|
||||||
const groupName = this.randString(8)
|
|
||||||
const coverLeft = this.shadowRoot.querySelector('.cover--left')
|
const coverLeft = this.shadowRoot.querySelector('.cover--left')
|
||||||
const coverRight = this.shadowRoot.querySelector('.cover--right')
|
const coverRight = this.shadowRoot.querySelector('.cover--right')
|
||||||
const navButtonLeft = this.shadowRoot.querySelector('.nav-button--left')
|
const navButtonLeft = this.shadowRoot.querySelector('.nav-button--left')
|
||||||
const navButtonRight = this.shadowRoot.querySelector('.nav-button--right')
|
const navButtonRight = this.shadowRoot.querySelector('.nav-button--right')
|
||||||
slot.addEventListener('slotchange', e => {
|
slot.addEventListener('slotchange', e => {
|
||||||
slot.assignedElements().forEach(elem => {
|
slot.assignedElements().forEach(elem => {
|
||||||
const label = document.createElement('label')
|
if (elem.hasAttribute('selected')) {
|
||||||
const input = document.createElement('input')
|
elem.setAttribute('active', '')
|
||||||
label.className = 'strip-option'
|
this._value = elem.value
|
||||||
label.tabIndex = 0
|
}
|
||||||
input.type = 'radio'
|
|
||||||
input.name = groupName
|
|
||||||
input.setAttribute('value', elem.getAttribute('value'))
|
|
||||||
label.append(input, elem)
|
|
||||||
this.stripSelect.append(label)
|
|
||||||
})
|
})
|
||||||
slot.remove()
|
if (slot.assignedElements().length) {
|
||||||
firstOptionObserver.observe(this.stripSelect.firstElementChild)
|
firstOptionObserver.observe(slot.assignedElements()[0])
|
||||||
lastOptionObserver.observe(this.stripSelect.lastElementChild)
|
lastOptionObserver.observe(slot.assignedElements()[slot.assignedElements().length - 1])
|
||||||
})
|
}
|
||||||
this.stripSelect.addEventListener('change', e => {
|
else {
|
||||||
this._value = e.target.value
|
navButtonLeft.classList.add('hide')
|
||||||
e.target.closest('label').scrollIntoView({behavior: "smooth", block: "start", inline: "center"})
|
navButtonRight.classList.add('hide')
|
||||||
Array.from(this.stripSelect.children).forEach(elem => elem.removeAttribute('active'))
|
coverLeft.classList.add('hide')
|
||||||
e.target.closest('.strip-option').setAttribute('active', '')
|
coverRight.classList.add('hide')
|
||||||
this.fireEvent()
|
|
||||||
})
|
|
||||||
this.stripSelect.addEventListener('keyup', e => {
|
|
||||||
if (e.key === 'Enter' || e.key === 'Space') {
|
|
||||||
e.target.click()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const widthObserver = new ResizeObserver(entries => {
|
this.stripSelect.addEventListener('change', e => {
|
||||||
entries.forEach(entry => {
|
if (this._value !== e.target.value) {
|
||||||
if(entry.contentBoxSize) {
|
this._value = e.target.value
|
||||||
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
|
e.target.scrollIntoView({behavior: "smooth", block: "nearest", inline: "center"})
|
||||||
this.style.width = `${contentBoxSize.inlineSize}px`
|
slot.assignedElements().forEach(elem => elem.removeAttribute('active'))
|
||||||
} else {
|
e.target.setAttribute('active', '')
|
||||||
this.style.width = `${contentRect.width}px`
|
this.fireEvent()
|
||||||
}
|
}
|
||||||
})
|
|
||||||
})
|
})
|
||||||
widthObserver.observe(this.parentNode)
|
|
||||||
|
|
||||||
const firstOptionObserver = new IntersectionObserver(entries => {
|
const firstOptionObserver = new IntersectionObserver(entries => {
|
||||||
entries.forEach(entry => {
|
entries.forEach(entry => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
@ -1834,6 +1806,82 @@ customElements.define('strip-select', class extends HTMLElement{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const stripOption = document.createElement('template')
|
||||||
|
stripOption.innerHTML = `
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
:host{
|
||||||
|
--border-radius: 2rem;
|
||||||
|
--background-color: inherit;
|
||||||
|
--active-option-color: inherit;
|
||||||
|
--active-option-backgroud-color: rgba(var(--text-color), .2);
|
||||||
|
}
|
||||||
|
.hide{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.strip-option{
|
||||||
|
display: flex;
|
||||||
|
flex-strink: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 0.5rem 0.8rem;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
|
||||||
|
}
|
||||||
|
:host([active]) .strip-option{
|
||||||
|
color: var(--active-option-color);
|
||||||
|
background-color: var(--active-option-backgroud-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<label class="strip-option" tabindex="0">
|
||||||
|
<slot></slot>
|
||||||
|
</label>
|
||||||
|
`
|
||||||
|
|
||||||
|
//Strip option
|
||||||
|
customElements.define('strip-option', class extends HTMLElement{
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.attachShadow({
|
||||||
|
mode: 'open'
|
||||||
|
}).append(stripOption.content.cloneNode(true))
|
||||||
|
this._value
|
||||||
|
this.radioButton = this.shadowRoot.querySelector('input')
|
||||||
|
}
|
||||||
|
get value() {
|
||||||
|
return this._value
|
||||||
|
}
|
||||||
|
fireEvent = () => {
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent("change", {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
detail: {
|
||||||
|
value: this._value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
//popup
|
//popup
|
||||||
const smPopup = document.createElement('template')
|
const smPopup = document.createElement('template')
|
||||||
smPopup.innerHTML = `
|
smPopup.innerHTML = `
|
||||||
|
|||||||
@ -606,6 +606,12 @@ sm-option {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_selector strip-option {
|
||||||
|
--border-radius: 0.3rem;
|
||||||
|
--active-option-color: white;
|
||||||
|
--active-option-backgroud-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
#main_footer {
|
#main_footer {
|
||||||
padding: 3rem 0;
|
padding: 3rem 0;
|
||||||
background-color: rgba(var(--text-color), 0.06);
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -534,6 +534,14 @@ ul{
|
|||||||
sm-option{
|
sm-option{
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_selector{
|
||||||
|
strip-option{
|
||||||
|
--border-radius: 0.3rem;
|
||||||
|
--active-option-color: white;
|
||||||
|
--active-option-backgroud-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
#main_footer{
|
#main_footer{
|
||||||
padding: 3rem 0;
|
padding: 3rem 0;
|
||||||
background-color: rgba(var(--text-color), 0.06);
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
|||||||
74
index.html
74
index.html
@ -108,13 +108,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<div id="result_for"></div>
|
<div id="result_for"></div>
|
||||||
<ul id="search_result" class="torrent-container observe-empty-state"></ul>
|
<ul id="search_result" class="torrent-container"></ul>
|
||||||
</section>
|
</section>
|
||||||
<section id="browse" class="hide-completely page page-layout">
|
<section id="browse" class="hide-completely page page-layout">
|
||||||
<section class="flex direction-column">
|
<section class="flex direction-column">
|
||||||
<h1 class="page__title">Browse</h1>
|
<h1 class="page__title">Browse</h1>
|
||||||
<strip-select id="browse_category_selector">
|
<strip-select id="browse_category_selector">
|
||||||
<strip-option value="movie">Movie</strip-option>
|
<strip-option value="movie" selected>Movie</strip-option>
|
||||||
<strip-option value="tv series">TV series</strip-option>
|
<strip-option value="tv series">TV series</strip-option>
|
||||||
<strip-option value="video">Video</strip-option>
|
<strip-option value="video">Video</strip-option>
|
||||||
<strip-option value="music">Music</strip-option>
|
<strip-option value="music">Music</strip-option>
|
||||||
@ -125,6 +125,8 @@
|
|||||||
<strip-option value="misc">Misc</strip-option>
|
<strip-option value="misc">Misc</strip-option>
|
||||||
</strip-select>
|
</strip-select>
|
||||||
</section>
|
</section>
|
||||||
|
<ul id="browser_category_torrents" class="torrent-container"></ul>
|
||||||
|
<strip-select id="page_selector"></strip-select>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
@ -581,11 +583,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function create(tagName, obj) {
|
function create(tagName, obj) {
|
||||||
const { className, text, innerHTML } = obj
|
const { className, textContent, innerHTML } = obj
|
||||||
const elem = document.createElement(tagName)
|
const elem = document.createElement(tagName)
|
||||||
elem.className = className
|
if(className)
|
||||||
elem.textContent = text
|
elem.className = className
|
||||||
elem.innerHTML = innerHTML
|
elem.textContent = textContent
|
||||||
|
if(innerHTML)
|
||||||
|
elem.innerHTML = innerHTML
|
||||||
return elem
|
return elem
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,7 +905,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function getParts(){
|
function getSearchParams(){
|
||||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||||
const params = Object.fromEntries(urlSearchParams.entries());
|
const params = Object.fromEntries(urlSearchParams.entries());
|
||||||
return params
|
return params
|
||||||
@ -963,7 +967,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showPage(target){
|
function showPage(target){
|
||||||
let params = getParts()
|
let params = getSearchParams()
|
||||||
let page = target.includes('#') ? target.split('#')[1] : target
|
let page = target.includes('#') ? target.split('#')[1] : target
|
||||||
switch(page){
|
switch(page){
|
||||||
case 'search':
|
case 'search':
|
||||||
@ -978,7 +982,8 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'browse':
|
case 'browse':
|
||||||
|
const category = getRef('browse_category_selector').value
|
||||||
|
showCategoryTorrents(category)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
page = 'homepage'
|
page = 'homepage'
|
||||||
@ -1000,12 +1005,61 @@
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
advancedSearch.isActive = false
|
advancedSearch.isActive = false
|
||||||
|
advancedSearch.category = ''
|
||||||
getRef('advance_search_panel').classList.add('hide-completely')
|
getRef('advance_search_panel').classList.add('hide-completely')
|
||||||
}
|
}
|
||||||
advancedSearch['query'] = getRef('advance_torrent_search').value.trim()
|
advancedSearch['query'] = getRef('advance_torrent_search').value.trim()
|
||||||
})
|
})
|
||||||
getRef('category_selector').addEventListener('change', e => {
|
getRef('category_selector').addEventListener('change', e => {
|
||||||
advancedSearch.category = e.detail.value
|
advancedSearch.category = e.detail.value
|
||||||
|
})
|
||||||
|
getRef('browse_category_selector').addEventListener('change', e => {
|
||||||
|
showCategoryTorrents(e.detail.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function showCategoryTorrents(category){
|
||||||
|
const torrents = await getDataFromIDB()
|
||||||
|
const options = {
|
||||||
|
keys: ['type'],
|
||||||
|
threshold: 0.2,
|
||||||
|
}
|
||||||
|
const fuseSearch = new Fuse(torrents, options)
|
||||||
|
const result = fuseSearch.search(category).map(elem => elem.item)
|
||||||
|
getRef('browser_category_torrents').innerHTML = ``
|
||||||
|
getRef('browser_category_torrents').append(renderTorrents(result.slice(0, 20)))
|
||||||
|
|
||||||
|
const paginationFrag = document.createDocumentFragment()
|
||||||
|
const pages = Math.round(result.length / 20)
|
||||||
|
for(let i = 0; i < pages; i++){
|
||||||
|
const pageButton = create('strip-option', {
|
||||||
|
textContent : (i + 1)
|
||||||
|
})
|
||||||
|
pageButton.setAttribute('value', i)
|
||||||
|
if(i === 0){
|
||||||
|
pageButton.setAttribute('selected', '')
|
||||||
|
}
|
||||||
|
paginationFrag.append(pageButton)
|
||||||
|
}
|
||||||
|
getRef('page_selector').innerHTML = ''
|
||||||
|
getRef('page_selector').append(paginationFrag)
|
||||||
|
}
|
||||||
|
|
||||||
|
getRef('page_selector').addEventListener('change', async e => {
|
||||||
|
const torrents = await getDataFromIDB()
|
||||||
|
const options = {
|
||||||
|
keys: ['type'],
|
||||||
|
threshold: 0.2,
|
||||||
|
}
|
||||||
|
const fuseSearch = new Fuse(torrents, options)
|
||||||
|
const category = getRef('browse_category_selector').value
|
||||||
|
const result = fuseSearch.search(category).map(elem => elem.item)
|
||||||
|
|
||||||
|
const startIndex = parseInt(e.detail.value) * 20
|
||||||
|
const endIndex = (parseInt(e.detail.value) * 20) + 20
|
||||||
|
|
||||||
|
getRef('browser_category_torrents').innerHTML = ``
|
||||||
|
getRef('browser_category_torrents').append(renderTorrents(result.slice(startIndex, endIndex)))
|
||||||
|
getRef('browser_category_torrents').scrollIntoView({behavior: 'smooth', block: 'start'})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user