update interface (fixes issue #6)
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
self.addEventListener( 'message', receivedMessageEvent, false );
|
||||
|
||||
function receivedMessageEvent ( event ) {
|
||||
if (
|
||||
event &&
|
||||
event.data &&
|
||||
event.data.glitch &&
|
||||
event.data.glitch.base64 &&
|
||||
event.data.glitch.parameters
|
||||
) {
|
||||
self.postMessage( { glitched: getGlitchedImageData( event.data.glitch.base64, event.data.glitch.parameters ) } );
|
||||
} else {
|
||||
self.postMessage( event.data );
|
||||
}
|
||||
}
|
||||
|
||||
var base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
var base64Map = base64Chars.split( '' );
|
||||
var reversedBase64Map = { };
|
||||
var base64ImageData;
|
||||
var byteArrayImageData;
|
||||
var jpgHeaderLength = 0;
|
||||
var params;
|
||||
|
||||
var i = 0;
|
||||
var len = 0;
|
||||
|
||||
base64Map.forEach( function ( val, key ) {
|
||||
reversedBase64Map[val] = key;
|
||||
} );
|
||||
|
||||
function getGlitchedImageData ( base64ImageData, parameters ) {
|
||||
params = parameters;
|
||||
byteArrayImageData = base64ToByteArray( base64ImageData );
|
||||
jpgHeaderLength = getJpegHeaderSize( byteArrayImageData );
|
||||
|
||||
for ( i = 0, len = params.iterations; i < len; i++ ) {
|
||||
glitchJpegBytes( byteArrayImageData, jpgHeaderLength, params.seed, params.amount, i, params.iterations );
|
||||
}
|
||||
|
||||
return byteArrayToBase64( byteArrayImageData );
|
||||
}
|
||||
|
||||
function glitchJpegBytes ( byteArray, jpgHeaderLength, seed, amount, i, len ) {
|
||||
var maxIndex = byteArray.length - jpgHeaderLength - 4;
|
||||
var pxMin = parseInt( maxIndex / len * i, 10 );
|
||||
var pxMax = parseInt( maxIndex / len * ( i + 1 ), 10 );
|
||||
var delta = pxMax - pxMin;
|
||||
var pxIndex = parseInt( pxMin + delta * seed, 10 );
|
||||
|
||||
if ( pxIndex > maxIndex ) {
|
||||
pxIndex = maxIndex;
|
||||
}
|
||||
|
||||
var index = Math.floor( jpgHeaderLength + pxIndex );
|
||||
|
||||
byteArray[index] = Math.floor( amount * 256 );
|
||||
}
|
||||
|
||||
function base64ToByteArray ( str ) {
|
||||
var result = [ ];
|
||||
var digitNum;
|
||||
var cur;
|
||||
var prev;
|
||||
for ( i = 23, len = str.length; i < len; i++ ) {
|
||||
cur = reversedBase64Map[str.charAt( i )];
|
||||
digitNum = ( i - 23 ) % 4;
|
||||
|
||||
switch ( digitNum ) {
|
||||
case 1:
|
||||
result.push( prev << 2 | cur >> 4 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result.push( ( prev & 15 ) << 4 | cur >> 2 );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
result.push( ( prev & 3 ) << 6 | cur );
|
||||
break;
|
||||
}
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function byteArrayToBase64 ( arr ) {
|
||||
var result = [ 'data:image/jpeg;base64,' ];
|
||||
var byteNum;
|
||||
var cur;
|
||||
var prev;
|
||||
|
||||
for ( i = 0, len = arr.length; i < len; i++ ) {
|
||||
cur = arr[i];
|
||||
byteNum = i % 3;
|
||||
|
||||
switch (byteNum) {
|
||||
case 0:
|
||||
result.push( base64Map[cur >> 2] );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
result.push( base64Map[( prev & 3 ) << 4 | cur >> 4] );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result.push( base64Map[( prev & 15 ) << 2 | cur >> 6] );
|
||||
result.push( base64Map[cur & 63] );
|
||||
break;
|
||||
}
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
if ( byteNum === 0 ) {
|
||||
result.push( base64Map[( prev & 3 ) << 4] );
|
||||
result.push( '==' );
|
||||
} else if ( byteNum === 1 ) {
|
||||
result.push( base64Map[( prev & 15 ) << 2] );
|
||||
result.push( '=' );
|
||||
}
|
||||
|
||||
return result.join( '' );
|
||||
}
|
||||
|
||||
function getJpegHeaderSize ( data ) {
|
||||
var result = 417;
|
||||
|
||||
for ( i = 0, len = data.length; i < len; i++ ) {
|
||||
if ( data[i] === 255 && data[i + 1] === 218 ) {
|
||||
result = i + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
importScripts( '../lib/localforage.nopromises.js' );
|
||||
|
||||
var settings;
|
||||
var defaultSettings;
|
||||
var storageKey = 'settings';
|
||||
|
||||
self.addEventListener( 'message', receivedMessageEvent, false );
|
||||
|
||||
function receivedMessageEvent ( event ) {
|
||||
if ( event && event.data ) {
|
||||
if ( event.data.load ) {
|
||||
load();
|
||||
}
|
||||
|
||||
if ( event.data.save ) {
|
||||
save( event.data.save );
|
||||
}
|
||||
|
||||
if ( event.data.setStorageKey ) {
|
||||
setStorageKey( event.data.setStorageKey );
|
||||
}
|
||||
|
||||
if ( event.data.setDefaultSettings ) {
|
||||
setDefaultSettings( event.data.setDefaultSettings );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage ( type, data ) {
|
||||
if ( typeof type === 'string' ) {
|
||||
if ( typeof data === 'undefined' ) {
|
||||
data = type;
|
||||
}
|
||||
|
||||
var message = { };
|
||||
message[type] = data;
|
||||
self.postMessage( message );
|
||||
}
|
||||
}
|
||||
|
||||
function sendError ( err ) {
|
||||
sendMessage( 'error', err );
|
||||
}
|
||||
|
||||
function setStorageKey ( newKey ) {
|
||||
if ( newKey ) {
|
||||
storageKey = newKey;
|
||||
}
|
||||
}
|
||||
|
||||
function setDefaultSettings ( newDefaultSettings ) {
|
||||
if ( newDefaultSettings ) {
|
||||
defaultSettings = newDefaultSettings;
|
||||
}
|
||||
}
|
||||
|
||||
function load () {
|
||||
localforage.getItem( storageKey, function ( err, loadedSettings ) {
|
||||
if ( err ) {
|
||||
sendError( 'settings.error.load' );
|
||||
console && console.log( 'localforage error', err );
|
||||
} else {
|
||||
if ( ! loadedSettings && defaultSettings ) {
|
||||
settings = defaultSettings;
|
||||
save( defaultSettings );
|
||||
} else {
|
||||
settings = loadedSettings;
|
||||
sendMessage( 'update', settings );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
function save ( newSettings ) {
|
||||
if ( newSettings ) {
|
||||
localforage.setItem( storageKey, newSettings, function ( err, savedSettings ) {
|
||||
if ( err ) {
|
||||
sendError( 'settings.error.save' );
|
||||
console && console.log( 'localforage error', err );
|
||||
} else {
|
||||
if ( savedSettings ) {
|
||||
settings = savedSettings || defaultSettings;
|
||||
sendMessage( 'update', settings );
|
||||
} else {
|
||||
console && console.log( 'no data was saved', savedSettings );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
importScripts( '../lib/localforage.nopromises.js' );
|
||||
importScripts( '../lib/md5.js' );
|
||||
|
||||
var storageKey = 'items';
|
||||
var entries = { };
|
||||
|
||||
self.addEventListener( 'message', receivedMessageEvent, false );
|
||||
|
||||
function receivedMessageEvent ( event ) {
|
||||
if ( event && event.data ) {
|
||||
if ( event.data.setStorageKey ) {
|
||||
setStorageKey( event.data.setStorageKey );
|
||||
}
|
||||
|
||||
if ( event.data.add ) {
|
||||
add( event.data.add );
|
||||
}
|
||||
|
||||
if ( event.data.removeCompletely ) {
|
||||
removeCompletely( event.data.removeCompletely );
|
||||
}
|
||||
|
||||
if ( event.data.removeLocalData ) {
|
||||
removeLocalData( event.data.removeLocalData );
|
||||
}
|
||||
|
||||
if ( event.data.removeImgurData ) {
|
||||
removeImgurData( event.data.removeImgurData );
|
||||
}
|
||||
|
||||
if ( event.data.load ) {
|
||||
load();
|
||||
}
|
||||
|
||||
if ( event.data.save ) {
|
||||
save();
|
||||
}
|
||||
|
||||
if ( event.data.loadItem ) {
|
||||
loadItem( event.data.loadItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage ( type, data ) {
|
||||
if ( typeof type === 'string' ) {
|
||||
if ( typeof data === 'undefined' ) {
|
||||
data = type;
|
||||
}
|
||||
|
||||
var message = { };
|
||||
message[type] = data;
|
||||
self.postMessage( message );
|
||||
}
|
||||
}
|
||||
|
||||
function sendError ( err ) {
|
||||
sendMessage( 'error', err );
|
||||
}
|
||||
|
||||
function setStorageKey ( newKey ) {
|
||||
if ( newKey ) {
|
||||
storageKey = newKey;
|
||||
}
|
||||
}
|
||||
|
||||
function add ( item ) {
|
||||
if ( item ) {
|
||||
var uid = createUID( item );
|
||||
|
||||
if (
|
||||
entries[uid] &&
|
||||
entries[uid].deleteHash === item.deleteHash &&
|
||||
entries[uid].publicUrl === item.publicUrl &&
|
||||
entries[uid].imgurID === item.imgurID
|
||||
) {
|
||||
sendError( 'file.message.before' );
|
||||
} else {
|
||||
item.timestamp = Date.now();
|
||||
entries[uid] = item;
|
||||
|
||||
save( function () {
|
||||
sendMessage( 'statusmessage', 'file.message.save' );
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeCompletely ( uid ) {
|
||||
if ( uid && entries[uid] ) {
|
||||
if (
|
||||
(
|
||||
entries[uid].deleteHash ||
|
||||
entries[uid].publicUrl ||
|
||||
entries[uid].imgurID ||
|
||||
entries[uid].values ||
|
||||
entries[uid].src
|
||||
)
|
||||
) {
|
||||
console && console.log( 'cant delete storage item because theres still some data left', entries[uid] );
|
||||
} else {
|
||||
sendMessage( 'removeall', entries[uid] );
|
||||
delete entries[uid];
|
||||
|
||||
save( function () {
|
||||
sendMessage( 'statusmessage', 'file.message.save' );
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeLocalData ( uid ) {
|
||||
if ( uid && entries[uid] ) {
|
||||
if ( entries[uid].src ) {
|
||||
delete entries[uid].src;
|
||||
|
||||
sendMessage( 'removelocaldata', entries[uid] );
|
||||
}
|
||||
|
||||
if ( entries[uid].values ) {
|
||||
delete entries[uid].values;
|
||||
}
|
||||
|
||||
if ( ! ( entries[uid].deleteHash || entries[uid].publicUrl || entries[uid].imgurID ) ) {
|
||||
removeCompletely( uid );
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
function removeImgurData ( uid ) {
|
||||
if ( uid && entries[uid] ) {
|
||||
if ( entries[uid].deleteHash ) {
|
||||
sendMessage( 'removeimgurdata', entries[uid] );
|
||||
delete entries[uid].deleteHash;
|
||||
}
|
||||
|
||||
if ( entries[uid].publicUrl ) {
|
||||
delete entries[uid].publicUrl;
|
||||
}
|
||||
|
||||
if ( entries[uid].imgurID ) {
|
||||
delete entries[uid].imgurID;
|
||||
}
|
||||
|
||||
if ( ! ( entries[uid].src || entries[uid].values ) ) {
|
||||
removeCompletely( uid );
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
function load ( callback ) {
|
||||
localforage.getItem( storageKey, function ( err, loadedData ) {
|
||||
if ( err ) {
|
||||
sendError( 'file.error.load' );
|
||||
console && console.log( 'localforage error', err );
|
||||
} else {
|
||||
entries = loadedData && loadedData.entries ? loadedData.entries : { };
|
||||
sendMessage( 'update', entries );
|
||||
|
||||
isFirstVisit = ( loadedData && loadedData.lastVisit ) ? false : true;
|
||||
|
||||
if ( isFirstVisit ) {
|
||||
sendMessage( 'firstvisit' );
|
||||
save();
|
||||
}
|
||||
|
||||
if ( typeof callback === 'function' ) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
function save ( callback ) {
|
||||
localforage.setItem( storageKey, { entries: entries, lastVisit: Date.now() }, function ( err, savedData ) {
|
||||
if ( err ) {
|
||||
sendError( 'file.error.save' );
|
||||
console && console.log( 'localforage error', err );
|
||||
} else {
|
||||
if ( savedData ) {
|
||||
entries = savedData.entries;
|
||||
sendMessage( 'update', entries );
|
||||
sendMessage( 'save' );
|
||||
|
||||
if ( typeof callback === 'function' ) {
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
console && console.log( 'no data was saved', savedData );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
function loadItem ( uid ) {
|
||||
if ( entries[uid] ) {
|
||||
sendMessage( 'loaditem', { uid: uid, entries: entries[uid] } );
|
||||
}
|
||||
}
|
||||
|
||||
function createUID ( item ) {
|
||||
var inputStr = 'N' + item.name + 'S' + item.src + 'L' + item.thumbnail.length || 0 + 'V';
|
||||
|
||||
for ( var key in item.values ) {
|
||||
inputStr += key.substr( 0, 2 );
|
||||
inputStr += item.values[key];
|
||||
}
|
||||
|
||||
return md5( inputStr );
|
||||
}
|
||||
|
||||
function getLatestUID () {
|
||||
var latestUid;
|
||||
var latestTimestamp;
|
||||
var timestamp;
|
||||
|
||||
for ( var uid in entries ) {
|
||||
timestamp = entries[uid].timestamp;
|
||||
|
||||
if ( timestamp ) {
|
||||
if ( ! latestUid || timestamp > latestTimestamp ) {
|
||||
latestUid = uid;
|
||||
latestTimestamp = timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return latestUid;
|
||||
}
|
||||
Reference in New Issue
Block a user