diff --git a/home.html b/home.html
index 936a903..97c2432 100644
--- a/home.html
+++ b/home.html
@@ -172,6 +172,7 @@
 <script src="scripts/CardListController.js"></script>
 <script src="scripts/VerifyEmailController.js"></script>
 <script src="scripts/HelpController.js"></script>
+<script src="scripts/CardGridController.js"></script>
 
 <!-- Services -->
 <script src="scripts/UserService.js"></script>
diff --git a/scripts/CardGridController.js b/scripts/CardGridController.js
new file mode 100644
index 0000000..f601769
--- /dev/null
+++ b/scripts/CardGridController.js
@@ -0,0 +1,85 @@
+angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate']).controller =
+    function($scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService) {
+
+        $scope.cards = false;
+        $scope.cardCols = []; // organized data
+        $scope.numCols = 0;
+        $scope.cardTable = {}; // look up table of cards, {'colNum':col, 'obj':card}
+        $scope.sectionId = parseInt($stateParams.sectionId);
+        $scope.section = $rootScope.SectionResource.get({sectionId: $scope.sectionId});
+        $rootScope.currentSection = $scope.section;
+        console.log('hello from cardgridcontroller');
+
+        if (!UserService.isInSection($scope.sectionId)) {
+            console.log('user is not enrolled in ' + $scope.sectionId);
+            return $state.go('addclass');
+        }
+
+        angular.element($window).bind('resize', $scope.refreshLayout);
+        $scope.refreshColumnWidth = function() {
+            console.log('refreshing column width');
+            avail = $window.innerWidth - 17;
+            width = Math.floor(avail / Math.floor(avail / 250));
+            $('.cardColumn').css({
+                width: width + 'px',
+                'font-size': 100 * width / 250 + '%'
+            });
+            $('.cardColumn .card.flashy').css({
+                width: width - 12 + 'px',
+                height: (width * 3 / 5) + 'px'
+            });
+        };
+
+        $scope.refreshLayout = function() {
+            numCols = Math.max(1, Math.floor(($window.innerWidth - 17) / 250));
+
+            // check if we actually need to refresh the whole layout
+            if (numCols == $scope.numCols) return $scope.refreshColumnWidth();
+            $scope.numCols = numCols;
+            console.log('refreshing layout for ' + $scope.numCols + ' columns');
+            $scope.cardCols = [];
+            var cols = [];
+            for (i = 0; i < $scope.numCols; i++) cols.push([]);
+            $scope.cards.forEach(function(card, i) {
+                cols[i % $scope.numCols].push(card);
+                $scope.cardTable[card.id] = {'colNum': (i % $scope.numCols), 'obj': card};
+            });
+            // wait until the next digest cycle to update cardCols
+
+            $timeout(function() {
+                $scope.cardCols = cols;
+                $timeout($scope.refreshColumnWidth);
+            });
+
+        };
+
+        $scope.add = function(card) {
+            var colNum = 0;
+            var lowestCol = $scope.cardCols[0];
+            var lowestColNum = 0;
+            while (colNum < $scope.numCols) {
+                if ($scope.cardCols[colNum].length == 0) {
+                    lowestCol = $scope.cardCols[colNum];
+                    break;
+                } else if ($scope.cardCols[colNum].length < lowestCol.length) {
+                    lowestCol = $scope.cardCols[colNum];
+                    lowestColNum = colNum;
+                    lowestColLen = $scope.cardCols[colNum].length;
+                }
+                colNum++;
+            }
+            console.log(card);
+            $scope.cards.push(data);
+            $timeout(function() {
+                lowestCol.unshift(card);
+                $scope.cardTable[card.id] = {'colNum': lowestColNum, 'obj': card};
+                $timeout($scope.refreshColumnWidth);
+            });
+        };
+
+        $scope.$on('$destroy', function() {
+            $scope.ws.close();
+            $rootScope.currentSection = {};
+            $(document).off('keydown');
+        });
+    };
diff --git a/scripts/DeckController.js b/scripts/DeckController.js
index d84a18f..94e0f97 100644
--- a/scripts/DeckController.js
+++ b/scripts/DeckController.js
@@ -1,55 +1,10 @@
 angular.module('flashy.DeckController', ['ui.router']).
 
-    controller('DeckController', function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams) {
-        sectionId = $stateParams.sectionId;
-        $rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId});
-        $scope.cards = false;
-        $scope.cardCols = []; // organized data
-        $scope.numCols = 0;
-
-        function calculate_cols() {
-            var avail = $window.innerWidth - 17;
-            return Math.max(1, Math.floor(avail / 250));
-        }
-
-        $scope.refreshColumnWidth = function() {
-            console.log('refreshing column width');
-            avail = $window.innerWidth - 17;
-            width = Math.floor(avail / Math.floor(avail / 250));
-            $('.cardColumn').css({
-                width: width + 'px',
-                'font-size': 100 * width / 250 + '%'
-            });
-            $('.cardColumn .card.flashy').css({
-                width: width - 12 + 'px',
-                height: (width * 3 / 5) + 'px'
-            });
-        };
-
-        $scope.refreshLayout = function() {
-            // check if we actually need to refresh the whole layout
-            if (calculate_cols() == $scope.numCols) return $scope.refreshColumnWidth();
-            $scope.numCols = calculate_cols();
-            console.log('refreshing layout for ' + $scope.numCols + ' columns');
-            $scope.cardCols = [];
-            var cols = [];
-            for (i = 0; i < $scope.numCols; i++) cols.push([]);
-            $scope.cards.forEach(function(card, i) {
-                cols[i % $scope.numCols].push(card);
-            });
-            // wait until the next digest cycle to update cardCols
-
-            $timeout(function() {
-                $scope.cardCols = cols;
-                $timeout($scope.refreshColumnWidth);
-            });
-
-        };
-
-        angular.element($window).bind('resize', $scope.refreshLayout);
+    controller('DeckController', function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, UserService) {
+        angular.module('flashy.CardGridController').controller.call(this, $scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService);
 
         $scope.refreshCards = function() {
-            $http.get('/api/sections/' + sectionId + '/deck/').
+            $http.get('/api/sections/' + $scope.sectionId + '/deck/').
                 success(function(data) {
                     console.log(data);
                     $scope.cards = data;
@@ -61,8 +16,5 @@ angular.module('flashy.DeckController', ['ui.router']).
                 });
         };
         $scope.refreshCards();
-        $scope.$on('$destroy', function() {
-            $rootScope.currentSection = {};
-        });
     }
 );
diff --git a/scripts/FeedController.js b/scripts/FeedController.js
index db63ebf..9e6ec94 100644
--- a/scripts/FeedController.js
+++ b/scripts/FeedController.js
@@ -1,63 +1,11 @@
 angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
 
     controller('FeedController', function($scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService) {
+        angular.module('flashy.CardGridController').controller.call(this, $scope, $rootScope, $stateParams, $state, $http, $window, $timeout, UserService);
         console.log('Hello from feed');
-        sectionId = parseInt($stateParams.sectionId);
-        if (!UserService.isInSection(sectionId)) {
-            console.log('user is not enrolled in ' + sectionId);
-            return $state.go('addclass');
-        }
-        $rootScope.currentSection = $rootScope.SectionResource.get({sectionId: sectionId});
-        $rootScope.debug_flashcard = false;
-        $scope.cards = false;
-        $scope.cardCols = []; // organized data
-        $scope.numCols = 0;
-        $scope.cardTable = {}; // look up table of cards, {'colNum':col, 'obj':card}
-
-        function calculate_cols() {
-            var avail = $window.innerWidth - 17;
-            return Math.max(1, Math.floor(avail / 250));
-        }
-
-        $scope.refreshColumnWidth = function() {
-            console.log('refreshing column width');
-            avail = $window.innerWidth - 17;
-            width = Math.floor(avail / Math.floor(avail / 250));
-            $('.cardColumn').css({
-                width: width + 'px',
-                'font-size': 100 * width / 250 + '%'
-            });
-            $('.cardColumn .card.flashy').css({
-                width: width - 12 + 'px',
-                height: (width * 3 / 5) + 'px'
-            });
-        };
-
-        $scope.refreshLayout = function() {
-            // check if we actually need to refresh the whole layout
-            if (calculate_cols() == $scope.numCols) return $scope.refreshColumnWidth();
-            $scope.numCols = calculate_cols();
-            console.log('refreshing layout for ' + $scope.numCols + ' columns');
-            $scope.cardCols = [];
-            var cols = [];
-            for (i = 0; i < $scope.numCols; i++) cols.push([]);
-            $scope.cards.forEach(function(card, i) {
-                cols[i % $scope.numCols].push(card);
-                $scope.cardTable[card.id] = {'colNum': (i % $scope.numCols), 'obj': card};
-            });
-            // wait until the next digest cycle to update cardCols
-
-            $timeout(function() {
-                $scope.cardCols = cols;
-                $timeout($scope.refreshColumnWidth);
-            });
-
-        };
-
-        angular.element($window).bind('resize', $scope.refreshLayout);
 
         $scope.refreshCards = function() {
-            $http.get('/api/sections/' + sectionId + '/feed/').
+            $http.get('/api/sections/' + $scope.sectionId + '/feed/').
                 success(function(data) {
                     console.log(data);
                     $scope.cards = data;
@@ -70,30 +18,6 @@ angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
                 });
         };
 
-        $scope.add = function(card) {
-            var colNum = 0;
-            var lowestCol = $scope.cardCols[0];
-            var lowestColNum = 0;
-            while (colNum < $scope.numCols) {
-                if ($scope.cardCols[colNum].length == 0) {
-                    lowestCol = $scope.cardCols[colNum];
-                    break;
-                } else if ($scope.cardCols[colNum].length < lowestCol.length) {
-                    lowestCol = $scope.cardCols[colNum];
-                    lowestColNum = colNum;
-                    lowestColLen = $scope.cardCols[colNum].length;
-                }
-                colNum++;
-            }
-            console.log(card);
-            $scope.cards.push(data);
-            $timeout(function() {
-                lowestCol.unshift(card);
-                $scope.cardTable[card.id] = {'colNum': lowestColNum, 'obj': card};
-                $timeout($scope.refreshColumnWidth);
-            });
-        };
-
         $scope.sortAdd = function(card, array) {
             console.log('sort add');
             array.forEach(function(ele, i, ary) {
@@ -119,26 +43,26 @@ angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
             return -1;
         };
 
-		$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;
-			for (; i < column.length; i++)
-				if (column[i].score <= new_score) break;
-			card.score = new_score;
-			if ($scope.$$phase) { // most of the time it is "$digest"
-				column.splice(i, 0, column.splice(found, 1)[0]);
-			} else {
-				$scope.$apply(column.splice(i, 0, column.splice(found, 1)[0]));
-			}
-		};
+        $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;
+            for (; i < column.length; i++)
+                if (column[i].score <= new_score) break;
+            card.score = new_score;
+            if ($scope.$$phase) { // most of the time it is "$digest"
+                column.splice(i, 0, column.splice(found, 1)[0]);
+            } else {
+                $scope.$apply(column.splice(i, 0, column.splice(found, 1)[0]));
+            }
+        };
 
         var loc = window.location, new_uri;
         if (loc.protocol === 'https:') {
@@ -147,12 +71,9 @@ angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
             new_uri = 'ws:';
         }
         new_uri += '//' + loc.host;
-        var ws = new WebSocket(new_uri + '/ws/feed/' + sectionId + '?subscribe-broadcast');
+        $scope.ws = new WebSocket(new_uri + '/ws/feed/' + $scope.sectionId + '?subscribe-broadcast');
 
-        ws.onopen = function() {
-            console.log('websocket connected');
-        };
-        ws.onmessage = function(e) {
+        $scope.ws.onmessage = function(e) {
             data = JSON.parse(e.data);
             console.log('got websocket message ' + e.data);
             console.log(data);
@@ -162,12 +83,6 @@ angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
                 $scope.update(data.flashcard_id, data.new_score);
             }
         };
-        ws.onerror = function(e) {
-            console.error(e);
-        };
-        ws.onclose = function(e) {
-            console.log('connection closed');
-        };
 
         var resetModal = function() {
             $('#new-card-input').html('');
@@ -268,11 +183,6 @@ angular.module('flashy.FeedController', ['ui.router', 'ngAnimate']).
             });
         });
         $scope.refreshCards();
-        $scope.$on('$destroy', function() {
-            ws.close();
-            $rootScope.currentSection = {};
-            $(document).off('keydown');
-        });
 
         $scope.shuffleCards = function() {
             $timeout(function() {
diff --git a/scripts/StudyController.js b/scripts/StudyController.js
index 3bbad7b..f6b17f7 100644
--- a/scripts/StudyController.js
+++ b/scripts/StudyController.js
@@ -5,7 +5,7 @@ controller('StudyController', ['$scope', '$stateParams', '$state', '$http', 'Use
         console.log('Flashy study controller content in this file. also hell0');
         sectionId = $stateParams.sectionId;
 		$scope.isParamOpen = true;
-		
+
         $(document).ready(function() {
             $('.datepicker').pickadate({
                 selectMonths: true, // Creates a dropdown to control month
diff --git a/scripts/UserService.js b/scripts/UserService.js
index 4dfb4f6..9ede76d 100644
--- a/scripts/UserService.js
+++ b/scripts/UserService.js
@@ -70,11 +70,11 @@ angular.module('flashy.UserService', ['ui.router']).
             }
             return true;
         };
-        this.showLockedMessage = function(){
+        this.showLockedMessage = function() {
             Materialize.toast('You must verify your email address before continuing.' +
                     '<a class="btn-flat cyan-text" onclick="rootscope.UserService.resendConfirmationEmail()">' +
                     'Resend Verification Email</a>', 4000);
-        }
+        };
         this.noAuthRequired = function(state) {
             if (['verifyemail'].indexOf(state.name) >= 0) {
                 return true;