diff --git a/src/components/VueCommand.vue b/src/components/VueCommand.vue index 14a2b0e4..4534c7a5 100644 --- a/src/components/VueCommand.vue +++ b/src/components/VueCommand.vue @@ -63,6 +63,7 @@ 'vue-command__history--invert': invert }" @click="autoFocus"> +
- { ) }) +// Determinates if the scrollbar is at the bottom +let scrolledToBottom = true + // Removes and adds the dispatched query to enforce the queries first position const addDispatchedQuery = dispatchedQuery => { local.dispatchedQueries.delete(dispatchedQuery) @@ -481,10 +488,46 @@ onMounted(() => { bindEventListener(currentInstance.refs, currentInstance.exposed) } + // TODO Norris' async response triggers new resize! + // Scroll to bottom if history changes + // Compute history height + const computeHistoryHeight = () => { + let historyHeight = 0 + for (const vueCommandHistroyEntry of vueCommandHistoryRef.value.children) { + historyHeight += get(vueCommandHistroyEntry.getBoundingClientRect(), 'height') + } + + return historyHeight + } + let isTriggeredByResize = false + // Observe if scrolled to bottom + // We use a timeout to force resize observer to run first + // Is called twice: First resize, then scroll to bottom + const eventListener = () => { + setTimeout(() => { + console.debug(isTriggeredByResize) + if (isTriggeredByResize) { + return + } + // Determinate if user scrolled to bottom + scrolledToBottom = eq( + floor(Math.abs( + vueCommandHistoryRef.value.scrollTop + vueCommandHistoryRef.value.clientHeight >= vueCommandHistoryRef.value.scrollHeight + )), + 0) + }, 0) + } + vueCommandHistoryRef.value.addEventListener('scroll', eventListener) + + // Scroll to bottom if resized and scrolled to bottom before const resizeObsever = new ResizeObserver(() => { - // TODO Only scroll to bottom if user scrolled to bottom before - vueCommandHistoryRef.value.scrollTop = vueCommandHistoryRef.value.scrollHeight + isTriggeredByResize = true + if (scrolledToBottom != null) { + // This fires scroll + vueCommandHistoryRef.value.scrollTop = vueCommandHistoryRef.value.scrollHeight + } + isTriggeredByResize = false }) for (const vueCommandHistoryEntry of vueCommandHistoryRef.value.children) { resizeObsever.observe(vueCommandHistoryEntry) diff --git a/src/components/VueCommandQuery.vue b/src/components/VueCommandQuery.vue index f1e4d40d..2f610f01 100644 --- a/src/components/VueCommandQuery.vue +++ b/src/components/VueCommandQuery.vue @@ -24,7 +24,7 @@ 'vue-command__query__input': !invert, 'vue-command__query__input--invert': invert }" - :disabled="isOutdatedQuery" + :disabled="isDisabledQuery" :placeholder="placeholder" autocapitalize="none" autocorrect="off" @@ -58,7 +58,7 @@ 'vue-command__multiline-query__input': !invert, 'vue-command__multiline-query__input--invert': invert }" - :disabled="isOutdatedMultilineQuery(index)" + :disabled="isDisabledMultilineQuery(index)" :value="multilineQuery" autocapitalize="none" autocorrect="off" @@ -176,6 +176,8 @@ const local = reactive({ // Entered with "\" const multilineQueries = reactive([]) +// Determinates if the given multiline query by index is before the current +// reverse I search or if reverse I search is not active const isBeforeReverseISearch = computed(() => { return index => xor( !isReverseISearch.value, @@ -185,7 +187,8 @@ const isBeforeReverseISearch = computed(() => { ) ) }) -const isOutdatedMultilineQuery = computed(() => { +// Determinates if the given multiline query by index is outdated +const isDisabledMultilineQuery = computed(() => { return index => or( isOutdated.value, and( @@ -194,7 +197,8 @@ const isOutdatedMultilineQuery = computed(() => { ) ) }) -const isOutdatedQuery = computed(() => { +// As soon as the there multiline queries, query is disabled +const isDisabledQuery = computed(() => { return or(isOutdated.value, !isEmpty(multilineQueries)) }) // Returns the last query or last multiline query