diff --git a/client/css/bg/scribbles2.png b/client/css/bg/scribbles2.png index 693c71ce..34677b34 100644 Binary files a/client/css/bg/scribbles2.png and b/client/css/bg/scribbles2.png differ diff --git a/client/css/bigcards.css b/client/css/bigcards.css index 9b7b9a2f..2746e5f8 100644 --- a/client/css/bigcards.css +++ b/client/css/bigcards.css @@ -18,6 +18,115 @@ display: block; } +/* .label .content { + font-family: "Rock Salt" !important; + font-size: 1.2em; +} */ + +.label { + width: 230px; + height: 60px; + xpadding: 5px; float: left; + xmargin: 0 10px 10px 0; + font-size: .9em; + font-family: "Rock Salt" !important; + border-radius: 5px; + + + + overflow: hidden; + + position: absolute; + z-index: 10; + + top: 460px; + left: 0px; + + display: block; +} + +.label .content { + overflow: hidden; + display: block; + width: 190px; + height: 60px; + margin: auto; + padding: 0 20px; + + font-family: "Rock Salt" !important; + font-size: 1.2em; + letter-spacing: 0px; + + xtext-shadow: 0px 0px 1px #444; + + opacity: .9; + text-align: center; + xline-height: 16px; + + align-items: center; + justify-content: center; + display: flex; +} + +.label .card-icon { + left: 210px; + top: 5px; + z-index: 99999990; +} + +.label .card-icon2 { + left: 210px; + top: 28px; + +} + +.label.white { + color: black; + background: rgba(255, 255, 255, 0.5); + box-shadow: 5px 5px 5px #ccc; +} + + +.label.green { + background: #016a70; + opacity: 0.8; + box-shadow: 5px 5px 5px #fff; + color: #ffffff; +} + +.label.green .content { + color: #ffffff; +} + +.label.yellow { + background: #f1cd5f; + opacity: 0.8; + box-shadow: 5px 5px 5px #ccc; + color: #black; +} + +.label.yellow .content { + color: black; +} + +.label.blue { + background: #d37153; + opacity: 0.8; + box-shadow: 5px 5px 5px #fff; + color: #ffffff; +} + +.label.blue .content { + color: #ffffff; +} + +/* .sticky .filler { + margin-right: 5px; + margin-bottom: 23px; + margin-left: 25px; +} */ + + .pink { } @@ -40,6 +149,17 @@ z-index: -1000; } +.card-avatar { + position: absolute; + top: 60% !important; + left: 80%; + width: 24px; + height: 24px; + overflow: hidden; + z-index: -500; + border-radius: 50%; +} + .content { overflow: hidden; display: block; @@ -47,7 +167,7 @@ height: 88px; margin: 5px 23px 0px 34px; - font-family: 'Covered By Your Grace',"Arial Rounded MT Bold", arial, serif; + font-family: 'Handlee',"Arial Rounded MT Bold", arial, serif; font-size: 18px; letter-spacing: 0px; @@ -103,7 +223,8 @@ height: 68px; margin: 1px 3px 0px 32px; - font-family: 'Covered By Your Grace',"Arial Rounded MT Bold", arial, serif; + font-family: 'Handlee',"Arial Rounded MT Bold", arial, serif; + font-weight: bold; font-size: 16px; letter-spacing: 0px; @@ -129,11 +250,11 @@ .sticky .card-icon2 { left: 100px; top: 14px; - + } .sticky .filler { margin-right: 5px; margin-bottom: 23px; margin-left: 25px; -} \ No newline at end of file +} diff --git a/client/css/nocards.css b/client/css/nocards.css index c324b2e2..fef7113d 100644 --- a/client/css/nocards.css +++ b/client/css/nocards.css @@ -1,22 +1,22 @@ -.card { +.card { width: 100px; height: 50px; xpadding: 5px; float: left; xmargin: 0 10px 10px 0; font-size: .9em; - + overflow: hidden; - + position: absolute; z-index: 10; - + top: 100px; left: 0px; - + display: block; - + xborder: solid rgba(92, 157, 181,0.5) 3px; background-color: #ECDC96; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ECDC96), color-stop(100%,#EAD272)); @@ -46,23 +46,34 @@ display: none; } -.content { +.card-avatar { + position: absolute; + top: 60% !important; + left: 80%; + width: 24px; + height: 24px; + overflow: hidden; + z-index: -500; + border-radius: 50%; +} + +.content { overflow: hidden; display: block; - xwidth: 70%; + xwidth: 70%; height: 90px; xmargin: 5px 20px 0px 30px; - + font-family: 'Helvetica Neue', arial, serif; font-size: 12px; - letter-spacing: 0px; - + letter-spacing: 0px; + xtext-shadow: 0px 0px 1px #444; - + opacity: 1; - + color: black; text-align: center; padding-top: 0px; - -} \ No newline at end of file + +} diff --git a/client/css/smallcards.css b/client/css/smallcards.css index 09cf97a7..2fb48bcb 100644 --- a/client/css/smallcards.css +++ b/client/css/smallcards.css @@ -41,6 +41,17 @@ z-index: -1000; } +.card-avatar { + position: absolute; + top: 60% !important; + left: 80%; + width: 16px; + height: 16px; + overflow: hidden; + z-index: -500; + border-radius: 50%; +} + .content { overflow: hidden; display: block; @@ -157,4 +168,4 @@ margin-right: 2px; margin-bottom: 12px; margin-left: 25px; -} \ No newline at end of file +} diff --git a/client/css/style.css b/client/css/style.css index 16852f42..155ab460 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -1,4 +1,73 @@ /* reset css */ + +@font-face { + font-family: 'Nexa Bold'; + src: url('/fonts/NexaFreeBoldwebfont.eot'); + src: local('Nexa Bold'), url('/fonts/NexaFreeBoldwebfont.woff') format('woff'), url('/fonts//NexaFreeBoldwebfont.ttf') format('truetype'); +} + +@font-face { + font-family: 'Poppins'; + src: url('/fonts/NexaFreeBoldwebfont.eot'); + src: local('Nexa Bold'), url('/fonts/NexaFreeBoldwebfont.woff') format('woff'), url('/fonts//NexaFreeBoldwebfont.ttf') format('truetype'); +} + +// ------------------------------------------------ + +/* Manrope-regular - latin */ +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 400; + src: local('Manrope Regular'), local('Manrope-Regular'), + url('/fonts/manrope-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('/fonts/Manrope-Regular.woff') format('woff'), /* Modern Browsers */ + url('/fonts/manrope-regular.ttf') format('truetype'); /* Safari, Android, iOS */ +} +/* Manrope-500 - latin */ +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 500; + src: local('Manrope Medium'), local('Manrope-SemiBold'), + url('/fonts/manrope-medium.woff2') format('woff2'), /* Super Modern Browsers */ + url('/fonts/Manrope-Medium.woff') format('woff'), /* Modern Browsers */ + url('/fonts/manrope-medium.ttf') format('truetype'); /* Safari, Android, iOS */ +} +/* Manrope-600 - latin */ +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 600; + src: local('Manrope SemiBold'), local('Manrope-SemiBold'), + url('/fonts/manrope-semibold.woff2') format('woff2'), /* Super Modern Browsers */ + url('/fonts/Manrope-SemiBold.woff') format('woff'), /* Modern Browsers */ + url('/fonts/manrope-semibold.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +/* Manrope-700 - latin */ +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 700; + src: local('Manrope Bold'), local('Manrope-SemiBold'), + url('/fonts/manrope-bold.woff2') format('woff2'), /* Super Modern Browsers */ + url('/fonts/Manrope-Bold.woff') format('woff'), /* Modern Browsers */ + url('/fonts/manrope-bold.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +/* Manrope-800 - latin */ +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 800; + src: local('Manrope ExtraBold'), local('Manrope-ExtraBold'), + url('/fonts/manrope-extrabold.woff2') format('woff2'), /* Super Modern Browsers */ + url('/fonts/Manrope-ExtraBold.woff') format('woff'), /* Modern Browsers */ + url('/fonts/manrope-extrabold.ttf') format('truetype'); /* Safari, Android, iOS */ +} + + html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline} article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block} body{line-height:1} @@ -19,21 +88,15 @@ body { font-family: 'Helvetica Neue Light', arial, serif; font-size: 13px; color: #333; - background-color: #ddd; - xbackground-image: -webkit-gradient(radial, 265 118, 456, 147 0, 29, from(#DDDDDD), to(#f3f3f3)); - padding-left: 10px; - xheight: 1400px; xwidth: 2000px; - user-select: none; -o-user-select:none; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; - background-image: url('bg/concrete_wall_2_2.png'); } /* @@ -42,12 +105,12 @@ https://headers-css.vercel.app/styles/header-1.css .site-header { position: relative; - background-color: none; + background-color: none; } .site-header__wrapper { padding-top: 1rem; - padding-bottom: 1rem; + padding-bottom: 1rem; } .site-header__wrapper { @@ -56,10 +119,10 @@ https://headers-css.vercel.app/styles/header-1.css align-items: center; padding-top: 0; padding-bottom: 0; -} +} .nav__wrapper { - display: flex; + display: flex; } .ui-menu { width: 150px; } @@ -74,7 +137,7 @@ https://headers-css.vercel.app/styles/header-1.css .nav__item a { display: block; - padding: .5rem 1rem; + padding: .5rem 1rem; } .ui-widget-content { @@ -96,22 +159,12 @@ https://headers-css.vercel.app/styles/header-1.css #board { position: relative; - background-color: #dcd5d1; + background-color: #f4f3f3; height: 100%; xwidth: 980px; xborder: solid silver 8px; - background-image: -webkit-gradient( - linear, - left top, - right bottom, - color-stop(0.49, rgb(214,210,206)), - color-stop(0.84, rgb(196,191,182)) - ); - - xbackground: -moz-linear-gradient(top, rgb(214,210,206), #000); - -moz-box-shadow:inset 1px 1px 3px #999; box-shadow:inset 1px 1px 3px #999; } @@ -119,10 +172,10 @@ https://headers-css.vercel.app/styles/header-1.css .board-outline { - border: solid #ccc 8px; + border: solid #ccc 2px; display: block; width: 996px; - height: 466px; + height: 510px; xmargin-left: auto; xmargin-right: auto; @@ -137,8 +190,8 @@ https://headers-css.vercel.app/styles/header-1.css height: 100%; position: absolute; display: inline; - opacity: 0.035; - background-image: url('scribbles2.png'); + opacity: 1; + background-repeat: no-repeat; } @@ -161,9 +214,14 @@ width: 16px; height: 16px; } +.card-avatar { + opacity: 1 !important; +} + + .card-icon2 { top: 17%; left: 85%; - + cursor: pointer; } @@ -224,7 +282,6 @@ width: 16px; height: 16px; xborder-left: dashed #19ba98 5px; text-align: center; vertical-align: top; - height: 100%; xopacity: 1; background-image: url('../images/green-board-line.png'); background-repeat: repeat-y; @@ -235,7 +292,6 @@ width: 16px; height: 16px; border-left: none; text-align: center; vertical-align: top; - height: 100%; background-image: none; } @@ -314,14 +370,37 @@ h2 { position: absolute; right: 3px; top: 228px; display: none; } -.col-icon { - opacity: 0.4; +.col-icon, .line-icon { + opacity: 0.4; + cursor: pointer; } -.col-icon:hover { +.col-icon:hover, .line-icon:hover { opacity: 1.0; } +.line-buttons { + position: relative; + height: 25px; + top: calc(100% - 25px); + width: 100%; +} + +.line-buttons-inner { + width: 52px; + margin: auto; + padding-right: 10px; +} + +.line-icon { + margin-left: 3px; + margin-right: 3px; +} + + #add-line, #delete-line { + display: none; +} + .column-editable { min-height: 40px; min-width: 70px; @@ -345,6 +424,11 @@ h2 { .buttons { float: left; + cursor: pointer; +} + +.buttons.dark { + color: #ffffff; } .names { @@ -353,8 +437,7 @@ h2 { xwidth: 980px; text-align: right; color: #bbb; - letter-spacing: 4px; - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", 'Helvetica Neue', arial, serif; + font-family: "Manrope", "Helvetica Neue Light", "HelveticaNeue-Light", 'Helvetica Neue', arial, serif; font-size: 13px; } @@ -377,7 +460,7 @@ h2 { padding: 0; //2px 8px 2px 2px; border: none; outline: 0; - width: 100px; + width: 200px; background: -webkit-gradient(linear, left top, left 25, from(#FFFFFF), color-stop(4%, #EEEEEE), to(#FFFFFF)); background: -moz-linear-gradient(top, #FFFFFF, #EEEEEE 1px, #FFFFFF 25px); @@ -387,7 +470,6 @@ h2 { text-align: right; font-family: "Helvetica Neue Light", "HelveticaNeue-Light", 'Helvetica Neue', arial, serif; font-size: 13px; - letter-spacing: 4px; margin:0; position: relative; @@ -397,7 +479,7 @@ h2 { xpadding: 2px 2px 2px 2px; xborder: solid 1px #E5E5E5; outline: 0; - width: 100px; + width: 200px; background: -webkit-gradient(linear, left top, left 25, from(#FFFFFF), color-stop(4%, #EEEEEE), to(#FFFFFF)); background: -moz-linear-gradient(top, #FFFFFF, #EEEEEE 1px, #FFFFFF 25px); xopacity: .5; @@ -408,7 +490,6 @@ xopacity: .5; text-align: right; font-family: "Helvetica Neue Light", "HelveticaNeue-Light", 'Helvetica Neue', arial, serif; font-size: 13px; - letter-spacing: 4px; margin:0; } @@ -636,6 +717,19 @@ input.text { border-bottom: dashed 3px #19ba98; } +input.url { + width: 360px; + background: none; + padding: 6px; + margin-bottom: 10px; + border: none; + font-size: 18px; + font-family: 'Covered By Your Grace',"Arial Rounded MT Bold", arial, serif; + color: #5c9db4; + text-align: center; + border-bottom: dashed 3px #19ba98; +} + input:hover { x-webkit-box-shadow: 0px 0px 4px #000; xbackground: none; @@ -672,11 +766,13 @@ input:hover { #marker { position: absolute; bottom: 0; right: 200px; z-index: 1; + display: none; } #eraser { position: absolute; bottom: 0; right: 70px; z-index: 1; + display: none; } @@ -763,7 +859,7 @@ img { -ms-user-select: none; user-select: none; } - + .signature-pad { position: absolute; left: 0; @@ -782,4 +878,22 @@ img { #pen[data-ison=true] { color: black; opacity: 1; -} \ No newline at end of file +} + +.sticker, #add-col, #delete-col { + cursor: pointer; +} + +.delete-card-icon { + cursor: pointer; +} + +.logo { + position: absolute; + top: 100%; + margin-top: -35px; + left: 100%; + margin-left: -95px; + opacity: 0.5; + z-index: 1; +} diff --git a/client/fonts/LatoLatin-Semibold.woff b/client/fonts/LatoLatin-Semibold.woff new file mode 100644 index 00000000..5e228979 Binary files /dev/null and b/client/fonts/LatoLatin-Semibold.woff differ diff --git a/client/fonts/Manrope-Bold.woff b/client/fonts/Manrope-Bold.woff new file mode 100644 index 00000000..75e3a441 Binary files /dev/null and b/client/fonts/Manrope-Bold.woff differ diff --git a/client/fonts/Manrope-ExtraBold.woff b/client/fonts/Manrope-ExtraBold.woff new file mode 100644 index 00000000..8bf9ec9d Binary files /dev/null and b/client/fonts/Manrope-ExtraBold.woff differ diff --git a/client/fonts/Manrope-ExtraLight.ttf b/client/fonts/Manrope-ExtraLight.ttf new file mode 100644 index 00000000..c403a28c Binary files /dev/null and b/client/fonts/Manrope-ExtraLight.ttf differ diff --git a/client/fonts/Manrope-ExtraLight.woff b/client/fonts/Manrope-ExtraLight.woff new file mode 100644 index 00000000..70c90382 Binary files /dev/null and b/client/fonts/Manrope-ExtraLight.woff differ diff --git a/client/fonts/Manrope-ExtraLight.woff2 b/client/fonts/Manrope-ExtraLight.woff2 new file mode 100644 index 00000000..b3521d0e Binary files /dev/null and b/client/fonts/Manrope-ExtraLight.woff2 differ diff --git a/client/fonts/Manrope-Light.woff b/client/fonts/Manrope-Light.woff new file mode 100644 index 00000000..718e921d Binary files /dev/null and b/client/fonts/Manrope-Light.woff differ diff --git a/client/fonts/Manrope-Medium.woff b/client/fonts/Manrope-Medium.woff new file mode 100644 index 00000000..a2b2b9eb Binary files /dev/null and b/client/fonts/Manrope-Medium.woff differ diff --git a/client/fonts/Manrope-Regular.woff b/client/fonts/Manrope-Regular.woff new file mode 100644 index 00000000..e828391a Binary files /dev/null and b/client/fonts/Manrope-Regular.woff differ diff --git a/client/fonts/Manrope-SemiBold.woff b/client/fonts/Manrope-SemiBold.woff new file mode 100644 index 00000000..43ba21d2 Binary files /dev/null and b/client/fonts/Manrope-SemiBold.woff differ diff --git a/client/fonts/NexaFreeBoldwebfont-bg.png b/client/fonts/NexaFreeBoldwebfont-bg.png new file mode 100644 index 00000000..c7075363 Binary files /dev/null and b/client/fonts/NexaFreeBoldwebfont-bg.png differ diff --git a/client/fonts/NexaFreeBoldwebfont-thumb.png b/client/fonts/NexaFreeBoldwebfont-thumb.png new file mode 100644 index 00000000..68517fb1 Binary files /dev/null and b/client/fonts/NexaFreeBoldwebfont-thumb.png differ diff --git a/client/fonts/NexaFreeBoldwebfont.eot b/client/fonts/NexaFreeBoldwebfont.eot new file mode 100644 index 00000000..0f1d80fc Binary files /dev/null and b/client/fonts/NexaFreeBoldwebfont.eot differ diff --git a/client/fonts/NexaFreeBoldwebfont.png b/client/fonts/NexaFreeBoldwebfont.png new file mode 100644 index 00000000..c94c7295 Binary files /dev/null and b/client/fonts/NexaFreeBoldwebfont.png differ diff --git a/client/fonts/NexaFreeBoldwebfont.ttf b/client/fonts/NexaFreeBoldwebfont.ttf new file mode 100644 index 00000000..1c7319f1 Binary files /dev/null and b/client/fonts/NexaFreeBoldwebfont.ttf differ diff --git a/client/fonts/NexaFreeBoldwebfont.woff b/client/fonts/NexaFreeBoldwebfont.woff new file mode 100644 index 00000000..7c80c0e8 Binary files /dev/null and b/client/fonts/NexaFreeBoldwebfont.woff differ diff --git a/client/fonts/manrope-bold.ttf b/client/fonts/manrope-bold.ttf new file mode 100644 index 00000000..3aacb53d Binary files /dev/null and b/client/fonts/manrope-bold.ttf differ diff --git a/client/fonts/manrope-bold.woff2 b/client/fonts/manrope-bold.woff2 new file mode 100644 index 00000000..97f295a2 Binary files /dev/null and b/client/fonts/manrope-bold.woff2 differ diff --git a/client/fonts/manrope-extrabold.ttf b/client/fonts/manrope-extrabold.ttf new file mode 100644 index 00000000..2d66dd67 Binary files /dev/null and b/client/fonts/manrope-extrabold.ttf differ diff --git a/client/fonts/manrope-extrabold.woff2 b/client/fonts/manrope-extrabold.woff2 new file mode 100644 index 00000000..e2a91438 Binary files /dev/null and b/client/fonts/manrope-extrabold.woff2 differ diff --git a/client/fonts/manrope-light.ttf b/client/fonts/manrope-light.ttf new file mode 100644 index 00000000..a28d1e49 Binary files /dev/null and b/client/fonts/manrope-light.ttf differ diff --git a/client/fonts/manrope-light.woff2 b/client/fonts/manrope-light.woff2 new file mode 100644 index 00000000..69a2d0d5 Binary files /dev/null and b/client/fonts/manrope-light.woff2 differ diff --git a/client/fonts/manrope-medium.ttf b/client/fonts/manrope-medium.ttf new file mode 100644 index 00000000..0fd05360 Binary files /dev/null and b/client/fonts/manrope-medium.ttf differ diff --git a/client/fonts/manrope-medium.woff2 b/client/fonts/manrope-medium.woff2 new file mode 100644 index 00000000..e23deaa2 Binary files /dev/null and b/client/fonts/manrope-medium.woff2 differ diff --git a/client/fonts/manrope-regular.ttf b/client/fonts/manrope-regular.ttf new file mode 100644 index 00000000..bf9d3a3e Binary files /dev/null and b/client/fonts/manrope-regular.ttf differ diff --git a/client/fonts/manrope-regular.woff2 b/client/fonts/manrope-regular.woff2 new file mode 100644 index 00000000..d6307609 Binary files /dev/null and b/client/fonts/manrope-regular.woff2 differ diff --git a/client/fonts/manrope-semibold.ttf b/client/fonts/manrope-semibold.ttf new file mode 100644 index 00000000..a1f285a4 Binary files /dev/null and b/client/fonts/manrope-semibold.ttf differ diff --git a/client/fonts/manrope-semibold.woff2 b/client/fonts/manrope-semibold.woff2 new file mode 100644 index 00000000..63fec32b Binary files /dev/null and b/client/fonts/manrope-semibold.woff2 differ diff --git a/client/fonts/poppins-v9-latin-600.eot b/client/fonts/poppins-v9-latin-600.eot new file mode 100644 index 00000000..14546cc1 Binary files /dev/null and b/client/fonts/poppins-v9-latin-600.eot differ diff --git a/client/fonts/poppins-v9-latin-600.svg b/client/fonts/poppins-v9-latin-600.svg new file mode 100644 index 00000000..ee342784 --- /dev/null +++ b/client/fonts/poppins-v9-latin-600.svg @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/fonts/poppins-v9-latin-600.ttf b/client/fonts/poppins-v9-latin-600.ttf new file mode 100644 index 00000000..9b165043 Binary files /dev/null and b/client/fonts/poppins-v9-latin-600.ttf differ diff --git a/client/fonts/poppins-v9-latin-600.woff b/client/fonts/poppins-v9-latin-600.woff new file mode 100644 index 00000000..a0a3ccf5 Binary files /dev/null and b/client/fonts/poppins-v9-latin-600.woff differ diff --git a/client/fonts/poppins-v9-latin-600.woff2 b/client/fonts/poppins-v9-latin-600.woff2 new file mode 100644 index 00000000..3ec0b09a Binary files /dev/null and b/client/fonts/poppins-v9-latin-600.woff2 differ diff --git a/client/fonts/poppins-v9-latin-800.eot b/client/fonts/poppins-v9-latin-800.eot new file mode 100644 index 00000000..ed877a90 Binary files /dev/null and b/client/fonts/poppins-v9-latin-800.eot differ diff --git a/client/fonts/poppins-v9-latin-800.svg b/client/fonts/poppins-v9-latin-800.svg new file mode 100644 index 00000000..29f08c80 --- /dev/null +++ b/client/fonts/poppins-v9-latin-800.svg @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/fonts/poppins-v9-latin-800.ttf b/client/fonts/poppins-v9-latin-800.ttf new file mode 100644 index 00000000..2d1ce148 Binary files /dev/null and b/client/fonts/poppins-v9-latin-800.ttf differ diff --git a/client/fonts/poppins-v9-latin-800.woff b/client/fonts/poppins-v9-latin-800.woff new file mode 100644 index 00000000..e8bdbfac Binary files /dev/null and b/client/fonts/poppins-v9-latin-800.woff differ diff --git a/client/fonts/poppins-v9-latin-800.woff2 b/client/fonts/poppins-v9-latin-800.woff2 new file mode 100644 index 00000000..375e0f18 Binary files /dev/null and b/client/fonts/poppins-v9-latin-800.woff2 differ diff --git a/client/fonts/poppins-v9-latin-regular.eot b/client/fonts/poppins-v9-latin-regular.eot new file mode 100644 index 00000000..e71bd731 Binary files /dev/null and b/client/fonts/poppins-v9-latin-regular.eot differ diff --git a/client/fonts/poppins-v9-latin-regular.svg b/client/fonts/poppins-v9-latin-regular.svg new file mode 100644 index 00000000..c3d485c1 --- /dev/null +++ b/client/fonts/poppins-v9-latin-regular.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/fonts/poppins-v9-latin-regular.ttf b/client/fonts/poppins-v9-latin-regular.ttf new file mode 100644 index 00000000..5fb39dcc Binary files /dev/null and b/client/fonts/poppins-v9-latin-regular.ttf differ diff --git a/client/fonts/poppins-v9-latin-regular.woff b/client/fonts/poppins-v9-latin-regular.woff new file mode 100644 index 00000000..606db1d7 Binary files /dev/null and b/client/fonts/poppins-v9-latin-regular.woff differ diff --git a/client/fonts/poppins-v9-latin-regular.woff2 b/client/fonts/poppins-v9-latin-regular.woff2 new file mode 100644 index 00000000..6711b0b8 Binary files /dev/null and b/client/fonts/poppins-v9-latin-regular.woff2 differ diff --git a/client/images/adh-logo.png b/client/images/adh-logo.png new file mode 100644 index 00000000..e764fd8f Binary files /dev/null and b/client/images/adh-logo.png differ diff --git a/client/script.js b/client/script.js index 17401efe..6bade416 100644 --- a/client/script.js +++ b/client/script.js @@ -1,5 +1,4 @@ var cards = {}; -var totalcolumns = 0; var columns = []; var currentTheme = "bigcards"; var boardInitialized = false; @@ -13,6 +12,9 @@ var baseurl = location.pathname.substring(0, location.pathname.lastIndexOf('/')) var socket = io({ path: '/socketio' }); + +var userCache = {}; + //an action has happened, send it to the //server function sendAction(a, d) { @@ -103,7 +105,7 @@ function getMessage(m) { case 'createCard': //console.log(data); drawNewCard(data.id, data.text, data.x, data.y, data.rot, data.colour, data.type, null, - null); + null, data.username); break; case 'deleteCard': @@ -120,6 +122,9 @@ function getMessage(m) { { $('#' + data.id).children('.change-colour').data('colour',data.colour); $('#' + data.id).children('.card-image').attr("src", 'images/' + data.colour + '-card.png'); + + // Remove all color classes and add new one + $('#' + data.id).removeClass(cardColours.join(' ')).addClass(data.colour); } break; @@ -135,6 +140,10 @@ function getMessage(m) { changeThemeTo(data); break; + case 'changeBg': + changeBgTo(data); + break; + case 'join-announce': displayUserJoined(data.sid, data.user_name); break; @@ -151,6 +160,11 @@ function getMessage(m) { updateName(message.data.sid, message.data.user_name); break; + case 'updateUserCache': + updateUserCache(message.data); + updateUserInfo(); + break; + case 'addSticker': addSticker(message.data.cardId, message.data.stickerId); break; @@ -186,9 +200,11 @@ $(document).bind('keyup', function(event) { keyTrap = event.which; }); -function drawNewCard(id, text, x, y, rot, colour, type, sticker, animationspeed) { +function drawNewCard(id, text, x, y, rot, colour, type, sticker, animationspeed, username) { //cards[id] = {id: id, text: text, x: x, y: y, rot: rot, colour: colour}; + const userAvatar = userCache[username] ? userCache[username].userAvatar : null; + var h = ''; if (type == 'card' || type == null) { @@ -199,7 +215,8 @@ function drawNewCard(id, text, x, y, rot, colour, type, sticker, animationspeed) \ \ \ -
'): '') + + '
' + text + '
\
'; @@ -211,6 +228,19 @@ function drawNewCard(id, text, x, y, rot, colour, type, sticker, animationspeed) ">\ \ \ + ' + (userAvatar ? (''): '') + + '
' + + text + '
\ + '; + } + else if (type == 'label') { + h = '
\ + \ + \
' + text + '
\ @@ -342,7 +372,7 @@ function drawNewCard(id, text, x, y, rot, colour, type, sticker, animationspeed) function() { rotateCardColor(id, $(this).data('colour')); }); - + card.children('.content').editable({ multiline: true, @@ -409,7 +439,8 @@ function addSticker(cardId, stickerId) { // cards //---------------------------------- function createCard(id, text, x, y, rot, colour, type) { - drawNewCard(id, text, x, y, rot, colour, type, null, null); + const username = getCookie('adh-username'); + drawNewCard(id, text, x, y, rot, colour, type, null, null, username); var action = "createCard"; @@ -420,7 +451,8 @@ function createCard(id, text, x, y, rot, colour, type) { y: y, rot: rot, colour: colour, - type: type + type: type, + username: getCookie('adh-username') }; sendAction(action, data); @@ -452,6 +484,7 @@ function rotateCardColor(id, currentColour) { var newIndex = index + 1; newIndex = newIndex % (stickyColours.length + 1); + $('#'+id).removeClass(currentColour).addClass(cardColours[newIndex]); $('#'+id).children('.card-image').attr("src", 'images/' + cardColours[newIndex] + '-card.png'); $('#'+id).children('.change-colour').data('colour',cardColours[newIndex]); @@ -480,6 +513,7 @@ function initCards(cardArray) { card.type, card.sticker, 0, + card.username ); } @@ -492,67 +526,106 @@ function initCards(cardArray) { // cols //---------------------------------- -function drawNewColumn(columnName) { +function drawNewColumn() { var cls = "col"; - if (totalcolumns === 0) { + var drawn_col_number = $('tr:first').find('td').length - 1; + + if (drawn_col_number === 0) { cls = "col first"; } - $('#icon-col').before('

' + columnName + '

'); + var columnName = 'New'; + var colId = drawn_col_number + 1; - $('.editable').editable({ - multiline: false, - save: function(content) { - onColumnChange(this.id, content.target.innerText); - } - }); + $('tr').each(function() { + var newTd = $('

' + columnName + '

'); + $( this ).find('#icon-col').before(newTd); + + newTd.hide(); + $( this ).find('.col:last').fadeIn(1500); + }); - $('.col:last').fadeIn(1500); + /*$('#icon-col').before('

' + columnName + '

');*/ - totalcolumns++; + refreshEditable(); + + //$('.col:last').fadeIn(1500); } -function onColumnChange(id, text) { - var names = Array(); +function refreshEditable(){ + $('.editable').editable({ + multiline: false, + save: function(content) { + const colId = parseInt($(this).attr('data-col')); + const rowId = parseInt($(this).parents('tr:first').attr('data-row')); + onColumnChange(colId, rowId, content.target.innerText); + } + }); +} - //console.log(id + " " + text ); +function setCellText(colId, rowId, text){ + const row = $('tr[data-row=' + rowId + ']'); + const col = row.find('h2[data-col=' + colId + ']'); + col.text(text); +} - //Get the names of all the columns right from the DOM - $('.col').each(function() { +function onColumnChange(colId, rowId, text) { + columns[colId - 1][rowId - 1] = text; + updateColumns(columns); +} - //get ID of current column we are traversing over - var thisID = $(this).children("h2").attr('id'); +function displayRemoveAllColumns() { + if (columns.length <= 0) return false; - if (id == thisID) { - names.push(text); - } else { - names.push($(this).text()); + $('.col').fadeOut(150, + function() { + $(this).remove(); } + ); +} + +function displayRemoveColumn() { + if (columns.length <= 0) return false; + + $('tr').each(function(){ + $(this).find('.col:last').fadeOut(150, + function() { + $(this).remove(); + } + ); }); - updateColumns(names); } -function displayRemoveColumn() { - if (totalcolumns <= 0) return false; +function displayRemoveRow() { + if (columns.length <= 0) return false; + if (columns[0].length <= 1) return false; - $('.col:last').fadeOut(150, + $('tr:last').fadeOut(150, function() { $(this).remove(); } ); - totalcolumns--; } -function createColumn(name) { - if (totalcolumns >= 8) return false; +function createColumn() { + if (columns.length >= 8) return false; - drawNewColumn(name); - columns.push(name); + drawNewColumn(); + if (columns.length){ + // Create a copy of the first col + var newCol = columns[0].map((x) => x); + columns.push(newCol); + } + else { + columns.push(['New']); + } var action = "updateColumns"; @@ -561,8 +634,19 @@ function createColumn(name) { sendAction(action, data); } +function deleteAllColumns() { + if (columns.length <= 0) return false; + + displayRemoveAllColumns(); + columns = []; + + var action = "updateColumns"; + var data = columns; + sendAction(action, data); +} + function deleteColumn() { - if (totalcolumns <= 0) return false; + if (columns.length <= 0) return false; displayRemoveColumn(); columns.pop(); @@ -574,6 +658,72 @@ function deleteColumn() { sendAction(action, data); } + +function deleteRow() { + if (columns.length <= 0) return false; + + // Delete all cols if last line + if (columns[0].length == 1){ + return deleteAllColumns(); + } + + if (columns[0].length <= 1) return false; + + displayRemoveRow(); + columns.forEach(function(col){ + col.pop(); + }); + + var action = "updateColumns"; + + var data = columns; + + sendAction(action, data); +} + + +function drawNewRow() { + + var line = $('tr:last'); + var newLine = line.clone(); + newLine.find('.col').css('opacity', '1'); + var latestRowId = parseInt(newLine.attr('data-row')); + newLine.attr('data-row', latestRowId + 1); + newLine.insertAfter(line); + newLine.hide(); + newLine.fadeIn(1500); + + rowCount = $('tr').length; + + $('tr td:last-child').hide(); + $('tr:first td:last-child').attr('rowspan', rowCount).show(); + + refreshEditable(); + +} + +function createRow() { + if (!columns.length){ + return createColumn(); + } + const totalrows = columns[0].length; + + if (totalrows >= 4) return false; + + drawNewRow(); + + columns.forEach(function(col){ + col.push('New'); + }); + + var action = "updateColumns"; + + var data = columns; + + sendAction(action, data); + +} + function updateColumns(c) { columns = c; @@ -590,18 +740,27 @@ function deleteColumns(next) { } function initColumns(columnArray) { - totalcolumns = 0; columns = columnArray; + // Remove all cols $('.col').remove(); + // Remove all rows except first + $("tr:not(:first)").remove(); + + // Init cols and rows + if (columnArray.length){ + columnArray.forEach(drawNewColumn); + for (var i=0; i < columnArray[0].length - 1; i++) + drawNewRow(); + } - for (var i in columnArray) { - column = columnArray[i]; - - drawNewColumn( - column - ); + for (var i in columns){ + const col = columns[i]; + for (var j in col){ + setCellText(parseInt(i)+1, parseInt(j)+1, col[j]); + } } + } @@ -611,6 +770,14 @@ function changeThemeTo(theme) { } +function changeBgTo(bgUrl) { + $("#board-doodles").css( + "background-image", + "url('" + bgUrl + "')" + ); +} + + ////////////////////////////////////////////////////////// ////////// NAMES STUFF /////////////////////////////////// ////////////////////////////////////////////////////////// @@ -644,6 +811,30 @@ function setName(name) { setCookie('scrumscrum-username', name, 365); } +function updateUserInfo() { + const username = getCookie('adh-username'); + const userEmail = getCookie('adh-email'); + const userAvatar = getCookie('adh-avatar'); + + if (!username) + return false; + + sendAction('setUserInfo', { + username, + userEmail, + userAvatar + }); + userCache[username] = { + username, + userEmail, + userAvatar + }; +} + +function updateUserCache(users) { + userCache = users; +} + function displayInitialUsers(users) { for (var i in users) { //console.log(users); @@ -768,7 +959,7 @@ function adjustMarker(originalSize, newSize) { $("#marker,#eraser").css('top',''); // console.log( "markerleft: " + $('#marker').css('left') ); // console.log( "size: " + newSize.width); - + //if either has gone over the edge of the board, just bring it in if ( parseFloat($('#marker').css('left')) > newSize.width - 100) { @@ -780,6 +971,18 @@ function adjustMarker(originalSize, newSize) { } } + +function fullscreenMode() { + var offsets = calcCardOffset(); + var size = { + width: $(window).width() - 32, + height: $(window).height() - 85 + }; + resizeBoard(size); + boardResizeHappened(null, size); + adjustCard(offsets, true); +} + ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// @@ -809,7 +1012,7 @@ $(function() { randomCardColour(), "card"); }); - + $("#create-sticky") .click(function() { var rotation = Math.random() * 4 - 2; //add a bit of random rotation (+/- 2deg) @@ -825,6 +1028,21 @@ $(function() { }); + $("#create-label") + .click(function() { + var rotation = Math.random() * 4 - 2; //add a bit of random rotation (+/- 2deg) + uniqueID = Math.round(Math.random() * 99999999); //is this big enough to assure uniqueness? + //alert(uniqueID); + createCard( + 'card' + uniqueID, + '', + 58, $('div.board-outline').height(), // hack - not a great way to get the new card coordinates, but most consistant ATM + rotation, + randomCardColour(), + "label"); + }); + + // Style changer $("#smallify").click(function() { @@ -834,7 +1052,7 @@ $(function() { var oldHeight = $(".board-outline").height(); var offsets = calcCardOffset(); - + if (currentTheme == "bigcards") { changeThemeTo('smallcards'); newBoardSize.height = oldHeight / 1.5; @@ -849,7 +1067,7 @@ $(function() { currentTheme = "bigcards"; $("link[title=cardsize]").attr("href", "css/bigcards.css"); }*/ - + resizeBoard(newBoardSize); boardResizeHappened(null, newBoardSize); adjustCard(offsets, true); @@ -874,9 +1092,18 @@ $(function() { } ); + $('.line-buttons').hover( + function() { + $('.line-icon').fadeIn(10); + }, + function() { + $('.line-icon').fadeOut(150); + } + ); + $('#add-col').click( function() { - createColumn('New'); + createColumn(); return false; } ); @@ -888,6 +1115,20 @@ $(function() { } ); + $('#add-line').click( + function() { + createRow(); + return false; + } + ); + + $('#delete-line').click( + function() { + deleteRow(); + return false; + } + ); + // $('#cog-button').click( function(){ // $('#config-dropdown').fadeToggle(); @@ -900,6 +1141,7 @@ $(function() { // var user_name = getCookie('scrumscrum-username'); + var adh_user_name = getCookie('adh-username'); @@ -921,7 +1163,14 @@ $(function() { setName($(this).val()); }); - $("#yourname-input").val(user_name); + if (adh_user_name){ + $("#yourname-input").val(adh_user_name); + $("#yourname-input").prop('readonly', true); + } + else { + $("#yourname-input").val(user_name); + } + $("#yourname-input").blur(); $("#yourname-li").hide(); @@ -979,7 +1228,7 @@ $(function() { }); - + $( "#menu" ).menu(); $('#configmenu').click(function() { $('#menu').show(); @@ -990,7 +1239,7 @@ $(function() { $("#menu,#configmenu").click( function(e) { e.stopPropagation(); // this stops the event from bubbling up to the body }); - + $(".ceditable").editable({ multiline: false, saveDelay: 600, //wait 600ms before calling "save" callback @@ -1005,7 +1254,7 @@ $(function() { item: 'board-title', text: content.target.innerText }; - + if (content.target.innerText.length > 0) sendAction(action, data); }, @@ -1015,5 +1264,5 @@ $(function() { } }); - + }); diff --git a/lib/data/redis.js b/lib/data/redis.js index 0d118d8c..87c59896 100644 --- a/lib/data/redis.js +++ b/lib/data/redis.js @@ -22,7 +22,7 @@ var db = function(callback) { redisClient = redis.createClient(nconf.get('redis:url')); redisClient.on("connect", function (err) { - callback(); + callback && callback(); }); redisClient.on("error", function (err) { @@ -32,37 +32,63 @@ var db = function(callback) { }; db.prototype = { - clearRoom: function(room, callback) { - redisClient.del(REDIS_PREFIX + '-room:/demo-cards', function (err, res) { - redisClient.del(REDIS_PREFIX + '-room:/demo-columns', function (err, res) { - callback(); - }); + clearRoom: function(room, callback) { + const keysToDelete = [ + REDIS_PREFIX + '-room:' + room + '-cards', + REDIS_PREFIX + '-room:' + room + '-columns', + REDIS_PREFIX + '-room:' + room + '-size', + REDIS_PREFIX + '-room:' + room + '-theme', + REDIS_PREFIX + '-room:' + room + '-bg', + REDIS_PREFIX + '-room:' + room + '-users', + REDIS_PREFIX + '-room:' + room + '-texts' + ]; + redisClient.del(keysToDelete, function (err, res) { + callback && callback(); }); }, // theme commands - setTheme: function(room, theme) { - redisClient.set(REDIS_PREFIX + '-room:' + room + '-theme', theme); + setTheme: function(room, theme, callback) { + redisClient.set(REDIS_PREFIX + '-room:' + room + '-theme', theme, function (err, res) { + callback && callback(); + }); }, getTheme: function(room, callback) { redisClient.get(REDIS_PREFIX + '-room:' + room + '-theme', function (err, res) { - callback(res); + callback && callback(res); + }); + }, + + getBg: function(room, callback) { + redisClient.get(REDIS_PREFIX + '-room:' + room + '-bg', function (err, res) { + callback && callback(res); + }); + }, + + setBg: function(room, theme, callback) { + redisClient.set(REDIS_PREFIX + '-room:' + room + '-bg', theme, function (err, res) { + callback && callback(); }); }, // Column commands - createColumn: function(room, name, callback) { - redisClient.rpush(REDIS_PREFIX + '-room:' + room + '-columns', name, + createColumn: function(room, col, callback) { + const colStr = JSON.stringify(col); + redisClient.rpush(REDIS_PREFIX + '-room:' + room + '-columns', colStr, function (err, res) { - if (typeof callback != "undefined" && callback !== null) callback(); + if (typeof callback != "undefined" && callback !== null) callback(); } ); }, getAllColumns: function(room, callback) { redisClient.lrange(REDIS_PREFIX + '-room:' + room + '-columns', 0, -1, function(err, res) { - callback(res); + var out = []; + res.forEach(function(col){ + out.push(JSON.parse(col)); + }); + callback && callback(out); }); }, @@ -70,7 +96,7 @@ db.prototype = { redisClient.rpop(REDIS_PREFIX + '-room:' + room + '-columns'); }, - setColumns: function(room, columns) { + setColumns: function(room, columns, callback) { //1. first delete all columns redisClient.del(REDIS_PREFIX + '-room:' + room + '-columns', function () { //2. now add columns for each thingy @@ -78,26 +104,30 @@ db.prototype = { columns, function( item, callback ) { //console.log('rpush: ' + REDIS_PREFIX + '-room:' + room + '-columns' + ' -- ' + item); - redisClient.rpush(REDIS_PREFIX + '-room:' + room + '-columns', item, + const stringCol = JSON.stringify(item); + redisClient.rpush(REDIS_PREFIX + '-room:' + room + '-columns', stringCol, function (err, res) { - callback(); + callback && callback(); } ); }, function() { - //this happens when the series is complete + callback && callback(); } ); }); }, // Card commands - createCard: function(room, id, card) { + createCard: function(room, id, card, callback) { var cardString = JSON.stringify(card); redisClient.hset( REDIS_PREFIX + '-room:' + room + '-cards', id, - cardString + cardString, + function (err, res) { + callback && callback(); + } ); }, @@ -115,18 +145,65 @@ db.prototype = { }); }, - cardEdit: function(room, id, text, colour) { - redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', id, function(err, res) { - var card = JSON.parse(res); - if (card !== null) { - if (text) card.text = text; - if (colour) card.colour = colour; + getAllUsers: function(room, callback) { + redisClient.hgetall(REDIS_PREFIX + '-room:' + room + '-users', function (err, res) { - redisClient.hset(REDIS_PREFIX + '-room:' + room + '-cards', id, JSON.stringify(card)); + var users = {}; + + for (var i in res) { + users[i] = JSON.parse(res[i]); } + + callback(users); }); }, + addUser: function(room, username, userinfo, callback) { + var userinfoStr = JSON.stringify(userinfo); + redisClient.hset( + REDIS_PREFIX + '-room:' + room + '-users', + username, + userinfoStr, + function (err, res) { + callback && callback(); + } + ); + }, + + getCard: function(room, id, callback) { + redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', id, function(err, res) { + var card = JSON.parse(res); + callback && callback(card); + }); + }, + + editCard: function(room, id, card, callback) { + redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', id, function(err, res) { + var storedCard = JSON.parse(res); + if (storedCard === null){ + callback && callback(null); + } + else { + const cardFields = ['colour', 'rot', 'x', 'y', 'text', 'type', 'sticker']; + // Update only supplied fields + cardFields.forEach(field => { + if (card[field]) + storedCard[field] = card[field]; + }); + redisClient.hset(REDIS_PREFIX + '-room:' + room + '-cards', id, JSON.stringify(storedCard), function(err, res) { + callback && callback(storedCard); + }); + } + }); + }, + + cardEdit: function(room, id, text, colour) { + const card = {}; + if (text) card.text = text; + if (colour) card.colour = colour; + this.editCard(room, id, card); + }, + cardSetXY: function(room, id, x, y) { redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', id, function(err, res) { var card = JSON.parse(res); @@ -138,10 +215,13 @@ db.prototype = { }); }, - deleteCard: function(room, id) { + deleteCard: function(room, id, callback) { redisClient.hdel( REDIS_PREFIX + '-room:' + room + '-cards', - id + id, + function (){ + callback && callback(); + } ); }, @@ -173,8 +253,10 @@ db.prototype = { }); }, - setBoardSize: function(room, size) { - redisClient.set(REDIS_PREFIX + '-room:' + room + '-size', JSON.stringify(size)); + setBoardSize: function(room, size, callback) { + redisClient.set(REDIS_PREFIX + '-room:' + room + '-size', JSON.stringify(size), function (err, res) { + callback && callback(); + }); }, getBoardSize: function(room, callback) { @@ -197,10 +279,24 @@ db.prototype = { }); }, - textEdit: function(room, id, text) { + getAllTextsMap: function(room, callback) { + redisClient.hgetall(REDIS_PREFIX + '-room:' + room + '-texts', function (err, res) { + callback && callback(res); + }); + }, + + setAllTextsMap: function(room, texts, callback) { + redisClient.hmset(REDIS_PREFIX + '-room:' + room + '-texts', texts, function (err, res) { + callback && callback(); + }); + }, + + textEdit: function(room, id, text, callback) { if (text !== null) { - redisClient.hset(REDIS_PREFIX + '-room:' + room + '-texts', id, text); + redisClient.hset(REDIS_PREFIX + '-room:' + room + '-texts', id, text, function (err, res) { + callback && callback(); + }); } } diff --git a/server.js b/server.js index cff0230a..f2907c2c 100644 --- a/server.js +++ b/server.js @@ -57,6 +57,7 @@ var router = express.Router(); app.set('view engine', 'pug'); app.use(compression()); +app.use(express.json()); app.use(nconf.get('server:baseurl'), router); // app.locals.ga = ga.enabled; @@ -106,12 +107,163 @@ router.get('/demo', function(req, res) { }); router.get('/:id', function(req, res){ - res.render('index.pug', { - pageTitle: ('scrumblr - ' + req.params.id) + + // Check for background param + if (req.query.bg !== undefined){ + const room = '/' + req.params.id; + db.setBg(room, req.query.bg, function() { + res.redirect(302, room); + }); + } + else { + res.render('index.pug', { + pageTitle: ('scrumblr - ' + req.params.id), + embed: req.query.embed, + darkMode: req.query.darkmode + }); + } +}); + +// ******************* +// REST API Routes +// ******************* + +router.get('/api/rooms/:id', function(req, res) { + const room = '/' + req.params.id; + + db.getAllColumns ( room, function (columns) { + db.getTheme( room, function(theme) { + db.getBg( room, function(bg) { + db.getBoardSize( room, function(size) { + db.getAllTextsMap( room , function (texts) { + res.json({ + columns, + theme, + size, + texts, + bg + }); + }); + }); + }); + }); + }); +}); + +router.put('/api/rooms/:id', function(req, res) { + const room = '/' + req.params.id; + var operations = []; + + // Add an empty function to avoid hangups + operations.push(function (callback){ + callback && callback(); + }); + + if (req.body.columns){ + // TODO: check columns format + operations.push(function (callback){ + db.setColumns(room, req.body.columns, callback); + }); + } + + if (req.body.theme){ + operations.push(function (callback){ + db.setTheme(room, req.body.theme, callback); + }); + } + + if (req.body.bg){ + operations.push(function (callback){ + db.setBg(room, req.body.bg, callback); + }); + } + + if (req.body.size){ + operations.push(function (callback){ + db.setBoardSize(room, req.body.size, callback); + }); + } + + if (req.body.texts){ + operations.push(function (callback){ + db.setAllTextsMap(room, req.body.texts, callback); + }); + } + + async.parallel(operations, function(){ + res.json({ ok: true }); + }); + +}); + + +router.delete('/api/rooms/:id', function(req, res) { + const room = '/' + req.params.id; + db.clearRoom('/' + room, function() { + res.json({ ok: true }); + }); +}); + + +router.get('/api/rooms/:roomId/cards', function(req, res) { + const room = '/' + req.params.roomId; + + db.getAllCards( room , function (cards) { + res.json(cards); + }); +}); + +router.post('/api/rooms/:roomId/cards', function(req, res) { + const room = '/' + req.params.roomId; + const card = req.body; + const scrub = sanitizer.sanitize; + + //delete card.id; + card.id = "card" + Math.floor(Math.random() * 100000000);; + card.colour = scrub(card.colour); + card.rot = scrub(card.rot); + card.rot = scrub(card.rot); + card.x = parseFloat(card.x); + card.y = parseFloat(card.y); + card.text = scrub(card.text); + card.type = scrub(card.type); + // TODO: validate stickers + + db.createCard(room, card.id, card, function() { + res.json(card); + }); + +}); + +router.get('/api/rooms/:roomId/cards/:cardId', function(req, res) { + const room = '/' + req.params.roomId; + const id = req.params.cardId; + + db.getCard( room , id , function (card) { + res.json(card); + }); +}); + +router.put('/api/rooms/:roomId/cards/:cardId', function(req, res) { + const room = '/' + req.params.roomId; + const id = req.params.cardId; + const card = req.body; + + db.editCard( room , id , card, function (card) { + res.json(card); }); }); +router.delete('/api/rooms/:roomId/cards/:cardId', function(req, res) { + const room = '/' + req.params.roomId; + const id = req.params.cardId; + + db.deleteCard( room , id , function (card) { + res.json({ok: true}); + }); +}); + /************** SOCKET.I0 **************/ @@ -195,10 +347,11 @@ io.on('connection', (client) => { clean_data.rot = scrub(data.rot); clean_data.colour = scrub(data.colour); clean_data.type = scrub(data.type); + clean_data.username = data.username ? scrub(data.username) : null; getRoom(client, function(room) { - createCard( room, clean_data.id, clean_data.text, clean_data.x, clean_data.y, clean_data.rot, clean_data.colour, clean_data.type); + createCard( room, clean_data.id, clean_data.text, clean_data.x, clean_data.y, clean_data.rot, clean_data.colour, clean_data.type, clean_data.username); }); message_out = { @@ -275,17 +428,11 @@ io.on('connection', (client) => { if (!(columns instanceof Array)) break; - var clean_columns = []; - - for (var i in columns) - { - clean_columns[i] = scrub( columns[i] ); - } getRoom( client, function(room) { - db.setColumns( room, clean_columns ); + db.setColumns( room, columns ); }); - broadcastToRoom( client, { action: 'updateColumns', data: clean_columns } ); + broadcastToRoom( client, { action: 'updateColumns', data: columns } ); break; @@ -315,6 +462,30 @@ io.on('connection', (client) => { broadcastToRoom( client, msg ); break; + + case 'setUserInfo': + const username = scrub(message.data.username); + const userEmail = scrub(message.data.userEmail); + const userAvatar = scrub(message.data.userAvatar); + const userinfo = { + username, + userEmail, + userAvatar + }; + + getRoom(client, function(room) { + db.addUser(room, username, userinfo, function(){ + db.getAllUsers(room, function(users){ + var msg = {}; + msg.action = 'updateUserCache'; + msg.data = users; + broadcastToRoom( client, msg ); + }); + }); + }); + + break; + case 'addSticker': var cardId = scrub(message.data.cardId); var stickerId = scrub(message.data.stickerId); @@ -384,18 +555,15 @@ function initClient ( client ) //console.log ('initClient Started'); getRoom(client, function(room) { - db.getAllCards( room , function (cards) { - + db.getAllUsers(room, function(users){ client.send( { - action: 'initCards', - data: cards + action: 'updateUserCache', + data: users } ); - }); - db.getAllColumns ( room, function (columns) { client.send( { @@ -418,6 +586,18 @@ function initClient ( client ) ); }); + db.getBg( room, function(bg) { + + if (bg === null) bg = 'css/bg/scribbles2.png'; + + client.send( + { + action: 'changeBg', + data: bg + } + ); + }); + db.getBoardSize( room, function(size) { if (size !== null) { @@ -443,6 +623,17 @@ function initClient ( client ) } }); + db.getAllCards( room , function (cards) { + + client.send( + { + action: 'initCards', + data: cards + } + ); + + }); + roommates_clients = rooms.room_clients(room); roommates = []; @@ -497,7 +688,7 @@ function broadcastToRoom ( client, message ) { } //----------------CARD FUNCTIONS -function createCard( room, id, text, x, y, rot, colour, type ) { +function createCard( room, id, text, x, y, rot, colour, type, username ) { var card = { id: id, colour: colour, @@ -506,7 +697,8 @@ function createCard( room, id, text, x, y, rot, colour, type ) { y: y, text: text, type: type, - sticker: null + sticker: null, + username: username }; db.createCard(room, id, card); diff --git a/views/home.pug b/views/home.pug index bdd84e54..b1b90b29 100644 --- a/views/home.pug +++ b/views/home.pug @@ -24,7 +24,10 @@ body form.home(onsubmit="return go();") label name your new board: br - input.text(type="text", name="name") + input.text(type="text", name="name", placeholder="Board name") + br + input.url(type="text", name="bg", placeholder="Background image URL (optionnal)") + br a#go(onclick="return go();")  go.

p.home example board: @@ -54,6 +57,6 @@ body //
this will be the backlog that only appears on drag or perhaps not at all
- + diff --git a/views/index.pug b/views/index.pug index 228bb2bb..d98af361 100644 --- a/views/index.pug +++ b/views/index.pug @@ -2,65 +2,14 @@ extends layout block body // Header Start - header.site-header - div.site-header__wrapper - a.greyheading(href="/") scrumblr - //ul.nav__wrapper - li.nav__item - a#configmenu(href="#") - svg.title(width='12', height='12') - - ul#menu - li - div Enlarge - li - div Books - li - div Electronics - li - div Movies - //- li.nav__item - //- a(href="#") - //- svg.title(width='12', height='12') - //- - - - - if (locals.demo) - div.notice-bar this is a demo board. to make a private board, go to scrumblr home - - //div.config - // i.fa.fa-cog.fa-lg.faded-icon - //- svg(width='15', height='15') - //- -

- //p.greyheading scrumblr by aliasaria div.board-wrapper - div.topflexcontainer(style="display: flex; justify-content: space-between; align-items: baseline;") - h1#board-title.ceditable(style="") Board Title - //div(style="") - a#configmenu(href="#") - svg.title(width='12', height='12') - - ul#menu - li - div(style="height: 12px;") - svg.title(width='12', height='12') - - li - div(style="height: 12px;") - svg.title(width='12', height='12') - - li - div(style="height: 12px;") - svg.title(width='12', height='12') - - li - div Poop + div.topflexcontainer(style="display: flex; justify-content: space-between; align-items: baseline; margin-top: 10px;") div.board-outline(style="clear:both;") + img.logo(src="images/adh-logo.png", height=25, style="") div#board - div#board-doodles + div#board-doodles(style="background-image: url('css/bg/scribbles2.png');") // image#marker(src='images/marker.png') @@ -68,21 +17,30 @@ block body table#board-table.board-table - tr + tr(data-row='1') td#icon-col(width='1%') - svg#add-col.col-icon(width='20', height='20') + svg#add-col.col-icon(width='20', height='20', title='Add column') - svg#delete-col.col-icon(width='20', height='20') + svg#delete-col.col-icon(width='20', height='20', title='Remove column') + div.line-buttons + div.line-buttons-inner + svg#add-line.line-icon(width='20', height='20') + + svg#delete-line.line-icon(width='20', height='20') + - div.buttons + + div.buttons(class=locals.darkMode ? "dark" : "") //- svg#pen.bottom-icon(width='20', height='20', data-ison='true') //- svg#create-card.bottom-icon(width='20', height='20') svg#create-sticky.bottom-icon(width='20', height='20') + svg#create-label.bottom-icon(width='20', height='20') + //- svg#smallify.bottom-icon(width='20', height='20') //- @@ -112,12 +70,13 @@ block body // image(src="/images/stickers/sticker-redstar.png") - div.names - p connected: - //image#user-icon(src="/images/icons/cc/black/png/user_icon&16.png") - input#yourname-input - span.you-text (you) - ul#names-ul + - if (!locals.embed) + div.names + p Connected users: + //image#user-icon(src="/images/icons/cc/black/png/user_icon&16.png") + input#yourname-input + span.you-text (you) + ul#names-ul //div.trash // i.fa.fa-trash-o.fa-lg.faded-icon diff --git a/views/layout.pug b/views/layout.pug index 6b5a48a5..c0292adc 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -11,6 +11,10 @@ html(lang="en") + + + +