Commit 7545660bf6dc22fda2d7b125c3e08d671d1bd803
Exists in
master
and in
1 other branch
Merge branch 'master' of git.ucsd.edu:110swag/flashy-frontend
Showing 12 changed files Side-by-side Diff
config.js
View file @
7545660
... | ... | @@ -4,7 +4,6 @@ |
4 | 4 | 'flashy.FeedController', |
5 | 5 | 'flashy.DeckController', |
6 | 6 | 'flashy.ClassAddController', |
7 | - 'flashy.ClassDropController', | |
8 | 7 | 'flashy.RequestResetController', |
9 | 8 | 'flashy.StudyController', |
10 | 9 | 'flashy.UserService', |
... | ... | @@ -107,12 +106,6 @@ |
107 | 106 | url: '/addclass', |
108 | 107 | templateUrl: 'templates/addclass.html', |
109 | 108 | controller: 'ClassAddController' |
110 | - }). | |
111 | - state('dropclass', { | |
112 | - resolve: auth_resolve, | |
113 | - url: '/settings/dropclass', | |
114 | - templateUrl: 'templates/dropclass.html', | |
115 | - controller: 'ClassDropController' | |
116 | 109 | }). |
117 | 110 | state('deck', { |
118 | 111 | resolve: auth_resolve, |
home.html
View file @
7545660
... | ... | @@ -170,7 +170,6 @@ |
170 | 170 | <script src="scripts/DeckController.js"></script> |
171 | 171 | <script src="scripts/RequestResetController.js"></script> |
172 | 172 | <script src="scripts/ClassAddController.js"></script> |
173 | -<script src="scripts/ClassDropController.js"></script> | |
174 | 173 | <script src="scripts/StudyController.js"></script> |
175 | 174 | <script src="scripts/ResetPasswordController.js"></script> |
176 | 175 | <script src="scripts/CardListController.js"></script> |
scripts/CardGridController.js
View file @
7545660
1 | 1 | angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate', 'ngWebSocket', 'flashy.DeckFactory']).CardGridController = |
2 | 2 | function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, $interval, UserService, Flashcard, Deck) { |
3 | + sectionId = parseInt($stateParams.sectionId); | |
3 | 4 | $scope.cards = []; // all cards |
4 | 5 | $scope.cardCols = []; // organized data |
5 | 6 | $scope.cardColsShow = []; // displayed data |
6 | 7 | $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 | - $scope.deck = new Deck($scope.sectionId, { | |
8 | + $scope.section = $rootScope.SectionResource.get({sectionId: sectionId}); | |
9 | + $scope.deck = new Deck(sectionId, { | |
11 | 10 | cardHideCallback: function(card) { |
12 | 11 | $scope.hideCardFromGrid(card); |
13 | 12 | } |
... | ... | @@ -93,6 +92,7 @@ |
93 | 92 | |
94 | 93 | $scope.$on('$destroy', function() { |
95 | 94 | $scope.deck.cleanup(); |
95 | + Flashcard.cleanup(); | |
96 | 96 | $rootScope.currentSection = {}; |
97 | 97 | $(document).off('keydown'); |
98 | 98 | }); |
scripts/CardListController.js
View file @
7545660
1 | -angular.module('flashy.CardListController', ['ui.router', 'angular.filter', 'ngSanitize']). | |
2 | - controller('CardListController', function($scope, $rootScope, $state, $http, $stateParams, Flashcard) { | |
1 | +angular.module('flashy.CardListController', ['ui.router', 'angular.filter', 'ngSanitize', 'flashy.DeckFactory']). | |
2 | + controller('CardListController', function($scope, $rootScope, $state, $http, $stateParams, Flashcard, Deck) { | |
3 | 3 | // cards array |
4 | - sectionId = $stateParams.sectionId; | |
4 | + sectionId = parseInt($stateParams.sectionId); | |
5 | + $scope.deck = new Deck(sectionId, { | |
6 | + cardPullCallback: function(card) { | |
7 | + Materialize.toast('Pulled!', 3000); | |
8 | + }, | |
9 | + cardUnpullCallback: function(card) { | |
10 | + Materialize.toast('Unpulled!', 3000); | |
11 | + }, | |
12 | + cardHideCallback: function(card) { | |
13 | + card.is_hidden = true; | |
14 | + Materialize.toast('Hidden!', 3000); | |
15 | + }, | |
16 | + cardUnhideCallback: function(card) { | |
17 | + card.is_hidden = false; | |
18 | + Materialize.toast('Unhidden!', 3000); | |
19 | + } | |
20 | + }); | |
5 | 21 | $rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId}); |
6 | 22 | $scope.cards = []; |
7 | 23 | |
8 | 24 | $http.get('/api/sections/' + sectionId + '/flashcards/?hidden=yes'). |
9 | 25 | success(function(data) { |
10 | - for (i in data) $scope.cards[data[i].id] = new Flashcard(data[i], $scope.cards); | |
26 | + for (i in data) $scope.cards[data[i].id] = new Flashcard(data[i], $scope.deck); | |
11 | 27 | }). |
12 | 28 | error(function(err) { |
13 | 29 | console.log('pulling feed failed'); |
14 | 30 | }); |
15 | 31 | |
16 | - $scope.viewFeed = function() { | |
17 | - $state.go('feed', {sectionId: sectionId}); | |
18 | - console.log('go to feed'); | |
19 | - }; | |
20 | - | |
21 | - | |
22 | - // unhide card | |
23 | - $scope.unhide = function(card) { | |
24 | - $http.post('/api/flashcards/' + card.id + '/unhide/'). | |
25 | - success(function(data) { | |
26 | - console.log(card.text + ' unhidden'); | |
27 | - | |
28 | - // locally change hidden | |
29 | - card.is_hidden = false; | |
30 | - Materialize.toast('Unhidden', 3000, 'rounded'); | |
31 | - }). | |
32 | - error(function(err) { | |
33 | - console.log('no unhide for you'); | |
34 | - }); | |
35 | - }; | |
36 | - | |
37 | - // hide card | |
38 | - $scope.hide = function(card) { | |
39 | - $http.post('/api/flashcards/' + card.id + '/hide/'). | |
40 | - success(function(data) { | |
41 | - console.log(card.text + ' hidden'); | |
42 | - | |
43 | - // locally change hidden | |
44 | - card.is_hidden = true; | |
45 | - Materialize.toast('Hidden', 3000, 'rounded'); | |
46 | - }). | |
47 | - error(function(err) { | |
48 | - console.log('no hide for you'); | |
49 | - }); | |
50 | - }; | |
51 | - | |
52 | - // pull card | |
53 | - $scope.pull = function(card) { | |
54 | - $http.post('/api/flashcards/' + card.id + '/pull/'). | |
55 | - success(function(data) { | |
56 | - console.log(card.text + ' pulled'); | |
57 | - | |
58 | - // locally change boolean for display purposes | |
59 | - card.is_in_deck = true; | |
60 | - Materialize.toast('Added to Your Deck', 3000, 'rounded'); | |
61 | - }). | |
62 | - error(function(err) { | |
63 | - console.log('no pull for you'); | |
64 | - }); | |
65 | - }; | |
66 | - | |
67 | - // unpull card | |
68 | - $scope.unpull = function(card) { | |
69 | - $http.post('/api/flashcards/' + card.id + '/unpull/'). | |
70 | - success(function(data) { | |
71 | - console.log(card.text + ' unpulled'); | |
72 | - | |
73 | - // local change for display purposes | |
74 | - card.is_in_deck = false; | |
75 | - Materialize.toast('Removed from Your Deck', 3000, 'rounded'); | |
76 | - }). | |
77 | - error(function(err) { | |
78 | - console.log('no unpull for you'); | |
79 | - }); | |
80 | - }; | |
81 | - | |
82 | 32 | // flag/report card |
83 | 33 | $scope.flag = function(card) { |
84 | 34 | $http.post('/api/flashcards/' + card.id + '/report/'). |
85 | 35 | success(function(data) { |
86 | 36 | console.log(card.text + ' reported'); |
87 | - | |
88 | - // local change for display purposes | |
89 | - Materialize.toast('Card Flagged', 3000, 'rounded'); | |
90 | 37 | }). |
91 | 38 | error(function(err) { |
92 | 39 | console.log('no flag for you'); |
... | ... | @@ -161,6 +108,10 @@ |
161 | 108 | (week == 9 && $scope.filter['week9']) || |
162 | 109 | (week == 10 && $scope.filter['week10']); |
163 | 110 | }; |
111 | + $scope.$on('$destroy', function() { | |
112 | + $scope.deck.cleanup(); | |
113 | + Flashcard.cleanup(); | |
114 | + }); | |
164 | 115 | |
165 | 116 | } |
166 | 117 | ). |
scripts/ClassDropController.js
View file @
7545660
1 | -angular.module('flashy.ClassDropController', ['ui.router']). | |
2 | - controller('ClassDropController', function($rootScope, $resource, $scope, $state, $http, UserService) { | |
3 | - $scope.hi = 'hi'; | |
4 | - $rootScope.SectionResource = $resource('/api/sections/:sectionId/'); | |
5 | - $rootScope.currentSection = {}; | |
6 | - $rootScope.UserService = UserService; | |
7 | - | |
8 | - $scope.dropClass = function(section) { | |
9 | - $http.post('/api/sections/' + section.id + '/drop/'). | |
10 | - success(function(data) { | |
11 | - console.log(section.short_name + ' dropped'); | |
12 | - | |
13 | - Materialize.toast('Dropped', 3000, 'rounded'); | |
14 | - }). | |
15 | - error(function(err) { | |
16 | - console.log('no drop for you'); | |
17 | - }); | |
18 | - }; | |
19 | - | |
20 | - }); |
scripts/DeckFactory.js
View file @
7545660
... | ... | @@ -30,6 +30,9 @@ |
30 | 30 | if (data.event_type == 'card_hidden') { |
31 | 31 | if (callbacks.cardHideCallback) callbacks.cardHideCallback(card); |
32 | 32 | } |
33 | + if (data.event_type == 'card_unhidden') { | |
34 | + if (callbacks.cardUnhideCallback) callbacks.cardUnhideCallback(card); | |
35 | + } | |
33 | 36 | }); |
34 | 37 | this.deckPromise = $http.get('/api/sections/' + sectionId + '/deck/').success(function (data) { |
35 | 38 | for (i in data) obj.cards[data[i].id] = new Flashcard(data[i], obj); |
scripts/FeedController.js
View file @
7545660
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | $scope.updateColRanks($scope.cardCols[card.colNum]); |
27 | 27 | }; |
28 | 28 | |
29 | - $scope.feed_ws = $websocket($scope.ws_host + '/ws/feed/' + $scope.sectionId + '?subscribe-broadcast'); | |
29 | + $scope.feed_ws = $websocket($scope.ws_host + '/ws/feed/' + sectionId + '?subscribe-broadcast'); | |
30 | 30 | $scope.feed_ws.onMessage(function(e) { |
31 | 31 | data = JSON.parse(e.data); |
32 | 32 | console.log('message', data); |
... | ... | @@ -166,7 +166,7 @@ |
166 | 166 | $scope.$on('$destroy', function() { |
167 | 167 | $scope.feed_ws.close(); |
168 | 168 | }); |
169 | - return $http.get('/api/sections/' + $scope.sectionId + '/feed/'). | |
169 | + return $http.get('/api/sections/' + sectionId + '/feed/'). | |
170 | 170 | success(function(data) { |
171 | 171 | console.log(data); |
172 | 172 | $scope.cards = data.map(function(card) { |
scripts/FlashcardFactory.js
View file @
7545660
1 | 1 | angular.module('flashy.FlashcardFactory', ['ui.router']). |
2 | 2 | factory('Flashcard', function ($http) { |
3 | 3 | var FlashcardCache = []; |
4 | + var Deck = null; | |
4 | 5 | var Flashcard = function (data, deck) { |
5 | 6 | if (typeof data == 'number') return FlashcardCache[data]; |
6 | 7 | if (FlashcardCache[data.id]) return FlashcardCache[data.id]; |
7 | - if (deck) this.deck = deck; | |
8 | + if (!Deck && deck) Deck = deck; | |
8 | 9 | for (var k in data) this[k] = data[k]; |
9 | 10 | this.textPieces = []; |
10 | 11 | this.mask.sort(function (a, b) { |
... | ... | @@ -26,7 +27,7 @@ |
26 | 27 | }; |
27 | 28 | |
28 | 29 | Flashcard.prototype.isInDeck = function () { |
29 | - return !(typeof this.deck.contains(this.id) === 'undefined'); | |
30 | + return !(typeof Deck.contains(this.id) === 'undefined'); | |
30 | 31 | }; |
31 | 32 | Flashcard.prototype.pullUnpull = function () { |
32 | 33 | if (this.isInDeck()) this.unpull(); |
... | ... | @@ -42,6 +43,13 @@ |
42 | 43 | }; |
43 | 44 | Flashcard.prototype.hide = function () { |
44 | 45 | return $http.post('/api/flashcards/' + this.id + '/hide/'); |
46 | + }; | |
47 | + Flashcard.prototype.unhide = function () { | |
48 | + return $http.post('/api/flashcards/' + this.id + '/unhide/'); | |
49 | + }; | |
50 | + Flashcard.cleanup = function () { | |
51 | + Deck = null; | |
52 | + FlashcardCache = []; | |
45 | 53 | }; |
46 | 54 | |
47 | 55 | return Flashcard; |
scripts/SettingsController.js
View file @
7545660
1 | 1 | angular.module('flashy.SettingsController', ['ui.router']). |
2 | 2 | |
3 | - controller('SettingsController', function($scope, $http) { | |
4 | - $scope.changePassword = function(oldPassword, newPassword, confirmedNewPassword) { | |
3 | + controller('SettingsController', function($rootScope, $resource, $scope, $state, $http, UserService) { | |
4 | + $scope.error = false; | |
5 | + $scope.success = false; | |
6 | + $scope.mismatch = false; | |
7 | + $scope.unacceptable = false; | |
5 | 8 | |
9 | + $scope.changePassword = function(oldPassword, newPassword, confirmedNewPassword) { | |
10 | + console.log('in change password'); | |
11 | + | |
12 | + $http.patch('/api/me/', { | |
13 | + 'old_password': oldPassword, | |
14 | + 'new_password': newPassword | |
15 | + }). | |
16 | + success(function(data) { | |
17 | + | |
18 | + console.log('password successfully changes'); | |
19 | + | |
20 | + }). | |
21 | + error(function(data) { | |
22 | + console.log('not changed'); | |
23 | + }); | |
24 | + | |
25 | + | |
6 | 26 | }; |
27 | + | |
28 | + $rootScope.SectionResource = $resource('/api/sections/:sectionId/'); | |
29 | + $rootScope.currentSection = {}; | |
30 | + $rootScope.UserService = UserService; | |
31 | + | |
32 | + $scope.dropClass = function(section) { | |
33 | + $http.post('/api/sections/' + section.id + '/drop/'). | |
34 | + success(function(data) { | |
35 | + console.log(section.short_name + ' dropped'); | |
36 | + | |
37 | + Materialize.toast('Dropped', 3000, 'rounded'); | |
38 | + }). | |
39 | + error(function(err) { | |
40 | + console.log('no drop for you'); | |
41 | + }); | |
42 | + }; | |
43 | + | |
44 | + | |
45 | + | |
7 | 46 | console.log('checking to see if chrome'); |
47 | + | |
8 | 48 | if (!chrome) { |
49 | + pushSwitch.disabled = true; | |
9 | 50 | return; |
10 | 51 | } |
52 | + | |
11 | 53 | console.log('chrome'); |
12 | 54 | |
13 | 55 | console.log('executing things outside of module'); |
14 | 56 | var PUSH_SERVER_URL = '/api/subscribe/'; |
57 | + var UNPUSH_SERVER_URL = '/api/unsubscribe/'; | |
15 | 58 | |
16 | 59 | function onPushSubscription(pushSubscription) { |
17 | 60 | console.log('pushSubscription = ', pushSubscription.endpoint); |
... | ... | @@ -27,6 +70,16 @@ |
27 | 70 | $http.post(PUSH_SERVER_URL, {'registration_id': subscriptionId}); |
28 | 71 | } |
29 | 72 | |
73 | + function removeSubscription(pushSubscription) { | |
74 | + console.log('removing subscription'); | |
75 | + console.log('pushSubscription endpoint = ', pushSubscription.endpoint); | |
76 | + | |
77 | + var subscriptionId = pushSubscription.subscriptionId; | |
78 | + | |
79 | + console.log('registration_id: ', subscriptionId); | |
80 | + $http.post(UNPUSH_SERVER_URL, {'registration_id': subscriptionId}); | |
81 | + } | |
82 | + | |
30 | 83 | function subscribeDevice() { |
31 | 84 | // We need the service worker registration to access the push manager |
32 | 85 | navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { |
33 | 86 | |
... | ... | @@ -41,12 +94,15 @@ |
41 | 94 | console.log('subscribe() Error: Push permission status = ', |
42 | 95 | permissionStatus); |
43 | 96 | if (permissionStatus.status === 'denied') { |
97 | + pushSwitch.checked = false; | |
98 | + pushSwitch.disabled = true; | |
44 | 99 | // The user blocked the permission prompt |
45 | 100 | console.log('Ooops Notifications are Blocked', |
46 | 101 | 'Unfortunately you just permanently blocked notifications. ' + |
47 | 102 | 'Please unblock / allow them to switch on push ' + |
48 | 103 | 'notifications.'); |
49 | 104 | } else { |
105 | + pushSwitch.checked = false; | |
50 | 106 | console.log('Ooops Push Couldn\'t Register', |
51 | 107 | '<p>When we tried to ' + |
52 | 108 | 'get the subscription ID for GCM, something went wrong,' + |
... | ... | @@ -58,6 +114,7 @@ |
58 | 114 | '</p>'); |
59 | 115 | } |
60 | 116 | }).catch(function(err) { |
117 | + pushSwitch.checked = false; | |
61 | 118 | console.log('Ooops Push Couldn\'t Register', |
62 | 119 | '<p>When we tried to ' + |
63 | 120 | 'get the subscription ID for GCM, something went wrong, not ' + |
64 | 121 | |
... | ... | @@ -71,10 +128,13 @@ |
71 | 128 | } else { |
72 | 129 | // Use notification permission to do something |
73 | 130 | if (Notification.permission === 'denied') { |
131 | + pushSwitch.disabled = true; | |
132 | + pushSwitch.checked = false; | |
74 | 133 | console.log('Ooops Notifications are Blocked', |
75 | 134 | 'Unfortunately you just permanently blocked notifications. ' + |
76 | 135 | 'Please unblock / allow them to switch on push notifications.'); |
77 | 136 | } else { |
137 | + pushSwitch.checked = false; | |
78 | 138 | console.log('Ooops Push Couldn\'t Register', |
79 | 139 | '<p>When we tried to ' + |
80 | 140 | 'get the subscription ID for GCM, something went wrong, not ' + |
81 | 141 | |
82 | 142 | |
83 | 143 | |
... | ... | @@ -96,21 +156,27 @@ |
96 | 156 | function(pushSubscription) { |
97 | 157 | // Check we have everything we need to unsubscribe |
98 | 158 | if (!pushSubscription) { |
159 | + pushSwitch.checked = false; | |
99 | 160 | return; |
100 | 161 | } |
101 | 162 | |
102 | 163 | // TODO: Remove the device details from the server |
103 | 164 | // i.e. the pushSubscription.subscriptionId and |
104 | 165 | // pushSubscription.endpoint |
166 | + var subscriptionId = pushSubscription.subscriptionId; | |
105 | 167 | |
106 | 168 | pushSubscription.unsubscribe().then(function(successful) { |
107 | 169 | console.log('Unsubscribed from push: ', successful); |
170 | + | |
108 | 171 | if (!successful) { |
109 | 172 | // The unsubscribe was unsuccessful, but we can |
110 | 173 | // remove the subscriptionId from our server |
111 | 174 | // and notifications will stop |
112 | 175 | // This just may be in a bad state when the user returns |
113 | - console.error('We were unable to unregister from push'); | |
176 | + pushSwitch.checked = true; | |
177 | + removeSubscription(pushSubscription); | |
178 | + console.error('We were unable to unregister from push, but we removed'+ | |
179 | + 'registration id from the server'); | |
114 | 180 | } |
115 | 181 | |
116 | 182 | }).catch(function(e) { |
... | ... | @@ -128,6 +194,7 @@ |
128 | 194 | // If the notification permission is denied, it's a permanent block |
129 | 195 | switch (permissionStatus.status) { |
130 | 196 | case 'denied': |
197 | + pushSwitch.disabled = true; | |
131 | 198 | console.log('Ooops Push has been Blocked', |
132 | 199 | 'Unfortunately the user permanently blocked push. Please unblock / ' + |
133 | 200 | 'allow them to switch on push notifications.'); |
... | ... | @@ -137,6 +204,7 @@ |
137 | 204 | console.log('case granted'); |
138 | 205 | break; |
139 | 206 | case 'prompt': |
207 | + pushSwitch.checked = false; | |
140 | 208 | console.log('case prompt'); |
141 | 209 | break; |
142 | 210 | } |
... | ... | @@ -163,6 +231,7 @@ |
163 | 231 | return; |
164 | 232 | } |
165 | 233 | |
234 | + console.log('update current state.'); | |
166 | 235 | // Update the current state with the |
167 | 236 | // subscriptionid and endpoint |
168 | 237 | onPushSubscription(subscription); |
... | ... | @@ -179,13 +248,9 @@ |
179 | 248 | } |
180 | 249 | |
181 | 250 | function setUpNotificationPermission() { |
182 | - // If the notification permission is denied, it's a permanent block | |
183 | - if (Notification.permission === 'denied') { | |
184 | - console.log('Ooops Notifications are Blocked', | |
185 | - 'Unfortunately notifications are permanently blocked. Please unblock / ' + | |
186 | - 'allow them to switch on push notifications.'); | |
187 | - return; | |
188 | - } else if (Notification.permission === 'default') { | |
251 | + console.log('setting notification setting'); | |
252 | + | |
253 | + if (Notification.permission === 'default') { | |
189 | 254 | console.log('notification permissions === default'); |
190 | 255 | return; |
191 | 256 | } |
... | ... | @@ -214,6 +279,27 @@ |
214 | 279 | |
215 | 280 | // Once the service worker is registered set the initial state |
216 | 281 | function initialiseState() { |
282 | + // Check if notifications are supported | |
283 | + if (!('showNotification' in ServiceWorkerRegistration.prototype)) { | |
284 | + console.warn('Notifications aren\'t supported.'); | |
285 | + return; | |
286 | + } | |
287 | + // Check the current Notification permission. | |
288 | + // If its denied, it's a permanent block until the | |
289 | + // user changes the permission | |
290 | + else if (Notification.permission === 'denied') { | |
291 | + console.log('Ooops Notifications are Blocked', | |
292 | + 'Unfortunately notifications are permanently blocked. Please unblock / ' + | |
293 | + 'allow them to switch on push notifications.'); | |
294 | + return; | |
295 | + } | |
296 | + // Check if push messaging is supported | |
297 | + else if (!('PushManager' in window)) { | |
298 | + console.warn('Push messaging isn\'t supported.'); | |
299 | + return; | |
300 | + } | |
301 | + | |
302 | + pushSwitch.disabled = false; | |
217 | 303 | // Is the Permissions API supported |
218 | 304 | if ('permissions' in navigator) { |
219 | 305 | console.log('setting push permissions'); |
... | ... | @@ -226,6 +312,21 @@ |
226 | 312 | } |
227 | 313 | |
228 | 314 | var enablePushSwitch = $('.js-checkbox'); |
315 | + | |
316 | + var pushSwitch = document.getElementById("notifbox"); | |
317 | + pushSwitch.disabled = true; | |
318 | + | |
319 | + var ua = navigator.userAgent.toLowerCase(); | |
320 | + var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile"); | |
321 | + | |
322 | + if(!isAndroid) { | |
323 | + // Do something! | |
324 | + // Redirect to Android-site? | |
325 | + pushSwitch.disabled = true; | |
326 | + console.log("not android"); | |
327 | + return; | |
328 | + } | |
329 | + | |
229 | 330 | enablePushSwitch.change(function(e) { |
230 | 331 | console.log('checkbox changed'); |
231 | 332 | if (e.target.checked) { |
... | ... | @@ -242,6 +343,7 @@ |
242 | 343 | navigator.serviceWorker.register('service-worker.js') |
243 | 344 | .then(initialiseState); |
244 | 345 | } else { |
346 | + // disable button if serviceworker is not available | |
245 | 347 | // Service Workers aren't supported so you should hide the push UI |
246 | 348 | // If it's currently visible. |
247 | 349 | console.log('Ooops Service Workers aren\'t Supported', |
templates/cardlist.html
View file @
7545660
1 | 1 | <body> |
2 | - <div class="row"> | |
3 | - <a class="btn" id="showHidden" ng-click="show = !show" style="margin-top: 15px">Show Hidden</a> | |
2 | +<div class="row"> | |
3 | + <a class="btn" id="showHidden" ng-click="show = !show" style="margin-top: 15px">Show Hidden</a> | |
4 | 4 | |
5 | - <div class="input-field col s6 right"> | |
6 | - <i class="mdi-action-search prefix"></i> | |
7 | - <input id="search" type="text" class="validate" ng-model="searchText"/> | |
8 | - <label for="search">Search</label> | |
9 | - </div> | |
5 | + <div class="input-field col s6 right"> | |
6 | + <i class="mdi-action-search prefix"></i> | |
7 | + <input id="search" type="text" class="validate" ng-model="searchText"/> | |
8 | + <label for="search">Search</label> | |
10 | 9 | </div> |
10 | +</div> | |
11 | 11 | |
12 | - <div class="row"> | |
13 | - <form> | |
14 | - <div class="col s12"> | |
15 | - <div class="col s2"> | |
16 | - <input type="checkbox" class="filled-in" id="weekOneCheck" ng-model="filter['week1']"/> | |
17 | - <label for="weekOneCheck">Week One</label> | |
18 | - </div> | |
19 | - <div class="col s2"> | |
20 | - <input type="checkbox" class="filled-in" id="weekTwoCheck" ng-model="filter['week2']"/> | |
21 | - <label for="weekTwoCheck">Week Two</label> | |
22 | - </div> | |
23 | - <div class="col s2"> | |
24 | - <input type="checkbox" class="filled-in" id="weekThreeCheck" ng-model="filter['week3']"/> | |
25 | - <label for="weekThreeCheck">Week Three</label> | |
26 | - </div> | |
27 | - <div class="col s2"> | |
28 | - <input type="checkbox" class="filled-in" id="weekFourCheck" ng-model="filter['week4']"/> | |
29 | - <label for="weekFourCheck">Week Four</label> | |
30 | - </div> | |
31 | - <div class="col s2"> | |
32 | - <input type="checkbox" class="filled-in" id="weekFiveCheck" ng-model="filter['week5']"/> | |
33 | - <label for="weekFiveCheck">Week Five</label> | |
34 | - </div> | |
12 | +<div class="row"> | |
13 | + <form> | |
14 | + <div class="col s12"> | |
15 | + <div class="col s2"> | |
16 | + <input type="checkbox" class="filled-in" id="weekOneCheck" ng-model="filter['week1']"/> | |
17 | + <label for="weekOneCheck">Week One</label> | |
35 | 18 | </div> |
36 | - <div class="col s12"> | |
37 | - <div class="col s2"> | |
38 | - <input type="checkbox" class="filled-in" id="weekSixCheck" ng-model="filter['week6']"/> | |
39 | - <label for="weekSixCheck">Week Six</label> | |
40 | - </div> | |
41 | - <div class="col s2"> | |
42 | - <input type="checkbox" class="filled-in" id="weekSevenCheck" ng-model="filter['week7']"/> | |
43 | - <label for="weekSevenCheck">Week Seven</label> | |
44 | - </div> | |
45 | - <div class="col s2"> | |
46 | - <input type="checkbox" class="filled-in" id="weekEightCheck" ng-model="filter['week8']"/> | |
47 | - <label for="weekEightCheck">Week Eight</label> | |
48 | - </div> | |
49 | - <div class="col s2"> | |
50 | - <input type="checkbox" class="filled-in" id="weekNineCheck" ng-model="filter['week9']"/> | |
51 | - <label for="weekNineCheck">Week Nine</label> | |
52 | - </div> | |
53 | - <div class="col s2"> | |
54 | - <input type="checkbox" class="filled-in" id="weekTenCheck" ng-model="filter['week10']"/> | |
55 | - <label for="weekTenCheck">Week Ten</label> | |
56 | - </div> | |
19 | + <div class="col s2"> | |
20 | + <input type="checkbox" class="filled-in" id="weekTwoCheck" ng-model="filter['week2']"/> | |
21 | + <label for="weekTwoCheck">Week Two</label> | |
57 | 22 | </div> |
58 | - </form> | |
59 | - </div> | |
23 | + <div class="col s2"> | |
24 | + <input type="checkbox" class="filled-in" id="weekThreeCheck" ng-model="filter['week3']"/> | |
25 | + <label for="weekThreeCheck">Week Three</label> | |
26 | + </div> | |
27 | + <div class="col s2"> | |
28 | + <input type="checkbox" class="filled-in" id="weekFourCheck" ng-model="filter['week4']"/> | |
29 | + <label for="weekFourCheck">Week Four</label> | |
30 | + </div> | |
31 | + <div class="col s2"> | |
32 | + <input type="checkbox" class="filled-in" id="weekFiveCheck" ng-model="filter['week5']"/> | |
33 | + <label for="weekFiveCheck">Week Five</label> | |
34 | + </div> | |
35 | + </div> | |
36 | + <div class="col s12"> | |
37 | + <div class="col s2"> | |
38 | + <input type="checkbox" class="filled-in" id="weekSixCheck" ng-model="filter['week6']"/> | |
39 | + <label for="weekSixCheck">Week Six</label> | |
40 | + </div> | |
41 | + <div class="col s2"> | |
42 | + <input type="checkbox" class="filled-in" id="weekSevenCheck" ng-model="filter['week7']"/> | |
43 | + <label for="weekSevenCheck">Week Seven</label> | |
44 | + </div> | |
45 | + <div class="col s2"> | |
46 | + <input type="checkbox" class="filled-in" id="weekEightCheck" ng-model="filter['week8']"/> | |
47 | + <label for="weekEightCheck">Week Eight</label> | |
48 | + </div> | |
49 | + <div class="col s2"> | |
50 | + <input type="checkbox" class="filled-in" id="weekNineCheck" ng-model="filter['week9']"/> | |
51 | + <label for="weekNineCheck">Week Nine</label> | |
52 | + </div> | |
53 | + <div class="col s2"> | |
54 | + <input type="checkbox" class="filled-in" id="weekTenCheck" ng-model="filter['week10']"/> | |
55 | + <label for="weekTenCheck">Week Ten</label> | |
56 | + </div> | |
57 | + </div> | |
58 | + </form> | |
59 | +</div> | |
60 | 60 | |
61 | - <div class="list" style="padding: 0px 25px"> | |
62 | - <ul class="collection" | |
63 | - ng-repeat="(weeknum, week_cards) in cards | filter:searchText | filter:filterByDate | groupBy: 'material_week_num'"> | |
64 | - <li class="collection-header"><h3>Week {{weeknum}}</h3></li> | |
65 | - <li class="collection-item" ng-click="expand = !expand" ng-repeat="card in week_cards" ng-show="show || !card.is_hidden"> | |
66 | - <div> | |
67 | - <span ng-bind-html="card | displayCard"></span> | |
68 | - <span class="badge">{{dayofweek(card)}}</span> | |
69 | - <p class="right-align" ng-show="expand"> | |
70 | - <a href="" class="tooltipped" ng-click="pull(card)" ng-show="!card.is_in_deck" data-position="bottom" data-delay="50" data-tooltip="Add to Deck"> | |
71 | - <i class="mdi-content-add-circle-outline small"></i></a> | |
72 | - <a href="" class="tooltipped" ng-click="unpull(card)" ng-show="card.is_in_deck" data-position="bottom" data-delay="50" data-tooltip="Add to Deck"> | |
73 | - <i class="mdi-content-remove-circle-outline small"></i></a> | |
74 | - <a href="" class="tooltipped" ng-click="hide(card)" ng-show="!card.is_hidden" data-position="bottom" data-delay="50" data-tooltip="Hide"> | |
75 | - <i class="mdi-action-visibility-off small"></i></a> | |
76 | - <a href="" class="tooltipped" ng-click="unhide(card)" ng-show="card.is_hidden" data-position="bottom" data-delay="50" data-tooltip="Unhide"> | |
77 | - <i class="mdi-action-visibility small"></i></a> | |
78 | - <a href="" ng-click="flag(card)" data-position="bottom" data-delay="50" data-tooltip="Flag"> | |
79 | - <i class="mdi-content-flag small"></i></a> | |
80 | - </p> | |
81 | - </div> | |
82 | - </li> | |
83 | - </ul> | |
84 | - </div> | |
61 | +<div class="list" style="padding: 0px 25px"> | |
62 | + <ul class="collection" | |
63 | + ng-repeat="(weeknum, week_cards) in cards | filter:searchText | filter:filterByDate | groupBy: 'material_week_num'"> | |
64 | + <li class="collection-header"><h3>Week {{weeknum}}</h3></li> | |
65 | + <li class="collection-item" ng-click="expand = !expand" ng-repeat="card in week_cards" | |
66 | + ng-show="show || !card.is_hidden"> | |
67 | + <i ng-show="card.isInDeck()" class="mdi-action-done small green-text"></i> | |
68 | + <span ng-bind-html="card | displayCard"></span> | |
69 | + <span class="badge">{{dayofweek(card)}}</span> | |
85 | 70 | |
71 | + <p class="right-align" ng-show="expand"> | |
72 | + <a href="" class="tooltipped" ng-click="card.pull()" ng-show="!card.isInDeck()" data-position="bottom" | |
73 | + data-delay="50" data-tooltip="Add to Deck"> | |
74 | + <i class="mdi-content-add-circle-outline small"></i></a> | |
75 | + <a href="" class="tooltipped" ng-click="card.unpull()" ng-show="card.isInDeck()" data-position="bottom" | |
76 | + data-delay="50" data-tooltip="Add to Deck"> | |
77 | + <i class="mdi-content-remove-circle-outline small"></i></a> | |
78 | + <a href="" class="tooltipped" ng-click="card.hide()" ng-show="!card.is_hidden" data-position="bottom" | |
79 | + data-delay="50" data-tooltip="Hide"> | |
80 | + <i class="mdi-action-visibility-off small"></i></a> | |
81 | + <a href="" class="tooltipped" ng-click="card.unhide()" ng-show="card.is_hidden" data-position="bottom" | |
82 | + data-delay="50" data-tooltip="Unhide"> | |
83 | + <i class="mdi-action-visibility small"></i></a> | |
84 | + <a href="" ng-click="flag(card)" data-position="bottom" data-delay="50" data-tooltip="Flag"> | |
85 | + <i class="mdi-content-flag small"></i></a> | |
86 | + </p> | |
87 | + </li> | |
88 | + </ul> | |
89 | +</div> | |
86 | 90 | |
87 | - <div class="fixed-action-btn back-to-top" style="bottom: 45px; right: 24px; display: none;"> | |
88 | - <a class="btn-floating btn-large"> | |
89 | - <i class="mdi-editor-publish medium"></i> | |
90 | - </a> | |
91 | - </div> | |
91 | + | |
92 | +<div class="fixed-action-btn back-to-top" style="bottom: 45px; right: 24px; display: none;"> | |
93 | + <a class="btn-floating btn-large"> | |
94 | + <i class="mdi-editor-publish medium"></i> | |
95 | + </a> | |
96 | +</div> | |
92 | 97 | </body> |
templates/dropclass.html
View file @
7545660
1 | -<div class="row"> | |
2 | - <div class="col s8 offset-s2"> | |
3 | - <div class="card-panel" id="dropClassForm"> | |
4 | - | |
5 | - <h2>Enrolled Classes</h2> | |
6 | - <div class="row" style="padding: 0px 25px"> | |
7 | - <table class="hoverable responsive-table"> | |
8 | - <thead> | |
9 | - <tr> | |
10 | - <th data-field="id">Class</th> | |
11 | - <th data-field="drop">Drop?</th> | |
12 | - </tr> | |
13 | - </thead> | |
14 | - | |
15 | - <tbody> | |
16 | - <tr ng-repeat="section in UserService.getUserData().sections"> | |
17 | - <td> | |
18 | - <span>{{section.short_name}}</span> | |
19 | - <p>{{section.long_name}}</p> | |
20 | - </td> | |
21 | - <td><a href="" ng-click="dropClass(section)"><i class="mdi-content-clear small"></i></a></td> | |
22 | - </tr> | |
23 | - </tbody> | |
24 | - </table> | |
25 | - </div> | |
26 | - </div> | |
27 | - </div> | |
28 | -</div> |
templates/settings.html
View file @
7545660
1 | -<div class="card" id="resetPasswordForm"> | |
1 | +<div class="row"> | |
2 | + <div class="col s6 offset-s3"> | |
3 | + <div class="card-panel" id="dropClassForm"> | |
4 | + <h2>Notification Settings</h2> | |
5 | + <!-- | |
6 | + class="js-checkbox" name="notifbox" value="toggle notifs"> --> | |
7 | + <form action="#"> | |
8 | + <input type="checkbox" id = "notifbox" class="js-checkbox" /> | |
9 | + <label for="notifbox">Enable notifications</label> | |
10 | + </form> | |
11 | + </div> | |
12 | + </div> | |
13 | +</div> | |
2 | 14 | |
3 | - <!-- | |
4 | - class="js-checkbox" name="notifbox" value="toggle notifs"> --> | |
5 | - <form action="#"> | |
6 | - <input type="checkbox" id = "notifbox" class="js-checkbox" /> | |
7 | - <label for="notifbox">Check this to enable notifications</label> | |
8 | - </form> | |
15 | +<div class="row"> | |
16 | + <div class="col s6 offset-s3"> | |
17 | + <div class="card-panel" id="resetPasswordForm"> | |
9 | 18 | |
10 | - <h2>Change Password</h2> | |
19 | + <h2>Change Password</h2> | |
11 | 20 | |
12 | - <div class="row"> | |
13 | - <form class="col s12"> | |
21 | + <form name="ChangePasswordForm"> | |
14 | 22 | |
15 | - <div class="row"> | |
16 | - <div class="input-field col s12"> | |
17 | - <input id="password" type="password" ng-model="oldPassword" class="validate"> | |
18 | - <label for="password">Old Password</label> | |
23 | + <div class="row"> | |
24 | + <div class="input-field col s12"> | |
25 | + <input id="password" required type="password" name="oldpw" ng-model="oldPassword" class="validate"> | |
26 | + <label for="password">Old Password</label> | |
27 | + </div> | |
19 | 28 | </div> |
20 | - </div> | |
21 | 29 | |
22 | - <div class="row"> | |
23 | - <div class="input-field col s12"> | |
24 | - <input id="password" type="password" ng-model="newPassword" class="validate"> | |
25 | - <label for="password">New Password</label> | |
30 | + <div role="alert"> | |
31 | + <span class="error" ng-show="ChangePasswordForm.oldpw.$error.required"> | |
32 | + Required!</span> | |
26 | 33 | </div> |
27 | - </div> | |
28 | 34 | |
29 | - <div class="row"> | |
30 | - <div class="input-field col s12"> | |
31 | - <input id="password" type="password" ng-model="confirmedNewPassword" class="validate"> | |
32 | - <label for="password">Confirm New Password</label> | |
35 | + | |
36 | + <div class="row"> | |
37 | + <div class="input-field col s12"> | |
38 | + <input id="password" required ng-minlength=8 type="password" name="newpw" ng-model="newPassword" class="validate"> | |
39 | + <label for="password">New Password</label> | |
40 | + </div> | |
33 | 41 | </div> |
34 | - </div> | |
42 | + | |
43 | + <div role="alert"> | |
44 | + <span class="error" ng-show="ChangePasswordForm.newpw.$error.minlength"> | |
45 | + New password must be at least 8 characters. </span> | |
46 | + </div> | |
35 | 47 | |
48 | + <div class="row"> | |
49 | + <div class="input-field col s12"> | |
50 | + <input id="password" required ng-minlength=8 compare-to="newpw" type="password" name="confirmpw" ng-model="confirmedNewPassword" class="validate"> | |
51 | + <label for="password">Confirm New Password</label> | |
52 | + </div> | |
53 | + </div> | |
54 | + | |
55 | + <div role="alert"> | |
56 | + <span class="error" ng-show="ChangePasswordForm.confirm.$error.minlength"> | |
57 | + Must be the same as the new password. </span> | |
58 | + </div> | |
36 | 59 | |
37 | - </form> | |
38 | 60 | |
39 | - <a class="waves-effect waves-light btn" id="resetPWButton" | |
40 | - ng-click="changePassword(oldPassword, newPassword, confirmedNewPassword)">Reset Password</a> | |
41 | - | |
61 | + </form> | |
62 | + <a class="waves-effect waves-light btn" id="resetPWButton" | |
63 | + ng-click="changePassword(oldPassword, newPassword, confirmedNewPassword)">Change Password</a> | |
64 | + </div> | |
42 | 65 | </div> |
66 | +</div> | |
67 | + | |
68 | +<div class="row"> | |
69 | + <div class="col s6 offset-s3"> | |
70 | + <div class="card-panel" id="dropClassForm"> | |
71 | + | |
72 | + <h2>Enrolled Classes</h2> | |
73 | + <div class="row" style="padding: 0px 25px"> | |
74 | + <table class="hoverable responsive-table"> | |
75 | + <thead> | |
76 | + <tr> | |
77 | + <th data-field="id">Class</th> | |
78 | + <th data-field="drop">Drop?</th> | |
79 | + </tr> | |
80 | + </thead> | |
81 | + | |
82 | + <tbody> | |
83 | + <tr ng-repeat="section in UserService.getUserData().sections"> | |
84 | + <td> | |
85 | + <span>{{section.short_name}}</span> | |
86 | + <p>{{section.long_name}}</p> | |
87 | + </td> | |
88 | + <td><a href="" ng-click="dropClass(section)"><i class="mdi-content-clear small"></i></a></td> | |
89 | + </tr> | |
90 | + </tbody> | |
91 | + </table> | |
92 | + </div> | |
93 | + </div> | |
94 | + </div> | |
43 | 95 | </div> |