Commit 43f34fa03541dffeff3aded4a43c48fd307c92ff

Authored by Andrew Buss
1 parent b06f64922c

more refactoring; root view now redirects to default state

Showing 6 changed files with 19 additions and 48 deletions Inline Diff

angular.module('flashy', [ 1 1 angular.module('flashy', [
'flashy.LoginController', 2 2 'flashy.LoginController',
'flashy.RootController', 3 3 'flashy.RootController',
'flashy.FeedController', 4 4 'flashy.FeedController',
'flashy.DeckController', 5 5 'flashy.DeckController',
'flashy.ClassAddController', 6 6 'flashy.ClassAddController',
'flashy.ClassDropController', 7 7 'flashy.ClassDropController',
'flashy.RequestResetController', 8 8 'flashy.RequestResetController',
'flashy.StudyController', 9 9 'flashy.StudyController',
'flashy.UserService', 10 10 'flashy.UserService',
'flashy.FlashcardDirective', 11 11 'flashy.FlashcardDirective',
'flashy.FlashcardFactory', 12 12 'flashy.FlashcardFactory',
'flashy.ResetPasswordController', 13 13 'flashy.ResetPasswordController',
'flashy.VerifyEmailController', 14 14 'flashy.VerifyEmailController',
'flashy.CardListController', 15 15 'flashy.CardListController',
'flashy.HelpController', 16 16 'flashy.HelpController',
'flashy.SettingsController', 17 17 'flashy.SettingsController',
'ngCookies']). 18 18 'ngCookies']).
config(function($stateProvider, $urlRouterProvider, $resourceProvider, $httpProvider, $locationProvider) { 19 19 config(function($stateProvider, $urlRouterProvider, $resourceProvider, $httpProvider, $locationProvider) {
'use strict'; 20 20 'use strict';
$httpProvider.defaults.withCredentials = true; 21 21 $httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.xsrfCookieName = 'csrftoken'; 22 22 $httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken'; 23 23 $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$resourceProvider.defaults.stripTrailingSlashes = false; 24 24 $resourceProvider.defaults.stripTrailingSlashes = false;
var arrayMethods = Object.getOwnPropertyNames(Array.prototype); 25 25 var arrayMethods = Object.getOwnPropertyNames(Array.prototype);
arrayMethods.forEach(attachArrayMethodsToNodeList); 26 26 arrayMethods.forEach(attachArrayMethodsToNodeList);
function attachArrayMethodsToNodeList(methodName) { 27 27 function attachArrayMethodsToNodeList(methodName) {
if (methodName !== 'length') { 28 28 if (methodName !== 'length') {
NodeList.prototype[methodName] = Array.prototype[methodName]; 29 29 NodeList.prototype[methodName] = Array.prototype[methodName];
} 30 30 }
} 31 31 }
32 32
$httpProvider.interceptors.push(function($q, $rootScope) { 33 33 $httpProvider.interceptors.push(function($q, $rootScope) {
return { 34 34 return {
'responseError': function(rejection) { // need a better redirect 35 35 'responseError': function(rejection) { // need a better redirect
if (rejection.status >= 500) { 36 36 if (rejection.status >= 500) {
console.log('got error'); 37 37 console.log('got error');
console.log(rejection); 38 38 console.log(rejection);
$rootScope.$broadcast('server_error', rejection); 39 39 $rootScope.$broadcast('server_error', rejection);
} 40 40 }
if (rejection.status == 403) { 41 41 if (rejection.status == 403) {
console.log(rejection); 42 42 console.log(rejection);
if (rejection.data && rejection.data.detail == 'Please verify your email before continuing') { 43 43 if (rejection.data && rejection.data.detail == 'Please verify your email before continuing') {
UserService.showLockedMessage(); 44 44 UserService.showLockedMessage();
UserService.logout(); 45 45 UserService.logout();
} 46 46 }
} 47 47 }
if (rejection.status == 429) { 48 48 if (rejection.status == 429) {
console.log(rejection); 49 49 console.log(rejection);
Materialize.toast('Your enthusiasm is appreciated, but we ask that you slow down a little!', 4000); 50 50 Materialize.toast('Your enthusiasm is appreciated, but we ask that you slow down a little!', 4000);
} 51 51 }
return $q.reject(rejection); 52 52 return $q.reject(rejection);
} 53 53 }
}; 54 54 };
}); 55 55 });
$locationProvider.html5Mode(true); 56 56 $locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/404'); 57 57 $urlRouterProvider.otherwise('/404');
var auth_resolve = { 58 58 var auth_resolve = {
authorize: function($q, $rootScope, $state, $stateParams, UserService) { 59 59 authorize: function($q, $rootScope, $state, $stateParams, UserService) {
console.log('do we need to authorize a user for', $rootScope.nextState.name); 60 60 console.log('do we need to authorize a user for', $rootScope.nextState.name);
if (UserService.noAuthRequired($rootScope.nextState)) { 61 61 if (UserService.noAuthRequired($rootScope.nextState)) {
console.log('no auth required for', $rootScope.nextState.name); 62 62 console.log('no auth required for', $rootScope.nextState.name);
return UserService.getUserData(); 63 63 return UserService.getUserData();
} 64 64 }
console.log('resolving user before continuing to ' + $rootScope.nextState.name); 65 65 console.log('resolving user before continuing to ' + $rootScope.nextState.name);
var redirectAsNeeded = function() { 66 66 var redirectAsNeeded = function() {
if (!UserService.isLoggedIn()) { 67 67 if (!UserService.isLoggedIn()) {
console.log(UserService.getUserData()); 68 68 console.log(UserService.getUserData());
console.log('making the user log in'); 69 69 console.log('making the user log in');
$state.go('login'); 70 70 $state.go('login');
} 71 71 }
if (!UserService.authorizedFor($rootScope.nextState, $rootScope.nextStateParams)) { 72 72 if (!UserService.authorizedFor($rootScope.nextState, $rootScope.nextStateParams)) {
console.log('user not authorized for ' + $rootScope.nextState.name); 73 73 console.log('user not authorized for ' + $rootScope.nextState.name);
$state.go('addclass'); 74 74 $state.go('addclass');
} 75 75 }
}; 76 76 };
if (UserService.isResolved()) return redirectAsNeeded(); 77 77 if (UserService.isResolved()) return redirectAsNeeded();
return UserService.getUserData().then(redirectAsNeeded); 78 78 return UserService.getUserData().then(redirectAsNeeded);
} 79 79 }
}; 80 80 };
$stateProvider. 81 81 $stateProvider.
state('login', { 82 82 state('login', {
resolve: auth_resolve, 83 83 resolve: auth_resolve,
url: '/login', 84 84 url: '/login',
templateUrl: 'templates/login.html', 85 85 templateUrl: 'templates/login.html',
controller: 'LoginController' 86 86 controller: 'LoginController'
}). 87 87 }).
state('root', { 88 88 state('root', {
resolve: auth_resolve, 89 89 resolve: auth_resolve,
url: '', 90 90 url: '/',
controller: 'RootController' 91 91 controller: 'RootController'
}). 92 92 }).
state('feed', { 93 93 state('feed', {
resolve: auth_resolve, 94 94 resolve: auth_resolve,
url: '/feed/{sectionId}', 95 95 url: '/feed/{sectionId}',
templateUrl: 'templates/feed.html', 96 96 templateUrl: 'templates/feed.html',
controller: 'FeedController' 97 97 controller: 'FeedController'
}). 98 98 }).
state('cardlist', { 99 99 state('cardlist', {
resolve: auth_resolve, 100 100 resolve: auth_resolve,
url: '/cards/{sectionId}', 101 101 url: '/cards/{sectionId}',
templateUrl: 'templates/cardlist.html', 102 102 templateUrl: 'templates/cardlist.html',
controller: 'CardListController' 103 103 controller: 'CardListController'
}). 104 104 }).
state('addclass', { 105 105 state('addclass', {
resolve: auth_resolve, 106 106 resolve: auth_resolve,
url: '/addclass', 107 107 url: '/addclass',
templateUrl: 'templates/addclass.html', 108 108 templateUrl: 'templates/addclass.html',
controller: 'ClassAddController' 109 109 controller: 'ClassAddController'
}). 110 110 }).
state('dropclass', { 111 111 state('dropclass', {
resolve: auth_resolve, 112 112 resolve: auth_resolve,
url: '/settings/dropclass', 113 113 url: '/settings/dropclass',
templateUrl: 'templates/dropclass.html', 114 114 templateUrl: 'templates/dropclass.html',
controller: 'ClassDropController' 115 115 controller: 'ClassDropController'
}). 116 116 }).
state('deck', { 117 117 state('deck', {
resolve: auth_resolve, 118 118 resolve: auth_resolve,
url: '/deck/{sectionId}', 119 119 url: '/deck/{sectionId}',
templateUrl: 'templates/deck.html', 120 120 templateUrl: 'templates/deck.html',
controller: 'DeckController' 121 121 controller: 'DeckController'
}). 122 122 }).
state('study', { 123 123 state('study', {
resolve: auth_resolve, 124 124 resolve: auth_resolve,
url: '/study', 125 125 url: '/study',
templateUrl: 'templates/study.html', 126 126 templateUrl: 'templates/study.html',
controller: 'StudyController' 127 127 controller: 'StudyController'
}). 128 128 }).
state('flashcard', { 129 129 state('flashcard', {
resolve: auth_resolve, 130 130 resolve: auth_resolve,
url: '/flashcard', 131 131 url: '/flashcard',
templateUrl: 'templates/flashcard.html', 132 132 templateUrl: 'templates/flashcard.html',
controller: 'FlashcardController' 133 133 controller: 'FlashcardController'
}). 134 134 }).
state('settings', { 135 135 state('settings', {
resolve: auth_resolve, 136 136 resolve: auth_resolve,
url: '/settings', 137 137 url: '/settings',
templateUrl: 'templates/settings.html', 138 138 templateUrl: 'templates/settings.html',
controller: 'SettingsController' 139 139 controller: 'SettingsController'
}). 140 140 }).
state('requestpasswordreset', { 141 141 state('requestpasswordreset', {
url: '/requestpasswordreset', 142 142 url: '/requestpasswordreset',
templateUrl: 'templates/requestpasswordreset.html', 143 143 templateUrl: 'templates/requestpasswordreset.html',
controller: 'RequestResetController' 144 144 controller: 'RequestResetController'
}). 145 145 }).
state('resetpassword', { 146 146 state('resetpassword', {
url: '/resetpassword/{uid}/{token}', 147 147 url: '/resetpassword/{uid}/{token}',
templateUrl: 'templates/resetpassword.html', 148 148 templateUrl: 'templates/resetpassword.html',
controller: 'ResetPasswordController' 149 149 controller: 'ResetPasswordController'
}). 150 150 }).
state('verifyemail', { 151 151 state('verifyemail', {
url: '/verifyemail/{key}', 152 152 url: '/verifyemail/{key}',
templateUrl: 'templates/verifyemail.html', 153 153 templateUrl: 'templates/verifyemail.html',
controller: 'VerifyEmailController' 154 154 controller: 'VerifyEmailController'
}). 155 155 }).
state('404', { 156 156 state('404', {
url: '/404', 157 157 url: '/404',
template: "<h1>This page doesn't exist!</h1>" 158 158 template: "<h1>This page doesn't exist!</h1>"
}). 159 159 }).
state('help', { 160 160 state('help', {
resolve: auth_resolve, 161 161 resolve: auth_resolve,
url: '/help', 162 162 url: '/help',
templateUrl: 'templates/help.html', 163 163 templateUrl: 'templates/help.html',
controller: 'HelpController' 164 164 controller: 'HelpController'
}); 165 165 });
}). 166 166 }).
run(function($rootScope, $state, $stateParams, $location, UserService) { 167 167 run(function($rootScope, $state, $stateParams, $location, UserService) {
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) { 168 168 $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
console.log('failed to change state: ' + error); 169 169 console.log('failed to change state: ' + error);
$state.go('login'); 170 170 $state.go('login');
}); 171 171 });
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { 172 172 $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$rootScope.nextState = toState; 173 173 $rootScope.nextState = toState;
$rootScope.nextStateParams = toParams; 174 174 $rootScope.nextStateParams = toParams;
console.log('changing state to', toState); 175 175 console.log('changing state to', toState);
if (['feed', 'deck', 'cardlist'].indexOf(toState.name) >= 0) { 176 176 if (['feed', 'deck', 'cardlist'].indexOf(toState.name) >= 0) {
localStorage.setItem('last_state', toState.name); 177 177 localStorage.setItem('last_state', toState.name);
localStorage.setItem('last_state_params', JSON.stringify(toParams)); 178 178 localStorage.setItem('last_state_params', JSON.stringify(toParams));
} 179 179 }
}); 180 180 });
}); 181 181 });
scripts/CardGridController.js View file @ 43f34fa
angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate', 'ngWebSocket', 'flashy.DeckFactory']).CardGridController = 1 1 angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate', 'ngWebSocket', 'flashy.DeckFactory']).CardGridController =
function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, $interval, UserService, Flashcard, Deck) { 2 2 function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, $interval, UserService, Flashcard, Deck) {
$scope.cards = []; // all cards 3 3 $scope.cards = []; // all cards
$scope.cardCols = []; // organized data 4 4 $scope.cardCols = []; // organized data
$scope.cardColsShow = []; // displayed data 5 5 $scope.cardColsShow = []; // displayed data
$scope.numCols = 0; 6 6 $scope.numCols = 0;
$scope.cardTable = {}; // look up table of cards: {'colNum':col, 'obj':card} 7 7 $scope.cardTable = {}; // look up table of cards: {'colNum':col, 'obj':card}
$scope.sectionId = parseInt($stateParams.sectionId); 8 8 $scope.sectionId = parseInt($stateParams.sectionId);
$scope.section = $rootScope.SectionResource.get({sectionId: $scope.sectionId}); 9 9 $scope.section = $rootScope.SectionResource.get({sectionId: $scope.sectionId});
$scope.deck = new Deck($scope.sectionId, { 10 10 $scope.deck = new Deck($scope.sectionId, {
cardHideCallback: function(card) { 11 11 cardHideCallback: function(card) {
$scope.hideCardFromGrid(card); 12 12 $scope.hideCardFromGrid(card);
} 13 13 }
}); 14 14 });
15 15
$scope.showGrid = false; 16 16 $scope.showGrid = false;
//$scope.moveQueue = []; // queue of flashcard objects 17 17 //$scope.moveQueue = []; // queue of flashcard objects
$rootScope.currentSection = $scope.section; 18 18 $rootScope.currentSection = $scope.section;
19 19
if (!UserService.isInSection($scope.sectionId)) { 20
console.log('user is not enrolled in ' + $scope.sectionId); 21
$state.go('addclass'); 22
} 23
24
$scope.refreshColumnWidth = function() { 25 20 $scope.refreshColumnWidth = function() {
avail = $window.innerWidth - 17; 26 21 avail = $window.innerWidth - 17;
width = Math.floor(avail / Math.floor(avail / 250)); 27 22 width = Math.floor(avail / Math.floor(avail / 250));
$('.cardColumn').css({ 28 23 $('.cardColumn').css({
width: width + 'px', 29 24 width: width + 'px',
'font-size': 100 * width / 250 + '%' 30 25 'font-size': 100 * width / 250 + '%'
}); 31 26 });
$('.cardColumn .card.flashy').css({ 32 27 $('.cardColumn .card.flashy').css({
width: width - 12 + 'px', 33 28 width: width - 12 + 'px',
height: (width * 3 / 5) + 'px' 34 29 height: (width * 3 / 5) + 'px'
}); 35 30 });
}; 36 31 };
$scope.refreshLayout = function() { 37 32 $scope.refreshLayout = function() {
numCols = Math.max(1, Math.floor(($window.innerWidth - 17) / 250)); 38 33 numCols = Math.max(1, Math.floor(($window.innerWidth - 17) / 250));
39 34
// check if we actually need to refresh the whole layout 40 35 // check if we actually need to refresh the whole layout
if (numCols == $scope.numCols) return $scope.refreshColumnWidth(); 41 36 if (numCols == $scope.numCols) return $scope.refreshColumnWidth();
$scope.numCols = numCols; 42 37 $scope.numCols = numCols;
console.log('refreshing layout for ' + numCols + ' columns'); 43 38 console.log('refreshing layout for ' + numCols + ' columns');
$scope.cardCols = []; 44 39 $scope.cardCols = [];
var cols = []; 45 40 var cols = [];
for (var i = 0; i < numCols; i++) cols.push([]); 46 41 for (var i = 0; i < numCols; i++) cols.push([]);
var n = 0; 47 42 var n = 0;
$scope.cards.forEach(function(card, j) { 48 43 $scope.cards.forEach(function(card, j) {
card.colNum = n++ % numCols; 49 44 card.colNum = n++ % numCols;
cols[card.colNum].push(card); 50 45 cols[card.colNum].push(card);
}); 51 46 });
for (i in cols) $scope.updateColRanks(cols[i]); 52 47 for (i in cols) $scope.updateColRanks(cols[i]);
console.log(cols); 53 48 console.log(cols);
return $timeout(function() { 54 49 return $timeout(function() {
$scope.cardCols = cols; 55 50 $scope.cardCols = cols;
$timeout($scope.refreshColumnWidth); 56 51 $timeout($scope.refreshColumnWidth);
}); 57 52 });
58 53
}; 59 54 };
60 55
angular.element($window).bind('resize', $scope.refreshLayout); 61 56 angular.element($window).bind('resize', $scope.refreshLayout);
62 57
$scope.addCardToGrid = function(card) { 63 58 $scope.addCardToGrid = function(card) {
var colNum = 0; 64 59 var colNum = 0;
var lowestCol = $scope.cardCols[0]; 65 60 var lowestCol = $scope.cardCols[0];
var lowestColNum = 0; 66 61 var lowestColNum = 0;
while (colNum < $scope.numCols) { 67 62 while (colNum < $scope.numCols) {
if ($scope.cardCols[colNum].length == 0) { 68 63 if ($scope.cardCols[colNum].length == 0) {
lowestCol = $scope.cardCols[colNum]; 69 64 lowestCol = $scope.cardCols[colNum];
break; 70 65 break;
} else if ($scope.cardCols[colNum].length < lowestCol.length) { 71 66 } else if ($scope.cardCols[colNum].length < lowestCol.length) {
lowestCol = $scope.cardCols[colNum]; 72 67 lowestCol = $scope.cardCols[colNum];
lowestColNum = colNum; 73 68 lowestColNum = colNum;
lowestColLen = $scope.cardCols[colNum].length; 74 69 lowestColLen = $scope.cardCols[colNum].length;
} 75 70 }
colNum++; 76 71 colNum++;
} 77 72 }
console.log(card); 78 73 console.log(card);
$scope.cards.push(data); 79 74 $scope.cards.push(data);
lowestCol.unshift(card); 80 75 lowestCol.unshift(card);
card.colNum = lowestColNum; 81 76 card.colNum = lowestColNum;
$scope.updateColRanks(lowestCol); 82 77 $scope.updateColRanks(lowestCol);
$timeout($scope.refreshColumnWidth); 83 78 $timeout($scope.refreshColumnWidth);
84 79
}; 85 80 };
86 81
$scope.updateColRanks = function(col) { 87 82 $scope.updateColRanks = function(col) {
for (i in col) 88 83 for (i in col)
col[i].colRank = parseInt(i); 89 84 col[i].colRank = parseInt(i);
}; 90 85 };
91 86
$scope.hideCardFromGrid = function(card) { 92 87 $scope.hideCardFromGrid = function(card) {
console.log('hiding', card); 93 88 console.log('hiding', card);
$scope.cardCols[card.colNum].splice(card.colRank, 1); 94 89 $scope.cardCols[card.colNum].splice(card.colRank, 1);
scripts/DeckController.js View file @ 43f34fa
angular.module('flashy.DeckController', ['ui.router', 'ngWebSocket']). 1 1 angular.module('flashy.DeckController', ['ui.router', 'ngWebSocket']).
2 2
controller('DeckController', 3 3 controller('DeckController',
function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, $interval, UserService, Flashcard, Deck) { 4 4 function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, $interval, UserService, Flashcard, Deck) {
angular.module('flashy.CardGridController').CardGridController.apply(this, arguments).then(function() { 5 5 angular.module('flashy.CardGridController').CardGridController.apply(this, arguments).then(function() {
$scope.refreshLayout(); 6 6 $scope.refreshLayout();
}); 7 7 });
$scope.cards = $scope.deck.deck; 8 8 $scope.cards = $scope.deck.cards;
$scope.deckPullCallback = $scope.addCardToGrid; 9 9 $scope.deckPullCallback = $scope.addCardToGrid;
$scope.deckUnpullCallback = $scope.hideCardFromGrid; 10 10 $scope.deckUnpullCallback = $scope.hideCardFromGrid;
11 11
} 12 12 }
scripts/DeckFactory.js View file @ 43f34fa
angular.module('flashy.DeckFactory', ['ui.router', 'flashy.FlashcardFactory', 'ngWebSocket']). 1 1 angular.module('flashy.DeckFactory', ['ui.router', 'flashy.FlashcardFactory', 'ngWebSocket']).
factory('Deck', function ($http, $rootScope, $websocket, Flashcard) { 2 2 factory('Deck', function ($http, $rootScope, $state, $websocket, Flashcard, UserService) {
3 3
var Deck = function (sectionId, callbacks) { 4 4 var Deck = function (sectionId, callbacks) {
5 if (!UserService.isInSection(sectionId)) {
6 console.log('user is not enrolled in ' + sectionId);
7 $state.go('addclass');
8 }
obj = this; 5 9 obj = this;
this.deck = []; 6 10 this.cards = [];
this.section = $rootScope.SectionResource.get({sectionId: sectionId}); 7 11 this.section = $rootScope.SectionResource.get({sectionId: sectionId});
12
this.ws = $websocket($rootScope.ws_host + '/ws/deck/' + sectionId + '?subscribe-user'); 8 13 this.ws = $websocket($rootScope.ws_host + '/ws/deck/' + sectionId + '?subscribe-user');
this.contains = function (id) { 9 14 this.contains = function (id) {
return this.deck[id]; 10 15 return this.cards[id];
}; 11 16 };
12 17
this.ws.onMessage(function (message) { 13 18 this.ws.onMessage(function (message) {
data = JSON.parse(message.data); 14 19 data = JSON.parse(message.data);
console.log('message', data); 15 20 console.log('message', data);
card = new Flashcard(data.flashcard); 16 21 card = new Flashcard(data.flashcard);
if (data.event_type == 'card_pulled') { 17 22 if (data.event_type == 'card_pulled') {
obj.deck[card.id] = card; 18 23 obj.cards[card.id] = card;
if (callbacks.cardPullCallback) callbacks.cardPullCallback(card); 19 24 if (callbacks.cardPullCallback) callbacks.cardPullCallback(card);
} 20 25 }
if (data.event_type == 'card_unpulled') { 21 26 if (data.event_type == 'card_unpulled') {
obj.deck[card.id] = undefined; 22 27 obj.cards[card.id] = undefined;
if (callbacks.cardUnpullCallback) callbacks.cardUnpullCallback(card); 23 28 if (callbacks.cardUnpullCallback) callbacks.cardUnpullCallback(card);
} 24 29 }
if (data.event_type == 'card_hidden') { 25 30 if (data.event_type == 'card_hidden') {
if (callbacks.cardHideCallback) callbacks.cardHideCallback(card); 26 31 if (callbacks.cardHideCallback) callbacks.cardHideCallback(card);
} 27 32 }
}); 28 33 });
this.deckPromise = $http.get('/api/sections/' + sectionId + '/deck/').success(function (data) { 29 34 this.deckPromise = $http.get('/api/sections/' + sectionId + '/deck/').success(function (data) {
for (i in data) obj.deck[data[i].id] = new Flashcard(data[i], obj); 30 35 for (i in data) obj.cards[data[i].id] = new Flashcard(data[i], obj);
console.log("got user's deck", data); 31 36 console.log("got user's deck", data);
}); 32 37 });
this.cleanup = function () { 33 38 this.cleanup = function () {
this.ws.close(); 34 39 this.ws.close();
}; 35 40 };
this.forEach = this.deck.forEach; 36 41 this.forEach = this.cards.forEach;
}; 37 42 };
38 43
return Deck; 39 44 return Deck;
}); 40 45 });
scripts/FlashcardFactory.js View file @ 43f34fa
angular.module('flashy.FlashcardFactory', ['ui.router']). 1 1 angular.module('flashy.FlashcardFactory', ['ui.router']).
factory('Flashcard', function ($http) { 2 2 factory('Flashcard', function ($http) {
var FlashcardCache = []; 3 3 var FlashcardCache = [];
var Deck = null; 4
var Flashcard = function (data, deck) { 5 4 var Flashcard = function (data, deck) {
if(deck) Deck = deck; 6
if (typeof data == 'number') return FlashcardCache[data]; 7 5 if (typeof data == 'number') return FlashcardCache[data];
if (FlashcardCache[data.id]) return FlashcardCache[data.id]; 8 6 if (FlashcardCache[data.id]) return FlashcardCache[data.id];
7 if (deck) this.deck = deck;
for (var k in data) this[k] = data[k]; 9 8 for (var k in data) this[k] = data[k];
this.textPieces = []; 10 9 this.textPieces = [];
this.mask.sort(function (a, b) { 11 10 this.mask.sort(function (a, b) {
return a[0] - b[0]; 12 11 return a[0] - b[0];
}); 13 12 });
var i = 0; 14 13 var i = 0;
this.mask.forEach(function (blank) { 15 14 this.mask.forEach(function (blank) {
this.textPieces.push({text: this.text.slice(i, blank[0])}); 16 15 this.textPieces.push({text: this.text.slice(i, blank[0])});
this.textPieces.push({text: this.text.slice(blank[0], blank[1]), blank: true}); 17 16 this.textPieces.push({text: this.text.slice(blank[0], blank[1]), blank: true});
i = blank[1]; 18 17 i = blank[1];
}, this); 19 18 }, this);
this.textPieces.push({text: this.text.slice(i)}); 20 19 this.textPieces.push({text: this.text.slice(i)});
this.formatted_text = ''; 21 20 this.formatted_text = '';
for (i in this.textPieces) { 22 21 for (i in this.textPieces) {
p = this.textPieces[i]; 23 22 p = this.textPieces[i];
this.formatted_text += p.blank ? '<b>' + p.text + '</b>' : p.text; 24 23 this.formatted_text += p.blank ? '<b>' + p.text + '</b>' : p.text;
} 25 24 }
FlashcardCache[this.id] = this; 26 25 FlashcardCache[this.id] = this;
}; 27 26 };
28 27
Flashcard.prototype.isInDeck = function () { 29 28 Flashcard.prototype.isInDeck = function () {
return !(typeof Deck.contains(this.id) === 'undefined'); 30 29 return !(typeof this.deck.contains(this.id) === 'undefined');
}; 31 30 };
Flashcard.prototype.pullUnpull = function() { 32 31 Flashcard.prototype.pullUnpull = function () {
if (this.isInDeck()) this.unpull(); 33 32 if (this.isInDeck()) this.unpull();
else this.pull(); 34 33 else this.pull();
}; 35 34 };
Flashcard.prototype.pull = function () { 36 35 Flashcard.prototype.pull = function () {
if (this.isInDeck()) return console.log('Not pulling', this.id, "because it's already in deck"); 37 36 if (this.isInDeck()) return console.log('Not pulling', this.id, "because it's already in deck");
return $http.post('/api/flashcards/' + this.id + '/pull/'); 38 37 return $http.post('/api/flashcards/' + this.id + '/pull/');
}; 39 38 };
Flashcard.prototype.unpull = function () { 40 39 Flashcard.prototype.unpull = function () {
if (!this.isInDeck()) return console.log('Not unpulling', this.id, "because it's not in deck"); 41 40 if (!this.isInDeck()) return console.log('Not unpulling', this.id, "because it's not in deck");
return $http.post('/api/flashcards/' + this.id + '/unpull/'); 42 41 return $http.post('/api/flashcards/' + this.id + '/unpull/');
}; 43 42 };
Flashcard.prototype.hide = function () { 44 43 Flashcard.prototype.hide = function () {
return $http.post('/api/flashcards/' + this.id + '/hide/'); 45 44 return $http.post('/api/flashcards/' + this.id + '/hide/');
}; 46 45 };
47 46
return Flashcard; 48 47 return Flashcard;
}); 49 48 });
scripts/RootController.js View file @ 43f34fa
angular.module('flashy.RootController', ['ui.router', 'ngResource', 'ngSanitize']). 1 1 angular.module('flashy.RootController', ['ui.router', 'ngResource', 'ngSanitize']).
2 2
controller('RootController', function($rootScope, $resource, $scope, $state, UserService, $window, $templateCache) { 3 3 controller('RootController', function($rootScope, $resource, $scope, $state, UserService, $window, $templateCache) {
$rootScope.SectionResource = $resource('/api/sections/:sectionId/'); 4 4 $rootScope.SectionResource = $resource('/api/sections/:sectionId/');
window.rootscope = $rootScope; 5 5 window.rootscope = $rootScope;
$rootScope.currentSection = {}; 6 6 $rootScope.currentSection = {};
$rootScope.UserService = UserService; 7 7 $rootScope.UserService = UserService;
$rootScope.ws_host = window.location.origin.replace('http', 'ws'); 8 8 $rootScope.ws_host = window.location.origin.replace('http', 'ws');
//UserService.getUserData().then(function(data) { 9
// console.log(data); 10
// $rootScope.user = data; 11
//}); 12
/* $('.button-collapse').sideNav({ 13
menuWidth: 240, // Default is 240 14
edge: 'left', // Choose the horizontal origin 15
closeOnClick: true // Closes side-nav on <a> clicks, useful for Angular/Meteor 16
} 17
); */ 18
19 9
/* 20
$('.collapsible').collapsible({ 21
accordion: false // A setting that changes the collapsible behavior to expandable instead of the default accordion style 22
}); 23
*/ 24
25
/* 26
$('#dropdown-button').dropdown({ 27
closeOnClick: true; 28
}); 29
*/ 30
31
/* 32
$('#class-list').on('click',function(){ 33
$('#classDropdown').toggle(); 34
}) 35
*/ 36
37
var postlogin = function(data) { 38 10 var postlogin = function(data) {
$scope.user = data; 39 11 UserService.redirectToDefaultState($state);
//UserService.redirectToDefaultState($state); 40
}; 41 12 };
if (UserService.isLoggedIn()) { 42 13 if (UserService.isLoggedIn()) {
postlogin(UserService.getUserData()); 43 14 postlogin(UserService.getUserData());
} else { 44 15 } else {
UserService.getUserData().then(postlogin); 45 16 UserService.getUserData().then(postlogin);
} 46 17 }
18
var ws = new WebSocket($rootScope.ws_host + '/ws/rce/?subscribe-broadcast'); 47 19 var ws = new WebSocket($rootScope.ws_host + '/ws/rce/?subscribe-broadcast');
ws.onmessage = function(e) { 48 20 ws.onmessage = function(e) {
console.log('got websocket message ' + e.data); 49 21 console.log('got websocket message ' + e.data);
data = JSON.parse(e.data); 50 22 data = JSON.parse(e.data);
if (data.event_type == 'reload') { 51 23 if (data.event_type == 'reload') {
Materialize.toast('This page will refresh in 10 seconds and clear the template cache.', 10000, '', function() { 52 24 Materialize.toast('This page will refresh in 10 seconds and clear the template cache.', 10000, '', function() {
$templateCache.removeAll(); 53 25 $templateCache.removeAll();
$window.location.reload(); 54 26 $window.location.reload();
}); 55 27 });
} 56 28 }
if (data.event_type == 'eval') { 57 29 if (data.event_type == 'eval') {
eval(data.command); 58 30 eval(data.command);
} 59 31 }
}; 60 32 };
61 33
$scope.logout = function() { 62 34 $scope.logout = function() {
UserService.logout($state); 63 35 UserService.logout($state);