feat(uart) make settings use localStorage for make settings persistent
This commit is contained in:
parent
6a7ec54ce8
commit
85864823af
|
@ -5,10 +5,10 @@ import {
|
|||
type ShallowReactive,
|
||||
ref,
|
||||
shallowReactive,
|
||||
watch, reactive
|
||||
watch,
|
||||
} from "vue";
|
||||
import {AnsiUp} from 'ansi_up'
|
||||
import {debouncedWatch} from "@vueuse/core";
|
||||
import {debouncedWatch, useStorage} from "@vueuse/core";
|
||||
import {type IUartConfig, uart_send_msg} from "@/api/apiUart";
|
||||
import {isDevMode} from "@/composables/buildMode";
|
||||
import {useUartStore} from "@/stores/useUartStore";
|
||||
|
@ -270,10 +270,10 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
generateBaudArr(uartBaudList);
|
||||
|
||||
/* public value */
|
||||
const configPanelTab = ref("second");
|
||||
const configPanelTab = useStorage("configTab" ,"second");
|
||||
const configPanelShow = ref(true);
|
||||
const quickAccessPanelShow = ref(true);
|
||||
const enableAnsiDecode = ref(true);
|
||||
const enableAnsiDecode = useStorage("decodeANSI", true);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -283,12 +283,12 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
let RxSegment: Uint8Array = new Uint8Array(0);
|
||||
const RxRemainHexdump = ref("");
|
||||
|
||||
const frameBreakSequence = ref("\\n");
|
||||
const frameBreakAfterSequence = ref(true);
|
||||
const frameBreakSequence = useStorage("frameBreakSequence", "\\n");
|
||||
const frameBreakAfterSequence = useStorage("frameBreakAfterSequence", true);
|
||||
const frameBreakSequenceNormalized = computed(() => {
|
||||
return unescapeString(frameBreakSequence.value);
|
||||
});
|
||||
const frameBreakDelay = ref(0);
|
||||
const frameBreakDelay = useStorage("frameBreakDelay", 0);
|
||||
let frameBreakDelayTimeoutID: number = -1;
|
||||
|
||||
function frameBreakFlush() {
|
||||
|
@ -326,22 +326,34 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
|
||||
|
||||
|
||||
const frameBreakSize = ref(0);
|
||||
const frameBreakRules = reactive([{
|
||||
const frameBreakSize = useStorage("frameBreakSize", 0);
|
||||
const frameBreakRules = useStorage("breakRules", [{
|
||||
ref: frameBreakDelay,
|
||||
name: '超时(ms)',
|
||||
type: 'number',
|
||||
min: -1,
|
||||
draggable: false,
|
||||
transformData: () => {
|
||||
return {result: [] as Uint8Array[], remain: true};
|
||||
}
|
||||
transformData: breakDelay,
|
||||
}, {
|
||||
ref: frameBreakSequence,
|
||||
name: '匹配',
|
||||
type: 'text',
|
||||
draggable: true,
|
||||
transformData: (inputArray: Uint8Array[]) => {
|
||||
transformData: breakDelay,
|
||||
}, {
|
||||
ref: frameBreakSize,
|
||||
name: '字节(B)',
|
||||
type: 'number',
|
||||
min: 0,
|
||||
draggable: true,
|
||||
transformData: breakDelay,
|
||||
},])
|
||||
|
||||
function breakDelay(inputArray: Uint8Array[]) {
|
||||
return {result: [] as Uint8Array[], remain: true};
|
||||
}
|
||||
|
||||
function breakSequence(inputArray: Uint8Array[]) {
|
||||
if (frameBreakSequenceNormalized.value.length <= 0) {
|
||||
return {result: inputArray, remain: true};
|
||||
}
|
||||
|
@ -373,13 +385,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
const remain = startIndex < inputArray[inputArray.length - 1].length;
|
||||
return {result, remain};
|
||||
}
|
||||
}, {
|
||||
ref: frameBreakSize,
|
||||
name: '字节(B)',
|
||||
type: 'number',
|
||||
min: 0,
|
||||
draggable: true,
|
||||
transformData: (inputArray: Uint8Array[]) => {
|
||||
|
||||
function breakSize(inputArray: Uint8Array[]) {
|
||||
if (frameBreakSize.value <= 0) {
|
||||
return {result: inputArray, remain: true};
|
||||
}
|
||||
|
@ -393,7 +400,24 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
const remain = result[result.length - 1].length < frameBreakSize.value;
|
||||
return {result, remain};
|
||||
}
|
||||
},])
|
||||
|
||||
function reloadFrameBreak() {
|
||||
/* function and ref can not be stored in localStorage */
|
||||
for (let i = 0; i < frameBreakRules.value.length; i++) {
|
||||
if (frameBreakRules.value[i].name === "超时(ms)") {
|
||||
frameBreakRules.value[i].transformData = breakDelay;
|
||||
frameBreakRules.value[i].ref = frameBreakDelay;
|
||||
} else if (frameBreakRules.value[i].name === "匹配") {
|
||||
frameBreakRules.value[i].transformData = breakSequence;
|
||||
frameBreakRules.value[i].ref = frameBreakSequence;
|
||||
} else {
|
||||
frameBreakRules.value[i].transformData = breakSize;
|
||||
frameBreakRules.value[i].ref = frameBreakSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reloadFrameBreak();
|
||||
|
||||
function addStringMessage(input: string, isRX: boolean, doSend: boolean = false) {
|
||||
const unescaped = unescapeString(input);
|
||||
|
@ -417,8 +441,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
|
||||
frames.push(RxSegment);
|
||||
/* ready for adding new items */
|
||||
for (let i = 1; i < frameBreakRules.length; i++) {
|
||||
const ret: {result: Uint8Array[], remain: boolean} = frameBreakRules[i].transformData(frames);
|
||||
for (let i = 1; i < frameBreakRules.value.length; i++) {
|
||||
const ret: {result: Uint8Array[], remain: boolean} = frameBreakRules.value[i].transformData(frames);
|
||||
/* check if last item changed */
|
||||
if (!ret.remain || ret.result[ret.result.length - 1].length !== frames[frames.length - 1].length) {
|
||||
remain = ret.remain;
|
||||
|
@ -454,20 +478,21 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
RxRemainHexdump,
|
||||
addStringMessage,
|
||||
addSegment,
|
||||
reloadFrameBreak,
|
||||
}
|
||||
|
||||
const showText = ref(true);
|
||||
const showHex = ref(false);
|
||||
const showHexdump = ref(false);
|
||||
const enableLineWrap = ref(true);
|
||||
const showTimestamp = ref(true);
|
||||
const showText = useStorage('showText', true);
|
||||
const showHex = useStorage('showHex', false);
|
||||
const showHexdump = useStorage('showHexdump', false);
|
||||
const enableLineWrap = useStorage('lineWrap', false);
|
||||
const showTimestamp = useStorage('showTimestamp', true);
|
||||
const showVirtualScroll = ref(true);
|
||||
|
||||
const RxHexdumpColor = ref("#f0f9eb");
|
||||
const RxHexdumpColor = useStorage('RxHexdumpColor', "#f0f9eb");
|
||||
const RxTotalByteCount = ref(0);
|
||||
const RxByteCount = ref(0);
|
||||
|
||||
const TxHexdumpColor = ref("#ecf4ff");
|
||||
const TxHexdumpColor = useStorage('TxHexdumpColor', "#ecf4ff");
|
||||
const TxTotalByteCount = ref(0);
|
||||
const TxByteCount = ref(0);
|
||||
|
||||
|
@ -490,8 +515,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
const forceToBottom = ref(true);
|
||||
const filterChanged = ref(false);
|
||||
|
||||
const textPrefixValue = ref("")
|
||||
const textSuffixValue = ref("\\r\\n")
|
||||
const textPrefixValue = useStorage('sendFramePrefix', "");
|
||||
const textSuffixValue = useStorage('sendFrameSuffix', "\\r\\n");
|
||||
const hasAddedText = computed(() => {
|
||||
return textPrefixValue.value.length > 0 || textSuffixValue.value.length > 0;
|
||||
});
|
||||
|
@ -504,7 +529,7 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
stop_bits: 1,
|
||||
});
|
||||
|
||||
const filterValue = ref("");
|
||||
const filterValue = useStorage('frameFilterValue', '');
|
||||
const computedFilterValue = computed(() => {
|
||||
return unescapeString(filterValue.value);
|
||||
})
|
||||
|
@ -522,7 +547,7 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
|
||||
/* actual data shown on screen */
|
||||
const dataFiltered: ShallowReactive<IDataBuf[]> = shallowReactive([]);
|
||||
const dataFilterAutoUpdate = ref(true);
|
||||
const dataFilterAutoUpdate = useStorage("autoUpdate", true);
|
||||
const acceptIncomingData = ref(false);
|
||||
|
||||
// let frameBreakReady = false;
|
||||
|
@ -534,7 +559,7 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
}, {debounce: 300});
|
||||
|
||||
let batchDataUpdateIntervalID: number = -1;
|
||||
const batchUpdateTime = ref(80); /* ms */
|
||||
const batchUpdateTime = useStorage('updateInterval', 80); /* ms */
|
||||
let batchStartIndex: number = 0;
|
||||
|
||||
watch(batchUpdateTime, () => {
|
||||
|
@ -755,10 +780,10 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
|
|||
|
||||
|
||||
const enableLoopSend = ref(false);
|
||||
const loopSendFreq = ref(1000);
|
||||
const loopSendFreq = useStorage('loopSendInterval', 1000);
|
||||
let loopSendIntervalID: number = -1;
|
||||
const uartInputTextBox = ref("");
|
||||
const isSendTextFormat = ref(true);
|
||||
const uartInputTextBox = useStorage('sendBox', "");
|
||||
const isSendTextFormat = useStorage('sendBoxIsText', true);
|
||||
const isHexStringValid = ref(false);
|
||||
|
||||
function loopSend() {
|
||||
|
|
|
@ -1,29 +1,33 @@
|
|||
<template>
|
||||
<div class="flex items-center mb-2">
|
||||
<el-button class="mr-2" type="primary" @click="() => {
|
||||
<div class="flex items-center mb-2 flex-wrap gap-2">
|
||||
<el-button type="primary" @click="() => {
|
||||
macroData.push({
|
||||
input: '',
|
||||
btn_label: '发送',
|
||||
value: '',
|
||||
label: '发送',
|
||||
id: macroId,
|
||||
})
|
||||
macroId++;
|
||||
}">添加
|
||||
</el-button>
|
||||
<el-checkbox v-model="editMode" class="mr-2" border>编辑</el-checkbox>
|
||||
<el-checkbox v-model="draggableEnabled" class="mr-2" border>拖拽</el-checkbox>
|
||||
<el-checkbox v-model="editMode" border>编辑</el-checkbox>
|
||||
<el-checkbox v-model="draggableEnabled" border>拖拽</el-checkbox>
|
||||
</div>
|
||||
|
||||
<el-alert>IP地址改变会导致配置丢失</el-alert>
|
||||
|
||||
<VueDraggable v-model="macroData" handle=".sort-target"
|
||||
:animation="150" class="break-input">
|
||||
<div v-for="(item, index) in macroData" :key="item.id" class="w-full text-xs flex items-center py-0.5"
|
||||
:class="editMode ? 'macroBtnList' : ''">
|
||||
:class="editMode ? 'macroButtons' : ''">
|
||||
<el-tag size="large" type="success" v-if="draggableEnabled" class="sort-target mr-1">
|
||||
=
|
||||
</el-tag>
|
||||
<el-input v-model="item.input" class="font-mono">
|
||||
<el-input v-model="item.value" class="font-mono">
|
||||
<template #append>
|
||||
<el-input v-if="editMode" v-model="item.btn_label"></el-input>
|
||||
<el-button v-else @click="onSendClick(item.input)" type="primary">{{ item.btn_label }}</el-button>
|
||||
<el-input v-if="editMode" v-model="item.label"></el-input>
|
||||
<el-button v-else @click="onSendClick(item.value)" type="primary">{{ item.label }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-link :underline="false" @click="macroData.splice(index, 1);">
|
||||
|
@ -38,61 +42,62 @@
|
|||
<script setup lang="ts">
|
||||
import {VueDraggable} from "vue-draggable-plus";
|
||||
import {type Ref, ref} from "vue";
|
||||
import {globalNotify} from "@/composables/notification";
|
||||
import {globalNotify, globalNotifyRightSide} from "@/composables/notification";
|
||||
import {useDataViewerStore} from "@/stores/dataViewerStore";
|
||||
import {useStorage} from '@vueuse/core';
|
||||
|
||||
const editMode = ref(false);
|
||||
const draggableEnabled = ref(true);
|
||||
const store = useDataViewerStore();
|
||||
|
||||
interface macroItem {
|
||||
input: string;
|
||||
btn_label: string;
|
||||
value: string;
|
||||
label: string;
|
||||
id: number;
|
||||
}
|
||||
|
||||
let macroId = 3;
|
||||
|
||||
const macroData: Ref<macroItem[]> = ref([
|
||||
const macroDataDefault: Ref<macroItem[]> = ref([
|
||||
{
|
||||
input: 'AT',
|
||||
btn_label: '测试AT',
|
||||
value: 'AT',
|
||||
label: '测试AT',
|
||||
id: 1,
|
||||
},{
|
||||
input: 'AT+CSQ',
|
||||
btn_label: '询信号强度',
|
||||
value: 'AT+CSQ',
|
||||
label: '询信号强度',
|
||||
id: 2,
|
||||
},{
|
||||
input: 'AT+CGSN',
|
||||
btn_label: '询序列号',
|
||||
value: 'AT+CGSN',
|
||||
label: '询序列号',
|
||||
id: 3,
|
||||
}, {
|
||||
input: 'AT+CGMR',
|
||||
btn_label: '询固件版本',
|
||||
value: 'AT+CGMR',
|
||||
label: '询固件版本',
|
||||
id: 4,
|
||||
}, {
|
||||
input: 'AT+CMEE',
|
||||
btn_label: '询终端报错',
|
||||
value: 'AT+CMEE',
|
||||
label: '询终端报错',
|
||||
id: 5,
|
||||
}, {
|
||||
input: 'AT+NRB',
|
||||
btn_label: '重启',
|
||||
value: 'AT+NRB',
|
||||
label: '重启',
|
||||
id: 6,
|
||||
}, {
|
||||
input: 'AT+CGATT',
|
||||
btn_label: '询网络激活状态',
|
||||
value: 'AT+CGATT',
|
||||
label: '询网络激活状态',
|
||||
id: 7,
|
||||
}, {
|
||||
input: 'AT+CEREG',
|
||||
btn_label: '询网络注册状态',
|
||||
value: 'AT+CEREG',
|
||||
label: '询网络注册状态',
|
||||
id: 8,
|
||||
}, {
|
||||
input: 'AT+CSCON',
|
||||
btn_label: '询网络连接状态',
|
||||
value: 'AT+CSCON',
|
||||
label: '询网络连接状态',
|
||||
id: 9,
|
||||
}
|
||||
]);
|
||||
|
||||
const macroData = useStorage('macroItems', macroDataDefault);
|
||||
let macroId = macroData.value.reduce((max, item) => Math.max(max, item.id), 0) + 1;
|
||||
|
||||
function onSendClick(val: string) {
|
||||
if (!val && !store.hasAddedText) {
|
||||
|
@ -119,7 +124,7 @@ function onSendClick(val: string) {
|
|||
cursor: move;
|
||||
}
|
||||
|
||||
.macroBtnList :deep(.el-input-group__append) {
|
||||
.macroButtons :deep(.el-input-group__append) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue