Commit c3350cb1fed6501553a7a65cae5d3ec9cd7c9418

Authored by Andrew Buss
1 parent d5f1502004

refactor common functionality into cardgridcontroller.js

Showing 6 changed files with 116 additions and 168 deletions Inline Diff

<!DOCTYPE html> 1 1 <!DOCTYPE html>
<html ng-app="flashy"> 2 2 <html ng-app="flashy">
<base href="/app/"> 3 3 <base href="/app/">
<head> 4 4 <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" 6 6 <link rel="stylesheet"
href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.css"> 7 7 href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.css">
8 8
<link rel="stylesheet" href="styles/flashier.css"/> 9 9 <link rel="stylesheet" href="styles/flashier.css"/>
<link rel="stylesheet" href="styles/flashy.css"/> 10 10 <link rel="stylesheet" href="styles/flashy.css"/>
<link href='https://fonts.googleapis.com/css?family=Titillium+Web:200,200italic,300,600,400,900,700,400italic,700italic,300italic,600italic' 11 11 <link href='https://fonts.googleapis.com/css?family=Titillium+Web:200,200italic,300,600,400,900,700,400italic,700italic,300italic,600italic'
rel='stylesheet' type='text/css'> 12 12 rel='stylesheet' type='text/css'>
<title>Flashy</title> 13 13 <title>Flashy</title>
</head> 14 14 </head>
<body ng-controller="RootController"> 15 15 <body ng-controller="RootController">
<header> 16 16 <header>
<nav> 17 17 <nav>
<div class="nav-wrapper"> 18 18 <div class="nav-wrapper">
<a ng-show="UserService.isLoggedIn()" href="#" data-activates="mobile-demo" 19 19 <a ng-show="UserService.isLoggedIn()" href="#" data-activates="mobile-demo"
class="left button-collapse hide-on-med-and-up"><i 20 20 class="left button-collapse hide-on-med-and-up"><i
class="mdi-navigation-menu"></i></a> 21 21 class="mdi-navigation-menu"></i></a>
<!-- User's classes dropdown --> 22 22 <!-- User's classes dropdown -->
<ul id="classDropdown" class="dropdown-content"> 23 23 <ul id="classDropdown" class="dropdown-content">
<li ui-sref-active="active" ng-repeat="section in UserService.getUserData().sections"> 24 24 <li ui-sref-active="active" ng-repeat="section in UserService.getUserData().sections">
<a ui-sref="feed({sectionId:section.id})">{{section.short_name}}</a> 25 25 <a ui-sref="feed({sectionId:section.id})">{{section.short_name}}</a>
</li> 26 26 </li>
<li class="divider"></li> 27 27 <li class="divider"></li>
<li><a ui-sref="addclass">Add Class</a></li> 28 28 <li><a ui-sref="addclass">Add Class</a></li>
</ul> 29 29 </ul>
<ul ng-show="UserService.isLoggedIn()" class="left hide-on-small-and-down"> 30 30 <ul ng-show="UserService.isLoggedIn()" class="left hide-on-small-and-down">
<li><a style="font-size:20px; font-weight:700" class="dropdown-button ng-cloak hide-on-small-and-down" 31 31 <li><a style="font-size:20px; font-weight:700" class="dropdown-button ng-cloak hide-on-small-and-down"
href="#!" 32 32 href="#!"
data-activates="classDropdown">{{currentSection.id?currentSection.short_name:"Classes"}}<i 33 33 data-activates="classDropdown">{{currentSection.id?currentSection.short_name:"Classes"}}<i
class="mdi-navigation-arrow-drop-down right"></i></a></li> 34 34 class="mdi-navigation-arrow-drop-down right"></i></a></li>
<li ng-show="currentSection.id" ui-sref-active="active"><a ui-sref="feed({sectionId:currentSection.id})" 35 35 <li ng-show="currentSection.id" ui-sref-active="active"><a ui-sref="feed({sectionId:currentSection.id})"
class="tooltipped" 36 36 class="tooltipped"
data-position="bottom" 37 37 data-position="bottom"
data-delay="50" data-tooltip="Feed"><i 38 38 data-delay="50" data-tooltip="Feed"><i
class="mdi-action-view-module"></i></a></li> 39 39 class="mdi-action-view-module"></i></a></li>
<li ng-show="currentSection.id" ui-sref-active="active"><a ui-sref="deck({sectionId:currentSection.id})" 40 40 <li ng-show="currentSection.id" ui-sref-active="active"><a ui-sref="deck({sectionId:currentSection.id})"
class="tooltipped" 41 41 class="tooltipped"
data-position="bottom" 42 42 data-position="bottom"
data-delay="50" data-tooltip="Deck"><i 43 43 data-delay="50" data-tooltip="Deck"><i
class="mdi-action-view-carousel"></i></a></li> 44 44 class="mdi-action-view-carousel"></i></a></li>
<li ng-show="currentSection.id" ui-sref-active="active"><a ui-sref="cardlist({sectionId:currentSection.id})" 45 45 <li ng-show="currentSection.id" ui-sref-active="active"><a ui-sref="cardlist({sectionId:currentSection.id})"
class="tooltipped" 46 46 class="tooltipped"
data-position="bottom" 47 47 data-position="bottom"
data-delay="50" data-tooltip="Card List"><i 48 48 data-delay="50" data-tooltip="Card List"><i
class="mdi-action-view-list"></i></a></li> 49 49 class="mdi-action-view-list"></i></a></li>
</ul> 50 50 </ul>
<a href="#" class="brand-logo center">Flashy</a> 51 51 <a href="#" class="brand-logo center">Flashy</a>
52 52
<ul ng-show="UserService.isLoggedIn()" ng-cloak id="nav-mobile" class="right hide-on-small-and-down"> 53 53 <ul ng-show="UserService.isLoggedIn()" ng-cloak id="nav-mobile" class="right hide-on-small-and-down">
54 54
<li ui-sref-active="active"><a ui-sref="study" class="tooltipped" data-position="bottom" data-delay="50" 55 55 <li ui-sref-active="active"><a ui-sref="study" class="tooltipped" data-position="bottom" data-delay="50"
data-tooltip="Study"> 56 56 data-tooltip="Study">
<i class="tiny mdi-action-pageview"></i></a></li> 57 57 <i class="tiny mdi-action-pageview"></i></a></li>
58 58
<!-- Settings Dropdown --> 59 59 <!-- Settings Dropdown -->
<ul id="settingsDropdown" class="dropdown-content"> 60 60 <ul id="settingsDropdown" class="dropdown-content">
61 61
62 62
</ul> 63 63 </ul>
64 64
<li ui-sref-active="active"><a ui-sref="help"><i class="tiny mdi-action-help tooltipped" 65 65 <li ui-sref-active="active"><a ui-sref="help"><i class="tiny mdi-action-help tooltipped"
data-position="bottom" 66 66 data-position="bottom"
data-delay="50" data-tooltip="Help"></i></a></li> 67 67 data-delay="50" data-tooltip="Help"></i></a></li>
<li ui-sref-active="active"><a ui-sref="settings"><i data-position="bottom" data-delay="50" 68 68 <li ui-sref-active="active"><a ui-sref="settings"><i data-position="bottom" data-delay="50"
data-tooltip="Settings" 69 69 data-tooltip="Settings"
class="mdi-action-settings tooltipped"></i></a></li> 70 70 class="mdi-action-settings tooltipped"></i></a></li>
<li><a ui-sref="logout"><i data-position="bottom" data-delay="50" data-tooltip="Logout" 71 71 <li><a ui-sref="logout"><i data-position="bottom" data-delay="50" data-tooltip="Logout"
class="mdi-content-forward tooltipped"></i></a></li> 72 72 class="mdi-content-forward tooltipped"></i></a></li>
73 73
74 74
</ul> 75 75 </ul>
76 76
<!-- Slide-in side-nav for small screens --> 77 77 <!-- Slide-in side-nav for small screens -->
<ul ng-show="UserService.isLoggedIn()" class="side-nav" id="mobile-demo"> 78 78 <ul ng-show="UserService.isLoggedIn()" class="side-nav" id="mobile-demo">
<span ng-show="currentSection.id"> 79 79 <span ng-show="currentSection.id">
<li ui-sref-active="active"><a ui-sref="feed({sectionId:currentSection.id})" class="tooltipped"> 80 80 <li ui-sref-active="active"><a ui-sref="feed({sectionId:currentSection.id})" class="tooltipped">
<i class="mdi-action-view-module left"></i> 81 81 <i class="mdi-action-view-module left"></i>
Feed</a> 82 82 Feed</a>
</li> 83 83 </li>
<li ui-sref-active="active"><a ui-sref="deck({sectionId:currentSection.id})" class="tooltipped"> 84 84 <li ui-sref-active="active"><a ui-sref="deck({sectionId:currentSection.id})" class="tooltipped">
<i class="mdi-action-view-carousel left"> </i> 85 85 <i class="mdi-action-view-carousel left"> </i>
Deck 86 86 Deck
</a> 87 87 </a>
</li> 88 88 </li>
<li ui-sref-active="active"><a ui-sref="cardlist({sectionId:currentSection.id})" class="tooltipped"> 89 89 <li ui-sref-active="active"><a ui-sref="cardlist({sectionId:currentSection.id})" class="tooltipped">
<i class="mdi-action-view-list left"></i> 90 90 <i class="mdi-action-view-list left"></i>
Card List 91 91 Card List
</a> 92 92 </a>
</li> 93 93 </li>
<hr> 94 94 <hr>
</span> 95 95 </span>
<!-- Collapsible menu for all the User's classes --> 96 96 <!-- Collapsible menu for all the User's classes -->
<ul class="collapsible" data-collapsible="accordion"> 97 97 <ul class="collapsible" data-collapsible="accordion">
<li class="bold"> 98 98 <li class="bold">
<a class="collapsible-header black-text"> 99 99 <a class="collapsible-header black-text">
Classes 100 100 Classes
<i class="mdi-navigation-arrow-drop-down right"></i> 101 101 <i class="mdi-navigation-arrow-drop-down right"></i>
</a> 102 102 </a>
</li> 103 103 </li>
<div class="collapsible-body" style="display: block"> 104 104 <div class="collapsible-body" style="display: block">
<ul> 105 105 <ul>
<li ui-sref-active="active" ng-repeat="section in UserService.getUserData().sections"> 106 106 <li ui-sref-active="active" ng-repeat="section in UserService.getUserData().sections">
<a class="class bold" ui-sref="feed({sectionId:section.id})">{{section.short_name}}</a> 107 107 <a class="class bold" ui-sref="feed({sectionId:section.id})">{{section.short_name}}</a>
</li> 108 108 </li>
<hr> 109 109 <hr>
<li><a ui-sref="addclass"><i class="tiny mdi-content-add">Add Class</i></a></li> 110 110 <li><a ui-sref="addclass"><i class="tiny mdi-content-add">Add Class</i></a></li>
</ul> 111 111 </ul>
</div> 112 112 </div>
</ul> 113 113 </ul>
<li><a ui-sref="study">Study</a></li> 114 114 <li><a ui-sref="study">Study</a></li>
<li><a ui-sref="settings">Settings</a></li> 115 115 <li><a ui-sref="settings">Settings</a></li>
<li><a ui-sref="logout">Logout</a></li> 116 116 <li><a ui-sref="logout">Logout</a></li>
</ul> 117 117 </ul>
</div> 118 118 </div>
</nav> 119 119 </nav>
120 120
</header> 121 121 </header>
122 122
123 123
<!-- Menu Bar --> 124 124 <!-- Menu Bar -->
125 125
<div class="wrapper"> 126 126 <div class="wrapper">
127 127
<main ui-view></main> 128 128 <main ui-view></main>
129 129
<div class="push"></div> 130 130 <div class="push"></div>
</div> 131 131 </div>
132 132
133 133
<footer class="page-footer"> 134 134 <footer class="page-footer">
<div class="footer-copyright"> 135 135 <div class="footer-copyright">
<div class="container"> 136 136 <div class="container">
&copy; 2015 Team Swag 137 137 &copy; 2015 Team Swag
<a class="grey-text text-lighten-4 right" id="contact" href="mailto:halp@flashy.cards">Concerns? Contact us by 138 138 <a class="grey-text text-lighten-4 right" id="contact" href="mailto:halp@flashy.cards">Concerns? Contact us by
email!</a> 139 139 email!</a>
</div> 140 140 </div>
141 141
</div> 142 142 </div>
</footer> 143 143 </footer>
144 144
</body> 145 145 </body>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script> 146 146 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.14/angular-ui-router.js"></script> 147 147 <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.14/angular-ui-router.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-cookies.js"></script> 148 148 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-cookies.js"></script>
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script> 149 149 <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="scripts/materialize.js"></script> 150 150 <script type="text/javascript" src="scripts/materialize.js"></script>
<script type="text/javascript" src="scripts/jquery.collapsible.js"></script> 151 151 <script type="text/javascript" src="scripts/jquery.collapsible.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.js"></script> 152 152 <script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script> 153 153 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script> 154 154 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-resource.min.js"></script> 155 155 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-resource.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.js"></script> 156 156 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.js"></script>
157 157
158 158
<script src="config.js"></script> 159 159 <script src="config.js"></script>
160 160
scripts/CardGridController.js View file @ c3350cb
File was created 1 angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate']).controller =
2 function($scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService) {
3
4 $scope.cards = false;
5 $scope.cardCols = []; // organized data
6 $scope.numCols = 0;
7 $scope.cardTable = {}; // look up table of cards, {'colNum':col, 'obj':card}
8 $scope.sectionId = parseInt($stateParams.sectionId);
9 $scope.section = $rootScope.SectionResource.get({sectionId: $scope.sectionId});
10 $rootScope.currentSection = $scope.section;
11 console.log('hello from cardgridcontroller');
12
13 if (!UserService.isInSection($scope.sectionId)) {
14 console.log('user is not enrolled in ' + $scope.sectionId);
15 return $state.go('addclass');
16 }
17
18 angular.element($window).bind('resize', $scope.refreshLayout);
19 $scope.refreshColumnWidth = function() {
20 console.log('refreshing column width');
21 avail = $window.innerWidth - 17;
22 width = Math.floor(avail / Math.floor(avail / 250));
23 $('.cardColumn').css({
24 width: width + 'px',
25 'font-size': 100 * width / 250 + '%'
26 });
27 $('.cardColumn .card.flashy').css({
28 width: width - 12 + 'px',
29 height: (width * 3 / 5) + 'px'
30 });
31 };
32
33 $scope.refreshLayout = function() {
34 numCols = Math.max(1, Math.floor(($window.innerWidth - 17) / 250));
35
36 // check if we actually need to refresh the whole layout
37 if (numCols == $scope.numCols) return $scope.refreshColumnWidth();
38 $scope.numCols = numCols;
39 console.log('refreshing layout for ' + $scope.numCols + ' columns');
40 $scope.cardCols = [];
41 var cols = [];
42 for (i = 0; i < $scope.numCols; i++) cols.push([]);
43 $scope.cards.forEach(function(card, i) {
44 cols[i % $scope.numCols].push(card);
45 $scope.cardTable[card.id] = {'colNum': (i % $scope.numCols), 'obj': card};
46 });
47 // wait until the next digest cycle to update cardCols
48
49 $timeout(function() {
50 $scope.cardCols = cols;
51 $timeout($scope.refreshColumnWidth);
52 });
53
54 };
55
56 $scope.add = function(card) {
57 var colNum = 0;
58 var lowestCol = $scope.cardCols[0];
59 var lowestColNum = 0;
60 while (colNum < $scope.numCols) {
61 if ($scope.cardCols[colNum].length == 0) {
62 lowestCol = $scope.cardCols[colNum];
63 break;
64 } else if ($scope.cardCols[colNum].length < lowestCol.length) {
65 lowestCol = $scope.cardCols[colNum];
66 lowestColNum = colNum;
67 lowestColLen = $scope.cardCols[colNum].length;
68 }
69 colNum++;
70 }
71 console.log(card);
72 $scope.cards.push(data);
73 $timeout(function() {
74 lowestCol.unshift(card);
75 $scope.cardTable[card.id] = {'colNum': lowestColNum, 'obj': card};
76 $timeout($scope.refreshColumnWidth);
scripts/DeckController.js View file @ c3350cb
angular.module('flashy.DeckController', ['ui.router']). 1 1 angular.module('flashy.DeckController', ['ui.router']).
2 2
controller('DeckController', function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams) { 3 3 controller('DeckController', function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, UserService) {
sectionId = $stateParams.sectionId; 4 4 angular.module('flashy.CardGridController').controller.call(this, $scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService);
$rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId}); 5
$scope.cards = false; 6
$scope.cardCols = []; // organized data 7
$scope.numCols = 0; 8
9 5
function calculate_cols() { 10
var avail = $window.innerWidth - 17; 11
return Math.max(1, Math.floor(avail / 250)); 12
} 13
14
$scope.refreshColumnWidth = function() { 15
console.log('refreshing column width'); 16
avail = $window.innerWidth - 17; 17
width = Math.floor(avail / Math.floor(avail / 250)); 18
$('.cardColumn').css({ 19
width: width + 'px', 20
'font-size': 100 * width / 250 + '%' 21
}); 22
$('.cardColumn .card.flashy').css({ 23
width: width - 12 + 'px', 24
height: (width * 3 / 5) + 'px' 25
}); 26
}; 27
28
$scope.refreshLayout = function() { 29
// check if we actually need to refresh the whole layout 30
if (calculate_cols() == $scope.numCols) return $scope.refreshColumnWidth(); 31
$scope.numCols = calculate_cols(); 32
console.log('refreshing layout for ' + $scope.numCols + ' columns'); 33
$scope.cardCols = []; 34
var cols = []; 35
for (i = 0; i < $scope.numCols; i++) cols.push([]); 36
$scope.cards.forEach(function(card, i) { 37
cols[i % $scope.numCols].push(card); 38
}); 39
// wait until the next digest cycle to update cardCols 40
41
$timeout(function() { 42
$scope.cardCols = cols; 43
$timeout($scope.refreshColumnWidth); 44
}); 45
46
}; 47
48
angular.element($window).bind('resize', $scope.refreshLayout); 49
50
$scope.refreshCards = function() { 51 6 $scope.refreshCards = function() {
$http.get('/api/sections/' + sectionId + '/deck/'). 52 7 $http.get('/api/sections/' + $scope.sectionId + '/deck/').
success(function(data) { 53 8 success(function(data) {
console.log(data); 54 9 console.log(data);
$scope.cards = data; 55 10 $scope.cards = data;
$scope.refreshLayout(); 56 11 $scope.refreshLayout();
console.log('success in refresh cards...'); 57 12 console.log('success in refresh cards...');
}). 58 13 }).
error(function(err) { 59 14 error(function(err) {
console.log('refresh fail'); 60 15 console.log('refresh fail');
}); 61 16 });
}; 62 17 };
$scope.refreshCards(); 63 18 $scope.refreshCards();
scripts/FeedController.js View file @ c3350cb
angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']). 1 1 angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
2 2
controller('FeedController', function($scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService) { 3 3 controller('FeedController', function($scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService) {
4 angular.module('flashy.CardGridController').controller.call(this, $scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService);
console.log('Hello from feed'); 4 5 console.log('Hello from feed');
sectionId = parseInt($stateParams.sectionId); 5
if (!UserService.isInSection(sectionId)) { 6
console.log('user is not enrolled in ' + sectionId); 7
return $state.go('addclass'); 8
} 9
$rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId}); 10
$rootScope.debug_flashcard = false; 11
$scope.cards = false; 12
$scope.cardCols = []; // organized data 13
$scope.numCols = 0; 14
$scope.cardTable = {}; // look up table of cards, {'colNum':col, 'obj':card} 15
16 6
function calculate_cols() { 17
var avail = $window.innerWidth - 17; 18
return Math.max(1, Math.floor(avail / 250)); 19
} 20
21
$scope.refreshColumnWidth = function() { 22
console.log('refreshing column width'); 23
avail = $window.innerWidth - 17; 24
width = Math.floor(avail / Math.floor(avail / 250)); 25
$('.cardColumn').css({ 26
width: width + 'px', 27
'font-size': 100 * width / 250 + '%' 28
}); 29
$('.cardColumn .card.flashy').css({ 30
width: width - 12 + 'px', 31
height: (width * 3 / 5) + 'px' 32
}); 33
}; 34
35
$scope.refreshLayout = function() { 36
// check if we actually need to refresh the whole layout 37
if (calculate_cols() == $scope.numCols) return $scope.refreshColumnWidth(); 38
$scope.numCols = calculate_cols(); 39
console.log('refreshing layout for ' + $scope.numCols + ' columns'); 40
$scope.cardCols = []; 41
var cols = []; 42
for (i = 0; i < $scope.numCols; i++) cols.push([]); 43
$scope.cards.forEach(function(card, i) { 44
cols[i % $scope.numCols].push(card); 45
$scope.cardTable[card.id] = {'colNum': (i % $scope.numCols), 'obj': card}; 46
}); 47
// wait until the next digest cycle to update cardCols 48
49
$timeout(function() { 50
$scope.cardCols = cols; 51
$timeout($scope.refreshColumnWidth); 52
}); 53
54
}; 55
56
angular.element($window).bind('resize', $scope.refreshLayout); 57
58
$scope.refreshCards = function() { 59 7 $scope.refreshCards = function() {
$http.get('/api/sections/' + sectionId + '/feed/'). 60 8 $http.get('/api/sections/' + $scope.sectionId + '/feed/').
success(function(data) { 61 9 success(function(data) {
console.log(data); 62 10 console.log(data);
$scope.cards = data; 63 11 $scope.cards = data;
$scope.refreshLayout(); 64 12 $scope.refreshLayout();
console.log('success in refresh cards...'); 65 13 console.log('success in refresh cards...');
}). 66 14 }).
error(function(err) { 67 15 error(function(err) {
console.log('refresh fail'); 68 16 console.log('refresh fail');
console.log(err); 69 17 console.log(err);
}); 70 18 });
}; 71 19 };
72 20
$scope.add = function(card) { 73
var colNum = 0; 74
var lowestCol = $scope.cardCols[0]; 75
var lowestColNum = 0; 76
while (colNum < $scope.numCols) { 77
if ($scope.cardCols[colNum].length == 0) { 78
lowestCol = $scope.cardCols[colNum]; 79
break; 80
} else if ($scope.cardCols[colNum].length < lowestCol.length) { 81
lowestCol = $scope.cardCols[colNum]; 82
lowestColNum = colNum; 83
lowestColLen = $scope.cardCols[colNum].length; 84
} 85
colNum++; 86
} 87
console.log(card); 88
$scope.cards.push(data); 89
$timeout(function() { 90
lowestCol.unshift(card); 91
$scope.cardTable[card.id] = {'colNum': lowestColNum, 'obj': card}; 92
$timeout($scope.refreshColumnWidth); 93
}); 94
}; 95
96
$scope.sortAdd = function(card, array) { 97 21 $scope.sortAdd = function(card, array) {
console.log('sort add'); 98 22 console.log('sort add');
array.forEach(function(ele, i, ary) { 99 23 array.forEach(function(ele, i, ary) {
if (ele.score <= card.score) { 100 24 if (ele.score <= card.score) {
ary.splice(i, 0, card); 101 25 ary.splice(i, 0, card);
return; 102 26 return;
} 103 27 }
}); 104 28 });
}; 105 29 };
106 30
$scope.hide = function(card) { 107 31 $scope.hide = function(card) {
console.log('hiding card'); 108 32 console.log('hiding card');
var found = -1; 109 33 var found = -1;
col = $scope.cardTable[card.id].colNum; 110 34 col = $scope.cardTable[card.id].colNum;
found = $scope.cardCols[col].indexOf(card); 111 35 found = $scope.cardCols[col].indexOf(card);
if (found != -1) { 112 36 if (found != -1) {
$scope.cardCols[col].splice(found, 1); 113 37 $scope.cardCols[col].splice(found, 1);
console.log('card hidden'); 114 38 console.log('card hidden');
return col; 115 39 return col;
} 116 40 }
console.log('Error finding card to hide:'); 117 41 console.log('Error finding card to hide:');
console.log(card); 118 42 console.log(card);
return -1; 119 43 return -1;
}; 120 44 };
121 45
$scope.update = function(id, new_score) { 122 46 $scope.update = function(id, new_score) {
card = $scope.cardTable[id].obj; 123 47 card = $scope.cardTable[id].obj;
if (Math.abs(new_score - card.score) < .0001) { 124 48 if (Math.abs(new_score - card.score) < .0001) {
console.log('score same, no update required'); 125 49 console.log('score same, no update required');
return; 126 50 return;
} 127 51 }
console.log('updating'); 128 52 console.log('updating');
console.log(card); 129 53 console.log(card);
var column = $scope.cardCols[$scope.cardTable[id].colNum]; 130 54 var column = $scope.cardCols[$scope.cardTable[id].colNum];
var found = column.indexOf(card); 131 55 var found = column.indexOf(card);
var i = 0; 132 56 var i = 0;
for (; i < column.length; i++) 133 57 for (; i < column.length; i++)
if (column[i].score <= new_score) break; 134 58 if (column[i].score <= new_score) break;
card.score = new_score; 135 59 card.score = new_score;
if ($scope.$$phase) { // most of the time it is "$digest" 136 60 if ($scope.$$phase) { // most of the time it is "$digest"
column.splice(i, 0, column.splice(found, 1)[0]); 137 61 column.splice(i, 0, column.splice(found, 1)[0]);
} else { 138 62 } else {
$scope.$apply(column.splice(i, 0, column.splice(found, 1)[0])); 139 63 $scope.$apply(column.splice(i, 0, column.splice(found, 1)[0]));
} 140 64 }
}; 141 65 };
142 66
var loc = window.location, new_uri; 143 67 var loc = window.location, new_uri;
if (loc.protocol === 'https:') { 144 68 if (loc.protocol === 'https:') {
new_uri = 'wss:'; 145 69 new_uri = 'wss:';
} else { 146 70 } else {
new_uri = 'ws:'; 147 71 new_uri = 'ws:';
} 148 72 }
new_uri += '//' + loc.host; 149 73 new_uri += '//' + loc.host;
var ws = new WebSocket(new_uri + '/ws/feed/' + sectionId + '?subscribe-broadcast'); 150 74 $scope.ws = new WebSocket(new_uri + '/ws/feed/' + $scope.sectionId + '?subscribe-broadcast');
151 75
ws.onopen = function() { 152 76 $scope.ws.onmessage = function(e) {
console.log('websocket connected'); 153
}; 154
ws.onmessage = function(e) { 155
data = JSON.parse(e.data); 156 77 data = JSON.parse(e.data);
console.log('got websocket message ' + e.data); 157 78 console.log('got websocket message ' + e.data);
console.log(data); 158 79 console.log(data);
if (data.event_type == 'new_card') { 159 80 if (data.event_type == 'new_card') {
$scope.add(data.flashcard); 160 81 $scope.add(data.flashcard);
} else if (data.event_type == 'score_change') { 161 82 } else if (data.event_type == 'score_change') {
$scope.update(data.flashcard_id, data.new_score); 162 83 $scope.update(data.flashcard_id, data.new_score);
} 163 84 }
}; 164 85 };
ws.onerror = function(e) { 165
console.error(e); 166
}; 167
ws.onclose = function(e) { 168
console.log('connection closed'); 169
}; 170
171 86
var resetModal = function() { 172 87 var resetModal = function() {
$('#new-card-input').html(''); 173 88 $('#new-card-input').html('');
$('#newCard').closeModal(modal_options); 174 89 $('#newCard').closeModal(modal_options);
}; 175 90 };
176 91
$scope.pushCard = function() { 177 92 $scope.pushCard = function() {
var i = 0; 178 93 var i = 0;
var blanks = []; 179 94 var blanks = [];
$('#new-card-input')[0].childNodes.forEach(function(node) { 180 95 $('#new-card-input')[0].childNodes.forEach(function(node) {
if (typeof node.data == 'undefined') { 181 96 if (typeof node.data == 'undefined') {
console.log('undefined node'); 182 97 console.log('undefined node');
return resetModal(); 183 98 return resetModal();
} 184 99 }
node = $(node)[0]; 185 100 node = $(node)[0];
console.log(node); 186 101 console.log(node);
if (node.tagName == 'B') { 187 102 if (node.tagName == 'B') {
text = $(node).text(); 188 103 text = $(node).text();
blanks.push([i, i + text.length]); 189 104 blanks.push([i, i + text.length]);
i += text.length; 190 105 i += text.length;
} else { 191 106 } else {
i += node.data.length; 192 107 i += node.data.length;
} 193 108 }
}); 194 109 });
var myCard = { 195 110 var myCard = {
'text': $('#new-card-input').text().trim(), 196 111 'text': $('#new-card-input').text().trim(),
'mask': blanks, 197 112 'mask': blanks,
section: sectionId 198 113 section: sectionId
}; 199 114 };
if (myCard.text == '') { 200 115 if (myCard.text == '') {
console.log('blank flashcard not pushed:' + myCard.text); 201 116 console.log('blank flashcard not pushed:' + myCard.text);
return resetModal(); 202 117 return resetModal();
} 203 118 }
$http.post('/api/flashcards/', myCard). 204 119 $http.post('/api/flashcards/', myCard).
success(function(data) { 205 120 success(function(data) {
console.log('flashcard pushed: ' + myCard.text); 206 121 console.log('flashcard pushed: ' + myCard.text);
if (!UserService.hasVerifiedEmail()) { 207 122 if (!UserService.hasVerifiedEmail()) {
Materialize.toast("<p>Thanks for contributing! However, others won't see your card until you verify your email address<p>", 4000); 208 123 Materialize.toast("<p>Thanks for contributing! However, others won't see your card until you verify your email address<p>", 4000);
} 209 124 }
210 125
}). 211 126 }).
error(function(error) { 212 127 error(function(error) {
console.log('something went wrong pushing a card!'); 213 128 console.log('something went wrong pushing a card!');
}); 214 129 });
return resetModal(); 215 130 return resetModal();
}; 216 131 };
217 132
/* Key bindings for the whole feed window. Hotkey it up! */ 218 133 /* Key bindings for the whole feed window. Hotkey it up! */
var listenForC = true; 219 134 var listenForC = true;
220 135
// Need to pass these options into openmodal and leanmodal, 221 136 // Need to pass these options into openmodal and leanmodal,
// otherwise the ready handler doesn't get called 222 137 // otherwise the ready handler doesn't get called
223 138
modal_options = { 224 139 modal_options = {
dismissible: true, // Modal can be dismissed by clicking outside of the modal 225 140 dismissible: true, // Modal can be dismissed by clicking outside of the modal
opacity: 0, // Opacity of modal background 226 141 opacity: 0, // Opacity of modal background
in_duration: 300, // Transition in duration 227 142 in_duration: 300, // Transition in duration
out_duration: 200, // Transition out duration 228 143 out_duration: 200, // Transition out duration
ready: function() { 229 144 ready: function() {
listenForC = false; 230 145 listenForC = false;
console.log('modal OPENING'); 231 146 console.log('modal OPENING');
$('#new-card-input').focus(); 232 147 $('#new-card-input').focus();
}, 233 148 },
complete: function() { 234 149 complete: function() {
listenForC = true; 235 150 listenForC = true;
console.log('modal done, closing'); 236 151 console.log('modal done, closing');
$('#new-card-input').blur(); 237 152 $('#new-card-input').blur();
} 238 153 }
}; 239 154 };
240 155
$(document).keydown(function(e) { 241 156 $(document).keydown(function(e) {
var keyed = e.which; 242 157 var keyed = e.which;
if (keyed == 67 && listenForC) { // "c" for compose 243 158 if (keyed == 67 && listenForC) { // "c" for compose
$('#newCard').openModal(modal_options); 244 159 $('#newCard').openModal(modal_options);
e.preventDefault(); 245 160 e.preventDefault();
listenForC = false; 246 161 listenForC = false;
return false; 247 162 return false;
} else if (keyed == 27) { // clear on ESC 248 163 } else if (keyed == 27) { // clear on ESC
listenForC = true; 249 164 listenForC = true;
document.getElementById('new-card-input').value = ''; 250 165 document.getElementById('new-card-input').value = '';
} 251 166 }
}); 252 167 });
$(document).ready(function() { 253 168 $(document).ready(function() {
$('.tooltipped').tooltip({delay: 50}); 254 169 $('.tooltipped').tooltip({delay: 50});
// the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered 255 170 // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
$('.modal-trigger').leanModal(modal_options); 256 171 $('.modal-trigger').leanModal(modal_options);
$('#new-card-input').on('keydown', function(e) { 257 172 $('#new-card-input').on('keydown', function(e) {
if (e.which == 13) { 258 173 if (e.which == 13) {
e.preventDefault(); 259 174 e.preventDefault();
$scope.pushCard(); 260 175 $scope.pushCard();
listenForC = true; 261 176 listenForC = true;
return false; 262 177 return false;
} 263 178 }
}); 264 179 });
$('button#blank-selected').click(function() { 265 180 $('button#blank-selected').click(function() {
console.log(window.getSelection()); 266 181 console.log(window.getSelection());
document.execCommand('bold'); 267 182 document.execCommand('bold');
}); 268 183 });
}); 269 184 });
$scope.refreshCards(); 270 185 $scope.refreshCards();
$scope.$on('$destroy', function() { 271
ws.close(); 272
$rootScope.currentSection = {}; 273
$(document).off('keydown'); 274
}); 275
276 186
$scope.shuffleCards = function() { 277 187 $scope.shuffleCards = function() {
$timeout(function() { 278 188 $timeout(function() {
(function(o) { 279 189 (function(o) {
for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); 280 190 for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o; 281 191 return o;
})($scope.cardCols[0]); 282 192 })($scope.cardCols[0]);
}); 283 193 });
}; 284 194 };
window.feedscope = $scope; 285 195 window.feedscope = $scope;
286 196
}); 287 197 });
scripts/StudyController.js View file @ c3350cb
angular.module('flashy.StudyController', ['ui.router']). 1 1 angular.module('flashy.StudyController', ['ui.router']).
2 2
controller('StudyController', ['$scope', '$stateParams', '$state', '$http', 'UserService', 3 3 controller('StudyController', ['$scope', '$stateParams', '$state', '$http', 'UserService',
function($scope, $stateParams, $state, $http, UserService) { 4 4 function($scope, $stateParams, $state, $http, UserService) {
console.log('Flashy study controller content in this file. also hell0'); 5 5 console.log('Flashy study controller content in this file. also hell0');
sectionId = $stateParams.sectionId; 6 6 sectionId = $stateParams.sectionId;
$scope.isParamOpen = true; 7 7 $scope.isParamOpen = true;
8 8
$(document).ready(function() { 9 9 $(document).ready(function() {
$('.datepicker').pickadate({ 10 10 $('.datepicker').pickadate({
selectMonths: true, // Creates a dropdown to control month 11 11 selectMonths: true, // Creates a dropdown to control month
selectYears: 15 // Creates a dropdown of 15 years to control year 12 12 selectYears: 15 // Creates a dropdown of 15 years to control year
}); 13 13 });
14 14
$('select').material_select(); 15 15 $('select').material_select();
}); 16 16 });
17 17
$scope.UserService = UserService; 18 18 $scope.UserService = UserService;
$scope.isParamOpen = true; 19 19 $scope.isParamOpen = true;
20 20
console.log($scope.UserService.getUserData().sections); 21 21 console.log($scope.UserService.getUserData().sections);
22 22
$scope.toggleSectionToStudy = function(id) { 23 23 $scope.toggleSectionToStudy = function(id) {
console.log('toggle sect', id); 24 24 console.log('toggle sect', id);
$scope.sectionToStudy = id; 25 25 $scope.sectionToStudy = id;
}; 26 26 };
27 27
$scope.openParams = function() { 28 28 $scope.openParams = function() {
$scope.isParamOpen = !$scope.isParamOpen; 29 29 $scope.isParamOpen = !$scope.isParamOpen;
}; 30 30 };
31 31
$scope.fetchQuiz = function(a, b) { 32 32 $scope.fetchQuiz = function(a, b) {
//console.log($scope.startDate, $scope.endDate); 33 33 //console.log($scope.startDate, $scope.endDate);
console.log(a, b); 34 34 console.log(a, b);
}; 35 35 };
36 36
/* 37 37 /*
$scope.fetchQuiz = function() { 38 38 $scope.fetchQuiz = function() {
console.log('fetching quiz...'); 39 39 console.log('fetching quiz...');
var studyRequest = { 40 40 var studyRequest = {
'sections': ($scope.sectionToStudy == null) ? [] : [$scope.sectionToStudy], 41 41 'sections': ($scope.sectionToStudy == null) ? [] : [$scope.sectionToStudy],
'material_date_begin':, 42 42 'material_date_begin':,
'material_date_end': 43 43 'material_date_end':
}; 44 44 };
45 45
// $http.post('/api/study/', studyRequest). 46 46 // $http.post('/api/study/', studyRequest).
//TODO 47 47 //TODO
}; 48 48 };
*/ 49 49 */
50 50
// Flashcard content 51 51 // Flashcard content
$scope.htmlContent = 'sample text here longwordddddddddddddddddddddddddddd hello there from js review ctrl alwkejflakewjflk awjkefjkwefjlkea jfkewjaweajkakwef jk fjeawkafj kaewjf jawekfj akwejfk '; 52 52 $scope.htmlContent = 'sample text here longwordddddddddddddddddddddddddddd hello there from js review ctrl alwkejflakewjflk awjkefjkwefjlkea jfkewjaweajkakwef jk fjeawkafj kaewjf jawekfj akwejfk ';
//single card 53 53 //single card
$scope.samples = 54 54 $scope.samples =
{ 55 55 {
'name': 'lol', 56 56 'name': 'lol',
'text': 'sample text here 111111 woo hoo I think it works', 57 57 'text': 'sample text here 111111 woo hoo I think it works',
'mask': [[0, 6], [16, 23]] 58 58 'mask': [[0, 6], [16, 23]]
}; 59 59 };
60 60
// get text to display as array 61 61 // get text to display as array
$scope.displayText = []; 62 62 $scope.displayText = [];
// get answers to blanks as array 63 63 // get answers to blanks as array
$scope.blankText = []; 64 64 $scope.blankText = [];
var start = 0; // where to start next string break 65 65 var start = 0; // where to start next string break
for (var i = 0; i < $scope.samples.mask.length; i++) { 66 66 for (var i = 0; i < $scope.samples.mask.length; i++) {
$scope.displayText.push($scope.samples.text.substring(start, $scope.samples.mask[i][0])); 67 67 $scope.displayText.push($scope.samples.text.substring(start, $scope.samples.mask[i][0]));
$scope.blankText.push($scope.samples.text.substring($scope.samples.mask[i][0], $scope.samples.mask[i][1])); 68 68 $scope.blankText.push($scope.samples.text.substring($scope.samples.mask[i][0], $scope.samples.mask[i][1]));
start = $scope.samples.mask[i][1]; 69 69 start = $scope.samples.mask[i][1];
} 70 70 }
if (start != $scope.samples.mask.length - 1) 71 71 if (start != $scope.samples.mask.length - 1)
$scope.displayText.push($scope.samples.text.substring(start)); 72 72 $scope.displayText.push($scope.samples.text.substring(start));
scripts/UserService.js View file @ c3350cb
angular.module('flashy.UserService', ['ui.router']). 1 1 angular.module('flashy.UserService', ['ui.router']).
service('UserService', function($rootScope, $http, $q) { 2 2 service('UserService', function($rootScope, $http, $q) {
var deferred = $q.defer(); 3 3 var deferred = $q.defer();
var _user = false; 4 4 var _user = false;
var login = function(data) { 5 5 var login = function(data) {
if (data.locked) { 6 6 if (data.locked) {
$rootScope.UserService.showLockedMessage(); 7 7 $rootScope.UserService.showLockedMessage();
return deferred.reject('account locked'); 8 8 return deferred.reject('account locked');
} 9 9 }
if (!data.is_confirmed) { 10 10 if (!data.is_confirmed) {
Materialize.toast('Please verify your email address! ' + 11 11 Materialize.toast('Please verify your email address! ' +
'<a class="btn-flat cyan-text" onclick="rootscope.UserService.resendConfirmationEmail()">' + 12 12 '<a class="btn-flat cyan-text" onclick="rootscope.UserService.resendConfirmationEmail()">' +
'Resend Verification Email</a>', 4000); 13 13 'Resend Verification Email</a>', 4000);
} 14 14 }
_user = data; 15 15 _user = data;
_user.sectionIdList = _user.sections.map(function(x) { 16 16 _user.sectionIdList = _user.sections.map(function(x) {
return x.id; 17 17 return x.id;
}); 18 18 });
deferred.resolve(data); 19 19 deferred.resolve(data);
}; 20 20 };
this.login = login; 21 21 this.login = login;
$http.get('/api/me/').success(function(data) { 22 22 $http.get('/api/me/').success(function(data) {
console.log('user is logged in!'); 23 23 console.log('user is logged in!');
login(data); 24 24 login(data);
}).error(function(data) { 25 25 }).error(function(data) {
console.log(data); 26 26 console.log(data);
console.log('not logged in yet: ' + data.detail); 27 27 console.log('not logged in yet: ' + data.detail);
_user = {email: false}; 28 28 _user = {email: false};
deferred.resolve(_user); 29 29 deferred.resolve(_user);
}); 30 30 });
31 31
this.isResolved = function() { 32 32 this.isResolved = function() {
return !!_user; 33 33 return !!_user;
}; 34 34 };
this.getUserData = function() { 35 35 this.getUserData = function() {
if (this.isResolved()) return _user; 36 36 if (this.isResolved()) return _user;
else return deferred.promise; 37 37 else return deferred.promise;
}; 38 38 };
this.hasVerifiedEmail = function() { 39 39 this.hasVerifiedEmail = function() {
return this.isResolved() && _user.is_confirmed; 40 40 return this.isResolved() && _user.is_confirmed;
}; 41 41 };
this.logout = function() { 42 42 this.logout = function() {
_user = false; 43 43 _user = false;
deferred.resolve({}); 44 44 deferred.resolve({});
}; 45 45 };
this.addClass = function(section) { 46 46 this.addClass = function(section) {
_user.sections.push(section); 47 47 _user.sections.push(section);
_user.sectionIdList.push(section.id); 48 48 _user.sectionIdList.push(section.id);
}; 49 49 };
this.isLoggedIn = function() { 50 50 this.isLoggedIn = function() {
rv = this.isResolved() && _user.email; 51 51 rv = this.isResolved() && _user.email;
return rv; 52 52 return rv;
}; 53 53 };
this.isInSection = function(sectionId) { 54 54 this.isInSection = function(sectionId) {
return (_user.sectionIdList.indexOf(sectionId) >= 0); 55 55 return (_user.sectionIdList.indexOf(sectionId) >= 0);
}; 56 56 };
this.redirectToDefaultState = function($state) { 57 57 this.redirectToDefaultState = function($state) {
console.log('redirecting user to their default state'); 58 58 console.log('redirecting user to their default state');
if (!this.isLoggedIn()) return $state.go('login'); 59 59 if (!this.isLoggedIn()) return $state.go('login');
if (!_user.sections.length) return $state.go('addclass'); 60 60 if (!_user.sections.length) return $state.go('addclass');
last_state = localStorage.getItem('last_state'); 61 61 last_state = localStorage.getItem('last_state');
if (last_state) return $state.go(last_state, JSON.parse(localStorage.getItem('last_state_params'))); 62 62 if (last_state) return $state.go(last_state, JSON.parse(localStorage.getItem('last_state_params')));
$state.go('feed', {sectionId: _user.sections[0].id}); 63 63 $state.go('feed', {sectionId: _user.sections[0].id});
}; 64 64 };
this.authorizedFor = function(state, stateParams) { 65 65 this.authorizedFor = function(state, stateParams) {
if (['feed', 'deck', 'cardlist'].indexOf(state.name) >= 0) { 66 66 if (['feed', 'deck', 'cardlist'].indexOf(state.name) >= 0) {
if (_user.sectionIdList.indexOf(stateParams.sectionId) < 0) { 67 67 if (_user.sectionIdList.indexOf(stateParams.sectionId) < 0) {
return false; 68 68 return false;
} 69 69 }
} 70 70 }
return true; 71 71 return true;
}; 72 72 };
this.showLockedMessage = function(){ 73 73 this.showLockedMessage = function() {
Materialize.toast('You must verify your email address before continuing.' + 74 74 Materialize.toast('You must verify your email address before continuing.' +
'<a class="btn-flat cyan-text" onclick="rootscope.UserService.resendConfirmationEmail()">' + 75 75 '<a class="btn-flat cyan-text" onclick="rootscope.UserService.resendConfirmationEmail()">' +
'Resend Verification Email</a>', 4000); 76 76 'Resend Verification Email</a>', 4000);
} 77 77 };
this.noAuthRequired = function(state) { 78 78 this.noAuthRequired = function(state) {
if (['verifyemail'].indexOf(state.name) >= 0) { 79 79 if (['verifyemail'].indexOf(state.name) >= 0) {
return true; 80 80 return true;
} 81 81 }
return false; 82 82 return false;
}; 83 83 };
this.resendConfirmationEmail = function() { 84 84 this.resendConfirmationEmail = function() {
console.log('Requesting resend of confirmation email'); 85 85 console.log('Requesting resend of confirmation email');
$http.post('/api/resend_confirmation_email/').success(function() { 86 86 $http.post('/api/resend_confirmation_email/').success(function() {
Materialize.toast('Resent confirmation email! Check your spam folder too.', 4000); 87 87 Materialize.toast('Resent confirmation email! Check your spam folder too.', 4000);
}); 88 88 });
}; 89 89 };
}); 90 90 });
91 91