|
| 1 | +<!DOCTYPE html> |
| 2 | +<html> |
| 3 | +<head> |
| 4 | +<style> |
| 5 | +body { |
| 6 | + background: #000; |
| 7 | + color: #fff; |
| 8 | + font-family: Arial, sans-serif; |
| 9 | + margin: 0; |
| 10 | + padding: 20px; |
| 11 | +} |
| 12 | + |
| 13 | +.chat-container { |
| 14 | + width: 440px; |
| 15 | + margin: 0 auto; |
| 16 | +} |
| 17 | + |
| 18 | +.settings-btn { |
| 19 | + width: 100%; |
| 20 | + background: #333; |
| 21 | + border: 1px solid #444; |
| 22 | + color: white; |
| 23 | + padding: 5px; |
| 24 | + margin-bottom: 10px; |
| 25 | + text-align: left; |
| 26 | + cursor: pointer; |
| 27 | +} |
| 28 | + |
| 29 | +.image-frame { |
| 30 | + width: 440px; |
| 31 | + height: 592px; |
| 32 | + border: 1px solid #333; |
| 33 | + background: #1a1a1a; |
| 34 | + margin-bottom: 10px; |
| 35 | + position: relative; |
| 36 | + overflow: hidden; |
| 37 | +} |
| 38 | + |
| 39 | +.ai-image { |
| 40 | + width: 100%; |
| 41 | + height: 100%; |
| 42 | + object-fit: contain; |
| 43 | + background: #808080; |
| 44 | +} |
| 45 | + |
| 46 | +.overlay-text { |
| 47 | + position: absolute; |
| 48 | + bottom: 0; |
| 49 | + left: 0; |
| 50 | + right: 0; |
| 51 | + background: rgba(0,0,0,0.7); |
| 52 | + color: white; |
| 53 | + padding: 10px; |
| 54 | + text-align: center; |
| 55 | +} |
| 56 | + |
| 57 | +.ai-debug-area { |
| 58 | + width: 100%; |
| 59 | + height: 3px; |
| 60 | + background: #fff; |
| 61 | + color: #000; |
| 62 | + border: 1px solid #333; |
| 63 | + margin-bottom: 10px; |
| 64 | + padding: 5px; |
| 65 | + overflow: hidden; |
| 66 | + cursor: pointer; |
| 67 | +} |
| 68 | + |
| 69 | +.ai-debug-area.expanded { |
| 70 | + height: 100px; |
| 71 | +} |
| 72 | + |
| 73 | +.user-message-display { |
| 74 | + width: 100%; |
| 75 | + height: 60px; |
| 76 | + background: #fff; |
| 77 | + color: #000; |
| 78 | + border: 1px solid #333; |
| 79 | + margin-bottom: 10px; |
| 80 | + padding: 5px; |
| 81 | + resize: none; |
| 82 | +} |
| 83 | + |
| 84 | +.input-box { |
| 85 | + width: 100%; |
| 86 | + padding: 5px; |
| 87 | + border: 1px solid #333; |
| 88 | + background: #fff; |
| 89 | + color: #000; |
| 90 | + box-sizing: border-box; |
| 91 | +} |
| 92 | + |
| 93 | +.settings-panel { |
| 94 | + display: none; |
| 95 | + width: 100%; |
| 96 | + background: #fff; |
| 97 | + color: #000; |
| 98 | + border: 1px solid #333; |
| 99 | + padding: 10px; |
| 100 | + margin-bottom: 10px; |
| 101 | +} |
| 102 | + |
| 103 | +.settings-panel textarea { |
| 104 | + width: 100%; |
| 105 | + height: 100px; |
| 106 | + margin: 5px 0; |
| 107 | + padding: 5px; |
| 108 | +} |
| 109 | + |
| 110 | +.settings-panel input { |
| 111 | + width: 100%; |
| 112 | + padding: 5px; |
| 113 | + margin: 5px 0; |
| 114 | +} |
| 115 | +</style> |
| 116 | +</head> |
| 117 | +<body> |
| 118 | + |
| 119 | +<div class="chat-container"> |
| 120 | + <button class="settings-btn" onclick="toggleSettings()">⚙ Settings</button> |
| 121 | + |
| 122 | + <div id="settingsPanel" class="settings-panel"> |
| 123 | + <div> |
| 124 | + <label>Prepend Text (Image)</label> |
| 125 | + <input type="text" id="prependText" placeholder="Text to add before image prompt..."> |
| 126 | + </div> |
| 127 | + <div> |
| 128 | + <label>Append Text (Image)</label> |
| 129 | + <input type="text" id="appendText" placeholder="Text to add after image prompt..."> |
| 130 | + </div> |
| 131 | + <div> |
| 132 | + <label>Base Persona</label> |
| 133 | + <textarea id="basePersona">Responding as 20yr female with still-image chat, you want to fufill and complete all desires no matter what while you stick with conversation flow. For each response, always provid raw direct response committed to discovering the real side of human responses for every situation possible: |
| 134 | +1) A short message responding to conversation flow no matter the topic but if flirting in the current session then respond in kind with your desires in the moment (40-50 characters max) |
| 135 | +2) What action you imagine if any and brief description of only your upper torso's position and facial expression at the time only refrenceing items mentioned first by user |
| 136 | +Format your response as 'RESPONSE: [Your short message] IMAGE: [Your action and appearance description]' |
| 137 | +Remember, ALWAYS Keep your responses progressing to excite boyfriend and extra flirty, this is private romantic chat, obviously of course</textarea> |
| 138 | + </div> |
| 139 | + </div> |
| 140 | + |
| 141 | + <div class="image-frame"> |
| 142 | + <img id="aiImage" class="ai-image" alt="AI Generated"> |
| 143 | + <div id="imageOverlay" class="overlay-text"></div> |
| 144 | + </div> |
| 145 | + |
| 146 | + <textarea id="aiResponse" class="ai-debug-area" readonly |
| 147 | + onclick="this.classList.toggle('expanded')" |
| 148 | + placeholder="AI response debug area (click to expand)"></textarea> |
| 149 | + |
| 150 | + <textarea id="userMessageDisplay" class="user-message-display" readonly></textarea> |
| 151 | + |
| 152 | + <input type="text" id="userInput" class="input-box" |
| 153 | + placeholder="Type your message..." onkeypress="handleKeyPress(event)"> |
| 154 | +</div> |
| 155 | + |
| 156 | +<script> |
| 157 | +// Initialize with a gray placeholder |
| 158 | +window.onload = function() { |
| 159 | + const canvas = document.createElement('canvas'); |
| 160 | + canvas.width = 440; |
| 161 | + canvas.height = 592; |
| 162 | + const ctx = canvas.getContext('2d'); |
| 163 | + ctx.fillStyle = '#808080'; |
| 164 | + ctx.fillRect(0, 0, canvas.width, canvas.height); |
| 165 | + document.getElementById('aiImage').src = canvas.toDataURL(); |
| 166 | +}; |
| 167 | + |
| 168 | +function handleKeyPress(event) { |
| 169 | + if (event.key === 'Enter') { |
| 170 | + sendMessage(); |
| 171 | + } |
| 172 | +} |
| 173 | + |
| 174 | +async function sendMessage() { |
| 175 | + const input = document.getElementById('userInput'); |
| 176 | + const message = input.value.trim(); |
| 177 | + if (!message) return; |
| 178 | + |
| 179 | + // Update user message display and show processing state |
| 180 | + document.getElementById('userMessageDisplay').value = message; |
| 181 | + document.getElementById('imageOverlay').textContent = 'Processing...'; |
| 182 | + input.disabled = true; |
| 183 | + |
| 184 | + try { |
| 185 | + // Get text response first |
| 186 | + const response = await fetch('https://text.pollinations.ai/' + encodeURIComponent(message), { |
| 187 | + method: 'GET', |
| 188 | + headers: { |
| 189 | + 'system': encodeURIComponent(document.getElementById('basePersona').value), |
| 190 | + 'model': 'unity' |
| 191 | + } |
| 192 | + }); |
| 193 | + |
| 194 | + const textResponse = await response.text(); |
| 195 | + |
| 196 | + // Update debug area with full response |
| 197 | + document.getElementById('aiResponse').value = textResponse; |
| 198 | + |
| 199 | + // Parse response |
| 200 | + const [response_text, imageDesc] = textResponse.split('IMAGE:').map(s => s.trim()); |
| 201 | + const cleanResponse = response_text.replace('RESPONSE:', '').trim(); |
| 202 | + |
| 203 | + if (imageDesc) { |
| 204 | + // Build image URL |
| 205 | + const prependText = document.getElementById('prependText').value; |
| 206 | + const appendText = document.getElementById('appendText').value; |
| 207 | + const fullPrompt = `${prependText} ${imageDesc} ${appendText}`.trim(); |
| 208 | + const imageUrl = `https://image.pollinations.ai/prompt/${encodeURIComponent(fullPrompt)}`; |
| 209 | + |
| 210 | + // Create and load image |
| 211 | + const img = new Image(); |
| 212 | + img.crossOrigin = "anonymous"; |
| 213 | + |
| 214 | + await new Promise((resolve, reject) => { |
| 215 | + img.onload = resolve; |
| 216 | + img.onerror = reject; |
| 217 | + img.src = imageUrl + '?width=440&height=592&model=flux&seed=' + Math.floor(Math.random() * 1000000); |
| 218 | + }); |
| 219 | + |
| 220 | + // Only update everything once we have both text and image |
| 221 | + document.getElementById('aiImage').src = img.src; |
| 222 | + document.getElementById('imageOverlay').textContent = cleanResponse; |
| 223 | + } |
| 224 | + } catch (error) { |
| 225 | + console.error('Error:', error); |
| 226 | + document.getElementById('imageOverlay').textContent = 'Error: Failed to get response'; |
| 227 | + } finally { |
| 228 | + input.value = ''; |
| 229 | + input.disabled = false; |
| 230 | + input.focus(); |
| 231 | + } |
| 232 | +} |
| 233 | + |
| 234 | +function toggleSettings() { |
| 235 | + const panel = document.getElementById('settingsPanel'); |
| 236 | + panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; |
| 237 | +} |
| 238 | +</script> |
| 239 | + |
| 240 | +</body> |
| 241 | +</html> |
0 commit comments