| { | |||||
| "interval": 8000, | |||||
| "disabled": true | |||||
| } |
| }); | }); | ||||
| }, | }, | ||||
| // Set a meta property for slide | |||||
| // Synchronous fs stuff, we don't want races | |||||
| slide_set_meta: function(query, conf, req, respond) { | |||||
| if (!hasargs(query, respond, [ "slide", "key", "val" ])) return; | |||||
| var metafile = pathlib.join(conf.slides, query.slide, "meta.json"); | |||||
| var meta = {}; | |||||
| try { | |||||
| meta = JSON.parse(fs.readFileSync(metafile)); | |||||
| } catch (err) { | |||||
| if (err.code !== "ENOENT") | |||||
| return respond(err); | |||||
| } | |||||
| meta[query.key] = JSON.parse(query.val); | |||||
| try { | |||||
| fs.writeFileSync(metafile, JSON.stringify(meta, null, 4)+"\n"); | |||||
| } catch (err) { | |||||
| respond(err); | |||||
| } | |||||
| slideshow.updateSlides(); | |||||
| respond(); | |||||
| }, | |||||
| // Get meta properties | |||||
| slide_get_meta: function(query, conf, req, respond) { | |||||
| if (!hasargs(query, respond, [ "slide" ])) return; | |||||
| var metafile = pathlib.join(conf.slides, query.slide, "meta.json"); | |||||
| fs.readFile(metafile, (err, res) => { | |||||
| if (err && err.code !== "ENOENT") | |||||
| return respond(err); | |||||
| var obj = {}; | |||||
| if (!err) { | |||||
| obj = JSON.parse(res); | |||||
| } | |||||
| respond(null, obj); | |||||
| }); | |||||
| }, | |||||
| // Create a slide | // Create a slide | ||||
| // Lots of synchronous fs stuff, we don't want races | // Lots of synchronous fs stuff, we don't want races | ||||
| slide_create: function(query, conf, req, respond) { | slide_create: function(query, conf, req, respond) { | ||||
| var newId = pad((parseInt(biggest) + 1).toString(), biggest.length); | var newId = pad((parseInt(biggest) + 1).toString(), biggest.length); | ||||
| var path = pathlib.join(conf.slides, newId); | var path = pathlib.join(conf.slides, newId); | ||||
| var meta = JSON.stringify({ | |||||
| disabled: true | |||||
| }, null, 4) + "\n"; | |||||
| try { | try { | ||||
| fs.mkdirSync(path); | fs.mkdirSync(path); | ||||
| fs.writeFileSync(pathlib.join(path, "index.md"), ""); | fs.writeFileSync(pathlib.join(path, "index.md"), ""); | ||||
| fs.writeFileSync(pathlib.join(path, "meta.json"), meta); | |||||
| } catch (err) { | } catch (err) { | ||||
| return respond(err); | return respond(err); | ||||
| } | } |
| var htmlPre = | var htmlPre = | ||||
| "<html>"+ | "<html>"+ | ||||
| "<head>"+ | |||||
| "<link rel='stylesheet' href='/slide.css'>"+ | |||||
| "<meta charset='utf-8'>"+ | |||||
| "</head>"+ | |||||
| "<body>"+ | |||||
| "<div id='_wrapper'>"; | |||||
| "<head>"+ | |||||
| "<link rel='stylesheet' href='/slide.css'>"+ | |||||
| "<meta charset='utf-8'>"+ | |||||
| "</head>"+ | |||||
| "<body>"+ | |||||
| "<div id='_wrapper'>"; | |||||
| var htmlPost = | var htmlPost = | ||||
| "<script src='/slide.js'></script>"+ | |||||
| "</div>"+ | |||||
| "</body>"+ | |||||
| "<script src='/slide.js'></script>"+ | |||||
| "</div>"+ | |||||
| "</body>"+ | |||||
| "</html>"; | "</html>"; | ||||
| function sendFile(path, res) { | function sendFile(path, res) { | ||||
| }); | }); | ||||
| res.end(); | res.end(); | ||||
| // Serve index if it's already /{name}/ | |||||
| // Serve index if it's already /{name}/ | |||||
| } else { | } else { | ||||
| self.sendIndex(res); | self.sendIndex(res); | ||||
| } | } | ||||
| // Return if the current slide is enabled and valid | // Return if the current slide is enabled and valid | ||||
| function currentEnabled() { | function currentEnabled() { | ||||
| return currentSlide.indexExists() && !currentSlide.disabled; | |||||
| return currentSlide.indexExists() && !currentSlide.meta.disabled; | |||||
| } | } | ||||
| self.getSlideName = getSlideName; | self.getSlideName = getSlideName; |
| e.on = function(name, fn) { | e.on = function(name, fn) { | ||||
| e.addEventListener(name, function(evt) { | e.addEventListener(name, function(evt) { | ||||
| fn.call(e, evt); | |||||
| fn(evt, e); | |||||
| }, false); | }, false); | ||||
| return e; | return e; | ||||
| } | } |
| text-align: center; | text-align: center; | ||||
| height: 24px; | height: 24px; | ||||
| margin-bottom: 12px; | margin-bottom: 12px; | ||||
| position: relative; | |||||
| } | } | ||||
| #root.edit #topBar a { | #root.edit #topBar a { | ||||
| float: left; | |||||
| position: absolute; | |||||
| left: 0px; | |||||
| display: inline-block; | display: inline-block; | ||||
| } | } | ||||
| #root.edit #topBar span { | #root.edit #topBar span { | ||||
| } | } | ||||
| #root.edit #fileList, | #root.edit #fileList, | ||||
| #root.edit #slide > .uploader, | |||||
| #root.edit #slide > .delete, | |||||
| #root.edit #controls, | |||||
| #root.edit #html { | #root.edit #html { | ||||
| margin-bottom: 24px; | margin-bottom: 24px; | ||||
| } | } | ||||
| #root.edit #controls > * { | |||||
| display: inline-block; | |||||
| margin-left: 4px; | |||||
| margin-right: 4px; | |||||
| } | |||||
| #root.edit #html { | #root.edit #html { | ||||
| height: 200px; | height: 200px; | ||||
| resize: vertical; | resize: vertical; |
| var fileListEl; | var fileListEl; | ||||
| var htmlTextEl; | var htmlTextEl; | ||||
| var previewEl; | var previewEl; | ||||
| var metaDisabledEl; | |||||
| function populateFileList() { | function populateFileList() { | ||||
| api("slide_file_list", { slide: slide }, (err, res) => { | api("slide_file_list", { slide: slide }, (err, res) => { | ||||
| }); | }); | ||||
| } | } | ||||
| function populateMeta() { | |||||
| api("slide_get_meta", { slide: slide }, (err, obj) => { | |||||
| if (err) | |||||
| return error(err); | |||||
| metaDisabledEl.checked = !!obj.disabled; | |||||
| }); | |||||
| } | |||||
| elem("div", { id: "slide" }, [ | elem("div", { id: "slide" }, [ | ||||
| elem("div", { id: "topBar" }, [ | elem("div", { id: "topBar" }, [ | ||||
| elem("a", { | elem("a", { | ||||
| fileListEl = elem("div", { id: "fileList" }), | fileListEl = elem("div", { id: "fileList" }), | ||||
| uploadEl({ | |||||
| slide: slide | |||||
| }, populateFileList), | |||||
| elem("div", { id: "controls" }, [ | |||||
| uploadEl({ | |||||
| slide: slide | |||||
| }, populateFileList), | |||||
| elem("button", { | |||||
| className: "delete", | |||||
| innerHTML: "Delete" | |||||
| }).on("click", () => { | |||||
| if (!confirm("Are you sure you want to delete slide "+slide+"?")) | |||||
| return; | |||||
| elem("button", { | |||||
| className: "delete", | |||||
| innerHTML: "Delete" | |||||
| }).on("click", () => { | |||||
| if (!confirm("Are you sure you want to delete slide "+slide+"?")) | |||||
| return; | |||||
| api("slide_delete", { slide: slide }, err => { | |||||
| if (err) | |||||
| return error(err); | |||||
| api("slide_delete", { slide: slide }, err => { | |||||
| if (err) | |||||
| return error(err); | |||||
| setView("main"); | |||||
| }); | |||||
| }), | |||||
| setView("main"); | |||||
| }); | |||||
| }), | |||||
| elem("label", { innerHTML: "Disabled" }, [ | |||||
| metaDisabledEl = elem("input", { | |||||
| type: "checkbox" | |||||
| }).on("change", (evt, el) => { | |||||
| api("slide_set_meta", { | |||||
| slide: slide, | |||||
| key: "disabled", | |||||
| val: JSON.stringify(!!el.checked) | |||||
| }, populateMeta); | |||||
| }) | |||||
| ]), | |||||
| ]), | |||||
| htmlTextEl = elem("textarea", { | htmlTextEl = elem("textarea", { | ||||
| id: "html" | id: "html" | ||||
| }).on("keydown", debounce(() => { | }).on("keydown", debounce(() => { | ||||
| console.log(htmlTextEl.value); | |||||
| api("slide_content_update", { | api("slide_content_update", { | ||||
| slide: slide, | slide: slide, | ||||
| text: htmlTextEl.value | text: htmlTextEl.value | ||||
| ]).appendTo(root); | ]).appendTo(root); | ||||
| populateFileList(); | populateFileList(); | ||||
| populateMeta(); | |||||
| api("slide_meta", { slide: slide }, (err, res) => { | api("slide_meta", { slide: slide }, (err, res) => { | ||||
| if (err) { | if (err) { | ||||
| root.className = name; | root.className = name; | ||||
| views[name].apply(null, args); | views[name].apply(null, args); | ||||
| window.scrollTo(0, 0); | |||||
| } | } | ||||
| route(); | route(); |