Skip to content

Commit

Permalink
clamp saved actions
Browse files Browse the repository at this point in the history
  • Loading branch information
ElectronicBlueberry committed Aug 2, 2024
1 parent d17971f commit 22dcb9d
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 4 deletions.
26 changes: 25 additions & 1 deletion client/src/components/UndoRedo/UndoRedoStack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ watch(
() => props.storeId,
(id) => (currentStore.value = useUndoRedoStore(id))
);
function onInput(event: Event) {
const value = (event.target as HTMLInputElement).value;
const valueNumber = parseFloat(value);
const nonNanValue = isNaN(valueNumber) ? 0 : valueNumber;
currentStore.value.savedUndoActions = nonNanValue;
savedUndoActions.value = nonNanValue;
}
const savedUndoActions = ref(currentStore.value.savedUndoActions);
function updateSavedUndoActions() {
savedUndoActions.value = currentStore.value.savedUndoActions;
}
</script>

<template>
Expand Down Expand Up @@ -59,7 +74,16 @@ watch(

<label>
Max saved changes
<input v-model.number="currentStore.maxUndoActions" type="number" step="1" min="10" max="10000" />
<input
:value="savedUndoActions"
type="number"
step="1"
:min="currentStore.minUndoActions"
:max="currentStore.maxUndoActions"
@input="onInput"
@focusin="updateSavedUndoActions"
@focusout="updateSavedUndoActions"
@keyup.enter="updateSavedUndoActions" />
</label>
</section>
</template>
Expand Down
49 changes: 49 additions & 0 deletions client/src/composables/math.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* There are similar functions to those in this module in vue-use, but they only work one-way.
* Unlike vue-use, these composables return refs which can be set.
*/

import { type MaybeRefOrGetter, toValue } from "@vueuse/core";
import { computed, type Ref } from "vue";

/**
* Wraps a number ref, restricting it's values to a given range
*
* @param ref ref containing a number to wrap
* @param min lowest possible value of range
* @param max highest possible value of range
* @returns clamped ref
*/
export function useClamp(ref: Ref<number>, min: MaybeRefOrGetter<number>, max: MaybeRefOrGetter<number>): Ref<number> {
const clamp = (value: number) => {
return Math.min(Math.max(value, toValue(min)), toValue(max));
};

const clampedRef = computed({
get: () => clamp(ref.value),
set: (value) => (ref.value = clamp(value)),
});

return clampedRef;
}

/**
* Wraps a number ref, restricting it's values to align to a given step size
*
* @param ref ref containing a number to wrap
* @param stepSize size of steps to restrict value to
* @returns wrapped red
*/
export function useStep(ref: Ref<number>, stepSize: MaybeRefOrGetter<number> = 1): Ref<number> {
const step = (value: number) => {
const stepSizeValue = toValue(stepSize);
return Math.round(value / stepSizeValue) * stepSizeValue;
};

const steppedRef = computed({
get: () => step(ref.value),
set: (value) => (ref.value = step(value)),
});

return steppedRef;
}
13 changes: 10 additions & 3 deletions client/src/stores/undoRedoStore/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { computed, ref } from "vue";

import { useClamp, useStep } from "@/composables/math";
import { useUserLocalStorage } from "@/composables/userLocalStorage";
import { defineScopedStore } from "@/stores/scopedStore";

Expand All @@ -22,9 +23,13 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
const undoActionStack = ref<UndoRedoAction[]>([]);
const redoActionStack = ref<UndoRedoAction[]>([]);

const maxUndoActions = useUserLocalStorage(`undoRedoStore-maxUndoActions`, 100);
const minUndoActions = ref(10);
const maxUndoActions = ref(10000);

/** names of actions which were deleted due to maxUndoActions being exceeded */
const savedUndoActionsValue = useUserLocalStorage(`undoRedoStore-savedUndoActions`, 100);
const savedUndoActions = useClamp(useStep(savedUndoActionsValue), minUndoActions, maxUndoActions);

/** names of actions which were deleted due to savedUndoActions being exceeded */
const deletedActions = ref<string[]>([]);

function $reset() {
Expand Down Expand Up @@ -59,7 +64,7 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
clearRedoStack();
undoActionStack.value.push(action);

while (undoActionStack.value.length > maxUndoActions.value && undoActionStack.value.length > 0) {
while (undoActionStack.value.length > savedUndoActions.value && undoActionStack.value.length > 0) {
const action = undoActionStack.value.shift();
deletedActions.value.push(action?.name ?? "unnamed action");
action?.destroy();
Expand Down Expand Up @@ -186,7 +191,9 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
return {
undoActionStack,
redoActionStack,
minUndoActions,
maxUndoActions,
savedUndoActions,
deletedActions,
undo,
redo,
Expand Down

0 comments on commit 22dcb9d

Please sign in to comment.