Initial commit.
/*######################################################################
### D A S C Y L L U S N A M E S P A C E
######################################################################*/
var D = {
// Versions
platform: Ti.getPlatform(),
name: Ti.API.Application.getName(),
version: Ti.API.Application.getVersion(),
ti_version: Ti.getVersion(),
architecture: Ti.Platform.getArchitecture(),
// Declared windows, for easy referencing
window: {},
// Very first run of Dasycllus?
firstrun: false,
// Persistent storage DB handle.
db: null,
// The current TF server we'll be connected to;
// uri: http://localhost:8080/
// version: Thingfish 0.5.0 (build ...)
//
tf: null,
// Open a handle to the local database, initializing it
// if necessary and performing rudamentary upwards migrations.
//
initDB: function() {
this.db = Ti.Database.openFile(
Ti.Filesystem.getFile(
Ti.Filesystem.getApplicationDataDirectory(), 'dascyllus.db'
)
);
var rv = this.db.execute( 'PRAGMA user_version' );
var schema_version = parseInt( rv.fieldByName('user_version') );
var schemas_dir = Ti.Filesystem.getFile(
Ti.Filesystem.getApplicationDirectory(), 'sql' );
var current_version = schemas_dir.getDirectoryListing().length;
if ( schema_version == 0 ) {
this.notify( 'Welcome!', 'Dascyllus defaults installed.' );
this.firstrun = true;
}
if ( schema_version != current_version ) {
console.log( 'Dascyllus DB at version ' + schema_version +
', needs to be upgraded to ' + current_version + '.' );
while ( schema_version != current_version ) {
var update_version = schema_version + 1;
console.log( ' updating to version ' + update_version );
var line;
var schema_file = Ti.Filesystem.getFileStream(
Ti.Filesystem.getApplicationDirectory(), 'sql', update_version + '.sql' );
schema_file.open();
this.db.execute( 'BEGIN' );
while ( line = schema_file.readLine() ) this.db.execute( line.toString() );
this.db.execute( 'PRAGMA user_version = ' + update_version );
this.db.execute( 'COMMIT' );
schema_version = update_version;
schema_file.close();
}
}
return this.db;
},
// Return a preference's current value, or null if nonexistent.
//
getPref: function( pref ) {
var row = this.db.execute( "SELECT val FROM prefs WHERE key=?", pref );
if ( ! row.isValidRow() ) return null;
var value = row.fieldByName( 'val' );
row.close();
return value;
},
// Return a preference's current value as a boolean.
//
getBoolPref: function( pref ) {
return this.getPref( pref ) == '1'
},
// Insert or update a preference value.
//
setPref: function( pref, value ) {
this.db.execute( 'BEGIN' );
// Row already exists, remove it first.
if ( this.getPref( pref ) != null )
this.db.execute( 'DELETE FROM prefs WHERE key=?', pref );
this.db.execute( 'INSERT INTO prefs VALUES ( ?, ? )', pref, value );
this.db.execute( 'COMMIT' );
},
// Set a bool preference value.
//
setBoolPref: function( pref, value ) {
this.setPref( pref, (value ? '1' : '0') );
},
// Generic delayed callback that returns the timer handle.
//
delay: (function() {
var timer = null;
return function( callback, ms, clear_previous ) {
if ( clear_previous) clearTimeout( timer );
timer = setTimeout( callback, ms );
return timer;
};
})(),
// Create and show a new notification.
//
notify: function( title, message, callback ) {
if ( ! callback ) callback = function(){};
var notification = Ti.Notification.createNotification({
'title' : title,
'message' : message,
'timeout' : 10,
'callback' : callback,
});
notification.show();
return notification;
},
// Attempt a connection to a remote Thingfish server, and
// populate the D.tf variable.
//
checkServer: function( uri ) {
this.tf = null;
var serverOk = function( data, status, xhr ) {
var info = xhr.getResponseHeader( 'x-thingfish' );
if ( info ) {
D.tf = {
uri: uri,
version: data.version
};
D.notify( 'Connected.', info );
}
else {
D.notify( 'Unable to connect.', 'Not a Thingfish server?' );
}
};
$.ajax({
url: uri,
sync: false,
success: serverOk,
error: function( xhr, status, err ) {
D.notify( 'Unable to connect.', err );
},
dataType: 'json'
});
},
// Build the main menu.
//
setupMenu: function() {
var menu = Ti.UI.createMenu();
var yep = Ti.UI.createMenuItem( 'Yep' );
yep.addItem( 'About', function() {
if ( D.window.about && D.window.about.isVisible() ) {
D.window.about.focus();
}
else {
D.window.about = D.window.main.createWindow( 'app://window/about.html' );
D.window.about.setTopMost( true );
D.window.about.open();
}
});
yep.addItem( 'Preferences', function() {
if ( D.window.prefs && D.window.prefs.isVisible() ) {
D.window.prefs.focus();
}
else {
D.window.prefs = D.window.main.createWindow( 'app://window/prefs.html' );
D.window.prefs.open();
}
});
yep.addItem( 'Toggle Full Screen', function() {
D.window.main.setFullscreen( ! D.window.main.isFullscreen() );
});
menu.appendItem( yep );
Ti.UI.setMenu( menu );
},
/*######################################################################
### M O D E L S
######################################################################*/
// A Thingfish asset.
//
initModel: function() {
D.Asset = can.Model({
id : 'oid',
findAll: 'GET ' + D.tf.uri + '/',
findOne: 'GET ' + D.tf.uri + '/{oid}',
create : 'POST ' + D.tf.uri + '/',
update : 'PUT ' + D.tf.uri + '/{oid}',
destroy: 'DELETE ' + D.tf.uri + '/{oid}',
// TODO: other metadata hooks? diff model?
metadata: 'GET ' + D.tf.uri + '/{oid}/metadata',
}, {}).
bind( 'created', function( ev, asset ) {
console.debug( "Created a new asset " + asset.id );
}).
bind( 'updated', function( ev, asset ) {
console.debug( "Updated asset " + asset.id );
}).
bind( 'destroyed', function( ev, asset ) {
console.debug( "Removed asset " + asset.id );
}
);
},
};
// Initialization.
//
D.window.main = Ti.UI.getMainWindow();
D.setupMenu();
D.initDB();