-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Keep state of the Rust Playgrounds when navigating between slides #1476
Comments
I would like to help with it. |
Hi @jnovikov, that would be awesome! I hope the idea is somewhat clear, otherwise please let me know 😄 The problem right now is that using Arrow-Left or Arrow-Right (or clicking links) navigates away from the current slide: when you navigate back, the playground is back at its initial state. The idea is to prevent this by storing the state in local storage. I don't know much about the editor here, except that |
Hey @mgeisler , I would like to give a try .If it Is still open. |
It's all yours! I'm not sure anyone has in mind a good way to do this, so the first step is coming up with an idea.. |
I looked at it there is a I will store all children's of that Then I will make a object with the URL as key and array of html elements as value. I will store that array of objects (Assuming user make changes in all playgrounds) in browser local storage. Every time loads the page, I will check the object is that url present in that key. If present then I will display object value code. else I will start assigning that code to new key in the object. Process of displaying code : |
That sounds like it will work -- try it out! |
May be few steps will change. I will come up with code tommarow. |
Is it okay to use indexedDb(Browser storage) to store data. Because , I cannot store HTML tags in local storage. |
I think either IndexdDB or LocalStorage is fine. I suspect it only needs to store text (the code in the playground) and not HTML, right? |
Yes, now, I am storing text instead of html elements. |
function setCodeToPlayground(){
const code = JSON.parse(localStorage.getItem(window.location.href));
console.log(code)
if(code){
const playground = document.getElementsByClassName('ace_text-layer')[0]
while (playground.lastElementChild) {
console.log(playground.lastElementChild.innerHTML.replace('<span>','^').replace('</span>',"^").replace(/\s+/g, '').split('^'))
playground.removeChild(playground.lastElementChild);
}
console.log(playground,"after removal")
for(let i = 0; i < code.length; i++){
let parentDiv = code[i][0]
let spanChild = code[i][1]
let div = document.createElement(parentDiv.tag)
div.style.height = "17.5938px"
div.style.top = `${17.5938*i}px`
for(let cls in parentDiv.classes){
div.classList.add(parentDiv.classes[cls])
}
for(let j = 0;j<spanChild.length;j++){
//console.log(spanChild[j].styles,typeof(spanChild[j].styles))
let span = document.createElement(spanChild[j].tag)
//span.classList = spanChild[j].classes
for(let cls in spanChild[j].classes){
span.classList.add(spanChild[j].classes[cls])
}
span.innerText = spanChild[j].text
div.insertBefore(span,div.lastChild)
}
playground.insertBefore(div,playground.lastChild)
}
}
localStorage.removeItem(window.location.href)
}
window.onunload = setTimeout(setCodeToPlayground,5000)
function getCodeFromPlayground() {
console.log("getCodeFromPlayground")
const playground = document.getElementsByClassName('ace_text-layer')[0].children
var code = []
for (let i = 0; i < playground.length; i++) {
let parentCodeList = {
tag : playground[i].tagName,
classes : playground[i].classList,
styles : playground[i].style
}
var line = []
for(let j = 0; j < playground[i].children.length; j++) {
console.log(playground[i].innerHTML)
let codeList = {
tag : playground[i].children[j].tagName,
text: playground[i].children[j].innerText,
classes : playground[i].children[j].classList,
styles : playground[i].children[j].style,
}
line.push(codeList)
}
code.push([parentCodeList,line])
}
console.log(code)
//localStorage.removeItem(window.location.href)
localStorage.setItem(window.location.href,JSON.stringify(code))
}
addEventListener('beforeunload',getCodeFromPlayground()) Need some help with this code . If any one can. |
Updated code. |
Getting problem with word without span tag. every word as a specific span tag except variables and print keyword.Missing those words without span tag. |
Can you push a draft PR that we could experiment with? |
Sure on it. |
It seems like the text editor widget (ace_text) should have some API for getting/setting text contents, rather than digging around in its internal markup. From the docs, it looks like these suffice: While teaching I rely on being able to reset the code samples to their original contents (both while discussing a slide and before teaching the course a second time), so I'd like to make sure there's still a straightforward way to do so before this lands. |
(moving this conversation to the PR, #1917) |
Hello @djmitche , still any thing needed to add to close this issue. |
I don't think so! |
Cc @djmitche, @fw-immunant, and @mani-chand. I merged this now so I can ensure the course works for the class I'm teaching in ~12 hours. I only saw this after browsing around on the site for 30 minutes or so. I don't really know why it would happen, but I guess the event that saves the playgrounds is unreliable. I would suggest looking into saving the state on changes to the playgrounds instead of trying to detect navigating away from the pages. I've seen problems with detecting the I ran into another problem: clearing saved playground data doesn't fully work. Navigating away from the current page will save the playgrounds on the page again. Originally posted by @mgeisler in #1935 (comment) |
LocalState is limited in the amount of storage a site is allowed. I think that's 5MB? That might be part of the issue. Docs on pagehide agree that it's unreliable, but I think it's better than |
on 2nd point.
When you reset the playground it will clear all including the current page but when you leave the current page |
1st point |
For onchange of innerText https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver. It looks good. What do you say? @djmitche @mgeisler |
I think all our codes doesn't consume even 3mb because they are only strings. |
Yeah, my quic mental math also suggested we weren't using 5MB. I think the ACE editor has its own events which would probably be better to listen to instead of the underlying DOM events. Will updating LocalStorage on every keypress be too slow? |
This is great. I think we can trust it. |
You really think my brain will know or understand |
I think this problem will also gets solved. If someone clears the playground and navigate to another page without changing playground code then it will won't save. |
Sorry! I've been working on QUIC things for a few months now and my fingers type that instead of "quick". It is, indeed, kind of 🤯! |
Leave it, Atleast I have learnt about it because of that message. |
#1476 issue. Updated the function call(`getCodeFromPlayground`) in `save-playground.js` file from `pagehide` event to change event in ace editor. --------- Co-authored-by: Martin Geisler <mgeisler@google.com>
Today, the embedded Playgrounds are reset when you navigate between slides. This has caused problems: if people navigate away from a slide to look something up, they've suddenly lost their work.
This is actually the reason why we don't make the exercises editable directly in the slides: too many people have lost work because of this.
We should be able to store the current state in the browser's local storage.
The text was updated successfully, but these errors were encountered: