Browse Source

首页样式初步实现

master
mk 6 months ago
parent
commit
7745a2980c
  1. 30
      src/app.html
  2. 136
      src/lib/components/chat/Header.svelte
  3. 4
      src/lib/components/chat/MessageInput.svelte
  4. 8
      src/lib/components/chat/Overview/Flow.svelte
  5. 44
      src/lib/components/chat/Placeholder.svelte
  6. 7
      src/lib/components/chat/Settings/General.svelte
  7. 6
      src/routes/(app)/+layout.svelte
  8. 2
      src/routes/(app)/admin/+layout.svelte
  9. 8
      src/routes/+layout.svelte
  10. BIN
      static/favicon.png
  11. BIN
      static/favicon/apple-touch-icon.png
  12. BIN
      static/favicon/favicon.ico
  13. BIN
      static/favicon/favicon.png
  14. 3
      static/favicon/favicon.svg
  15. BIN
      static/img/bg-chat.png
  16. BIN
      static/img/icon/document.png
  17. BIN
      static/img/icon/document_active.png
  18. BIN
      static/img/icon/knowledge.png
  19. BIN
      static/img/icon/knowledge_active.png
  20. BIN
      static/img/icon/record.png
  21. BIN
      static/img/icon/record_active.png
  22. BIN
      static/img/icon/upload.png
  23. BIN
      static/img/icon/upload_active.png
  24. BIN
      static/img/icon/work.png
  25. BIN
      static/img/icon/work_active.png
  26. BIN
      static/img/knowledge.png
  27. BIN
      static/img/record.png
  28. BIN
      static/img/user.png
  29. BIN
      static/img/work.png
  30. BIN
      static/static/favicon.jpg
  31. BIN
      static/static/favicon.png
  32. 16
      tailwind.config.js
  33. 3
      vite.config.ts

30
src/app.html

@ -40,8 +40,8 @@
}
if (localStorage.theme === 'system') {
document.documentElement.classList.add(prefersDarkTheme ? 'dark' : 'light');
metaThemeColorTag.setAttribute('content', prefersDarkTheme ? '#171717' : '#ffffff');
document.documentElement.classList.add('light');
metaThemeColorTag.setAttribute('content', '#171717');
} else if (localStorage.theme === 'oled-dark') {
document.documentElement.style.setProperty('--color-gray-800', '#101010');
document.documentElement.style.setProperty('--color-gray-850', '#050505');
@ -61,19 +61,19 @@
metaThemeColorTag.setAttribute('content', '#171717');
}
window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
if (localStorage.theme === 'system') {
if (e.matches) {
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('light');
metaThemeColorTag.setAttribute('content', '#171717');
} else {
document.documentElement.classList.add('light');
document.documentElement.classList.remove('dark');
metaThemeColorTag.setAttribute('content', '#ffffff');
}
}
});
// window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
// if (localStorage.theme === 'system') {
// if (e.matches) {
// document.documentElement.classList.add('dark');
// document.documentElement.classList.remove('light');
// metaThemeColorTag.setAttribute('content', '#171717');
// } else {
// document.documentElement.classList.add('light');
// document.documentElement.classList.remove('dark');
// metaThemeColorTag.setAttribute('content', '#ffffff');
// }
// }
// });
})();
</script>

136
src/lib/components/chat/Header.svelte

@ -0,0 +1,136 @@
<script lang="ts">
let list = [
{
title: '工作',
bg: '/img/work.png',
id: '3',
buttons: [
{
label: '工作总结',
img: '/img/icon/work.png',
imgActive: '/img/icon/work_active.png'
},
{
label: '工作总结',
img: '/img/icon/document.png',
imgActive: '/img/icon/document_active.png'
}
],
introduce: [
{
label: '介绍'
},
{
label: '介绍'
},
{
label: '介绍'
}
],
active:true
},
{
title: '知识库',
bg: '/img/knowledge.png',
id: '2',
buttons: [
{
label: '检索知识库',
img: '/img/icon/knowledge.png',
imgActive: '/img/icon/knowledge_active.png'
},
{
label: '上传文档',
img: '/img/icon/upload.png',
imgActive: '/img/icon/upload_active.png'
}
],
introduce: [
{
label: '介绍'
},
{
label: '介绍'
},
{
label: '介绍'
}
]
},
{
title: '使用记录',
bg: '/img/record.png',
id: '1',
buttons: [
{
label: '历史消息',
img: '/img/icon/record.png',
imgActive: '/img/icon/record_active.png'
}
],
introduce: [
{
label: '介绍'
},
{
label: '介绍'
},
{
label: '介绍'
}
]
}
];
</script>
<div class="flex flex-col border-box header_box">
<div class="top flex">
<img src={'favicon.png'} alt="" class="w-16 h-16 mr-5" />
<div class="tip flex flex-col">
<h1 class="text-gray-800">Hi,我是您的AI小助手<span class="text-blue-700">e小星</span></h1>
<p class="text-gray-800 text-left text-base">需要我帮您做点什么?</p>
</div>
</div>
<div class="flex justify-around w-full mt-10">
{#each list as item, itemIndex (item.id)}
<div
class="flex flex-col flex-1 mr-3 rounded-2xl p-6 box-border bg-cover"
style="background-image: url('{item.bg}')"
>
<h2 class="text-gray-800 text-left text-2xl">{item.title}</h2>
<div>
{#each item.introduce as itemP, index (index)}
<p class="text-gray-500 text-left text-sm mt-1.5">{itemP.label}</p>
{/each}
</div>
<div class="flex mt-5.5">
{#each item.buttons as but, index (index)}
<button
class="font-medium text-black text-base mr-4 bg-white rounded-2xl px-6 py-1 box-border flex items-center border"
on:click={() => {
console.log(but, index);
}}
>
<img src={but.img} alt="" class="w-5 h-5" />
{but.label}
</button>
{/each}
</div>
</div>
{/each}
</div>
</div>
<style lang="scss" scoped>
.header_box {
background-image: url('img/bg-chat.png');
height: 400px;
background-size: 100% 100%;
padding: 50px 70px 39px;
box-sizing: border-box;
width: calc(100vw - 20px);
margin: 0 auto;
border-radius: 5px;
}
</style>

4
src/lib/components/chat/MessageInput.svelte

@ -1175,7 +1175,7 @@
{#if $config?.features?.enable_code_interpreter && ($_user.role === 'admin' || $_user?.permissions?.features?.code_interpreter)}
<Tooltip content={$i18n.t('Execute code for analysis')} placement="top">
<button
<!-- <button
on:click|preventDefault={() =>
(codeInterpreterEnabled = !codeInterpreterEnabled)}
type="button"
@ -1188,7 +1188,7 @@
class="hidden @sm:block whitespace-nowrap overflow-hidden text-ellipsis translate-y-[0.5px] mr-0.5"
>{$i18n.t('Code Interpreter')}</span
>
</button>
</button> -->
</Tooltip>
{/if}
{/if}

8
src/lib/components/chat/Overview/Flow.svelte

@ -17,13 +17,7 @@
{edges}
fitView
minZoom={0.001}
colorMode={$theme.includes('dark')
? 'dark'
: $theme === 'system'
? window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light'
: 'light'}
colorMode={'light'}
nodesConnectable={false}
nodesDraggable={false}
on:nodeclick={(e) => dispatch('nodeclick', e.detail)}

44
src/lib/components/chat/Placeholder.svelte

@ -15,6 +15,7 @@
import Tooltip from '$lib/components/common/Tooltip.svelte';
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
import MessageInput from './MessageInput.svelte';
import Header from './Header.svelte';
const i18n = getContext('i18n');
@ -106,43 +107,7 @@
>
<div class="w-full flex flex-col justify-center items-center">
<div class="flex flex-row justify-center gap-3 @sm:gap-3.5 w-fit px-5 ">
<div class="flex shrink-0 justify-center">
<div class="flex -space-x-4 mb-0.5" in:fade={{ duration: 100 }}>
{#each models as model, modelIdx}
<Tooltip
content={(models[modelIdx]?.info?.meta?.tags ?? [])
.map((tag) => tag.name.toUpperCase())
.join(', ')}
placement="top"
>
<button
on:click={() => {
selectedModelIdx = modelIdx;
}}
>
<img
crossorigin="anonymous"
src={model?.info?.meta?.profile_image_url ??
($i18n.language === 'dg-DG'
? `/doge.png`
: `${WEBUI_BASE_URL}/static/favicon.png`)}
class=" size-9 @sm:size-10 rounded-full border-[1px] border-gray-200 dark:border-none"
alt="logo"
draggable="false"
/>
</button>
</Tooltip>
{/each}
</div>
</div>
<div class=" text-3xl @sm:text-4xl line-clamp-1" in:fade={{ duration: 100 }}>
{#if models[selectedModelIdx]?.name}
{models[selectedModelIdx]?.name}
{:else}
{$i18n.t('Hello, {{name}}', { name: $user.name })}
{/if}
</div>
<Header></Header>
</div>
<div class="flex mt-1 mb-2">
@ -210,7 +175,8 @@
</div>
</div>
</div>
<div class="mx-auto max-w-2xl font-primary" in:fade={{ duration: 200, delay: 200 }}>
<!--建议 -->
<!-- <div class="mx-auto max-w-2xl font-primary" in:fade={{ duration: 200, delay: 200 }}>
<div class="mx-5">
<Suggestions
suggestionPrompts={models[selectedModelIdx]?.info?.meta?.suggestion_prompts ??
@ -222,5 +188,5 @@
}}
/>
</div>
</div>
</div> -->
</div>

7
src/lib/components/chat/Settings/General.svelte

@ -123,11 +123,8 @@
const metaThemeColor = document.querySelector('meta[name="theme-color"]');
if (metaThemeColor) {
if (_theme.includes('system')) {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
console.log('Setting system meta theme color: ' + systemTheme);
metaThemeColor.setAttribute('content', systemTheme === 'light' ? '#ffffff' : '#171717');
const systemTheme = window.matchMedia('light');
metaThemeColor.setAttribute('content','#171717');
} else {
console.log('Setting meta theme color: ' + _theme);
metaThemeColor.setAttribute(

6
src/routes/(app)/+layout.svelte

@ -224,7 +224,7 @@
<SettingsModal bind:show={$showSettings} />
<ChangelogModal bind:show={$showChangelog} />
{#if version && compareVersion(version.latest, version.current) && ($settings?.showUpdateToast ?? true)}
<!-- {#if version && compareVersion(version.latest, version.current) && ($settings?.showUpdateToast ?? true)}
<div class=" absolute bottom-8 right-8 z-50" in:fade={{ duration: 100 }}>
<UpdateInfoToast
{version}
@ -234,11 +234,11 @@
}}
/>
</div>
{/if}
{/if} -->
<div class="app relative">
<div
class=" text-gray-700 dark:text-gray-100 bg-white dark:bg-gray-900 h-screen max-h-[100dvh] overflow-auto flex flex-row justify-end"
class=" text-gray-700 bg-white h-screen max-h-[100dvh] overflow-auto flex flex-row justify-end"
>
{#if loaded}
{#if !['user', 'admin'].includes($user.role)}

2
src/routes/(app)/admin/+layout.svelte

@ -50,7 +50,7 @@
class="flex gap-1 scrollbar-none overflow-x-auto w-fit text-center text-sm font-medium rounded-full bg-transparent pt-1"
>
<a
class="min-w-fit rounded-full p-1.5 {['/admin/users'].includes($page.url.pathname)
class="min-w-fit flex rounded-full p-1.5 {['/admin/users'].includes($page.url.pathname)
? ''
: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
href="/admin">{$i18n.t('Users')}</a

8
src/routes/+layout.svelte

@ -585,13 +585,7 @@
{/if}
<Toaster
theme={$theme.includes('dark')
? 'dark'
: $theme === 'system'
? window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light'
: 'light'}
theme={'light'}
richColors
position="top-right"
/>

BIN
static/favicon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/favicon/apple-touch-icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/favicon/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

BIN
static/favicon/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

3
static/favicon/favicon.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 15 KiB

BIN
static/img/bg-chat.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

BIN
static/img/icon/document.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/img/icon/document_active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/img/icon/knowledge.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/img/icon/knowledge_active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/img/icon/record.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/img/icon/record_active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/img/icon/upload.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/img/icon/upload_active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/img/icon/work.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

BIN
static/img/icon/work_active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

BIN
static/img/knowledge.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

BIN
static/img/record.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

BIN
static/img/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
static/img/work.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

BIN
static/static/favicon.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/static/favicon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

16
tailwind.config.js

@ -3,25 +3,11 @@ import containerQuries from '@tailwindcss/container-queries';
/** @type {import('tailwindcss').Config} */
export default {
darkMode: 'class',
darkMode: '',
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
colors: {
gray: {
50: 'var(--color-gray-50, #f9f9f9)',
100: 'var(--color-gray-100, #ececec)',
200: 'var(--color-gray-200, #e3e3e3)',
300: 'var(--color-gray-300, #cdcdcd)',
400: 'var(--color-gray-400, #b4b4b4)',
500: 'var(--color-gray-500, #9b9b9b)',
600: 'var(--color-gray-600, #676767)',
700: 'var(--color-gray-700, #4e4e4e)',
800: 'var(--color-gray-800, #333)',
850: 'var(--color-gray-850, #262626)',
900: 'var(--color-gray-900, #fefeff)',
950: 'var(--color-gray-950, #0d0d0d)'
},
blue: {
50: 'var(--color-blue-50, #2a75f0)',
}

3
vite.config.ts

@ -48,5 +48,6 @@ export default defineConfig({
},
worker: {
format: 'es'
}
},
base: '/openwebui/'
});

Loading…
Cancel
Save