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")
+
+
+
+