From 0f3b3d527da2e1705acf4422623548fa5ab3a176 Mon Sep 17 00:00:00 2001 From: Darius Rapalis Date: Sat, 17 Sep 2022 22:54:24 +0300 Subject: [PATCH] Updates... --- extension/manifest.json | 3 +- extension/twitch-notes.js | 2 +- src/CustomHTMLElement.ts | 168 ------ src/HTMLBuilder.ts | 23 +- src/HTMLElements/TwitchButton.ts | 30 + src/HTMLElements/TwitchCloseButton.ts | 31 + src/HTMLElements/TwitchNotesImport.ts | 113 ++++ src/HTMLElements/TwitchNotesImportResolve.ts | 76 +++ src/HTMLElements/TwitchNotesWindow.ts | 259 ++++++++ src/Mouse.ts | 2 +- src/NoteContainers.ts | 26 +- src/TwitchNote.ts | 40 +- src/importNotesConflictResolve.ts | 156 ++--- src/importNotesResult.ts | 104 ++-- src/openAllNoteListWindow.ts | 241 ++++---- src/openClearDataWindow.ts | 64 +- src/openImprtNotesWindow.ts | 117 ++-- src/openTwitchNote.ts | 12 +- src/styles/main.scss | 585 ++++++++++--------- src/toggleSettingsList.ts | 90 +-- src/types.ts | 14 +- 21 files changed, 1246 insertions(+), 910 deletions(-) delete mode 100644 src/CustomHTMLElement.ts create mode 100644 src/HTMLElements/TwitchButton.ts create mode 100644 src/HTMLElements/TwitchCloseButton.ts create mode 100644 src/HTMLElements/TwitchNotesImport.ts create mode 100644 src/HTMLElements/TwitchNotesImportResolve.ts create mode 100644 src/HTMLElements/TwitchNotesWindow.ts diff --git a/extension/manifest.json b/extension/manifest.json index ec5e4b6..6e8351b 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -39,6 +39,5 @@ "*://*.twitch.tv/*" ] } - ], - "permissions": ["webNavigation"] + ] } diff --git a/extension/twitch-notes.js b/extension/twitch-notes.js index 75ea943..d4beb5f 100644 --- a/extension/twitch-notes.js +++ b/extension/twitch-notes.js @@ -1 +1 @@ -(()=>{"use strict";var t={144:(t,e,n)=>{n.d(e,{Z:()=>a});var o=n(81),i=n.n(o),r=n(645),s=n.n(r)()(i());s.push([t.id,".twitch-note-container{position:fixed;z-index:1000000;min-width:420px;max-width:95vw;min-height:240px;max-height:50vh;background:var(--color-background-base);border:var(--border-width-default) solid var(--color-border-base) !important}.twitch-note-header{width:100%;height:32px;line-height:32px;border-bottom:var(--border-width-default) solid var(--color-border-base) !important;position:relative;cursor:move}.twitch-note-title{color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;padding-left:calc((32px - var(--font-size-6))/2)}.twitch-note-close-button{position:absolute;right:5px;top:5px;width:22px;height:22px;line-height:22px;text-align:center;aspect-ratio:1;color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;cursor:pointer}.twitch-note-content{position:absolute;top:32px;left:0;right:0;bottom:32px;background:rgba(0,0,0,0);color:var(--color-text-base) !important;font-family:var(--font-base);vertical-align:baseline;outline:none;overflow:auto;padding:calc((32px - var(--font-size-6))/2)}.twitch-note-save-button{position:absolute;bottom:0;left:0;right:0;height:32px;border-top:var(--border-width-default) solid var(--color-border-base) !important;cursor:pointer;color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;text-align:center;line-height:32px}.twitch-notes-settings-button{z-index:var(--z-index-default) !important;position:relative !important;background-color:var(--color-background-button-primary-default);color:var(--color-text-button-primary);text-decoration:none;cursor:pointer;display:inline-flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;vertical-align:middle;overflow:hidden;white-space:nowrap;user-select:none;font-weight:var(--font-weight-semibold);border-radius:var(--border-radius-medium);font-size:var(--button-text-default);height:var(--button-size-default);padding:0 var(--button-padding-x)}.twitch-notes-settings-button__outline{background:rgba(0,0,0,0);border:2px solid var(--color-text-button-primary)}.twitch-notes-settings-container{border:0;font:inherit;padding:0;vertical-align:baseline;position:fixed;z-index:var(--z-index-balloon);inset:auto 0 0 auto;margin:0 69px 48px 0}.twitch-notes-settings-balloon{display:inline-block;max-width:90vw;min-width:0;white-space:nowrap;border-radius:.6rem !important;background-color:var(--color-background-base) !important;box-shadow:var(--shadow-elevation-2) !important;color:inherit !important}.twitch-notes-settings-popover{white-space:normal;width:32rem}.twitch-notes-settings-header{display:flex !important;-webkit-box-align:center !important;align-items:center !important;position:relative !important;padding-left:1rem !important;padding-right:1rem !important;background-color:var(--color-background-base) !important;min-height:4rem}.twitch-notes-settings-header-left-element{left:0 !important;margin-right:.5rem !important;width:3rem}.twitch-notes-settings-header-center-element{-webkit-box-align:center !important;align-items:center !important;display:flex !important;text-align:center !important;-webkit-box-flex:1 !important;flex-grow:1 !important;-webkit-box-pack:center !important;justify-content:center !important}.twitch-notes-settings-header-center-element-content{line-height:1.5;color:var(--color-text-alt) !important;font-size:var(--font-size-5) !important;font-weight:var(--font-weight-semibold) !important}.twitch-notes-settings-header-right-element{right:0 !important;margin-left:.5rem !important}.twitch-notes-settings-close-button{cursor:default;text-transform:none;text-indent:0;text-shadow:none;letter-spacing:normal;text-rendering:auto;appearance:auto;writing-mode:horizontal-tb !important;box-sizing:border-box;margin:0;font:inherit;border:none;font-size:var(--button-text-default);font-weight:var(--font-weight-semibold);vertical-align:middle;overflow:hidden;text-decoration:none;white-space:nowrap;position:relative;display:inline-flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;user-select:none;border-radius:var(--border-radius-medium);height:calc(var(--button-size-default) - 1rem);width:calc(var(--button-size-default) - 1rem);background-color:var(--color-background-button-text-default);color:var(--color-fill-button-icon)}.twitch-notes-settings-scrollable-area{display:flex;overflow:hidden;z-index:0;height:100%;position:relative;max-height:478px}.twitch-notes-settings-content{box-sizing:content-box;min-width:100%;overflow-x:hidden;overflow-y:auto;max-height:inherit !important;margin:1rem;padding-bottom:0 !important}.twitch-notes-settings-option-line{position:relative !important;width:calc(100% - 2rem) !important}.twitch-notes-settings-option-line-button{border-radius:var(--border-radius-medium);display:block;width:100%;color:inherit}.twitch-notes-settings-option-line-button:hover{cursor:pointer;text-decoration:none;color:inherit;background-color:var(--color-background-interactable-hover)}.twitch-notes-settings-option-line-button-container{display:flex !important;-webkit-box-align:center !important;align-items:center !important;position:relative !important;padding:.5rem !important}.twitch-notes-settings-option-line-button-container-content{-webkit-box-flex:1 !important;flex-grow:1 !important}.twitch-note-settings-separator{border-top:1px solid var(--color-border-base);margin-top:1rem !important;margin-left:.5rem !important;margin-right:.5rem !important;padding-bottom:1rem !important}.twitch-notes-x-button{position:absolute;left:0;width:100%;min-height:100%;top:0;fill:currentcolor}.twitch-notes-blurred-background{position:fixed;inset:0 0 0 0;z-index:2000000;background:rgba(0,0,0,.4);backdrop-filter:blur(2px)}.twitch-notes-center-floating-container{background:var(--color-background-base);border:var(--border-width-default) solid var(--color-border-base) !important;padding:4rem 2rem 2rem;position:fixed;top:50vh;left:50vw;transform:translate(-50%, -50%);max-height:90vh;max-width:90vw;overflow:auto}.twitch-notes-user-list-user{padding:1rem;border-bottom:var(--border-width-default) solid var(--color-border-base) !important;cursor:pointer}.twitch-notes-user-list-user[data-active]{background:rgba(119,44,232,.2)}",""]);const a=s},645:t=>{t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n="",o=void 0!==e[5];return e[4]&&(n+="@supports (".concat(e[4],") {")),e[2]&&(n+="@media ".concat(e[2]," {")),o&&(n+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),n+=t(e),o&&(n+="}"),e[2]&&(n+="}"),e[4]&&(n+="}"),n})).join("")},e.i=function(t,n,o,i,r){"string"==typeof t&&(t=[[null,t,void 0]]);var s={};if(o)for(var a=0;a0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=r),n&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=n):d[2]=n),i&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=i):d[4]="".concat(i)),e.push(d))}},e}},81:t=>{t.exports=function(t){return t[1]}},379:t=>{var e=[];function n(t){for(var n=-1,o=0;o{var e={};t.exports=function(t,n){var o=function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(t){n=null}e[t]=n}return e[t]}(t);if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(n)}},216:t=>{t.exports=function(t){var e=document.createElement("style");return t.setAttributes(e,t.attributes),t.insert(e,t.options),e}},565:(t,e,n)=>{t.exports=function(t){var e=n.nc;e&&t.setAttribute("nonce",e)}},795:t=>{t.exports=function(t){var e=t.insertStyleElement(t);return{update:function(n){!function(t,e,n){var o="";n.supports&&(o+="@supports (".concat(n.supports,") {")),n.media&&(o+="@media ".concat(n.media," {"));var i=void 0!==n.layer;i&&(o+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),o+=n.css,i&&(o+="}"),n.media&&(o+="}"),n.supports&&(o+="}");var r=n.sourceMap;r&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(r))))," */")),e.styleTagTransform(o,t,e.options)}(e,t,n)},remove:function(){!function(t){if(null===t.parentNode)return!1;t.parentNode.removeChild(t)}(e)}}}},589:t=>{t.exports=function(t,e){if(e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}}},e={};function n(o){var i=e[o];if(void 0!==i)return i.exports;var r=e[o]={id:o,exports:{}};return t[o](r,r.exports,n),r.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.nc=void 0,(()=>{var t=n(379),e=n.n(t),o=n(795),i=n.n(o),r=n(569),s=n.n(r),a=n(565),l=n.n(a),c=n(216),d=n.n(c),u=n(589),p=n.n(u),h=n(144),m={};m.styleTagTransform=p(),m.setAttributes=l(),m.insert=s().bind(null,"head"),m.domAPI=i(),m.insertStyleElement=d(),e()(h.Z,m),h.Z&&h.Z.locals&&h.Z.locals;var v="twitch-note-all-users-list",f="twitch-note-";const g=function(){function t(){}return t.getSavedUserList=function(){return JSON.parse(localStorage.getItem(v)||"[]")},t.getNote=function(t){return localStorage.getItem(f+t)||""},t.addUserToSavedList=function(t){var e=this.getSavedUserList();e.includes(t)||(e.push(t),localStorage.setItem(v,JSON.stringify(e)))},t.removeUserFromSavedList=function(t){var e=this.getSavedUserList();(e=e.filter((function(e){return e!==t}))).length?localStorage.setItem(v,JSON.stringify(e)):localStorage.removeItem(v)},t.saveNote=function(t,e){this.addUserToSavedList(t),localStorage.setItem(f+t,e)},t.deleteNote=function(t){this.removeUserFromSavedList(t),localStorage.removeItem(f+t)},t.exportNotes=function(){var t=this,e={users:this.getSavedUserList(),notes:this.getSavedUserList().map((function(e){return{user:e,note:t.getNote(e)}})),settings:{}},n=JSON.stringify(e),o=new Blob([n],{type:"text/json"}),i=window.document.createElement("a");i.href=window.URL.createObjectURL(o),i.download="twitch-notes-"+Date.now()+".json",document.body.appendChild(i),i.click(),document.body.removeChild(i)},t.clearData=function(){for(var t=0,e=this.getSavedUserList();tNote conflicts found for:
");p.setStyle({marginTop:"1rem"});for(var h=function(n){var o=new C("",n+" "),r=null===(i=g.inputData.notes.find((function(t){return t.user===n})))||void 0===i?void 0:i.resolved;o.setStyle({color:r?"green":"red"});var s=new E("",r?"[update]":"[resolve]");s.setStyle({cursor:"pointer"}),s.setClickListener((function(){!function(t,e,n,o){var i=new C("twitch-notes-blurred-background"),r=new C("twitch-notes-center-floating-container","Select which note to keep for "+t+"
You can modify notes to merge them and keep updated one

"),s=new C;s.setStyle({display:"flex",flexDirection:"row",flexWrap:"no-wrap",width:"100%"});var a={minWidth:"320px",padding:"6px",border:"1px solid #FFFFFF19",outline:"none"},l=["contentEditable","true"],c=new C,d=new L("","Locally saved note");c.appendCustomChild(d);var u=new C;u.setStyle(a),u.addAttribute.apply(u,l),u.setId("local-value-container");var p=new k("twitch-notes-settings-button","Save this");p.setClickListener((function(){var r,s=(null===(r=document.getElementById("local-value-container"))||void 0===r?void 0:r.innerHTML)||"";g.inputData.notes=g.inputData.notes.map((function(e){return e.user===t?{user:e.user,note:s,resolved:!0}:e})),i.remove(),e.remove(),N(n,o)})),c.appendCustomChild(u),c.appendBody("
"),c.appendCustomChild(p);var h=new C,m=new L("","Imported note");h.appendCustomChild(m);var v=new C("",g.inputData.notes.filter((function(e){return e.user===t}))[0].note||"");v.setId("import-value-container"),v.setStyle(a),v.addAttribute.apply(v,l);var f=new k("twitch-notes-settings-button","Save this");f.setClickListener((function(){var r,s=(null===(r=document.getElementById("import-value-container"))||void 0===r?void 0:r.innerHTML)||"";g.inputData.notes=g.inputData.notes.map((function(e){return e.user===t?{user:e.user,note:s,resolved:!0}:e})),i.remove(),e.remove(),N(n,o)})),h.appendCustomChild(v),h.appendBody("
"),h.appendCustomChild(f),s.appendCustomChild(c),s.appendCustomChild(h),r.appendCustomChild(s),i.appendCustomChild(r),document.body.appendChild(i.getElement())}(n,u,t,e)})),o.appendCustomChild(s),p.appendCustomChild(o)},m=0,v=s;mNote will be added for:
"+r.join("
"));f.setStyle({marginTop:"1rem",color:"white"}),u.appendCustomChild(f)}if(a.length){var b=new C("","No changes for:
"+a.join("
"));b.setStyle({marginTop:"1rem",color:"gray"}),u.appendCustomChild(b)}var w=new C;w.setStyle({height:"24px"}),u.appendCustomChild(w),s=s.filter((function(t){var e;return!(null===(e=g.inputData.notes.find((function(e){return e.user===t})))||void 0===e?void 0:e.resolved)}));var y=new k("twitch-notes-settings-button","Complete import");if(y.setStyle({}),s.length>0&&y.setStyle({background:"gray"}),s.length>0&&y.addAttribute("disabled","true"),u.appendCustomChild(y),s.length>0){var x=new C("","Import cannot be completed while there are unresolved conflicts");x.setStyle({color:"gray"}),u.appendCustomChild(x)}else y.setClickListener((function(){for(var t=0,n=g.inputData.notes;t\n \n \n \n '],mouseClickEvent:function(){return D()}}]}]},{element:"div",class:"twitch-notes-settings-scrollable-area",content:[{element:"div",class:"twitch-notes-settings-content",content:[T("Export Notes",(function(){g.exportNotes(),D()})),T("Import Notes",(function(){!function(){var t=new C("twitch-notes-blurred-background"),e=new C("twitch-notes-center-floating-container","WARNING! This action might override existing data!

"),n=new C("","Select exported twitch notes file

"),o=new S("twitch-notes-file-input");o.addAttribute("type","file").addAttribute("accept","json");var i=new k("twitch-notes-settings-close-button",'\n \n \n \n ');i.setStyle({position:"absolute",top:"1rem",right:"1rem"}),n.appendCustomChild(o),i.setClickListener((function(){t.remove()})),o.setChangeListener((function(){var i;if(null===(i=null==o?void 0:o.getElement())||void 0===i?void 0:i.files){var r=o.getElement().files.item(0);if(r){var s=new FileReader;s.readAsText(r,"UTF-8"),s.onload=function(o){var i;(null===(i=null==o?void 0:o.target)||void 0===i?void 0:i.result)&&(g.inputData=JSON.parse(o.target.result.toString()),g.inputData&&(n.setStyle({display:"none"}),N(e,t)))},s.onerror=function(){console.error("error reading file")}}}})),e.appendCustomChild(i),e.appendCustomChild(n),t.appendCustomChild(e),document.body.appendChild(t.getElement())}(),D()})),T("Clear Data",(function(){!function(){var t=new C("twitch-notes-blurred-background"),e=new C("twitch-notes-center-floating-container","This action will delete all saved notes!

Consider exporting notes before performing this action in case you will need to use notes again"),n=new C;n.setStyle({height:"24px"});var o=new k("twitch-notes-settings-button","DELETE ALL NOTES");o.setStyle({background:"red"}),o.setClickListener((function(){g.clearData(),t.remove()}));var i=new k("twitch-notes-settings-button","Cancel");i.setClickListener((function(){t.remove()})),e.appendCustomChild(n),e.appendCustomChild(o),e.appendCustomChild(i),t.appendCustomChild(e),document.body.appendChild(t.getElement())}(),D()})),{element:"div",class:"twitch-note-settings-separator"},T("View All Notes",(function(){!function(){var t="",e=new C("twitch-notes-blurred-background"),n=new M("","Note saved!");n.setStyle({color:"green",marginLeft:"2rem"}),n.hide();var o=new C("twitch-notes-center-floating-container");o.setStyle({padding:"0",paddingTop:"1rem",width:"100%",maxWidth:"800px",height:"calc(320px + 5rem)",maxHeight:"90vh"});var i=new k("twitch-notes-settings-close-button",'\n \n \n \n ');i.setStyle({position:"absolute",top:"1rem",right:"1rem"});var r=new C("twitch-note-title","Notes:");r.setStyle({borderBottom:"1px solid #FFFFFF19",paddingBottom:"1rem"}),o.appendCustomChild(r);var s=new C;s.setStyle({display:"flex",flexDirection:"row",flexWrap:"no-wrap",width:"100%",height:"320px"}),o.appendCustomChild(s),i.setClickListener((function(){e.remove()})),o.appendCustomChild(i);var a=new C;a.setStyle({borderRight:"1px solid #FFFFFF19",height:"320px",minWidth:"240px",overflowY:"auto",overflowX:"hidden"});var l=new C;l.setStyle({height:"320px",padding:"1rem",width:"100%",opacity:"0"});var c=new C;c.setStyle({marginBottom:"3rem",border:"1px solid #FFFFFF19",height:"calc(320px - 7rem)",width:"100%",padding:"6px",outline:"none",overflowY:"auto",overflowX:"hidden"}),c.addAttribute("contentEditable","true");var d=new k("twitch-notes-settings-button","Save Note");d.setStyle({position:"absolute",bottom:"1rem",left:"1rem"}),d.setClickListener((function(){t&&(g.saveNote(t,c.getElement().innerHTML),n.setStyle({display:"inline-block"}))}));for(var u=function(e){var o=new C("twitch-notes-user-list-user",e);o.setClickListener((function(){for(var i,r=document.getElementsByClassName("twitch-notes-user-list-user"),s=0;s\n \n \n \n '],mouseClickEvent:function(){return F.removeContainer(t)}},{element:"span",class:"twitch-note-title",content:[t]}]},{element:"div",class:"twitch-note-content",content:[g.getNote(t)],attributes:{contentEditable:"true"},keyUpEvent:function(t){e=t}},{element:"div",class:"twitch-note-save-button",content:["SAVE"],mouseClickEvent:function(){g.saveNote(t,e),F.removeContainer(t)}}]},o=new U(n);document.body.appendChild(o.getElement()),F.addContainer(t,o)}}(r)},content:[{element:"img",style:{height:"18px",paddingRight:"4px"},attributes:{src:"https://cdn.rdarius.lt/icons/32-id-card.png"}}]});i.insertBefore(s.getElement(),i.firstChild)}},n=0;n{"use strict";var t={144:(t,e,n)=>{n.d(e,{Z:()=>s});var o=n(81),i=n.n(o),r=n(645),a=n.n(r)()(i());a.push([t.id,".twitch-notes_button{z-index:var(--z-index-default) !important;position:relative !important;background-color:var(--color-background-button-primary-default);color:var(--color-text-button-primary);text-decoration:none;cursor:pointer;display:inline-flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;vertical-align:middle;overflow:hidden;white-space:nowrap;user-select:none;font-weight:var(--font-weight-semibold);border-radius:var(--border-radius-medium);font-size:var(--button-text-default);height:var(--button-size-default);padding:0 var(--button-padding-x)}.twitch-notes_button__outline{background:rgba(0,0,0,0);border:2px solid var(--color-text-button-primary)}.twitch-notes_close-button{cursor:default;text-transform:none;text-indent:0;text-shadow:none;letter-spacing:normal;text-rendering:auto;appearance:auto;writing-mode:horizontal-tb !important;box-sizing:border-box;margin:0;font:inherit;border:none;font-size:var(--button-text-default);font-weight:var(--font-weight-semibold);vertical-align:middle;overflow:hidden;text-decoration:none;white-space:nowrap;position:absolute;display:inline-flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;user-select:none;border-radius:var(--border-radius-medium);height:calc(var(--button-size-default) - 1rem);width:calc(var(--button-size-default) - 1rem);background-color:var(--color-background-button-text-default);color:var(--color-fill-button-icon);top:1rem;right:1rem}.twitch-notes_close-button .twitch-notes_x-button{position:absolute;left:0;width:calc(var(--button-size-default) - 1rem);height:calc(var(--button-size-default) - 1rem);top:0;fill:currentcolor}.twitch-notes-floating-container{position:fixed;z-index:1000000;width:320px;height:240px;background:var(--color-background-base);border:var(--border-width-default) solid var(--color-border-base) !important}.twitch-notes-container{position:fixed;z-index:1000000;min-width:500px;max-width:95vw;min-height:240px;max-height:50vh;background:var(--color-background-base);border:var(--border-width-default) solid var(--color-border-base) !important}.twitch-notes-container-header{width:100%;height:calc(var(--button-size-default) + 1rem);line-height:calc(var(--button-size-default) + 1rem);border-bottom:var(--border-width-default) solid var(--color-border-base) !important;position:relative}.twitch-notes-container-header-title{color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;margin-left:calc((32px - var(--font-size-6))/2);width:calc(100% - 2rem)}.twitch-notes-container-content{display:grid;grid-template-columns:240px 1fr}.twitch-notes-container-content-user-list{border-right:1px solid rgba(255,255,255,.0980392157);height:100%;min-width:240px;overflow-y:auto;overflow-x:hidden}.twitch-notes-container-content-user-list-item{padding:1rem;border-bottom:var(--border-width-default) solid var(--color-border-base) !important;cursor:pointer;width:100%;color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important}.twitch-notes-container-content-user-list-item-search{background:rgba(0,0,0,0);outline:none;color:var(--color-fill-button-icon)}.twitch-notes-container-content-note-container-note{min-width:420px;min-height:320px;display:block;margin:1rem;border:var(--border-width-default) solid var(--color-border-base) !important;padding:1rem}.twitch-notes-container-content-note-container-controls{padding:1rem;display:flex;align-content:center}.twitch-notes-container-content-note-container-controls-saved{color:green;padding-left:1rem;line-height:var(--button-size-default)}.twitch-notes-container-footer{display:grid;grid-template-columns:1fr 1fr 1fr;width:100%;border-top:var(--border-width-default) solid var(--color-border-base) !important;padding:1rem;text-align:center}.twitch-notes-header{width:100%;height:32px;line-height:32px;border-bottom:var(--border-width-default) solid var(--color-border-base) !important;position:relative;cursor:move}.twitch-notes--container-header-title{color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;padding-left:calc((32px - var(--font-size-6))/2)}.twitch-notes-title{color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;padding-left:calc((32px - var(--font-size-6))/2)}.twitch-notes-close-button{position:absolute;right:5px;top:5px;width:22px;height:22px;line-height:22px;text-align:center;aspect-ratio:1;color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;cursor:pointer}.twitch-notes-content{position:absolute;top:32px;left:0;right:0;bottom:32px;background:rgba(0,0,0,0);color:var(--color-text-base) !important;font-family:var(--font-base);vertical-align:baseline;outline:none;overflow:auto;padding:calc((32px - var(--font-size-6))/2)}.twitch-notes-save-button{position:absolute;bottom:0;left:0;right:0;height:32px;border-top:var(--border-width-default) solid var(--color-border-base) !important;cursor:pointer;color:var(--color-text-alt) !important;font-size:var(--font-size-6) !important;font-weight:var(--font-weight-semibold) !important;text-transform:uppercase !important;text-align:center;line-height:32px}.twitch-notes-x-button{position:absolute;left:0;width:100%;min-height:100%;top:0;fill:currentcolor}.twitch-notes-blurred-background{position:fixed;inset:0 0 0 0;z-index:2000000;background:rgba(0,0,0,.4);backdrop-filter:blur(2px)}.twitch-notes-center-floating-container{background:var(--color-background-base);border:var(--border-width-default) solid var(--color-border-base) !important;position:fixed;top:50vh;left:50vw;transform:translate(-50%, -50%);min-height:320px;min-width:300px;max-height:90vh;max-width:90vw;overflow:auto}.twitch-notes-link{display:inline-block;-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--color-text-link) !important;line-height:var(--line-height-heading) !important;overflow:hidden !important;text-overflow:ellipsis !important;white-space:normal !important;font-weight:var(--font-weight-semibold) !important}.twitch-notes-link:hover{text-decoration:underline;cursor:pointer}.twitch-notes-grid-col-2{display:grid;grid-template-columns:1fr 1fr;width:100%}",""]);const s=a},645:t=>{t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n="",o=void 0!==e[5];return e[4]&&(n+="@supports (".concat(e[4],") {")),e[2]&&(n+="@media ".concat(e[2]," {")),o&&(n+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),n+=t(e),o&&(n+="}"),e[2]&&(n+="}"),e[4]&&(n+="}"),n})).join("")},e.i=function(t,n,o,i,r){"string"==typeof t&&(t=[[null,t,void 0]]);var a={};if(o)for(var s=0;s0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=r),n&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=n):d[2]=n),i&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=i):d[4]="".concat(i)),e.push(d))}},e}},81:t=>{t.exports=function(t){return t[1]}},379:t=>{var e=[];function n(t){for(var n=-1,o=0;o{var e={};t.exports=function(t,n){var o=function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(t){n=null}e[t]=n}return e[t]}(t);if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(n)}},216:t=>{t.exports=function(t){var e=document.createElement("style");return t.setAttributes(e,t.attributes),t.insert(e,t.options),e}},565:(t,e,n)=>{t.exports=function(t){var e=n.nc;e&&t.setAttribute("nonce",e)}},795:t=>{t.exports=function(t){var e=t.insertStyleElement(t);return{update:function(n){!function(t,e,n){var o="";n.supports&&(o+="@supports (".concat(n.supports,") {")),n.media&&(o+="@media ".concat(n.media," {"));var i=void 0!==n.layer;i&&(o+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),o+=n.css,i&&(o+="}"),n.media&&(o+="}"),n.supports&&(o+="}");var r=n.sourceMap;r&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(r))))," */")),e.styleTagTransform(o,t,e.options)}(e,t,n)},remove:function(){!function(t){if(null===t.parentNode)return!1;t.parentNode.removeChild(t)}(e)}}}},589:t=>{t.exports=function(t,e){if(e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}}},e={};function n(o){var i=e[o];if(void 0!==i)return i.exports;var r=e[o]={id:o,exports:{}};return t[o](r,r.exports,n),r.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.nc=void 0,(()=>{var t=n(379),e=n.n(t),o=n(795),i=n.n(o),r=n(569),a=n.n(r),s=n(565),c=n.n(s),l=n(216),d=n.n(l),u=n(589),p=n.n(u),h=n(144),m={};m.styleTagTransform=p(),m.setAttributes=c(),m.insert=a().bind(null,"head"),m.domAPI=i(),m.insertStyleElement=d(),e()(h.Z,m),h.Z&&h.Z.locals&&h.Z.locals;var v="twitch-note-all-users-list",f="twitch-note-";const g=function(){function t(){}return t.addContainer=function(e,n){t.containers[e]||(t.containers[e]=n)},t.removeContainer=function(e){t.containers[e]&&(t.containers[e].remove(),delete t.containers[e])},t.activeContainer=null,t.containers={},t}();var b=function(){return b=Object.assign||function(t){for(var e,n=1,o=arguments.length;n\n \n \n \n ',this.element.classList.add("twitch-notes_close-button"),t)if("string"==typeof t)this.element.classList.add(t);else for(var e=0,n=t;eSelect which note to keep for "+t+"
You can modify notes to merge them and keep updated one

",{element:"div",class:"twitch-notes-grid-col-2",style:{width:"100%"},content:[{element:"div",content:[{element:"p",content:["Locally saved note",{element:"div",style:i,attributes:r,id:"local-value-container",content:[y.getNote(t)]},"
",{element:"button",class:"twitch-notes_button",content:["Save this"],mouseClickEvent:function(){var i,r=(null===(i=document.getElementById("local-value-container"))||void 0===i?void 0:i.innerHTML)||"";y.inputData.notes=y.inputData.notes.map((function(e){return e.user===t?{user:e.user,note:r,resolved:!0}:e})),a.remove(),e.remove(),k(n,o)}}]}]},{element:"div",content:[{element:"p",content:["Locally saved note",{element:"div",style:i,attributes:r,id:"import-value-container",content:[y.inputData.notes.filter((function(e){return e.user===t}))[0].note||""]},"
",{element:"button",class:"twitch-notes_button",content:["Save this"],mouseClickEvent:function(){var i,r=(null===(i=document.getElementById("import-value-container"))||void 0===i?void 0:i.innerHTML)||"";y.inputData.notes=y.inputData.notes.map((function(e){return e.user===t?{user:e.user,note:r,resolved:!0}:e})),a.remove(),e.remove(),k(n,o)}}]}]}]}]});return a.getElement()}(t,this.element,e,n)),this.element.appendChild(r),document.body.appendChild(this.element)},t.prototype.close=function(){this.element&&this.element.remove(),this.element=void 0},t.open=function(e,n,o){t.instance=new t,t.instance.create(e,n,o)},t}();function k(t,e,n){for(var o,i,r,a=[],s=[],c=[],l=function(t){y.getNote(t)?(null===(o=y.inputData.notes.find((function(e){return e.user===t})))||void 0===o?void 0:o.resolved)||y.getNote(t)!==(null===(i=y.inputData.notes.find((function(e){return e.user===t})))||void 0===i?void 0:i.note)?s.push(t):c.push(t):a.push(t)},d=0,u=y.inputData.users;dNote conflicts found for:
"],style:{marginTop:"1rem"}}),m=function(n){var o=null===(r=y.inputData.notes.find((function(t){return t.user===n})))||void 0===r?void 0:r.resolved;h.addContent({element:"div",content:[n+" ",{element:"a",content:[o?"[update]":"[resolve]"],style:{cursor:"pointer"},mouseClickEvent:function(){E.open(n,t,e)}}],style:{color:o?"green":"red"}})},v=0,f=s;vNote will be added for:
"+a.join("
")],style:{marginTop:"1rem",color:"white"}}),c.length&&p.addContent({element:"div",content:["No changes for:
"+c.join("
")],style:{marginTop:"1rem",color:"gray"}}),p.addContent({element:"div",style:{height:"24px"}}),s=s.filter((function(t){var e;return!(null===(e=y.inputData.notes.find((function(e){return e.user===t})))||void 0===e?void 0:e.resolved)}));var g=new C("Complete import");s.length>0&&(g.element.style.background="gray"),s.length>0&&g.element.setAttribute("disabled","true"),p.addContent(g.element),s.length>0?p.addContent({element:"div",content:["Import cannot be completed while there are unresolved conflicts"],style:{color:"gray"}}):g.element.addEventListener("click",(function(){for(var t=0,o=y.inputData.notes;tWARNING! This action might override existing data!
\n
\n Select exported twitch notes file
\n ";var s=this.element,c=document.createElement("input");c.classList.add("twitch-notes-file-input"),c.setAttribute("type","file"),c.setAttribute("accept","json"),c.addEventListener("change",(function(){if(c.files){var e=c.files.item(0);if(e){var n=new FileReader;n.readAsText(e,"UTF-8"),n.onload=function(e){var n;(null===(n=null==e?void 0:e.target)||void 0===n?void 0:n.result)&&(y.inputData=JSON.parse(e.target.result.toString()),y.inputData&&(c.style.display="none",k(o,s,t.resolveCallback)))},n.onerror=function(){console.error("error reading file")}}}})),a.appendChild(c),this.element.appendChild(o),document.body.appendChild(this.element)},t.prototype.close=function(){this.element&&this.element.remove(),this.element=void 0},t.update=function(){var e;null===(e=t.instance)||void 0===e||e.create()},t.open=function(e){t.resolveCallback=e,t.instance=new t,t.instance.create()},t.close=function(){var e,n;null===(n=null===(e=t.instance)||void 0===e?void 0:e.element)||void 0===n||n.remove(),t.instance=void 0},t}(),N=function(){function t(){this.element=document.createElement("div")}return t.prototype.buildContent=function(t){var e=this;t.innerHTML="";var n=[];this.userList=document.createElement("div"),this.userList.classList.add("twitch-notes-container-content-user-list");var o=document.createElement("div");o.classList.add("twitch-notes-container-content-user-list-item"),o.textContent="+ Add New Note",o.addEventListener("click",(function(){e.newNote(l,n)})),this.userList.appendChild(o);var i=document.createElement("input");i.classList.add("twitch-notes-container-content-user-list-item"),i.classList.add("twitch-notes-container-content-user-list-item-search"),i.placeholder="Search...",i.addEventListener("keyup",(function(){for(var t,e=0,o=n;eThis action will delete all saved notes!

Consider exporting notes before performing this action in case you will need to use notes again",{element:"div",style:{height:"24px"}},{element:"button",class:"twitch-notes_button",content:["DELETE ALL NOTES"],style:{background:"red"},mouseClickEvent:function(){y.clearData(),t.remove(),N.update()}},{element:"button",class:"twitch-notes_button",content:["Cancel"],mouseClickEvent:function(){t.remove()}}]}]}),document.body.appendChild(t.getElement())})),s.appendChild(d),this.element.appendChild(o),document.body.appendChild(this.element)},t.prototype.close=function(){this.element&&this.element.remove(),this.element=void 0},t.update=function(){var e;null===(e=t.instance)||void 0===e||e.create()},t.toggle=function(){if(!t.instance)return t.instance=new t,void t.instance.create();t.instance.element?t.instance.close():t.instance.create()},t}();var S=function(){function t(){}return t.prototype.init=function(t){var e=this;this.chatContainerNode=t,this.startObserver(t),this.addNotesButton(),setTimeout((function(){e.addUserNoteBadges()}),1e3)},t.prototype.startObserver=function(t){var e=this;this.observer&&this.observer.disconnect();var n=!1;this.observer=new MutationObserver((function(t){if(!n)for(var o=0,i=t;o\n \n \n \n '],mouseClickEvent:function(){return g.removeContainer(t)}},{element:"span",class:"twitch-notes-title",content:[t]}]},{element:"div",class:"twitch-notes-content",content:[y.getNote(t)],attributes:{contentEditable:"true"},keyUpEvent:function(t){e=t}},{element:"div",class:"twitch-notes-save-button",content:["SAVE"],mouseClickEvent:function(){y.saveNote(t,e),g.removeContainer(t)}}]},o=new x(n);document.body.appendChild(o.getElement()),g.addContainer(t,o)}}(r)},content:[{element:"img",style:{height:"18px",paddingRight:"4px"},attributes:{src:"https://cdn.rdarius.lt/icons/32-id-card.png"}}]});i.insertBefore(a.getElement(),i.firstChild)}},n=0;n { - - element: HTMLElement; - - constructor(element: string, data: CustomHTMLElementConstructor) { - this.element = document.createElement(element); - - if (data.id) { - this.setId(data.id); - } else { - this.setId(element + '-generated-id-' + Math.floor(Math.random() * 10000000)); - } - - if (data.class) { - if (typeof data.class === "string") { - this.addClass(data.class); - } else { - for (const className of data.class) { - this.addClass(className); - } - } - } - - if (data.attributes) { - for (const key in data.attributes) { - this.addAttribute(key, data.attributes[key]); - } - } - - if (data.css) this.setStyle(data.css); - - if (data.body) typeof data.body === "string" ? this.setBody(data.body) : this.appendChild(data.body); - if (data.customBody) this.appendCustomChild(data.customBody); - } - - setId(id: string): CustomHTMLElement { - this.element.id = id; - return this; - } - - addClass(classes: string): CustomHTMLElement { - this.element.classList.add(classes); - return this; - } - - addAttribute(name: string, value: string): CustomHTMLElement { - this.element.setAttribute(name, value); - return this; - } - - setStyle(attributes: Partial): CustomHTMLElement { - for(let key in attributes) { - this.element.style[key] = attributes[key] || ''; - } - return this; - } - - setBody(body: string): CustomHTMLElement { - this.element.innerHTML = body; - return this; - } - - appendBody(body: string): CustomHTMLElement { - this.element.innerHTML += body; - return this; - } - - appendChild(child: HTMLElement): CustomHTMLElement { - this.element.appendChild(child); - return this; - } - - appendCustomChild(child: CustomHTMLElement): CustomHTMLElement { - this.element.appendChild(child.getElement()); - return this; - } - - getElement(): T { - return this.element as T; - } - - setClickListener(listener: Function): CustomHTMLElement { - this.element.addEventListener('click', () => listener()); - return this; - } - - setChangeListener(listener: Function): CustomHTMLElement { - this.element.addEventListener('change', () => listener()); - return this; - } - - setMouseMoveListener(listener: Function): CustomHTMLElement { - this.element.addEventListener('mousemove', () => listener()); - return this; - } - - setMouseDownListener(listener: Function): CustomHTMLElement { - this.element.addEventListener('mousedown', () => listener()); - return this; - } - - setMouseUpListener(listener: Function): CustomHTMLElement { - this.element.addEventListener('mouseup', () => listener()); - return this; - } - - remove(): void { - this.element.remove(); - } - - show(): CustomHTMLElement { - this.setStyle({ - display: 'unset', - }); - return this; - } - - hide(): CustomHTMLElement { - this.setStyle({ - display: 'none', - }); - return this; - } - -} - -export class CustomDivElement extends CustomHTMLElement { - constructor(className: string = '', content: string = '') { - super('div', {class: className, body: content}); - } -} -export class CustomInputElement extends CustomHTMLElement { - constructor(className: string = '') { - super('input', {class: className}); - } -} - -export class CustomPElement extends CustomHTMLElement { - constructor(className: string = '', content: string = '') { - super('p', {class: className, body: content}); - } -} - -export class CustomButtonElement extends CustomHTMLElement { - constructor(className: string = '', content: string = '') { - super('button', {class: className, body: content}); - } -} - -export class CustomAElement extends CustomHTMLElement { - constructor(className: string = '', content: string = '') { - super('a', {class: className, body: content}); - } -} - -export class CustomSpanElement extends CustomHTMLElement { - constructor(className: string = '', content: string = '') { - super('span', {class: className, body: content}); - } -} - -export class CustomImgElement extends CustomHTMLElement { - constructor(className: string = '', content: string = '') { - super('img', {class: className, body: content}); - } -} \ No newline at end of file diff --git a/src/HTMLBuilder.ts b/src/HTMLBuilder.ts index 669cb8f..8e52892 100644 --- a/src/HTMLBuilder.ts +++ b/src/HTMLBuilder.ts @@ -11,10 +11,11 @@ export default class HTMLBuilder { if (data.attributes) this.setAttributes(data.attributes); if (data.style) this.setStyles(data.style); if (data.mouseClickEvent) this.setMouseClickListener(data.mouseClickEvent); - if (data.mouseMoveEvent) this.setMouseClickListener(data.mouseMoveEvent); - if (data.mouseDownEvent) this.setMouseClickListener(data.mouseDownEvent); - if (data.mouseUpEvent) this.setMouseClickListener(data.mouseUpEvent); + if (data.mouseMoveEvent) this.setMouseMoveListener(data.mouseMoveEvent); + if (data.mouseDownEvent) this.setMouseDownListener(data.mouseDownEvent); + if (data.mouseUpEvent) this.setMouseUpListener(data.mouseUpEvent); if (data.keyUpEvent) this.setKeyUpListener(data.keyUpEvent); + if (data.changeListener) this.setChangeListener(data.changeListener); if (data.content) this.setContent(data.content); } @@ -61,18 +62,22 @@ export default class HTMLBuilder { this.element.addEventListener('click', () => cb()); } - setContent(content: (HTMLBuilderBlock|string)[]) { + setContent(content: (HTMLBuilderBlock|string|HTMLElement)[]) { for (let block of content) { this.addContent(block); } } - addContent(content: HTMLBuilderBlock|string) { + addContent(content: HTMLBuilderBlock|string|HTMLElement) { if (typeof content === 'string') { this.element.innerHTML += content; } else { - const el = new HTMLBuilder(content); - this.element.appendChild(el.element) + if (content instanceof HTMLElement) { + this.element.appendChild(content); + } else { + const el = new HTMLBuilder(content); + this.element.appendChild(el.element) + } } } @@ -92,6 +97,10 @@ export default class HTMLBuilder { this.element.addEventListener('keyup', () => cb(this.element.innerHTML)); } + setChangeListener(cb: Function) { + this.element.addEventListener('change', (e) => cb(e)); + } + getElement() { return this.element; } diff --git a/src/HTMLElements/TwitchButton.ts b/src/HTMLElements/TwitchButton.ts new file mode 100644 index 0000000..f260e05 --- /dev/null +++ b/src/HTMLElements/TwitchButton.ts @@ -0,0 +1,30 @@ +export default class TwitchButton { + + element: HTMLButtonElement; + + constructor(content: string, type: 'default' | 'outline' = 'default', classes: string|string[] = '') { + this.element = document.createElement('button'); + this.element.textContent = content; + + this.element.classList.add('twitch-notes_button'); + if(type === 'outline') { + this.element.classList.add('twitch-notes_button__outline'); + } + + if (classes) { + if (typeof classes === 'string') { + this.element.classList.add(classes); + } else { + for (let className of classes) { + this.element.classList.add(className); + } + } + } + } + + onClick(cb: Function) { + this.element.addEventListener('click', () => cb()); + } + + +} \ No newline at end of file diff --git a/src/HTMLElements/TwitchCloseButton.ts b/src/HTMLElements/TwitchCloseButton.ts new file mode 100644 index 0000000..bf65ad3 --- /dev/null +++ b/src/HTMLElements/TwitchCloseButton.ts @@ -0,0 +1,31 @@ +export default class TwitchCloseButton { + + element: HTMLButtonElement; + + constructor(classes: string|string[] = '') { + this.element = document.createElement('button'); + this.element.innerHTML = ` + + + + `; + + this.element.classList.add('twitch-notes_close-button'); + + if (classes) { + if (typeof classes === 'string') { + this.element.classList.add(classes); + } else { + for (let className of classes) { + this.element.classList.add(className); + } + } + } + } + + onClick(cb: Function) { + this.element.addEventListener('click', () => cb()); + } + + +} \ No newline at end of file diff --git a/src/HTMLElements/TwitchNotesImport.ts b/src/HTMLElements/TwitchNotesImport.ts new file mode 100644 index 0000000..410c16d --- /dev/null +++ b/src/HTMLElements/TwitchNotesImport.ts @@ -0,0 +1,113 @@ +import TwitchCloseButton from "./TwitchCloseButton"; +import NoteStorage from "../NoteStorage"; +// import openImportNotesWindow from "../openImprtNotesWindow"; +import openClearDataWindow from "../openClearDataWindow"; +import TwitchButton from "./TwitchButton"; +import TwitchNotesWindow from "./TwitchNotesWindow"; +import importNotesResult from "../importNotesResult"; +import TwitchNotesImportResolve from "./TwitchNotesImportResolve"; + +export default class TwitchNotesImport { + + private static instance?: TwitchNotesImport; + private element?: HTMLDivElement; + private userList?: HTMLDivElement; + private static resolveCallback?: Function; + + constructor() { + this.element = document.createElement('div'); + } + + private create() { + if (!this.element) { + this.element = document.createElement('div'); + } + + this.element.innerHTML = ''; + + this.element.classList.add('twitch-notes-blurred-background'); + + const closeButton = new TwitchCloseButton(); + closeButton.onClick(() => { + this.close(); + }); + + const container = document.createElement('div'); + container.classList.add('twitch-notes-center-floating-container'); + + const header = document.createElement('div'); + header.classList.add('twitch-notes-container-header'); + + const title = document.createElement('div'); + title.classList.add('twitch-notes-container-header-title'); + title.textContent = 'Import Notes'; + header.appendChild(title); + container.appendChild(header); + header.insertAdjacentElement("beforeend", closeButton.element); + + const content = document.createElement('div'); + content.classList.add('twitch-notes-container-content'); + content.style.display = 'block'; + content.style.padding = '1rem'; + container.appendChild(content); + + content.innerHTML = ` + WARNING! This action might override existing data!
+
+ Select exported twitch notes file
+ `; + + const blurredBackground = this.element; + + const input = document.createElement('input'); + input.classList.add('twitch-notes-file-input'); + input.setAttribute('type', 'file'); + input.setAttribute('accept', 'json'); + input.addEventListener('change', () => { + if (!input.files) return; + // @ts-ignore + let file = input.files.item(0); + if (!file) return; + let reader = new FileReader(); + reader.readAsText(file, "UTF-8"); + reader.onload = function (evt) { + if (!evt?.target?.result) return; + + NoteStorage.inputData = JSON.parse(evt.target.result.toString()); + if (NoteStorage.inputData) { + input.style.display = 'none'; + importNotesResult(container, blurredBackground, TwitchNotesImport.resolveCallback); + } + } + reader.onerror = function () { + console.error("error reading file"); + } + }); + + content.appendChild(input); + + this.element.appendChild(container); + document.body.appendChild(this.element); + } + + private close() { + if (this.element) this.element.remove(); + this.element = undefined; + } + + public static update() { + TwitchNotesImport.instance?.create(); + } + + public static open(cb: Function) { + TwitchNotesImport.resolveCallback = cb; + TwitchNotesImport.instance = new TwitchNotesImport(); + TwitchNotesImport.instance.create(); + } + + public static close() { + TwitchNotesImport.instance?.element?.remove(); + TwitchNotesImport.instance = undefined; + } + +} \ No newline at end of file diff --git a/src/HTMLElements/TwitchNotesImportResolve.ts b/src/HTMLElements/TwitchNotesImportResolve.ts new file mode 100644 index 0000000..8c36d1f --- /dev/null +++ b/src/HTMLElements/TwitchNotesImportResolve.ts @@ -0,0 +1,76 @@ +import TwitchCloseButton from "./TwitchCloseButton"; +import NoteStorage from "../NoteStorage"; +// import openImportNotesWindow from "../openImprtNotesWindow"; +import openClearDataWindow from "../openClearDataWindow"; +import TwitchButton from "./TwitchButton"; +import TwitchNotesWindow from "./TwitchNotesWindow"; +import importNotesResult from "../importNotesResult"; +import importNotesConflictResolve from "../importNotesConflictResolve"; +import HTMLBuilder from "../HTMLBuilder"; + +export default class TwitchNotesImportResolve { + + private static instance?: TwitchNotesImportResolve; + private element?: HTMLDivElement; + + constructor() { + this.element = document.createElement('div'); + } + + private create( + user: string, + parentContainer: HTMLElement, + blurredBackground: HTMLElement + ) { + if (!this.element) { + this.element = document.createElement('div'); + } + + this.element.innerHTML = ''; + + this.element.classList.add('twitch-notes-blurred-background'); + + const closeButton = new TwitchCloseButton(); + closeButton.onClick(() => { + this.close(); + }); + + const container = document.createElement('div'); + container.classList.add('twitch-notes-center-floating-container'); + + const header = document.createElement('div'); + header.classList.add('twitch-notes-container-header'); + + const title = document.createElement('div'); + title.classList.add('twitch-notes-container-header-title'); + title.textContent = 'Resolve note ('+user+') conflict'; + header.appendChild(title); + container.appendChild(header); + header.insertAdjacentElement("beforeend", closeButton.element); + + const content = document.createElement('div'); + content.classList.add('twitch-notes-container-content'); + content.style.display = 'block'; + content.style.padding = '1rem'; + container.appendChild(content); + + content.appendChild(importNotesConflictResolve(user, this.element, parentContainer, blurredBackground)); + + this.element.appendChild(container); + document.body.appendChild(this.element); + } + + private close() { + if (this.element) this.element.remove(); + this.element = undefined; + } + + public static open(user: string, + container: HTMLElement, + blurredBackground: HTMLElement) { + TwitchNotesImportResolve.instance = new TwitchNotesImportResolve(); + TwitchNotesImportResolve.instance.create(user, container, blurredBackground); + } + + +} \ No newline at end of file diff --git a/src/HTMLElements/TwitchNotesWindow.ts b/src/HTMLElements/TwitchNotesWindow.ts new file mode 100644 index 0000000..d36cff7 --- /dev/null +++ b/src/HTMLElements/TwitchNotesWindow.ts @@ -0,0 +1,259 @@ +import TwitchCloseButton from "./TwitchCloseButton"; +import NoteStorage from "../NoteStorage"; +// import openImportNotesWindow from "../openImprtNotesWindow"; +import openClearDataWindow from "../openClearDataWindow"; +import TwitchButton from "./TwitchButton"; +import TwitchNotesImport from "./TwitchNotesImport"; + +export default class TwitchNotesWindow { + + private static instance?: TwitchNotesWindow; + private element?: HTMLDivElement; + private userList?: HTMLDivElement; + + constructor() { + this.element = document.createElement('div'); + } + + private buildContent(content: HTMLDivElement) { + content.innerHTML = ''; + + const userButtons: HTMLDivElement[] = []; + + this.userList = document.createElement('div'); + this.userList.classList.add('twitch-notes-container-content-user-list'); + + const addNoteButton = document.createElement('div'); + addNoteButton.classList.add('twitch-notes-container-content-user-list-item'); + addNoteButton.textContent = '+ Add New Note'; + addNoteButton.addEventListener('click', () => { + this.newNote(noteContainer, userButtons); + }); + this.userList.appendChild(addNoteButton); + + const searchField = document.createElement('input'); + searchField.classList.add('twitch-notes-container-content-user-list-item'); + searchField.classList.add('twitch-notes-container-content-user-list-item-search'); + searchField.placeholder = 'Search...' + searchField.addEventListener('keyup', () => { + for(let row of userButtons) { + if (searchField.value === '') { + row.style.display = 'block'; + continue; + } + if(row.textContent?.includes(searchField.value)) { + row.style.display = 'block'; + } else { + row.style.display = 'none'; + } + } + }); + + this.userList.appendChild(searchField); + + for (const user of NoteStorage.getSavedUserList()) { + const userButton = document.createElement('div'); + userButton.classList.add('twitch-notes-container-content-user-list-item'); + userButton.textContent = user; + userButtons.push(userButton); + this.userList.appendChild(userButton); + userButton.addEventListener('click', () => { + this.openNote(noteContainer, user, userButtons, userButton); + }); + } + + const noteContainer = document.createElement('div'); + noteContainer.classList.add('twitch-notes-container-content-note-container'); + + if (NoteStorage.getSavedUserList().length) { + userButtons[0].click(); + } else { + noteContainer.textContent = ''; + const noNotes = document.createElement('div'); + noNotes.classList.add('twitch-notes-container-content-note-container-note'); + noNotes.innerHTML = 'You have not notes yet...'; + noteContainer.appendChild(noNotes); + } + + content.appendChild(this.userList); + content.appendChild(noteContainer); + } + + private newNote(noteContainer: HTMLDivElement, userButtons: HTMLDivElement[]) { + noteContainer.innerHTML = ''; + for (let btn of userButtons) { + btn.style.background = 'transparent'; + } + + const noteTitle = document.createElement('input'); + noteTitle.classList.add('twitch-notes-container-header-title'); + noteTitle.classList.add('twitch-notes-container-content-user-list-item-search'); + noteTitle.style.marginTop = '1rem'; + noteTitle.placeholder = 'Note title or username'; + noteContainer.appendChild(noteTitle); + + const note = document.createElement('div'); + note.classList.add('twitch-notes-container-content-note-container-note'); + note.setAttribute('contentEditable', 'true'); + note.innerHTML = ''; + + noteContainer.appendChild(note); + + const controls = document.createElement('div'); + controls.classList.add('twitch-notes-container-content-note-container-controls'); + noteContainer.appendChild(controls); + + const save = new TwitchButton('Save'); + controls.appendChild(save.element); + + const savedNote = document.createElement('span'); + savedNote.classList.add('twitch-notes-container-content-note-container-controls-saved') + savedNote.textContent = 'Note Saved!'; + savedNote.style.opacity = '0'; + controls.appendChild(savedNote); + + save.onClick(() => { + const user = noteTitle.value.trim().toLowerCase(); + const userButton = document.createElement('div'); + userButton.classList.add('twitch-notes-container-content-user-list-item'); + userButton.textContent = user; + userButtons.push(userButton); + this.userList?.appendChild(userButton); + userButton.addEventListener('click', () => { + this.openNote(noteContainer, user, userButtons, userButton); + }); + userButtons.push(userButton); + NoteStorage.saveNote(user, note.innerHTML); + this.openNote(noteContainer, user, userButtons, userButton); + }); + + } + + private openNote(noteContainer: HTMLDivElement, user: string, userButtons: HTMLDivElement[], userButton: HTMLDivElement) { + noteContainer.innerHTML = ''; + for (let btn of userButtons) { + btn.style.background = 'transparent'; + } + userButton.style.background = 'var(--color-twitch-purple-5)' + const noteTitle = document.createElement('div'); + noteTitle.classList.add('twitch-notes-container-header-title'); + noteTitle.textContent = user; + noteTitle.style.marginTop = '1rem'; + noteContainer.appendChild(noteTitle); + + const note = document.createElement('div'); + note.classList.add('twitch-notes-container-content-note-container-note'); + note.setAttribute('contentEditable', 'true'); + note.innerHTML = NoteStorage.getNote(user); + + noteContainer.appendChild(note); + + const controls = document.createElement('div'); + controls.classList.add('twitch-notes-container-content-note-container-controls'); + noteContainer.appendChild(controls); + + const save = new TwitchButton('Save'); + controls.appendChild(save.element); + + const savedNote = document.createElement('span'); + savedNote.classList.add('twitch-notes-container-content-note-container-controls-saved') + savedNote.textContent = 'Note Saved!'; + savedNote.style.opacity = '0'; + controls.appendChild(savedNote); + + save.onClick(() => { + NoteStorage.saveNote(user, note.innerHTML); + savedNote.style.opacity = '1'; + }); + } + + private create() { + if (!this.element) { + this.element = document.createElement('div'); + } + + this.element.innerHTML = ''; + + this.element.classList.add('twitch-notes-blurred-background'); + + const closeButton = new TwitchCloseButton(); + closeButton.onClick(() => { + this.close(); + }); + + const container = document.createElement('div'); + container.classList.add('twitch-notes-center-floating-container'); + + const header = document.createElement('div'); + header.classList.add('twitch-notes-container-header'); + + const title = document.createElement('div'); + title.classList.add('twitch-notes-container-header-title'); + title.textContent = 'Twitch Notes'; + header.appendChild(title); + container.appendChild(header); + header.insertAdjacentElement("beforeend", closeButton.element); + + const content = document.createElement('div'); + content.classList.add('twitch-notes-container-content') + container.appendChild(content); + + this.buildContent(content); + + const footer = document.createElement('div'); + footer.classList.add('twitch-notes-container-footer'); + container.appendChild(footer); + + const exportNotes = document.createElement('span'); + exportNotes.classList.add('twitch-notes-link'); + exportNotes.textContent = 'Export Notes'; + exportNotes.addEventListener('click', () => { + NoteStorage.exportNotes(); + }) + footer.appendChild(exportNotes); + + const importNotes = document.createElement('span'); + importNotes.classList.add('twitch-notes-link'); + importNotes.textContent = 'Import Notes'; + importNotes.addEventListener('click', () => { + TwitchNotesImport.open(() => { + TwitchNotesWindow.update(); + }); + }); + footer.appendChild(importNotes); + + const clearNotes = document.createElement('span'); + clearNotes.classList.add('twitch-notes-link'); + clearNotes.textContent = 'Clear Notes'; + clearNotes.addEventListener('click', () => { + openClearDataWindow(); + }); + footer.appendChild(clearNotes); + + this.element.appendChild(container); + document.body.appendChild(this.element); + } + + private close() { + if (this.element) this.element.remove(); + this.element = undefined; + } + + public static update() { + TwitchNotesWindow.instance?.create(); + } + + public static toggle() { + if (!TwitchNotesWindow.instance) { + TwitchNotesWindow.instance = new TwitchNotesWindow(); + TwitchNotesWindow.instance.create(); + return; + } + if (TwitchNotesWindow.instance.element) { + TwitchNotesWindow.instance.close(); + } else { + TwitchNotesWindow.instance.create(); + } + } + +} \ No newline at end of file diff --git a/src/Mouse.ts b/src/Mouse.ts index f722c81..1b7f4e0 100644 --- a/src/Mouse.ts +++ b/src/Mouse.ts @@ -18,7 +18,7 @@ export default class Mouse { } static handleMouseUp() { - NoteContainers.activeContainer = ''; + NoteContainers.activeContainer = null; Mouse.isMouseDown = false; } diff --git a/src/NoteContainers.ts b/src/NoteContainers.ts index 65f647d..a48ac06 100644 --- a/src/NoteContainers.ts +++ b/src/NoteContainers.ts @@ -1,17 +1,17 @@ import HTMLBuilder from "./HTMLBuilder"; -const containers: {[key: string]: HTMLBuilder} = {}; +export default class NoteContainers { + static activeContainer: string | null = null; + static containers: { [key: string]: HTMLBuilder } = {}; -export default { - activeContainer: '', - containers, - addContainer(username: string, container: HTMLBuilder) { - if (this.containers[username]) return; - this.containers[username] = container; - }, - removeContainer(username: string) { - if (!this.containers[username]) return; - this.containers[username].remove(); - delete this.containers[username]; - } + static addContainer(username: string, container: HTMLBuilder) { + if (NoteContainers.containers[username]) return; + NoteContainers.containers[username] = container; + }; + + static removeContainer(username: string) { + if (!NoteContainers.containers[username]) return; + NoteContainers.containers[username].remove(); + delete NoteContainers.containers[username]; + }; } \ No newline at end of file diff --git a/src/TwitchNote.ts b/src/TwitchNote.ts index bcb9306..48869a9 100644 --- a/src/TwitchNote.ts +++ b/src/TwitchNote.ts @@ -2,15 +2,14 @@ import { ELEMENT_ButtonContainer } from "./const"; import toggleSettingsList from "./toggleSettingsList"; import openTwitchNote from "./openTwitchNote"; import HTMLBuilder from "./HTMLBuilder"; +import TwitchButton from "./HTMLElements/TwitchButton"; +import TwitchNotesWindow from "./HTMLElements/TwitchNotesWindow"; export default class TwitchNote { - observer: MutationObserver | null = null; + observer?: MutationObserver; chatContainerNode?: Element; - constructor() { - } - init(chatContainerNode: Element) { this.chatContainerNode = chatContainerNode; this.startObserver(chatContainerNode); @@ -55,41 +54,16 @@ export default class TwitchNote { return; } - const btn = new HTMLBuilder({ - element: 'div', - style: { - marginLeft: "0.5rem !important" - }, - content: [ - { - element: 'div', - style: { - display: "inline-flex !important" - }, - content: [ - { - element: 'button', - class: [ - 'twitch-notes-settings-button', - 'twitch-notes-settings-button__outline' - ], - content: [ - 'Notes' - ], - mouseClickEvent: () => toggleSettingsList(), - } - ] - } - ] - }); + const button = new TwitchButton('Notes', 'outline'); + button.onClick(TwitchNotesWindow.toggle); if (buttonContainer.lastChild) { buttonContainer.lastChild.insertBefore( - btn.getElement(), + button.element, buttonContainer.lastChild.lastChild ); } else { - buttonContainer.appendChild(btn.getElement()); + buttonContainer.appendChild(button.element); } } diff --git a/src/importNotesConflictResolve.ts b/src/importNotesConflictResolve.ts index d3336ab..882c08f 100644 --- a/src/importNotesConflictResolve.ts +++ b/src/importNotesConflictResolve.ts @@ -1,85 +1,101 @@ -import {CustomButtonElement, CustomDivElement, CustomHTMLElement, CustomPElement} from "./CustomHTMLElement"; import NoteStorage from "./NoteStorage"; import importNotesResult from "./importNotesResult"; +import HTMLBuilder from "./HTMLBuilder"; export default function importNotesConflictResolve( user: string, - resultsContainer: CustomHTMLElement, - container: CustomHTMLElement, - blurredBackground: CustomHTMLElement + resultsContainer: HTMLElement, + container: HTMLElement, + blurredBackground: HTMLElement ) { - const diffBlurredBackground = new CustomDivElement('twitch-notes-blurred-background'); - const diffContainer = new CustomDivElement('twitch-notes-center-floating-container', 'Select which note to keep for ' + user + '
You can modify notes to merge them and keep updated one

'); - - const inputContainer = new CustomDivElement(); - inputContainer.setStyle({ - display: 'flex', - flexDirection: 'row', - flexWrap: 'no-wrap', - width: '100%', - }); - const valueStyle = { minWidth: '320px', padding: '6px', border: '1px solid #FFFFFF19', outline: 'none', }; - const valueAttr: [string, string] = ['contentEditable', 'true']; + const valueAttr = {contentEditable: 'true'}; - const localValueContainer = new CustomDivElement(); - const pLocal = new CustomPElement('', 'Locally saved note'); - localValueContainer.appendCustomChild(pLocal); - - const localValue = new CustomDivElement(); - localValue.setStyle(valueStyle); - localValue.addAttribute(...valueAttr); - localValue.setId('local-value-container'); - const localValueSave = new CustomButtonElement('twitch-notes-settings-button', 'Save this'); - localValueSave.setClickListener(() => { - const val = document.getElementById('local-value-container')?.innerHTML || ''; - NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? { - user: n.user, - note: val, - resolved: true - } : n); - diffBlurredBackground.remove(); - resultsContainer.remove(); - importNotesResult(container, blurredBackground); + const diffBlurredBackground = new HTMLBuilder({ + element: 'div', + content: [ + 'Select which note to keep for ' + user + '
You can modify notes to merge them and keep updated one

', + { + element: 'div', + class: 'twitch-notes-grid-col-2', + style: { + width: '100%', + }, + content: [ + { + element: 'div', + content: [{ + element: 'p', + content: [ + 'Locally saved note', + { + element: 'div', + style: valueStyle, + attributes: valueAttr, + id: 'local-value-container', + content: [NoteStorage.getNote(user)] + }, + '
', + { + element: 'button', + class: 'twitch-notes_button', + content: ['Save this'], + mouseClickEvent: () => { + const val = document.getElementById('local-value-container')?.innerHTML || ''; + NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? { + user: n.user, + note: val, + resolved: true + } : n); + diffBlurredBackground.remove(); + resultsContainer.remove(); + importNotesResult(container, blurredBackground); + } + } + ] + }] + }, + { + element: 'div', + content: [{ + element: 'p', + content: [ + 'Locally saved note', + { + element: 'div', + style: valueStyle, + attributes: valueAttr, + id: 'import-value-container', + content: [NoteStorage.inputData.notes.filter(n => n.user === user)[0].note || ''] + }, + '
', + { + element: 'button', + class: 'twitch-notes_button', + content: ['Save this'], + mouseClickEvent: () => { + const val = document.getElementById('import-value-container')?.innerHTML || ''; + NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? { + user: n.user, + note: val, + resolved: true + } : n); + diffBlurredBackground.remove(); + resultsContainer.remove(); + importNotesResult(container, blurredBackground); + } + } + ] + }] + } + ] + } + ] }); - localValueContainer.appendCustomChild(localValue); - localValueContainer.appendBody('
'); - localValueContainer.appendCustomChild(localValueSave); - - const importedValueContainer = new CustomDivElement(); - const iLocal = new CustomPElement('', 'Imported note'); - importedValueContainer.appendCustomChild(iLocal); - const importedValue = new CustomDivElement('', NoteStorage.inputData.notes.filter(n => n.user === user)[0].note || ''); - importedValue.setId('import-value-container'); - importedValue.setStyle(valueStyle); - importedValue.addAttribute(...valueAttr); - const importedValueSave = new CustomButtonElement('twitch-notes-settings-button', 'Save this'); - importedValueSave.setClickListener(() => { - const val = document.getElementById('import-value-container')?.innerHTML || ''; - NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? { - user: n.user, - note: val, - resolved: true - } : n); - diffBlurredBackground.remove(); - resultsContainer.remove(); - importNotesResult(container, blurredBackground); - }); - - importedValueContainer.appendCustomChild(importedValue); - importedValueContainer.appendBody('
'); - importedValueContainer.appendCustomChild(importedValueSave); - - - inputContainer.appendCustomChild(localValueContainer); - inputContainer.appendCustomChild(importedValueContainer); - - diffContainer.appendCustomChild(inputContainer); - diffBlurredBackground.appendCustomChild(diffContainer); - document.body.appendChild(diffBlurredBackground.getElement()); + return diffBlurredBackground.getElement(); } \ No newline at end of file diff --git a/src/importNotesResult.ts b/src/importNotesResult.ts index 470c8b8..7dd6897 100644 --- a/src/importNotesResult.ts +++ b/src/importNotesResult.ts @@ -1,8 +1,10 @@ -import {CustomAElement, CustomButtonElement, CustomDivElement, CustomHTMLElement} from "./CustomHTMLElement"; import NoteStorage from "./NoteStorage"; import importNotesConflictResolve from "./importNotesConflictResolve"; +import HTMLBuilder from "./HTMLBuilder"; +import TwitchButton from "./HTMLElements/TwitchButton"; +import TwitchNotesImportResolve from "./HTMLElements/TwitchNotesImportResolve"; -export default function importNotesResult(container: CustomHTMLElement, blurredBackground: CustomHTMLElement) { +export default function importNotesResult(container: HTMLElement, blurredBackground: HTMLElement, cb?: Function) { const willBeAdded = []; let willBeOverwritten = []; const noChanges = []; @@ -19,71 +21,85 @@ export default function importNotesResult(container: CustomHTMLElement, blurredB } } - const resultsContainer = new CustomDivElement(); + const resultsContainer = new HTMLBuilder({ + element: 'div', + style: { + padding: '1rem' + } + }); if (willBeOverwritten.length) { - const overwrittenContainer = new CustomDivElement('', 'Note conflicts found for:
'); - overwrittenContainer.setStyle({marginTop: '1rem'}); + const overwrittenContainer = new HTMLBuilder({ + element: 'div', + content: ['Note conflicts found for:
'], + style: { + marginTop: '1rem', + } + }); for (let item of willBeOverwritten) { - const row = new CustomDivElement('', item + ' '); const isResolved = NoteStorage.inputData.notes.find(note => note.user === item)?.resolved; - row.setStyle({ - color: isResolved ? 'green' : 'red', + overwrittenContainer.addContent({ + element: 'div', + content: [item + ' ', { + element: 'a', + content: [isResolved ? '[update]' : '[resolve]'], + style: { + cursor: 'pointer', + }, + mouseClickEvent: () => { + TwitchNotesImportResolve.open(item, container, blurredBackground); + // importNotesConflictResolve(item, resultsContainer, container, blurredBackground); + } + }], + style: { + color: isResolved ? 'green' : 'red', + } }); - const resolve = new CustomAElement('', isResolved ? '[update]' : '[resolve]'); - resolve.setStyle({ - cursor: 'pointer' - }); - - resolve.setClickListener(() => { - importNotesConflictResolve(item, resultsContainer, container, blurredBackground); - }) - row.appendCustomChild(resolve); - overwrittenContainer.appendCustomChild(row); } - resultsContainer.appendCustomChild(overwrittenContainer); + resultsContainer.addContent(overwrittenContainer.getElement()); } if (willBeAdded.length) { - const addedContainer = new CustomDivElement('', 'Note will be added for:
' + willBeAdded.join('
')); - addedContainer.setStyle({ - marginTop: '1rem', - color: 'white' + resultsContainer.addContent({ + element: 'div', + content: ['Note will be added for:
' + willBeAdded.join('
')], + style: { + marginTop: '1rem', + color: 'white' + } }); - resultsContainer.appendCustomChild(addedContainer); } if (noChanges.length) { - const noChangesContainer = new CustomDivElement('', 'No changes for:
' + noChanges.join('
')); - noChangesContainer.setStyle({ - marginTop: '1rem', - color: 'gray' + resultsContainer.addContent({ + element: 'div', + content: ['No changes for:
' + noChanges.join('
')], + style: { + marginTop: '1rem', + color: 'gray' + } }); - resultsContainer.appendCustomChild(noChangesContainer); } - const spacer = new CustomDivElement(); - spacer.setStyle({height: '24px'}); - resultsContainer.appendCustomChild(spacer); + resultsContainer.addContent({element: 'div', style: {height: '24px'}}); willBeOverwritten = willBeOverwritten.filter(x => !NoteStorage.inputData.notes.find(n => n.user === x)?.resolved); - const saveButton = new CustomButtonElement('twitch-notes-settings-button', 'Complete import'); - saveButton.setStyle({}) - if (willBeOverwritten.length > 0) saveButton.setStyle({background: 'gray'}); - if (willBeOverwritten.length > 0) saveButton.addAttribute('disabled', 'true'); + const saveButton = new TwitchButton('Complete import'); + if (willBeOverwritten.length > 0) saveButton.element.style.background = 'gray'; + if (willBeOverwritten.length > 0) saveButton.element.setAttribute('disabled', 'true'); - resultsContainer.appendCustomChild(saveButton) + resultsContainer.addContent(saveButton.element) if (willBeOverwritten.length > 0) { - const note = new CustomDivElement('', 'Import cannot be completed while there are unresolved conflicts'); - note.setStyle({ - color: 'gray', + resultsContainer.addContent({ + element: 'div', + content: ['Import cannot be completed while there are unresolved conflicts'], + style: {color: 'gray'} }); - resultsContainer.appendCustomChild(note); } else { - saveButton.setClickListener(() => { + saveButton.element.addEventListener('click', () => { for (let note of NoteStorage.inputData.notes) { NoteStorage.saveNote(note.user, note.note); } @@ -93,8 +109,10 @@ export default function importNotesResult(container: CustomHTMLElement, blurredB notes: [], settings: {}, }; + cb ? cb() : () => {}; }); } - container.appendCustomChild(resultsContainer); + container.innerHTML = ''; + container.appendChild(resultsContainer.getElement()); } \ No newline at end of file diff --git a/src/openAllNoteListWindow.ts b/src/openAllNoteListWindow.ts index 2e78613..02dbc17 100644 --- a/src/openAllNoteListWindow.ts +++ b/src/openAllNoteListWindow.ts @@ -1,126 +1,149 @@ -import {CustomButtonElement, CustomDivElement, CustomSpanElement} from "./CustomHTMLElement"; import NoteStorage from "./NoteStorage"; import {getCloseButtonSVG} from "./HTMLTemplates"; +import HTMLBuilder from "./HTMLBuilder"; export default function openAllNoteListWindow() { let activeNote: string = ''; - const blurredBackground = new CustomDivElement('twitch-notes-blurred-background'); + const blurredBackground = new HTMLBuilder({element: "div", class: 'twitch-notes-blurred-background'}); - const noteSaved = new CustomSpanElement('', 'Note saved!'); - noteSaved.setStyle({ - color: 'green', - marginLeft: '2rem', - }); - noteSaved.hide(); - - const container = new CustomDivElement('twitch-notes-center-floating-container'); - container.setStyle({ - padding: '0', - paddingTop: '1rem', - width: '100%', - maxWidth: '800px', - height: 'calc(320px + 5rem)', - maxHeight: '90vh', - }); - - const closeButton = new CustomButtonElement('twitch-notes-settings-close-button', getCloseButtonSVG()); - closeButton.setStyle({ - position: 'absolute', - top: '1rem', - right: '1rem', - }); - - const title = new CustomDivElement('twitch-note-title', 'Notes:'); - title.setStyle({ - borderBottom: '1px solid #FFFFFF19', - paddingBottom: '1rem', - }); - container.appendCustomChild(title); - - const content = new CustomDivElement(); - content.setStyle({ - display: 'flex', - flexDirection: 'row', - flexWrap: 'no-wrap', - width: '100%', - height: '320px' - }); - container.appendCustomChild(content); - closeButton.setClickListener(() => { - blurredBackground.remove(); - }); - container.appendCustomChild(closeButton); - - const userList = new CustomDivElement(); - userList.setStyle({ - borderRight: '1px solid #FFFFFF19', - height: '320px', - minWidth: '240px', - overflowY: 'auto', - overflowX: 'hidden', - }); - - const noteContainer = new CustomDivElement(); - noteContainer.setStyle({ - height: '320px', - padding: '1rem', - width: '100%', - opacity: '0', - }); - - const note = new CustomDivElement(); - note.setStyle({ - marginBottom: '3rem', - border: '1px solid #FFFFFF19', - height: 'calc(320px - 7rem)', - width: '100%', - padding: '6px', - outline: 'none', - overflowY: 'auto', - overflowX: 'hidden', - }); - note.addAttribute('contentEditable', 'true'); - - const saveNote = new CustomButtonElement('twitch-notes-settings-button','Save Note'); - saveNote.setStyle({ - position: 'absolute', - bottom: '1rem', - left: '1rem' - }); - - saveNote.setClickListener(() => { - if(!activeNote) { - return; + const noteSaved = new HTMLBuilder({ + element: 'span', + content: ['Note saved!'], + style: { + color: 'green', + marginLeft: '2rem', + display: 'none' } - NoteStorage.saveNote(activeNote, note.getElement().innerHTML); - noteSaved.setStyle({ - display: 'inline-block', - }); }); - for(let user of NoteStorage.getSavedUserList()) { - const userLine = new CustomDivElement('twitch-notes-user-list-user', user); - userLine.setClickListener(() => { - const list = document.getElementsByClassName('twitch-notes-user-list-user'); - for(let i = 0; i < list.length; i++) { - list.item(i)?.removeAttribute('data-active'); + const content = new HTMLBuilder({ + element: 'div', + style: { + display: 'flex', + flexDirection: 'row', + flexWrap: 'no-wrap', + width: '100%', + height: '320px' + } + }); + + const closeButton = new HTMLBuilder({ + element: 'button', + class: 'twitch-notes-settings-close-button', + content: [getCloseButtonSVG()], + style: { + position: 'absolute', + top: '1rem', + right: '1rem', + }, + mouseClickEvent: () => { + blurredBackground.remove(); + } + }); + + const container = new HTMLBuilder({ + element: 'div', + class: 'twitch-notes-center-floating-container', + style: { + padding: '0', + paddingTop: '1rem', + width: '100%', + maxWidth: '800px', + height: 'calc(320px + 5rem)', + maxHeight: '90vh', + }, + content: [ + { + element: 'div', + class: 'twitch-notes-title', + content: ['Notes:'], + style: { + borderBottom: '1px solid #FFFFFF19', + paddingBottom: '1rem', + } + }, + content.getElement(), + closeButton.getElement() + ] + }); + + const userList = new HTMLBuilder({ + element: 'div', + class: 'twitch-notes-user-list' + }); + + const noteContainer = new HTMLBuilder({ + element: 'div', + style: { + height: '320px', + padding: '1rem', + width: '100%', + opacity: '0', + } + }); + + const note = new HTMLBuilder({ + element: 'div', + style: { + marginBottom: '3rem', + border: '1px solid #FFFFFF19', + height: 'calc(320px - 7rem)', + width: '100%', + padding: '6px', + outline: 'none', + overflowY: 'auto', + overflowX: 'hidden', + }, + attributes: { + contentEditable: 'true' + } + }); + + const saveNote = new HTMLBuilder({ + element: 'button', + class: 'twitch-notes-settings-button', + content: ['Save Note'], + style: { + position: 'absolute', + bottom: '1rem', + left: '1rem' + }, + mouseClickEvent: () => { + if (!activeNote) { + return; + } + NoteStorage.saveNote(activeNote, note.getElement().innerHTML); + noteSaved.getElement().style.display = 'inline-block'; + } + }); + + for (let user of NoteStorage.getSavedUserList()) { + const userLine = new HTMLBuilder({ + element: 'div', + class: 'twitch-notes-user-list-user', + content: [user], + mouseClickEvent: () => { + const list = document.getElementsByClassName('twitch-notes-user-list-user'); + for (let i = 0; i < list.length; i++) { + list.item(i)?.removeAttribute('data-active'); + } + noteSaved.getElement().style.display = 'none'; + userLine.addAttribute('data-active', 'true'); + noteContainer.getElement().style.opacity = '1'; + note.getElement().innerHTML = NoteStorage.getNote(user); + activeNote = user; } - noteSaved.hide(); - userLine.addAttribute('data-active', 'true'); - noteContainer.setStyle({opacity: '1'}); - note.getElement().innerHTML = NoteStorage.getNote(user); - activeNote = user; }); - userList.appendCustomChild(userLine); + userList.addContent(userLine.getElement()); } - noteContainer.appendCustomChild(note); - noteContainer.appendCustomChild(saveNote); - noteContainer.appendCustomChild(noteSaved); + noteContainer.addContent(note.getElement()); + noteContainer.addContent(saveNote.getElement()); + noteContainer.addContent(noteSaved.getElement()); - content.appendCustomChild(userList); - content.appendCustomChild(noteContainer); + content.addContent(userList.getElement()); + content.addContent(noteContainer.getElement()); - blurredBackground.appendCustomChild(container); + blurredBackground.addContent(container.getElement()); document.body.appendChild(blurredBackground.getElement()); } \ No newline at end of file diff --git a/src/openClearDataWindow.ts b/src/openClearDataWindow.ts index 9dfb7a9..d23c143 100644 --- a/src/openClearDataWindow.ts +++ b/src/openClearDataWindow.ts @@ -1,28 +1,48 @@ -import {CustomButtonElement, CustomDivElement} from "./CustomHTMLElement"; import NoteStorage from "./NoteStorage"; +import HTMLBuilder from "./HTMLBuilder"; +import TwitchNotesWindow from "./HTMLElements/TwitchNotesWindow"; export default function openClearDataWindow() { - const blurredBackground = new CustomDivElement( 'twitch-notes-blurred-background'); - const container = new CustomDivElement('twitch-notes-center-floating-container', 'This action will delete all saved notes!

Consider exporting notes before performing this action in case you will need to use notes again'); - const spacer = new CustomDivElement(); - spacer.setStyle({ - height: '24px' + const blurredBackground = new HTMLBuilder({ + element: 'div', + class: 'twitch-notes-blurred-background', + content: [{ + element: 'div', + class: 'twitch-notes-center-floating-container', + style: { + padding: '1rem', + }, + content: [ + 'This action will delete all saved notes!

Consider exporting notes before performing this action in case you will need to use notes again', + { + element: 'div', + style: { + height: '24px', + } + }, + { + element: 'button', + class: 'twitch-notes_button', + content: ['DELETE ALL NOTES'], + style: { + background: 'red' + }, + mouseClickEvent: () => { + NoteStorage.clearData(); + blurredBackground.remove(); + TwitchNotesWindow.update(); + } + }, + { + element: 'button', + class: 'twitch-notes_button', + content: ['Cancel'], + mouseClickEvent: () => { + blurredBackground.remove(); + } + } + ] + }] }); - const deleteAction = new CustomButtonElement('twitch-notes-settings-button', 'DELETE ALL NOTES'); - deleteAction.setStyle({ - background: 'red' - }); - deleteAction.setClickListener(() => { - NoteStorage.clearData(); - blurredBackground.remove(); - }); - const cancelAction = new CustomButtonElement('twitch-notes-settings-button', 'Cancel'); - cancelAction.setClickListener(() => { - blurredBackground.remove(); - }); - container.appendCustomChild(spacer); - container.appendCustomChild(deleteAction); - container.appendCustomChild(cancelAction); - blurredBackground.appendCustomChild(container); document.body.appendChild(blurredBackground.getElement()); } \ No newline at end of file diff --git a/src/openImprtNotesWindow.ts b/src/openImprtNotesWindow.ts index f59a1c5..33209e6 100644 --- a/src/openImprtNotesWindow.ts +++ b/src/openImprtNotesWindow.ts @@ -1,52 +1,73 @@ -import {CustomButtonElement, CustomDivElement, CustomInputElement} from "./CustomHTMLElement"; import NoteStorage from "./NoteStorage"; import {getCloseButtonSVG} from "./HTMLTemplates"; import importNotesResult from "./importNotesResult"; +import HTMLBuilder from "./HTMLBuilder"; -export default function openImportNotesWindow() { - const blurredBackground = new CustomDivElement('twitch-notes-blurred-background'); - const container = new CustomDivElement('twitch-notes-center-floating-container', 'WARNING! This action might override existing data!

'); - const inputBlock = new CustomDivElement('','Select exported twitch notes file

'); - const input = new CustomInputElement('twitch-notes-file-input'); - input.addAttribute('type', 'file').addAttribute('accept', 'json'); - const settingsCloseButton = new CustomButtonElement('twitch-notes-settings-close-button', getCloseButtonSVG()); - settingsCloseButton.setStyle({ - position: 'absolute', - top: '1rem', - right: '1rem', - }); - - inputBlock.appendCustomChild(input); - - settingsCloseButton.setClickListener(() => { - blurredBackground.remove(); - }) - - input.setChangeListener(() => { - if (!input?.getElement()?.files) return; - // @ts-ignore - let file = input.getElement().files.item(0); - if (!file) { - return; - } - let reader = new FileReader(); - reader.readAsText(file, "UTF-8"); - reader.onload = function (evt) { - if (!evt?.target?.result) return; - - NoteStorage.inputData = JSON.parse(evt.target.result.toString()); - if (NoteStorage.inputData) { - inputBlock.setStyle({display: 'none'}); - importNotesResult(container, blurredBackground); - } - } - reader.onerror = function () { - console.error("error reading file"); - } - }); - - container.appendCustomChild(settingsCloseButton); - container.appendCustomChild(inputBlock); - blurredBackground.appendCustomChild(container); - document.body.appendChild(blurredBackground.getElement()); -} \ No newline at end of file +// export default function openImportNotesWindow() { +// const blurredBackground = new HTMLBuilder({ +// element: 'div', +// class: 'twitch-notes-blurred-background' +// }); +// const container = new HTMLBuilder({ +// element: 'div', +// class: 'twitch-notes-center-floating-container', +// style: { +// padding: '1rem', +// }, +// content: [ +// 'WARNING! This action might override existing data!

', +// { +// element: 'button', +// class: 'twitch-notes-settings-close-button', +// content: [getCloseButtonSVG()], +// style: { +// position: 'absolute', +// top: '1rem', +// right: '1rem', +// }, +// mouseClickEvent:() => { +// blurredBackground.remove(); +// } +// } +// ] +// }); +// const input = new HTMLBuilder({ +// element: 'input', +// class: 'twitch-notes-file-input', +// attributes: { +// type: 'file', +// accept: 'json' +// } +// }); +// const inputBlock = new HTMLBuilder({ +// element: 'div', +// content: ['Select exported twitch notes file

', input.getElement()] +// }); +// +// input.setChangeListener(() => { +// if (!(input?.getElement() as HTMLInputElement)?.files) return; +// // @ts-ignore +// let file = input.getElement().files.item(0); +// if (!file) { +// return; +// } +// let reader = new FileReader(); +// reader.readAsText(file, "UTF-8"); +// reader.onload = function (evt) { +// if (!evt?.target?.result) return; +// +// NoteStorage.inputData = JSON.parse(evt.target.result.toString()); +// if (NoteStorage.inputData) { +// inputBlock.setStyles({display: 'none'}); +// importNotesResult(container, blurredBackground); +// } +// } +// reader.onerror = function () { +// console.error("error reading file"); +// } +// }); +// +// container.addContent(inputBlock.getElement()); +// blurredBackground.addContent(container.getElement()); +// document.body.appendChild(blurredBackground.getElement()); +// } \ No newline at end of file diff --git a/src/openTwitchNote.ts b/src/openTwitchNote.ts index c3c8e51..8c9e00e 100644 --- a/src/openTwitchNote.ts +++ b/src/openTwitchNote.ts @@ -10,7 +10,7 @@ export default function openTwitchNote(username: string) { let noteContent = NoteStorage.getNote(username); const container: HTMLBuilderBlock = { element: 'div', - class: 'twitch-note-container', + class: 'twitch-notes-floating-container', style: { left: Mouse.mousePosition.x + 'px', top: Mouse.mousePosition.y + 10 + 'px' @@ -18,7 +18,7 @@ export default function openTwitchNote(username: string) { content: [ { element: 'div', - class: 'twitch-note-header', + class: 'twitch-notes-header', mouseDownEvent: () => { NoteContainers.activeContainer = username; Mouse.isMouseDown = true; @@ -26,20 +26,20 @@ export default function openTwitchNote(username: string) { content: [ { element: 'span', - class: 'twitch-note-close-button', + class: 'twitch-notes-close-button', content: [getCloseButtonSVG()], mouseClickEvent: () => NoteContainers.removeContainer(username), }, { element: 'span', - class: 'twitch-note-title', + class: 'twitch-notes-title', content: [username], } ] }, { element: 'div', - class: 'twitch-note-content', + class: 'twitch-notes-content', content: [NoteStorage.getNote(username)], attributes: { contentEditable: 'true' @@ -50,7 +50,7 @@ export default function openTwitchNote(username: string) { }, { element: 'div', - class: 'twitch-note-save-button', + class: 'twitch-notes-save-button', content: ['SAVE'], mouseClickEvent: () => { NoteStorage.saveNote(username, noteContent); diff --git a/src/styles/main.scss b/src/styles/main.scss index e7b8562..064ef12 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -1,302 +1,303 @@ -.twitch-note-container { - position: fixed; - z-index: 1000000; - min-width: 420px; - max-width: 95vw; - min-height: 240px; - max-height: 50vh; - background: var(--color-background-base); - border: var(--border-width-default) solid var(--color-border-base) !important; -} +.twitch-notes { -.twitch-note-header { - width: 100%; - height: 32px; - line-height: 32px; - border-bottom: var(--border-width-default) solid var(--color-border-base) !important; - position: relative; - cursor: move; -} + &_button { + z-index: var(--z-index-default) !important; + position: relative !important; + background-color: var(--color-background-button-primary-default); + color: var(--color-text-button-primary); + text-decoration: none; + cursor: pointer; + display: inline-flex; + -webkit-box-align: center; + align-items: center; + -webkit-box-pack: center; + justify-content: center; + vertical-align: middle; + overflow: hidden; + white-space: nowrap; + user-select: none; + font-weight: var(--font-weight-semibold); + border-radius: var(--border-radius-medium); + font-size: var(--button-text-default); + height: var(--button-size-default); + padding: 0 var(--button-padding-x); -.twitch-note-title { - color: var(--color-text-alt) !important; - font-size: var(--font-size-6) !important; - font-weight: var(--font-weight-semibold) !important; - text-transform: uppercase !important; - padding-left: calc((32px - var(--font-size-6)) / 2); -} + &__outline { + background: transparent; + border: 2px solid var(--color-text-button-primary); + } -.twitch-note-close-button { - position: absolute; - right: 5px; - top: 5px; - width: 22px; - height: 22px; - line-height: 22px; - text-align: center; - aspect-ratio: 1; - color: var(--color-text-alt) !important; - font-size: var(--font-size-6) !important; - font-weight: var(--font-weight-semibold) !important; - text-transform: uppercase !important; - cursor: pointer; -} + } -.twitch-note-content { - position: absolute; - top: 32px; - left: 0; - right: 0; - bottom: 32px; - background: transparent; - color: var(--color-text-base) !important; - font-family: var(--font-base); - vertical-align: baseline; - outline: none; - overflow: auto; - padding: calc((32px - var(--font-size-6)) / 2); -} + &_close-button { + cursor: default; + text-transform: none; + text-indent: 0; + text-shadow: none; + letter-spacing: normal; + text-rendering: auto; + appearance: auto; + writing-mode: horizontal-tb !important; + box-sizing: border-box; + margin: 0; + font: inherit; + border: none; + font-size: var(--button-text-default); + font-weight: var(--font-weight-semibold); + vertical-align: middle; + overflow: hidden; + text-decoration: none; + white-space: nowrap; + position: absolute; + display: inline-flex; + -webkit-box-align: center; + align-items: center; + -webkit-box-pack: center; + justify-content: center; + user-select: none; + border-radius: var(--border-radius-medium); + height: calc(var(--button-size-default) - 1rem); + width: calc(var(--button-size-default) - 1rem); + background-color: var(--color-background-button-text-default); + color: var(--color-fill-button-icon); + top: 1rem; + right: 1rem; -.twitch-note-save-button { - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 32px; - border-top: var(--border-width-default) solid var(--color-border-base) !important; - cursor: pointer; - color: var(--color-text-alt) !important; - font-size: var(--font-size-6) !important; - font-weight: var(--font-weight-semibold) !important; - text-transform: uppercase !important; - text-align: center; - line-height: 32px; -} + .twitch-notes_x-button { + position: absolute; + left: 0; + width: calc(var(--button-size-default) - 1rem); + height: calc(var(--button-size-default) - 1rem); + top: 0; + fill: currentcolor; + } + } -.twitch-notes-settings-button { - z-index: var(--z-index-default) !important; - position: relative !important; - background-color: var(--color-background-button-primary-default); - color: var(--color-text-button-primary); - text-decoration: none; - cursor: pointer; - display: inline-flex; - -webkit-box-align: center; - align-items: center; - -webkit-box-pack: center; - justify-content: center; - vertical-align: middle; - overflow: hidden; - white-space: nowrap; - user-select: none; - font-weight: var(--font-weight-semibold); - border-radius: var(--border-radius-medium); - font-size: var(--button-text-default); - height: var(--button-size-default); - padding: 0 var(--button-padding-x); + &-floating-container { + position: fixed; + z-index: 1000000; + width: 320px; + height: 240px; + background: var(--color-background-base); + border: var(--border-width-default) solid var(--color-border-base) !important; + } - &__outline { + &-container { + position: fixed; + z-index: 1000000; + min-width: 500px; + max-width: 95vw; + min-height: 240px; + max-height: 50vh; + background: var(--color-background-base); + border: var(--border-width-default) solid var(--color-border-base) !important; + + &-header { + width: 100%; + height: calc(var(--button-size-default) + 1rem); + line-height: calc(var(--button-size-default) + 1rem); + border-bottom: var(--border-width-default) solid var(--color-border-base) !important; + position: relative; + + &-title { + color: var(--color-text-alt) !important; + font-size: var(--font-size-6) !important; + font-weight: var(--font-weight-semibold) !important; + text-transform: uppercase !important; + margin-left: calc((32px - var(--font-size-6)) / 2); + width: calc(100% - 2rem); + } + } + + &-content { + display: grid; + grid-template-columns: 240px 1fr; + + + &-user-list { + border-right: 1px solid #FFFFFF19; + height: 100%; + min-width: 240px; + overflow-y: auto; + overflow-x: hidden; + + + &-item { + padding: 1rem; + border-bottom: var(--border-width-default) solid var(--color-border-base) !important; + cursor: pointer; + width: 100%; + color: var(--color-text-alt) !important; + font-size: var(--font-size-6) !important; + font-weight: var(--font-weight-semibold) !important; + text-transform: uppercase !important; + + &-search { + background: transparent; + outline: none; + color: var(--color-fill-button-icon); + } + } + } + + &-note-container { + + &-note { + min-width: 420px; + min-height: 320px; + display: block; + margin: 1rem; + border: var(--border-width-default) solid var(--color-border-base) !important; + padding: 1rem; + } + + &-controls { + padding: 1rem; + display: flex; + align-content: center; + + &-saved { + color: green; + padding-left: 1rem; + line-height: var(--button-size-default); + } + } + } + } + + &-footer { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + width: 100%; + border-top: var(--border-width-default) solid var(--color-border-base) !important; + padding: 1rem; + text-align: center; + } + } + + &-header { + width: 100%; + height: 32px; + line-height: 32px; + border-bottom: var(--border-width-default) solid var(--color-border-base) !important; + position: relative; + cursor: move; + } + + &--container-header-title { + color: var(--color-text-alt) !important; + font-size: var(--font-size-6) !important; + font-weight: var(--font-weight-semibold) !important; + text-transform: uppercase !important; + padding-left: calc((32px - var(--font-size-6)) / 2); + } + + &-title { + color: var(--color-text-alt) !important; + font-size: var(--font-size-6) !important; + font-weight: var(--font-weight-semibold) !important; + text-transform: uppercase !important; + padding-left: calc((32px - var(--font-size-6)) / 2); + } + + &-close-button { + position: absolute; + right: 5px; + top: 5px; + width: 22px; + height: 22px; + line-height: 22px; + text-align: center; + aspect-ratio: 1; + color: var(--color-text-alt) !important; + font-size: var(--font-size-6) !important; + font-weight: var(--font-weight-semibold) !important; + text-transform: uppercase !important; + cursor: pointer; + } + + &-content { + position: absolute; + top: 32px; + left: 0; + right: 0; + bottom: 32px; background: transparent; - border: 2px solid var(--color-text-button-primary); + color: var(--color-text-base) !important; + font-family: var(--font-base); + vertical-align: baseline; + outline: none; + overflow: auto; + padding: calc((32px - var(--font-size-6)) / 2); + } + + &-save-button { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 32px; + border-top: var(--border-width-default) solid var(--color-border-base) !important; + cursor: pointer; + color: var(--color-text-alt) !important; + font-size: var(--font-size-6) !important; + font-weight: var(--font-weight-semibold) !important; + text-transform: uppercase !important; + text-align: center; + line-height: 32px; + } + + &-x-button { + position: absolute; + left: 0; + width: 100%; + min-height: 100%; + top: 0; + fill: currentcolor; + } + + &-blurred-background { + position: fixed; + inset: 0 0 0 0; + z-index: 2000000; + background: rgba(0, 0, 0, 0.4); + backdrop-filter: blur(2px); + } + + &-center-floating-container { + background: var(--color-background-base); + border: var(--border-width-default) solid var(--color-border-base) !important; + position: fixed; + top: 50vh; + left: 50vw; + transform: translate(-50%, -50%); + min-height: 320px; + min-width: 300px; + max-height: 90vh; + max-width: 90vw; + overflow: auto; + } + + &-link { + display: inline-block; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + color: var(--color-text-link) !important; + line-height: var(--line-height-heading) !important; + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: normal !important; + font-weight: var(--font-weight-semibold) !important; + + &:hover { + text-decoration: underline; + cursor: pointer; + } + } + + &-grid-col-2 { + display: grid; + grid-template-columns: 1fr 1fr; + width: 100%; } } - -.twitch-notes-settings-container { - border: 0; - font: inherit; - padding: 0; - vertical-align: baseline; - position: fixed; - z-index: var(--z-index-balloon); - inset: auto 0 0 auto; - margin: 0 69px 48px 0; -} - -.twitch-notes-settings-balloon { - display: inline-block; - max-width: 90vw; - min-width: 0; - white-space: nowrap; - border-radius: 0.6rem !important; - background-color: var(--color-background-base) !important; - box-shadow: var(--shadow-elevation-2) !important; - color: inherit !important; -} - -.twitch-notes-settings-popover { - white-space: normal; - width: 32rem; -} - -.twitch-notes-settings-header { - display: flex !important; - -webkit-box-align: center !important; - align-items: center !important; - position: relative !important; - padding-left: 1rem !important; - padding-right: 1rem !important; - background-color: var(--color-background-base) !important; - min-height: 4rem; -} - -.twitch-notes-settings-header-left-element { - left: 0 !important; - margin-right: 0.5rem !important; - width: 3rem; -} - -.twitch-notes-settings-header-center-element { - -webkit-box-align: center !important; - align-items: center !important; - display: flex !important; - text-align: center !important; - -webkit-box-flex: 1 !important; - flex-grow: 1 !important; - -webkit-box-pack: center !important; - justify-content: center !important; -} - -.twitch-notes-settings-header-center-element-content { - line-height: 1.5; - color: var(--color-text-alt) !important; - font-size: var(--font-size-5) !important; - font-weight: var(--font-weight-semibold) !important; -} - - -.twitch-notes-settings-header-right-element { - right: 0 !important; - margin-left: 0.5rem !important; -} - -.twitch-notes-settings-close-button { - cursor: default; - text-transform: none; - text-indent: 0; - text-shadow: none; - letter-spacing: normal; - text-rendering: auto; - appearance: auto; - writing-mode: horizontal-tb !important; - box-sizing: border-box; - margin: 0; - font: inherit; - border: none; - font-size: var(--button-text-default); - font-weight: var(--font-weight-semibold); - vertical-align: middle; - overflow: hidden; - text-decoration: none; - white-space: nowrap; - position: relative; - display: inline-flex; - -webkit-box-align: center; - align-items: center; - -webkit-box-pack: center; - justify-content: center; - user-select: none; - border-radius: var(--border-radius-medium); - height: calc(var(--button-size-default) - 1rem); - width: calc(var(--button-size-default) - 1rem); - background-color: var(--color-background-button-text-default); - color: var(--color-fill-button-icon); -} - -.twitch-notes-settings-scrollable-area { - display: flex; - overflow: hidden; - z-index: 0; - height: 100%; - position: relative; - max-height: 478px; -} - -.twitch-notes-settings-content { - box-sizing: content-box; - min-width: 100%; - overflow-x: hidden; - overflow-y: auto; - max-height: inherit !important; - margin: 1rem; - padding-bottom: 0 !important; -} - -.twitch-notes-settings-option-line { - position: relative !important; - width: calc(100% - 2rem) !important; -} - -.twitch-notes-settings-option-line-button { - border-radius: var(--border-radius-medium); - display: block; - width: 100%; - color: inherit; -} - -.twitch-notes-settings-option-line-button:hover { - cursor: pointer; - text-decoration: none; - color: inherit; - background-color: var(--color-background-interactable-hover); -} - -.twitch-notes-settings-option-line-button-container { - display: flex !important; - -webkit-box-align: center !important; - align-items: center !important; - position: relative !important; - padding: 0.5rem !important; -} - -.twitch-notes-settings-option-line-button-container-content { - -webkit-box-flex: 1 !important; - flex-grow: 1 !important; -} - -.twitch-note-settings-separator { - border-top: 1px solid var(--color-border-base); - margin-top: 1rem !important; - margin-left: 0.5rem !important; - margin-right: 0.5rem !important; - padding-bottom: 1rem !important; -} - -.twitch-notes-x-button { - position: absolute; - left: 0; - width: 100%; - min-height: 100%; - top: 0; - fill: currentcolor; -} - -.twitch-notes-blurred-background { - position: fixed; - inset: 0 0 0 0; - z-index: 2000000; - background: rgba(0, 0, 0, 0.4); - backdrop-filter: blur(2px); -} - -.twitch-notes-center-floating-container { - background: var(--color-background-base); - border: var(--border-width-default) solid var(--color-border-base) !important; - padding: 4rem 2rem 2rem; - position: fixed; - top: 50vh; - left: 50vw; - transform: translate(-50%, -50%); - max-height: 90vh; - max-width: 90vw; - overflow: auto; -} - -.twitch-notes-user-list-user { - padding: 1rem; - border-bottom: var(--border-width-default) solid var(--color-border-base) !important; - cursor: pointer; -} - -.twitch-notes-user-list-user[data-active] { - background: #772ce833; -} diff --git a/src/toggleSettingsList.ts b/src/toggleSettingsList.ts index df33423..080f1c2 100644 --- a/src/toggleSettingsList.ts +++ b/src/toggleSettingsList.ts @@ -1,94 +1,18 @@ import NoteStorage from "./NoteStorage"; -import { getCloseButtonSVG } from "./HTMLTemplates"; import openAllNoteListWindow from "./openAllNoteListWindow"; import openClearDataWindow from "./openClearDataWindow"; -import openImportNotesWindow from "./openImprtNotesWindow"; +// import openImportNotesWindow from "./openImprtNotesWindow"; import createChatSettingsLine from "./chatSettingsLine"; -import { HTMLBuilderBlock } from "./types"; +import {HTMLBuilderBlock} from "./types"; import HTMLBuilder from "./HTMLBuilder"; +import TwitchCloseButton from "./HTMLElements/TwitchCloseButton"; export default function toggleSettingsList() { const settingsWindow = document.querySelector('.twitch-notes-settings-container') as HTMLElement; - if (!settingsWindow) { - const settingsContainer: HTMLBuilderBlock = { - element: 'div', - class: 'twitch-notes-settings-container', - content: [{ - element: 'div', - class: 'twitch-notes-settings-balloon', - content: [{ - element: 'div', - class: 'twitch-notes-settings-popover', - content: [ - { - element: 'div', - class: 'twitch-notes-settings-header', - content: [ - { - element: 'div', - class: 'twitch-notes-settings-header-left-element', - }, - { - element: 'div', - class: 'twitch-notes-settings-header-center-element', - content: [{ - element: 'p', - class: 'twitch-notes-settings-header-center-element-content', - content: ['Twitch Notes Settings'] - }] - }, - { - element: 'div', - class: 'twitch-notes-settings-header-right-element', - content: [{ - element: 'button', - class: 'twitch-notes-settings-close-button', - content: [getCloseButtonSVG()], - mouseClickEvent: () => toggleSettingsList(), - }] - } - ] - }, - { - element: 'div', - class: 'twitch-notes-settings-scrollable-area', - content: [{ - element: 'div', - class: 'twitch-notes-settings-content', - content: [ - createChatSettingsLine('Export Notes', () => { - NoteStorage.exportNotes(); - toggleSettingsList(); - }), - createChatSettingsLine('Import Notes',() => { - openImportNotesWindow(); - toggleSettingsList(); - }), - createChatSettingsLine('Clear Data',() => { - openClearDataWindow(); - toggleSettingsList(); - }), - { - element: 'div', - class: 'twitch-note-settings-separator', - }, - createChatSettingsLine('View All Notes',() => { - openAllNoteListWindow(); - toggleSettingsList(); - }), - ] - }] - } - ] - }] - }] - }; - - const settingsContainerElement = new HTMLBuilder(settingsContainer); - - document.body.appendChild(settingsContainerElement.getElement()); - return; - } else { + if (settingsWindow) { settingsWindow.remove(); + return; } + + } \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 9dd28ed..329bde2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,24 +1,14 @@ -import {CustomHTMLElement} from "./CustomHTMLElement"; - -export type CustomHTMLElementConstructor = { - class?: string | string[], - id?: string, - css?: Partial, - attributes?: {[key: string]: string}, - body?: string | HTMLElement, - customBody?: CustomHTMLElement, -} - export type HTMLBuilderBlock = { element: 'div' | 'span' | 'button' | 'a' | 'p' | 'strong' | 'em' | 'input' | 'img', id?: string, class?: string | string[], style?: Partial, attributes?: {[key: string]: string}, - content?: (HTMLBuilderBlock | string)[], + content?: (HTMLBuilderBlock | string | HTMLElement)[], mouseClickEvent?: Function, mouseMoveEvent?: Function, mouseDownEvent?: Function, mouseUpEvent?: Function, keyUpEvent?: Function, + changeListener?: Function, } \ No newline at end of file