tiny-rdm/frontend/src/components/dialogs/DecoderDialog.vue
2024-11-07 14:58:44 +08:00

208 lines
9.3 KiB
Vue

<script setup>
import useDialog from 'stores/dialog.js'
import { computed, reactive, ref, toRaw, watch } from 'vue'
import FileOpenInput from '@/components/common/FileOpenInput.vue'
import Delete from '@/components/icons/Delete.vue'
import Add from '@/components/icons/Add.vue'
import IconButton from '@/components/common/IconButton.vue'
import { cloneDeep, get, isEmpty } from 'lodash'
import usePreferencesStore from 'stores/preferences.js'
import { joinCommand } from '@/utils/decoder_cmd.js'
import Help from '@/components/icons/Help.vue'
const editName = ref('')
const decoderForm = reactive({
name: '',
auto: true,
decodePath: '',
decodeArgs: [],
encodePath: '',
encodeArgs: [],
})
const dialogStore = useDialog()
const prefStore = usePreferencesStore()
watch(
() => dialogStore.decodeDialogVisible,
(visible) => {
if (visible) {
const name = get(dialogStore.decodeParam, 'name', '')
if (!isEmpty(name)) {
editName.value = decoderForm.name = name
decoderForm.auto = dialogStore.decodeParam.auto !== false
decoderForm.decodePath = get(dialogStore.decodeParam, 'decodePath', '')
decoderForm.decodeArgs = get(dialogStore.decodeParam, 'decodeArgs', [])
decoderForm.encodePath = get(dialogStore.decodeParam, 'encodePath', '')
decoderForm.encodeArgs = get(dialogStore.decodeParam, 'encodeArgs', [])
} else {
editName.value = ''
decoderForm.decodePath = ''
decoderForm.encodePath = ''
decoderForm.decodeArgs = []
decoderForm.encodeArgs = []
}
} else {
editName.value = ''
}
},
)
const decodeCmdPreview = computed(() => {
return joinCommand(decoderForm.decodePath, decoderForm.decodeArgs, '')
})
const encodeCmdPreview = computed(() => {
return joinCommand(decoderForm.encodePath, decoderForm.encodeArgs, '')
})
const onAddOrUpdate = () => {
if (isEmpty(editName.value)) {
// add decoder
prefStore.addCustomDecoder(toRaw(decoderForm))
} else {
// update decoder
const param = cloneDeep(toRaw(decoderForm))
param.newName = param.name
param.name = editName.value
prefStore.updateCustomDecoder(param)
}
}
const onClose = () => {}
</script>
<template>
<n-modal
v-model:show="dialogStore.decodeDialogVisible"
:closable="false"
:mask-closable="false"
:negative-button-props="{ focusable: false, size: 'medium' }"
:negative-text="$t('common.cancel')"
:positive-button-props="{ focusable: false, size: 'medium' }"
:positive-text="$t('common.confirm')"
:show-icon="false"
:title="editName ? $t('dialogue.decoder.edit_name') : $t('dialogue.decoder.name')"
close-on-esc
preset="dialog"
transform-origin="center"
@esc="onClose"
@positive-click="onAddOrUpdate"
@negative-click="onClose">
<n-form :model="decoderForm" :show-require-mark="false" label-align="left" label-placement="top">
<n-form-item :label="$t('dialogue.decoder.decoder_name')" required show-require-mark>
<n-input v-model:value="decoderForm.name" />
</n-form-item>
<n-tabs type="line">
<!-- decode pane -->
<n-tab-pane :tab="$t('dialogue.decoder.decoder')" name="decode">
<n-form-item required show-require-mark>
<template #label>
<n-space :size="5" :wrap-item="false" align="center" justify="center">
<span>{{ $t('dialogue.decoder.decode_path') }}</span>
<n-tooltip trigger="hover">
<template #trigger>
<n-icon :component="Help" />
</template>
<div class="text-block" style="max-width: 600px">
{{ $t('dialogue.decoder.path_help') }}
</div>
</n-tooltip>
</n-space>
</template>
<file-open-input
v-model:value="decoderForm.decodePath"
:placeholder="$t('dialogue.decoder.decode_path')" />
</n-form-item>
<n-form-item required>
<template #label>
<n-space :size="5" :wrap-item="false" align="center" justify="center">
<span>{{ $t('dialogue.decoder.args') }}</span>
<n-tooltip trigger="hover">
<template #trigger>
<n-icon :component="Help" />
</template>
<div class="text-block" style="max-width: 600px">
{{ $t('dialogue.decoder.args_help').replace('[', '{').replace(']', '}') }}
</div>
</n-tooltip>
</n-space>
</template>
<n-dynamic-input v-model:value="decoderForm.decodeArgs" @create="() => ''">
<template #action="{ index, create, remove, move }">
<icon-button :icon="Add" size="18" @click="() => create(index)" />
<icon-button :icon="Delete" size="18" @click="() => remove(index)" />
</template>
</n-dynamic-input>
</n-form-item>
<n-card
v-if="decodeCmdPreview"
content-class="cmd-line"
content-style="padding: 10px;"
embedded
size="small">
{{ decodeCmdPreview }}
</n-card>
</n-tab-pane>
<!-- encode pane -->
<n-tab-pane :tab="$t('dialogue.decoder.encoder')" name="encode">
<n-form-item required show-require-mark>
<template #label>
<n-space :size="5" :wrap-item="false" align="center" justify="center">
<span>{{ $t('dialogue.decoder.encode_path') }}</span>
<n-tooltip trigger="hover">
<template #trigger>
<n-icon :component="Help" />
</template>
<div class="text-block" style="max-width: 600px">
{{ $t('dialogue.decoder.path_help') }}
</div>
</n-tooltip>
</n-space>
</template>
<file-open-input
v-model:value="decoderForm.encodePath"
:placeholder="$t('dialogue.decoder.encode_path')" />
</n-form-item>
<n-form-item :label="$t('dialogue.decoder.args')" required>
<template #label>
<n-space :size="5" :wrap-item="false" align="center" justify="center">
<span>{{ $t('dialogue.decoder.args') }}</span>
<n-tooltip trigger="hover">
<template #trigger>
<n-icon :component="Help" />
</template>
<div class="text-block" style="max-width: 600px">
{{ $t('dialogue.decoder.args_help').replace('[', '{').replace(']', '}') }}
</div>
</n-tooltip>
</n-space>
</template>
<n-dynamic-input v-model:value="decoderForm.encodeArgs" @create="() => ''">
<template #action="{ index, create, remove, move }">
<icon-button :icon="Add" size="18" @click="() => create(index)" />
<icon-button :icon="Delete" size="18" @click="() => remove(index)" />
</template>
</n-dynamic-input>
</n-form-item>
<n-card
v-if="encodeCmdPreview"
content-class="cmd-line"
content-style="padding: 10px;"
embedded
size="small">
{{ encodeCmdPreview }}
</n-card>
</n-tab-pane>
</n-tabs>
<n-form-item :show-feedback="false">
<n-checkbox v-model:checked="decoderForm.auto" :label="$t('dialogue.decoder.auto')" />
</n-form-item>
</n-form>
</n-modal>
</template>
<style lang="scss" scoped>
@use '@/styles/content';
</style>