fix 2
This commit is contained in:
@@ -1,16 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, defineAsyncComponent, ref } from 'vue';
|
||||
import { useRequestStore } from '../stores/requestStore';
|
||||
import { useSettingsStore } from '../stores/settingsStore';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { json } from '@codemirror/lang-json';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import { Clipboard, Check } from 'lucide-vue-next';
|
||||
|
||||
const CodeEditor = defineAsyncComponent(() => import('./CodeEditor.vue'));
|
||||
const store = useRequestStore();
|
||||
const settings = useSettingsStore();
|
||||
const isCopied = ref(false);
|
||||
const activeTab = ref<'body' | 'headers'>('body');
|
||||
|
||||
const isJsonResponse = computed(() => {
|
||||
const response = store.activeRequest.response;
|
||||
@@ -29,26 +25,14 @@ const isJsonResponse = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const extensions = computed(() => {
|
||||
const theme = EditorView.theme({
|
||||
"&": {
|
||||
backgroundColor: "transparent !important",
|
||||
height: "100%"
|
||||
},
|
||||
".cm-content, .cm-gutter": {
|
||||
fontFamily: `${settings.editorFontFamily} !important`
|
||||
},
|
||||
".cm-gutters": {
|
||||
backgroundColor: "transparent !important"
|
||||
}
|
||||
});
|
||||
const formattedHeaders = computed(() => {
|
||||
const response = store.activeRequest.response;
|
||||
if (!response) return '';
|
||||
|
||||
return [
|
||||
oneDark,
|
||||
theme,
|
||||
EditorView.editable.of(false),
|
||||
...(isJsonResponse.value ? [json()] : []),
|
||||
];
|
||||
return Object.entries(response.headers)
|
||||
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
||||
.map(([key, value]) => `${key}: ${value}`)
|
||||
.join('\n');
|
||||
});
|
||||
|
||||
const formattedBody = computed(() => {
|
||||
@@ -61,6 +45,10 @@ const formattedBody = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const displayedContent = computed(() => (
|
||||
activeTab.value === 'headers' ? formattedHeaders.value : formattedBody.value
|
||||
));
|
||||
|
||||
const statusColor = computed(() => {
|
||||
const s = store.activeRequest.response?.status || 0;
|
||||
if (s >= 200 && s < 300) return 'text-emerald-400';
|
||||
@@ -69,9 +57,9 @@ const statusColor = computed(() => {
|
||||
});
|
||||
|
||||
const copyToClipboard = async () => {
|
||||
if (!formattedBody.value) return;
|
||||
if (!displayedContent.value) return;
|
||||
try {
|
||||
await navigator.clipboard.writeText(formattedBody.value);
|
||||
await navigator.clipboard.writeText(displayedContent.value);
|
||||
isCopied.value = true;
|
||||
setTimeout(() => {
|
||||
isCopied.value = false;
|
||||
@@ -98,30 +86,50 @@ const copyToClipboard = async () => {
|
||||
Size: <span class="text-slate-300">{{ (store.activeRequest.response.size / 1024).toFixed(2) }} KB</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
@click="copyToClipboard"
|
||||
class="p-1.5 text-slate-400 hover:text-indigo-400 hover:bg-indigo-500/10 rounded transition-colors"
|
||||
title="Copy Body"
|
||||
>
|
||||
<Check v-if="isCopied" class="w-3.5 h-3.5" />
|
||||
<Clipboard v-else class="w-3.5 h-3.5" />
|
||||
</button>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex rounded-lg border border-slate-800 bg-slate-900 p-0.5">
|
||||
<button
|
||||
@click="activeTab = 'body'"
|
||||
class="rounded-md px-2.5 py-1 transition-colors"
|
||||
:class="activeTab === 'body' ? 'bg-indigo-500/15 text-indigo-300' : 'text-slate-400 hover:text-slate-200'"
|
||||
>
|
||||
Body
|
||||
</button>
|
||||
<button
|
||||
@click="activeTab = 'headers'"
|
||||
class="rounded-md px-2.5 py-1 transition-colors"
|
||||
:class="activeTab === 'headers' ? 'bg-indigo-500/15 text-indigo-300' : 'text-slate-400 hover:text-slate-200'"
|
||||
>
|
||||
Headers
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
@click="copyToClipboard"
|
||||
class="p-1.5 text-slate-400 hover:text-indigo-400 hover:bg-indigo-500/10 rounded transition-colors"
|
||||
:title="activeTab === 'headers' ? 'Copy Headers' : 'Copy Body'"
|
||||
>
|
||||
<Check v-if="isCopied" class="w-3.5 h-3.5" />
|
||||
<Clipboard v-else class="w-3.5 h-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Output -->
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<Codemirror
|
||||
:model-value="formattedBody"
|
||||
:style="{
|
||||
height: '100%',
|
||||
fontSize: settings.editorFontSize + 'px',
|
||||
fontFamily: settings.editorFontFamily
|
||||
}"
|
||||
:extensions="extensions"
|
||||
<CodeEditor
|
||||
:model-value="displayedContent"
|
||||
:language="activeTab === 'body' && isJsonResponse ? 'json' : 'text'"
|
||||
:read-only="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="store.requestError" class="flex-1 flex items-center justify-center p-6">
|
||||
<div class="max-w-2xl rounded-xl border border-rose-500/30 bg-rose-500/10 p-4 text-sm text-rose-200">
|
||||
{{ store.requestError }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex-1 flex items-center justify-center text-slate-600 text-sm">
|
||||
No response yet
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user