Commit dbf77a0124e90aff5bc873444bfa3dcc6f517276

Authored by Kevin Mach
1 parent 0bf5d19119

back to original

Showing 4 changed files with 17 additions and 12 deletions Inline Diff

scripts/FeedController.js View file @ dbf77a0
angular.module('flashy.FeedController', ['ui.router']). 1 1 angular.module('flashy.FeedController', ['ui.router']).
controller('FeedController', function($scope, $rootScope, $stateParams, $state, $http) { 2 2 controller('FeedController', function($scope, $rootScope, $stateParams, $state, $http) {
console.log('Hello from feed'); 3 3 console.log('Hello from feed');
sectionId = $stateParams.sectionId; 4 4 sectionId = $stateParams.sectionId;
$rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId}); 5 5 $rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId});
$scope.cards = []; 6 6 $scope.cards = [];
7 7
var loc = window.location, new_uri; 8 8 var loc = window.location, new_uri;
if (loc.protocol === 'https:') { 9 9 if (loc.protocol === 'https:') {
new_uri = 'wss:'; 10 10 new_uri = 'wss:';
} else { 11 11 } else {
new_uri = 'ws:'; 12 12 new_uri = 'ws:';
} 13 13 }
new_uri += '//' + loc.host; 14 14 new_uri += '//' + loc.host;
var ws = new WebSocket(new_uri + '/ws/feed/' + sectionId + '?subscribe-broadcast'); 15 15 var ws = new WebSocket(new_uri + '/ws/feed/' + sectionId + '?subscribe-broadcast');
16 16
ws.onopen = function() { 17 17 ws.onopen = function() {
console.log('websocket connected'); 18 18 console.log('websocket connected');
}; 19 19 };
ws.onmessage = function(e) { 20 20 ws.onmessage = function(e) {
console.log('got websocket message ' + e.data); 21 21 console.log('got websocket message ' + e.data);
$scope.refreshCards(); 22 22 $scope.refreshCards();
}; 23 23 };
ws.onerror = function(e) { 24 24 ws.onerror = function(e) {
console.error(e); 25 25 console.error(e);
}; 26 26 };
ws.onclose = function(e) { 27 27 ws.onclose = function(e) {
console.log('connection closed'); 28 28 console.log('connection closed');
}; 29 29 };
30 30
$http.get('/api/sections/' + sectionId + '/feed/'). 31 31 $http.get('/api/sections/' + sectionId + '/feed/').
success(function(data) { 32 32 success(function(data) {
console.log(data); 33 33 console.log(data);
$scope.cards = data; 34 34 $scope.cards = data;
35
36 $scope.noCards = function () {
37
38 alert(data.length);
39
40 if (data.length == 0) {
41 return true;
42 } else {
43 return false;
44 }
45
46 }
47
48
49
50
}). 35 51 }).
error(function(err) { 36 52 error(function(err) {
console.log('pulling feed failed'); 37 53 console.log('pulling feed failed');
}); 38 54 });
39 55
$scope.viewDeck = function() { 40 56 $scope.viewDeck = function() {
$state.go('deck', {sectionId: sectionId}); 41 57 $state.go('deck', {sectionId: sectionId});
console.log('go to deck'); 42 58 console.log('go to deck');
}; 43 59 };
44 60
$scope.pushCard = function() { 45 61 $scope.pushCard = function() {
var pushed = new Date(Date.now()); 46 62 var pushed = new Date(Date.now());
var i = 0; 47 63 var i = 0;
var blanks = []; 48 64 var blanks = [];
$('#new-card-input')[0].childNodes.forEach(function(node) { 49 65 $('#new-card-input')[0].childNodes.forEach(function(node) {
node = $(node)[0]; 50 66 node = $(node)[0];
console.log(node); 51 67 console.log(node);
if (node.tagName == 'B') { 52 68 if (node.tagName == 'B') {
text = $(node).text(); 53 69 text = $(node).text();
blanks.push([i, i + text.length]); 54 70 blanks.push([i, i + text.length]);
i += text.length; 55 71 i += text.length;
} else { 56 72 } else {
i += node.data.length; 57 73 i += node.data.length;
} 58 74 }
}); 59 75 });
console.log(blanks); 60 76 console.log(blanks);
text = $('#new-card-input').text(); 61 77 text = $('#new-card-input').text();
var myCard = { 62 78 var myCard = {
'text': text, 63 79 'text': text,
'material_date': pushed, 64 80 'material_date': pushed,
'mask': JSON.stringify(blanks), 65 81 'mask': JSON.stringify(blanks),
section: sectionId 66 82 section: sectionId
}; 67 83 };
$http.post('/api/flashcards/', myCard). 68 84 $http.post('/api/flashcards/', myCard).
success(function(data) { 69 85 success(function(data) {
console.log('pushed a card!'); 70 86 console.log('pushed a card!');
listenForC = true; 71 87 listenForC = true;
}). 72 88 }).
error(function(error) { 73 89 error(function(error) {
console.log('something went wrong pushing a card!'); 74 90 console.log('something went wrong pushing a card!');
}); 75 91 });
76 92
$('#new-card-input').html(''); 77 93 $('#new-card-input').html('');
}; 78 94 };
79 95
$scope.refreshCards = function() { 80 96 $scope.refreshCards = function() {
$http.get('/api/sections/' + sectionId + '/feed/'). 81 97 $http.get('/api/sections/' + sectionId + '/feed/').
success(function(data) { 82 98 success(function(data) {
console.log(data); 83 99 console.log(data);
$scope.cards = data; 84 100 $scope.cards = data;
console.log('success in refresh cards...'); 85 101 console.log('success in refresh cards...');
}). 86 102 }).
error(function(err) { 87 103 error(function(err) {
console.log('refresh fail'); 88 104 console.log('refresh fail');
}); 89 105 });
}; 90 106 };
91 107
/* Key bindings for the whole feed window. Hotkey it up! */ 92 108 /* Key bindings for the whole feed window. Hotkey it up! */
var listenForC = true; 93 109 var listenForC = true;
94 110
// Need to pass these options into openmodal and leanmodal, 95 111 // Need to pass these options into openmodal and leanmodal,
// otherwise the ready handler doesn't get called 96 112 // otherwise the ready handler doesn't get called
97 113
modal_options = { 98 114 modal_options = {
dismissible: true, // Modal can be dismissed by clicking outside of the modal 99 115 dismissible: true, // Modal can be dismissed by clicking outside of the modal
opacity: 0, // Opacity of modal background 100 116 opacity: 0, // Opacity of modal background
in_duration: 300, // Transition in duration 101 117 in_duration: 300, // Transition in duration
out_duration: 200, // Transition out duration 102 118 out_duration: 200, // Transition out duration
ready: function() { 103 119 ready: function() {
listenForC = false; 104 120 listenForC = false;
console.log('modal OPENING'); 105 121 console.log('modal OPENING');
$('#new-card-input').focus(); 106 122 $('#new-card-input').focus();
}, 107 123 },
complete: function() { 108 124 complete: function() {
listenForC = true; 109 125 listenForC = true;
console.log('modal done, closing'); 110 126 console.log('modal done, closing');
$('#new-card-input').blur(); 111 127 $('#new-card-input').blur();
} 112 128 }
}; 113 129 };
114 130
$(document).keydown(function(e) { 115 131 $(document).keydown(function(e) {
console.log(e.which); 116 132 console.log(e.which);
var keyed = e.which; 117 133 var keyed = e.which;
if (keyed == 67 && listenForC) { // "c" or "C" for compose 118 134 if (keyed == 67 && listenForC) { // "c" or "C" for compose
$('#newCard').openModal(modal_options); 119 135 $('#newCard').openModal(modal_options);
e.preventDefault(); 120 136 e.preventDefault();
listenForC = false; 121 137 listenForC = false;
return false; 122 138 return false;
} else if (keyed == 27) { // enter or esc, respectively 123 139 } else if (keyed == 27) { // enter or esc, respectively
listenForC = true; 124 140 listenForC = true;
document.getElementById('new-card-input').value = ''; 125 141 document.getElementById('new-card-input').value = '';
} 126 142 }
}); 127 143 });
$scope.flashcard = ''; 128 144 $scope.flashcard = '';
$scope.text = ''; 129 145 $scope.text = '';
var selected_start = 0; 130 146 var selected_start = 0;
var selected_end = 0; 131 147 var selected_end = 0;
$(document).ready(function() { 132 148 $(document).ready(function() {
// the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered 133 149 // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
$('.modal-trigger').leanModal(modal_options); 134 150 $('.modal-trigger').leanModal(modal_options);
$('#new-card-input').on('keydown', function(e) { 135 151 $('#new-card-input').on('keydown', function(e) {
if (e.which == 13) { 136 152 if (e.which == 13) {
e.preventDefault(); 137 153 e.preventDefault();
$scope.pushCard(); 138 154 $scope.pushCard();
$('#newCard').closeModal(modal_options); 139 155 $('#newCard').closeModal(modal_options);
return false; 140 156 return false;
} 141 157 }
}); 142 158 });
$('#new-card-input').on('mouseup', function() { 143 159 $('#new-card-input').on('mouseup', function() {
console.log('got selection: ' + selected_start); 144 160 console.log('got selection: ' + selected_start);
}); 145 161 });
styles/flashy.css View file @ dbf77a0
.no-user-select { 1 1 .no-user-select {
-moz-user-select: none; 2 2 -moz-user-select: none;
-webkit-user-select: none; 3 3 -webkit-user-select: none;
-ms-user-select: none; 4 4 -ms-user-select: none;
user-select: none; 5 5 user-select: none;
} 6 6 }
7 7
.angucomplete-dropdown { 8 8 .angucomplete-dropdown {
border-color: #ececec; 9 9 border-color: #ececec;
border-width: 1px; 10 10 border-width: 1px;
border-style: solid; 11 11 border-style: solid;
border-radius: 2px; 12 12 border-radius: 2px;
/*width: 250px;*/ 13 13 /*width: 250px;*/
padding: 6px; 14 14 padding: 6px;
cursor: pointer; 15 15 cursor: pointer;
z-index: 9999; 16 16 z-index: 9999;
position: absolute; 17 17 position: absolute;
/*top: 32px; 18 18 /*top: 32px;
left: 0px; 19 19 left: 0px;
*/ 20 20 */
margin-top: -6px; 21 21 margin-top: -6px;
background-color: #ffffff; 22 22 background-color: #ffffff;
} 23 23 }
24 24
.angucomplete-description { 25 25 .angucomplete-description {
font-size: 14px; 26 26 font-size: 14px;
} 27 27 }
28 28
.angucomplete-row { 29 29 .angucomplete-row {
padding: 5px; 30 30 padding: 5px;
color: #000000; 31 31 color: #000000;
margin-bottom: 4px; 32 32 margin-bottom: 4px;
clear: both; 33 33 clear: both;
} 34 34 }
35 35
.angucomplete-selected-row { 36 36 .angucomplete-selected-row {
background-color: #aaaaff; 37 37 background-color: #aaaaff;
} 38 38 }
39 39
/*.container .row {*/ 40 40 /*.container .row {*/
/*margin-left: 0;*/ 41 41 /*margin-left: 0;*/
/*margin-right: 0;*/ 42 42 /*margin-right: 0;*/
/*}*/ 43 43 /*}*/
44 44
/* Flashcard directive css */ 45 45 /* Flashcard directive css */
.card { 46 46 .card {
word-wrap: break-word; 47 47 word-wrap: break-word;
} 48 48 }
49 49
.card.flashy { 50 50 .card.flashy {
background-color: #fff; 51 51 background-color: #fff;
font-family: 'Titillium Web', sans-serif; 52 52 font-family: 'Titillium Web', sans-serif;
float: left; 53 53 float: left;
text-align: center; 54 54 text-align: center;
margin: 6px; 55 55 margin: 6px;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1); 56 56 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1);
} 57 57 }
58 58
.card.flashy.shrinky { 59 59 .card.flashy.shrinky {
height: 0; 60 60 height: 0;
opacity: 0; 61 61 opacity: 0;
overflow: hidden; 62 62 overflow: hidden;
} 63 63 }
64 64
.card-overlay { 65 65 .card-overlay {
cursor: pointer; 66 66 cursor: pointer;
left: 0; 67 67 left: 0;
opacity: 0; 68 68 opacity: 0;
position: absolute; 69 69 position: absolute;
top: 0; 70 70 top: 0;
transition: visibility 0s cubic-bezier(0, 0, 0.6, 1) 0.2s, 71 71 transition: visibility 0s cubic-bezier(0, 0, 0.6, 1) 0.2s,
opacity 0.2s cubic-bezier(0, 0, 0.6, 1); 72 72 opacity 0.2s cubic-bezier(0, 0, 0.6, 1);
/* animation effect to appear on off-hover */ 73 73 /* animation effect to appear on off-hover */
visibility: hidden; 74 74 visibility: hidden;
height: 100%; 75 75 height: 100%;
width: 100%; 76 76 width: 100%;
} 77 77 }
78 78
.card-overlay i { 79 79 .card-overlay i {
color: #FFF; 80 80 color: #FFF;
left: 50%; 81 81 left: 50%;
position: absolute; 82 82 position: absolute;
top: 50%; 83 83 top: 50%;
transform: translate(-50%, -50%); 84 84 transform: translate(-50%, -50%);
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 85 85 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
} 86 86 }
87 87
.center-me:hover i { 88 88 .center-me:hover i {
text-shadow: 0 0 15px rgba(255, 255, 255, 0.9); 89 89 text-shadow: 0 0 15px rgba(255, 255, 255, 0.9);
} 90 90 }
91 91
.card:hover .card-overlay { 92 92 .card:hover .card-overlay {
opacity: 1.0; 93 93 opacity: 1.0;
transition-delay: 0s; /* animation effect to appear on hover */ 94 94 transition-delay: 0s; /* animation effect to appear on hover */
visibility: visible; 95 95 visibility: visible;
} 96 96 }
97 97
.top-box { 98 98 .top-box {
background-color: rgba(0, 184, 76, 0.5); 99 99 background-color: rgba(0, 184, 76, 0.5);
height: 65%; 100 100 height: 65%;
position: relative; 101 101 position: relative;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 102 102 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
width: 100%; 103 103 width: 100%;
} 104 104 }
105 105
.top-box:hover { 106 106 .top-box:hover {
background-color: rgba(0, 184, 76, 0.6); 107 107 background-color: rgba(0, 184, 76, 0.6);
} 108 108 }
109 109
.bottom-box { 110 110 .bottom-box {
height: 35%; 111 111 height: 35%;
width: 100%; 112 112 width: 100%;
} 113 113 }
114 114
.left-box { 115 115 .left-box {
background-color: rgba(119, 146, 255, 0.5); 116 116 background-color: rgba(119, 146, 255, 0.5);
float: left; 117 117 float: left;
position: relative; 118 118 position: relative;
height: 100%; 119 119 height: 100%;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 120 120 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
width: 50%; 121 121 width: 50%;
} 122 122 }
123 123
.left-box:hover { 124 124 .left-box:hover {
background-color: rgba(119, 146, 255, 0.6); 125 125 background-color: rgba(119, 146, 255, 0.6);
} 126 126 }
127 127
.right-box { 128 128 .right-box {
background-color: rgba(255, 62, 76, 0.5); 129 129 background-color: rgba(255, 62, 76, 0.5);
float: right; 130 130 float: right;
height: 100%; 131 131 height: 100%;
position: relative; 132 132 position: relative;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 133 133 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
width: 50%; 134 134 width: 50%;
} 135 135 }
136 136
.right-box:hover { 137 137 .right-box:hover {
background-color: rgba(255, 62, 76, 0.6); 138 138 background-color: rgba(255, 62, 76, 0.6);
} 139 139 }
140 140
.center-me { 141 141 .center-me {
height: 100%; 142 142 height: 100%;
margin: 0 auto; 143 143 margin: 0 auto;
text-align: center; 144 144 text-align: center;
vertical-align: middle; 145 145 vertical-align: middle;
width: 100%; 146 146 width: 100%;
} 147 147 }
148 148
.modal.bottom-sheet { 149 149 .modal.bottom-sheet {
max-width: 600px; 150 150 max-width: 600px;
margin-left: auto; 151 151 margin-left: auto;
margin-right: auto; 152 152 margin-right: auto;
} 153 153 }
154 154
#newCard input[type=text] { 155 155 #newCard input[type=text] {
height: 3rem !important; 156 156 height: 3rem !important;
} 157 157 }
158 158
.input-field label { 159 159 .input-field label {
color: #00b3c2; 160 160 color: #00b3c2;
} 161 161 }
162 162
/* label focus color */ 163 163 /* label focus color */
.input-field input[type]:focus + label { 164 164 .input-field input[type]:focus + label {
color: #00b3c2; 165 165 color: #00b3c2;
} 166 166 }
167 167
/* label underline focus color */ 168 168 /* label underline focus color */
.input-field input[type]:focus { 169 169 .input-field input[type]:focus {
border-bottom: 1px solid #00b3c2; 170 170 border-bottom: 1px solid #00b3c2;
box-shadow: 0 1px 0 0 #b388ff; 171 171 box-shadow: 0 1px 0 0 #b388ff;
} 172 172 }
173 173
/* valid color */ 174 174 /* valid color */
.input-field input[type].valid { 175 175 .input-field input[type].valid {
border-bottom: 1px solid #00c28f; 176 176 border-bottom: 1px solid #00c28f;
box-shadow: 0 1px 0 0 #673ab7; 177 177 box-shadow: 0 1px 0 0 #673ab7;
} 178 178 }
179 179
/* invalid color */ 180 180 /* invalid color */
.input-field input[type].invalid { 181 181 .input-field input[type].invalid {
border-bottom: 1px solid #673ab7; 182 182 border-bottom: 1px solid #673ab7;
box-shadow: 0 1px 0 0 #673ab7; 183 183 box-shadow: 0 1px 0 0 #673ab7;
} 184 184 }
185 185
/* icon prefix focus color */ 186 186 /* icon prefix focus color */
.input-field .prefix.active { 187 187 .input-field .prefix.active {
color: #b388ff; 188 188 color: #b388ff;
} 189 189 }
190 190
/* label focus color */ 191 191 /* label focus color */
.input-field textarea[type]:focus + label { 192 192 .input-field textarea[type]:focus + label {
color: #b388ff; 193 193 color: #b388ff;
} 194 194 }
195 195
/* label underline focus color */ 196 196 /* label underline focus color */
.input-field textarea[type]:focus { 197 197 .input-field textarea[type]:focus {
border-bottom: 1px solid #00b3c2; 198 198 border-bottom: 1px solid #00b3c2;
box-shadow: 0 1px 0 0 #b388ff; 199 199 box-shadow: 0 1px 0 0 #b388ff;
} 200 200 }
201 201
body { 202 202 body {
background-color: #e8e8e8; 203 203 background-color: #e8e8e8;
overflow-x: hidden; 204 204 overflow-x: hidden;
font-family: 'Titillium Web', sans-serif; 205 205 font-family: 'Titillium Web', sans-serif;
display: flex; 206
min-height: 100vh; 207
flex-direction: column; 208
} 209 206 }
210 207
html { 211 208 html {
background: transparent; 212 209 background: transparent;
} 213 210 }
214 211
.btn { 215 212 .btn {
background-color: #00b3c2; 216 213 background-color: #00b3c2;
} 217 214 }
218 215
.btn:hover { 219 216 .btn:hover {
background-color: #0097cb; 220 217 background-color: #0097cb;
} 221 218 }
222 219
.btn-floating { 223 220 .btn-floating {
background-color: #00b3c2; 224 221 background-color: #00b3c2;
} 225 222 }
226 223
.btn-floating:hover { 227 224 .btn-floating:hover {
background-color: #0097cb; 228 225 background-color: #0097cb;
} 229 226 }
230 227
#logo-container { 231 228 #logo-container {
margin-bottom: 18px; 232 229 margin-bottom: 18px;
} 233 230 }
234 231
#lean-overlay { 235 232 #lean-overlay {
display: none !important; 236 233 display: none !important;
} 237 234 }
238 235
nav { 239 236 nav {
background-color: #d2143f !important; 240 237 background-color: #d2143f !important;
} 241 238 }
templates/feed.html View file @ dbf77a0
1 1
<div class="row"> 2 2 <div class="row">
<div ng-repeat="card in cards"> 3 3 <div ng-repeat="card in cards">
<flashcard flashcard-obj="card" refresh="refreshCards()"/> 4 4 <flashcard flashcard-obj="card" refresh="refreshCards()"/>
</div> 5 5 </div>
</div> 6 6 </div>
7 7
8 <h2 ng-show="noCards()">No cards. Be the first one to add a card!</h2>
8 9
<!--Lil plus button in corner--> 9 10 <!--Lil plus button in corner-->
<div class="fixed-action-btn" style="bottom: 96px; right: 24px;"> 10 11 <div class="fixed-action-btn" style="bottom: 96px; right: 24px;">
<a data-target="newCard" class="btn-floating btn-large modal-trigger" href="#newCard"> 11 12 <a data-target="newCard" class="btn-floating btn-large modal-trigger" href="#newCard">
<i class="large mdi-content-add"></i> 12 13 <i class="large mdi-content-add"></i>
</a> 13 14 </a>
</div> 14 15 </div>
15 16
<div id="newCard" class="modal bottom-sheet"> 16 17 <div id="newCard" class="modal bottom-sheet">
<form id="new-card-form"> 17 18 <form id="new-card-form">
<div class="modal-content"> 18 19 <div class="modal-content">
<div class="input-field"> 19 20 <div class="input-field">
<!--<label id="newCardSign" for="newCard">New Flashcard Text</label>--> 20 21 <!--<label id="newCardSign" for="newCard">New Flashcard Text</label>-->
<div id="new-card-input" contenteditable> 21 22 <div id="new-card-input" contenteditable>
22 23
</div> 23 24 </div>
</div> 24 25 </div>
</div> 25 26 </div>
<div class="modal-footer"> 26 27 <div class="modal-footer">
<button class="btn modal-close" type="submit" ng-click="pushCard()">Submit 27 28 <button class="btn modal-close" type="submit" ng-click="pushCard()">Submit
<i class="mdi-content-send right"></i> 28 29 <i class="mdi-content-send right"></i>
templates/login.html View file @ dbf77a0
<h3>Create and share flashcards in real time!</h3> 1
2
<div class="" style="margin-top:32px;"> 3 1 <div class="" style="margin-top:32px;">
<div class="row" style="max-width:512px; width:50%; min-width:256px; margin: 0 auto"> 4 2 <div class="row" style="max-width:512px; width:50%; min-width:256px; margin: 0 auto">
<ul class="tabs"> 5 3 <ul class="tabs">
<li class="tab col s6"><a class="active" href="#login-tab">Login</a></li> 6 4 <li class="tab col s6"><a class="active" href="#login-tab">Login</a></li>
<li class="tab col s6"><a href="#register-tab">Sign Up</a></li> 7 5 <li class="tab col s6"><a href="#register-tab">Sign Up</a></li>
</ul> 8 6 </ul>
<div class="card"> 9 7 <div class="card">
<!--LOGIN TAB--> 10 8 <!--LOGIN TAB-->
<div id="login-tab" class="row col s12"> 11 9 <div id="login-tab" class="row col s12">
<form id="login-form"> 12 10 <form id="login-form">
<div class="card-content"> 13 11 <div class="card-content">
<div class="check-element animate-show" role="alert" ng-show="loginError"> 14 12 <div class="check-element animate-show" role="alert" ng-show="loginError">
<span style="color:#8E2323">Invalid username or password!!</span> 15 13 <span style="color:#8E2323">Invalid username or password!!</span>
</div> 16 14 </div>
17 15
<div class="input-field"> 18 16 <div class="input-field">
<input id="email" type="email" name="login" class="validate" ng-model="loginEmail" required autofocus 19 17 <input id="email" type="email" name="login" class="validate" ng-model="loginEmail" required autofocus
autocomplete/> 20 18 autocomplete/>
<label for="email">Email</label> 21 19 <label for="email">Email</label>
</div> 22 20 </div>
<div class="input-field"> 23 21 <div class="input-field">
<input id="password" type="password" name="password" class="validate" ng-model="loginPassword" required/> 24 22 <input id="password" type="password" name="password" class="validate" ng-model="loginPassword" required/>
<label for="password">Password</label> 25 23 <label for="password">Password</label>
</div> 26 24 </div>
</div> 27 25 </div>
<div class="card-action"> 28 26 <div class="card-action">
<button class="btn waves-effect waves-light col s12" type="submit" name="action" 29 27 <button class="btn waves-effect waves-light col s12" type="submit" name="action"
ng-click="login(loginEmail, loginPassword)">Login 30 28 ng-click="login(loginEmail, loginPassword)">Login
</button> 31 29 </button>
</div> 32 30 </div>
</form> 33 31 </form>
</div> 34 32 </div>
<!--REGISTER TAB--> 35 33 <!--REGISTER TAB-->
<div id="register-tab" class="row col s12"> 36 34 <div id="register-tab" class="row col s12">
<form> 37 35 <form>
<div class="card-content"> 38 36 <div class="card-content">
<div class="check-element animate-show" role="alert" ng-show="uniqueError"> 39 37 <div class="check-element animate-show" role="alert" ng-show="uniqueError">
<span style="color:#8E2323">Invalid username or password!</span> 40 38 <span style="color:#8E2323">Invalid username or password!</span>
</div> 41 39 </div>
<div class="input-field"> 42 40 <div class="input-field">
<input id="email" type="email" class="validate" ng-model="registerEmail" required/> 43 41 <input id="email" type="email" class="validate" ng-model="registerEmail" required/>
<label for="email">Email</label> 44 42 <label for="email">Email</label>
</div> 45 43 </div>
<div class="input-field"> 46 44 <div class="input-field">
<input type="password" class="validate" ng-model="registerPassword" required/> 47 45 <input type="password" class="validate" ng-model="registerPassword" required/>
<label for="password">Password</label> 48 46 <label for="password">Password</label>
</div> 49 47 </div>
</div> 50 48 </div>
<div class="card-action"> 51 49 <div class="card-action">
<button class="btn waves-effect waves-light col s12" type="submit" name="action" 52 50 <button class="btn waves-effect waves-light col s12" type="submit" name="action"
ng-click="signUp(registerEmail, registerPassword)">Register 53 51 ng-click="signUp(registerEmail, registerPassword)">Register
</button> 54 52 </button>
</div> 55 53 </div>
</form> 56 54 </form>
</div> 57 55 </div>
<div class="row offset-s1 col s12"> 58 56 <div class="row offset-s1 col s12">
<a class="trigger-password-reset" ng-click="triggerPasswordReset()" href="#">Forgot Password?</a> 59 57 <a class="trigger-password-reset" ng-click="triggerPasswordReset()" href="#">Forgot Password?</a>
</div> 60 58 </div>
</div> 61 59 </div>