ChatCompletion.svelte 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <script lang="ts">
  2. import { onMount } from 'svelte';
  3. export let messages = [];
  4. let textAreaElement: HTMLTextAreaElement;
  5. onMount(() => {
  6. messages.forEach((message, idx) => {
  7. textAreaElement.style.height = '';
  8. textAreaElement.style.height = textAreaElement.scrollHeight + 'px';
  9. });
  10. });
  11. </script>
  12. <div class="py-3 space-y-3">
  13. {#each messages as message, idx}
  14. <div class="flex gap-2 group">
  15. <div class="flex items-start pt-1">
  16. <button
  17. class="px-2 py-1 text-sm font-semibold uppercase min-w-[6rem] text-left dark:group-hover:bg-gray-800 rounded-lg transition"
  18. on:click={() => {
  19. message.role = message.role === 'user' ? 'assistant' : 'user';
  20. }}>{message.role}</button
  21. >
  22. </div>
  23. <div class="flex-1">
  24. <textarea
  25. id="{message.role}-{idx}-textarea"
  26. bind:this={textAreaElement}
  27. class="w-full bg-transparent outline-none rounded-lg p-2 text-sm resize-none overflow-hidden"
  28. placeholder="Enter {message.role === 'user' ? 'a user' : 'an assistant'} message here"
  29. rows="1"
  30. on:input={(e) => {
  31. textAreaElement.style.height = '';
  32. textAreaElement.style.height = textAreaElement.scrollHeight + 'px';
  33. }}
  34. on:focus={(e) => {
  35. textAreaElement.style.height = '';
  36. textAreaElement.style.height = textAreaElement.scrollHeight + 'px';
  37. // e.target.style.height = Math.min(e.target.scrollHeight, 200) + 'px';
  38. }}
  39. bind:value={message.content}
  40. />
  41. </div>
  42. <div class=" pt-1">
  43. <button
  44. class=" group-hover:text-gray-500 dark:text-gray-900 dark:hover:text-gray-300 transition"
  45. on:click={() => {
  46. messages = messages.filter((message, messageIdx) => messageIdx !== idx);
  47. }}
  48. >
  49. <svg
  50. xmlns="http://www.w3.org/2000/svg"
  51. fill="none"
  52. viewBox="0 0 24 24"
  53. stroke-width="2"
  54. stroke="currentColor"
  55. class="w-5 h-5"
  56. >
  57. <path
  58. stroke-linecap="round"
  59. stroke-linejoin="round"
  60. d="M15 12H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
  61. />
  62. </svg>
  63. </button>
  64. </div>
  65. </div>
  66. <hr class=" dark:border-gray-800" />
  67. {/each}
  68. <button
  69. class="flex items-center gap-2 px-2 py-1"
  70. on:click={() => {
  71. console.log(messages.at(-1));
  72. messages.push({
  73. role: (messages.at(-1)?.role ?? 'assistant') === 'user' ? 'assistant' : 'user',
  74. content: ''
  75. });
  76. messages = messages;
  77. }}
  78. >
  79. <div>
  80. <svg
  81. xmlns="http://www.w3.org/2000/svg"
  82. fill="none"
  83. viewBox="0 0 24 24"
  84. stroke-width="1.5"
  85. stroke="currentColor"
  86. class="w-5 h-5"
  87. >
  88. <path
  89. stroke-linecap="round"
  90. stroke-linejoin="round"
  91. d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
  92. />
  93. </svg>
  94. </div>
  95. <div class=" text-sm font-medium">Add message</div>
  96. </button>
  97. </div>