Controls.svelte 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <script lang="ts">
  2. import { getContext } from 'svelte';
  3. const i18n = getContext('i18n');
  4. import XMark from '$lib/components/icons/XMark.svelte';
  5. import { models } from '$lib/stores';
  6. import Collapsible from '$lib/components/common/Collapsible.svelte';
  7. import FileItem from '$lib/components/common/FileItem.svelte';
  8. import Image from '$lib/components/common/Image.svelte';
  9. export let show = false;
  10. export let selectedModelId = '';
  11. export let files = [];
  12. export let onUpdate = (files: any[]) => {
  13. // Default no-op function
  14. };
  15. </script>
  16. <div class="flex items-center mb-1.5 pt-1.5 px-2.5">
  17. <div class=" mr-1 flex items-center">
  18. <button
  19. class="p-0.5 bg-transparent transition rounded-lg"
  20. on:click={() => {
  21. show = !show;
  22. }}
  23. >
  24. <XMark className="size-5" strokeWidth="2.5" />
  25. </button>
  26. </div>
  27. <div class=" font-medium text-base flex items-center gap-1">
  28. <div>
  29. {$i18n.t('Controls')}
  30. </div>
  31. </div>
  32. </div>
  33. <div class="mt-1 px-2.5">
  34. <div class="pb-10">
  35. {#if files.length > 0}
  36. <div class=" text-xs font-medium pb-1">{$i18n.t('Files')}</div>
  37. <div class="flex flex-col gap-1">
  38. {#each files.filter((file) => file.type !== 'image') as file, fileIdx}
  39. <FileItem
  40. className="w-full"
  41. item={file}
  42. small={true}
  43. edit={true}
  44. dismissible={true}
  45. url={file.url}
  46. name={file.name}
  47. type={file.type}
  48. size={file?.size}
  49. loading={file.status === 'uploading'}
  50. on:dismiss={() => {
  51. // Remove the file from the files array
  52. files = files.filter((item) => item.id !== file.id);
  53. files = files;
  54. onUpdate(files);
  55. }}
  56. on:click={() => {
  57. console.log(file);
  58. }}
  59. />
  60. {/each}
  61. <div class="flex items-center flex-wrap gap-2 mt-1.5">
  62. {#each files.filter((file) => file.type === 'image') as file, fileIdx}
  63. <Image
  64. src={file.url}
  65. imageClassName=" size-14 rounded-xl object-cover"
  66. dismissible={true}
  67. onDismiss={() => {
  68. files = files.filter((item) => item.id !== file.id);
  69. files = files;
  70. onUpdate(files);
  71. }}
  72. />
  73. {/each}
  74. </div>
  75. </div>
  76. <hr class="my-2 border-gray-50 dark:border-gray-700/10" />
  77. {/if}
  78. <div class=" text-xs font-medium mb-1">{$i18n.t('Model')}</div>
  79. <div class="w-full">
  80. <select class="w-full bg-transparent text-sm outline-hidden" bind:value={selectedModelId}>
  81. <option value="" class="bg-gray-50 dark:bg-gray-700" disabled>
  82. {$i18n.t('Select a model')}
  83. </option>
  84. {#each $models.filter((model) => !(model?.info?.meta?.hidden ?? false)) as model}
  85. <option value={model.id} class="bg-gray-50 dark:bg-gray-700">{model.name}</option>
  86. {/each}
  87. </select>
  88. </div>
  89. </div>
  90. </div>