From 82d2d445d7c81068ac02862407929dc7afada2a4 Mon Sep 17 00:00:00 2001 From: alex4401 Date: Tue, 26 Dec 2023 19:28:26 +0100 Subject: [PATCH] feat: silly new wiki list rendering with a search prototype Issue: #39 --- css/popup.css | 60 +++++++++++++++++++++++++ js/popup/WikiList.js | 103 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 161 insertions(+), 2 deletions(-) diff --git a/css/popup.css b/css/popup.css index 3d96d17..476612a 100644 --- a/css/popup.css +++ b/css/popup.css @@ -219,3 +219,63 @@ table > thead > tr:last-child > th { [data-component='SearchFilterSettings'] td { text-align: center; } + + +[data-component='WikiList'] { + position: relative; + border: 1px solid var(--spacer-colour); + padding: 0.2rem 0; + border-radius: 2px; +} +[data-component='WikiList'] .site-list__search-box { + width: 100%; + background: #bdc1c1aa; + border-radius: 4px; + border: 1px solid var( --spacer-colour ); + margin-top: calc(-0.2rem - 1px); + margin-bottom: 0.3rem; +} +[data-component='WikiList'] .site-list__search-box > input { + appearance: none; + border: 0; + width: 100%; + height: 100%; + background: transparent; + padding: 0.3rem 0.6rem; +} +[data-component='WikiList'] > .site-list { + max-height: 350px; + overflow-y: auto; + font-size: 102%; + scrollbar-width: thin; + scrollbar-color: var(--accent-colour); +} +[data-component=WikiList] .site-list__entry { + display: flex; + align-items: center; + padding: 0.15rem 0.2rem; + box-sizing: border-box; +} +[data-component=WikiList] .site-list__entry[data-is-filtered-out='true'] { + height: 0px; + max-height: 0px; + overflow-y: clip; + padding: 0; +} +[data-component=WikiList] .site-list__entry > label { + flex-grow: 1; + line-height: 1.2; + margin: 0 0.15rem; +} +[data-component=WikiList] .site-list__site-link { + display: block; + flex-basis: 12px; + flex-shrink: 0; + width: 12px; + height: 12px; + margin-right: calc(var(--spacing) / 2); + background: url(/icons/ooui-ltr.svg) center center / contain no-repeat; + filter: var(--icon-filter); + opacity: 0.5; +} + \ No newline at end of file diff --git a/js/popup/WikiList.js b/js/popup/WikiList.js index 13519b7..38cc3ed 100644 --- a/js/popup/WikiList.js +++ b/js/popup/WikiList.js @@ -1,12 +1,111 @@ +/** @typedef {import( '../util.js' ).SiteListEntity} SiteListEntity */ + import { + getWikis, createDomElement, getMessage -} from "../util.js"; +} from "../util.js"; + + +function debounce( callback, wait ) { + let timeoutId = null; + return ( ...args ) => { + clearTimeout( timeoutId ); + timeoutId = setTimeout( () => callback( ...args ), wait ); + }; +} export default class WikiList { /** * @param {HTMLElement} container */ - static initialise( container ) { } + static initialise( container ) { + const wikis = getWikis( true, false, false ); + + const siteList = this.#createSiteList( wikis ); + container.appendChild( this.#createSearch( siteList ) ); + container.appendChild( siteList ); + } + + + static #createSearch( container ) { + return createDomElement( 'div', { + classes: [ 'site-list__search-box' ], + html: createDomElement( 'input', { + attributes: { + type: 'text', + placeholder: getMessage( 'sites_search_pl' ), + }, + events: { + keydown: debounce( event => { + const value = event.target.value.trim().toLowerCase(); + for ( const element of container.querySelectorAll( '.site-list__entry > label' ) ) { + const isVisible = element.innerText.toLowerCase().includes( value ); + element.parentNode.setAttribute( 'data-is-filtered-out', !isVisible ); + } + }, 50 ), + } + } ), + } ); + } + + + /** + * @param {( SiteListEntity[] | SiteListEntity )[]} wikis + * @return {HTMLElement} + */ + static #createSiteList( wikis ) { + const result = createDomElement( 'div', { + classes: [ 'site-list' ], + } ); + + for ( const pack of wikis ) { + // Recurse if this is a site group + if ( Array.isArray( pack ) ) { + result.appendChild( this.#createSiteList( pack ) ); + } else if ( 'spacer' in pack ) { + createDomElement( 'h3', { + classes: [ 'site-list__heading' ], + text: pack.spacer, + appendTo: result, + } ); + } else { + createDomElement( 'div', { + classes: [ 'site-list__entry' ], + attributes: { + 'data-wiki-id': pack.id, + }, + html: [ + createDomElement( 'input', { + attributes: { + type: 'checkbox', + id: `site-list__toggle--${pack.id}`, + 'data-setting-id': 'disabledWikis', + 'data-array-value': pack.id, + 'data-on': 'false', + 'data-off': 'true', + }, + } ), + createDomElement( 'label', { + attributes: { + for: `site-list__toggle--${pack.id}`, + }, + text: pack.name, + } ), + createDomElement( 'a', { + classes: [ 'site-list__site-link' ], + attributes: { + href: `https://${pack.id}.wiki.gg`, + target: '_blank', + }, + } ), + ], + appendTo: result, + } ); + } + } + + return result; + } }