UI update

added browse by category
This commit is contained in:
sairaj mote 2021-06-24 16:57:43 +05:30
parent b28d1e27ba
commit 5c8fc0570c
5 changed files with 191 additions and 75 deletions

View File

@ -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 = `

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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);

View File

@ -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>