gaeunseo commited on
Commit
7e7a3be
ยท
verified ยท
1 Parent(s): 7dd799a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -39
app.py CHANGED
@@ -7,56 +7,62 @@ ai_message = "Hello, how can I help you?"
7
 
8
  def stream_human_message():
9
  """
10
- Human ๋ฉ”์‹œ์ง€๋ฅผ ํ•œ ๊ธ€์ž์”ฉ ํƒ€์ดํ•‘ํ•˜๋Š” ํšจ๊ณผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋ฉด์„œ,
11
- ๊ฐ ๋ฌธ์ž์— ํด๋ฆญ ์ด๋ฒคํŠธ(handleClick)๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
12
  """
13
- js_script = """
14
- <script>
15
- if (window.cutDone === undefined) { window.cutDone = false; }
16
- function handleClick(span) {
17
- if (window.cutDone) return;
18
- window.cutDone = true;
19
- // ํด๋ฆญํ•œ span ๋ฐ”๋กœ ๋’ค์— โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜ ์‚ฝ์ž…
20
- var scissor = document.createElement('span');
21
- scissor.textContent = 'โœ‚๏ธ';
22
- span.parentNode.insertBefore(scissor, span.nextSibling);
23
- // ํด๋ฆญํ•œ ๋ฌธ์ž์˜ data-index ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์ดํ›„ ๋ฌธ์ž๋“ค์˜ ์ƒ‰์ƒ์„ ํšŒ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ
24
- var cutIndex = parseInt(span.getAttribute('data-index'));
25
- var spans = span.parentNode.querySelectorAll('span[data-index]');
26
- spans.forEach(function(s) {
27
- var idx = parseInt(s.getAttribute('data-index'));
28
- if (idx > cutIndex) {
29
- s.style.color = 'grey';
30
- }
31
- });
32
- }
33
- </script>
34
- """
35
- # Human ๋งํ’์„  ์ปจํ…Œ์ด๋„ˆ (CSS ํด๋ž˜์Šค 'speech-bubble human'๋ฅผ ์ ์šฉ)
36
- html = js_script + "<div id='human_message' class='speech-bubble human'>"
37
- yield html
38
- # ํ•œ ๊ธ€์ž์”ฉ <span> ํƒœ๊ทธ๋กœ ์ถ”๊ฐ€ (ํด๋ฆญ ์‹œ handleClick(this) ํ˜ธ์ถœ)
39
  for i, ch in enumerate(human_message):
40
- html += f"<span data-index='{i}' onclick='handleClick(this)'>{ch}</span>"
41
  yield html
42
- time.sleep(0.05) # ํƒ€์ดํ•‘ ํšจ๊ณผ ๋”œ๋ ˆ์ด (0.05์ดˆ)
43
  html += "</div>"
44
  yield html
45
 
46
  # Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
47
  with gr.Blocks() as demo:
48
- gr.Markdown("## Chat Interface")
49
- # CSS ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜์—ฌ ๋งํ’์„  ๋ชจ์–‘๊ณผ ๋ฐฐ์น˜ ์„ค์ •
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  gr.HTML(
51
  """
52
  <style>
53
- /* ์ฑ„ํŒ… ์ „์ฒด ์ปจํ…Œ์ด๋„ˆ (์„ธ๋กœ ๋ฐฐ์น˜) */
54
  .chat-container {
55
  display: flex;
56
  flex-direction: column;
57
  gap: 10px;
58
  }
59
- /* ๊ณตํ†ต ๋งํ’์„  ์Šคํƒ€์ผ */
60
  .speech-bubble {
61
  position: relative;
62
  padding: 10px 15px;
@@ -66,7 +72,6 @@ with gr.Blocks() as demo:
66
  font-size: 16px;
67
  line-height: 1.4;
68
  }
69
- /* Human ๋งํ’์„  (์˜ค๋ฅธ์ชฝ ์ •๋ ฌ, ๋งํ’์„  ๊ผฌ๋ฆฌ ์˜ค๋ฅธ์ชฝ) */
70
  .human {
71
  background: #d0f0d0;
72
  align-self: flex-end;
@@ -81,7 +86,6 @@ with gr.Blocks() as demo:
81
  border-style: solid;
82
  border-color: transparent transparent transparent #d0f0d0;
83
  }
84
- /* AI ๋งํ’์„  (์™ผ์ชฝ ์ •๋ ฌ, ๋งํ’์„  ๊ผฌ๋ฆฌ ์™ผ์ชฝ) */
85
  .ai {
86
  background: #e0e0e0;
87
  align-self: flex-start;
@@ -100,16 +104,15 @@ with gr.Blocks() as demo:
100
  """
101
  )
102
 
103
- # ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€๋“ค์ด ๋‹ด๊ธธ ์ปจํ…Œ์ด๋„ˆ (์„ธ๋กœ ๋ฐฐ์น˜)
104
  with gr.Column(elem_classes="chat-container"):
105
- # ์œ„์ชฝ์— Human ๋ฉ”์‹œ์ง€ (์ŠคํŠธ๋ฆฌ๋ฐ ์—…๋ฐ์ดํŠธ๋จ)
106
  human_bubble = gr.HTML("")
107
  # ์•„๋ž˜์ชฝ์— AI ๋ฉ”์‹œ์ง€ (๊ณ ์ •)
108
  ai_bubble = gr.HTML(f"<div id='ai_message' class='speech-bubble ai'>{ai_message}</div>")
109
 
110
  # ํƒ€์ดํ•‘ ํšจ๊ณผ๋ฅผ ์‹œ์ž‘ํ•  ๋ฒ„ํŠผ
111
  start_button = gr.Button("Start Typing")
112
- # ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜ ์‚ฌ์šฉ (stream=True ์—†์ด yield ๋ฐฉ์‹์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ)
113
  start_button.click(fn=stream_human_message, outputs=human_bubble)
114
 
115
  demo.launch()
 
7
 
8
  def stream_human_message():
9
  """
10
+ Human ๋ฉ”์‹œ์ง€๋ฅผ ํ•œ ๊ธ€์ž์”ฉ ํƒ€์ดํ•‘ ํšจ๊ณผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
11
+ ๊ฐ ๋ฌธ์ž๋Š” <span> ํƒœ๊ทธ๋กœ ์ƒ์„ฑ๋˜๋ฉฐ, ํด๋ฆญ ์‹œ ํ›„์† ๋™์ž‘์€ ํŽ˜์ด์ง€ ์ƒ๋‹จ์— ๋ฏธ๋ฆฌ ๋กœ๋“œํ•œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
12
  """
13
+ html = "<div id='human_message' class='speech-bubble human'>"
14
+ yield html # ์ดˆ๊ธฐ ์ปจํ…Œ์ด๋„ˆ๋งŒ ์ถœ๋ ฅ
15
+ # ํ•œ ๊ธ€์ž์”ฉ ์ถ”๊ฐ€
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  for i, ch in enumerate(human_message):
17
+ html += f"<span data-index='{i}'>{ch}</span>"
18
  yield html
19
+ time.sleep(0.05)
20
  html += "</div>"
21
  yield html
22
 
23
  # Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
24
  with gr.Blocks() as demo:
25
+ # ํŽ˜์ด์ง€ ์ƒ๋‹จ์— ํ•œ ๋ฒˆ๋งŒ ๋กœ๋“œํ•  ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€ (์ด๋ฒคํŠธ ์œ„์ž„ ๋ฐฉ์‹ ์‚ฌ์šฉ)
26
+ gr.HTML(
27
+ """
28
+ <script>
29
+ // ์ „์—ญ ํ”Œ๋ž˜๊ทธ: ํ•œ ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌํ•˜๋„๋ก
30
+ window.cutDone = false;
31
+ // ๋ถ€๋ชจ ์ปจํ…Œ์ด๋„ˆ์— ์ด๋ฒคํŠธ ์œ„์ž„์œผ๋กœ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
32
+ document.addEventListener("click", function(event) {
33
+ if (window.cutDone) return; // ์ด๋ฏธ ์ฒ˜๋ฆฌํ•œ ๊ฒฝ์šฐ
34
+ // ํด๋ฆญํ•œ ์š”์†Œ๊ฐ€ data-index ์†์„ฑ์„ ๊ฐ€์ง„ span ์ธ์ง€ ํ™•์ธ
35
+ if (event.target && event.target.matches("span[data-index]")) {
36
+ var span = event.target;
37
+ window.cutDone = true;
38
+ // ํด๋ฆญํ•œ span ๋ฐ”๋กœ ๋’ค์— โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜ ์‚ฝ์ž…
39
+ var scissor = document.createElement('span');
40
+ scissor.textContent = 'โœ‚๏ธ';
41
+ span.parentNode.insertBefore(scissor, span.nextSibling);
42
+ // ํด๋ฆญํ•œ ๋ฌธ์ž์˜ data-index ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์ดํ›„ ๋ฌธ์ž๋“ค์˜ ์ƒ‰์ƒ์„ ํšŒ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ
43
+ var cutIndex = parseInt(span.getAttribute('data-index'));
44
+ var spans = span.parentNode.querySelectorAll('span[data-index]');
45
+ spans.forEach(function(s) {
46
+ var idx = parseInt(s.getAttribute('data-index'));
47
+ if (idx > cutIndex) {
48
+ s.style.color = 'grey';
49
+ }
50
+ });
51
+ }
52
+ });
53
+ </script>
54
+ """
55
+ )
56
+
57
+ # CSS ์Šคํƒ€์ผ ์ ์šฉ (๋งํ’์„  ๋ชจ์–‘ ๋ฐ ๋ฐฐ์น˜)
58
  gr.HTML(
59
  """
60
  <style>
 
61
  .chat-container {
62
  display: flex;
63
  flex-direction: column;
64
  gap: 10px;
65
  }
 
66
  .speech-bubble {
67
  position: relative;
68
  padding: 10px 15px;
 
72
  font-size: 16px;
73
  line-height: 1.4;
74
  }
 
75
  .human {
76
  background: #d0f0d0;
77
  align-self: flex-end;
 
86
  border-style: solid;
87
  border-color: transparent transparent transparent #d0f0d0;
88
  }
 
89
  .ai {
90
  background: #e0e0e0;
91
  align-self: flex-start;
 
104
  """
105
  )
106
 
107
+ gr.Markdown("## Chat Interface")
108
  with gr.Column(elem_classes="chat-container"):
109
+ # ์œ„์ชฝ์— Human ๋ฉ”์‹œ์ง€ (์ŠคํŠธ๋ฆฌ๋ฐ ์—…๋ฐ์ดํŠธ)
110
  human_bubble = gr.HTML("")
111
  # ์•„๋ž˜์ชฝ์— AI ๋ฉ”์‹œ์ง€ (๊ณ ์ •)
112
  ai_bubble = gr.HTML(f"<div id='ai_message' class='speech-bubble ai'>{ai_message}</div>")
113
 
114
  # ํƒ€์ดํ•‘ ํšจ๊ณผ๋ฅผ ์‹œ์ž‘ํ•  ๋ฒ„ํŠผ
115
  start_button = gr.Button("Start Typing")
 
116
  start_button.click(fn=stream_human_message, outputs=human_bubble)
117
 
118
  demo.launch()