Skip to content

Commit

Permalink
Add media galleries API sample
Browse files Browse the repository at this point in the history
Add media galleries API sample app
  • Loading branch information
joemarini committed Nov 6, 2012
1 parent 6b50a2a commit 726e3b4
Show file tree
Hide file tree
Showing 7 changed files with 370 additions and 0 deletions.
17 changes: 17 additions & 0 deletions media-gallery/manifest.json
Original file line number Diff line number Diff line change
@@ -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"]
}
}
}
266 changes: 266 additions & 0 deletions media-gallery/media-gallery.js
Original file line number Diff line number Diff line change
@@ -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);
});
});

Binary file added media-gallery/mga-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media-gallery/mga-128color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions media-gallery/page.html
Original file line number Diff line number Diff line change
@@ -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>
22 changes: 22 additions & 0 deletions media-gallery/runtime.js
Original file line number Diff line number Diff line change
@@ -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");
});
39 changes: 39 additions & 0 deletions media-gallery/styles.css
Original file line number Diff line number Diff line change
@@ -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 726e3b4

Please sign in to comment.