Browser extension that demonstrates the Web Annotation Discovery mechanism: subscribe to people’s annotation collections/‘feeds’, to see their notes on the web; and create & publish annotations yourself.

web-annotation-discovery-we.../src/components/ AnnotationsList.tsx
94 lines
2.6 KiB

  1. import { Component, h, Fragment } from 'preact';
  2. import classes from './AnnotationsList.module.scss';
  3. import { Annotation } from '../storage/Annotation';
  4. import { getTargetUrls } from 'web-annotation-utils';
  5. import { IAnnotationSource } from '../storage/AnnotationSource';
  6. import { AnnotationBody } from '../content_script/AnnotationBody';
  7. interface AnnotationsListProps {
  8. source?: IAnnotationSource;
  9. withTotal?: boolean;
  10. }
  11. interface AnnotationsListState {
  12. annotations?: Annotation[];
  13. totalAnnotationCount?: number;
  14. }
  15. export class AnnotationsList extends Component<
  16. AnnotationsListProps,
  17. AnnotationsListState
  18. > {
  19. state: AnnotationsListState = {};
  20. async componentDidMount() {
  21. await this.loadData();
  22. }
  23. async componentDidUpdate(previousProps: Readonly<AnnotationsListProps>) {
  24. if (
  25. previousProps.source?.lastModified !== this.props.source?.lastModified
  26. ) {
  27. this.loadData();
  28. }
  29. }
  30. async loadData() {
  31. let annotations;
  32. if (this.props.source) {
  33. if (this.props.source._id === undefined)
  34. throw new Error(`Got source without an _id`);
  35. annotations = await Annotation.getAnnotationsFromSource(
  36. this.props.source._id,
  37. );
  38. } else {
  39. annotations = await Annotation.getAll();
  40. }
  41. this.setState({ annotations });
  42. }
  43. render(
  44. { withTotal }: AnnotationsListProps,
  45. { annotations }: AnnotationsListState,
  46. ) {
  47. const annotationList = annotations?.map((annotation) => {
  48. const webAnnotation = annotation.data.annotation;
  49. return (
  50. <li class={classes.annotationWrapper} key={annotation.data._id}>
  51. <div class={classes.annotationBody}>
  52. <AnnotationBody
  53. body={webAnnotation.body}
  54. bodyValue={webAnnotation.bodyValue}
  55. />
  56. </div>
  57. <div>
  58. On:{' '}
  59. {getTargetUrls(webAnnotation.target).map((url) => (
  60. <><a href={url}>{url}</a>{' '}</>
  61. ))}
  62. </div>
  63. {' '}
  64. {/* <div class={classes.viewAsJson}>
  65. <a target="_blank" href={`data:application/json,${encodeURIComponent(JSON.stringify(annotation.data.annotation, null, 2))}`}>View annotation JSON</a>
  66. </div> */}
  67. </li>
  68. );
  69. });
  70. return (
  71. <>
  72. {annotationList ? (
  73. <ul class={classes.annotationList}>{annotationList}</ul>
  74. ) : (
  75. <p>
  76. <i>Loading…</i>
  77. </p>
  78. )}
  79. {withTotal && (
  80. <p>Total: {this.state.annotations?.length ?? <i>'counting…'</i>}</p>
  81. )}
  82. </>
  83. );
  84. }
  85. }