SarahXia0405 commited on
Commit
bcb26ab
·
verified ·
1 Parent(s): 6f29c38

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -92
app.py CHANGED
@@ -28,8 +28,9 @@ from rag_engine import (
28
  from syllabus_utils import extract_course_topics_from_file
29
 
30
  # ================== Assets ==================
 
31
  HANBRIDGE_LOGO_PATH = "hanbridge_logo.png"
32
- CLARE_LOGO_PATH = "clare_mascot.png"
33
  CLARE_RUN_PATH = "Clare_Run.png"
34
 
35
  # ================== Base64 Helper ==================
@@ -60,7 +61,7 @@ USER_GUIDE_SECTIONS = {
60
  "faq": "## FAQ\n\n**Q: Does Clare give assignment answers?** No..."
61
  }
62
 
63
- # ================== CSS (Trademark Style) ==================
64
  CUSTOM_CSS = """
65
  /* Header */
66
  .header-container {
@@ -72,47 +73,6 @@ CUSTOM_CSS = """
72
  /* User Guide Accordion */
73
  .user-guide-item { margin-bottom: 5px; }
74
 
75
- /* === Trademark Style Question Mark Buttons === */
76
- .tm-help-btn {
77
- display: inline-block !important;
78
- background: transparent !important;
79
- border: none !important;
80
- box-shadow: none !important;
81
- padding: 0 !important;
82
- color: #9ca3af !important; /* Light Grey */
83
- font-size: 14px !important; /* Small font */
84
- line-height: 1 !important;
85
- min-width: auto !important;
86
- width: 20px !important;
87
- height: 20px !important;
88
- margin-top: -8px !important; /* Lift up like superscript */
89
- margin-left: 0px !important;
90
- cursor: pointer !important;
91
- vertical-align: top !important;
92
- z-index: 10;
93
- }
94
- .tm-help-btn:hover {
95
- color: #4b5563 !important; /* Darker grey on hover */
96
- transform: scale(1.1);
97
- }
98
-
99
- /* Container to hold Text + TM-Button tightly */
100
- .label-row {
101
- display: flex !important;
102
- align-items: center !important;
103
- gap: 0px !important; /* No gap between text and ? */
104
- margin-bottom: 5px !important;
105
- width: fit-content !important;
106
- }
107
-
108
- /* Remove default Markdown margins for tight layout */
109
- .tight-label p {
110
- margin: 0 !important;
111
- font-weight: bold;
112
- font-size: 1rem;
113
- line-height: 1.2;
114
- }
115
-
116
  /* Memory Line Box */
117
  .memory-line-box {
118
  border: 1px solid #e5e7eb; padding: 12px; border-radius: 8px;
@@ -120,12 +80,69 @@ CUSTOM_CSS = """
120
  display: flex; flex-direction: column; justify-content: space-between;
121
  }
122
 
123
- /* Action Buttons Row */
124
- .action-row {
125
- display: flex !important;
126
- align-items: center !important;
127
- margin-bottom: 5px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  """
130
 
131
  # ================== Gradio App ==================
@@ -145,7 +162,7 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
145
  <div style="display:flex; align-items:center; gap: 20px;">
146
  <img src="{image_to_base64(CLARE_LOGO_PATH)}" style="height: 75px; object-fit: contain;">
147
  <div style="display:flex; flex-direction:column;">
148
- <div style="font-size: 34px; font-weight: 800; line-height: 1.1; color: #000;">
149
  Clare
150
  <span style="font-size: 18px; font-weight: 600; margin-left: 10px;">Your Personalized AI Tutor</span>
151
  </div>
@@ -176,22 +193,16 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
176
  model_name = gr.Textbox(label="Model", value=DEFAULT_MODEL, lines=1)
177
  language_preference = gr.Radio(choices=["Auto", "English", "简体中文"], value="Auto", label="Language")
178
 
179
- # Learning Mode Title + Trademark (?)
180
- with gr.Row(elem_classes="label-row"):
181
- gr.Markdown("Learning Mode", elem_classes="tight-label")
182
- mode_help_btn = gr.Button("?", elem_classes="tm-help-btn")
183
-
184
  learning_mode = gr.Radio(
185
  choices=LEARNING_MODES,
186
  value="Concept Explainer",
187
- label=None,
188
- show_label=False,
189
- info="Select style"
190
  )
191
 
192
  # User Guide Accordion
193
  with gr.Accordion("User Guide", open=True):
194
- # Using lambda to defer content loading isn't necessary here, simple strings work
195
  with gr.Accordion("Getting Started", open=False, elem_classes="user-guide-item"):
196
  gr.Markdown(USER_GUIDE_SECTIONS["getting_started"])
197
  with gr.Accordion("Mode Definition", open=False, elem_classes="user-guide-item"):
@@ -224,36 +235,32 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
224
  with gr.Row():
225
  # Upload
226
  with gr.Column(scale=1):
227
- with gr.Row(elem_classes="label-row"):
228
- gr.Markdown("Upload Course File", elem_classes="tight-label")
229
- file_help_btn = gr.Button("?", elem_classes="tm-help-btn") # Added help here too for consistency
230
-
231
- syllabus_file = gr.File(file_types=[".docx", ".pdf", ".pptx"], file_count="single", height=100, show_label=False)
232
  doc_type = gr.Dropdown(choices=DOC_TYPES, value="Syllabus", label="File type", container=False)
233
 
234
  # Memory Line
235
  with gr.Column(scale=1):
236
  with gr.Group(elem_classes="memory-line-box"):
237
- # Title Row (TM Style)
238
- with gr.Row(elem_classes="label-row"):
239
- gr.Markdown("Memory Line", elem_classes="tight-label")
240
- ml_help_btn = gr.Button("?", elem_classes="tm-help-btn")
241
-
242
- # Progress Bar HTML
243
  gr.HTML(
244
  f"""
 
 
 
 
245
  <div style="position: relative; height: 35px; margin-top: 10px; margin-bottom: 5px;">
246
  <div style="position: absolute; bottom: 5px; left: 0; width: 100%; height: 8px; background-color: #e5e7eb; border-radius: 4px;"></div>
247
  <div style="position: absolute; bottom: 5px; left: 0; width: 40%; height: 8px; background-color: #8B1A1A; border-radius: 4px 0 0 4px;"></div>
248
  <img src="{image_to_base64(CLARE_RUN_PATH)}" style="position: absolute; left: 36%; bottom: 8px; height: 35px; z-index: 10;">
249
  </div>
 
250
  <div style="display:flex; justify-content:space-between; align-items:center;">
251
  <div style="font-size: 12px; color: #666;">Next Review: T+7</div>
252
  <div style="font-size: 12px; color: #004a99; text-decoration:underline; cursor:pointer;">Report ⬇️</div>
253
  </div>
254
  """
255
  )
256
- # Review Button (Inside the box)
257
  review_btn = gr.Button("Review Now", size="sm", variant="primary")
258
  session_status = gr.Markdown(visible=False)
259
 
@@ -273,34 +280,16 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
273
  with gr.Column(scale=1, min_width=180):
274
  gr.Markdown("### Actions")
275
 
276
- # Action: Export
277
- with gr.Row(elem_classes="action-row", variant="compact"):
278
- export_btn = gr.Button("Export Conversation", size="sm", scale=10)
279
- export_help_btn = gr.Button("?", elem_classes="tm-help-btn", scale=1) # The TM button
280
-
281
- # Action: Quiz
282
- with gr.Row(elem_classes="action-row", variant="compact"):
283
- quiz_btn = gr.Button("Let's Try (Micro-Quiz)", size="sm", scale=10)
284
- quiz_help_btn = gr.Button("?", elem_classes="tm-help-btn", scale=1)
285
-
286
- # Action: Summary
287
- with gr.Row(elem_classes="action-row", variant="compact"):
288
- summary_btn = gr.Button("Summarization", size="sm", scale=10)
289
- summary_help_btn = gr.Button("?", elem_classes="tm-help-btn", scale=1)
290
 
291
  gr.Markdown("### Results")
292
  result_display = gr.Textbox(label="Generated Content", lines=15, placeholder="Results...", show_label=False)
293
 
294
  # ================== Logic Bindings ==================
295
- # Help Buttons (Pop-ups)
296
- mode_help_btn.click(lambda: gr.Info(USER_GUIDE_SECTIONS["mode_definition"], title="Mode Definition"))
297
- file_help_btn.click(lambda: gr.Info(USER_GUIDE_SECTIONS["how_files"], title="How Files Work"))
298
- ml_help_btn.click(lambda: gr.Info(USER_GUIDE_SECTIONS["memory_line"], title="Memory Line"))
299
- export_help_btn.click(lambda: gr.Info(USER_GUIDE_SECTIONS["export_conversation"], title="Export"))
300
- quiz_help_btn.click(lambda: gr.Info(USER_GUIDE_SECTIONS["micro_quiz"], title="Micro-Quiz"))
301
- summary_help_btn.click(lambda: gr.Info(USER_GUIDE_SECTIONS["summarization"], title="Summarization"))
302
 
303
- # Core Logic
304
  def update_course_and_rag(file, doc_type_val):
305
  topics = extract_course_topics_from_file(file, doc_type_val)
306
  rag_chunks = build_rag_chunks_from_file(file, doc_type_val)
 
28
  from syllabus_utils import extract_course_topics_from_file
29
 
30
  # ================== Assets ==================
31
+ # 根据你的截图文件名配置
32
  HANBRIDGE_LOGO_PATH = "hanbridge_logo.png"
33
+ CLARE_LOGO_PATH = "clare_mascot.png"
34
  CLARE_RUN_PATH = "Clare_Run.png"
35
 
36
  # ================== Base64 Helper ==================
 
61
  "faq": "## FAQ\n\n**Q: Does Clare give assignment answers?** No..."
62
  }
63
 
64
+ # ================== CSS (悬停提示 Tooltip 样式) ==================
65
  CUSTOM_CSS = """
66
  /* Header */
67
  .header-container {
 
73
  /* User Guide Accordion */
74
  .user-guide-item { margin-bottom: 5px; }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  /* Memory Line Box */
77
  .memory-line-box {
78
  border: 1px solid #e5e7eb; padding: 12px; border-radius: 8px;
 
80
  display: flex; flex-direction: column; justify-content: space-between;
81
  }
82
 
83
+ /* === CSS Tooltip Logic (纯 CSS 实现悬停提示) ===
84
+ 应用于 Buttons (.action-btn) 和 HTML 元素 (.html-tooltip)
85
+ */
86
+
87
+ /* 1. 针对 Gradio 按钮的 Tooltip */
88
+ .action-btn {
89
+ position: relative;
90
+ overflow: visible !important; /* 允许提示框超出按钮边界 */
91
+ }
92
+ .action-btn:hover::before {
93
+ content: "See User Guide for details"; /* 提示文字 */
94
+ position: absolute;
95
+ bottom: 110%; /* 显示在按钮上方 */
96
+ left: 50%;
97
+ transform: translateX(-50%);
98
+ background-color: #333;
99
+ color: #fff;
100
+ padding: 5px 10px;
101
+ border-radius: 5px;
102
+ font-size: 12px;
103
+ white-space: nowrap;
104
+ z-index: 1000;
105
+ pointer-events: none;
106
+ box-shadow: 0 2px 5px rgba(0,0,0,0.2);
107
+ opacity: 0;
108
+ animation: fadeIn 0.2s forwards;
109
+ }
110
+ /* 小三角箭头 */
111
+ .action-btn:hover::after {
112
+ content: "";
113
+ position: absolute;
114
+ bottom: 100%;
115
+ left: 50%;
116
+ margin-left: -5px;
117
+ border-width: 5px;
118
+ border-style: solid;
119
+ border-color: #333 transparent transparent transparent;
120
+ opacity: 0;
121
+ animation: fadeIn 0.2s forwards;
122
+ }
123
+
124
+ /* 2. 针对 HTML 文本的 Tooltip (Memory Line Title) */
125
+ .html-tooltip {
126
+ border-bottom: 1px dashed #999; /* 虚线表示可悬停 */
127
+ cursor: help;
128
+ position: relative;
129
  }
130
+ .html-tooltip:hover::before {
131
+ content: attr(data-tooltip);
132
+ position: absolute;
133
+ bottom: 120%;
134
+ left: 0;
135
+ background-color: #333;
136
+ color: #fff;
137
+ padding: 5px 8px;
138
+ border-radius: 4px;
139
+ font-size: 11px;
140
+ white-space: nowrap;
141
+ z-index: 100;
142
+ pointer-events: none;
143
+ }
144
+
145
+ @keyframes fadeIn { to { opacity: 1; } }
146
  """
147
 
148
  # ================== Gradio App ==================
 
162
  <div style="display:flex; align-items:center; gap: 20px;">
163
  <img src="{image_to_base64(CLARE_LOGO_PATH)}" style="height: 75px; object-fit: contain;">
164
  <div style="display:flex; flex-direction:column;">
165
+ <div style="font-size: 32px; font-weight: 800; line-height: 1.1; color: #000;">
166
  Clare
167
  <span style="font-size: 18px; font-weight: 600; margin-left: 10px;">Your Personalized AI Tutor</span>
168
  </div>
 
193
  model_name = gr.Textbox(label="Model", value=DEFAULT_MODEL, lines=1)
194
  language_preference = gr.Radio(choices=["Auto", "English", "简体中文"], value="Auto", label="Language")
195
 
196
+ # Learning Mode (Use `info` for built-in hint)
 
 
 
 
197
  learning_mode = gr.Radio(
198
  choices=LEARNING_MODES,
199
  value="Concept Explainer",
200
+ label="Learning Mode",
201
+ info="See User Guide for mode definitions details."
 
202
  )
203
 
204
  # User Guide Accordion
205
  with gr.Accordion("User Guide", open=True):
 
206
  with gr.Accordion("Getting Started", open=False, elem_classes="user-guide-item"):
207
  gr.Markdown(USER_GUIDE_SECTIONS["getting_started"])
208
  with gr.Accordion("Mode Definition", open=False, elem_classes="user-guide-item"):
 
235
  with gr.Row():
236
  # Upload
237
  with gr.Column(scale=1):
238
+ syllabus_file = gr.File(file_types=[".docx", ".pdf", ".pptx"], file_count="single", height=100, label="Upload File")
 
 
 
 
239
  doc_type = gr.Dropdown(choices=DOC_TYPES, value="Syllabus", label="File type", container=False)
240
 
241
  # Memory Line
242
  with gr.Column(scale=1):
243
  with gr.Group(elem_classes="memory-line-box"):
244
+ # 使用 HTML class 实现悬停提示
 
 
 
 
 
245
  gr.HTML(
246
  f"""
247
+ <div style="font-weight:bold; font-size:14px; margin-bottom:5px;">
248
+ <span class="html-tooltip" data-tooltip="See User Guide for explanation">Memory Line</span>
249
+ </div>
250
+
251
  <div style="position: relative; height: 35px; margin-top: 10px; margin-bottom: 5px;">
252
  <div style="position: absolute; bottom: 5px; left: 0; width: 100%; height: 8px; background-color: #e5e7eb; border-radius: 4px;"></div>
253
  <div style="position: absolute; bottom: 5px; left: 0; width: 40%; height: 8px; background-color: #8B1A1A; border-radius: 4px 0 0 4px;"></div>
254
  <img src="{image_to_base64(CLARE_RUN_PATH)}" style="position: absolute; left: 36%; bottom: 8px; height: 35px; z-index: 10;">
255
  </div>
256
+
257
  <div style="display:flex; justify-content:space-between; align-items:center;">
258
  <div style="font-size: 12px; color: #666;">Next Review: T+7</div>
259
  <div style="font-size: 12px; color: #004a99; text-decoration:underline; cursor:pointer;">Report ⬇️</div>
260
  </div>
261
  """
262
  )
263
+ # Review Button
264
  review_btn = gr.Button("Review Now", size="sm", variant="primary")
265
  session_status = gr.Markdown(visible=False)
266
 
 
280
  with gr.Column(scale=1, min_width=180):
281
  gr.Markdown("### Actions")
282
 
283
+ # Action Buttons: 使用 elem_classes="action-btn" 来激活 CSS Tooltip
284
+ export_btn = gr.Button("Export Conversation", size="sm", elem_classes="action-btn")
285
+ quiz_btn = gr.Button("Let's Try (Micro-Quiz)", size="sm", elem_classes="action-btn")
286
+ summary_btn = gr.Button("Summarization", size="sm", elem_classes="action-btn")
 
 
 
 
 
 
 
 
 
 
287
 
288
  gr.Markdown("### Results")
289
  result_display = gr.Textbox(label="Generated Content", lines=15, placeholder="Results...", show_label=False)
290
 
291
  # ================== Logic Bindings ==================
 
 
 
 
 
 
 
292
 
 
293
  def update_course_and_rag(file, doc_type_val):
294
  topics = extract_course_topics_from_file(file, doc_type_val)
295
  rag_chunks = build_rag_chunks_from_file(file, doc_type_val)