Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
|
|
@ -0,0 +1,19 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module',
|
||||
'cropResizeRotate'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
var cropResizeRotate = require('cropResizeRotate');
|
||||
module.exports = function (imageBlob, metadata, thumbnailSize, done) {
|
||||
cropResizeRotate(imageBlob, null, thumbnailSize, null, metadata, function (error, resizedBlob) {
|
||||
if (error) {
|
||||
console.error('Error while resizing image: ' + error);
|
||||
done(imageBlob);
|
||||
return;
|
||||
}
|
||||
done(resizedBlob);
|
||||
});
|
||||
};
|
||||
});
|
||||
84
assets/webapps/camera.gaiamobile.org/js/lib/dcf.js
Normal file
84
assets/webapps/camera.gaiamobile.org/js/lib/dcf.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module',
|
||||
'asyncStorage',
|
||||
'debug',
|
||||
'format'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
var asyncStorage = require('asyncStorage');
|
||||
var debug = require('debug')('dcf');
|
||||
var format = require('format');
|
||||
var dcfConfigLoaded = false;
|
||||
var deferredArgs = null;
|
||||
var defaultSeq = {
|
||||
file: 1,
|
||||
dir: 100
|
||||
};
|
||||
var dcfConfig = {
|
||||
key: 'dcf_key',
|
||||
seq: null,
|
||||
postFix: 'MZLLA',
|
||||
prefix: {
|
||||
video: 'VID_',
|
||||
image: 'IMG_'
|
||||
},
|
||||
ext: {
|
||||
video: '3gp',
|
||||
image: 'jpg'
|
||||
}
|
||||
};
|
||||
exports.init = function () {
|
||||
debug('initializing');
|
||||
exports.checkFileCounter(function () {
|
||||
if (deferredArgs) {
|
||||
var args = deferredArgs;
|
||||
exports.createDCFFilename(args.storage, args.type, args.callback);
|
||||
deferredArgs = null;
|
||||
}
|
||||
debug('initialized');
|
||||
});
|
||||
};
|
||||
exports.checkFileCounter = function (callback) {
|
||||
asyncStorage.getItem(dcfConfig.key, function (value) {
|
||||
dcfConfigLoaded = true;
|
||||
dcfConfig.seq = value ? value : defaultSeq;
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
exports.createDCFFilename = function (storage, type, callback) {
|
||||
if (!dcfConfigLoaded) {
|
||||
deferredArgs = {
|
||||
storage: storage,
|
||||
type: type,
|
||||
callback: callback
|
||||
};
|
||||
return;
|
||||
}
|
||||
var dir = 'DCIM/' + dcfConfig.seq.dir + dcfConfig.postFix + '/';
|
||||
var filename = dcfConfig.prefix[type] + format.padLeft(dcfConfig.seq.file, 4, '0') + '.' + dcfConfig.ext[type];
|
||||
var filepath = dir + filename;
|
||||
var req = storage.get(filepath);
|
||||
req.onsuccess = function () {
|
||||
dcfConfig.seq.file = 1;
|
||||
dcfConfig.seq.dir += 1;
|
||||
asyncStorage.setItem(dcfConfig.key, dcfConfig.seq, function () {
|
||||
exports.createDCFFilename(storage, type, callback);
|
||||
});
|
||||
};
|
||||
req.onerror = function () {
|
||||
if (dcfConfig.seq.file < 9999) {
|
||||
dcfConfig.seq.file += 1;
|
||||
} else {
|
||||
dcfConfig.seq.file = 1;
|
||||
dcfConfig.seq.dir += 1;
|
||||
}
|
||||
asyncStorage.setItem(dcfConfig.key, dcfConfig.seq, function () {
|
||||
callback(filepath, filename, dir);
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
||||
26
assets/webapps/camera.gaiamobile.org/js/lib/format-timer.js
Normal file
26
assets/webapps/camera.gaiamobile.org/js/lib/format-timer.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module',
|
||||
'format'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
var format = require('format');
|
||||
function digits(value) {
|
||||
return format.padLeft(value, 2, '0');
|
||||
}
|
||||
module.exports = function (ms) {
|
||||
var totalSeconds = ms / 1000;
|
||||
var seconds = Math.round(totalSeconds % 60);
|
||||
var minutes = Math.floor(totalSeconds / 60);
|
||||
var hours;
|
||||
if (minutes < 60) {
|
||||
return digits(minutes) + ':' + digits(seconds);
|
||||
} else {
|
||||
hours = Math.floor(minutes / 60);
|
||||
minutes = Math.round(minutes % 60);
|
||||
return hours + ':' + digits(minutes) + ':' + digits(seconds);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
});
|
||||
51
assets/webapps/camera.gaiamobile.org/js/lib/panzoom.js
Normal file
51
assets/webapps/camera.gaiamobile.org/js/lib/panzoom.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module',
|
||||
'GestureDetector'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
var GestureDetector = require('GestureDetector');
|
||||
module.exports = addPanAndZoomHandlers;
|
||||
function addPanAndZoomHandlers(frame, swipeCallback) {
|
||||
var container = frame.container;
|
||||
var gestureDetector = new GestureDetector(container);
|
||||
gestureDetector.startDetecting();
|
||||
var swipeAmount = 0;
|
||||
container.addEventListener('dbltap', handleDoubleTap);
|
||||
container.addEventListener('transform', handleTransform);
|
||||
container.addEventListener('pan', handlePan);
|
||||
if (swipeCallback) {
|
||||
container.addEventListener('swipe', handleSwipe);
|
||||
}
|
||||
function handleDoubleTap(e) {
|
||||
var scale;
|
||||
if (frame.fit.scale > frame.fit.baseScale) {
|
||||
scale = frame.fit.baseScale / frame.fit.scale;
|
||||
} else {
|
||||
scale = 2;
|
||||
}
|
||||
frame.zoom(scale, e.detail.clientX, e.detail.clientY, 200);
|
||||
}
|
||||
function handleTransform(e) {
|
||||
frame.zoom(e.detail.relative.scale, e.detail.midpoint.clientX, e.detail.midpoint.clientY);
|
||||
}
|
||||
function handlePan(e) {
|
||||
var dx = e.detail.relative.dx;
|
||||
var dy = e.detail.relative.dy;
|
||||
if (swipeCallback) {
|
||||
dx += swipeAmount;
|
||||
swipeAmount = frame.pan(dx, dy);
|
||||
swipeCallback(swipeAmount);
|
||||
} else {
|
||||
frame.pan(dx, dy);
|
||||
}
|
||||
}
|
||||
function handleSwipe(e) {
|
||||
if (swipeAmount !== 0) {
|
||||
swipeCallback(swipeAmount, e.detail.vx);
|
||||
swipeAmount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module',
|
||||
'jpegMetaDataParser'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
var parseJpegMetadata = require('jpegMetaDataParser');
|
||||
module.exports = function (blob, done) {
|
||||
parseJpegMetadata(blob, onJpegParsed);
|
||||
function onJpegParsed(metadata) {
|
||||
metadata.blob = blob;
|
||||
if (!metadata.preview) {
|
||||
done(metadata);
|
||||
return;
|
||||
}
|
||||
var start = metadata.preview.start;
|
||||
var end = metadata.preview.end;
|
||||
var previewBlob = blob.slice(start, end, 'image/jpeg');
|
||||
parseJpegMetadata(previewBlob, onSuccess, onError);
|
||||
function onSuccess(previewMetadata) {
|
||||
metadata.preview.width = previewMetadata.width;
|
||||
metadata.preview.height = previewMetadata.height;
|
||||
done(metadata);
|
||||
}
|
||||
function onError() {
|
||||
done(metadata);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module',
|
||||
'lib/storage',
|
||||
'cropResizeRotate'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
var Storage = require('lib/storage');
|
||||
var cropResizeRotate = require('cropResizeRotate');
|
||||
module.exports = function (options, done) {
|
||||
var blob = options.blob;
|
||||
var outputSize = options.width && options.height ? {
|
||||
width: options.width,
|
||||
height: options.height
|
||||
} : options.size || null;
|
||||
cropResizeRotate(blob, null, outputSize, 'image/jpeg+exif', function (error, resizedBlob) {
|
||||
if (error) {
|
||||
console.error('Error while resizing image: ' + error);
|
||||
done(blob);
|
||||
return;
|
||||
}
|
||||
if (resizedBlob === blob) {
|
||||
done(blob);
|
||||
return;
|
||||
}
|
||||
var storage = new Storage();
|
||||
storage.deletePicture(blob.name, addPicture);
|
||||
function addPicture(error) {
|
||||
if (error) {
|
||||
done(blob);
|
||||
return;
|
||||
}
|
||||
storage.addPicture(resizedBlob, { filepath: blob.name }, onSavedPicture);
|
||||
}
|
||||
function onSavedPicture(error, filepath, absolutePath, fileBlob) {
|
||||
done(fileBlob);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
75
assets/webapps/camera.gaiamobile.org/js/lib/sounds.js
Normal file
75
assets/webapps/camera.gaiamobile.org/js/lib/sounds.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
define([
|
||||
'require',
|
||||
'exports',
|
||||
'module'
|
||||
], function (require, exports, module) {
|
||||
'use strict';
|
||||
module.exports = Sounds;
|
||||
function Sounds(list) {
|
||||
this.items = {};
|
||||
(list || []).forEach(this.add, this);
|
||||
}
|
||||
Sounds.prototype.add = function (data) {
|
||||
var self = this;
|
||||
var sound = {
|
||||
name: data.name,
|
||||
url: data.url,
|
||||
setting: data.setting,
|
||||
enabled: false
|
||||
};
|
||||
this.items[data.name] = sound;
|
||||
this.isEnabled(sound, function (value) {
|
||||
self.setEnabled(sound, value);
|
||||
self.observeSetting(sound);
|
||||
});
|
||||
};
|
||||
Sounds.prototype.isEnabled = function (sound, done) {
|
||||
setTimeout(function () {
|
||||
var mozSettings = navigator.mozSettings;
|
||||
var key = sound.setting;
|
||||
if (!mozSettings) {
|
||||
return;
|
||||
}
|
||||
mozSettings.createLock().get(key).onsuccess = onSuccess;
|
||||
function onSuccess(e) {
|
||||
var result = e.target.result[key];
|
||||
done(result);
|
||||
}
|
||||
});
|
||||
};
|
||||
Sounds.prototype.observeSetting = function (sound) {
|
||||
var mozSettings = navigator.mozSettings;
|
||||
var key = sound.setting;
|
||||
var self = this;
|
||||
if (mozSettings) {
|
||||
mozSettings.addObserver(key, function (e) {
|
||||
self.setEnabled(sound, e.settingValue);
|
||||
});
|
||||
}
|
||||
};
|
||||
Sounds.prototype.setEnabled = function (sound, value) {
|
||||
sound.enabled = value;
|
||||
};
|
||||
Sounds.prototype.play = function (name) {
|
||||
var sound = this.items[name];
|
||||
if (!sound.audio) {
|
||||
sound.audio = this.createAudio(sound.url);
|
||||
}
|
||||
this.playSound(sound);
|
||||
};
|
||||
Sounds.prototype.player = function (name) {
|
||||
return function () {
|
||||
this.play(name);
|
||||
}.bind(this);
|
||||
};
|
||||
Sounds.prototype.playSound = function (sound) {
|
||||
if (sound.enabled) {
|
||||
sound.audio.cloneNode(true).play();
|
||||
}
|
||||
};
|
||||
Sounds.prototype.createAudio = function (url) {
|
||||
var audio = new Audio(url);
|
||||
audio.mozAudioChannelType = 'notification';
|
||||
return audio;
|
||||
};
|
||||
});
|
||||
20
assets/webapps/camera.gaiamobile.org/js/lib/string-utils.js
Normal file
20
assets/webapps/camera.gaiamobile.org/js/lib/string-utils.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
define(['require'], function (require) {
|
||||
'use strict';
|
||||
var StringUtils = {};
|
||||
StringUtils.toCamelCase = function (str) {
|
||||
str = str.toLowerCase().replace(/_/g, '-');
|
||||
return str.replace(/-([a-z])/g, function (g) {
|
||||
return g[1].toUpperCase();
|
||||
});
|
||||
};
|
||||
StringUtils.toHyphenate = function (str) {
|
||||
return str.replace(/([a-z][A-Z])/g, function (g) {
|
||||
return g[0] + '-' + g[1].toLowerCase();
|
||||
});
|
||||
};
|
||||
StringUtils.lastPathComponent = function (path) {
|
||||
var pathComponents = path.split('/');
|
||||
return pathComponents[pathComponents.length - 1];
|
||||
};
|
||||
return StringUtils;
|
||||
});
|
||||
Loading…
Reference in a new issue