Permalink
Browse files

Merge pull request #45 from joemarini/master

Add media galleries API sample
  • Loading branch information...
2 parents 2e351bb + 726e3b4 commit ecc58edcc74c1914fd9345f27f8d60effb44412f @PaulKinlan PaulKinlan committed Nov 6, 2012
View
17 media-gallery/manifest.json
@@ -0,0 +1,17 @@
+{
+ "name": "Media Gallery Sample",
+ "version": "0.2.0",
+ "manifest_version": 2,
+ "description": "Used to test Media Gallery API",
+ "permissions": [{
+ "mediaGalleries": ["read", "allAutoDetected"]
+ }],
+ "icons": {
+ "128": "mga-128color.png"
+ },
+ "app": {
+ "background": {
+ "scripts": ["runtime.js"]
+ }
+ }
+}
View
266 media-gallery/media-gallery.js
@@ -0,0 +1,266 @@
+var gGalleryIndex = 0; // gallery currently being iterated
+var gGalleryReader = null; // the filesytem reader for the current gallery
+var gDirectories = []; // used to process subdirectories
+var gGalleryArray = []; // holds information about all top-level Galleries found
+var gGalleryData = []; // hold computed information about each Gallery
+var gCurOptGrp = null;
+var imgFormats = ['png', 'bmp', 'jpeg', 'jpg', 'gif', 'png', 'svg', 'xbm', 'webp'];
+var audFormats = ['wav', 'mp3'];
+var vidFormats = ['3gp', '3gpp', 'avi', 'flv', 'mov', 'mpeg', 'mpeg4', 'mp4', 'webm', 'wmv'];
+
+function errorPrintFactory(custom) {
+ return function(e) {
+ var msg = '';
+
+ switch (e.code) {
+ case FileError.QUOTA_EXCEEDED_ERR:
+ msg = 'QUOTA_EXCEEDED_ERR';
+ break;
+ case FileError.NOT_FOUND_ERR:
+ msg = 'NOT_FOUND_ERR';
+ break;
+ case FileError.SECURITY_ERR:
+ msg = 'SECURITY_ERR';
+ break;
+ case FileError.INVALID_MODIFICATION_ERR:
+ msg = 'INVALID_MODIFICATION_ERR';
+ break;
+ case FileError.INVALID_STATE_ERR:
+ msg = 'INVALID_STATE_ERR';
+ break;
+ default:
+ msg = 'Unknown Error';
+ break;
+ };
+
+ console.log(custom + ': ' + msg);
+ };
+}
+
+function GalleryData(id) {
+ this._id = id;
+ this.path = "";
+ this.sizeBytes = 0;
+ this.numFiles = 0;
+ this.numDirs = 0;
+}
+
+function addImageToContentDiv() {
+ var content_div = document.getElementById('content');
+ var image = document.createElement('img');
+ content_div.appendChild(image);
+ return image;
+}
+
+function addAudioToContentDiv() {
+ var content_div = document.getElementById('content');
+ var audio = document.createElement('audio');
+ audio.setAttribute("controls","controls");
+ content_div.appendChild(audio);
+ return audio;
+}
+
+function addVideoToContentDiv() {
+ var content_div = document.getElementById('content');
+ var audio = document.createElement('video');
+ audio.setAttribute("controls","controls");
+ content_div.appendChild(audio);
+ return audio;
+}
+
+function getFileType(filename) {
+ var ext = filename.substr(filename.lastIndexOf('.') + 1).toLowerCase();
+ if (imgFormats.indexOf(ext) >= 0)
+ return "image";
+ else if (audFormats.indexOf(ext) >= 0)
+ return "audio";
+ else if (vidFormats.indexOf(ext) >= 0)
+ return "video";
+ else return null;
+}
+
+function clearContentDiv() {
+ var content_div = document.getElementById('content');
+ while (content_div.childNodes.length >= 1) {
+ content_div.removeChild(content_div.firstChild);
+ }
+}
+function clearList() {
+ document.getElementById("GalleryList").innerHTML = "";
+}
+
+function updateSelection(e) {
+ var selList = document.getElementById("GalleryList");
+ var indx = selList.selectedIndex;
+ var fsId = selList.options[indx].getAttribute("data-fsid");
+ var fs = null;
+
+ // get the filesystem that the selected file belongs to
+ for (var i=0; i < gGalleryArray.length; i++) {
+ var galInfo = JSON.parse(gGalleryArray[i].name);
+
+ if (galInfo.galleryId == fsId) {
+ fs = gGalleryArray[i];
+ break;
+ }
+ }
+ if (fs) {
+ var path = selList.options[indx].getAttribute("data-fullpath");
+ fs.root.getFile(path, {create: false}, function(fileEntry) {
+ var url = fileEntry.toURL();
+ var newElem = null;
+ // show the file data
+ clearContentDiv();
+ var type = getFileType(path);
+ if (type == "image")
+ newElem = addImageToContentDiv();
+ else if (type == "audio")
+ newElem = addAudioToContentDiv();
+ else if (type == "video")
+ newElem = addVideoToContentDiv();
+
+ if (newElem) {
+ (function(image_element) {
+ fileEntry.file(function(fff) {
+ var reader = new FileReader();
+ reader.onerror = errorPrintFactory('FileReader');
+ reader.onloadend = function(e) {
+ image_element.src = this.result;
+ };
+ reader.readAsDataURL(fff);
+ }, errorPrintFactory('PlayBack'));
+ }(newElem));
+ }
+ });
+ }
+}
+
+function addGallery(name, id) {
+ var optGrp = document.createElement("optgroup");
+ optGrp.setAttribute("label",name);
+ optGrp.setAttribute("id", id);
+ document.getElementById("GalleryList").appendChild(optGrp);
+ return optGrp;
+}
+
+function addItem(itemEntry) {
+ var opt = document.createElement("option");
+ if (itemEntry.isFile) {
+ opt.setAttribute("data-fullpath", itemEntry.fullPath);
+
+ var galInfo = JSON.parse(itemEntry.filesystem.name);
+ opt.setAttribute("data-fsid", galInfo.galleryId);
+ }
+ opt.appendChild(document.createTextNode(itemEntry.name));
+ gCurOptGrp.appendChild(opt);
+}
+
+function scanGallery(entries) {
+ // when the size of the entries array is 0, we've processed all the directory contents
+ if (entries.length == 0) {
+ if (gDirectories.length > 0) {
+ var dir_entry = gDirectories.shift();
+ console.log('Doing subdir: ' + dir_entry.fullPath);
+ gGalleryReader = dir_entry.createReader();
+ gGalleryReader.readEntries(scanGallery, errorPrintFactory('readEntries'));
+ }
+ else {
+ gGalleryIndex++;
+ if (gGalleryIndex < gGalleryArray.length) {
+ console.log('Doing next Gallery: ' + gGalleryArray[gGalleryIndex].name);
+ scanGalleries(gGalleryArray[gGalleryIndex]);
+ }
+ }
+ return;
+ }
+ for (var i = 0; i < entries.length; i++) {
+ console.log(entries[i].name);
+
+ if (entries[i].isFile) {
+ addItem(entries[i]);
+ gGalleryData[gGalleryIndex].numFiles++;
+ (function(galData) {
+ entries[i].getMetadata(function(metadata){
+ galData.sizeBytes += metadata.size;
+ });
+ }(gGalleryData[gGalleryIndex]));
+ }
+ else if (entries[i].isDirectory) {
+ gDirectories.push(entries[i]);
+ }
+ else {
+ console.log("Got something other than a file or directory.");
+ }
+ }
+ // readEntries has to be called until it returns an empty array. According to the spec,
+ // the function might not return all of the directory's contents during a given call.
+ gGalleryReader.readEntries(scanGallery, errorPrintFactory('readMoreEntries'));
+}
+
+function scanGalleries(fs) {
+ console.log('Reading gallery: ' + fs.name);
+ var galInfo = JSON.parse(fs.name);
+ gCurOptGrp = addGallery(galInfo.name, galInfo.galleryId);
+ gGalleryData[gGalleryIndex] = new GalleryData(galInfo.galleryId);
+ gGalleryReader = fs.root.createReader();
+ gGalleryReader.readEntries(scanGallery, errorPrintFactory('readEntries'));
+}
+
+function getGalleriesInfo(results) {
+ clearContentDiv();
+ if (results.length) {
+ var str = 'Gallery count: ' + results.length + ' ( ';
+ results.forEach(function(item, indx, arr) {
+ // the gallery name is a JSON string containing and id and a name
+ var gallery = JSON.parse(item.name);
+ str += gallery.name;
+ if (indx < arr.length-1)
+ str += ",";
+ str += " ";
+ });
+ str += ')';
+ document.getElementById("filename").innerText = str;
+ gGalleryArray = results; // store the list of gallery directories
+ gGalleryIndex = 0;
+
+ document.getElementById("scan-button").disabled = "";
+ }
+ else {
+ document.getElementById("filename").innerText = 'No galleries found';
+ document.getElementById("scan-button").disabled = "disabled";
+ }
+}
+
+window.addEventListener("load", function() {
+ // __MGA__bRestart is set in the launcher code to indicate that the app was
+ // restarted instead of being normally launched
+ if (window.__MGA__bRestart) {
+ console.log("App was restarted");
+ // if the app was restarted, get the media gallery information
+ chrome.mediaGalleries.getMediaFileSystems({
+ interactive : 'if_needed'
+ }, getGalleriesInfo);
+ }
+
+ document.getElementById('gallery-button').addEventListener("click", function() {
+ chrome.mediaGalleries.getMediaFileSystems({
+ interactive : 'if_needed'
+ }, getGalleriesInfo);
+ });
+ document.getElementById('configure-button').addEventListener("click", function() {
+ chrome.mediaGalleries.getMediaFileSystems({
+ interactive : 'yes'
+ }, getGalleriesInfo);
+ });
+ document.getElementById('scan-button').addEventListener("click", function () {
+ clearContentDiv();
+ clearList();
+ if (gGalleryArray.length > 0) {
+ scanGalleries(gGalleryArray[0]);
+ }
+ });
+ document.getElementById('GalleryList').addEventListener("change", function(e) {
+ updateSelection(e);
+ });
+});
+
View
BIN media-gallery/mga-128.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN media-gallery/mga-128color.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
26 media-gallery/page.html
@@ -0,0 +1,26 @@
+<!--- Copyright (c) 2010 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file. -->
+<html>
+ <head>
+ <title>Media Gallery API Sample</title>
+ <link rel="stylesheet" href="styles.css">
+ <script src="media-gallery.js"></script>
+ </head>
+ <body>
+ <h1>Media Gallery Explorer</h1>
+ <button id="gallery-button">Get Galleries Info</button>
+ <button id="configure-button">Select Galleries...</button>
+ <button id="scan-button" disabled="false">Scan galleries</button>
+ <p id="info">
+ <span id="filename">&nbsp;</span>
+ </p>
+ <div id="container">
+ <div id="list">
+ <select id="GalleryList" size="10" style="width:100%; height:100%">
+ </select>
+ </div>
+ <div id="content"></div>
+ </div>
+ </body>
+</html>
View
22 media-gallery/runtime.js
@@ -0,0 +1,22 @@
+// Use the runtime event listeners to set a window property indicating whether the
+// app was launched normally or as a result of being restarted
+
+chrome.app.runtime.onLaunched.addListener(function(data) {
+ chrome.app.window.create('page.html',
+ {width:900, height:600, minWidth:900, maxWidth: 900, minHeight:600, maxHeight: 600, id:"MGExp"},
+ function(app_win) {
+ app_win.contentWindow.__MGA__bRestart = false;
+ }
+ );
+ console.log("app launched");
+});
+
+chrome.app.runtime.onRestarted.addListener(function() {
+ chrome.app.window.create('page.html',
+ {width:900, height:600, minWidth:900, maxWidth: 900, minHeight:600, maxHeight: 600, id:"MGExp"},
+ function(app_win) {
+ app_win.contentWindow.__MGA__bRestart = true;
+ }
+ );
+ console.log("app restarted");
+});
View
39 media-gallery/styles.css
@@ -0,0 +1,39 @@
+body {
+ background: #555;
+ color: #eee;
+ font-family: "Open Sans", Arial, sans-serif;
+}
+
+h1 {
+ font-weight: 200;
+ color: white;
+}
+
+#content {
+ height: 75%;
+ width: 74%;
+ overflow-y: scroll;
+ border: 1px solid #aaa;
+ border-radius: 5px;
+ display: inline-block;
+ background-color: #777;
+}
+
+#list {
+ height: 75%;
+ width: 25%;
+ border: 1px solid #aaa;
+ border-radius: 5px;
+ display: inline-block;
+ vertical-align: top;
+ background-color: #777;
+}
+
+#info {
+ border: 1px solid #aaa;
+ background-color: #777;
+ width: auto;
+ border-radius: 5px;
+ overflow: hidden;
+ padding: 5px;
+}

0 comments on commit ecc58ed

Please sign in to comment.