From 26f679b2a3b7cecbcdec396f87c1600f0c065e9e Mon Sep 17 00:00:00 2001 From: fatchan Date: Sat, 26 Oct 2019 16:51:54 +1100 Subject: [PATCH] menu and post hiding --- gulp/res/css/style.css | 4 +++ gulp/res/js/hide.js | 15 +++++++--- gulp/res/js/live.js | 63 +++++++++++++++++++++++++++++---------- gulp/res/js/modal.js | 55 ++++++++++++++++++++++++++++++++-- gulp/res/js/progress.js | 24 +++++++-------- gulp/res/js/settings.js | 37 +++++++++++++++++++++++ gulp/res/js/theme.js | 26 +++++++++++----- gulp/res/js/themelist.js | 2 ++ gulpfile.js | 12 +++++++- views/includes/navbar.pug | 1 + views/mixins/modal.pug | 24 +++++++++++---- 11 files changed, 214 insertions(+), 49 deletions(-) create mode 100644 gulp/res/js/settings.js create mode 100644 gulp/res/js/themelist.js diff --git a/gulp/res/css/style.css b/gulp/res/css/style.css index e3844b2d..8817dbda 100644 --- a/gulp/res/css/style.css +++ b/gulp/res/css/style.css @@ -142,6 +142,10 @@ pre { padding: 5px 0; } +#settings { + cursor: pointer; +} + .pages, .live { box-sizing: border-box; padding: 10px; diff --git a/gulp/res/js/hide.js b/gulp/res/js/hide.js index eeb87d0c..376befb6 100644 --- a/gulp/res/js/hide.js +++ b/gulp/res/js/hide.js @@ -24,7 +24,7 @@ window.addEventListener('DOMContentLoaded', (event) => { } const setHidden = (posts, hide) => { - if (posts && posts.length > 0) { + if (posts && posts.length > 0) { for (let i = 0; i < posts.length; i++) { const post = posts[i]; if (!post.dataset) { @@ -48,7 +48,7 @@ window.addEventListener('DOMContentLoaded', (event) => { post.classList.remove('hidden'); } } - } + } } const changeOption = function(e) { @@ -108,12 +108,19 @@ window.addEventListener('DOMContentLoaded', (event) => { if (hidden.has(hiddenKey) || hidden.has(userId)) { post.classList.add('hidden'); } - const menu = post.getElementsByClassName('postmenu'); + const menu = post.querySelector('.postmenu'); +console.log(menu) for (let i = 0; i < menu.children.length; i++) { menu.children[i].originalText = menu.children[i].innerText; } menu.value = ''; - menu[0].addEventListener('change', changeOption, false); + menu.addEventListener('change', changeOption, false); + }); + + window.addEventListener('settingsReady', function(event) { + + //add option here and in modal compiledclient for clearing hide list and unhide all hidden posts + }); }); diff --git a/gulp/res/js/live.js b/gulp/res/js/live.js index 8d35a898..9197962b 100644 --- a/gulp/res/js/live.js +++ b/gulp/res/js/live.js @@ -1,8 +1,20 @@ -window.addEventListener('DOMContentLoaded', (event) => { +if (!localStorage.getItem('live')) { + localStorage.setItem('live', true); +} +let liveEnabled = localStorage.getItem('live') == 'true'; +const isThread = /\/\w+\/thread\/\d+.html/.test(window.location.pathname); +let socket; - const isThread = /\/\w+\/thread\/\d+.html/.test(window.location.pathname); +window.addEventListener('settingsReady', function(event) { //after domcontentloaded - if (isThread) { + const livecolor = document.getElementById('livecolor'); + const livetext = document.getElementById('livetext').childNodes[1]; + const updateLive = (message, color) => { + livecolor.style.backgroundColor = color; + livetext.nodeValue = message; + } + + const startLive = () => { const anchors = document.getElementsByClassName('anchor'); if (anchors.length === 0) { return; //url matches, but on a 404 page so dont bother with the rest @@ -76,21 +88,10 @@ window.addEventListener('DOMContentLoaded', (event) => { const roomParts = window.location.pathname.replace(/\.html$/, '').split('/'); const room = `${roomParts[1]}-${roomParts[3]}`; const thread = document.querySelector('.thread'); - const socket = io({ transports: ['websocket'] }); //no polling - const livecolor = document.getElementById('livecolor'); - const livetext = document.getElementById('livetext').childNodes[1]; - const updateLive = (message, color) => { - livecolor.style.backgroundColor = color; - livetext.nodeValue = message; - } - - let firstConnect = true; + socket = io({ transports: ['websocket'] }); //no polling socket.on('connect', () => { console.log('joined room', room); - if (firstConnect) { - updateLive('Connected for live posts', '#0de600'); - firstConnect = false; - } + updateLive('Connected for live posts', '#0de600'); socket.emit('room', room); }); socket.on('pong', (latency) => { @@ -113,7 +114,37 @@ window.addEventListener('DOMContentLoaded', (event) => { jsonCatchup(); }); socket.on('newPost', newPost); + } + + const toggleLive = () => { + if (isThread) { + if (socket && liveEnabled) { + socket.disconnect(); + updateLive('Live posts disabled', 'red'); + } else if (!socket) { + startLive(); + } else { + socket.connect(); + } + } + liveEnabled = !liveEnabled; + console.log('toggling live posts', liveEnabled); + localStorage.setItem('live', liveEnabled); + } + + //todo + startLive(); + + /* + const liveSetting = document.getElementById('live-setting'); + liveSetting.checked = liveEnabled; + liveSetting.addEventListener('change', toggleLive, false); + if (liveEnabled) { + startLive(); + } else { + updateLive('Live posts disabled', 'red'); } + */ }); diff --git a/gulp/res/js/modal.js b/gulp/res/js/modal.js index cef68b05..d3f62edb 100644 --- a/gulp/res/js/modal.js +++ b/gulp/res/js/modal.js @@ -1,7 +1,12 @@ +function pug_attr(t,e,n,r){if(!1===e||null==e||!e&&("class"===t||"style"===t))return"";if(!0===e)return" "+(r?t:t+'="'+t+'"');var f=typeof e;return"object"!==f&&"function"!==f||"function"!=typeof e.toJSON||(e=e.toJSON()),"string"==typeof e||(e=JSON.stringify(e),n||-1===e.indexOf('"'))?(n&&(e=pug_escape(e))," "+t+'="'+e+'"'):" "+t+"='"+e.replace(/'/g,"'")+"'"} function pug_escape(e){var a=""+e,t=pug_match_html.exec(a);if(!t)return e;var r,c,n,s="";for(r=t.index,c=0;r]/;function modal(locals) {var pug_html = "", pug_mixins = {}, pug_interp;;var locals_for_with = (locals || {});(function (modal) {pug_mixins["modal"] = pug_interp = function(data){ +var pug_has_own_property=Object.prototype.hasOwnProperty; +var pug_match_html=/["&<>]/; +function pug_style(r){if(!r)return"";if("object"==typeof r){var t="";for(var e in r)pug_has_own_property.call(r,e)&&(t=t+e+":"+r[e]+";");return t}return r+""}function modal(locals) {var pug_html = "", pug_mixins = {}, pug_interp;;var locals_for_with = (locals || {});(function (modal) {pug_mixins["modal"] = pug_interp = function(data){ var block = (this && this.block), attributes = (this && this.attributes) || {}; -pug_html = pug_html + "\u003Cdiv class=\"modal-bg\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal\"\u003E\u003Cdiv class=\"row\"\u003E\u003Cp class=\"bold\"\u003E" + (pug_escape(null == (pug_interp = data.title) ? "" : pug_interp)) + "\u003C\u002Fp\u003E\u003Ca class=\"close postform-style\" id=\"modalclose\"\u003EX\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"row\"\u003E\u003Cul class=\"nomarks\"\u003E"; +pug_html = pug_html + "\u003Cdiv" + (" class=\"modal-bg\""+pug_attr("style", pug_style(data.hidden?'display:none':''), true, false)) + "\u003E\u003C\u002Fdiv\u003E\u003Cdiv" + (" class=\"modal\""+pug_attr("style", pug_style(data.hidden?'display:none':''), true, false)) + "\u003E\u003Cdiv class=\"row\"\u003E\u003Cp class=\"bold\"\u003E" + (pug_escape(null == (pug_interp = data.title) ? "" : pug_interp)) + "\u003C\u002Fp\u003E\u003Ca class=\"close postform-style\" id=\"modalclose\"\u003EX\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"row\"\u003E"; +if (data.message || data.messages || data.error || data.errors) { +pug_html = pug_html + "\u003Cul class=\"nomarks\"\u003E"; if (data.message) { pug_html = pug_html + "\u003Cli\u003E" + (pug_escape(null == (pug_interp = data.message) ? "" : pug_interp)) + "\u003C\u002Fli\u003E"; } @@ -48,6 +53,50 @@ pug_html = pug_html + "\u003Cli\u003E" + (pug_escape(null == (pug_interp = error }).call(this); } -pug_html = pug_html + "\u003C\u002Ful\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E"; +pug_html = pug_html + "\u003C\u002Ful\u003E"; +} +else +if (data.settings) { +pug_html = pug_html + "\u003Cdiv class=\"form-wrapper flexleft mt-10\"\u003E\u003Cdiv class=\"row\"\u003E\u003Cdiv class=\"label\"\u003EMain Theme\u003C\u002Fdiv\u003E\u003Cselect id=\"theme-changer\" name=\"theme\"\u003E\u003Coption value=\"default\"\u003Edefault\u003C\u002Foption\u003E"; +// iterate data.settings.themes +;(function(){ + var $$obj = data.settings.themes; + if ('number' == typeof $$obj.length) { + for (var pug_index2 = 0, $$l = $$obj.length; pug_index2 < $$l; pug_index2++) { + var theme = $$obj[pug_index2]; +pug_html = pug_html + "\u003Coption" + (pug_attr("value", theme, true, false)) + "\u003E" + (pug_escape(null == (pug_interp = theme) ? "" : pug_interp)) + "\u003C\u002Foption\u003E"; + } + } else { + var $$l = 0; + for (var pug_index2 in $$obj) { + $$l++; + var theme = $$obj[pug_index2]; +pug_html = pug_html + "\u003Coption" + (pug_attr("value", theme, true, false)) + "\u003E" + (pug_escape(null == (pug_interp = theme) ? "" : pug_interp)) + "\u003C\u002Foption\u003E"; + } + } +}).call(this); + +pug_html = pug_html + "\u003C\u002Fselect\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"row\"\u003E\u003Cdiv class=\"label\"\u003ECode Block Theme\u003C\u002Fdiv\u003E\u003Cselect id=\"code-theme-changer\"\u003E\u003Coption value=\"default\"\u003Edefault\u003C\u002Foption\u003E"; +// iterate data.settings.codeThemes +;(function(){ + var $$obj = data.settings.codeThemes; + if ('number' == typeof $$obj.length) { + for (var pug_index3 = 0, $$l = $$obj.length; pug_index3 < $$l; pug_index3++) { + var theme = $$obj[pug_index3]; +pug_html = pug_html + "\u003Coption" + (pug_attr("value", theme, true, false)) + "\u003E" + (pug_escape(null == (pug_interp = theme) ? "" : pug_interp)) + "\u003C\u002Foption\u003E"; + } + } else { + var $$l = 0; + for (var pug_index3 in $$obj) { + $$l++; + var theme = $$obj[pug_index3]; +pug_html = pug_html + "\u003Coption" + (pug_attr("value", theme, true, false)) + "\u003E" + (pug_escape(null == (pug_interp = theme) ? "" : pug_interp)) + "\u003C\u002Foption\u003E"; + } + } +}).call(this); + +pug_html = pug_html + "\u003C\u002Fselect\u003E\u003C\u002Fdiv\u003E\u003C!--removed until i find a solution to not scrolling without reload--\u003E\u003C!--.row.label Live Post Updates\ninput#live-setting(type='checkbox')--\u003E\u003C\u002Fdiv\u003E"; +} +pug_html = pug_html + "\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E"; }; pug_mixins["modal"](modal);}.call(this,"modal" in locals_for_with?locals_for_with.modal:typeof modal!=="undefined"?modal:undefined));;return pug_html;} \ No newline at end of file diff --git a/gulp/res/js/progress.js b/gulp/res/js/progress.js index 52eba56e..76cd15d2 100644 --- a/gulp/res/js/progress.js +++ b/gulp/res/js/progress.js @@ -1,3 +1,14 @@ +const removeModal = () => { + document.getElementsByClassName('modal')[0].remove(); + document.getElementsByClassName('modal-bg')[0].remove(); +} + +const doModal = (data) => { + const modalHtml = modal({ modal: data }); + document.body.insertAdjacentHTML('afterbegin', modalHtml); + document.getElementById('modalclose').onclick = removeModal; +} + window.addEventListener('DOMContentLoaded', () => { const isThread = /\/\w+\/thread\/\d+.html/.test(window.location.pathname); @@ -9,17 +20,6 @@ window.addEventListener('DOMContentLoaded', () => { return; //no postform on this page } - const doModal = (data) => { - const modalHtml = modal({ modal: data }); - document.body.insertAdjacentHTML('afterbegin', modalHtml); - document.getElementById('modalclose').onclick = closeModal; - } - - const closeModal = () => { - document.getElementsByClassName('modal')[0].remove(); - document.getElementsByClassName('modal-bg')[0].remove(); - } - form.addEventListener('submit', function(event) { event.preventDefault(); submit.disabled = true; @@ -49,7 +49,7 @@ window.addEventListener('DOMContentLoaded', () => { //successful post if (!isThread && xhr.responseURL) { window.location = xhr.responseURL; - } else if (json) { + } else if (socket && socket.connected && json) { window.myPostId = json.postId; window.location.hash = json.postId; } diff --git a/gulp/res/js/settings.js b/gulp/res/js/settings.js new file mode 100644 index 00000000..54933fa1 --- /dev/null +++ b/gulp/res/js/settings.js @@ -0,0 +1,37 @@ +window.addEventListener('DOMContentLoaded', (event) => { + + let settingsModal; + let settingsBg; + + const hideSettings = () => { + settingsModal.style.display = 'none'; + settingsBg.style.display = 'none'; + } + + const openSettings = (data) => { + settingsModal.style.display = 'unset'; + settingsBg.style.display = 'unset'; + } + + const settings = document.getElementById('settings'); + + const modalHtml = modal({ + modal: { + title: 'Settings', + settings: { + themes, codeThemes + }, + hidden: true, + } + }); + + const inserted = document.body.insertAdjacentHTML('afterbegin', modalHtml); + settingsBg = document.getElementsByClassName('modal-bg')[0]; + settingsModal = document.getElementsByClassName('modal')[0]; + + settingsModal.getElementsByClassName('close')[0].onclick = hideSettings; + settings.onclick = openSettings; + + window.dispatchEvent(new CustomEvent('settingsReady')); + +}); diff --git a/gulp/res/js/theme.js b/gulp/res/js/theme.js index 70633ce1..5e4109c5 100644 --- a/gulp/res/js/theme.js +++ b/gulp/res/js/theme.js @@ -1,14 +1,17 @@ -function changeTheme(e) { +function changeTheme(e, type) { //is this the initial load, or an event from changing theme dropdown - let theme = e ? this.value : localStorage.getItem('theme'); + if (!type) { + type = this.id === 'theme-changer' ? 'theme' : 'codetheme'; + } + let theme = e ? this.value : localStorage.getItem(type); //first visit, set theme to default if (!theme) { theme = 'default'; } //add theme setting to localstorage - localStorage.setItem('theme', theme); + localStorage.setItem(type, theme); //check for theme style tag - let tempLink = document.getElementById('customtheme'); + let tempLink = document.getElementById(`custom${type}`); if (theme === 'default') { if (tempLink) { //remove theme style tag if we switching to default @@ -16,7 +19,7 @@ function changeTheme(e) { } } else { //path of the theme css - const path = '/css/themes/'+theme+'.css'; + const path = `/css/${type}s/${theme}.css`; //get the raw css from localstorage let css = localStorage.getItem(path); if (!tempLink) { @@ -31,7 +34,7 @@ function changeTheme(e) { //then createa new link rel=stylesheet, and load the css const themeLink = document.createElement('link'); themeLink.rel = 'stylesheet'; - themeLink.id = 'customtheme'; + themeLink.id = `custom${type}`; themeLink.onload = function() { css = ''; const rulesName = themeLink.sheet.rules != null ? 'rules' : 'cssRules'; //browser compatibility shit @@ -49,13 +52,20 @@ function changeTheme(e) { } } -changeTheme(); +changeTheme(null, 'theme'); +changeTheme(null, 'codetheme'); -window.addEventListener('DOMContentLoaded', (event) => { +window.addEventListener('settingsReady', function(event) { + //for main theme const themePicker = document.getElementById('theme-changer'); themePicker.value = localStorage.getItem('theme') + //for code theme + const codeThemePicker = document.getElementById('code-theme-changer'); + codeThemePicker.value = localStorage.getItem('codetheme') + themePicker.addEventListener('change', changeTheme, false); + codeThemePicker.addEventListener('change', changeTheme, false); }); diff --git a/gulp/res/js/themelist.js b/gulp/res/js/themelist.js new file mode 100644 index 00000000..9c205ede --- /dev/null +++ b/gulp/res/js/themelist.js @@ -0,0 +1,2 @@ +const themes = ['choc', 'gurochan', 'lain', 'makaba', 'navy', 'rei-zero', 'sushi', 'tomorrow', 'yotsuba b', 'yotsuba'] +const codeThemes = ['a11y-dark', 'a11y-light', 'agate', 'an-old-hope', 'androidstudio', 'arduino-light', 'arta', 'ascetic', 'atelier-cave-dark', 'atelier-cave-light', 'atelier-dune-dark', 'atelier-dune-light', 'atelier-estuary-dark', 'atelier-estuary-light', 'atelier-forest-dark', 'atelier-forest-light', 'atelier-heath-dark', 'atelier-heath-light', 'atelier-lakeside-dark', 'atelier-lakeside-light', 'atelier-plateau-dark', 'atelier-plateau-light', 'atelier-savanna-dark', 'atelier-savanna-light', 'atelier-seaside-dark', 'atelier-seaside-light', 'atelier-sulphurpool-dark', 'atelier-sulphurpool-light', 'atom-one-dark-reasonable', 'atom-one-dark', 'atom-one-light', 'brown-paper', 'brown-papersq', 'codepen-embed', 'color-brewer', 'darcula', 'dark', 'darkula', 'default', 'docco', 'dracula', 'far', 'foundation', 'github-gist', 'github', 'gml', 'googlecode', 'grayscale', 'gruvbox-dark', 'gruvbox-light', 'hopscotch', 'hybrid', 'idea', 'ir-black', 'isbl-editor-dark', 'isbl-editor-light', 'kimbie.dark', 'kimbie.light', 'lightfair', 'magula', 'mono-blue', 'monokai-sublime', 'monokai', 'nord', 'obsidian', 'ocean', 'paraiso-dark', 'paraiso-light', 'pojoaque', 'pojoaque', 'purebasic', 'qtcreator_dark', 'qtcreator_light', 'railscasts', 'rainbow', 'routeros', 'school-book', 'school-book', 'shades-of-purple', 'solarized-dark', 'solarized-light', 'sunburst', 'tomorrow-night-blue', 'tomorrow-night-bright', 'tomorrow-night-eighties', 'tomorrow-night', 'tomorrow', 'vs', 'vs2015', 'xcode', 'xt256', 'zenburn'] \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index f510593d..1ade1572 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -148,6 +148,9 @@ function custompages() { function scripts() { try { + const themelist = `const themes = ['${themes.join("', '")}'] +const codeThemes = ['${codeThemes.join("', '")}']`; + fs.writeFileSync('gulp/res/js/themelist.js', themelist); fs.writeFileSync('gulp/res/js/post.js', pug.compileFileClient(`${paths.pug.src}/includes/post.pug`, { compileDebug: false, debug: false, name: 'post' })); fs.writeFileSync('gulp/res/js/modal.js', pug.compileFileClient(`${paths.pug.src}/includes/modal.pug`, { compileDebug: false, debug: false, name: 'modal' })); fs.symlinkSync(__dirname+'/node_modules/socket.io-client/dist/socket.io.js', __dirname+'/gulp/res/js/socket.io.js', 'file'); @@ -155,7 +158,14 @@ function scripts() { console.log(e); //already exists, ignore error } - gulp.src(`${paths.scripts.src}/*.js`) + gulp.src([ + `${paths.scripts.src}/themelist.js`, + `${paths.scripts.src}/modal.js`, + `${paths.scripts.src}/settings.js`, + `${paths.scripts.src}/hide.js`, + `${paths.scripts.src}/live.js`, + `${paths.scripts.src}/*.js` + ]) .pipe(concat('all.js')) .pipe(uglify()) .pipe(gulp.dest(paths.scripts.dest)); diff --git a/views/includes/navbar.pug b/views/includes/navbar.pug index 637e6bcf..2ab16bc9 100644 --- a/views/includes/navbar.pug +++ b/views/includes/navbar.pug @@ -4,3 +4,4 @@ nav.navbar#top a.nav-item(href='/boards.html') Boards a.nav-item(href=`/${board ? board._id+'/manage/reports' : 'globalmanage/reports'}.html`) Manage a.nav-item(href='/create.html') Create + a.jsonly.nav-item.right#settings ⚙ diff --git a/views/mixins/modal.pug b/views/mixins/modal.pug index d5ee8de7..1fb43a6d 100644 --- a/views/mixins/modal.pug +++ b/views/mixins/modal.pug @@ -1,6 +1,6 @@ mixin modal(data) - .modal-bg - .modal + .modal-bg(style=data.hidden?'display:none':'') + .modal(style=data.hidden?'display:none':'') .row p.bold #{data.title} a.close.postform-style#modalclose X @@ -18,6 +18,20 @@ mixin modal(data) each error in data.errors li #{error} else if data.settings - each setting in settings - //settings here - + .form-wrapper.flexleft.mt-10 + .row + .label Main Theme + select#theme-changer(name='theme') + option(value='default') default + each theme in data.settings.themes + option(value=theme) #{theme} + .row + .label Code Block Theme + select#code-theme-changer + option(value='default') default + each theme in data.settings.codeThemes + option(value=theme) #{theme} + //removed until i find a solution to not scrolling without reload + //.row + .label Live Post Updates + input#live-setting(type='checkbox')