Commit db9df0ff authored by 神楽坂玲奈's avatar 神楽坂玲奈

share, url

parent 390ad061
...@@ -55,37 +55,61 @@ class Deck extends Spine.Controller ...@@ -55,37 +55,61 @@ class Deck extends Spine.Controller
'mouseover .card_usage': 'show', 'mouseover .card_usage': 'show',
'click .card_usage': 'add', 'click .card_usage': 'add',
'contextmenu .card_usage': 'minus' 'contextmenu .card_usage': 'minus'
key: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-=" key: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-="
constructor: -> constructor: ->
super super
CardUsage.bind("refresh change", @render) CardUsage.bind("refresh change", @render)
encode: ->
result = ''
for card_usage in @main.concat @extra, @side
c = card_usage.side << 29 | card_usage.count << 27 | card_usage.card_id
for i in [4..0]
result += @key.charAt((c >> i*6) & 0x3F)
result
decode: (str)->
card_usages = for i in [0...str.length] by 5
decoded = 0
for char in str.substr(i, 5)
decoded = (decoded << 6) + @key.indexOf(char)
card_id = decoded & 0x07FFFFFF
side = decoded >> 29
count = decoded >> 27 & 0x3
{card_id: card_id, side: side, count: count}
Card.query {_id:
{ $in: card_usage.card_id for card_usage in card_usages}}, =>
CardUsage.refresh card_usages, clear: true
render: => render: =>
main = [] @main = []
side = [] @side = []
extra = [] @extra = []
main_count = 0 main_count = 0
side_count = 0 side_count = 0
extra_count = 0 extra_count = 0
category_count = {} category_count = {}
for category in Card.categories for category in Card.categories
category_count[category] = 0 category_count[category] = 0
CardUsage.each (card_usage)-> CardUsage.each (card_usage)=>
card = card_usage.card() card = card_usage.card()
if card_usage.side if card_usage.side
side.push card_usage @side.push card_usage
side_count += card_usage.count side_count += card_usage.count
else if (card_type for card_type in card.card_type when card_type in Card.card_types_extra).length else if (card_type for card_type in card.card_type when card_type in Card.card_types_extra).length
extra.push card_usage @extra.push card_usage
extra_count += card_usage.count extra_count += card_usage.count
else else
main.push card_usage @main.push card_usage
main_count += card_usage.count main_count += card_usage.count
category_count[(category for category in card.card_type when category in Card.categories).pop()] += card_usage.count category_count[(category for category in card.card_type when category in Card.categories).pop()] += card_usage.count
@html $('#deck_template').tmpl({main: main, side: side, extra: extra, main_count: main_count, side_count: side_count, extra_count: extra_count, category_count: category_count}) @html $('#deck_template').tmpl({main: @main, side: @side, extra: @extra, main_count: main_count, side_count: side_count, extra_count: extra_count, category_count: category_count})
@el.jscroll({W: "12px", Btn: @el.jscroll({W: "12px", Btn:
{btn: false}}); {btn: false}});
$('#deck_url').attr 'download', Deck.deck_name + '.ydk'
$('#deck_url').attr 'href', 'data:application/octet-stream,' + (card_usage.card_id for card_usage in main).concat((card_usage.card_id for card_usage in extra), ["!side"], (card_usage.card_id for card_usage in side)).join("%0a") @url = "http://my-card.in/decks/?name=#{@deck_name}&cards=#{@encode()}"
#alert @url
#$('#deck_url_ydk').attr 'download', Deck.deck_name + '.ydk'
#$('#deck_url_ydk').attr 'href', 'data:application/octet-stream,' + (card_usage.card_id for i in ).concat((card_usage.card_id for i in [0...card_usage.count] for card_usage in @extra), ["!side"], (card_usage.card_id for i in [0...card_usage.count] for card_usage in @side)).join("%0a")
tab_control: -> tab_control: ->
$(".bottom_area div").click -> $(".bottom_area div").click ->
$(this).addClass("bottom_button_active").removeClass("bottom_button") $(this).addClass("bottom_button_active").removeClass("bottom_button")
...@@ -112,6 +136,7 @@ class Deck extends Spine.Controller ...@@ -112,6 +136,7 @@ class Deck extends Spine.Controller
if count < 3 #TODO: lflist if count < 3 #TODO: lflist
card_usage.count++ card_usage.count++
card_usage.save() card_usage.save()
history.pushState(null,@deck_name, @url)
minus: (e)-> minus: (e)->
card_usage = $(e.target).tmplItem().data card_usage = $(e.target).tmplItem().data
card_usage.count-- card_usage.count--
...@@ -119,26 +144,20 @@ class Deck extends Spine.Controller ...@@ -119,26 +144,20 @@ class Deck extends Spine.Controller
card_usage.save() card_usage.save()
else else
card_usage.destroy() card_usage.destroy()
history.pushState(null,@deck_name, @url)
return false #TODO: prevent showing menu return false #TODO: prevent showing menu
parse: (str)->
card_usages = (for i in [0...str.length] by 5
decoded = 0
for char in str.substr(i, 5)
decoded = (decoded << 6) + @key.indexOf(char)
card_id = decoded & 0x07FFFFFF
side = decoded >> 29
count = decoded >> 27 & 0x3
{card_id: card_id, side: side, count: count}
)
Card.query {_id:
{ $in: card_usage.card_id for card_usage in card_usages}}, =>
CardUsage.refresh card_usages
$(document).ready -> $(document).ready ->
name = $.url().param('name') $('#name').html $.url().param('name')
cards_encoded = $.url().param('cards') $( "#deck_share_dialog" ).dialog
$('img#qrcode').attr('src', 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=|0&chl=' + encodeURIComponent("http://my-card.in/decks/?name=#{name}&cards=#{cards_encoded}")) modal: true
$('#name').html(name) autoOpen: false
$('#deck_share').click ->
$("#deck_url").val
$( "#deck_share_dialog" ).dialog('open')
#$.ajax({url: 'https://www.googleapis.com/urlshortener/v1/url', type: 'POST', data:JSON.stringify({longUrl: 'http://my-card.in/'}), contentType: 'application/json; charset=utf-8', success: function(data){alert(data)} })"
$.i18n.properties $.i18n.properties
name: 'card' name: 'card'
path: '/locales/' path: '/locales/'
...@@ -146,6 +165,10 @@ $(document).ready -> ...@@ -146,6 +165,10 @@ $(document).ready ->
cache: true cache: true
callback: -> callback: ->
deck = new Deck(el: $("#deck")) deck = new Deck(el: $("#deck"))
Deck.deck_name = name deck.deck_name = $.url().param('name')
deck.tab_control() deck.tab_control()
deck.parse cards_encoded deck.decode $.url().param('cards')
\ No newline at end of file #window.addEventListener 'popstate', (ev)->
# alert ev.state
#if ev.state
# CardUsage.refresh ev.state, clear: true
\ No newline at end of file
...@@ -153,11 +153,69 @@ ...@@ -153,11 +153,69 @@
CardUsage.bind("refresh change", this.render); CardUsage.bind("refresh change", this.render);
} }
Deck.prototype.encode = function() {
var c, card_usage, i, result, _i, _j, _len, _ref;
result = '';
_ref = this.main.concat(this.extra, this.side);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
card_usage = _ref[_i];
c = card_usage.side << 29 | card_usage.count << 27 | card_usage.card_id;
for (i = _j = 4; _j >= 0; i = --_j) {
result += this.key.charAt((c >> i * 6) & 0x3F);
}
}
return result;
};
Deck.prototype.decode = function(str) {
var card_id, card_usage, card_usages, char, count, decoded, i, side,
_this = this;
card_usages = (function() {
var _i, _j, _len, _ref, _ref1, _results;
_results = [];
for (i = _i = 0, _ref = str.length; _i < _ref; i = _i += 5) {
decoded = 0;
_ref1 = str.substr(i, 5);
for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
char = _ref1[_j];
decoded = (decoded << 6) + this.key.indexOf(char);
}
card_id = decoded & 0x07FFFFFF;
side = decoded >> 29;
count = decoded >> 27 & 0x3;
_results.push({
card_id: card_id,
side: side,
count: count
});
}
return _results;
}).call(this);
return Card.query({
_id: {
$in: (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = card_usages.length; _i < _len; _i++) {
card_usage = card_usages[_i];
_results.push(card_usage.card_id);
}
return _results;
})()
}
}, function() {
return CardUsage.refresh(card_usages, {
clear: true
});
});
};
Deck.prototype.render = function() { Deck.prototype.render = function() {
var card_usage, category, category_count, extra, extra_count, main, main_count, side, side_count, _i, _len, _ref; var category, category_count, extra_count, main_count, side_count, _i, _len, _ref,
main = []; _this = this;
side = []; this.main = [];
extra = []; this.side = [];
this.extra = [];
main_count = 0; main_count = 0;
side_count = 0; side_count = 0;
extra_count = 0; extra_count = 0;
...@@ -171,7 +229,7 @@ ...@@ -171,7 +229,7 @@
var card, card_type; var card, card_type;
card = card_usage.card(); card = card_usage.card();
if (card_usage.side) { if (card_usage.side) {
side.push(card_usage); _this.side.push(card_usage);
return side_count += card_usage.count; return side_count += card_usage.count;
} else if (((function() { } else if (((function() {
var _j, _len1, _ref1, _results; var _j, _len1, _ref1, _results;
...@@ -185,10 +243,10 @@ ...@@ -185,10 +243,10 @@
} }
return _results; return _results;
})()).length) { })()).length) {
extra.push(card_usage); _this.extra.push(card_usage);
return extra_count += card_usage.count; return extra_count += card_usage.count;
} else { } else {
main.push(card_usage); _this.main.push(card_usage);
main_count += card_usage.count; main_count += card_usage.count;
return category_count[((function() { return category_count[((function() {
var _j, _len1, _ref1, _results; var _j, _len1, _ref1, _results;
...@@ -205,9 +263,9 @@ ...@@ -205,9 +263,9 @@
} }
}); });
this.html($('#deck_template').tmpl({ this.html($('#deck_template').tmpl({
main: main, main: this.main,
side: side, side: this.side,
extra: extra, extra: this.extra,
main_count: main_count, main_count: main_count,
side_count: side_count, side_count: side_count,
extra_count: extra_count, extra_count: extra_count,
...@@ -219,32 +277,7 @@ ...@@ -219,32 +277,7 @@
btn: false btn: false
} }
}); });
$('#deck_url').attr('download', Deck.deck_name + '.ydk'); return this.url = "http://my-card.in/decks/?name=" + this.deck_name + "&cards=" + (this.encode());
return $('#deck_url').attr('href', 'data:application/octet-stream,' + ((function() {
var _j, _len1, _results;
_results = [];
for (_j = 0, _len1 = main.length; _j < _len1; _j++) {
card_usage = main[_j];
_results.push(card_usage.card_id);
}
return _results;
})()).concat((function() {
var _j, _len1, _results;
_results = [];
for (_j = 0, _len1 = extra.length; _j < _len1; _j++) {
card_usage = extra[_j];
_results.push(card_usage.card_id);
}
return _results;
})(), ["!side"], (function() {
var _j, _len1, _results;
_results = [];
for (_j = 0, _len1 = side.length; _j < _len1; _j++) {
card_usage = side[_j];
_results.push(card_usage.card_id);
}
return _results;
})()).join("%0a"));
}; };
Deck.prototype.tab_control = function() { Deck.prototype.tab_control = function() {
...@@ -287,8 +320,9 @@ ...@@ -287,8 +320,9 @@
} }
if (count < 3) { if (count < 3) {
card_usage.count++; card_usage.count++;
return card_usage.save(); card_usage.save();
} }
return history.pushState(null, this.deck_name, this.url);
}; };
Deck.prototype.minus = function(e) { Deck.prototype.minus = function(e) {
...@@ -300,60 +334,24 @@ ...@@ -300,60 +334,24 @@
} else { } else {
card_usage.destroy(); card_usage.destroy();
} }
history.pushState(null, this.deck_name, this.url);
return false; return false;
}; };
Deck.prototype.parse = function(str) {
var card_id, card_usage, card_usages, char, count, decoded, i, side,
_this = this;
card_usages = (function() {
var _i, _j, _len, _ref, _ref1, _results;
_results = [];
for (i = _i = 0, _ref = str.length; _i < _ref; i = _i += 5) {
decoded = 0;
_ref1 = str.substr(i, 5);
for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
char = _ref1[_j];
decoded = (decoded << 6) + this.key.indexOf(char);
}
card_id = decoded & 0x07FFFFFF;
side = decoded >> 29;
count = decoded >> 27 & 0x3;
_results.push({
card_id: card_id,
side: side,
count: count
});
}
return _results;
}).call(this);
return Card.query({
_id: {
$in: (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = card_usages.length; _i < _len; _i++) {
card_usage = card_usages[_i];
_results.push(card_usage.card_id);
}
return _results;
})()
}
}, function() {
return CardUsage.refresh(card_usages);
});
};
return Deck; return Deck;
})(Spine.Controller); })(Spine.Controller);
$(document).ready(function() { $(document).ready(function() {
var cards_encoded, name; $('#name').html($.url().param('name'));
name = $.url().param('name'); $("#deck_share_dialog").dialog({
cards_encoded = $.url().param('cards'); modal: true,
$('img#qrcode').attr('src', 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=|0&chl=' + encodeURIComponent("http://my-card.in/decks/?name=" + name + "&cards=" + cards_encoded)); autoOpen: false
$('#name').html(name); });
$('#deck_share').click(function() {
$("#deck_url").val;
return $("#deck_share_dialog").dialog('open');
});
return $.i18n.properties({ return $.i18n.properties({
name: 'card', name: 'card',
path: '/locales/', path: '/locales/',
...@@ -364,9 +362,9 @@ ...@@ -364,9 +362,9 @@
deck = new Deck({ deck = new Deck({
el: $("#deck") el: $("#deck")
}); });
Deck.deck_name = name; deck.deck_name = $.url().param('name');
deck.tab_control(); deck.tab_control();
return deck.parse(cards_encoded); return deck.decode($.url().param('cards'));
} }
}); });
}); });
......
/*
* HTML5 Boilerplate
*
* What follows is the result of much research on cross-browser styling.
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
* Kroc Camen, and the H5BP dev community and team.
*/
/* ==========================================================================
Base styles: opinionated defaults
========================================================================== */
html,
button,
input,
select,
textarea {
color: #222;
}
body {
font-size: 1em;
line-height: 1.4;
}
/*
* Remove text-shadow in selection highlight: h5bp.com/i
* These selection declarations have to be separate.
* Customize the background color to match your design.
*/
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
/*
* A better looking default horizontal rule
*/
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
/*
* Remove the gap between images and the bottom of their containers: h5bp.com/i/440
*/
img {
vertical-align: middle;
}
/*
* Remove default fieldset styles.
*/
fieldset {
border: 0;
margin: 0;
padding: 0;
}
/*
* Allow only vertical resizing of textareas.
*/
textarea {
resize: vertical;
}
/* ==========================================================================
Chrome Frame prompt
========================================================================== */
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
/* ==========================================================================
Author's custom styles
========================================================================== */
/* ==========================================================================
Helper classes
========================================================================== */
/*
* Image replacement
*/
.ir {
background-color: transparent;
border: 0;
overflow: hidden;
/* IE 6/7 fallback */
*text-indent: -9999px;
}
.ir:before {
content: "";
display: block;
width: 0;
height: 100%;
}
/*
* Hide from both screenreaders and browsers: h5bp.com/u
*/
.hidden {
display: none !important;
visibility: hidden;
}
/*
* Hide only visually, but have it available for screenreaders: h5bp.com/v
*/
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
/*
* Extends the .visuallyhidden class to allow the element to be focusable
* when navigated to via the keyboard: h5bp.com/p
*/
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}
/*
* Hide visually and from screenreaders, but maintain layout
*/
.invisible {
visibility: hidden;
}
/*
* Clearfix: contain floats
*
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* `contenteditable` attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that receive the `clearfix` class.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.clearfix:before,
.clearfix:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.clearfix:after {
clear: both;
}
/*
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/
.clearfix {
*zoom: 1;
}
/* ==========================================================================
EXAMPLE Media Queries for Responsive Design.
Theses examples override the primary ('mobile first') styles.
Modify as content requires.
========================================================================== */
@media only screen and (min-width: 35em) {
/* Style adjustments for viewports that meet the condition */
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-resolution: 144dpi) {
/* Style adjustments for high resolution devices */
}
/* ==========================================================================
Print styles.
Inlined to avoid required HTTP connection: h5bp.com/r
========================================================================== */
@media print {
* {
background: transparent !important;
color: #000 !important; /* Black prints faster: h5bp.com/s */
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
/*
* Don't show links for images, or javascript/internal links
*/
.ir a:after,
a[href^="javascript:"]:after,
a[href^="#"]:after {
content: "";
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
thead {
display: table-header-group; /* h5bp.com/t */
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
@page {
margin: 0.5cm;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment