Merge 2067126dec
into d4654dd7bd
This commit is contained in:
commit
f33d741980
|
@ -5,7 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<template>
|
<template>
|
||||||
<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }, (darkMode ? $style.dark : $style.light)]" v-html="html"></div>
|
<div
|
||||||
|
:class="[$style.codeBlockRoot, {
|
||||||
|
[$style.codeEditor]: codeEditor,
|
||||||
|
[$style.outerStyle]: !codeEditor && withOuterStyle,
|
||||||
|
[$style.dark]: darkMode,
|
||||||
|
[$style.light]: !darkMode,
|
||||||
|
}]" v-html="html"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -15,11 +21,15 @@ import type { BundledLanguage } from 'shiki/langs';
|
||||||
import { getHighlighter, getTheme } from '@/utility/code-highlighter.js';
|
import { getHighlighter, getTheme } from '@/utility/code-highlighter.js';
|
||||||
import { store } from '@/store.js';
|
import { store } from '@/store.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
code: string;
|
code: string;
|
||||||
lang?: string;
|
lang?: string;
|
||||||
codeEditor?: boolean;
|
codeEditor?: boolean;
|
||||||
}>();
|
withOuterStyle?: boolean;
|
||||||
|
}>(), {
|
||||||
|
codeEditor: false,
|
||||||
|
withOuterStyle: true,
|
||||||
|
});
|
||||||
|
|
||||||
const highlighter = await getHighlighter();
|
const highlighter = await getHighlighter();
|
||||||
const darkMode = store.r.darkMode;
|
const darkMode = store.r.darkMode;
|
||||||
|
@ -73,17 +83,13 @@ watch(() => props.lang, (to) => {
|
||||||
|
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
.codeBlockRoot :global(.shiki) {
|
.codeBlockRoot :global(.shiki) {
|
||||||
padding: 1em;
|
|
||||||
margin: 0;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
||||||
|
|
||||||
color: var(--shiki-fallback);
|
color: var(--shiki-fallback);
|
||||||
background-color: var(--shiki-fallback-bg);
|
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--shiki-fallback);
|
color: var(--shiki-fallback);
|
||||||
background-color: var(--shiki-fallback-bg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& pre,
|
& pre,
|
||||||
|
@ -92,26 +98,40 @@ watch(() => props.lang, (to) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.outerStyle.codeBlockRoot :global(.shiki) {
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--MI_THEME-divider);
|
||||||
|
background-color: var(--shiki-fallback-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.light.codeBlockRoot :global(.shiki) {
|
.light.codeBlockRoot :global(.shiki) {
|
||||||
color: var(--shiki-light);
|
color: var(--shiki-light);
|
||||||
background-color: var(--shiki-light-bg);
|
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--shiki-light);
|
color: var(--shiki-light);
|
||||||
background-color: var(--shiki-light-bg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.light.outerStyle.codeBlockRoot :global(.shiki),
|
||||||
|
.light.codeEditor.codeBlockRoot :global(.shiki) {
|
||||||
|
background-color: var(--shiki-light-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.dark.codeBlockRoot :global(.shiki) {
|
.dark.codeBlockRoot :global(.shiki) {
|
||||||
color: var(--shiki-dark);
|
color: var(--shiki-dark);
|
||||||
background-color: var(--shiki-dark-bg);
|
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--shiki-dark);
|
color: var(--shiki-dark);
|
||||||
background-color: var(--shiki-dark-bg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark.outerStyle.codeBlockRoot :global(.shiki),
|
||||||
|
.dark.codeEditor.codeBlockRoot :global(.shiki) {
|
||||||
|
background-color: var(--shiki-dark-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.codeBlockRoot.codeEditor {
|
.codeBlockRoot.codeEditor {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -5,15 +5,32 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.codeBlockRoot">
|
<div :class="$style.codeBlockRoot">
|
||||||
<button v-if="copyButton" :class="$style.codeBlockCopyButton" class="_button" @click="copy">
|
<button v-if="copyButton" :class="[$style.codeBlockCopyButton, { [$style.withOuterStyle]: withOuterStyle }]" class="_button" @click="copy">
|
||||||
<i class="ti ti-copy"></i>
|
<i class="ti ti-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<template #fallback>
|
<template #fallback>
|
||||||
<MkLoading/>
|
<pre
|
||||||
|
class="_selectable"
|
||||||
|
:class="[$style.codeBlockFallbackRoot, {
|
||||||
|
[$style.outerStyle]: withOuterStyle,
|
||||||
|
}]"
|
||||||
|
><code :class="$style.codeBlockFallbackCode">Loading...</code></pre>
|
||||||
</template>
|
</template>
|
||||||
<XCode v-if="show && lang" class="_selectable" :code="code" :lang="lang"/>
|
<XCode
|
||||||
<pre v-else-if="show" class="_selectable" :class="$style.codeBlockFallbackRoot"><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
|
v-if="show && lang"
|
||||||
|
class="_selectable"
|
||||||
|
:code="code"
|
||||||
|
:lang="lang"
|
||||||
|
:withOuterStyle="withOuterStyle"
|
||||||
|
/>
|
||||||
|
<pre
|
||||||
|
v-else-if="show"
|
||||||
|
class="_selectable"
|
||||||
|
:class="[$style.codeBlockFallbackRoot, {
|
||||||
|
[$style.outerStyle]: withOuterStyle,
|
||||||
|
}]"
|
||||||
|
><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
|
||||||
<button v-else :class="$style.codePlaceholderRoot" @click="show = true">
|
<button v-else :class="$style.codePlaceholderRoot" @click="show = true">
|
||||||
<div :class="$style.codePlaceholderContainer">
|
<div :class="$style.codePlaceholderContainer">
|
||||||
<div><i class="ti ti-code"></i> {{ i18n.ts.code }}</div>
|
<div><i class="ti ti-code"></i> {{ i18n.ts.code }}</div>
|
||||||
|
@ -26,7 +43,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, ref } from 'vue';
|
import { defineAsyncComponent, ref } from 'vue';
|
||||||
import * as os from '@/os.js';
|
|
||||||
import MkLoading from '@/components/global/MkLoading.vue';
|
import MkLoading from '@/components/global/MkLoading.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||||
|
@ -36,10 +52,12 @@ const props = withDefaults(defineProps<{
|
||||||
code: string;
|
code: string;
|
||||||
forceShow?: boolean;
|
forceShow?: boolean;
|
||||||
copyButton?: boolean;
|
copyButton?: boolean;
|
||||||
|
withOuterStyle?: boolean;
|
||||||
lang?: string;
|
lang?: string;
|
||||||
}>(), {
|
}>(), {
|
||||||
copyButton: true,
|
copyButton: true,
|
||||||
forceShow: false,
|
forceShow: false,
|
||||||
|
withOuterStyle: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code);
|
const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code);
|
||||||
|
@ -58,10 +76,16 @@ function copy() {
|
||||||
|
|
||||||
.codeBlockCopyButton {
|
.codeBlockCopyButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
|
||||||
right: 8px;
|
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
&.withOuterStyle {
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
@ -70,11 +94,17 @@ function copy() {
|
||||||
.codeBlockFallbackRoot {
|
.codeBlockFallbackRoot {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
padding: 1em;
|
|
||||||
margin: 0;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.outerStyle.codeBlockFallbackRoot {
|
||||||
|
background: var(--MI_THEME-bg);
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--MI_THEME-divider);
|
||||||
|
}
|
||||||
|
|
||||||
.codeBlockFallbackCode {
|
.codeBlockFallbackCode {
|
||||||
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,9 +101,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #value>{{ Math.floor(job.progress) }}%</template>
|
<template #value>{{ Math.floor(job.progress) }}%</template>
|
||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
</div>
|
</div>
|
||||||
<MkFolder :withSpacer="false">
|
<MkFolder>
|
||||||
<template #label>Options</template>
|
<template #label>Options</template>
|
||||||
<MkCode :code="JSON5.stringify(job.opts, null, '\t')" lang="js"/>
|
<MkCode :code="JSON5.stringify(job.opts, null, '\t')" lang="json5" :withOuterStyle="false"/>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'timeline'">
|
<div v-else-if="tab === 'timeline'">
|
||||||
|
@ -143,7 +143,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkTl>
|
</MkTl>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'data'">
|
<div v-else-if="tab === 'data'">
|
||||||
<MkCode :code="JSON5.stringify(job.data, null, '\t')" lang="js"/>
|
<MkCode :code="JSON5.stringify(job.data, null, '\t')" lang="json5"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'dataEdit'" class="_gaps_s">
|
<div v-else-if="tab === 'dataEdit'" class="_gaps_s">
|
||||||
<MkCodeEditor v-model="editData" lang="json5"></MkCodeEditor>
|
<MkCodeEditor v-model="editData" lang="json5"></MkCodeEditor>
|
||||||
|
@ -153,7 +153,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkCode :code="JSON5.stringify(job.returnValue, null, '\t')" lang="json5"/>
|
<MkCode :code="JSON5.stringify(job.returnValue, null, '\t')" lang="json5"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'error'" class="_gaps_s">
|
<div v-else-if="tab === 'error'" class="_gaps_s">
|
||||||
<MkCode v-for="log in job.stacktrace" :code="log" lang="stacktrace"/>
|
<MkCode v-for="log in job.stacktrace" :code="log"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'logs'">
|
<div v-else-if="tab === 'logs'">
|
||||||
<MkButton primary rounded @click="loadLogs()"><i class="ti ti-refresh"></i> Load logs</MkButton>
|
<MkButton primary rounded @click="loadLogs()"><i class="ti ti-refresh"></i> Load logs</MkButton>
|
||||||
|
|
Loading…
Reference in New Issue