From b38b8c85866d82c8774dd38d6fe7e734fda7d6b2 Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Thu, 15 Feb 2024 18:45:43 +0100 Subject: [PATCH] Refactor and simplify code to create a highlight --- client/src/components/ContentBlock.vue | 53 +++-------------------- client/src/helpers/highlight.ts | 57 ++++++++++++++++++++++++- client/src/pages/instrument.vue | 59 +++++--------------------- 3 files changed, 73 insertions(+), 96 deletions(-) diff --git a/client/src/components/ContentBlock.vue b/client/src/components/ContentBlock.vue index 61b1ae11..2b7387e3 100644 --- a/client/src/components/ContentBlock.vue +++ b/client/src/components/ContentBlock.vue @@ -127,11 +127,11 @@ import type { Modal } from '@/plugins/modal.types'; import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts'; -import { getSelectionHandler, replacePopover, SelectionHandlerOptions } from '@/helpers/highlight'; +import { createHighlightCurry, getSelectionHandler, SelectionHandlerOptions } from '@/helpers/highlight'; import { graphql } from '@/__generated__'; import log from 'loglevel'; import highlightSidebar from '@/helpers/highlight-sidebar'; -import { doCreateHighlight, doUpdateHighlight } from '@/graphql/mutations'; +import { doUpdateHighlight } from '@/graphql/mutations'; import { AddHighlightArgument } from '@/__generated__/graphql'; export interface Props { @@ -290,50 +290,11 @@ const contentBlockHighlightsFragment = graphql(` let selectionHandler: (event: Event) => void; -const createHighlight = (highlight: AddHighlightArgument) => { - return doCreateHighlight( - { - input: { - highlight: highlight, - }, - }, - { - update: (cache, { data }) => { - const id = cache.identify({ id: props.contentBlock.id, __typename: 'ContentBlockNode' }); - const contentBlockWithHighlights = cache.readFragment({ - id, - fragment: contentBlockHighlightsFragment, - fragmentName: 'ContentBlockHighlightsFragment', - }); - const highlight = data?.addHighlight?.highlight; - - if (highlight) { - cache.writeFragment({ - id, - fragment: contentBlockHighlightsFragment, - fragmentName: 'ContentBlockHighlightsFragment', - data: { - ...contentBlockWithHighlights, - highlights: [ - ...(contentBlockWithHighlights?.highlights.filter((h) => h.id !== highlight.id) || []), - highlight, - ], - }, - }); - } - }, - } - ).then( - ({ - data: { - addHighlight: { highlight }, - }, - }) => { - replacePopover(highlight); - return highlight; - } - ); -}; +const createHighlight = createHighlightCurry({ + fragment: contentBlockHighlightsFragment, + fragmentName: 'ContentBlockHighlightsFragment', + cacheSignature: { id: props.contentBlock.id, __typename: 'ContentBlockNode' }, +}); const isNested = computed(() => props.contentBlock.root); // if it's nested, a the parent has the root propert onMounted(() => { diff --git a/client/src/helpers/highlight.ts b/client/src/helpers/highlight.ts index a2b9a44e..fe747f2a 100644 --- a/client/src/helpers/highlight.ts +++ b/client/src/helpers/highlight.ts @@ -1,8 +1,11 @@ import * as rangy from 'rangy'; import 'rangy/lib/rangy-textrange'; import log from 'loglevel'; -import { HighlightableNode } from '@/__generated__/graphql'; +import { AddHighlightArgument, HighlightableNode } from '@/__generated__/graphql'; import popover from '@/helpers/popover'; +import { doCreateHighlight } from '@/graphql/mutations'; +import { StoreObject } from '@apollo/client/cache'; +import { DocumentNode } from 'graphql'; // todo: we need to get the following information for a highlight: // Which ContentBlock? => contentBlock.id @@ -205,3 +208,55 @@ export const replacePopover = (highlight: HighlightNode) => { mark.click(); } }; + +interface CreateHighlightOptions { + fragment: DocumentNode; + fragmentName: string; + cacheSignature: StoreObject; +} +// todo: convert to async? +export const createHighlightCurry = + ({ fragment, fragmentName, cacheSignature }: CreateHighlightOptions) => + (highlight: AddHighlightArgument) => { + return doCreateHighlight( + { + input: { + highlight, + }, + }, + { + update: (cache, { data }) => { + const id = cache.identify(cacheSignature); + const fragmentWithHighlights = cache.readFragment({ + id, + fragment, + fragmentName, + }); + const highlight = data?.addHighlight?.highlight; + if (highlight) { + cache.writeFragment({ + id, + fragment, + fragmentName, + data: { + ...fragmentWithHighlights, + highlights: [ + ...(fragmentWithHighlights?.highlights.filter((h) => h.id !== highlight.id) || []), + highlight, + ], + }, + }); + } + }, + } + ).then( + ({ + data: { + addHighlight: { highlight }, + }, + }) => { + replacePopover(highlight); + return highlight; + } + ); + }; diff --git a/client/src/pages/instrument.vue b/client/src/pages/instrument.vue index 6a0227be..91e6050e 100644 --- a/client/src/pages/instrument.vue +++ b/client/src/pages/instrument.vue @@ -38,8 +38,8 @@ import { graphql } from '@/__generated__'; import { useQuery } from '@vue/apollo-composable'; import { computed } from '@vue/reactivity'; import { AddHighlightArgument, InstrumentNode } from '@/__generated__/graphql'; -import { getSelectionHandler, replacePopover, SelectionHandlerOptions } from '@/helpers/highlight'; -import { doCreateHighlight, doUpdateHighlight } from '@/graphql/mutations'; +import { createHighlightCurry, getSelectionHandler, SelectionHandlerOptions } from '@/helpers/highlight'; +import { doUpdateHighlight } from '@/graphql/mutations'; import highlightSidebar from '@/helpers/highlight-sidebar'; const instrumentDiv = ref(null); @@ -106,56 +106,17 @@ const instrumentHighlightsFragment = graphql(` } `); -// todo: merge with other createHighlight function over in ContentBlock.vue -const createHighlight = (highlight: AddHighlightArgument) => { - return doCreateHighlight( - { - input: { - highlight, - }, - }, - { - update: (cache, { data }) => { - const fragment = instrumentHighlightsFragment; - const fragmentName = 'instrumentHighlightsFragment'; - const id = cache.identify({ slug: instrument.value.slug, __typename: 'InstrumentNode' }); - const fragmentWithHighlights = cache.readFragment({ - id, - fragment, - fragmentName, - }); - const highlight = data?.addHighlight?.highlight; - if (highlight) { - cache.writeFragment({ - id, - fragment, - fragmentName, - data: { - ...fragmentWithHighlights, - highlights: [ - ...(fragmentWithHighlights?.highlights.filter((h) => h.id !== highlight.id) || []), - highlight, - ], - }, - }); - } - }, - } - ).then( - ({ - data: { - addHighlight: { highlight }, - }, - }) => { - replacePopover(highlight); - return highlight; - } - ); -}; - let selectionHandler; onResult(() => { const element = instrumentDiv.value; + const createHighlight = createHighlightCurry({ + fragment: instrumentHighlightsFragment, + fragmentName: 'instrumentHighlightsFragment', + cacheSignature: { + slug: instrument.value.slug, // this value is only known onResult + __typename: 'InstrumentNode', + }, + }); if (element !== null) { const options: SelectionHandlerOptions = {