added export conversation feature.

This commit is contained in:
Xiaohan-Tian
2025-08-21 21:56:22 -07:00
parent c1112f41d5
commit 0c54332401
6 changed files with 181 additions and 8 deletions
+24 -1
View File
@@ -66,4 +66,27 @@ export const generateNewRegionName = (trackId: string): string => {
}
i++;
}
};
};
/** Create and trigger a download for a text/blob payload */
export function downloadBlob(content: BlobPart, mimeType: string, filename: string): void {
const blob = new Blob([content], { type: mimeType });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
/** Pad number with leading zero to 2 digits */
export function pad2(n: number): string {
return n.toString().padStart(2, '0');
}
/** Build timestamped filename suffix YYYY-MM-DD-hh-mm-ss */
export function buildTimestampSuffix(date: Date = new Date()): string {
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}-${pad2(date.getHours())}-${pad2(date.getMinutes())}-${pad2(date.getSeconds())}`;
}
+19 -1
View File
@@ -87,4 +87,22 @@ export function beatsToTimeString(
const mmm = milliseconds.toString().padStart(3, '0');
return `${BBB}:${B} | ${mm}:${ss}:${mmm}`;
}
}
/**
* Format a Date object into a human-readable local datetime string with timezone.
* Example: 2025/08/21, 19:57:11 GMT-7
*/
export function formatLocalDateTime(date: Date): string {
const options: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZoneName: 'short'
};
return date.toLocaleString(undefined, options);
}
+18 -1
View File
@@ -49,4 +49,21 @@ export function extractXMLFromString(input: string): string[] {
}
return matches;
}
}
/**
* Wrap XML blocks in content with fenced code blocks
* @param content - The input string that may contain XML blocks
* @returns The input string with XML blocks wrapped in fenced code blocks
*/
export const wrapXmlBlocksInContent = (content: string): string => {
if (!content) return content;
const xmlBlocks = extractXMLFromString(content);
if (!xmlBlocks || xmlBlocks.length === 0) return content;
let result = content;
for (const block of xmlBlocks) {
const fenced = '```\n' + block + '\n```';
result = result.split(block).join(fenced);
}
return result;
};