Compare View
Commits (2)
Diff
Showing 3 changed files Inline Diff
scripts/FlashcardDirective.js
View file @
fc88fb8
angular.module('flashy.FlashcardDirective', []). | 1 | 1 | angular.module('flashy.FlashcardDirective', []). | |
2 | 2 | |||
directive('flashcard', | 3 | 3 | directive('flashcard', | |
4 | 4 | |||
5 | 5 | |||
function($http, $state, $window) { | 6 | 6 | function($http, $state, $window) { | |
return { | 7 | 7 | return { | |
templateUrl: '/app/templates/flashcard.html', | 8 | 8 | templateUrl: '/app/templates/flashcard.html', | |
restrict: 'E', | 9 | 9 | restrict: 'E', | |
scope: { | 10 | 10 | scope: { | |
flashcard: '=flashcardObj', // flashcard-obj in parent html | 11 | 11 | flashcard: '=flashcardObj', // flashcard-obj in parent html | |
refresh: '&' // eval refresh in parent html | 12 | 12 | refresh: '&' // eval refresh in parent html | |
}, | 13 | 13 | }, | |
14 | colNum: 0, | |||
15 | colRank: 0, | |||
16 | /*link: function(scope, element) { | |||
17 | ||||
colNum: 0, | 14 | 18 | link: function(scope, element) { | |
colRank: 0, | 15 | 19 | $('.tooltipped').tooltip(); | |
/*link: function(scope, element) { | 16 | 20 | // /* Handles width of the card */ | |
$('.tooltipped').tooltip(); | 17 | 21 | //} | |
// /* Handles width of the card */ | 18 | 22 | }; | |
//} | 19 | 23 | } | |
}; | 20 | 24 |
scripts/FlashcardFactory.js
View file @
fc88fb8
angular.module('flashy.FlashcardFactory', ['ui.router']). | 1 | 1 | angular.module('flashy.FlashcardFactory', ['ui.router']). | |
factory('Flashcard', function ($http, UserService) { | 2 | 2 | factory('Flashcard', function ($http, UserService) { | |
var FlashcardCache = []; | 3 | 3 | var FlashcardCache = []; | |
var Deck = null; | 4 | 4 | var Deck = null; | |
var Flashcard = function (data) { | 5 | 5 | var Flashcard = function (data) { | |
if (typeof data == 'number') return FlashcardCache[data]; | 6 | 6 | if (typeof data == 'number') return FlashcardCache[data]; | |
if (FlashcardCache[data.id]) return FlashcardCache[data.id]; | 7 | 7 | if (FlashcardCache[data.id]) return FlashcardCache[data.id]; | |
for (var k in data) this[k] = data[k]; | 8 | 8 | for (var k in data) this[k] = data[k]; | |
this.textPieces = []; | 9 | 9 | this.textPieces = []; | |
this.mask.sort(function (a, b) { | 10 | 10 | this.mask.sort(function (a, b) { | |
return a[0] - b[0]; | 11 | 11 | return a[0] - b[0]; | |
}); | 12 | 12 | }); | |
var i = 0; | 13 | 13 | var i = 0; | |
this.mask.forEach(function (blank) { | 14 | 14 | this.mask.forEach(function (blank) { | |
this.textPieces.push({text: this.text.slice(i, blank[0])}); | 15 | 15 | this.textPieces.push({text: this.text.slice(i, blank[0])}); | |
this.textPieces.push({text: this.text.slice(blank[0], blank[1]), blank: true}); | 16 | 16 | this.textPieces.push({text: this.text.slice(blank[0], blank[1]), blank: true}); | |
i = blank[1]; | 17 | 17 | i = blank[1]; | |
}, this); | 18 | 18 | }, this); | |
this.textPieces.push({text: this.text.slice(i)}); | 19 | 19 | this.textPieces.push({text: this.text.slice(i)}); | |
this.formatted_text = ''; | 20 | 20 | this.formatted_text = ''; | |
for (i in this.textPieces) { | 21 | 21 | for (i in this.textPieces) { | |
p = this.textPieces[i]; | 22 | 22 | p = this.textPieces[i]; | |
this.formatted_text += p.blank ? '<b>' + p.text + '</b>' : p.text; | 23 | 23 | this.formatted_text += p.blank ? '<b>' + p.text + '</b>' : p.text; | |
} | 24 | 24 | } | |
FlashcardCache[this.id] = this; | 25 | 25 | this.moveUp = false; | |
}; | 26 | 26 | this.moveDown = false; | |
27 | 27 | this.colNum = 0; | ||
Flashcard.prototype.isInDeck = function () { | 28 | 28 | this.colRank = 0; | |
return !(typeof Deck.contains(this.id) === 'undefined'); | 29 | 29 | FlashcardCache[this.id] = this; | |
}; | 30 | 30 | }; | |
Flashcard.prototype.pullUnpull = function () { | 31 | 31 | ||
if (this.isInDeck()) this.unpull(); | 32 | 32 | Flashcard.prototype.isInDeck = function () { | |
else this.pull(); | 33 | 33 | return !(typeof Deck.contains(this.id) === 'undefined'); | |
}; | 34 | 34 | }; | |
Flashcard.prototype.pull = function () { | 35 | 35 | Flashcard.prototype.pullUnpull = function () { | |
if (this.isInDeck()) return console.log('Not pulling', this.id, "because it's already in deck"); | 36 | 36 | if (this.isInDeck()) this.unpull(); | |
return $http.post('/api/flashcards/' + this.id + '/pull/'); | 37 | 37 | else this.pull(); | |
}; | 38 | 38 | }; | |
Flashcard.prototype.unpull = function () { | 39 | 39 | Flashcard.prototype.pull = function () { | |
if (!this.isInDeck()) return console.log('Not unpulling', this.id, "because it's not in deck"); | 40 | 40 | if (this.isInDeck()) return console.log('Not pulling', this.id, "because it's already in deck"); | |
return $http.post('/api/flashcards/' + this.id + '/unpull/'); | 41 | 41 | return $http.post('/api/flashcards/' + this.id + '/pull/'); | |
}; | 42 | 42 | }; | |
Flashcard.prototype.hide = function () { | 43 | 43 | Flashcard.prototype.unpull = function () { | |
return $http.post('/api/flashcards/' + this.id + '/hide/'); | 44 | 44 | if (!this.isInDeck()) return console.log('Not unpulling', this.id, "because it's not in deck"); | |
}; | 45 | 45 | return $http.post('/api/flashcards/' + this.id + '/unpull/'); | |
Flashcard.prototype.unhide = function () { | 46 | 46 | }; | |
return $http.post('/api/flashcards/' + this.id + '/unhide/'); | 47 | 47 | Flashcard.prototype.hide = function () { | |
}; | 48 | 48 | return $http.post('/api/flashcards/' + this.id + '/hide/'); | |
Flashcard.cleanup = function () { | 49 | 49 | }; | |
Deck = null; | 50 | 50 | Flashcard.prototype.unhide = function () { | |
FlashcardCache = []; | 51 | 51 | return $http.post('/api/flashcards/' + this.id + '/unhide/'); | |
}; | 52 | 52 | }; | |
Flashcard.linkDeck = function(deck){ | 53 | 53 | Flashcard.cleanup = function () { | |
Deck = deck; | 54 | 54 | Deck = null; | |
} | 55 | 55 | FlashcardCache = []; | |
56 | 56 | }; | ||
Flashcard.prototype.edit = function () { | 57 | 57 | Flashcard.linkDeck = function(deck){ | |
58 | 58 | Deck = deck; | ||
59 | 59 | } | ||
var editableText = this.formatted_text; | 60 | 60 | ||
61 | 61 | Flashcard.prototype.edit = function () { | ||
$('.modal-trigger').leanModal({ | 62 | 62 | ||
dismissible: true, // Modal can be dismissed by clicking outside of the modal | 63 | 63 | ||
opacity: .5, // Opacity of modal background | 64 | 64 | var editableText = this.formatted_text; | |
in_duration: 300, // Transition in duration | 65 | 65 | ||
out_duration: 200, // Transition out duration | 66 | |||
ready: function () { | 67 | |||
68 | 66 | $('.modal-trigger').leanModal({ | ||
$('#edit-card-input').html(editableText); | 69 | 67 | dismissible: true, // Modal can be dismissed by clicking outside of the modal | |
70 | 68 | opacity: .5, // Opacity of modal background | ||
71 | 69 | in_duration: 300, // Transition in duration | ||
}, // Callback for Modal open | 72 | 70 | out_duration: 200, // Transition out duration | |
complete: function () { | 73 | 71 | ready: function () { | |
74 | 72 | |||
console.log("EDIT MODAL CLOSED"); | 75 | 73 | $('#edit-card-input').html(editableText); | |
76 | 74 | |||
} // Callback for Modal close | 77 | 75 | ||
}); | 78 | |||
79 | 76 | }, // Callback for Modal open | ||
}; | 80 | 77 | complete: function () { | |
81 | 78 | |||
82 | 79 | console.log("EDIT MODAL CLOSED"); | ||
83 | 80 | |||
Flashcard.prototype.refreshEditCardInput = function () { | 84 | 81 | } // Callback for Modal close | |
85 | 82 | }); | ||
this.editCardText = $('#edit-card-input').text(); | 86 | 83 | ||
87 | 84 | }; | ||
this.submit_enabled = this.editCardText.length >= 5 && this.editCardText.length <= 160; | 88 | 85 | ||
89 | 86 | Flashcard.prototype.refreshEditCardInput = function () { | ||
90 | 87 | |||
91 | ||||
var i = 0; | 92 | |||
this.editCardBlanks = []; | 93 | |||
$('#edit-card-input')[0].childNodes.forEach(function (node) { | 94 | 88 | this.editCardText = $('#edit-card-input').text(); | |
node = $(node)[0]; | 95 | 89 | ||
if (node.tagName == 'B') { | 96 | |||
var text = $(node).text(); | 97 | 90 | this.submit_enabled = this.editCardText.length >= 5 && this.editCardText.length <= 160; | |
var leftspaces = 0, rightspaces = 0; | 98 | 91 | ||
// awful way to find the first non-space character from the left or the right. thanks.js | 99 | 92 | ||
while (text[leftspaces] == ' ' || text[leftspaces] == '\xa0') leftspaces++; | 100 | 93 | ||
while (text[text.length - 1 - rightspaces] == ' ' || text[text.length - 1 - rightspaces] == '\xa0') rightspaces++; | 101 | 94 | var i = 0; | |
console.log(leftspaces, text.length); | 102 | 95 | this.editCardBlanks = []; | |
if (leftspaces != text.length) $scope.editCardBlanks.push([i + leftspaces, i + text.length - rightspaces]); | 103 | 96 | $('#edit-card-input')[0].childNodes.forEach(function (node) { | |
i += text.length; | 104 | 97 | node = $(node)[0]; | |
} else if (!node.data) { | 105 | 98 | if (node.tagName == 'B') { | |
i += $(node).text().length; | 106 | 99 | var text = $(node).text(); | |
} else { | 107 | 100 | var leftspaces = 0, rightspaces = 0; | |
i += node.data.length; | 108 | 101 | // awful way to find the first non-space character from the left or the right. thanks.js | |
} | 109 | 102 | while (text[leftspaces] == ' ' || text[leftspaces] == '\xa0') leftspaces++; | |
}); | 110 | 103 | while (text[text.length - 1 - rightspaces] == ' ' || text[text.length - 1 - rightspaces] == '\xa0') rightspaces++; | |
this.editCardBlanks.sort(function (a, b) { | 111 | 104 | console.log(leftspaces, text.length); | |
return a[0] - b[0]; | 112 | 105 | if (leftspaces != text.length) $scope.editCardBlanks.push([i + leftspaces, i + text.length - rightspaces]); | |
}); | 113 | 106 | i += text.length; | |
i = 0; | 114 | 107 | } else if (!node.data) { | |
newtext = ''; | 115 | 108 | i += $(node).text().length; | |
this.editCardBlanks.forEach(function (blank) { | 116 | 109 | } else { | |
newtext += this.editCardText.slice(i, blank[0]); | 117 | 110 | i += node.data.length; | |
newtext += '<b>' + this.editCardText.slice(blank[0], blank[1]) + '</b>'; | 118 | 111 | } | |
i = blank[1]; | 119 | 112 | }); | |
}); | 120 | 113 | this.editCardBlanks.sort(function (a, b) { | |
newtext += this.editCardText.slice(i); | 121 | 114 | return a[0] - b[0]; | |
//$scope.newCardFormattedText = newtext;*/ | 122 | 115 | }); | |
123 | 116 | i = 0; | ||
124 | 117 | newtext = ''; | ||
}; | 125 | 118 | this.editCardBlanks.forEach(function (blank) { | |
126 | 119 | newtext += this.editCardText.slice(i, blank[0]); | ||
127 | 120 | newtext += '<b>' + this.editCardText.slice(blank[0], blank[1]) + '</b>'; | ||
128 | 121 | i = blank[1]; | ||
129 | 122 | }); | ||
Flashcard.prototype.pushCard = function () { | 130 | 123 | newtext += this.editCardText.slice(i); | |
131 | 124 | //$scope.newCardFormattedText = newtext;*/ | ||
//console.log() | 132 | 125 | ||
133 | 126 | |||
var myCard = { | 134 | 127 | }; | |
'text': $('#edit-card-input').text(), | 135 | 128 | ||
'mask': this.editCardBlanks, | 136 | 129 | ||
//section: this.section.id | 137 | 130 | ||
}; | 138 | 131 | ||
if (myCard.text == '') { | 139 | 132 | Flashcard.prototype.pushCard = function () { | |
console.log('blank flashcard not pushed:' + myCard.text); | 140 | 133 | ||
//return closeNewCard(); | 141 | 134 | //console.log() | |
142 | 135 |
templates/flashcard.html
View file @
fc88fb8
<div class="card flashy smallify black-text text-darken-2" ng-class="{'in-deck':flashcard.isInDeck()}"> | 1 | 1 | <div class="card flashy smallify black-text text-darken-2" | |
2 | 2 | ng-class="{'in-deck':flashcard.isInDeck(), 'card-moveUp':flashcard.moveUp, | ||
<div class="card flashy black-text" | 3 | 3 | 'card-moveDown':flashcard.moveDown}"> | |
ng-class="{'in-deck':flashcard.isInDeck()}"> | 4 | 4 | <div class="valign-wrapper"> | |
<div class="valign-wrapper"> | 5 | 5 | <div class="card-content valign center-align" ng-bind-html="flashcard.formatted_text"></div> | |
<div class="card-content valign center-align" ng-bind-html="flashcard.formatted_text"></div> | 6 | 6 | </div> | |
</div> | 7 | 7 | ||
8 | 8 | |||
9 | 9 | <div class="card-overlay"> | ||
10 | 10 | <div class="top-box no-user-select" | ||
11 | 11 | ng-click="flashcard.pullUnpull()"> | ||
12 | 12 | <div class="center-me"> | ||
<div class="card-overlay"> | 13 | 13 | <i ng-if="flashcard.isInDeck()" class="fadey mdi-content-remove-circle-outline medium"></i> | |
<div class="top-box no-user-select" | 14 | 14 | <i ng-if="!flashcard.isInDeck()" class="fadey mdi-content-add-circle-outline medium"></i> | |
ng-click="flashcard.pullUnpull()"> | 15 | 15 | </div> | |
<div class="center-me"> | 16 | 16 | </div> | |
<i ng-if="flashcard.isInDeck()" class="fadey mdi-content-remove-circle-outline medium"></i> | 17 | 17 | <div class="bottom-box no-user-select"> | |
<i ng-if="!flashcard.isInDeck()" class="fadey mdi-content-add-circle-outline medium"></i> | 18 | 18 | ||
19 | <div class="left-box tooltipped" data-position=" bottom" data-tooltip="Edit"> | |||
20 | <div class="center-me modal-trigger" href="#editModal" ng-click="flashcard.edit()"><i class="mdi-editor-border-color small"></i></div> | |||
21 | </div> | |||
22 | ||||
</div> | 19 | 23 | ||
24 | <div class="right-box tooltipped" ng-click="flashcard.hide()" data-position="bottom" data-tooltip="Hide"> | |||
</div> | 20 | 25 | <div class="left-box"> | |
<div class="bottom-box no-user-select"> | 21 | 26 | <a class="center-me modal-trigger" href="#editModal" ng-click="flashcard.edit()"><i | |
22 | 27 | class="mdi-editor-border-color small"></i></a> | ||
23 | 28 | </div> | ||
<div class="left-box tooltipped" data-position=" bottom" data-tooltip="Edit"> | 24 | 29 | ||
<div class="center-me modal-trigger" href="#editModal" ng-click="flashcard.edit()"><i class="mdi-editor-border-color small"></i></div> | 25 | 30 | ||
</div> | 26 | 31 | <div class="right-box" ng-click="flashcard.hide()"> | |
27 | 32 | <div class="center-me"><i class="mdi-action-delete small"></i></div> | ||
28 | 33 | </div> | ||
<div class="right-box tooltipped" ng-click="flashcard.hide()" data-position="bottom" data-tooltip="Hide"> | 29 | 34 | ||
<div class="center-me"><i class="mdi-action-delete small"></i></div> | 30 | 35 | </div> | |
</div> | 31 | 36 | </div> | |
32 | 37 | |||
38 | <!-- Edit Modal --> | |||
39 | <div id="editModal" class="modal row" style="max-height:none;"> | |||
40 | <form id="edit-card-form"> | |||
41 | <div class="modal-content col"> | |||
42 | <div class="row" style="margin-bottom:0"> | |||
43 | <div class="card cyan-text text-darken-2" | |||
44 | style="width:300px; height:180px; margin-bottom:0; font-size:120%;"> | |||
45 | <div class="valign-wrapper"> | |||
46 | <div id="edit-card-input" ng-model="newCardFormattedText" style="outline:0px solid transparent;" | |||
47 | class="card-content valign center-align" | |||
48 | contenteditable select-non-editable="true" ng-change="flashcard.refreshEditCardInput()"> | |||
49 | </div> | |||
50 | </div> | |||
51 | </div> | |||
52 | </div> | |||
53 | </div> | |||
54 | <div class="col"> | |||
55 | <div class="row"> | |||
56 | </div> | |||
57 | <div class="row"> | |||
58 | <button class="btn modal-close tooltipped" type="submit" ng-click="flashcard.pushCard()" | |||
59 | data-position="left" | |||
60 | data-delay="50" ng-class="flashcard.submit_enabled?{}:'disabled'" | |||
61 | data-tooltip="Enter"> | |||
62 | Edit | |||
63 | <i class="mdi-action-done right"></i> | |||
64 | </button> | |||
65 | </div> | |||
66 | ||||
67 | ||||
68 | <div class="row"> | |||
69 | <button class="btn modal-close" ng-click="flashcard.discardChanges()" | |||
70 | data-position="left" | |||
71 | data-delay="50"> | |||
72 | Discard Changes | |||
73 | <i class="mdi-content-clear right"></i> | |||
74 | </button> | |||
75 | </div> | |||
76 | ||||
77 | <!--<div class="row"> | |||
78 | <button id="blank-selected" style="float:left" class="btn tooltipped" data-position="right" data-delay="50" | |||
79 | data-tooltip="Ctrl-B"> | |||
80 | Blank Selected Text | |||
81 | </button> | |||
82 | </div>--> | |||
83 | ||||
84 | ||||
85 | <div class="row" ng-show="flashcard.editCardText" ng-style="(flashcard.editCardText.length>160)?{color:'red'}:{}"> | |||
86 | {{flashcard.editCardText.length}}/160 characters | |||
87 | </div> | |||
88 | <div class="row" ng-show="flashcard.editCardText.length < 5"> | |||
89 | Please write a little more! | |||
90 | </div> | |||
91 | <div class="row" ng-show="flashcard.editCardText.length > 140"> | |||
92 | Good flashcards have a<br> | |||
93 | single atomic fact | |||
94 | </div> | |||
95 | </div> | |||
96 | </form> | |||
97 | </div> | |||
98 | ||||
99 | ||||
</div> | 33 | 100 | ||
</div> | 34 | 101 | <!--<div id="editModal" class="modal"> | |
35 | 102 | <div class="modal-content"> | ||
36 | 103 | <h4 id="flashcardEditText"></h4> | ||
<!-- Edit Modal --> | 37 | 104 | </div> | |
<div id="editModal" class="modal row" style="max-height:none;"> | 38 | 105 | <div class="modal-footer"> | |
<form id="edit-card-form"> | 39 | 106 | ||
<div class="modal-content col"> | 40 | 107 | </div> | |
<div class="row" style="margin-bottom:0"> | 41 | 108 | </div>--> | |
<div class="card cyan-text text-darken-2" | 42 | 109 | ||
style="width:300px; height:180px; margin-bottom:0; font-size:120%;"> | 43 | 110 | ||
<div class="valign-wrapper"> | 44 | 111 | <div ng-show="flashcard.isInDeck()" class="green-text" style="position:absolute; top:-9px;right:0px"> | |
<div id="edit-card-input" ng-model="newCardFormattedText" style="outline:0px solid transparent;" | 45 | 112 | <div class="center-me"><i | |
class="card-content valign center-align" | 46 | 113 | class="mdi-action-done small"></i></div> | |
contenteditable select-non-editable="true" ng-change="flashcard.refreshEditCardInput()"> | 47 | 114 | </div> | |
</div> | 48 | 115 | <div ng-show="rootScope.debug_flashcards" style="position:absolute; bottom:0px; right:5px;"> | |
</div> | 49 | 116 | <span class="center-me">score:{{flashcard.score}}</span> | |
</div> | 50 | 117 | </div> | |
</div> | 51 | 118 | ||
</div> | 52 | 119 | ||
<div class="col"> | 53 | 120 | </div> | |
<div class="row"> | 54 | 121 | ||
</div> | 55 | |||
<div class="row"> | 56 | |||
<button class="btn modal-close tooltipped" type="submit" ng-click="flashcard.pushCard()" | 57 | |||
data-position="left" | 58 | |||
data-delay="50" ng-class="flashcard.submit_enabled?{}:'disabled'" | 59 | |||
data-tooltip="Enter"> | 60 | |||
Edit | 61 | |||
<i class="mdi-action-done right"></i> | 62 | |||
</button> | 63 | |||
</div> | 64 | |||
65 | ||||
66 | ||||
<div class="row"> | 67 | |||
<button class="btn modal-close" ng-click="flashcard.discardChanges()" | 68 | |||
data-position="left" | 69 | |||
data-delay="50"> | 70 | |||
Discard Changes | 71 | |||
<i class="mdi-content-clear right"></i> | 72 | |||
</button> | 73 | |||
</div> | 74 | |||
75 | ||||
<!--<div class="row"> | 76 | |||
<button id="blank-selected" style="float:left" class="btn tooltipped" data-position="right" data-delay="50" | 77 | |||
data-tooltip="Ctrl-B"> | 78 | |||
Blank Selected Text | 79 | |||
</button> | 80 | |||
</div>--> | 81 | |||
82 | ||||
83 | ||||
<div class="row" ng-show="flashcard.editCardText" ng-style="(flashcard.editCardText.length>160)?{color:'red'}:{}"> | 84 | |||
{{flashcard.editCardText.length}}/160 characters | 85 | |||
</div> | 86 |