Commit 0adf8f867a689fc1ed180def8bf02f20ba703479

Authored by Andrew Buss
1 parent 5673511eb3

nice hide animations

Showing 4 changed files with 29 additions and 40 deletions Inline Diff

scripts/CardGridController.js View file @ 0adf8f8
angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate', 'ngWebSocket']).controller = 1 1 angular.module('flashy.CardGridController', ['ui.router', 'ngAnimate', 'ngWebSocket']).controller =
function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, UserService, Flashcard) { 2 2 function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, UserService, Flashcard) {
$scope.cards = []; 3 3 $scope.cards = [];
$scope.deck = []; 4 4 $scope.deck = [];
$scope.cardCols = []; // organized data 5 5 $scope.cardCols = []; // organized 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.showGrid = false; 10 10 $scope.showGrid = false;
11 $scope.moveQueue = [];
$rootScope.currentSection = $scope.section; 11 12 $rootScope.currentSection = $scope.section;
12 13
if (!UserService.isInSection($scope.sectionId)) { 13 14 if (!UserService.isInSection($scope.sectionId)) {
console.log('user is not enrolled in ' + $scope.sectionId); 14 15 console.log('user is not enrolled in ' + $scope.sectionId);
$state.go('addclass'); 15 16 $state.go('addclass');
} 16 17 }
17 18
$scope.refreshColumnWidth = function() { 18 19 $scope.refreshColumnWidth = function() {
avail = $window.innerWidth - 17; 19 20 avail = $window.innerWidth - 17;
width = Math.floor(avail / Math.floor(avail / 250)); 20 21 width = Math.floor(avail / Math.floor(avail / 250));
$('.cardColumn').css({ 21 22 $('.cardColumn').css({
width: width + 'px', 22 23 width: width + 'px',
'font-size': 100 * width / 250 + '%' 23 24 'font-size': 100 * width / 250 + '%'
}); 24 25 });
$('.cardColumn .card.flashy').css({ 25 26 $('.cardColumn .card.flashy').css({
width: width - 12 + 'px', 26 27 width: width - 12 + 'px',
height: (width * 3 / 5) + 'px' 27 28 height: (width * 3 / 5) + 'px'
}); 28 29 });
}; 29 30 };
30 31
$scope.refreshLayout = function() { 31 32 $scope.refreshLayout = function() {
numCols = Math.max(1, Math.floor(($window.innerWidth - 17) / 250)); 32 33 numCols = Math.max(1, Math.floor(($window.innerWidth - 17) / 250));
33 34
// check if we actually need to refresh the whole layout 34 35 // check if we actually need to refresh the whole layout
if (numCols == $scope.numCols) return $scope.refreshColumnWidth(); 35 36 if (numCols == $scope.numCols) return $scope.refreshColumnWidth();
$scope.numCols = numCols; 36 37 $scope.numCols = numCols;
console.log('refreshing layout for ' + $scope.numCols + ' columns'); 37 38 console.log('refreshing layout for ' + $scope.numCols + ' columns');
$scope.cardCols = []; 38 39 $scope.cardCols = [];
var cols = []; 39 40 var cols = [];
for (i = 0; i < $scope.numCols; i++) cols.push([]); 40 41 for (i = 0; i < $scope.numCols; i++) cols.push([]);
$scope.cards.forEach(function(card, i) { 41 42 $scope.cards.forEach(function(card, i) {
card.colNum = i % $scope.numCols; 42 43 card.colNum = i % $scope.numCols;
cols[card.colNum].push(card); 43 44 cols[card.colNum].push(card);
}); 44 45 });
for (i in cols) $scope.updateColRanks(cols[i]); 45 46 for (i in cols) $scope.updateColRanks(cols[i]);
console.log(cols); 46 47 console.log(cols);
return $timeout(function() { 47 48 return $timeout(function() {
$scope.cardCols = cols; 48 49 $scope.cardCols = cols;
$timeout($scope.refreshColumnWidth); 49 50 $timeout($scope.refreshColumnWidth);
}); 50 51 });
51 52
}; 52 53 };
53 54
angular.element($window).bind('resize', $scope.refreshLayout); 54 55 angular.element($window).bind('resize', $scope.refreshLayout);
55 56
$scope.ws_host = window.location.origin.replace('http', 'ws'); 56 57 $scope.ws_host = window.location.origin.replace('http', 'ws');
$scope.deck_ws = $websocket($scope.ws_host + '/ws/deck/' + $scope.sectionId + '?subscribe-user'); 57 58 $scope.deck_ws = $websocket($scope.ws_host + '/ws/deck/' + $scope.sectionId + '?subscribe-user');
$scope.deck_ws.onOpen(function() { 58 59 $scope.deck_ws.onOpen(function() {
console.log('deck ws open'); 59 60 console.log('deck ws open');
}); 60 61 });
61 62
$scope.deck_ws.onMessage(function(message) { 62 63 $scope.deck_ws.onMessage(function(message) {
data = JSON.parse(message.data); 63 64 data = JSON.parse(message.data);
console.log('message', data); 64 65 console.log('message', data);
card = new Flashcard(data.flashcard.id); 65 66 card = new Flashcard(data.flashcard.id);
if (data.event_type == 'card_pulled') { 66 67 if (data.event_type == 'card_pulled') {
$scope.deck[card.id] = card; 67 68 $scope.deck[card.id] = card;
} 68 69 }
if (data.event_type == 'card_unpulled') { 69 70 if (data.event_type == 'card_unpulled') {
$scope.deck[card.id] = undefined; 70 71 $scope.deck[card.id] = undefined;
} 71 72 }
if (data.event_type == 'card_hidden') { 72 73 if (data.event_type == 'card_hidden') {
$scope.hideCardFromGrid(card); 73 74 $scope.hideCardFromGrid(card);
} 74 75 }
}); 75 76 });
76 77
$scope.cardInDeck = function(id) { 77 78 $scope.cardInDeck = function(id) {
return $scope.deck[id]; 78 79 return $scope.deck[id];
}; 79 80 };
$scope.addCardToGrid = function(card) { 80 81 $scope.addCardToGrid = function(card) {
var colNum = 0; 81 82 var colNum = 0;
var lowestCol = $scope.cardCols[0]; 82 83 var lowestCol = $scope.cardCols[0];
var lowestColNum = 0; 83 84 var lowestColNum = 0;
while (colNum < $scope.numCols) { 84 85 while (colNum < $scope.numCols) {
if ($scope.cardCols[colNum].length == 0) { 85 86 if ($scope.cardCols[colNum].length == 0) {
lowestCol = $scope.cardCols[colNum]; 86 87 lowestCol = $scope.cardCols[colNum];
break; 87 88 break;
} else if ($scope.cardCols[colNum].length < lowestCol.length) { 88 89 } else if ($scope.cardCols[colNum].length < lowestCol.length) {
lowestCol = $scope.cardCols[colNum]; 89 90 lowestCol = $scope.cardCols[colNum];
lowestColNum = colNum; 90 91 lowestColNum = colNum;
lowestColLen = $scope.cardCols[colNum].length; 91 92 lowestColLen = $scope.cardCols[colNum].length;
} 92 93 }
colNum++; 93 94 colNum++;
} 94 95 }
console.log(card); 95 96 console.log(card);
$scope.cards.push(data); 96 97 $scope.cards.push(data);
lowestCol.unshift(card); 97 98 lowestCol.unshift(card);
card.colNum = lowestColNum; 98 99 card.colNum = lowestColNum;
$scope.updateColRanks(lowestCol); 99 100 $scope.updateColRanks(lowestCol);
$timeout($scope.refreshColumnWidth); 100 101 $timeout($scope.refreshColumnWidth);
101 102
}; 102 103 };
103 104
$scope.updateColRanks = function(col) { 104 105 $scope.updateColRanks = function(col) {
for (i in col) 105 106 for (i in col)
col[i].colRank = i; 106 107 col[i].colRank = parseInt(i);
}; 107 108 };
$scope.hideCardFromGrid = function(card) { 108 109 $scope.hideCardFromGrid = function(card) {
console.log('hiding', card); 109 110 console.log('hiding', card);
$scope.cardCols[card.colNum].splice(card.colRank, 1); 110 111 $scope.cardCols[card.colNum].splice(card.colRank, 1);
$scope.updateColRanks($scope.cardCols[card.colNum]); 111 112 $scope.updateColRanks($scope.cardCols[card.colNum]);
113 console.log($scope.cardCols);
}; 112 114 };
113 115
$http.get('/api/sections/' + $scope.sectionId + '/deck/'). 114 116 $http.get('/api/sections/' + $scope.sectionId + '/deck/').
success(function(data) { 115 117 success(function(data) {
for (i in data) $scope.deck[data[i].id] = data[i]; 116 118 for (i in data) $scope.deck[data[i].id] = data[i];
scripts/FeedController.js View file @ 0adf8f8
angular.module('flashy.FeedController', ['ui.router', 'ngAnimate', 'ngWebSocket', 'contenteditable']). 1 1 angular.module('flashy.FeedController', ['ui.router', 'ngAnimate', 'ngWebSocket', 'contenteditable']).
2 2
controller('FeedController', function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, UserService, Flashcard) { 3 3 controller('FeedController', function($scope, $rootScope, $state, $http, $window, $timeout, $stateParams, $websocket, UserService, Flashcard) {
angular.module('flashy.CardGridController').controller.apply(this, arguments); 4 4 angular.module('flashy.CardGridController').controller.apply(this, arguments);
5 5
$scope.refreshCards = function() { 6 6 $scope.refreshCards = function() {
$http.get('/api/sections/' + $scope.sectionId + '/feed/'). 7 7 $http.get('/api/sections/' + $scope.sectionId + '/feed/').
success(function(data) { 8 8 success(function(data) {
console.log(data); 9 9 console.log(data);
$scope.cards = data.map(function(card) { 10 10 $scope.cards = data.map(function(card) {
return new Flashcard(card, $scope.deck); 11 11 return new Flashcard(card, $scope.deck);
}); 12 12 });
$scope.refreshLayout().then(function() { 13 13 $scope.refreshLayout().then(function() {
$timeout($scope.refreshColumnWidth).then(function() { 14 14 $timeout($scope.refreshColumnWidth).then(function() {
$scope.showGrid = true; 15 15 $scope.showGrid = true;
}); 16 16 });
console.log('layout done'); 17 17 console.log('layout done');
}); 18 18 });
}); 19 19 });
}; 20 20 };
21 21
$scope.sortAdd = function(card, array) { 22 22 $scope.sortAdd = function(card, array) {
console.log('sort add'); 23 23 console.log('sort add');
array.forEach(function(ele, i, ary) { 24 24 array.forEach(function(ele, i, ary) {
if (ele.score <= card.score) { 25 25 if (ele.score <= card.score) {
ary.splice(i, 0, card); 26 26 ary.splice(i, 0, card);
return; 27 27 return;
} 28 28 }
}); 29 29 });
}; 30 30 };
31 31
$scope.updateCardScore = function(card) { 32 32 $scope.updateCardScore = function(card) {
console.log($scope.cardCols, card); 33 33 console.log($scope.cardCols, card);
// if no colNum is attached, then this doesn't exist on the feed yet 34 34 // if no colNum is attached, then this doesn't exist on the feed yet
if (!card.colNum) return; 35 35 if (!card.colNum) return;
$scope.cardCols[card.colNum].sort(function(a, b) { 36 36 $scope.cardCols[card.colNum].sort(function(a, b) {
return b.score - a.score; 37 37 return b.score - a.score;
}); 38 38 });
39 $scope.updateColRanks($scope.cardCols[card.colNum]);
}; 39 40 };
40 41
$scope.feed_ws = $websocket($scope.ws_host + '/ws/feed/' + $scope.sectionId + '?subscribe-broadcast'); 41 42 $scope.feed_ws = $websocket($scope.ws_host + '/ws/feed/' + $scope.sectionId + '?subscribe-broadcast');
$scope.feed_ws.onMessage(function(e) { 42 43 $scope.feed_ws.onMessage(function(e) {
data = JSON.parse(e.data); 43 44 data = JSON.parse(e.data);
console.log('message', data); 44 45 console.log('message', data);
if (data.event_type == 'new_card') { 45 46 if (data.event_type == 'new_card') {
$scope.addCardToGrid(new Flashcard(data.flashcard, $scope.deck)); 46 47 $scope.addCardToGrid(new Flashcard(data.flashcard, $scope.deck));
} else if (data.event_type == 'score_change') { 47 48 } else if (data.event_type == 'score_change') {
card = new Flashcard(data.flashcard); 48 49 card = new Flashcard(data.flashcard);
card.score = data.flashcard.score; 49 50 card.score = data.flashcard.score;
$scope.updateCardScore(card); 50 51 $scope.updateCardScore(card);
} 51 52 }
}); 52 53 });
53 54
$scope.pushCard = function() { 54 55 $scope.pushCard = function() {
var myCard = { 55 56 var myCard = {
// we can't trim this string because it'd mess up the blanks. Something to fix. 56 57 // we can't trim this string because it'd mess up the blanks. Something to fix.
'text': $('#new-card-input').text(), 57 58 'text': $('#new-card-input').text(),
'mask': $scope.newCardBlanks, 58 59 'mask': $scope.newCardBlanks,
section: $scope.section.id 59 60 section: $scope.section.id
}; 60 61 };
if (myCard.text == '') { 61 62 if (myCard.text == '') {
console.log('blank flashcard not pushed:' + myCard.text); 62 63 console.log('blank flashcard not pushed:' + myCard.text);
return closeNewCard(); 63 64 return closeNewCard();
} 64 65 }
$http.post('/api/flashcards/', myCard). 65 66 $http.post('/api/flashcards/', myCard).
success(function(data) { 66 67 success(function(data) {
console.log('flashcard pushed: ' + myCard.text); 67 68 console.log('flashcard pushed: ' + myCard.text);
if (!UserService.hasVerifiedEmail()) { 68 69 if (!UserService.hasVerifiedEmail()) {
Materialize.toast("<p>Thanks for contributing! However, others won't see your card until you verify your email address<p>", 4000); 69 70 Materialize.toast("<p>Thanks for contributing! However, others won't see your card until you verify your email address<p>", 4000);
} 70 71 }
}); 71 72 });
return $scope.closeNewCardModal(); 72 73 return $scope.closeNewCardModal();
}; 73 74 };
74 75
/* Key bindings for the whole feed window. Hotkey it up! */ 75 76 /* Key bindings for the whole feed window. Hotkey it up! */
var listenForC = true; 76 77 var listenForC = true;
77 78
// Need to pass these options into openmodal and leanmodal, 78 79 // Need to pass these options into openmodal and leanmodal,
// otherwise the ready handler doesn't get called 79 80 // otherwise the ready handler doesn't get called
80 81
modal_options = { 81 82 modal_options = {
dismissible: true, // Modal can be dismissed by clicking outside of the modal 82 83 dismissible: true, // Modal can be dismissed by clicking outside of the modal
opacity: 0, // Opacity of modal background 83 84 opacity: 0, // Opacity of modal background
in_duration: 300, // Transition in duration 84 85 in_duration: 300, // Transition in duration
out_duration: 200, // Transition out duration 85 86 out_duration: 200, // Transition out duration
ready: function() { 86 87 ready: function() {
$('#new-card-input').focus(); 87 88 $('#new-card-input').focus();
document.execCommand('selectAll', false, null); 88 89 document.execCommand('selectAll', false, null);
} 89 90 }
}; 90 91 };
91 92
$(document).keydown(function(e) { 92 93 $(document).keydown(function(e) {
var keyed = e.which; 93 94 var keyed = e.which;
if (keyed == 67 && listenForC) { // "c" for compose 94 95 if (keyed == 67 && listenForC) { // "c" for compose
$scope.openNewCardModal(); 95 96 $scope.openNewCardModal();
e.preventDefault(); 96 97 e.preventDefault();
return false; 97 98 return false;
} else if (keyed == 27) { // clear on ESC 98 99 } else if (keyed == 27) { // clear on ESC
$scope.closeNewCardModal(); 99 100 $scope.closeNewCardModal();
} 100 101 }
}); 101 102 });
102 103
$scope.openNewCardModal = function() { 103 104 $scope.openNewCardModal = function() {
$('#newCard').openModal(modal_options); 104 105 $('#newCard').openModal(modal_options);
listenForC = false; 105 106 listenForC = false;
$('#new-card-input').html('Write a flashcard!'); 106 107 $('#new-card-input').html('Write a flashcard!');
}; 107 108 };
108 109
$scope.closeNewCardModal = function() { 109 110 $scope.closeNewCardModal = function() {
listenForC = true; 110 111 listenForC = true;
$('#new-card-input').html('').blur(); 111 112 $('#new-card-input').html('').blur();
$('#newCard').closeModal(modal_options); 112 113 $('#newCard').closeModal(modal_options);
}; 113 114 };
114 115
$('.tooltipped').tooltip({delay: 50}); 115 116 $('.tooltipped').tooltip({delay: 50});
// the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered 116 117 // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
$('.modal-trigger').leanModal(modal_options); 117 118 $('.modal-trigger').leanModal(modal_options);
$('#new-card-input').on('keydown', function(e) { 118 119 $('#new-card-input').on('keydown', function(e) {
if (e.which == 13) { 119 120 if (e.which == 13) {
e.preventDefault(); 120 121 e.preventDefault();
if ($scope.submit_enabled) { 121 122 if ($scope.submit_enabled) {
$scope.pushCard(); 122 123 $scope.pushCard();
listenForC = true; 123 124 listenForC = true;
} 124 125 }
return false; 125 126 return false;
} else { 126 127 } else {
127 128
} 128 129 }
}); 129 130 });
$('button#blank-selected').click(function() { 130 131 $('button#blank-selected').click(function() {
console.log(window.getSelection()); 131 132 console.log(window.getSelection());
document.execCommand('bold'); 132 133 document.execCommand('bold');
}); 133 134 });
$scope.refreshCards(); 134 135 $scope.refreshCards();
$scope.newCardBlanks = []; 135 136 $scope.newCardBlanks = [];
$scope.refreshNewCardInput = function() { 136 137 $scope.refreshNewCardInput = function() {
$scope.newCardText = $('#new-card-input').text(); 137 138 $scope.newCardText = $('#new-card-input').text();
$scope.submit_enabled = $scope.newCardText.length >= 5 && $scope.newCardText.length <= 160; 138 139 $scope.submit_enabled = $scope.newCardText.length >= 5 && $scope.newCardText.length <= 160;
var i = 0; 139 140 var i = 0;
$scope.newCardBlanks = []; 140 141 $scope.newCardBlanks = [];
$('#new-card-input')[0].childNodes.forEach(function(node) { 141 142 $('#new-card-input')[0].childNodes.forEach(function(node) {
node = $(node)[0]; 142 143 node = $(node)[0];
if (node.tagName == 'B') { 143 144 if (node.tagName == 'B') {
var text = $(node).text(); 144 145 var text = $(node).text();
var leftspaces = 0, rightspaces = 0; 145 146 var leftspaces = 0, rightspaces = 0;
// awful way to find the first non-space character from the left or the right. thanks.js 146 147 // awful way to find the first non-space character from the left or the right. thanks.js
while (text[leftspaces] == ' ' || text[leftspaces] == '\xa0') leftspaces++; 147 148 while (text[leftspaces] == ' ' || text[leftspaces] == '\xa0') leftspaces++;
while (text[text.length - 1 - rightspaces] == ' ' || text[text.length - 1 - rightspaces] == '\xa0') rightspaces++; 148 149 while (text[text.length - 1 - rightspaces] == ' ' || text[text.length - 1 - rightspaces] == '\xa0') rightspaces++;
console.log(leftspaces, text.length); 149 150 console.log(leftspaces, text.length);
if (leftspaces != text.length) $scope.newCardBlanks.push([i + leftspaces, i + text.length - rightspaces]); 150 151 if (leftspaces != text.length) $scope.newCardBlanks.push([i + leftspaces, i + text.length - rightspaces]);
i += text.length; 151 152 i += text.length;
} else if (!node.data) { 152 153 } else if (!node.data) {
i += $(node).text().length; 153 154 i += $(node).text().length;
} else { 154 155 } else {
i += node.data.length; 155 156 i += node.data.length;
} 156 157 }
}); 157 158 });
$scope.newCardBlanks.sort(function(a, b) { 158 159 $scope.newCardBlanks.sort(function(a, b) {
return a[0] - b[0]; 159 160 return a[0] - b[0];
}); 160 161 });
i = 0; 161 162 i = 0;
newtext = ''; 162 163 newtext = '';
$scope.newCardBlanks.forEach(function(blank) { 163 164 $scope.newCardBlanks.forEach(function(blank) {
newtext += $scope.newCardText.slice(i, blank[0]); 164 165 newtext += $scope.newCardText.slice(i, blank[0]);
newtext += '<b>' + $scope.newCardText.slice(blank[0], blank[1]) + '</b>'; 165 166 newtext += '<b>' + $scope.newCardText.slice(blank[0], blank[1]) + '</b>';
i = blank[1]; 166 167 i = blank[1];
}); 167 168 });
newtext += $scope.newCardText.slice(i); 168 169 newtext += $scope.newCardText.slice(i);
styles/flashy.css View file @ 0adf8f8
๏ปฟ.no-user-select { 1 1 ๏ปฟ.no-user-select {
-moz-user-select: none; 2 2 -moz-user-select: none;
-webkit-user-select: none; 3 3 -webkit-user-select: none;
-ms-user-select: none; 4 4 -ms-user-select: none;
user-select: none; 5 5 user-select: none;
} 6 6 }
7 7
.angucomplete-dropdown { 8 8 .angucomplete-dropdown {
border-color: #ececec; 9 9 border-color: #ececec;
border-width: 1px; 10 10 border-width: 1px;
border-style: solid; 11 11 border-style: solid;
border-radius: 2px; 12 12 border-radius: 2px;
/*width: 250px;*/ 13 13 /*width: 250px;*/
padding: 6px; 14 14 padding: 6px;
cursor: pointer; 15 15 cursor: pointer;
z-index: 9999; 16 16 z-index: 9999;
position: absolute; 17 17 position: absolute;
/*top: 32px; 18 18 /*top: 32px;
left: 0px; 19 19 left: 0px;
*/ 20 20 */
margin-top: -6px; 21 21 margin-top: -6px;
background-color: #ffffff; 22 22 background-color: #ffffff;
} 23 23 }
24 24
.angucomplete-description { 25 25 .angucomplete-description {
font-size: 14px; 26 26 font-size: 14px;
} 27 27 }
28 28
.angucomplete-row { 29 29 .angucomplete-row {
padding: 5px; 30 30 padding: 5px;
color: #000000; 31 31 color: #000000;
margin-bottom: 4px; 32 32 margin-bottom: 4px;
clear: both; 33 33 clear: both;
} 34 34 }
35 35
.angucomplete-selected-row { 36 36 .angucomplete-selected-row {
background-color: #aaaaff; 37 37 background-color: #aaaaff;
} 38 38 }
39 39
/*.container .row {*/ 40 40 /*.container .row {*/
/*margin-left: 0;*/ 41 41 /*margin-left: 0;*/
/*margin-right: 0;*/ 42 42 /*margin-right: 0;*/
/*}*/ 43 43 /*}*/
44 44
/* Flashcard directive css */ 45 45 /* Flashcard directive css */
.card { 46 46 .card {
word-wrap: break-word; 47 47 word-wrap: break-word;
} 48 48 }
49 49
.card.flashy.in-deck { 50 50 .card.flashy.in-deck {
border: 3px solid rgba(0, 184, 76, 0.4); 51 51 border: 3px solid rgba(0, 184, 76, 0.4);
} 52 52 }
53 53
.card.flashy { 54 54 .card.flashy {
55 border: 0px solid rgba(0, 184, 76, 0.4);
background-color: #fff; 55 56 background-color: #fff;
font-family: 'Titillium Web', sans-serif; 56 57 font-family: 'Titillium Web', sans-serif;
float: left; 57 58 float: left;
text-align: center; 58 59 text-align: center;
margin: 6px; 59 60 margin: 6px;
/*transition: all 0.2s cubic-bezier(0, 0, 0.6, 1);*/ 60 61 /*transition: all 0.2s cubic-bezier(0, 0, 0.6, 1);*/
} 61 62 }
62 63
.card.flashy.shrinky { 63 64 /*.card.flashy.shrinky {*/
height: 0; 64 65 /*height: 0;*/
opacity: 0; 65 66 /*opacity: 0;*/
overflow: hidden; 66 67 /*overflow: hidden;*/
} 67 68 /*}*/
68 69
.card-overlay { 69 70 .card-overlay {
cursor: pointer; 70 71 cursor: pointer;
left: 0; 71 72 left: 0;
opacity: 0; 72 73 opacity: 0;
position: absolute; 73 74 position: absolute;
/*pointer-events: none;*/ 74 75 /*pointer-events: none;*/
top: 0; 75 76 top: 0;
transition: visibility 0s cubic-bezier(0, 0, 0.6, 1) 0.2s, 76 77 transition: visibility 0s cubic-bezier(0, 0, 0.6, 1) 0.2s,
opacity 0.2s cubic-bezier(0, 0, 0.6, 1); 77 78 opacity 0.2s cubic-bezier(0, 0, 0.6, 1);
/* animation effect to appear on off-hover */ 78 79 /* animation effect to appear on off-hover */
visibility: hidden; 79 80 visibility: hidden;
height: 100%; 80 81 height: 100%;
width: 100%; 81 82 width: 100%;
} 82 83 }
83 84
.card-overlay i { 84 85 .card-overlay i {
color: #FFF; 85 86 color: #FFF;
left: 50%; 86 87 left: 50%;
position: absolute; 87 88 position: absolute;
top: 50%; 88 89 top: 50%;
transform: translate(-50%, -50%); 89 90 transform: translate(-50%, -50%);
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 90 91 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
} 91 92 }
92 93
.center-me:hover i { 93 94 .center-me:hover i {
text-shadow: 0 0 15px rgba(255, 255, 255, 0.9); 94 95 text-shadow: 0 0 15px rgba(255, 255, 255, 0.9);
} 95 96 }
96 97
.card:hover .card-overlay { 97 98 .card:hover .card-overlay {
opacity: 1.0; 98 99 opacity: 1.0;
transition-delay: 0s; /* animation effect to appear on hover */ 99 100 transition-delay: 0s; /* animation effect to appear on hover */
visibility: visible; 100 101 visibility: visible;
} 101 102 }
102 103
.top-box { 103 104 .top-box {
background-color: rgba(0, 184, 76, 0.4); 104 105 background-color: rgba(0, 184, 76, 0.4);
height: 65%; 105 106 height: 65%;
position: relative; 106 107 position: relative;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 107 108 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
width: 100%; 108 109 width: 100%;
} 109 110 }
110 111
.top-box:hover { 111 112 .top-box:hover {
background-color: rgba(0, 184, 76, 0.5); 112 113 background-color: rgba(0, 184, 76, 0.5);
} 113 114 }
114 115
.bottom-box { 115 116 .bottom-box {
height: 35%; 116 117 height: 35%;
width: 100%; 117 118 width: 100%;
} 118 119 }
119 120
.left-box { 120 121 .left-box {
background-color: rgba(119, 146, 255, 0.5); 121 122 background-color: rgba(119, 146, 255, 0.5);
float: left; 122 123 float: left;
position: relative; 123 124 position: relative;
height: 100%; 124 125 height: 100%;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 125 126 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
width: 50%; 126 127 width: 50%;
} 127 128 }
128 129
.left-box:hover { 129 130 .left-box:hover {
background-color: rgba(119, 146, 255, 0.6); 130 131 background-color: rgba(119, 146, 255, 0.6);
} 131 132 }
132 133
.right-box { 133 134 .right-box {
background-color: rgba(255, 62, 76, 0.5); 134 135 background-color: rgba(255, 62, 76, 0.5);
float: right; 135 136 float: right;
height: 100%; 136 137 height: 100%;
position: relative; 137 138 position: relative;
transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s; 138 139 transition: all 0.2s cubic-bezier(0, 0, 0.6, 1) 0s;
width: 50%; 139 140 width: 50%;
} 140 141 }
141 142
.right-box:hover { 142 143 .right-box:hover {
background-color: rgba(255, 62, 76, 0.6); 143 144 background-color: rgba(255, 62, 76, 0.6);
} 144 145 }
145 146
.center-me { 146 147 .center-me {
height: 100%; 147 148 height: 100%;
margin: 0 auto; 148 149 margin: 0 auto;
text-align: center; 149 150 text-align: center;
vertical-align: middle; 150 151 vertical-align: middle;
width: 100%; 151 152 width: 100%;
} 152 153 }
153 154
/* Card Colors */ 154 155 /* Card Colors */
.card.flashy.cardcolor-blue div { 155 156 .card.flashy.cardcolor-blue div {
background-color: rgba(119, 158, 203, 0.5) !important; 156 157 background-color: rgba(119, 158, 203, 0.5) !important;
} 157 158 }
158 159
.cardcolor-red div { 159 160 .cardcolor-red div {
background-color: rgba(255, 105, 97, 0.5) !important; 160 161 background-color: rgba(255, 105, 97, 0.5) !important;
} 161 162 }
162 163
.cardcolor-green div { 163 164 .cardcolor-green div {
background-color: rgba(119, 190, 119, 0.5) !important; 164 165 background-color: rgba(119, 190, 119, 0.5) !important;
} 165 166 }
166 167
.cardcolor-yellow div { 167 168 .cardcolor-yellow div {
background-color: rgba(253, 253, 150, 0.5) !important; 168 169 background-color: rgba(253, 253, 150, 0.5) !important;
} 169 170 }
170 171
/* Card Colors END */ 171 172 /* Card Colors END */
172 173
.modal.bottom-sheet { 173 174 .modal.bottom-sheet {
max-width: 600px; 174 175 max-width: 600px;
margin-left: auto; 175 176 margin-left: auto;
margin-right: auto; 176 177 margin-right: auto;
} 177 178 }
178 179
.feed-modal-input { 179 180 .feed-modal-input {
background-color: #D3D3D3; 180 181 background-color: #D3D3D3;
/ / border-style : solid; 181 182 border-style: solid;
/ / border-width : 1 px; 182 183 border-width: 1px;
box-shadow: 2px 2px 5px #888888; 183 184 box-shadow: 2px 2px 5px #888888;
height: 24px; 184 185 height: 24px;
} 185 186 }
186 187
#newCard input[type=text] { 187
height: 3rem !important; 188
} 189
190
.input-field label { 191 188 .input-field label {
color: #00b3c2; 192 189 color: #00b3c2;
} 193 190 }
194 191
/* label focus color */ 195 192 /* label focus color */
.input-field input[type]:focus + label { 196 193 .input-field input[type]:focus + label {
color: #00b3c2; 197 194 color: #00b3c2;
} 198 195 }
199 196
/* label underline focus color */ 200 197 /* label underline focus color */
.input-field input[type]:focus { 201 198 .input-field input[type]:focus {
border-bottom: 1px solid #00b3c2; 202 199 border-bottom: 1px solid #00b3c2;
box-shadow: 0 1px 0 0 #b388ff; 203 200 box-shadow: 0 1px 0 0 #b388ff;
} 204 201 }
205 202
/* valid color */ 206 203 /* valid color */
.input-field input[type].valid { 207 204 .input-field input[type].valid {
border-bottom: 1px solid #00c28f; 208 205 border-bottom: 1px solid #00c28f;
box-shadow: 0 1px 0 0 #673ab7; 209 206 box-shadow: 0 1px 0 0 #673ab7;
} 210 207 }
211 208
/* invalid color */ 212 209 /* invalid color */
.input-field input[type].invalid { 213 210 .input-field input[type].invalid {
border-bottom: 1px solid #673ab7; 214 211 border-bottom: 1px solid #673ab7;
box-shadow: 0 1px 0 0 #673ab7; 215 212 box-shadow: 0 1px 0 0 #673ab7;
} 216 213 }
217 214
/* icon prefix focus color */ 218 215 /* icon prefix focus color */
.input-field .prefix.active { 219 216 .input-field .prefix.active {
color: #b388ff; 220 217 color: #b388ff;
} 221 218 }
222 219
/* label focus color */ 223 220 /* label focus color */
.input-field textarea[type]:focus + label { 224 221 .input-field textarea[type]:focus + label {
color: #b388ff; 225 222 color: #b388ff;
} 226 223 }
227 224
/* label underline focus color */ 228 225 /* label underline focus color */
.input-field textarea[type]:focus { 229 226 .input-field textarea[type]:focus {
border-bottom: 1px solid #00b3c2; 230 227 border-bottom: 1px solid #00b3c2;
box-shadow: 0 1px 0 0 #b388ff; 231 228 box-shadow: 0 1px 0 0 #b388ff;
} 232 229 }
233 230
body { 234 231 body {
background-color: #e8e8e8; 235 232 background-color: #e8e8e8;
overflow-x: hidden; 236 233 overflow-x: hidden;
font-family: 'Titillium Web', sans-serif; 237 234 font-family: 'Titillium Web', sans-serif;
height: 100%; 238 235 height: 100%;
} 239 236 }
240 237
html { 241 238 html {
background: transparent; 242 239 background: transparent;
height: 100%; 243 240 height: 100%;
} 244 241 }
245 242
.btn { 246 243 .btn {
background-color: #00b3c2; 247 244 background-color: #00b3c2;
} 248 245 }
249 246
.btn:hover { 250 247 .btn:hover {
background-color: #0097cb; 251 248 background-color: #0097cb;
} 252 249 }
253 250
.btn-floating { 254 251 .btn-floating {
background-color: #00b3c2; 255 252 background-color: #00b3c2;
} 256 253 }
257 254
.btn-floating:hover { 258 255 .btn-floating:hover {
background-color: #0097cb; 259 256 background-color: #0097cb;
} 260 257 }
261 258
.toggley { 262 259 .toggley {
float: left; 263 260 float: left;
margin: 10px; 264 261 margin: 10px;
} 265 262 }
266 263
#logo-container { 267 264 #logo-container {
margin-bottom: 18px; 268 265 margin-bottom: 18px;
} 269 266 }
270 267
#lean-overlay { 271 268 #lean-overlay {
display: none !important; 272 269 display: none !important;
} 273 270 }
274 271
nav { 275 272 nav {
background-color: #d2143f !important; 276 273 background-color: #d2143f !important;
} 277 274 }
278 275
main { 279 276 main {
min-height: 145px; 280 277 min-height: 145px;
} 281 278 }
282 279
.side-nav .collapsible-body { 283 280 .side-nav .collapsible-body {
width: 100%; 284 281 width: 100%;
} 285 282 }
286 283
.side-nav .collapsible-body li.active, .side-nav.fixed .collapsible-body li.active { 287 284 .side-nav .collapsible-body li.active, .side-nav.fixed .collapsible-body li.active {
background-color: #00b3c2; 288 285 background-color: #00b3c2;
} 289 286 }
290 287
nav .button-collapse { 291 288 nav .button-collapse {
margin: 0 20px; 292 289 margin: 0 20px;
} 293 290 }
294 291
.collapsible-body i { 295 292 .collapsible-body i {
font-size: 1rem !important; 296 293 font-size: 1rem !important;
} 297 294 }
298 295
.tabs .tab a { 299 296 .tabs .tab a {
color: #00b3c2; 300 297 color: #00b3c2;
} 301 298 }
302 299
.tabs .tab a:hover { 303 300 .tabs .tab a:hover {
color: #0041dd; 304 301 color: #0041dd;
} 305 302 }
306 303
.tabs .indicator { 307 304 .tabs .indicator {
border-bottom: 1px solid #00b3c2; 308 305 border-bottom: 1px solid #00b3c2;
} 309 306 }
310 307
h2 { 311 308 h2 {
text-align: center; 312 309 text-align: center;
} 313 310 }
314 311
md-content.md-default-theme { 315 312 md-content.md-default-theme {
background-color: rgba(255, 255, 255, 0); 316 313 background-color: rgba(255, 255, 255, 0);
border: 1px solid #fff; 317 314 border: 1px solid #fff;
} 318 315 }
319 316
/*#sidenav-overlay { 320 317 /*#sidenav-overlay {
background-color: rgba(0, 0, 0, 0) !important; 321 318 background-color: rgba(0, 0, 0, 0) !important;
}*/ 322 319 }*/
.card-content { 323 320 .card-content {
width: 100%; 324 321 width: 100%;
} 325 322 }
326 323
.valign-wrapper { 327 324 .valign-wrapper {
height: 100%; 328 325 height: 100%;
} 329 326 }
330 327
/*.toast { 331 328 /*.toast {
height: 100px; 332 329 height: 100px;
width: 300px; 333 330 width: 300px;
line-height: 20px; 334 331 line-height: 20px;
max-height: 100px; 335 332 max-height: 100px;
word-wrap: normal; 336 333 word-wrap: normal;
}*/ 337 334 }*/
338 335
[ng-cloak] { 339 336 [ng-cloak] {
display: none !important; 340 337 display: none !important;
} 341 338 }
342 339
.cardColumn { 343 340 .cardColumn {
float: left; 344 341 float: left;
} 345 342 }
346 343
/* Animation CSS, http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html */ 347 344 /* Animation CSS, http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html */
.repeated-card.ng-enter, 348 345 .repeated-card.ng-enter,
.repeated-card.ng-enter > flashcard > .card, 349 346 .repeated-card.ng-enter > flashcard > .card,
.repeated-card.ng-leave, 350 347 .repeated-card.ng-leave,
348 .repeated-card.ng-leave > flashcard > .card,
.repeated-card.ng-move, 351 349 .repeated-card.ng-move,
.repeated-card.ng-move > flashcard > .card { 352 350 .repeated-card.ng-move > flashcard > .card {
-webkit-transition: 0.5s all cubic-bezier(0, 0, 0.6, 1); 353 351 -webkit-transition: 0.5s all cubic-bezier(0, 0, 0.6, 1);
-moz-transition: 0.5s all cubic-bezier(0, 0, 0.6, 1); 354 352 -moz-transition: 0.5s all cubic-bezier(0, 0, 0.6, 1);
-o-transition: 0.5s all cubic-bezier(0, 0, 0.6, 1); 355 353 -o-transition: 0.5s all cubic-bezier(0, 0, 0.6, 1);
transition: 1s cubic-bezier(0.6, 0.3, 0.7, 1.4); 356 354 transition: 1s all cubic-bezier(0.6, 0.3, 0.7, 1.0);
/*1s all cubic-bezier(0, 0, 1, 0.3);*/ 357
position: relative; 358 355 position: relative;
} 359 356 }
360 357
.repeated-card.ng-enter > flashcard > .card { 361 358 .repeated-card.ng-enter > flashcard > .card {
z-index: 1; 362 359 z-index: 1;
top: -236px; 363 360 top: -236px;
margin-bottom: -230px; 364 361 margin-bottom: -230px;
} 365 362 }
366 363
.repeated-card.ng-enter.ng-enter-active > flashcard > .card { 367 364 .repeated-card.ng-enter.ng-enter-active > flashcard > .card {
top: 0px; 368 365 top: 0px;
margin-bottom: 6px; 369 366 margin-bottom: 6px;
} 370 367 }
371 368
.repeated-card.ng-leave { 372 369 .repeated-card.ng-leave > flashcard > .card {
top: 0; 373 370 z-index: -100;
opacity: 1; 374 371 top: 0px;
372 margin-bottom: 6px;
} 375 373 }
376 374
.repeated-card.ng-leave.ng-leave-active { 377 375 .repeated-card.ng-leave.ng-leave-active > flashcard > .card {
top: -60px; 378 376 z-index: -100;
opacity: 0; 379 377 opacity: 0;
378 top: -236px;
379 margin-bottom: -230px;
} 380 380 }
381 381
/* Animation CSS END */ 382 382 /* Animation CSS END */
383
/* Footer */ 384
* { 385
margin: 0; 386
} 387
388
/*.wrapper {*/ 389
/*min-height: 100%;*/ 390
/*height: 100%;*/ 391
/*/!*margin: 0 auto -4em;*!/*/ 392
/*}*/ 393
394 383
.container, .push { 395 384 .container, .push {
height: 4em; 396 385 height: 4em;
} 397 386 }
398 387
#resetPasswordForm { 399 388 #resetPasswordForm {
display: block; 400 389 display: block;
margin-left: auto; 401 390 margin-left: auto;
templates/flashcard.html View file @ 0adf8f8
<div class="card flashy smallify cyan-text text-darken-2" ng-init="startShrink = false" 1 1 <div class="card flashy smallify black-text text-darken-2" ng-init="startShrink = false"
ng-class="{'shrinky': startShrink, 'in-deck':flashcard.isInDeck()}"> 2 2 ng-class="{'shrinky': startShrink, 'in-deck':flashcard.isInDeck()}">
<div class="valign-wrapper"> 3 3 <div class="valign-wrapper">
<div class="card-content valign center-align" ng-bind-html="flashcard.formatted_text"> 4 4 <div class="card-content valign center-align" ng-bind-html="flashcard.formatted_text"></div>
<!--<span ng-repeat="piece in flashcard.textPieces"--> 5
<!--ng-style="piece.blank ? {'opacity':'0.4', 'border-bottom': '1px solid black'} : {}">{{piece.text}}</span>--> 6
</div> 7
</div> 8 5 </div>
<div class="card-overlay" > 9 6 <div class="card-overlay">
<div class="top-box no-user-select" ng-show="!flashcard.isInDeck()" 10 7 <div class="top-box no-user-select" ng-show="!flashcard.isInDeck()"
ng-click="flashcard.pull()"> 11 8 ng-click="flashcard.pull()">
<div class="center-me"><i class="mdi-content-add-circle-outline medium"></i></div> 12 9 <div class="center-me"><i class="mdi-content-add-circle-outline medium"></i></div>
</div> 13 10 </div>
<div class="top-box no-user-select" ng-show="flashcard.isInDeck()" 14 11 <div class="top-box no-user-select" ng-show="flashcard.isInDeck()"
ng-click="flashcard.unpull()"> 15 12 ng-click="flashcard.unpull()">
<div class="center-me"><i class="mdi-content-remove-circle-outline medium"></i></div> 16 13 <div class="center-me"><i class="mdi-content-remove-circle-outline medium"></i></div>
</div> 17 14 </div>
<div class="bottom-box no-user-select"> 18 15 <div class="bottom-box no-user-select">
<div class="left-box"> 19 16 <div class="left-box tooltipped" data-position="bottom" data-tooltip="Info">
<div class="center-me"><i class="mdi-action-info-outline small"></i></div> 20 17 <div class="center-me"><i class="mdi-action-info-outline small"></i></div>
</div> 21 18 </div>
<div class="right-box" ng-click="flashcard.hide()"> 22 19 <div class="right-box tooltipped" ng-click="flashcard.hide()" data-position="bottom" data-tooltip="Hide">
<div class="center-me"><i class="mdi-action-delete small"></i></div> 23 20 <div class="center-me"><i class="mdi-action-delete small"></i></div>
</div> 24 21 </div>
25 22
</div> 26 23 </div>
</div> 27 24 </div>
<div ng-show="flashcard.isInDeck()" class="green-text" style="position:absolute; top:-9px;right:0px"> 28 25 <div ng-show="flashcard.isInDeck()" class="green-text" style="position:absolute; top:-9px;right:0px">
<div class="center-me tooltipped" data-position="bottom" 29 26 <div class="center-me tooltipped" data-position="bottom" data-tooltip="In deck"><i
data-delay="50" data-tooltip="In deck"><i class="mdi-action-done small"></i></div> 30 27 class="mdi-action-done small"></i></div>
</div> 31 28 </div>
<div ng-show="$root.debug_flashcard" style="position:absolute; bottom:0px; right:5px;"> 32 29 <div ng-show="$root.debug_flashcard" style="position:absolute; bottom:0px; right:5px;">
<span class="center-me">score:{{flashcard.score}}</span> 33 30 <span class="center-me">score:{{flashcard.score}}</span>
</div> 34 31 </div>
</div> 35 32 </div>
36 33