diff --git a/front/public/hotkeys-iframe.js b/front/public/hotkeys-iframe.js index 9a2179a3f..d3dd54ea6 100644 --- a/front/public/hotkeys-iframe.js +++ b/front/public/hotkeys-iframe.js @@ -366,6 +366,13 @@ hotkeys('ctrl+k, command+k', function (event) { parent.postMessage('showSearchDialog', '*'); }); +hotkeys('ctrl+s, command+s', function (event) { + event.stopImmediatePropagation(); + event.preventDefault(); + + parent.postMessage('solveTask', '*'); +}); + // Hotkeys for HedgeDoc CodeMirror editor editor.setOption('extraKeys', { 'Ctrl-K': () => { @@ -376,4 +383,12 @@ editor.setOption('extraKeys', { parent.postMessage('showSearchDialog', '*'); return false; }, + 'Ctrl-S': () => { + parent.postMessage('solveTask', '*'); + return false; + }, + 'Cmd-S': () => { + parent.postMessage('solveTask', '*'); + return false; + }, }); diff --git a/front/src/components/Dialogs/SearchDialog.vue b/front/src/components/Dialogs/SearchDialog.vue index 34edc46ab..7e7f00ac0 100644 --- a/front/src/components/Dialogs/SearchDialog.vue +++ b/front/src/components/Dialogs/SearchDialog.vue @@ -4,12 +4,7 @@ Global search - ctrl+k + @@ -75,10 +70,12 @@ import ctfnote from 'src/ctfnote'; import { safeSlugify } from 'src/ctfnote/ctfs'; import { Ctf, Task } from 'src/ctfnote/models'; import { defineComponent, onMounted, onUnmounted, Ref, ref } from 'vue'; +import ShortcutHint from '../Utils/ShortcutHint.vue'; import TaskTagsList from '../Task/TaskTagsList.vue'; export default defineComponent({ components: { + ShortcutHint, TaskTagsList, }, emits: useDialogPluginComponent.emits, diff --git a/front/src/components/Dialogs/TaskSolveDialog.vue b/front/src/components/Dialogs/TaskSolveDialog.vue new file mode 100644 index 000000000..86cec86a6 --- /dev/null +++ b/front/src/components/Dialogs/TaskSolveDialog.vue @@ -0,0 +1,92 @@ + + + + + + Submit flag for {{ task.title }} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/front/src/components/Utils/ShortcutHint.vue b/front/src/components/Utils/ShortcutHint.vue new file mode 100644 index 000000000..cd8c07667 --- /dev/null +++ b/front/src/components/Utils/ShortcutHint.vue @@ -0,0 +1,40 @@ + + + + {{ key }} + + + + + + + + + diff --git a/front/src/ctfnote/tasks.ts b/front/src/ctfnote/tasks.ts index ce45b6970..9f729d00c 100644 --- a/front/src/ctfnote/tasks.ts +++ b/front/src/ctfnote/tasks.ts @@ -13,6 +13,8 @@ import { import { Ctf, Id, Task, WorkingOn, makeId } from './models'; import { Dialog } from 'quasar'; import TaskEditDialogVue from '../components/Dialogs/TaskEditDialog.vue'; +import TaskSolveDialogVue from '../components/Dialogs/TaskSolveDialog.vue'; +import { ref, computed } from 'vue'; export function buildWorkingOn(w: WorkingOnFragment): WorkingOn { return { @@ -56,36 +58,28 @@ export function useCancelWorkingOn() { } export function useSolveTaskPopup() { - const updateTask = useUpdateTask(); + // Used to force opening at most one dialog at a time + const openedSolveTaskPopup = ref(false); + + const lock = () => (openedSolveTaskPopup.value = true); + const unlock = () => (openedSolveTaskPopup.value = false); + const locked = computed(() => openedSolveTaskPopup.value); + return (task: Task) => { + // If the dialog is already opened, don't do anything + if (locked.value) return; + + lock(); + Dialog.create({ - title: 'Submit flag for ' + task.title, - color: 'primary', - class: 'compact-dialog', - prompt: { - model: task.flag ?? '', - type: 'text', - label: 'Flag', - filled: true, - class: 'solve-task-popup-focus', - }, - cancel: { - label: 'Cancel', - flat: true, - }, - ok: { - color: 'positive', - label: 'Save', + component: TaskSolveDialogVue, + componentProps: { + task, }, - }).onOk((flag: string) => { - void updateTask(task, { flag }); - }); - - window.setTimeout(() => { - ( - document.querySelector('.solve-task-popup-focus') as HTMLElement - ).focus(); - }, 0); + }) + .onOk(unlock) + .onCancel(unlock) + .onDismiss(unlock); }; } diff --git a/front/src/pages/Task.vue b/front/src/pages/Task.vue index 9a2877c62..1fd390678 100644 --- a/front/src/pages/Task.vue +++ b/front/src/pages/Task.vue @@ -1,6 +1,6 @@ - + @@ -23,8 +23,10 @@