ChatPlaceholder.svelte 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <script lang="ts">
  2. import { WEBUI_BASE_URL } from '$lib/constants';
  3. import { marked } from 'marked';
  4. import { config, user, models as _models, temporaryChatEnabled } from '$lib/stores';
  5. import { onMount, getContext } from 'svelte';
  6. import { blur, fade } from 'svelte/transition';
  7. import Suggestions from './Suggestions.svelte';
  8. import { sanitizeResponseContent } from '$lib/utils';
  9. import Tooltip from '$lib/components/common/Tooltip.svelte';
  10. import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
  11. const i18n = getContext('i18n');
  12. export let modelIds = [];
  13. export let models = [];
  14. export let atSelectedModel;
  15. export let submitPrompt;
  16. let mounted = false;
  17. let selectedModelIdx = 0;
  18. $: if (modelIds.length > 0) {
  19. selectedModelIdx = models.length - 1;
  20. }
  21. $: models = modelIds.map((id) => $_models.find((m) => m.id === id));
  22. onMount(() => {
  23. mounted = true;
  24. });
  25. </script>
  26. {#key mounted}
  27. <div class="m-auto w-full max-w-6xl px-8 lg:px-20">
  28. <div class="flex justify-start">
  29. <div class="flex -space-x-4 mb-0.5" in:fade={{ duration: 200 }}>
  30. {#each models as model, modelIdx}
  31. <button
  32. on:click={() => {
  33. selectedModelIdx = modelIdx;
  34. }}
  35. >
  36. <Tooltip
  37. content={marked.parse(
  38. sanitizeResponseContent(models[selectedModelIdx]?.info?.meta?.description ?? '')
  39. )}
  40. placement="right"
  41. >
  42. <img
  43. crossorigin="anonymous"
  44. src={model?.info?.meta?.profile_image_url ??
  45. ($i18n.language === 'dg-DG'
  46. ? `/doge.png`
  47. : `${WEBUI_BASE_URL}/static/favicon.png`)}
  48. class=" size-[2.7rem] rounded-full border-[1px] border-gray-200 dark:border-none"
  49. alt="logo"
  50. draggable="false"
  51. />
  52. </Tooltip>
  53. </button>
  54. {/each}
  55. </div>
  56. </div>
  57. {#if $temporaryChatEnabled}
  58. <Tooltip
  59. content="This chat won't appear in history and your messages will not be saved."
  60. className="w-fit"
  61. placement="top-start"
  62. >
  63. <div class="flex items-center gap-2 text-gray-500 font-medium text-lg my-2 w-fit">
  64. <EyeSlash strokeWidth="2.5" className="size-5" /> Temporary Chat
  65. </div>
  66. </Tooltip>
  67. {/if}
  68. <div
  69. class=" mt-2 mb-4 text-3xl text-gray-800 dark:text-gray-100 font-medium text-left flex items-center gap-4 font-primary"
  70. >
  71. <div>
  72. <div class=" capitalize line-clamp-1" in:fade={{ duration: 200 }}>
  73. {#if models[selectedModelIdx]?.name}
  74. {models[selectedModelIdx]?.name}
  75. {:else}
  76. {$i18n.t('Hello, {{name}}', { name: $user.name })}
  77. {/if}
  78. </div>
  79. <div in:fade={{ duration: 200, delay: 200 }}>
  80. {#if models[selectedModelIdx]?.info?.meta?.description ?? null}
  81. <div
  82. class="mt-0.5 text-base font-normal text-gray-500 dark:text-gray-400 line-clamp-3 markdown"
  83. >
  84. {@html marked.parse(
  85. sanitizeResponseContent(models[selectedModelIdx]?.info?.meta?.description)
  86. )}
  87. </div>
  88. {#if models[selectedModelIdx]?.info?.meta?.user}
  89. <div class="mt-0.5 text-sm font-normal text-gray-400 dark:text-gray-500">
  90. By
  91. {#if models[selectedModelIdx]?.info?.meta?.user.community}
  92. <a
  93. href="https://openwebui.com/m/{models[selectedModelIdx]?.info?.meta?.user
  94. .username}"
  95. >{models[selectedModelIdx]?.info?.meta?.user.name
  96. ? models[selectedModelIdx]?.info?.meta?.user.name
  97. : `@${models[selectedModelIdx]?.info?.meta?.user.username}`}</a
  98. >
  99. {:else}
  100. {models[selectedModelIdx]?.info?.meta?.user.name}
  101. {/if}
  102. </div>
  103. {/if}
  104. {:else}
  105. <div class=" font-medium text-gray-400 dark:text-gray-500 line-clamp-1 font-p">
  106. {$i18n.t('How can I help you today?')}
  107. </div>
  108. {/if}
  109. </div>
  110. </div>
  111. </div>
  112. <div class=" w-full font-primary" in:fade={{ duration: 200, delay: 300 }}>
  113. <Suggestions
  114. className="grid grid-cols-2"
  115. suggestionPrompts={atSelectedModel?.info?.meta?.suggestion_prompts ??
  116. models[selectedModelIdx]?.info?.meta?.suggestion_prompts ??
  117. $config?.default_prompt_suggestions ??
  118. []}
  119. on:select={(e) => {
  120. submitPrompt(e.detail);
  121. }}
  122. />
  123. </div>
  124. </div>
  125. {/key}