Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

ディレクトリ整理した

  • Loading branch information...
commit 1e42c87b69f983a1ecae47b7e1a68454698d9b5e 1 parent 44c54ac
cho45 authored April 13, 2012
10  README.markdown
Source Rendered
@@ -4,7 +4,6 @@ My FlashAir files
4 4
 ## 最新の画像を表示
5 5
 
6 6
  *  recent.htm
7  
- *  lib.js
8 7
 
9 8
 SDカードのルートディレクトリなど、適当なところにコピーする。Android, iPhone などでいい感じになるように調整済み
10 9
 
@@ -18,6 +17,13 @@ iPad:
18 17
 <img src="https://lh4.googleusercontent.com/-JujV74pEGMM/T3nOyEHySBI/AAAAAAAABz8/5rpJsnMUbAE/s640/2012-04-03-01.05.02.png"/>
19 18
 
20 19
 
  20
+## Markdown で書かれた .txt をブログっぽく見せるやつ
  21
+
  22
+  * blog.htm
  23
+
  24
+  SDカードのルートディレクトリなど、適当なところにコピーする。/blog 以下に .txt を置く。
  25
+
  26
+
21 27
 ## FlashAir エミュレータ
22 28
 
23 29
 FlashAir の HTTPD のエミュレータ
@@ -65,8 +71,6 @@ FlashAir の HTTPD のエミュレータ
65 71
 
66 72
 ## Copyright
67 73
 
68  
-lib.js is made from:
69  
-
70 74
  * [jQuery]( http://jquery.com/ ) MIT License
71 75
  * [JSDeferred]( http://cho45.stfuawsc.com/jsdeferred/ ) MIT License
72 76
  * [lscache]( https://github.com/pamelafox/lscache ) Apache License
33  Rakefile
... ...
@@ -0,0 +1,33 @@
  1
+require "rubygems"
  2
+require "rake"
  3
+require "rake/clean"
  4
+require "pathname"
  5
+
  6
+
  7
+CLOBBER.include("recent.htm", "blog.htm")
  8
+
  9
+def compile(htm)
  10
+	base = Pathname.new(htm).parent
  11
+	body = File.read(htm)
  12
+	body.gsub!(%r|<script type="text/javascript" src="([^"]+?)"></script>|) do
  13
+		file = base + $1
  14
+		"<script>#{File.read(file)}</script>"
  15
+	end
  16
+	body.gsub!(/[ \t]+/, ' ')
  17
+end
  18
+
  19
+task :default => ["recent.htm", "blog.htm"]
  20
+
  21
+file "recent.htm" => FileList["recent/*"] do |t|
  22
+	compiled = compile("recent/recent.htm")
  23
+	File.open(t.name, "w") do |f|
  24
+		f.puts compiled
  25
+	end
  26
+end
  27
+
  28
+file "blog.htm" => FileList["flashairsxom/*"] do |t|
  29
+	compiled = compile("flashairsxom/blog.htm")
  30
+	File.open(t.name, "w") do |f|
  31
+		f.puts compiled
  32
+	end
  33
+end
1,100  lib.js → blog.htm 100755 → 100644
1025 additions, 75 deletions not shown
1  emulator.psgi
@@ -6,6 +6,7 @@ use warnings;
6 6
 use parent qw(Plack::App::File);
7 7
 use Plack::Request;
8 8
 use Path::Class::Dir;
  9
+use Path::Class::File;
9 10
 use Time::Piece;
10 11
 use Image::ExifTool qw(:Public);
11 12
 use POSIX qw(floor);
241  flashair.js
... ...
@@ -0,0 +1,241 @@
  1
+Deferred.define();
  2
+
  3
+var FlashAir = {};
  4
+FlashAir.API = {
  5
+	isConnected : function () {
  6
+		var d = new Deferred();
  7
+		$.ajax({
  8
+			url: '/command.cgi?op=101',
  9
+			type : "GET",
  10
+			timeout: 10 * 1000,
  11
+			dataType: 'text',
  12
+			success : function (data, status, xhr) {
  13
+				d.call(true);
  14
+			},
  15
+			error : function (jqXHR, status, error) {
  16
+				d.call(false);
  17
+			}
  18
+		});
  19
+		return d;
  20
+	},
  21
+
  22
+	waitUntilConnect : function () {
  23
+		return next(function () {
  24
+			return FlashAir.API.isConnected().next(function (connected) {
  25
+				if (!connected) {
  26
+					return wait(3).next(FlashAir.API.waitUntilConnect);
  27
+				}
  28
+			});
  29
+		});
  30
+	},
  31
+
  32
+	waitUntilConnectToInternet : function () {
  33
+		return next(function () {
  34
+			var d = new Deferred();
  35
+			var img = new Image();
  36
+			var timer;
  37
+			img.onload = function () {
  38
+				clearInterval(timer);
  39
+				d.call();
  40
+			};
  41
+			img.onerror = function () {
  42
+				clearInterval(timer);
  43
+				d.fail('not connected; onerror');
  44
+			};
  45
+			timer = setInterval(function () {
  46
+				img.onload = null;
  47
+				img.onerror = null;
  48
+				img = null;
  49
+				d.fail('not connected; timeout');
  50
+			}, 10 * 1000);
  51
+			img.src = "http://www.google.com/textinputassistant/tia.png?" + new Date().getTime();
  52
+			return d;
  53
+		}).
  54
+		error(function (e) {
  55
+			console.log(e);
  56
+			if (e.match(/not connected/)) {
  57
+				return wait(3).next(FlashAir.API.waitUntilConnectToInternet);
  58
+			} else {
  59
+				throw e;
  60
+			}
  61
+		});
  62
+	},
  63
+
  64
+	loadAsBinary : function (path) {
  65
+		var d = new Deferred();
  66
+		$.ajax({
  67
+			url: path,
  68
+			type : "GET",
  69
+			dataType: 'text',
  70
+			beforeSend: function ( xhr ) {
  71
+				xhr.overrideMimeType("text/plain; charset=x-user-defined");
  72
+			},
  73
+			success : function (data, status, xhr) {
  74
+				var binary = '';
  75
+				for (var i = 0, len = data.length; i < len; i++) {
  76
+					binary += String.fromCharCode(data[i].charCodeAt(0) & 0xff);
  77
+				}
  78
+				d.call(binary);
  79
+			}
  80
+		});
  81
+		return d;
  82
+	},
  83
+
  84
+	getFiles : function (path) {
  85
+		// console.log(['getFiles', path]);
  86
+		var d = new Deferred();
  87
+		$.ajax({
  88
+			url: path,
  89
+			type : "GET",
  90
+			dataType: 'text',
  91
+			success : function (data, status, xhr) {
  92
+				try {
  93
+					var js = data.match(/wlansd\[\d+\]=.+/g) || [];
  94
+					var files = new Function("wlansd", js.join("\n") + "return wlansd")([]);
  95
+					for (var i = 0, it; (it = files[i]); i++) files[i] = new FlashAir.File(it);
  96
+					d.call(files);
  97
+				} catch (e) { d.fail(e) }
  98
+			},
  99
+			error : function (jqXHR, status, error) {
  100
+				d.fail([jqXHR, status, error]);
  101
+			}
  102
+		});
  103
+		return d;
  104
+	},
  105
+
  106
+	getRecent : function (start, end) {
  107
+		end = end || start + 1;
  108
+
  109
+		if (!arguments.callee.cache) arguments.callee.cache = { directories: null, files : [] };
  110
+		var cache = arguments.callee.cache;
  111
+		// console.log(cache);
  112
+
  113
+		return next(function () {
  114
+			if (!cache.directories) {
  115
+				return FlashAir.API.getFiles('/DCIM').next(function (files) {
  116
+					files.sort(function (a, b) { return a.date.getTime() - b.date.getTime() });
  117
+					var directories = [];
  118
+					for (var i = 0, it; (it = files[i]); i++) {
  119
+						if (it.isDCFDirectory && it.filename != '100__TSB') directories.push(it);
  120
+					}
  121
+					cache.directories = directories;
  122
+					return directories;
  123
+				});
  124
+			} else {
  125
+				return cache.directories;
  126
+			}
  127
+		}).
  128
+		next(function (directories) {
  129
+			var enough   = !!cache.files[end-1];
  130
+			var finished = !directories.length;
  131
+			if (enough || finished) return cache.files.slice(start, end);
  132
+
  133
+			var directory = directories.pop();
  134
+			return FlashAir.API.getFiles(directory.path).next(function (files) {
  135
+				files.sort(function (a, b) { return b.date.getTime() - a.date.getTime() });
  136
+				for (var i = 0, it; (it = files[i]); i++) {
  137
+					if (it.isDCFBasicFile) cache.files.push(it);
  138
+				}
  139
+				return FlashAir.API.getRecent(start, end);
  140
+			});
  141
+		});
  142
+	},
  143
+
  144
+	// require lscache
  145
+	getThumbnailURL : function (path, size) {
  146
+		var d = new Deferred();
  147
+		size = size * (window.devicePixelRatio || 1);
  148
+
  149
+		var cache = lscache.get('thumbnail:' + path);
  150
+		if (!cache) {
  151
+			console.log(['create thumbnail', path]);
  152
+
  153
+			if (!arguments.callee.queue) arguments.callee.queue = [];
  154
+			var queue = arguments.callee.queue;
  155
+			queue.push({ path : path, size : size, deferred : d });
  156
+
  157
+			if (!queue.worker) {
  158
+				queue.worker = next(function () {
  159
+					return next(function () {
  160
+						var job  = queue.shift();
  161
+						if (!job) throw "done";
  162
+						var path = job.path;
  163
+						var size = job.size;
  164
+						var ret  = new Deferred();
  165
+
  166
+						var img = new Image();
  167
+						img.onload = function () {
  168
+							try {
  169
+								var canvas = document.createElement('canvas');
  170
+								canvas.setAttribute('width', size);
  171
+								canvas.setAttribute('height', size);
  172
+
  173
+								var ctx = canvas.getContext('2d');
  174
+								var source = Math.min(img.height, img.width) * 0.9;
  175
+								ctx.drawImage(img,
  176
+									(img.width  - source) / 2,
  177
+									(img.height - source) / 2,
  178
+									source,
  179
+									source,
  180
+									0,
  181
+									0,
  182
+									size,
  183
+									size
  184
+								);
  185
+								var url = canvas.toDataURL('image/jpeg', 0.8);
  186
+								console.log(['cached thumbnail/size:', url.length ]);
  187
+								lscache.set('thumbnail:' + path, url);
  188
+								job.deferred.call(url);
  189
+							} catch (e) { job.deferred.fail(e) }
  190
+							ret.call();
  191
+						};
  192
+						img.src = '/thumbnail.cgi?' + path;
  193
+
  194
+						return ret;
  195
+					}).
  196
+					next(arguments.callee);
  197
+				}).
  198
+				error(function (e) {
  199
+					if (e === 'done') return delete queue.worker;
  200
+					alert(e);
  201
+				});
  202
+			}
  203
+		} else {
  204
+			// console.log(['cached thumbnail:', path]);
  205
+			next(function () { d.call(cache) });
  206
+		}
  207
+
  208
+		return d;
  209
+	}
  210
+};
  211
+
  212
+FlashAir.File = function () { this.init.apply(this, arguments) };
  213
+FlashAir.File.prototype = {
  214
+	init : function (data) {
  215
+		data = data.split(/,/);
  216
+		this.directory = data[0];
  217
+		this.filename  = data[1];
  218
+		this.path      = this.directory + '/' + this.filename;
  219
+		this.ext       = (this.filename.split(/\./)[1] || '').toUpperCase();
  220
+		this.size      = +data[2];
  221
+		this.attribute = +data[3];
  222
+
  223
+		var d = +data[4], t = +data[5];
  224
+		this.date = new Date(
  225
+			((d & 0xfe00) >> 9) + 1980, // 1111111000000000 (origin=1980)
  226
+			((d & 0x1e0) >> 5) + 1,     // 0000000111100000 (1-12)
  227
+			d & 0x1f,                   // 0000000000011111 (1-31)
  228
+			((t & 0xf800) >> 11),       // 1111100000000000 (hour)
  229
+			((t & 0x7e0) >> 5),         // 0000011111100000 (min)
  230
+			t & 0x1f * 2                // 0000000000011111 (sec / 2)
  231
+		);
  232
+
  233
+		this.isDirectory    = this.attribute & 0x08 !== 0;
  234
+		this.isFile         = !this.isDirectory;
  235
+		this.isDCFDirectory = new RegExp('^/DCIM/[0-9]{3}[0-9A-Z_]+$', 'i').test(this.path);
  236
+		this.isDCFBasicFile = new RegExp('^/DCIM/[0-9]{3}[0-9A-Z_]+/[0-9A-Z_]{4}[0-9]{4}.JPG$', 'i').test(this.path);
  237
+	}
  238
+};
  239
+
  240
+
  241
+
8  flashairsxom/blog.htm
@@ -4,7 +4,13 @@
4 4
 		<title>FlashAirsxom</title>
5 5
 		<meta charset="utf-8"/>
6 6
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
7  
-		<script type="text/javascript" src="lib.js"></script>
  7
+		<script type="text/javascript" src="../lib/jquery-1.7.2.min.js"></script>
  8
+		<script type="text/javascript" src="../lib/jsdeferred.jquery.js"></script>
  9
+		<script type="text/javascript" src="../lib/lscache.js"></script>
  10
+		<script type="text/javascript" src="../lib/jpeg_encoder_basic.js"></script>
  11
+		<script type="text/javascript" src="../lib/jpeg_encoder_basic_todataurl.js"></script>
  12
+		<script type="text/javascript" src="../lib/tmpl.js"></script>
  13
+		<script type="text/javascript" src="../flashair.js"></script>
8 14
 		<script type="text/javascript" src="showdown.js"></script>
9 15
 		<script type="text/javascript" src="hash.js"></script>
10 16
 
238  flashairsxom/blog.js
... ...
@@ -1,241 +1,3 @@
1  
-Deferred.define();
2  
-
3  
-var FlashAir = {};
4  
-FlashAir.API = {
5  
-	isConnected : function () {
6  
-		var d = new Deferred();
7  
-		$.ajax({
8  
-			url: '/command.cgi?op=101',
9  
-			type : "GET",
10  
-			timeout: 10 * 1000,
11  
-			dataType: 'text',
12  
-			success : function (data, status, xhr) {
13  
-				d.call(true);
14  
-			},
15  
-			error : function (jqXHR, status, error) {
16  
-				d.call(false);
17  
-			}
18  
-		});
19  
-		return d;
20  
-	},
21  
-
22  
-	waitUntilConnect : function () {
23  
-		return next(function () {
24  
-			return FlashAir.API.isConnected().next(function (connected) {
25  
-				if (!connected) {
26  
-					return wait(3).next(FlashAir.API.waitUntilConnect);
27  
-				}
28  
-			});
29  
-		});
30  
-	},
31  
-
32  
-	waitUntilConnectToInternet : function () {
33  
-		return next(function () {
34  
-			var d = new Deferred();
35  
-			var img = new Image();
36  
-			var timer;
37  
-			img.onload = function () {
38  
-				clearInterval(timer);
39  
-				d.call();
40  
-			};
41  
-			img.onerror = function () {
42  
-				clearInterval(timer);
43  
-				d.fail('not connected; onerror');
44  
-			};
45  
-			timer = setInterval(function () {
46  
-				img.onload = null;
47  
-				img.onerror = null;
48  
-				img = null;
49  
-				d.fail('not connected; timeout');
50  
-			}, 10 * 1000);
51  
-			img.src = "http://www.google.com/textinputassistant/tia.png?" + new Date().getTime();
52  
-			return d;
53  
-		}).
54  
-		error(function (e) {
55  
-			console.log(e);
56  
-			if (e.match(/not connected/)) {
57  
-				return wait(3).next(FlashAir.API.waitUntilConnectToInternet);
58  
-			} else {
59  
-				throw e;
60  
-			}
61  
-		});
62  
-	},
63  
-
64  
-	loadAsBinary : function (path) {
65  
-		var d = new Deferred();
66  
-		$.ajax({
67  
-			url: "path",
68  
-			type : "GET",
69  
-			dataType: 'text',
70  
-			beforeSend: function ( xhr ) {
71  
-				xhr.overrideMimeType("text/plain; charset=x-user-defined");
72  
-			},
73  
-			success : function (data, status, xhr) {
74  
-				d.call(data.replace(/./g, function (_) {
75  
-					return _.charCodeAt(0) & 0xff;
76  
-				}));
77  
-			}
78  
-		});
79  
-		return d;
80  
-	},
81  
-
82  
-	getFiles : function (path) {
83  
-		// console.log(['getFiles', path]);
84  
-		var d = new Deferred();
85  
-		$.ajax({
86  
-			url: path,
87  
-			type : "GET",
88  
-			dataType: 'text',
89  
-			success : function (data, status, xhr) {
90  
-				try {
91  
-					var js = data.match(/wlansd\[\d+\]=.+/g) || [];
92  
-					var files = new Function("wlansd", js.join("\n") + "return wlansd")([]);
93  
-					for (var i = 0, it; (it = files[i]); i++) files[i] = new FlashAir.File(it);
94  
-					d.call(files);
95  
-				} catch (e) { d.fail(e) }
96  
-			},
97  
-			error : function (jqXHR, status, error) {
98  
-				d.fail([jqXHR, status, error]);
99  
-			}
100  
-		});
101  
-		return d;
102  
-	},
103  
-
104  
-	getRecent : function (start, end) {
105  
-		end = end || start + 1;
106  
-
107  
-		if (!arguments.callee.cache) arguments.callee.cache = { directories: null, files : [] };
108  
-		var cache = arguments.callee.cache;
109  
-		// console.log(cache);
110  
-
111  
-		return next(function () {
112  
-			if (!cache.directories) {
113  
-				return FlashAir.API.getFiles('/DCIM').next(function (files) {
114  
-					files.sort(function (a, b) { return a.date.getTime() - b.date.getTime() });
115  
-					var directories = [];
116  
-					for (var i = 0, it; (it = files[i]); i++) {
117  
-						if (it.isDCFDirectory && it.filename != '100__TSB') directories.push(it);
118  
-					}
119  
-					cache.directories = directories;
120  
-					return directories;
121  
-				});
122  
-			} else {
123  
-				return cache.directories;
124  
-			}
125  
-		}).
126  
-		next(function (directories) {
127  
-			var enough   = !!cache.files[end-1];
128  
-			var finished = !directories.length;
129  
-			if (enough || finished) return cache.files.slice(start, end);
130  
-
131  
-			var directory = directories.pop();
132  
-			return FlashAir.API.getFiles(directory.path).next(function (files) {
133  
-				files.sort(function (a, b) { return b.date.getTime() - a.date.getTime() });
134  
-				for (var i = 0, it; (it = files[i]); i++) {
135  
-					if (it.isDCFBasicFile) cache.files.push(it);
136  
-				}
137  
-				return FlashAir.API.getRecent(start, end);
138  
-			});
139  
-		});
140  
-	},
141  
-
142  
-	// require lscache
143  
-	getThumbnailURL : function (path, size) {
144  
-		var d = new Deferred();
145  
-		size = size * (window.devicePixelRatio || 1);
146  
-
147  
-		var cache = lscache.get('thumbnail:' + path);
148  
-		if (!cache) {
149  
-			console.log(['create thumbnail', path]);
150  
-
151  
-			if (!arguments.callee.queue) arguments.callee.queue = [];
152  
-			var queue = arguments.callee.queue;
153  
-			queue.push({ path : path, size : size, deferred : d });
154  
-
155  
-			if (!queue.worker) {
156  
-				queue.worker = next(function () {
157  
-					return next(function () {
158  
-						var job  = queue.shift();
159  
-						if (!job) throw "done";
160  
-						var path = job.path;
161  
-						var size = job.size;
162  
-						var ret  = new Deferred();
163  
-
164  
-						var img = new Image();
165  
-						img.onload = function () {
166  
-							try {
167  
-								var canvas = document.createElement('canvas');
168  
-								canvas.setAttribute('width', size);
169  
-								canvas.setAttribute('height', size);
170  
-
171  
-								var ctx = canvas.getContext('2d');
172  
-								var source = Math.min(img.height, img.width) * 0.9;
173  
-								ctx.drawImage(img,
174  
-									(img.width  - source) / 2,
175  
-									(img.height - source) / 2,
176  
-									source,
177  
-									source,
178  
-									0,
179  
-									0,
180  
-									size,
181  
-									size
182  
-								);
183  
-								var url = canvas.toDataURL('image/jpeg', 0.8);
184  
-								console.log(['cached thumbnail/size:', url.length ]);
185  
-								lscache.set('thumbnail:' + path, url);
186  
-								job.deferred.call(url);
187  
-							} catch (e) { job.deferred.fail(e) }
188  
-							ret.call();
189  
-						};
190  
-						img.src = '/thumbnail.cgi?' + path;
191  
-
192  
-						return ret;
193  
-					}).
194  
-					next(arguments.callee);
195  
-				}).
196  
-				error(function (e) {
197  
-					if (e === 'done') return delete queue.worker;
198  
-					alert(e);
199  
-				});
200  
-			}
201  
-		} else {
202  
-			// console.log(['cached thumbnail:', path]);
203  
-			next(function () { d.call(cache) });
204  
-		}
205  
-
206  
-		return d;
207  
-	}
208  
-};
209  
-
210  
-FlashAir.File = function () { this.init.apply(this, arguments) };
211  
-FlashAir.File.prototype = {
212  
-	init : function (data) {
213  
-		data = data.split(/,/);
214  
-		this.directory = data[0];
215  
-		this.filename  = data[1];
216  
-		this.path      = this.directory + '/' + this.filename;
217  
-		this.ext       = (this.filename.split(/\./)[1] || '').toUpperCase();
218  
-		this.size      = +data[2];
219  
-		this.attribute = +data[3];
220  
-
221  
-		var d = +data[4], t = +data[5];
222  
-		this.date = new Date(
223  
-			((d & 0xfe00) >> 9) + 1980, // 1111111000000000 (origin=1980)
224  
-			((d & 0x1e0) >> 5) + 1,     // 0000000111100000 (1-12)
225  
-			d & 0x1f,                   // 0000000000011111 (1-31)
226  
-			((t & 0xf800) >> 11),       // 1111100000000000 (hour)
227  
-			((t & 0x7e0) >> 5),         // 0000011111100000 (min)
228  
-			t & 0x1f * 2                // 0000000000011111 (sec / 2)
229  
-		);
230  
-
231  
-		this.isDirectory    = this.attribute & 0x08 !== 0;
232  
-		this.isFile         = !this.isDirectory;
233  
-		this.isDCFDirectory = new RegExp('^/DCIM/[0-9]{3}[0-9A-Z_]+$', 'i').test(this.path);
234  
-		this.isDCFBasicFile = new RegExp('^/DCIM/[0-9]{3}[0-9A-Z_]+/[0-9A-Z_]{4}[0-9]{4}.JPG$', 'i').test(this.path);
235  
-	}
236  
-};
237  
-
238  
-
239 1
 FlashAir.Blosxom = {
240 2
 	base  : '/blog',
241 3
 	limit : 3,
1  flashairsxom/lib.js
11  make.sh
... ...
@@ -1,11 +0,0 @@
1  
-#!/bin/sh
2  
-
3  
-cat \
4  
-	./lib/jquery-1.7.2.min.js \
5  
-	./lib/jsdeferred.jquery.js \
6  
-	./lib/lscache.js \
7  
-	./lib/jpeg_encoder_basic.js \
8  
-	./lib/jpeg_encoder_basic_todataurl.js \
9  
-	./lib/tmpl.js \
10  
-	> ./lib.js
11  
-
1,074  recent.htm 100755 → 100644
624 additions, 450 deletions not shown
127  recent/recent.htm
... ...
@@ -0,0 +1,127 @@
  1
+<!DOCTYPE html>
  2
+<html>
  3
+	<head>
  4
+		<title>Recent Photos</title>
  5
+		<meta charset="utf-8"/>
  6
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
  7
+		<script type="text/javascript" src="../lib/jquery-1.7.2.min.js"></script>
  8
+		<script type="text/javascript" src="../lib/jsdeferred.jquery.js"></script>
  9
+		<script type="text/javascript" src="../lib/lscache.js"></script>
  10
+		<script type="text/javascript" src="../lib/jpeg_encoder_basic.js"></script>
  11
+		<script type="text/javascript" src="../lib/jpeg_encoder_basic_todataurl.js"></script>
  12
+		<script type="text/javascript" src="../lib/tmpl.js"></script>
  13
+
  14
+		<style>
  15
+			html, body {
  16
+				font-family: sans-serif;
  17
+				margin: 0;
  18
+				padding: 0 0 20px 0;
  19
+				background: #fff;
  20
+				color: #444;
  21
+			}
  22
+
  23
+			header {
  24
+				padding: 10px;
  25
+				background: #f1f1f1;
  26
+				border-width: 0 0 1px 0;
  27
+				border-style: solid;
  28
+				border-color: #d8d8d8;
  29
+				font-weight: bold;
  30
+			}
  31
+
  32
+			header a {
  33
+				display: block;
  34
+				margin: 0 auto;
  35
+			}
  36
+
  37
+			#list {
  38
+				padding: 20px 0 20px 5px;
  39
+				margin: 0 auto;
  40
+			}
  41
+
  42
+			#list::after {
  43
+				display: block
  44
+				clear: both;
  45
+				content: " ";
  46
+			}
  47
+
  48
+			.loading {
  49
+				font-size: 12px;
  50
+				clear: both;
  51
+				font-weight: bold;
  52
+				color: #666;
  53
+				text-align: center;
  54
+				margin: 0;
  55
+				padding: 10px;
  56
+			}
  57
+
  58
+			a:link ,
  59
+			a:visited {
  60
+				color: #333;
  61
+				text-decoration: none;
  62
+			}
  63
+
  64
+			.file {
  65
+				display: inline-block;
  66
+				width: 100px;
  67
+				height: 100px;
  68
+				margin: 0 5px 5px 0;
  69
+				padding: 0;
  70
+				float: left;
  71
+			}
  72
+
  73
+			.file.jpg {
  74
+				border: 1px solid #fff;
  75
+			}
  76
+
  77
+			.file .filename ,
  78
+			.file .thumbnail {
  79
+				max-width: 100%;
  80
+				min-width: 100%;
  81
+				max-height: 100%;
  82
+				min-height: 100%;
  83
+				line-height: 100px;
  84
+				text-align: center;
  85
+				vertical-align: middle;
  86
+				margin: 0;
  87
+				padding: 0;
  88
+				background: #f1f1f1 url('/SD_WLAN/file.jpg') no-repeat 50% 50%;
  89
+			}
  90
+
  91
+			.file .filename {
  92
+				display: inline-block;
  93
+			}
  94
+
  95
+			footer {
  96
+				display: block;
  97
+				clear: both;
  98
+			}
  99
+		</style>
  100
+
  101
+	</head>
  102
+	<body>
  103
+		<header>
  104
+			<a href="/" class="ui-just">Recent Photos</a>
  105
+		</header>
  106
+		<div id="list" class="ui-just">
  107
+			<script type="text/html" id="listTmpl">
  108
+				<a class="file <%= obj.ext %>" href="<%= obj.path %>" download>
  109
+					<!--
  110
+					<%= [obj.date.getFullYear(), obj.date.getMonth() + 1, obj.date.getDate()].join('/') %>
  111
+					<%= [obj.date.getHours(), obj.date.getMinutes(), obj.date.getSeconds()].join(':') %>
  112
+					-->
  113
+					<% if (obj.ext == 'JPG') { %>
  114
+					<img src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D" data-path="<%= obj.path %>" class="thumbnail"/>
  115
+					<% } else { %>
  116
+					<span class="filename"><%= obj.filename %></span>
  117
+					<% } %>
  118
+				</a>
  119
+			</script>
  120
+		</div>
  121
+
  122
+		<p class="loading">Loading...</p>
  123
+
  124
+		<script type="text/javascript" src="../flashair.js"></script>
  125
+		<script type="text/javascript" src="recent.js"></script>
  126
+	</body>
  127
+</html>
91  recent/recent.js
... ...
@@ -0,0 +1,91 @@
  1
+FlashAir.RecentPhotos = {
  2
+	init : function () {
  3
+		var self = this;
  4
+
  5
+		if (location.hash == '#nocache') lscache.flush();
  6
+
  7
+		self.bindResizeEvent();
  8
+		self.load();
  9
+	},
  10
+
  11
+	bindResizeEvent : function () {
  12
+		var self = this;
  13
+		var eles = $('.ui-just');
  14
+		$(window).resize(function () {
  15
+			var padding = 5;
  16
+			var itemWidth = 100 + padding;
  17
+			var row = Math.floor( ($(window).width() - padding) / itemWidth );
  18
+			eles.width(row * itemWidth);
  19
+			self.row = row;
  20
+		}).resize();
  21
+	},
  22
+
  23
+	load : function () {
  24
+		var self = this;
  25
+
  26
+		var list = $('#list');
  27
+		var loading = $('.loading');
  28
+		var start = 0, limit = 1;
  29
+		next(function () {
  30
+			console.log(['getRecent', start, limit ]);
  31
+			loading.show();
  32
+			return FlashAir.API.getRecent(start, start + limit).
  33
+				next(function (files) {
  34
+					if (!files.length) throw "done";
  35
+					start = start + files.length;
  36
+
  37
+					for (var i = 0, it; (it = files[i]); i++) {
  38
+						var box = $(window.tmpl('listTmpl')(it));
  39
+						self.loadThumbnailImage(box);
  40
+						list.append(box);
  41
+					}
  42
+				}).
  43
+				next(function () {
  44
+					var loadNext;
  45
+					if ($(document).height() <= $(window).height() + 150) {
  46
+						/*
  47
+						 * row = 3
  48
+						 * 1, 2, 3, 6 ...
  49
+						 * row = 4
  50
+						 * 1, 3, 4, 8 ...
  51
+						 * row = 12
  52
+						 * 1, 11, 12, 24 ...
  53
+						 */
  54
+						limit = self.row - start % self.row + Math.min(self.row * Math.floor(start / self.row), self.row);
  55
+						loadNext = next();
  56
+					} else {
  57
+						// scroll event...
  58
+						limit = self.row * 2;
  59
+						loadNext = new Deferred();
  60
+						$(window).scroll(function () {
  61
+							var rest = $(document).height() - $(window).scrollTop();
  62
+							if (rest < $(window).height() + 150) {
  63
+								$(window).unbind('scroll', arguments.callee);
  64
+								loadNext.call();
  65
+							}
  66
+						});
  67
+					}
  68
+					return loadNext;
  69
+				}).
  70
+				next(arguments.callee);
  71
+		}).
  72
+		error(function (e) {
  73
+			if (e == 'done') return;
  74
+			alert(e);
  75
+		}).
  76
+		next(function () {
  77
+			loading.hide();
  78
+		});
  79
+	},
  80
+
  81
+	loadThumbnailImage : function (parent) {
  82
+		parent.find('img.thumbnail[data-path]').each(function () {
  83
+			var target = this;
  84
+			var path = target.getAttribute('data-path');
  85
+			return FlashAir.API.getThumbnailURL(path, 100).next(function (url) {
  86
+				target.src = url;
  87
+			});
  88
+		});
  89
+	}
  90
+};
  91
+FlashAir.RecentPhotos.init();
1  sdcard/blog.htm
1  sdcard/blog/flashairsxom
1  sdcard/flashair.js
1  sdcard/flashairsxom
1  sdcard/lib
1  sdcard/lib.js
1  sdcard/recent

0 notes on commit 1e42c87

Please sign in to comment.
Something went wrong with that request. Please try again.