diff --git a/report-viewer/src/components/ScrollableComponent.vue b/report-viewer/src/components/ScrollableComponent.vue index 986680957..2e5a0e7fd 100644 --- a/report-viewer/src/components/ScrollableComponent.vue +++ b/report-viewer/src/components/ScrollableComponent.vue @@ -2,9 +2,26 @@ Offers a unstyled scrollable container --> + + diff --git a/report-viewer/src/components/fileDisplaying/CodeLine.vue b/report-viewer/src/components/fileDisplaying/CodeLine.vue index bcced0c92..e0644f65d 100644 --- a/report-viewer/src/components/fileDisplaying/CodeLine.vue +++ b/report-viewer/src/components/fileDisplaying/CodeLine.vue @@ -57,14 +57,6 @@ function matchSelected(match?: MatchInSingleFile) { const lineRef = ref(null) -function scrollTo() { - if (lineRef.value) { - lineRef.value.scrollIntoView({ block: 'center' }) - } -} - -defineExpose({ scrollTo }) - interface TextPart { line: string match?: MatchInSingleFile diff --git a/report-viewer/src/components/fileDisplaying/CodePanel.vue b/report-viewer/src/components/fileDisplaying/CodePanel.vue index 75010c1ea..6dce9e8e3 100644 --- a/report-viewer/src/components/fileDisplaying/CodePanel.vue +++ b/report-viewer/src/components/fileDisplaying/CodePanel.vue @@ -30,6 +30,7 @@ v-for="(_, index) in codeLines" :key="index" class="col-span-1 col-start-1 row-span-1 text-right" + ref="lineRefs" :style="{ gridRowStart: index + 1 }" @@ -40,7 +41,6 @@ import type { MatchInSingleFile } from '@/model/MatchInSingleFile' -import { ref, nextTick, type PropType, computed, type Ref } from 'vue' +import { ref, type PropType, computed, type Ref } from 'vue' import Interactable from '../InteractableComponent.vue' import type { SubmissionFile } from '@/model/File' import { highlight } from '@/utils/CodeHighlighter' @@ -94,7 +94,7 @@ const props = defineProps({ const emit = defineEmits(['matchSelected']) const collapsed = ref(true) -const lineRefs = ref<(typeof CodeLine)[]>([]) +const lineRefs = ref([]) const codeLines: Ref<{ line: string; matches: MatchInSingleFile[] }[]> = computed(() => highlight(props.file.data, props.highlightLanguage).map((line, index) => { @@ -109,17 +109,6 @@ function matchSelected(match: Match) { emit('matchSelected', match) } -/** - * Scrolls to the line number in the file. - * @param lineNumber line number in the file - */ -function scrollTo(lineNumber: number) { - collapsed.value = false - nextTick(function () { - lineRefs.value[lineNumber - 1].scrollTo() - }) -} - /** * Collapses the container. */ @@ -127,9 +116,19 @@ function collapse() { collapsed.value = true } +function expand() { + console.log('expand') + collapsed.value = false +} + +function getLineRect(lineNumber: number): DOMRect { + return lineRefs.value[lineNumber - 1].getBoundingClientRect() +} + defineExpose({ - scrollTo, - collapse + collapse, + expand, + getLineRect }) /** diff --git a/report-viewer/src/components/fileDisplaying/FilesContainer.vue b/report-viewer/src/components/fileDisplaying/FilesContainer.vue index 1e9b2365e..27dcd6553 100644 --- a/report-viewer/src/components/fileDisplaying/FilesContainer.vue +++ b/report-viewer/src/components/fileDisplaying/FilesContainer.vue @@ -17,7 +17,7 @@ > - + = ref([]) +const scrollContainer: Ref = ref(null) const tokenCount = computed(() => { return props.files.reduce((acc, file) => (file.tokenCount ?? 0) + acc - 1, 0) @@ -99,7 +100,19 @@ const tokenCount = computed(() => { function scrollTo(file: string, line: number) { const fileIndex = Array.from(props.files).findIndex((f) => f.fileName === file) if (fileIndex !== -1) { - codePanels.value[fileIndex].scrollTo(line) + console.log(fileIndex) + codePanels.value[fileIndex].expand() + nextTick(() => { + if (!scrollContainer.value) { + console.log('null') + return + } + const childToScrollTo = codePanels.value[fileIndex].getLineRect(line) as DOMRect + const scrollBox = scrollContainer.value.getRoot() as HTMLElement + scrollBox.scrollTo({ + top: childToScrollTo.top + scrollBox.scrollTop - (scrollBox.clientHeight * 2) / 3 + }) + }) } }