ChatPlaceholder.svelte 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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 onSelect = (e) => {};
  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(
  39. models[selectedModelIdx]?.info?.meta?.description ?? ''
  40. ).replaceAll('\n', '<br>')
  41. )}
  42. placement="right"
  43. >
  44. <img
  45. crossorigin="anonymous"
  46. src={model?.info?.meta?.profile_image_url ??
  47. ($i18n.language === 'dg-DG'
  48. ? `${WEBUI_BASE_URL}/doge.png`
  49. : `${WEBUI_BASE_URL}/static/favicon.png`)}
  50. class=" size-[2.7rem] rounded-full border-[1px] border-gray-100 dark:border-none"
  51. alt="logo"
  52. draggable="false"
  53. />
  54. </Tooltip>
  55. </button>
  56. {/each}
  57. </div>
  58. </div>
  59. {#if $temporaryChatEnabled}
  60. <Tooltip
  61. content={$i18n.t("This chat won't appear in history and your messages will not be saved.")}
  62. className="w-full flex justify-start mb-0.5"
  63. placement="top"
  64. >
  65. <div class="flex items-center gap-2 text-gray-500 text-lg mt-2 w-fit">
  66. <EyeSlash strokeWidth="2.5" className="size-5" />{$i18n.t('Temporary Chat')}
  67. </div>
  68. </Tooltip>
  69. {/if}
  70. <div
  71. class=" mt-2 mb-4 text-3xl text-gray-800 dark:text-gray-100 text-left flex items-center gap-4 font-primary"
  72. >
  73. <div>
  74. <div class=" capitalize line-clamp-1" in:fade={{ duration: 200 }}>
  75. {#if models[selectedModelIdx]?.name}
  76. {models[selectedModelIdx]?.name}
  77. {:else}
  78. {$i18n.t('Hello, {{name}}', { name: $user?.name })}
  79. {/if}
  80. </div>
  81. <div in:fade={{ duration: 200, delay: 200 }}>
  82. {#if models[selectedModelIdx]?.info?.meta?.description ?? null}
  83. <div
  84. class="mt-0.5 text-base font-normal text-gray-500 dark:text-gray-400 line-clamp-3 markdown"
  85. >
  86. {@html marked.parse(
  87. sanitizeResponseContent(
  88. models[selectedModelIdx]?.info?.meta?.description
  89. ).replaceAll('\n', '<br>')
  90. )}
  91. </div>
  92. {#if models[selectedModelIdx]?.info?.meta?.user}
  93. <div class="mt-0.5 text-sm font-normal text-gray-400 dark:text-gray-500">
  94. By
  95. {#if models[selectedModelIdx]?.info?.meta?.user.community}
  96. <a
  97. href="https://openwebui.com/m/{models[selectedModelIdx]?.info?.meta?.user
  98. .username}"
  99. >{models[selectedModelIdx]?.info?.meta?.user.name
  100. ? models[selectedModelIdx]?.info?.meta?.user.name
  101. : `@${models[selectedModelIdx]?.info?.meta?.user.username}`}</a
  102. >
  103. {:else}
  104. {models[selectedModelIdx]?.info?.meta?.user.name}
  105. {/if}
  106. </div>
  107. {/if}
  108. {:else}
  109. <div class=" text-gray-400 dark:text-gray-500 line-clamp-1 font-p">
  110. {$i18n.t('How can I help you today?')}
  111. </div>
  112. {/if}
  113. </div>
  114. </div>
  115. </div>
  116. <div class=" w-full font-primary" in:fade={{ duration: 200, delay: 300 }}>
  117. <Suggestions
  118. className="grid grid-cols-2"
  119. suggestionPrompts={atSelectedModel?.info?.meta?.suggestion_prompts ??
  120. models[selectedModelIdx]?.info?.meta?.suggestion_prompts ??
  121. $config?.default_prompt_suggestions ??
  122. []}
  123. {onSelect}
  124. />
  125. </div>
  126. </div>
  127. {/key}