TheHickman commited on
Commit
5ef7f7e
·
verified ·
1 Parent(s): fe5d643

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -28
app.py CHANGED
@@ -7,10 +7,10 @@ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
7
  # ---- GPT explanation backend ----
8
  def explain_text(selected_text):
9
  if selected_text is None:
10
- return ""
11
  selected_text = selected_text.strip()
12
  if not selected_text:
13
- return "Please select or enter some text first."
14
 
15
  try:
16
  response = client.chat.completions.create(
@@ -28,9 +28,11 @@ def explain_text(selected_text):
28
  temperature=0.7,
29
  max_tokens=500
30
  )
31
- return response.choices[0].message.content
 
 
32
  except Exception as e:
33
- return f"Error: {str(e)}"
34
 
35
 
36
  # ---- Your work content (UNCHANGED) ----
@@ -53,7 +55,7 @@ YOUR_WORK_HTML = """
53
  """
54
 
55
 
56
- # ---- Hugging Face reference content (FULL ORIGINAL TEXT RESTORED) ----
57
  HF_REFERENCE_HTML = """
58
  <div id="hf-content" style="max-width: 800px; margin: auto; font-size: 16px; line-height: 1.6;">
59
  <h1>Text Generation (Hugging Face Reference)</h1>
@@ -163,30 +165,59 @@ def switch_content(choice):
163
  return HF_REFERENCE_HTML
164
 
165
 
166
- with gr.Blocks(
167
- head="""
 
 
 
168
  <script>
169
- document.addEventListener("mouseup", function () {
170
- const selection = window.getSelection().toString().trim();
171
- if (selection.length > 0) {
172
- const textboxContainer = document.querySelector('[aria-label="Selected text"]');
173
- if (textboxContainer) {
174
- const textarea = textboxContainer.querySelector("textarea");
175
- if (textarea) {
176
- const nativeSetter = Object.getOwnPropertyDescriptor(
177
- window.HTMLTextAreaElement.prototype,
178
- "value"
179
- ).set;
180
- nativeSetter.call(textarea, selection);
181
- textarea.dispatchEvent(new Event("input", { bubbles: true }));
 
 
 
 
 
 
 
 
 
 
 
182
  }
183
  }
 
184
  }
185
- });
 
 
 
 
 
 
 
 
 
 
 
 
186
  </script>
187
  """
188
- ) as demo:
189
- gr.Markdown("### 📘 Highlight text and ask GPT for help")
 
 
190
 
191
  view_toggle = gr.Radio(
192
  choices=["My Work", "HF Reference"],
@@ -204,17 +235,20 @@ document.addEventListener("mouseup", function () {
204
 
205
  selected_text = gr.Textbox(
206
  label="Selected text",
207
- placeholder="Highlight text above...",
208
  lines=3
209
  )
210
 
211
- explain_btn = gr.Button("Explain selection 🧠")
212
- output = gr.Markdown()
213
-
 
 
 
214
  explain_btn.click(
215
  fn=explain_text,
216
  inputs=selected_text,
217
- outputs=output,
218
  )
219
 
220
  demo.launch()
 
7
  # ---- GPT explanation backend ----
8
  def explain_text(selected_text):
9
  if selected_text is None:
10
+ return "", ""
11
  selected_text = selected_text.strip()
12
  if not selected_text:
13
+ return "Please select or enter some text first.", selected_text
14
 
15
  try:
16
  response = client.chat.completions.create(
 
28
  temperature=0.7,
29
  max_tokens=500
30
  )
31
+ explanation = response.choices[0].message.content
32
+ # Replace the selected text box with the AI explanation
33
+ return explanation, explanation
34
  except Exception as e:
35
+ return f"Error: {str(e)}", selected_text
36
 
37
 
38
  # ---- Your work content (UNCHANGED) ----
 
55
  """
56
 
57
 
58
+ # ---- Hugging Face reference content ----
59
  HF_REFERENCE_HTML = """
60
  <div id="hf-content" style="max-width: 800px; margin: auto; font-size: 16px; line-height: 1.6;">
61
  <h1>Text Generation (Hugging Face Reference)</h1>
 
165
  return HF_REFERENCE_HTML
166
 
167
 
168
+ # This JS uses a more reliable approach:
169
+ # 1. Listens for mouseup on the whole document
170
+ # 2. Finds the Gradio textbox by its data-testid or label, then dispatches
171
+ # a proper React-compatible input event so Gradio picks up the value change.
172
+ SELECTION_JS = """
173
  <script>
174
+ (function() {
175
+ function setGradioTextbox(value) {
176
+ // Find the textarea inside the component labelled "Selected text"
177
+ const labels = document.querySelectorAll('label span');
178
+ for (const label of labels) {
179
+ if (label.textContent.trim() === 'Selected text') {
180
+ const container = label.closest('label') || label.parentElement;
181
+ // Walk up to find the wrapping block, then find textarea
182
+ let el = container;
183
+ for (let i = 0; i < 5; i++) {
184
+ el = el.parentElement;
185
+ if (!el) break;
186
+ const ta = el.querySelector('textarea');
187
+ if (ta) {
188
+ // Use React's native value setter to trigger onChange
189
+ const nativeSetter = Object.getOwnPropertyDescriptor(
190
+ window.HTMLTextAreaElement.prototype, 'value'
191
+ ).set;
192
+ nativeSetter.call(ta, value);
193
+ ta.dispatchEvent(new Event('input', { bubbles: true }));
194
+ ta.dispatchEvent(new Event('change', { bubbles: true }));
195
+ return true;
196
+ }
197
+ }
198
  }
199
  }
200
+ return false;
201
  }
202
+
203
+ document.addEventListener('mouseup', function () {
204
+ // Small delay to let the browser finalize the selection
205
+ setTimeout(function () {
206
+ const selection = window.getSelection();
207
+ if (!selection) return;
208
+ const text = selection.toString().trim();
209
+ if (text.length > 0) {
210
+ setGradioTextbox(text);
211
+ }
212
+ }, 50);
213
+ });
214
+ })();
215
  </script>
216
  """
217
+
218
+
219
+ with gr.Blocks(head=SELECTION_JS) as demo:
220
+ gr.Markdown("### 📘 Highlight text above and click **Explain selection** to get an AI explanation")
221
 
222
  view_toggle = gr.Radio(
223
  choices=["My Work", "HF Reference"],
 
235
 
236
  selected_text = gr.Textbox(
237
  label="Selected text",
238
+ placeholder="Highlight text above to populate this box, then click Explain...",
239
  lines=3
240
  )
241
 
242
+ explain_btn = gr.Button("Explain selection 🧠", variant="primary")
243
+
244
+ # The explanation replaces the content of the selected_text box
245
+ # so the user sees the AI output right where the selection was shown.
246
+ output = gr.Markdown(label="Explanation")
247
+
248
  explain_btn.click(
249
  fn=explain_text,
250
  inputs=selected_text,
251
+ outputs=[output, selected_text],
252
  )
253
 
254
  demo.launch()