import { Component, h, Fragment, createRef } from 'preact'; import { RpcClient } from 'webextension-rpc'; import type { backgroundRpcServer } from '../background'; import { AnnotationSource } from '../storage/AnnotationSource'; import classes from './AnnotationSourcesList.module.scss'; import cls from 'classnames'; import niceTime from '../util/niceTime'; import { Annotation } from '../storage/Annotation'; import { AnnotationsList } from './AnnotationsList'; import infoIcon from '../assets/icons/info.svg'; import rssIcon from '../assets/icons/rss.svg'; const backgroundRpc = new RpcClient(); // Run refresh in the background: should continue if the page/popup is closed. const refreshAnnotationSource = backgroundRpc.func('refreshAnnotationSource'); const refreshAnnotationSources = backgroundRpc.func('refreshAnnotationSources'); interface AnnotationSourcesListProps { withAnnotations?: boolean; } interface AnnotationSourcesListState { sources?: AnnotationSource[]; totalAnnotationCount?: number; } export class AnnotationSourcesList extends Component< AnnotationSourcesListProps, AnnotationSourcesListState > { state: AnnotationSourcesListState = {}; refreshButton = createRef(); async componentDidMount() { await this.loadData(); } async loadData() { this.setState({ sources: await AnnotationSource.getAll(), // sources: await AnnotationSource.getActiveSources(), totalAnnotationCount: await Annotation.count(), }); } refreshAll = async () => { const button = this.refreshButton.current!; try { button.classList.add(classes.loading); button.disabled = true; await refreshAnnotationSources({ forceAll: true }); await this.loadData(); } catch (error) { alert(`Refreshing failed: ${error}`); throw error; } finally { button.disabled = false; button.classList.remove(classes.loading); } }; refreshSource = async (source: AnnotationSource) => { try { await refreshAnnotationSource(source.data, true); } catch (error) { alert(`Refreshing failed: ${error}`); } await this.loadData(); }; removeSource = async (source: AnnotationSource) => { await source.delete(); await this.loadData(); }; render( { withAnnotations }: AnnotationSourcesListProps, { sources }: AnnotationSourcesListState, ) { const sourceList = sources?.map((source) => (
  • {source.data.active && ( <> {' '} )} “{source.data.title}”
    {source.data.active ? 'Feed: ' : 'Source: '} {source.data.url}
    {' '}
    {source.data.active ? 'Last update: ' : 'Imported: '} {source.data.lastUpdate ? niceTime(source.data.lastUpdate) : '?'} {source.data.active || ( (this source is not refreshed automatically) )}
    {withAnnotations && (
    Stored annotations from this source
    )}
  • )); return (
    {sourceList ? (
      {sourceList}
    ) : (

    Loading list of sources…

    )}
    Total number of annotations:{' '} {this.state.totalAnnotationCount ?? 'counting…'}
    ); } }