Skip to content

Commit 333c6f4

Browse files
committed
Add progress bubble
1 parent e5bdd06 commit 333c6f4

1 file changed

Lines changed: 51 additions & 1 deletion

File tree

bases/rsptx/interactives/runestone/common/js/bookfuncs.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,47 @@ function createStudyCluesWidget() {
549549
border: 1px solid #e5e7eb;
550550
}
551551
552+
.studyclues-message.studyclues-loading {
553+
color: #6b7280;
554+
font-style: italic;
555+
}
556+
557+
.studyclues-spinner {
558+
display: inline-flex;
559+
align-items: center;
560+
gap: 4px;
561+
}
562+
563+
.studyclues-spinner-dot {
564+
width: 6px;
565+
height: 6px;
566+
border-radius: 50%;
567+
background: #6b7280;
568+
opacity: 0.35;
569+
animation: studyclues-dot-pulse 1s infinite ease-in-out;
570+
}
571+
572+
.studyclues-spinner-dot:nth-child(2) {
573+
animation-delay: 0.15s;
574+
}
575+
576+
.studyclues-spinner-dot:nth-child(3) {
577+
animation-delay: 0.3s;
578+
}
579+
580+
@keyframes studyclues-dot-pulse {
581+
0%,
582+
80%,
583+
100% {
584+
opacity: 0.35;
585+
transform: scale(1);
586+
}
587+
40% {
588+
opacity: 1;
589+
transform: scale(1.2);
590+
}
591+
}
592+
552593
.studyclues-inputbar {
553594
display: flex;
554595
gap: 8px;
@@ -629,6 +670,14 @@ function createStudyCluesWidget() {
629670
inputEl.value = "";
630671
sendBtn.disabled = true;
631672

673+
const loadingBubble = document.createElement("div");
674+
loadingBubble.className =
675+
"studyclues-message assistant studyclues-loading";
676+
loadingBubble.innerHTML =
677+
'Thinking <span class="studyclues-spinner"><span class="studyclues-spinner-dot"></span><span class="studyclues-spinner-dot"></span><span class="studyclues-spinner-dot"></span></span>';
678+
messagesEl.appendChild(loadingBubble);
679+
messagesEl.scrollTop = messagesEl.scrollHeight;
680+
632681
try {
633682
const response = await fetch(
634683
`/assignment/student/studyclues_query`,
@@ -671,6 +720,7 @@ function createStudyCluesWidget() {
671720
);
672721
console.error("StudyClues chat error:", err);
673722
} finally {
723+
loadingBubble.remove();
674724
sendBtn.disabled = false;
675725
inputEl.focus();
676726
}
@@ -759,7 +809,7 @@ async function handlePageSetup() {
759809
document.dispatchEvent(new Event("runestone:login"));
760810
addReadingList();
761811
// Only show the StudyClues widget for certain base courses and when the path includes "/ns/books/".
762-
if (["csawesome2", "py4e-int", "thinkcspy", "PTXSB"].includes(eBookConfig.basecourse)
812+
if (["csawesome2", "py4e-int", "thinkcspy", "PTXSB"].includes(eBookConfig.basecourse)
763813
&& location.pathname.includes("/ns/books/")) {
764814
createStudyCluesWidget();
765815
}

0 commit comments

Comments
 (0)