src/presentation/components/Code/CodeButtons/CodeRunButton.vue
<template>
<IconButton
v-if="canRun"
text="Run"
icon-name="play"
@click="runCode"
/>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue';
import { injectKey } from '@/presentation/injectionSymbols';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { CodeRunError } from '@/application/CodeRunner/CodeRunner';
import IconButton from './IconButton.vue';
import { createScriptErrorDialog } from './ScriptErrorDialog';
export default defineComponent({
components: {
IconButton,
},
setup() {
const { currentState, currentContext } = injectKey((keys) => keys.useCollectionState);
const { os, isRunningAsDesktopApplication } = injectKey((keys) => keys.useRuntimeEnvironment);
const { codeRunner } = injectKey((keys) => keys.useCodeRunner);
const { dialog } = injectKey((keys) => keys.useDialog);
const { scriptDiagnosticsCollector } = injectKey((keys) => keys.useScriptDiagnosticsCollector);
const canRun = computed<boolean>(() => getCanRunState(
currentState.value.os,
isRunningAsDesktopApplication,
os,
));
async function runCode() {
if (!codeRunner) { throw new Error('missing code runner'); }
const { success, error } = await codeRunner.runCode(
currentContext.state.code.current,
currentContext.state.collection.scripting.fileExtension,
);
if (!success) {
await handleCodeRunFailure(error);
}
}
async function handleCodeRunFailure(error: CodeRunError) {
dialog.showError(...(await createScriptErrorDialog({
errorContext: 'run',
errorType: error.type,
errorMessage: error.message,
isFileReadbackError: error.type === 'FileReadbackVerificationError',
}, scriptDiagnosticsCollector)));
}
return {
canRun,
runCode,
};
},
});
function getCanRunState(
selectedOs: OperatingSystem,
isRunningAsDesktopApplication: boolean,
hostOs: OperatingSystem | undefined,
): boolean {
const isRunningOnSelectedOs = selectedOs === hostOs;
return isRunningAsDesktopApplication && isRunningOnSelectedOs;
}
</script>