fix: replace optional chaining/nullish coalescing in Vue templates

Vue template compiler does not support ?. and ?? in v-if expressions.
This commit is contained in:
LIghtJUNction
2026-04-29 06:46:47 +08:00
parent dcaaf6286a
commit c7cfb81756
2 changed files with 66 additions and 19 deletions

View File

@@ -145,12 +145,15 @@
}}</span>
<v-icon
v-if="
downloadingFiles.has(part.embedded_file.attachment_id ?? "")
downloadingFiles.has(
part.embedded_file.attachment_id || '',
)
"
size="small"
class="download-icon"
>mdi-loading mdi-spin</v-icon
>
<v-icon v-else size="small" class="download-icon"
>mdi-download</v-icon
>
@@ -504,7 +507,14 @@ export default defineComponent({
typeof toolCall.result === "string"
? JSON.parse(toolCall.result)
: toolCall.result
) as { results?: Array<{ index: string; url: string; title: string; snippet: string }> };
) as {
results?: Array<{
index: string;
url: string;
title: string;
snippet: string;
}>;
};
if (resultData.results && Array.isArray(resultData.results)) {
resultData.results.forEach((item) => {
@@ -557,8 +567,9 @@ export default defineComponent({
return;
}
const messageItems =
(this.$refs.messageContainer as HTMLElement | null)?.querySelectorAll(".message-item");
const messageItems = (
this.$refs.messageContainer as HTMLElement | null
)?.querySelectorAll(".message-item");
let messageIndex = -1;
if (messageItems) {
for (let i = 0; i < messageItems.length; i++) {
@@ -614,7 +625,9 @@ export default defineComponent({
// 获取被引用消息的内容
getReplyContent(messageId: string | number | undefined): string {
const replyMsg = this.messages.find((m: ChatRecord) => m.id === messageId);
const replyMsg = this.messages.find(
(m: ChatRecord) => m.id === messageId,
);
if (!replyMsg) {
return this.tm("reply.notFound");
}
@@ -900,8 +913,7 @@ export default defineComponent({
initCodeCopyButtons(): void {
this.$nextTick(() => {
if (this.isUnmounted) return;
const container =
this.$refs.messageContainer as HTMLElement | null;
const container = this.$refs.messageContainer as HTMLElement | null;
const codeBlocks = container?.querySelectorAll("pre code") || [];
codeBlocks.forEach((codeBlock) => {
const pre = codeBlock.parentElement;
@@ -1114,7 +1126,10 @@ export default defineComponent({
// Get input tokens (input_other + input_cached)
getInputTokens(
tokenUsage: { input_other?: number; input_cached?: number } | null | undefined,
tokenUsage:
| { input_other?: number; input_cached?: number }
| null
| undefined,
): number {
if (!tokenUsage) return 0;
return (tokenUsage.input_other || 0) + (tokenUsage.input_cached || 0);
@@ -1154,7 +1169,7 @@ export default defineComponent({
this.$emit("openRefs", refs);
},
},
};
});
</script>
<style scoped>

View File

@@ -31,7 +31,9 @@
{{ tm("actions.toolCallUsed", { name: toolCall.name ?? "" }) }}
<span style="opacity: 0.6">{{
toolCall.finished_ts
? formatDuration((toolCall.finished_ts ?? 0) - (toolCall.ts ?? 0))
? formatDuration(
(toolCall.finished_ts ?? 0) - (toolCall.ts ?? 0),
)
: getElapsedTime(toolCall.ts ?? 0)
}}</span>
<v-icon
@@ -178,11 +180,7 @@
renderPart.part?.embedded_file?.filename
}}</span>
<v-icon
v-if="
downloadingFiles?.has(
renderPart.part?.embedded_file?.attachment_id ?? "",
)
"
v-if="isFileDownloading(renderPart)"
size="small"
class="download-icon"
>mdi-loading mdi-spin</v-icon
@@ -235,7 +233,8 @@ const emitDownloadFile = (file: unknown): void => {
emit("download-file", file);
};
const isMarkdownCodeFence = (text: string): boolean => /^(```|~~~)/.test(text.trim());
const isMarkdownCodeFence = (text: string): boolean =>
/^(```|~~~)/.test(text.trim());
const looksLikeStandaloneHtml = (text: string): boolean => {
const normalized = text.trim();
@@ -303,11 +302,44 @@ const isIPythonTool = (toolCall: { name?: string }): boolean => {
);
};
interface PendingToolCall { name?: string; finished_ts?: number; ts?: number; id?: string; args?: unknown; result?: unknown; [key: string]: unknown }
interface PendingToolCall {
name?: string;
finished_ts?: number;
ts?: number;
id?: string;
args?: unknown;
result?: unknown;
[key: string]: unknown;
}
const getRenderParts = (messageParts: MessagePart[]): Array<{ type: string; toolCalls?: PendingToolCall[]; toolCall?: PendingToolCall; part?: MessagePart; key?: string }> => {
const isFileDownloading = (renderPart: {
type: string;
part?: { embedded_file?: { attachment_id?: string } };
}): boolean => {
const downloadSet = props.downloadingFiles;
if (!downloadSet) return false;
const attachmentId = renderPart?.part?.embedded_file?.attachment_id;
if (!attachmentId) return false;
return downloadSet.has(attachmentId);
};
const getRenderParts = (
messageParts: MessagePart[],
): Array<{
type: string;
toolCalls?: PendingToolCall[];
toolCall?: PendingToolCall;
part?: MessagePart;
key?: string;
}> => {
if (!Array.isArray(messageParts)) return [];
const rendered: Array<{ type: string; toolCalls?: PendingToolCall[]; toolCall?: PendingToolCall; part?: MessagePart; key?: string }> = [];
const rendered: Array<{
type: string;
toolCalls?: PendingToolCall[];
toolCall?: PendingToolCall;
part?: MessagePart;
key?: string;
}> = [];
let pendingToolCalls: PendingToolCall[] = [];
let groupIndex = 0;