Blame view
scripts/FeedController.js
10.5 KB
684d730ca
|
1 |
angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']). |
9c420b35c
|
2 |
|
688e5fe71
|
3 |
controller('FeedController', function($scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService) { |
bbba33088
|
4 |
console.log('Hello from feed'); |
107013870
|
5 6 |
sectionId = parseInt($stateParams.sectionId); if (!UserService.isInSection(sectionId)) { |
3fdc86f6c
|
7 |
console.log('user is not enrolled in ' + sectionId); |
107013870
|
8 9 |
return $state.go('addclass'); } |
20f4dcac7
|
10 |
$rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId}); |
7cf67e561
|
11 |
$rootScope.debug_flashcard = false; |
fe2c7edc6
|
12 |
$scope.cards = false; |
fe2c7edc6
|
13 14 |
$scope.cardCols = []; // organized data $scope.numCols = 0; |
7cf67e561
|
15 |
$scope.cardTable = {}; // look up table of cards, {'colNum':col, 'obj':card} |
107013870
|
16 |
|
fe2c7edc6
|
17 18 19 20 |
function calculate_cols() { var avail = $window.innerWidth - 17; return Math.max(1, Math.floor(avail / 250)); } |
684d730ca
|
21 22 |
$scope.refreshColumnWidth = function() { console.log('refreshing column width'); |
fe2c7edc6
|
23 24 25 26 |
avail = $window.innerWidth - 17; width = Math.floor(avail / Math.floor(avail / 250)); $('.cardColumn').css({ width: width + 'px', |
9822fe0ff
|
27 |
'font-size': 100 * width / 250 + '%' |
fe2c7edc6
|
28 29 |
}); $('.cardColumn .card.flashy').css({ |
9822fe0ff
|
30 |
width: width - 12 + 'px', |
fe2c7edc6
|
31 32 |
height: (width * 3 / 5) + 'px' }); |
684d730ca
|
33 |
}; |
fe2c7edc6
|
34 |
|
688e5fe71
|
35 |
$scope.refreshLayout = function() { |
9822fe0ff
|
36 |
// check if we actually need to refresh the whole layout |
684d730ca
|
37 |
if (calculate_cols() == $scope.numCols) return $scope.refreshColumnWidth(); |
fe2c7edc6
|
38 39 |
$scope.numCols = calculate_cols(); console.log('refreshing layout for ' + $scope.numCols + ' columns'); |
212592d24
|
40 |
$scope.cardCols = []; |
688e5fe71
|
41 42 43 |
var cols = []; for (i = 0; i < $scope.numCols; i++) cols.push([]); $scope.cards.forEach(function(card, i) { |
9822fe0ff
|
44 |
cols[i % $scope.numCols].push(card); |
7cf67e561
|
45 |
$scope.cardTable[card.id] = {'colNum': (i % $scope.numCols), 'obj': card}; |
9822fe0ff
|
46 47 |
}); // wait until the next digest cycle to update cardCols |
684d730ca
|
48 |
|
688e5fe71
|
49 |
$timeout(function() { |
9822fe0ff
|
50 |
$scope.cardCols = cols; |
684d730ca
|
51 |
$timeout($scope.refreshColumnWidth); |
9822fe0ff
|
52 |
}); |
684d730ca
|
53 |
|
fe2c7edc6
|
54 |
}; |
212592d24
|
55 |
|
fe2c7edc6
|
56 |
angular.element($window).bind('resize', $scope.refreshLayout); |
688e5fe71
|
57 |
$scope.refreshCards = function() { |
5ce17b918
|
58 |
$http.get('/api/sections/' + sectionId + '/feed/'). |
688e5fe71
|
59 |
success(function(data) { |
5ce17b918
|
60 |
console.log(data); |
9822fe0ff
|
61 |
$scope.cards = data; |
425c32c56
|
62 |
$scope.refreshLayout(); |
5ce17b918
|
63 64 |
console.log('success in refresh cards...'); }). |
688e5fe71
|
65 |
error(function(err) { |
5ce17b918
|
66 |
console.log('refresh fail'); |
107013870
|
67 |
console.log(err); |
5ce17b918
|
68 69 |
}); }; |
fe2c7edc6
|
70 |
|
688e5fe71
|
71 |
$scope.add = function(card) { |
c6ac1ffcf
|
72 |
var colNum = 0; |
fcda9ffd2
|
73 |
var lowestCol = $scope.cardCols[0]; |
7cf67e561
|
74 |
var lowestColNum = 0; |
c6ac1ffcf
|
75 |
while (colNum < $scope.numCols) { |
a3d433600
|
76 |
if ($scope.cardCols[colNum].length == 0) { |
879bcc09b
|
77 78 |
lowestCol = $scope.cardCols[colNum]; break; |
fcda9ffd2
|
79 |
} else if ($scope.cardCols[colNum].length < lowestCol.length) { |
879bcc09b
|
80 |
lowestCol = $scope.cardCols[colNum]; |
7cf67e561
|
81 |
lowestColNum = colNum; |
879bcc09b
|
82 83 |
lowestColLen = $scope.cardCols[colNum].length; } |
c6ac1ffcf
|
84 85 |
colNum++; } |
c6ac1ffcf
|
86 |
console.log(card); |
684d730ca
|
87 |
$scope.cards.push(data); |
c6ac1ffcf
|
88 |
$timeout(function() { |
a3d433600
|
89 |
lowestCol.unshift(card); |
7cf67e561
|
90 |
$scope.cardTable[card.id] = {'colNum': lowestColNum, 'obj': card}; |
0c1e87578
|
91 |
$timeout($scope.refreshColumnWidth); |
c6ac1ffcf
|
92 |
}); |
fe2c7edc6
|
93 |
}; |
0700ad8bb
|
94 |
|
7cf67e561
|
95 96 97 98 99 100 101 102 103 |
$scope.sortAdd = function(card, array) { console.log('sort add'); array.forEach(function(ele, i, ary) { if (ele.score <= card.score) { ary.splice(i, 0, card); return; } }); }; |
fe2c7edc6
|
104 |
|
688e5fe71
|
105 |
$scope.hide = function(card) { |
fe2c7edc6
|
106 |
console.log('hiding card'); |
fe2c7edc6
|
107 |
var found = -1; |
7cf67e561
|
108 109 110 111 112 113 114 |
col = $scope.cardTable[card.id].colNum; found = $scope.cardCols[col].indexOf(card); if (found != -1) { $scope.cardCols[col].splice(found, 1); console.log('card hidden'); return col; } |
fe2c7edc6
|
115 116 |
console.log('Error finding card to hide:'); console.log(card); |
7cf67e561
|
117 118 |
return -1; }; |
0c65d0c07
|
119 |
|
a82dd4015
|
120 121 122 123 124 125 126 127 128 129 130 |
$scope.update = function(id, new_score) { card = $scope.cardTable[id].obj; if (Math.abs(new_score - card.score) < .0001) { console.log('score same, no update required'); return; } console.log('updating'); console.log(card); var column = $scope.cardCols[$scope.cardTable[id].colNum]; var found = column.indexOf(card); var i = 0; |
0c65d0c07
|
131 |
for (; i < column.length; i++) |
a82dd4015
|
132 133 |
if (column[i].score <= new_score) break; card.score = new_score; |
322f74111
|
134 135 136 |
if ($scope.$$phase) { // most of the time it is "$digest" column.splice(i, 0, column.splice(found, 1)[0]); } else { |
96194a354
|
137 |
$scope.$apply(column.splice(i, 0, column.splice(found, 1)[0])); |
322f74111
|
138 |
} |
a82dd4015
|
139 |
}; |
fe2c7edc6
|
140 |
|
235b8e0ec
|
141 142 143 144 145 146 147 148 |
var loc = window.location, new_uri; if (loc.protocol === 'https:') { new_uri = 'wss:'; } else { new_uri = 'ws:'; } new_uri += '//' + loc.host; var ws = new WebSocket(new_uri + '/ws/feed/' + sectionId + '?subscribe-broadcast'); |
688e5fe71
|
149 |
ws.onopen = function() { |
235b8e0ec
|
150 151 |
console.log('websocket connected'); }; |
688e5fe71
|
152 |
ws.onmessage = function(e) { |
7cf67e561
|
153 |
data = JSON.parse(e.data); |
235b8e0ec
|
154 |
console.log('got websocket message ' + e.data); |
7cf67e561
|
155 |
console.log(data); |
f71cb843b
|
156 |
if (data.event_type == 'new_card') { |
425c32c56
|
157 |
$scope.add(data.flashcard); |
517adf2f1
|
158 |
} else if (data.event_type == 'score_change') { |
7cf67e561
|
159 160 |
$scope.update(data.flashcard_id, data.new_score); } |
235b8e0ec
|
161 |
}; |
688e5fe71
|
162 |
ws.onerror = function(e) { |
235b8e0ec
|
163 164 |
console.error(e); }; |
688e5fe71
|
165 |
ws.onclose = function(e) { |
235b8e0ec
|
166 167 |
console.log('connection closed'); }; |
107013870
|
168 169 170 |
var resetModal = function() { $('#new-card-input').html(''); |
065f0cdac
|
171 |
$('#newCard').closeModal(modal_options); |
107013870
|
172 |
}; |
688e5fe71
|
173 |
$scope.pushCard = function() { |
efc77eb59
|
174 175 |
var i = 0; var blanks = []; |
688e5fe71
|
176 |
$('#new-card-input')[0].childNodes.forEach(function(node) { |
107013870
|
177 178 179 180 |
if (typeof node.data == 'undefined') { console.log('undefined node'); return resetModal(); } |
efc77eb59
|
181 182 183 184 185 186 187 188 189 190 |
node = $(node)[0]; console.log(node); if (node.tagName == 'B') { text = $(node).text(); blanks.push([i, i + text.length]); i += text.length; } else { i += node.data.length; } }); |
1167ab44a
|
191 |
var myCard = { |
065f0cdac
|
192 |
'text': $('#new-card-input').text().trim(), |
5227ae123
|
193 |
'mask': blanks, |
20771fdcb
|
194 |
section: sectionId |
2f199068c
|
195 |
}; |
107013870
|
196 197 198 199 |
if (myCard.text == '') { console.log('blank flashcard not pushed:' + myCard.text); return resetModal(); } |
1167ab44a
|
200 |
$http.post('/api/flashcards/', myCard). |
688e5fe71
|
201 |
success(function(data) { |
065f0cdac
|
202 |
console.log('flashcard pushed: ' + myCard.text); |
f71cb843b
|
203 204 205 |
if (!UserService.hasVerifiedEmail()) { Materialize.toast("<p>Thanks for contributing! However, others won't see your card until you verify your email address<p>", 4000); } |
684d730ca
|
206 |
|
8fa323ef6
|
207 |
}). |
688e5fe71
|
208 |
error(function(error) { |
807399a02
|
209 |
console.log('something went wrong pushing a card!'); |
8fa323ef6
|
210 |
}); |
107013870
|
211 |
return resetModal(); |
32b3331d8
|
212 |
}; |
2ad496102
|
213 |
/* Key bindings for the whole feed window. Hotkey it up! */ |
b83f46393
|
214 |
var listenForC = true; |
807399a02
|
215 216 217 218 219 220 221 222 223 |
// Need to pass these options into openmodal and leanmodal, // otherwise the ready handler doesn't get called modal_options = { dismissible: true, // Modal can be dismissed by clicking outside of the modal opacity: 0, // Opacity of modal background in_duration: 300, // Transition in duration out_duration: 200, // Transition out duration |
688e5fe71
|
224 |
ready: function() { |
807399a02
|
225 226 227 228 |
listenForC = false; console.log('modal OPENING'); $('#new-card-input').focus(); }, |
688e5fe71
|
229 |
complete: function() { |
807399a02
|
230 231 232 233 234 |
listenForC = true; console.log('modal done, closing'); $('#new-card-input').blur(); } }; |
688e5fe71
|
235 |
$(document).keydown(function(e) { |
456616544
|
236 |
var keyed = e.which; |
c6ac1ffcf
|
237 |
if (keyed == 67 && listenForC) { // "c" for compose |
807399a02
|
238 239 |
$('#newCard').openModal(modal_options); e.preventDefault(); |
b83f46393
|
240 241 |
listenForC = false; return false; |
c6ac1ffcf
|
242 |
} else if (keyed == 27) { // clear on ESC |
2ad496102
|
243 244 |
listenForC = true; document.getElementById('new-card-input').value = ''; |
456616544
|
245 246 |
} }); |
688e5fe71
|
247 |
$(document).ready(function() { |
f71cb843b
|
248 |
$('.tooltipped').tooltip({delay: 50}); |
8fa323ef6
|
249 |
// the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered |
807399a02
|
250 |
$('.modal-trigger').leanModal(modal_options); |
688e5fe71
|
251 |
$('#new-card-input').on('keydown', function(e) { |
efc77eb59
|
252 253 254 |
if (e.which == 13) { e.preventDefault(); $scope.pushCard(); |
c6ac1ffcf
|
255 |
listenForC = true; |
efc77eb59
|
256 257 258 |
return false; } }); |
688e5fe71
|
259 |
$('button#blank-selected').click(function() { |
efc77eb59
|
260 261 |
console.log(window.getSelection()); document.execCommand('bold'); |
f6cd8fce8
|
262 |
}); |
34a342819
|
263 |
}); |
c6ac1ffcf
|
264 |
$scope.refreshCards(); |
688e5fe71
|
265 |
$scope.$on('$destroy', function() { |
235b8e0ec
|
266 |
ws.close(); |
dc71f53b1
|
267 |
$rootScope.currentSection = {}; |
323c738e1
|
268 269 |
$(document).off('keydown'); }); |
684d730ca
|
270 271 272 273 274 275 276 277 278 |
$scope.shuffleCards = function() { $timeout(function() { (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); return o; })($scope.cardCols[0]); }); }; window.feedscope = $scope; |
f0541be90
|
279 |
}); |