diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2025-05-10 07:58:26 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-10 07:58:26 +0900 |
| commit | e1cd7c94fb13f8e49667b17554d22ce8de627a2a (patch) | |
| tree | a064c4b0937160cf1e26697dcfe18de8f2eb0144 /packages/frontend/src/composables/use-form.ts | |
| parent | Bump version to 2025.5.1-alpha.0 (diff) | |
| download | misskey-e1cd7c94fb13f8e49667b17554d22ce8de627a2a.tar.gz misskey-e1cd7c94fb13f8e49667b17554d22ce8de627a2a.tar.bz2 misskey-e1cd7c94fb13f8e49667b17554d22ce8de627a2a.zip | |
refactor(frontend): use* 関数の格納場所のフォルダ名を composables に変更 (#16004)
* refactor(frontend): use* 関数の格納場所を正式名称(composables)に変更
* migrate
* move useLoading
Diffstat (limited to 'packages/frontend/src/composables/use-form.ts')
| -rw-r--r-- | packages/frontend/src/composables/use-form.ts | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/packages/frontend/src/composables/use-form.ts b/packages/frontend/src/composables/use-form.ts new file mode 100644 index 0000000000..1c93557413 --- /dev/null +++ b/packages/frontend/src/composables/use-form.ts @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { computed, reactive, watch } from 'vue'; +import type { Reactive } from 'vue'; +import { deepEqual } from '@/utility/deep-equal'; + +function copy<T>(v: T): T { + return JSON.parse(JSON.stringify(v)); +} + +function unwrapReactive<T>(v: Reactive<T>): T { + return JSON.parse(JSON.stringify(v)); +} + +export function useForm<T extends Record<string, any>>(initialState: T, save: (newState: T) => Promise<void>) { + const currentState = reactive<T>(copy(initialState)); + const previousState = reactive<T>(copy(initialState)); + + const modifiedStates = reactive<Record<keyof T, boolean>>({} as any); + for (const key in currentState) { + modifiedStates[key] = false; + } + const modified = computed(() => Object.values(modifiedStates).some(v => v)); + const modifiedCount = computed(() => Object.values(modifiedStates).filter(v => v).length); + + watch([currentState, previousState], () => { + for (const key in modifiedStates) { + modifiedStates[key] = !deepEqual(currentState[key], previousState[key]); + } + }, { deep: true }); + + async function _save() { + await save(unwrapReactive(currentState)); + for (const key in currentState) { + previousState[key] = copy(currentState[key]); + } + } + + function discard() { + for (const key in currentState) { + currentState[key] = copy(previousState[key]); + } + } + + return { + state: currentState, + savedState: previousState, + modifiedStates, + modified, + modifiedCount, + save: _save, + discard, + }; +} |