File size: 10,093 Bytes
4450790
1
{"version":3,"file":"KeybindingPanel-lcJrxHwZ.js","sources":["../../src/components/dialog/content/setting/keybinding/KeyComboDisplay.vue","../../src/components/dialog/content/setting/KeybindingPanel.vue"],"sourcesContent":["<template>\n  <span>\n    <template v-for=\"(sequence, index) in keySequences\" :key=\"index\">\n      <Tag :severity=\"isModified ? 'info' : 'secondary'\">\n        {{ sequence }}\n      </Tag>\n      <span v-if=\"index < keySequences.length - 1\" class=\"px-2\">+</span>\n    </template>\n  </span>\n</template>\n\n<script setup lang=\"ts\">\nimport Tag from 'primevue/tag'\nimport { KeyComboImpl } from '@/stores/keybindingStore'\nimport { computed } from 'vue'\n\nconst props = withDefaults(\n  defineProps<{\n    keyCombo: KeyComboImpl\n    isModified: boolean\n  }>(),\n  {\n    isModified: false\n  }\n)\n\nconst keySequences = computed(() => props.keyCombo.getKeySequences())\n</script>\n","<template>\n  <PanelTemplate value=\"Keybinding\" class=\"keybinding-panel\">\n    <template #header>\n      <SearchBox\n        v-model=\"filters['global'].value\"\n        :placeholder=\"$t('searchKeybindings') + '...'\"\n      />\n    </template>\n\n    <DataTable\n      :value=\"commandsData\"\n      v-model:selection=\"selectedCommandData\"\n      :global-filter-fields=\"['id']\"\n      :filters=\"filters\"\n      selectionMode=\"single\"\n      stripedRows\n      :pt=\"{\n        header: 'px-0'\n      }\"\n    >\n      <Column field=\"actions\" header=\"\">\n        <template #body=\"slotProps\">\n          <div class=\"actions invisible flex flex-row\">\n            <Button\n              icon=\"pi pi-pencil\"\n              class=\"p-button-text\"\n              @click=\"editKeybinding(slotProps.data)\"\n            />\n            <Button\n              icon=\"pi pi-trash\"\n              class=\"p-button-text p-button-danger\"\n              @click=\"removeKeybinding(slotProps.data)\"\n              :disabled=\"!slotProps.data.keybinding\"\n            />\n          </div>\n        </template>\n      </Column>\n      <Column\n        field=\"id\"\n        header=\"Command ID\"\n        sortable\n        class=\"max-w-64 2xl:max-w-full\"\n      >\n        <template #body=\"slotProps\">\n          <div\n            class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n            :title=\"slotProps.data.id\"\n          >\n            {{ slotProps.data.id }}\n          </div>\n        </template>\n      </Column>\n      <Column field=\"keybinding\" header=\"Keybinding\">\n        <template #body=\"slotProps\">\n          <KeyComboDisplay\n            v-if=\"slotProps.data.keybinding\"\n            :keyCombo=\"slotProps.data.keybinding.combo\"\n            :isModified=\"\n              keybindingStore.isCommandKeybindingModified(slotProps.data.id)\n            \"\n          />\n          <span v-else>-</span>\n        </template>\n      </Column>\n    </DataTable>\n\n    <Dialog\n      class=\"min-w-96\"\n      v-model:visible=\"editDialogVisible\"\n      modal\n      :header=\"currentEditingCommand?.id\"\n      @hide=\"cancelEdit\"\n    >\n      <div>\n        <InputText\n          class=\"mb-2 text-center\"\n          ref=\"keybindingInput\"\n          :modelValue=\"newBindingKeyCombo?.toString() ?? ''\"\n          placeholder=\"Press keys for new binding\"\n          @keydown.stop.prevent=\"captureKeybinding\"\n          autocomplete=\"off\"\n          fluid\n          :invalid=\"!!existingKeybindingOnCombo\"\n        />\n        <Message v-if=\"existingKeybindingOnCombo\" severity=\"error\">\n          Keybinding already exists on\n          <Tag\n            severity=\"secondary\"\n            :value=\"existingKeybindingOnCombo.commandId\"\n          />\n        </Message>\n      </div>\n      <template #footer>\n        <Button\n          label=\"Save\"\n          icon=\"pi pi-check\"\n          @click=\"saveKeybinding\"\n          :disabled=\"!!existingKeybindingOnCombo\"\n          autofocus\n        />\n      </template>\n    </Dialog>\n    <Button\n      class=\"mt-4\"\n      :label=\"$t('reset')\"\n      v-tooltip=\"$t('resetKeybindingsTooltip')\"\n      icon=\"pi pi-trash\"\n      severity=\"danger\"\n      fluid\n      text\n      @click=\"resetKeybindings\"\n    />\n  </PanelTemplate>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watchEffect } from 'vue'\nimport {\n  useKeybindingStore,\n  KeyComboImpl,\n  KeybindingImpl\n} from '@/stores/keybindingStore'\nimport { useCommandStore } from '@/stores/commandStore'\nimport DataTable from 'primevue/datatable'\nimport Column from 'primevue/column'\nimport Button from 'primevue/button'\nimport Dialog from 'primevue/dialog'\nimport InputText from 'primevue/inputtext'\nimport Message from 'primevue/message'\nimport Tag from 'primevue/tag'\nimport PanelTemplate from './PanelTemplate.vue'\nimport KeyComboDisplay from './keybinding/KeyComboDisplay.vue'\nimport SearchBox from '@/components/common/SearchBox.vue'\nimport { useToast } from 'primevue/usetoast'\nimport { FilterMatchMode } from '@primevue/core/api'\n\nconst filters = ref({\n  global: { value: '', matchMode: FilterMatchMode.CONTAINS }\n})\n\nconst keybindingStore = useKeybindingStore()\nconst commandStore = useCommandStore()\n\ninterface ICommandData {\n  id: string\n  keybinding: KeybindingImpl | null\n}\n\nconst commandsData = computed<ICommandData[]>(() => {\n  return Object.values(commandStore.commands).map((command) => ({\n    id: command.id,\n    keybinding: keybindingStore.getKeybindingByCommandId(command.id)\n  }))\n})\n\nconst selectedCommandData = ref<ICommandData | null>(null)\nconst editDialogVisible = ref(false)\nconst newBindingKeyCombo = ref<KeyComboImpl | null>(null)\nconst currentEditingCommand = ref<ICommandData | null>(null)\nconst keybindingInput = ref(null)\n\nconst existingKeybindingOnCombo = computed<KeybindingImpl | null>(() => {\n  if (!currentEditingCommand.value) {\n    return null\n  }\n\n  // If the new keybinding is the same as the current editing command, then don't show the error\n  if (\n    currentEditingCommand.value.keybinding?.combo?.equals(\n      newBindingKeyCombo.value\n    )\n  ) {\n    return null\n  }\n\n  if (!newBindingKeyCombo.value) {\n    return null\n  }\n\n  return keybindingStore.getKeybinding(newBindingKeyCombo.value)\n})\n\nfunction editKeybinding(commandData: ICommandData) {\n  currentEditingCommand.value = commandData\n  newBindingKeyCombo.value = commandData.keybinding\n    ? commandData.keybinding.combo\n    : null\n  editDialogVisible.value = true\n}\n\nwatchEffect(() => {\n  if (editDialogVisible.value) {\n    // nextTick doesn't work here, so we use a timeout instead\n    setTimeout(() => {\n      keybindingInput.value?.$el?.focus()\n    }, 300)\n  }\n})\n\nfunction removeKeybinding(commandData: ICommandData) {\n  if (commandData.keybinding) {\n    keybindingStore.unsetKeybinding(commandData.keybinding)\n    keybindingStore.persistUserKeybindings()\n  }\n}\n\nfunction captureKeybinding(event: KeyboardEvent) {\n  const keyCombo = KeyComboImpl.fromEvent(event)\n  newBindingKeyCombo.value = keyCombo\n}\n\nfunction cancelEdit() {\n  editDialogVisible.value = false\n  currentEditingCommand.value = null\n  newBindingKeyCombo.value = null\n}\n\nfunction saveKeybinding() {\n  if (currentEditingCommand.value && newBindingKeyCombo.value) {\n    const updated = keybindingStore.updateKeybindingOnCommand(\n      new KeybindingImpl({\n        commandId: currentEditingCommand.value.id,\n        combo: newBindingKeyCombo.value\n      })\n    )\n    if (updated) {\n      keybindingStore.persistUserKeybindings()\n    }\n  }\n  cancelEdit()\n}\n\nconst toast = useToast()\nasync function resetKeybindings() {\n  keybindingStore.resetKeybindings()\n  await keybindingStore.persistUserKeybindings()\n  toast.add({\n    severity: 'info',\n    summary: 'Info',\n    detail: 'Keybindings reset',\n    life: 3000\n  })\n}\n</script>\n\n<style scoped>\n:deep(.p-datatable-tbody) > tr > td {\n  @apply p-1;\n  min-height: 2rem;\n}\n\n:deep(.p-datatable-row-selected) .actions,\n:deep(.p-datatable-selectable-row:hover) .actions {\n  @apply visible;\n}\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAgBA,UAAM,QAAQ;AAUd,UAAM,eAAe,SAAS,MAAM,MAAM,SAAS,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;AC8GpE,UAAM,UAAU,IAAI;AAAA,MAClB,QAAQ,EAAE,OAAO,IAAI,WAAW,gBAAgB,SAAS;AAAA,IAAA,CAC1D;AAED,UAAM,kBAAkB;AACxB,UAAM,eAAe;AAOf,UAAA,eAAe,SAAyB,MAAM;AAClD,aAAO,OAAO,OAAO,aAAa,QAAQ,EAAE,IAAI,CAAC,aAAa;AAAA,QAC5D,IAAI,QAAQ;AAAA,QACZ,YAAY,gBAAgB,yBAAyB,QAAQ,EAAE;AAAA,MAC/D,EAAA;AAAA,IAAA,CACH;AAEK,UAAA,sBAAsB,IAAyB,IAAI;AACnD,UAAA,oBAAoB,IAAI,KAAK;AAC7B,UAAA,qBAAqB,IAAyB,IAAI;AAClD,UAAA,wBAAwB,IAAyB,IAAI;AACrD,UAAA,kBAAkB,IAAI,IAAI;AAE1B,UAAA,4BAA4B,SAAgC,MAAM;AAClE,UAAA,CAAC,sBAAsB,OAAO;AACzB,eAAA;AAAA,MACT;AAIE,UAAA,sBAAsB,MAAM,YAAY,OAAO;AAAA,QAC7C,mBAAmB;AAAA,MAAA,GAErB;AACO,eAAA;AAAA,MACT;AAEI,UAAA,CAAC,mBAAmB,OAAO;AACtB,eAAA;AAAA,MACT;AAEO,aAAA,gBAAgB,cAAc,mBAAmB,KAAK;AAAA,IAAA,CAC9D;AAED,aAAS,eAAe,aAA2B;AACjD,4BAAsB,QAAQ;AAC9B,yBAAmB,QAAQ,YAAY,aACnC,YAAY,WAAW,QACvB;AACJ,wBAAkB,QAAQ;AAAA,IAC5B;AANS;AAQT,gBAAY,MAAM;AAChB,UAAI,kBAAkB,OAAO;AAE3B,mBAAW,MAAM;AACC,0BAAA,OAAO,KAAK;WAC3B,GAAG;AAAA,MACR;AAAA,IAAA,CACD;AAED,aAAS,iBAAiB,aAA2B;AACnD,UAAI,YAAY,YAAY;AACV,wBAAA,gBAAgB,YAAY,UAAU;AACtD,wBAAgB,uBAAuB;AAAA,MACzC;AAAA,IACF;AALS;AAOT,aAAS,kBAAkB,OAAsB;AACzC,YAAA,WAAW,aAAa,UAAU,KAAK;AAC7C,yBAAmB,QAAQ;AAAA,IAC7B;AAHS;AAKT,aAAS,aAAa;AACpB,wBAAkB,QAAQ;AAC1B,4BAAsB,QAAQ;AAC9B,yBAAmB,QAAQ;AAAA,IAC7B;AAJS;AAMT,aAAS,iBAAiB;AACpB,UAAA,sBAAsB,SAAS,mBAAmB,OAAO;AAC3D,cAAM,UAAU,gBAAgB;AAAA,UAC9B,IAAI,eAAe;AAAA,YACjB,WAAW,sBAAsB,MAAM;AAAA,YACvC,OAAO,mBAAmB;AAAA,UAAA,CAC3B;AAAA,QAAA;AAEH,YAAI,SAAS;AACX,0BAAgB,uBAAuB;AAAA,QACzC;AAAA,MACF;AACW;IACb;AAbS;AAeT,UAAM,QAAQ;AACd,mBAAe,mBAAmB;AAChC,sBAAgB,iBAAiB;AACjC,YAAM,gBAAgB;AACtB,YAAM,IAAI;AAAA,QACR,UAAU;AAAA,QACV,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA,CACP;AAAA,IACH;AATe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}