-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
/*jslint devel: true*/
/*global tizen, $, app, localStorage */
* @class SystemIO
*/
function SystemIO() {
- 'use strict';
+ 'use strict';
}
(function () { // strict mode wrapper
- 'use strict';
- SystemIO.prototype = {
- /**
- * Creates new empty file in specified location
- * @param {File} directoryHandle
- * @param {string} fileName
- */
- createFile: function SystemIO_createFile(directoryHandle, fileName) {
- try {
- return directoryHandle.createFile(fileName);
- } catch (e) {
- console.error('SystemIO_createFile error: ' + e.message);
- return false;
- }
- },
+ 'use strict';
+ SystemIO.prototype = {
+ /**
+ * Creates new empty file in specified location
+ *
+ * @param {File} directoryHandle
+ * @param {string} fileName
+ */
+ createFile: function SystemIO_createFile(directoryHandle, fileName) {
+
+ try {
+ return directoryHandle.createFile(fileName);
+ } catch (e) {
+ console.error('SystemIO_createFile error: ' + e.message);
+ return false;
+ }
+ },
- /**
- * Writes content to file stream
- * @param {File} file handler
- * @param {string} file content
- * @param {function} on success callback with one argument {File}
- * fileHandle
- * @param {string} content encoding
- */
- writeFile: function SystemIO_writeFile(fileHandle, fileContent,
- onSuccess, onError, contentEncoding) {
- onError = onError || function () {};
- fileHandle.openStream('w', function (fileStream) {
- try {
- if (contentEncoding === 'base64') {
- fileStream.writeBase64(fileContent);
- } else {
- fileStream.write(fileContent);
- }
- fileStream.close();
- } catch (e) {
- fileStream.close();
- onError(fileHandle);
- return;
- }
- if (typeof onSuccess === 'function') {
- onSuccess(fileHandle);
- }
- }, onError, 'UTF-8');
- },
+ /**
+ * Writes content to file stream
+ *
+ * @param {File} file handler
+ * @param {string} file content
+ * @param {function} on success callback with one argument {File} fileHandle
+ * @param {string} content encoding
+ */
+ writeFile: function SystemIO_writeFile(fileHandle, fileContent, onSuccess, onError, contentEncoding) {
+ onError = onError || function () {};
+ fileHandle.openStream('w', function (fileStream) {
+ try {
+ if (contentEncoding === 'base64') {
+ fileStream.writeBase64(fileContent);
+ } else {
+ fileStream.write(fileContent);
+ }
+ fileStream.close();
+ } catch(e) {
+ onError(fileHandle);
+ }
+ if (typeof onSuccess === 'function') {
+ onSuccess(fileHandle);
+ }
+ }, onError, 'UTF-8');
+ },
- /**
- * Opens specified location
- * @param {string} directory path
- * @param {function} on success callback
- * @param {function} on error callback
- * @param {string} mode
- */
- openDir: function SystemIO_openDir(directoryPath, onSuccess, onError,
- openMode) {
- openMode = openMode || 'rw';
- onSuccess = onSuccess || function () {};
- onError = onError || function () {};
+ /**
+ * Opens specified location
+ *
+ * @param {string} directory path
+ * @param {function} on success callback
+ * @param {function} on error callback
+ * @param {string} mode
+ */
+ openDir: function SystemIO_openDir(directoryPath, onSuccess, onError, openMode) {
+ openMode = openMode || 'rw';
+ onSuccess = onSuccess || function () {};
+ onError = onError || function () {};
- try {
- tizen.filesystem.resolve(directoryPath, onSuccess, onError,
- openMode);
- } catch (e) {
- console.error('SystemIO_openDir error:' + e.message);
- }
- },
+ try {
+ tizen.filesystem.resolve(directoryPath, onSuccess, onError, openMode);
+ } catch (e) {
+ console.error('SystemIO_openDir error:' + e.message);
+ }
+ },
- /**
- * Get list of files
- * @param {string} directoryPath directory path
- * @param {function} onSuccess on success callback
- * @param {function} onError on error callback
- * @param {string} fileMask
- */
- dir:
- function SystemIO_dir(directoryPath, onSuccess, onError, fileMask) {
- fileMask = fileMask || '';
- onSuccess = onSuccess || function () {};
+ /**
+ * Get list of files
+ *
+ * @param {string} directoryPath directory path
+ * @param {function} onSuccess on success callback
+ * @param {function} onError on error callback
+ * @param {string} fileMask
+ */
+ dir: function SystemIO_dir(directoryPath, onSuccess, onError, fileMask) {
+ fileMask = fileMask || '';
+ onSuccess = onSuccess || function () {};
- function onOpenDir(dir) {
- var filter = null;
- if (typeof dir === 'undefined') {
- throw {message: 'dir is not object'};
- }
- if (!dir.toString().match('File')) {
- throw {message: 'dir is not instance of File'};
- }
- fileMask = (typeof fileMask === 'string')
- ? {name: fileMask} : fileMask;
- filter = fileMask || null;
- dir.listFiles(onSuccess, onError, filter);
- }
+ function onOpenDir(dir) {
+ var filter = null;
+ if (typeof dir === 'undefined') {
+ throw {message: 'dir is not object'};
+ }
+ if (!dir.toString().match('File')) {
+ throw {message: 'dir is not instance of File'};
+ }
+ fileMask = (typeof fileMask === 'string') ? {name: fileMask} : fileMask;
+ filter = fileMask || null;
+ dir.listFiles(onSuccess, onError, filter);
+ }
- function onOpenDirError(e) {
- console.error('onOpenDirError: ' + e.message);
- }
+ function onOpenDirError(e) {
+ console.error('onOpenDirError: ' + e.message);
+ }
- try {
- this.openDir(directoryPath, onOpenDir, onOpenDirError, 'r');
- } catch (e) {
- console.error('SystemIO_dir error:' + e.message);
- }
- },
+ try {
+ this.openDir(directoryPath, onOpenDir, onOpenDirError, 'r');
+ } catch (e) {
+ console.error('SystemIO_dir error:' + e.message);
+ }
+ },
- /**
- * Parse specified filepath and returns data parts
- * @param {string} filePath
- * @returnss {array}
- */
- getPathData: function SystemIO_getPathData(filePath) {
- var path = {
- originalPath: filePath,
- fileName: '',
- dirName: ''
- },
- splittedPath = filePath.split('/');
+ /**
+ * Parse specified filepath and returns data parts
+ *
+ * @param {string} filePath
+ * @returnss {array}
+ */
+ getPathData: function SystemIO_getPathData(filePath) {
+ var path = {
+ originalPath: filePath,
+ fileName: '',
+ dirName: ''
+ },
+ splittedPath = filePath.split('/');
- path.fileName = splittedPath.pop();
- path.dirName = splittedPath.join('/') || '/';
+ path.fileName = splittedPath.pop();
+ path.dirName = splittedPath.join('/') || '/';
- return path;
- },
+ return path;
+ },
- /**
- * Save specified content to file
- * @param {string} file path
- * @param {string} file content
- * @param {string} file encoding
- */
- saveFileContent: function SystemIO_saveFileContent(filePath,
- fileContent, onSaveSuccess, onSaveFailure, fileEncoding) {
- var pathData = this.getPathData(filePath),
- self = this,
- fileHandle;
+ /**
+ * Save specified content to file
+ *
+ * @param {string} file path
+ * @param {string} file content
+ * @param {string} file encoding
+ */
+ saveFileContent: function SystemIO_saveFileContent(filePath, fileContent, onSaveSuccess, onSaveFailure, fileEncoding) {
+ var pathData = this.getPathData(filePath),
+ self = this,
+ fileHandle;
- function onOpenDirSuccess(dir) {
- // create new file
- fileHandle = self.createFile(dir, pathData.fileName);
- if (fileHandle !== false) {
- // save data into this file
- self.writeFile(fileHandle, fileContent, onSaveSuccess,
- onSaveFailure, fileEncoding);
- } else {
- onSaveFailure();
- }
- }
+ function onOpenDirSuccess(dir) {
+ // create new file
+ fileHandle = self.createFile(dir, pathData.fileName);
+ if (fileHandle !== false) {
+ // save data into this file
+ self.writeFile(fileHandle, fileContent, onSaveSuccess, onSaveFailure, fileEncoding);
+ } else {
+ onSaveFailure();
+ }
+ }
- // open directory
- this.openDir(pathData.dirName, onOpenDirSuccess, onSaveFailure);
- },
+ // open directory
+ this.openDir(pathData.dirName, onOpenDirSuccess, onSaveFailure);
+ },
- /**
- * Deletes node with specified path
- * @param {string} node path
- * @param {function} success callback
- */
- deleteNode: function SystemIO_deleteNode(nodePath, onSuccess) {
- var pathData = this.getPathData(nodePath),
- self = this;
+ /**
+ * Deletes node with specified path
+ *
+ * @param {string} node path
+ * @param {function} success callback
+ */
+ deleteNode: function SystemIO_deleteNode(nodePath, onSuccess) {
+ var pathData = this.getPathData(nodePath),
+ self = this;
- function onDeleteSuccess() {
- tizen.content.scanFile(nodePath, function () {});
- onSuccess();
- }
+ function onDeleteSuccess() {
+ onSuccess();
+ }
- function onDeleteError(e) {
- console.error('SystemIO_deleteNode:_onDeleteError', e);
- }
+ function onDeleteError(e) {
+ console.error('SystemIO_deleteNode:_onDeleteError', e);
+ }
- function onOpenDirSuccess(dir) {
- var onListFiles = function (files) {
- if (files.length > 0) {
- // file exists;
- if (files[0].isDirectory) {
- self.deleteDir(dir, files[0].fullPath,
- onDeleteSuccess, onDeleteError);
- } else {
- self.deleteFile(dir, files[0].fullPath,
- onDeleteSuccess, onDeleteError);
- }
- } else {
- onDeleteSuccess();
- }
- };
+ function onOpenDirSuccess(dir) {
+ var onListFiles = function (files) {
+ if (files.length > 0) {
+ // file exists;
+ if (files[0].isDirectory) {
+ self.deleteDir(dir, files[0].fullPath, onDeleteSuccess, onDeleteError);
+ } else {
+ self.deleteFile(dir, files[0].fullPath, onDeleteSuccess, onDeleteError);
+ }
+ } else {
+ onDeleteSuccess();
+ }
+ };
- // check file exists;
- dir.listFiles(onListFiles, function (e) {
- console.error(e);
- }, {
- name: pathData.fileName
- });
- }
+ // check file exists;
+ dir.listFiles(onListFiles, function (e) {
+ console.error(e);
+ }, {
+ name: pathData.fileName
+ });
+ }
- this.openDir(pathData.dirName, onOpenDirSuccess, function (e) {
- console.error('openDir error:' + e.message);
- alert("Cannot save photo\n" + e.message);
- });
- },
+ this.openDir(pathData.dirName, onOpenDirSuccess, function (e) {
+ console.error('openDir error:' + e.message);
+ alert("Cannot save photo\n" + e.message);
+ });
+ },
- /**
- * Deletes specified file
- * @param {File} dir
- * @param {string} filePath file path
- * @param {function} onDeleteSuccess delete success callback
- * @param {function} onDeleteError delete error callback
- */
- deleteFile: function SystemIO_deleteFile(dir, filePath, onDeleteSuccess,
- onDeleteError) {
- try {
- dir.deleteFile(filePath, onDeleteSuccess, onDeleteError);
- } catch (e) {
- console.error('SystemIO_deleteFile error:' + e.message);
- return false;
- }
- },
+ /**
+ * Deletes specified file
+ *
+ * @param {File} dir
+ * @param {string} filePath file path
+ * @param {function} onDeleteSuccess delete success callback
+ * @param {function} onDeleteError delete error callback
+ */
+ deleteFile: function SystemIO_deleteFile(dir, filePath, onDeleteSuccess, onDeleteError) {
+ try {
+ dir.deleteFile(filePath, onDeleteSuccess, onDeleteError);
+ } catch (e) {
+ console.error('SystemIO_deleteFile error:' + e.message);
+ return false;
+ }
+ },
- /**
- * Deletes specified directory
- * @param {File} dir
- * @param {string} dir path
- * @param {function} delete success callback
- * @param {function} delete error callback
- * @returns {boolean}
- */
- deleteDir: function SystemIO_deleteDir(dir, dirPath, onDeleteSuccess,
- onDeleteError) {
- try {
- dir.deleteDirectory(dirPath, false, onDeleteSuccess,
- onDeleteError);
- } catch (e) {
- console.error('SystemIO_deleteDir error:' + e.message);
- return false;
- }
+ /**
+ * Deletes specified directory
+ *
+ * @param {File} dir
+ * @param {string} dir path
+ * @param {function} delete success callback
+ * @param {function} delete error callback
+ * @returns {boolean}
+ */
+ deleteDir: function SystemIO_deleteDir(dir, dirPath, onDeleteSuccess, onDeleteError) {
+ try {
+ dir.deleteDirectory(dirPath, false, onDeleteSuccess, onDeleteError);
+ } catch (e) {
+ console.error('SystemIO_deleteDir error:' + e.message);
+ return false;
+ }
- return true;
- },
+ return true;
+ },
- /**
- * The method check the file exists;
- * @param {string} filePath
- * @param {function} onCheck success callback
- * @returns {undefined}
- */
- fileExists: function SystemIO_fileExists(filePath, onCheck) {
- var pathData = this.getPathData(filePath);
+ /**
+ * The method check the file exists;
+ * @param {string} filePath
+ * @param {function} onCheck success callback
+ * @returns {undefined}
+ */
+ fileExists: function SystemIO_fileExists(filePath, onCheck) {
+ var pathData = this.getPathData(filePath);
- function onOpenDirSuccess(dir) {
- try {
- dir.resolve(pathData.fileName);
- onCheck(true);
- } catch (error) {
- onCheck(false);
- }
- }
+ function onOpenDirSuccess(dir) {
+ try {
+ dir.resolve(pathData.fileName);
+ onCheck(true);
+ } catch (error) {
+ onCheck(false);
+ }
+ }
- // if directory not exists, the file also not exists;
- function onOpenDirError(error) {
- onCheck(false);
- }
+ // if directory not exists, the file also not exists;
+ function onOpenDirError(error) {
+ onCheck(false);
+ }
- // open directory
- this.openDir(pathData.dirName, onOpenDirSuccess, onOpenDirError);
- }
- };
+ // open directory
+ this.openDir(pathData.dirName, onOpenDirSuccess, onOpenDirError);
+ }
+ };
}());
\ No newline at end of file
*/
/*jslint devel: true*/
-/*global $, Audio, window, localStorage, tizen, canvas, SystemIO, document,
- navigator, clearInterval, setInterval, setTimeout */
+/*global $, Audio, window, localStorage, tizen, canvas, SystemIO, document, navigator, clearInterval, setInterval, setTimeout */
var selfCamera;
function SelfCamera() {
- "use strict";
+ "use strict";
}
(function () {
- "use strict";
- var DELAY_2_SECOND = 2, DELAY_5_SECOND = 5, DELAY_10_SECOND = 10;
-
- SelfCamera.prototype = {
- countdown: -1, // current value after clicking the camera button
- countdownTimeoutID: -1,
- countSound: new Audio('sounds/sounds_count.wav'),
- img: document.createElement('canvas'),
- filename: '',
- loadDirectory: '',
- parentSaveDirectory: 'file:///opt/usr/media/',
- saveDirectory: 'file:///opt/usr/media/Images/',
- IMG_PREFIX: 'SelfCamera_',
- shutterSound: new Audio('sounds/sounds_Shutter_01.wav'),
- timer: null, // value set by the buttons
- systemIO: null,
- video: null,
- src: null,
- isMediaWorking: false,
- previewLock: false
- };
-
- /**
- * Initialize timer buttons
- * @param {Number} value - number of countdown seconds
- */
- SelfCamera.prototype.setTimer = function setTimer(value) {
- this.timer = value;
- // clear buttons
- $('#timer2, #timer5, #timer10').removeClass('selected');
- // mark active button
- $('#timer' + value).addClass('selected');
- // if media is working
- if (this.isMediaWorking) {
- try {
- // try to play stream
- selfCamera.video.play();
- } catch (e) {
- console.error(e);
- }
- }
- };
-
- /**
- * Stream object handler
- * @param {Stream} stream
- */
- SelfCamera.prototype.onCaptureVideoSuccess =
- function onCaptureVideoSuccess(stream) {
- var urlStream;
- // create stream
- urlStream = window.webkitURL.createObjectURL(stream);
- this.isMediaWorking = true;
- // create video element with stream handler
- this.createVideoElement(urlStream);
- // initialize timer buttons options
- this.setTimer(DELAY_2_SECOND);
- };
-
- /**
- * Create HTML video element and adds it to DOM
- * @param {Stream} src
- */
- SelfCamera.prototype.createVideoElement = function (src) {
- this.video = $('<video/>', {
- autoplay: 'autoplay',
- id: 'video',
- style: 'height:' + $(window).height() + 'px',
- src: src
- }).appendTo("#camera").get(0);
-
- this.bindVideoEvents();
- };
-
- SelfCamera.prototype.onCaptureVideoError = function onCaptureVideoError(e) {
- console.error(e);
- };
-
- /**
- * Enable navigator media options to manage video stream
- */
- SelfCamera.prototype.startPreview = function startPreview() {
- // declare what will be used by this application
- var options = {
- audio: true,
- video: true
- };
-
- navigator.getUserMedia = navigator.getUserMedia
- || navigator.webkitGetUserMedia;
- try {
- if (typeof (navigator.getUserMedia) === 'function') {
- // ask user to grant permissions to use media objects
- navigator.getUserMedia(options,
- this.onCaptureVideoSuccess.bind(this),
- this.onCaptureVideoError.bind(this));
- }
- } catch (e) {
- alert('navigator.getUserMedia() error.');
- console.error('navigator.getUserMedia() error: ' + e.message);
- }
- };
-
- /**
- * Launch service to display taken photo
- * @retutn {Boolean} success or failure
- */
- SelfCamera.prototype.launchPreview = function launchPreview() {
- var service, onReply, self = this;
- // if preview is locked
- if (this.previewLock) {
- return false;
- }
- // if filename is invalid
- if (this.filename === '') {
- return false;
- }
- // try to launch service
- this.showPhotoPreview(this.filename);
- return true;
- };
-
- /**
- * TODO unused function ?
- */
- SelfCamera.prototype.showGallery = function showGallery(service) {
- var onReply, self = this;
- onReply = {
- onsuccess: function (data) {
- self.showPhotoPreview(data[0].value[0]);
- },
- onfailure: function () {}
- };
-
- try {
- tizen.application.launchAppControl(
- service,
- null,
- function () {
- setTimeout(function () {self.previewLock = false; }, 700);
- },
- function (err) {
- self.previewLock = false;
- console.error('Gallery launch failed: ' + err.message);
- },
- onReply
- );
- self.previewLock = true;
- } catch (exc) {
- alert('Exception: ' + exc.message);
- }
- };
-
- /**
- * Run external application service to show taken photo
- * @param {File} file
- */
- SelfCamera.prototype.showPhotoPreview = function showPhotoPreview(file) {
- var service, onReply, self = this;
-
- // configure service
- service = new tizen.ApplicationControl(
- 'http://tizen.org/appcontrol/operation/view',
- file
- );
- onReply = {onsuccess: function () {}, onfailure: function () {}};
-
- try {
- // trye to launch service
- tizen.application.launchAppControl(
- service,
- null,
- function () {
- setTimeout(function () {self.previewLock = false; }, 700);
- },
- function (err) {
- self.previewLock = false;
- console.error('Photo launch failed: ' + err.message);
- },
- onReply
- );
- self.previewLock = true;
- } catch (exc) {
- alert('Exception: ' + exc.message);
- }
- };
-
- /**
- * Set dir for new images
- * @param {String} dirName
- */
- SelfCamera.prototype.setLoadDirectory = function setLoadDirectory(dirName) {
- this.loadDirectory = dirName;
- if (!this.loadDirectory.match(/\/$/)) {
- this.loadDirectory += '/';
- }
- };
-
- /**
- * Display for 3s failure message
- */
- SelfCamera.prototype.showFailureMessage = function showFailureMessage() {
- $('#failure').css('display', 'block');
- setTimeout(
- function () {
- $('#failure').css('display', 'none');
- },
- 3000
- );
- };
-
- /**
- * Saves taken screenshoot to file
- * @param {Object} canvas
- * @param {String} fileName
- */
- SelfCamera.prototype.saveCanvas = function saveCanvas(canvas, fileName) {
- var data,
- self = this,
- // successful save callback
- onSuccess = function (fileHandle) {
- self.setLoadDirectory(self.getFileDirectoryURI(fileHandle));
- tizen.content.scanFile(
- fileName,
- function () {
- // if taken photo exists load it as thumb
- self.loadThumbnail(true, true);
- },
- function () {
- console.error('scanFile: file not found');
- self.loadThumbnail(true, false);
- }
- );
- }.bind(this),
- // failure save callback
- onFailure = function (e) {
- console.log('Failed to take photo.');
- self.showFailureMessage();
- // if file wasn't saved properly
- // delete corrupted file
- self.systemIO.deleteNode(fileName,
- function () {
- console.log('Deleted corrupted file.');
- setTimeout(
- function () {
- // back to old thumb
- self.loadThumbnail(true, false);
- },
- 1000
- );
- });
- };
-
- try {
- // get base64 data from canvas
- data = canvas.toDataURL().replace('data:image/png;base64,', '')
- .replace('data:,', '');
- if (data === '') { // if data is not valid
- throw {message: "No image source"};
- }
- } catch (e) { // if can't get valid base64 info
- this.filename = '';
- console.error('canvas.toDataUrl error: ' + e.message);
- alert("Data source error: " + e.message);
- return;
- }
-
- try {
- this.systemIO.deleteNode(fileName, function () {
- try {
- // try to save file data into file
- this.systemIO.saveFileContent(fileName, data, onSuccess,
- onFailure, 'base64');
- } catch (e) {
- console.error('saveDataToFile error: ' + e.message);
- }
- }.bind(this));
- } catch (e2) {
- console.error('Delete old file error: ' + e2.message);
- }
- };
-
- /**
- * Take screenshoot from the current displaying video frame
- * @param {Video} video
- */
- SelfCamera.prototype.captureImage = function captureImage(video) {
- var sourceWidth = window.innerWidth,
- sourceHeight = window.innerHeight,
- sourceX = (sourceWidth - $(video).width()) / 2,
- sourceY = (sourceHeight - $(video).height()) / 2;
-
- this.img.width = sourceWidth;
- this.img.height = sourceHeight;
-
- // Crop image to viewport dimension
- this.img.getContext('2d').drawImage(video, sourceX, sourceY,
- $(video).width(), $(video).height());
-
- // To get best available dimension
- // this.img.width = video.videoWidth;
- // this.img.height = video.videoHeight;
- // this.img.getContext('2d').drawImage(video, 0, 0);
- };
-
- /**
- * Sets current file name
- */
- SelfCamera.prototype.setFileName = function setFileName(filename) {
- this.filename = filename;
- this.loadThumbnail(false, false);
- };
-
- /**
- * Changes Date object into string timestamp
- * @return {String} timestamp
- */
- SelfCamera.prototype.getTimestamp = function getTimestamp() {
- var d = new Date();
- return d.getUTCFullYear() +
- '-' + d.getUTCMonth() +
- '-' + d.getUTCDay() +
- '-' + d.getUTCHours() +
- '-' + d.getUTCMinutes() +
- '-' + d.getUTCSeconds() +
- '-' + d.getUTCMilliseconds();
- };
-
- /**
- * Creates screenshoot and save on device hard drive
- */
- SelfCamera.prototype.takePhoto = function takePhoto() {
- this.captureImage(this.video);
- this.filename = this.IMG_PREFIX + this.getTimestamp() + '.png';
- this.savePhoto();
- };
-
- /**
- * Saves canvas screenshoot on device hard drive
- */
- SelfCamera.prototype.savePhoto = function savePhoto() {
- var self = this;
- this.saveCanvas(this.img, this.saveDirectory + this.filename);
- };
-
- /**
- * Find last taken photo with specified prefix
- * @param {Function} onFind callback
- */
- SelfCamera.prototype.findLastPhoto = function findLastPhoto(onFind) {
- // find all images in content storage with specified prefix
- tizen.content.find(
- function (files) {
- if (files.length !== 0) {
- // run callback with last image
- onFind(files[0].contentURI);
- } else {
- onFind(null);
- }
- },
- null,
- null,
- new tizen.CompositeFilter("INTERSECTION",
- [
- new tizen.AttributeFilter("title", "STARTSWITH",
- this.IMG_PREFIX),
- new tizen.AttributeFilter("type", "EXACTLY", 'IMAGE')
- ]),
- new tizen.SortMode("modifiedDate", "DESC")
- );
- };
-
- /**
- * Count down step handler
- */
- SelfCamera.prototype.onCountdownTimeout = function onCountdownTimeout() {
- // update steps to the end
- this.countdown -= 1;
- // it it is last step
- if (this.countdown < 0) {
- // remove DOM element
- this.clearCountdown();
- this.shutterSound.play();
- try {
- // take photo
- this.takePhoto();
- } catch (e) {
- console.error(e);
- }
- } else { // if it isn't last step
- // update DOM element
- $('#countdown').text(this.countdown);
- this.countSound.currentTime = 0;
- this.countSound.play();
- // set new timeout
- this.countdownTimeoutID =
- setTimeout(this.onCountdownTimeout.bind(this), 1000);
- }
- };
-
- /**
- * Display count down element on the screen
- * and starts counting down to zero from startVlue
- * @param {Number} startValue
- */
- SelfCamera.prototype.startCountdown = function startCountdown(startValue) {
- // hide thumb
- $("#thumbnail").hide();
- // unbind timer buttons click listeners
- $(".timers div").off("click");
- // if there is running count down switch it off
- if (this.countdownTimeoutID > 0) {
- clearTimeout(this.countdownTimeoutID);
- this.countdownTimeoutID = -1;
- }
- // set number of seconds to end
- this.countdown = startValue || this.timer;
- // launch timer and remember its id
- this.countdownTimeoutID =
- setTimeout(this.onCountdownTimeout.bind(this), 1000);
- // show countdown element
- $('#countdown').show().text(this.countdown);
- this.countSound.currentTime = 0;
- this.countSound.play();
- };
-
- /**
- * Clear count down informations
- */
- SelfCamera.prototype.clearCountdown = function clearCountdown() {
- // hide countdown DOM element
- $('#countdown').text('').hide();
- this.countdown = -1;
- // clear current countdown id
- clearTimeout(this.countdownTimeoutID);
- this.countdownTimeoutID = -1;
- // refresh bindings to timer buttons
- this.bindTimerClicks();
- };
-
- /**
- * Resize video element to full screen
- */
- SelfCamera.prototype.resizeVideo = function () {
- var w = this.video.videoWidth, // video height
- h = this.video.videoHeight, // video width
- W = $(window).width(), // window width
- H = $(window).height(), // window height
- // is video stream resolution greater than window resolution
- wide = w / h >= W / H,
- margin,
- size;
- // if stream hasn't been loaded yet
- if (w <= 0 || h <= 0) {
- setTimeout(this.resizeVideo.bind(this), 100); // wait for stream
- return;
- }
- if (wide) {
- size = Math.round(w * H / h);
- margin = (W - size) / 2;
- $(this.video).css({
- 'margin-left': margin + 'px',
- 'margin-top': '0 px',
- 'width': size + 'px',
- 'height': H + 'px'
- });
- } else {
- size = Math.round(h * W / w);
- margin = (H - size) / 2;
- $(this.video).css({
- 'margin-left': '0 px',
- 'margin-top': margin + 'px',
- 'width': W + 'px',
- 'height': size + 'px'
- });
- }
- $('#camera').css({
- 'width': W + 'px',
- 'height': H + 'px'
- });
- };
-
- /**
- * Bind event handlers to video element
- */
- SelfCamera.prototype.bindVideoEvents = function () {
- // handle video stream suspendtion
- $(this.video).on("stalled", function (e) {
- this.load();
- });
- // when video start playind
- $(this.video).on("playing", this.resizeVideo.bind(this));
- $(this.video).on('click', function () { this.play(); });
- };
-
- /**
- * Bind event handlers to DOM elements
- */
- SelfCamera.prototype.bindEvents = function bindEvents() {
- var self = this;
-
- document.addEventListener('webkitvisibilitychange', function (event) {
- self.clearCountdown();
- self.previewLock = false;
- if (document.webkitVisibilityState === 'visible') {
- self.reloadSaveDirectory();
- if (self.video !== null) {
- self.video.play();
- }
- self.loadThumbnail(true, false);
- }
- });
-
- $('shutter').mousedown(function (ev) {
- $('shutter').addClass('active');
- }).mouseup(function (ev) {
- $('shutter').removeClass('active');
- }).on('touchstart', function (ev) {
- $('shutter').addClass('active');
- }).on('touchend', function (ev) {
- $('shutter').removeClass('active');
- });
-
- $(window).on('tizenhwkey', function (e) {
- if (e.originalEvent.keyName === "back") {
- if (self.countdownTimeoutID !== -1) {
- self.clearCountdown();
- self.loadThumbnail(true, false);
- } else {
- tizen.application.getCurrentApplication().exit();
- }
- }
- });
-
- this.bindTimerClicks();
-
- $('#thumbnail').on('click', this.launchPreview.bind(this));
- $('#shutter').on('touchstart', this.shutterTouched.bind(this));
- };
-
- /**
- * Handle press shutter buttton
- */
- SelfCamera.prototype.shutterTouched = function () {
- if (this.previewLock) {
- return;
- }
- // if media is working
- if (this.isMediaWorking) {
- // start count down
- this.startCountdown();
- } else { // if media doesn't work display information message
- alert("To be able to take pictures you have to allow application "
- + "to use your media. Please restart app and allow "
- + "Self Camera to access media content.");
- }
- };
-
- /**
- * Sets handlers for click event to timer buttons
- */
- SelfCamera.prototype.bindTimerClicks = function bindTimerClicks() {
- $('#timer2').on('click', this.setTimer.bind(this, DELAY_2_SECOND));
- $('#timer5').on('click', this.setTimer.bind(this, DELAY_5_SECOND));
- $('#timer10').on('click', this.setTimer.bind(this, DELAY_10_SECOND));
- };
-
- // FIX for file.parent.toURI() + escaping white signs
- /**
- * Retrieve parent directory URI from file URI
- * @param {File} file
- * @return {String} file parent directory URI
- */
- SelfCamera.prototype.getFileDirectoryURI = function (file) {
- var dirURI;
- dirURI = encodeURI(
- file.toURI()
- .split('/')
- .slice(0, -1)
- .join('/')
- );
- return dirURI;
- };
-
- /**
- * Loads thumb image and add it to appropriate DOM element
- * @param {Boolean} show
- * @param {Boolean} animate
- */
- SelfCamera.prototype.loadThumbnail = function (show, animate) {
- var self = this, image;
- show = show || false;
- animate = animate || false;
- // find last taken photo
- this.findLastPhoto(function (file) {
- if (file) {
- self.filename = file;
- file = this.fixURI(file) + '?r=' + Math.random();
- // create new image object
- image = new Image();
- // add listener load event
- image.onload = function () {
- // update DOM element css styles
- $('#upImage').css('background-image', 'url(' + file + ')');
- $('#thumbnail').css('background-image',
- 'url("./images/transparent.png")');
- if (show) {
- if (animate) {
- $('#thumbnail').css({'opacity': 0.01}).show()
- .animate({'opacity': 1.00});
- } else {
- $('#thumbnail').show();
- }
- }
- };
- // start downloading image
- image.src = file;
- } else { // if thera are no photos in expected catalog
- self.filename = '';
- $('#thumbnail').hide();
- $('#upImage').css('background-image', '');
- }
- }.bind(this));
- };
-
- /**
- * FIXes invalid URI returned by API's File::contentURI
- * See File::toURI() issue https://bugs.tizendev.org/jira/browse/N_SE-54639
- * @param {String} invaliduri
- * @return {String} valid file URI
- */
- SelfCamera.prototype.fixURI = function (invaliduri) {
- var scheme, address, k;
- invaliduri = invaliduri.split('://');
- scheme = invaliduri[0];
- invaliduri.shift();
- address = invaliduri.join('://').split('/');
- for (k = address.length - 1; k >= 0; k -= 1) {
- address[k] = encodeURIComponent(address[k]);
- }
- return scheme + '://' + address.join('/');
- };
-
- /**
- * Check if exists Images directory, creates new one if doesn't
- * @param {Function} callback
- */
- SelfCamera.prototype.reloadSaveDirectory = function (callback) {
- var self = this;
- callback = callback || function () {};
- tizen.filesystem.resolve('images', function () {
- // if Images directory exists just call callback
- callback();
- }, function () {
- // if Images directory doesn't exists
- // create new on and call callback
- self.systemIO.openDir(self.parentSaveDirectory, function (dir) {
- dir.createDirectory('Images');
- callback();
- }, function () {
- console.error('no parent directory');
- callback();
- });
- }, 'r');
- };
-
- /**
- * Initialize self camera application
- */
- SelfCamera.prototype.init = function init() {
- var self = this;
- this.reloadSaveDirectory(function () {
- self.systemIO = new SystemIO();
- self.loadThumbnail(true, false);
- self.startPreview();
- self.bindEvents();
- });
- };
+ "use strict";
+ var DELAY_2_SECOND = 2, DELAY_5_SECOND = 5, DELAY_10_SECOND = 10;
+ var previewLock = false;
+
+ SelfCamera.prototype = {
+ countdown: -1, // current value after clicking the camera button
+ countdownTimeoutID: -1,
+ countSound: new Audio('sounds/sounds_count.wav'),
+ img: document.createElement('canvas'),
+ filename: '',
+ loadDirectory: '',
+ parentSaveDirectory: 'file:///opt/usr/media/',
+ saveDirectory: 'file:///opt/usr/media/Images/',
+ IMG_PREFIX: 'SelfCamera_',
+ shutterSound: new Audio('sounds/sounds_Shutter_01.wav'),
+ timer: null, // value set by the buttons
+ systemIO: null,
+ video: null,
+ src: null,
+ isMediaWorking: false
+ };
+
+ SelfCamera.prototype.setTimer = function setTimer(value) {
+ this.timer = value;
+ $('#timer2, #timer5, #timer10').removeClass('selected');
+ $('#timer' + value).addClass('selected');
+ if (this.isMediaWorking) {
+ try {
+ selfCamera.video.play();
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ };
+
+ SelfCamera.prototype.onCaptureVideoSuccess = function onCaptureVideoSuccess(stream) {
+ var urlStream;
+ urlStream = window.webkitURL.createObjectURL(stream);
+ this.isMediaWorking = true;
+ this.createVideoElement(urlStream);
+ this.setTimer(DELAY_2_SECOND);
+ };
+
+ SelfCamera.prototype.createVideoElement = function (src) {
+ this.video = $('<video/>', {
+ autoplay: 'autoplay',
+ id: 'video',
+ style: 'height:' + $(window).height() + 'px',
+ src: src
+ }).appendTo("#camera").get(0);
+
+ this.bindVideoEvents();
+ };
+
+ SelfCamera.prototype.onCaptureVideoError = function onCaptureVideoError(e) {
+ // alert("Video Capture Error");
+ console.error(e);
+ };
+
+ SelfCamera.prototype.startPreview = function startPreview() {
+ var options = {
+ audio: true,
+ video: true
+ };
+
+ navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
+ try {
+ if (typeof (navigator.getUserMedia) === 'function') {
+ navigator.getUserMedia(options, this.onCaptureVideoSuccess.bind(this), this.onCaptureVideoError.bind(this));
+ }
+ } catch (e) {
+ alert('navigator.getUserMedia() error.');
+ console.error('navigator.getUserMedia() error: ' + e.message);
+ }
+
+ };
+
+ SelfCamera.prototype.launchPreview = function launchPreview() {
+ var service, onReply, self = this;
+ if (previewLock) {
+ return false;
+ }
+ if (this.filename === '') {
+ return false;
+ }
+ this.showPhotoPreview(this.filename);
+ return true;
+ };
+
+ SelfCamera.prototype.showGallery = function showGallery(service) {
+ var onReply, self = this;
+ onReply = {
+ onsuccess: function (data) {
+ self.showPhotoPreview(data[0].value[0]);
+ },
+ onfailure: function () {}
+ };
+
+ try {
+ tizen.application.launchAppControl(
+ service,
+ null,
+ function () {
+ setTimeout(function() {previewLock = false;}, 700);
+ },
+ function (err) {
+ previewLock = false;
+ console.error('Gallery launch failed: ' + err.message);
+ },
+ onReply
+ );
+ previewLock = true;
+ } catch (exc) {
+ alert('Exception: ' + exc.message);
+ }
+ };
+
+ SelfCamera.prototype.showPhotoPreview = function showPhotoPreview(file) {
+ var service, onReply, self = this;
+ service = new tizen.ApplicationControl('http://tizen.org/appcontrol/operation/view', file, "image/*");
+ onReply = {onsuccess: function () {}, onfailure: function () {}};
+
+ try {
+ tizen.application.launchAppControl(
+ service,
+ null,
+ function () {
+ setTimeout(function() {previewLock = false;}, 700);
+ },
+ function (err) {
+ previewLock = false;
+ console.error('Photo launch failed: ' + err.message);
+ },
+ onReply
+ );
+ previewLock = true;
+ } catch (exc) {
+ alert('Exception: ' + exc.message);
+ }
+ };
+
+ SelfCamera.prototype.setLoadDirectory = function setLoadDirectory(dirName) {
+ this.loadDirectory = dirName;
+ if (!this.loadDirectory.match(/\/$/)) {
+ this.loadDirectory += '/';
+ }
+ };
+
+ SelfCamera.prototype.saveCanvas = function saveCanvas(canvas, fileName) {
+ var data,
+ self = this,
+ onSuccess = function (fileHandle) {
+ this.setLoadDirectory(this.getFileDirectoryURI(fileHandle));
+ tizen.content.scanFile(
+ fileName,
+ function () {
+ setTimeout(function(){ self.loadThumbnail(true, true); }, 200);
+ },
+ function () {
+ console.error('scanFile: file not found');
+ self.loadThumbnail(true, false);
+ });
+ }.bind(this),
+ onFailure = function (e) {
+ alert("Failed to take photo!");
+ };
+
+ try {
+ data = canvas.toDataURL().replace('data:image/png;base64,', '').replace('data:,', '');
+ if (data === '') {
+ throw {message: "No image source"};
+ }
+ } catch (e) {
+ this.filename = '';
+ console.error('canvas.toDataUrl error: ' + e.message);
+ alert("Data source error: " + e.message);
+ return;
+ }
+
+ try {
+ this.systemIO.deleteNode(fileName, function () {
+ try {
+ this.systemIO.saveFileContent(fileName, data, onSuccess, onFailure, 'base64');
+ } catch (e) {
+ console.error('saveDataToFile error: ' + e.message);
+ }
+ }.bind(this));
+ } catch (e2) {
+ console.error('Delete old file error: ' + e2.message);
+ }
+ };
+
+ SelfCamera.prototype.captureImage = function captureImage(video) {
+ var sourceWidth = window.innerWidth,
+ sourceHeight = window.innerHeight,
+ sourceX = (sourceWidth - $(video).width()) / 2,
+ sourceY = (sourceHeight - $(video).height()) / 2;
+
+ this.img.width = sourceWidth;
+ this.img.height = sourceHeight;
+
+ // Crop image to viewport dimension
+ this.img.getContext('2d').drawImage(video, sourceX, sourceY, $(video).width(), $(video).height());
+
+ // To get best available dimension
+ // this.img.width = video.videoWidth;
+ // this.img.height = video.videoHeight;
+ // this.img.getContext('2d').drawImage(video, 0, 0);
+ };
+
+ SelfCamera.prototype.setFileName = function setFileName(filename) {
+ this.filename = filename;
+ this.loadThumbnail(false, false);
+ };
+
+ SelfCamera.prototype.getTimestamp = function getTimestamp() {
+ var d = new Date();
+ return '' + d.getUTCFullYear() +
+ '-' + d.getUTCMonth() +
+ '-' + d.getUTCDay() +
+ '-' + d.getUTCHours() +
+ '-' + d.getUTCMinutes() +
+ '-' + d.getUTCSeconds() +
+ '-' + d.getUTCMilliseconds();
+ };
+
+ SelfCamera.prototype.takePhoto = function takePhoto() {
+ this.captureImage(this.video);
+ this.filename = this.IMG_PREFIX + this.getTimestamp() + '.png';
+ this.savePhoto();
+ };
+
+ SelfCamera.prototype.savePhoto = function savePhoto() {
+ var self = this;
+ this.saveCanvas(this.img, this.saveDirectory + this.filename);
+ };
+
+ SelfCamera.prototype.findLastPhoto = function findLastPhoto(onFind) {
+ tizen.content.find(
+ function (files) {
+ if (files.length !== 0) {
+ onFind(files[0].contentURI);
+ } else {
+ onFind(null);
+ }
+ },
+ null,
+ null,
+ new tizen.CompositeFilter("INTERSECTION",
+ [
+ new tizen.AttributeFilter("title", "STARTSWITH", this.IMG_PREFIX),
+ new tizen.AttributeFilter("type", "EXACTLY", 'IMAGE')
+ ]),
+ new tizen.SortMode("modifiedDate", "DESC")
+ );
+ };
+
+ SelfCamera.prototype.onCountdownTimeout = function onCountdownTimeout() {
+ this.countdown -= 1;
+ if (this.countdown < 0) {
+ this.clearCountdown();
+ this.shutterSound.play();
+ try {
+ this.takePhoto();
+ } catch (e) {
+ console.error(e);
+ }
+ } else {
+ $('#countdown').text(this.countdown);
+ this.countSound.currentTime = 0;
+ this.countSound.play();
+ this.countdownTimeoutID = setTimeout(this.onCountdownTimeout.bind(this), 1000);
+ }
+ };
+
+ SelfCamera.prototype.startCountdown = function startCountdown(startValue) {
+ $("#thumbnail").hide();
+ $(".timers div").off("click");
+ if (this.countdownTimeoutID > 0) {
+ clearTimeout(this.countdownTimeoutID);
+ this.countdownTimeoutID = -1;
+ }
+ this.countdown = startValue || this.timer;
+ this.countdownTimeoutID = setTimeout(this.onCountdownTimeout.bind(this), 1000);
+ $('#countdown').show().text(this.countdown);
+ this.countSound.currentTime = 0;
+ this.countSound.play();
+ };
+
+ SelfCamera.prototype.clearCountdown = function clearCountdown() {
+ $('#countdown').text('').hide();
+ this.countdown = -1;
+ clearTimeout(this.countdownTimeoutID);
+ this.countdownTimeoutID = -1;
+ this.bindTimerClicks();
+ };
+
+ SelfCamera.prototype.bindVideoEvents = function () {
+ var self = this;
+ $(this.video).on("stalled", function (e) {
+ this.load();
+ });
+ $(this.video).on("playing", function () {
+ var margin = ($(window).width() - $(self.video).width()) / 2,
+ width = Math.round($(window).height() *
+ self.video.videoWidth / self.video.videoHeight);
+ $(self.video).css({
+ 'margin-left': margin + 'px',
+ 'width': width + 'px'
+ });
+ });
+ $(this.video).on('click', function () { this.play(); });
+ };
+
+ SelfCamera.prototype.bindEvents = function bindEvents() {
+ var self = this;
+
+ document.addEventListener('webkitvisibilitychange', function (event) {
+ self.clearCountdown();
+ previewLock = false;
+ if (document.webkitVisibilityState === 'visible') {
+ if (self.video !== null) {
+ self.reloadSaveDirectory(function () {
+ self.video.play();
+ });
+ }
+ self.loadThumbnail(true, false);
+ }
+ });
+
+ $('shutter').mousedown(function (ev) {
+ $('shutter').addClass('active');
+ }).mouseup(function (ev) {
+ $('shutter').removeClass('active');
+ }).on('touchstart', function (ev) {
+ $('shutter').addClass('active');
+ }).on('touchend', function (ev) {
+ $('shutter').removeClass('active');
+ });
+
+ $(window).on('tizenhwkey', function (e) {
+ if (e.originalEvent.keyName === "back") {
+ if (self.countdownTimeoutID !== -1) {
+ self.clearCountdown();
+ self.loadThumbnail(true, false);
+ } else {
+ tizen.application.getCurrentApplication().exit();
+ }
+ }
+ });
+
+ this.bindTimerClicks();
+
+ $('#thumbnail').on('click', this.launchPreview.bind(this));
+ $('#shutter').on('touchstart', this.shutterTouched.bind(this));
+ };
+
+ SelfCamera.prototype.shutterTouched = function () {
+ if (this.isMediaWorking) {
+ this.startCountdown();
+ } else {
+ alert("To be able to take pictures you have to allow application to use" +
+ " your media. Please restart app and allow Self Camera to" +
+ " access media content.");
+ }
+ };
+
+ SelfCamera.prototype.bindTimerClicks = function bindTimerClicks() {
+ $('#timer2').on('click', this.setTimer.bind(this, DELAY_2_SECOND));
+ $('#timer5').on('click', this.setTimer.bind(this, DELAY_5_SECOND));
+ $('#timer10').on('click', this.setTimer.bind(this, DELAY_10_SECOND));
+ };
+
+ // Fix for file.parent.toURI() + escaping white signs
+ SelfCamera.prototype.getFileDirectoryURI = function (file) {
+ var dirURI;
+ dirURI = encodeURI(
+ file.toURI()
+ .split('/')
+ .slice(0, -1)
+ .join('/')
+ );
+ return dirURI;
+ };
+
+ SelfCamera.prototype.loadThumbnail = function (show, animate) {
+ var self = this, image;
+ show = show || false;
+ animate = animate || false;
+ this.findLastPhoto(function (file) {
+ if (file) {
+ self.filename = file;
+ file = file + '?r=' + Math.random();
+ image = new Image();
+ image.onload = function() {
+ $('#upImage').css('background-image', 'url(' + file + ')');
+ $('#thumbnail').css('background-image', 'url("./images/transparent.png")');
+ if (show) {
+ if (animate) {
+ $('#thumbnail').css({'opacity':0.01}).show().animate({'opacity':1.00});
+ }
+ else {
+ $('#thumbnail').show();
+ }
+ }
+ }
+ image.src = file;
+ } else {
+ self.filename = '';
+ $('#thumbnail').hide();
+ $('#upImage').css('background-image', '');
+ }
+ }.bind(this));
+ };
+
+ SelfCamera.prototype.reloadSaveDirectory = function (callback) {
+ var self = this;
+ tizen.filesystem.resolve('images', function () {
+ callback();
+ }, function () {
+ self.systemIO.openDir(self.parentSaveDirectory, function (dir) {
+ dir.createDirectory('Images');
+ callback();
+ }, function () {
+ console.error('no parent directory');
+ callback();
+ });
+ }, 'r');
+ };
+
+ SelfCamera.prototype.init = function init() {
+ var self = this;
+ this.reloadSaveDirectory(function () {
+ self.systemIO = new SystemIO();
+ self.loadThumbnail(true, false);
+ self.startPreview();
+ self.bindEvents();
+ });
+ };
}());
selfCamera = new SelfCamera();
$(document).ready(function () {
- "use strict";
- selfCamera.init();
+ "use strict";
+ selfCamera.init();
});