aigorithm commited on
Commit
8a46dd4
·
verified ·
1 Parent(s): 36c293d

Upload 2 files

Browse files
Files changed (2) hide show
  1. index.html +55 -41
  2. main.js +60 -22
index.html CHANGED
@@ -3,27 +3,30 @@
3
  <html lang="en">
4
  <head>
5
  <meta charset="UTF-8" />
6
- <title>AiCut Pro Style Chat Builder</title>
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
8
  <style>
9
  body {
10
  margin: 0;
11
- background: #000;
12
- color: white;
13
- font-family: sans-serif;
14
  display: flex;
15
  flex-direction: column;
16
  align-items: center;
17
  }
18
- .phone {
 
 
 
19
  width: 360px;
20
- height: 640px;
21
  background: #f0f2f5;
22
- border-radius: 32px;
 
23
  overflow-y: auto;
24
- box-shadow: 0 0 12px rgba(0,0,0,0.5);
25
- margin: 20px 0;
26
  padding: 10px;
 
27
  }
28
  .message {
29
  display: flex;
@@ -37,73 +40,84 @@
37
  border-radius: 18px;
38
  max-width: 70%;
39
  font-size: 14px;
40
- line-height: 1.4;
41
- opacity: 1;
42
  }
43
- .left .bubble { background: #e5e5ea; color: black; }
44
- .right .bubble { background: #007aff; color: white; }
 
 
 
 
 
 
45
  .avatar {
46
  width: 28px;
47
  height: 28px;
48
  border-radius: 50%;
49
  margin: 0 6px;
50
  }
51
- .timeline {
52
  width: 100%;
53
  max-width: 420px;
54
- background: #111;
 
 
55
  padding: 10px;
56
- border-radius: 8px;
57
- box-shadow: 0 0 8px rgba(255,255,255,0.1);
58
  }
59
- .msg-row {
60
- background: #1e1e1e;
61
- margin: 6px 0;
62
- padding: 8px;
63
- border-radius: 8px;
64
  display: flex;
65
  flex-direction: column;
66
- gap: 4px;
 
67
  }
68
- select, input[type="text"] {
69
- width: 100%;
70
- padding: 6px;
71
- border-radius: 4px;
72
- border: none;
73
- background: #222;
74
- color: white;
75
  }
76
  button {
77
- margin-top: 10px;
78
- padding: 8px 14px;
79
  background: #007aff;
80
  border: none;
81
  border-radius: 6px;
82
  color: white;
 
 
83
  cursor: pointer;
84
  }
85
- .toolbar {
86
  display: flex;
87
- justify-content: space-between;
 
88
  width: 100%;
89
  max-width: 420px;
 
 
 
 
 
90
  }
91
  </style>
92
  </head>
93
  <body>
94
- <h2>📱 Fake Chat Builder</h2>
95
- <div class="toolbar">
96
- <select id="styleSelect" onchange="updatePreview()">
97
  <option value="imessage">iMessage</option>
98
  <option value="whatsapp">WhatsApp</option>
99
  <option value="instagram">Instagram</option>
100
  <option value="reddit">Reddit</option>
101
  </select>
102
- <button onclick="addMessage()">+ Add Message</button>
 
 
 
103
  </div>
104
- <div class="phone" id="chatPreview"></div>
105
- <div class="timeline" id="timeline"></div>
106
- <button onclick="exportJSON()">📤 Export JSON</button>
107
  <script type="module" src="main.js"></script>
108
  </body>
109
  </html>
 
3
  <html lang="en">
4
  <head>
5
  <meta charset="UTF-8" />
6
+ <title>Fake Chat Studio - AiCut Pro</title>
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
8
  <style>
9
  body {
10
  margin: 0;
11
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
12
+ background: #f9f9f9;
13
+ color: #111;
14
  display: flex;
15
  flex-direction: column;
16
  align-items: center;
17
  }
18
+ h2 {
19
+ margin-top: 16px;
20
+ }
21
+ .chat-preview {
22
  width: 360px;
23
+ height: 600px;
24
  background: #f0f2f5;
25
+ border-radius: 24px;
26
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
27
  overflow-y: auto;
 
 
28
  padding: 10px;
29
+ margin: 12px 0;
30
  }
31
  .message {
32
  display: flex;
 
40
  border-radius: 18px;
41
  max-width: 70%;
42
  font-size: 14px;
 
 
43
  }
44
+ .left .bubble {
45
+ background: #e5e5ea;
46
+ color: black;
47
+ }
48
+ .right .bubble {
49
+ background: #007aff;
50
+ color: white;
51
+ }
52
  .avatar {
53
  width: 28px;
54
  height: 28px;
55
  border-radius: 50%;
56
  margin: 0 6px;
57
  }
58
+ .editor {
59
  width: 100%;
60
  max-width: 420px;
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: 10px;
64
  padding: 10px;
 
 
65
  }
66
+ .msg-editor {
67
+ background: #fff;
68
+ border: 1px solid #ddd;
69
+ border-radius: 12px;
70
+ padding: 12px;
71
  display: flex;
72
  flex-direction: column;
73
+ gap: 6px;
74
+ box-shadow: 0 2px 6px rgba(0,0,0,0.05);
75
  }
76
+ .msg-editor input, .msg-editor select {
77
+ padding: 8px;
78
+ font-size: 14px;
79
+ border-radius: 6px;
80
+ border: 1px solid #ccc;
 
 
81
  }
82
  button {
 
 
83
  background: #007aff;
84
  border: none;
85
  border-radius: 6px;
86
  color: white;
87
+ padding: 10px;
88
+ font-size: 14px;
89
  cursor: pointer;
90
  }
91
+ .controls {
92
  display: flex;
93
+ flex-wrap: wrap;
94
+ gap: 10px;
95
  width: 100%;
96
  max-width: 420px;
97
+ justify-content: space-between;
98
+ padding: 0 10px;
99
+ }
100
+ .controls input[type="text"] {
101
+ flex: 1;
102
  }
103
  </style>
104
  </head>
105
  <body>
106
+ <h2>📱 Fake Chat Studio</h2>
107
+ <div class="controls">
108
+ <select id="styleSelect" onchange="renderPreview()">
109
  <option value="imessage">iMessage</option>
110
  <option value="whatsapp">WhatsApp</option>
111
  <option value="instagram">Instagram</option>
112
  <option value="reddit">Reddit</option>
113
  </select>
114
+ <input type="text" id="prompt" placeholder="Generate chat: funny convo about aliens">
115
+ <button onclick="generateAI()">🤖 Generate</button>
116
+ <button onclick="addMessage()">+ Add</button>
117
+ <button onclick="renderAndExport()">🎬 Export Video</button>
118
  </div>
119
+ <div class="chat-preview" id="chatPreview"></div>
120
+ <div class="editor" id="editor"></div>
 
121
  <script type="module" src="main.js"></script>
122
  </body>
123
  </html>
main.js CHANGED
@@ -5,15 +5,17 @@ let messages = [
5
  ];
6
 
7
  const preview = document.getElementById("chatPreview");
8
- const timeline = document.getElementById("timeline");
9
  const styles = {
10
  imessage: { left: "#e5e5ea", right: "#007aff" },
11
  whatsapp: { left: "#dcf8c6", right: "#34b7f1" },
12
  instagram: { left: "#fff0f5", right: "#ffb6c1" },
13
  reddit: { left: "#f6f7f8", right: "#ccc" }
14
  };
 
 
15
 
16
- function updatePreview() {
17
  const style = document.getElementById("styleSelect").value;
18
  preview.innerHTML = "";
19
  messages.forEach(msg => {
@@ -32,43 +34,79 @@ function updatePreview() {
32
  });
33
  }
34
 
35
- function renderTimeline() {
36
- timeline.innerHTML = "";
37
  messages.forEach((msg, i) => {
38
  const row = document.createElement("div");
39
- row.className = "msg-row";
40
  row.innerHTML = `
41
- <input type="text" value="${msg.name}" placeholder="Name" onchange="messages[${i}].name = this.value" />
42
- <input type="text" value="${msg.avatar}" placeholder="Avatar URL" onchange="messages[${i}].avatar = this.value" />
43
- <select onchange="messages[${i}].voice = this.value">
44
  <option ${msg.voice==="Rachel"?"selected":""}>Rachel</option>
45
  <option ${msg.voice==="Adam"?"selected":""}>Adam</option>
46
  <option ${msg.voice==="Bella"?"selected":""}>Bella</option>
47
  </select>
48
- <select onchange="messages[${i}].side = this.value">
49
  <option value="left" ${msg.side==="left"?"selected":""}>Left</option>
50
  <option value="right" ${msg.side==="right"?"selected":""}>Right</option>
51
  </select>
52
- <input type="text" value="${msg.text}" placeholder="Message" onchange="messages[${i}].text = this.value" />
53
  `;
54
- timeline.appendChild(row);
55
  });
56
- updatePreview();
57
  }
58
 
59
  function addMessage() {
60
  messages.push({ name: "New", side: "left", avatar: "https://i.pravatar.cc/30", voice: "Rachel", text: "..." });
61
- renderTimeline();
62
  }
63
 
64
- function exportJSON() {
65
- const output = JSON.stringify(messages, null, 2);
66
- const blob = new Blob([output], { type: "application/json" });
67
- const url = URL.createObjectURL(blob);
68
- const a = document.createElement("a");
69
- a.href = url;
70
- a.download = "chat_script.json";
71
- a.click();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
 
74
- renderTimeline();
 
 
 
 
 
 
 
 
 
5
  ];
6
 
7
  const preview = document.getElementById("chatPreview");
8
+ const editor = document.getElementById("editor");
9
  const styles = {
10
  imessage: { left: "#e5e5ea", right: "#007aff" },
11
  whatsapp: { left: "#dcf8c6", right: "#34b7f1" },
12
  instagram: { left: "#fff0f5", right: "#ffb6c1" },
13
  reddit: { left: "#f6f7f8", right: "#ccc" }
14
  };
15
+ const apiKey = "sk_4e67c39c0e9cbc87462cd2643e1f4d1d9959d7d81203adc2";
16
+ const voiceIdMap = { Rachel: "21m00Tcm4TlvDq8ikWAM", Adam: "pNInz6obpgDQGcFmaJgB", Bella: "EXAVITQu4vr4xnSDxMaL" };
17
 
18
+ function renderPreview() {
19
  const style = document.getElementById("styleSelect").value;
20
  preview.innerHTML = "";
21
  messages.forEach(msg => {
 
34
  });
35
  }
36
 
37
+ function renderEditor() {
38
+ editor.innerHTML = "";
39
  messages.forEach((msg, i) => {
40
  const row = document.createElement("div");
41
+ row.className = "msg-editor";
42
  row.innerHTML = `
43
+ <input type="text" value="${msg.name}" placeholder="Name" onchange="messages[${i}].name=this.value">
44
+ <input type="text" value="${msg.avatar}" placeholder="Avatar URL" onchange="messages[${i}].avatar=this.value">
45
+ <select onchange="messages[${i}].voice=this.value">
46
  <option ${msg.voice==="Rachel"?"selected":""}>Rachel</option>
47
  <option ${msg.voice==="Adam"?"selected":""}>Adam</option>
48
  <option ${msg.voice==="Bella"?"selected":""}>Bella</option>
49
  </select>
50
+ <select onchange="messages[${i}].side=this.value">
51
  <option value="left" ${msg.side==="left"?"selected":""}>Left</option>
52
  <option value="right" ${msg.side==="right"?"selected":""}>Right</option>
53
  </select>
54
+ <input type="text" value="${msg.text}" placeholder="Message" onchange="messages[${i}].text=this.value">
55
  `;
56
+ editor.appendChild(row);
57
  });
58
+ renderPreview();
59
  }
60
 
61
  function addMessage() {
62
  messages.push({ name: "New", side: "left", avatar: "https://i.pravatar.cc/30", voice: "Rachel", text: "..." });
63
+ renderEditor();
64
  }
65
 
66
+ async function getVoiceBlob(text, voice) {
67
+ const voiceId = voiceIdMap[voice] || voiceIdMap.Rachel;
68
+ const res = await fetch("https://api.elevenlabs.io/v1/text-to-speech/" + voiceId, {
69
+ method: "POST",
70
+ headers: {
71
+ "Content-Type": "application/json",
72
+ "xi-api-key": apiKey
73
+ },
74
+ body: JSON.stringify({ text, model_id: "eleven_monolingual_v1", voice_settings: { stability: 0.5, similarity_boost: 0.75 } })
75
+ });
76
+ return await res.blob();
77
+ }
78
+
79
+ async function renderAndExport() {
80
+ renderPreview();
81
+ const stream = preview.captureStream(30);
82
+ const recorder = new MediaRecorder(stream);
83
+ const chunks = [];
84
+ recorder.ondataavailable = e => chunks.push(e.data);
85
+ recorder.onstop = () => {
86
+ const blob = new Blob(chunks, { type: "video/webm" });
87
+ const a = document.createElement("a");
88
+ a.href = URL.createObjectURL(blob);
89
+ a.download = "chat_ai_video.mp4";
90
+ a.click();
91
+ };
92
+ recorder.start();
93
+ for (const msg of messages) {
94
+ const voice = await getVoiceBlob(msg.text, msg.voice);
95
+ const audio = new Audio(URL.createObjectURL(voice));
96
+ await new Promise(res => {
97
+ audio.onended = res;
98
+ audio.play();
99
+ });
100
+ }
101
+ recorder.stop();
102
  }
103
 
104
+ async function generateAI() {
105
+ const prompt = document.getElementById("prompt").value || "funny conversation between Suren and Elon Musk";
106
+ const mock = [
107
+ { name: "Suren", side: "left", avatar: "https://i.pravatar.cc/30?img=4", voice: "Rachel", text: "Did you launch that rocket again?" },
108
+ { name: "Elon", side: "right", avatar: "https://i.pravatar.cc/30?img=8", voice: "Adam", text: "Yes... but it came back with fries." }
109
+ ];
110
+ messages = mock;
111
+ renderEditor();
112
+ }