| <!DOCTYPE html> |
| <html lang="zh-Hant" class="h-full bg-gray-50 dark:bg-gray-900"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Qwen2.5‑1.5B‑Instruct – 繁體中文聊天</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
|
|
| |
| <script src="https://cdn.tailwindcss.com"></script> |
|
|
| |
| <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script> |
|
|
| |
| <link rel="stylesheet" href="/static/style.css"> |
| </head> |
|
|
| <body class="flex flex-col h-full" x-data="chatApp()"> |
| |
| <header class="bg-white dark:bg-gray-800 shadow p-4 flex items-center justify-between"> |
| <h1 class="text-xl font-semibold text-gray-800 dark:text-gray-100"> |
| Qwen2.5‑1.5B‑Instruct <span class="text-sm font-normal text-gray-500 dark:text-gray-400">(繁體中文)</span> |
| </h1> |
|
|
| |
| <button @click="toggleDark()" class="p-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700"> |
| <svg x-show="!dark" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-800" fill="none" |
| viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" |
| stroke-linejoin="round" stroke-width="2" |
| d="M12 3v1m0 16v1m8.66-9.66l-.71.71M4.05 19.95l-.71-.71M21 12h-1M4 12H3m15.36 5.36l-.71-.71M6.34 6.34l-.71-.71M12 5a7 7 0 100 14 7 7 0 000-14z"/></svg> |
| <svg x-show="dark" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-yellow-400" fill="none" |
| viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" |
| stroke-linejoin="round" stroke-width="2" |
| d="M12 3v1m0 16v1m8.66-9.66l-.71.71M4.05 19.95l-.71-.71M21 12h-1M4 12H3m15.36 5.36l-.71-.71M6.34 6.34l-.71-.71M12 5a7 7 0 100 14 7 7 0 000-14z"/></svg> |
| </button> |
| </header> |
|
|
| |
| <main class="flex-1 overflow-y-auto p-4 space-y-4" id="chat-window"> |
| <template x-for="msg in messages" :key="msg.id"> |
| <div :class="msg.role === 'assistant' ? 'flex justify-start' : 'flex justify-end'"> |
| <div class="max-w-xl rounded-lg p-3 text-sm" |
| :class="msg.role === 'assistant' ? |
| 'bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-gray-100' : |
| 'bg-blue-600 text-white'"> |
| <p x-html="msg.content"></p> |
| </div> |
| </div> |
| </template> |
|
|
| |
| <div x-show="loading" class="flex justify-start"> |
| <div class="bg-gray-200 dark:bg-gray-700 rounded-lg p-3 text-sm text-gray-600 dark:text-gray-300"> |
| <span class="animate-pulse">思考中…</span> |
| </div> |
| </div> |
| </main> |
|
|
| |
| <footer class="p-4 bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700"> |
| <form @submit.prevent="sendMessage()" class="flex gap-2"> |
| <textarea x-model="userInput" |
| rows="1" |
| placeholder="在此輸入訊息…" |
| class="flex-1 rounded-md border border-gray-300 dark:border-gray-600 p-2 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-gray-100 resize-none" |
| @keydown.enter.exact.prevent="sendMessage()" |
| @input="autoResize($event)"></textarea> |
|
|
| <button type="submit" |
| class="bg-blue-600 hover:bg-blue-700 text-white rounded-md px-4 py-2 disabled:opacity-50" |
| :disabled="loading || userInput.trim() === ''"> |
| 送出 |
| </button> |
| </form> |
| </footer> |
|
|
| |
| <script src="/static/script.js"></script> |
| </body> |
| </html> |
|
|