Added ChatUI branding & put theming behind an env variable (#298)
Browse files* Moved all huggingchat branding behind an env variable
* Refactored branding to use multiple env variables
* pr review
* prettier
* move the ethics modal behind the flag PUBLIC_APP_DISCLAIMER
* inline chat ui logo so it would take the color
* flex-none
- .env +13 -0
- src/app.html +0 -22
- src/hooks.server.ts +8 -2
- src/lib/components/AnnouncementBanner.svelte +1 -1
- src/lib/components/LoginModal.svelte +18 -11
- src/lib/components/ModelsModal.svelte +2 -2
- src/lib/components/NavMenu.svelte +19 -17
- src/lib/components/SettingsModal.svelte +29 -25
- src/lib/components/chat/ChatIntroduction.svelte +3 -3
- src/lib/components/chat/ChatWindow.svelte +1 -1
- src/lib/components/icons/Logo.svelte +23 -20
- src/routes/+layout.svelte +42 -5
- src/routes/r/[id]/+page.svelte +4 -1
- static/chatui/favicon.png +0 -0
- static/chatui/favicon.svg +6 -0
- static/chatui/touch-icon-ipad-retina.png +0 -0
- static/chatui/touch-icon-ipad.png +0 -0
- static/chatui/touch-icon-iphone-retina.png +0 -0
- static/{favicon.png → huggingchat/favicon.png} +0 -0
- static/{favicon.svg → huggingchat/favicon.svg} +1 -1
- static/{thumbnail.png → huggingchat/thumbnail.png} +0 -0
- static/{touch-icon-ipad-retina.png → huggingchat/touch-icon-ipad-retina.png} +0 -0
- static/{touch-icon-ipad.png → huggingchat/touch-icon-ipad.png} +0 -0
- static/{touch-icon-iphone-retina.png → huggingchat/touch-icon-iphone-retina.png} +0 -0
- svelte.config.js +1 -2
- tailwind.config.cjs +7 -0
.env
CHANGED
@@ -68,3 +68,16 @@ PUBLIC_ANNOUNCEMENT_BANNERS=`[
|
|
68 |
PARQUET_EXPORT_DATASET=
|
69 |
PARQUET_EXPORT_HF_TOKEN=
|
70 |
PARQUET_EXPORT_SECRET=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
PARQUET_EXPORT_DATASET=
|
69 |
PARQUET_EXPORT_HF_TOKEN=
|
70 |
PARQUET_EXPORT_SECRET=
|
71 |
+
|
72 |
+
|
73 |
+
PUBLIC_APP_NAME=ChatUI # name used as title throughout the app
|
74 |
+
PUBLIC_APP_ASSETS=chatui # used to find logos & favicons in static/$PUBLIC_APP_ASSETS
|
75 |
+
PUBLIC_APP_COLOR=blue # can be any of tailwind colors: https://tailwindcss.com/docs/customizing-colors#default-color-palette
|
76 |
+
PUBLIC_APP_DATA_SHARING=#set to 1 to enable options & text regarding data sharing
|
77 |
+
PUBLIC_APP_DISCLAIMER=#set to 1 to show a disclaimer on login page
|
78 |
+
|
79 |
+
# PUBLIC_APP_NAME=HuggingChat
|
80 |
+
# PUBLIC_APP_ASSETS=huggingchat
|
81 |
+
# PUBLIC_APP_COLOR=yellow
|
82 |
+
# PUBLIC_APP_DATA_SHARING=1
|
83 |
+
# PUBLIC_APP_DISCLAIMER=1
|
src/app.html
CHANGED
@@ -2,29 +2,7 @@
|
|
2 |
<html lang="en" class="h-full">
|
3 |
<head>
|
4 |
<meta charset="utf-8" />
|
5 |
-
<link rel="icon" href="%sveltekit.assets%/favicon.svg" type="image/svg+xml" />
|
6 |
-
<link rel="icon" href="%sveltekit.assets%/favicon.png" type="image/png" />
|
7 |
-
<!-- Icon Support for iOS Bookmark Home Screen -->
|
8 |
-
<link
|
9 |
-
rel="apple-touch-icon"
|
10 |
-
href="%sveltekit.assets%/touch-icon-ipad-retina.png"
|
11 |
-
sizes="167x167"
|
12 |
-
type="image/png"
|
13 |
-
/>
|
14 |
-
<link
|
15 |
-
rel="apple-touch-icon"
|
16 |
-
href="%sveltekit.assets%/touch-icon-ipad.png"
|
17 |
-
sizes="152x152"
|
18 |
-
type="image/png"
|
19 |
-
/>
|
20 |
-
<link
|
21 |
-
rel="apple-touch-icon"
|
22 |
-
href="%sveltekit.assets%/touch-icon-iphone-retina.png"
|
23 |
-
sizes="180x180"
|
24 |
-
type="image/png"
|
25 |
-
/>
|
26 |
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
27 |
-
<title>HuggingChat</title>
|
28 |
<script>
|
29 |
if (
|
30 |
localStorage.theme === "dark" ||
|
|
|
2 |
<html lang="en" class="h-full">
|
3 |
<head>
|
4 |
<meta charset="utf-8" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
|
|
6 |
<script>
|
7 |
if (
|
8 |
localStorage.theme === "dark" ||
|
src/hooks.server.ts
CHANGED
@@ -4,6 +4,7 @@ import {
|
|
4 |
PUBLIC_GOOGLE_ANALYTICS_ID,
|
5 |
PUBLIC_DEPRECATED_GOOGLE_ANALYTICS_ID,
|
6 |
PUBLIC_ORIGIN,
|
|
|
7 |
} from "$env/static/public";
|
8 |
import { collections } from "$lib/server/database";
|
9 |
import { base } from "$app/paths";
|
@@ -67,9 +68,14 @@ export const handle: Handle = async ({ event, resolve }) => {
|
|
67 |
return errorResponse(401, ERROR_MESSAGES.authOnly);
|
68 |
}
|
69 |
|
70 |
-
// if login is not required and the call is not from /settings
|
|
|
71 |
// If login is required, `ethicsModalAcceptedAt` is already true at this point, so do not pass this condition. This saves a DB call.
|
72 |
-
if (
|
|
|
|
|
|
|
|
|
73 |
const hasAcceptedEthicsModal = await collections.settings.countDocuments({
|
74 |
sessionId: event.locals.sessionId,
|
75 |
ethicsModalAcceptedAt: { $exists: true },
|
|
|
4 |
PUBLIC_GOOGLE_ANALYTICS_ID,
|
5 |
PUBLIC_DEPRECATED_GOOGLE_ANALYTICS_ID,
|
6 |
PUBLIC_ORIGIN,
|
7 |
+
PUBLIC_APP_DISCLAIMER,
|
8 |
} from "$env/static/public";
|
9 |
import { collections } from "$lib/server/database";
|
10 |
import { base } from "$app/paths";
|
|
|
68 |
return errorResponse(401, ERROR_MESSAGES.authOnly);
|
69 |
}
|
70 |
|
71 |
+
// if login is not required and the call is not from /settings and we display the ethics modal with PUBLIC_APP_DISCLAIMER
|
72 |
+
// we check if the user has accepted the ethics modal first.
|
73 |
// If login is required, `ethicsModalAcceptedAt` is already true at this point, so do not pass this condition. This saves a DB call.
|
74 |
+
if (
|
75 |
+
!requiresUser &&
|
76 |
+
!event.url.pathname.startsWith(`${base}/settings`) &&
|
77 |
+
!!PUBLIC_APP_DISCLAIMER
|
78 |
+
) {
|
79 |
const hasAcceptedEthicsModal = await collections.settings.countDocuments({
|
80 |
sessionId: event.locals.sessionId,
|
81 |
ethicsModalAcceptedAt: { $exists: true },
|
src/lib/components/AnnouncementBanner.svelte
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
|
6 |
<div class="flex items-center rounded-xl bg-gray-100 p-1 text-sm dark:bg-gray-800 {classNames}">
|
7 |
<span
|
8 |
-
class="mr-2 inline-flex items-center rounded-lg bg-gradient-to-br from-
|
9 |
>New</span
|
10 |
>
|
11 |
{title}
|
|
|
5 |
|
6 |
<div class="flex items-center rounded-xl bg-gray-100 p-1 text-sm dark:bg-gray-800 {classNames}">
|
7 |
<span
|
8 |
+
class="mr-2 inline-flex items-center rounded-lg bg-gradient-to-br from-primary-300 px-2 py-1 text-xxs font-medium uppercase leading-3 text-primary-700 dark:from-primary-900 dark:text-primary-400"
|
9 |
>New</span
|
10 |
>
|
11 |
{title}
|
src/lib/components/LoginModal.svelte
CHANGED
@@ -2,12 +2,11 @@
|
|
2 |
import { browser } from "$app/environment";
|
3 |
import { base } from "$app/paths";
|
4 |
import { page } from "$app/stores";
|
5 |
-
import { PUBLIC_VERSION } from "$env/static/public";
|
6 |
-
import Logo from "$lib/components/icons/Logo.svelte";
|
7 |
import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
|
8 |
import Modal from "$lib/components/Modal.svelte";
|
9 |
import type { LayoutData } from "../../routes/$types";
|
10 |
-
|
11 |
export let settings: LayoutData["settings"];
|
12 |
|
13 |
const isIframe = browser && window.self !== window.parent;
|
@@ -15,10 +14,11 @@
|
|
15 |
|
16 |
<Modal>
|
17 |
<div
|
18 |
-
class="flex w-full flex-col items-center gap-6 bg-gradient-to-t from-
|
19 |
>
|
20 |
<h2 class="flex items-center text-2xl font-semibold text-gray-800">
|
21 |
-
<Logo classNames="
|
|
|
22 |
<div
|
23 |
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400"
|
24 |
>
|
@@ -32,20 +32,27 @@
|
|
32 |
AI is an area of active research with known problems such as biased generation and
|
33 |
misinformation. Do not use this application for high-stakes decisions or advice.
|
34 |
</p>
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
38 |
<form
|
39 |
action="{base}/{$page.data.requiresLogin ? 'login' : 'settings'}"
|
40 |
target={isIframe ? "_blank" : ""}
|
41 |
method="POST"
|
|
|
42 |
>
|
43 |
{#if $page.data.requiresLogin}
|
44 |
<button
|
45 |
type="submit"
|
46 |
-
class="mt-2 flex items-center whitespace-nowrap rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-
|
47 |
>
|
48 |
-
Sign in
|
|
|
|
|
|
|
49 |
</button>
|
50 |
<p class="mt-2 px-2 text-sm text-gray-500">to start chatting right away</p>
|
51 |
{:else}
|
@@ -55,7 +62,7 @@
|
|
55 |
{/each}
|
56 |
<button
|
57 |
type="submit"
|
58 |
-
class="mt-2 rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-
|
59 |
>
|
60 |
Start chatting
|
61 |
</button>
|
|
|
2 |
import { browser } from "$app/environment";
|
3 |
import { base } from "$app/paths";
|
4 |
import { page } from "$app/stores";
|
5 |
+
import { PUBLIC_APP_DATA_SHARING, PUBLIC_APP_NAME, PUBLIC_VERSION } from "$env/static/public";
|
|
|
6 |
import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
|
7 |
import Modal from "$lib/components/Modal.svelte";
|
8 |
import type { LayoutData } from "../../routes/$types";
|
9 |
+
import Logo from "./icons/Logo.svelte";
|
10 |
export let settings: LayoutData["settings"];
|
11 |
|
12 |
const isIframe = browser && window.self !== window.parent;
|
|
|
14 |
|
15 |
<Modal>
|
16 |
<div
|
17 |
+
class="flex w-full flex-col items-center gap-6 bg-gradient-to-t from-primary-500/40 via-primary-500/10 to-primary-500/0 px-4 pb-10 pt-9 text-center "
|
18 |
>
|
19 |
<h2 class="flex items-center text-2xl font-semibold text-gray-800">
|
20 |
+
<Logo classNames="mr-1" />
|
21 |
+
{PUBLIC_APP_NAME}
|
22 |
<div
|
23 |
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400"
|
24 |
>
|
|
|
32 |
AI is an area of active research with known problems such as biased generation and
|
33 |
misinformation. Do not use this application for high-stakes decisions or advice.
|
34 |
</p>
|
35 |
+
{#if PUBLIC_APP_DATA_SHARING}
|
36 |
+
<p class="px-2 text-sm text-gray-500">
|
37 |
+
Your conversations will be shared with model authors unless you disable it from your
|
38 |
+
settings.
|
39 |
+
</p>
|
40 |
+
{/if}
|
41 |
<form
|
42 |
action="{base}/{$page.data.requiresLogin ? 'login' : 'settings'}"
|
43 |
target={isIframe ? "_blank" : ""}
|
44 |
method="POST"
|
45 |
+
class="flex w-full flex-col items-center gap-2"
|
46 |
>
|
47 |
{#if $page.data.requiresLogin}
|
48 |
<button
|
49 |
type="submit"
|
50 |
+
class="mt-2 flex items-center whitespace-nowrap rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-primary-500"
|
51 |
>
|
52 |
+
Sign in
|
53 |
+
{#if PUBLIC_APP_NAME === "HuggingChat"}
|
54 |
+
with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5" /> Hugging Face
|
55 |
+
{/if}
|
56 |
</button>
|
57 |
<p class="mt-2 px-2 text-sm text-gray-500">to start chatting right away</p>
|
58 |
{:else}
|
|
|
62 |
{/each}
|
63 |
<button
|
64 |
type="submit"
|
65 |
+
class="mt-2 rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-primary-500"
|
66 |
>
|
67 |
Start chatting
|
68 |
</button>
|
src/lib/components/ModelsModal.svelte
CHANGED
@@ -41,7 +41,7 @@
|
|
41 |
{#each models as model}
|
42 |
<div
|
43 |
class="rounded-xl border border-gray-100 {model.id === selectedModelId
|
44 |
-
? 'bg-gradient-to-r from-
|
45 |
: ''}"
|
46 |
>
|
47 |
<label class="group flex cursor-pointer p-3" on:change aria-label={model.displayName}>
|
@@ -62,7 +62,7 @@
|
|
62 |
</span>
|
63 |
<CarbonCheckmark
|
64 |
class="-mr-1 -mt-1 ml-auto shrink-0 text-xl {model.id === selectedModelId
|
65 |
-
? 'text-
|
66 |
: 'text-transparent group-hover:text-gray-200'}"
|
67 |
/>
|
68 |
</label>
|
|
|
41 |
{#each models as model}
|
42 |
<div
|
43 |
class="rounded-xl border border-gray-100 {model.id === selectedModelId
|
44 |
+
? 'bg-gradient-to-r from-primary-200/40 via-primary-500/10'
|
45 |
: ''}"
|
46 |
>
|
47 |
<label class="group flex cursor-pointer p-3" on:change aria-label={model.displayName}>
|
|
|
62 |
</span>
|
63 |
<CarbonCheckmark
|
64 |
class="-mr-1 -mt-1 ml-auto shrink-0 text-xl {model.id === selectedModelId
|
65 |
+
? 'text-primary-400'
|
66 |
: 'text-transparent group-hover:text-gray-200'}"
|
67 |
/>
|
68 |
</label>
|
src/lib/components/NavMenu.svelte
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
import Logo from "$lib/components/icons/Logo.svelte";
|
6 |
import { switchTheme } from "$lib/switchTheme";
|
7 |
-
import { PUBLIC_ORIGIN } from "$env/static/public";
|
8 |
import NavConversationItem from "./NavConversationItem.svelte";
|
9 |
import type { LayoutData } from "../../routes/$types";
|
10 |
|
@@ -23,8 +23,8 @@
|
|
23 |
|
24 |
<div class="sticky top-0 flex flex-none items-center justify-between px-3 py-3.5 max-sm:pt-0">
|
25 |
<a class="flex items-center rounded-xl text-lg font-semibold" href="{PUBLIC_ORIGIN}{base}/">
|
26 |
-
<Logo classNames="mr-1
|
27 |
-
|
28 |
</a>
|
29 |
<a
|
30 |
href={`${base}/`}
|
@@ -75,18 +75,20 @@
|
|
75 |
>
|
76 |
Settings
|
77 |
</button>
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
92 |
</div>
|
|
|
4 |
|
5 |
import Logo from "$lib/components/icons/Logo.svelte";
|
6 |
import { switchTheme } from "$lib/switchTheme";
|
7 |
+
import { PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
|
8 |
import NavConversationItem from "./NavConversationItem.svelte";
|
9 |
import type { LayoutData } from "../../routes/$types";
|
10 |
|
|
|
23 |
|
24 |
<div class="sticky top-0 flex flex-none items-center justify-between px-3 py-3.5 max-sm:pt-0">
|
25 |
<a class="flex items-center rounded-xl text-lg font-semibold" href="{PUBLIC_ORIGIN}{base}/">
|
26 |
+
<Logo classNames="mr-1" />
|
27 |
+
{PUBLIC_APP_NAME}
|
28 |
</a>
|
29 |
<a
|
30 |
href={`${base}/`}
|
|
|
75 |
>
|
76 |
Settings
|
77 |
</button>
|
78 |
+
{#if PUBLIC_APP_NAME === "HuggingChat"}
|
79 |
+
<a
|
80 |
+
href="https://huggingface.co/spaces/huggingchat/chat-ui/discussions"
|
81 |
+
target="_blank"
|
82 |
+
rel="noreferrer"
|
83 |
+
class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
|
84 |
+
>
|
85 |
+
Feedback
|
86 |
+
</a>
|
87 |
+
<a
|
88 |
+
href="{base}/privacy"
|
89 |
+
class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
|
90 |
+
>
|
91 |
+
About & Privacy
|
92 |
+
</a>
|
93 |
+
{/if}
|
94 |
</div>
|
src/lib/components/SettingsModal.svelte
CHANGED
@@ -7,6 +7,7 @@
|
|
7 |
import type { Settings } from "$lib/types/Settings";
|
8 |
import { enhance } from "$app/forms";
|
9 |
import { base } from "$app/paths";
|
|
|
10 |
|
11 |
export let settings: Pick<Settings, "shareConversationsWithModelAuthors">;
|
12 |
|
@@ -32,32 +33,35 @@
|
|
32 |
method="post"
|
33 |
action="{base}/settings"
|
34 |
>
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
|
|
|
|
61 |
<form
|
62 |
method="post"
|
63 |
action="{base}/conversations?/delete"
|
|
|
7 |
import type { Settings } from "$lib/types/Settings";
|
8 |
import { enhance } from "$app/forms";
|
9 |
import { base } from "$app/paths";
|
10 |
+
import { PUBLIC_APP_DATA_SHARING } from "$env/static/public";
|
11 |
|
12 |
export let settings: Pick<Settings, "shareConversationsWithModelAuthors">;
|
13 |
|
|
|
33 |
method="post"
|
34 |
action="{base}/settings"
|
35 |
>
|
36 |
+
{#if PUBLIC_APP_DATA_SHARING}
|
37 |
+
<label class="flex cursor-pointer select-none items-center gap-2 text-gray-500">
|
38 |
+
{#each Object.entries(settings).filter(([k]) => k !== "shareConversationsWithModelAuthors") as [key, val]}
|
39 |
+
<input type="hidden" name={key} value={val} />
|
40 |
+
{/each}
|
41 |
+
<Switch
|
42 |
+
name="shareConversationsWithModelAuthors"
|
43 |
+
bind:checked={shareConversationsWithModelAuthors}
|
44 |
+
/>
|
45 |
+
Share conversations with model authors
|
46 |
+
</label>
|
47 |
|
48 |
+
<p class="text-gray-800">
|
49 |
+
Sharing your data will help improve the training data and make open models better over
|
50 |
+
time.
|
51 |
+
</p>
|
52 |
+
<p class="text-gray-800">
|
53 |
+
You can change this setting at any time, it applies to all your conversations.
|
54 |
+
</p>
|
55 |
+
<p class="text-gray-800">
|
56 |
+
Read more about this model's authors,
|
57 |
+
<a
|
58 |
+
href="https://open-assistant.io/"
|
59 |
+
target="_blank"
|
60 |
+
rel="noreferrer"
|
61 |
+
class="underline decoration-gray-300 hover:decoration-gray-700">Open Assistant</a
|
62 |
+
>.
|
63 |
+
</p>
|
64 |
+
{/if}
|
65 |
<form
|
66 |
method="post"
|
67 |
action="{base}/conversations?/delete"
|
src/lib/components/chat/ChatIntroduction.svelte
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<script lang="ts">
|
2 |
-
import { PUBLIC_VERSION } from "$env/static/public";
|
3 |
import { PUBLIC_ANNOUNCEMENT_BANNERS } from "$env/static/public";
|
4 |
import Logo from "$lib/components/icons/Logo.svelte";
|
5 |
import { createEventDispatcher } from "svelte";
|
@@ -31,8 +31,8 @@
|
|
31 |
<div class="lg:col-span-1">
|
32 |
<div>
|
33 |
<div class="mb-3 flex items-center text-2xl font-semibold">
|
34 |
-
<Logo classNames="mr-1
|
35 |
-
|
36 |
<div
|
37 |
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400 dark:border-gray-700/60 dark:bg-gray-800"
|
38 |
>
|
|
|
1 |
<script lang="ts">
|
2 |
+
import { PUBLIC_APP_NAME, PUBLIC_VERSION } from "$env/static/public";
|
3 |
import { PUBLIC_ANNOUNCEMENT_BANNERS } from "$env/static/public";
|
4 |
import Logo from "$lib/components/icons/Logo.svelte";
|
5 |
import { createEventDispatcher } from "svelte";
|
|
|
31 |
<div class="lg:col-span-1">
|
32 |
<div>
|
33 |
<div class="mb-3 flex items-center text-2xl font-semibold">
|
34 |
+
<Logo classNames="mr-1 flex-none" />
|
35 |
+
{PUBLIC_APP_NAME}
|
36 |
<div
|
37 |
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400 dark:border-gray-700/60 dark:bg-gray-800"
|
38 |
>
|
src/lib/components/chat/ChatWindow.svelte
CHANGED
@@ -137,7 +137,7 @@
|
|
137 |
type="button"
|
138 |
on:click={() => dispatch("share")}
|
139 |
>
|
140 |
-
<CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-
|
141 |
<div class="max-sm:hidden">Share this conversation</div>
|
142 |
</button>
|
143 |
{/if}
|
|
|
137 |
type="button"
|
138 |
on:click={() => dispatch("share")}
|
139 |
>
|
140 |
+
<CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-primary-500" />
|
141 |
<div class="max-sm:hidden">Share this conversation</div>
|
142 |
</button>
|
143 |
{/if}
|
src/lib/components/icons/Logo.svelte
CHANGED
@@ -1,25 +1,28 @@
|
|
1 |
<script lang="ts">
|
|
|
|
|
|
|
|
|
2 |
export let classNames = "";
|
3 |
</script>
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
>
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
d="M6.97 7.12c-.2.16-.49.27-.85.27-.34 0-.6-.1-.81-.24a.94.94 0 0 1 .57-.49c.04-.01.09.06.13.14.05.07.1.15.14.15.05 0 .1-.08.14-.15.05-.08.1-.15.14-.13a.93.93 0 0 1 .54.45Z"
|
24 |
/>
|
25 |
-
|
|
|
1 |
<script lang="ts">
|
2 |
+
import { page } from "$app/stores";
|
3 |
+
import { PUBLIC_APP_ASSETS, PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
|
4 |
+
import { base } from "$app/paths";
|
5 |
+
|
6 |
export let classNames = "";
|
7 |
</script>
|
8 |
|
9 |
+
{#if PUBLIC_APP_ASSETS === "chatui"}
|
10 |
+
<svg
|
11 |
+
height="30"
|
12 |
+
width="30"
|
13 |
+
viewBox="0 0 30 30"
|
14 |
+
xmlns="http://www.w3.org/2000/svg"
|
15 |
+
class={classNames}
|
16 |
+
>
|
17 |
+
<path
|
18 |
+
d="M4.06151 14.1464C4.06151 11.8818 4.9611 9.71004 6.56237 8.10877C8.16364 6.5075 10.3354 5.60791 12.6 5.60791H16.5231C18.6254 5.60791 20.6416 6.44307 22.1282 7.92965C23.6148 9.41624 24.45 11.4325 24.45 13.5348C24.45 15.6372 23.6148 17.6534 22.1282 19.14C20.6416 20.6266 18.6254 21.4618 16.5231 21.4618H7.08459L4.63844 23.8387C4.59547 23.8942 4.53557 23.9343 4.4678 23.9527C4.40004 23.9712 4.32811 23.9671 4.2629 23.941C4.1977 23.9149 4.14276 23.8683 4.10643 23.8082C4.07009 23.7481 4.05432 23.6778 4.06151 23.6079V14.1464Z"
|
19 |
+
class="fill-primary-500"
|
20 |
+
/>
|
21 |
+
</svg>
|
22 |
+
{:else}
|
23 |
+
<object
|
24 |
+
class={classNames}
|
25 |
+
data="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/favicon.svg"
|
26 |
+
title="{PUBLIC_APP_NAME} logo"
|
|
|
27 |
/>
|
28 |
+
{/if}
|
src/routes/+layout.svelte
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
import { page } from "$app/stores";
|
5 |
import "../styles/main.css";
|
6 |
import { base } from "$app/paths";
|
7 |
-
import { PUBLIC_ORIGIN } from "$env/static/public";
|
8 |
|
9 |
import { shareConversation } from "$lib/shareConversation";
|
10 |
import { UrlDependency } from "$lib/types/UrlDependency";
|
@@ -15,6 +15,7 @@
|
|
15 |
import Toast from "$lib/components/Toast.svelte";
|
16 |
import SettingsModal from "$lib/components/SettingsModal.svelte";
|
17 |
import LoginModal from "$lib/components/LoginModal.svelte";
|
|
|
18 |
|
19 |
export let data;
|
20 |
|
@@ -94,18 +95,54 @@
|
|
94 |
|
95 |
const requiresLogin =
|
96 |
!$page.error &&
|
97 |
-
|
98 |
-
|
|
|
|
|
99 |
</script>
|
100 |
|
101 |
<svelte:head>
|
|
|
102 |
<meta name="description" content="The first open source alternative to ChatGPT. 💪" />
|
103 |
<meta name="twitter:card" content="summary_large_image" />
|
104 |
<meta name="twitter:site" content="@huggingface" />
|
105 |
-
<meta property="og:title" content=
|
106 |
<meta property="og:type" content="website" />
|
107 |
<meta property="og:url" content="{PUBLIC_ORIGIN || $page.url.origin}{base}" />
|
108 |
-
<meta
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
</svelte:head>
|
110 |
|
111 |
<div
|
|
|
4 |
import { page } from "$app/stores";
|
5 |
import "../styles/main.css";
|
6 |
import { base } from "$app/paths";
|
7 |
+
import { PUBLIC_ORIGIN, PUBLIC_APP_DISCLAIMER } from "$env/static/public";
|
8 |
|
9 |
import { shareConversation } from "$lib/shareConversation";
|
10 |
import { UrlDependency } from "$lib/types/UrlDependency";
|
|
|
15 |
import Toast from "$lib/components/Toast.svelte";
|
16 |
import SettingsModal from "$lib/components/SettingsModal.svelte";
|
17 |
import LoginModal from "$lib/components/LoginModal.svelte";
|
18 |
+
import { PUBLIC_APP_ASSETS, PUBLIC_APP_NAME } from "$env/static/public";
|
19 |
|
20 |
export let data;
|
21 |
|
|
|
95 |
|
96 |
const requiresLogin =
|
97 |
!$page.error &&
|
98 |
+
!$page.route.id?.startsWith("/r/") &&
|
99 |
+
(data.requiresLogin
|
100 |
+
? !data.user
|
101 |
+
: !data.settings.ethicsModalAcceptedAt && !!PUBLIC_APP_DISCLAIMER);
|
102 |
</script>
|
103 |
|
104 |
<svelte:head>
|
105 |
+
<title>{PUBLIC_APP_NAME}</title>
|
106 |
<meta name="description" content="The first open source alternative to ChatGPT. 💪" />
|
107 |
<meta name="twitter:card" content="summary_large_image" />
|
108 |
<meta name="twitter:site" content="@huggingface" />
|
109 |
+
<meta property="og:title" content={PUBLIC_APP_NAME} />
|
110 |
<meta property="og:type" content="website" />
|
111 |
<meta property="og:url" content="{PUBLIC_ORIGIN || $page.url.origin}{base}" />
|
112 |
+
<meta
|
113 |
+
property="og:image"
|
114 |
+
content="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/thumbnail.png"
|
115 |
+
/>
|
116 |
+
<link
|
117 |
+
rel="icon"
|
118 |
+
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/favicon.svg"
|
119 |
+
type="image/svg+xml"
|
120 |
+
/>
|
121 |
+
<link
|
122 |
+
rel="icon"
|
123 |
+
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/favicon.png"
|
124 |
+
type="image/png"
|
125 |
+
/>
|
126 |
+
<!-- Icon Support for iOS Bookmark Home Screen -->
|
127 |
+
<link
|
128 |
+
rel="apple-touch-icon"
|
129 |
+
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/touch-icon-ipad-retina.png"
|
130 |
+
sizes="167x167"
|
131 |
+
type="image/png"
|
132 |
+
/>
|
133 |
+
<link
|
134 |
+
rel="apple-touch-icon"
|
135 |
+
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/touch-icon-ipad.png"
|
136 |
+
sizes="152x152"
|
137 |
+
type="image/png"
|
138 |
+
/>
|
139 |
+
<link
|
140 |
+
rel="apple-touch-icon"
|
141 |
+
href="{PUBLIC_ORIGIN ||
|
142 |
+
$page.url.origin}{base}/{PUBLIC_APP_ASSETS}/touch-icon-iphone-retina.png"
|
143 |
+
sizes="180x180"
|
144 |
+
type="image/png"
|
145 |
+
/>
|
146 |
</svelte:head>
|
147 |
|
148 |
<div
|
src/routes/r/[id]/+page.svelte
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
import { goto } from "$app/navigation";
|
3 |
import { base } from "$app/paths";
|
4 |
import { page } from "$app/stores";
|
|
|
5 |
import ChatWindow from "$lib/components/chat/ChatWindow.svelte";
|
6 |
import { ERROR_MESSAGES, error } from "$lib/stores/errors";
|
7 |
import { pendingMessage } from "$lib/stores/pendingMessage";
|
@@ -80,5 +81,7 @@
|
|
80 |
currentModel={findCurrentModel(data.models, data.model)}
|
81 |
settings={data.settings}
|
82 |
loginRequired={!$page.error &&
|
83 |
-
(data.requiresLogin
|
|
|
|
|
84 |
/>
|
|
|
2 |
import { goto } from "$app/navigation";
|
3 |
import { base } from "$app/paths";
|
4 |
import { page } from "$app/stores";
|
5 |
+
import { PUBLIC_APP_DISCLAIMER } from "$env/static/public";
|
6 |
import ChatWindow from "$lib/components/chat/ChatWindow.svelte";
|
7 |
import { ERROR_MESSAGES, error } from "$lib/stores/errors";
|
8 |
import { pendingMessage } from "$lib/stores/pendingMessage";
|
|
|
81 |
currentModel={findCurrentModel(data.models, data.model)}
|
82 |
settings={data.settings}
|
83 |
loginRequired={!$page.error &&
|
84 |
+
(data.requiresLogin
|
85 |
+
? !data.user
|
86 |
+
: !data.settings.ethicsModalAcceptedAt && !!PUBLIC_APP_DISCLAIMER)}
|
87 |
/>
|
static/chatui/favicon.png
ADDED
static/chatui/favicon.svg
ADDED
static/chatui/touch-icon-ipad-retina.png
ADDED
static/chatui/touch-icon-ipad.png
ADDED
static/chatui/touch-icon-iphone-retina.png
ADDED
static/{favicon.png → huggingchat/favicon.png}
RENAMED
File without changes
|
static/{favicon.svg → huggingchat/favicon.svg}
RENAMED
File without changes
|
static/{thumbnail.png → huggingchat/thumbnail.png}
RENAMED
File without changes
|
static/{touch-icon-ipad-retina.png → huggingchat/touch-icon-ipad-retina.png}
RENAMED
File without changes
|
static/{touch-icon-ipad.png → huggingchat/touch-icon-ipad.png}
RENAMED
File without changes
|
static/{touch-icon-iphone-retina.png → huggingchat/touch-icon-iphone-retina.png}
RENAMED
File without changes
|
svelte.config.js
CHANGED
@@ -1,12 +1,11 @@
|
|
1 |
import adapter from "@sveltejs/adapter-node";
|
2 |
import { vitePreprocess } from "@sveltejs/kit/vite";
|
3 |
import dotenv from "dotenv";
|
4 |
-
import pkg from "./package.json" assert { type: "json" };
|
5 |
|
6 |
dotenv.config({ path: "./.env.local" });
|
7 |
dotenv.config({ path: "./.env" });
|
8 |
|
9 |
-
process.env.PUBLIC_VERSION =
|
10 |
|
11 |
/** @type {import('@sveltejs/kit').Config} */
|
12 |
const config = {
|
|
|
1 |
import adapter from "@sveltejs/adapter-node";
|
2 |
import { vitePreprocess } from "@sveltejs/kit/vite";
|
3 |
import dotenv from "dotenv";
|
|
|
4 |
|
5 |
dotenv.config({ path: "./.env.local" });
|
6 |
dotenv.config({ path: "./.env" });
|
7 |
|
8 |
+
process.env.PUBLIC_VERSION = process.env.npm_package_version;
|
9 |
|
10 |
/** @type {import('@sveltejs/kit').Config} */
|
11 |
const config = {
|
tailwind.config.cjs
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
const defaultTheme = require("tailwindcss/defaultTheme");
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/** @type {import('tailwindcss').Config} */
|
4 |
export default {
|
@@ -6,6 +10,9 @@ export default {
|
|
6 |
content: ["./src/**/*.{html,js,svelte,ts}"],
|
7 |
theme: {
|
8 |
extend: {
|
|
|
|
|
|
|
9 |
// fontFamily: {
|
10 |
// sans: ['"Inter"', ...defaultTheme.fontFamily.sans]
|
11 |
// },
|
|
|
1 |
const defaultTheme = require("tailwindcss/defaultTheme");
|
2 |
+
const colors = require("tailwindcss/colors");
|
3 |
+
|
4 |
+
import dotenv from "dotenv";
|
5 |
+
dotenv.config({ path: "./.env" });
|
6 |
|
7 |
/** @type {import('tailwindcss').Config} */
|
8 |
export default {
|
|
|
10 |
content: ["./src/**/*.{html,js,svelte,ts}"],
|
11 |
theme: {
|
12 |
extend: {
|
13 |
+
colors: {
|
14 |
+
primary: colors[process.env.PUBLIC_APP_COLOR],
|
15 |
+
},
|
16 |
// fontFamily: {
|
17 |
// sans: ['"Inter"', ...defaultTheme.fontFamily.sans]
|
18 |
// },
|