123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import Element, { emit, on, s } from '@dom111/element';
- import Collection from '../lib/Collection';
- import DAV from '../lib/DAV';
- import Entry from '../lib/Entry';
- import Item from './Item';
- import State from '../lib/State';
- import previewItems from '../lib/previewItems';
- import supportsFocusWithin from '../lib/supportsFocusWithin';
- export class List extends Element<HTMLUListElement> {
- #dav: DAV;
- #state: State;
- constructor(dav: DAV, state: State) {
- super(s('<ul class="loading"></ul>'));
- this.#dav = dav;
- this.#state = state;
- this.load();
- this.bindEvents();
- }
- private bindEvents(): void {
- this.#state.on('updated', (bypassCache: boolean): void => {
- if (this.#state.isDirectory()) {
- this.load(bypassCache);
- return;
- }
- const item = this.query<HTMLLIElement>(
- `[data-full-path="${this.#state.getPath()}"]`
- );
- if (!item) {
- return;
- }
- emit(item, new MouseEvent('click'));
- });
- this.#state.on('collection-updated', (): void => this.render());
- const arrowHandler = (event: KeyboardEvent): void => {
- if (!['ArrowUp', 'ArrowDown'].includes(event.key)) {
- return;
- }
- event.preventDefault();
- event.stopPropagation();
- const current = this.query(
- `li:focus${supportsFocusWithin ? ', li:focus-within' : ''}`
- ) as HTMLElement,
- [previous, next] = current
- ? previewItems(current)
- : [
- this.element().firstElementChild as HTMLElement,
- this.element().firstElementChild as HTMLElement,
- ];
- if (event.key === 'ArrowUp' && previous) {
- previous.focus();
- }
- if (event.key === 'ArrowDown' && next) {
- next.focus();
- }
- };
- on(document, 'keydown', arrowHandler);
- }
- async load(bypassCache: boolean = false): Promise<void> {
- const collection = await this.#dav.list(this.#state.getPath(), bypassCache);
- if (!collection) {
- return;
- }
- this.update(collection);
- }
- private render(): void {
- this.addClass('loading');
- this.empty();
- this.#state
- .getCollection()
- .forEach((entry: Entry): void =>
- this.append(new Item(entry, this.#dav, this.#state))
- );
- this.removeClass('loading');
- }
- update(collection: Collection): void {
- this.#state.setCollection(collection);
- this.render();
- }
- }
- export default List;
|