Skip to content

Latest commit

 

History

History
3116 lines (2038 loc) · 99.5 KB

DOCS.md

File metadata and controls

3116 lines (2038 loc) · 99.5 KB

Classes

AuthForm

AuthForm is a wrapper component that switches between LoginForm and Signup Form It can be primed with a default via the initialMode prop.

Browser

Browser is a drop-down menu embedded in Nav that lets the user jump to any level or island that they have beaten in the past

Checkpoint

Checkpoint is a one-time pop-up that asks the user to fill in his or her school/location Originally intended to be a more generic "Checkpoint" system that would support arbitrary banners/messages, it is currently only used for gathering school info

CodeBlockCard

CodeBlockCards appear throughout the site as a way of previewing a student's codeblock It contains both the small clickable card with preview image AND the dialog box that pops up over the page and shows the full screen code editor.

CodeBlockEditor

CodeBlockEditor is the popover that comes up for the final test of an island. It is mostly a wrapper around CodeEditor that provides the student with the test prompt, cheat sheet, and db routes to save their progress when they pass the test

CodeBlockList

CodeBlockList is used by Projects to display codeblocks to draw inspiration from.

CodeEditor

CodeEditor is a two-panel rendering component for student code. It uses AceEditor for the student panel (left), and a remote rendering iframe for the page preview (right).

DrawerValidation

The CodeEditor is responsible for handling violation of the rules set out for a given programming challenge. A list of errors is passed in as a prop - this component is responsible for creating a readable sentence form of what is wrong with the student's code. For example, "Your HTML code is missing an

tag". The format of this language is stored in the database as "Your {{p1}} is missing {{p2}}." (Note that this need be translated by lang)

CollabList

Provides a list of Collaborators for a project provided by props.

CollabSearch

Popover window so that project owners can find and add new users to collaborate on a given project

Comment

Comments belong to Threads. Note that there is no text editor here - all posting is handled by Thread.jsx. This component is for displaying only.

ContestSignup

Signup page for (currently postponed) project contest. Signing up simply enters the user in the contest, users still must go to the ContestSubmit page to select a project and finalize the procedure.

ContestSubmit

User selects a project for the contest and submits their entry.

CTA

Call To Action Component, encourage users to sign up after visiting SEO-enable page

Discussion

Discussion Board wraps a list of threads (which in turn hosts a list of comments). Discussion boards currently only apply to slides, but they are designed to be able to apply to anything (projects, codeblocks, etc)

IslandLink

IslandLink is the zoomed-out picture of the island used in the overworld map, lesson plan, etc

Loading

Loading is explicitly used by CANON itself for any page that has canon "needs", which is why this is a full container page with . The LoadingSpinner component was separated out for embedded use (no clouds)

LoadingSpinner

Loading spinner for a huge number of components in Codelife, mostly used in render cycles while waiting for axios to return with data

LoginForm

Works alongside SignUpForm to log users in. Essentially a wrapper for the canon "login" action

Nav

Nav Component is the header of the page - containing login controls and the Island Browser

PasswordReset

Wrapper Component for the reset password dispatch action of canon

ProjectCard

ProjectCard, similar to CodeBlockCard, is a small visual container with a Dialog popover to showcase projects. It is used on the Homepage as well as in User Profiles to list their projects

ReportBox

ReportBox is a reusable component for reporting threads, comments, projects, and codeblocks for inappropriate content. As with many data structures in codelife, it uses a SINGLE reports table, with a "type" column that designates which table the report_id refers to.

Search

The Search component is embedded in Nav and is used to search users and projects. It utilizes postgres trigrams serverside (see readme)

SelectGeo

Component for selecting a location from a database of geo codes in Brazil

SelectSchool

Component for choosing a school from a db of school ids and geos - meant to be used in conjunction with SelectGeo

ShareDirectLink

Popover Component for sharing a link to a students project/codeblock. Copies url to clipboard.

ShareFacebookLink

Component for sharing facebook links. Due to the fact that xvfb screenshots require a few seconds to render, this component receives a "screenshotReady" prop from the embedding component, which waits a few seconds to ensure that Facebook's FIRST capture of the page has the finished screenshot

SignupForm

Sister component to AuthForm, this component wraps the Canon "signup" action and does appropriate error checking

InputCode

InputCode is a slide type that requires the student to complete a coding test The CodeEditor component is embedded with a series of rules, and the slide will not unblock until the student submits a passing code section. It is mostly a wrapper for CodeEditor, with some controls to execute controls or unblock a slide.

Quiz

Quiz is a blocking multiple-choice question, powered by the quizjson column in the slides db

RenderCode

RenderCode is similar to InputCode, but the CodeEditor is in readonly mode For showing code examples with explanations.

TextImage

TextImage is text left, image right. Images are stored in /slide_images/{id}.jpg Images are uploaded through the CMS and a translated version is chosen here via locales

Thread

A thread is the top-level child of a Discussion. Discussions have many threads, threads have many comments.

UserCard

UserCard is a component used on a profile page to display other users that share the logged in user's school or location

About

About page - contains translated about text and a simple photoslide component from Datawheel's first visit to Minas

Contest

Contest Component handles the (currently postponed) contest, including all the steps and checks to ensure eligibility. Page is public-facing (doesn't require login) to gain attention - the first step is creating an account

Glossary

The Glossary component retrieves words It is worth noting that the storage of glossary words is somewhat split-brained. Here in Glossary.jsx, canon's "need" functionality is used to ensure that words are rendered server-side and therefore indexable by search engines. However, glossary words used to live in the Redux Store (and in QuillWrapper, this is still how they are loaded). Both places use the same API endpoint - but one uses canon needs, the other puts the data into redux in App.jsx's mount method.

Home

Homepage component - mostly a wrapper for other smaller components (cards, features, etc)

Level

Main Level-viewing component (e.g., Jungle Island). It shows a list of the levels available as well as the ending codeblock test. Codeblocks by other users are listed underneath the island

Island

Displays all available islands

Leaderboard

Leaderboard is a sortable table that lists users by their in-game progress.

LearnMore

Simple partners page to link to other online coding projects

LessonPlan

A public-facing listing of all slides and quizzes, to be used by teachers as a lesson plan, students as a reference guide, and to aid in directing users to the site via search engines. Lesson plan uses Canon's "Needs" to render the page serverside, so that the page is indexable by SEO bots

Profile

Class component for a user profile. This is a public page and meant to be shared. If a user is logged in AND this is their profile, show an edit button allowing them to edit it.

UserCodeBlocks

Class component for displaying lists of user's snippets. This is shown on the public profile for a user and requires sending 1 prop: a ref to the user

UserProjects

Class component for displaying lists of user's projects. This is shown on the public profile for a user and requires sending 1 prop: a ref to the user

UsersList

Class component for displaying lists of user's snippets. This is shown on the public profile for a user and requires sending 1 prop: a ref to the user

Projects

Projects is one of the largest Pages in codelife - It is responsible for all CRUD operations of projects, processing screenshots, and listing user codeblocks for inspiration. Longer term, this should be refactored into smaller components.

ResetPw

Very small wrapper class for PasswordReset Component

Share

The Share Page is a top-level page that does not require login, enabling users to share their projects or codeblocks on facebook or with others. It looks up the content via name/user and renders a fullscreen codeeditor for display, essentially acting as a hosting page for the students' work. Show a Report bar on the bottom for logged in users to report inappropriate content

Slide

The slide component is the wrapper for all the various slidetypes in Codelife. However, it interacts a great deal with the db and greater site, as reaching the last slide updates user progress, and each slide has a Discussion board beneath it. It's important to note that currently a Level must be beaten all at once - the "latestSlideCompleted" variable in state is not persisted anywhere, and leaving the lesson does not restart the user halfway through a level. Longer term, more granular tracking of user location would be a nice enhancement.

Splash

Simple splash page that lists about text for the Codelife Project

Survey

Completed/Deprecated Survey Module from a 2017 Survey that followed a beta test in Minas Gerais. Consists of Radio buttons and a DB post.

Constants

threadInclude

threadsRoute is used for retrieving threads and their associated comments. Unlike islands, likes, and many of the other earlier data structures in development, threads make better use of Sequelize associations, implicitly including comments in the thread payloads they belong to. This is distinctly different from islands/levels/slides, which get entire lists from the tables and then compile them client side. Going forward, the hierarchical/sequelize-association method of delivering API data (without flattening) is the more correct one. Threads have entity_ids and types. Currently the only two types are comments and threads, however the intention was that discussions could expand to encompass projects/codeblocks or more

cvMatch

Given a rule and a block of code, check the Javascript and perform an exact match check on the regex. Used for things like "code must contain getElementById"

cvNests

Given a rule and a block of code, check that a given tag is nested inside another tag. Used for things like "html nests body." Note that this does not currently account for subsequent occurences (only checks for first occurences)

cvUses

Given a rule and a block of code, use a hard-coded regex to check for a SPECIFIC pattern. Example include a for block "for (;;) {}", ifelse "if () {} else {}" or a generic invocation of a function "functionName(){}"

attrCount

Given a needle (like h1), an attribute (like color), a value (like red), and a JSON representation of the code as prepared by himalaya (HTML parser), recursively climb down the nested json tree, testing at each node for the presence of the needle, and if provided, whether that node has an attribute, and, if provided, whether that attribute's value exactly matches the provided value.

cvContainsSelfClosingTag

Given a rule and a block of code, search for a self closing tag such as Optionally run attrCount to check for extra rules (such as requiring "src")

cvContainsOne

Given a rule and a block of code, ensure that the given needle (such as ) occurs once and only once in the code (useful for tags like body, head, html)

cvContainsTag

Given a rule and a block of code, check if a given tag (such as

) is included in the code. Optionally, use attrCount to match any provided attributes or values in the rule.

cvContainsStyle

Given a rule and a block of code, using the "css" module to turn the css into a crawlable object. Fold over that generated parsed object and drill down to check if the rule's property matches the property and value of the css entered by the student.

Functions

flattenCodeBlock(user, cb)Object

Given the logged-in user and a codeblock, this function "flattens" the object by reaching into the associated tables queries (such as reports and likes) and bubbling them up to a top-level prop This type of function is really only used here and in projectsRoute. As codelife development progressed, the pattern shifted more to expect the nested nature of sequelize queries, meaning flattening wasn't necessary.

strip()

This route is specifically for the canon "needs" version of the glossary It has a lang switch because the glossary needs to be rendered server side for SEO optimization.

flattenProfile(user, p)

Similar to codeblocksroute, earlier in the project a lot of work was done to keep the payloads returned by APIs as flat objects. Later routes trended more towards trusting sequelize to form the hierarchy via associations. This helper function bubbles up associations into top-level properties.

flattenProject(user, p)Object

Given the logged-in user and a project, this function "flattens" the object by reaching into the associated tables queries (such as reports and likes) and bubbling them up to a top-level prop This type of function is really only used here and in codeblocksroute. As codelife development progressed, the pattern shifted more to expect the nested nature of sequelize queries, meaning flattening wasn't necessary.

pruneThread(user, t)Object

Given a user and a thread, prepare the thread to be returned to the requester. This involves a number of operations, including collating likes and reports, rewriting banned content, and deleting certain sensitive keys so they don't leak out through the API

AuthForm

AuthForm is a wrapper component that switches between LoginForm and Signup Form It can be primed with a default via the initialMode prop.

Kind: global class


Browser

Browser is a drop-down menu embedded in Nav that lets the user jump to any level or island that they have beaten in the past

Kind: global class


browser.componentDidMount()

On mount, fetch all islands/levels/slides, sort them, and arrange them hierarchically for use in the Blueprint Tree. Also grab the logged in user's progress so that the browser can lock unbeaten levels.

Kind: instance method of Browser


browser.buildTree()

Builds the "nodes" object that will be used to populate the blueprint tree. The Blueprint Tree component requires lots of metadata and nesting, so a fair amount of crawling must be done to populate it properly Note: This is borrowed heavily from the tree in the CMS. Someday they should be merged

Kind: instance method of Browser


browser.initFromProps(nodeFromProps)

Given a blueprint tree node, saved during the buildTree function, expand and select the appropriate node to match the location

Kind: instance method of Browser

Param Type Description
nodeFromProps Object A Blueprint Tree node

browser.fixNulls(obj) ⇒ Object

Helper function to avoid errors from accessing non-existent properties Longer term, database defaults values should be established to avoid this

Kind: instance method of Browser
Returns: Object - an object whose null/undefined params are changed to ""

Param Type Description
obj Object the object to prune

browser.reloadProgress()

As the user beats new levels, they are written to the db, but no redux-level store is updated. This public-facing function is invoked by Nav.jsx when the Browser is opened, resulting in a short loading screen while the latest progress is retrieved. See Nav.jsx for more details.

Kind: instance method of Browser


browser.selectNodeFromProps()

Similar to initNodeFromProps which expands the Blueprint Tree, this function selects the node that matches the LinkObj provided by Nav.

Kind: instance method of Browser


browser.handleNodeClick(node)

Callback for clicking a node. Uses browserhistory to navigate the user to the new page

Kind: instance method of Browser

Param Type Description
node Object The blueprint node that was clicked

Checkpoint

Checkpoint is a one-time pop-up that asks the user to fill in his or her school/location Originally intended to be a more generic "Checkpoint" system that would support arbitrary banners/messages, it is currently only used for gathering school info

Kind: global class


CodeBlockCard

CodeBlockCards appear throughout the site as a way of previewing a student's codeblock It contains both the small clickable card with preview image AND the dialog box that pops up over the page and shows the full screen code editor.

Kind: global class


codeBlockCard.saveLikeStatus()

Write the current like status of this codeblock to the db. CodeBlockList must be informed when this happens so it can reorder the codeblocks (liked codeblocks come first) so props.reportLike on return.

Kind: instance method of CodeBlockCard


codeBlockCard.generateScreenshot()

Admin-only button callback that pings an API route to manually generate a screenshot for this codeblock (usually only happens when codeblock owner saves file)

Kind: instance method of CodeBlockCard


codeBlockCard.selectFork()

When the forking sub-menu is opened, highlight and select the text for easy editing

Kind: instance method of CodeBlockCard


codeBlockCard.toggleFeature()

Admin-only button callback that sets a codeblock as featured or not (featured codeblocks show up on the homepage)

Kind: instance method of CodeBlockCard


codeBlockCard.toggleFork()

Codeblocks can be forked into projects, so students may remix another student's work. This function creates that new project and populates it with the codeblock data

Kind: instance method of CodeBlockCard


codeBlockCard.toggleLike()

Switch that functions a like on and off. Note that this is front-end only and does not update the backend.

Kind: instance method of CodeBlockCard


codeBlockCard.directLike()

Toggles the like visually (toggleLike) and saves it to the db (saveLikeStatus)

Kind: instance method of CodeBlockCard


codeBlockCard.componentDidMount()

On mount, grab the codeblock from props and create a unique placeholder fork name via epoch time

Kind: instance method of CodeBlockCard


codeBlockCard.componentDidUpdate()

On Update, if new props have been loaded in, load the new codeblock into state and update fork title

Kind: instance method of CodeBlockCard


codeBlockCard.handleReport()

This method is passed down as a callback to ReportBox. When reportBox signals a report, it calls this function, which updates the embedded codeblock itself and forces a refresh

Kind: instance method of CodeBlockCard


CodeBlockEditor

CodeBlockEditor is the popover that comes up for the final test of an island. It is mostly a wrapper around CodeEditor that provides the student with the test prompt, cheat sheet, and db routes to save their progress when they pass the test

Kind: global class


codeBlockEditor.componentDidMount()

On Mount, parse various props passed down and add them to state.

Kind: instance method of CodeBlockEditor


codeBlockEditor.onFirstCompletion()

When a user passes a codeblock for the first time, the parent Island component must be informed so it can close the popover and show a the "next island" dialog. Pass this callback down to codeeditor to enable that

Kind: instance method of CodeBlockEditor


codeBlockEditor.setExecState()

Callback passed to CodeEditor so that CodeEditor can report when the user is using a script tag (therefore show an execute button in here in CodeBlockEditor)

Kind: instance method of CodeBlockEditor


codeBlockEditor.saveProgress()

Write progress to db when codeblock is passed

Kind: instance method of CodeBlockEditor


codeBlockEditor.onChangeText()

Callback passed down to the CodeEditor, allowing this parent component to respond to text changes if desired.

Kind: instance method of CodeBlockEditor


codeBlockEditor.resetCodeBlock()

Set codeblock back to original test prompt state

Kind: instance method of CodeBlockEditor


codeBlockEditor.attemptReset()

Show popup warning (Are you sure?)

Kind: instance method of CodeBlockEditor


codeBlockEditor.executeCode()

Show popup warning (Are you sure?)

Kind: instance method of CodeBlockEditor


codeBlockEditor.changeCodeblockName()

Change codeblock name in place. Note that this doesn't save it to the db yet

Kind: instance method of CodeBlockEditor


codeBlockEditor.clickSave()

Intermediary function that blocks some editing functions until the save is complete This gets around a known bug where clicking save twice can write two copies to the db

Kind: instance method of CodeBlockEditor


codeBlockEditor.verifyAndSaveCode()

When the user clicks save & submit, make sure the internal CodeEditor has verified that their code is passing. If so, write the codeblock and progress to the db, and update the in-state version to reflect the new code

Kind: instance method of CodeBlockEditor


CodeBlockList

CodeBlockList is used by Projects to display codeblocks to draw inspiration from.

Kind: global class


codeBlockList.componentDidMount()

On Mount, fetch all codeblocks, sort them by island, then separate into liked, unliked, and "mine" (logged in user's) Also fetch user progress so that unbeaten island codeblocks show as greyed out

Kind: instance method of CodeBlockList


codeBlockList.reportLike()

Because a like can occur in a nested component (in this case, CodeBlockCard), this container component needs a callback function that can rearrange the items that exist in state.

Kind: instance method of CodeBlockList


codeBlockList.handleFork()

Codeblocks have the ability to "fork" into a new project. For most embeddings of CodeBlockCards, this is as simple as creating the new project and using browserHistory to navigate the user to that page. However, as the user is ALREADY ON the Projects page, a callback is required to tell the parent component (Projects.jsx) to make a new project and update itself accordingly

Kind: instance method of CodeBlockList


CodeEditor

CodeEditor is a two-panel rendering component for student code. It uses AceEditor for the student panel (left), and a remote rendering iframe for the page preview (right).

Kind: global class


codeEditor.componentDidMount()

When CodeEditor mounts, add an EventListener that listens for postMessage events from the sandbox. Also, initiate a ping that checks with the sandbox page until it is ready to render.

Kind: instance method of CodeEditor


codeEditor.componentWillUnmount()

Before CodeEditor unmounts, remove the EventListener that listens for postMessage events from the sandbox.

Kind: instance method of CodeEditor


codeEditor.pingRemote()

On a set interval, ping the remote sandbox until we receive a postMessage indicating that it's ready.

Kind: instance method of CodeEditor


codeEditor.componentDidUpdate()

On update, detect the state change of hasJS to inform the parent component whether or not to show an "Execute" button. If the rules in the props have changed, the parent component has changed (e.g., changing slides), necessitating state change of rules. Additionally, if the code content in the props have changed, clear any execution timeouts and reset the editor state.

Kind: instance method of CodeEditor


codeEditor.getBaseRules() ⇒ Array

Generates a base state of HTML rules that will always be true for a well-formed page.

Kind: instance method of CodeEditor
Returns: Array - Array of basic HTML rules in JSON format


codeEditor.receiveMessage(event)

Listens for events from postMessage, generated by the embedded iframe sandbox on codelife.tech. If the message didn't come from codelife.tech, automatically return. If the message is a special wakeup message, clear the ping intervals and set the iframe as ready for use. For all other messages, forward them to the handlePost function.

Kind: instance method of CodeEditor

Param Type Description
event String A postMessage event.

codeEditor.getTitleText(theText) ⇒ String

Given the current text in the editor, if the HTML has a properly formatted <title> field, extract and return it.

Kind: instance method of CodeEditor
Returns: String - The extracted text between <title> and </title>

Param Type Description
theText String The current text contents of the editor

codeEditor.stripJS(json) ⇒ Array

Given a parsed JSON representation of the current code, recursively find and remove the contents of anything between <script> tags. This is important because we re-render the page on each keystroke, so firing JavaScript executions for each key is not ideal. Save the stripped-out JS into state, so we can determine from its prescence there if we should show an execute button or not.

Kind: instance method of CodeEditor
Returns: Array - A rebuilt (minus JavaScript) JSON object that himalaya can parse back into HTML.

Param Type Description
json Object A JSON Representation of the current text, as parsed by the himalaya library

codeEditor.checkForErrors()

Grabs the current editor text from state, and prepare an array of true/false tests to be applied to it. Based on the results of those testing rules, set state variables that provide completion % feedback to the student.

Kind: instance method of CodeEditor


codeEditor.writeToIFrame(theText)

Given the text currently in the editor, send a postMessage containing that source to the sandbox for rendering.

Kind: instance method of CodeEditor

Param Type Description
theText String The text to be rendered in the sandbox

codeEditor.hasJS(theText)

Given the text currently in the editor, determine if it has open and closing script tags.

Kind: instance method of CodeEditor

Param Type Description
theText String The current editor text

codeEditor.renderText(executeJS)

Called explictly after state updates that change the text. Using the helper function stripJS, this function prepares the code to be shipped to the sandbox via writeToIFrame. If it is the first time we are rendering, such as in a slide example, execute the JavaScript after a short delay.

Kind: instance method of CodeEditor

Param Type Description
executeJS Boolean If set to true, this function will execute any included JavaScript after a short delay.

codeEditor.iFrameLoaded()

Called after "awake" message is received from sandbox, indicating that the iFrame is loaded and ready for postMessage events. Fetches rule text from API. On completion, set the prop-given initial text in state and invoke the onChangeText callback, so any componenent that embeds CodeEdtior may subscribes to this callback may be notified that the text has changed.

Kind: instance method of CodeEditor


codeEditor.onChangeText(theText)

Callback for the embedded AceEditor component. Used to bubble up text change events to this object's state and to the parent.

Kind: instance method of CodeEditor

Param Type Description
theText String The current state of the text in the code editor.

codeEditor.myCatch(e)

Invoked by handlePost when an error is caught by the sandbox. Concatenates the error message to the console.

Kind: instance method of CodeEditor

Param Type Description
e String The error string retrieved from the sandbox

codeEditor.myLog()

Invoked by handlePost when an log message is returned by the sandbox. Concatenates the log message to the console. Because console.log can take multiple comma-separated arguments, extract the list using Array.from(arguments)

Kind: instance method of CodeEditor


codeEditor.evalType(value) ⇒ String

Helper function to determine argument type for syntax highlighting in emulated console.

Kind: instance method of CodeEditor
Returns: String - A String representing the type of the provided object

Param Type Description
value * Value of any type

codeEditor.handlePost()

Called by receiveMessage when postMessage events arrive from the sandbox. The first argument will always be a type designator that describes the following arguments so they can be routed for processing. A type of "completed" means the JavaScript has completed execution in the remote sandbox and error checking can begin.

Kind: instance method of CodeEditor


codeEditor.checkJVMState(needle, value)

Called by handlePost to process postMessage events of type "rule". Iterates over list of rules in state and sets each rule's passing state based on whether the given argument matches type and value restrictions.

Kind: instance method of CodeEditor

Param Type Description
needle String The keyword rulename this value belongs to, typically a variable or function name
value * The actual, remote-sandbox determined value to check against.

codeEditor.reverse(s) ⇒ String

Reverses a string. Used by internalRender() to assist with regex.

Kind: instance method of CodeEditor
Returns: String - The reversed string

Param Type Description
s String The string to be reversed

codeEditor.internalRender()

One of the more complex functions in CodeLife, internalRender is invoked when an "execute code" button is pressed. This function is responsible for sending a specially prepared version of the student's source code to a remote sandbox for execution. The remote sandbox has an iFrame of its own, where the code is being injected. References to the "parent" of this iFrame refer to functions in the sandbox responsible for sending information back to Codelife.com via postMessage. To prepare the code for remote execution, several steps must be taken:

  • replace console.log with parent.myPost("console"...) to intercept console statements.
  • prepend JavaScript code with initialization functions that "zero out" any rule variables the student must set correctly.
  • append JavaScript code with parent.myPost("rule"...) methods that send variable state back to Codelife.com
  • further append JavaScript code with parent.myPost("completed"...) to indicate that the run has completed.
  • take ALL of that code, wrap it into a string literal that eval()s the code and catches any runtime errors.
  • take the student's current code and replace its JavaScript with the prepared JavaScript
  • invoke writeToIFrame, which sends the entire payload to the remote sandbox for execution. The sandbox then injects the prepared code into the iFrame, which calls its parent functions, and reports back here via postMessage.

Kind: instance method of CodeEditor


codeEditor.setEntireContents(theText)

Externally available method that components can use to set the contents of the Code Editor functionally (as opposed to via props)

Kind: instance method of CodeEditor

Param Type Description
theText String The string to set as the editor contents.

codeEditor.getEntireContents() ⇒ String

Externally available method that components can use to get the contents of the Code Editor functionally (as opposed to via props)

Kind: instance method of CodeEditor
Returns: String - The current contents of the editor


codeEditor.isPassing() ⇒ Boolean

Externally available method that components can use to fetch passing state

Kind: instance method of CodeEditor
Returns: Boolean - Whether the code is in a passing state


codeEditor.changesMade() ⇒ Boolean

Externally available method that components can use to determine whether the editor is "dirty," i.e., changes made that require saving

Kind: instance method of CodeEditor
Returns: Boolean - Whether changes have been made to the code since its initial state or last save


codeEditor.setChangeStatus(changesMade)

Externally available method that components can use to set the editor as "dirty/clean" i.e., changes made. This is a necessary callback for operations like Saving Content - embedding components need to set changesMade to false.

Kind: instance method of CodeEditor

Param Type Description
changesMade Boolean Boolean value to set "dirty/clean" status in editor.

codeEditor.executeCode()

Externally available method that components can use to execute the JavaScript contents of the editor.

Kind: instance method of CodeEditor


codeEditor.toggleDrawer()

Externally available method that components can use to set drawer visibility state.

Kind: instance method of CodeEditor


codeEditor.fullscreenEditorToggle()

toggle fullscreen state

Kind: instance method of CodeEditor


DrawerValidation

The CodeEditor is responsible for handling violation of the rules set out for a given programming challenge. A list of errors is passed in as a prop - this component is responsible for creating a readable sentence form of what is wrong with the student's code. For example, "Your HTML code is missing an

tag". The format of this language is stored in the database as "Your {{p1}} is missing {{p2}}." (Note that this need be translated by lang)

Kind: global class


CollabList

Provides a list of Collaborators for a project provided by props.

Kind: global class


CollabSearch

Popover window so that project owners can find and add new users to collaborate on a given project

Kind: global class


collabSearch.handleChange()

Don't start hitting the database until the query is more than 2 characters long

Kind: instance method of CollabSearch


collabSearch.addCollaborator()

Given a clicked collaborator, if the constraints are met, post it to userprofiles_profiles (collab table)

Kind: instance method of CollabSearch


collabSearch.removeCollaborator()

Given a uid and the pid of the current project, remove the matching row from userprofiles_profiles

Kind: instance method of CollabSearch


Comment

Comments belong to Threads. Note that there is no text editor here - all posting is handled by Thread.jsx. This component is for displaying only.

Kind: global class


comment.componentDidMount()

The comment itself is passed in via props. Put it in state

Kind: instance method of Comment


comment.toggleLike()

Handle Liking and Unliking of comments

Kind: instance method of Comment


comment.handleReport()

When the nested ReportBox component processes a report, This commment module needs to update the button to reflect the new state. This callback handles that.

Kind: instance method of Comment


ContestSignup

Signup page for (currently postponed) project contest. Signing up simply enters the user in the contest, users still must go to the ContestSubmit page to select a project and finalize the procedure.

Kind: global class


contestSignup.componentWillMount()

On Mount, fetch the profile of the logged in user.

Kind: instance method of ContestSignup


contestSignup.formatCPF()

Formatting rules for Cadastro de Pessoas Físicas

Kind: instance method of ContestSignup


contestSignup.enterContest()

Onclick handler that prepares entry payloads to various endpoints. Note that setting school id/ geo id in this contest entry page also updates the actual profile of the user.

Kind: instance method of ContestSignup


ContestSubmit

User selects a project for the contest and submits their entry.

Kind: global class


contestSubmit.componentDidMount()

On Mount, fetch all the projects of the currently logged-in user, as well as their entry status

Kind: instance method of ContestSubmit


contestSubmit.submit()

On Click, prepare contest payload and post it to the endpoint

Kind: instance method of ContestSubmit


CTA

Call To Action Component, encourage users to sign up after visiting SEO-enable page

Kind: global class


Discussion

Discussion Board wraps a list of threads (which in turn hosts a list of comments). Discussion boards currently only apply to slides, but they are designed to be able to apply to anything (projects, codeblocks, etc)

Kind: global class


discussion.componentDidUpdate()

When the user changes slides, hit the API endpoind and fetch the new thread data

Kind: instance method of Discussion


discussion.newThread()

Prepare payload and post a new thread to the db

Kind: instance method of Discussion


discussion.selectSort()

On sort selection, sort the threads in state

Kind: instance method of Discussion


IslandLink

IslandLink is the zoomed-out picture of the island used in the overworld map, lesson plan, etc

Kind: global class


Loading

Loading is explicitly used by CANON itself for any page that has canon "needs", which is why this is a full container page with . The LoadingSpinner component was separated out for embedded use (no clouds)

Kind: global class


LoadingSpinner

Loading spinner for a huge number of components in Codelife, mostly used in render cycles while waiting for axios to return with data

Kind: global class


LoginForm

Works alongside SignUpForm to log users in. Essentially a wrapper for the canon "login" action

Kind: global class


loginForm.onSubmit()

The login dispatch is mapped to props and called here

Kind: instance method of LoginForm


Nav

Nav Component is the header of the page - containing login controls and the Island Browser

Kind: global class


nav.componentDidMount()

When Nav Mounts, it is almost always because the page/app is being loaded from scratch, either because the user is visiting for the first time, OR a login has been attempted, and the result must be handled. As such, there is a fairly length decision tree here so that feedback can be shown.

Kind: instance method of Nav


nav.reportClick()

When the user clicks an island/location in the embedded Browser component, they have chosen to navigate to a new page. This callback is needed so the Browser's wrapping component (this one) can hide the Browser.

Kind: instance method of Nav


PasswordReset

Wrapper Component for the reset password dispatch action of canon

Kind: global class


passwordReset.componentDidMount()

On Mount, access the URL information from router and grab the token if it is there.

Kind: instance method of PasswordReset


passwordReset.changePassword()

Password field change handler, ensure passwords match before submitting dispatch

Kind: instance method of PasswordReset


passwordReset.componentDidUpdate()

Listen for changes to this.props.auth, and show a Toast message that reflects its state

Kind: instance method of PasswordReset


ProjectCard

ProjectCard, similar to CodeBlockCard, is a small visual container with a Dialog popover to showcase projects. It is used on the Homepage as well as in User Profiles to list their projects

Kind: global class


projectCard.toggleDialog()

Project Cards, though small visually, are responsible for containing and controlling their own Dialog Popover that shows the entirety of the project and its code

Kind: instance method of ProjectCard


projectCard.toggleFeature()

Admin Only function to promote the given project to featured

Kind: instance method of ProjectCard


projectCard.generateScreenshot()

Admin only function to generate a screenshot for this project (usually so it can be featured on the homepage)

Kind: instance method of ProjectCard


projectCard.handleReport()

Projects embed a ReportBox to allow for flagging. If a user uses that box to report the content, this callback notifies its parent (this component) that the project has been reported, so state can be updated

Kind: instance method of ProjectCard


ReportBox

ReportBox is a reusable component for reporting threads, comments, projects, and codeblocks for inappropriate content. As with many data structures in codelife, it uses a SINGLE reports table, with a "type" column that designates which table the report_id refers to.

Kind: global class


Search

The Search component is embedded in Nav and is used to search users and projects. It utilizes postgres trigrams serverside (see readme)

Kind: global class


search.handleChange()

On keystroke, hit the search API endpoint

Kind: instance method of Search


search.componentDidUpdate()

Search is not a top-level component in routes.jsx, so it doesn't have access to the Router object that would indicate what page the user is on. This makes it difficult to collapse the search results if the user clicks a link outside the results. To get around this, a linkObj is passed down from App to Nav to here, and search is collapsed on URL change.

Kind: instance method of Search


search.onKeyDown()

onKeyDown is meant to capture inputs - but the arrow up/down aren't currently functional (user can use tabs and Enter key to go through links however). This UX could be improved.

Kind: instance method of Search


search.search()

Send search query to API endpoint

Kind: instance method of Search


SelectGeo

Component for selecting a location from a database of geo codes in Brazil

Kind: global class


selectGeo.componentDidMount()

On Mount, get the gid (embedded in props via userprofile) and populate the search bar accordingly

Kind: instance method of SelectGeo


selectGeo.changeState()

Callback for the select box. Contains some code from what was going to be an "Unspecified" option, but was changed to a higher up "Rather not say" option in EditProfile.jsx which cancels out the dialog entirely and writes a hard-coded "-1" to the user's geo id.

Kind: instance method of SelectGeo


SelectSchool

Component for choosing a school from a db of school ids and geos - meant to be used in conjunction with SelectGeo

Kind: global class


selectSchool.componentDidMount()

On Mount, get the sid from props (originally retrieved from userprofile) and populate the dropdown accordingly

Kind: instance method of SelectSchool


selectSchool.updateSchoolList()

Callback for dual dropdown - Given a selected Geo, hit the API to retrieve all the schools for that Geo and populate the dropdown.

Kind: instance method of SelectSchool


ShareDirectLink

Popover Component for sharing a link to a students project/codeblock. Copies url to clipboard.

Kind: global class


ShareFacebookLink

Component for sharing facebook links. Due to the fact that xvfb screenshots require a few seconds to render, this component receives a "screenshotReady" prop from the embedding component, which waits a few seconds to ensure that Facebook's FIRST capture of the page has the finished screenshot

Kind: global class


SignupForm

Sister component to AuthForm, this component wraps the Canon "signup" action and does appropriate error checking

Kind: global class


signupForm.onSubmit()

When the user clicks submit, verify some info before calling datawheel-canon's signup action

Kind: instance method of SignupForm


InputCode

InputCode is a slide type that requires the student to complete a coding test The CodeEditor component is embedded with a series of rules, and the slide will not unblock until the student submits a passing code section. It is mostly a wrapper for CodeEditor, with some controls to execute controls or unblock a slide.

Kind: global class


inputCode.componentDidMount()

Retrieve the rules and starting code from props and put them into state

Kind: instance method of InputCode


inputCode.componentDidUpdate()

If the user changes slides, update the rules

Kind: instance method of InputCode


inputCode.setExecState()

The Embedded CodeEditor itself knows whether the student has written any javascript in the editor window. Dynamically show and hide an "execute" button based on this callback function

Kind: instance method of InputCode


inputCode.submitAnswer()

Attempt to submit the current code state on click. Requires reaching into the wrapped CodeEditor instance itself to call a public function, isPassing, which is managed by the CodeEditor. If the student passes, inform the parent Slide component that this slide is unblocked and the student can continue

Kind: instance method of InputCode


inputCode.resetAnswer()

Reset CodeEditor to original testing state, again by reaching into the CodeEditor instance itself and setting contents via a public method.

Kind: instance method of InputCode


inputCode.attemptReset()

Display Are you sure? Dialog

Kind: instance method of InputCode


inputCode.executeCode()

Reach into the codeEditor and trigger javascript execution.

Kind: instance method of InputCode


Quiz

Quiz is a blocking multiple-choice question, powered by the quizjson column in the slides db

Kind: global class


quiz.onChooseAnswer()

Callback for clicking an answer. Check ths JSON, and unblock the parent Slide if correct

Kind: instance method of Quiz


quiz.componentDidMount()

On Mount, populate the quiz prompt from props

Kind: instance method of Quiz


quiz.componentDidUpdate()

When the user changes slides, update the quizjson in state.

Kind: instance method of Quiz


RenderCode

RenderCode is similar to InputCode, but the CodeEditor is in readonly mode For showing code examples with explanations.

Kind: global class


renderCode.setExecState()

Callback for CodeEditor, when it reports that the student is using javascript, show an exec button on this slide.

Kind: instance method of RenderCode


renderCode.executeCode()

When the execute button is clicked, pass the command down to the public method in CodeEditor

Kind: instance method of RenderCode


TextImage

TextImage is text left, image right. Images are stored in /slide_images/{id}.jpg Images are uploaded through the CMS and a translated version is chosen here via locales

Kind: global class


Thread

A thread is the top-level child of a Discussion. Discussions have many threads, threads have many comments.

Kind: global class


thread.componentDidMount()

On Mount, retrieve the thread from props

Kind: instance method of Thread


thread.newComment()

A thread can only have one text window open at a time for a new comment to be added. Keep the details of this comment in state, and post it to the endpoint on submit

Kind: instance method of Thread


thread.handleReport()

A report, handled by the sub-component ReportBox, uses this callback to tell Thread that the user has submitted a report

Kind: instance method of Thread


UserCard

UserCard is a component used on a profile page to display other users that share the logged in user's school or location

Kind: global class


About

About page - contains translated about text and a simple photoslide component from Datawheel's first visit to Minas

Kind: global class


Contest

Contest Component handles the (currently postponed) contest, including all the steps and checks to ensure eligibility. Page is public-facing (doesn't require login) to gain attention - the first step is creating an account

Kind: global class


contest.componentDidMount()

On mount, load the user, their progress, and their projects. Use this data to populate state and fill in the appropriate steps on the page

Kind: instance method of Contest


contest.determineStep()

Signing up for the contest is a multi-step progress - use the state to determine where the user is so the boxes on the page can be checked accordingly.

Kind: instance method of Contest


Glossary

The Glossary component retrieves words It is worth noting that the storage of glossary words is somewhat split-brained. Here in Glossary.jsx, canon's "need" functionality is used to ensure that words are rendered server-side and therefore indexable by search engines. However, glossary words used to live in the Redux Store (and in QuillWrapper, this is still how they are loaded). Both places use the same API endpoint - but one uses canon needs, the other puts the data into redux in App.jsx's mount method.

Kind: global class


Home

Homepage component - mostly a wrapper for other smaller components (cards, features, etc)

Kind: global class


home.componentDidMount()

On mount, fetch the users progress so that a "continue your adventure" placard can be shown. Whether the user is logged or not, fetch the featured cb/projects

Kind: instance method of Home


Level

Main Level-viewing component (e.g., Jungle Island). It shows a list of the levels available as well as the ending codeblock test. Codeblocks by other users are listed underneath the island

Kind: global class


level.loadFromDB()

On Mount, or Update (meaning the user switched islands) Load the necessary progress/codeblock data from the db.

Kind: instance method of Level


level.maybeTriggerCodeblock()

The presence of /show in the URL is a permalink to open the codeblock. Was originally intended so that codeblockcards could directly link to a user's own codeblock and automatically open it, but this feature was postponed.

Kind: instance method of Level


level.componentDidUpdate()

When the user changes pages, flush the state and reload from the database

Kind: instance method of Level


level.componentDidMount()

The code to load from DB already exists in ComponentDidUpdate, this dedupes that logic by just manually calling update on mount.

Kind: instance method of Level


level.componentWillUnmount()

A timeout is registered on Codeblock completion to process the screenshot, ensuring that it is complete before allowing fb sharing. Clear this timeout if the user leaves the page

Kind: instance method of Level


level.toggleTest()

Hide or Show the codeblock test popover. Adjust the URL accordingly

Kind: instance method of Level


level.handleSave()

Callback for CodeBlockEditor on save. The CodeBlockEditor passes its codeblock back out to Level so that its Codeblock can be set.

Kind: instance method of Level


level.onFirstCompletion()

Called when the user finishes an island for the first time. Calls a refresh on the data to unlock codeblocks, shows the victory message, and invites the user to the next island.

Kind: instance method of Level


level.closeOverlay()

Upon Closing the winning pop-up, send the player to the next island.

Kind: instance method of Level


level.hasUserCompleted()

Levels and Islands are mixed together in a single array - so this can be used to test if a user has beaten a level (e.g. hello-world) or an entire island (e.g. island-1).

Kind: instance method of Level


level.reportLike()

The codeblocks underneath the island need to be informed via a callback when they are liked or unliked, as this affects the sorting.

Kind: instance method of Level


level.allLevelsBeaten()

Used to determine if the final test should be shown.

Kind: instance method of Level


level.promptFinalTest()

If a user has beaten all the levels on this island, but has NOT created a codeblock yet, they are in the state were the codeblock need be prompted

Kind: instance method of Level


level.saveCheckpoint()

Checkpoint is a pop-up that appears after level 1, asking the user to share their school. This is the api callback to update their profile

Kind: instance method of Level


level.skipCheckpoint()

If the user elects not to provide their school, write a hard-coded -1 to their sid. This saves the "prefer not to answer" choice and prevents future popups.

Kind: instance method of Level


level.buildCheckpointPopover()

This was written early in the project, before the Component nesting of React was fully put to use. This method encapsulates the checkpoint popover - but this should obviously be moved to a component, not a method.

Kind: instance method of Level


level.buildWinPopover()

This was written early in the project, before the Component nesting of React was fully put to use. This method encapsulates the "You Win" popover - but this should obviously be moved to a component, not a method.

Kind: instance method of Level


level.buildTestPopover()

This was written early in the project, before the Component nesting of React was fully put to use. This method encapsulates the test popover - but this should obviously be moved to a component, not a method.

Kind: instance method of Level


Island

Displays all available islands

Kind: global class


island.componentDidMount()

On mount, fetch the progress for the currently logged in user.

Kind: instance method of Island


island.hasUserCompleted(milestone) ⇒ Boolean

On mount, fetch the progress for the currently logged in user.

Kind: instance method of Island
Returns: Boolean - Returns a boolean whether or not the user has completed the provided island ID.

Param Type Description
milestone String An island ID.

Leaderboard

Leaderboard is a sortable table that lists users by their in-game progress.

Kind: global class


leaderboard.componentDidMount()

On Mount, retrieve stats from the API, calculate what percentage of completion this refers to, given the state of currently released islands, and update state.

Kind: instance method of Leaderboard


leaderboard.handleHeaderClick()

On selection of a sorting property, sort the users accordingly

Kind: instance method of Leaderboard


LearnMore

Simple partners page to link to other online coding projects

Kind: global class


LessonPlan

A public-facing listing of all slides and quizzes, to be used by teachers as a lesson plan, students as a reference guide, and to aid in directing users to the site via search engines. Lesson plan uses Canon's "Needs" to render the page serverside, so that the page is indexable by SEO bots

Kind: global class


Profile

Class component for a user profile. This is a public page and meant to be shared. If a user is logged in AND this is their profile, show an edit button allowing them to edit it.

Kind: global class


new Profile(loading, error, profileUser)

Creates the Profile component with its initial state.

Param Type Description
loading boolean true by defaults gets flipped post AJAX.
error string Gets set if no username matches username URL param.
profileUser object Gets set to full user object from DB.

profile.componentDidMount()

Grabs username from URL param, makes AJAX call to server and sets error state (if no user is found) or profileUser (if one is).

Kind: instance method of Profile


profile.render()

3 render states: case (loading)

  • show loading case (error)
  • show error msg from server case (user found)
  • user info

Kind: instance method of Profile


UserCodeBlocks

Class component for displaying lists of user's snippets. This is shown on the public profile for a user and requires sending 1 prop: a ref to the user

Kind: global class


new UserCodeBlocks(loading, snippets)

Creates the UserSnippets component with initial state.

Param Type Description
loading boolean true by defaults gets flipped post AJAX.
snippets array Gets set by AJAX call from DB call.

userCodeBlocks.componentDidMount()

Grabs user id from user prop, makes AJAX call to server and returns the list of snippets.

Kind: instance method of UserCodeBlocks


UserProjects

Class component for displaying lists of user's projects. This is shown on the public profile for a user and requires sending 1 prop: a ref to the user

Kind: global class


new UserProjects(loading, projects)

Creates the UserProjects component with initial state.

Param Type Description
loading boolean true by defaults gets flipped post AJAX.
projects array Gets set by AJAX call from DB call.

userProjects.componentDidMount()

Grabs user id from user prop, makes AJAX call to server and returns the list of projects.

Kind: instance method of UserProjects


UsersList

Class component for displaying lists of user's snippets. This is shown on the public profile for a user and requires sending 1 prop: a ref to the user

Kind: global class


new UsersList(loading, snippets)

Creates the UserSnippets component with initial state.

Param Type Description
loading boolean true by defaults gets flipped post AJAX.
snippets array Gets set by AJAX call from DB call.

usersList.componentDidMount()

Grabs user id from user prop, makes AJAX call to server and returns the list of snippets.

Kind: instance method of UsersList


Projects

Projects is one of the largest Pages in codelife - It is responsible for all CRUD operations of projects, processing screenshots, and listing user codeblocks for inspiration. Longer term, this should be refactored into smaller components.

Kind: global class


projects.componentDidMount()

On Mount, retrieve all projects by the logged in user, as well as the projects by OTHER users with whom the logged in user is listed as a collaborator, and put these in state.

Kind: instance method of Projects


projects.openProject()

Given a project id, open the project itself by fetching it from the database and loading it into state. Set the URL so it continues to match the open project permalink

Kind: instance method of Projects


projects.setExecState()

The embedded CodeEditor is the only component that knows if the user has used javascript in their project. When this changes in CodeEditor, it bubbles that up via this callback so that Projects can dynamically show and hide an "Execute Code" button

Kind: instance method of Projects


projects.createNewProject()

Callback for the create new project button. Trims the name of URL-breakers and whitespace, posts an empty project to the API endpoint, and refreshes the project list from that API payload so the Project List accurately reflects the new project collection. Update the URL when the project is finished opening.

Kind: instance method of Projects


projects.clickNewProject()

Opens the popover to name the project (which eventually calles createNewProject)

Kind: instance method of Projects


projects.shareProject()

Deprecated / unused function

Kind: instance method of Projects


projects.showLeaveAlert()

The alerts in this component have two states, false, or "truthy," that is, leaveAlert=false means that the window closed, and setting leaveAlert to what you want the alert to say makes it truthy, and therefore open. This click callback is the "are you sure" dialogue for leaving a collaboration

Kind: instance method of Projects


projects.leaveCollab()

Upon confirming that this user wants to leave a collab, remove that user from the collabs tabel. Additionally, filter it out in state. Either way, close the leaveAlert

Kind: instance method of Projects


projects.handleCheckbox()

Though users are normally invited to share new projects on facebook, they may elect to opt out and "never show this again" which needs to write to their userprofile

Kind: instance method of Projects


projects.deleteProject()

Delete a given project. The argument here is confusing - originally clicking delete would delete the project immediately. The addition of a deleteAlert (similar to leaveAlert) stores the project to be deleted in the deleteAlert.

Kind: instance method of Projects


projects.onClickProject()

When a user clicks a project, attempt to open it. Reach into the CodeEditor and check if changes have been made, and if so, block the opening attempt until they save.

Kind: instance method of Projects


projects.saveCodeToDB()

Prepare a payload containing the filename, id, content, etc to be sent to the update api. If this is the first time the user is saving a project, offer to share it on Facebook. Note that this is one of the many places in Codelife where a 5 second timer is used to allow the screenshot time to process

Kind: instance method of Projects


projects.closeFirstTimeShare()

Callback for closing the share window, save the users preference if they asked not to be asked again.

Kind: instance method of Projects


projects.executeCode()

Reach into the CodeEditor and call the executeCode function. This requires manual execution - otherwise if the user was writing something like "alert()" then it would render every single keystroke

Kind: instance method of Projects


projects.handleFork()

On most parts of the site, forking a codeblock is as easy as creating the project and navigating the user to that page. However, if a user forks a codeblock from HERE on the project page, a slightly different behavior is required

Kind: instance method of Projects


projects.changeProjectName()

Rename a project. Set title editability to false temporarily and prune URL-breakers and leading/trailing whitespace from the new name. Write the project to the db and update state

Kind: instance method of Projects


projects.handleKey()

Keyboard callbacks

Kind: instance method of Projects


ResetPw

Very small wrapper class for PasswordReset Component

Kind: global class


Share

The Share Page is a top-level page that does not require login, enabling users to share their projects or codeblocks on facebook or with others. It looks up the content via name/user and renders a fullscreen codeeditor for display, essentially acting as a hosting page for the students' work. Show a Report bar on the bottom for logged in users to report inappropriate content

Kind: global class


share.componentDidMount()

In order to color the ReportBox Button appropriate, it needs to be known if the logged in user has reported this content. Fetch the reports to check.

Kind: instance method of Share


share.handleReport()

The ReportBox component needs a callback to tell this outer component that a report has been processed.

Kind: instance method of Share


Slide

The slide component is the wrapper for all the various slidetypes in Codelife. However, it interacts a great deal with the db and greater site, as reaching the last slide updates user progress, and each slide has a Discussion board beneath it. It's important to note that currently a Level must be beaten all at once - the "latestSlideCompleted" variable in state is not persisted anywhere, and leaving the lesson does not restart the user halfway through a level. Longer term, more granular tracking of user location would be a nice enhancement.

Kind: global class


slide.unblock()

InputCode and Quiz slides are "blockers" in that they do not allow progress until a correct answer is provided. This function is called when the user beats a slide.

Kind: instance method of Slide


slide.saveProgress()

When the user reaches the final slide, write the level to the userprogress table. If the user looks at the discussion board, this level is marked as "skipped", which ultimately does not count towards overall completion%. Completing the level without help marks the level as completed.

Kind: instance method of Slide


slide.componentDidUpdate()

Slide.jsx handles all the transitions from slide to slide, so a lot of work need be done when the user changes slides. The simplest case is beating a single slide, but they also may have beaten this lesson (db write), reached a blocking slide, or be changing levels entirely

Kind: instance method of Slide


slide.componentDidMount()

On mount, hit the DB and add the keyboard listener

Kind: instance method of Slide


slide.hitDB()

Given the island / level / slide (lid, mlid, sid) from the URL params Fetch the slides and userprogress from the db and start from the first slides

Kind: instance method of Slide


slide.editSlide()

Admin-only direct link to the CMS to edit a slide's content

Kind: instance method of Slide


slide.advanceLevel()

When the user goes to the next level, push the new URL and hard-reload. This should be refactored to a more React-y state reset.

Kind: instance method of Slide


slide.toggleSkip()

Show or hide the "show discussion" confirm/deny menu

Kind: instance method of Slide


slide.toggleDiscussion()

Reveal or hide the discussion component.

Kind: instance method of Slide


slide.onNewThread()

When a Discussion board posts a new thread, Slide needs to know this has happened. This callback pushes the new thread onto the list so the "thread count" updates

Kind: instance method of Slide


Splash

Simple splash page that lists about text for the Codelife Project

Kind: global class


Survey

Completed/Deprecated Survey Module from a 2017 Survey that followed a beta test in Minas Gerais. Consists of Radio buttons and a DB post.

Kind: global class


survey.componentWillMount()

Grabs username from URL param, makes AJAX call to server and sets error state (if no user is found) or overrides state (if one is).

Kind: instance method of Survey


threadInclude

threadsRoute is used for retrieving threads and their associated comments. Unlike islands, likes, and many of the other earlier data structures in development, threads make better use of Sequelize associations, implicitly including comments in the thread payloads they belong to. This is distinctly different from islands/levels/slides, which get entire lists from the tables and then compile them client side. Going forward, the hierarchical/sequelize-association method of delivering API data (without flattening) is the more correct one. Threads have entity_ids and types. Currently the only two types are comments and threads, however the intention was that discussions could expand to encompass projects/codeblocks or more

Kind: global constant


cvMatch

Given a rule and a block of code, check the Javascript and perform an exact match check on the regex. Used for things like "code must contain getElementById"

Kind: global constant


cvNests

Given a rule and a block of code, check that a given tag is nested inside another tag. Used for things like "html nests body." Note that this does not currently account for subsequent occurences (only checks for first occurences)

Kind: global constant


cvUses

Given a rule and a block of code, use a hard-coded regex to check for a SPECIFIC pattern. Example include a for block "for (;;) {}", ifelse "if () {} else {}" or a generic invocation of a function "functionName(){}"

Kind: global constant


attrCount

Given a needle (like h1), an attribute (like color), a value (like red), and a JSON representation of the code as prepared by himalaya (HTML parser), recursively climb down the nested json tree, testing at each node for the presence of the needle, and if provided, whether that node has an attribute, and, if provided, whether that attribute's value exactly matches the provided value.

Kind: global constant


cvContainsSelfClosingTag

Given a rule and a block of code, search for a self closing tag such as Optionally run attrCount to check for extra rules (such as requiring "src")

Kind: global constant


cvContainsOne

Given a rule and a block of code, ensure that the given needle (such as ) occurs once and only once in the code (useful for tags like body, head, html)

Kind: global constant


cvContainsTag

Given a rule and a block of code, check if a given tag (such as

) is included in the code. Optionally, use attrCount to match any provided attributes or values in the rule.

Kind: global constant


cvContainsStyle

Given a rule and a block of code, using the "css" module to turn the css into a crawlable object. Fold over that generated parsed object and drill down to check if the rule's property matches the property and value of the css entered by the student.

Kind: global constant


flattenCodeBlock(user, cb) ⇒ Object

Given the logged-in user and a codeblock, this function "flattens" the object by reaching into the associated tables queries (such as reports and likes) and bubbling them up to a top-level prop This type of function is really only used here and in projectsRoute. As codelife development progressed, the pattern shifted more to expect the nested nature of sequelize queries, meaning flattening wasn't necessary.

Kind: global function
Returns: Object - The "flattened" codeblock, ready to be returned to the requester

Param Type Description
user string The currently logged in user, as specified by datawheel-canon
cb Object The codeblock to flatten

strip()

This route is specifically for the canon "needs" version of the glossary It has a lang switch because the glossary needs to be rendered server side for SEO optimization.

Kind: global function


flattenProfile(user, p)

Similar to codeblocksroute, earlier in the project a lot of work was done to keep the payloads returned by APIs as flat objects. Later routes trended more towards trusting sequelize to form the hierarchy via associations. This helper function bubbles up associations into top-level properties.

Kind: global function

Param Type Description
user Object The logged in user
p Object the profile to flatten

flattenProject(user, p) ⇒ Object

Given the logged-in user and a project, this function "flattens" the object by reaching into the associated tables queries (such as reports and likes) and bubbling them up to a top-level prop This type of function is really only used here and in codeblocksroute. As codelife development progressed, the pattern shifted more to expect the nested nature of sequelize queries, meaning flattening wasn't necessary.

Kind: global function
Returns: Object - The "flattened" project, ready to be returned to the requester

Param Type Description
user string The currently logged in user, as specified by datawheel-canon
p Object The project to flatten

pruneThread(user, t) ⇒ Object

Given a user and a thread, prepare the thread to be returned to the requester. This involves a number of operations, including collating likes and reports, rewriting banned content, and deleting certain sensitive keys so they don't leak out through the API

Kind: global function
Returns: Object - the pruned thread

Param Type Description
user Object The logged-in user
t Object the Thread to be pruned