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/content_script/ MarginalAnnotations.tsx
83 lines
2.3 KiB

  1. import { h, Component, ComponentChildren } from 'preact';
  2. import classes from './MarginalAnnotations.module.scss';
  3. import cls from 'classnames';
  4. import { AnnotationTargetHighlight } from './AnnotationTargetHighlight';
  5. import type { IAnnotation, IAnnotationWithSource } from '../storage/Annotation';
  6. import { WebAnnotation } from 'web-annotation-utils';
  7. interface MarginalAnnotationsProps {
  8. appContainer: Node;
  9. annotations: IAnnotationWithSource[];
  10. annotationInFocus?: IAnnotationWithSource;
  11. toolbarButtons?: ComponentChildren;
  12. onUpdateAnnotation: (
  13. id: IAnnotation['_id'],
  14. newWebAnnotation: WebAnnotation,
  15. ) => Promise<void>;
  16. onDeleteAnnotation: (id: IAnnotation['_id']) => Promise<void>;
  17. }
  18. interface MarginalAnnotationsState {
  19. showAll: boolean;
  20. }
  21. export class MarginalAnnotations extends Component<
  22. MarginalAnnotationsProps,
  23. MarginalAnnotationsState
  24. > {
  25. state: MarginalAnnotationsState = { showAll: false };
  26. toggleShowAll = () => {
  27. this.setState(({ showAll }) => ({ showAll: !showAll }));
  28. };
  29. render(
  30. {
  31. annotations,
  32. annotationInFocus,
  33. toolbarButtons,
  34. appContainer,
  35. onUpdateAnnotation,
  36. onDeleteAnnotation,
  37. }: MarginalAnnotationsProps,
  38. { showAll }: MarginalAnnotationsState,
  39. ) {
  40. const annotationElements = annotations.map((annotation) => (
  41. <AnnotationTargetHighlight
  42. key={annotation._id}
  43. annotation={annotation}
  44. appContainer={appContainer}
  45. inFocus={annotation._id === annotationInFocus?._id}
  46. onUpdateAnnotation={onUpdateAnnotation}
  47. onDeleteAnnotation={onDeleteAnnotation}
  48. />
  49. ));
  50. return (
  51. <div class={classes.annotationOuterContainer}>
  52. <div
  53. class={cls(classes.annotationContainer, {
  54. [classes.showAll]: showAll,
  55. })}
  56. >
  57. <div class={classes.toolbarContainer}>
  58. <div class={classes.toolbar}>
  59. {toolbarButtons}
  60. {(toolbarButtons || annotations.length > 0) && (
  61. <button
  62. class={classes.showAllButton}
  63. onClick={this.toggleShowAll}
  64. title="Show/hide all annotations"
  65. >
  66. {showAll ? '❯' : '❮'}
  67. </button>
  68. )}
  69. </div>
  70. </div>
  71. {annotationElements}
  72. </div>
  73. </div>
  74. );
  75. }
  76. }