Skip to content

Commit b130039

Browse files
authored
Reflection Learning Widget (sugarlabs#4747)
* reflection-widget * reflection widget * reflection widget * added comments * no need for indexdb * thinking animation * help string improved * add message sending on Enter key, improve error handling, and update localStorage usage * refactor: enhance bot reply handling and add Markdown to HTML conversion * fix: no trailing space * deleted reflection.css * fix: update widget description and improve logging in generateAnalysis method * enter key bug fix * feat: add developer guide for Reflection Widget * Revert "feat: add developer guide for Reflection Widget" This reverts commit b9c38a1.
1 parent 54d5cff commit b130039

File tree

9 files changed

+683
-0
lines changed

9 files changed

+683
-0
lines changed

css/activities.css

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,3 +2020,53 @@ table {
20202020
min-width: 250px;
20212021
max-width: 80%;
20222022
}
2023+
2024+
.chatInterface{
2025+
display: flex;
2026+
flex-direction: column;
2027+
height: 100%;
2028+
padding: "10px";
2029+
background-color: white;
2030+
}
2031+
2032+
.chatLog {
2033+
flex: 1;
2034+
overflow-y: auto;
2035+
border: 1px solid #ccc;
2036+
padding: 10px;
2037+
margin-bottom: 10px;
2038+
display: flex;
2039+
flex-direction: column;
2040+
}
2041+
2042+
.select-mentor {
2043+
width: 80px;
2044+
background: white;
2045+
border-width: 1px;
2046+
border-style: solid;
2047+
border-color: black;
2048+
}
2049+
2050+
.input-query {
2051+
flex: 1;
2052+
padding: 10px;
2053+
margin-right: 10px;
2054+
}
2055+
2056+
.message-container {
2057+
align-self: flex-start;
2058+
background: #dfdfdf;
2059+
color: #000;
2060+
padding: 10px;
2061+
border-radius: 12px;
2062+
max-width: 60%;
2063+
margin-bottom: 8px;
2064+
display: flex;
2065+
flex-direction: column;
2066+
word-wrap: break-word;
2067+
}
2068+
2069+
.message-container.user {
2070+
align-self: flex-end;
2071+
background-color: #DCF8C6;
2072+
}

header-icons/code.svg

Lines changed: 1 addition & 0 deletions
Loading

header-icons/general_mentor.svg

Lines changed: 1 addition & 0 deletions
Loading

header-icons/music.svg

Lines changed: 4 additions & 0 deletions
Loading

header-icons/notes_icon.svg

Lines changed: 1 addition & 0 deletions
Loading

js/activity.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ if (_THIS_IS_MUSIC_BLOCKS_) {
173173
"widgets/timbre",
174174
"widgets/oscilloscope",
175175
"widgets/sampler",
176+
"widgets/reflection",
176177
"activity/lilypond",
177178
"activity/abc",
178179
"activity/midi",
@@ -3123,6 +3124,8 @@ class Activity {
31233124
break;
31243125
}
31253126
case 13: { // 'R or ENTER'
3127+
if (this.isInputON) return;
3128+
31263129
if (this.searchWidget.style.visibility === "visible") {
31273130
return;
31283131
}

js/blocks/WidgetBlocks.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,62 @@ function setupWidgetBlocks(activity) {
16401640
}
16411641
}
16421642

1643+
1644+
class ReflectionBlock extends StackClampBlock {
1645+
/**
1646+
* Creates a ReflectionBlock instance.
1647+
*/
1648+
constructor() {
1649+
super("reflection");
1650+
this.setPalette("widgets", activity);
1651+
this.beginnerBlock(true);
1652+
1653+
this.setHelpString([
1654+
_("The Reflection block opens a space for you to think about your learning."),
1655+
null,
1656+
"reflection"
1657+
]);
1658+
1659+
this.formBlock({ name: _("reflection"), canCollapse: true });
1660+
this.makeMacro((x, y) => [
1661+
[0, "reflection", x, y, [null, 1]],
1662+
[1, "print", 0, 0, [0,2,null]],
1663+
[2, ["text",{"value":"Reflective Learning"}], 0, 0, [1]]
1664+
]);
1665+
}
1666+
1667+
/**
1668+
* Handles the flow of data for the status block.
1669+
* @param {any[]} args - The arguments passed to the block.
1670+
* @param {object} logo - The logo object.
1671+
* @param {object} turtle - The turtle object.
1672+
* @param {object} blk - The block object.
1673+
*/
1674+
flow(args, logo, turtle, blk) {
1675+
if (logo.reflection === null) {
1676+
logo.reflection = new ReflectionMatrix();
1677+
}
1678+
1679+
logo.reflection.init(activity);
1680+
logo.statusFields = [];
1681+
1682+
logo.inReflectionMatrix = true;
1683+
1684+
const listenerName = "_reflection_" + turtle;
1685+
logo.setDispatchBlock(blk, turtle, listenerName);
1686+
1687+
const __listener = () => {
1688+
logo.reflection.init(activity);
1689+
logo.inReflectionMatrix = false;
1690+
};
1691+
1692+
logo.setTurtleListener(turtle, listenerName, __listener);
1693+
1694+
if (args.length === 1) return [args[0], 1];
1695+
}
1696+
}
1697+
1698+
16431699
class AIDebugger extends StackClampBlock {
16441700
constructor() {
16451701
super("aidebugger");
@@ -1690,6 +1746,7 @@ function setupWidgetBlocks(activity) {
16901746
}
16911747
}
16921748

1749+
16931750
// Set up blocks if this is Music Blocks environment
16941751
if (_THIS_IS_MUSIC_BLOCKS_) {
16951752
new EnvelopeBlock().setup(activity);
@@ -1705,6 +1762,7 @@ function setupWidgetBlocks(activity) {
17051762
new oscilloscopeWidgetBlock().setup(activity);
17061763
new PitchSliderBlock().setup(activity);
17071764
new ChromaticBlock().setup(activity);
1765+
new ReflectionBlock().setup(activity);
17081766
// new AIMusicBlocks().setup(activity);
17091767
new MusicKeyboard2Block().setup(activity);
17101768
new MusicKeyboardBlock().setup(activity);

js/logo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class Logo {
110110
this._meSpeak = this.activity.meSpeak;
111111

112112
// Widgets
113+
this.reflection = null;
113114
this.phraseMaker = null;
114115
this.pitchDrumMatrix = null;
115116
this.arpeggio = null;

0 commit comments

Comments
 (0)