diff --git a/client/.eslintrc.js b/client/.eslintrc.js
index 5de6f54c..b9dd09d7 100644
--- a/client/.eslintrc.js
+++ b/client/.eslintrc.js
@@ -94,5 +94,7 @@ module.exports = {
],
},
],
+ 'no-unused-vars': 'off',
+ '@typescript-eslint/no-unused-vars': 'error',
},
};
diff --git a/client/src/components/ContentBlock.vue b/client/src/components/ContentBlock.vue
index 222dc243..04289339 100644
--- a/client/src/components/ContentBlock.vue
+++ b/client/src/components/ContentBlock.vue
@@ -126,9 +126,12 @@ import type { Modal } from '@/plugins/modal.types';
import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts';
-import { getSelectionHandler } from '@/directives/highlight';
+import { getSelectionHandler, SelectionHandlerOptions } from '@/helpers/highlight';
import { graphql } from '@/__generated__';
import log from 'loglevel';
+import highlightSidebar from '@/helpers/highlight-sidebar';
+import { doUpdateHighlight } from '@/graphql/mutations';
+import { AddHighlightArgument } from '@/__generated__/graphql';
export interface Props {
contentBlock: ExtendedContentBlockNode;
@@ -255,11 +258,11 @@ graphql(`
selectionLength
contentUuid
startPosition
+ color
note {
text
}
text
- color
contentBlock {
id
}
@@ -312,6 +315,16 @@ const { mutate: doCreateHighlight } = useMutation(
})
);
+let selectionHandler: (event: Event) => void;
+
+const createHighlight = (highlight: AddHighlightArgument) => {
+ return doCreateHighlight({
+ input: {
+ highlight: highlight,
+ },
+ });
+};
+
onMounted(() => {
log.debug('onMounted ContentBlock called');
@@ -329,17 +342,38 @@ onMounted(() => {
}, PAGE_LOAD_TIMEOUT);
}
+ const options: SelectionHandlerOptions = {
+ el: element,
+ contentBlock: props.contentBlock,
+ onChangeColor: (newHighlight: AddHighlightArgument) => {
+ createHighlight(newHighlight);
+ },
+ onCreateNote: (newHighlight: AddHighlightArgument) => {
+ // we also open the sidebar when clicking on the note icon
+ createHighlight(newHighlight).then(
+ ({
+ data: {
+ addHighlight: { highlight },
+ },
+ }) => {
+ highlightSidebar.open({
+ highlight,
+ onUpdateText: (text: string) => {
+ doUpdateHighlight({
+ input: {
+ note: text,
+ id: highlight.id,
+ },
+ });
+ },
+ });
+ }
+ );
+ },
+ };
+ selectionHandler = getSelectionHandler(options);
// add the listener from highlights
- element.addEventListener(
- 'mouseup',
- getSelectionHandler(element, props.contentBlock, (newHighlight) => {
- doCreateHighlight({
- input: {
- highlight: newHighlight,
- },
- });
- })
- );
+ element.addEventListener('mouseup', selectionHandler);
}
});
@@ -347,8 +381,7 @@ onUnmounted(() => {
const element = contentBlockDiv.value;
if (element !== null) {
- console.log('unmounting');
- element.removeEventListener('mouseup', getSelectionHandler(element, props.contentBlock));
+ element.removeEventListener('mouseup', selectionHandler);
}
});
diff --git a/client/src/components/highlights/HighlightPopover.vue b/client/src/components/highlights/HighlightPopover.vue
index 4706f269..acfcdd64 100644
--- a/client/src/components/highlights/HighlightPopover.vue
+++ b/client/src/components/highlights/HighlightPopover.vue
@@ -17,7 +17,7 @@
diff --git a/client/src/directives/highlight.ts b/client/src/helpers/highlight.ts
similarity index 86%
rename from client/src/directives/highlight.ts
rename to client/src/helpers/highlight.ts
index 9cc53f00..afa32357 100644
--- a/client/src/directives/highlight.ts
+++ b/client/src/helpers/highlight.ts
@@ -1,10 +1,7 @@
-import { DirectiveBinding } from 'vue';
import * as rangy from 'rangy';
import 'rangy/lib/rangy-textrange';
import log from 'loglevel';
-import Mark from 'mark.js';
import { ContentBlockNode } from '@/__generated__/graphql';
-import ContentBlock from '@/components/ContentBlock.vue';
import popover from '@/helpers/popover';
// todo: we need to get the following information for a highlight:
@@ -119,8 +116,16 @@ const getSiblings = (element: HTMLElement): Element[] => {
return children;
};
+export interface SelectionHandlerOptions {
+ el: HTMLElement;
+ contentBlock: ContentBlockNode;
+ onChangeColor?: (highlight: any) => void;
+ onCreateNote?: (highlight: any) => void;
+}
+
export const getSelectionHandler =
- (el: HTMLElement, contentBlock: ContentBlockNode, onUpdateHighlight: (highlight: any) => void = () => {}) =>
+ ({ el, contentBlock, onChangeColor, onCreateNote }: SelectionHandlerOptions) =>
+ // (el: HTMLElement, contentBlock: ContentBlockNode, onUpdateHighlight: (highlight: any) => void = () => {}) =>
(_e: Event) => {
const rect = el.getBoundingClientRect();
if (isInsideViewport(rect.top) || isInsideViewport(rect.bottom)) {
@@ -167,24 +172,25 @@ export const getSelectionHandler =
const positionOfContentBlock = el.getBoundingClientRect();
const positionOfSelection = startAncestor?.getBoundingClientRect();
const offsetTop = positionOfSelection.top - positionOfContentBlock.top;
- popover
- .show({
- wrapper: el,
- offsetTop,
- onChooseColor: (color: string) => {
- console.log('chosenColor', color);
- highlightedText.color = color;
- onUpdateHighlight(highlightedText);
- },
- })
- .then(() => {
- console.log('confirmed here');
- })
- .catch(() => {
- console.log('canceled');
- });
- // todo: how do we save this? maybe we need to move away from the directive and do this inside the mounted
- // and unmounted hooks of the ContentBlock
+ const onChooseColor = (color: string) => {
+ console.log('chosenColor', color);
+ highlightedText.color = color;
+ if (onChangeColor) {
+ onChangeColor(highlightedText);
+ }
+ };
+ const onNote = () => {
+ highlightedText.color = 'alpha';
+ if (onCreateNote) {
+ onCreateNote(highlightedText);
+ }
+ };
+ popover.show({
+ wrapper: el,
+ offsetTop,
+ onChooseColor,
+ onNote,
+ });
}
}
}
diff --git a/client/src/helpers/popover.ts b/client/src/helpers/popover.ts
index 73b68a32..299ee943 100644
--- a/client/src/helpers/popover.ts
+++ b/client/src/helpers/popover.ts
@@ -9,10 +9,11 @@ interface Options {
onChooseColor: (color: string) => void;
// we don't use the id as a param here, because the calling component knows already which entity it is
onDelete?: () => void;
+ onNote?: () => void;
}
export default {
- show({ wrapper, offsetTop, onChooseColor, onDelete }: Options) {
+ show({ wrapper, offsetTop, onChooseColor, onDelete, onNote }: Options) {
const mountEl = document.createElement('div');
wrapper.appendChild(mountEl);
@@ -46,6 +47,11 @@ export default {
cleanUp();
_resolve();
},
+ onNote() {
+ if (onNote) {
+ onNote();
+ }
+ },
onClose() {
cleanUp();
_reject();
@@ -63,7 +69,7 @@ export default {
setTimeout(() => {
document.addEventListener('click', clickOutsideElementListener);
- }, 1); // do not triger ont the same event that created the popover
+ }, 1); // do not trigger on the same event that created the popover
return promise;
},
};