luxopes commited on
Commit
5a96ab4
·
verified ·
1 Parent(s): 7d09e30

Make design more colorful and switching between models move down to prompt field.

Browse files
Files changed (3) hide show
  1. README.md +8 -5
  2. index.html +191 -18
  3. style.css +81 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Rainbow Ai Chatter
3
- emoji: 🦀
4
- colorFrom: red
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Rainbow AI Chatter 🦄
3
+ colorFrom: pink
4
+ colorTo: pink
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
index.html CHANGED
@@ -1,19 +1,192 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <!doctype html>
2
+ <html lang="cs">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>LuxAI Chat</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <link rel="stylesheet" href="style.css">
11
+ <script>
12
+ tailwind.config = {
13
+ theme: {
14
+ extend: {
15
+ colors: {
16
+ primary: {
17
+ 50: '#f0fdfa',
18
+ 100: '#ccfbf1',
19
+ 500: '#10a37f',
20
+ 600: '#0d9488',
21
+ 700: '#0f766e',
22
+ },
23
+ dark: {
24
+ 800: '#1e293b',
25
+ 900: '#0f172a',
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ </script>
32
+ </head>
33
+
34
+ <body class="bg-gray-50 dark:bg-dark-900 text-gray-900 dark:text-gray-100 h-screen flex flex-col">
35
+ <!-- Header -->
36
+ <header class="bg-gradient-to-r from-purple-500 to-pink-500 dark:from-purple-700 dark:to-pink-700 h-14 px-4 flex items-center justify-between shadow-lg">
37
+ <div class="flex items-center space-x-2">
38
+ <div class="w-8 h-8 rounded-full bg-white flex items-center justify-center">
39
+ <i data-feather="cpu" class="text-purple-600 w-4 h-4"></i>
40
+ </div>
41
+ <h1 class="font-bold text-lg text-white">Rainbow AI</h1>
42
+ </div>
43
+ <button id="newChat" class="flex items-center space-x-1 bg-white/20 hover:bg-white/30 text-white border border-white/30 rounded-lg px-3 py-1.5 text-sm transition-colors backdrop-blur-sm">
44
+ <i data-feather="plus" class="w-4 h-4"></i>
45
+ <span>Nový chat</span>
46
+ </button>
47
+ </header>
48
+ <!-- Chat Area -->
49
+ <main class="flex-1 overflow-y-auto p-4 md:p-6">
50
+ <div class="max-w-3xl mx-auto space-y-4" id="chat">
51
+ <div class="text-center text-gray-500 dark:text-gray-400 mt-12">
52
+ <i data-feather="message-square" class="w-12 h-12 mx-auto mb-4 opacity-30"></i>
53
+ <p class="text-lg">Začni nový rozhovor</p>
54
+ </div>
55
+ </div>
56
+ </main>
57
+ <!-- Input Area -->
58
+ <form id="chatForm" class="bg-gradient-to-r from-blue-500/10 to-purple-500/10 dark:from-blue-700/20 dark:to-purple-700/20 border-t border-gray-200/50 dark:border-gray-700/50 px-4 py-3 backdrop-blur-sm">
59
+ <div class="max-w-3xl mx-auto">
60
+ <div class="flex items-center gap-2 mb-2">
61
+ <select id="modelSelect" class="bg-white/80 dark:bg-dark-800/80 border border-gray-200/50 dark:border-gray-700/50 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-purple-500 shadow-sm">
62
+ <option value="gpt-a">GPT-A</option>
63
+ <option value="gpt2">GPT-2</option>
64
+ </select>
65
+ <div class="text-xs text-gray-500 dark:text-gray-400">Press Shift+Enter for new line</div>
66
+ </div>
67
+ <div class="flex items-end gap-2">
68
+ <div class="flex-1 relative">
69
+ <textarea id="input" rows="2" placeholder="Napiš zprávu…"
70
+ class="w-full bg-white/80 dark:bg-dark-700/80 border border-gray-200/50 dark:border-gray-600/50 rounded-xl px-4 py-3 pr-10 focus:outline-none focus:ring-2 focus:ring-purple-500 resize-none shadow-sm"></textarea>
71
+ <button type="submit" class="absolute right-3 bottom-3 bg-gradient-to-r from-purple-500 to-pink-500 text-white p-1 rounded-full hover:opacity-90 transition-opacity shadow-md">
72
+ <i data-feather="arrow-up" class="w-5 h-5"></i>
73
+ </button>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </form>
78
+ <script>
79
+ // Rainbow color animation for empty state icon
80
+ function animateRainbowIcon() {
81
+ const icon = document.querySelector('.empty i');
82
+ if (icon) {
83
+ let hue = 0;
84
+ setInterval(() => {
85
+ hue = (hue + 1) % 360;
86
+ icon.style.color = `hsl(${hue}, 100%, 70%)`;
87
+ }, 50);
88
+ }
89
+ }
90
+
91
+ const MODELS = {
92
+ "gpt-a": {
93
+ name: "GPT-A",
94
+ url: "https://luxopes-gpt-a.hf.space/generate"
95
+ },
96
+ "gpt2": {
97
+ name: "GPT-2",
98
+ url: "https://luxopes-gpt2-backend.hf.space/generate"
99
+ }
100
+ };
101
+
102
+ let currentModel = "gpt-a";
103
+
104
+ const chat = document.getElementById("chat");
105
+ const input = document.getElementById("input");
106
+ const form = document.getElementById("chatForm");
107
+
108
+ function appendMessage(text, cls, model=null) {
109
+ const div = document.createElement("div");
110
+ div.className = cls === "user"
111
+ ? "bg-gradient-to-r from-purple-500 to-pink-500 text-white px-5 py-4 rounded-xl rounded-tr-none max-w-[85%] ml-auto shadow-lg"
112
+ : "bg-white/90 dark:bg-dark-700/90 border border-gray-200/50 dark:border-gray-600/50 px-5 py-4 rounded-xl rounded-tl-none max-w-[85%] shadow-lg backdrop-blur-sm";
113
+ if (model) {
114
+ const modelIndicator = document.createElement("div");
115
+ modelIndicator.className = "text-xs text-gray-500 dark:text-gray-400 mb-1";
116
+ modelIndicator.textContent = model;
117
+ div.appendChild(modelIndicator);
118
+ }
119
+
120
+ const content = document.createElement("div");
121
+ content.className = cls === "user" ? "text-white" : "text-gray-800 dark:text-gray-100";
122
+ content.textContent = text;
123
+ div.appendChild(content);
124
+
125
+ chat.appendChild(div);
126
+ chat.scrollTop = chat.scrollHeight;
127
+ document.querySelector(".empty")?.remove();
128
+ return div;
129
+ }
130
+
131
+ form.addEventListener("submit", async e => {
132
+ e.preventDefault();
133
+ const msg = input.value.trim();
134
+ if (!msg) return;
135
+
136
+ appendMessage(msg, "user");
137
+ input.value = "";
138
+ input.disabled = true;
139
+
140
+ const bot = appendMessage(
141
+ `${MODELS[currentModel].name} přemýšlí…`,
142
+ "bot",
143
+ MODELS[currentModel].name
144
+ );
145
+ bot.classList.add("opacity-80");
146
+
147
+ try {
148
+ const res = await fetch(MODELS[currentModel].url, {
149
+ method: "POST",
150
+ headers: { "Content-Type": "application/json" },
151
+ body: JSON.stringify({ user_input: msg, model: currentModel })
152
+ });
153
+ const data = await res.json();
154
+ bot.classList.remove("opacity-80");
155
+ bot.lastChild.textContent = data.response || "Chyba odpovědi";
156
+ } catch (e) {
157
+ bot.classList.remove("opacity-80");
158
+ bot.lastChild.textContent = "Chyba připojení";
159
+ }
160
+
161
+ input.disabled = false;
162
+ input.focus();
163
+ });
164
+
165
+ document.getElementById("modelSelect").onchange = e => {
166
+ currentModel = e.target.value;
167
+ appendMessage(`Přepnuto na ${MODELS[currentModel].name}`, "bot", "System");
168
+ };
169
+
170
+ document.getElementById("newChat").onclick = () => {
171
+ chat.innerHTML = `
172
+ <div class="text-center text-gray-500 dark:text-gray-400 mt-12">
173
+ <i data-feather="message-square" class="w-12 h-12 mx-auto mb-4 opacity-30"></i>
174
+ <p class="text-lg">Začni nový rozhovor</p>
175
+ </div>
176
+ `;
177
+ feather.replace();
178
+ input.focus();
179
+ };
180
+
181
+ input.addEventListener("keydown", e => {
182
+ if (e.key === "Enter" && !e.shiftKey) {
183
+ e.preventDefault();
184
+ form.requestSubmit();
185
+ }
186
+ });
187
+ feather.replace();
188
+ animateRainbowIcon();
189
+ </script>
190
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
191
+ </body>
192
+ </html>
style.css CHANGED
@@ -1,28 +1,90 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
 
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
 
28
  }
 
 
 
 
 
1
+
2
+ @keyframes fadeIn {
3
+ from { opacity: 0; transform: translateY(10px); }
4
+ to { opacity: 1; transform: translateY(0); }
5
+ }
6
+
7
+ @keyframes rainbow {
8
+ 0% { background-position: 0% 50%; }
9
+ 50% { background-position: 100% 50%; }
10
+ 100% { background-position: 0% 50%; }
11
+ }
12
+ .message {
13
+ animation: fadeIn 0.3s ease-out;
14
+ }
15
+
16
+ .bot {
17
+ position: relative;
18
+ }
19
+
20
+ .bot:not(:last-child) {
21
+ margin-bottom: 1.5rem;
22
  }
23
 
24
+ .user:not(:last-child) {
25
+ margin-bottom: 1.5rem;
26
+ }
27
+ .bot::after {
28
+ content: "";
29
+ position: absolute;
30
+ left: -8px;
31
+ top: 0;
32
+ width: 8px;
33
+ height: 12px;
34
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='M8 12V0H0l8 12z' fill='%23ffffff'/%3E%3C/svg%3E") no-repeat;
35
+ background-size: contain;
36
+ filter: drop-shadow(1px 0 1px rgba(0,0,0,0.1));
37
+ }
38
+
39
+ .dark .bot::after {
40
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='M8 12V0H0l8 12z' fill='%231e293b'/%3E%3C/svg%3E");
41
+ filter: drop-shadow(1px 0 1px rgba(0,0,0,0.2));
42
+ }
43
+ .user::before {
44
+ content: "";
45
+ position: absolute;
46
+ right: -8px;
47
+ top: 0;
48
+ width: 8px;
49
+ height: 12px;
50
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='M0 0v12h8L0 0z' fill='%23a855f7'/%3E%3C/svg%3E") no-repeat;
51
+ background-size: contain;
52
+ filter: drop-shadow(-1px 0 1px rgba(0,0,0,0.1));
53
+ }
54
+ @keyframes pulse {
55
+ 0%, 100% { opacity: 0.5; }
56
+ 50% { opacity: 1; }
57
+ }
58
+
59
+ .thinking {
60
+ position: relative;
61
+ display: inline-block;
62
  }
63
 
64
+ .thinking::after {
65
+ content: "...";
66
+ position: absolute;
67
+ animation: pulse 1.5s infinite;
68
+ }
69
+ textarea {
70
+ min-height: 60px;
71
+ max-height: 200px;
72
+ transition: all 0.2s ease;
73
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
74
  }
75
 
76
+ .empty i {
77
+ animation: rainbowPulse 2s infinite;
 
 
 
 
78
  }
79
 
80
+ @keyframes rainbowPulse {
81
+ 0% { filter: drop-shadow(0 0 5px rgba(168,85,247,0.5)); }
82
+ 25% { filter: drop-shadow(0 0 5px rgba(236,72,153,0.5)); }
83
+ 50% { filter: drop-shadow(0 0 5px rgba(59,130,246,0.5)); }
84
+ 75% { filter: drop-shadow(0 0 5px rgba(16,185,129,0.5)); }
85
+ 100% { filter: drop-shadow(0 0 5px rgba(168,85,247,0.5)); }
86
  }
87
+ /* Smooth scrolling */
88
+ main {
89
+ scroll-behavior: smooth;
90
+ }